OSDN Git Service

* builtin-types.def (BT_UINT): Rename from BT_UNSIGNED.
[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 "tree-gimple.h"
31 #include "flags.h"
32 #include "regs.h"
33 #include "hard-reg-set.h"
34 #include "except.h"
35 #include "function.h"
36 #include "insn-config.h"
37 #include "expr.h"
38 #include "optabs.h"
39 #include "libfuncs.h"
40 #include "recog.h"
41 #include "output.h"
42 #include "typeclass.h"
43 #include "toplev.h"
44 #include "predict.h"
45 #include "tm_p.h"
46 #include "target.h"
47 #include "langhooks.h"
48 #include "basic-block.h"
49
50 #define CALLED_AS_BUILT_IN(NODE) \
51    (!strncmp (IDENTIFIER_POINTER (DECL_NAME (NODE)), "__builtin_", 10))
52
53 #ifndef PAD_VARARGS_DOWN
54 #define PAD_VARARGS_DOWN BYTES_BIG_ENDIAN
55 #endif
56
57 /* Define the names of the builtin function types and codes.  */
58 const char *const built_in_class_names[4]
59   = {"NOT_BUILT_IN", "BUILT_IN_FRONTEND", "BUILT_IN_MD", "BUILT_IN_NORMAL"};
60
61 #define DEF_BUILTIN(X, N, C, T, LT, B, F, NA, AT, IM) #X,
62 const char *const built_in_names[(int) END_BUILTINS] =
63 {
64 #include "builtins.def"
65 };
66 #undef DEF_BUILTIN
67
68 /* Setup an array of _DECL trees, make sure each element is
69    initialized to NULL_TREE.  */
70 tree built_in_decls[(int) END_BUILTINS];
71 /* Declarations used when constructing the builtin implicitly in the compiler.
72    It may be NULL_TREE when this is invalid (for instance runtime is not
73    required to implement the function call in all cases).  */
74 tree implicit_built_in_decls[(int) END_BUILTINS];
75
76 static int get_pointer_alignment (tree, unsigned int);
77 static const char *c_getstr (tree);
78 static rtx c_readstr (const char *, enum machine_mode);
79 static int target_char_cast (tree, char *);
80 static rtx get_memory_rtx (tree);
81 static tree build_string_literal (int, const char *);
82 static int apply_args_size (void);
83 static int apply_result_size (void);
84 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
85 static rtx result_vector (int, rtx);
86 #endif
87 static rtx expand_builtin_setjmp (tree, rtx);
88 static void expand_builtin_update_setjmp_buf (rtx);
89 static void expand_builtin_prefetch (tree);
90 static rtx expand_builtin_apply_args (void);
91 static rtx expand_builtin_apply_args_1 (void);
92 static rtx expand_builtin_apply (rtx, rtx, rtx);
93 static void expand_builtin_return (rtx);
94 static enum type_class type_to_class (tree);
95 static rtx expand_builtin_classify_type (tree);
96 static void expand_errno_check (tree, rtx);
97 static rtx expand_builtin_mathfn (tree, rtx, rtx);
98 static rtx expand_builtin_mathfn_2 (tree, rtx, rtx);
99 static rtx expand_builtin_mathfn_3 (tree, rtx, rtx);
100 static rtx expand_builtin_args_info (tree);
101 static rtx expand_builtin_next_arg (tree);
102 static rtx expand_builtin_va_start (tree);
103 static rtx expand_builtin_va_end (tree);
104 static rtx expand_builtin_va_copy (tree);
105 static rtx expand_builtin_memcmp (tree, tree, rtx, enum machine_mode);
106 static rtx expand_builtin_strcmp (tree, rtx, enum machine_mode);
107 static rtx expand_builtin_strncmp (tree, rtx, enum machine_mode);
108 static rtx builtin_memcpy_read_str (void *, HOST_WIDE_INT, enum machine_mode);
109 static rtx expand_builtin_strcat (tree, rtx, enum machine_mode);
110 static rtx expand_builtin_strncat (tree, rtx, enum machine_mode);
111 static rtx expand_builtin_strspn (tree, rtx, enum machine_mode);
112 static rtx expand_builtin_strcspn (tree, rtx, enum machine_mode);
113 static rtx expand_builtin_memcpy (tree, rtx, enum machine_mode);
114 static rtx expand_builtin_mempcpy (tree, rtx, enum machine_mode, int);
115 static rtx expand_builtin_memmove (tree, rtx, enum machine_mode);
116 static rtx expand_builtin_bcopy (tree);
117 static rtx expand_builtin_strcpy (tree, rtx, enum machine_mode);
118 static rtx expand_builtin_stpcpy (tree, rtx, enum machine_mode);
119 static rtx builtin_strncpy_read_str (void *, HOST_WIDE_INT, enum machine_mode);
120 static rtx expand_builtin_strncpy (tree, rtx, enum machine_mode);
121 static rtx builtin_memset_read_str (void *, HOST_WIDE_INT, enum machine_mode);
122 static rtx builtin_memset_gen_str (void *, HOST_WIDE_INT, enum machine_mode);
123 static rtx expand_builtin_memset (tree, rtx, enum machine_mode);
124 static rtx expand_builtin_bzero (tree);
125 static rtx expand_builtin_strlen (tree, rtx, enum machine_mode);
126 static rtx expand_builtin_strstr (tree, rtx, enum machine_mode);
127 static rtx expand_builtin_strpbrk (tree, rtx, enum machine_mode);
128 static rtx expand_builtin_strchr (tree, rtx, enum machine_mode);
129 static rtx expand_builtin_strrchr (tree, rtx, enum machine_mode);
130 static rtx expand_builtin_alloca (tree, rtx);
131 static rtx expand_builtin_unop (enum machine_mode, tree, rtx, rtx, optab);
132 static rtx expand_builtin_frame_address (tree, tree);
133 static rtx expand_builtin_fputs (tree, rtx, bool);
134 static rtx expand_builtin_printf (tree, rtx, enum machine_mode, bool);
135 static rtx expand_builtin_fprintf (tree, rtx, enum machine_mode, bool);
136 static rtx expand_builtin_sprintf (tree, rtx, enum machine_mode);
137 static tree stabilize_va_list (tree, int);
138 static rtx expand_builtin_expect (tree, rtx);
139 static tree fold_builtin_constant_p (tree);
140 static tree fold_builtin_classify_type (tree);
141 static tree fold_builtin_inf (tree, int);
142 static tree fold_builtin_nan (tree, tree, int);
143 static int validate_arglist (tree, ...);
144 static bool integer_valued_real_p (tree);
145 static tree fold_trunc_transparent_mathfn (tree);
146 static bool readonly_data_expr (tree);
147 static rtx expand_builtin_fabs (tree, rtx, rtx);
148 static rtx expand_builtin_cabs (tree, rtx);
149 static rtx expand_builtin_signbit (tree, rtx);
150 static tree fold_builtin_cabs (tree, tree);
151 static tree fold_builtin_trunc (tree);
152 static tree fold_builtin_floor (tree);
153 static tree fold_builtin_ceil (tree);
154 static tree fold_builtin_round (tree);
155 static tree fold_builtin_bitop (tree);
156 static tree fold_builtin_memcpy (tree);
157 static tree fold_builtin_mempcpy (tree);
158 static tree fold_builtin_memmove (tree);
159 static tree fold_builtin_strchr (tree, bool);
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 static tree fold_builtin_copysign (tree, tree);
165 static tree fold_builtin_isascii (tree);
166 static tree fold_builtin_toascii (tree);
167 static tree fold_builtin_isdigit (tree);
168 static tree fold_builtin_fabs (tree, tree);
169 static tree fold_builtin_abs (tree, tree);
170 static tree fold_builtin_unordered_cmp (tree, enum tree_code, enum tree_code);
171 static tree fold_builtin_1 (tree, bool);
172
173 static tree simplify_builtin_memcmp (tree);
174 static tree simplify_builtin_strcmp (tree);
175 static tree simplify_builtin_strncmp (tree);
176 static tree simplify_builtin_strpbrk (tree);
177 static tree simplify_builtin_strstr (tree);
178 static tree simplify_builtin_strchr (tree);
179 static tree simplify_builtin_strrchr (tree);
180 static tree simplify_builtin_strcat (tree);
181 static tree simplify_builtin_strncat (tree);
182 static tree simplify_builtin_strspn (tree);
183 static tree simplify_builtin_strcspn (tree);
184 static void simplify_builtin_next_arg (tree);
185 static void simplify_builtin_va_start (tree);
186 static tree simplify_builtin_sprintf (tree, int);
187
188
189 /* Return the alignment in bits of EXP, a pointer valued expression.
190    But don't return more than MAX_ALIGN no matter what.
191    The alignment returned is, by default, the alignment of the thing that
192    EXP points to.  If it is not a POINTER_TYPE, 0 is returned.
193
194    Otherwise, look at the expression to see if we can do better, i.e., if the
195    expression is actually pointing at an object whose alignment is tighter.  */
196
197 static int
198 get_pointer_alignment (tree exp, unsigned int max_align)
199 {
200   unsigned int align, inner;
201
202   if (TREE_CODE (TREE_TYPE (exp)) != POINTER_TYPE)
203     return 0;
204
205   align = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
206   align = MIN (align, max_align);
207
208   while (1)
209     {
210       switch (TREE_CODE (exp))
211         {
212         case NOP_EXPR:
213         case CONVERT_EXPR:
214         case NON_LVALUE_EXPR:
215           exp = TREE_OPERAND (exp, 0);
216           if (TREE_CODE (TREE_TYPE (exp)) != POINTER_TYPE)
217             return align;
218
219           inner = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
220           align = MIN (inner, max_align);
221           break;
222
223         case PLUS_EXPR:
224           /* If sum of pointer + int, restrict our maximum alignment to that
225              imposed by the integer.  If not, we can't do any better than
226              ALIGN.  */
227           if (! host_integerp (TREE_OPERAND (exp, 1), 1))
228             return align;
229
230           while (((tree_low_cst (TREE_OPERAND (exp, 1), 1))
231                   & (max_align / BITS_PER_UNIT - 1))
232                  != 0)
233             max_align >>= 1;
234
235           exp = TREE_OPERAND (exp, 0);
236           break;
237
238         case ADDR_EXPR:
239           /* See what we are pointing at and look at its alignment.  */
240           exp = TREE_OPERAND (exp, 0);
241           if (TREE_CODE (exp) == FUNCTION_DECL)
242             align = FUNCTION_BOUNDARY;
243           else if (DECL_P (exp))
244             align = DECL_ALIGN (exp);
245 #ifdef CONSTANT_ALIGNMENT
246           else if (TREE_CODE_CLASS (TREE_CODE (exp)) == 'c')
247             align = CONSTANT_ALIGNMENT (exp, align);
248 #endif
249           return MIN (align, max_align);
250
251         default:
252           return align;
253         }
254     }
255 }
256
257 /* Compute the length of a C string.  TREE_STRING_LENGTH is not the right
258    way, because it could contain a zero byte in the middle.
259    TREE_STRING_LENGTH is the size of the character array, not the string.
260
261    ONLY_VALUE should be nonzero if the result is not going to be emitted
262    into the instruction stream and zero if it is going to be expanded.
263    E.g. with i++ ? "foo" : "bar", if ONLY_VALUE is nonzero, constant 3
264    is returned, otherwise NULL, since
265    len = c_strlen (src, 1); if (len) expand_expr (len, ...); would not
266    evaluate the side-effects.
267
268    The value returned is of type `ssizetype'.
269
270    Unfortunately, string_constant can't access the values of const char
271    arrays with initializers, so neither can we do so here.  */
272
273 tree
274 c_strlen (tree src, int only_value)
275 {
276   tree offset_node;
277   HOST_WIDE_INT offset;
278   int max;
279   const char *ptr;
280
281   STRIP_NOPS (src);
282   if (TREE_CODE (src) == COND_EXPR
283       && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0))))
284     {
285       tree len1, len2;
286
287       len1 = c_strlen (TREE_OPERAND (src, 1), only_value);
288       len2 = c_strlen (TREE_OPERAND (src, 2), only_value);
289       if (tree_int_cst_equal (len1, len2))
290         return len1;
291     }
292
293   if (TREE_CODE (src) == COMPOUND_EXPR
294       && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0))))
295     return c_strlen (TREE_OPERAND (src, 1), only_value);
296
297   src = string_constant (src, &offset_node);
298   if (src == 0)
299     return 0;
300
301   max = TREE_STRING_LENGTH (src) - 1;
302   ptr = TREE_STRING_POINTER (src);
303
304   if (offset_node && TREE_CODE (offset_node) != INTEGER_CST)
305     {
306       /* If the string has an internal zero byte (e.g., "foo\0bar"), we can't
307          compute the offset to the following null if we don't know where to
308          start searching for it.  */
309       int i;
310
311       for (i = 0; i < max; i++)
312         if (ptr[i] == 0)
313           return 0;
314
315       /* We don't know the starting offset, but we do know that the string
316          has no internal zero bytes.  We can assume that the offset falls
317          within the bounds of the string; otherwise, the programmer deserves
318          what he gets.  Subtract the offset from the length of the string,
319          and return that.  This would perhaps not be valid if we were dealing
320          with named arrays in addition to literal string constants.  */
321
322       return size_diffop (size_int (max), offset_node);
323     }
324
325   /* We have a known offset into the string.  Start searching there for
326      a null character if we can represent it as a single HOST_WIDE_INT.  */
327   if (offset_node == 0)
328     offset = 0;
329   else if (! host_integerp (offset_node, 0))
330     offset = -1;
331   else
332     offset = tree_low_cst (offset_node, 0);
333
334   /* If the offset is known to be out of bounds, warn, and call strlen at
335      runtime.  */
336   if (offset < 0 || offset > max)
337     {
338       warning ("offset outside bounds of constant string");
339       return 0;
340     }
341
342   /* Use strlen to search for the first zero byte.  Since any strings
343      constructed with build_string will have nulls appended, we win even
344      if we get handed something like (char[4])"abcd".
345
346      Since OFFSET is our starting index into the string, no further
347      calculation is needed.  */
348   return ssize_int (strlen (ptr + offset));
349 }
350
351 /* Return a char pointer for a C string if it is a string constant
352    or sum of string constant and integer constant.  */
353
354 static const char *
355 c_getstr (tree src)
356 {
357   tree offset_node;
358
359   src = string_constant (src, &offset_node);
360   if (src == 0)
361     return 0;
362
363   if (offset_node == 0)
364     return TREE_STRING_POINTER (src);
365   else if (!host_integerp (offset_node, 1)
366            || compare_tree_int (offset_node, TREE_STRING_LENGTH (src) - 1) > 0)
367     return 0;
368
369   return TREE_STRING_POINTER (src) + tree_low_cst (offset_node, 1);
370 }
371
372 /* Return a CONST_INT or CONST_DOUBLE corresponding to target reading
373    GET_MODE_BITSIZE (MODE) bits from string constant STR.  */
374
375 static rtx
376 c_readstr (const char *str, enum machine_mode mode)
377 {
378   HOST_WIDE_INT c[2];
379   HOST_WIDE_INT ch;
380   unsigned int i, j;
381
382   if (GET_MODE_CLASS (mode) != MODE_INT)
383     abort ();
384   c[0] = 0;
385   c[1] = 0;
386   ch = 1;
387   for (i = 0; i < GET_MODE_SIZE (mode); i++)
388     {
389       j = i;
390       if (WORDS_BIG_ENDIAN)
391         j = GET_MODE_SIZE (mode) - i - 1;
392       if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN
393           && GET_MODE_SIZE (mode) > UNITS_PER_WORD)
394         j = j + UNITS_PER_WORD - 2 * (j % UNITS_PER_WORD) - 1;
395       j *= BITS_PER_UNIT;
396       if (j > 2 * HOST_BITS_PER_WIDE_INT)
397         abort ();
398       if (ch)
399         ch = (unsigned char) str[i];
400       c[j / HOST_BITS_PER_WIDE_INT] |= ch << (j % HOST_BITS_PER_WIDE_INT);
401     }
402   return immed_double_const (c[0], c[1], mode);
403 }
404
405 /* Cast a target constant CST to target CHAR and if that value fits into
406    host char type, return zero and put that value into variable pointed by
407    P.  */
408
409 static int
410 target_char_cast (tree cst, char *p)
411 {
412   unsigned HOST_WIDE_INT val, hostval;
413
414   if (!host_integerp (cst, 1)
415       || CHAR_TYPE_SIZE > HOST_BITS_PER_WIDE_INT)
416     return 1;
417
418   val = tree_low_cst (cst, 1);
419   if (CHAR_TYPE_SIZE < HOST_BITS_PER_WIDE_INT)
420     val &= (((unsigned HOST_WIDE_INT) 1) << CHAR_TYPE_SIZE) - 1;
421
422   hostval = val;
423   if (HOST_BITS_PER_CHAR < HOST_BITS_PER_WIDE_INT)
424     hostval &= (((unsigned HOST_WIDE_INT) 1) << HOST_BITS_PER_CHAR) - 1;
425
426   if (val != hostval)
427     return 1;
428
429   *p = hostval;
430   return 0;
431 }
432
433 /* Similar to save_expr, but assumes that arbitrary code is not executed
434    in between the multiple evaluations.  In particular, we assume that a
435    non-addressable local variable will not be modified.  */
436
437 static tree
438 builtin_save_expr (tree exp)
439 {
440   if (TREE_ADDRESSABLE (exp) == 0
441       && (TREE_CODE (exp) == PARM_DECL
442           || (TREE_CODE (exp) == VAR_DECL && !TREE_STATIC (exp))))
443     return exp;
444
445   return save_expr (exp);
446 }
447
448 /* Given TEM, a pointer to a stack frame, follow the dynamic chain COUNT
449    times to get the address of either a higher stack frame, or a return
450    address located within it (depending on FNDECL_CODE).  */
451
452 rtx
453 expand_builtin_return_addr (enum built_in_function fndecl_code, int count,
454                             rtx tem)
455 {
456   int i;
457
458   /* Some machines need special handling before we can access
459      arbitrary frames.  For example, on the sparc, we must first flush
460      all register windows to the stack.  */
461 #ifdef SETUP_FRAME_ADDRESSES
462   if (count > 0)
463     SETUP_FRAME_ADDRESSES ();
464 #endif
465
466   /* On the sparc, the return address is not in the frame, it is in a
467      register.  There is no way to access it off of the current frame
468      pointer, but it can be accessed off the previous frame pointer by
469      reading the value from the register window save area.  */
470 #ifdef RETURN_ADDR_IN_PREVIOUS_FRAME
471   if (fndecl_code == BUILT_IN_RETURN_ADDRESS)
472     count--;
473 #endif
474
475   /* Scan back COUNT frames to the specified frame.  */
476   for (i = 0; i < count; i++)
477     {
478       /* Assume the dynamic chain pointer is in the word that the
479          frame address points to, unless otherwise specified.  */
480 #ifdef DYNAMIC_CHAIN_ADDRESS
481       tem = DYNAMIC_CHAIN_ADDRESS (tem);
482 #endif
483       tem = memory_address (Pmode, tem);
484       tem = gen_rtx_MEM (Pmode, tem);
485       set_mem_alias_set (tem, get_frame_alias_set ());
486       tem = copy_to_reg (tem);
487     }
488
489   /* For __builtin_frame_address, return what we've got.  */
490   if (fndecl_code == BUILT_IN_FRAME_ADDRESS)
491     return tem;
492
493   /* For __builtin_return_address, Get the return address from that
494      frame.  */
495 #ifdef RETURN_ADDR_RTX
496   tem = RETURN_ADDR_RTX (count, tem);
497 #else
498   tem = memory_address (Pmode,
499                         plus_constant (tem, GET_MODE_SIZE (Pmode)));
500   tem = gen_rtx_MEM (Pmode, tem);
501   set_mem_alias_set (tem, get_frame_alias_set ());
502 #endif
503   return tem;
504 }
505
506 /* Alias set used for setjmp buffer.  */
507 static HOST_WIDE_INT setjmp_alias_set = -1;
508
509 /* Construct the leading half of a __builtin_setjmp call.  Control will
510    return to RECEIVER_LABEL.  This is used directly by sjlj exception
511    handling code.  */
512
513 void
514 expand_builtin_setjmp_setup (rtx buf_addr, rtx receiver_label)
515 {
516   enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
517   rtx stack_save;
518   rtx mem;
519
520   if (setjmp_alias_set == -1)
521     setjmp_alias_set = new_alias_set ();
522
523   buf_addr = convert_memory_address (Pmode, buf_addr);
524
525   buf_addr = force_reg (Pmode, force_operand (buf_addr, NULL_RTX));
526
527   emit_queue ();
528
529   /* We store the frame pointer and the address of receiver_label in
530      the buffer and use the rest of it for the stack save area, which
531      is machine-dependent.  */
532
533   mem = gen_rtx_MEM (Pmode, buf_addr);
534   set_mem_alias_set (mem, setjmp_alias_set);
535   emit_move_insn (mem, targetm.builtin_setjmp_frame_value ());
536
537   mem = gen_rtx_MEM (Pmode, plus_constant (buf_addr, GET_MODE_SIZE (Pmode))),
538   set_mem_alias_set (mem, setjmp_alias_set);
539
540   emit_move_insn (validize_mem (mem),
541                   force_reg (Pmode, gen_rtx_LABEL_REF (Pmode, receiver_label)));
542
543   stack_save = gen_rtx_MEM (sa_mode,
544                             plus_constant (buf_addr,
545                                            2 * GET_MODE_SIZE (Pmode)));
546   set_mem_alias_set (stack_save, setjmp_alias_set);
547   emit_stack_save (SAVE_NONLOCAL, &stack_save, NULL_RTX);
548
549   /* If there is further processing to do, do it.  */
550 #ifdef HAVE_builtin_setjmp_setup
551   if (HAVE_builtin_setjmp_setup)
552     emit_insn (gen_builtin_setjmp_setup (buf_addr));
553 #endif
554
555   /* Tell optimize_save_area_alloca that extra work is going to
556      need to go on during alloca.  */
557   current_function_calls_setjmp = 1;
558
559   /* Set this so all the registers get saved in our frame; we need to be
560      able to copy the saved values for any registers from frames we unwind.  */
561   current_function_has_nonlocal_label = 1;
562 }
563
564 /* Construct the trailing part of a __builtin_setjmp call.
565    This is used directly by sjlj exception handling code.  */
566
567 void
568 expand_builtin_setjmp_receiver (rtx receiver_label ATTRIBUTE_UNUSED)
569 {
570   /* Clobber the FP when we get here, so we have to make sure it's
571      marked as used by this function.  */
572   emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
573
574   /* Mark the static chain as clobbered here so life information
575      doesn't get messed up for it.  */
576   emit_insn (gen_rtx_CLOBBER (VOIDmode, static_chain_rtx));
577
578   /* Now put in the code to restore the frame pointer, and argument
579      pointer, if needed.  The code below is from expand_end_bindings
580      in stmt.c; see detailed documentation there.  */
581 #ifdef HAVE_nonlocal_goto
582   if (! HAVE_nonlocal_goto)
583 #endif
584     emit_move_insn (virtual_stack_vars_rtx, hard_frame_pointer_rtx);
585
586 #if ARG_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
587   if (fixed_regs[ARG_POINTER_REGNUM])
588     {
589 #ifdef ELIMINABLE_REGS
590       size_t i;
591       static const struct elims {const int from, to;} elim_regs[] = ELIMINABLE_REGS;
592
593       for (i = 0; i < ARRAY_SIZE (elim_regs); i++)
594         if (elim_regs[i].from == ARG_POINTER_REGNUM
595             && elim_regs[i].to == HARD_FRAME_POINTER_REGNUM)
596           break;
597
598       if (i == ARRAY_SIZE (elim_regs))
599 #endif
600         {
601           /* Now restore our arg pointer from the address at which it
602              was saved in our stack frame.  */
603           emit_move_insn (virtual_incoming_args_rtx,
604                           copy_to_reg (get_arg_pointer_save_area (cfun)));
605         }
606     }
607 #endif
608
609 #ifdef HAVE_builtin_setjmp_receiver
610   if (HAVE_builtin_setjmp_receiver)
611     emit_insn (gen_builtin_setjmp_receiver (receiver_label));
612   else
613 #endif
614 #ifdef HAVE_nonlocal_goto_receiver
615     if (HAVE_nonlocal_goto_receiver)
616       emit_insn (gen_nonlocal_goto_receiver ());
617     else
618 #endif
619       { /* Nothing */ }
620
621   /* @@@ This is a kludge.  Not all machine descriptions define a blockage
622      insn, but we must not allow the code we just generated to be reordered
623      by scheduling.  Specifically, the update of the frame pointer must
624      happen immediately, not later.  So emit an ASM_INPUT to act as blockage
625      insn.  */
626   emit_insn (gen_rtx_ASM_INPUT (VOIDmode, ""));
627 }
628
629 /* __builtin_setjmp is passed a pointer to an array of five words (not
630    all will be used on all machines).  It operates similarly to the C
631    library function of the same name, but is more efficient.  Much of
632    the code below (and for longjmp) is copied from the handling of
633    non-local gotos.
634
635    NOTE: This is intended for use by GNAT and the exception handling
636    scheme in the compiler and will only work in the method used by
637    them.  */
638
639 static rtx
640 expand_builtin_setjmp (tree arglist, rtx target)
641 {
642   rtx buf_addr, next_lab, cont_lab;
643
644   if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
645     return NULL_RTX;
646
647   if (target == 0 || !REG_P (target)
648       || REGNO (target) < FIRST_PSEUDO_REGISTER)
649     target = gen_reg_rtx (TYPE_MODE (integer_type_node));
650
651   buf_addr = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
652
653   next_lab = gen_label_rtx ();
654   cont_lab = gen_label_rtx ();
655
656   expand_builtin_setjmp_setup (buf_addr, next_lab);
657
658   /* Set TARGET to zero and branch to the continue label.  Use emit_jump to
659      ensure that pending stack adjustments are flushed.  */
660   emit_move_insn (target, const0_rtx);
661   emit_jump (cont_lab);
662
663   emit_label (next_lab);
664
665   expand_builtin_setjmp_receiver (next_lab);
666
667   /* Set TARGET to one.  */
668   emit_move_insn (target, const1_rtx);
669   emit_label (cont_lab);
670
671   /* Tell flow about the strange goings on.  Putting `next_lab' on
672      `nonlocal_goto_handler_labels' to indicates that function
673      calls may traverse the arc back to this label.  */
674
675   current_function_has_nonlocal_label = 1;
676   nonlocal_goto_handler_labels
677     = gen_rtx_EXPR_LIST (VOIDmode, next_lab, nonlocal_goto_handler_labels);
678
679   return target;
680 }
681
682 /* __builtin_longjmp is passed a pointer to an array of five words (not
683    all will be used on all machines).  It operates similarly to the C
684    library function of the same name, but is more efficient.  Much of
685    the code below is copied from the handling of non-local gotos.
686
687    NOTE: This is intended for use by GNAT and the exception handling
688    scheme in the compiler and will only work in the method used by
689    them.  */
690
691 void
692 expand_builtin_longjmp (rtx buf_addr, rtx value)
693 {
694   rtx fp, lab, stack, insn, last;
695   enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
696
697   if (setjmp_alias_set == -1)
698     setjmp_alias_set = new_alias_set ();
699
700   buf_addr = convert_memory_address (Pmode, buf_addr);
701
702   buf_addr = force_reg (Pmode, buf_addr);
703
704   /* We used to store value in static_chain_rtx, but that fails if pointers
705      are smaller than integers.  We instead require that the user must pass
706      a second argument of 1, because that is what builtin_setjmp will
707      return.  This also makes EH slightly more efficient, since we are no
708      longer copying around a value that we don't care about.  */
709   if (value != const1_rtx)
710     abort ();
711
712   current_function_calls_longjmp = 1;
713
714   last = get_last_insn ();
715 #ifdef HAVE_builtin_longjmp
716   if (HAVE_builtin_longjmp)
717     emit_insn (gen_builtin_longjmp (buf_addr));
718   else
719 #endif
720     {
721       fp = gen_rtx_MEM (Pmode, buf_addr);
722       lab = gen_rtx_MEM (Pmode, plus_constant (buf_addr,
723                                                GET_MODE_SIZE (Pmode)));
724
725       stack = gen_rtx_MEM (sa_mode, plus_constant (buf_addr,
726                                                    2 * GET_MODE_SIZE (Pmode)));
727       set_mem_alias_set (fp, setjmp_alias_set);
728       set_mem_alias_set (lab, setjmp_alias_set);
729       set_mem_alias_set (stack, setjmp_alias_set);
730
731       /* Pick up FP, label, and SP from the block and jump.  This code is
732          from expand_goto in stmt.c; see there for detailed comments.  */
733 #if HAVE_nonlocal_goto
734       if (HAVE_nonlocal_goto)
735         /* We have to pass a value to the nonlocal_goto pattern that will
736            get copied into the static_chain pointer, but it does not matter
737            what that value is, because builtin_setjmp does not use it.  */
738         emit_insn (gen_nonlocal_goto (value, lab, stack, fp));
739       else
740 #endif
741         {
742           lab = copy_to_reg (lab);
743
744           emit_insn (gen_rtx_CLOBBER (VOIDmode,
745                                       gen_rtx_MEM (BLKmode,
746                                                    gen_rtx_SCRATCH (VOIDmode))));
747           emit_insn (gen_rtx_CLOBBER (VOIDmode,
748                                       gen_rtx_MEM (BLKmode,
749                                                    hard_frame_pointer_rtx)));
750
751           emit_move_insn (hard_frame_pointer_rtx, fp);
752           emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
753
754           emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
755           emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
756           emit_indirect_jump (lab);
757         }
758     }
759
760   /* Search backwards and mark the jump insn as a non-local goto.
761      Note that this precludes the use of __builtin_longjmp to a
762      __builtin_setjmp target in the same function.  However, we've
763      already cautioned the user that these functions are for
764      internal exception handling use only.  */
765   for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
766     {
767       if (insn == last)
768         abort ();
769       if (JUMP_P (insn))
770         {
771           REG_NOTES (insn) = alloc_EXPR_LIST (REG_NON_LOCAL_GOTO, const0_rtx,
772                                               REG_NOTES (insn));
773           break;
774         }
775       else if (CALL_P (insn))
776         break;
777     }
778 }
779
780 /* Expand a call to __builtin_nonlocal_goto.  We're passed the target label
781    and the address of the save area.  */
782
783 static rtx
784 expand_builtin_nonlocal_goto (tree arglist)
785 {
786   tree t_label, t_save_area;
787   rtx r_label, r_save_area, r_fp, r_sp, insn;
788
789   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
790     return NULL_RTX;
791
792   t_label = TREE_VALUE (arglist);
793   arglist = TREE_CHAIN (arglist);
794   t_save_area = TREE_VALUE (arglist);
795
796   r_label = expand_expr (t_label, NULL_RTX, VOIDmode, 0);
797   r_save_area = expand_expr (t_save_area, NULL_RTX, VOIDmode, 0);
798   r_fp = gen_rtx_MEM (Pmode, r_save_area);
799   r_sp = gen_rtx_MEM (STACK_SAVEAREA_MODE (SAVE_NONLOCAL),
800                       plus_constant (r_save_area, GET_MODE_SIZE (Pmode)));
801
802   current_function_has_nonlocal_goto = 1;
803
804 #if HAVE_nonlocal_goto
805   /* ??? We no longer need to pass the static chain value, afaik.  */
806   if (HAVE_nonlocal_goto)
807     emit_insn (gen_nonlocal_goto (const0_rtx, r_label, r_sp, r_fp));
808   else
809 #endif
810     {
811       r_label = copy_to_reg (r_label);
812
813       emit_insn (gen_rtx_CLOBBER (VOIDmode,
814                                   gen_rtx_MEM (BLKmode,
815                                                gen_rtx_SCRATCH (VOIDmode))));
816
817       emit_insn (gen_rtx_CLOBBER (VOIDmode,
818                                   gen_rtx_MEM (BLKmode,
819                                                hard_frame_pointer_rtx)));
820  
821       /* Restore frame pointer for containing function.
822          This sets the actual hard register used for the frame pointer
823          to the location of the function's incoming static chain info.
824          The non-local goto handler will then adjust it to contain the
825          proper value and reload the argument pointer, if needed.  */
826       emit_move_insn (hard_frame_pointer_rtx, r_fp);
827       emit_stack_restore (SAVE_NONLOCAL, r_sp, NULL_RTX);
828  
829       /* USE of hard_frame_pointer_rtx added for consistency;
830          not clear if really needed.  */
831       emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
832       emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
833       emit_indirect_jump (r_label);
834     }
835  
836   /* Search backwards to the jump insn and mark it as a
837      non-local goto.  */
838   for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
839     {
840       if (JUMP_P (insn))
841         {
842           REG_NOTES (insn) = alloc_EXPR_LIST (REG_NON_LOCAL_GOTO,
843                                               const0_rtx, REG_NOTES (insn));
844           break;
845         }
846       else if (CALL_P (insn))
847         break;
848     }
849
850   return const0_rtx;
851 }
852
853 /* __builtin_update_setjmp_buf is passed a pointer to an array of five words
854    (not all will be used on all machines) that was passed to __builtin_setjmp.
855    It updates the stack pointer in that block to correspond to the current
856    stack pointer.  */
857
858 static void
859 expand_builtin_update_setjmp_buf (rtx buf_addr)
860 {
861   enum machine_mode sa_mode = Pmode;
862   rtx stack_save;
863
864
865 #ifdef HAVE_save_stack_nonlocal
866   if (HAVE_save_stack_nonlocal)
867     sa_mode = insn_data[(int) CODE_FOR_save_stack_nonlocal].operand[0].mode;
868 #endif
869 #ifdef STACK_SAVEAREA_MODE
870   sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
871 #endif
872
873   stack_save
874     = gen_rtx_MEM (sa_mode,
875                    memory_address
876                    (sa_mode,
877                     plus_constant (buf_addr, 2 * GET_MODE_SIZE (Pmode))));
878
879 #ifdef HAVE_setjmp
880   if (HAVE_setjmp)
881     emit_insn (gen_setjmp ());
882 #endif
883
884   emit_stack_save (SAVE_NONLOCAL, &stack_save, NULL_RTX);
885 }
886
887 /* Expand a call to __builtin_prefetch.  For a target that does not support
888    data prefetch, evaluate the memory address argument in case it has side
889    effects.  */
890
891 static void
892 expand_builtin_prefetch (tree arglist)
893 {
894   tree arg0, arg1, arg2;
895   rtx op0, op1, op2;
896
897   if (!validate_arglist (arglist, POINTER_TYPE, 0))
898     return;
899
900   arg0 = TREE_VALUE (arglist);
901   /* Arguments 1 and 2 are optional; argument 1 (read/write) defaults to
902      zero (read) and argument 2 (locality) defaults to 3 (high degree of
903      locality).  */
904   if (TREE_CHAIN (arglist))
905     {
906       arg1 = TREE_VALUE (TREE_CHAIN (arglist));
907       if (TREE_CHAIN (TREE_CHAIN (arglist)))
908         arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
909       else
910         arg2 = build_int_2 (3, 0);
911     }
912   else
913     {
914       arg1 = integer_zero_node;
915       arg2 = build_int_2 (3, 0);
916     }
917
918   /* Argument 0 is an address.  */
919   op0 = expand_expr (arg0, NULL_RTX, Pmode, EXPAND_NORMAL);
920
921   /* Argument 1 (read/write flag) must be a compile-time constant int.  */
922   if (TREE_CODE (arg1) != INTEGER_CST)
923     {
924       error ("second arg to `__builtin_prefetch' must be a constant");
925       arg1 = integer_zero_node;
926     }
927   op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
928   /* Argument 1 must be either zero or one.  */
929   if (INTVAL (op1) != 0 && INTVAL (op1) != 1)
930     {
931       warning ("invalid second arg to __builtin_prefetch; using zero");
932       op1 = const0_rtx;
933     }
934
935   /* Argument 2 (locality) must be a compile-time constant int.  */
936   if (TREE_CODE (arg2) != INTEGER_CST)
937     {
938       error ("third arg to `__builtin_prefetch' must be a constant");
939       arg2 = integer_zero_node;
940     }
941   op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0);
942   /* Argument 2 must be 0, 1, 2, or 3.  */
943   if (INTVAL (op2) < 0 || INTVAL (op2) > 3)
944     {
945       warning ("invalid third arg to __builtin_prefetch; using zero");
946       op2 = const0_rtx;
947     }
948
949 #ifdef HAVE_prefetch
950   if (HAVE_prefetch)
951     {
952       if ((! (*insn_data[(int) CODE_FOR_prefetch].operand[0].predicate)
953              (op0,
954               insn_data[(int) CODE_FOR_prefetch].operand[0].mode))
955           || (GET_MODE (op0) != Pmode))
956         {
957           op0 = convert_memory_address (Pmode, op0);
958           op0 = force_reg (Pmode, op0);
959         }
960       emit_insn (gen_prefetch (op0, op1, op2));
961     }
962   else
963 #endif
964     op0 = protect_from_queue (op0, 0);
965   /* Don't do anything with direct references to volatile memory, but
966      generate code to handle other side effects.  */
967   if (!MEM_P (op0) && side_effects_p (op0))
968     emit_insn (op0);
969 }
970
971 /* Get a MEM rtx for expression EXP which is the address of an operand
972    to be used to be used in a string instruction (cmpstrsi, movmemsi, ..).  */
973
974 static rtx
975 get_memory_rtx (tree exp)
976 {
977   rtx addr = expand_expr (exp, NULL_RTX, ptr_mode, EXPAND_SUM);
978   rtx mem;
979
980   addr = convert_memory_address (Pmode, addr);
981
982   mem = gen_rtx_MEM (BLKmode, memory_address (BLKmode, addr));
983
984   /* Get an expression we can use to find the attributes to assign to MEM.
985      If it is an ADDR_EXPR, use the operand.  Otherwise, dereference it if
986      we can.  First remove any nops.  */
987   while ((TREE_CODE (exp) == NOP_EXPR || TREE_CODE (exp) == CONVERT_EXPR
988           || TREE_CODE (exp) == NON_LVALUE_EXPR)
989          && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (exp, 0))))
990     exp = TREE_OPERAND (exp, 0);
991
992   if (TREE_CODE (exp) == ADDR_EXPR)
993     {
994       exp = TREE_OPERAND (exp, 0);
995       set_mem_attributes (mem, exp, 0);
996     }
997   else if (POINTER_TYPE_P (TREE_TYPE (exp)))
998     {
999       exp = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (exp)), exp);
1000       /* memcpy, memset and other builtin stringops can alias with anything.  */
1001       set_mem_alias_set (mem, 0);
1002     }
1003
1004   return mem;
1005 }
1006 \f
1007 /* Built-in functions to perform an untyped call and return.  */
1008
1009 /* For each register that may be used for calling a function, this
1010    gives a mode used to copy the register's value.  VOIDmode indicates
1011    the register is not used for calling a function.  If the machine
1012    has register windows, this gives only the outbound registers.
1013    INCOMING_REGNO gives the corresponding inbound register.  */
1014 static enum machine_mode apply_args_mode[FIRST_PSEUDO_REGISTER];
1015
1016 /* For each register that may be used for returning values, this gives
1017    a mode used to copy the register's value.  VOIDmode indicates the
1018    register is not used for returning values.  If the machine has
1019    register windows, this gives only the outbound registers.
1020    INCOMING_REGNO gives the corresponding inbound register.  */
1021 static enum machine_mode apply_result_mode[FIRST_PSEUDO_REGISTER];
1022
1023 /* For each register that may be used for calling a function, this
1024    gives the offset of that register into the block returned by
1025    __builtin_apply_args.  0 indicates that the register is not
1026    used for calling a function.  */
1027 static int apply_args_reg_offset[FIRST_PSEUDO_REGISTER];
1028
1029 /* Return the size required for the block returned by __builtin_apply_args,
1030    and initialize apply_args_mode.  */
1031
1032 static int
1033 apply_args_size (void)
1034 {
1035   static int size = -1;
1036   int align;
1037   unsigned int regno;
1038   enum machine_mode mode;
1039
1040   /* The values computed by this function never change.  */
1041   if (size < 0)
1042     {
1043       /* The first value is the incoming arg-pointer.  */
1044       size = GET_MODE_SIZE (Pmode);
1045
1046       /* The second value is the structure value address unless this is
1047          passed as an "invisible" first argument.  */
1048       if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0))
1049         size += GET_MODE_SIZE (Pmode);
1050
1051       for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1052         if (FUNCTION_ARG_REGNO_P (regno))
1053           {
1054             mode = reg_raw_mode[regno];
1055
1056             if (mode == VOIDmode)
1057               abort ();
1058
1059             align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1060             if (size % align != 0)
1061               size = CEIL (size, align) * align;
1062             apply_args_reg_offset[regno] = size;
1063             size += GET_MODE_SIZE (mode);
1064             apply_args_mode[regno] = mode;
1065           }
1066         else
1067           {
1068             apply_args_mode[regno] = VOIDmode;
1069             apply_args_reg_offset[regno] = 0;
1070           }
1071     }
1072   return size;
1073 }
1074
1075 /* Return the size required for the block returned by __builtin_apply,
1076    and initialize apply_result_mode.  */
1077
1078 static int
1079 apply_result_size (void)
1080 {
1081   static int size = -1;
1082   int align, regno;
1083   enum machine_mode mode;
1084
1085   /* The values computed by this function never change.  */
1086   if (size < 0)
1087     {
1088       size = 0;
1089
1090       for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1091         if (FUNCTION_VALUE_REGNO_P (regno))
1092           {
1093             mode = reg_raw_mode[regno];
1094
1095             if (mode == VOIDmode)
1096               abort ();
1097
1098             align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1099             if (size % align != 0)
1100               size = CEIL (size, align) * align;
1101             size += GET_MODE_SIZE (mode);
1102             apply_result_mode[regno] = mode;
1103           }
1104         else
1105           apply_result_mode[regno] = VOIDmode;
1106
1107       /* Allow targets that use untyped_call and untyped_return to override
1108          the size so that machine-specific information can be stored here.  */
1109 #ifdef APPLY_RESULT_SIZE
1110       size = APPLY_RESULT_SIZE;
1111 #endif
1112     }
1113   return size;
1114 }
1115
1116 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
1117 /* Create a vector describing the result block RESULT.  If SAVEP is true,
1118    the result block is used to save the values; otherwise it is used to
1119    restore the values.  */
1120
1121 static rtx
1122 result_vector (int savep, rtx result)
1123 {
1124   int regno, size, align, nelts;
1125   enum machine_mode mode;
1126   rtx reg, mem;
1127   rtx *savevec = alloca (FIRST_PSEUDO_REGISTER * sizeof (rtx));
1128
1129   size = nelts = 0;
1130   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1131     if ((mode = apply_result_mode[regno]) != VOIDmode)
1132       {
1133         align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1134         if (size % align != 0)
1135           size = CEIL (size, align) * align;
1136         reg = gen_rtx_REG (mode, savep ? regno : INCOMING_REGNO (regno));
1137         mem = adjust_address (result, mode, size);
1138         savevec[nelts++] = (savep
1139                             ? gen_rtx_SET (VOIDmode, mem, reg)
1140                             : gen_rtx_SET (VOIDmode, reg, mem));
1141         size += GET_MODE_SIZE (mode);
1142       }
1143   return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (nelts, savevec));
1144 }
1145 #endif /* HAVE_untyped_call or HAVE_untyped_return */
1146
1147 /* Save the state required to perform an untyped call with the same
1148    arguments as were passed to the current function.  */
1149
1150 static rtx
1151 expand_builtin_apply_args_1 (void)
1152 {
1153   rtx registers, tem;
1154   int size, align, regno;
1155   enum machine_mode mode;
1156   rtx struct_incoming_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 1);
1157
1158   /* Create a block where the arg-pointer, structure value address,
1159      and argument registers can be saved.  */
1160   registers = assign_stack_local (BLKmode, apply_args_size (), -1);
1161
1162   /* Walk past the arg-pointer and structure value address.  */
1163   size = GET_MODE_SIZE (Pmode);
1164   if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0))
1165     size += GET_MODE_SIZE (Pmode);
1166
1167   /* Save each register used in calling a function to the block.  */
1168   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1169     if ((mode = apply_args_mode[regno]) != VOIDmode)
1170       {
1171         align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1172         if (size % align != 0)
1173           size = CEIL (size, align) * align;
1174
1175         tem = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1176
1177         emit_move_insn (adjust_address (registers, mode, size), tem);
1178         size += GET_MODE_SIZE (mode);
1179       }
1180
1181   /* Save the arg pointer to the block.  */
1182   tem = copy_to_reg (virtual_incoming_args_rtx);
1183 #ifdef STACK_GROWS_DOWNWARD
1184   /* We need the pointer as the caller actually passed them to us, not
1185      as we might have pretended they were passed.  Make sure it's a valid
1186      operand, as emit_move_insn isn't expected to handle a PLUS.  */
1187   tem
1188     = force_operand (plus_constant (tem, current_function_pretend_args_size),
1189                      NULL_RTX);
1190 #endif
1191   emit_move_insn (adjust_address (registers, Pmode, 0), tem);
1192
1193   size = GET_MODE_SIZE (Pmode);
1194
1195   /* Save the structure value address unless this is passed as an
1196      "invisible" first argument.  */
1197   if (struct_incoming_value)
1198     {
1199       emit_move_insn (adjust_address (registers, Pmode, size),
1200                       copy_to_reg (struct_incoming_value));
1201       size += GET_MODE_SIZE (Pmode);
1202     }
1203
1204   /* Return the address of the block.  */
1205   return copy_addr_to_reg (XEXP (registers, 0));
1206 }
1207
1208 /* __builtin_apply_args returns block of memory allocated on
1209    the stack into which is stored the arg pointer, structure
1210    value address, static chain, and all the registers that might
1211    possibly be used in performing a function call.  The code is
1212    moved to the start of the function so the incoming values are
1213    saved.  */
1214
1215 static rtx
1216 expand_builtin_apply_args (void)
1217 {
1218   /* Don't do __builtin_apply_args more than once in a function.
1219      Save the result of the first call and reuse it.  */
1220   if (apply_args_value != 0)
1221     return apply_args_value;
1222   {
1223     /* When this function is called, it means that registers must be
1224        saved on entry to this function.  So we migrate the
1225        call to the first insn of this function.  */
1226     rtx temp;
1227     rtx seq;
1228
1229     start_sequence ();
1230     temp = expand_builtin_apply_args_1 ();
1231     seq = get_insns ();
1232     end_sequence ();
1233
1234     apply_args_value = temp;
1235
1236     /* Put the insns after the NOTE that starts the function.
1237        If this is inside a start_sequence, make the outer-level insn
1238        chain current, so the code is placed at the start of the
1239        function.  */
1240     push_topmost_sequence ();
1241     emit_insn_before (seq, NEXT_INSN (entry_of_function ()));
1242     pop_topmost_sequence ();
1243     return temp;
1244   }
1245 }
1246
1247 /* Perform an untyped call and save the state required to perform an
1248    untyped return of whatever value was returned by the given function.  */
1249
1250 static rtx
1251 expand_builtin_apply (rtx function, rtx arguments, rtx argsize)
1252 {
1253   int size, align, regno;
1254   enum machine_mode mode;
1255   rtx incoming_args, result, reg, dest, src, call_insn;
1256   rtx old_stack_level = 0;
1257   rtx call_fusage = 0;
1258   rtx struct_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0);
1259
1260   arguments = convert_memory_address (Pmode, arguments);
1261
1262   /* Create a block where the return registers can be saved.  */
1263   result = assign_stack_local (BLKmode, apply_result_size (), -1);
1264
1265   /* Fetch the arg pointer from the ARGUMENTS block.  */
1266   incoming_args = gen_reg_rtx (Pmode);
1267   emit_move_insn (incoming_args, gen_rtx_MEM (Pmode, arguments));
1268 #ifndef STACK_GROWS_DOWNWARD
1269   incoming_args = expand_simple_binop (Pmode, MINUS, incoming_args, argsize,
1270                                        incoming_args, 0, OPTAB_LIB_WIDEN);
1271 #endif
1272
1273   /* Perform postincrements before actually calling the function.  */
1274   emit_queue ();
1275
1276   /* Push a new argument block and copy the arguments.  Do not allow
1277      the (potential) memcpy call below to interfere with our stack
1278      manipulations.  */
1279   do_pending_stack_adjust ();
1280   NO_DEFER_POP;
1281
1282   /* Save the stack with nonlocal if available.  */
1283 #ifdef HAVE_save_stack_nonlocal
1284   if (HAVE_save_stack_nonlocal)
1285     emit_stack_save (SAVE_NONLOCAL, &old_stack_level, NULL_RTX);
1286   else
1287 #endif
1288     emit_stack_save (SAVE_BLOCK, &old_stack_level, NULL_RTX);
1289
1290   /* Allocate a block of memory onto the stack and copy the memory
1291      arguments to the outgoing arguments address.  */
1292   allocate_dynamic_stack_space (argsize, 0, BITS_PER_UNIT);
1293   dest = virtual_outgoing_args_rtx;
1294 #ifndef STACK_GROWS_DOWNWARD
1295   if (GET_CODE (argsize) == CONST_INT)
1296     dest = plus_constant (dest, -INTVAL (argsize));
1297   else
1298     dest = gen_rtx_PLUS (Pmode, dest, negate_rtx (Pmode, argsize));
1299 #endif
1300   dest = gen_rtx_MEM (BLKmode, dest);
1301   set_mem_align (dest, PARM_BOUNDARY);
1302   src = gen_rtx_MEM (BLKmode, incoming_args);
1303   set_mem_align (src, PARM_BOUNDARY);
1304   emit_block_move (dest, src, argsize, BLOCK_OP_NORMAL);
1305
1306   /* Refer to the argument block.  */
1307   apply_args_size ();
1308   arguments = gen_rtx_MEM (BLKmode, arguments);
1309   set_mem_align (arguments, PARM_BOUNDARY);
1310
1311   /* Walk past the arg-pointer and structure value address.  */
1312   size = GET_MODE_SIZE (Pmode);
1313   if (struct_value)
1314     size += GET_MODE_SIZE (Pmode);
1315
1316   /* Restore each of the registers previously saved.  Make USE insns
1317      for each of these registers for use in making the call.  */
1318   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1319     if ((mode = apply_args_mode[regno]) != VOIDmode)
1320       {
1321         align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1322         if (size % align != 0)
1323           size = CEIL (size, align) * align;
1324         reg = gen_rtx_REG (mode, regno);
1325         emit_move_insn (reg, adjust_address (arguments, mode, size));
1326         use_reg (&call_fusage, reg);
1327         size += GET_MODE_SIZE (mode);
1328       }
1329
1330   /* Restore the structure value address unless this is passed as an
1331      "invisible" first argument.  */
1332   size = GET_MODE_SIZE (Pmode);
1333   if (struct_value)
1334     {
1335       rtx value = gen_reg_rtx (Pmode);
1336       emit_move_insn (value, adjust_address (arguments, Pmode, size));
1337       emit_move_insn (struct_value, value);
1338       if (REG_P (struct_value))
1339         use_reg (&call_fusage, struct_value);
1340       size += GET_MODE_SIZE (Pmode);
1341     }
1342
1343   /* All arguments and registers used for the call are set up by now!  */
1344   function = prepare_call_address (function, NULL, &call_fusage, 0, 0);
1345
1346   /* Ensure address is valid.  SYMBOL_REF is already valid, so no need,
1347      and we don't want to load it into a register as an optimization,
1348      because prepare_call_address already did it if it should be done.  */
1349   if (GET_CODE (function) != SYMBOL_REF)
1350     function = memory_address (FUNCTION_MODE, function);
1351
1352   /* Generate the actual call instruction and save the return value.  */
1353 #ifdef HAVE_untyped_call
1354   if (HAVE_untyped_call)
1355     emit_call_insn (gen_untyped_call (gen_rtx_MEM (FUNCTION_MODE, function),
1356                                       result, result_vector (1, result)));
1357   else
1358 #endif
1359 #ifdef HAVE_call_value
1360   if (HAVE_call_value)
1361     {
1362       rtx valreg = 0;
1363
1364       /* Locate the unique return register.  It is not possible to
1365          express a call that sets more than one return register using
1366          call_value; use untyped_call for that.  In fact, untyped_call
1367          only needs to save the return registers in the given block.  */
1368       for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1369         if ((mode = apply_result_mode[regno]) != VOIDmode)
1370           {
1371             if (valreg)
1372               abort (); /* HAVE_untyped_call required.  */
1373             valreg = gen_rtx_REG (mode, regno);
1374           }
1375
1376       emit_call_insn (GEN_CALL_VALUE (valreg,
1377                                       gen_rtx_MEM (FUNCTION_MODE, function),
1378                                       const0_rtx, NULL_RTX, const0_rtx));
1379
1380       emit_move_insn (adjust_address (result, GET_MODE (valreg), 0), valreg);
1381     }
1382   else
1383 #endif
1384     abort ();
1385
1386   /* Find the CALL insn we just emitted, and attach the register usage
1387      information.  */
1388   call_insn = last_call_insn ();
1389   add_function_usage_to (call_insn, call_fusage);
1390
1391   /* Restore the stack.  */
1392 #ifdef HAVE_save_stack_nonlocal
1393   if (HAVE_save_stack_nonlocal)
1394     emit_stack_restore (SAVE_NONLOCAL, old_stack_level, NULL_RTX);
1395   else
1396 #endif
1397     emit_stack_restore (SAVE_BLOCK, old_stack_level, NULL_RTX);
1398
1399   OK_DEFER_POP;
1400
1401   /* Return the address of the result block.  */
1402   result = copy_addr_to_reg (XEXP (result, 0));
1403   return convert_memory_address (ptr_mode, result);
1404 }
1405
1406 /* Perform an untyped return.  */
1407
1408 static void
1409 expand_builtin_return (rtx result)
1410 {
1411   int size, align, regno;
1412   enum machine_mode mode;
1413   rtx reg;
1414   rtx call_fusage = 0;
1415
1416   result = convert_memory_address (Pmode, result);
1417
1418   apply_result_size ();
1419   result = gen_rtx_MEM (BLKmode, result);
1420
1421 #ifdef HAVE_untyped_return
1422   if (HAVE_untyped_return)
1423     {
1424       emit_jump_insn (gen_untyped_return (result, result_vector (0, result)));
1425       emit_barrier ();
1426       return;
1427     }
1428 #endif
1429
1430   /* Restore the return value and note that each value is used.  */
1431   size = 0;
1432   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1433     if ((mode = apply_result_mode[regno]) != VOIDmode)
1434       {
1435         align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1436         if (size % align != 0)
1437           size = CEIL (size, align) * align;
1438         reg = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1439         emit_move_insn (reg, adjust_address (result, mode, size));
1440
1441         push_to_sequence (call_fusage);
1442         emit_insn (gen_rtx_USE (VOIDmode, reg));
1443         call_fusage = get_insns ();
1444         end_sequence ();
1445         size += GET_MODE_SIZE (mode);
1446       }
1447
1448   /* Put the USE insns before the return.  */
1449   emit_insn (call_fusage);
1450
1451   /* Return whatever values was restored by jumping directly to the end
1452      of the function.  */
1453   expand_naked_return ();
1454 }
1455
1456 /* Used by expand_builtin_classify_type and fold_builtin_classify_type.  */
1457
1458 static enum type_class
1459 type_to_class (tree type)
1460 {
1461   switch (TREE_CODE (type))
1462     {
1463     case VOID_TYPE:        return void_type_class;
1464     case INTEGER_TYPE:     return integer_type_class;
1465     case CHAR_TYPE:        return char_type_class;
1466     case ENUMERAL_TYPE:    return enumeral_type_class;
1467     case BOOLEAN_TYPE:     return boolean_type_class;
1468     case POINTER_TYPE:     return pointer_type_class;
1469     case REFERENCE_TYPE:   return reference_type_class;
1470     case OFFSET_TYPE:      return offset_type_class;
1471     case REAL_TYPE:        return real_type_class;
1472     case COMPLEX_TYPE:     return complex_type_class;
1473     case FUNCTION_TYPE:    return function_type_class;
1474     case METHOD_TYPE:      return method_type_class;
1475     case RECORD_TYPE:      return record_type_class;
1476     case UNION_TYPE:
1477     case QUAL_UNION_TYPE:  return union_type_class;
1478     case ARRAY_TYPE:       return (TYPE_STRING_FLAG (type)
1479                                    ? string_type_class : array_type_class);
1480     case SET_TYPE:         return set_type_class;
1481     case FILE_TYPE:        return file_type_class;
1482     case LANG_TYPE:        return lang_type_class;
1483     default:               return no_type_class;
1484     }
1485 }
1486
1487 /* Expand a call to __builtin_classify_type with arguments found in
1488    ARGLIST.  */
1489
1490 static rtx
1491 expand_builtin_classify_type (tree arglist)
1492 {
1493   if (arglist != 0)
1494     return GEN_INT (type_to_class (TREE_TYPE (TREE_VALUE (arglist))));
1495   return GEN_INT (no_type_class);
1496 }
1497
1498 /* This helper macro, meant to be used in mathfn_built_in below,
1499    determines which among a set of three builtin math functions is
1500    appropriate for a given type mode.  The `F' and `L' cases are
1501    automatically generated from the `double' case.  */
1502 #define CASE_MATHFN(BUILT_IN_MATHFN) \
1503   case BUILT_IN_MATHFN: case BUILT_IN_MATHFN##F: case BUILT_IN_MATHFN##L: \
1504   fcode = BUILT_IN_MATHFN; fcodef = BUILT_IN_MATHFN##F ; \
1505   fcodel = BUILT_IN_MATHFN##L ; break;
1506
1507 /* Return mathematic function equivalent to FN but operating directly
1508    on TYPE, if available.  If we can't do the conversion, return zero.  */
1509 tree
1510 mathfn_built_in (tree type, enum built_in_function fn)
1511 {
1512   enum built_in_function fcode, fcodef, fcodel;
1513
1514   switch (fn)
1515     {
1516       CASE_MATHFN (BUILT_IN_ACOS)
1517       CASE_MATHFN (BUILT_IN_ACOSH)
1518       CASE_MATHFN (BUILT_IN_ASIN)
1519       CASE_MATHFN (BUILT_IN_ASINH)
1520       CASE_MATHFN (BUILT_IN_ATAN)
1521       CASE_MATHFN (BUILT_IN_ATAN2)
1522       CASE_MATHFN (BUILT_IN_ATANH)
1523       CASE_MATHFN (BUILT_IN_CBRT)
1524       CASE_MATHFN (BUILT_IN_CEIL)
1525       CASE_MATHFN (BUILT_IN_COPYSIGN)
1526       CASE_MATHFN (BUILT_IN_COS)
1527       CASE_MATHFN (BUILT_IN_COSH)
1528       CASE_MATHFN (BUILT_IN_DREM)
1529       CASE_MATHFN (BUILT_IN_ERF)
1530       CASE_MATHFN (BUILT_IN_ERFC)
1531       CASE_MATHFN (BUILT_IN_EXP)
1532       CASE_MATHFN (BUILT_IN_EXP10)
1533       CASE_MATHFN (BUILT_IN_EXP2)
1534       CASE_MATHFN (BUILT_IN_EXPM1)
1535       CASE_MATHFN (BUILT_IN_FABS)
1536       CASE_MATHFN (BUILT_IN_FDIM)
1537       CASE_MATHFN (BUILT_IN_FLOOR)
1538       CASE_MATHFN (BUILT_IN_FMA)
1539       CASE_MATHFN (BUILT_IN_FMAX)
1540       CASE_MATHFN (BUILT_IN_FMIN)
1541       CASE_MATHFN (BUILT_IN_FMOD)
1542       CASE_MATHFN (BUILT_IN_FREXP)
1543       CASE_MATHFN (BUILT_IN_GAMMA)
1544       CASE_MATHFN (BUILT_IN_HUGE_VAL)
1545       CASE_MATHFN (BUILT_IN_HYPOT)
1546       CASE_MATHFN (BUILT_IN_ILOGB)
1547       CASE_MATHFN (BUILT_IN_INF)
1548       CASE_MATHFN (BUILT_IN_J0)
1549       CASE_MATHFN (BUILT_IN_J1)
1550       CASE_MATHFN (BUILT_IN_JN)
1551       CASE_MATHFN (BUILT_IN_LDEXP)
1552       CASE_MATHFN (BUILT_IN_LGAMMA)
1553       CASE_MATHFN (BUILT_IN_LLRINT)
1554       CASE_MATHFN (BUILT_IN_LLROUND)
1555       CASE_MATHFN (BUILT_IN_LOG)
1556       CASE_MATHFN (BUILT_IN_LOG10)
1557       CASE_MATHFN (BUILT_IN_LOG1P)
1558       CASE_MATHFN (BUILT_IN_LOG2)
1559       CASE_MATHFN (BUILT_IN_LOGB)
1560       CASE_MATHFN (BUILT_IN_LRINT)
1561       CASE_MATHFN (BUILT_IN_LROUND)
1562       CASE_MATHFN (BUILT_IN_MODF)
1563       CASE_MATHFN (BUILT_IN_NAN)
1564       CASE_MATHFN (BUILT_IN_NANS)
1565       CASE_MATHFN (BUILT_IN_NEARBYINT)
1566       CASE_MATHFN (BUILT_IN_NEXTAFTER)
1567       CASE_MATHFN (BUILT_IN_NEXTTOWARD)
1568       CASE_MATHFN (BUILT_IN_POW)
1569       CASE_MATHFN (BUILT_IN_POW10)
1570       CASE_MATHFN (BUILT_IN_REMAINDER)
1571       CASE_MATHFN (BUILT_IN_REMQUO)
1572       CASE_MATHFN (BUILT_IN_RINT)
1573       CASE_MATHFN (BUILT_IN_ROUND)
1574       CASE_MATHFN (BUILT_IN_SCALB)
1575       CASE_MATHFN (BUILT_IN_SCALBLN)
1576       CASE_MATHFN (BUILT_IN_SCALBN)
1577       CASE_MATHFN (BUILT_IN_SIGNIFICAND)
1578       CASE_MATHFN (BUILT_IN_SIN)
1579       CASE_MATHFN (BUILT_IN_SINCOS)
1580       CASE_MATHFN (BUILT_IN_SINH)
1581       CASE_MATHFN (BUILT_IN_SQRT)
1582       CASE_MATHFN (BUILT_IN_TAN)
1583       CASE_MATHFN (BUILT_IN_TANH)
1584       CASE_MATHFN (BUILT_IN_TGAMMA)
1585       CASE_MATHFN (BUILT_IN_TRUNC)
1586       CASE_MATHFN (BUILT_IN_Y0)
1587       CASE_MATHFN (BUILT_IN_Y1)
1588       CASE_MATHFN (BUILT_IN_YN)
1589
1590       default:
1591         return 0;
1592       }
1593
1594   if (TYPE_MAIN_VARIANT (type) == double_type_node)
1595     return implicit_built_in_decls[fcode];
1596   else if (TYPE_MAIN_VARIANT (type) == float_type_node)
1597     return implicit_built_in_decls[fcodef];
1598   else if (TYPE_MAIN_VARIANT (type) == long_double_type_node)
1599     return implicit_built_in_decls[fcodel];
1600   else
1601     return 0;
1602 }
1603
1604 /* If errno must be maintained, expand the RTL to check if the result,
1605    TARGET, of a built-in function call, EXP, is NaN, and if so set
1606    errno to EDOM.  */
1607
1608 static void
1609 expand_errno_check (tree exp, rtx target)
1610 {
1611   rtx lab = gen_label_rtx ();
1612
1613   /* Test the result; if it is NaN, set errno=EDOM because
1614      the argument was not in the domain.  */
1615   emit_cmp_and_jump_insns (target, target, EQ, 0, GET_MODE (target),
1616                            0, lab);
1617
1618 #ifdef TARGET_EDOM
1619   /* If this built-in doesn't throw an exception, set errno directly.  */
1620   if (TREE_NOTHROW (TREE_OPERAND (TREE_OPERAND (exp, 0), 0)))
1621     {
1622 #ifdef GEN_ERRNO_RTX
1623       rtx errno_rtx = GEN_ERRNO_RTX;
1624 #else
1625       rtx errno_rtx
1626           = gen_rtx_MEM (word_mode, gen_rtx_SYMBOL_REF (Pmode, "errno"));
1627 #endif
1628       emit_move_insn (errno_rtx, GEN_INT (TARGET_EDOM));
1629       emit_label (lab);
1630       return;
1631     }
1632 #endif
1633
1634   /* We can't set errno=EDOM directly; let the library call do it.
1635      Pop the arguments right away in case the call gets deleted.  */
1636   NO_DEFER_POP;
1637   expand_call (exp, target, 0);
1638   OK_DEFER_POP;
1639   emit_label (lab);
1640 }
1641
1642
1643 /* Expand a call to one of the builtin math functions (sqrt, exp, or log).
1644    Return 0 if a normal call should be emitted rather than expanding the
1645    function in-line.  EXP is the expression that is a call to the builtin
1646    function; if convenient, the result should be placed in TARGET.
1647    SUBTARGET may be used as the target for computing one of EXP's operands.  */
1648
1649 static rtx
1650 expand_builtin_mathfn (tree exp, rtx target, rtx subtarget)
1651 {
1652   optab builtin_optab;
1653   rtx op0, insns, before_call;
1654   tree fndecl = get_callee_fndecl (exp);
1655   tree arglist = TREE_OPERAND (exp, 1);
1656   enum machine_mode mode;
1657   bool errno_set = false;
1658   tree arg, narg;
1659
1660   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
1661     return 0;
1662
1663   arg = TREE_VALUE (arglist);
1664
1665   switch (DECL_FUNCTION_CODE (fndecl))
1666     {
1667     case BUILT_IN_SQRT:
1668     case BUILT_IN_SQRTF:
1669     case BUILT_IN_SQRTL:
1670       errno_set = ! tree_expr_nonnegative_p (arg);
1671       builtin_optab = sqrt_optab;
1672       break;
1673     case BUILT_IN_EXP:
1674     case BUILT_IN_EXPF:
1675     case BUILT_IN_EXPL:
1676       errno_set = true; builtin_optab = exp_optab; break;
1677     case BUILT_IN_EXP10:
1678     case BUILT_IN_EXP10F:
1679     case BUILT_IN_EXP10L:
1680     case BUILT_IN_POW10:
1681     case BUILT_IN_POW10F:
1682     case BUILT_IN_POW10L:
1683       errno_set = true; builtin_optab = exp10_optab; break;
1684     case BUILT_IN_EXP2:
1685     case BUILT_IN_EXP2F:
1686     case BUILT_IN_EXP2L:
1687       errno_set = true; builtin_optab = exp2_optab; break;
1688     case BUILT_IN_EXPM1:
1689     case BUILT_IN_EXPM1F:
1690     case BUILT_IN_EXPM1L:
1691       errno_set = true; builtin_optab = expm1_optab; break;
1692     case BUILT_IN_LOGB:
1693     case BUILT_IN_LOGBF:
1694     case BUILT_IN_LOGBL:
1695       errno_set = true; builtin_optab = logb_optab; break;
1696     case BUILT_IN_ILOGB:
1697     case BUILT_IN_ILOGBF:
1698     case BUILT_IN_ILOGBL:
1699       errno_set = true; builtin_optab = ilogb_optab; break;
1700     case BUILT_IN_LOG:
1701     case BUILT_IN_LOGF:
1702     case BUILT_IN_LOGL:
1703       errno_set = true; builtin_optab = log_optab; break;
1704     case BUILT_IN_LOG10:
1705     case BUILT_IN_LOG10F:
1706     case BUILT_IN_LOG10L:
1707       errno_set = true; builtin_optab = log10_optab; break;
1708     case BUILT_IN_LOG2:
1709     case BUILT_IN_LOG2F:
1710     case BUILT_IN_LOG2L:
1711       errno_set = true; builtin_optab = log2_optab; break;
1712     case BUILT_IN_LOG1P:
1713     case BUILT_IN_LOG1PF:
1714     case BUILT_IN_LOG1PL:
1715       errno_set = true; builtin_optab = log1p_optab; break;
1716     case BUILT_IN_ASIN:
1717     case BUILT_IN_ASINF:
1718     case BUILT_IN_ASINL:
1719       builtin_optab = asin_optab; break;
1720     case BUILT_IN_ACOS:
1721     case BUILT_IN_ACOSF:
1722     case BUILT_IN_ACOSL:
1723       builtin_optab = acos_optab; break;
1724     case BUILT_IN_TAN:
1725     case BUILT_IN_TANF:
1726     case BUILT_IN_TANL:
1727       builtin_optab = tan_optab; break;
1728     case BUILT_IN_ATAN:
1729     case BUILT_IN_ATANF:
1730     case BUILT_IN_ATANL:
1731       builtin_optab = atan_optab; break;
1732     case BUILT_IN_FLOOR:
1733     case BUILT_IN_FLOORF:
1734     case BUILT_IN_FLOORL:
1735       builtin_optab = floor_optab; break;
1736     case BUILT_IN_CEIL:
1737     case BUILT_IN_CEILF:
1738     case BUILT_IN_CEILL:
1739       builtin_optab = ceil_optab; break;
1740     case BUILT_IN_TRUNC:
1741     case BUILT_IN_TRUNCF:
1742     case BUILT_IN_TRUNCL:
1743       builtin_optab = btrunc_optab; break;
1744     case BUILT_IN_ROUND:
1745     case BUILT_IN_ROUNDF:
1746     case BUILT_IN_ROUNDL:
1747       builtin_optab = round_optab; break;
1748     case BUILT_IN_NEARBYINT:
1749     case BUILT_IN_NEARBYINTF:
1750     case BUILT_IN_NEARBYINTL:
1751       builtin_optab = nearbyint_optab; break;
1752     default:
1753       abort ();
1754     }
1755
1756   /* Make a suitable register to place result in.  */
1757   mode = TYPE_MODE (TREE_TYPE (exp));
1758
1759   if (! flag_errno_math || ! HONOR_NANS (mode))
1760     errno_set = false;
1761
1762   /* Before working hard, check whether the instruction is available.  */
1763   if (builtin_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1764     {
1765       target = gen_reg_rtx (mode);
1766
1767       /* Wrap the computation of the argument in a SAVE_EXPR, as we may
1768          need to expand the argument again.  This way, we will not perform
1769          side-effects more the once.  */
1770       narg = builtin_save_expr (arg);
1771       if (narg != arg)
1772         {
1773           arglist = build_tree_list (NULL_TREE, arg);
1774           exp = build_function_call_expr (fndecl, arglist);
1775         }
1776
1777       op0 = expand_expr (arg, subtarget, VOIDmode, 0);
1778
1779       emit_queue ();
1780       start_sequence ();
1781
1782       /* Compute into TARGET.
1783          Set TARGET to wherever the result comes back.  */
1784       target = expand_unop (mode, builtin_optab, op0, target, 0);
1785
1786       if (target != 0)
1787         {
1788           if (errno_set)
1789             expand_errno_check (exp, target);
1790
1791           /* Output the entire sequence.  */
1792           insns = get_insns ();
1793           end_sequence ();
1794           emit_insn (insns);
1795           return target;
1796         }
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       end_sequence ();
1802     }
1803
1804   before_call = get_last_insn ();
1805
1806   target = expand_call (exp, target, target == const0_rtx);
1807
1808   /* If this is a sqrt operation and we don't care about errno, try to
1809      attach a REG_EQUAL note with a SQRT rtx to the emitted libcall.
1810      This allows the semantics of the libcall to be visible to the RTL
1811      optimizers.  */
1812   if (builtin_optab == sqrt_optab && !errno_set)
1813     {
1814       /* Search backwards through the insns emitted by expand_call looking
1815          for the instruction with the REG_RETVAL note.  */
1816       rtx last = get_last_insn ();
1817       while (last != before_call)
1818         {
1819           if (find_reg_note (last, REG_RETVAL, NULL))
1820             {
1821               rtx note = find_reg_note (last, REG_EQUAL, NULL);
1822               /* Check that the REQ_EQUAL note is an EXPR_LIST with
1823                  two elements, i.e. symbol_ref(sqrt) and the operand.  */
1824               if (note
1825                   && GET_CODE (note) == EXPR_LIST
1826                   && GET_CODE (XEXP (note, 0)) == EXPR_LIST
1827                   && XEXP (XEXP (note, 0), 1) != NULL_RTX
1828                   && XEXP (XEXP (XEXP (note, 0), 1), 1) == NULL_RTX)
1829                 {
1830                   rtx operand = XEXP (XEXP (XEXP (note, 0), 1), 0);
1831                   /* Check operand is a register with expected mode.  */
1832                   if (operand
1833                       && REG_P (operand)
1834                       && GET_MODE (operand) == mode)
1835                     {
1836                       /* Replace the REG_EQUAL note with a SQRT rtx.  */
1837                       rtx equiv = gen_rtx_SQRT (mode, operand);
1838                       set_unique_reg_note (last, REG_EQUAL, equiv);
1839                     }
1840                 }
1841               break;
1842             }
1843           last = PREV_INSN (last);
1844         }
1845     }
1846
1847   return target;
1848 }
1849
1850 /* Expand a call to the builtin binary math functions (pow and atan2).
1851    Return 0 if a normal call should be emitted rather than expanding the
1852    function in-line.  EXP is the expression that is a call to the builtin
1853    function; if convenient, the result should be placed in TARGET.
1854    SUBTARGET may be used as the target for computing one of EXP's
1855    operands.  */
1856
1857 static rtx
1858 expand_builtin_mathfn_2 (tree exp, rtx target, rtx subtarget)
1859 {
1860   optab builtin_optab;
1861   rtx op0, op1, insns;
1862   tree fndecl = get_callee_fndecl (exp);
1863   tree arglist = TREE_OPERAND (exp, 1);
1864   tree arg0, arg1, temp, narg;
1865   enum machine_mode mode;
1866   bool errno_set = true;
1867   bool stable = true;
1868
1869   if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
1870     return 0;
1871
1872   arg0 = TREE_VALUE (arglist);
1873   arg1 = TREE_VALUE (TREE_CHAIN (arglist));
1874
1875   switch (DECL_FUNCTION_CODE (fndecl))
1876     {
1877     case BUILT_IN_POW:
1878     case BUILT_IN_POWF:
1879     case BUILT_IN_POWL:
1880       builtin_optab = pow_optab; break;
1881     case BUILT_IN_ATAN2:
1882     case BUILT_IN_ATAN2F:
1883     case BUILT_IN_ATAN2L:
1884       builtin_optab = atan2_optab; break;
1885     case BUILT_IN_FMOD:
1886     case BUILT_IN_FMODF:
1887     case BUILT_IN_FMODL:
1888       builtin_optab = fmod_optab; break;
1889     case BUILT_IN_DREM:
1890     case BUILT_IN_DREMF:
1891     case BUILT_IN_DREML:
1892       builtin_optab = drem_optab; break;
1893     default:
1894       abort ();
1895     }
1896
1897   /* Make a suitable register to place result in.  */
1898   mode = TYPE_MODE (TREE_TYPE (exp));
1899
1900   /* Before working hard, check whether the instruction is available.  */
1901   if (builtin_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing)
1902     return 0;
1903
1904   target = gen_reg_rtx (mode);
1905
1906   if (! flag_errno_math || ! HONOR_NANS (mode))
1907     errno_set = false;
1908
1909   /* Always stabilize the argument list.  */
1910   narg = builtin_save_expr (arg1);
1911   if (narg != arg1)
1912     {
1913       temp = build_tree_list (NULL_TREE, narg);
1914       stable = false;
1915     }
1916   else
1917     temp = TREE_CHAIN (arglist);
1918
1919   narg = builtin_save_expr (arg0);
1920   if (narg != arg0)
1921     {
1922       arglist = tree_cons (NULL_TREE, narg, temp);
1923       stable = false;
1924     }
1925   else if (! stable)
1926     arglist = tree_cons (NULL_TREE, arg0, temp);
1927
1928   if (! stable)
1929     exp = build_function_call_expr (fndecl, arglist);
1930
1931   op0 = expand_expr (arg0, subtarget, VOIDmode, 0);
1932   op1 = expand_expr (arg1, 0, VOIDmode, 0);
1933
1934   emit_queue ();
1935   start_sequence ();
1936
1937   /* Compute into TARGET.
1938      Set TARGET to wherever the result comes back.  */
1939   target = expand_binop (mode, builtin_optab, op0, op1,
1940                          target, 0, OPTAB_DIRECT);
1941
1942   /* If we were unable to expand via the builtin, stop the sequence
1943      (without outputting the insns) and call to the library function
1944      with the stabilized argument list.  */
1945   if (target == 0)
1946     {
1947       end_sequence ();
1948       return expand_call (exp, target, target == const0_rtx);
1949     }
1950
1951   if (errno_set)
1952     expand_errno_check (exp, target);
1953
1954   /* Output the entire sequence.  */
1955   insns = get_insns ();
1956   end_sequence ();
1957   emit_insn (insns);
1958
1959   return target;
1960 }
1961
1962 /* Expand a call to the builtin sin and cos math functions.
1963    Return 0 if a normal call should be emitted rather than expanding the
1964    function in-line.  EXP is the expression that is a call to the builtin
1965    function; if convenient, the result should be placed in TARGET.
1966    SUBTARGET may be used as the target for computing one of EXP's
1967    operands.  */
1968
1969 static rtx
1970 expand_builtin_mathfn_3 (tree exp, rtx target, rtx subtarget)
1971 {
1972   optab builtin_optab;
1973   rtx op0, insns, before_call;
1974   tree fndecl = get_callee_fndecl (exp);
1975   tree arglist = TREE_OPERAND (exp, 1);
1976   enum machine_mode mode;
1977   bool errno_set = false;
1978   tree arg, narg;
1979
1980   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
1981     return 0;
1982
1983   arg = TREE_VALUE (arglist);
1984
1985   switch (DECL_FUNCTION_CODE (fndecl))
1986     {
1987     case BUILT_IN_SIN:
1988     case BUILT_IN_SINF:
1989     case BUILT_IN_SINL:
1990     case BUILT_IN_COS:
1991     case BUILT_IN_COSF:
1992     case BUILT_IN_COSL:
1993       builtin_optab = sincos_optab; break;
1994     default:
1995       abort ();
1996     }
1997
1998   /* Make a suitable register to place result in.  */
1999   mode = TYPE_MODE (TREE_TYPE (exp));
2000
2001   if (! flag_errno_math || ! HONOR_NANS (mode))
2002     errno_set = false;
2003
2004   /* Check if sincos insn is available, otherwise fallback
2005      to sin or cos insn.  */
2006   if (builtin_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing) {
2007     switch (DECL_FUNCTION_CODE (fndecl))
2008       {
2009       case BUILT_IN_SIN:
2010       case BUILT_IN_SINF:
2011       case BUILT_IN_SINL:
2012         builtin_optab = sin_optab; break;
2013       case BUILT_IN_COS:
2014       case BUILT_IN_COSF:
2015       case BUILT_IN_COSL:
2016         builtin_optab = cos_optab; break;
2017       default:
2018         abort();
2019       }
2020   }
2021
2022   /* Before working hard, check whether the instruction is available.  */
2023   if (builtin_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2024     {
2025       target = gen_reg_rtx (mode);
2026
2027       /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2028          need to expand the argument again.  This way, we will not perform
2029          side-effects more the once.  */
2030       narg = save_expr (arg);
2031       if (narg != arg)
2032         {
2033           arglist = build_tree_list (NULL_TREE, arg);
2034           exp = build_function_call_expr (fndecl, arglist);
2035         }
2036
2037       op0 = expand_expr (arg, subtarget, VOIDmode, 0);
2038
2039       emit_queue ();
2040       start_sequence ();
2041
2042       /* Compute into TARGET.
2043          Set TARGET to wherever the result comes back.  */
2044       if (builtin_optab == sincos_optab)
2045         {
2046           switch (DECL_FUNCTION_CODE (fndecl))
2047             {
2048             case BUILT_IN_SIN:
2049             case BUILT_IN_SINF:
2050             case BUILT_IN_SINL:
2051               if (!expand_twoval_unop (builtin_optab, op0, 0, target, 0))    
2052                 abort();
2053               break;
2054             case BUILT_IN_COS:
2055             case BUILT_IN_COSF:
2056             case BUILT_IN_COSL:
2057               if (!expand_twoval_unop (builtin_optab, op0, target, 0, 0))
2058                 abort();
2059               break;
2060             default:
2061               abort();
2062             }
2063         }
2064       else
2065         {
2066           target = expand_unop (mode, builtin_optab, op0, target, 0);
2067         }
2068
2069       if (target != 0)
2070         {
2071           if (errno_set)
2072             expand_errno_check (exp, target);
2073
2074           /* Output the entire sequence.  */
2075           insns = get_insns ();
2076           end_sequence ();
2077           emit_insn (insns);
2078           return target;
2079         }
2080
2081       /* If we were unable to expand via the builtin, stop the sequence
2082          (without outputting the insns) and call to the library function
2083          with the stabilized argument list.  */
2084       end_sequence ();
2085     }
2086
2087   before_call = get_last_insn ();
2088
2089   target = expand_call (exp, target, target == const0_rtx);
2090
2091   return target;
2092 }
2093
2094 /* To evaluate powi(x,n), the floating point value x raised to the
2095    constant integer exponent n, we use a hybrid algorithm that
2096    combines the "window method" with look-up tables.  For an
2097    introduction to exponentiation algorithms and "addition chains",
2098    see section 4.6.3, "Evaluation of Powers" of Donald E. Knuth,
2099    "Seminumerical Algorithms", Vol. 2, "The Art of Computer Programming",
2100    3rd Edition, 1998, and Daniel M. Gordon, "A Survey of Fast Exponentiation
2101    Methods", Journal of Algorithms, Vol. 27, pp. 129-146, 1998.  */
2102
2103 /* Provide a default value for POWI_MAX_MULTS, the maximum number of
2104    multiplications to inline before calling the system library's pow
2105    function.  powi(x,n) requires at worst 2*bits(n)-2 multiplications,
2106    so this default never requires calling pow, powf or powl.  */
2107
2108 #ifndef POWI_MAX_MULTS
2109 #define POWI_MAX_MULTS  (2*HOST_BITS_PER_WIDE_INT-2)
2110 #endif
2111
2112 /* The size of the "optimal power tree" lookup table.  All
2113    exponents less than this value are simply looked up in the
2114    powi_table below.  This threshold is also used to size the
2115    cache of pseudo registers that hold intermediate results.  */
2116 #define POWI_TABLE_SIZE 256
2117
2118 /* The size, in bits of the window, used in the "window method"
2119    exponentiation algorithm.  This is equivalent to a radix of
2120    (1<<POWI_WINDOW_SIZE) in the corresponding "m-ary method".  */
2121 #define POWI_WINDOW_SIZE 3
2122
2123 /* The following table is an efficient representation of an
2124    "optimal power tree".  For each value, i, the corresponding
2125    value, j, in the table states than an optimal evaluation
2126    sequence for calculating pow(x,i) can be found by evaluating
2127    pow(x,j)*pow(x,i-j).  An optimal power tree for the first
2128    100 integers is given in Knuth's "Seminumerical algorithms".  */
2129
2130 static const unsigned char powi_table[POWI_TABLE_SIZE] =
2131   {
2132       0,   1,   1,   2,   2,   3,   3,   4,  /*   0 -   7 */
2133       4,   6,   5,   6,   6,  10,   7,   9,  /*   8 -  15 */
2134       8,  16,   9,  16,  10,  12,  11,  13,  /*  16 -  23 */
2135      12,  17,  13,  18,  14,  24,  15,  26,  /*  24 -  31 */
2136      16,  17,  17,  19,  18,  33,  19,  26,  /*  32 -  39 */
2137      20,  25,  21,  40,  22,  27,  23,  44,  /*  40 -  47 */
2138      24,  32,  25,  34,  26,  29,  27,  44,  /*  48 -  55 */
2139      28,  31,  29,  34,  30,  60,  31,  36,  /*  56 -  63 */
2140      32,  64,  33,  34,  34,  46,  35,  37,  /*  64 -  71 */
2141      36,  65,  37,  50,  38,  48,  39,  69,  /*  72 -  79 */
2142      40,  49,  41,  43,  42,  51,  43,  58,  /*  80 -  87 */
2143      44,  64,  45,  47,  46,  59,  47,  76,  /*  88 -  95 */
2144      48,  65,  49,  66,  50,  67,  51,  66,  /*  96 - 103 */
2145      52,  70,  53,  74,  54, 104,  55,  74,  /* 104 - 111 */
2146      56,  64,  57,  69,  58,  78,  59,  68,  /* 112 - 119 */
2147      60,  61,  61,  80,  62,  75,  63,  68,  /* 120 - 127 */
2148      64,  65,  65, 128,  66, 129,  67,  90,  /* 128 - 135 */
2149      68,  73,  69, 131,  70,  94,  71,  88,  /* 136 - 143 */
2150      72, 128,  73,  98,  74, 132,  75, 121,  /* 144 - 151 */
2151      76, 102,  77, 124,  78, 132,  79, 106,  /* 152 - 159 */
2152      80,  97,  81, 160,  82,  99,  83, 134,  /* 160 - 167 */
2153      84,  86,  85,  95,  86, 160,  87, 100,  /* 168 - 175 */
2154      88, 113,  89,  98,  90, 107,  91, 122,  /* 176 - 183 */
2155      92, 111,  93, 102,  94, 126,  95, 150,  /* 184 - 191 */
2156      96, 128,  97, 130,  98, 133,  99, 195,  /* 192 - 199 */
2157     100, 128, 101, 123, 102, 164, 103, 138,  /* 200 - 207 */
2158     104, 145, 105, 146, 106, 109, 107, 149,  /* 208 - 215 */
2159     108, 200, 109, 146, 110, 170, 111, 157,  /* 216 - 223 */
2160     112, 128, 113, 130, 114, 182, 115, 132,  /* 224 - 231 */
2161     116, 200, 117, 132, 118, 158, 119, 206,  /* 232 - 239 */
2162     120, 240, 121, 162, 122, 147, 123, 152,  /* 240 - 247 */
2163     124, 166, 125, 214, 126, 138, 127, 153,  /* 248 - 255 */
2164   };
2165
2166
2167 /* Return the number of multiplications required to calculate
2168    powi(x,n) where n is less than POWI_TABLE_SIZE.  This is a
2169    subroutine of powi_cost.  CACHE is an array indicating
2170    which exponents have already been calculated.  */
2171
2172 static int
2173 powi_lookup_cost (unsigned HOST_WIDE_INT n, bool *cache)
2174 {
2175   /* If we've already calculated this exponent, then this evaluation
2176      doesn't require any additional multiplications.  */
2177   if (cache[n])
2178     return 0;
2179
2180   cache[n] = true;
2181   return powi_lookup_cost (n - powi_table[n], cache)
2182          + powi_lookup_cost (powi_table[n], cache) + 1;
2183 }
2184
2185 /* Return the number of multiplications required to calculate
2186    powi(x,n) for an arbitrary x, given the exponent N.  This
2187    function needs to be kept in sync with expand_powi below.  */
2188
2189 static int
2190 powi_cost (HOST_WIDE_INT n)
2191 {
2192   bool cache[POWI_TABLE_SIZE];
2193   unsigned HOST_WIDE_INT digit;
2194   unsigned HOST_WIDE_INT val;
2195   int result;
2196
2197   if (n == 0)
2198     return 0;
2199
2200   /* Ignore the reciprocal when calculating the cost.  */
2201   val = (n < 0) ? -n : n;
2202
2203   /* Initialize the exponent cache.  */
2204   memset (cache, 0, POWI_TABLE_SIZE * sizeof (bool));
2205   cache[1] = true;
2206
2207   result = 0;
2208
2209   while (val >= POWI_TABLE_SIZE)
2210     {
2211       if (val & 1)
2212         {
2213           digit = val & ((1 << POWI_WINDOW_SIZE) - 1);
2214           result += powi_lookup_cost (digit, cache)
2215                     + POWI_WINDOW_SIZE + 1;
2216           val >>= POWI_WINDOW_SIZE;
2217         }
2218       else
2219         {
2220           val >>= 1;
2221           result++;
2222         }
2223     }
2224
2225   return result + powi_lookup_cost (val, cache);
2226 }
2227
2228 /* Recursive subroutine of expand_powi.  This function takes the array,
2229    CACHE, of already calculated exponents and an exponent N and returns
2230    an RTX that corresponds to CACHE[1]**N, as calculated in mode MODE.  */
2231
2232 static rtx
2233 expand_powi_1 (enum machine_mode mode, unsigned HOST_WIDE_INT n, rtx *cache)
2234 {
2235   unsigned HOST_WIDE_INT digit;
2236   rtx target, result;
2237   rtx op0, op1;
2238
2239   if (n < POWI_TABLE_SIZE)
2240     {
2241       if (cache[n])
2242         return cache[n];
2243
2244       target = gen_reg_rtx (mode);
2245       cache[n] = target;
2246
2247       op0 = expand_powi_1 (mode, n - powi_table[n], cache);
2248       op1 = expand_powi_1 (mode, powi_table[n], cache);
2249     }
2250   else if (n & 1)
2251     {
2252       target = gen_reg_rtx (mode);
2253       digit = n & ((1 << POWI_WINDOW_SIZE) - 1);
2254       op0 = expand_powi_1 (mode, n - digit, cache);
2255       op1 = expand_powi_1 (mode, digit, cache);
2256     }
2257   else
2258     {
2259       target = gen_reg_rtx (mode);
2260       op0 = expand_powi_1 (mode, n >> 1, cache);
2261       op1 = op0;
2262     }
2263
2264   result = expand_mult (mode, op0, op1, target, 0);
2265   if (result != target)
2266     emit_move_insn (target, result);
2267   return target;
2268 }
2269
2270 /* Expand the RTL to evaluate powi(x,n) in mode MODE.  X is the
2271    floating point operand in mode MODE, and N is the exponent.  This
2272    function needs to be kept in sync with powi_cost above.  */
2273
2274 static rtx
2275 expand_powi (rtx x, enum machine_mode mode, HOST_WIDE_INT n)
2276 {
2277   unsigned HOST_WIDE_INT val;
2278   rtx cache[POWI_TABLE_SIZE];
2279   rtx result;
2280
2281   if (n == 0)
2282     return CONST1_RTX (mode);
2283
2284   val = (n < 0) ? -n : n;
2285
2286   memset (cache, 0, sizeof (cache));
2287   cache[1] = x;
2288
2289   result = expand_powi_1 (mode, (n < 0) ? -n : n, cache);
2290
2291   /* If the original exponent was negative, reciprocate the result.  */
2292   if (n < 0)
2293     result = expand_binop (mode, sdiv_optab, CONST1_RTX (mode),
2294                            result, NULL_RTX, 0, OPTAB_LIB_WIDEN);
2295
2296   return result;
2297 }
2298
2299 /* Expand a call to the pow built-in mathematical function.  Return 0 if
2300    a normal call should be emitted rather than expanding the function
2301    in-line.  EXP is the expression that is a call to the builtin
2302    function; if convenient, the result should be placed in TARGET.  */
2303
2304 static rtx
2305 expand_builtin_pow (tree exp, rtx target, rtx subtarget)
2306 {
2307   tree arglist = TREE_OPERAND (exp, 1);
2308   tree arg0, arg1;
2309
2310   if (! validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
2311     return 0;
2312
2313   arg0 = TREE_VALUE (arglist);
2314   arg1 = TREE_VALUE (TREE_CHAIN (arglist));
2315
2316   if (TREE_CODE (arg1) == REAL_CST
2317       && ! TREE_CONSTANT_OVERFLOW (arg1))
2318     {
2319       REAL_VALUE_TYPE cint;
2320       REAL_VALUE_TYPE c;
2321       HOST_WIDE_INT n;
2322
2323       c = TREE_REAL_CST (arg1);
2324       n = real_to_integer (&c);
2325       real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
2326       if (real_identical (&c, &cint))
2327         {
2328           /* If the exponent is -1, 0, 1 or 2, then expand_powi is exact.
2329              Otherwise, check the number of multiplications required.
2330              Note that pow never sets errno for an integer exponent.  */
2331           if ((n >= -1 && n <= 2)
2332               || (flag_unsafe_math_optimizations
2333                   && ! optimize_size
2334                   && powi_cost (n) <= POWI_MAX_MULTS))
2335             {
2336               enum machine_mode mode = TYPE_MODE (TREE_TYPE (exp));
2337               rtx op = expand_expr (arg0, subtarget, VOIDmode, 0);
2338               op = force_reg (mode, op);
2339               return expand_powi (op, mode, n);
2340             }
2341         }
2342     }
2343
2344   if (! flag_unsafe_math_optimizations)
2345     return NULL_RTX;
2346   return expand_builtin_mathfn_2 (exp, target, subtarget);
2347 }
2348
2349 /* Expand expression EXP which is a call to the strlen builtin.  Return 0
2350    if we failed the caller should emit a normal call, otherwise
2351    try to get the result in TARGET, if convenient.  */
2352
2353 static rtx
2354 expand_builtin_strlen (tree arglist, rtx target,
2355                        enum machine_mode target_mode)
2356 {
2357   if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
2358     return 0;
2359   else
2360     {
2361       rtx pat;
2362       tree len, src = TREE_VALUE (arglist);
2363       rtx result, src_reg, char_rtx, before_strlen;
2364       enum machine_mode insn_mode = target_mode, char_mode;
2365       enum insn_code icode = CODE_FOR_nothing;
2366       int align;
2367
2368       /* If the length can be computed at compile-time, return it.  */
2369       len = c_strlen (src, 0);
2370       if (len)
2371         return expand_expr (len, target, target_mode, EXPAND_NORMAL);
2372
2373       /* If the length can be computed at compile-time and is constant
2374          integer, but there are side-effects in src, evaluate
2375          src for side-effects, then return len.
2376          E.g. x = strlen (i++ ? "xfoo" + 1 : "bar");
2377          can be optimized into: i++; x = 3;  */
2378       len = c_strlen (src, 1);
2379       if (len && TREE_CODE (len) == INTEGER_CST)
2380         {
2381           expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
2382           return expand_expr (len, target, target_mode, EXPAND_NORMAL);
2383         }
2384
2385       align = get_pointer_alignment (src, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
2386
2387       /* If SRC is not a pointer type, don't do this operation inline.  */
2388       if (align == 0)
2389         return 0;
2390
2391       /* Bail out if we can't compute strlen in the right mode.  */
2392       while (insn_mode != VOIDmode)
2393         {
2394           icode = strlen_optab->handlers[(int) insn_mode].insn_code;
2395           if (icode != CODE_FOR_nothing)
2396             break;
2397
2398           insn_mode = GET_MODE_WIDER_MODE (insn_mode);
2399         }
2400       if (insn_mode == VOIDmode)
2401         return 0;
2402
2403       /* Make a place to write the result of the instruction.  */
2404       result = target;
2405       if (! (result != 0
2406              && REG_P (result)
2407              && GET_MODE (result) == insn_mode
2408              && REGNO (result) >= FIRST_PSEUDO_REGISTER))
2409         result = gen_reg_rtx (insn_mode);
2410
2411       /* Make a place to hold the source address.  We will not expand
2412          the actual source until we are sure that the expansion will
2413          not fail -- there are trees that cannot be expanded twice.  */
2414       src_reg = gen_reg_rtx (Pmode);
2415
2416       /* Mark the beginning of the strlen sequence so we can emit the
2417          source operand later.  */
2418       before_strlen = get_last_insn ();
2419
2420       char_rtx = const0_rtx;
2421       char_mode = insn_data[(int) icode].operand[2].mode;
2422       if (! (*insn_data[(int) icode].operand[2].predicate) (char_rtx,
2423                                                             char_mode))
2424         char_rtx = copy_to_mode_reg (char_mode, char_rtx);
2425
2426       pat = GEN_FCN (icode) (result, gen_rtx_MEM (BLKmode, src_reg),
2427                              char_rtx, GEN_INT (align));
2428       if (! pat)
2429         return 0;
2430       emit_insn (pat);
2431
2432       /* Now that we are assured of success, expand the source.  */
2433       start_sequence ();
2434       pat = memory_address (BLKmode,
2435                             expand_expr (src, src_reg, ptr_mode, EXPAND_SUM));
2436       if (pat != src_reg)
2437         emit_move_insn (src_reg, pat);
2438       pat = get_insns ();
2439       end_sequence ();
2440
2441       if (before_strlen)
2442         emit_insn_after (pat, before_strlen);
2443       else
2444         emit_insn_before (pat, get_insns ());
2445
2446       /* Return the value in the proper mode for this function.  */
2447       if (GET_MODE (result) == target_mode)
2448         target = result;
2449       else if (target != 0)
2450         convert_move (target, result, 0);
2451       else
2452         target = convert_to_mode (target_mode, result, 0);
2453
2454       return target;
2455     }
2456 }
2457
2458 /* Expand a call to the strstr builtin.  Return 0 if we failed the
2459    caller should emit a normal call, otherwise try to get the result
2460    in TARGET, if convenient (and in mode MODE if that's convenient).  */
2461
2462 static rtx
2463 expand_builtin_strstr (tree arglist, rtx target, enum machine_mode mode)
2464 {
2465   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2466     return 0;
2467   else
2468     {
2469       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
2470       tree fn, tmp;
2471       const char *p1, *p2;
2472
2473       p2 = c_getstr (s2);
2474       if (p2 == NULL)
2475         return 0;
2476
2477       p1 = c_getstr (s1);
2478       if (p1 != NULL)
2479         {
2480           const char *r = strstr (p1, p2);
2481
2482           if (r == NULL)
2483             return const0_rtx;
2484
2485           /* Return an offset into the constant string argument.  */
2486           tmp = fold (build2 (PLUS_EXPR, TREE_TYPE (s1), s1,
2487                               fold_convert (TREE_TYPE (s1),
2488                                             ssize_int (r - p1))));
2489           return expand_expr (tmp, target, mode, EXPAND_NORMAL);
2490         }
2491
2492       if (p2[0] == '\0')
2493         return expand_expr (s1, target, mode, EXPAND_NORMAL);
2494
2495       if (p2[1] != '\0')
2496         return 0;
2497
2498       fn = implicit_built_in_decls[BUILT_IN_STRCHR];
2499       if (!fn)
2500         return 0;
2501
2502       /* New argument list transforming strstr(s1, s2) to
2503          strchr(s1, s2[0]).  */
2504       arglist =
2505         build_tree_list (NULL_TREE, build_int_2 (p2[0], 0));
2506       arglist = tree_cons (NULL_TREE, s1, arglist);
2507       return expand_expr (build_function_call_expr (fn, arglist),
2508                           target, mode, EXPAND_NORMAL);
2509     }
2510 }
2511
2512 /* Expand a call to the strchr builtin.  Return 0 if we failed the
2513    caller should emit a normal call, otherwise try to get the result
2514    in TARGET, if convenient (and in mode MODE if that's convenient).  */
2515
2516 static rtx
2517 expand_builtin_strchr (tree arglist, rtx target, enum machine_mode mode)
2518 {
2519   if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2520     return 0;
2521   else
2522     {
2523       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
2524       const char *p1;
2525
2526       if (TREE_CODE (s2) != INTEGER_CST)
2527         return 0;
2528
2529       p1 = c_getstr (s1);
2530       if (p1 != NULL)
2531         {
2532           char c;
2533           const char *r;
2534           tree tmp;
2535
2536           if (target_char_cast (s2, &c))
2537             return 0;
2538
2539           r = strchr (p1, c);
2540
2541           if (r == NULL)
2542             return const0_rtx;
2543
2544           /* Return an offset into the constant string argument.  */
2545           tmp = fold (build2 (PLUS_EXPR, TREE_TYPE (s1), s1,
2546                               fold_convert (TREE_TYPE (s1),
2547                                             ssize_int (r - p1))));
2548           return expand_expr (tmp, target, mode, EXPAND_NORMAL);
2549         }
2550
2551       /* FIXME: Should use here strchrM optab so that ports can optimize
2552          this.  */
2553       return 0;
2554     }
2555 }
2556
2557 /* Expand a call to the strrchr builtin.  Return 0 if we failed the
2558    caller should emit a normal call, otherwise try to get the result
2559    in TARGET, if convenient (and in mode MODE if that's convenient).  */
2560
2561 static rtx
2562 expand_builtin_strrchr (tree arglist, rtx target, enum machine_mode mode)
2563 {
2564   if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2565     return 0;
2566   else
2567     {
2568       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
2569       tree fn, tmp;
2570       const char *p1;
2571
2572       if (TREE_CODE (s2) != INTEGER_CST)
2573         return 0;
2574
2575       p1 = c_getstr (s1);
2576       if (p1 != NULL)
2577         {
2578           char c;
2579           const char *r;
2580
2581           if (target_char_cast (s2, &c))
2582             return 0;
2583
2584           r = strrchr (p1, c);
2585
2586           if (r == NULL)
2587             return const0_rtx;
2588
2589           /* Return an offset into the constant string argument.  */
2590           tmp = fold (build2 (PLUS_EXPR, TREE_TYPE (s1), s1,
2591                               fold_convert (TREE_TYPE (s1),
2592                                             ssize_int (r - p1))));
2593           return expand_expr (tmp, target, mode, EXPAND_NORMAL);
2594         }
2595
2596       if (! integer_zerop (s2))
2597         return 0;
2598
2599       fn = implicit_built_in_decls[BUILT_IN_STRCHR];
2600       if (!fn)
2601         return 0;
2602
2603       /* Transform strrchr(s1, '\0') to strchr(s1, '\0').  */
2604       return expand_expr (build_function_call_expr (fn, arglist),
2605                           target, mode, EXPAND_NORMAL);
2606     }
2607 }
2608
2609 /* Expand a call to the strpbrk builtin.  Return 0 if we failed the
2610    caller should emit a normal call, otherwise try to get the result
2611    in TARGET, if convenient (and in mode MODE if that's convenient).  */
2612
2613 static rtx
2614 expand_builtin_strpbrk (tree arglist, rtx target, enum machine_mode mode)
2615 {
2616   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2617     return 0;
2618   else
2619     {
2620       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
2621       tree fn, tmp;
2622       const char *p1, *p2;
2623
2624       p2 = c_getstr (s2);
2625       if (p2 == NULL)
2626         return 0;
2627
2628       p1 = c_getstr (s1);
2629       if (p1 != NULL)
2630         {
2631           const char *r = strpbrk (p1, p2);
2632
2633           if (r == NULL)
2634             return const0_rtx;
2635
2636           /* Return an offset into the constant string argument.  */
2637           tmp = fold (build2 (PLUS_EXPR, TREE_TYPE (s1), s1,
2638                               fold_convert (TREE_TYPE (s1),
2639                                             ssize_int (r - p1))));
2640           return expand_expr (tmp, target, mode, EXPAND_NORMAL);
2641         }
2642
2643       if (p2[0] == '\0')
2644         {
2645           /* strpbrk(x, "") == NULL.
2646              Evaluate and ignore the arguments in case they had
2647              side-effects.  */
2648           expand_expr (s1, const0_rtx, VOIDmode, EXPAND_NORMAL);
2649           return const0_rtx;
2650         }
2651
2652       if (p2[1] != '\0')
2653         return 0;  /* Really call strpbrk.  */
2654
2655       fn = implicit_built_in_decls[BUILT_IN_STRCHR];
2656       if (!fn)
2657         return 0;
2658
2659       /* New argument list transforming strpbrk(s1, s2) to
2660          strchr(s1, s2[0]).  */
2661       arglist =
2662         build_tree_list (NULL_TREE, build_int_2 (p2[0], 0));
2663       arglist = tree_cons (NULL_TREE, s1, arglist);
2664       return expand_expr (build_function_call_expr (fn, arglist),
2665                           target, mode, EXPAND_NORMAL);
2666     }
2667 }
2668
2669 /* Callback routine for store_by_pieces.  Read GET_MODE_BITSIZE (MODE)
2670    bytes from constant string DATA + OFFSET and return it as target
2671    constant.  */
2672
2673 static rtx
2674 builtin_memcpy_read_str (void *data, HOST_WIDE_INT offset,
2675                          enum machine_mode mode)
2676 {
2677   const char *str = (const char *) data;
2678
2679   if (offset < 0
2680       || ((unsigned HOST_WIDE_INT) offset + GET_MODE_SIZE (mode)
2681           > strlen (str) + 1))
2682     abort ();  /* Attempt to read past the end of constant string.  */
2683
2684   return c_readstr (str + offset, mode);
2685 }
2686
2687 /* Expand a call to the memcpy builtin, with arguments in ARGLIST.
2688    Return 0 if we failed, the caller should emit a normal call,
2689    otherwise try to get the result in TARGET, if convenient (and in
2690    mode MODE if that's convenient).  */
2691 static rtx
2692 expand_builtin_memcpy (tree arglist, rtx target, enum machine_mode mode)
2693 {
2694   if (!validate_arglist (arglist,
2695                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2696     return 0;
2697   else
2698     {
2699       tree dest = TREE_VALUE (arglist);
2700       tree src = TREE_VALUE (TREE_CHAIN (arglist));
2701       tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2702       const char *src_str;
2703       unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
2704       unsigned int dest_align
2705         = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2706       rtx dest_mem, src_mem, dest_addr, len_rtx;
2707
2708       /* If DEST is not a pointer type, call the normal function.  */
2709       if (dest_align == 0)
2710         return 0;
2711
2712       /* If the LEN parameter is zero, return DEST.  */
2713       if (integer_zerop (len))
2714         {
2715           /* Evaluate and ignore SRC in case it has side-effects.  */
2716           expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
2717           return expand_expr (dest, target, mode, EXPAND_NORMAL);
2718         }
2719
2720       /* If SRC and DEST are the same (and not volatile), return DEST.  */
2721       if (operand_equal_p (src, dest, 0))
2722         {
2723           /* Evaluate and ignore LEN in case it has side-effects.  */
2724           expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
2725           return expand_expr (dest, target, mode, EXPAND_NORMAL);
2726         }
2727
2728       /* If either SRC is not a pointer type, don't do this
2729          operation in-line.  */
2730       if (src_align == 0)
2731         return 0;
2732
2733       dest_mem = get_memory_rtx (dest);
2734       set_mem_align (dest_mem, dest_align);
2735       len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
2736       src_str = c_getstr (src);
2737
2738       /* If SRC is a string constant and block move would be done
2739          by pieces, we can avoid loading the string from memory
2740          and only stored the computed constants.  */
2741       if (src_str
2742           && GET_CODE (len_rtx) == CONST_INT
2743           && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
2744           && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
2745                                   (void *) src_str, dest_align))
2746         {
2747           dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
2748                                       builtin_memcpy_read_str,
2749                                       (void *) src_str, dest_align, 0);
2750           dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2751           dest_mem = convert_memory_address (ptr_mode, dest_mem);
2752           return dest_mem;
2753         }
2754
2755       src_mem = get_memory_rtx (src);
2756       set_mem_align (src_mem, src_align);
2757
2758       /* Copy word part most expediently.  */
2759       dest_addr = emit_block_move (dest_mem, src_mem, len_rtx,
2760                                    BLOCK_OP_NORMAL);
2761
2762       if (dest_addr == 0)
2763         {
2764           dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2765           dest_addr = convert_memory_address (ptr_mode, dest_addr);
2766         }
2767       return dest_addr;
2768     }
2769 }
2770
2771 /* Expand a call to the mempcpy builtin, with arguments in ARGLIST.
2772    Return 0 if we failed the caller should emit a normal call,
2773    otherwise try to get the result in TARGET, if convenient (and in
2774    mode MODE if that's convenient).  If ENDP is 0 return the
2775    destination pointer, if ENDP is 1 return the end pointer ala
2776    mempcpy, and if ENDP is 2 return the end pointer minus one ala
2777    stpcpy.  */
2778
2779 static rtx
2780 expand_builtin_mempcpy (tree arglist, rtx target, enum machine_mode mode,
2781                         int endp)
2782 {
2783   if (!validate_arglist (arglist,
2784                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2785     return 0;
2786   /* If return value is ignored, transform mempcpy into memcpy.  */
2787   else if (target == const0_rtx)
2788     {
2789       tree fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
2790
2791       if (!fn)
2792         return 0;
2793
2794       return expand_expr (build_function_call_expr (fn, arglist),
2795                           target, mode, EXPAND_NORMAL);
2796     }
2797   else
2798     {
2799       tree dest = TREE_VALUE (arglist);
2800       tree src = TREE_VALUE (TREE_CHAIN (arglist));
2801       tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2802       const char *src_str;
2803       unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
2804       unsigned int dest_align
2805         = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2806       rtx dest_mem, src_mem, len_rtx;
2807
2808       /* If DEST is not a pointer type, call the normal function.  */
2809       if (dest_align == 0)
2810         return 0;
2811
2812       /* If SRC and DEST are the same (and not volatile), do nothing.  */
2813       if (operand_equal_p (src, dest, 0))
2814         {
2815           tree expr;
2816
2817           if (endp == 0)
2818             {
2819               /* Evaluate and ignore LEN in case it has side-effects.  */
2820               expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
2821               return expand_expr (dest, target, mode, EXPAND_NORMAL);
2822             }
2823
2824           if (endp == 2)
2825             len = fold (build2 (MINUS_EXPR, TREE_TYPE (len), len,
2826                                 integer_one_node));
2827           len = fold_convert (TREE_TYPE (dest), len);
2828           expr = fold (build2 (PLUS_EXPR, TREE_TYPE (dest), dest, len));
2829           return expand_expr (expr, target, mode, EXPAND_NORMAL);
2830         }
2831
2832       /* If LEN is not constant, call the normal function.  */
2833       if (! host_integerp (len, 1))
2834         return 0;
2835
2836       /* If the LEN parameter is zero, return DEST.  */
2837       if (tree_low_cst (len, 1) == 0)
2838         {
2839           /* Evaluate and ignore SRC in case it has side-effects.  */
2840           expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
2841           return expand_expr (dest, target, mode, EXPAND_NORMAL);
2842         }
2843
2844       /* If either SRC is not a pointer type, don't do this
2845          operation in-line.  */
2846       if (src_align == 0)
2847         return 0;
2848
2849       len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
2850       src_str = c_getstr (src);
2851
2852       /* If SRC is a string constant and block move would be done
2853          by pieces, we can avoid loading the string from memory
2854          and only stored the computed constants.  */
2855       if (src_str
2856           && GET_CODE (len_rtx) == CONST_INT
2857           && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
2858           && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
2859                                   (void *) src_str, dest_align))
2860         {
2861           dest_mem = get_memory_rtx (dest);
2862           set_mem_align (dest_mem, dest_align);
2863           dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
2864                                       builtin_memcpy_read_str,
2865                                       (void *) src_str, dest_align, endp);
2866           dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2867           dest_mem = convert_memory_address (ptr_mode, dest_mem);
2868           return dest_mem;
2869         }
2870
2871       if (GET_CODE (len_rtx) == CONST_INT
2872           && can_move_by_pieces (INTVAL (len_rtx),
2873                                  MIN (dest_align, src_align)))
2874         {
2875           dest_mem = get_memory_rtx (dest);
2876           set_mem_align (dest_mem, dest_align);
2877           src_mem = get_memory_rtx (src);
2878           set_mem_align (src_mem, src_align);
2879           dest_mem = move_by_pieces (dest_mem, src_mem, INTVAL (len_rtx),
2880                                      MIN (dest_align, src_align), endp);
2881           dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2882           dest_mem = convert_memory_address (ptr_mode, dest_mem);
2883           return dest_mem;
2884         }
2885
2886       return 0;
2887     }
2888 }
2889
2890 /* Expand expression EXP, which is a call to the memmove builtin.  Return 0
2891    if we failed the caller should emit a normal call.  */
2892
2893 static rtx
2894 expand_builtin_memmove (tree arglist, rtx target, enum machine_mode mode)
2895 {
2896   if (!validate_arglist (arglist,
2897                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2898     return 0;
2899   else
2900     {
2901       tree dest = TREE_VALUE (arglist);
2902       tree src = TREE_VALUE (TREE_CHAIN (arglist));
2903       tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2904
2905       unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
2906       unsigned int dest_align
2907         = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2908
2909       /* If DEST is not a pointer type, call the normal function.  */
2910       if (dest_align == 0)
2911         return 0;
2912
2913       /* If the LEN parameter is zero, return DEST.  */
2914       if (integer_zerop (len))
2915         {
2916           /* Evaluate and ignore SRC in case it has side-effects.  */
2917           expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
2918           return expand_expr (dest, target, mode, EXPAND_NORMAL);
2919         }
2920
2921       /* If SRC and DEST are the same (and not volatile), return DEST.  */
2922       if (operand_equal_p (src, dest, 0))
2923         {
2924           /* Evaluate and ignore LEN in case it has side-effects.  */
2925           expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
2926           return expand_expr (dest, target, mode, EXPAND_NORMAL);
2927         }
2928
2929       /* If either SRC is not a pointer type, don't do this
2930          operation in-line.  */
2931       if (src_align == 0)
2932         return 0;
2933
2934       /* If src is categorized for a readonly section we can use
2935          normal memcpy.  */
2936       if (readonly_data_expr (src))
2937         {
2938           tree const fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
2939           if (!fn)
2940             return 0;
2941           return expand_expr (build_function_call_expr (fn, arglist),
2942                               target, mode, EXPAND_NORMAL);
2943         }
2944
2945       /* Otherwise, call the normal function.  */
2946       return 0;
2947    }
2948 }
2949
2950 /* Expand expression EXP, which is a call to the bcopy builtin.  Return 0
2951    if we failed the caller should emit a normal call.  */
2952
2953 static rtx
2954 expand_builtin_bcopy (tree arglist)
2955 {
2956   tree src, dest, size, newarglist;
2957
2958   if (!validate_arglist (arglist,
2959                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2960     return NULL_RTX;
2961
2962   src = TREE_VALUE (arglist);
2963   dest = TREE_VALUE (TREE_CHAIN (arglist));
2964   size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2965
2966   /* New argument list transforming bcopy(ptr x, ptr y, int z) to
2967      memmove(ptr y, ptr x, size_t z).   This is done this way
2968      so that if it isn't expanded inline, we fallback to
2969      calling bcopy instead of memmove.  */
2970
2971   newarglist = build_tree_list (NULL_TREE, fold_convert (sizetype, size));
2972   newarglist = tree_cons (NULL_TREE, src, newarglist);
2973   newarglist = tree_cons (NULL_TREE, dest, newarglist);
2974
2975   return expand_builtin_memmove (newarglist, const0_rtx, VOIDmode);
2976 }
2977
2978 #ifndef HAVE_movstr
2979 # define HAVE_movstr 0
2980 # define CODE_FOR_movstr CODE_FOR_nothing
2981 #endif
2982
2983 /* Expand into a movstr instruction, if one is available.  Return 0 if
2984    we failed, the caller should emit a normal call, otherwise try to
2985    get the result in TARGET, if convenient.  If ENDP is 0 return the
2986    destination pointer, if ENDP is 1 return the end pointer ala
2987    mempcpy, and if ENDP is 2 return the end pointer minus one ala
2988    stpcpy.  */
2989
2990 static rtx
2991 expand_movstr (tree dest, tree src, rtx target, int endp)
2992 {
2993   rtx end;
2994   rtx dest_mem;
2995   rtx src_mem;
2996   rtx insn;
2997   const struct insn_data * data;
2998
2999   if (!HAVE_movstr)
3000     return 0;
3001
3002   dest_mem = get_memory_rtx (dest);
3003   src_mem = get_memory_rtx (src);
3004   if (!endp)
3005     {
3006       target = force_reg (Pmode, XEXP (dest_mem, 0));
3007       dest_mem = replace_equiv_address (dest_mem, target);
3008       end = gen_reg_rtx (Pmode);
3009     }
3010   else
3011     {
3012       if (target == 0 || target == const0_rtx)
3013         {
3014           end = gen_reg_rtx (Pmode);
3015           if (target == 0)
3016             target = end;
3017         }
3018       else
3019         end = target;
3020     }
3021
3022   data = insn_data + CODE_FOR_movstr;
3023
3024   if (data->operand[0].mode != VOIDmode)
3025     end = gen_lowpart (data->operand[0].mode, end);
3026
3027   insn = data->genfun (end, dest_mem, src_mem);
3028
3029   if (insn == 0)
3030     abort ();
3031
3032   emit_insn (insn);
3033
3034   /* movstr is supposed to set end to the address of the NUL
3035      terminator.  If the caller requested a mempcpy-like return value,
3036      adjust it.  */
3037   if (endp == 1 && target != const0_rtx)
3038     emit_move_insn (target, plus_constant (gen_lowpart (GET_MODE (target),
3039                                                         end), 1));
3040
3041   return target;
3042 }
3043
3044 /* Expand expression EXP, which is a call to the strcpy builtin.  Return 0
3045    if we failed the caller should emit a normal call, otherwise try to get
3046    the result in TARGET, if convenient (and in mode MODE if that's
3047    convenient).  */
3048
3049 static rtx
3050 expand_builtin_strcpy (tree arglist, rtx target, enum machine_mode mode)
3051 {
3052   tree fn, len, src, dst;
3053
3054   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3055     return 0;
3056
3057   src = TREE_VALUE (TREE_CHAIN (arglist));
3058   dst = TREE_VALUE (arglist);
3059
3060   /* If SRC and DST are equal (and not volatile), return DST.  */
3061   if (operand_equal_p (src, dst, 0))
3062     return expand_expr (dst, target, mode, EXPAND_NORMAL);
3063
3064   len = c_strlen (src, 1);
3065   if (len == 0 || TREE_SIDE_EFFECTS (len))
3066     return expand_movstr (TREE_VALUE (arglist),
3067                           TREE_VALUE (TREE_CHAIN (arglist)),
3068                           target, /*endp=*/0);
3069
3070   fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
3071   if (!fn)
3072     return 0;
3073
3074   len = size_binop (PLUS_EXPR, len, ssize_int (1));
3075   arglist = build_tree_list (NULL_TREE, len);
3076   arglist = tree_cons (NULL_TREE, src, arglist);
3077   arglist = tree_cons (NULL_TREE, dst, arglist);
3078   return expand_expr (build_function_call_expr (fn, arglist),
3079                       target, mode, EXPAND_NORMAL);
3080 }
3081
3082 /* Expand a call to the stpcpy builtin, with arguments in ARGLIST.
3083    Return 0 if we failed the caller should emit a normal call,
3084    otherwise try to get the result in TARGET, if convenient (and in
3085    mode MODE if that's convenient).  */
3086
3087 static rtx
3088 expand_builtin_stpcpy (tree arglist, rtx target, enum machine_mode mode)
3089 {
3090   /* If return value is ignored, transform stpcpy into strcpy.  */
3091   if (target == const0_rtx)
3092     {
3093       tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
3094       if (!fn)
3095         return 0;
3096
3097       return expand_expr (build_function_call_expr (fn, arglist),
3098                           target, mode, EXPAND_NORMAL);
3099     }
3100
3101   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3102     return 0;
3103   else
3104     {
3105       tree dst, src, len;
3106       tree narglist;
3107       rtx ret;
3108
3109       /* Ensure we get an actual string whose length can be evaluated at
3110          compile-time, not an expression containing a string.  This is
3111          because the latter will potentially produce pessimized code
3112          when used to produce the return value.  */
3113       src = TREE_VALUE (TREE_CHAIN (arglist));
3114       if (! c_getstr (src) || ! (len = c_strlen (src, 0)))
3115         return expand_movstr (TREE_VALUE (arglist),
3116                               TREE_VALUE (TREE_CHAIN (arglist)),
3117                               target, /*endp=*/2);
3118
3119       dst = TREE_VALUE (arglist);
3120       len = fold (size_binop (PLUS_EXPR, len, ssize_int (1)));
3121       narglist = build_tree_list (NULL_TREE, len);
3122       narglist = tree_cons (NULL_TREE, src, narglist);
3123       narglist = tree_cons (NULL_TREE, dst, narglist);
3124       ret = expand_builtin_mempcpy (narglist, target, mode, /*endp=*/2);
3125
3126       if (ret)
3127         return ret;
3128
3129       if (TREE_CODE (len) == INTEGER_CST)
3130         {
3131           rtx len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
3132
3133           if (GET_CODE (len_rtx) == CONST_INT)
3134             {
3135               ret = expand_builtin_strcpy (arglist, target, mode);
3136
3137               if (ret)
3138                 {
3139                   if (! target)
3140                     target = gen_reg_rtx (mode);
3141                   if (GET_MODE (target) != GET_MODE (ret))
3142                     ret = gen_lowpart (GET_MODE (target), ret);
3143
3144                   ret = emit_move_insn (target,
3145                                         plus_constant (ret,
3146                                                        INTVAL (len_rtx)));
3147                   if (! ret)
3148                     abort ();
3149
3150                   return target;
3151                 }
3152             }
3153         }
3154
3155       return expand_movstr (TREE_VALUE (arglist),
3156                             TREE_VALUE (TREE_CHAIN (arglist)),
3157                             target, /*endp=*/2);
3158     }
3159 }
3160
3161 /* Callback routine for store_by_pieces.  Read GET_MODE_BITSIZE (MODE)
3162    bytes from constant string DATA + OFFSET and return it as target
3163    constant.  */
3164
3165 static rtx
3166 builtin_strncpy_read_str (void *data, HOST_WIDE_INT offset,
3167                           enum machine_mode mode)
3168 {
3169   const char *str = (const char *) data;
3170
3171   if ((unsigned HOST_WIDE_INT) offset > strlen (str))
3172     return const0_rtx;
3173
3174   return c_readstr (str + offset, mode);
3175 }
3176
3177 /* Expand expression EXP, which is a call to the strncpy builtin.  Return 0
3178    if we failed the caller should emit a normal call.  */
3179
3180 static rtx
3181 expand_builtin_strncpy (tree arglist, rtx target, enum machine_mode mode)
3182 {
3183   if (!validate_arglist (arglist,
3184                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3185     return 0;
3186   else
3187     {
3188       tree slen = c_strlen (TREE_VALUE (TREE_CHAIN (arglist)), 1);
3189       tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3190       tree fn;
3191
3192       /* We must be passed a constant len parameter.  */
3193       if (TREE_CODE (len) != INTEGER_CST)
3194         return 0;
3195
3196       /* If the len parameter is zero, return the dst parameter.  */
3197       if (integer_zerop (len))
3198         {
3199           /* Evaluate and ignore the src argument in case it has
3200              side-effects.  */
3201           expand_expr (TREE_VALUE (TREE_CHAIN (arglist)), const0_rtx,
3202                        VOIDmode, EXPAND_NORMAL);
3203           /* Return the dst parameter.  */
3204           return expand_expr (TREE_VALUE (arglist), target, mode,
3205                               EXPAND_NORMAL);
3206         }
3207
3208       /* Now, we must be passed a constant src ptr parameter.  */
3209       if (slen == 0 || TREE_CODE (slen) != INTEGER_CST)
3210         return 0;
3211
3212       slen = size_binop (PLUS_EXPR, slen, ssize_int (1));
3213
3214       /* We're required to pad with trailing zeros if the requested
3215          len is greater than strlen(s2)+1.  In that case try to
3216          use store_by_pieces, if it fails, punt.  */
3217       if (tree_int_cst_lt (slen, len))
3218         {
3219           tree dest = TREE_VALUE (arglist);
3220           unsigned int dest_align
3221             = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
3222           const char *p = c_getstr (TREE_VALUE (TREE_CHAIN (arglist)));
3223           rtx dest_mem;
3224
3225           if (!p || dest_align == 0 || !host_integerp (len, 1)
3226               || !can_store_by_pieces (tree_low_cst (len, 1),
3227                                        builtin_strncpy_read_str,
3228                                        (void *) p, dest_align))
3229             return 0;
3230
3231           dest_mem = get_memory_rtx (dest);
3232           store_by_pieces (dest_mem, tree_low_cst (len, 1),
3233                            builtin_strncpy_read_str,
3234                            (void *) p, dest_align, 0);
3235           dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3236           dest_mem = convert_memory_address (ptr_mode, dest_mem);
3237           return dest_mem;
3238         }
3239
3240       /* OK transform into builtin memcpy.  */
3241       fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
3242       if (!fn)
3243         return 0;
3244       return expand_expr (build_function_call_expr (fn, arglist),
3245                           target, mode, EXPAND_NORMAL);
3246     }
3247 }
3248
3249 /* Callback routine for store_by_pieces.  Read GET_MODE_BITSIZE (MODE)
3250    bytes from constant string DATA + OFFSET and return it as target
3251    constant.  */
3252
3253 static rtx
3254 builtin_memset_read_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
3255                          enum machine_mode mode)
3256 {
3257   const char *c = (const char *) data;
3258   char *p = alloca (GET_MODE_SIZE (mode));
3259
3260   memset (p, *c, GET_MODE_SIZE (mode));
3261
3262   return c_readstr (p, mode);
3263 }
3264
3265 /* Callback routine for store_by_pieces.  Return the RTL of a register
3266    containing GET_MODE_SIZE (MODE) consecutive copies of the unsigned
3267    char value given in the RTL register data.  For example, if mode is
3268    4 bytes wide, return the RTL for 0x01010101*data.  */
3269
3270 static rtx
3271 builtin_memset_gen_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
3272                         enum machine_mode mode)
3273 {
3274   rtx target, coeff;
3275   size_t size;
3276   char *p;
3277
3278   size = GET_MODE_SIZE (mode);
3279   if (size == 1)
3280     return (rtx) data;
3281
3282   p = alloca (size);
3283   memset (p, 1, size);
3284   coeff = c_readstr (p, mode);
3285
3286   target = convert_to_mode (mode, (rtx) data, 1);
3287   target = expand_mult (mode, target, coeff, NULL_RTX, 1);
3288   return force_reg (mode, target);
3289 }
3290
3291 /* Expand expression EXP, which is a call to the memset builtin.  Return 0
3292    if we failed the caller should emit a normal call, otherwise try to get
3293    the result in TARGET, if convenient (and in mode MODE if that's
3294    convenient).  */
3295
3296 static rtx
3297 expand_builtin_memset (tree arglist, rtx target, enum machine_mode mode)
3298 {
3299   if (!validate_arglist (arglist,
3300                          POINTER_TYPE, INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
3301     return 0;
3302   else
3303     {
3304       tree dest = TREE_VALUE (arglist);
3305       tree val = TREE_VALUE (TREE_CHAIN (arglist));
3306       tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3307       char c;
3308
3309       unsigned int dest_align
3310         = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
3311       rtx dest_mem, dest_addr, len_rtx;
3312
3313       /* If DEST is not a pointer type, don't do this
3314          operation in-line.  */
3315       if (dest_align == 0)
3316         return 0;
3317
3318       /* If the LEN parameter is zero, return DEST.  */
3319       if (integer_zerop (len))
3320         {
3321           /* Evaluate and ignore VAL in case it has side-effects.  */
3322           expand_expr (val, const0_rtx, VOIDmode, EXPAND_NORMAL);
3323           return expand_expr (dest, target, mode, EXPAND_NORMAL);
3324         }
3325
3326       if (TREE_CODE (val) != INTEGER_CST)
3327         {
3328           rtx val_rtx;
3329
3330           if (!host_integerp (len, 1))
3331             return 0;
3332
3333           if (optimize_size && tree_low_cst (len, 1) > 1)
3334             return 0;
3335
3336           /* Assume that we can memset by pieces if we can store the
3337            * the coefficients by pieces (in the required modes).
3338            * We can't pass builtin_memset_gen_str as that emits RTL.  */
3339           c = 1;
3340           if (!can_store_by_pieces (tree_low_cst (len, 1),
3341                                     builtin_memset_read_str,
3342                                     &c, dest_align))
3343             return 0;
3344
3345           val = fold (build1 (CONVERT_EXPR, unsigned_char_type_node, val));
3346           val_rtx = expand_expr (val, NULL_RTX, VOIDmode, 0);
3347           val_rtx = force_reg (TYPE_MODE (unsigned_char_type_node),
3348                                val_rtx);
3349           dest_mem = get_memory_rtx (dest);
3350           store_by_pieces (dest_mem, tree_low_cst (len, 1),
3351                            builtin_memset_gen_str,
3352                            val_rtx, dest_align, 0);
3353           dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3354           dest_mem = convert_memory_address (ptr_mode, dest_mem);
3355           return dest_mem;
3356         }
3357
3358       if (target_char_cast (val, &c))
3359         return 0;
3360
3361       if (c)
3362         {
3363           if (!host_integerp (len, 1))
3364             return 0;
3365           if (!can_store_by_pieces (tree_low_cst (len, 1),
3366                                     builtin_memset_read_str, &c,
3367                                     dest_align))
3368             return 0;
3369
3370           dest_mem = get_memory_rtx (dest);
3371           store_by_pieces (dest_mem, tree_low_cst (len, 1),
3372                            builtin_memset_read_str,
3373                            &c, dest_align, 0);
3374           dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3375           dest_mem = convert_memory_address (ptr_mode, dest_mem);
3376           return dest_mem;
3377         }
3378
3379       len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
3380
3381       dest_mem = get_memory_rtx (dest);
3382       set_mem_align (dest_mem, dest_align);
3383       dest_addr = clear_storage (dest_mem, len_rtx);
3384
3385       if (dest_addr == 0)
3386         {
3387           dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3388           dest_addr = convert_memory_address (ptr_mode, dest_addr);
3389         }
3390
3391       return dest_addr;
3392     }
3393 }
3394
3395 /* Expand expression EXP, which is a call to the bzero builtin.  Return 0
3396    if we failed the caller should emit a normal call.  */
3397
3398 static rtx
3399 expand_builtin_bzero (tree arglist)
3400 {
3401   tree dest, size, newarglist;
3402
3403   if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3404     return NULL_RTX;
3405
3406   dest = TREE_VALUE (arglist);
3407   size = TREE_VALUE (TREE_CHAIN (arglist));
3408
3409   /* New argument list transforming bzero(ptr x, int y) to
3410      memset(ptr x, int 0, size_t y).   This is done this way
3411      so that if it isn't expanded inline, we fallback to
3412      calling bzero instead of memset.  */
3413
3414   newarglist = build_tree_list (NULL_TREE, fold_convert (sizetype, size));
3415   newarglist = tree_cons (NULL_TREE, integer_zero_node, newarglist);
3416   newarglist = tree_cons (NULL_TREE, dest, newarglist);
3417
3418   return expand_builtin_memset (newarglist, const0_rtx, VOIDmode);
3419 }
3420
3421 /* Expand expression EXP, which is a call to the memcmp built-in function.
3422    ARGLIST is the argument list for this call.  Return 0 if we failed and the
3423    caller should emit a normal call, otherwise try to get the result in
3424    TARGET, if convenient (and in mode MODE, if that's convenient).  */
3425
3426 static rtx
3427 expand_builtin_memcmp (tree exp ATTRIBUTE_UNUSED, tree arglist, rtx target,
3428                        enum machine_mode mode)
3429 {
3430   tree arg1, arg2, len;
3431   const char *p1, *p2;
3432
3433   if (!validate_arglist (arglist,
3434                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3435     return 0;
3436
3437   arg1 = TREE_VALUE (arglist);
3438   arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3439   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3440
3441   /* If the len parameter is zero, return zero.  */
3442   if (integer_zerop (len))
3443     {
3444       /* Evaluate and ignore arg1 and arg2 in case they have
3445          side-effects.  */
3446       expand_expr (arg1, const0_rtx, VOIDmode, EXPAND_NORMAL);
3447       expand_expr (arg2, const0_rtx, VOIDmode, EXPAND_NORMAL);
3448       return const0_rtx;
3449     }
3450
3451   /* If both arguments are equal (and not volatile), return zero.  */
3452   if (operand_equal_p (arg1, arg2, 0))
3453     {
3454       /* Evaluate and ignore len in case it has side-effects.  */
3455       expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
3456       return const0_rtx;
3457     }
3458
3459   p1 = c_getstr (arg1);
3460   p2 = c_getstr (arg2);
3461
3462   /* If all arguments are constant, and the value of len is not greater
3463      than the lengths of arg1 and arg2, evaluate at compile-time.  */
3464   if (host_integerp (len, 1) && p1 && p2
3465       && compare_tree_int (len, strlen (p1) + 1) <= 0
3466       && compare_tree_int (len, strlen (p2) + 1) <= 0)
3467     {
3468       const int r = memcmp (p1, p2, tree_low_cst (len, 1));
3469
3470       return (r < 0 ? constm1_rtx : (r > 0 ? const1_rtx : const0_rtx));
3471     }
3472
3473   /* If len parameter is one, return an expression corresponding to
3474      (*(const unsigned char*)arg1 - (const unsigned char*)arg2).  */
3475   if (integer_onep (len))
3476     {
3477       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
3478       tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
3479       tree ind1 =
3480       fold (build1 (CONVERT_EXPR, integer_type_node,
3481                     build1 (INDIRECT_REF, cst_uchar_node,
3482                             fold_convert (cst_uchar_ptr_node, arg1))));
3483       tree ind2 =
3484       fold (build1 (CONVERT_EXPR, integer_type_node,
3485                     build1 (INDIRECT_REF, cst_uchar_node,
3486                             fold_convert (cst_uchar_ptr_node, arg2))));
3487       tree result = fold (build2 (MINUS_EXPR, integer_type_node, ind1, ind2));
3488       return expand_expr (result, target, mode, EXPAND_NORMAL);
3489     }
3490
3491 #if defined HAVE_cmpmemsi || defined HAVE_cmpstrsi
3492   {
3493     rtx arg1_rtx, arg2_rtx, arg3_rtx;
3494     rtx result;
3495     rtx insn;
3496
3497     int arg1_align
3498       = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3499     int arg2_align
3500       = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3501     enum machine_mode insn_mode;
3502
3503 #ifdef HAVE_cmpmemsi
3504     if (HAVE_cmpmemsi)
3505       insn_mode = insn_data[(int) CODE_FOR_cmpmemsi].operand[0].mode;
3506     else
3507 #endif
3508 #ifdef HAVE_cmpstrsi
3509     if (HAVE_cmpstrsi)
3510       insn_mode = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
3511     else
3512 #endif
3513       return 0;
3514
3515     /* If we don't have POINTER_TYPE, call the function.  */
3516     if (arg1_align == 0 || arg2_align == 0)
3517       return 0;
3518
3519     /* Make a place to write the result of the instruction.  */
3520     result = target;
3521     if (! (result != 0
3522            && REG_P (result) && GET_MODE (result) == insn_mode
3523            && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3524       result = gen_reg_rtx (insn_mode);
3525
3526     arg1_rtx = get_memory_rtx (arg1);
3527     arg2_rtx = get_memory_rtx (arg2);
3528     arg3_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
3529 #ifdef HAVE_cmpmemsi
3530     if (HAVE_cmpmemsi)
3531       insn = gen_cmpmemsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3532                            GEN_INT (MIN (arg1_align, arg2_align)));
3533     else
3534 #endif
3535 #ifdef HAVE_cmpstrsi
3536     if (HAVE_cmpstrsi)
3537       insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3538                            GEN_INT (MIN (arg1_align, arg2_align)));
3539     else
3540 #endif
3541       abort ();
3542
3543     if (insn)
3544       emit_insn (insn);
3545     else
3546       emit_library_call_value (memcmp_libfunc, result, LCT_PURE_MAKE_BLOCK,
3547                                TYPE_MODE (integer_type_node), 3,
3548                                XEXP (arg1_rtx, 0), Pmode,
3549                                XEXP (arg2_rtx, 0), Pmode,
3550                                convert_to_mode (TYPE_MODE (sizetype), arg3_rtx,
3551                                                 TYPE_UNSIGNED (sizetype)),
3552                                TYPE_MODE (sizetype));
3553
3554     /* Return the value in the proper mode for this function.  */
3555     mode = TYPE_MODE (TREE_TYPE (exp));
3556     if (GET_MODE (result) == mode)
3557       return result;
3558     else if (target != 0)
3559       {
3560         convert_move (target, result, 0);
3561         return target;
3562       }
3563     else
3564       return convert_to_mode (mode, result, 0);
3565   }
3566 #endif
3567
3568   return 0;
3569 }
3570
3571 /* Expand expression EXP, which is a call to the strcmp builtin.  Return 0
3572    if we failed the caller should emit a normal call, otherwise try to get
3573    the result in TARGET, if convenient.  */
3574
3575 static rtx
3576 expand_builtin_strcmp (tree exp, rtx target, enum machine_mode mode)
3577 {
3578   tree arglist = TREE_OPERAND (exp, 1);
3579   tree arg1, arg2;
3580   const char *p1, *p2;
3581
3582   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3583     return 0;
3584
3585   arg1 = TREE_VALUE (arglist);
3586   arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3587
3588   /* If both arguments are equal (and not volatile), return zero.  */
3589   if (operand_equal_p (arg1, arg2, 0))
3590     return const0_rtx;
3591
3592   p1 = c_getstr (arg1);
3593   p2 = c_getstr (arg2);
3594
3595   if (p1 && p2)
3596     {
3597       const int i = strcmp (p1, p2);
3598       return (i < 0 ? constm1_rtx : (i > 0 ? const1_rtx : const0_rtx));
3599     }
3600
3601   /* If either arg is "", return an expression corresponding to
3602      (*(const unsigned char*)arg1 - (const unsigned char*)arg2).  */
3603   if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
3604     {
3605       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
3606       tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
3607       tree ind1 =
3608         fold (build1 (CONVERT_EXPR, integer_type_node,
3609                       build1 (INDIRECT_REF, cst_uchar_node,
3610                               fold_convert (cst_uchar_ptr_node, arg1))));
3611       tree ind2 =
3612         fold (build1 (CONVERT_EXPR, integer_type_node,
3613                       build1 (INDIRECT_REF, cst_uchar_node,
3614                               fold_convert (cst_uchar_ptr_node, arg2))));
3615       tree result = fold (build2 (MINUS_EXPR, integer_type_node, ind1, ind2));
3616       return expand_expr (result, target, mode, EXPAND_NORMAL);
3617     }
3618
3619 #ifdef HAVE_cmpstrsi
3620   if (HAVE_cmpstrsi)
3621   {
3622     tree len, len1, len2;
3623     rtx arg1_rtx, arg2_rtx, arg3_rtx;
3624     rtx result, insn;
3625     tree fndecl;
3626
3627     int arg1_align
3628       = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3629     int arg2_align
3630       = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3631     enum machine_mode insn_mode
3632       = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
3633
3634     len1 = c_strlen (arg1, 1);
3635     len2 = c_strlen (arg2, 1);
3636
3637     if (len1)
3638       len1 = size_binop (PLUS_EXPR, ssize_int (1), len1);
3639     if (len2)
3640       len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
3641
3642     /* If we don't have a constant length for the first, use the length
3643        of the second, if we know it.  We don't require a constant for
3644        this case; some cost analysis could be done if both are available
3645        but neither is constant.  For now, assume they're equally cheap,
3646        unless one has side effects.  If both strings have constant lengths,
3647        use the smaller.  */
3648
3649     if (!len1)
3650       len = len2;
3651     else if (!len2)
3652       len = len1;
3653     else if (TREE_SIDE_EFFECTS (len1))
3654       len = len2;
3655     else if (TREE_SIDE_EFFECTS (len2))
3656       len = len1;
3657     else if (TREE_CODE (len1) != INTEGER_CST)
3658       len = len2;
3659     else if (TREE_CODE (len2) != INTEGER_CST)
3660       len = len1;
3661     else if (tree_int_cst_lt (len1, len2))
3662       len = len1;
3663     else
3664       len = len2;
3665
3666     /* If both arguments have side effects, we cannot optimize.  */
3667     if (!len || TREE_SIDE_EFFECTS (len))
3668       return 0;
3669
3670     /* If we don't have POINTER_TYPE, call the function.  */
3671     if (arg1_align == 0 || arg2_align == 0)
3672       return 0;
3673
3674     /* Make a place to write the result of the instruction.  */
3675     result = target;
3676     if (! (result != 0
3677            && REG_P (result) && GET_MODE (result) == insn_mode
3678            && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3679       result = gen_reg_rtx (insn_mode);
3680
3681     /* Stabilize the arguments in case gen_cmpstrsi fails.  */
3682     arg1 = builtin_save_expr (arg1);
3683     arg2 = builtin_save_expr (arg2);
3684
3685     arg1_rtx = get_memory_rtx (arg1);
3686     arg2_rtx = get_memory_rtx (arg2);
3687     arg3_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
3688     insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3689                          GEN_INT (MIN (arg1_align, arg2_align)));
3690     if (insn)
3691       {
3692         emit_insn (insn);
3693
3694         /* Return the value in the proper mode for this function.  */
3695         mode = TYPE_MODE (TREE_TYPE (exp));
3696         if (GET_MODE (result) == mode)
3697           return result;
3698         if (target == 0)
3699           return convert_to_mode (mode, result, 0);
3700         convert_move (target, result, 0);
3701         return target;
3702       }
3703
3704     /* Expand the library call ourselves using a stabilized argument
3705        list to avoid re-evaluating the function's arguments twice.  */
3706     arglist = build_tree_list (NULL_TREE, arg2);
3707     arglist = tree_cons (NULL_TREE, arg1, arglist);
3708     fndecl = get_callee_fndecl (exp);
3709     exp = build_function_call_expr (fndecl, arglist);
3710     return expand_call (exp, target, target == const0_rtx);
3711   }
3712 #endif
3713   return 0;
3714 }
3715
3716 /* Expand expression EXP, which is a call to the strncmp builtin.  Return 0
3717    if we failed the caller should emit a normal call, otherwise try to get
3718    the result in TARGET, if convenient.  */
3719
3720 static rtx
3721 expand_builtin_strncmp (tree exp, rtx target, enum machine_mode mode)
3722 {
3723   tree arglist = TREE_OPERAND (exp, 1);
3724   tree arg1, arg2, arg3;
3725   const char *p1, *p2;
3726
3727   if (!validate_arglist (arglist,
3728                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3729     return 0;
3730
3731   arg1 = TREE_VALUE (arglist);
3732   arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3733   arg3 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3734
3735   /* If the len parameter is zero, return zero.  */
3736   if (integer_zerop (arg3))
3737     {
3738       /* Evaluate and ignore arg1 and arg2 in case they have
3739          side-effects.  */
3740       expand_expr (arg1, const0_rtx, VOIDmode, EXPAND_NORMAL);
3741       expand_expr (arg2, const0_rtx, VOIDmode, EXPAND_NORMAL);
3742       return const0_rtx;
3743     }
3744
3745   /* If arg1 and arg2 are equal (and not volatile), return zero.  */
3746   if (operand_equal_p (arg1, arg2, 0))
3747     {
3748       /* Evaluate and ignore arg3 in case it has side-effects.  */
3749       expand_expr (arg3, const0_rtx, VOIDmode, EXPAND_NORMAL);
3750       return const0_rtx;
3751     }
3752
3753   p1 = c_getstr (arg1);
3754   p2 = c_getstr (arg2);
3755
3756   /* If all arguments are constant, evaluate at compile-time.  */
3757   if (host_integerp (arg3, 1) && p1 && p2)
3758     {
3759       const int r = strncmp (p1, p2, tree_low_cst (arg3, 1));
3760       return (r < 0 ? constm1_rtx : (r > 0 ? const1_rtx : const0_rtx));
3761     }
3762
3763   /* If len == 1 or (either string parameter is "" and (len >= 1)),
3764       return (*(const u_char*)arg1 - *(const u_char*)arg2).  */
3765   if (host_integerp (arg3, 1)
3766       && (tree_low_cst (arg3, 1) == 1
3767           || (tree_low_cst (arg3, 1) > 1
3768               && ((p1 && *p1 == '\0') || (p2 && *p2 == '\0')))))
3769     {
3770       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
3771       tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
3772       tree ind1 =
3773         fold (build1 (CONVERT_EXPR, integer_type_node,
3774                       build1 (INDIRECT_REF, cst_uchar_node,
3775                               fold_convert (cst_uchar_ptr_node, arg1))));
3776       tree ind2 =
3777         fold (build1 (CONVERT_EXPR, integer_type_node,
3778                       build1 (INDIRECT_REF, cst_uchar_node,
3779                               fold_convert (cst_uchar_ptr_node, arg2))));
3780       tree result = fold (build2 (MINUS_EXPR, integer_type_node, ind1, ind2));
3781       return expand_expr (result, target, mode, EXPAND_NORMAL);
3782     }
3783
3784   /* If c_strlen can determine an expression for one of the string
3785      lengths, and it doesn't have side effects, then emit cmpstrsi
3786      using length MIN(strlen(string)+1, arg3).  */
3787 #ifdef HAVE_cmpstrsi
3788   if (HAVE_cmpstrsi)
3789   {
3790     tree len, len1, len2;
3791     rtx arg1_rtx, arg2_rtx, arg3_rtx;
3792     rtx result, insn;
3793     tree fndecl;
3794
3795     int arg1_align
3796       = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3797     int arg2_align
3798       = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3799     enum machine_mode insn_mode
3800       = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
3801
3802     len1 = c_strlen (arg1, 1);
3803     len2 = c_strlen (arg2, 1);
3804
3805     if (len1)
3806       len1 = size_binop (PLUS_EXPR, ssize_int (1), len1);
3807     if (len2)
3808       len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
3809
3810     /* If we don't have a constant length for the first, use the length
3811        of the second, if we know it.  We don't require a constant for
3812        this case; some cost analysis could be done if both are available
3813        but neither is constant.  For now, assume they're equally cheap,
3814        unless one has side effects.  If both strings have constant lengths,
3815        use the smaller.  */
3816
3817     if (!len1)
3818       len = len2;
3819     else if (!len2)
3820       len = len1;
3821     else if (TREE_SIDE_EFFECTS (len1))
3822       len = len2;
3823     else if (TREE_SIDE_EFFECTS (len2))
3824       len = len1;
3825     else if (TREE_CODE (len1) != INTEGER_CST)
3826       len = len2;
3827     else if (TREE_CODE (len2) != INTEGER_CST)
3828       len = len1;
3829     else if (tree_int_cst_lt (len1, len2))
3830       len = len1;
3831     else
3832       len = len2;
3833
3834     /* If both arguments have side effects, we cannot optimize.  */
3835     if (!len || TREE_SIDE_EFFECTS (len))
3836       return 0;
3837
3838     /* The actual new length parameter is MIN(len,arg3).  */
3839     len = fold (build2 (MIN_EXPR, TREE_TYPE (len), len, arg3));
3840
3841     /* If we don't have POINTER_TYPE, call the function.  */
3842     if (arg1_align == 0 || arg2_align == 0)
3843       return 0;
3844
3845     /* Make a place to write the result of the instruction.  */
3846     result = target;
3847     if (! (result != 0
3848            && REG_P (result) && GET_MODE (result) == insn_mode
3849            && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3850       result = gen_reg_rtx (insn_mode);
3851
3852     /* Stabilize the arguments in case gen_cmpstrsi fails.  */
3853     arg1 = builtin_save_expr (arg1);
3854     arg2 = builtin_save_expr (arg2);
3855     len = builtin_save_expr (len);
3856
3857     arg1_rtx = get_memory_rtx (arg1);
3858     arg2_rtx = get_memory_rtx (arg2);
3859     arg3_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
3860     insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3861                          GEN_INT (MIN (arg1_align, arg2_align)));
3862     if (insn)
3863       {
3864         emit_insn (insn);
3865
3866         /* Return the value in the proper mode for this function.  */
3867         mode = TYPE_MODE (TREE_TYPE (exp));
3868         if (GET_MODE (result) == mode)
3869           return result;
3870         if (target == 0)
3871           return convert_to_mode (mode, result, 0);
3872         convert_move (target, result, 0);
3873         return target;
3874       }
3875
3876     /* Expand the library call ourselves using a stabilized argument
3877        list to avoid re-evaluating the function's arguments twice.  */
3878     arglist = build_tree_list (NULL_TREE, len);
3879     arglist = tree_cons (NULL_TREE, arg2, arglist);
3880     arglist = tree_cons (NULL_TREE, arg1, arglist);
3881     fndecl = get_callee_fndecl (exp);
3882     exp = build_function_call_expr (fndecl, arglist);
3883     return expand_call (exp, target, target == const0_rtx);
3884   }
3885 #endif
3886   return 0;
3887 }
3888
3889 /* Expand expression EXP, which is a call to the strcat builtin.
3890    Return 0 if we failed the caller should emit a normal call,
3891    otherwise try to get the result in TARGET, if convenient.  */
3892
3893 static rtx
3894 expand_builtin_strcat (tree arglist, rtx target, enum machine_mode mode)
3895 {
3896   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3897     return 0;
3898   else
3899     {
3900       tree dst = TREE_VALUE (arglist),
3901         src = TREE_VALUE (TREE_CHAIN (arglist));
3902       const char *p = c_getstr (src);
3903
3904       if (p)
3905         {
3906           /* If the string length is zero, return the dst parameter.  */
3907           if (*p == '\0')
3908             return expand_expr (dst, target, mode, EXPAND_NORMAL);
3909           else if (!optimize_size)
3910             {
3911               /* Otherwise if !optimize_size, see if we can store by
3912                  pieces into (dst + strlen(dst)).  */
3913               tree newdst, arglist,
3914                 strlen_fn = implicit_built_in_decls[BUILT_IN_STRLEN];
3915
3916               /* This is the length argument.  */
3917               arglist = build_tree_list (NULL_TREE,
3918                                          fold (size_binop (PLUS_EXPR,
3919                                                            c_strlen (src, 0),
3920                                                            ssize_int (1))));
3921               /* Prepend src argument.  */
3922               arglist = tree_cons (NULL_TREE, src, arglist);
3923
3924               /* We're going to use dst more than once.  */
3925               dst = builtin_save_expr (dst);
3926
3927               /* Create strlen (dst).  */
3928               newdst =
3929                 fold (build_function_call_expr (strlen_fn,
3930                                                 build_tree_list (NULL_TREE,
3931                                                                  dst)));
3932               /* Create (dst + strlen (dst)).  */
3933               newdst = fold (build2 (PLUS_EXPR, TREE_TYPE (dst), dst, newdst));
3934
3935               /* Prepend the new dst argument.  */
3936               arglist = tree_cons (NULL_TREE, newdst, arglist);
3937
3938               /* We don't want to get turned into a memcpy if the
3939                  target is const0_rtx, i.e. when the return value
3940                  isn't used.  That would produce pessimized code so
3941                  pass in a target of zero, it should never actually be
3942                  used.  If this was successful return the original
3943                  dst, not the result of mempcpy.  */
3944               if (expand_builtin_mempcpy (arglist, /*target=*/0, mode, /*endp=*/0))
3945                 return expand_expr (dst, target, mode, EXPAND_NORMAL);
3946               else
3947                 return 0;
3948             }
3949         }
3950
3951       return 0;
3952     }
3953 }
3954
3955 /* Expand expression EXP, which is a call to the strncat builtin.
3956    Return 0 if we failed the caller should emit a normal call,
3957    otherwise try to get the result in TARGET, if convenient.  */
3958
3959 static rtx
3960 expand_builtin_strncat (tree arglist, rtx target, enum machine_mode mode)
3961 {
3962   if (!validate_arglist (arglist,
3963                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3964     return 0;
3965   else
3966     {
3967       tree dst = TREE_VALUE (arglist),
3968         src = TREE_VALUE (TREE_CHAIN (arglist)),
3969         len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3970       const char *p = c_getstr (src);
3971
3972       /* If the requested length is zero, or the src parameter string
3973           length is zero, return the dst parameter.  */
3974       if (integer_zerop (len) || (p && *p == '\0'))
3975         {
3976           /* Evaluate and ignore the src and len parameters in case
3977              they have side-effects.  */
3978           expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
3979           expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
3980           return expand_expr (dst, target, mode, EXPAND_NORMAL);
3981         }
3982
3983       /* If the requested len is greater than or equal to the string
3984          length, call strcat.  */
3985       if (TREE_CODE (len) == INTEGER_CST && p
3986           && compare_tree_int (len, strlen (p)) >= 0)
3987         {
3988           tree newarglist
3989             = tree_cons (NULL_TREE, dst, build_tree_list (NULL_TREE, src));
3990           tree fn = implicit_built_in_decls[BUILT_IN_STRCAT];
3991
3992           /* If the replacement _DECL isn't initialized, don't do the
3993              transformation.  */
3994           if (!fn)
3995             return 0;
3996
3997           return expand_expr (build_function_call_expr (fn, newarglist),
3998                               target, mode, EXPAND_NORMAL);
3999         }
4000       return 0;
4001     }
4002 }
4003
4004 /* Expand expression EXP, which is a call to the strspn builtin.
4005    Return 0 if we failed the caller should emit a normal call,
4006    otherwise try to get the result in TARGET, if convenient.  */
4007
4008 static rtx
4009 expand_builtin_strspn (tree arglist, rtx target, enum machine_mode mode)
4010 {
4011   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4012     return 0;
4013   else
4014     {
4015       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
4016       const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
4017
4018       /* If both arguments are constants, evaluate at compile-time.  */
4019       if (p1 && p2)
4020         {
4021           const size_t r = strspn (p1, p2);
4022           return expand_expr (size_int (r), target, mode, EXPAND_NORMAL);
4023         }
4024
4025       /* If either argument is "", return 0.  */
4026       if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
4027         {
4028           /* Evaluate and ignore both arguments in case either one has
4029              side-effects.  */
4030           expand_expr (s1, const0_rtx, VOIDmode, EXPAND_NORMAL);
4031           expand_expr (s2, const0_rtx, VOIDmode, EXPAND_NORMAL);
4032           return const0_rtx;
4033         }
4034       return 0;
4035     }
4036 }
4037
4038 /* Expand expression EXP, which is a call to the strcspn builtin.
4039    Return 0 if we failed the caller should emit a normal call,
4040    otherwise try to get the result in TARGET, if convenient.  */
4041
4042 static rtx
4043 expand_builtin_strcspn (tree arglist, rtx target, enum machine_mode mode)
4044 {
4045   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4046     return 0;
4047   else
4048     {
4049       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
4050       const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
4051
4052       /* If both arguments are constants, evaluate at compile-time.  */
4053       if (p1 && p2)
4054         {
4055           const size_t r = strcspn (p1, p2);
4056           return expand_expr (size_int (r), target, mode, EXPAND_NORMAL);
4057         }
4058
4059       /* If the first argument is "", return 0.  */
4060       if (p1 && *p1 == '\0')
4061         {
4062           /* Evaluate and ignore argument s2 in case it has
4063              side-effects.  */
4064           expand_expr (s2, const0_rtx, VOIDmode, EXPAND_NORMAL);
4065           return const0_rtx;
4066         }
4067
4068       /* If the second argument is "", return __builtin_strlen(s1).  */
4069       if (p2 && *p2 == '\0')
4070         {
4071           tree newarglist = build_tree_list (NULL_TREE, s1),
4072             fn = implicit_built_in_decls[BUILT_IN_STRLEN];
4073
4074           /* If the replacement _DECL isn't initialized, don't do the
4075              transformation.  */
4076           if (!fn)
4077             return 0;
4078
4079           return expand_expr (build_function_call_expr (fn, newarglist),
4080                               target, mode, EXPAND_NORMAL);
4081         }
4082       return 0;
4083     }
4084 }
4085
4086 /* Expand a call to __builtin_saveregs, generating the result in TARGET,
4087    if that's convenient.  */
4088
4089 rtx
4090 expand_builtin_saveregs (void)
4091 {
4092   rtx val, seq;
4093
4094   /* Don't do __builtin_saveregs more than once in a function.
4095      Save the result of the first call and reuse it.  */
4096   if (saveregs_value != 0)
4097     return saveregs_value;
4098
4099   /* When this function is called, it means that registers must be
4100      saved on entry to this function.  So we migrate the call to the
4101      first insn of this function.  */
4102
4103   start_sequence ();
4104
4105   /* Do whatever the machine needs done in this case.  */
4106   val = targetm.calls.expand_builtin_saveregs ();
4107
4108   seq = get_insns ();
4109   end_sequence ();
4110
4111   saveregs_value = val;
4112
4113   /* Put the insns after the NOTE that starts the function.  If this
4114      is inside a start_sequence, make the outer-level insn chain current, so
4115      the code is placed at the start of the function.  */
4116   push_topmost_sequence ();
4117   emit_insn_after (seq, entry_of_function ());
4118   pop_topmost_sequence ();
4119
4120   return val;
4121 }
4122
4123 /* __builtin_args_info (N) returns word N of the arg space info
4124    for the current function.  The number and meanings of words
4125    is controlled by the definition of CUMULATIVE_ARGS.  */
4126
4127 static rtx
4128 expand_builtin_args_info (tree arglist)
4129 {
4130   int nwords = sizeof (CUMULATIVE_ARGS) / sizeof (int);
4131   int *word_ptr = (int *) &current_function_args_info;
4132
4133   if (sizeof (CUMULATIVE_ARGS) % sizeof (int) != 0)
4134     abort ();
4135
4136   if (arglist != 0)
4137     {
4138       if (!host_integerp (TREE_VALUE (arglist), 0))
4139         error ("argument of `__builtin_args_info' must be constant");
4140       else
4141         {
4142           HOST_WIDE_INT wordnum = tree_low_cst (TREE_VALUE (arglist), 0);
4143
4144           if (wordnum < 0 || wordnum >= nwords)
4145             error ("argument of `__builtin_args_info' out of range");
4146           else
4147             return GEN_INT (word_ptr[wordnum]);
4148         }
4149     }
4150   else
4151     error ("missing argument in `__builtin_args_info'");
4152
4153   return const0_rtx;
4154 }
4155
4156 /* Expand ARGLIST, from a call to __builtin_next_arg.  */
4157
4158 static rtx
4159 expand_builtin_next_arg (tree arglist)
4160 {
4161   tree fntype = TREE_TYPE (current_function_decl);
4162
4163   if (TYPE_ARG_TYPES (fntype) == 0
4164       || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
4165           == void_type_node))
4166     {
4167       error ("`va_start' used in function with fixed args");
4168       return const0_rtx;
4169     }
4170
4171   if (arglist)
4172     {
4173       tree last_parm = tree_last (DECL_ARGUMENTS (current_function_decl));
4174       tree arg = TREE_VALUE (arglist);
4175
4176       /* Strip off all nops for the sake of the comparison.  This
4177          is not quite the same as STRIP_NOPS.  It does more.
4178          We must also strip off INDIRECT_EXPR for C++ reference
4179          parameters.  */
4180       while (TREE_CODE (arg) == NOP_EXPR
4181              || TREE_CODE (arg) == CONVERT_EXPR
4182              || TREE_CODE (arg) == NON_LVALUE_EXPR
4183              || TREE_CODE (arg) == INDIRECT_REF)
4184         arg = TREE_OPERAND (arg, 0);
4185       if (arg != last_parm)
4186         warning ("second parameter of `va_start' not last named argument");
4187     }
4188   else
4189     /* Evidently an out of date version of <stdarg.h>; can't validate
4190        va_start's second argument, but can still work as intended.  */
4191     warning ("`__builtin_next_arg' called without an argument");
4192
4193   return expand_binop (Pmode, add_optab,
4194                        current_function_internal_arg_pointer,
4195                        current_function_arg_offset_rtx,
4196                        NULL_RTX, 0, OPTAB_LIB_WIDEN);
4197 }
4198
4199 /* Make it easier for the backends by protecting the valist argument
4200    from multiple evaluations.  */
4201
4202 static tree
4203 stabilize_va_list (tree valist, int needs_lvalue)
4204 {
4205   if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
4206     {
4207       if (TREE_SIDE_EFFECTS (valist))
4208         valist = save_expr (valist);
4209
4210       /* For this case, the backends will be expecting a pointer to
4211          TREE_TYPE (va_list_type_node), but it's possible we've
4212          actually been given an array (an actual va_list_type_node).
4213          So fix it.  */
4214       if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
4215         {
4216           tree p1 = build_pointer_type (TREE_TYPE (va_list_type_node));
4217           valist = build_fold_addr_expr_with_type (valist, p1);
4218         }
4219     }
4220   else
4221     {
4222       tree pt;
4223
4224       if (! needs_lvalue)
4225         {
4226           if (! TREE_SIDE_EFFECTS (valist))
4227             return valist;
4228
4229           pt = build_pointer_type (va_list_type_node);
4230           valist = fold (build1 (ADDR_EXPR, pt, valist));
4231           TREE_SIDE_EFFECTS (valist) = 1;
4232         }
4233
4234       if (TREE_SIDE_EFFECTS (valist))
4235         valist = save_expr (valist);
4236       valist = build_fold_indirect_ref (valist);
4237     }
4238
4239   return valist;
4240 }
4241
4242 /* The "standard" definition of va_list is void*.  */
4243
4244 tree
4245 std_build_builtin_va_list (void)
4246 {
4247   return ptr_type_node;
4248 }
4249
4250 /* The "standard" implementation of va_start: just assign `nextarg' to
4251    the variable.  */
4252
4253 void
4254 std_expand_builtin_va_start (tree valist, rtx nextarg)
4255 {
4256   tree t;
4257
4258   t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist,
4259               make_tree (ptr_type_node, nextarg));
4260   TREE_SIDE_EFFECTS (t) = 1;
4261
4262   expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4263 }
4264
4265 /* Expand ARGLIST, from a call to __builtin_va_start.  */
4266
4267 static rtx
4268 expand_builtin_va_start (tree arglist)
4269 {
4270   rtx nextarg;
4271   tree chain, valist;
4272
4273   chain = TREE_CHAIN (arglist);
4274
4275   if (TREE_CHAIN (chain))
4276     error ("too many arguments to function `va_start'");
4277
4278   nextarg = expand_builtin_next_arg (chain);
4279   valist = stabilize_va_list (TREE_VALUE (arglist), 1);
4280
4281 #ifdef EXPAND_BUILTIN_VA_START
4282   EXPAND_BUILTIN_VA_START (valist, nextarg);
4283 #else
4284   std_expand_builtin_va_start (valist, nextarg);
4285 #endif
4286
4287   return const0_rtx;
4288 }
4289
4290 /* The "standard" implementation of va_arg: read the value from the
4291    current (padded) address and increment by the (padded) size.  */
4292
4293 rtx
4294 std_expand_builtin_va_arg (tree valist, tree type)
4295 {
4296   tree addr_tree, t, type_size = NULL;
4297   tree align, alignm1;
4298   tree rounded_size;
4299   rtx addr;
4300   HOST_WIDE_INT boundary;
4301
4302   /* Compute the rounded size of the type.  */
4303   align = size_int (PARM_BOUNDARY / BITS_PER_UNIT);
4304   alignm1 = size_int (PARM_BOUNDARY / BITS_PER_UNIT - 1);
4305   boundary = FUNCTION_ARG_BOUNDARY (TYPE_MODE (type), type);
4306
4307   /* va_list pointer is aligned to PARM_BOUNDARY.  If argument actually
4308      requires greater alignment, we must perform dynamic alignment.  */
4309
4310   if (boundary > PARM_BOUNDARY)
4311     {
4312       if (!PAD_VARARGS_DOWN)
4313         {
4314           t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist,
4315                       build2 (PLUS_EXPR, TREE_TYPE (valist), valist,
4316                               build_int_2 (boundary / BITS_PER_UNIT - 1, 0)));
4317           TREE_SIDE_EFFECTS (t) = 1;
4318           expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4319         }
4320       t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist,
4321                   build2 (BIT_AND_EXPR, TREE_TYPE (valist), valist,
4322                           build_int_2 (~(boundary / BITS_PER_UNIT - 1), -1)));
4323       TREE_SIDE_EFFECTS (t) = 1;
4324       expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4325     }
4326   if (type == error_mark_node
4327       || (type_size = TYPE_SIZE_UNIT (TYPE_MAIN_VARIANT (type))) == NULL
4328       || TREE_OVERFLOW (type_size))
4329     rounded_size = size_zero_node;
4330   else
4331     {
4332       rounded_size = fold (build2 (PLUS_EXPR, sizetype, type_size, alignm1));
4333       rounded_size = fold (build2 (TRUNC_DIV_EXPR, sizetype,
4334                                    rounded_size, align));
4335       rounded_size = fold (build2 (MULT_EXPR, sizetype,
4336                                    rounded_size, align));
4337     }
4338
4339   /* Get AP.  */
4340   addr_tree = valist;
4341   if (PAD_VARARGS_DOWN && ! integer_zerop (rounded_size))
4342     {
4343       /* Small args are padded downward.  */
4344       addr_tree = fold (build2 (PLUS_EXPR, TREE_TYPE (addr_tree), addr_tree,
4345                                 fold (build3 (COND_EXPR, sizetype,
4346                                               fold (build2 (GT_EXPR, sizetype,
4347                                                             rounded_size,
4348                                                             align)),
4349                                               size_zero_node,
4350                                               fold (build2 (MINUS_EXPR,
4351                                                             sizetype,
4352                                                             rounded_size,
4353                                                             type_size))))));
4354     }
4355
4356   addr = expand_expr (addr_tree, NULL_RTX, Pmode, EXPAND_NORMAL);
4357   addr = copy_to_reg (addr);
4358
4359   /* Compute new value for AP.  */
4360   if (! integer_zerop (rounded_size))
4361     {
4362       t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist,
4363                   build2 (PLUS_EXPR, TREE_TYPE (valist), valist,
4364                           rounded_size));
4365       TREE_SIDE_EFFECTS (t) = 1;
4366       expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4367     }
4368
4369   return addr;
4370 }
4371
4372 /* Expand __builtin_va_arg, which is not really a builtin function, but
4373    a very special sort of operator.  */
4374
4375 rtx
4376 expand_builtin_va_arg (tree valist, tree type)
4377 {
4378   rtx addr, result;
4379   tree promoted_type, want_va_type, have_va_type;
4380
4381   /* Verify that valist is of the proper type.  */
4382
4383   want_va_type = va_list_type_node;
4384   have_va_type = TREE_TYPE (valist);
4385   if (TREE_CODE (want_va_type) == ARRAY_TYPE)
4386     {
4387       /* If va_list is an array type, the argument may have decayed
4388          to a pointer type, e.g. by being passed to another function.
4389          In that case, unwrap both types so that we can compare the
4390          underlying records.  */
4391       if (TREE_CODE (have_va_type) == ARRAY_TYPE
4392           || TREE_CODE (have_va_type) == POINTER_TYPE)
4393         {
4394           want_va_type = TREE_TYPE (want_va_type);
4395           have_va_type = TREE_TYPE (have_va_type);
4396         }
4397     }
4398   if (TYPE_MAIN_VARIANT (want_va_type) != TYPE_MAIN_VARIANT (have_va_type))
4399     {
4400       error ("first argument to `va_arg' not of type `va_list'");
4401       addr = const0_rtx;
4402     }
4403
4404   /* Generate a diagnostic for requesting data of a type that cannot
4405      be passed through `...' due to type promotion at the call site.  */
4406   else if ((promoted_type = lang_hooks.types.type_promotes_to (type))
4407            != type)
4408     {
4409       const char *name = "<anonymous type>", *pname = 0;
4410       static bool gave_help;
4411
4412       if (TYPE_NAME (type))
4413         {
4414           if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE)
4415             name = IDENTIFIER_POINTER (TYPE_NAME (type));
4416           else if (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
4417                    && DECL_NAME (TYPE_NAME (type)))
4418             name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type)));
4419         }
4420       if (TYPE_NAME (promoted_type))
4421         {
4422           if (TREE_CODE (TYPE_NAME (promoted_type)) == IDENTIFIER_NODE)
4423             pname = IDENTIFIER_POINTER (TYPE_NAME (promoted_type));
4424           else if (TREE_CODE (TYPE_NAME (promoted_type)) == TYPE_DECL
4425                    && DECL_NAME (TYPE_NAME (promoted_type)))
4426             pname = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (promoted_type)));
4427         }
4428
4429       /* Unfortunately, this is merely undefined, rather than a constraint
4430          violation, so we cannot make this an error.  If this call is never
4431          executed, the program is still strictly conforming.  */
4432       warning ("`%s' is promoted to `%s' when passed through `...'",
4433                name, pname);
4434       if (! gave_help)
4435         {
4436           gave_help = true;
4437           warning ("(so you should pass `%s' not `%s' to `va_arg')",
4438                    pname, name);
4439         }
4440
4441       /* We can, however, treat "undefined" any way we please.
4442          Call abort to encourage the user to fix the program.  */
4443       inform ("if this code is reached, the program will abort");
4444       expand_builtin_trap ();
4445
4446       /* This is dead code, but go ahead and finish so that the
4447          mode of the result comes out right.  */
4448       addr = const0_rtx;
4449     }
4450   else
4451     {
4452       /* Make it easier for the backends by protecting the valist argument
4453          from multiple evaluations.  */
4454       valist = stabilize_va_list (valist, 0);
4455
4456 #ifdef EXPAND_BUILTIN_VA_ARG
4457       addr = EXPAND_BUILTIN_VA_ARG (valist, type);
4458 #else
4459       addr = std_expand_builtin_va_arg (valist, type);
4460 #endif
4461     }
4462
4463   addr = convert_memory_address (Pmode, addr);
4464
4465   result = gen_rtx_MEM (TYPE_MODE (type), addr);
4466   set_mem_alias_set (result, get_varargs_alias_set ());
4467
4468   return result;
4469 }
4470
4471 /* Like std_expand_builtin_va_arg, but gimplify instead of expanding.  */
4472
4473 tree
4474 std_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p, tree *post_p)
4475 {
4476   tree addr, t, type_size = NULL;
4477   tree align, alignm1, malign;
4478   tree rounded_size;
4479   tree valist_tmp;
4480   HOST_WIDE_INT boundary;
4481
4482   /* Compute the rounded size of the type.  */
4483   align = size_int (PARM_BOUNDARY / BITS_PER_UNIT);
4484   alignm1 = size_int (PARM_BOUNDARY / BITS_PER_UNIT - 1);
4485   malign = size_int (-(PARM_BOUNDARY / BITS_PER_UNIT));
4486   boundary = FUNCTION_ARG_BOUNDARY (TYPE_MODE (type), type);
4487
4488   valist_tmp = get_initialized_tmp_var (valist, pre_p, NULL);
4489
4490   /* va_list pointer is aligned to PARM_BOUNDARY.  If argument actually
4491      requires greater alignment, we must perform dynamic alignment.  */
4492
4493   if (boundary > PARM_BOUNDARY)
4494     {
4495       if (!PAD_VARARGS_DOWN)
4496         {
4497           t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
4498                       build2 (PLUS_EXPR, TREE_TYPE (valist), valist_tmp,
4499                               build_int_2 (boundary / BITS_PER_UNIT - 1, 0)));
4500           gimplify_and_add (t, pre_p);
4501         }
4502       t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
4503                   build2 (BIT_AND_EXPR, TREE_TYPE (valist), valist_tmp,
4504                           build_int_2 (~(boundary / BITS_PER_UNIT - 1), -1)));
4505       gimplify_and_add (t, pre_p);
4506     }
4507   if (type == error_mark_node
4508       || (type_size = TYPE_SIZE_UNIT (TYPE_MAIN_VARIANT (type))) == NULL
4509       || TREE_OVERFLOW (type_size))
4510     rounded_size = size_zero_node;
4511   else
4512     {
4513       rounded_size = fold (build2 (PLUS_EXPR, sizetype, type_size, alignm1));
4514       rounded_size = fold (build2 (BIT_AND_EXPR, sizetype,
4515                                    rounded_size, malign));
4516     }
4517
4518   /* Reduce rounded_size so it's sharable with the postqueue.  */
4519   gimplify_expr (&rounded_size, pre_p, post_p, is_gimple_val, fb_rvalue);
4520
4521   /* Get AP.  */
4522   addr = valist_tmp;
4523   if (PAD_VARARGS_DOWN && ! integer_zerop (rounded_size))
4524     {
4525       /* Small args are padded downward.  */
4526       addr = fold (build2 (PLUS_EXPR, TREE_TYPE (addr), addr,
4527                                 fold (build3 (COND_EXPR, sizetype,
4528                                               fold (build2 (GT_EXPR, sizetype,
4529                                                             rounded_size,
4530                                                             align)),
4531                                               size_zero_node,
4532                                               fold (build2 (MINUS_EXPR,
4533                                                             sizetype,
4534                                                             rounded_size,
4535                                                             type_size))))));
4536     }
4537
4538   /* Compute new value for AP.  */
4539   t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist,
4540               fold (build2 (PLUS_EXPR, TREE_TYPE (valist),
4541                             valist_tmp, rounded_size)));
4542   gimplify_and_add (t, pre_p);
4543
4544   addr = fold_convert (build_pointer_type (type), addr);
4545   return build_fold_indirect_ref (addr);
4546 }
4547
4548 /* Like std_gimplify_va_arg_expr, but uses pass-by-reference.  */
4549  
4550 tree
4551 ind_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p, tree *post_p)
4552 {
4553   tree t;
4554   t = build_pointer_type (type);
4555   t = std_gimplify_va_arg_expr (valist, t, pre_p, post_p);
4556   return build_fold_indirect_ref (t);
4557 }
4558
4559 /* Return a dummy expression of type TYPE in order to keep going after an
4560    error.  */
4561
4562 static tree
4563 dummy_object (tree type)
4564 {
4565   tree t = convert (build_pointer_type (type), null_pointer_node);
4566   return build1 (INDIRECT_REF, type, t);
4567 }
4568
4569 /* Like expand_builtin_va_arg, but gimplify instead of expanding.  */
4570
4571 enum gimplify_status
4572 gimplify_va_arg_expr (tree *expr_p, tree *pre_p, tree *post_p)
4573 {
4574   tree promoted_type, want_va_type, have_va_type;
4575   tree valist = TREE_OPERAND (*expr_p, 0);
4576   tree type = TREE_TYPE (*expr_p);
4577   tree t;
4578
4579   /* Verify that valist is of the proper type.  */
4580   want_va_type = va_list_type_node;
4581   have_va_type = TREE_TYPE (valist);
4582
4583   if (have_va_type == error_mark_node)
4584     return GS_ERROR;
4585
4586   if (TREE_CODE (want_va_type) == ARRAY_TYPE)
4587     {
4588       /* If va_list is an array type, the argument may have decayed
4589          to a pointer type, e.g. by being passed to another function.
4590          In that case, unwrap both types so that we can compare the
4591          underlying records.  */
4592       if (TREE_CODE (have_va_type) == ARRAY_TYPE
4593           || TREE_CODE (have_va_type) == POINTER_TYPE)
4594         {
4595           want_va_type = TREE_TYPE (want_va_type);
4596           have_va_type = TREE_TYPE (have_va_type);
4597         }
4598     }
4599
4600   if (TYPE_MAIN_VARIANT (want_va_type) != TYPE_MAIN_VARIANT (have_va_type))
4601     {
4602       error ("first argument to `va_arg' not of type `va_list'");
4603       return GS_ERROR;
4604     }
4605
4606   /* Generate a diagnostic for requesting data of a type that cannot
4607      be passed through `...' due to type promotion at the call site.  */
4608   else if ((promoted_type = lang_hooks.types.type_promotes_to (type))
4609            != type)
4610     {
4611       static bool gave_help;
4612
4613       /* Unfortunately, this is merely undefined, rather than a constraint
4614          violation, so we cannot make this an error.  If this call is never
4615          executed, the program is still strictly conforming.  */
4616       warning ("`%T' is promoted to `%T' when passed through `...'",
4617                type, promoted_type);
4618       if (! gave_help)
4619         {
4620           gave_help = true;
4621           warning ("(so you should pass `%T' not `%T' to `va_arg')",
4622                    promoted_type, type);
4623         }
4624
4625       /* We can, however, treat "undefined" any way we please.
4626          Call abort to encourage the user to fix the program.  */
4627       inform ("if this code is reached, the program will abort");
4628       t = build_function_call_expr (implicit_built_in_decls[BUILT_IN_TRAP],
4629                                     NULL);
4630       append_to_statement_list (t, pre_p);
4631
4632       /* This is dead code, but go ahead and finish so that the
4633          mode of the result comes out right.  */
4634       *expr_p = dummy_object (type);
4635       return GS_ALL_DONE;
4636     }
4637   else
4638     {
4639       /* Make it easier for the backends by protecting the valist argument
4640          from multiple evaluations.  */
4641       if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
4642         {
4643           /* For this case, the backends will be expecting a pointer to
4644              TREE_TYPE (va_list_type_node), but it's possible we've
4645              actually been given an array (an actual va_list_type_node).
4646              So fix it.  */
4647           if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
4648             {
4649               tree p1 = build_pointer_type (TREE_TYPE (va_list_type_node));
4650               valist = build_fold_addr_expr_with_type (valist, p1);
4651             }
4652           gimplify_expr (&valist, pre_p, post_p, is_gimple_val, fb_rvalue);
4653         }
4654       else
4655         gimplify_expr (&valist, pre_p, post_p, is_gimple_min_lval, fb_lvalue);
4656
4657       if (!targetm.calls.gimplify_va_arg_expr)
4658         /* Once most targets are converted this should abort.  */
4659         return GS_ALL_DONE;
4660
4661       *expr_p = targetm.calls.gimplify_va_arg_expr (valist, type, pre_p, post_p);
4662       return GS_OK;
4663     }
4664 }
4665
4666 /* Expand ARGLIST, from a call to __builtin_va_end.  */
4667
4668 static rtx
4669 expand_builtin_va_end (tree arglist)
4670 {
4671   tree valist = TREE_VALUE (arglist);
4672
4673   /* Evaluate for side effects, if needed.  I hate macros that don't
4674      do that.  */
4675   if (TREE_SIDE_EFFECTS (valist))
4676     expand_expr (valist, const0_rtx, VOIDmode, EXPAND_NORMAL);
4677
4678   return const0_rtx;
4679 }
4680
4681 /* Expand ARGLIST, from a call to __builtin_va_copy.  We do this as a
4682    builtin rather than just as an assignment in stdarg.h because of the
4683    nastiness of array-type va_list types.  */
4684
4685 static rtx
4686 expand_builtin_va_copy (tree arglist)
4687 {
4688   tree dst, src, t;
4689
4690   dst = TREE_VALUE (arglist);
4691   src = TREE_VALUE (TREE_CHAIN (arglist));
4692
4693   dst = stabilize_va_list (dst, 1);
4694   src = stabilize_va_list (src, 0);
4695
4696   if (TREE_CODE (va_list_type_node) != ARRAY_TYPE)
4697     {
4698       t = build2 (MODIFY_EXPR, va_list_type_node, dst, src);
4699       TREE_SIDE_EFFECTS (t) = 1;
4700       expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4701     }
4702   else
4703     {
4704       rtx dstb, srcb, size;
4705
4706       /* Evaluate to pointers.  */
4707       dstb = expand_expr (dst, NULL_RTX, Pmode, EXPAND_NORMAL);
4708       srcb = expand_expr (src, NULL_RTX, Pmode, EXPAND_NORMAL);
4709       size = expand_expr (TYPE_SIZE_UNIT (va_list_type_node), NULL_RTX,
4710                           VOIDmode, EXPAND_NORMAL);
4711
4712       dstb = convert_memory_address (Pmode, dstb);
4713       srcb = convert_memory_address (Pmode, srcb);
4714
4715       /* "Dereference" to BLKmode memories.  */
4716       dstb = gen_rtx_MEM (BLKmode, dstb);
4717       set_mem_alias_set (dstb, get_alias_set (TREE_TYPE (TREE_TYPE (dst))));
4718       set_mem_align (dstb, TYPE_ALIGN (va_list_type_node));
4719       srcb = gen_rtx_MEM (BLKmode, srcb);
4720       set_mem_alias_set (srcb, get_alias_set (TREE_TYPE (TREE_TYPE (src))));
4721       set_mem_align (srcb, TYPE_ALIGN (va_list_type_node));
4722
4723       /* Copy.  */
4724       emit_block_move (dstb, srcb, size, BLOCK_OP_NORMAL);
4725     }
4726
4727   return const0_rtx;
4728 }
4729
4730 /* Expand a call to one of the builtin functions __builtin_frame_address or
4731    __builtin_return_address.  */
4732
4733 static rtx
4734 expand_builtin_frame_address (tree fndecl, tree arglist)
4735 {
4736   /* The argument must be a nonnegative integer constant.
4737      It counts the number of frames to scan up the stack.
4738      The value is the return address saved in that frame.  */
4739   if (arglist == 0)
4740     /* Warning about missing arg was already issued.  */
4741     return const0_rtx;
4742   else if (! host_integerp (TREE_VALUE (arglist), 1))
4743     {
4744       if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4745         error ("invalid arg to `__builtin_frame_address'");
4746       else
4747         error ("invalid arg to `__builtin_return_address'");
4748       return const0_rtx;
4749     }
4750   else
4751     {
4752       rtx tem
4753         = expand_builtin_return_addr (DECL_FUNCTION_CODE (fndecl),
4754                                       tree_low_cst (TREE_VALUE (arglist), 1),
4755                                       hard_frame_pointer_rtx);
4756
4757       /* Some ports cannot access arbitrary stack frames.  */
4758       if (tem == NULL)
4759         {
4760           if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4761             warning ("unsupported arg to `__builtin_frame_address'");
4762           else
4763             warning ("unsupported arg to `__builtin_return_address'");
4764           return const0_rtx;
4765         }
4766
4767       /* For __builtin_frame_address, return what we've got.  */
4768       if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4769         return tem;
4770
4771       if (!REG_P (tem)
4772           && ! CONSTANT_P (tem))
4773         tem = copy_to_mode_reg (Pmode, tem);
4774       return tem;
4775     }
4776 }
4777
4778 /* Expand a call to the alloca builtin, with arguments ARGLIST.  Return 0 if
4779    we failed and the caller should emit a normal call, otherwise try to get
4780    the result in TARGET, if convenient.  */
4781
4782 static rtx
4783 expand_builtin_alloca (tree arglist, rtx target)
4784 {
4785   rtx op0;
4786   rtx result;
4787
4788   /* In -fmudflap-instrumented code, alloca() and __builtin_alloca()
4789      should always expand to function calls.  These can be intercepted
4790      in libmudflap.  */
4791   if (flag_mudflap)
4792     return 0;
4793
4794   if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
4795     return 0;
4796
4797   /* Compute the argument.  */
4798   op0 = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
4799
4800   /* Allocate the desired space.  */
4801   result = allocate_dynamic_stack_space (op0, target, BITS_PER_UNIT);
4802   result = convert_memory_address (ptr_mode, result);
4803
4804   return result;
4805 }
4806
4807 /* Expand a call to a unary builtin.  The arguments are in ARGLIST.
4808    Return 0 if a normal call should be emitted rather than expanding the
4809    function in-line.  If convenient, the result should be placed in TARGET.
4810    SUBTARGET may be used as the target for computing one of EXP's operands.  */
4811
4812 static rtx
4813 expand_builtin_unop (enum machine_mode target_mode, tree arglist, rtx target,
4814                      rtx subtarget, optab op_optab)
4815 {
4816   rtx op0;
4817   if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
4818     return 0;
4819
4820   /* Compute the argument.  */
4821   op0 = expand_expr (TREE_VALUE (arglist), subtarget, VOIDmode, 0);
4822   /* Compute op, into TARGET if possible.
4823      Set TARGET to wherever the result comes back.  */
4824   target = expand_unop (TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist))),
4825                         op_optab, op0, target, 1);
4826   if (target == 0)
4827     abort ();
4828
4829   return convert_to_mode (target_mode, target, 0);
4830 }
4831
4832 /* If the string passed to fputs is a constant and is one character
4833    long, we attempt to transform this call into __builtin_fputc().  */
4834
4835 static rtx
4836 expand_builtin_fputs (tree arglist, rtx target, bool unlocked)
4837 {
4838   tree len, fn;
4839   tree fn_fputc = unlocked ? implicit_built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
4840     : implicit_built_in_decls[BUILT_IN_FPUTC];
4841   tree fn_fwrite = unlocked ? implicit_built_in_decls[BUILT_IN_FWRITE_UNLOCKED]
4842     : implicit_built_in_decls[BUILT_IN_FWRITE];
4843
4844   /* If the return value is used, or the replacement _DECL isn't
4845      initialized, don't do the transformation.  */
4846   if (target != const0_rtx || !fn_fputc || !fn_fwrite)
4847     return 0;
4848
4849   /* Verify the arguments in the original call.  */
4850   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4851     return 0;
4852
4853   /* Get the length of the string passed to fputs.  If the length
4854      can't be determined, punt.  */
4855   if (!(len = c_strlen (TREE_VALUE (arglist), 1))
4856       || TREE_CODE (len) != INTEGER_CST)
4857     return 0;
4858
4859   switch (compare_tree_int (len, 1))
4860     {
4861     case -1: /* length is 0, delete the call entirely .  */
4862       {
4863         /* Evaluate and ignore the argument in case it has
4864            side-effects.  */
4865         expand_expr (TREE_VALUE (TREE_CHAIN (arglist)), const0_rtx,
4866                      VOIDmode, EXPAND_NORMAL);
4867         return const0_rtx;
4868       }
4869     case 0: /* length is 1, call fputc.  */
4870       {
4871         const char *p = c_getstr (TREE_VALUE (arglist));
4872
4873         if (p != NULL)
4874           {
4875             /* New argument list transforming fputs(string, stream) to
4876                fputc(string[0], stream).  */
4877             arglist =
4878               build_tree_list (NULL_TREE, TREE_VALUE (TREE_CHAIN (arglist)));
4879             arglist =
4880               tree_cons (NULL_TREE, build_int_2 (p[0], 0), arglist);
4881             fn = fn_fputc;
4882             break;
4883           }
4884       }
4885       /* Fall through.  */
4886     case 1: /* length is greater than 1, call fwrite.  */
4887       {
4888         tree string_arg;
4889
4890         /* If optimizing for size keep fputs.  */
4891         if (optimize_size)
4892           return 0;
4893         string_arg = TREE_VALUE (arglist);
4894         /* New argument list transforming fputs(string, stream) to
4895            fwrite(string, 1, len, stream).  */
4896         arglist = build_tree_list (NULL_TREE, TREE_VALUE (TREE_CHAIN (arglist)));
4897         arglist = tree_cons (NULL_TREE, len, arglist);
4898         arglist = tree_cons (NULL_TREE, size_one_node, arglist);
4899         arglist = tree_cons (NULL_TREE, string_arg, arglist);
4900         fn = fn_fwrite;
4901         break;
4902       }
4903     default:
4904       abort ();
4905     }
4906
4907   return expand_expr (build_function_call_expr (fn, arglist),
4908                       const0_rtx, VOIDmode, EXPAND_NORMAL);
4909 }
4910
4911 /* Expand a call to __builtin_expect.  We return our argument and emit a
4912    NOTE_INSN_EXPECTED_VALUE note.  This is the expansion of __builtin_expect in
4913    a non-jump context.  */
4914
4915 static rtx
4916 expand_builtin_expect (tree arglist, rtx target)
4917 {
4918   tree exp, c;
4919   rtx note, rtx_c;
4920
4921   if (arglist == NULL_TREE
4922       || TREE_CHAIN (arglist) == NULL_TREE)
4923     return const0_rtx;
4924   exp = TREE_VALUE (arglist);
4925   c = TREE_VALUE (TREE_CHAIN (arglist));
4926
4927   if (TREE_CODE (c) != INTEGER_CST)
4928     {
4929       error ("second arg to `__builtin_expect' must be a constant");
4930       c = integer_zero_node;
4931     }
4932
4933   target = expand_expr (exp, target, VOIDmode, EXPAND_NORMAL);
4934
4935   /* Don't bother with expected value notes for integral constants.  */
4936   if (flag_guess_branch_prob && GET_CODE (target) != CONST_INT)
4937     {
4938       /* We do need to force this into a register so that we can be
4939          moderately sure to be able to correctly interpret the branch
4940          condition later.  */
4941       target = force_reg (GET_MODE (target), target);
4942
4943       rtx_c = expand_expr (c, NULL_RTX, GET_MODE (target), EXPAND_NORMAL);
4944
4945       note = emit_note (NOTE_INSN_EXPECTED_VALUE);
4946       NOTE_EXPECTED_VALUE (note) = gen_rtx_EQ (VOIDmode, target, rtx_c);
4947     }
4948
4949   return target;
4950 }
4951
4952 /* Like expand_builtin_expect, except do this in a jump context.  This is
4953    called from do_jump if the conditional is a __builtin_expect.  Return either
4954    a list of insns to emit the jump or NULL if we cannot optimize
4955    __builtin_expect.  We need to optimize this at jump time so that machines
4956    like the PowerPC don't turn the test into a SCC operation, and then jump
4957    based on the test being 0/1.  */
4958
4959 rtx
4960 expand_builtin_expect_jump (tree exp, rtx if_false_label, rtx if_true_label)
4961 {
4962   tree arglist = TREE_OPERAND (exp, 1);
4963   tree arg0 = TREE_VALUE (arglist);
4964   tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
4965   rtx ret = NULL_RTX;
4966
4967   /* Only handle __builtin_expect (test, 0) and
4968      __builtin_expect (test, 1).  */
4969   if (TREE_CODE (TREE_TYPE (arg1)) == INTEGER_TYPE
4970       && (integer_zerop (arg1) || integer_onep (arg1)))
4971     {
4972       rtx insn, drop_through_label, temp;
4973
4974       /* Expand the jump insns.  */
4975       start_sequence ();
4976       do_jump (arg0, if_false_label, if_true_label);
4977       ret = get_insns ();
4978
4979       drop_through_label = get_last_insn ();
4980       if (drop_through_label && NOTE_P (drop_through_label))
4981         drop_through_label = prev_nonnote_insn (drop_through_label);
4982       if (drop_through_label && !LABEL_P (drop_through_label))
4983         drop_through_label = NULL_RTX;
4984       end_sequence ();
4985
4986       if (! if_true_label)
4987         if_true_label = drop_through_label;
4988       if (! if_false_label)
4989         if_false_label = drop_through_label;
4990
4991       /* Go through and add the expect's to each of the conditional jumps.  */
4992       insn = ret;
4993       while (insn != NULL_RTX)
4994         {
4995           rtx next = NEXT_INSN (insn);
4996
4997           if (JUMP_P (insn) && any_condjump_p (insn))
4998             {
4999               rtx ifelse = SET_SRC (pc_set (insn));
5000               rtx then_dest = XEXP (ifelse, 1);
5001               rtx else_dest = XEXP (ifelse, 2);
5002               int taken = -1;
5003
5004               /* First check if we recognize any of the labels.  */
5005               if (GET_CODE (then_dest) == LABEL_REF
5006                   && XEXP (then_dest, 0) == if_true_label)
5007                 taken = 1;
5008               else if (GET_CODE (then_dest) == LABEL_REF
5009                        && XEXP (then_dest, 0) == if_false_label)
5010                 taken = 0;
5011               else if (GET_CODE (else_dest) == LABEL_REF
5012                        && XEXP (else_dest, 0) == if_false_label)
5013                 taken = 1;
5014               else if (GET_CODE (else_dest) == LABEL_REF
5015                        && XEXP (else_dest, 0) == if_true_label)
5016                 taken = 0;
5017               /* Otherwise check where we drop through.  */
5018               else if (else_dest == pc_rtx)
5019                 {
5020                   if (next && NOTE_P (next))
5021                     next = next_nonnote_insn (next);
5022
5023                   if (next && JUMP_P (next)
5024                       && any_uncondjump_p (next))
5025                     temp = XEXP (SET_SRC (pc_set (next)), 0);
5026                   else
5027                     temp = next;
5028
5029                   /* TEMP is either a CODE_LABEL, NULL_RTX or something
5030                      else that can't possibly match either target label.  */
5031                   if (temp == if_false_label)
5032                     taken = 1;
5033                   else if (temp == if_true_label)
5034                     taken = 0;
5035                 }
5036               else if (then_dest == pc_rtx)
5037                 {
5038                   if (next && NOTE_P (next))
5039                     next = next_nonnote_insn (next);
5040
5041                   if (next && JUMP_P (next)
5042                       && any_uncondjump_p (next))
5043                     temp = XEXP (SET_SRC (pc_set (next)), 0);
5044                   else
5045                     temp = next;
5046
5047                   if (temp == if_false_label)
5048                     taken = 0;
5049                   else if (temp == if_true_label)
5050                     taken = 1;
5051                 }
5052
5053               if (taken != -1)
5054                 {
5055                   /* If the test is expected to fail, reverse the
5056                      probabilities.  */
5057                   if (integer_zerop (arg1))
5058                     taken = 1 - taken;
5059                   predict_insn_def (insn, PRED_BUILTIN_EXPECT, taken);
5060                 }
5061             }
5062
5063           insn = next;
5064         }
5065     }
5066
5067   return ret;
5068 }
5069
5070 void
5071 expand_builtin_trap (void)
5072 {
5073 #ifdef HAVE_trap
5074   if (HAVE_trap)
5075     emit_insn (gen_trap ());
5076   else
5077 #endif
5078     emit_library_call (abort_libfunc, LCT_NORETURN, VOIDmode, 0);
5079   emit_barrier ();
5080 }
5081
5082 /* Expand a call to fabs, fabsf or fabsl with arguments ARGLIST.
5083    Return 0 if a normal call should be emitted rather than expanding
5084    the function inline.  If convenient, the result should be placed
5085    in TARGET.  SUBTARGET may be used as the target for computing
5086    the operand.  */
5087
5088 static rtx
5089 expand_builtin_fabs (tree arglist, rtx target, rtx subtarget)
5090 {
5091   enum machine_mode mode;
5092   tree arg;
5093   rtx op0;
5094
5095   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
5096     return 0;
5097
5098   arg = TREE_VALUE (arglist);
5099   mode = TYPE_MODE (TREE_TYPE (arg));
5100   op0 = expand_expr (arg, subtarget, VOIDmode, 0);
5101   return expand_abs (mode, op0, target, 0, safe_from_p (target, arg, 1));
5102 }
5103
5104 /* Expand a call to cabs, cabsf or cabsl with arguments ARGLIST.
5105    Return 0 if a normal call should be emitted rather than expanding
5106    the function inline.  If convenient, the result should be placed
5107    in target.  */
5108
5109 static rtx
5110 expand_builtin_cabs (tree arglist, rtx target)
5111 {
5112   enum machine_mode mode;
5113   tree arg;
5114   rtx op0;
5115
5116   if (arglist == 0 || TREE_CHAIN (arglist))
5117     return 0;
5118   arg = TREE_VALUE (arglist);
5119   if (TREE_CODE (TREE_TYPE (arg)) != COMPLEX_TYPE
5120       || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) != REAL_TYPE)
5121     return 0;
5122
5123   mode = TYPE_MODE (TREE_TYPE (arg));
5124   op0 = expand_expr (arg, NULL_RTX, VOIDmode, 0);
5125   return expand_complex_abs (mode, op0, target, 0);
5126 }
5127
5128 /* Create a new constant string literal and return a char* pointer to it.
5129    The STRING_CST value is the LEN characters at STR.  */
5130 static tree
5131 build_string_literal (int len, const char *str)
5132 {
5133   tree t, elem, index, type;
5134
5135   t = build_string (len, str);
5136   elem = build_type_variant (char_type_node, 1, 0);
5137   index = build_index_type (build_int_2 (len - 1, 0));
5138   type = build_array_type (elem, index);
5139   TREE_TYPE (t) = type;
5140   TREE_CONSTANT (t) = 1;
5141   TREE_INVARIANT (t) = 1;
5142   TREE_READONLY (t) = 1;
5143   TREE_STATIC (t) = 1;
5144
5145   type = build_pointer_type (type);
5146   t = build1 (ADDR_EXPR, type, t);
5147
5148   type = build_pointer_type (elem);
5149   t = build1 (NOP_EXPR, type, t);
5150   return t;
5151 }
5152
5153 /* Expand a call to printf or printf_unlocked with argument list ARGLIST.
5154    Return 0 if a normal call should be emitted rather than transforming
5155    the function inline.  If convenient, the result should be placed in
5156    TARGET with mode MODE.  UNLOCKED indicates this is a printf_unlocked
5157    call.  */
5158 static rtx
5159 expand_builtin_printf (tree arglist, rtx target, enum machine_mode mode,
5160                        bool unlocked)
5161 {
5162   tree fn_putchar = unlocked
5163                     ? implicit_built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED]
5164                     : implicit_built_in_decls[BUILT_IN_PUTCHAR];
5165   tree fn_puts = unlocked ? implicit_built_in_decls[BUILT_IN_PUTS_UNLOCKED]
5166                           : implicit_built_in_decls[BUILT_IN_PUTS];
5167   const char *fmt_str;
5168   tree fn, fmt, arg;
5169
5170   /* If the return value is used, don't do the transformation.  */
5171   if (target != const0_rtx)
5172     return 0;
5173
5174   /* Verify the required arguments in the original call.  */
5175   if (! arglist)
5176     return 0;
5177   fmt = TREE_VALUE (arglist);
5178   if (TREE_CODE (TREE_TYPE (fmt)) != POINTER_TYPE)
5179     return 0;
5180   arglist = TREE_CHAIN (arglist);
5181
5182   /* Check whether the format is a literal string constant.  */
5183   fmt_str = c_getstr (fmt);
5184   if (fmt_str == NULL)
5185     return 0;
5186
5187   /* If the format specifier was "%s\n", call __builtin_puts(arg).  */
5188   if (strcmp (fmt_str, "%s\n") == 0)
5189     {
5190       if (! arglist
5191           || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE
5192           || TREE_CHAIN (arglist))
5193         return 0;
5194       fn = fn_puts;
5195     }
5196   /* If the format specifier was "%c", call __builtin_putchar(arg).  */
5197   else if (strcmp (fmt_str, "%c") == 0)
5198     {
5199       if (! arglist
5200           || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
5201           || TREE_CHAIN (arglist))
5202         return 0;
5203       fn = fn_putchar;
5204     }
5205   else
5206     {
5207       /* We can't handle anything else with % args or %% ... yet.  */
5208       if (strchr (fmt_str, '%'))
5209         return 0;
5210
5211       if (arglist)
5212         return 0;
5213
5214       /* If the format specifier was "", printf does nothing.  */
5215       if (fmt_str[0] == '\0')
5216         return const0_rtx;
5217       /* If the format specifier has length of 1, call putchar.  */
5218       if (fmt_str[1] == '\0')
5219         {
5220           /* Given printf("c"), (where c is any one character,)
5221              convert "c"[0] to an int and pass that to the replacement
5222              function.  */
5223           arg = build_int_2 (fmt_str[0], 0);
5224           arglist = build_tree_list (NULL_TREE, arg);
5225           fn = fn_putchar;
5226         }
5227       else
5228         {
5229           /* If the format specifier was "string\n", call puts("string").  */
5230           size_t len = strlen (fmt_str);
5231           if (fmt_str[len - 1] == '\n')
5232             {
5233               /* Create a NUL-terminated string that's one char shorter
5234                  than the original, stripping off the trailing '\n'.  */
5235               char *newstr = alloca (len);
5236               memcpy (newstr, fmt_str, len - 1);
5237               newstr[len - 1] = 0;
5238
5239               arg = build_string_literal (len, newstr);
5240               arglist = build_tree_list (NULL_TREE, arg);
5241               fn = fn_puts;
5242             }
5243           else
5244             /* We'd like to arrange to call fputs(string,stdout) here,
5245                but we need stdout and don't have a way to get it yet.  */
5246             return 0;
5247         }
5248     }
5249
5250   if (!fn)
5251     return 0;
5252   return expand_expr (build_function_call_expr (fn, arglist),
5253                       target, mode, EXPAND_NORMAL);
5254 }
5255
5256 /* Expand a call to fprintf or fprintf_unlocked with argument list ARGLIST.
5257    Return 0 if a normal call should be emitted rather than transforming
5258    the function inline.  If convenient, the result should be placed in
5259    TARGET with mode MODE.  UNLOCKED indicates this is a fprintf_unlocked
5260    call.  */
5261 static rtx
5262 expand_builtin_fprintf (tree arglist, rtx target, enum machine_mode mode,
5263                         bool unlocked)
5264 {
5265   tree fn_fputc = unlocked ? implicit_built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
5266                            : implicit_built_in_decls[BUILT_IN_FPUTC];
5267   tree fn_fputs = unlocked ? implicit_built_in_decls[BUILT_IN_FPUTS_UNLOCKED]
5268                            : implicit_built_in_decls[BUILT_IN_FPUTS];
5269   const char *fmt_str;
5270   tree fn, fmt, fp, arg;
5271
5272   /* If the return value is used, don't do the transformation.  */
5273   if (target != const0_rtx)
5274     return 0;
5275
5276   /* Verify the required arguments in the original call.  */
5277   if (! arglist)
5278     return 0;
5279   fp = TREE_VALUE (arglist);
5280   if (TREE_CODE (TREE_TYPE (fp)) != POINTER_TYPE)
5281     return 0;
5282   arglist = TREE_CHAIN (arglist);
5283   if (! arglist)
5284     return 0;
5285   fmt = TREE_VALUE (arglist);
5286   if (TREE_CODE (TREE_TYPE (fmt)) != POINTER_TYPE)
5287     return 0;
5288   arglist = TREE_CHAIN (arglist);
5289
5290   /* Check whether the format is a literal string constant.  */
5291   fmt_str = c_getstr (fmt);
5292   if (fmt_str == NULL)
5293     return 0;
5294
5295   /* If the format specifier was "%s", call __builtin_fputs(arg,fp).  */
5296   if (strcmp (fmt_str, "%s") == 0)
5297     {
5298       if (! arglist
5299           || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE
5300           || TREE_CHAIN (arglist))
5301         return 0;
5302       arg = TREE_VALUE (arglist);
5303       arglist = build_tree_list (NULL_TREE, fp);
5304       arglist = tree_cons (NULL_TREE, arg, arglist);
5305       fn = fn_fputs;
5306     }
5307   /* If the format specifier was "%c", call __builtin_fputc(arg,fp).  */
5308   else if (strcmp (fmt_str, "%c") == 0)
5309     {
5310       if (! arglist
5311           || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
5312           || TREE_CHAIN (arglist))
5313         return 0;
5314       arg = TREE_VALUE (arglist);
5315       arglist = build_tree_list (NULL_TREE, fp);
5316       arglist = tree_cons (NULL_TREE, arg, arglist);
5317       fn = fn_fputc;
5318     }
5319   else
5320     {
5321       /* We can't handle anything else with % args or %% ... yet.  */
5322       if (strchr (fmt_str, '%'))
5323         return 0;
5324
5325       if (arglist)
5326         return 0;
5327
5328       /* If the format specifier was "", fprintf does nothing.  */
5329       if (fmt_str[0] == '\0')
5330         {
5331           /* Evaluate and ignore FILE* argument for side-effects.  */
5332           expand_expr (fp, const0_rtx, VOIDmode, EXPAND_NORMAL);
5333           return const0_rtx;
5334         }
5335
5336       /* When "string" doesn't contain %, replace all cases of
5337          fprintf(stream,string) with fputs(string,stream).  The fputs
5338          builtin will take care of special cases like length == 1.  */
5339       arglist = build_tree_list (NULL_TREE, fp);
5340       arglist = tree_cons (NULL_TREE, fmt, arglist);
5341       fn = fn_fputs;
5342     }
5343
5344   if (!fn)
5345     return 0;
5346   return expand_expr (build_function_call_expr (fn, arglist),
5347                       target, mode, EXPAND_NORMAL);
5348 }
5349
5350 /* Expand a call to sprintf with argument list ARGLIST.  Return 0 if
5351    a normal call should be emitted rather than expanding the function
5352    inline.  If convenient, the result should be placed in TARGET with
5353    mode MODE.  */
5354
5355 static rtx
5356 expand_builtin_sprintf (tree arglist, rtx target, enum machine_mode mode)
5357 {
5358   tree orig_arglist, dest, fmt;
5359   const char *fmt_str;
5360
5361   orig_arglist = arglist;
5362
5363   /* Verify the required arguments in the original call.  */
5364   if (! arglist)
5365     return 0;
5366   dest = TREE_VALUE (arglist);
5367   if (TREE_CODE (TREE_TYPE (dest)) != POINTER_TYPE)
5368     return 0;
5369   arglist = TREE_CHAIN (arglist);
5370   if (! arglist)
5371     return 0;
5372   fmt = TREE_VALUE (arglist);
5373   if (TREE_CODE (TREE_TYPE (fmt)) != POINTER_TYPE)
5374     return 0;
5375   arglist = TREE_CHAIN (arglist);
5376
5377   /* Check whether the format is a literal string constant.  */
5378   fmt_str = c_getstr (fmt);
5379   if (fmt_str == NULL)
5380     return 0;
5381
5382   /* If the format doesn't contain % args or %%, use strcpy.  */
5383   if (strchr (fmt_str, '%') == 0)
5384     {
5385       tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
5386       tree exp;
5387
5388       if (arglist || ! fn)
5389         return 0;
5390       expand_expr (build_function_call_expr (fn, orig_arglist),
5391                    const0_rtx, VOIDmode, EXPAND_NORMAL);
5392       if (target == const0_rtx)
5393         return const0_rtx;
5394       exp = build_int_2 (strlen (fmt_str), 0);
5395       exp = fold_convert (integer_type_node, exp);
5396       return expand_expr (exp, target, mode, EXPAND_NORMAL);
5397     }
5398   /* If the format is "%s", use strcpy if the result isn't used.  */
5399   else if (strcmp (fmt_str, "%s") == 0)
5400     {
5401       tree fn, arg, len;
5402       fn = implicit_built_in_decls[BUILT_IN_STRCPY];
5403
5404       if (! fn)
5405         return 0;
5406
5407       if (! arglist || TREE_CHAIN (arglist))
5408         return 0;
5409       arg = TREE_VALUE (arglist);
5410       if (TREE_CODE (TREE_TYPE (arg)) != POINTER_TYPE)
5411         return 0;
5412
5413       if (target != const0_rtx)
5414         {
5415           len = c_strlen (arg, 1);
5416           if (! len || TREE_CODE (len) != INTEGER_CST)
5417             return 0;
5418         }
5419       else
5420         len = NULL_TREE;
5421
5422       arglist = build_tree_list (NULL_TREE, arg);
5423       arglist = tree_cons (NULL_TREE, dest, arglist);
5424       expand_expr (build_function_call_expr (fn, arglist),
5425                    const0_rtx, VOIDmode, EXPAND_NORMAL);
5426
5427       if (target == const0_rtx)
5428         return const0_rtx;
5429       return expand_expr (len, target, mode, EXPAND_NORMAL);
5430     }
5431
5432   return 0;
5433 }
5434
5435 /* Expand a call to either the entry or exit function profiler.  */
5436
5437 static rtx
5438 expand_builtin_profile_func (bool exitp)
5439 {
5440   rtx this, which;
5441
5442   this = DECL_RTL (current_function_decl);
5443   if (MEM_P (this))
5444     this = XEXP (this, 0);
5445   else
5446     abort ();
5447
5448   if (exitp)
5449     which = profile_function_exit_libfunc;
5450   else
5451     which = profile_function_entry_libfunc;
5452
5453   emit_library_call (which, LCT_NORMAL, VOIDmode, 2, this, Pmode,
5454                      expand_builtin_return_addr (BUILT_IN_RETURN_ADDRESS,
5455                                                  0, hard_frame_pointer_rtx),
5456                      Pmode);
5457
5458   return const0_rtx;
5459 }
5460
5461 /* Given a trampoline address, make sure it satisfies TRAMPOLINE_ALIGNMENT.  */
5462
5463 static rtx
5464 round_trampoline_addr (rtx tramp)
5465 {
5466   rtx temp, addend, mask;
5467
5468   /* If we don't need too much alignment, we'll have been guaranteed
5469      proper alignment by get_trampoline_type.  */
5470   if (TRAMPOLINE_ALIGNMENT <= STACK_BOUNDARY)
5471     return tramp;
5472
5473   /* Round address up to desired boundary.  */
5474   temp = gen_reg_rtx (Pmode);
5475   addend = GEN_INT (TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT - 1);
5476   mask = GEN_INT (-TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT);
5477
5478   temp  = expand_simple_binop (Pmode, PLUS, tramp, addend,
5479                                temp, 0, OPTAB_LIB_WIDEN);
5480   tramp = expand_simple_binop (Pmode, AND, temp, mask,
5481                                temp, 0, OPTAB_LIB_WIDEN);
5482
5483   return tramp;
5484 }
5485
5486 static rtx
5487 expand_builtin_init_trampoline (tree arglist)
5488 {
5489   tree t_tramp, t_func, t_chain;
5490   rtx r_tramp, r_func, r_chain;
5491 #ifdef TRAMPOLINE_TEMPLATE
5492   rtx blktramp;
5493 #endif
5494
5495   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE,
5496                          POINTER_TYPE, VOID_TYPE))
5497     return NULL_RTX;
5498
5499   t_tramp = TREE_VALUE (arglist);
5500   arglist = TREE_CHAIN (arglist);
5501   t_func = TREE_VALUE (arglist);
5502   arglist = TREE_CHAIN (arglist);
5503   t_chain = TREE_VALUE (arglist);
5504
5505   r_tramp = expand_expr (t_tramp, NULL_RTX, VOIDmode, 0);
5506   r_func = expand_expr (t_func, NULL_RTX, VOIDmode, 0);
5507   r_chain = expand_expr (t_chain, NULL_RTX, VOIDmode, 0);
5508
5509   /* Generate insns to initialize the trampoline.  */
5510   r_tramp = round_trampoline_addr (r_tramp);
5511 #ifdef TRAMPOLINE_TEMPLATE
5512   blktramp = gen_rtx_MEM (BLKmode, r_tramp);
5513   set_mem_align (blktramp, TRAMPOLINE_ALIGNMENT);
5514   emit_block_move (blktramp, assemble_trampoline_template (),
5515                    GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL);
5516 #endif
5517   trampolines_created = 1;
5518   INITIALIZE_TRAMPOLINE (r_tramp, r_func, r_chain);
5519
5520   return const0_rtx;
5521 }
5522
5523 static rtx
5524 expand_builtin_adjust_trampoline (tree arglist)
5525 {
5526   rtx tramp;
5527
5528   if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5529     return NULL_RTX;
5530
5531   tramp = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
5532   tramp = round_trampoline_addr (tramp);
5533 #ifdef TRAMPOLINE_ADJUST_ADDRESS
5534   TRAMPOLINE_ADJUST_ADDRESS (tramp);
5535 #endif
5536
5537   return tramp;
5538 }
5539
5540 /* Expand a call to the built-in signbit, signbitf or signbitl function.
5541    Return NULL_RTX if a normal call should be emitted rather than expanding
5542    the function in-line.  EXP is the expression that is a call to the builtin
5543    function; if convenient, the result should be placed in TARGET.  */
5544
5545 static rtx
5546 expand_builtin_signbit (tree exp, rtx target)
5547 {
5548   const struct real_format *fmt;
5549   enum machine_mode fmode, imode, rmode;
5550   HOST_WIDE_INT hi, lo;
5551   tree arg, arglist;
5552   int bitpos;
5553   rtx temp;
5554
5555   arglist = TREE_OPERAND (exp, 1);
5556   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
5557     return 0;
5558
5559   arg = TREE_VALUE (arglist);
5560   fmode = TYPE_MODE (TREE_TYPE (arg));
5561   rmode = TYPE_MODE (TREE_TYPE (exp));
5562   fmt = REAL_MODE_FORMAT (fmode);
5563
5564   /* For floating point formats without a sign bit, implement signbit
5565      as "ARG < 0.0".  */
5566   if (fmt->signbit < 0)
5567   {
5568     /* But we can't do this if the format supports signed zero.  */
5569     if (fmt->has_signed_zero && HONOR_SIGNED_ZEROS (fmode))
5570       return 0;
5571
5572     arg = fold (build2 (LT_EXPR, TREE_TYPE (exp), arg,
5573                         build_real (TREE_TYPE (arg), dconst0)));
5574     return expand_expr (arg, target, VOIDmode, EXPAND_NORMAL);
5575   }
5576
5577   imode = int_mode_for_mode (fmode);
5578   if (imode == BLKmode)
5579     return 0;
5580
5581   bitpos = fmt->signbit;
5582   /* Handle targets with different FP word orders.  */
5583   if (FLOAT_WORDS_BIG_ENDIAN != WORDS_BIG_ENDIAN)
5584     {
5585       int nwords = GET_MODE_BITSIZE (fmode) / BITS_PER_WORD;
5586       int word = nwords - (bitpos / BITS_PER_WORD) - 1;
5587       bitpos = word * BITS_PER_WORD + bitpos % BITS_PER_WORD;
5588     }
5589
5590   /* If the sign bit is not in the lowpart and the floating point format
5591      is wider than an integer, check that is twice the size of an integer
5592      so that we can use gen_highpart below.  */
5593   if (bitpos >= GET_MODE_BITSIZE (rmode)
5594       && GET_MODE_BITSIZE (imode) != 2 * GET_MODE_BITSIZE (rmode))
5595     return 0;
5596
5597   temp = expand_expr (arg, NULL_RTX, VOIDmode, 0);
5598   temp = gen_lowpart (imode, temp);
5599
5600   if (GET_MODE_BITSIZE (imode) > GET_MODE_BITSIZE (rmode))
5601     {
5602       if (BYTES_BIG_ENDIAN)
5603         bitpos = GET_MODE_BITSIZE (imode) - 1 - bitpos;
5604       temp = copy_to_mode_reg (imode, temp);
5605       temp = extract_bit_field (temp, 1, bitpos, 1,
5606                                 NULL_RTX, rmode, rmode,
5607                                 GET_MODE_SIZE (imode));
5608     }
5609   else
5610     {
5611       if (GET_MODE_BITSIZE (imode) < GET_MODE_BITSIZE (rmode))
5612         temp = gen_lowpart (rmode, temp);
5613       if (bitpos < HOST_BITS_PER_WIDE_INT)
5614         {
5615           hi = 0;
5616           lo = (HOST_WIDE_INT) 1 << bitpos;
5617         }
5618       else
5619         {
5620           hi = (HOST_WIDE_INT) 1 << (bitpos - HOST_BITS_PER_WIDE_INT);
5621           lo = 0;
5622         }
5623
5624       temp = force_reg (rmode, temp);
5625       temp = expand_binop (rmode, and_optab, temp,
5626                            immed_double_const (lo, hi, rmode),
5627                            target, 1, OPTAB_LIB_WIDEN);
5628     }
5629   return temp;
5630 }
5631
5632 /* Expand fork or exec calls.  TARGET is the desired target of the
5633    call.  ARGLIST is the list of arguments of the call.  FN is the
5634    identificator of the actual function.  IGNORE is nonzero if the
5635    value is to be ignored.  */
5636
5637 static rtx
5638 expand_builtin_fork_or_exec (tree fn, tree arglist, rtx target, int ignore)
5639 {
5640   tree id, decl;
5641   tree call;
5642
5643   /* If we are not profiling, just call the function.  */
5644   if (!profile_arc_flag)
5645     return NULL_RTX;
5646
5647   /* Otherwise call the wrapper.  This should be equivalent for the rest of
5648      compiler, so the code does not diverge, and the wrapper may run the
5649      code necessary for keeping the profiling sane.  */
5650
5651   switch (DECL_FUNCTION_CODE (fn))
5652     {
5653     case BUILT_IN_FORK:
5654       id = get_identifier ("__gcov_fork");
5655       break;
5656
5657     case BUILT_IN_EXECL:
5658       id = get_identifier ("__gcov_execl");
5659       break;
5660
5661     case BUILT_IN_EXECV:
5662       id = get_identifier ("__gcov_execv");
5663       break;
5664
5665     case BUILT_IN_EXECLP:
5666       id = get_identifier ("__gcov_execlp");
5667       break;
5668
5669     case BUILT_IN_EXECLE:
5670       id = get_identifier ("__gcov_execle");
5671       break;
5672
5673     case BUILT_IN_EXECVP:
5674       id = get_identifier ("__gcov_execvp");
5675       break;
5676
5677     case BUILT_IN_EXECVE:
5678       id = get_identifier ("__gcov_execve");
5679       break;
5680
5681     default:
5682       abort ();
5683     }
5684
5685   decl = build_decl (FUNCTION_DECL, id, TREE_TYPE (fn));
5686   DECL_EXTERNAL (decl) = 1;
5687   TREE_PUBLIC (decl) = 1;
5688   DECL_ARTIFICIAL (decl) = 1;
5689   TREE_NOTHROW (decl) = 1;
5690   call = build_function_call_expr (decl, arglist);
5691
5692   return expand_call (call, target, ignore);
5693 }
5694 \f
5695 /* Expand an expression EXP that calls a built-in function,
5696    with result going to TARGET if that's convenient
5697    (and in mode MODE if that's convenient).
5698    SUBTARGET may be used as the target for computing one of EXP's operands.
5699    IGNORE is nonzero if the value is to be ignored.  */
5700
5701 rtx
5702 expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
5703                 int ignore)
5704 {
5705   tree fndecl = get_callee_fndecl (exp);
5706   tree arglist = TREE_OPERAND (exp, 1);
5707   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
5708   enum machine_mode target_mode = TYPE_MODE (TREE_TYPE (exp));
5709
5710   /* Perform postincrements before expanding builtin functions.  */
5711   emit_queue ();
5712
5713   if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
5714     return targetm.expand_builtin (exp, target, subtarget, mode, ignore);
5715
5716   /* When not optimizing, generate calls to library functions for a certain
5717      set of builtins.  */
5718   if (!optimize
5719       && !CALLED_AS_BUILT_IN (fndecl)
5720       && DECL_ASSEMBLER_NAME_SET_P (fndecl)
5721       && fcode != BUILT_IN_ALLOCA)
5722     return expand_call (exp, target, ignore);
5723
5724   /* The built-in function expanders test for target == const0_rtx
5725      to determine whether the function's result will be ignored.  */
5726   if (ignore)
5727     target = const0_rtx;
5728
5729   /* If the result of a pure or const built-in function is ignored, and
5730      none of its arguments are volatile, we can avoid expanding the
5731      built-in call and just evaluate the arguments for side-effects.  */
5732   if (target == const0_rtx
5733       && (DECL_IS_PURE (fndecl) || TREE_READONLY (fndecl)))
5734     {
5735       bool volatilep = false;
5736       tree arg;
5737
5738       for (arg = arglist; arg; arg = TREE_CHAIN (arg))
5739         if (TREE_THIS_VOLATILE (TREE_VALUE (arg)))
5740           {
5741             volatilep = true;
5742             break;
5743           }
5744
5745       if (! volatilep)
5746         {
5747           for (arg = arglist; arg; arg = TREE_CHAIN (arg))
5748             expand_expr (TREE_VALUE (arg), const0_rtx,
5749                          VOIDmode, EXPAND_NORMAL);
5750           return const0_rtx;
5751         }
5752     }
5753
5754   switch (fcode)
5755     {
5756     case BUILT_IN_FABS:
5757     case BUILT_IN_FABSF:
5758     case BUILT_IN_FABSL:
5759       target = expand_builtin_fabs (arglist, target, subtarget);
5760       if (target)
5761         return target;
5762       break;
5763
5764     case BUILT_IN_CABS:
5765     case BUILT_IN_CABSF:
5766     case BUILT_IN_CABSL:
5767       if (flag_unsafe_math_optimizations)
5768         {
5769           target = expand_builtin_cabs (arglist, target);
5770           if (target)
5771             return target;
5772         }
5773       break;
5774
5775     case BUILT_IN_EXP:
5776     case BUILT_IN_EXPF:
5777     case BUILT_IN_EXPL:
5778     case BUILT_IN_EXP10:
5779     case BUILT_IN_EXP10F:
5780     case BUILT_IN_EXP10L:
5781     case BUILT_IN_POW10:
5782     case BUILT_IN_POW10F:
5783     case BUILT_IN_POW10L:
5784     case BUILT_IN_EXP2:
5785     case BUILT_IN_EXP2F:
5786     case BUILT_IN_EXP2L:
5787     case BUILT_IN_EXPM1:
5788     case BUILT_IN_EXPM1F:
5789     case BUILT_IN_EXPM1L:
5790     case BUILT_IN_LOGB:
5791     case BUILT_IN_LOGBF:
5792     case BUILT_IN_LOGBL:
5793     case BUILT_IN_ILOGB:
5794     case BUILT_IN_ILOGBF:
5795     case BUILT_IN_ILOGBL:
5796     case BUILT_IN_LOG:
5797     case BUILT_IN_LOGF:
5798     case BUILT_IN_LOGL:
5799     case BUILT_IN_LOG10:
5800     case BUILT_IN_LOG10F:
5801     case BUILT_IN_LOG10L:
5802     case BUILT_IN_LOG2:
5803     case BUILT_IN_LOG2F:
5804     case BUILT_IN_LOG2L:
5805     case BUILT_IN_LOG1P:
5806     case BUILT_IN_LOG1PF:
5807     case BUILT_IN_LOG1PL:
5808     case BUILT_IN_TAN:
5809     case BUILT_IN_TANF:
5810     case BUILT_IN_TANL:
5811     case BUILT_IN_ASIN:
5812     case BUILT_IN_ASINF:
5813     case BUILT_IN_ASINL:
5814     case BUILT_IN_ACOS:
5815     case BUILT_IN_ACOSF:
5816     case BUILT_IN_ACOSL:
5817     case BUILT_IN_ATAN:
5818     case BUILT_IN_ATANF:
5819     case BUILT_IN_ATANL:
5820       /* Treat these like sqrt only if unsafe math optimizations are allowed,
5821          because of possible accuracy problems.  */
5822       if (! flag_unsafe_math_optimizations)
5823         break;
5824     case BUILT_IN_SQRT:
5825     case BUILT_IN_SQRTF:
5826     case BUILT_IN_SQRTL:
5827     case BUILT_IN_FLOOR:
5828     case BUILT_IN_FLOORF:
5829     case BUILT_IN_FLOORL:
5830     case BUILT_IN_CEIL:
5831     case BUILT_IN_CEILF:
5832     case BUILT_IN_CEILL:
5833     case BUILT_IN_TRUNC:
5834     case BUILT_IN_TRUNCF:
5835     case BUILT_IN_TRUNCL:
5836     case BUILT_IN_ROUND:
5837     case BUILT_IN_ROUNDF:
5838     case BUILT_IN_ROUNDL:
5839     case BUILT_IN_NEARBYINT:
5840     case BUILT_IN_NEARBYINTF:
5841     case BUILT_IN_NEARBYINTL:
5842       target = expand_builtin_mathfn (exp, target, subtarget);
5843       if (target)
5844         return target;
5845       break;
5846
5847     case BUILT_IN_POW:
5848     case BUILT_IN_POWF:
5849     case BUILT_IN_POWL:
5850       target = expand_builtin_pow (exp, target, subtarget);
5851       if (target)
5852         return target;
5853       break;
5854
5855     case BUILT_IN_ATAN2:
5856     case BUILT_IN_ATAN2F:
5857     case BUILT_IN_ATAN2L:
5858     case BUILT_IN_FMOD:
5859     case BUILT_IN_FMODF:
5860     case BUILT_IN_FMODL:
5861     case BUILT_IN_DREM:
5862     case BUILT_IN_DREMF:
5863     case BUILT_IN_DREML:
5864       if (! flag_unsafe_math_optimizations)
5865         break;
5866       target = expand_builtin_mathfn_2 (exp, target, subtarget);
5867       if (target)
5868         return target;
5869       break;
5870
5871     case BUILT_IN_SIN:
5872     case BUILT_IN_SINF:
5873     case BUILT_IN_SINL:
5874     case BUILT_IN_COS:
5875     case BUILT_IN_COSF:
5876     case BUILT_IN_COSL:
5877       if (! flag_unsafe_math_optimizations)
5878         break;
5879       target = expand_builtin_mathfn_3 (exp, target, subtarget);
5880       if (target)
5881         return target;
5882       break;
5883
5884     case BUILT_IN_APPLY_ARGS:
5885       return expand_builtin_apply_args ();
5886
5887       /* __builtin_apply (FUNCTION, ARGUMENTS, ARGSIZE) invokes
5888          FUNCTION with a copy of the parameters described by
5889          ARGUMENTS, and ARGSIZE.  It returns a block of memory
5890          allocated on the stack into which is stored all the registers
5891          that might possibly be used for returning the result of a
5892          function.  ARGUMENTS is the value returned by
5893          __builtin_apply_args.  ARGSIZE is the number of bytes of
5894          arguments that must be copied.  ??? How should this value be
5895          computed?  We'll also need a safe worst case value for varargs
5896          functions.  */
5897     case BUILT_IN_APPLY:
5898       if (!validate_arglist (arglist, POINTER_TYPE,
5899                              POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)
5900           && !validate_arglist (arglist, REFERENCE_TYPE,
5901                                 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
5902         return const0_rtx;
5903       else
5904         {
5905           int i;
5906           tree t;
5907           rtx ops[3];
5908
5909           for (t = arglist, i = 0; t; t = TREE_CHAIN (t), i++)
5910             ops[i] = expand_expr (TREE_VALUE (t), NULL_RTX, VOIDmode, 0);
5911
5912           return expand_builtin_apply (ops[0], ops[1], ops[2]);
5913         }
5914
5915       /* __builtin_return (RESULT) causes the function to return the
5916          value described by RESULT.  RESULT is address of the block of
5917          memory returned by __builtin_apply.  */
5918     case BUILT_IN_RETURN:
5919       if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5920         expand_builtin_return (expand_expr (TREE_VALUE (arglist),
5921                                             NULL_RTX, VOIDmode, 0));
5922       return const0_rtx;
5923
5924     case BUILT_IN_SAVEREGS:
5925       return expand_builtin_saveregs ();
5926
5927     case BUILT_IN_ARGS_INFO:
5928       return expand_builtin_args_info (arglist);
5929
5930       /* Return the address of the first anonymous stack arg.  */
5931     case BUILT_IN_NEXT_ARG:
5932       simplify_builtin_next_arg (arglist);
5933       return expand_builtin_next_arg (arglist);
5934
5935     case BUILT_IN_CLASSIFY_TYPE:
5936       return expand_builtin_classify_type (arglist);
5937
5938     case BUILT_IN_CONSTANT_P:
5939       return const0_rtx;
5940
5941     case BUILT_IN_FRAME_ADDRESS:
5942     case BUILT_IN_RETURN_ADDRESS:
5943       return expand_builtin_frame_address (fndecl, arglist);
5944
5945     /* Returns the address of the area where the structure is returned.
5946        0 otherwise.  */
5947     case BUILT_IN_AGGREGATE_INCOMING_ADDRESS:
5948       if (arglist != 0
5949           || ! AGGREGATE_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl)))
5950           || !MEM_P (DECL_RTL (DECL_RESULT (current_function_decl))))
5951         return const0_rtx;
5952       else
5953         return XEXP (DECL_RTL (DECL_RESULT (current_function_decl)), 0);
5954
5955     case BUILT_IN_ALLOCA:
5956       target = expand_builtin_alloca (arglist, target);
5957       if (target)
5958         return target;
5959       break;
5960
5961     case BUILT_IN_STACK_ALLOC:
5962       expand_stack_alloc (TREE_VALUE (arglist),
5963                           TREE_VALUE (TREE_CHAIN (arglist)));
5964       return const0_rtx;
5965
5966     case BUILT_IN_STACK_SAVE:
5967       return expand_stack_save ();
5968
5969     case BUILT_IN_STACK_RESTORE:
5970       expand_stack_restore (TREE_VALUE (arglist));
5971       return const0_rtx;
5972
5973     case BUILT_IN_FFS:
5974     case BUILT_IN_FFSL:
5975     case BUILT_IN_FFSLL:
5976     case BUILT_IN_FFSIMAX:
5977       target = expand_builtin_unop (target_mode, arglist, target,
5978                                     subtarget, ffs_optab);
5979       if (target)
5980         return target;
5981       break;
5982
5983     case BUILT_IN_CLZ:
5984     case BUILT_IN_CLZL:
5985     case BUILT_IN_CLZLL:
5986     case BUILT_IN_CLZIMAX:
5987       target = expand_builtin_unop (target_mode, arglist, target,
5988                                     subtarget, clz_optab);
5989       if (target)
5990         return target;
5991       break;
5992
5993     case BUILT_IN_CTZ:
5994     case BUILT_IN_CTZL:
5995     case BUILT_IN_CTZLL:
5996     case BUILT_IN_CTZIMAX:
5997       target = expand_builtin_unop (target_mode, arglist, target,
5998                                     subtarget, ctz_optab);
5999       if (target)
6000         return target;
6001       break;
6002
6003     case BUILT_IN_POPCOUNT:
6004     case BUILT_IN_POPCOUNTL:
6005     case BUILT_IN_POPCOUNTLL:
6006     case BUILT_IN_POPCOUNTIMAX:
6007       target = expand_builtin_unop (target_mode, arglist, target,
6008                                     subtarget, popcount_optab);
6009       if (target)
6010         return target;
6011       break;
6012
6013     case BUILT_IN_PARITY:
6014     case BUILT_IN_PARITYL:
6015     case BUILT_IN_PARITYLL:
6016     case BUILT_IN_PARITYIMAX:
6017       target = expand_builtin_unop (target_mode, arglist, target,
6018                                     subtarget, parity_optab);
6019       if (target)
6020         return target;
6021       break;
6022
6023     case BUILT_IN_STRLEN:
6024       target = expand_builtin_strlen (arglist, target, target_mode);
6025       if (target)
6026         return target;
6027       break;
6028
6029     case BUILT_IN_STRCPY:
6030       target = expand_builtin_strcpy (arglist, target, mode);
6031       if (target)
6032         return target;
6033       break;
6034
6035     case BUILT_IN_STRNCPY:
6036       target = expand_builtin_strncpy (arglist, target, mode);
6037       if (target)
6038         return target;
6039       break;
6040
6041     case BUILT_IN_STPCPY:
6042       target = expand_builtin_stpcpy (arglist, target, mode);
6043       if (target)
6044         return target;
6045       break;
6046
6047     case BUILT_IN_STRCAT:
6048       target = expand_builtin_strcat (arglist, target, mode);
6049       if (target)
6050         return target;
6051       break;
6052
6053     case BUILT_IN_STRNCAT:
6054       target = expand_builtin_strncat (arglist, target, mode);
6055       if (target)
6056         return target;
6057       break;
6058
6059     case BUILT_IN_STRSPN:
6060       target = expand_builtin_strspn (arglist, target, mode);
6061       if (target)
6062         return target;
6063       break;
6064
6065     case BUILT_IN_STRCSPN:
6066       target = expand_builtin_strcspn (arglist, target, mode);
6067       if (target)
6068         return target;
6069       break;
6070
6071     case BUILT_IN_STRSTR:
6072       target = expand_builtin_strstr (arglist, target, mode);
6073       if (target)
6074         return target;
6075       break;
6076
6077     case BUILT_IN_STRPBRK:
6078       target = expand_builtin_strpbrk (arglist, target, mode);
6079       if (target)
6080         return target;
6081       break;
6082
6083     case BUILT_IN_INDEX:
6084     case BUILT_IN_STRCHR:
6085       target = expand_builtin_strchr (arglist, target, mode);
6086       if (target)
6087         return target;
6088       break;
6089
6090     case BUILT_IN_RINDEX:
6091     case BUILT_IN_STRRCHR:
6092       target = expand_builtin_strrchr (arglist, target, mode);
6093       if (target)
6094         return target;
6095       break;
6096
6097     case BUILT_IN_MEMCPY:
6098       target = expand_builtin_memcpy (arglist, target, mode);
6099       if (target)
6100         return target;
6101       break;
6102
6103     case BUILT_IN_MEMPCPY:
6104       target = expand_builtin_mempcpy (arglist, target, mode, /*endp=*/ 1);
6105       if (target)
6106         return target;
6107       break;
6108
6109     case BUILT_IN_MEMMOVE:
6110       target = expand_builtin_memmove (arglist, target, mode);
6111       if (target)
6112         return target;
6113       break;
6114
6115     case BUILT_IN_BCOPY:
6116       target = expand_builtin_bcopy (arglist);
6117       if (target)
6118         return target;
6119       break;
6120
6121     case BUILT_IN_MEMSET:
6122       target = expand_builtin_memset (arglist, target, mode);
6123       if (target)
6124         return target;
6125       break;
6126
6127     case BUILT_IN_BZERO:
6128       target = expand_builtin_bzero (arglist);
6129       if (target)
6130         return target;
6131       break;
6132
6133     case BUILT_IN_STRCMP:
6134       target = expand_builtin_strcmp (exp, target, mode);
6135       if (target)
6136         return target;
6137       break;
6138
6139     case BUILT_IN_STRNCMP:
6140       target = expand_builtin_strncmp (exp, target, mode);
6141       if (target)
6142         return target;
6143       break;
6144
6145     case BUILT_IN_BCMP:
6146     case BUILT_IN_MEMCMP:
6147       target = expand_builtin_memcmp (exp, arglist, target, mode);
6148       if (target)
6149         return target;
6150       break;
6151
6152     case BUILT_IN_SETJMP:
6153       target = expand_builtin_setjmp (arglist, target);
6154       if (target)
6155         return target;
6156       break;
6157
6158       /* __builtin_longjmp is passed a pointer to an array of five words.
6159          It's similar to the C library longjmp function but works with
6160          __builtin_setjmp above.  */
6161     case BUILT_IN_LONGJMP:
6162       if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
6163         break;
6164       else
6165         {
6166           rtx buf_addr = expand_expr (TREE_VALUE (arglist), subtarget,
6167                                       VOIDmode, 0);
6168           rtx value = expand_expr (TREE_VALUE (TREE_CHAIN (arglist)),
6169                                    NULL_RTX, VOIDmode, 0);
6170
6171           if (value != const1_rtx)
6172             {
6173               error ("__builtin_longjmp second argument must be 1");
6174               return const0_rtx;
6175             }
6176
6177           expand_builtin_longjmp (buf_addr, value);
6178           return const0_rtx;
6179         }
6180
6181     case BUILT_IN_NONLOCAL_GOTO:
6182       target = expand_builtin_nonlocal_goto (arglist);
6183       if (target)
6184         return target;
6185       break;
6186
6187       /* This updates the setjmp buffer that is its argument with the value
6188          of the current stack pointer.  */
6189     case BUILT_IN_UPDATE_SETJMP_BUF:
6190       if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6191         {
6192           rtx buf_addr
6193             = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
6194
6195           expand_builtin_update_setjmp_buf (buf_addr);
6196           return const0_rtx;
6197         }
6198       break;
6199
6200     case BUILT_IN_TRAP:
6201       expand_builtin_trap ();
6202       return const0_rtx;
6203
6204     case BUILT_IN_PRINTF:
6205       target = expand_builtin_printf (arglist, target, mode, false);
6206       if (target)
6207         return target;
6208       break;
6209
6210     case BUILT_IN_PRINTF_UNLOCKED:
6211       target = expand_builtin_printf (arglist, target, mode, true);
6212       if (target)
6213         return target;
6214       break;
6215
6216     case BUILT_IN_FPUTS:
6217       target = expand_builtin_fputs (arglist, target, false);
6218       if (target)
6219         return target;
6220       break;
6221     case BUILT_IN_FPUTS_UNLOCKED:
6222       target = expand_builtin_fputs (arglist, target, true);
6223       if (target)
6224         return target;
6225       break;
6226
6227     case BUILT_IN_FPRINTF:
6228       target = expand_builtin_fprintf (arglist, target, mode, false);
6229       if (target)
6230         return target;
6231       break;
6232
6233     case BUILT_IN_FPRINTF_UNLOCKED:
6234       target = expand_builtin_fprintf (arglist, target, mode, true);
6235       if (target)
6236         return target;
6237       break;
6238
6239     case BUILT_IN_SPRINTF:
6240       target = expand_builtin_sprintf (arglist, target, mode);
6241       if (target)
6242         return target;
6243       break;
6244
6245     case BUILT_IN_SIGNBIT:
6246     case BUILT_IN_SIGNBITF:
6247     case BUILT_IN_SIGNBITL:
6248       target = expand_builtin_signbit (exp, target);
6249       if (target)
6250         return target;
6251       break;
6252
6253       /* Various hooks for the DWARF 2 __throw routine.  */
6254     case BUILT_IN_UNWIND_INIT:
6255       expand_builtin_unwind_init ();
6256       return const0_rtx;
6257     case BUILT_IN_DWARF_CFA:
6258       return virtual_cfa_rtx;
6259 #ifdef DWARF2_UNWIND_INFO
6260     case BUILT_IN_DWARF_SP_COLUMN:
6261       return expand_builtin_dwarf_sp_column ();
6262     case BUILT_IN_INIT_DWARF_REG_SIZES:
6263       expand_builtin_init_dwarf_reg_sizes (TREE_VALUE (arglist));
6264       return const0_rtx;
6265 #endif
6266     case BUILT_IN_FROB_RETURN_ADDR:
6267       return expand_builtin_frob_return_addr (TREE_VALUE (arglist));
6268     case BUILT_IN_EXTRACT_RETURN_ADDR:
6269       return expand_builtin_extract_return_addr (TREE_VALUE (arglist));
6270     case BUILT_IN_EH_RETURN:
6271       expand_builtin_eh_return (TREE_VALUE (arglist),
6272                                 TREE_VALUE (TREE_CHAIN (arglist)));
6273       return const0_rtx;
6274 #ifdef EH_RETURN_DATA_REGNO
6275     case BUILT_IN_EH_RETURN_DATA_REGNO:
6276       return expand_builtin_eh_return_data_regno (arglist);
6277 #endif
6278     case BUILT_IN_EXTEND_POINTER:
6279       return expand_builtin_extend_pointer (TREE_VALUE (arglist));
6280
6281     case BUILT_IN_VA_START:
6282     case BUILT_IN_STDARG_START:
6283       return expand_builtin_va_start (arglist);
6284     case BUILT_IN_VA_END:
6285       return expand_builtin_va_end (arglist);
6286     case BUILT_IN_VA_COPY:
6287       return expand_builtin_va_copy (arglist);
6288     case BUILT_IN_EXPECT:
6289       return expand_builtin_expect (arglist, target);
6290     case BUILT_IN_PREFETCH:
6291       expand_builtin_prefetch (arglist);
6292       return const0_rtx;
6293
6294     case BUILT_IN_PROFILE_FUNC_ENTER:
6295       return expand_builtin_profile_func (false);
6296     case BUILT_IN_PROFILE_FUNC_EXIT:
6297       return expand_builtin_profile_func (true);
6298
6299     case BUILT_IN_INIT_TRAMPOLINE:
6300       return expand_builtin_init_trampoline (arglist);
6301     case BUILT_IN_ADJUST_TRAMPOLINE:
6302       return expand_builtin_adjust_trampoline (arglist);
6303
6304     case BUILT_IN_FORK:
6305     case BUILT_IN_EXECL:
6306     case BUILT_IN_EXECV:
6307     case BUILT_IN_EXECLP:
6308     case BUILT_IN_EXECLE:
6309     case BUILT_IN_EXECVP:
6310     case BUILT_IN_EXECVE:
6311       target = expand_builtin_fork_or_exec (fndecl, arglist, target, ignore);
6312       if (target)
6313         return target;
6314       break;
6315
6316     default:    /* just do library call, if unknown builtin */
6317       break;
6318     }
6319
6320   /* The switch statement above can drop through to cause the function
6321      to be called normally.  */
6322   return expand_call (exp, target, ignore);
6323 }
6324
6325 /* Determine whether a tree node represents a call to a built-in
6326    function.  If the tree T is a call to a built-in function with
6327    the right number of arguments of the appropriate types, return
6328    the DECL_FUNCTION_CODE of the call, e.g. BUILT_IN_SQRT.
6329    Otherwise the return value is END_BUILTINS.  */
6330
6331 enum built_in_function
6332 builtin_mathfn_code (tree t)
6333 {
6334   tree fndecl, arglist, parmlist;
6335   tree argtype, parmtype;
6336
6337   if (TREE_CODE (t) != CALL_EXPR
6338       || TREE_CODE (TREE_OPERAND (t, 0)) != ADDR_EXPR)
6339     return END_BUILTINS;
6340
6341   fndecl = get_callee_fndecl (t);
6342   if (fndecl == NULL_TREE
6343       || TREE_CODE (fndecl) != FUNCTION_DECL
6344       || ! DECL_BUILT_IN (fndecl)
6345       || DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
6346     return END_BUILTINS;
6347
6348   arglist = TREE_OPERAND (t, 1);
6349   parmlist = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
6350   for (; parmlist; parmlist = TREE_CHAIN (parmlist))
6351     {
6352       /* If a function doesn't take a variable number of arguments,
6353          the last element in the list will have type `void'.  */
6354       parmtype = TREE_VALUE (parmlist);
6355       if (VOID_TYPE_P (parmtype))
6356         {
6357           if (arglist)
6358             return END_BUILTINS;
6359           return DECL_FUNCTION_CODE (fndecl);
6360         }
6361
6362       if (! arglist)
6363         return END_BUILTINS;
6364
6365       argtype = TREE_TYPE (TREE_VALUE (arglist));
6366
6367       if (SCALAR_FLOAT_TYPE_P (parmtype))
6368         {
6369           if (! SCALAR_FLOAT_TYPE_P (argtype))
6370             return END_BUILTINS;
6371         }
6372       else if (COMPLEX_FLOAT_TYPE_P (parmtype))
6373         {
6374           if (! COMPLEX_FLOAT_TYPE_P (argtype))
6375             return END_BUILTINS;
6376         }
6377       else if (POINTER_TYPE_P (parmtype))
6378         {
6379           if (! POINTER_TYPE_P (argtype))
6380             return END_BUILTINS;
6381         }
6382       else if (INTEGRAL_TYPE_P (parmtype))
6383         {
6384           if (! INTEGRAL_TYPE_P (argtype))
6385             return END_BUILTINS;
6386         }
6387       else
6388         return END_BUILTINS;
6389
6390       arglist = TREE_CHAIN (arglist);
6391     }
6392
6393   /* Variable-length argument list.  */
6394   return DECL_FUNCTION_CODE (fndecl);
6395 }
6396
6397 /* Fold a call to __builtin_constant_p, if we know it will evaluate to a
6398    constant.  ARGLIST is the argument list of the call.  */
6399
6400 static tree
6401 fold_builtin_constant_p (tree arglist)
6402 {
6403   if (arglist == 0)
6404     return 0;
6405
6406   arglist = TREE_VALUE (arglist);
6407
6408   /* We return 1 for a numeric type that's known to be a constant
6409      value at compile-time or for an aggregate type that's a
6410      literal constant.  */
6411   STRIP_NOPS (arglist);
6412
6413   /* If we know this is a constant, emit the constant of one.  */
6414   if (TREE_CODE_CLASS (TREE_CODE (arglist)) == 'c'
6415       || (TREE_CODE (arglist) == CONSTRUCTOR
6416           && TREE_CONSTANT (arglist))
6417       || (TREE_CODE (arglist) == ADDR_EXPR
6418           && TREE_CODE (TREE_OPERAND (arglist, 0)) == STRING_CST))
6419     return integer_one_node;
6420
6421   /* If this expression has side effects, show we don't know it to be a
6422      constant.  Likewise if it's a pointer or aggregate type since in
6423      those case we only want literals, since those are only optimized
6424      when generating RTL, not later.
6425      And finally, if we are compiling an initializer, not code, we
6426      need to return a definite result now; there's not going to be any
6427      more optimization done.  */
6428   if (TREE_SIDE_EFFECTS (arglist)
6429       || AGGREGATE_TYPE_P (TREE_TYPE (arglist))
6430       || POINTER_TYPE_P (TREE_TYPE (arglist))
6431       || cfun == 0)
6432     return integer_zero_node;
6433
6434   return 0;
6435 }
6436
6437 /* Fold a call to __builtin_expect, if we expect that a comparison against
6438    the argument will fold to a constant.  In practice, this means a true
6439    constant or the address of a non-weak symbol.  ARGLIST is the argument
6440    list of the call.  */
6441
6442 static tree
6443 fold_builtin_expect (tree arglist)
6444 {
6445   tree arg, inner;
6446
6447   if (arglist == 0)
6448     return 0;
6449
6450   arg = TREE_VALUE (arglist);
6451
6452   /* If the argument isn't invariant, then there's nothing we can do.  */
6453   if (!TREE_INVARIANT (arg))
6454     return 0;
6455
6456   /* If we're looking at an address of a weak decl, then do not fold.  */
6457   inner = arg;
6458   STRIP_NOPS (inner);
6459   if (TREE_CODE (inner) == ADDR_EXPR)
6460     {
6461       do
6462         {
6463           inner = TREE_OPERAND (inner, 0);
6464         }
6465       while (TREE_CODE (inner) == COMPONENT_REF
6466              || TREE_CODE (inner) == ARRAY_REF);
6467       if (DECL_P (inner) && DECL_WEAK (inner))
6468         return 0;
6469     }
6470
6471   /* Otherwise, ARG already has the proper type for the return value.  */
6472   return arg;
6473 }
6474
6475 /* Fold a call to __builtin_classify_type.  */
6476
6477 static tree
6478 fold_builtin_classify_type (tree arglist)
6479 {
6480   if (arglist == 0)
6481     return build_int_2 (no_type_class, 0);
6482
6483   return build_int_2 (type_to_class (TREE_TYPE (TREE_VALUE (arglist))), 0);
6484 }
6485
6486 /* Fold a call to __builtin_inf or __builtin_huge_val.  */
6487
6488 static tree
6489 fold_builtin_inf (tree type, int warn)
6490 {
6491   REAL_VALUE_TYPE real;
6492
6493   if (!MODE_HAS_INFINITIES (TYPE_MODE (type)) && warn)
6494     warning ("target format does not support infinity");
6495
6496   real_inf (&real);
6497   return build_real (type, real);
6498 }
6499
6500 /* Fold a call to __builtin_nan or __builtin_nans.  */
6501
6502 static tree
6503 fold_builtin_nan (tree arglist, tree type, int quiet)
6504 {
6505   REAL_VALUE_TYPE real;
6506   const char *str;
6507
6508   if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6509     return 0;
6510   str = c_getstr (TREE_VALUE (arglist));
6511   if (!str)
6512     return 0;
6513
6514   if (!real_nan (&real, str, quiet, TYPE_MODE (type)))
6515     return 0;
6516
6517   return build_real (type, real);
6518 }
6519
6520 /* Return true if the floating point expression T has an integer value.
6521    We also allow +Inf, -Inf and NaN to be considered integer values.  */
6522
6523 static bool
6524 integer_valued_real_p (tree t)
6525 {
6526   switch (TREE_CODE (t))
6527     {
6528     case FLOAT_EXPR:
6529       return true;
6530
6531     case ABS_EXPR:
6532     case SAVE_EXPR:
6533     case NON_LVALUE_EXPR:
6534       return integer_valued_real_p (TREE_OPERAND (t, 0));
6535
6536     case COMPOUND_EXPR:
6537     case MODIFY_EXPR:
6538     case BIND_EXPR:
6539       return integer_valued_real_p (TREE_OPERAND (t, 1));
6540
6541     case PLUS_EXPR:
6542     case MINUS_EXPR:
6543     case MULT_EXPR:
6544     case MIN_EXPR:
6545     case MAX_EXPR:
6546       return integer_valued_real_p (TREE_OPERAND (t, 0))
6547              && integer_valued_real_p (TREE_OPERAND (t, 1));
6548
6549     case COND_EXPR:
6550       return integer_valued_real_p (TREE_OPERAND (t, 1))
6551              && integer_valued_real_p (TREE_OPERAND (t, 2));
6552
6553     case REAL_CST:
6554       if (! TREE_CONSTANT_OVERFLOW (t))
6555       {
6556         REAL_VALUE_TYPE c, cint;
6557
6558         c = TREE_REAL_CST (t);
6559         real_trunc (&cint, TYPE_MODE (TREE_TYPE (t)), &c);
6560         return real_identical (&c, &cint);
6561       }
6562
6563     case NOP_EXPR:
6564       {
6565         tree type = TREE_TYPE (TREE_OPERAND (t, 0));
6566         if (TREE_CODE (type) == INTEGER_TYPE)
6567           return true;
6568         if (TREE_CODE (type) == REAL_TYPE)
6569           return integer_valued_real_p (TREE_OPERAND (t, 0));
6570         break;
6571       }
6572
6573     case CALL_EXPR:
6574       switch (builtin_mathfn_code (t))
6575         {
6576         case BUILT_IN_CEIL:
6577         case BUILT_IN_CEILF:
6578         case BUILT_IN_CEILL:
6579         case BUILT_IN_FLOOR:
6580         case BUILT_IN_FLOORF:
6581         case BUILT_IN_FLOORL:
6582         case BUILT_IN_NEARBYINT:
6583         case BUILT_IN_NEARBYINTF:
6584         case BUILT_IN_NEARBYINTL:
6585         case BUILT_IN_RINT:
6586         case BUILT_IN_RINTF:
6587         case BUILT_IN_RINTL:
6588         case BUILT_IN_ROUND:
6589         case BUILT_IN_ROUNDF:
6590         case BUILT_IN_ROUNDL:
6591         case BUILT_IN_TRUNC:
6592         case BUILT_IN_TRUNCF:
6593         case BUILT_IN_TRUNCL:
6594           return true;
6595
6596         default:
6597           break;
6598         }
6599       break;
6600
6601     default:
6602       break;
6603     }
6604   return false;
6605 }
6606
6607 /* EXP is assumed to be builtin call where truncation can be propagated
6608    across (for instance floor((double)f) == (double)floorf (f).
6609    Do the transformation.  */
6610
6611 static tree
6612 fold_trunc_transparent_mathfn (tree exp)
6613 {
6614   tree fndecl = get_callee_fndecl (exp);
6615   tree arglist = TREE_OPERAND (exp, 1);
6616   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
6617   tree arg;
6618
6619   if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6620     return 0;
6621
6622   arg = TREE_VALUE (arglist);
6623   /* Integer rounding functions are idempotent.  */
6624   if (fcode == builtin_mathfn_code (arg))
6625     return arg;
6626
6627   /* If argument is already integer valued, and we don't need to worry
6628      about setting errno, there's no need to perform rounding.  */
6629   if (! flag_errno_math && integer_valued_real_p (arg))
6630     return arg;
6631
6632   if (optimize)
6633     {
6634       tree arg0 = strip_float_extensions (arg);
6635       tree ftype = TREE_TYPE (exp);
6636       tree newtype = TREE_TYPE (arg0);
6637       tree decl;
6638
6639       if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
6640           && (decl = mathfn_built_in (newtype, fcode)))
6641         {
6642           arglist =
6643             build_tree_list (NULL_TREE, fold_convert (newtype, arg0));
6644           return fold_convert (ftype,
6645                                build_function_call_expr (decl, arglist));
6646         }
6647     }
6648   return 0;
6649 }
6650
6651 /* EXP is assumed to be builtin call which can narrow the FP type of
6652    the argument, for instance lround((double)f) -> lroundf (f).  */
6653
6654 static tree
6655 fold_fixed_mathfn (tree exp)
6656 {
6657   tree fndecl = get_callee_fndecl (exp);
6658   tree arglist = TREE_OPERAND (exp, 1);
6659   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
6660   tree arg;
6661
6662   if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6663     return 0;
6664
6665   arg = TREE_VALUE (arglist);
6666
6667   /* If argument is already integer valued, and we don't need to worry
6668      about setting errno, there's no need to perform rounding.  */
6669   if (! flag_errno_math && integer_valued_real_p (arg))
6670     return fold (build1 (FIX_TRUNC_EXPR, TREE_TYPE (exp), arg));
6671
6672   if (optimize)
6673     {
6674       tree ftype = TREE_TYPE (arg);
6675       tree arg0 = strip_float_extensions (arg);
6676       tree newtype = TREE_TYPE (arg0);
6677       tree decl;
6678
6679       if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
6680           && (decl = mathfn_built_in (newtype, fcode)))
6681         {
6682           arglist =
6683             build_tree_list (NULL_TREE, fold_convert (newtype, arg0));
6684           return build_function_call_expr (decl, arglist);
6685         }
6686     }
6687   return 0;
6688 }
6689
6690 /* Fold function call to builtin cabs, cabsf or cabsl.  ARGLIST
6691    is the argument list and TYPE is the return type.  Return
6692    NULL_TREE if no if no simplification can be made.  */
6693
6694 static tree
6695 fold_builtin_cabs (tree arglist, tree type)
6696 {
6697   tree arg;
6698
6699   if (!arglist || TREE_CHAIN (arglist))
6700     return NULL_TREE;
6701
6702   arg = TREE_VALUE (arglist);
6703   if (TREE_CODE (TREE_TYPE (arg)) != COMPLEX_TYPE
6704       || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) != REAL_TYPE)
6705     return NULL_TREE;
6706
6707   /* Evaluate cabs of a constant at compile-time.  */
6708   if (flag_unsafe_math_optimizations
6709       && TREE_CODE (arg) == COMPLEX_CST
6710       && TREE_CODE (TREE_REALPART (arg)) == REAL_CST
6711       && TREE_CODE (TREE_IMAGPART (arg)) == REAL_CST
6712       && ! TREE_CONSTANT_OVERFLOW (TREE_REALPART (arg))
6713       && ! TREE_CONSTANT_OVERFLOW (TREE_IMAGPART (arg)))
6714     {
6715       REAL_VALUE_TYPE r, i;
6716
6717       r = TREE_REAL_CST (TREE_REALPART (arg));
6718       i = TREE_REAL_CST (TREE_IMAGPART (arg));
6719
6720       real_arithmetic (&r, MULT_EXPR, &r, &r);
6721       real_arithmetic (&i, MULT_EXPR, &i, &i);
6722       real_arithmetic (&r, PLUS_EXPR, &r, &i);
6723       if (real_sqrt (&r, TYPE_MODE (type), &r)
6724           || ! flag_trapping_math)
6725         return build_real (type, r);
6726     }
6727
6728   /* If either part is zero, cabs is fabs of the other.  */
6729   if (TREE_CODE (arg) == COMPLEX_EXPR
6730       && real_zerop (TREE_OPERAND (arg, 0)))
6731     return fold (build1 (ABS_EXPR, type, TREE_OPERAND (arg, 1)));
6732   if (TREE_CODE (arg) == COMPLEX_EXPR
6733       && real_zerop (TREE_OPERAND (arg, 1)))
6734     return fold (build1 (ABS_EXPR, type, TREE_OPERAND (arg, 0)));
6735
6736   if (flag_unsafe_math_optimizations)
6737     {
6738       tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
6739
6740       if (sqrtfn != NULL_TREE)
6741         {
6742           tree rpart, ipart, result, arglist;
6743
6744           arg = builtin_save_expr (arg);
6745
6746           rpart = fold (build1 (REALPART_EXPR, type, arg));
6747           ipart = fold (build1 (IMAGPART_EXPR, type, arg));
6748
6749           rpart = builtin_save_expr (rpart);
6750           ipart = builtin_save_expr (ipart);
6751
6752           result = fold (build2 (PLUS_EXPR, type,
6753                                  fold (build2 (MULT_EXPR, type,
6754                                                rpart, rpart)),
6755                                  fold (build2 (MULT_EXPR, type,
6756                                                ipart, ipart))));
6757
6758           arglist = build_tree_list (NULL_TREE, result);
6759           return build_function_call_expr (sqrtfn, arglist);
6760         }
6761     }
6762
6763   return NULL_TREE;
6764 }
6765
6766 /* Fold function call to builtin trunc, truncf or truncl.  Return
6767    NULL_TREE if no simplification can be made.  */
6768
6769 static tree
6770 fold_builtin_trunc (tree exp)
6771 {
6772   tree arglist = TREE_OPERAND (exp, 1);
6773   tree arg;
6774
6775   if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6776     return 0;
6777
6778   /* Optimize trunc of constant value.  */
6779   arg = TREE_VALUE (arglist);
6780   if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
6781     {
6782       REAL_VALUE_TYPE r, x;
6783       tree type = TREE_TYPE (exp);
6784
6785       x = TREE_REAL_CST (arg);
6786       real_trunc (&r, TYPE_MODE (type), &x);
6787       return build_real (type, r);
6788     }
6789
6790   return fold_trunc_transparent_mathfn (exp);
6791 }
6792
6793 /* Fold function call to builtin floor, floorf or floorl.  Return
6794    NULL_TREE if no simplification can be made.  */
6795
6796 static tree
6797 fold_builtin_floor (tree exp)
6798 {
6799   tree arglist = TREE_OPERAND (exp, 1);
6800   tree arg;
6801
6802   if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6803     return 0;
6804
6805   /* Optimize floor of constant value.  */
6806   arg = TREE_VALUE (arglist);
6807   if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
6808     {
6809       REAL_VALUE_TYPE x;
6810
6811       x = TREE_REAL_CST (arg);
6812       if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
6813         {
6814           tree type = TREE_TYPE (exp);
6815           REAL_VALUE_TYPE r;
6816
6817           real_floor (&r, TYPE_MODE (type), &x);
6818           return build_real (type, r);
6819         }
6820     }
6821
6822   return fold_trunc_transparent_mathfn (exp);
6823 }
6824
6825 /* Fold function call to builtin ceil, ceilf or ceill.  Return
6826    NULL_TREE if no simplification can be made.  */
6827
6828 static tree
6829 fold_builtin_ceil (tree exp)
6830 {
6831   tree arglist = TREE_OPERAND (exp, 1);
6832   tree arg;
6833
6834   if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6835     return 0;
6836
6837   /* Optimize ceil of constant value.  */
6838   arg = TREE_VALUE (arglist);
6839   if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
6840     {
6841       REAL_VALUE_TYPE x;
6842
6843       x = TREE_REAL_CST (arg);
6844       if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
6845         {
6846           tree type = TREE_TYPE (exp);
6847           REAL_VALUE_TYPE r;
6848
6849           real_ceil (&r, TYPE_MODE (type), &x);
6850           return build_real (type, r);
6851         }
6852     }
6853
6854   return fold_trunc_transparent_mathfn (exp);
6855 }
6856
6857 /* Fold function call to builtin round, roundf or roundl.  Return
6858    NULL_TREE if no simplification can be made.  */
6859
6860 static tree
6861 fold_builtin_round (tree exp)
6862 {
6863   tree arglist = TREE_OPERAND (exp, 1);
6864   tree arg;
6865
6866   if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6867     return 0;
6868
6869   /* Optimize round of constant value.  */
6870   arg = TREE_VALUE (arglist);
6871   if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
6872     {
6873       REAL_VALUE_TYPE x;
6874
6875       x = TREE_REAL_CST (arg);
6876       if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
6877         {
6878           tree type = TREE_TYPE (exp);
6879           REAL_VALUE_TYPE r;
6880
6881           real_round (&r, TYPE_MODE (type), &x);
6882           return build_real (type, r);
6883         }
6884     }
6885
6886   return fold_trunc_transparent_mathfn (exp);
6887 }
6888
6889 /* Fold function call to builtin lround, lroundf or lroundl (or the
6890    corresponding long long versions).  Return NULL_TREE if no
6891    simplification can be made.  */
6892
6893 static tree
6894 fold_builtin_lround (tree exp)
6895 {
6896   tree arglist = TREE_OPERAND (exp, 1);
6897   tree arg;
6898
6899   if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6900     return 0;
6901
6902   /* Optimize lround of constant value.  */
6903   arg = TREE_VALUE (arglist);
6904   if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
6905     {
6906       const REAL_VALUE_TYPE x = TREE_REAL_CST (arg);
6907
6908       if (! REAL_VALUE_ISNAN (x) && ! REAL_VALUE_ISINF (x))
6909         {
6910           tree itype = TREE_TYPE (exp), ftype = TREE_TYPE (arg), result;
6911           HOST_WIDE_INT hi, lo;
6912           REAL_VALUE_TYPE r;
6913
6914           real_round (&r, TYPE_MODE (ftype), &x);
6915           REAL_VALUE_TO_INT (&lo, &hi, r);
6916           result = build_int_2 (lo, hi);
6917           if (int_fits_type_p (result, itype))
6918             return fold_convert (itype, result);
6919         }
6920     }
6921
6922   return fold_fixed_mathfn (exp);
6923 }
6924
6925 /* Fold function call to builtin ffs, clz, ctz, popcount and parity
6926    and their long and long long variants (i.e. ffsl and ffsll).
6927    Return NULL_TREE if no simplification can be made.  */
6928
6929 static tree
6930 fold_builtin_bitop (tree exp)
6931 {
6932   tree fndecl = get_callee_fndecl (exp);
6933   tree arglist = TREE_OPERAND (exp, 1);
6934   tree arg;
6935
6936   if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
6937     return NULL_TREE;
6938
6939   /* Optimize for constant argument.  */
6940   arg = TREE_VALUE (arglist);
6941   if (TREE_CODE (arg) == INTEGER_CST && ! TREE_CONSTANT_OVERFLOW (arg))
6942     {
6943       HOST_WIDE_INT hi, width, result;
6944       unsigned HOST_WIDE_INT lo;
6945       tree type, t;
6946
6947       type = TREE_TYPE (arg);
6948       width = TYPE_PRECISION (type);
6949       lo = TREE_INT_CST_LOW (arg);
6950
6951       /* Clear all the bits that are beyond the type's precision.  */
6952       if (width > HOST_BITS_PER_WIDE_INT)
6953         {
6954           hi = TREE_INT_CST_HIGH (arg);
6955           if (width < 2 * HOST_BITS_PER_WIDE_INT)
6956             hi &= ~((HOST_WIDE_INT) (-1) >> (width - HOST_BITS_PER_WIDE_INT));
6957         }
6958       else
6959         {
6960           hi = 0;
6961           if (width < HOST_BITS_PER_WIDE_INT)
6962             lo &= ~((unsigned HOST_WIDE_INT) (-1) << width);
6963         }
6964
6965       switch (DECL_FUNCTION_CODE (fndecl))
6966         {
6967         case BUILT_IN_FFS:
6968         case BUILT_IN_FFSL:
6969         case BUILT_IN_FFSLL:
6970           if (lo != 0)
6971             result = exact_log2 (lo & -lo) + 1;
6972           else if (hi != 0)
6973             result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi) + 1;
6974           else
6975             result = 0;
6976           break;
6977
6978         case BUILT_IN_CLZ:
6979         case BUILT_IN_CLZL:
6980         case BUILT_IN_CLZLL:
6981           if (hi != 0)
6982             result = width - floor_log2 (hi) - 1 - HOST_BITS_PER_WIDE_INT;
6983           else if (lo != 0)
6984             result = width - floor_log2 (lo) - 1;
6985           else if (! CLZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
6986             result = width;
6987           break;
6988
6989         case BUILT_IN_CTZ:
6990         case BUILT_IN_CTZL:
6991         case BUILT_IN_CTZLL:
6992           if (lo != 0)
6993             result = exact_log2 (lo & -lo);
6994           else if (hi != 0)
6995             result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi);
6996           else if (! CTZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
6997             result = width;
6998           break;
6999
7000         case BUILT_IN_POPCOUNT:
7001         case BUILT_IN_POPCOUNTL:
7002         case BUILT_IN_POPCOUNTLL:
7003           result = 0;
7004           while (lo)
7005             result++, lo &= lo - 1;
7006           while (hi)
7007             result++, hi &= hi - 1;
7008           break;
7009
7010         case BUILT_IN_PARITY:
7011         case BUILT_IN_PARITYL:
7012         case BUILT_IN_PARITYLL:
7013           result = 0;
7014           while (lo)
7015             result++, lo &= lo - 1;
7016           while (hi)
7017             result++, hi &= hi - 1;
7018           result &= 1;
7019           break;
7020
7021         default:
7022           abort();
7023         }
7024
7025       t = build_int_2 (result, 0);
7026       TREE_TYPE (t) = TREE_TYPE (exp);
7027       return t;
7028     }
7029
7030   return NULL_TREE;
7031 }
7032
7033 /* Return true if EXPR is the real constant contained in VALUE.  */
7034
7035 static bool
7036 real_dconstp (tree expr, const REAL_VALUE_TYPE *value)
7037 {
7038   STRIP_NOPS (expr);
7039
7040   return ((TREE_CODE (expr) == REAL_CST
7041            && ! TREE_CONSTANT_OVERFLOW (expr)
7042            && REAL_VALUES_EQUAL (TREE_REAL_CST (expr), *value))
7043           || (TREE_CODE (expr) == COMPLEX_CST
7044               && real_dconstp (TREE_REALPART (expr), value)
7045               && real_zerop (TREE_IMAGPART (expr))));
7046 }
7047
7048 /* A subroutine of fold_builtin to fold the various logarithmic
7049    functions.  EXP is the CALL_EXPR of a call to a builtin logN
7050    function.  VALUE is the base of the logN function.  */
7051
7052 static tree
7053 fold_builtin_logarithm (tree exp, const REAL_VALUE_TYPE *value)
7054 {
7055   tree arglist = TREE_OPERAND (exp, 1);
7056
7057   if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7058     {
7059       tree fndecl = get_callee_fndecl (exp);
7060       tree type = TREE_TYPE (TREE_TYPE (fndecl));
7061       tree arg = TREE_VALUE (arglist);
7062       const enum built_in_function fcode = builtin_mathfn_code (arg);
7063
7064       /* Optimize logN(1.0) = 0.0.  */
7065       if (real_onep (arg))
7066         return build_real (type, dconst0);
7067
7068       /* Optimize logN(N) = 1.0.  If N can't be truncated to MODE
7069          exactly, then only do this if flag_unsafe_math_optimizations.  */
7070       if (exact_real_truncate (TYPE_MODE (type), value)
7071           || flag_unsafe_math_optimizations)
7072         {
7073           const REAL_VALUE_TYPE value_truncate =
7074             real_value_truncate (TYPE_MODE (type), *value);
7075           if (real_dconstp (arg, &value_truncate))
7076             return build_real (type, dconst1);
7077         }
7078
7079       /* Special case, optimize logN(expN(x)) = x.  */
7080       if (flag_unsafe_math_optimizations
7081           && ((value == &dconste
7082                && (fcode == BUILT_IN_EXP
7083                    || fcode == BUILT_IN_EXPF
7084                    || fcode == BUILT_IN_EXPL))
7085               || (value == &dconst2
7086                   && (fcode == BUILT_IN_EXP2
7087                       || fcode == BUILT_IN_EXP2F
7088                       || fcode == BUILT_IN_EXP2L))
7089               || (value == &dconst10 && (BUILTIN_EXP10_P (fcode)))))
7090         return fold_convert (type, TREE_VALUE (TREE_OPERAND (arg, 1)));
7091
7092       /* Optimize logN(func()) for various exponential functions.  We
7093          want to determine the value "x" and the power "exponent" in
7094          order to transform logN(x**exponent) into exponent*logN(x).  */
7095       if (flag_unsafe_math_optimizations)
7096         {
7097           tree exponent = 0, x = 0;
7098
7099           switch (fcode)
7100           {
7101           case BUILT_IN_EXP:
7102           case BUILT_IN_EXPF:
7103           case BUILT_IN_EXPL:
7104             /* Prepare to do logN(exp(exponent) -> exponent*logN(e).  */
7105             x = build_real (type,
7106                             real_value_truncate (TYPE_MODE (type), dconste));
7107             exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
7108             break;
7109           case BUILT_IN_EXP2:
7110           case BUILT_IN_EXP2F:
7111           case BUILT_IN_EXP2L:
7112             /* Prepare to do logN(exp2(exponent) -> exponent*logN(2).  */
7113             x = build_real (type, dconst2);
7114             exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
7115             break;
7116           case BUILT_IN_EXP10:
7117           case BUILT_IN_EXP10F:
7118           case BUILT_IN_EXP10L:
7119           case BUILT_IN_POW10:
7120           case BUILT_IN_POW10F:
7121           case BUILT_IN_POW10L:
7122             /* Prepare to do logN(exp10(exponent) -> exponent*logN(10).  */
7123             x = build_real (type, dconst10);
7124             exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
7125             break;
7126           case BUILT_IN_SQRT:
7127           case BUILT_IN_SQRTF:
7128           case BUILT_IN_SQRTL:
7129             /* Prepare to do logN(sqrt(x) -> 0.5*logN(x).  */
7130             x = TREE_VALUE (TREE_OPERAND (arg, 1));
7131             exponent = build_real (type, dconsthalf);
7132             break;
7133           case BUILT_IN_CBRT:
7134           case BUILT_IN_CBRTF:
7135           case BUILT_IN_CBRTL:
7136             /* Prepare to do logN(cbrt(x) -> (1/3)*logN(x).  */
7137             x = TREE_VALUE (TREE_OPERAND (arg, 1));
7138             exponent = build_real (type, real_value_truncate (TYPE_MODE (type),
7139                                                               dconstthird));
7140             break;
7141           case BUILT_IN_POW:
7142           case BUILT_IN_POWF:
7143           case BUILT_IN_POWL:
7144             /* Prepare to do logN(pow(x,exponent) -> exponent*logN(x).  */
7145             x = TREE_VALUE (TREE_OPERAND (arg, 1));
7146             exponent = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
7147             break;
7148           default:
7149             break;
7150           }
7151
7152           /* Now perform the optimization.  */
7153           if (x && exponent)
7154             {
7155               tree logfn;
7156               arglist = build_tree_list (NULL_TREE, x);
7157               logfn = build_function_call_expr (fndecl, arglist);
7158               return fold (build2 (MULT_EXPR, type, exponent, logfn));
7159             }
7160         }
7161     }
7162
7163   return 0;
7164 }
7165
7166 /* A subroutine of fold_builtin to fold the various exponent
7167    functions.  EXP is the CALL_EXPR of a call to a builtin function.
7168    VALUE is the value which will be raised to a power.  */
7169
7170 static tree
7171 fold_builtin_exponent (tree exp, const REAL_VALUE_TYPE *value)
7172 {
7173   tree arglist = TREE_OPERAND (exp, 1);
7174
7175   if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7176     {
7177       tree fndecl = get_callee_fndecl (exp);
7178       tree type = TREE_TYPE (TREE_TYPE (fndecl));
7179       tree arg = TREE_VALUE (arglist);
7180
7181       /* Optimize exp*(0.0) = 1.0.  */
7182       if (real_zerop (arg))
7183         return build_real (type, dconst1);
7184
7185       /* Optimize expN(1.0) = N.  */
7186       if (real_onep (arg))
7187         {
7188           REAL_VALUE_TYPE cst;
7189
7190           real_convert (&cst, TYPE_MODE (type), value);
7191           return build_real (type, cst);
7192         }
7193
7194       /* Attempt to evaluate expN(integer) at compile-time.  */
7195       if (flag_unsafe_math_optimizations
7196           && TREE_CODE (arg) == REAL_CST
7197           && ! TREE_CONSTANT_OVERFLOW (arg))
7198         {
7199           REAL_VALUE_TYPE cint;
7200           REAL_VALUE_TYPE c;
7201           HOST_WIDE_INT n;
7202
7203           c = TREE_REAL_CST (arg);
7204           n = real_to_integer (&c);
7205           real_from_integer (&cint, VOIDmode, n,
7206                              n < 0 ? -1 : 0, 0);
7207           if (real_identical (&c, &cint))
7208             {
7209               REAL_VALUE_TYPE x;
7210
7211               real_powi (&x, TYPE_MODE (type), value, n);
7212               return build_real (type, x);
7213             }
7214         }
7215
7216       /* Optimize expN(logN(x)) = x.  */
7217       if (flag_unsafe_math_optimizations)
7218         {
7219           const enum built_in_function fcode = builtin_mathfn_code (arg);
7220
7221           if ((value == &dconste
7222                && (fcode == BUILT_IN_LOG
7223                    || fcode == BUILT_IN_LOGF
7224                    || fcode == BUILT_IN_LOGL))
7225               || (value == &dconst2
7226                   && (fcode == BUILT_IN_LOG2
7227                       || fcode == BUILT_IN_LOG2F
7228                       || fcode == BUILT_IN_LOG2L))
7229               || (value == &dconst10
7230                   && (fcode == BUILT_IN_LOG10
7231                       || fcode == BUILT_IN_LOG10F
7232                       || fcode == BUILT_IN_LOG10L)))
7233             return fold_convert (type, TREE_VALUE (TREE_OPERAND (arg, 1)));
7234         }
7235     }
7236
7237   return 0;
7238 }
7239
7240 /* Fold function call to builtin memcpy.  Return
7241    NULL_TREE if no simplification can be made.  */
7242
7243 static tree
7244 fold_builtin_memcpy (tree exp)
7245 {
7246   tree arglist = TREE_OPERAND (exp, 1);
7247   tree dest, src, len;
7248
7249   if (!validate_arglist (arglist,
7250                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7251     return 0;
7252
7253   dest = TREE_VALUE (arglist);
7254   src = TREE_VALUE (TREE_CHAIN (arglist));
7255   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7256
7257   /* If the LEN parameter is zero, return DEST.  */
7258   if (integer_zerop (len))
7259     return omit_one_operand (TREE_TYPE (exp), dest, src);
7260
7261   /* If SRC and DEST are the same (and not volatile), return DEST.  */
7262   if (operand_equal_p (src, dest, 0))
7263     return omit_one_operand (TREE_TYPE (exp), dest, len);
7264
7265   return 0;
7266 }
7267
7268 /* Fold function call to builtin mempcpy.  Return
7269    NULL_TREE if no simplification can be made.  */
7270
7271 static tree
7272 fold_builtin_mempcpy (tree exp)
7273 {
7274   tree arglist = TREE_OPERAND (exp, 1);
7275   tree dest, src, len;
7276
7277   if (!validate_arglist (arglist,
7278                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7279     return 0;
7280
7281   dest = TREE_VALUE (arglist);
7282   src = TREE_VALUE (TREE_CHAIN (arglist));
7283   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7284
7285   /* If the LEN parameter is zero, return DEST.  */
7286   if (integer_zerop (len))
7287     return omit_one_operand (TREE_TYPE (exp), dest, src);
7288
7289   /* If SRC and DEST are the same (and not volatile), return DEST+LEN.  */
7290   if (operand_equal_p (src, dest, 0))
7291     {
7292       tree temp = fold_convert (TREE_TYPE (dest), len);
7293       temp = fold (build2 (PLUS_EXPR, TREE_TYPE (dest), dest, temp));
7294       return fold_convert (TREE_TYPE (exp), temp);
7295     }
7296
7297   return 0;
7298 }
7299
7300 /* Fold function call to builtin memmove.  Return
7301    NULL_TREE if no simplification can be made.  */
7302
7303 static tree
7304 fold_builtin_memmove (tree exp)
7305 {
7306   tree arglist = TREE_OPERAND (exp, 1);
7307   tree dest, src, len;
7308
7309   if (!validate_arglist (arglist,
7310                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7311     return 0;
7312
7313   dest = TREE_VALUE (arglist);
7314   src = TREE_VALUE (TREE_CHAIN (arglist));
7315   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7316
7317   /* If the LEN parameter is zero, return DEST.  */
7318   if (integer_zerop (len))
7319     return omit_one_operand (TREE_TYPE (exp), dest, src);
7320
7321   /* If SRC and DEST are the same (and not volatile), return DEST.  */
7322   if (operand_equal_p (src, dest, 0))
7323     return omit_one_operand (TREE_TYPE (exp), dest, len);
7324
7325   return 0;
7326 }
7327
7328 /* Fold function call to builtin strcpy.  If LEN is not NULL, it represents
7329    the length of the string to be copied.  Return NULL_TREE if no
7330    simplification can be made.  */
7331
7332 tree
7333 fold_builtin_strcpy (tree exp, tree len)
7334 {
7335   tree arglist = TREE_OPERAND (exp, 1);
7336   tree dest, src, fn;
7337
7338   if (!validate_arglist (arglist,
7339                          POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
7340     return 0;
7341
7342   dest = TREE_VALUE (arglist);
7343   src = TREE_VALUE (TREE_CHAIN (arglist));
7344
7345   /* If SRC and DEST are the same (and not volatile), return DEST.  */
7346   if (operand_equal_p (src, dest, 0))
7347     return fold_convert (TREE_TYPE (exp), dest);
7348
7349   if (optimize_size)
7350     return 0;
7351
7352   fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
7353   if (!fn)
7354     return 0;
7355
7356   if (!len)
7357     {
7358       len = c_strlen (src, 1);
7359       if (! len || TREE_SIDE_EFFECTS (len))
7360         return 0;
7361     }
7362
7363   len = size_binop (PLUS_EXPR, len, ssize_int (1));
7364   arglist = build_tree_list (NULL_TREE, len);
7365   arglist = tree_cons (NULL_TREE, src, arglist);
7366   arglist = tree_cons (NULL_TREE, dest, arglist);
7367   return fold_convert (TREE_TYPE (exp),
7368                        build_function_call_expr (fn, arglist));
7369 }
7370
7371 /* Fold function call to builtin strncpy.  If SLEN is not NULL, it represents
7372    the length of the source string.  Return NULL_TREE if no simplification
7373    can be made.  */
7374
7375 tree
7376 fold_builtin_strncpy (tree exp, tree slen)
7377 {
7378   tree arglist = TREE_OPERAND (exp, 1);
7379   tree dest, src, len, fn;
7380
7381   if (!validate_arglist (arglist,
7382                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7383     return 0;
7384
7385   dest = TREE_VALUE (arglist);
7386   src = TREE_VALUE (TREE_CHAIN (arglist));
7387   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7388
7389   /* If the LEN parameter is zero, return DEST.  */
7390   if (integer_zerop (len))
7391     return omit_one_operand (TREE_TYPE (exp), dest, src);
7392
7393   /* We can't compare slen with len as constants below if len is not a
7394      constant.  */
7395   if (len == 0 || TREE_CODE (len) != INTEGER_CST)
7396     return 0;
7397
7398   if (!slen)
7399     slen = c_strlen (src, 1);
7400
7401   /* Now, we must be passed a constant src ptr parameter.  */
7402   if (slen == 0 || TREE_CODE (slen) != INTEGER_CST)
7403     return 0;
7404
7405   slen = size_binop (PLUS_EXPR, slen, ssize_int (1));
7406
7407   /* We do not support simplification of this case, though we do
7408      support it when expanding trees into RTL.  */
7409   /* FIXME: generate a call to __builtin_memset.  */
7410   if (tree_int_cst_lt (slen, len))
7411     return 0;
7412
7413   /* OK transform into builtin memcpy.  */
7414   fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
7415   if (!fn)
7416     return 0;
7417   return fold_convert (TREE_TYPE (exp),
7418                        build_function_call_expr (fn, arglist));
7419 }
7420
7421 /* Fold function call to builtin strchr and strrchr.
7422    Return NULL_TREE if no simplification can be made.  */
7423
7424 static tree
7425 fold_builtin_strchr (tree exp, bool actually_strrchr)
7426 {
7427   tree arglist = TREE_OPERAND (exp, 1);
7428   if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7429     return 0;
7430   else
7431     {
7432       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
7433       const char *p1;
7434
7435       if (TREE_CODE (s2) != INTEGER_CST)
7436         return 0;
7437
7438       p1 = c_getstr (s1);
7439       if (p1 != NULL)
7440         {
7441           char c;
7442           const char *r;
7443
7444           if (target_char_cast (s2, &c))
7445             return 0;
7446
7447           r = actually_strrchr ? strrchr (p1, c) : strchr (p1, c);
7448
7449           if (r == NULL)
7450             return fold_convert (TREE_TYPE (s1), integer_zero_node);
7451
7452           /* Return an offset into the constant string argument.  */
7453           return fold (build2 (PLUS_EXPR, TREE_TYPE (s1),
7454                                s1, fold_convert (TREE_TYPE (s1),
7455                                                  ssize_int (r - p1))));
7456         }
7457
7458       if (actually_strrchr)
7459         {
7460           tree fn;
7461
7462           if (!integer_zerop (s2))
7463             return 0;
7464
7465           fn = implicit_built_in_decls[BUILT_IN_STRCHR];
7466           if (!fn)
7467             return 0;
7468
7469           /* Transform strrchr(s1, '\0') to strchr(s1, '\0').  */
7470           return build_function_call_expr (fn, arglist);
7471         }
7472
7473       return 0;
7474     }
7475 }
7476
7477 /* Fold function call to builtin memcmp.  Return
7478    NULL_TREE if no simplification can be made.  */
7479
7480 static tree
7481 fold_builtin_memcmp (tree exp)
7482 {
7483   tree arglist = TREE_OPERAND (exp, 1);
7484   tree arg1, arg2, len;
7485
7486   if (!validate_arglist (arglist,
7487                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7488     return 0;
7489
7490   arg1 = TREE_VALUE (arglist);
7491   arg2 = TREE_VALUE (TREE_CHAIN (arglist));
7492   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7493
7494   /* If the LEN parameter is zero, return zero.  */
7495   if (integer_zerop (len))
7496     {
7497       tree temp = omit_one_operand (TREE_TYPE (exp), integer_zero_node, arg2);
7498       return omit_one_operand (TREE_TYPE (exp), temp, arg1);
7499     }
7500
7501   /* If ARG1 and ARG2 are the same (and not volatile), return zero.  */
7502   if (operand_equal_p (arg1, arg2, 0))
7503     return omit_one_operand (TREE_TYPE (exp), integer_zero_node, len);
7504
7505   return 0;
7506 }
7507
7508 /* Fold function call to builtin strcmp.  Return
7509    NULL_TREE if no simplification can be made.  */
7510
7511 static tree
7512 fold_builtin_strcmp (tree exp)
7513 {
7514   tree arglist = TREE_OPERAND (exp, 1);
7515   tree arg1, arg2;
7516   const char *p1, *p2;
7517
7518   if (!validate_arglist (arglist,
7519                          POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
7520     return 0;
7521
7522   arg1 = TREE_VALUE (arglist);
7523   arg2 = TREE_VALUE (TREE_CHAIN (arglist));
7524
7525   /* If ARG1 and ARG2 are the same (and not volatile), return zero.  */
7526   if (operand_equal_p (arg1, arg2, 0))
7527     return fold_convert (TREE_TYPE (exp), integer_zero_node);
7528
7529   p1 = c_getstr (arg1);
7530   p2 = c_getstr (arg2);
7531
7532   if (p1 && p2)
7533     {
7534       tree temp;
7535       const int i = strcmp (p1, p2);
7536       if (i < 0)
7537         temp = integer_minus_one_node;
7538       else if (i > 0)
7539         temp = integer_one_node;
7540       else
7541         temp = integer_zero_node;
7542       return fold_convert (TREE_TYPE (exp), temp);
7543     }
7544
7545   return 0;
7546 }
7547
7548 /* Fold function call to builtin strncmp.  Return
7549    NULL_TREE if no simplification can be made.  */
7550
7551 static tree
7552 fold_builtin_strncmp (tree exp)
7553 {
7554   tree arglist = TREE_OPERAND (exp, 1);
7555   tree arg1, arg2, len;
7556   const char *p1, *p2;
7557
7558   if (!validate_arglist (arglist,
7559                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7560     return 0;
7561
7562   arg1 = TREE_VALUE (arglist);
7563   arg2 = TREE_VALUE (TREE_CHAIN (arglist));
7564   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7565
7566   /* If the LEN parameter is zero, return zero.  */
7567   if (integer_zerop (len))
7568     {
7569       tree temp = omit_one_operand (TREE_TYPE (exp), integer_zero_node, arg2);
7570       return omit_one_operand (TREE_TYPE (exp), temp, arg1);
7571     }
7572
7573   /* If ARG1 and ARG2 are the same (and not volatile), return zero.  */
7574   if (operand_equal_p (arg1, arg2, 0))
7575     return omit_one_operand (TREE_TYPE (exp), integer_zero_node, len);
7576
7577   p1 = c_getstr (arg1);
7578   p2 = c_getstr (arg2);
7579
7580   if (host_integerp (len, 1) && p1 && p2)
7581     {
7582       tree temp;
7583       const int i = strncmp (p1, p2, tree_low_cst (len, 1));
7584       if (i < 0)
7585         temp = integer_minus_one_node;
7586       else if (i > 0)
7587         temp = integer_one_node;
7588       else
7589         temp = integer_zero_node;
7590       return fold_convert (TREE_TYPE (exp), temp);
7591     }
7592
7593   return 0;
7594 }
7595
7596 /* Fold function call to builtin signbit, signbitf or signbitl.  Return
7597    NULL_TREE if no simplification can be made.  */
7598
7599 static tree
7600 fold_builtin_signbit (tree exp)
7601 {
7602   tree arglist = TREE_OPERAND (exp, 1);
7603   tree arg, temp;
7604
7605   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7606     return NULL_TREE;
7607
7608   arg = TREE_VALUE (arglist);
7609
7610   /* If ARG is a compile-time constant, determine the result.  */
7611   if (TREE_CODE (arg) == REAL_CST
7612       && !TREE_CONSTANT_OVERFLOW (arg))
7613     {
7614       REAL_VALUE_TYPE c;
7615
7616       c = TREE_REAL_CST (arg);
7617       temp = REAL_VALUE_NEGATIVE (c) ? integer_one_node : integer_zero_node;
7618       return fold_convert (TREE_TYPE (exp), temp);
7619     }
7620
7621   /* If ARG is non-negative, the result is always zero.  */
7622   if (tree_expr_nonnegative_p (arg))
7623     return omit_one_operand (TREE_TYPE (exp), integer_zero_node, arg);
7624
7625   /* If ARG's format doesn't have signed zeros, return "arg < 0.0".  */
7626   if (!HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg))))
7627     return fold (build2 (LT_EXPR, TREE_TYPE (exp), arg,
7628                          build_real (TREE_TYPE (arg), dconst0)));
7629
7630   return NULL_TREE;
7631 }
7632
7633 /* Fold function call to builtin copysign, copysignf or copysignl.
7634    Return NULL_TREE if no simplification can be made.  */
7635
7636 static tree
7637 fold_builtin_copysign (tree arglist, tree type)
7638 {
7639   tree arg1, arg2;
7640
7641   if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
7642     return NULL_TREE;
7643
7644   arg1 = TREE_VALUE (arglist);
7645   arg2 = TREE_VALUE (TREE_CHAIN (arglist));
7646
7647   /* copysign(X,X) is X.  */
7648   if (operand_equal_p (arg1, arg2, 0))
7649     return fold_convert (type, arg1);
7650
7651   /* If ARG1 and ARG2 are compile-time constants, determine the result.  */
7652   if (TREE_CODE (arg1) == REAL_CST
7653       && TREE_CODE (arg2) == REAL_CST
7654       && !TREE_CONSTANT_OVERFLOW (arg1)
7655       && !TREE_CONSTANT_OVERFLOW (arg2))
7656     {
7657       REAL_VALUE_TYPE c1, c2;
7658
7659       c1 = TREE_REAL_CST (arg1);
7660       c2 = TREE_REAL_CST (arg2);
7661       real_copysign (&c1, &c2);
7662       return build_real (type, c1);
7663       c1.sign = c2.sign;
7664     }
7665
7666   /* copysign(X, Y) is fabs(X) when Y is always non-negative.
7667      Remember to evaluate Y for side-effects.  */
7668   if (tree_expr_nonnegative_p (arg2))
7669     return omit_one_operand (type,
7670                              fold (build1 (ABS_EXPR, type, arg1)),
7671                              arg2);
7672
7673   return NULL_TREE;
7674 }
7675
7676 /* Fold a call to builtin isascii.  */
7677
7678 static tree
7679 fold_builtin_isascii (tree arglist)
7680 {
7681   if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
7682     return 0;
7683   else
7684     {
7685       /* Transform isascii(c) -> ((c & ~0x7f) == 0).  */
7686       tree arg = TREE_VALUE (arglist);
7687       
7688       arg = fold (build2 (EQ_EXPR, integer_type_node,
7689                           build2 (BIT_AND_EXPR, integer_type_node, arg,
7690                                   build_int_2 (~ (unsigned HOST_WIDE_INT) 0x7f,
7691                                                ~ (HOST_WIDE_INT) 0)),
7692                           integer_zero_node));
7693       
7694       if (in_gimple_form && !TREE_CONSTANT (arg))
7695         return NULL_TREE;
7696       else
7697         return arg;
7698     }
7699 }
7700
7701 /* Fold a call to builtin toascii.  */
7702
7703 static tree
7704 fold_builtin_toascii (tree arglist)
7705 {
7706   if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
7707     return 0;
7708   else
7709     {
7710       /* Transform toascii(c) -> (c & 0x7f).  */
7711       tree arg = TREE_VALUE (arglist);
7712       
7713       return fold (build2 (BIT_AND_EXPR, integer_type_node, arg,
7714                            build_int_2 (0x7f, 0)));
7715     }
7716 }
7717
7718 /* Fold a call to builtin isdigit.  */
7719
7720 static tree
7721 fold_builtin_isdigit (tree arglist)
7722 {
7723   if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
7724     return 0;
7725   else
7726     {
7727       /* Transform isdigit(c) -> (unsigned)(c) - '0' <= 9.  */
7728       /* According to the C standard, isdigit is unaffected by locale.  */
7729       tree arg = TREE_VALUE (arglist);
7730       arg = fold_convert (unsigned_type_node, arg);
7731       arg = build2 (MINUS_EXPR, unsigned_type_node, arg,
7732                     fold_convert (unsigned_type_node,
7733                                   build_int_2 (TARGET_DIGIT0, 0)));
7734       arg = build2 (LE_EXPR, integer_type_node, arg,
7735                     fold_convert (unsigned_type_node, build_int_2 (9, 0)));
7736       arg = fold (arg);
7737       if (in_gimple_form && !TREE_CONSTANT (arg))
7738         return NULL_TREE;
7739       else
7740         return arg;
7741     }
7742 }
7743
7744 /* Fold a call to fabs, fabsf or fabsl.  */
7745
7746 static tree
7747 fold_builtin_fabs (tree arglist, tree type)
7748 {
7749   tree arg;
7750
7751   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7752     return 0;
7753
7754   arg = TREE_VALUE (arglist);
7755   if (TREE_CODE (arg) == REAL_CST)
7756     return fold_abs_const (arg, type);
7757   return fold (build1 (ABS_EXPR, type, arg));
7758 }
7759
7760 /* Fold a call to abs, labs, llabs or imaxabs.  */
7761
7762 static tree
7763 fold_builtin_abs (tree arglist, tree type)
7764 {
7765   tree arg;
7766
7767   if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
7768     return 0;
7769
7770   arg = TREE_VALUE (arglist);
7771   if (TREE_CODE (arg) == INTEGER_CST)
7772     return fold_abs_const (arg, type);
7773   return fold (build1 (ABS_EXPR, type, arg));
7774 }
7775
7776 /* Fold a call to __builtin_isnan(), __builtin_isinf, __builtin_finite.
7777    EXP is the CALL_EXPR for the call.  */
7778
7779 static tree
7780 fold_builtin_classify (tree exp, int builtin_index)
7781 {
7782   tree fndecl = get_callee_fndecl (exp);
7783   tree arglist = TREE_OPERAND (exp, 1);
7784   tree type = TREE_TYPE (TREE_TYPE (fndecl));
7785   tree arg;
7786   REAL_VALUE_TYPE r;
7787
7788   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7789     {
7790       /* Check that we have exactly one argument.  */
7791       if (arglist == 0)
7792         {
7793           error ("too few arguments to function `%s'",
7794                  IDENTIFIER_POINTER (DECL_NAME (fndecl)));
7795           return error_mark_node;
7796         }
7797       else if (TREE_CHAIN (arglist) != 0)
7798         {
7799           error ("too many arguments to function `%s'",
7800                  IDENTIFIER_POINTER (DECL_NAME (fndecl)));
7801           return error_mark_node;
7802         }
7803       else
7804         {
7805           error ("non-floating-point argument to function `%s'",
7806                  IDENTIFIER_POINTER (DECL_NAME (fndecl)));
7807           return error_mark_node;
7808         }
7809     }
7810
7811   arg = TREE_VALUE (arglist);
7812   switch (builtin_index)
7813     {
7814     case BUILT_IN_ISINF:
7815       if (!MODE_HAS_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
7816         return omit_one_operand (type, integer_zero_node, arg);
7817
7818       if (TREE_CODE (arg) == REAL_CST)
7819         {
7820           r = TREE_REAL_CST (arg);
7821           if (real_isinf (&r))
7822             return real_compare (GT_EXPR, &r, &dconst0)
7823                    ? integer_one_node : integer_minus_one_node;
7824           else
7825             return integer_zero_node;
7826         }
7827
7828       return NULL_TREE;
7829
7830     case BUILT_IN_FINITE:
7831       if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg)))
7832           && !MODE_HAS_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
7833         return omit_one_operand (type, integer_zero_node, arg);
7834
7835       if (TREE_CODE (arg) == REAL_CST)
7836         {
7837           r = TREE_REAL_CST (arg);
7838           return real_isinf (&r) || real_isnan (&r)
7839                  ? integer_zero_node : integer_one_node;
7840         }
7841
7842       return NULL_TREE;
7843
7844     case BUILT_IN_ISNAN:
7845       if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg))))
7846         return omit_one_operand (type, integer_zero_node, arg);
7847
7848       if (TREE_CODE (arg) == REAL_CST)
7849         {
7850           r = TREE_REAL_CST (arg);
7851           return real_isnan (&r) ? integer_one_node : integer_zero_node;
7852         }
7853
7854       arg = builtin_save_expr (arg);
7855       return fold (build2 (UNORDERED_EXPR, type, arg, arg));
7856
7857     default:
7858       abort ();
7859     }
7860 }
7861
7862 /* Fold a call to an unordered comparison function such as
7863    __builtin_isgreater().  EXP is the CALL_EXPR for the call.
7864    UNORDERED_CODE and ORDERED_CODE are comparison codes that give
7865    the opposite of the desired result.  UNORDERED_CODE is used
7866    for modes that can hold NaNs and ORDERED_CODE is used for
7867    the rest.  */
7868
7869 static tree
7870 fold_builtin_unordered_cmp (tree exp,
7871                             enum tree_code unordered_code,
7872                             enum tree_code ordered_code)
7873 {
7874   tree fndecl = get_callee_fndecl (exp);
7875   tree arglist = TREE_OPERAND (exp, 1);
7876   tree type = TREE_TYPE (TREE_TYPE (fndecl));
7877   enum tree_code code;
7878   tree arg0, arg1;
7879
7880   if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
7881     {
7882       enum tree_code code0, code1;
7883       tree type0, type1;
7884       tree cmp_type = 0;
7885
7886       /* Check that we have exactly two arguments.  */
7887       if (arglist == 0 || TREE_CHAIN (arglist) == 0)
7888         {
7889           error ("too few arguments to function `%s'",
7890                  IDENTIFIER_POINTER (DECL_NAME (fndecl)));
7891           return error_mark_node;
7892         }
7893       else if (TREE_CHAIN (TREE_CHAIN (arglist)) != 0)
7894         {
7895           error ("too many arguments to function `%s'",
7896                  IDENTIFIER_POINTER (DECL_NAME (fndecl)));
7897           return error_mark_node;
7898         }
7899
7900       arg0 = TREE_VALUE (arglist);
7901       arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7902
7903       type0 = TREE_TYPE (arg0);
7904       type1 = TREE_TYPE (arg1);
7905
7906       code0 = TREE_CODE (type0);
7907       code1 = TREE_CODE (type1);
7908
7909       if (code0 == REAL_TYPE && code1 == REAL_TYPE)
7910         /* Choose the wider of two real types.  */
7911         cmp_type = TYPE_PRECISION (type0) >= TYPE_PRECISION (type1)
7912                    ? type0 : type1;
7913       else if (code0 == REAL_TYPE && code1 == INTEGER_TYPE)
7914         cmp_type = type0;
7915       else if (code0 == INTEGER_TYPE && code1 == REAL_TYPE)
7916         cmp_type = type1;
7917       else
7918         {
7919           error ("non-floating-point argument to function `%s'",
7920                  IDENTIFIER_POINTER (DECL_NAME (fndecl)));
7921           return error_mark_node;
7922         }
7923
7924       arg0 = fold_convert (cmp_type, arg0);
7925       arg1 = fold_convert (cmp_type, arg1);
7926     }
7927   else
7928     {
7929       arg0 = TREE_VALUE (arglist);
7930       arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7931     }
7932
7933   if (unordered_code == UNORDERED_EXPR)
7934     {
7935       if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg0))))
7936         return omit_two_operands (type, integer_zero_node, arg0, arg1);
7937       return fold (build2 (UNORDERED_EXPR, type, arg0, arg1));
7938     }
7939
7940   code = MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg0))) ? unordered_code
7941                                                       : ordered_code;
7942   return fold (build1 (TRUTH_NOT_EXPR, type,
7943                        fold (build2 (code, type, arg0, arg1))));
7944 }
7945
7946 /* Used by constant folding to simplify calls to builtin functions.  EXP is
7947    the CALL_EXPR of a call to a builtin function.  IGNORE is true if the
7948    result of the function call is ignored.  This function returns NULL_TREE
7949    if no simplification was possible.  */
7950
7951 static tree
7952 fold_builtin_1 (tree exp, bool ignore)
7953 {
7954   tree fndecl = get_callee_fndecl (exp);
7955   tree arglist = TREE_OPERAND (exp, 1);
7956   tree type = TREE_TYPE (TREE_TYPE (fndecl));
7957
7958   if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
7959     return 0;
7960
7961   switch (DECL_FUNCTION_CODE (fndecl))
7962     {
7963     case BUILT_IN_CONSTANT_P:
7964       return fold_builtin_constant_p (arglist);
7965
7966     case BUILT_IN_EXPECT:
7967       return fold_builtin_expect (arglist);
7968
7969     case BUILT_IN_CLASSIFY_TYPE:
7970       return fold_builtin_classify_type (arglist);
7971
7972     case BUILT_IN_STRLEN:
7973       if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
7974         {
7975           tree len = c_strlen (TREE_VALUE (arglist), 0);
7976           if (len)
7977             {
7978               /* Convert from the internal "sizetype" type to "size_t".  */
7979               if (size_type_node)
7980                 len = fold_convert (size_type_node, len);
7981               return len;
7982             }
7983         }
7984       break;
7985
7986     case BUILT_IN_FABS:
7987     case BUILT_IN_FABSF:
7988     case BUILT_IN_FABSL:
7989       return fold_builtin_fabs (arglist, type);
7990
7991     case BUILT_IN_ABS:
7992     case BUILT_IN_LABS:
7993     case BUILT_IN_LLABS:
7994     case BUILT_IN_IMAXABS:
7995       return fold_builtin_abs (arglist, type);
7996
7997     case BUILT_IN_CONJ:
7998     case BUILT_IN_CONJF:
7999     case BUILT_IN_CONJL:
8000       if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
8001         return fold (build1 (CONJ_EXPR, type, TREE_VALUE (arglist)));
8002       break;
8003
8004     case BUILT_IN_CREAL:
8005     case BUILT_IN_CREALF:
8006     case BUILT_IN_CREALL:
8007       if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
8008         return non_lvalue (fold (build1 (REALPART_EXPR, type,
8009                                          TREE_VALUE (arglist))));
8010       break;
8011
8012     case BUILT_IN_CIMAG:
8013     case BUILT_IN_CIMAGF:
8014     case BUILT_IN_CIMAGL:
8015       if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
8016         return non_lvalue (fold (build1 (IMAGPART_EXPR, type,
8017                                          TREE_VALUE (arglist))));
8018       break;
8019
8020     case BUILT_IN_CABS:
8021     case BUILT_IN_CABSF:
8022     case BUILT_IN_CABSL:
8023       return fold_builtin_cabs (arglist, type);
8024
8025     case BUILT_IN_SQRT:
8026     case BUILT_IN_SQRTF:
8027     case BUILT_IN_SQRTL:
8028       if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8029         {
8030           enum built_in_function fcode;
8031           tree arg = TREE_VALUE (arglist);
8032
8033           /* Optimize sqrt of constant value.  */
8034           if (TREE_CODE (arg) == REAL_CST
8035               && ! TREE_CONSTANT_OVERFLOW (arg))
8036             {
8037               REAL_VALUE_TYPE r, x;
8038
8039               x = TREE_REAL_CST (arg);
8040               if (real_sqrt (&r, TYPE_MODE (type), &x)
8041                   || (!flag_trapping_math && !flag_errno_math))
8042                 return build_real (type, r);
8043             }
8044
8045           /* Optimize sqrt(expN(x)) = expN(x*0.5).  */
8046           fcode = builtin_mathfn_code (arg);
8047           if (flag_unsafe_math_optimizations && BUILTIN_EXPONENT_P (fcode))
8048             {
8049               tree expfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
8050               arg = fold (build2 (MULT_EXPR, type,
8051                                   TREE_VALUE (TREE_OPERAND (arg, 1)),
8052                                   build_real (type, dconsthalf)));
8053               arglist = build_tree_list (NULL_TREE, arg);
8054               return build_function_call_expr (expfn, arglist);
8055             }
8056
8057           /* Optimize sqrt(Nroot(x)) -> pow(x,1/(2*N)).  */
8058           if (flag_unsafe_math_optimizations && BUILTIN_ROOT_P (fcode))
8059             {
8060               tree powfn = mathfn_built_in (type, BUILT_IN_POW);
8061               
8062               if (powfn)
8063                 {
8064                   tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
8065                   tree tree_root;
8066                   /* The inner root was either sqrt or cbrt.  */
8067                   REAL_VALUE_TYPE dconstroot =
8068                     BUILTIN_SQRT_P (fcode) ? dconsthalf : dconstthird;
8069                   
8070                   /* Adjust for the outer root.  */
8071                   SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
8072                   dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
8073                   tree_root = build_real (type, dconstroot);
8074                   arglist = tree_cons (NULL_TREE, arg0,
8075                                        build_tree_list (NULL_TREE, tree_root));
8076                   return build_function_call_expr (powfn, arglist);
8077                 }
8078             }
8079
8080           /* Optimize sqrt(pow(x,y)) = pow(x,y*0.5).  */
8081           if (flag_unsafe_math_optimizations
8082               && (fcode == BUILT_IN_POW
8083                   || fcode == BUILT_IN_POWF
8084                   || fcode == BUILT_IN_POWL))
8085             {
8086               tree powfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
8087               tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
8088               tree arg1 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
8089               tree narg1 = fold (build2 (MULT_EXPR, type, arg1,
8090                                          build_real (type, dconsthalf)));
8091               arglist = tree_cons (NULL_TREE, arg0,
8092                                    build_tree_list (NULL_TREE, narg1));
8093               return build_function_call_expr (powfn, arglist);
8094             }
8095         }
8096       break;
8097
8098     case BUILT_IN_CBRT:
8099     case BUILT_IN_CBRTF:
8100     case BUILT_IN_CBRTL:
8101       if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8102         {
8103           tree arg = TREE_VALUE (arglist);
8104           const enum built_in_function fcode = builtin_mathfn_code (arg);
8105
8106           /* Optimize cbrt of constant value.  */
8107           if (real_zerop (arg) || real_onep (arg) || real_minus_onep (arg))
8108             return arg;
8109
8110           /* Optimize cbrt(expN(x)) -> expN(x/3).  */
8111           if (flag_unsafe_math_optimizations && BUILTIN_EXPONENT_P (fcode))
8112             {
8113               tree expfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
8114               const REAL_VALUE_TYPE third_trunc =
8115                 real_value_truncate (TYPE_MODE (type), dconstthird);
8116               arg = fold (build2 (MULT_EXPR, type,
8117                                   TREE_VALUE (TREE_OPERAND (arg, 1)),
8118                                   build_real (type, third_trunc)));
8119               arglist = build_tree_list (NULL_TREE, arg);
8120               return build_function_call_expr (expfn, arglist);
8121             }
8122
8123           /* Optimize cbrt(sqrt(x)) -> pow(x,1/6).  */
8124           /* We don't optimize cbrt(cbrt(x)) -> pow(x,1/9) because if
8125              x is negative pow will error but cbrt won't.  */
8126           if (flag_unsafe_math_optimizations && BUILTIN_SQRT_P (fcode))
8127             {
8128               tree powfn = mathfn_built_in (type, BUILT_IN_POW);
8129
8130               if (powfn)
8131                 {
8132                   tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
8133                   tree tree_root;
8134                   REAL_VALUE_TYPE dconstroot = dconstthird;
8135
8136                   SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
8137                   dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
8138                   tree_root = build_real (type, dconstroot);
8139                   arglist = tree_cons (NULL_TREE, arg0,
8140                                        build_tree_list (NULL_TREE, tree_root));
8141                   return build_function_call_expr (powfn, arglist);
8142                 }
8143               
8144             }
8145         }
8146       break;
8147
8148     case BUILT_IN_SIN:
8149     case BUILT_IN_SINF:
8150     case BUILT_IN_SINL:
8151       if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8152         {
8153           tree arg = TREE_VALUE (arglist);
8154
8155           /* Optimize sin(0.0) = 0.0.  */
8156           if (real_zerop (arg))
8157             return arg;
8158         }
8159       break;
8160
8161     case BUILT_IN_COS:
8162     case BUILT_IN_COSF:
8163     case BUILT_IN_COSL:
8164       if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8165         {
8166           tree arg = TREE_VALUE (arglist);
8167
8168           /* Optimize cos(0.0) = 1.0.  */
8169           if (real_zerop (arg))
8170             return build_real (type, dconst1);
8171
8172           /* Optimize cos(-x) into cos(x).  */
8173           if (TREE_CODE (arg) == NEGATE_EXPR)
8174             {
8175               tree arglist = build_tree_list (NULL_TREE,
8176                                               TREE_OPERAND (arg, 0));
8177               return build_function_call_expr (fndecl, arglist);
8178             }
8179         }
8180       break;
8181
8182     case BUILT_IN_EXP:
8183     case BUILT_IN_EXPF:
8184     case BUILT_IN_EXPL:
8185       return fold_builtin_exponent (exp, &dconste);
8186
8187     case BUILT_IN_EXP2:
8188     case BUILT_IN_EXP2F:
8189     case BUILT_IN_EXP2L:
8190       return fold_builtin_exponent (exp, &dconst2);
8191
8192     case BUILT_IN_EXP10:
8193     case BUILT_IN_EXP10F:
8194     case BUILT_IN_EXP10L:
8195     case BUILT_IN_POW10:
8196     case BUILT_IN_POW10F:
8197     case BUILT_IN_POW10L:
8198       return fold_builtin_exponent (exp, &dconst10);
8199
8200     case BUILT_IN_LOG:
8201     case BUILT_IN_LOGF:
8202     case BUILT_IN_LOGL:
8203       return fold_builtin_logarithm (exp, &dconste);
8204
8205     case BUILT_IN_LOG2:
8206     case BUILT_IN_LOG2F:
8207     case BUILT_IN_LOG2L:
8208       return fold_builtin_logarithm (exp, &dconst2);
8209
8210     case BUILT_IN_LOG10:
8211     case BUILT_IN_LOG10F:
8212     case BUILT_IN_LOG10L:
8213       return fold_builtin_logarithm (exp, &dconst10);
8214
8215     case BUILT_IN_TAN:
8216     case BUILT_IN_TANF:
8217     case BUILT_IN_TANL:
8218       if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8219         {
8220           enum built_in_function fcode;
8221           tree arg = TREE_VALUE (arglist);
8222
8223           /* Optimize tan(0.0) = 0.0.  */
8224           if (real_zerop (arg))
8225             return arg;
8226
8227           /* Optimize tan(atan(x)) = x.  */
8228           fcode = builtin_mathfn_code (arg);
8229           if (flag_unsafe_math_optimizations
8230               && (fcode == BUILT_IN_ATAN
8231                   || fcode == BUILT_IN_ATANF
8232                   || fcode == BUILT_IN_ATANL))
8233             return TREE_VALUE (TREE_OPERAND (arg, 1));
8234         }
8235       break;
8236
8237     case BUILT_IN_ATAN:
8238     case BUILT_IN_ATANF:
8239     case BUILT_IN_ATANL:
8240       if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8241         {
8242           tree arg = TREE_VALUE (arglist);
8243
8244           /* Optimize atan(0.0) = 0.0.  */
8245           if (real_zerop (arg))
8246             return arg;
8247
8248           /* Optimize atan(1.0) = pi/4.  */
8249           if (real_onep (arg))
8250             {
8251               REAL_VALUE_TYPE cst;
8252
8253               real_convert (&cst, TYPE_MODE (type), &dconstpi);
8254               SET_REAL_EXP (&cst, REAL_EXP (&cst) - 2);
8255               return build_real (type, cst);
8256             }
8257         }
8258       break;
8259
8260     case BUILT_IN_POW:
8261     case BUILT_IN_POWF:
8262     case BUILT_IN_POWL:
8263       if (validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
8264         {
8265           enum built_in_function fcode;
8266           tree arg0 = TREE_VALUE (arglist);
8267           tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
8268
8269           /* Optimize pow(1.0,y) = 1.0.  */
8270           if (real_onep (arg0))
8271             return omit_one_operand (type, build_real (type, dconst1), arg1);
8272
8273           if (TREE_CODE (arg1) == REAL_CST
8274               && ! TREE_CONSTANT_OVERFLOW (arg1))
8275             {
8276               REAL_VALUE_TYPE c;
8277               c = TREE_REAL_CST (arg1);
8278
8279               /* Optimize pow(x,0.0) = 1.0.  */
8280               if (REAL_VALUES_EQUAL (c, dconst0))
8281                 return omit_one_operand (type, build_real (type, dconst1),
8282                                          arg0);
8283
8284               /* Optimize pow(x,1.0) = x.  */
8285               if (REAL_VALUES_EQUAL (c, dconst1))
8286                 return arg0;
8287
8288               /* Optimize pow(x,-1.0) = 1.0/x.  */
8289               if (REAL_VALUES_EQUAL (c, dconstm1))
8290                 return fold (build2 (RDIV_EXPR, type,
8291                                      build_real (type, dconst1), arg0));
8292
8293               /* Optimize pow(x,0.5) = sqrt(x).  */
8294               if (flag_unsafe_math_optimizations
8295                   && REAL_VALUES_EQUAL (c, dconsthalf))
8296                 {
8297                   tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
8298
8299                   if (sqrtfn != NULL_TREE)
8300                     {
8301                       tree arglist = build_tree_list (NULL_TREE, arg0);
8302                       return build_function_call_expr (sqrtfn, arglist);
8303                     }
8304                 }
8305
8306               /* Attempt to evaluate pow at compile-time.  */
8307               if (TREE_CODE (arg0) == REAL_CST
8308                   && ! TREE_CONSTANT_OVERFLOW (arg0))
8309                 {
8310                   REAL_VALUE_TYPE cint;
8311                   HOST_WIDE_INT n;
8312
8313                   n = real_to_integer (&c);
8314                   real_from_integer (&cint, VOIDmode, n,
8315                                      n < 0 ? -1 : 0, 0);
8316                   if (real_identical (&c, &cint))
8317                     {
8318                       REAL_VALUE_TYPE x;
8319                       bool inexact;
8320
8321                       x = TREE_REAL_CST (arg0);
8322                       inexact = real_powi (&x, TYPE_MODE (type), &x, n);
8323                       if (flag_unsafe_math_optimizations || !inexact)
8324                         return build_real (type, x);
8325                     }
8326                 }
8327             }
8328
8329           /* Optimize pow(expN(x),y) = expN(x*y).  */
8330           fcode = builtin_mathfn_code (arg0);
8331           if (flag_unsafe_math_optimizations && BUILTIN_EXPONENT_P (fcode))
8332             {
8333               tree expfn = TREE_OPERAND (TREE_OPERAND (arg0, 0), 0);
8334               tree arg = TREE_VALUE (TREE_OPERAND (arg0, 1));
8335               arg = fold (build2 (MULT_EXPR, type, arg, arg1));
8336               arglist = build_tree_list (NULL_TREE, arg);
8337               return build_function_call_expr (expfn, arglist);
8338             }
8339
8340           /* Optimize pow(sqrt(x),y) = pow(x,y*0.5).  */
8341           if (flag_unsafe_math_optimizations && BUILTIN_SQRT_P (fcode))
8342             {
8343               tree narg0 = TREE_VALUE (TREE_OPERAND (arg0, 1));
8344               tree narg1 = fold (build2 (MULT_EXPR, type, arg1,
8345                                          build_real (type, dconsthalf)));
8346
8347               arglist = tree_cons (NULL_TREE, narg0,
8348                                    build_tree_list (NULL_TREE, narg1));
8349               return build_function_call_expr (fndecl, arglist);
8350             }
8351
8352           /* Optimize pow(pow(x,y),z) = pow(x,y*z).  */
8353           if (flag_unsafe_math_optimizations
8354               && (fcode == BUILT_IN_POW
8355                   || fcode == BUILT_IN_POWF
8356                   || fcode == BUILT_IN_POWL))
8357             {
8358               tree arg00 = TREE_VALUE (TREE_OPERAND (arg0, 1));
8359               tree arg01 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg0, 1)));
8360               tree narg1 = fold (build2 (MULT_EXPR, type, arg01, arg1));
8361               arglist = tree_cons (NULL_TREE, arg00,
8362                                    build_tree_list (NULL_TREE, narg1));
8363               return build_function_call_expr (fndecl, arglist);
8364             }
8365         }
8366       break;
8367
8368     case BUILT_IN_INF:
8369     case BUILT_IN_INFF:
8370     case BUILT_IN_INFL:
8371       return fold_builtin_inf (type, true);
8372
8373     case BUILT_IN_HUGE_VAL:
8374     case BUILT_IN_HUGE_VALF:
8375     case BUILT_IN_HUGE_VALL:
8376       return fold_builtin_inf (type, false);
8377
8378     case BUILT_IN_NAN:
8379     case BUILT_IN_NANF:
8380     case BUILT_IN_NANL:
8381       return fold_builtin_nan (arglist, type, true);
8382
8383     case BUILT_IN_NANS:
8384     case BUILT_IN_NANSF:
8385     case BUILT_IN_NANSL:
8386       return fold_builtin_nan (arglist, type, false);
8387
8388     case BUILT_IN_FLOOR:
8389     case BUILT_IN_FLOORF:
8390     case BUILT_IN_FLOORL:
8391       return fold_builtin_floor (exp);
8392
8393     case BUILT_IN_CEIL:
8394     case BUILT_IN_CEILF:
8395     case BUILT_IN_CEILL:
8396       return fold_builtin_ceil (exp);
8397
8398     case BUILT_IN_TRUNC:
8399     case BUILT_IN_TRUNCF:
8400     case BUILT_IN_TRUNCL:
8401       return fold_builtin_trunc (exp);
8402
8403     case BUILT_IN_ROUND:
8404     case BUILT_IN_ROUNDF:
8405     case BUILT_IN_ROUNDL:
8406       return fold_builtin_round (exp);
8407
8408     case BUILT_IN_NEARBYINT:
8409     case BUILT_IN_NEARBYINTF:
8410     case BUILT_IN_NEARBYINTL:
8411     case BUILT_IN_RINT:
8412     case BUILT_IN_RINTF:
8413     case BUILT_IN_RINTL:
8414       return fold_trunc_transparent_mathfn (exp);
8415
8416     case BUILT_IN_LROUND:
8417     case BUILT_IN_LROUNDF:
8418     case BUILT_IN_LROUNDL:
8419     case BUILT_IN_LLROUND:
8420     case BUILT_IN_LLROUNDF:
8421     case BUILT_IN_LLROUNDL:
8422       return fold_builtin_lround (exp);
8423
8424     case BUILT_IN_LRINT:
8425     case BUILT_IN_LRINTF:
8426     case BUILT_IN_LRINTL:
8427     case BUILT_IN_LLRINT:
8428     case BUILT_IN_LLRINTF:
8429     case BUILT_IN_LLRINTL:
8430       return fold_fixed_mathfn (exp);
8431
8432     case BUILT_IN_FFS:
8433     case BUILT_IN_FFSL:
8434     case BUILT_IN_FFSLL:
8435     case BUILT_IN_CLZ:
8436     case BUILT_IN_CLZL:
8437     case BUILT_IN_CLZLL:
8438     case BUILT_IN_CTZ:
8439     case BUILT_IN_CTZL:
8440     case BUILT_IN_CTZLL:
8441     case BUILT_IN_POPCOUNT:
8442     case BUILT_IN_POPCOUNTL:
8443     case BUILT_IN_POPCOUNTLL:
8444     case BUILT_IN_PARITY:
8445     case BUILT_IN_PARITYL:
8446     case BUILT_IN_PARITYLL:
8447       return fold_builtin_bitop (exp);
8448
8449     case BUILT_IN_MEMCPY:
8450       return fold_builtin_memcpy (exp);
8451
8452     case BUILT_IN_MEMPCPY:
8453       return fold_builtin_mempcpy (exp);
8454
8455     case BUILT_IN_MEMMOVE:
8456       return fold_builtin_memmove (exp);
8457
8458     case BUILT_IN_STRCPY:
8459       return fold_builtin_strcpy (exp, NULL_TREE);
8460
8461     case BUILT_IN_STRNCPY:
8462       return fold_builtin_strncpy (exp, NULL_TREE);
8463
8464     case BUILT_IN_INDEX:
8465     case BUILT_IN_STRCHR:
8466       return fold_builtin_strchr (exp, false);
8467
8468     case BUILT_IN_RINDEX:
8469     case BUILT_IN_STRRCHR:
8470       return fold_builtin_strchr (exp, true);
8471
8472     case BUILT_IN_MEMCMP:
8473       return fold_builtin_memcmp (exp);
8474
8475     case BUILT_IN_STRCMP:
8476       return fold_builtin_strcmp (exp);
8477
8478     case BUILT_IN_STRNCMP:
8479       return fold_builtin_strncmp (exp);
8480
8481     case BUILT_IN_SIGNBIT:
8482     case BUILT_IN_SIGNBITF:
8483     case BUILT_IN_SIGNBITL:
8484       return fold_builtin_signbit (exp);
8485
8486     case BUILT_IN_ISASCII:
8487       return fold_builtin_isascii (arglist);
8488
8489     case BUILT_IN_TOASCII:
8490       return fold_builtin_toascii (arglist);
8491
8492     case BUILT_IN_ISDIGIT:
8493       return fold_builtin_isdigit (arglist);
8494
8495     case BUILT_IN_COPYSIGN:
8496     case BUILT_IN_COPYSIGNF:
8497     case BUILT_IN_COPYSIGNL:
8498       return fold_builtin_copysign (arglist, type);
8499
8500     case BUILT_IN_FINITE:
8501     case BUILT_IN_FINITEF:
8502     case BUILT_IN_FINITEL:
8503       return fold_builtin_classify (exp, BUILT_IN_FINITE);
8504
8505     case BUILT_IN_ISINF:
8506     case BUILT_IN_ISINFF:
8507     case BUILT_IN_ISINFL:
8508       return fold_builtin_classify (exp, BUILT_IN_ISINF);
8509
8510     case BUILT_IN_ISNAN:
8511     case BUILT_IN_ISNANF:
8512     case BUILT_IN_ISNANL:
8513       return fold_builtin_classify (exp, BUILT_IN_ISNAN);
8514
8515     case BUILT_IN_ISGREATER:
8516       return fold_builtin_unordered_cmp (exp, UNLE_EXPR, LE_EXPR);
8517     case BUILT_IN_ISGREATEREQUAL:
8518       return fold_builtin_unordered_cmp (exp, UNLT_EXPR, LT_EXPR);
8519     case BUILT_IN_ISLESS:
8520       return fold_builtin_unordered_cmp (exp, UNGE_EXPR, GE_EXPR);
8521     case BUILT_IN_ISLESSEQUAL:
8522       return fold_builtin_unordered_cmp (exp, UNGT_EXPR, GT_EXPR);
8523     case BUILT_IN_ISLESSGREATER:
8524       return fold_builtin_unordered_cmp (exp, UNEQ_EXPR, EQ_EXPR);
8525     case BUILT_IN_ISUNORDERED:
8526       return fold_builtin_unordered_cmp (exp, UNORDERED_EXPR, NOP_EXPR);
8527
8528     case BUILT_IN_FPUTS:
8529       return fold_builtin_fputs (arglist, ignore, false, NULL_TREE);
8530
8531     case BUILT_IN_FPUTS_UNLOCKED:
8532       return fold_builtin_fputs (arglist, ignore, true, NULL_TREE);
8533
8534     default:
8535       break;
8536     }
8537
8538   return 0;
8539 }
8540
8541 /* A wrapper function for builtin folding that prevents warnings for
8542    "statement without effect" and the like, caused by removing the 
8543    call node earlier than the warning is generated.  */
8544
8545 tree
8546 fold_builtin (tree exp, bool ignore)
8547 {
8548   exp = fold_builtin_1 (exp, ignore);
8549   if (exp)
8550     {
8551       /* ??? Don't clobber shared nodes such as integer_zero_node.  */
8552       if (TREE_CODE_CLASS (TREE_CODE (exp)) == 'c')
8553         exp = build1 (NOP_EXPR, TREE_TYPE (exp), exp);
8554       TREE_NO_WARNING (exp) = 1;
8555     }
8556   return exp;
8557 }
8558
8559 /* Conveniently construct a function call expression.  */
8560
8561 tree
8562 build_function_call_expr (tree fn, tree arglist)
8563 {
8564   tree call_expr;
8565
8566   call_expr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
8567   call_expr = build3 (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)),
8568                       call_expr, arglist, NULL_TREE);
8569   return fold (call_expr);
8570 }
8571
8572 /* This function validates the types of a function call argument list
8573    represented as a tree chain of parameters against a specified list
8574    of tree_codes.  If the last specifier is a 0, that represents an
8575    ellipses, otherwise the last specifier must be a VOID_TYPE.  */
8576
8577 static int
8578 validate_arglist (tree arglist, ...)
8579 {
8580   enum tree_code code;
8581   int res = 0;
8582   va_list ap;
8583
8584   va_start (ap, arglist);
8585
8586   do
8587     {
8588       code = va_arg (ap, enum tree_code);
8589       switch (code)
8590         {
8591         case 0:
8592           /* This signifies an ellipses, any further arguments are all ok.  */
8593           res = 1;
8594           goto end;
8595         case VOID_TYPE:
8596           /* This signifies an endlink, if no arguments remain, return
8597              true, otherwise return false.  */
8598           res = arglist == 0;
8599           goto end;
8600         default:
8601           /* If no parameters remain or the parameter's code does not
8602              match the specified code, return false.  Otherwise continue
8603              checking any remaining arguments.  */
8604           if (arglist == 0
8605               || code != TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))))
8606             goto end;
8607           break;
8608         }
8609       arglist = TREE_CHAIN (arglist);
8610     }
8611   while (1);
8612
8613   /* We need gotos here since we can only have one VA_CLOSE in a
8614      function.  */
8615  end: ;
8616   va_end (ap);
8617
8618   return res;
8619 }
8620
8621 /* Default target-specific builtin expander that does nothing.  */
8622
8623 rtx
8624 default_expand_builtin (tree exp ATTRIBUTE_UNUSED,
8625                         rtx target ATTRIBUTE_UNUSED,
8626                         rtx subtarget ATTRIBUTE_UNUSED,
8627                         enum machine_mode mode ATTRIBUTE_UNUSED,
8628                         int ignore ATTRIBUTE_UNUSED)
8629 {
8630   return NULL_RTX;
8631 }
8632
8633 /* Returns true is EXP represents data that would potentially reside
8634    in a readonly section.  */
8635
8636 static bool
8637 readonly_data_expr (tree exp)
8638 {
8639   STRIP_NOPS (exp);
8640
8641   if (TREE_CODE (exp) != ADDR_EXPR)
8642     return false;
8643
8644   exp = get_base_address (TREE_OPERAND (exp, 0));
8645   if (!exp)
8646     return false;
8647
8648   /* Make sure we call decl_readonly_section only for trees it
8649      can handle (since it returns true for everything it doesn't
8650      understand).  */
8651   if (TREE_CODE (exp) == STRING_CST 
8652       || TREE_CODE (exp) == CONSTRUCTOR
8653       || (TREE_CODE (exp) == VAR_DECL && TREE_STATIC (exp)))
8654     return decl_readonly_section (exp, 0);
8655   else
8656     return false;
8657 }
8658
8659 /* Front-end to the simplify_builtin_XXX routines.
8660
8661    EXP is a call to a builtin function.  If possible try to simplify
8662    that into a constant, expression or call to a more efficient
8663    builtin function.
8664
8665    If IGNORE is nonzero, then the result of this builtin function
8666    call is ignored.
8667
8668    If simplification is possible, return the simplified tree, otherwise
8669    return NULL_TREE.  */
8670
8671 tree
8672 simplify_builtin (tree exp, int ignore)
8673 {
8674   tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
8675   tree arglist = TREE_OPERAND (exp, 1);
8676   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
8677   tree val;
8678
8679   switch (fcode)
8680     {
8681     case BUILT_IN_FPUTS:
8682       val = fold_builtin_fputs (arglist, ignore, false, NULL_TREE);
8683       break;
8684     case BUILT_IN_FPUTS_UNLOCKED:
8685       val = fold_builtin_fputs (arglist, ignore, true, NULL_TREE);
8686       break;
8687     case BUILT_IN_STRSTR:
8688       val = simplify_builtin_strstr (arglist);
8689       break;
8690     case BUILT_IN_STRCAT:
8691       val = simplify_builtin_strcat (arglist);
8692       break;
8693     case BUILT_IN_STRNCAT:
8694       val = simplify_builtin_strncat (arglist);
8695       break;
8696     case BUILT_IN_STRSPN:
8697       val = simplify_builtin_strspn (arglist);
8698       break;
8699     case BUILT_IN_STRCSPN:
8700       val = simplify_builtin_strcspn (arglist);
8701       break;
8702     case BUILT_IN_STRCHR:
8703     case BUILT_IN_INDEX:
8704       val = simplify_builtin_strchr (arglist);
8705       break;
8706     case BUILT_IN_STRRCHR:
8707     case BUILT_IN_RINDEX:
8708       val = simplify_builtin_strrchr (arglist);
8709       break;
8710     case BUILT_IN_STRCPY:
8711       val = fold_builtin_strcpy (exp, NULL_TREE);
8712       break;
8713     case BUILT_IN_STRNCPY:
8714       val = fold_builtin_strncpy (exp, NULL_TREE);
8715       break;
8716     case BUILT_IN_STRCMP:
8717       val = simplify_builtin_strcmp (arglist);
8718       break;
8719     case BUILT_IN_STRNCMP:
8720       val = simplify_builtin_strncmp (arglist);
8721       break;
8722     case BUILT_IN_STRPBRK:
8723       val = simplify_builtin_strpbrk (arglist);
8724       break;
8725     case BUILT_IN_BCMP:
8726     case BUILT_IN_MEMCMP:
8727       val = simplify_builtin_memcmp (arglist);
8728       break;
8729     case BUILT_IN_VA_START:
8730       simplify_builtin_va_start (arglist);
8731       val = NULL_TREE;
8732       break;
8733     case BUILT_IN_SPRINTF:
8734       val = simplify_builtin_sprintf (arglist, ignore);
8735       break;
8736     case BUILT_IN_CONSTANT_P:
8737       val = fold_builtin_constant_p (arglist);
8738       /* Gimplification will pull the CALL_EXPR for the builtin out of
8739          an if condition.  When not optimizing, we'll not CSE it back.
8740          To avoid link error types of regressions, return false now.  */
8741       if (!val && !optimize)
8742         val = integer_zero_node;
8743       break;
8744     default:
8745       val = NULL_TREE;
8746       break;
8747     }
8748
8749   if (val)
8750     val = fold_convert (TREE_TYPE (exp), val);
8751   return val;
8752 }
8753
8754 /* Simplify a call to the strstr builtin.
8755
8756    Return 0 if no simplification was possible, otherwise return the
8757    simplified form of the call as a tree.
8758
8759    The simplified form may be a constant or other expression which
8760    computes the same value, but in a more efficient manner (including
8761    calls to other builtin functions).
8762
8763    The call may contain arguments which need to be evaluated, but
8764    which are not useful to determine the result of the call.  In
8765    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
8766    COMPOUND_EXPR will be an argument which must be evaluated.
8767    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
8768    COMPOUND_EXPR in the chain will contain the tree for the simplified
8769    form of the builtin function call.  */
8770
8771 static tree
8772 simplify_builtin_strstr (tree arglist)
8773 {
8774   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
8775     return 0;
8776   else
8777     {
8778       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
8779       tree fn;
8780       const char *p1, *p2;
8781
8782       p2 = c_getstr (s2);
8783       if (p2 == NULL)
8784         return 0;
8785
8786       p1 = c_getstr (s1);
8787       if (p1 != NULL)
8788         {
8789           const char *r = strstr (p1, p2);
8790
8791           if (r == NULL)
8792             return fold_convert (TREE_TYPE (s1), integer_zero_node);
8793
8794           /* Return an offset into the constant string argument.  */
8795           return fold (build2 (PLUS_EXPR, TREE_TYPE (s1),
8796                                s1, fold_convert (TREE_TYPE (s1),
8797                                                  ssize_int (r - p1))));
8798         }
8799
8800       if (p2[0] == '\0')
8801         return s1;
8802
8803       if (p2[1] != '\0')
8804         return 0;
8805
8806       fn = implicit_built_in_decls[BUILT_IN_STRCHR];
8807       if (!fn)
8808         return 0;
8809
8810       /* New argument list transforming strstr(s1, s2) to
8811          strchr(s1, s2[0]).  */
8812       arglist = build_tree_list (NULL_TREE, build_int_2 (p2[0], 0));
8813       arglist = tree_cons (NULL_TREE, s1, arglist);
8814       return build_function_call_expr (fn, arglist);
8815     }
8816 }
8817
8818 /* Simplify a call to the strstr builtin.
8819
8820    Return 0 if no simplification was possible, otherwise return the
8821    simplified form of the call as a tree.
8822
8823    The simplified form may be a constant or other expression which
8824    computes the same value, but in a more efficient manner (including
8825    calls to other builtin functions).
8826
8827    The call may contain arguments which need to be evaluated, but
8828    which are not useful to determine the result of the call.  In
8829    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
8830    COMPOUND_EXPR will be an argument which must be evaluated.
8831    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
8832    COMPOUND_EXPR in the chain will contain the tree for the simplified
8833    form of the builtin function call.  */
8834
8835 static tree
8836 simplify_builtin_strchr (tree arglist)
8837 {
8838   if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8839     return 0;
8840   else
8841     {
8842       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
8843       const char *p1;
8844
8845       if (TREE_CODE (s2) != INTEGER_CST)
8846         return 0;
8847
8848       p1 = c_getstr (s1);
8849       if (p1 != NULL)
8850         {
8851           char c;
8852           const char *r;
8853
8854           if (target_char_cast (s2, &c))
8855             return 0;
8856
8857           r = strchr (p1, c);
8858
8859           if (r == NULL)
8860             return fold_convert (TREE_TYPE (s1), integer_zero_node);
8861
8862           /* Return an offset into the constant string argument.  */
8863           return fold (build2 (PLUS_EXPR, TREE_TYPE (s1),
8864                                s1, fold_convert (TREE_TYPE (s1),
8865                                                  ssize_int (r - p1))));
8866         }
8867
8868       /* FIXME: Should use here strchrM optab so that ports can optimize
8869          this.  */
8870       return 0;
8871     }
8872 }
8873
8874 /* Simplify a call to the strrchr builtin.
8875
8876    Return 0 if no simplification was possible, otherwise return the
8877    simplified form of the call as a tree.
8878
8879    The simplified form may be a constant or other expression which
8880    computes the same value, but in a more efficient manner (including
8881    calls to other builtin functions).
8882
8883    The call may contain arguments which need to be evaluated, but
8884    which are not useful to determine the result of the call.  In
8885    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
8886    COMPOUND_EXPR will be an argument which must be evaluated.
8887    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
8888    COMPOUND_EXPR in the chain will contain the tree for the simplified
8889    form of the builtin function call.  */
8890
8891 static tree
8892 simplify_builtin_strrchr (tree arglist)
8893 {
8894   if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8895     return 0;
8896   else
8897     {
8898       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
8899       tree fn;
8900       const char *p1;
8901
8902       if (TREE_CODE (s2) != INTEGER_CST)
8903         return 0;
8904
8905       p1 = c_getstr (s1);
8906       if (p1 != NULL)
8907         {
8908           char c;
8909           const char *r;
8910
8911           if (target_char_cast (s2, &c))
8912             return 0;
8913
8914           r = strrchr (p1, c);
8915
8916           if (r == NULL)
8917             return fold_convert (TREE_TYPE (s1), integer_zero_node);
8918
8919           /* Return an offset into the constant string argument.  */
8920           return fold (build2 (PLUS_EXPR, TREE_TYPE (s1),
8921                                s1, fold_convert (TREE_TYPE (s1),
8922                                                  ssize_int (r - p1))));
8923         }
8924
8925       if (! integer_zerop (s2))
8926         return 0;
8927
8928       fn = implicit_built_in_decls[BUILT_IN_STRCHR];
8929       if (!fn)
8930         return 0;
8931
8932       /* Transform strrchr(s1, '\0') to strchr(s1, '\0').  */
8933       return build_function_call_expr (fn, arglist);
8934     }
8935 }
8936
8937 /* Simplify a call to the strpbrk builtin.
8938
8939    Return 0 if no simplification was possible, otherwise return the
8940    simplified form of the call as a tree.
8941
8942    The simplified form may be a constant or other expression which
8943    computes the same value, but in a more efficient manner (including
8944    calls to other builtin functions).
8945
8946    The call may contain arguments which need to be evaluated, but
8947    which are not useful to determine the result of the call.  In
8948    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
8949    COMPOUND_EXPR will be an argument which must be evaluated.
8950    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
8951    COMPOUND_EXPR in the chain will contain the tree for the simplified
8952    form of the builtin function call.  */
8953
8954 static tree
8955 simplify_builtin_strpbrk (tree arglist)
8956 {
8957   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
8958     return 0;
8959   else
8960     {
8961       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
8962       tree fn;
8963       const char *p1, *p2;
8964
8965       p2 = c_getstr (s2);
8966       if (p2 == NULL)
8967         return 0;
8968
8969       p1 = c_getstr (s1);
8970       if (p1 != NULL)
8971         {
8972           const char *r = strpbrk (p1, p2);
8973
8974           if (r == NULL)
8975             return fold_convert (TREE_TYPE (s1), integer_zero_node);
8976
8977           /* Return an offset into the constant string argument.  */
8978           return fold (build2 (PLUS_EXPR, TREE_TYPE (s1),
8979                                s1, fold_convert (TREE_TYPE (s1),
8980                                                  ssize_int (r - p1))));
8981         }
8982
8983       if (p2[0] == '\0')
8984         /* strpbrk(x, "") == NULL.
8985            Evaluate and ignore s1 in case it had side-effects.  */
8986         return omit_one_operand (TREE_TYPE (s1), integer_zero_node, s1);
8987
8988       if (p2[1] != '\0')
8989         return 0;  /* Really call strpbrk.  */
8990
8991       fn = implicit_built_in_decls[BUILT_IN_STRCHR];
8992       if (!fn)
8993         return 0;
8994
8995       /* New argument list transforming strpbrk(s1, s2) to
8996          strchr(s1, s2[0]).  */
8997       arglist =
8998         build_tree_list (NULL_TREE, build_int_2 (p2[0], 0));
8999       arglist = tree_cons (NULL_TREE, s1, arglist);
9000       return build_function_call_expr (fn, arglist);
9001     }
9002 }
9003
9004 /* Simplify a call to the memcmp builtin.
9005
9006    Return 0 if no simplification was possible, otherwise return the
9007    simplified form of the call as a tree.
9008
9009    The simplified form may be a constant or other expression which
9010    computes the same value, but in a more efficient manner (including
9011    calls to other builtin functions).
9012
9013    The call may contain arguments which need to be evaluated, but
9014    which are not useful to determine the result of the call.  In
9015    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
9016    COMPOUND_EXPR will be an argument which must be evaluated.
9017    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
9018    COMPOUND_EXPR in the chain will contain the tree for the simplified
9019    form of the builtin function call.  */
9020
9021 static tree
9022 simplify_builtin_memcmp (tree arglist)
9023 {
9024   tree arg1, arg2, len;
9025   const char *p1, *p2;
9026
9027   if (!validate_arglist (arglist,
9028                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9029     return 0;
9030
9031   arg1 = TREE_VALUE (arglist);
9032   arg2 = TREE_VALUE (TREE_CHAIN (arglist));
9033   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
9034
9035   /* If the len parameter is zero, return zero.  */
9036   if (host_integerp (len, 1) && tree_low_cst (len, 1) == 0)
9037     /* Evaluate and ignore arg1 and arg2 in case they have side-effects.  */
9038     return omit_two_operands (integer_type_node, integer_zero_node,
9039                               arg1, arg2);
9040
9041   p1 = c_getstr (arg1);
9042   p2 = c_getstr (arg2);
9043
9044   /* If all arguments are constant, and the value of len is not greater
9045      than the lengths of arg1 and arg2, evaluate at compile-time.  */
9046   if (host_integerp (len, 1) && p1 && p2
9047       && compare_tree_int (len, strlen (p1) + 1) <= 0
9048       && compare_tree_int (len, strlen (p2) + 1) <= 0)
9049     {
9050       const int r = memcmp (p1, p2, tree_low_cst (len, 1));
9051
9052       return (r < 0
9053               ? integer_minus_one_node
9054               : (r > 0 ? integer_one_node : integer_zero_node));
9055     }
9056
9057   /* If len parameter is one, return an expression corresponding to
9058      (*(const unsigned char*)arg1 - (const unsigned char*)arg2).  */
9059   if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
9060     {
9061       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
9062       tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
9063       tree ind1 =
9064       fold (build1 (CONVERT_EXPR, integer_type_node,
9065                     build1 (INDIRECT_REF, cst_uchar_node,
9066                             build1 (NOP_EXPR, cst_uchar_ptr_node, arg1))));
9067       tree ind2 =
9068       fold (build1 (CONVERT_EXPR, integer_type_node,
9069                     build1 (INDIRECT_REF, cst_uchar_node,
9070                             build1 (NOP_EXPR, cst_uchar_ptr_node, arg2))));
9071       return fold (build2 (MINUS_EXPR, integer_type_node, ind1, ind2));
9072     }
9073
9074   return 0;
9075 }
9076
9077 /* Simplify a call to the strcmp builtin.
9078
9079    Return 0 if no simplification was possible, otherwise return the
9080    simplified form of the call as a tree.
9081
9082    The simplified form may be a constant or other expression which
9083    computes the same value, but in a more efficient manner (including
9084    calls to other builtin functions).
9085
9086    The call may contain arguments which need to be evaluated, but
9087    which are not useful to determine the result of the call.  In
9088    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
9089    COMPOUND_EXPR will be an argument which must be evaluated.
9090    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
9091    COMPOUND_EXPR in the chain will contain the tree for the simplified
9092    form of the builtin function call.  */
9093
9094 static tree
9095 simplify_builtin_strcmp (tree arglist)
9096 {
9097   tree arg1, arg2;
9098   const char *p1, *p2;
9099
9100   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9101     return 0;
9102
9103   arg1 = TREE_VALUE (arglist);
9104   arg2 = TREE_VALUE (TREE_CHAIN (arglist));
9105
9106   /* If both arguments are equal (and not volatile), return zero.  */
9107   if (operand_equal_p (arg1, arg2, 0))
9108     return integer_zero_node;
9109
9110   p1 = c_getstr (arg1);
9111   p2 = c_getstr (arg2);
9112
9113   if (p1 && p2)
9114     {
9115       const int i = strcmp (p1, p2);
9116       return (i < 0
9117               ? integer_minus_one_node
9118               : (i > 0 ? integer_one_node : integer_zero_node));
9119     }
9120
9121   /* If either arg is "", return an expression corresponding to
9122      (*(const unsigned char*)arg1 - (const unsigned char*)arg2).  */
9123   if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
9124     {
9125       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
9126       tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
9127       tree ind1 =
9128         fold (build1 (CONVERT_EXPR, integer_type_node,
9129                       build1 (INDIRECT_REF, cst_uchar_node,
9130                               build1 (NOP_EXPR, cst_uchar_ptr_node, arg1))));
9131       tree ind2 =
9132         fold (build1 (CONVERT_EXPR, integer_type_node,
9133                       build1 (INDIRECT_REF, cst_uchar_node,
9134                               build1 (NOP_EXPR, cst_uchar_ptr_node, arg2))));
9135       return fold (build2 (MINUS_EXPR, integer_type_node, ind1, ind2));
9136     }
9137
9138   return 0;
9139 }
9140
9141 /* Simplify a call to the strncmp builtin.
9142
9143    Return 0 if no simplification was possible, otherwise return the
9144    simplified form of the call as a tree.
9145
9146    The simplified form may be a constant or other expression which
9147    computes the same value, but in a more efficient manner (including
9148    calls to other builtin functions).
9149
9150    The call may contain arguments which need to be evaluated, but
9151    which are not useful to determine the result of the call.  In
9152    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
9153    COMPOUND_EXPR will be an argument which must be evaluated.
9154    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
9155    COMPOUND_EXPR in the chain will contain the tree for the simplified
9156    form of the builtin function call.  */
9157
9158 static tree
9159 simplify_builtin_strncmp (tree arglist)
9160 {
9161   tree arg1, arg2, arg3;
9162   const char *p1, *p2;
9163
9164   if (!validate_arglist (arglist,
9165                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9166     return 0;
9167
9168   arg1 = TREE_VALUE (arglist);
9169   arg2 = TREE_VALUE (TREE_CHAIN (arglist));
9170   arg3 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
9171
9172   /* If the len parameter is zero, return zero.  */
9173   if (integer_zerop (arg3))
9174     /* Evaluate and ignore arg1 and arg2 in case they have side-effects.  */
9175     return omit_two_operands (integer_type_node, integer_zero_node,
9176                               arg1, arg2);
9177
9178   /* If arg1 and arg2 are equal (and not volatile), return zero.  */
9179   if (operand_equal_p (arg1, arg2, 0))
9180     /* Evaluate and ignore arg3 in case it has side-effects.  */
9181     return omit_one_operand (integer_type_node, integer_zero_node, arg3);
9182
9183   p1 = c_getstr (arg1);
9184   p2 = c_getstr (arg2);
9185
9186   /* If all arguments are constant, evaluate at compile-time.  */
9187   if (host_integerp (arg3, 1) && p1 && p2)
9188     {
9189       const int r = strncmp (p1, p2, tree_low_cst (arg3, 1));
9190       return (r < 0
9191               ? integer_minus_one_node
9192               : (r > 0 ? integer_one_node : integer_zero_node));
9193     }
9194
9195   /* If len == 1 or (either string parameter is "" and (len >= 1)),
9196       return (*(const u_char*)arg1 - *(const u_char*)arg2).  */
9197   if (host_integerp (arg3, 1)
9198       && (tree_low_cst (arg3, 1) == 1
9199           || (tree_low_cst (arg3, 1) > 1
9200               && ((p1 && *p1 == '\0') || (p2 && *p2 == '\0')))))
9201     {
9202       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
9203       tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
9204       tree ind1 =
9205         fold (build1 (CONVERT_EXPR, integer_type_node,
9206                       build1 (INDIRECT_REF, cst_uchar_node,
9207                               build1 (NOP_EXPR, cst_uchar_ptr_node, arg1))));
9208       tree ind2 =
9209         fold (build1 (CONVERT_EXPR, integer_type_node,
9210                       build1 (INDIRECT_REF, cst_uchar_node,
9211                               build1 (NOP_EXPR, cst_uchar_ptr_node, arg2))));
9212       return fold (build2 (MINUS_EXPR, integer_type_node, ind1, ind2));
9213     }
9214
9215   return 0;
9216 }
9217
9218 /* Simplify a call to the strcat builtin.
9219
9220    Return 0 if no simplification was possible, otherwise return the
9221    simplified form of the call as a tree.
9222
9223    The simplified form may be a constant or other expression which
9224    computes the same value, but in a more efficient manner (including
9225    calls to other builtin functions).
9226
9227    The call may contain arguments which need to be evaluated, but
9228    which are not useful to determine the result of the call.  In
9229    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
9230    COMPOUND_EXPR will be an argument which must be evaluated.
9231    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
9232    COMPOUND_EXPR in the chain will contain the tree for the simplified
9233    form of the builtin function call.  */
9234
9235 static tree
9236 simplify_builtin_strcat (tree arglist)
9237 {
9238   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9239     return 0;
9240   else
9241     {
9242       tree dst = TREE_VALUE (arglist),
9243         src = TREE_VALUE (TREE_CHAIN (arglist));
9244       const char *p = c_getstr (src);
9245
9246       /* If the string length is zero, return the dst parameter.  */
9247       if (p && *p == '\0')
9248         return dst;
9249
9250       return 0;
9251     }
9252 }
9253
9254 /* Simplify a call to the strncat builtin.
9255
9256    Return 0 if no simplification was possible, otherwise return the
9257    simplified form of the call as a tree.
9258
9259    The simplified form may be a constant or other expression which
9260    computes the same value, but in a more efficient manner (including
9261    calls to other builtin functions).
9262
9263    The call may contain arguments which need to be evaluated, but
9264    which are not useful to determine the result of the call.  In
9265    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
9266    COMPOUND_EXPR will be an argument which must be evaluated.
9267    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
9268    COMPOUND_EXPR in the chain will contain the tree for the simplified
9269    form of the builtin function call.  */
9270
9271 static tree
9272 simplify_builtin_strncat (tree arglist)
9273 {
9274   if (!validate_arglist (arglist,
9275                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9276     return 0;
9277   else
9278     {
9279       tree dst = TREE_VALUE (arglist);
9280       tree src = TREE_VALUE (TREE_CHAIN (arglist));
9281       tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
9282       const char *p = c_getstr (src);
9283
9284       /* If the requested length is zero, or the src parameter string
9285           length is zero, return the dst parameter.  */
9286       if (integer_zerop (len) || (p && *p == '\0'))
9287         return omit_two_operands (TREE_TYPE (dst), dst, src, len);
9288
9289       /* If the requested len is greater than or equal to the string
9290          length, call strcat.  */
9291       if (TREE_CODE (len) == INTEGER_CST && p
9292           && compare_tree_int (len, strlen (p)) >= 0)
9293         {
9294           tree newarglist
9295             = tree_cons (NULL_TREE, dst, build_tree_list (NULL_TREE, src));
9296           tree fn = implicit_built_in_decls[BUILT_IN_STRCAT];
9297
9298           /* If the replacement _DECL isn't initialized, don't do the
9299              transformation.  */
9300           if (!fn)
9301             return 0;
9302
9303           return build_function_call_expr (fn, newarglist);
9304         }
9305       return 0;
9306     }
9307 }
9308
9309 /* Simplify a call to the strspn builtin.
9310
9311    Return 0 if no simplification was possible, otherwise return the
9312    simplified form of the call as a tree.
9313
9314    The simplified form may be a constant or other expression which
9315    computes the same value, but in a more efficient manner (including
9316    calls to other builtin functions).
9317
9318    The call may contain arguments which need to be evaluated, but
9319    which are not useful to determine the result of the call.  In
9320    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
9321    COMPOUND_EXPR will be an argument which must be evaluated.
9322    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
9323    COMPOUND_EXPR in the chain will contain the tree for the simplified
9324    form of the builtin function call.  */
9325
9326 static tree
9327 simplify_builtin_strspn (tree arglist)
9328 {
9329   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9330     return 0;
9331   else
9332     {
9333       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9334       const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
9335
9336       /* If both arguments are constants, evaluate at compile-time.  */
9337       if (p1 && p2)
9338         {
9339           const size_t r = strspn (p1, p2);
9340           return size_int (r);
9341         }
9342
9343       /* If either argument is "", return 0.  */
9344       if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
9345         /* Evaluate and ignore both arguments in case either one has
9346            side-effects.  */
9347         return omit_two_operands (integer_type_node, integer_zero_node,
9348                                   s1, s2);
9349       return 0;
9350     }
9351 }
9352
9353 /* Simplify a call to the strcspn builtin.
9354
9355    Return 0 if no simplification was possible, otherwise return the
9356    simplified form of the call as a tree.
9357
9358    The simplified form may be a constant or other expression which
9359    computes the same value, but in a more efficient manner (including
9360    calls to other builtin functions).
9361
9362    The call may contain arguments which need to be evaluated, but
9363    which are not useful to determine the result of the call.  In
9364    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
9365    COMPOUND_EXPR will be an argument which must be evaluated.
9366    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
9367    COMPOUND_EXPR in the chain will contain the tree for the simplified
9368    form of the builtin function call.  */
9369
9370 static tree
9371 simplify_builtin_strcspn (tree arglist)
9372 {
9373   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9374     return 0;
9375   else
9376     {
9377       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9378       const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
9379
9380       /* If both arguments are constants, evaluate at compile-time.  */
9381       if (p1 && p2)
9382         {
9383           const size_t r = strcspn (p1, p2);
9384           return size_int (r);
9385         }
9386
9387       /* If the first argument is "", return 0.  */
9388       if (p1 && *p1 == '\0')
9389         {
9390           /* Evaluate and ignore argument s2 in case it has
9391              side-effects.  */
9392           return omit_one_operand (integer_type_node,
9393                                    integer_zero_node, s2);
9394         }
9395
9396       /* If the second argument is "", return __builtin_strlen(s1).  */
9397       if (p2 && *p2 == '\0')
9398         {
9399           tree newarglist = build_tree_list (NULL_TREE, s1),
9400             fn = implicit_built_in_decls[BUILT_IN_STRLEN];
9401
9402           /* If the replacement _DECL isn't initialized, don't do the
9403              transformation.  */
9404           if (!fn)
9405             return 0;
9406
9407           return build_function_call_expr (fn, newarglist);
9408         }
9409       return 0;
9410     }
9411 }
9412
9413 /* Fold a call to the fputs builtin.  IGNORE is true if the value returned
9414    by the builtin will be ignored.  UNLOCKED is true is true if this
9415    actually a call to fputs_unlocked.  If LEN in non-NULL, it represents
9416    the known length of the string.  Return NULL_TREE if no simplification
9417    was possible.  */
9418
9419 tree
9420 fold_builtin_fputs (tree arglist, bool ignore, bool unlocked, tree len)
9421 {
9422   tree fn;
9423   tree fn_fputc = unlocked ? implicit_built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
9424     : implicit_built_in_decls[BUILT_IN_FPUTC];
9425   tree fn_fwrite = unlocked ? implicit_built_in_decls[BUILT_IN_FWRITE_UNLOCKED]
9426     : implicit_built_in_decls[BUILT_IN_FWRITE];
9427
9428   /* If the return value is used, or the replacement _DECL isn't
9429      initialized, don't do the transformation.  */
9430   if (!ignore || !fn_fputc || !fn_fwrite)
9431     return 0;
9432
9433   /* Verify the arguments in the original call.  */
9434   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9435     return 0;
9436
9437   if (! len)
9438     len = c_strlen (TREE_VALUE (arglist), 0);
9439
9440   /* Get the length of the string passed to fputs.  If the length
9441      can't be determined, punt.  */
9442   if (!len
9443       || TREE_CODE (len) != INTEGER_CST)
9444     return 0;
9445
9446   switch (compare_tree_int (len, 1))
9447     {
9448     case -1: /* length is 0, delete the call entirely .  */
9449       return omit_one_operand (integer_type_node, integer_zero_node,
9450                                TREE_VALUE (TREE_CHAIN (arglist)));
9451
9452     case 0: /* length is 1, call fputc.  */
9453       {
9454         const char *p = c_getstr (TREE_VALUE (arglist));
9455
9456         if (p != NULL)
9457           {
9458             /* New argument list transforming fputs(string, stream) to
9459                fputc(string[0], stream).  */
9460             arglist =
9461               build_tree_list (NULL_TREE, TREE_VALUE (TREE_CHAIN (arglist)));
9462             arglist = tree_cons (NULL_TREE, build_int_2 (p[0], 0), arglist);
9463             fn = fn_fputc;
9464             break;
9465           }
9466       }
9467       /* FALLTHROUGH */
9468     case 1: /* length is greater than 1, call fwrite.  */
9469       {
9470         tree string_arg;
9471
9472         /* If optimizing for size keep fputs.  */
9473         if (optimize_size)
9474           return 0;
9475         string_arg = TREE_VALUE (arglist);
9476         /* New argument list transforming fputs(string, stream) to
9477            fwrite(string, 1, len, stream).  */
9478         arglist = build_tree_list (NULL_TREE,
9479                                    TREE_VALUE (TREE_CHAIN (arglist)));
9480         arglist = tree_cons (NULL_TREE, len, arglist);
9481         arglist = tree_cons (NULL_TREE, size_one_node, arglist);
9482         arglist = tree_cons (NULL_TREE, string_arg, arglist);
9483         fn = fn_fwrite;
9484         break;
9485       }
9486     default:
9487       abort ();
9488     }
9489
9490   return fold_convert (integer_type_node,
9491                        build_function_call_expr (fn, arglist));
9492 }
9493
9494 static void
9495 simplify_builtin_va_start (tree arglist)
9496 {
9497   tree chain = TREE_CHAIN (arglist);
9498
9499   if (TREE_CHAIN (chain))
9500     error ("too many arguments to function `va_start'");
9501
9502   simplify_builtin_next_arg (chain);
9503 }
9504
9505 static void
9506 simplify_builtin_next_arg (tree arglist)
9507 {
9508   tree fntype = TREE_TYPE (current_function_decl);
9509
9510   if (TYPE_ARG_TYPES (fntype) == 0
9511       || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
9512           == void_type_node))
9513     error ("`va_start' used in function with fixed args");
9514   else if (arglist)
9515     {
9516       tree last_parm = tree_last (DECL_ARGUMENTS (current_function_decl));
9517       tree arg = TREE_VALUE (arglist);
9518
9519       /* Strip off all nops for the sake of the comparison.  This
9520          is not quite the same as STRIP_NOPS.  It does more.
9521          We must also strip off INDIRECT_EXPR for C++ reference
9522          parameters.  */
9523       while (TREE_CODE (arg) == NOP_EXPR
9524              || TREE_CODE (arg) == CONVERT_EXPR
9525              || TREE_CODE (arg) == NON_LVALUE_EXPR
9526              || TREE_CODE (arg) == INDIRECT_REF)
9527         arg = TREE_OPERAND (arg, 0);
9528       if (arg != last_parm)
9529         warning ("second parameter of `va_start' not last named argument");
9530       TREE_VALUE (arglist) = arg;
9531     }
9532   else
9533     /* Evidently an out of date version of <stdarg.h>; can't validate
9534        va_start's second argument, but can still work as intended.  */
9535     warning ("`__builtin_next_arg' called without an argument");
9536 }
9537
9538
9539 /* Simplify a call to the sprintf builtin.
9540
9541    Return 0 if no simplification was possible, otherwise return the
9542    simplified form of the call as a tree.  If IGNORED is true, it means that
9543    the caller does not use the returned value of the function.  */
9544
9545 static tree
9546 simplify_builtin_sprintf (tree arglist, int ignored)
9547 {
9548   tree call, retval, dest, fmt;
9549   const char *fmt_str = NULL;
9550
9551   /* Verify the required arguments in the original call.  We deal with two
9552      types of sprintf() calls: 'sprintf (str, fmt)' and
9553      'sprintf (dest, "%s", orig)'.  */
9554   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)
9555       && !validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, POINTER_TYPE,
9556                             VOID_TYPE))
9557     return NULL_TREE;
9558
9559   /* Get the destination string and the format specifier.  */
9560   dest = TREE_VALUE (arglist);
9561   fmt = TREE_VALUE (TREE_CHAIN (arglist));
9562
9563   /* Check whether the format is a literal string constant.  */
9564   fmt_str = c_getstr (fmt);
9565   if (fmt_str == NULL)
9566     return NULL_TREE;
9567
9568   call = NULL_TREE;
9569   retval = NULL_TREE;
9570
9571   /* If the format doesn't contain % args or %%, use strcpy.  */
9572   if (strchr (fmt_str, '%') == NULL)
9573     {
9574       tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
9575
9576       if (!fn)
9577         return NULL_TREE;
9578
9579       /* Convert sprintf (str, fmt) into strcpy (str, fmt) when
9580          'format' is known to contain no % formats.  */
9581       arglist = build_tree_list (NULL_TREE, fmt);
9582       arglist = tree_cons (NULL_TREE, dest, arglist);
9583       call = build_function_call_expr (fn, arglist);
9584       if (!ignored)
9585         retval = build_int_2 (strlen (fmt_str), 0);
9586     }
9587
9588   /* If the format is "%s", use strcpy if the result isn't used.  */
9589   else if (fmt_str && strcmp (fmt_str, "%s") == 0)
9590     {
9591       tree fn, orig;
9592       fn = implicit_built_in_decls[BUILT_IN_STRCPY];
9593
9594       if (!fn)
9595         return NULL_TREE;
9596
9597       /* Convert sprintf (str1, "%s", str2) into strcpy (str1, str2).  */
9598       orig = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
9599       arglist = build_tree_list (NULL_TREE, orig);
9600       arglist = tree_cons (NULL_TREE, dest, arglist);
9601       if (!ignored)
9602         {
9603           retval = c_strlen (orig, 1);
9604           if (!retval || TREE_CODE (retval) != INTEGER_CST)
9605             return NULL_TREE;
9606         }
9607       call = build_function_call_expr (fn, arglist);
9608     }
9609
9610   if (call && retval)
9611     {
9612       retval = convert
9613         (TREE_TYPE (TREE_TYPE (implicit_built_in_decls[BUILT_IN_SPRINTF])),
9614          retval);
9615       return build2 (COMPOUND_EXPR, TREE_TYPE (retval), call, retval);
9616     }
9617   else
9618     return call;
9619 }