OSDN Git Service

* target.h (struct gcc_target): Move gimplify_va_arg_expr
[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, lenp1;
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       lenp1 = size_binop (PLUS_EXPR, len, ssize_int (1));
3121       narglist = build_tree_list (NULL_TREE, lenp1);
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, rounded_size, valist_tmp;
4477   unsigned HOST_WIDE_INT align, boundary;
4478
4479 #ifdef ARGS_GROW_DOWNWARD
4480   /* All of the alignment and movement below is for args-grow-up machines.
4481      As of 2004, there are only 3 ARGS_GROW_DOWNWARD targets, and they all
4482      implement their own specialized gimplify_va_arg_expr routines.  */
4483   abort ();
4484 #endif
4485
4486   align = PARM_BOUNDARY / BITS_PER_UNIT;
4487   boundary = FUNCTION_ARG_BOUNDARY (TYPE_MODE (type), type) / BITS_PER_UNIT;
4488
4489   /* Hoist the valist value into a temporary for the moment.  */
4490   valist_tmp = get_initialized_tmp_var (valist, pre_p, NULL);
4491
4492   /* va_list pointer is aligned to PARM_BOUNDARY.  If argument actually
4493      requires greater alignment, we must perform dynamic alignment.  */
4494   if (boundary > align)
4495     {
4496       t = fold_convert (TREE_TYPE (valist), size_int (boundary - 1));
4497       t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
4498                   build2 (PLUS_EXPR, TREE_TYPE (valist), valist_tmp, t));
4499       gimplify_and_add (t, pre_p);
4500
4501       t = fold_convert (TREE_TYPE (valist), size_int (-boundary));
4502       t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
4503                   build2 (BIT_AND_EXPR, TREE_TYPE (valist), valist_tmp, t));
4504       gimplify_and_add (t, pre_p);
4505     }
4506
4507   /* Compute the rounded size of the type.  */
4508   type_size = size_in_bytes (type);
4509   rounded_size = round_up (type_size, align);
4510
4511   /* Reduce rounded_size so it's sharable with the postqueue.  */
4512   gimplify_expr (&rounded_size, pre_p, post_p, is_gimple_val, fb_rvalue);
4513
4514   /* Get AP.  */
4515   addr = valist_tmp;
4516   if (PAD_VARARGS_DOWN && !integer_zerop (rounded_size))
4517     {
4518       /* Small args are padded downward.  */
4519       t = fold (build2 (GT_EXPR, sizetype, rounded_size, size_int (align)));
4520       t = fold (build3 (COND_EXPR, sizetype, t, size_zero_node,
4521                         size_binop (MINUS_EXPR, rounded_size, type_size)));
4522       t = fold_convert (TREE_TYPE (addr), t);
4523       addr = fold (build2 (PLUS_EXPR, TREE_TYPE (addr), addr, t));
4524     }
4525
4526   /* Compute new value for AP.  */
4527   t = fold_convert (TREE_TYPE (valist), rounded_size);
4528   t = build2 (PLUS_EXPR, TREE_TYPE (valist), valist_tmp, t);
4529   t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist, t);
4530   gimplify_and_add (t, pre_p);
4531
4532   addr = fold_convert (build_pointer_type (type), addr);
4533   return build_fold_indirect_ref (addr);
4534 }
4535
4536 /* Like std_gimplify_va_arg_expr, but uses pass-by-reference.  */
4537  
4538 tree
4539 ind_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p, tree *post_p)
4540 {
4541   tree t;
4542   t = build_pointer_type (type);
4543   t = std_gimplify_va_arg_expr (valist, t, pre_p, post_p);
4544   return build_fold_indirect_ref (t);
4545 }
4546
4547 /* Return a dummy expression of type TYPE in order to keep going after an
4548    error.  */
4549
4550 static tree
4551 dummy_object (tree type)
4552 {
4553   tree t = convert (build_pointer_type (type), null_pointer_node);
4554   return build1 (INDIRECT_REF, type, t);
4555 }
4556
4557 /* Like expand_builtin_va_arg, but gimplify instead of expanding.  */
4558
4559 enum gimplify_status
4560 gimplify_va_arg_expr (tree *expr_p, tree *pre_p, tree *post_p)
4561 {
4562   tree promoted_type, want_va_type, have_va_type;
4563   tree valist = TREE_OPERAND (*expr_p, 0);
4564   tree type = TREE_TYPE (*expr_p);
4565   tree t;
4566
4567   /* Verify that valist is of the proper type.  */
4568   want_va_type = va_list_type_node;
4569   have_va_type = TREE_TYPE (valist);
4570
4571   if (have_va_type == error_mark_node)
4572     return GS_ERROR;
4573
4574   if (TREE_CODE (want_va_type) == ARRAY_TYPE)
4575     {
4576       /* If va_list is an array type, the argument may have decayed
4577          to a pointer type, e.g. by being passed to another function.
4578          In that case, unwrap both types so that we can compare the
4579          underlying records.  */
4580       if (TREE_CODE (have_va_type) == ARRAY_TYPE
4581           || TREE_CODE (have_va_type) == POINTER_TYPE)
4582         {
4583           want_va_type = TREE_TYPE (want_va_type);
4584           have_va_type = TREE_TYPE (have_va_type);
4585         }
4586     }
4587
4588   if (TYPE_MAIN_VARIANT (want_va_type) != TYPE_MAIN_VARIANT (have_va_type))
4589     {
4590       error ("first argument to `va_arg' not of type `va_list'");
4591       return GS_ERROR;
4592     }
4593
4594   /* Generate a diagnostic for requesting data of a type that cannot
4595      be passed through `...' due to type promotion at the call site.  */
4596   else if ((promoted_type = lang_hooks.types.type_promotes_to (type))
4597            != type)
4598     {
4599       static bool gave_help;
4600
4601       /* Unfortunately, this is merely undefined, rather than a constraint
4602          violation, so we cannot make this an error.  If this call is never
4603          executed, the program is still strictly conforming.  */
4604       warning ("`%T' is promoted to `%T' when passed through `...'",
4605                type, promoted_type);
4606       if (! gave_help)
4607         {
4608           gave_help = true;
4609           warning ("(so you should pass `%T' not `%T' to `va_arg')",
4610                    promoted_type, type);
4611         }
4612
4613       /* We can, however, treat "undefined" any way we please.
4614          Call abort to encourage the user to fix the program.  */
4615       inform ("if this code is reached, the program will abort");
4616       t = build_function_call_expr (implicit_built_in_decls[BUILT_IN_TRAP],
4617                                     NULL);
4618       append_to_statement_list (t, pre_p);
4619
4620       /* This is dead code, but go ahead and finish so that the
4621          mode of the result comes out right.  */
4622       *expr_p = dummy_object (type);
4623       return GS_ALL_DONE;
4624     }
4625   else
4626     {
4627       /* Make it easier for the backends by protecting the valist argument
4628          from multiple evaluations.  */
4629       if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
4630         {
4631           /* For this case, the backends will be expecting a pointer to
4632              TREE_TYPE (va_list_type_node), but it's possible we've
4633              actually been given an array (an actual va_list_type_node).
4634              So fix it.  */
4635           if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
4636             {
4637               tree p1 = build_pointer_type (TREE_TYPE (va_list_type_node));
4638               valist = build_fold_addr_expr_with_type (valist, p1);
4639             }
4640           gimplify_expr (&valist, pre_p, post_p, is_gimple_val, fb_rvalue);
4641         }
4642       else
4643         gimplify_expr (&valist, pre_p, post_p, is_gimple_min_lval, fb_lvalue);
4644
4645       if (!targetm.gimplify_va_arg_expr)
4646         /* Once most targets are converted this should abort.  */
4647         return GS_ALL_DONE;
4648
4649       *expr_p = targetm.gimplify_va_arg_expr (valist, type, pre_p, post_p);
4650       return GS_OK;
4651     }
4652 }
4653
4654 /* Expand ARGLIST, from a call to __builtin_va_end.  */
4655
4656 static rtx
4657 expand_builtin_va_end (tree arglist)
4658 {
4659   tree valist = TREE_VALUE (arglist);
4660
4661   /* Evaluate for side effects, if needed.  I hate macros that don't
4662      do that.  */
4663   if (TREE_SIDE_EFFECTS (valist))
4664     expand_expr (valist, const0_rtx, VOIDmode, EXPAND_NORMAL);
4665
4666   return const0_rtx;
4667 }
4668
4669 /* Expand ARGLIST, from a call to __builtin_va_copy.  We do this as a
4670    builtin rather than just as an assignment in stdarg.h because of the
4671    nastiness of array-type va_list types.  */
4672
4673 static rtx
4674 expand_builtin_va_copy (tree arglist)
4675 {
4676   tree dst, src, t;
4677
4678   dst = TREE_VALUE (arglist);
4679   src = TREE_VALUE (TREE_CHAIN (arglist));
4680
4681   dst = stabilize_va_list (dst, 1);
4682   src = stabilize_va_list (src, 0);
4683
4684   if (TREE_CODE (va_list_type_node) != ARRAY_TYPE)
4685     {
4686       t = build2 (MODIFY_EXPR, va_list_type_node, dst, src);
4687       TREE_SIDE_EFFECTS (t) = 1;
4688       expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4689     }
4690   else
4691     {
4692       rtx dstb, srcb, size;
4693
4694       /* Evaluate to pointers.  */
4695       dstb = expand_expr (dst, NULL_RTX, Pmode, EXPAND_NORMAL);
4696       srcb = expand_expr (src, NULL_RTX, Pmode, EXPAND_NORMAL);
4697       size = expand_expr (TYPE_SIZE_UNIT (va_list_type_node), NULL_RTX,
4698                           VOIDmode, EXPAND_NORMAL);
4699
4700       dstb = convert_memory_address (Pmode, dstb);
4701       srcb = convert_memory_address (Pmode, srcb);
4702
4703       /* "Dereference" to BLKmode memories.  */
4704       dstb = gen_rtx_MEM (BLKmode, dstb);
4705       set_mem_alias_set (dstb, get_alias_set (TREE_TYPE (TREE_TYPE (dst))));
4706       set_mem_align (dstb, TYPE_ALIGN (va_list_type_node));
4707       srcb = gen_rtx_MEM (BLKmode, srcb);
4708       set_mem_alias_set (srcb, get_alias_set (TREE_TYPE (TREE_TYPE (src))));
4709       set_mem_align (srcb, TYPE_ALIGN (va_list_type_node));
4710
4711       /* Copy.  */
4712       emit_block_move (dstb, srcb, size, BLOCK_OP_NORMAL);
4713     }
4714
4715   return const0_rtx;
4716 }
4717
4718 /* Expand a call to one of the builtin functions __builtin_frame_address or
4719    __builtin_return_address.  */
4720
4721 static rtx
4722 expand_builtin_frame_address (tree fndecl, tree arglist)
4723 {
4724   /* The argument must be a nonnegative integer constant.
4725      It counts the number of frames to scan up the stack.
4726      The value is the return address saved in that frame.  */
4727   if (arglist == 0)
4728     /* Warning about missing arg was already issued.  */
4729     return const0_rtx;
4730   else if (! host_integerp (TREE_VALUE (arglist), 1))
4731     {
4732       if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4733         error ("invalid arg to `__builtin_frame_address'");
4734       else
4735         error ("invalid arg to `__builtin_return_address'");
4736       return const0_rtx;
4737     }
4738   else
4739     {
4740       rtx tem
4741         = expand_builtin_return_addr (DECL_FUNCTION_CODE (fndecl),
4742                                       tree_low_cst (TREE_VALUE (arglist), 1),
4743                                       hard_frame_pointer_rtx);
4744
4745       /* Some ports cannot access arbitrary stack frames.  */
4746       if (tem == NULL)
4747         {
4748           if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4749             warning ("unsupported arg to `__builtin_frame_address'");
4750           else
4751             warning ("unsupported arg to `__builtin_return_address'");
4752           return const0_rtx;
4753         }
4754
4755       /* For __builtin_frame_address, return what we've got.  */
4756       if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4757         return tem;
4758
4759       if (!REG_P (tem)
4760           && ! CONSTANT_P (tem))
4761         tem = copy_to_mode_reg (Pmode, tem);
4762       return tem;
4763     }
4764 }
4765
4766 /* Expand a call to the alloca builtin, with arguments ARGLIST.  Return 0 if
4767    we failed and the caller should emit a normal call, otherwise try to get
4768    the result in TARGET, if convenient.  */
4769
4770 static rtx
4771 expand_builtin_alloca (tree arglist, rtx target)
4772 {
4773   rtx op0;
4774   rtx result;
4775
4776   /* In -fmudflap-instrumented code, alloca() and __builtin_alloca()
4777      should always expand to function calls.  These can be intercepted
4778      in libmudflap.  */
4779   if (flag_mudflap)
4780     return 0;
4781
4782   if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
4783     return 0;
4784
4785   /* Compute the argument.  */
4786   op0 = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
4787
4788   /* Allocate the desired space.  */
4789   result = allocate_dynamic_stack_space (op0, target, BITS_PER_UNIT);
4790   result = convert_memory_address (ptr_mode, result);
4791
4792   return result;
4793 }
4794
4795 /* Expand a call to a unary builtin.  The arguments are in ARGLIST.
4796    Return 0 if a normal call should be emitted rather than expanding the
4797    function in-line.  If convenient, the result should be placed in TARGET.
4798    SUBTARGET may be used as the target for computing one of EXP's operands.  */
4799
4800 static rtx
4801 expand_builtin_unop (enum machine_mode target_mode, tree arglist, rtx target,
4802                      rtx subtarget, optab op_optab)
4803 {
4804   rtx op0;
4805   if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
4806     return 0;
4807
4808   /* Compute the argument.  */
4809   op0 = expand_expr (TREE_VALUE (arglist), subtarget, VOIDmode, 0);
4810   /* Compute op, into TARGET if possible.
4811      Set TARGET to wherever the result comes back.  */
4812   target = expand_unop (TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist))),
4813                         op_optab, op0, target, 1);
4814   if (target == 0)
4815     abort ();
4816
4817   return convert_to_mode (target_mode, target, 0);
4818 }
4819
4820 /* If the string passed to fputs is a constant and is one character
4821    long, we attempt to transform this call into __builtin_fputc().  */
4822
4823 static rtx
4824 expand_builtin_fputs (tree arglist, rtx target, bool unlocked)
4825 {
4826   tree len, fn;
4827   tree fn_fputc = unlocked ? implicit_built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
4828     : implicit_built_in_decls[BUILT_IN_FPUTC];
4829   tree fn_fwrite = unlocked ? implicit_built_in_decls[BUILT_IN_FWRITE_UNLOCKED]
4830     : implicit_built_in_decls[BUILT_IN_FWRITE];
4831
4832   /* If the return value is used, or the replacement _DECL isn't
4833      initialized, don't do the transformation.  */
4834   if (target != const0_rtx || !fn_fputc || !fn_fwrite)
4835     return 0;
4836
4837   /* Verify the arguments in the original call.  */
4838   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4839     return 0;
4840
4841   /* Get the length of the string passed to fputs.  If the length
4842      can't be determined, punt.  */
4843   if (!(len = c_strlen (TREE_VALUE (arglist), 1))
4844       || TREE_CODE (len) != INTEGER_CST)
4845     return 0;
4846
4847   switch (compare_tree_int (len, 1))
4848     {
4849     case -1: /* length is 0, delete the call entirely .  */
4850       {
4851         /* Evaluate and ignore the argument in case it has
4852            side-effects.  */
4853         expand_expr (TREE_VALUE (TREE_CHAIN (arglist)), const0_rtx,
4854                      VOIDmode, EXPAND_NORMAL);
4855         return const0_rtx;
4856       }
4857     case 0: /* length is 1, call fputc.  */
4858       {
4859         const char *p = c_getstr (TREE_VALUE (arglist));
4860
4861         if (p != NULL)
4862           {
4863             /* New argument list transforming fputs(string, stream) to
4864                fputc(string[0], stream).  */
4865             arglist =
4866               build_tree_list (NULL_TREE, TREE_VALUE (TREE_CHAIN (arglist)));
4867             arglist =
4868               tree_cons (NULL_TREE, build_int_2 (p[0], 0), arglist);
4869             fn = fn_fputc;
4870             break;
4871           }
4872       }
4873       /* Fall through.  */
4874     case 1: /* length is greater than 1, call fwrite.  */
4875       {
4876         tree string_arg;
4877
4878         /* If optimizing for size keep fputs.  */
4879         if (optimize_size)
4880           return 0;
4881         string_arg = TREE_VALUE (arglist);
4882         /* New argument list transforming fputs(string, stream) to
4883            fwrite(string, 1, len, stream).  */
4884         arglist = build_tree_list (NULL_TREE, TREE_VALUE (TREE_CHAIN (arglist)));
4885         arglist = tree_cons (NULL_TREE, len, arglist);
4886         arglist = tree_cons (NULL_TREE, size_one_node, arglist);
4887         arglist = tree_cons (NULL_TREE, string_arg, arglist);
4888         fn = fn_fwrite;
4889         break;
4890       }
4891     default:
4892       abort ();
4893     }
4894
4895   return expand_expr (build_function_call_expr (fn, arglist),
4896                       const0_rtx, VOIDmode, EXPAND_NORMAL);
4897 }
4898
4899 /* Expand a call to __builtin_expect.  We return our argument and emit a
4900    NOTE_INSN_EXPECTED_VALUE note.  This is the expansion of __builtin_expect in
4901    a non-jump context.  */
4902
4903 static rtx
4904 expand_builtin_expect (tree arglist, rtx target)
4905 {
4906   tree exp, c;
4907   rtx note, rtx_c;
4908
4909   if (arglist == NULL_TREE
4910       || TREE_CHAIN (arglist) == NULL_TREE)
4911     return const0_rtx;
4912   exp = TREE_VALUE (arglist);
4913   c = TREE_VALUE (TREE_CHAIN (arglist));
4914
4915   if (TREE_CODE (c) != INTEGER_CST)
4916     {
4917       error ("second arg to `__builtin_expect' must be a constant");
4918       c = integer_zero_node;
4919     }
4920
4921   target = expand_expr (exp, target, VOIDmode, EXPAND_NORMAL);
4922
4923   /* Don't bother with expected value notes for integral constants.  */
4924   if (flag_guess_branch_prob && GET_CODE (target) != CONST_INT)
4925     {
4926       /* We do need to force this into a register so that we can be
4927          moderately sure to be able to correctly interpret the branch
4928          condition later.  */
4929       target = force_reg (GET_MODE (target), target);
4930
4931       rtx_c = expand_expr (c, NULL_RTX, GET_MODE (target), EXPAND_NORMAL);
4932
4933       note = emit_note (NOTE_INSN_EXPECTED_VALUE);
4934       NOTE_EXPECTED_VALUE (note) = gen_rtx_EQ (VOIDmode, target, rtx_c);
4935     }
4936
4937   return target;
4938 }
4939
4940 /* Like expand_builtin_expect, except do this in a jump context.  This is
4941    called from do_jump if the conditional is a __builtin_expect.  Return either
4942    a list of insns to emit the jump or NULL if we cannot optimize
4943    __builtin_expect.  We need to optimize this at jump time so that machines
4944    like the PowerPC don't turn the test into a SCC operation, and then jump
4945    based on the test being 0/1.  */
4946
4947 rtx
4948 expand_builtin_expect_jump (tree exp, rtx if_false_label, rtx if_true_label)
4949 {
4950   tree arglist = TREE_OPERAND (exp, 1);
4951   tree arg0 = TREE_VALUE (arglist);
4952   tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
4953   rtx ret = NULL_RTX;
4954
4955   /* Only handle __builtin_expect (test, 0) and
4956      __builtin_expect (test, 1).  */
4957   if (TREE_CODE (TREE_TYPE (arg1)) == INTEGER_TYPE
4958       && (integer_zerop (arg1) || integer_onep (arg1)))
4959     {
4960       rtx insn, drop_through_label, temp;
4961
4962       /* Expand the jump insns.  */
4963       start_sequence ();
4964       do_jump (arg0, if_false_label, if_true_label);
4965       ret = get_insns ();
4966
4967       drop_through_label = get_last_insn ();
4968       if (drop_through_label && NOTE_P (drop_through_label))
4969         drop_through_label = prev_nonnote_insn (drop_through_label);
4970       if (drop_through_label && !LABEL_P (drop_through_label))
4971         drop_through_label = NULL_RTX;
4972       end_sequence ();
4973
4974       if (! if_true_label)
4975         if_true_label = drop_through_label;
4976       if (! if_false_label)
4977         if_false_label = drop_through_label;
4978
4979       /* Go through and add the expect's to each of the conditional jumps.  */
4980       insn = ret;
4981       while (insn != NULL_RTX)
4982         {
4983           rtx next = NEXT_INSN (insn);
4984
4985           if (JUMP_P (insn) && any_condjump_p (insn))
4986             {
4987               rtx ifelse = SET_SRC (pc_set (insn));
4988               rtx then_dest = XEXP (ifelse, 1);
4989               rtx else_dest = XEXP (ifelse, 2);
4990               int taken = -1;
4991
4992               /* First check if we recognize any of the labels.  */
4993               if (GET_CODE (then_dest) == LABEL_REF
4994                   && XEXP (then_dest, 0) == if_true_label)
4995                 taken = 1;
4996               else if (GET_CODE (then_dest) == LABEL_REF
4997                        && XEXP (then_dest, 0) == if_false_label)
4998                 taken = 0;
4999               else if (GET_CODE (else_dest) == LABEL_REF
5000                        && XEXP (else_dest, 0) == if_false_label)
5001                 taken = 1;
5002               else if (GET_CODE (else_dest) == LABEL_REF
5003                        && XEXP (else_dest, 0) == if_true_label)
5004                 taken = 0;
5005               /* Otherwise check where we drop through.  */
5006               else if (else_dest == pc_rtx)
5007                 {
5008                   if (next && NOTE_P (next))
5009                     next = next_nonnote_insn (next);
5010
5011                   if (next && JUMP_P (next)
5012                       && any_uncondjump_p (next))
5013                     temp = XEXP (SET_SRC (pc_set (next)), 0);
5014                   else
5015                     temp = next;
5016
5017                   /* TEMP is either a CODE_LABEL, NULL_RTX or something
5018                      else that can't possibly match either target label.  */
5019                   if (temp == if_false_label)
5020                     taken = 1;
5021                   else if (temp == if_true_label)
5022                     taken = 0;
5023                 }
5024               else if (then_dest == pc_rtx)
5025                 {
5026                   if (next && NOTE_P (next))
5027                     next = next_nonnote_insn (next);
5028
5029                   if (next && JUMP_P (next)
5030                       && any_uncondjump_p (next))
5031                     temp = XEXP (SET_SRC (pc_set (next)), 0);
5032                   else
5033                     temp = next;
5034
5035                   if (temp == if_false_label)
5036                     taken = 0;
5037                   else if (temp == if_true_label)
5038                     taken = 1;
5039                 }
5040
5041               if (taken != -1)
5042                 {
5043                   /* If the test is expected to fail, reverse the
5044                      probabilities.  */
5045                   if (integer_zerop (arg1))
5046                     taken = 1 - taken;
5047                   predict_insn_def (insn, PRED_BUILTIN_EXPECT, taken);
5048                 }
5049             }
5050
5051           insn = next;
5052         }
5053     }
5054
5055   return ret;
5056 }
5057
5058 void
5059 expand_builtin_trap (void)
5060 {
5061 #ifdef HAVE_trap
5062   if (HAVE_trap)
5063     emit_insn (gen_trap ());
5064   else
5065 #endif
5066     emit_library_call (abort_libfunc, LCT_NORETURN, VOIDmode, 0);
5067   emit_barrier ();
5068 }
5069
5070 /* Expand a call to fabs, fabsf or fabsl with arguments ARGLIST.
5071    Return 0 if a normal call should be emitted rather than expanding
5072    the function inline.  If convenient, the result should be placed
5073    in TARGET.  SUBTARGET may be used as the target for computing
5074    the operand.  */
5075
5076 static rtx
5077 expand_builtin_fabs (tree arglist, rtx target, rtx subtarget)
5078 {
5079   enum machine_mode mode;
5080   tree arg;
5081   rtx op0;
5082
5083   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
5084     return 0;
5085
5086   arg = TREE_VALUE (arglist);
5087   mode = TYPE_MODE (TREE_TYPE (arg));
5088   op0 = expand_expr (arg, subtarget, VOIDmode, 0);
5089   return expand_abs (mode, op0, target, 0, safe_from_p (target, arg, 1));
5090 }
5091
5092 /* Expand a call to cabs, cabsf or cabsl with arguments ARGLIST.
5093    Return 0 if a normal call should be emitted rather than expanding
5094    the function inline.  If convenient, the result should be placed
5095    in target.  */
5096
5097 static rtx
5098 expand_builtin_cabs (tree arglist, rtx target)
5099 {
5100   enum machine_mode mode;
5101   tree arg;
5102   rtx op0;
5103
5104   if (arglist == 0 || TREE_CHAIN (arglist))
5105     return 0;
5106   arg = TREE_VALUE (arglist);
5107   if (TREE_CODE (TREE_TYPE (arg)) != COMPLEX_TYPE
5108       || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) != REAL_TYPE)
5109     return 0;
5110
5111   mode = TYPE_MODE (TREE_TYPE (arg));
5112   op0 = expand_expr (arg, NULL_RTX, VOIDmode, 0);
5113   return expand_complex_abs (mode, op0, target, 0);
5114 }
5115
5116 /* Create a new constant string literal and return a char* pointer to it.
5117    The STRING_CST value is the LEN characters at STR.  */
5118 static tree
5119 build_string_literal (int len, const char *str)
5120 {
5121   tree t, elem, index, type;
5122
5123   t = build_string (len, str);
5124   elem = build_type_variant (char_type_node, 1, 0);
5125   index = build_index_type (build_int_2 (len - 1, 0));
5126   type = build_array_type (elem, index);
5127   TREE_TYPE (t) = type;
5128   TREE_CONSTANT (t) = 1;
5129   TREE_INVARIANT (t) = 1;
5130   TREE_READONLY (t) = 1;
5131   TREE_STATIC (t) = 1;
5132
5133   type = build_pointer_type (type);
5134   t = build1 (ADDR_EXPR, type, t);
5135
5136   type = build_pointer_type (elem);
5137   t = build1 (NOP_EXPR, type, t);
5138   return t;
5139 }
5140
5141 /* Expand a call to printf or printf_unlocked with argument list ARGLIST.
5142    Return 0 if a normal call should be emitted rather than transforming
5143    the function inline.  If convenient, the result should be placed in
5144    TARGET with mode MODE.  UNLOCKED indicates this is a printf_unlocked
5145    call.  */
5146 static rtx
5147 expand_builtin_printf (tree arglist, rtx target, enum machine_mode mode,
5148                        bool unlocked)
5149 {
5150   tree fn_putchar = unlocked
5151                     ? implicit_built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED]
5152                     : implicit_built_in_decls[BUILT_IN_PUTCHAR];
5153   tree fn_puts = unlocked ? implicit_built_in_decls[BUILT_IN_PUTS_UNLOCKED]
5154                           : implicit_built_in_decls[BUILT_IN_PUTS];
5155   const char *fmt_str;
5156   tree fn, fmt, arg;
5157
5158   /* If the return value is used, don't do the transformation.  */
5159   if (target != const0_rtx)
5160     return 0;
5161
5162   /* Verify the required arguments in the original call.  */
5163   if (! arglist)
5164     return 0;
5165   fmt = TREE_VALUE (arglist);
5166   if (TREE_CODE (TREE_TYPE (fmt)) != POINTER_TYPE)
5167     return 0;
5168   arglist = TREE_CHAIN (arglist);
5169
5170   /* Check whether the format is a literal string constant.  */
5171   fmt_str = c_getstr (fmt);
5172   if (fmt_str == NULL)
5173     return 0;
5174
5175   /* If the format specifier was "%s\n", call __builtin_puts(arg).  */
5176   if (strcmp (fmt_str, "%s\n") == 0)
5177     {
5178       if (! arglist
5179           || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE
5180           || TREE_CHAIN (arglist))
5181         return 0;
5182       fn = fn_puts;
5183     }
5184   /* If the format specifier was "%c", call __builtin_putchar(arg).  */
5185   else if (strcmp (fmt_str, "%c") == 0)
5186     {
5187       if (! arglist
5188           || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
5189           || TREE_CHAIN (arglist))
5190         return 0;
5191       fn = fn_putchar;
5192     }
5193   else
5194     {
5195       /* We can't handle anything else with % args or %% ... yet.  */
5196       if (strchr (fmt_str, '%'))
5197         return 0;
5198
5199       if (arglist)
5200         return 0;
5201
5202       /* If the format specifier was "", printf does nothing.  */
5203       if (fmt_str[0] == '\0')
5204         return const0_rtx;
5205       /* If the format specifier has length of 1, call putchar.  */
5206       if (fmt_str[1] == '\0')
5207         {
5208           /* Given printf("c"), (where c is any one character,)
5209              convert "c"[0] to an int and pass that to the replacement
5210              function.  */
5211           arg = build_int_2 (fmt_str[0], 0);
5212           arglist = build_tree_list (NULL_TREE, arg);
5213           fn = fn_putchar;
5214         }
5215       else
5216         {
5217           /* If the format specifier was "string\n", call puts("string").  */
5218           size_t len = strlen (fmt_str);
5219           if (fmt_str[len - 1] == '\n')
5220             {
5221               /* Create a NUL-terminated string that's one char shorter
5222                  than the original, stripping off the trailing '\n'.  */
5223               char *newstr = alloca (len);
5224               memcpy (newstr, fmt_str, len - 1);
5225               newstr[len - 1] = 0;
5226
5227               arg = build_string_literal (len, newstr);
5228               arglist = build_tree_list (NULL_TREE, arg);
5229               fn = fn_puts;
5230             }
5231           else
5232             /* We'd like to arrange to call fputs(string,stdout) here,
5233                but we need stdout and don't have a way to get it yet.  */
5234             return 0;
5235         }
5236     }
5237
5238   if (!fn)
5239     return 0;
5240   return expand_expr (build_function_call_expr (fn, arglist),
5241                       target, mode, EXPAND_NORMAL);
5242 }
5243
5244 /* Expand a call to fprintf or fprintf_unlocked with argument list ARGLIST.
5245    Return 0 if a normal call should be emitted rather than transforming
5246    the function inline.  If convenient, the result should be placed in
5247    TARGET with mode MODE.  UNLOCKED indicates this is a fprintf_unlocked
5248    call.  */
5249 static rtx
5250 expand_builtin_fprintf (tree arglist, rtx target, enum machine_mode mode,
5251                         bool unlocked)
5252 {
5253   tree fn_fputc = unlocked ? implicit_built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
5254                            : implicit_built_in_decls[BUILT_IN_FPUTC];
5255   tree fn_fputs = unlocked ? implicit_built_in_decls[BUILT_IN_FPUTS_UNLOCKED]
5256                            : implicit_built_in_decls[BUILT_IN_FPUTS];
5257   const char *fmt_str;
5258   tree fn, fmt, fp, arg;
5259
5260   /* If the return value is used, don't do the transformation.  */
5261   if (target != const0_rtx)
5262     return 0;
5263
5264   /* Verify the required arguments in the original call.  */
5265   if (! arglist)
5266     return 0;
5267   fp = TREE_VALUE (arglist);
5268   if (TREE_CODE (TREE_TYPE (fp)) != POINTER_TYPE)
5269     return 0;
5270   arglist = TREE_CHAIN (arglist);
5271   if (! arglist)
5272     return 0;
5273   fmt = TREE_VALUE (arglist);
5274   if (TREE_CODE (TREE_TYPE (fmt)) != POINTER_TYPE)
5275     return 0;
5276   arglist = TREE_CHAIN (arglist);
5277
5278   /* Check whether the format is a literal string constant.  */
5279   fmt_str = c_getstr (fmt);
5280   if (fmt_str == NULL)
5281     return 0;
5282
5283   /* If the format specifier was "%s", call __builtin_fputs(arg,fp).  */
5284   if (strcmp (fmt_str, "%s") == 0)
5285     {
5286       if (! arglist
5287           || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE
5288           || TREE_CHAIN (arglist))
5289         return 0;
5290       arg = TREE_VALUE (arglist);
5291       arglist = build_tree_list (NULL_TREE, fp);
5292       arglist = tree_cons (NULL_TREE, arg, arglist);
5293       fn = fn_fputs;
5294     }
5295   /* If the format specifier was "%c", call __builtin_fputc(arg,fp).  */
5296   else if (strcmp (fmt_str, "%c") == 0)
5297     {
5298       if (! arglist
5299           || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_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_fputc;
5306     }
5307   else
5308     {
5309       /* We can't handle anything else with % args or %% ... yet.  */
5310       if (strchr (fmt_str, '%'))
5311         return 0;
5312
5313       if (arglist)
5314         return 0;
5315
5316       /* If the format specifier was "", fprintf does nothing.  */
5317       if (fmt_str[0] == '\0')
5318         {
5319           /* Evaluate and ignore FILE* argument for side-effects.  */
5320           expand_expr (fp, const0_rtx, VOIDmode, EXPAND_NORMAL);
5321           return const0_rtx;
5322         }
5323
5324       /* When "string" doesn't contain %, replace all cases of
5325          fprintf(stream,string) with fputs(string,stream).  The fputs
5326          builtin will take care of special cases like length == 1.  */
5327       arglist = build_tree_list (NULL_TREE, fp);
5328       arglist = tree_cons (NULL_TREE, fmt, arglist);
5329       fn = fn_fputs;
5330     }
5331
5332   if (!fn)
5333     return 0;
5334   return expand_expr (build_function_call_expr (fn, arglist),
5335                       target, mode, EXPAND_NORMAL);
5336 }
5337
5338 /* Expand a call to sprintf with argument list ARGLIST.  Return 0 if
5339    a normal call should be emitted rather than expanding the function
5340    inline.  If convenient, the result should be placed in TARGET with
5341    mode MODE.  */
5342
5343 static rtx
5344 expand_builtin_sprintf (tree arglist, rtx target, enum machine_mode mode)
5345 {
5346   tree orig_arglist, dest, fmt;
5347   const char *fmt_str;
5348
5349   orig_arglist = arglist;
5350
5351   /* Verify the required arguments in the original call.  */
5352   if (! arglist)
5353     return 0;
5354   dest = TREE_VALUE (arglist);
5355   if (TREE_CODE (TREE_TYPE (dest)) != POINTER_TYPE)
5356     return 0;
5357   arglist = TREE_CHAIN (arglist);
5358   if (! arglist)
5359     return 0;
5360   fmt = TREE_VALUE (arglist);
5361   if (TREE_CODE (TREE_TYPE (fmt)) != POINTER_TYPE)
5362     return 0;
5363   arglist = TREE_CHAIN (arglist);
5364
5365   /* Check whether the format is a literal string constant.  */
5366   fmt_str = c_getstr (fmt);
5367   if (fmt_str == NULL)
5368     return 0;
5369
5370   /* If the format doesn't contain % args or %%, use strcpy.  */
5371   if (strchr (fmt_str, '%') == 0)
5372     {
5373       tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
5374       tree exp;
5375
5376       if (arglist || ! fn)
5377         return 0;
5378       expand_expr (build_function_call_expr (fn, orig_arglist),
5379                    const0_rtx, VOIDmode, EXPAND_NORMAL);
5380       if (target == const0_rtx)
5381         return const0_rtx;
5382       exp = build_int_2 (strlen (fmt_str), 0);
5383       exp = fold_convert (integer_type_node, exp);
5384       return expand_expr (exp, target, mode, EXPAND_NORMAL);
5385     }
5386   /* If the format is "%s", use strcpy if the result isn't used.  */
5387   else if (strcmp (fmt_str, "%s") == 0)
5388     {
5389       tree fn, arg, len;
5390       fn = implicit_built_in_decls[BUILT_IN_STRCPY];
5391
5392       if (! fn)
5393         return 0;
5394
5395       if (! arglist || TREE_CHAIN (arglist))
5396         return 0;
5397       arg = TREE_VALUE (arglist);
5398       if (TREE_CODE (TREE_TYPE (arg)) != POINTER_TYPE)
5399         return 0;
5400
5401       if (target != const0_rtx)
5402         {
5403           len = c_strlen (arg, 1);
5404           if (! len || TREE_CODE (len) != INTEGER_CST)
5405             return 0;
5406         }
5407       else
5408         len = NULL_TREE;
5409
5410       arglist = build_tree_list (NULL_TREE, arg);
5411       arglist = tree_cons (NULL_TREE, dest, arglist);
5412       expand_expr (build_function_call_expr (fn, arglist),
5413                    const0_rtx, VOIDmode, EXPAND_NORMAL);
5414
5415       if (target == const0_rtx)
5416         return const0_rtx;
5417       return expand_expr (len, target, mode, EXPAND_NORMAL);
5418     }
5419
5420   return 0;
5421 }
5422
5423 /* Expand a call to either the entry or exit function profiler.  */
5424
5425 static rtx
5426 expand_builtin_profile_func (bool exitp)
5427 {
5428   rtx this, which;
5429
5430   this = DECL_RTL (current_function_decl);
5431   if (MEM_P (this))
5432     this = XEXP (this, 0);
5433   else
5434     abort ();
5435
5436   if (exitp)
5437     which = profile_function_exit_libfunc;
5438   else
5439     which = profile_function_entry_libfunc;
5440
5441   emit_library_call (which, LCT_NORMAL, VOIDmode, 2, this, Pmode,
5442                      expand_builtin_return_addr (BUILT_IN_RETURN_ADDRESS,
5443                                                  0, hard_frame_pointer_rtx),
5444                      Pmode);
5445
5446   return const0_rtx;
5447 }
5448
5449 /* Given a trampoline address, make sure it satisfies TRAMPOLINE_ALIGNMENT.  */
5450
5451 static rtx
5452 round_trampoline_addr (rtx tramp)
5453 {
5454   rtx temp, addend, mask;
5455
5456   /* If we don't need too much alignment, we'll have been guaranteed
5457      proper alignment by get_trampoline_type.  */
5458   if (TRAMPOLINE_ALIGNMENT <= STACK_BOUNDARY)
5459     return tramp;
5460
5461   /* Round address up to desired boundary.  */
5462   temp = gen_reg_rtx (Pmode);
5463   addend = GEN_INT (TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT - 1);
5464   mask = GEN_INT (-TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT);
5465
5466   temp  = expand_simple_binop (Pmode, PLUS, tramp, addend,
5467                                temp, 0, OPTAB_LIB_WIDEN);
5468   tramp = expand_simple_binop (Pmode, AND, temp, mask,
5469                                temp, 0, OPTAB_LIB_WIDEN);
5470
5471   return tramp;
5472 }
5473
5474 static rtx
5475 expand_builtin_init_trampoline (tree arglist)
5476 {
5477   tree t_tramp, t_func, t_chain;
5478   rtx r_tramp, r_func, r_chain;
5479 #ifdef TRAMPOLINE_TEMPLATE
5480   rtx blktramp;
5481 #endif
5482
5483   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE,
5484                          POINTER_TYPE, VOID_TYPE))
5485     return NULL_RTX;
5486
5487   t_tramp = TREE_VALUE (arglist);
5488   arglist = TREE_CHAIN (arglist);
5489   t_func = TREE_VALUE (arglist);
5490   arglist = TREE_CHAIN (arglist);
5491   t_chain = TREE_VALUE (arglist);
5492
5493   r_tramp = expand_expr (t_tramp, NULL_RTX, VOIDmode, 0);
5494   r_func = expand_expr (t_func, NULL_RTX, VOIDmode, 0);
5495   r_chain = expand_expr (t_chain, NULL_RTX, VOIDmode, 0);
5496
5497   /* Generate insns to initialize the trampoline.  */
5498   r_tramp = round_trampoline_addr (r_tramp);
5499 #ifdef TRAMPOLINE_TEMPLATE
5500   blktramp = gen_rtx_MEM (BLKmode, r_tramp);
5501   set_mem_align (blktramp, TRAMPOLINE_ALIGNMENT);
5502   emit_block_move (blktramp, assemble_trampoline_template (),
5503                    GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL);
5504 #endif
5505   trampolines_created = 1;
5506   INITIALIZE_TRAMPOLINE (r_tramp, r_func, r_chain);
5507
5508   return const0_rtx;
5509 }
5510
5511 static rtx
5512 expand_builtin_adjust_trampoline (tree arglist)
5513 {
5514   rtx tramp;
5515
5516   if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5517     return NULL_RTX;
5518
5519   tramp = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
5520   tramp = round_trampoline_addr (tramp);
5521 #ifdef TRAMPOLINE_ADJUST_ADDRESS
5522   TRAMPOLINE_ADJUST_ADDRESS (tramp);
5523 #endif
5524
5525   return tramp;
5526 }
5527
5528 /* Expand a call to the built-in signbit, signbitf or signbitl function.
5529    Return NULL_RTX if a normal call should be emitted rather than expanding
5530    the function in-line.  EXP is the expression that is a call to the builtin
5531    function; if convenient, the result should be placed in TARGET.  */
5532
5533 static rtx
5534 expand_builtin_signbit (tree exp, rtx target)
5535 {
5536   const struct real_format *fmt;
5537   enum machine_mode fmode, imode, rmode;
5538   HOST_WIDE_INT hi, lo;
5539   tree arg, arglist;
5540   int bitpos;
5541   rtx temp;
5542
5543   arglist = TREE_OPERAND (exp, 1);
5544   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
5545     return 0;
5546
5547   arg = TREE_VALUE (arglist);
5548   fmode = TYPE_MODE (TREE_TYPE (arg));
5549   rmode = TYPE_MODE (TREE_TYPE (exp));
5550   fmt = REAL_MODE_FORMAT (fmode);
5551
5552   /* For floating point formats without a sign bit, implement signbit
5553      as "ARG < 0.0".  */
5554   if (fmt->signbit < 0)
5555   {
5556     /* But we can't do this if the format supports signed zero.  */
5557     if (fmt->has_signed_zero && HONOR_SIGNED_ZEROS (fmode))
5558       return 0;
5559
5560     arg = fold (build2 (LT_EXPR, TREE_TYPE (exp), arg,
5561                         build_real (TREE_TYPE (arg), dconst0)));
5562     return expand_expr (arg, target, VOIDmode, EXPAND_NORMAL);
5563   }
5564
5565   imode = int_mode_for_mode (fmode);
5566   if (imode == BLKmode)
5567     return 0;
5568
5569   bitpos = fmt->signbit;
5570   /* Handle targets with different FP word orders.  */
5571   if (FLOAT_WORDS_BIG_ENDIAN != WORDS_BIG_ENDIAN)
5572     {
5573       int nwords = GET_MODE_BITSIZE (fmode) / BITS_PER_WORD;
5574       int word = nwords - (bitpos / BITS_PER_WORD) - 1;
5575       bitpos = word * BITS_PER_WORD + bitpos % BITS_PER_WORD;
5576     }
5577
5578   /* If the sign bit is not in the lowpart and the floating point format
5579      is wider than an integer, check that is twice the size of an integer
5580      so that we can use gen_highpart below.  */
5581   if (bitpos >= GET_MODE_BITSIZE (rmode)
5582       && GET_MODE_BITSIZE (imode) != 2 * GET_MODE_BITSIZE (rmode))
5583     return 0;
5584
5585   temp = expand_expr (arg, NULL_RTX, VOIDmode, 0);
5586   temp = gen_lowpart (imode, temp);
5587
5588   if (GET_MODE_BITSIZE (imode) > GET_MODE_BITSIZE (rmode))
5589     {
5590       if (BYTES_BIG_ENDIAN)
5591         bitpos = GET_MODE_BITSIZE (imode) - 1 - bitpos;
5592       temp = copy_to_mode_reg (imode, temp);
5593       temp = extract_bit_field (temp, 1, bitpos, 1,
5594                                 NULL_RTX, rmode, rmode);
5595     }
5596   else
5597     {
5598       if (GET_MODE_BITSIZE (imode) < GET_MODE_BITSIZE (rmode))
5599         temp = gen_lowpart (rmode, temp);
5600       if (bitpos < HOST_BITS_PER_WIDE_INT)
5601         {
5602           hi = 0;
5603           lo = (HOST_WIDE_INT) 1 << bitpos;
5604         }
5605       else
5606         {
5607           hi = (HOST_WIDE_INT) 1 << (bitpos - HOST_BITS_PER_WIDE_INT);
5608           lo = 0;
5609         }
5610
5611       temp = force_reg (rmode, temp);
5612       temp = expand_binop (rmode, and_optab, temp,
5613                            immed_double_const (lo, hi, rmode),
5614                            target, 1, OPTAB_LIB_WIDEN);
5615     }
5616   return temp;
5617 }
5618
5619 /* Expand fork or exec calls.  TARGET is the desired target of the
5620    call.  ARGLIST is the list of arguments of the call.  FN is the
5621    identificator of the actual function.  IGNORE is nonzero if the
5622    value is to be ignored.  */
5623
5624 static rtx
5625 expand_builtin_fork_or_exec (tree fn, tree arglist, rtx target, int ignore)
5626 {
5627   tree id, decl;
5628   tree call;
5629
5630   /* If we are not profiling, just call the function.  */
5631   if (!profile_arc_flag)
5632     return NULL_RTX;
5633
5634   /* Otherwise call the wrapper.  This should be equivalent for the rest of
5635      compiler, so the code does not diverge, and the wrapper may run the
5636      code necessary for keeping the profiling sane.  */
5637
5638   switch (DECL_FUNCTION_CODE (fn))
5639     {
5640     case BUILT_IN_FORK:
5641       id = get_identifier ("__gcov_fork");
5642       break;
5643
5644     case BUILT_IN_EXECL:
5645       id = get_identifier ("__gcov_execl");
5646       break;
5647
5648     case BUILT_IN_EXECV:
5649       id = get_identifier ("__gcov_execv");
5650       break;
5651
5652     case BUILT_IN_EXECLP:
5653       id = get_identifier ("__gcov_execlp");
5654       break;
5655
5656     case BUILT_IN_EXECLE:
5657       id = get_identifier ("__gcov_execle");
5658       break;
5659
5660     case BUILT_IN_EXECVP:
5661       id = get_identifier ("__gcov_execvp");
5662       break;
5663
5664     case BUILT_IN_EXECVE:
5665       id = get_identifier ("__gcov_execve");
5666       break;
5667
5668     default:
5669       abort ();
5670     }
5671
5672   decl = build_decl (FUNCTION_DECL, id, TREE_TYPE (fn));
5673   DECL_EXTERNAL (decl) = 1;
5674   TREE_PUBLIC (decl) = 1;
5675   DECL_ARTIFICIAL (decl) = 1;
5676   TREE_NOTHROW (decl) = 1;
5677   call = build_function_call_expr (decl, arglist);
5678
5679   return expand_call (call, target, ignore);
5680 }
5681 \f
5682 /* Expand an expression EXP that calls a built-in function,
5683    with result going to TARGET if that's convenient
5684    (and in mode MODE if that's convenient).
5685    SUBTARGET may be used as the target for computing one of EXP's operands.
5686    IGNORE is nonzero if the value is to be ignored.  */
5687
5688 rtx
5689 expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
5690                 int ignore)
5691 {
5692   tree fndecl = get_callee_fndecl (exp);
5693   tree arglist = TREE_OPERAND (exp, 1);
5694   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
5695   enum machine_mode target_mode = TYPE_MODE (TREE_TYPE (exp));
5696
5697   /* Perform postincrements before expanding builtin functions.  */
5698   emit_queue ();
5699
5700   if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
5701     return targetm.expand_builtin (exp, target, subtarget, mode, ignore);
5702
5703   /* When not optimizing, generate calls to library functions for a certain
5704      set of builtins.  */
5705   if (!optimize
5706       && !CALLED_AS_BUILT_IN (fndecl)
5707       && DECL_ASSEMBLER_NAME_SET_P (fndecl)
5708       && fcode != BUILT_IN_ALLOCA)
5709     return expand_call (exp, target, ignore);
5710
5711   /* The built-in function expanders test for target == const0_rtx
5712      to determine whether the function's result will be ignored.  */
5713   if (ignore)
5714     target = const0_rtx;
5715
5716   /* If the result of a pure or const built-in function is ignored, and
5717      none of its arguments are volatile, we can avoid expanding the
5718      built-in call and just evaluate the arguments for side-effects.  */
5719   if (target == const0_rtx
5720       && (DECL_IS_PURE (fndecl) || TREE_READONLY (fndecl)))
5721     {
5722       bool volatilep = false;
5723       tree arg;
5724
5725       for (arg = arglist; arg; arg = TREE_CHAIN (arg))
5726         if (TREE_THIS_VOLATILE (TREE_VALUE (arg)))
5727           {
5728             volatilep = true;
5729             break;
5730           }
5731
5732       if (! volatilep)
5733         {
5734           for (arg = arglist; arg; arg = TREE_CHAIN (arg))
5735             expand_expr (TREE_VALUE (arg), const0_rtx,
5736                          VOIDmode, EXPAND_NORMAL);
5737           return const0_rtx;
5738         }
5739     }
5740
5741   switch (fcode)
5742     {
5743     case BUILT_IN_FABS:
5744     case BUILT_IN_FABSF:
5745     case BUILT_IN_FABSL:
5746       target = expand_builtin_fabs (arglist, target, subtarget);
5747       if (target)
5748         return target;
5749       break;
5750
5751     case BUILT_IN_CABS:
5752     case BUILT_IN_CABSF:
5753     case BUILT_IN_CABSL:
5754       if (flag_unsafe_math_optimizations)
5755         {
5756           target = expand_builtin_cabs (arglist, target);
5757           if (target)
5758             return target;
5759         }
5760       break;
5761
5762     case BUILT_IN_EXP:
5763     case BUILT_IN_EXPF:
5764     case BUILT_IN_EXPL:
5765     case BUILT_IN_EXP10:
5766     case BUILT_IN_EXP10F:
5767     case BUILT_IN_EXP10L:
5768     case BUILT_IN_POW10:
5769     case BUILT_IN_POW10F:
5770     case BUILT_IN_POW10L:
5771     case BUILT_IN_EXP2:
5772     case BUILT_IN_EXP2F:
5773     case BUILT_IN_EXP2L:
5774     case BUILT_IN_EXPM1:
5775     case BUILT_IN_EXPM1F:
5776     case BUILT_IN_EXPM1L:
5777     case BUILT_IN_LOGB:
5778     case BUILT_IN_LOGBF:
5779     case BUILT_IN_LOGBL:
5780     case BUILT_IN_ILOGB:
5781     case BUILT_IN_ILOGBF:
5782     case BUILT_IN_ILOGBL:
5783     case BUILT_IN_LOG:
5784     case BUILT_IN_LOGF:
5785     case BUILT_IN_LOGL:
5786     case BUILT_IN_LOG10:
5787     case BUILT_IN_LOG10F:
5788     case BUILT_IN_LOG10L:
5789     case BUILT_IN_LOG2:
5790     case BUILT_IN_LOG2F:
5791     case BUILT_IN_LOG2L:
5792     case BUILT_IN_LOG1P:
5793     case BUILT_IN_LOG1PF:
5794     case BUILT_IN_LOG1PL:
5795     case BUILT_IN_TAN:
5796     case BUILT_IN_TANF:
5797     case BUILT_IN_TANL:
5798     case BUILT_IN_ASIN:
5799     case BUILT_IN_ASINF:
5800     case BUILT_IN_ASINL:
5801     case BUILT_IN_ACOS:
5802     case BUILT_IN_ACOSF:
5803     case BUILT_IN_ACOSL:
5804     case BUILT_IN_ATAN:
5805     case BUILT_IN_ATANF:
5806     case BUILT_IN_ATANL:
5807       /* Treat these like sqrt only if unsafe math optimizations are allowed,
5808          because of possible accuracy problems.  */
5809       if (! flag_unsafe_math_optimizations)
5810         break;
5811     case BUILT_IN_SQRT:
5812     case BUILT_IN_SQRTF:
5813     case BUILT_IN_SQRTL:
5814     case BUILT_IN_FLOOR:
5815     case BUILT_IN_FLOORF:
5816     case BUILT_IN_FLOORL:
5817     case BUILT_IN_CEIL:
5818     case BUILT_IN_CEILF:
5819     case BUILT_IN_CEILL:
5820     case BUILT_IN_TRUNC:
5821     case BUILT_IN_TRUNCF:
5822     case BUILT_IN_TRUNCL:
5823     case BUILT_IN_ROUND:
5824     case BUILT_IN_ROUNDF:
5825     case BUILT_IN_ROUNDL:
5826     case BUILT_IN_NEARBYINT:
5827     case BUILT_IN_NEARBYINTF:
5828     case BUILT_IN_NEARBYINTL:
5829       target = expand_builtin_mathfn (exp, target, subtarget);
5830       if (target)
5831         return target;
5832       break;
5833
5834     case BUILT_IN_POW:
5835     case BUILT_IN_POWF:
5836     case BUILT_IN_POWL:
5837       target = expand_builtin_pow (exp, target, subtarget);
5838       if (target)
5839         return target;
5840       break;
5841
5842     case BUILT_IN_ATAN2:
5843     case BUILT_IN_ATAN2F:
5844     case BUILT_IN_ATAN2L:
5845     case BUILT_IN_FMOD:
5846     case BUILT_IN_FMODF:
5847     case BUILT_IN_FMODL:
5848     case BUILT_IN_DREM:
5849     case BUILT_IN_DREMF:
5850     case BUILT_IN_DREML:
5851       if (! flag_unsafe_math_optimizations)
5852         break;
5853       target = expand_builtin_mathfn_2 (exp, target, subtarget);
5854       if (target)
5855         return target;
5856       break;
5857
5858     case BUILT_IN_SIN:
5859     case BUILT_IN_SINF:
5860     case BUILT_IN_SINL:
5861     case BUILT_IN_COS:
5862     case BUILT_IN_COSF:
5863     case BUILT_IN_COSL:
5864       if (! flag_unsafe_math_optimizations)
5865         break;
5866       target = expand_builtin_mathfn_3 (exp, target, subtarget);
5867       if (target)
5868         return target;
5869       break;
5870
5871     case BUILT_IN_APPLY_ARGS:
5872       return expand_builtin_apply_args ();
5873
5874       /* __builtin_apply (FUNCTION, ARGUMENTS, ARGSIZE) invokes
5875          FUNCTION with a copy of the parameters described by
5876          ARGUMENTS, and ARGSIZE.  It returns a block of memory
5877          allocated on the stack into which is stored all the registers
5878          that might possibly be used for returning the result of a
5879          function.  ARGUMENTS is the value returned by
5880          __builtin_apply_args.  ARGSIZE is the number of bytes of
5881          arguments that must be copied.  ??? How should this value be
5882          computed?  We'll also need a safe worst case value for varargs
5883          functions.  */
5884     case BUILT_IN_APPLY:
5885       if (!validate_arglist (arglist, POINTER_TYPE,
5886                              POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)
5887           && !validate_arglist (arglist, REFERENCE_TYPE,
5888                                 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
5889         return const0_rtx;
5890       else
5891         {
5892           int i;
5893           tree t;
5894           rtx ops[3];
5895
5896           for (t = arglist, i = 0; t; t = TREE_CHAIN (t), i++)
5897             ops[i] = expand_expr (TREE_VALUE (t), NULL_RTX, VOIDmode, 0);
5898
5899           return expand_builtin_apply (ops[0], ops[1], ops[2]);
5900         }
5901
5902       /* __builtin_return (RESULT) causes the function to return the
5903          value described by RESULT.  RESULT is address of the block of
5904          memory returned by __builtin_apply.  */
5905     case BUILT_IN_RETURN:
5906       if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5907         expand_builtin_return (expand_expr (TREE_VALUE (arglist),
5908                                             NULL_RTX, VOIDmode, 0));
5909       return const0_rtx;
5910
5911     case BUILT_IN_SAVEREGS:
5912       return expand_builtin_saveregs ();
5913
5914     case BUILT_IN_ARGS_INFO:
5915       return expand_builtin_args_info (arglist);
5916
5917       /* Return the address of the first anonymous stack arg.  */
5918     case BUILT_IN_NEXT_ARG:
5919       simplify_builtin_next_arg (arglist);
5920       return expand_builtin_next_arg (arglist);
5921
5922     case BUILT_IN_CLASSIFY_TYPE:
5923       return expand_builtin_classify_type (arglist);
5924
5925     case BUILT_IN_CONSTANT_P:
5926       return const0_rtx;
5927
5928     case BUILT_IN_FRAME_ADDRESS:
5929     case BUILT_IN_RETURN_ADDRESS:
5930       return expand_builtin_frame_address (fndecl, arglist);
5931
5932     /* Returns the address of the area where the structure is returned.
5933        0 otherwise.  */
5934     case BUILT_IN_AGGREGATE_INCOMING_ADDRESS:
5935       if (arglist != 0
5936           || ! AGGREGATE_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl)))
5937           || !MEM_P (DECL_RTL (DECL_RESULT (current_function_decl))))
5938         return const0_rtx;
5939       else
5940         return XEXP (DECL_RTL (DECL_RESULT (current_function_decl)), 0);
5941
5942     case BUILT_IN_ALLOCA:
5943       target = expand_builtin_alloca (arglist, target);
5944       if (target)
5945         return target;
5946       break;
5947
5948     case BUILT_IN_STACK_ALLOC:
5949       expand_stack_alloc (TREE_VALUE (arglist),
5950                           TREE_VALUE (TREE_CHAIN (arglist)));
5951       return const0_rtx;
5952
5953     case BUILT_IN_STACK_SAVE:
5954       return expand_stack_save ();
5955
5956     case BUILT_IN_STACK_RESTORE:
5957       expand_stack_restore (TREE_VALUE (arglist));
5958       return const0_rtx;
5959
5960     case BUILT_IN_FFS:
5961     case BUILT_IN_FFSL:
5962     case BUILT_IN_FFSLL:
5963     case BUILT_IN_FFSIMAX:
5964       target = expand_builtin_unop (target_mode, arglist, target,
5965                                     subtarget, ffs_optab);
5966       if (target)
5967         return target;
5968       break;
5969
5970     case BUILT_IN_CLZ:
5971     case BUILT_IN_CLZL:
5972     case BUILT_IN_CLZLL:
5973     case BUILT_IN_CLZIMAX:
5974       target = expand_builtin_unop (target_mode, arglist, target,
5975                                     subtarget, clz_optab);
5976       if (target)
5977         return target;
5978       break;
5979
5980     case BUILT_IN_CTZ:
5981     case BUILT_IN_CTZL:
5982     case BUILT_IN_CTZLL:
5983     case BUILT_IN_CTZIMAX:
5984       target = expand_builtin_unop (target_mode, arglist, target,
5985                                     subtarget, ctz_optab);
5986       if (target)
5987         return target;
5988       break;
5989
5990     case BUILT_IN_POPCOUNT:
5991     case BUILT_IN_POPCOUNTL:
5992     case BUILT_IN_POPCOUNTLL:
5993     case BUILT_IN_POPCOUNTIMAX:
5994       target = expand_builtin_unop (target_mode, arglist, target,
5995                                     subtarget, popcount_optab);
5996       if (target)
5997         return target;
5998       break;
5999
6000     case BUILT_IN_PARITY:
6001     case BUILT_IN_PARITYL:
6002     case BUILT_IN_PARITYLL:
6003     case BUILT_IN_PARITYIMAX:
6004       target = expand_builtin_unop (target_mode, arglist, target,
6005                                     subtarget, parity_optab);
6006       if (target)
6007         return target;
6008       break;
6009
6010     case BUILT_IN_STRLEN:
6011       target = expand_builtin_strlen (arglist, target, target_mode);
6012       if (target)
6013         return target;
6014       break;
6015
6016     case BUILT_IN_STRCPY:
6017       target = expand_builtin_strcpy (arglist, target, mode);
6018       if (target)
6019         return target;
6020       break;
6021
6022     case BUILT_IN_STRNCPY:
6023       target = expand_builtin_strncpy (arglist, target, mode);
6024       if (target)
6025         return target;
6026       break;
6027
6028     case BUILT_IN_STPCPY:
6029       target = expand_builtin_stpcpy (arglist, target, mode);
6030       if (target)
6031         return target;
6032       break;
6033
6034     case BUILT_IN_STRCAT:
6035       target = expand_builtin_strcat (arglist, target, mode);
6036       if (target)
6037         return target;
6038       break;
6039
6040     case BUILT_IN_STRNCAT:
6041       target = expand_builtin_strncat (arglist, target, mode);
6042       if (target)
6043         return target;
6044       break;
6045
6046     case BUILT_IN_STRSPN:
6047       target = expand_builtin_strspn (arglist, target, mode);
6048       if (target)
6049         return target;
6050       break;
6051
6052     case BUILT_IN_STRCSPN:
6053       target = expand_builtin_strcspn (arglist, target, mode);
6054       if (target)
6055         return target;
6056       break;
6057
6058     case BUILT_IN_STRSTR:
6059       target = expand_builtin_strstr (arglist, target, mode);
6060       if (target)
6061         return target;
6062       break;
6063
6064     case BUILT_IN_STRPBRK:
6065       target = expand_builtin_strpbrk (arglist, target, mode);
6066       if (target)
6067         return target;
6068       break;
6069
6070     case BUILT_IN_INDEX:
6071     case BUILT_IN_STRCHR:
6072       target = expand_builtin_strchr (arglist, target, mode);
6073       if (target)
6074         return target;
6075       break;
6076
6077     case BUILT_IN_RINDEX:
6078     case BUILT_IN_STRRCHR:
6079       target = expand_builtin_strrchr (arglist, target, mode);
6080       if (target)
6081         return target;
6082       break;
6083
6084     case BUILT_IN_MEMCPY:
6085       target = expand_builtin_memcpy (arglist, target, mode);
6086       if (target)
6087         return target;
6088       break;
6089
6090     case BUILT_IN_MEMPCPY:
6091       target = expand_builtin_mempcpy (arglist, target, mode, /*endp=*/ 1);
6092       if (target)
6093         return target;
6094       break;
6095
6096     case BUILT_IN_MEMMOVE:
6097       target = expand_builtin_memmove (arglist, target, mode);
6098       if (target)
6099         return target;
6100       break;
6101
6102     case BUILT_IN_BCOPY:
6103       target = expand_builtin_bcopy (arglist);
6104       if (target)
6105         return target;
6106       break;
6107
6108     case BUILT_IN_MEMSET:
6109       target = expand_builtin_memset (arglist, target, mode);
6110       if (target)
6111         return target;
6112       break;
6113
6114     case BUILT_IN_BZERO:
6115       target = expand_builtin_bzero (arglist);
6116       if (target)
6117         return target;
6118       break;
6119
6120     case BUILT_IN_STRCMP:
6121       target = expand_builtin_strcmp (exp, target, mode);
6122       if (target)
6123         return target;
6124       break;
6125
6126     case BUILT_IN_STRNCMP:
6127       target = expand_builtin_strncmp (exp, target, mode);
6128       if (target)
6129         return target;
6130       break;
6131
6132     case BUILT_IN_BCMP:
6133     case BUILT_IN_MEMCMP:
6134       target = expand_builtin_memcmp (exp, arglist, target, mode);
6135       if (target)
6136         return target;
6137       break;
6138
6139     case BUILT_IN_SETJMP:
6140       target = expand_builtin_setjmp (arglist, target);
6141       if (target)
6142         return target;
6143       break;
6144
6145       /* __builtin_longjmp is passed a pointer to an array of five words.
6146          It's similar to the C library longjmp function but works with
6147          __builtin_setjmp above.  */
6148     case BUILT_IN_LONGJMP:
6149       if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
6150         break;
6151       else
6152         {
6153           rtx buf_addr = expand_expr (TREE_VALUE (arglist), subtarget,
6154                                       VOIDmode, 0);
6155           rtx value = expand_expr (TREE_VALUE (TREE_CHAIN (arglist)),
6156                                    NULL_RTX, VOIDmode, 0);
6157
6158           if (value != const1_rtx)
6159             {
6160               error ("__builtin_longjmp second argument must be 1");
6161               return const0_rtx;
6162             }
6163
6164           expand_builtin_longjmp (buf_addr, value);
6165           return const0_rtx;
6166         }
6167
6168     case BUILT_IN_NONLOCAL_GOTO:
6169       target = expand_builtin_nonlocal_goto (arglist);
6170       if (target)
6171         return target;
6172       break;
6173
6174       /* This updates the setjmp buffer that is its argument with the value
6175          of the current stack pointer.  */
6176     case BUILT_IN_UPDATE_SETJMP_BUF:
6177       if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6178         {
6179           rtx buf_addr
6180             = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
6181
6182           expand_builtin_update_setjmp_buf (buf_addr);
6183           return const0_rtx;
6184         }
6185       break;
6186
6187     case BUILT_IN_TRAP:
6188       expand_builtin_trap ();
6189       return const0_rtx;
6190
6191     case BUILT_IN_PRINTF:
6192       target = expand_builtin_printf (arglist, target, mode, false);
6193       if (target)
6194         return target;
6195       break;
6196
6197     case BUILT_IN_PRINTF_UNLOCKED:
6198       target = expand_builtin_printf (arglist, target, mode, true);
6199       if (target)
6200         return target;
6201       break;
6202
6203     case BUILT_IN_FPUTS:
6204       target = expand_builtin_fputs (arglist, target, false);
6205       if (target)
6206         return target;
6207       break;
6208     case BUILT_IN_FPUTS_UNLOCKED:
6209       target = expand_builtin_fputs (arglist, target, true);
6210       if (target)
6211         return target;
6212       break;
6213
6214     case BUILT_IN_FPRINTF:
6215       target = expand_builtin_fprintf (arglist, target, mode, false);
6216       if (target)
6217         return target;
6218       break;
6219
6220     case BUILT_IN_FPRINTF_UNLOCKED:
6221       target = expand_builtin_fprintf (arglist, target, mode, true);
6222       if (target)
6223         return target;
6224       break;
6225
6226     case BUILT_IN_SPRINTF:
6227       target = expand_builtin_sprintf (arglist, target, mode);
6228       if (target)
6229         return target;
6230       break;
6231
6232     case BUILT_IN_SIGNBIT:
6233     case BUILT_IN_SIGNBITF:
6234     case BUILT_IN_SIGNBITL:
6235       target = expand_builtin_signbit (exp, target);
6236       if (target)
6237         return target;
6238       break;
6239
6240       /* Various hooks for the DWARF 2 __throw routine.  */
6241     case BUILT_IN_UNWIND_INIT:
6242       expand_builtin_unwind_init ();
6243       return const0_rtx;
6244     case BUILT_IN_DWARF_CFA:
6245       return virtual_cfa_rtx;
6246 #ifdef DWARF2_UNWIND_INFO
6247     case BUILT_IN_DWARF_SP_COLUMN:
6248       return expand_builtin_dwarf_sp_column ();
6249     case BUILT_IN_INIT_DWARF_REG_SIZES:
6250       expand_builtin_init_dwarf_reg_sizes (TREE_VALUE (arglist));
6251       return const0_rtx;
6252 #endif
6253     case BUILT_IN_FROB_RETURN_ADDR:
6254       return expand_builtin_frob_return_addr (TREE_VALUE (arglist));
6255     case BUILT_IN_EXTRACT_RETURN_ADDR:
6256       return expand_builtin_extract_return_addr (TREE_VALUE (arglist));
6257     case BUILT_IN_EH_RETURN:
6258       expand_builtin_eh_return (TREE_VALUE (arglist),
6259                                 TREE_VALUE (TREE_CHAIN (arglist)));
6260       return const0_rtx;
6261 #ifdef EH_RETURN_DATA_REGNO
6262     case BUILT_IN_EH_RETURN_DATA_REGNO:
6263       return expand_builtin_eh_return_data_regno (arglist);
6264 #endif
6265     case BUILT_IN_EXTEND_POINTER:
6266       return expand_builtin_extend_pointer (TREE_VALUE (arglist));
6267
6268     case BUILT_IN_VA_START:
6269     case BUILT_IN_STDARG_START:
6270       return expand_builtin_va_start (arglist);
6271     case BUILT_IN_VA_END:
6272       return expand_builtin_va_end (arglist);
6273     case BUILT_IN_VA_COPY:
6274       return expand_builtin_va_copy (arglist);
6275     case BUILT_IN_EXPECT:
6276       return expand_builtin_expect (arglist, target);
6277     case BUILT_IN_PREFETCH:
6278       expand_builtin_prefetch (arglist);
6279       return const0_rtx;
6280
6281     case BUILT_IN_PROFILE_FUNC_ENTER:
6282       return expand_builtin_profile_func (false);
6283     case BUILT_IN_PROFILE_FUNC_EXIT:
6284       return expand_builtin_profile_func (true);
6285
6286     case BUILT_IN_INIT_TRAMPOLINE:
6287       return expand_builtin_init_trampoline (arglist);
6288     case BUILT_IN_ADJUST_TRAMPOLINE:
6289       return expand_builtin_adjust_trampoline (arglist);
6290
6291     case BUILT_IN_FORK:
6292     case BUILT_IN_EXECL:
6293     case BUILT_IN_EXECV:
6294     case BUILT_IN_EXECLP:
6295     case BUILT_IN_EXECLE:
6296     case BUILT_IN_EXECVP:
6297     case BUILT_IN_EXECVE:
6298       target = expand_builtin_fork_or_exec (fndecl, arglist, target, ignore);
6299       if (target)
6300         return target;
6301       break;
6302
6303     default:    /* just do library call, if unknown builtin */
6304       break;
6305     }
6306
6307   /* The switch statement above can drop through to cause the function
6308      to be called normally.  */
6309   return expand_call (exp, target, ignore);
6310 }
6311
6312 /* Determine whether a tree node represents a call to a built-in
6313    function.  If the tree T is a call to a built-in function with
6314    the right number of arguments of the appropriate types, return
6315    the DECL_FUNCTION_CODE of the call, e.g. BUILT_IN_SQRT.
6316    Otherwise the return value is END_BUILTINS.  */
6317
6318 enum built_in_function
6319 builtin_mathfn_code (tree t)
6320 {
6321   tree fndecl, arglist, parmlist;
6322   tree argtype, parmtype;
6323
6324   if (TREE_CODE (t) != CALL_EXPR
6325       || TREE_CODE (TREE_OPERAND (t, 0)) != ADDR_EXPR)
6326     return END_BUILTINS;
6327
6328   fndecl = get_callee_fndecl (t);
6329   if (fndecl == NULL_TREE
6330       || TREE_CODE (fndecl) != FUNCTION_DECL
6331       || ! DECL_BUILT_IN (fndecl)
6332       || DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
6333     return END_BUILTINS;
6334
6335   arglist = TREE_OPERAND (t, 1);
6336   parmlist = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
6337   for (; parmlist; parmlist = TREE_CHAIN (parmlist))
6338     {
6339       /* If a function doesn't take a variable number of arguments,
6340          the last element in the list will have type `void'.  */
6341       parmtype = TREE_VALUE (parmlist);
6342       if (VOID_TYPE_P (parmtype))
6343         {
6344           if (arglist)
6345             return END_BUILTINS;
6346           return DECL_FUNCTION_CODE (fndecl);
6347         }
6348
6349       if (! arglist)
6350         return END_BUILTINS;
6351
6352       argtype = TREE_TYPE (TREE_VALUE (arglist));
6353
6354       if (SCALAR_FLOAT_TYPE_P (parmtype))
6355         {
6356           if (! SCALAR_FLOAT_TYPE_P (argtype))
6357             return END_BUILTINS;
6358         }
6359       else if (COMPLEX_FLOAT_TYPE_P (parmtype))
6360         {
6361           if (! COMPLEX_FLOAT_TYPE_P (argtype))
6362             return END_BUILTINS;
6363         }
6364       else if (POINTER_TYPE_P (parmtype))
6365         {
6366           if (! POINTER_TYPE_P (argtype))
6367             return END_BUILTINS;
6368         }
6369       else if (INTEGRAL_TYPE_P (parmtype))
6370         {
6371           if (! INTEGRAL_TYPE_P (argtype))
6372             return END_BUILTINS;
6373         }
6374       else
6375         return END_BUILTINS;
6376
6377       arglist = TREE_CHAIN (arglist);
6378     }
6379
6380   /* Variable-length argument list.  */
6381   return DECL_FUNCTION_CODE (fndecl);
6382 }
6383
6384 /* Fold a call to __builtin_constant_p, if we know it will evaluate to a
6385    constant.  ARGLIST is the argument list of the call.  */
6386
6387 static tree
6388 fold_builtin_constant_p (tree arglist)
6389 {
6390   if (arglist == 0)
6391     return 0;
6392
6393   arglist = TREE_VALUE (arglist);
6394
6395   /* We return 1 for a numeric type that's known to be a constant
6396      value at compile-time or for an aggregate type that's a
6397      literal constant.  */
6398   STRIP_NOPS (arglist);
6399
6400   /* If we know this is a constant, emit the constant of one.  */
6401   if (TREE_CODE_CLASS (TREE_CODE (arglist)) == 'c'
6402       || (TREE_CODE (arglist) == CONSTRUCTOR
6403           && TREE_CONSTANT (arglist))
6404       || (TREE_CODE (arglist) == ADDR_EXPR
6405           && TREE_CODE (TREE_OPERAND (arglist, 0)) == STRING_CST))
6406     return integer_one_node;
6407
6408   /* If this expression has side effects, show we don't know it to be a
6409      constant.  Likewise if it's a pointer or aggregate type since in
6410      those case we only want literals, since those are only optimized
6411      when generating RTL, not later.
6412      And finally, if we are compiling an initializer, not code, we
6413      need to return a definite result now; there's not going to be any
6414      more optimization done.  */
6415   if (TREE_SIDE_EFFECTS (arglist)
6416       || AGGREGATE_TYPE_P (TREE_TYPE (arglist))
6417       || POINTER_TYPE_P (TREE_TYPE (arglist))
6418       || cfun == 0)
6419     return integer_zero_node;
6420
6421   return 0;
6422 }
6423
6424 /* Fold a call to __builtin_expect, if we expect that a comparison against
6425    the argument will fold to a constant.  In practice, this means a true
6426    constant or the address of a non-weak symbol.  ARGLIST is the argument
6427    list of the call.  */
6428
6429 static tree
6430 fold_builtin_expect (tree arglist)
6431 {
6432   tree arg, inner;
6433
6434   if (arglist == 0)
6435     return 0;
6436
6437   arg = TREE_VALUE (arglist);
6438
6439   /* If the argument isn't invariant, then there's nothing we can do.  */
6440   if (!TREE_INVARIANT (arg))
6441     return 0;
6442
6443   /* If we're looking at an address of a weak decl, then do not fold.  */
6444   inner = arg;
6445   STRIP_NOPS (inner);
6446   if (TREE_CODE (inner) == ADDR_EXPR)
6447     {
6448       do
6449         {
6450           inner = TREE_OPERAND (inner, 0);
6451         }
6452       while (TREE_CODE (inner) == COMPONENT_REF
6453              || TREE_CODE (inner) == ARRAY_REF);
6454       if (DECL_P (inner) && DECL_WEAK (inner))
6455         return 0;
6456     }
6457
6458   /* Otherwise, ARG already has the proper type for the return value.  */
6459   return arg;
6460 }
6461
6462 /* Fold a call to __builtin_classify_type.  */
6463
6464 static tree
6465 fold_builtin_classify_type (tree arglist)
6466 {
6467   if (arglist == 0)
6468     return build_int_2 (no_type_class, 0);
6469
6470   return build_int_2 (type_to_class (TREE_TYPE (TREE_VALUE (arglist))), 0);
6471 }
6472
6473 /* Fold a call to __builtin_inf or __builtin_huge_val.  */
6474
6475 static tree
6476 fold_builtin_inf (tree type, int warn)
6477 {
6478   REAL_VALUE_TYPE real;
6479
6480   if (!MODE_HAS_INFINITIES (TYPE_MODE (type)) && warn)
6481     warning ("target format does not support infinity");
6482
6483   real_inf (&real);
6484   return build_real (type, real);
6485 }
6486
6487 /* Fold a call to __builtin_nan or __builtin_nans.  */
6488
6489 static tree
6490 fold_builtin_nan (tree arglist, tree type, int quiet)
6491 {
6492   REAL_VALUE_TYPE real;
6493   const char *str;
6494
6495   if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6496     return 0;
6497   str = c_getstr (TREE_VALUE (arglist));
6498   if (!str)
6499     return 0;
6500
6501   if (!real_nan (&real, str, quiet, TYPE_MODE (type)))
6502     return 0;
6503
6504   return build_real (type, real);
6505 }
6506
6507 /* Return true if the floating point expression T has an integer value.
6508    We also allow +Inf, -Inf and NaN to be considered integer values.  */
6509
6510 static bool
6511 integer_valued_real_p (tree t)
6512 {
6513   switch (TREE_CODE (t))
6514     {
6515     case FLOAT_EXPR:
6516       return true;
6517
6518     case ABS_EXPR:
6519     case SAVE_EXPR:
6520     case NON_LVALUE_EXPR:
6521       return integer_valued_real_p (TREE_OPERAND (t, 0));
6522
6523     case COMPOUND_EXPR:
6524     case MODIFY_EXPR:
6525     case BIND_EXPR:
6526       return integer_valued_real_p (TREE_OPERAND (t, 1));
6527
6528     case PLUS_EXPR:
6529     case MINUS_EXPR:
6530     case MULT_EXPR:
6531     case MIN_EXPR:
6532     case MAX_EXPR:
6533       return integer_valued_real_p (TREE_OPERAND (t, 0))
6534              && integer_valued_real_p (TREE_OPERAND (t, 1));
6535
6536     case COND_EXPR:
6537       return integer_valued_real_p (TREE_OPERAND (t, 1))
6538              && integer_valued_real_p (TREE_OPERAND (t, 2));
6539
6540     case REAL_CST:
6541       if (! TREE_CONSTANT_OVERFLOW (t))
6542       {
6543         REAL_VALUE_TYPE c, cint;
6544
6545         c = TREE_REAL_CST (t);
6546         real_trunc (&cint, TYPE_MODE (TREE_TYPE (t)), &c);
6547         return real_identical (&c, &cint);
6548       }
6549
6550     case NOP_EXPR:
6551       {
6552         tree type = TREE_TYPE (TREE_OPERAND (t, 0));
6553         if (TREE_CODE (type) == INTEGER_TYPE)
6554           return true;
6555         if (TREE_CODE (type) == REAL_TYPE)
6556           return integer_valued_real_p (TREE_OPERAND (t, 0));
6557         break;
6558       }
6559
6560     case CALL_EXPR:
6561       switch (builtin_mathfn_code (t))
6562         {
6563         case BUILT_IN_CEIL:
6564         case BUILT_IN_CEILF:
6565         case BUILT_IN_CEILL:
6566         case BUILT_IN_FLOOR:
6567         case BUILT_IN_FLOORF:
6568         case BUILT_IN_FLOORL:
6569         case BUILT_IN_NEARBYINT:
6570         case BUILT_IN_NEARBYINTF:
6571         case BUILT_IN_NEARBYINTL:
6572         case BUILT_IN_RINT:
6573         case BUILT_IN_RINTF:
6574         case BUILT_IN_RINTL:
6575         case BUILT_IN_ROUND:
6576         case BUILT_IN_ROUNDF:
6577         case BUILT_IN_ROUNDL:
6578         case BUILT_IN_TRUNC:
6579         case BUILT_IN_TRUNCF:
6580         case BUILT_IN_TRUNCL:
6581           return true;
6582
6583         default:
6584           break;
6585         }
6586       break;
6587
6588     default:
6589       break;
6590     }
6591   return false;
6592 }
6593
6594 /* EXP is assumed to be builtin call where truncation can be propagated
6595    across (for instance floor((double)f) == (double)floorf (f).
6596    Do the transformation.  */
6597
6598 static tree
6599 fold_trunc_transparent_mathfn (tree exp)
6600 {
6601   tree fndecl = get_callee_fndecl (exp);
6602   tree arglist = TREE_OPERAND (exp, 1);
6603   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
6604   tree arg;
6605
6606   if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6607     return 0;
6608
6609   arg = TREE_VALUE (arglist);
6610   /* Integer rounding functions are idempotent.  */
6611   if (fcode == builtin_mathfn_code (arg))
6612     return arg;
6613
6614   /* If argument is already integer valued, and we don't need to worry
6615      about setting errno, there's no need to perform rounding.  */
6616   if (! flag_errno_math && integer_valued_real_p (arg))
6617     return arg;
6618
6619   if (optimize)
6620     {
6621       tree arg0 = strip_float_extensions (arg);
6622       tree ftype = TREE_TYPE (exp);
6623       tree newtype = TREE_TYPE (arg0);
6624       tree decl;
6625
6626       if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
6627           && (decl = mathfn_built_in (newtype, fcode)))
6628         {
6629           arglist =
6630             build_tree_list (NULL_TREE, fold_convert (newtype, arg0));
6631           return fold_convert (ftype,
6632                                build_function_call_expr (decl, arglist));
6633         }
6634     }
6635   return 0;
6636 }
6637
6638 /* EXP is assumed to be builtin call which can narrow the FP type of
6639    the argument, for instance lround((double)f) -> lroundf (f).  */
6640
6641 static tree
6642 fold_fixed_mathfn (tree exp)
6643 {
6644   tree fndecl = get_callee_fndecl (exp);
6645   tree arglist = TREE_OPERAND (exp, 1);
6646   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
6647   tree arg;
6648
6649   if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6650     return 0;
6651
6652   arg = TREE_VALUE (arglist);
6653
6654   /* If argument is already integer valued, and we don't need to worry
6655      about setting errno, there's no need to perform rounding.  */
6656   if (! flag_errno_math && integer_valued_real_p (arg))
6657     return fold (build1 (FIX_TRUNC_EXPR, TREE_TYPE (exp), arg));
6658
6659   if (optimize)
6660     {
6661       tree ftype = TREE_TYPE (arg);
6662       tree arg0 = strip_float_extensions (arg);
6663       tree newtype = TREE_TYPE (arg0);
6664       tree decl;
6665
6666       if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
6667           && (decl = mathfn_built_in (newtype, fcode)))
6668         {
6669           arglist =
6670             build_tree_list (NULL_TREE, fold_convert (newtype, arg0));
6671           return build_function_call_expr (decl, arglist);
6672         }
6673     }
6674   return 0;
6675 }
6676
6677 /* Fold function call to builtin cabs, cabsf or cabsl.  ARGLIST
6678    is the argument list and TYPE is the return type.  Return
6679    NULL_TREE if no if no simplification can be made.  */
6680
6681 static tree
6682 fold_builtin_cabs (tree arglist, tree type)
6683 {
6684   tree arg;
6685
6686   if (!arglist || TREE_CHAIN (arglist))
6687     return NULL_TREE;
6688
6689   arg = TREE_VALUE (arglist);
6690   if (TREE_CODE (TREE_TYPE (arg)) != COMPLEX_TYPE
6691       || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) != REAL_TYPE)
6692     return NULL_TREE;
6693
6694   /* Evaluate cabs of a constant at compile-time.  */
6695   if (flag_unsafe_math_optimizations
6696       && TREE_CODE (arg) == COMPLEX_CST
6697       && TREE_CODE (TREE_REALPART (arg)) == REAL_CST
6698       && TREE_CODE (TREE_IMAGPART (arg)) == REAL_CST
6699       && ! TREE_CONSTANT_OVERFLOW (TREE_REALPART (arg))
6700       && ! TREE_CONSTANT_OVERFLOW (TREE_IMAGPART (arg)))
6701     {
6702       REAL_VALUE_TYPE r, i;
6703
6704       r = TREE_REAL_CST (TREE_REALPART (arg));
6705       i = TREE_REAL_CST (TREE_IMAGPART (arg));
6706
6707       real_arithmetic (&r, MULT_EXPR, &r, &r);
6708       real_arithmetic (&i, MULT_EXPR, &i, &i);
6709       real_arithmetic (&r, PLUS_EXPR, &r, &i);
6710       if (real_sqrt (&r, TYPE_MODE (type), &r)
6711           || ! flag_trapping_math)
6712         return build_real (type, r);
6713     }
6714
6715   /* If either part is zero, cabs is fabs of the other.  */
6716   if (TREE_CODE (arg) == COMPLEX_EXPR
6717       && real_zerop (TREE_OPERAND (arg, 0)))
6718     return fold (build1 (ABS_EXPR, type, TREE_OPERAND (arg, 1)));
6719   if (TREE_CODE (arg) == COMPLEX_EXPR
6720       && real_zerop (TREE_OPERAND (arg, 1)))
6721     return fold (build1 (ABS_EXPR, type, TREE_OPERAND (arg, 0)));
6722
6723   if (flag_unsafe_math_optimizations)
6724     {
6725       tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
6726
6727       if (sqrtfn != NULL_TREE)
6728         {
6729           tree rpart, ipart, result, arglist;
6730
6731           arg = builtin_save_expr (arg);
6732
6733           rpart = fold (build1 (REALPART_EXPR, type, arg));
6734           ipart = fold (build1 (IMAGPART_EXPR, type, arg));
6735
6736           rpart = builtin_save_expr (rpart);
6737           ipart = builtin_save_expr (ipart);
6738
6739           result = fold (build2 (PLUS_EXPR, type,
6740                                  fold (build2 (MULT_EXPR, type,
6741                                                rpart, rpart)),
6742                                  fold (build2 (MULT_EXPR, type,
6743                                                ipart, ipart))));
6744
6745           arglist = build_tree_list (NULL_TREE, result);
6746           return build_function_call_expr (sqrtfn, arglist);
6747         }
6748     }
6749
6750   return NULL_TREE;
6751 }
6752
6753 /* Fold function call to builtin trunc, truncf or truncl.  Return
6754    NULL_TREE if no simplification can be made.  */
6755
6756 static tree
6757 fold_builtin_trunc (tree exp)
6758 {
6759   tree arglist = TREE_OPERAND (exp, 1);
6760   tree arg;
6761
6762   if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6763     return 0;
6764
6765   /* Optimize trunc of constant value.  */
6766   arg = TREE_VALUE (arglist);
6767   if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
6768     {
6769       REAL_VALUE_TYPE r, x;
6770       tree type = TREE_TYPE (exp);
6771
6772       x = TREE_REAL_CST (arg);
6773       real_trunc (&r, TYPE_MODE (type), &x);
6774       return build_real (type, r);
6775     }
6776
6777   return fold_trunc_transparent_mathfn (exp);
6778 }
6779
6780 /* Fold function call to builtin floor, floorf or floorl.  Return
6781    NULL_TREE if no simplification can be made.  */
6782
6783 static tree
6784 fold_builtin_floor (tree exp)
6785 {
6786   tree arglist = TREE_OPERAND (exp, 1);
6787   tree arg;
6788
6789   if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6790     return 0;
6791
6792   /* Optimize floor of constant value.  */
6793   arg = TREE_VALUE (arglist);
6794   if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
6795     {
6796       REAL_VALUE_TYPE x;
6797
6798       x = TREE_REAL_CST (arg);
6799       if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
6800         {
6801           tree type = TREE_TYPE (exp);
6802           REAL_VALUE_TYPE r;
6803
6804           real_floor (&r, TYPE_MODE (type), &x);
6805           return build_real (type, r);
6806         }
6807     }
6808
6809   return fold_trunc_transparent_mathfn (exp);
6810 }
6811
6812 /* Fold function call to builtin ceil, ceilf or ceill.  Return
6813    NULL_TREE if no simplification can be made.  */
6814
6815 static tree
6816 fold_builtin_ceil (tree exp)
6817 {
6818   tree arglist = TREE_OPERAND (exp, 1);
6819   tree arg;
6820
6821   if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6822     return 0;
6823
6824   /* Optimize ceil of constant value.  */
6825   arg = TREE_VALUE (arglist);
6826   if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
6827     {
6828       REAL_VALUE_TYPE x;
6829
6830       x = TREE_REAL_CST (arg);
6831       if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
6832         {
6833           tree type = TREE_TYPE (exp);
6834           REAL_VALUE_TYPE r;
6835
6836           real_ceil (&r, TYPE_MODE (type), &x);
6837           return build_real (type, r);
6838         }
6839     }
6840
6841   return fold_trunc_transparent_mathfn (exp);
6842 }
6843
6844 /* Fold function call to builtin round, roundf or roundl.  Return
6845    NULL_TREE if no simplification can be made.  */
6846
6847 static tree
6848 fold_builtin_round (tree exp)
6849 {
6850   tree arglist = TREE_OPERAND (exp, 1);
6851   tree arg;
6852
6853   if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6854     return 0;
6855
6856   /* Optimize round of constant value.  */
6857   arg = TREE_VALUE (arglist);
6858   if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
6859     {
6860       REAL_VALUE_TYPE x;
6861
6862       x = TREE_REAL_CST (arg);
6863       if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
6864         {
6865           tree type = TREE_TYPE (exp);
6866           REAL_VALUE_TYPE r;
6867
6868           real_round (&r, TYPE_MODE (type), &x);
6869           return build_real (type, r);
6870         }
6871     }
6872
6873   return fold_trunc_transparent_mathfn (exp);
6874 }
6875
6876 /* Fold function call to builtin lround, lroundf or lroundl (or the
6877    corresponding long long versions).  Return NULL_TREE if no
6878    simplification can be made.  */
6879
6880 static tree
6881 fold_builtin_lround (tree exp)
6882 {
6883   tree arglist = TREE_OPERAND (exp, 1);
6884   tree arg;
6885
6886   if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6887     return 0;
6888
6889   /* Optimize lround of constant value.  */
6890   arg = TREE_VALUE (arglist);
6891   if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
6892     {
6893       const REAL_VALUE_TYPE x = TREE_REAL_CST (arg);
6894
6895       if (! REAL_VALUE_ISNAN (x) && ! REAL_VALUE_ISINF (x))
6896         {
6897           tree itype = TREE_TYPE (exp), ftype = TREE_TYPE (arg), result;
6898           HOST_WIDE_INT hi, lo;
6899           REAL_VALUE_TYPE r;
6900
6901           real_round (&r, TYPE_MODE (ftype), &x);
6902           REAL_VALUE_TO_INT (&lo, &hi, r);
6903           result = build_int_2 (lo, hi);
6904           if (int_fits_type_p (result, itype))
6905             return fold_convert (itype, result);
6906         }
6907     }
6908
6909   return fold_fixed_mathfn (exp);
6910 }
6911
6912 /* Fold function call to builtin ffs, clz, ctz, popcount and parity
6913    and their long and long long variants (i.e. ffsl and ffsll).
6914    Return NULL_TREE if no simplification can be made.  */
6915
6916 static tree
6917 fold_builtin_bitop (tree exp)
6918 {
6919   tree fndecl = get_callee_fndecl (exp);
6920   tree arglist = TREE_OPERAND (exp, 1);
6921   tree arg;
6922
6923   if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
6924     return NULL_TREE;
6925
6926   /* Optimize for constant argument.  */
6927   arg = TREE_VALUE (arglist);
6928   if (TREE_CODE (arg) == INTEGER_CST && ! TREE_CONSTANT_OVERFLOW (arg))
6929     {
6930       HOST_WIDE_INT hi, width, result;
6931       unsigned HOST_WIDE_INT lo;
6932       tree type, t;
6933
6934       type = TREE_TYPE (arg);
6935       width = TYPE_PRECISION (type);
6936       lo = TREE_INT_CST_LOW (arg);
6937
6938       /* Clear all the bits that are beyond the type's precision.  */
6939       if (width > HOST_BITS_PER_WIDE_INT)
6940         {
6941           hi = TREE_INT_CST_HIGH (arg);
6942           if (width < 2 * HOST_BITS_PER_WIDE_INT)
6943             hi &= ~((HOST_WIDE_INT) (-1) >> (width - HOST_BITS_PER_WIDE_INT));
6944         }
6945       else
6946         {
6947           hi = 0;
6948           if (width < HOST_BITS_PER_WIDE_INT)
6949             lo &= ~((unsigned HOST_WIDE_INT) (-1) << width);
6950         }
6951
6952       switch (DECL_FUNCTION_CODE (fndecl))
6953         {
6954         case BUILT_IN_FFS:
6955         case BUILT_IN_FFSL:
6956         case BUILT_IN_FFSLL:
6957           if (lo != 0)
6958             result = exact_log2 (lo & -lo) + 1;
6959           else if (hi != 0)
6960             result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi) + 1;
6961           else
6962             result = 0;
6963           break;
6964
6965         case BUILT_IN_CLZ:
6966         case BUILT_IN_CLZL:
6967         case BUILT_IN_CLZLL:
6968           if (hi != 0)
6969             result = width - floor_log2 (hi) - 1 - HOST_BITS_PER_WIDE_INT;
6970           else if (lo != 0)
6971             result = width - floor_log2 (lo) - 1;
6972           else if (! CLZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
6973             result = width;
6974           break;
6975
6976         case BUILT_IN_CTZ:
6977         case BUILT_IN_CTZL:
6978         case BUILT_IN_CTZLL:
6979           if (lo != 0)
6980             result = exact_log2 (lo & -lo);
6981           else if (hi != 0)
6982             result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi);
6983           else if (! CTZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
6984             result = width;
6985           break;
6986
6987         case BUILT_IN_POPCOUNT:
6988         case BUILT_IN_POPCOUNTL:
6989         case BUILT_IN_POPCOUNTLL:
6990           result = 0;
6991           while (lo)
6992             result++, lo &= lo - 1;
6993           while (hi)
6994             result++, hi &= hi - 1;
6995           break;
6996
6997         case BUILT_IN_PARITY:
6998         case BUILT_IN_PARITYL:
6999         case BUILT_IN_PARITYLL:
7000           result = 0;
7001           while (lo)
7002             result++, lo &= lo - 1;
7003           while (hi)
7004             result++, hi &= hi - 1;
7005           result &= 1;
7006           break;
7007
7008         default:
7009           abort();
7010         }
7011
7012       t = build_int_2 (result, 0);
7013       TREE_TYPE (t) = TREE_TYPE (exp);
7014       return t;
7015     }
7016
7017   return NULL_TREE;
7018 }
7019
7020 /* Return true if EXPR is the real constant contained in VALUE.  */
7021
7022 static bool
7023 real_dconstp (tree expr, const REAL_VALUE_TYPE *value)
7024 {
7025   STRIP_NOPS (expr);
7026
7027   return ((TREE_CODE (expr) == REAL_CST
7028            && ! TREE_CONSTANT_OVERFLOW (expr)
7029            && REAL_VALUES_EQUAL (TREE_REAL_CST (expr), *value))
7030           || (TREE_CODE (expr) == COMPLEX_CST
7031               && real_dconstp (TREE_REALPART (expr), value)
7032               && real_zerop (TREE_IMAGPART (expr))));
7033 }
7034
7035 /* A subroutine of fold_builtin to fold the various logarithmic
7036    functions.  EXP is the CALL_EXPR of a call to a builtin logN
7037    function.  VALUE is the base of the logN function.  */
7038
7039 static tree
7040 fold_builtin_logarithm (tree exp, const REAL_VALUE_TYPE *value)
7041 {
7042   tree arglist = TREE_OPERAND (exp, 1);
7043
7044   if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7045     {
7046       tree fndecl = get_callee_fndecl (exp);
7047       tree type = TREE_TYPE (TREE_TYPE (fndecl));
7048       tree arg = TREE_VALUE (arglist);
7049       const enum built_in_function fcode = builtin_mathfn_code (arg);
7050
7051       /* Optimize logN(1.0) = 0.0.  */
7052       if (real_onep (arg))
7053         return build_real (type, dconst0);
7054
7055       /* Optimize logN(N) = 1.0.  If N can't be truncated to MODE
7056          exactly, then only do this if flag_unsafe_math_optimizations.  */
7057       if (exact_real_truncate (TYPE_MODE (type), value)
7058           || flag_unsafe_math_optimizations)
7059         {
7060           const REAL_VALUE_TYPE value_truncate =
7061             real_value_truncate (TYPE_MODE (type), *value);
7062           if (real_dconstp (arg, &value_truncate))
7063             return build_real (type, dconst1);
7064         }
7065
7066       /* Special case, optimize logN(expN(x)) = x.  */
7067       if (flag_unsafe_math_optimizations
7068           && ((value == &dconste
7069                && (fcode == BUILT_IN_EXP
7070                    || fcode == BUILT_IN_EXPF
7071                    || fcode == BUILT_IN_EXPL))
7072               || (value == &dconst2
7073                   && (fcode == BUILT_IN_EXP2
7074                       || fcode == BUILT_IN_EXP2F
7075                       || fcode == BUILT_IN_EXP2L))
7076               || (value == &dconst10 && (BUILTIN_EXP10_P (fcode)))))
7077         return fold_convert (type, TREE_VALUE (TREE_OPERAND (arg, 1)));
7078
7079       /* Optimize logN(func()) for various exponential functions.  We
7080          want to determine the value "x" and the power "exponent" in
7081          order to transform logN(x**exponent) into exponent*logN(x).  */
7082       if (flag_unsafe_math_optimizations)
7083         {
7084           tree exponent = 0, x = 0;
7085
7086           switch (fcode)
7087           {
7088           case BUILT_IN_EXP:
7089           case BUILT_IN_EXPF:
7090           case BUILT_IN_EXPL:
7091             /* Prepare to do logN(exp(exponent) -> exponent*logN(e).  */
7092             x = build_real (type,
7093                             real_value_truncate (TYPE_MODE (type), dconste));
7094             exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
7095             break;
7096           case BUILT_IN_EXP2:
7097           case BUILT_IN_EXP2F:
7098           case BUILT_IN_EXP2L:
7099             /* Prepare to do logN(exp2(exponent) -> exponent*logN(2).  */
7100             x = build_real (type, dconst2);
7101             exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
7102             break;
7103           case BUILT_IN_EXP10:
7104           case BUILT_IN_EXP10F:
7105           case BUILT_IN_EXP10L:
7106           case BUILT_IN_POW10:
7107           case BUILT_IN_POW10F:
7108           case BUILT_IN_POW10L:
7109             /* Prepare to do logN(exp10(exponent) -> exponent*logN(10).  */
7110             x = build_real (type, dconst10);
7111             exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
7112             break;
7113           case BUILT_IN_SQRT:
7114           case BUILT_IN_SQRTF:
7115           case BUILT_IN_SQRTL:
7116             /* Prepare to do logN(sqrt(x) -> 0.5*logN(x).  */
7117             x = TREE_VALUE (TREE_OPERAND (arg, 1));
7118             exponent = build_real (type, dconsthalf);
7119             break;
7120           case BUILT_IN_CBRT:
7121           case BUILT_IN_CBRTF:
7122           case BUILT_IN_CBRTL:
7123             /* Prepare to do logN(cbrt(x) -> (1/3)*logN(x).  */
7124             x = TREE_VALUE (TREE_OPERAND (arg, 1));
7125             exponent = build_real (type, real_value_truncate (TYPE_MODE (type),
7126                                                               dconstthird));
7127             break;
7128           case BUILT_IN_POW:
7129           case BUILT_IN_POWF:
7130           case BUILT_IN_POWL:
7131             /* Prepare to do logN(pow(x,exponent) -> exponent*logN(x).  */
7132             x = TREE_VALUE (TREE_OPERAND (arg, 1));
7133             exponent = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
7134             break;
7135           default:
7136             break;
7137           }
7138
7139           /* Now perform the optimization.  */
7140           if (x && exponent)
7141             {
7142               tree logfn;
7143               arglist = build_tree_list (NULL_TREE, x);
7144               logfn = build_function_call_expr (fndecl, arglist);
7145               return fold (build2 (MULT_EXPR, type, exponent, logfn));
7146             }
7147         }
7148     }
7149
7150   return 0;
7151 }
7152
7153 /* A subroutine of fold_builtin to fold the various exponent
7154    functions.  EXP is the CALL_EXPR of a call to a builtin function.
7155    VALUE is the value which will be raised to a power.  */
7156
7157 static tree
7158 fold_builtin_exponent (tree exp, const REAL_VALUE_TYPE *value)
7159 {
7160   tree arglist = TREE_OPERAND (exp, 1);
7161
7162   if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7163     {
7164       tree fndecl = get_callee_fndecl (exp);
7165       tree type = TREE_TYPE (TREE_TYPE (fndecl));
7166       tree arg = TREE_VALUE (arglist);
7167
7168       /* Optimize exp*(0.0) = 1.0.  */
7169       if (real_zerop (arg))
7170         return build_real (type, dconst1);
7171
7172       /* Optimize expN(1.0) = N.  */
7173       if (real_onep (arg))
7174         {
7175           REAL_VALUE_TYPE cst;
7176
7177           real_convert (&cst, TYPE_MODE (type), value);
7178           return build_real (type, cst);
7179         }
7180
7181       /* Attempt to evaluate expN(integer) at compile-time.  */
7182       if (flag_unsafe_math_optimizations
7183           && TREE_CODE (arg) == REAL_CST
7184           && ! TREE_CONSTANT_OVERFLOW (arg))
7185         {
7186           REAL_VALUE_TYPE cint;
7187           REAL_VALUE_TYPE c;
7188           HOST_WIDE_INT n;
7189
7190           c = TREE_REAL_CST (arg);
7191           n = real_to_integer (&c);
7192           real_from_integer (&cint, VOIDmode, n,
7193                              n < 0 ? -1 : 0, 0);
7194           if (real_identical (&c, &cint))
7195             {
7196               REAL_VALUE_TYPE x;
7197
7198               real_powi (&x, TYPE_MODE (type), value, n);
7199               return build_real (type, x);
7200             }
7201         }
7202
7203       /* Optimize expN(logN(x)) = x.  */
7204       if (flag_unsafe_math_optimizations)
7205         {
7206           const enum built_in_function fcode = builtin_mathfn_code (arg);
7207
7208           if ((value == &dconste
7209                && (fcode == BUILT_IN_LOG
7210                    || fcode == BUILT_IN_LOGF
7211                    || fcode == BUILT_IN_LOGL))
7212               || (value == &dconst2
7213                   && (fcode == BUILT_IN_LOG2
7214                       || fcode == BUILT_IN_LOG2F
7215                       || fcode == BUILT_IN_LOG2L))
7216               || (value == &dconst10
7217                   && (fcode == BUILT_IN_LOG10
7218                       || fcode == BUILT_IN_LOG10F
7219                       || fcode == BUILT_IN_LOG10L)))
7220             return fold_convert (type, TREE_VALUE (TREE_OPERAND (arg, 1)));
7221         }
7222     }
7223
7224   return 0;
7225 }
7226
7227 /* Fold function call to builtin memcpy.  Return
7228    NULL_TREE if no simplification can be made.  */
7229
7230 static tree
7231 fold_builtin_memcpy (tree exp)
7232 {
7233   tree arglist = TREE_OPERAND (exp, 1);
7234   tree dest, src, len;
7235
7236   if (!validate_arglist (arglist,
7237                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7238     return 0;
7239
7240   dest = TREE_VALUE (arglist);
7241   src = TREE_VALUE (TREE_CHAIN (arglist));
7242   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7243
7244   /* If the LEN parameter is zero, return DEST.  */
7245   if (integer_zerop (len))
7246     return omit_one_operand (TREE_TYPE (exp), dest, src);
7247
7248   /* If SRC and DEST are the same (and not volatile), return DEST.  */
7249   if (operand_equal_p (src, dest, 0))
7250     return omit_one_operand (TREE_TYPE (exp), dest, len);
7251
7252   return 0;
7253 }
7254
7255 /* Fold function call to builtin mempcpy.  Return
7256    NULL_TREE if no simplification can be made.  */
7257
7258 static tree
7259 fold_builtin_mempcpy (tree exp)
7260 {
7261   tree arglist = TREE_OPERAND (exp, 1);
7262   tree dest, src, len;
7263
7264   if (!validate_arglist (arglist,
7265                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7266     return 0;
7267
7268   dest = TREE_VALUE (arglist);
7269   src = TREE_VALUE (TREE_CHAIN (arglist));
7270   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7271
7272   /* If the LEN parameter is zero, return DEST.  */
7273   if (integer_zerop (len))
7274     return omit_one_operand (TREE_TYPE (exp), dest, src);
7275
7276   /* If SRC and DEST are the same (and not volatile), return DEST+LEN.  */
7277   if (operand_equal_p (src, dest, 0))
7278     {
7279       tree temp = fold_convert (TREE_TYPE (dest), len);
7280       temp = fold (build2 (PLUS_EXPR, TREE_TYPE (dest), dest, temp));
7281       return fold_convert (TREE_TYPE (exp), temp);
7282     }
7283
7284   return 0;
7285 }
7286
7287 /* Fold function call to builtin memmove.  Return
7288    NULL_TREE if no simplification can be made.  */
7289
7290 static tree
7291 fold_builtin_memmove (tree exp)
7292 {
7293   tree arglist = TREE_OPERAND (exp, 1);
7294   tree dest, src, len;
7295
7296   if (!validate_arglist (arglist,
7297                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7298     return 0;
7299
7300   dest = TREE_VALUE (arglist);
7301   src = TREE_VALUE (TREE_CHAIN (arglist));
7302   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7303
7304   /* If the LEN parameter is zero, return DEST.  */
7305   if (integer_zerop (len))
7306     return omit_one_operand (TREE_TYPE (exp), dest, src);
7307
7308   /* If SRC and DEST are the same (and not volatile), return DEST.  */
7309   if (operand_equal_p (src, dest, 0))
7310     return omit_one_operand (TREE_TYPE (exp), dest, len);
7311
7312   return 0;
7313 }
7314
7315 /* Fold function call to builtin strcpy.  If LEN is not NULL, it represents
7316    the length of the string to be copied.  Return NULL_TREE if no
7317    simplification can be made.  */
7318
7319 tree
7320 fold_builtin_strcpy (tree exp, tree len)
7321 {
7322   tree arglist = TREE_OPERAND (exp, 1);
7323   tree dest, src, fn;
7324
7325   if (!validate_arglist (arglist,
7326                          POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
7327     return 0;
7328
7329   dest = TREE_VALUE (arglist);
7330   src = TREE_VALUE (TREE_CHAIN (arglist));
7331
7332   /* If SRC and DEST are the same (and not volatile), return DEST.  */
7333   if (operand_equal_p (src, dest, 0))
7334     return fold_convert (TREE_TYPE (exp), dest);
7335
7336   if (optimize_size)
7337     return 0;
7338
7339   fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
7340   if (!fn)
7341     return 0;
7342
7343   if (!len)
7344     {
7345       len = c_strlen (src, 1);
7346       if (! len || TREE_SIDE_EFFECTS (len))
7347         return 0;
7348     }
7349
7350   len = size_binop (PLUS_EXPR, len, ssize_int (1));
7351   arglist = build_tree_list (NULL_TREE, len);
7352   arglist = tree_cons (NULL_TREE, src, arglist);
7353   arglist = tree_cons (NULL_TREE, dest, arglist);
7354   return fold_convert (TREE_TYPE (exp),
7355                        build_function_call_expr (fn, arglist));
7356 }
7357
7358 /* Fold function call to builtin strncpy.  If SLEN is not NULL, it represents
7359    the length of the source string.  Return NULL_TREE if no simplification
7360    can be made.  */
7361
7362 tree
7363 fold_builtin_strncpy (tree exp, tree slen)
7364 {
7365   tree arglist = TREE_OPERAND (exp, 1);
7366   tree dest, src, len, fn;
7367
7368   if (!validate_arglist (arglist,
7369                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7370     return 0;
7371
7372   dest = TREE_VALUE (arglist);
7373   src = TREE_VALUE (TREE_CHAIN (arglist));
7374   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7375
7376   /* If the LEN parameter is zero, return DEST.  */
7377   if (integer_zerop (len))
7378     return omit_one_operand (TREE_TYPE (exp), dest, src);
7379
7380   /* We can't compare slen with len as constants below if len is not a
7381      constant.  */
7382   if (len == 0 || TREE_CODE (len) != INTEGER_CST)
7383     return 0;
7384
7385   if (!slen)
7386     slen = c_strlen (src, 1);
7387
7388   /* Now, we must be passed a constant src ptr parameter.  */
7389   if (slen == 0 || TREE_CODE (slen) != INTEGER_CST)
7390     return 0;
7391
7392   slen = size_binop (PLUS_EXPR, slen, ssize_int (1));
7393
7394   /* We do not support simplification of this case, though we do
7395      support it when expanding trees into RTL.  */
7396   /* FIXME: generate a call to __builtin_memset.  */
7397   if (tree_int_cst_lt (slen, len))
7398     return 0;
7399
7400   /* OK transform into builtin memcpy.  */
7401   fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
7402   if (!fn)
7403     return 0;
7404   return fold_convert (TREE_TYPE (exp),
7405                        build_function_call_expr (fn, arglist));
7406 }
7407
7408 /* Fold function call to builtin strchr and strrchr.
7409    Return NULL_TREE if no simplification can be made.  */
7410
7411 static tree
7412 fold_builtin_strchr (tree exp, bool actually_strrchr)
7413 {
7414   tree arglist = TREE_OPERAND (exp, 1);
7415   if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7416     return 0;
7417   else
7418     {
7419       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
7420       const char *p1;
7421
7422       if (TREE_CODE (s2) != INTEGER_CST)
7423         return 0;
7424
7425       p1 = c_getstr (s1);
7426       if (p1 != NULL)
7427         {
7428           char c;
7429           const char *r;
7430
7431           if (target_char_cast (s2, &c))
7432             return 0;
7433
7434           r = actually_strrchr ? strrchr (p1, c) : strchr (p1, c);
7435
7436           if (r == NULL)
7437             return fold_convert (TREE_TYPE (s1), integer_zero_node);
7438
7439           /* Return an offset into the constant string argument.  */
7440           return fold (build2 (PLUS_EXPR, TREE_TYPE (s1),
7441                                s1, fold_convert (TREE_TYPE (s1),
7442                                                  ssize_int (r - p1))));
7443         }
7444
7445       if (actually_strrchr)
7446         {
7447           tree fn;
7448
7449           if (!integer_zerop (s2))
7450             return 0;
7451
7452           fn = implicit_built_in_decls[BUILT_IN_STRCHR];
7453           if (!fn)
7454             return 0;
7455
7456           /* Transform strrchr(s1, '\0') to strchr(s1, '\0').  */
7457           return build_function_call_expr (fn, arglist);
7458         }
7459
7460       return 0;
7461     }
7462 }
7463
7464 /* Fold function call to builtin memcmp.  Return
7465    NULL_TREE if no simplification can be made.  */
7466
7467 static tree
7468 fold_builtin_memcmp (tree exp)
7469 {
7470   tree arglist = TREE_OPERAND (exp, 1);
7471   tree arg1, arg2, len;
7472
7473   if (!validate_arglist (arglist,
7474                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7475     return 0;
7476
7477   arg1 = TREE_VALUE (arglist);
7478   arg2 = TREE_VALUE (TREE_CHAIN (arglist));
7479   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7480
7481   /* If the LEN parameter is zero, return zero.  */
7482   if (integer_zerop (len))
7483     {
7484       tree temp = omit_one_operand (TREE_TYPE (exp), integer_zero_node, arg2);
7485       return omit_one_operand (TREE_TYPE (exp), temp, arg1);
7486     }
7487
7488   /* If ARG1 and ARG2 are the same (and not volatile), return zero.  */
7489   if (operand_equal_p (arg1, arg2, 0))
7490     return omit_one_operand (TREE_TYPE (exp), integer_zero_node, len);
7491
7492   return 0;
7493 }
7494
7495 /* Fold function call to builtin strcmp.  Return
7496    NULL_TREE if no simplification can be made.  */
7497
7498 static tree
7499 fold_builtin_strcmp (tree exp)
7500 {
7501   tree arglist = TREE_OPERAND (exp, 1);
7502   tree arg1, arg2;
7503   const char *p1, *p2;
7504
7505   if (!validate_arglist (arglist,
7506                          POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
7507     return 0;
7508
7509   arg1 = TREE_VALUE (arglist);
7510   arg2 = TREE_VALUE (TREE_CHAIN (arglist));
7511
7512   /* If ARG1 and ARG2 are the same (and not volatile), return zero.  */
7513   if (operand_equal_p (arg1, arg2, 0))
7514     return fold_convert (TREE_TYPE (exp), integer_zero_node);
7515
7516   p1 = c_getstr (arg1);
7517   p2 = c_getstr (arg2);
7518
7519   if (p1 && p2)
7520     {
7521       tree temp;
7522       const int i = strcmp (p1, p2);
7523       if (i < 0)
7524         temp = integer_minus_one_node;
7525       else if (i > 0)
7526         temp = integer_one_node;
7527       else
7528         temp = integer_zero_node;
7529       return fold_convert (TREE_TYPE (exp), temp);
7530     }
7531
7532   return 0;
7533 }
7534
7535 /* Fold function call to builtin strncmp.  Return
7536    NULL_TREE if no simplification can be made.  */
7537
7538 static tree
7539 fold_builtin_strncmp (tree exp)
7540 {
7541   tree arglist = TREE_OPERAND (exp, 1);
7542   tree arg1, arg2, len;
7543   const char *p1, *p2;
7544
7545   if (!validate_arglist (arglist,
7546                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7547     return 0;
7548
7549   arg1 = TREE_VALUE (arglist);
7550   arg2 = TREE_VALUE (TREE_CHAIN (arglist));
7551   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7552
7553   /* If the LEN parameter is zero, return zero.  */
7554   if (integer_zerop (len))
7555     {
7556       tree temp = omit_one_operand (TREE_TYPE (exp), integer_zero_node, arg2);
7557       return omit_one_operand (TREE_TYPE (exp), temp, arg1);
7558     }
7559
7560   /* If ARG1 and ARG2 are the same (and not volatile), return zero.  */
7561   if (operand_equal_p (arg1, arg2, 0))
7562     return omit_one_operand (TREE_TYPE (exp), integer_zero_node, len);
7563
7564   p1 = c_getstr (arg1);
7565   p2 = c_getstr (arg2);
7566
7567   if (host_integerp (len, 1) && p1 && p2)
7568     {
7569       tree temp;
7570       const int i = strncmp (p1, p2, tree_low_cst (len, 1));
7571       if (i < 0)
7572         temp = integer_minus_one_node;
7573       else if (i > 0)
7574         temp = integer_one_node;
7575       else
7576         temp = integer_zero_node;
7577       return fold_convert (TREE_TYPE (exp), temp);
7578     }
7579
7580   return 0;
7581 }
7582
7583 /* Fold function call to builtin signbit, signbitf or signbitl.  Return
7584    NULL_TREE if no simplification can be made.  */
7585
7586 static tree
7587 fold_builtin_signbit (tree exp)
7588 {
7589   tree arglist = TREE_OPERAND (exp, 1);
7590   tree arg, temp;
7591
7592   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7593     return NULL_TREE;
7594
7595   arg = TREE_VALUE (arglist);
7596
7597   /* If ARG is a compile-time constant, determine the result.  */
7598   if (TREE_CODE (arg) == REAL_CST
7599       && !TREE_CONSTANT_OVERFLOW (arg))
7600     {
7601       REAL_VALUE_TYPE c;
7602
7603       c = TREE_REAL_CST (arg);
7604       temp = REAL_VALUE_NEGATIVE (c) ? integer_one_node : integer_zero_node;
7605       return fold_convert (TREE_TYPE (exp), temp);
7606     }
7607
7608   /* If ARG is non-negative, the result is always zero.  */
7609   if (tree_expr_nonnegative_p (arg))
7610     return omit_one_operand (TREE_TYPE (exp), integer_zero_node, arg);
7611
7612   /* If ARG's format doesn't have signed zeros, return "arg < 0.0".  */
7613   if (!HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg))))
7614     return fold (build2 (LT_EXPR, TREE_TYPE (exp), arg,
7615                          build_real (TREE_TYPE (arg), dconst0)));
7616
7617   return NULL_TREE;
7618 }
7619
7620 /* Fold function call to builtin copysign, copysignf or copysignl.
7621    Return NULL_TREE if no simplification can be made.  */
7622
7623 static tree
7624 fold_builtin_copysign (tree arglist, tree type)
7625 {
7626   tree arg1, arg2;
7627
7628   if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
7629     return NULL_TREE;
7630
7631   arg1 = TREE_VALUE (arglist);
7632   arg2 = TREE_VALUE (TREE_CHAIN (arglist));
7633
7634   /* copysign(X,X) is X.  */
7635   if (operand_equal_p (arg1, arg2, 0))
7636     return fold_convert (type, arg1);
7637
7638   /* If ARG1 and ARG2 are compile-time constants, determine the result.  */
7639   if (TREE_CODE (arg1) == REAL_CST
7640       && TREE_CODE (arg2) == REAL_CST
7641       && !TREE_CONSTANT_OVERFLOW (arg1)
7642       && !TREE_CONSTANT_OVERFLOW (arg2))
7643     {
7644       REAL_VALUE_TYPE c1, c2;
7645
7646       c1 = TREE_REAL_CST (arg1);
7647       c2 = TREE_REAL_CST (arg2);
7648       real_copysign (&c1, &c2);
7649       return build_real (type, c1);
7650       c1.sign = c2.sign;
7651     }
7652
7653   /* copysign(X, Y) is fabs(X) when Y is always non-negative.
7654      Remember to evaluate Y for side-effects.  */
7655   if (tree_expr_nonnegative_p (arg2))
7656     return omit_one_operand (type,
7657                              fold (build1 (ABS_EXPR, type, arg1)),
7658                              arg2);
7659
7660   return NULL_TREE;
7661 }
7662
7663 /* Fold a call to builtin isascii.  */
7664
7665 static tree
7666 fold_builtin_isascii (tree arglist)
7667 {
7668   if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
7669     return 0;
7670   else
7671     {
7672       /* Transform isascii(c) -> ((c & ~0x7f) == 0).  */
7673       tree arg = TREE_VALUE (arglist);
7674       
7675       arg = fold (build2 (EQ_EXPR, integer_type_node,
7676                           build2 (BIT_AND_EXPR, integer_type_node, arg,
7677                                   build_int_2 (~ (unsigned HOST_WIDE_INT) 0x7f,
7678                                                ~ (HOST_WIDE_INT) 0)),
7679                           integer_zero_node));
7680       
7681       if (in_gimple_form && !TREE_CONSTANT (arg))
7682         return NULL_TREE;
7683       else
7684         return arg;
7685     }
7686 }
7687
7688 /* Fold a call to builtin toascii.  */
7689
7690 static tree
7691 fold_builtin_toascii (tree arglist)
7692 {
7693   if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
7694     return 0;
7695   else
7696     {
7697       /* Transform toascii(c) -> (c & 0x7f).  */
7698       tree arg = TREE_VALUE (arglist);
7699       
7700       return fold (build2 (BIT_AND_EXPR, integer_type_node, arg,
7701                            build_int_2 (0x7f, 0)));
7702     }
7703 }
7704
7705 /* Fold a call to builtin isdigit.  */
7706
7707 static tree
7708 fold_builtin_isdigit (tree arglist)
7709 {
7710   if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
7711     return 0;
7712   else
7713     {
7714       /* Transform isdigit(c) -> (unsigned)(c) - '0' <= 9.  */
7715       /* According to the C standard, isdigit is unaffected by locale.  */
7716       tree arg = TREE_VALUE (arglist);
7717       arg = fold_convert (unsigned_type_node, arg);
7718       arg = build2 (MINUS_EXPR, unsigned_type_node, arg,
7719                     fold_convert (unsigned_type_node,
7720                                   build_int_2 (TARGET_DIGIT0, 0)));
7721       arg = build2 (LE_EXPR, integer_type_node, arg,
7722                     fold_convert (unsigned_type_node, build_int_2 (9, 0)));
7723       arg = fold (arg);
7724       if (in_gimple_form && !TREE_CONSTANT (arg))
7725         return NULL_TREE;
7726       else
7727         return arg;
7728     }
7729 }
7730
7731 /* Fold a call to fabs, fabsf or fabsl.  */
7732
7733 static tree
7734 fold_builtin_fabs (tree arglist, tree type)
7735 {
7736   tree arg;
7737
7738   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7739     return 0;
7740
7741   arg = TREE_VALUE (arglist);
7742   if (TREE_CODE (arg) == REAL_CST)
7743     return fold_abs_const (arg, type);
7744   return fold (build1 (ABS_EXPR, type, arg));
7745 }
7746
7747 /* Fold a call to abs, labs, llabs or imaxabs.  */
7748
7749 static tree
7750 fold_builtin_abs (tree arglist, tree type)
7751 {
7752   tree arg;
7753
7754   if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
7755     return 0;
7756
7757   arg = TREE_VALUE (arglist);
7758   if (TREE_CODE (arg) == INTEGER_CST)
7759     return fold_abs_const (arg, type);
7760   return fold (build1 (ABS_EXPR, type, arg));
7761 }
7762
7763 /* Fold a call to __builtin_isnan(), __builtin_isinf, __builtin_finite.
7764    EXP is the CALL_EXPR for the call.  */
7765
7766 static tree
7767 fold_builtin_classify (tree exp, int builtin_index)
7768 {
7769   tree fndecl = get_callee_fndecl (exp);
7770   tree arglist = TREE_OPERAND (exp, 1);
7771   tree type = TREE_TYPE (TREE_TYPE (fndecl));
7772   tree arg;
7773   REAL_VALUE_TYPE r;
7774
7775   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7776     {
7777       /* Check that we have exactly one argument.  */
7778       if (arglist == 0)
7779         {
7780           error ("too few arguments to function `%s'",
7781                  IDENTIFIER_POINTER (DECL_NAME (fndecl)));
7782           return error_mark_node;
7783         }
7784       else if (TREE_CHAIN (arglist) != 0)
7785         {
7786           error ("too many arguments to function `%s'",
7787                  IDENTIFIER_POINTER (DECL_NAME (fndecl)));
7788           return error_mark_node;
7789         }
7790       else
7791         {
7792           error ("non-floating-point argument to function `%s'",
7793                  IDENTIFIER_POINTER (DECL_NAME (fndecl)));
7794           return error_mark_node;
7795         }
7796     }
7797
7798   arg = TREE_VALUE (arglist);
7799   switch (builtin_index)
7800     {
7801     case BUILT_IN_ISINF:
7802       if (!MODE_HAS_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
7803         return omit_one_operand (type, integer_zero_node, arg);
7804
7805       if (TREE_CODE (arg) == REAL_CST)
7806         {
7807           r = TREE_REAL_CST (arg);
7808           if (real_isinf (&r))
7809             return real_compare (GT_EXPR, &r, &dconst0)
7810                    ? integer_one_node : integer_minus_one_node;
7811           else
7812             return integer_zero_node;
7813         }
7814
7815       return NULL_TREE;
7816
7817     case BUILT_IN_FINITE:
7818       if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg)))
7819           && !MODE_HAS_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
7820         return omit_one_operand (type, integer_zero_node, arg);
7821
7822       if (TREE_CODE (arg) == REAL_CST)
7823         {
7824           r = TREE_REAL_CST (arg);
7825           return real_isinf (&r) || real_isnan (&r)
7826                  ? integer_zero_node : integer_one_node;
7827         }
7828
7829       return NULL_TREE;
7830
7831     case BUILT_IN_ISNAN:
7832       if (!MODE_HAS_NANS (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_isnan (&r) ? integer_one_node : integer_zero_node;
7839         }
7840
7841       arg = builtin_save_expr (arg);
7842       return fold (build2 (UNORDERED_EXPR, type, arg, arg));
7843
7844     default:
7845       abort ();
7846     }
7847 }
7848
7849 /* Fold a call to an unordered comparison function such as
7850    __builtin_isgreater().  EXP is the CALL_EXPR for the call.
7851    UNORDERED_CODE and ORDERED_CODE are comparison codes that give
7852    the opposite of the desired result.  UNORDERED_CODE is used
7853    for modes that can hold NaNs and ORDERED_CODE is used for
7854    the rest.  */
7855
7856 static tree
7857 fold_builtin_unordered_cmp (tree exp,
7858                             enum tree_code unordered_code,
7859                             enum tree_code ordered_code)
7860 {
7861   tree fndecl = get_callee_fndecl (exp);
7862   tree arglist = TREE_OPERAND (exp, 1);
7863   tree type = TREE_TYPE (TREE_TYPE (fndecl));
7864   enum tree_code code;
7865   tree arg0, arg1;
7866
7867   if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
7868     {
7869       enum tree_code code0, code1;
7870       tree type0, type1;
7871       tree cmp_type = 0;
7872
7873       /* Check that we have exactly two arguments.  */
7874       if (arglist == 0 || TREE_CHAIN (arglist) == 0)
7875         {
7876           error ("too few arguments to function `%s'",
7877                  IDENTIFIER_POINTER (DECL_NAME (fndecl)));
7878           return error_mark_node;
7879         }
7880       else if (TREE_CHAIN (TREE_CHAIN (arglist)) != 0)
7881         {
7882           error ("too many arguments to function `%s'",
7883                  IDENTIFIER_POINTER (DECL_NAME (fndecl)));
7884           return error_mark_node;
7885         }
7886
7887       arg0 = TREE_VALUE (arglist);
7888       arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7889
7890       type0 = TREE_TYPE (arg0);
7891       type1 = TREE_TYPE (arg1);
7892
7893       code0 = TREE_CODE (type0);
7894       code1 = TREE_CODE (type1);
7895
7896       if (code0 == REAL_TYPE && code1 == REAL_TYPE)
7897         /* Choose the wider of two real types.  */
7898         cmp_type = TYPE_PRECISION (type0) >= TYPE_PRECISION (type1)
7899                    ? type0 : type1;
7900       else if (code0 == REAL_TYPE && code1 == INTEGER_TYPE)
7901         cmp_type = type0;
7902       else if (code0 == INTEGER_TYPE && code1 == REAL_TYPE)
7903         cmp_type = type1;
7904       else
7905         {
7906           error ("non-floating-point argument to function `%s'",
7907                  IDENTIFIER_POINTER (DECL_NAME (fndecl)));
7908           return error_mark_node;
7909         }
7910
7911       arg0 = fold_convert (cmp_type, arg0);
7912       arg1 = fold_convert (cmp_type, arg1);
7913     }
7914   else
7915     {
7916       arg0 = TREE_VALUE (arglist);
7917       arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7918     }
7919
7920   if (unordered_code == UNORDERED_EXPR)
7921     {
7922       if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg0))))
7923         return omit_two_operands (type, integer_zero_node, arg0, arg1);
7924       return fold (build2 (UNORDERED_EXPR, type, arg0, arg1));
7925     }
7926
7927   code = MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg0))) ? unordered_code
7928                                                       : ordered_code;
7929   return fold (build1 (TRUTH_NOT_EXPR, type,
7930                        fold (build2 (code, type, arg0, arg1))));
7931 }
7932
7933 /* Used by constant folding to simplify calls to builtin functions.  EXP is
7934    the CALL_EXPR of a call to a builtin function.  IGNORE is true if the
7935    result of the function call is ignored.  This function returns NULL_TREE
7936    if no simplification was possible.  */
7937
7938 static tree
7939 fold_builtin_1 (tree exp, bool ignore)
7940 {
7941   tree fndecl = get_callee_fndecl (exp);
7942   tree arglist = TREE_OPERAND (exp, 1);
7943   tree type = TREE_TYPE (TREE_TYPE (fndecl));
7944
7945   if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
7946     return 0;
7947
7948   switch (DECL_FUNCTION_CODE (fndecl))
7949     {
7950     case BUILT_IN_CONSTANT_P:
7951       return fold_builtin_constant_p (arglist);
7952
7953     case BUILT_IN_EXPECT:
7954       return fold_builtin_expect (arglist);
7955
7956     case BUILT_IN_CLASSIFY_TYPE:
7957       return fold_builtin_classify_type (arglist);
7958
7959     case BUILT_IN_STRLEN:
7960       if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
7961         {
7962           tree len = c_strlen (TREE_VALUE (arglist), 0);
7963           if (len)
7964             {
7965               /* Convert from the internal "sizetype" type to "size_t".  */
7966               if (size_type_node)
7967                 len = fold_convert (size_type_node, len);
7968               return len;
7969             }
7970         }
7971       break;
7972
7973     case BUILT_IN_FABS:
7974     case BUILT_IN_FABSF:
7975     case BUILT_IN_FABSL:
7976       return fold_builtin_fabs (arglist, type);
7977
7978     case BUILT_IN_ABS:
7979     case BUILT_IN_LABS:
7980     case BUILT_IN_LLABS:
7981     case BUILT_IN_IMAXABS:
7982       return fold_builtin_abs (arglist, type);
7983
7984     case BUILT_IN_CONJ:
7985     case BUILT_IN_CONJF:
7986     case BUILT_IN_CONJL:
7987       if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
7988         return fold (build1 (CONJ_EXPR, type, TREE_VALUE (arglist)));
7989       break;
7990
7991     case BUILT_IN_CREAL:
7992     case BUILT_IN_CREALF:
7993     case BUILT_IN_CREALL:
7994       if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
7995         return non_lvalue (fold (build1 (REALPART_EXPR, type,
7996                                          TREE_VALUE (arglist))));
7997       break;
7998
7999     case BUILT_IN_CIMAG:
8000     case BUILT_IN_CIMAGF:
8001     case BUILT_IN_CIMAGL:
8002       if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
8003         return non_lvalue (fold (build1 (IMAGPART_EXPR, type,
8004                                          TREE_VALUE (arglist))));
8005       break;
8006
8007     case BUILT_IN_CABS:
8008     case BUILT_IN_CABSF:
8009     case BUILT_IN_CABSL:
8010       return fold_builtin_cabs (arglist, type);
8011
8012     case BUILT_IN_SQRT:
8013     case BUILT_IN_SQRTF:
8014     case BUILT_IN_SQRTL:
8015       if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8016         {
8017           enum built_in_function fcode;
8018           tree arg = TREE_VALUE (arglist);
8019
8020           /* Optimize sqrt of constant value.  */
8021           if (TREE_CODE (arg) == REAL_CST
8022               && ! TREE_CONSTANT_OVERFLOW (arg))
8023             {
8024               REAL_VALUE_TYPE r, x;
8025
8026               x = TREE_REAL_CST (arg);
8027               if (real_sqrt (&r, TYPE_MODE (type), &x)
8028                   || (!flag_trapping_math && !flag_errno_math))
8029                 return build_real (type, r);
8030             }
8031
8032           /* Optimize sqrt(expN(x)) = expN(x*0.5).  */
8033           fcode = builtin_mathfn_code (arg);
8034           if (flag_unsafe_math_optimizations && BUILTIN_EXPONENT_P (fcode))
8035             {
8036               tree expfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
8037               arg = fold (build2 (MULT_EXPR, type,
8038                                   TREE_VALUE (TREE_OPERAND (arg, 1)),
8039                                   build_real (type, dconsthalf)));
8040               arglist = build_tree_list (NULL_TREE, arg);
8041               return build_function_call_expr (expfn, arglist);
8042             }
8043
8044           /* Optimize sqrt(Nroot(x)) -> pow(x,1/(2*N)).  */
8045           if (flag_unsafe_math_optimizations && BUILTIN_ROOT_P (fcode))
8046             {
8047               tree powfn = mathfn_built_in (type, BUILT_IN_POW);
8048               
8049               if (powfn)
8050                 {
8051                   tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
8052                   tree tree_root;
8053                   /* The inner root was either sqrt or cbrt.  */
8054                   REAL_VALUE_TYPE dconstroot =
8055                     BUILTIN_SQRT_P (fcode) ? dconsthalf : dconstthird;
8056                   
8057                   /* Adjust for the outer root.  */
8058                   SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
8059                   dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
8060                   tree_root = build_real (type, dconstroot);
8061                   arglist = tree_cons (NULL_TREE, arg0,
8062                                        build_tree_list (NULL_TREE, tree_root));
8063                   return build_function_call_expr (powfn, arglist);
8064                 }
8065             }
8066
8067           /* Optimize sqrt(pow(x,y)) = pow(x,y*0.5).  */
8068           if (flag_unsafe_math_optimizations
8069               && (fcode == BUILT_IN_POW
8070                   || fcode == BUILT_IN_POWF
8071                   || fcode == BUILT_IN_POWL))
8072             {
8073               tree powfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
8074               tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
8075               tree arg1 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
8076               tree narg1 = fold (build2 (MULT_EXPR, type, arg1,
8077                                          build_real (type, dconsthalf)));
8078               arglist = tree_cons (NULL_TREE, arg0,
8079                                    build_tree_list (NULL_TREE, narg1));
8080               return build_function_call_expr (powfn, arglist);
8081             }
8082         }
8083       break;
8084
8085     case BUILT_IN_CBRT:
8086     case BUILT_IN_CBRTF:
8087     case BUILT_IN_CBRTL:
8088       if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8089         {
8090           tree arg = TREE_VALUE (arglist);
8091           const enum built_in_function fcode = builtin_mathfn_code (arg);
8092
8093           /* Optimize cbrt of constant value.  */
8094           if (real_zerop (arg) || real_onep (arg) || real_minus_onep (arg))
8095             return arg;
8096
8097           /* Optimize cbrt(expN(x)) -> expN(x/3).  */
8098           if (flag_unsafe_math_optimizations && BUILTIN_EXPONENT_P (fcode))
8099             {
8100               tree expfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
8101               const REAL_VALUE_TYPE third_trunc =
8102                 real_value_truncate (TYPE_MODE (type), dconstthird);
8103               arg = fold (build2 (MULT_EXPR, type,
8104                                   TREE_VALUE (TREE_OPERAND (arg, 1)),
8105                                   build_real (type, third_trunc)));
8106               arglist = build_tree_list (NULL_TREE, arg);
8107               return build_function_call_expr (expfn, arglist);
8108             }
8109
8110           /* Optimize cbrt(sqrt(x)) -> pow(x,1/6).  */
8111           /* We don't optimize cbrt(cbrt(x)) -> pow(x,1/9) because if
8112              x is negative pow will error but cbrt won't.  */
8113           if (flag_unsafe_math_optimizations && BUILTIN_SQRT_P (fcode))
8114             {
8115               tree powfn = mathfn_built_in (type, BUILT_IN_POW);
8116
8117               if (powfn)
8118                 {
8119                   tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
8120                   tree tree_root;
8121                   REAL_VALUE_TYPE dconstroot = dconstthird;
8122
8123                   SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
8124                   dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
8125                   tree_root = build_real (type, dconstroot);
8126                   arglist = tree_cons (NULL_TREE, arg0,
8127                                        build_tree_list (NULL_TREE, tree_root));
8128                   return build_function_call_expr (powfn, arglist);
8129                 }
8130               
8131             }
8132         }
8133       break;
8134
8135     case BUILT_IN_SIN:
8136     case BUILT_IN_SINF:
8137     case BUILT_IN_SINL:
8138       if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8139         {
8140           tree arg = TREE_VALUE (arglist);
8141
8142           /* Optimize sin(0.0) = 0.0.  */
8143           if (real_zerop (arg))
8144             return arg;
8145         }
8146       break;
8147
8148     case BUILT_IN_COS:
8149     case BUILT_IN_COSF:
8150     case BUILT_IN_COSL:
8151       if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8152         {
8153           tree arg = TREE_VALUE (arglist);
8154
8155           /* Optimize cos(0.0) = 1.0.  */
8156           if (real_zerop (arg))
8157             return build_real (type, dconst1);
8158
8159           /* Optimize cos(-x) into cos(x).  */
8160           if (TREE_CODE (arg) == NEGATE_EXPR)
8161             {
8162               tree arglist = build_tree_list (NULL_TREE,
8163                                               TREE_OPERAND (arg, 0));
8164               return build_function_call_expr (fndecl, arglist);
8165             }
8166         }
8167       break;
8168
8169     case BUILT_IN_EXP:
8170     case BUILT_IN_EXPF:
8171     case BUILT_IN_EXPL:
8172       return fold_builtin_exponent (exp, &dconste);
8173
8174     case BUILT_IN_EXP2:
8175     case BUILT_IN_EXP2F:
8176     case BUILT_IN_EXP2L:
8177       return fold_builtin_exponent (exp, &dconst2);
8178
8179     case BUILT_IN_EXP10:
8180     case BUILT_IN_EXP10F:
8181     case BUILT_IN_EXP10L:
8182     case BUILT_IN_POW10:
8183     case BUILT_IN_POW10F:
8184     case BUILT_IN_POW10L:
8185       return fold_builtin_exponent (exp, &dconst10);
8186
8187     case BUILT_IN_LOG:
8188     case BUILT_IN_LOGF:
8189     case BUILT_IN_LOGL:
8190       return fold_builtin_logarithm (exp, &dconste);
8191
8192     case BUILT_IN_LOG2:
8193     case BUILT_IN_LOG2F:
8194     case BUILT_IN_LOG2L:
8195       return fold_builtin_logarithm (exp, &dconst2);
8196
8197     case BUILT_IN_LOG10:
8198     case BUILT_IN_LOG10F:
8199     case BUILT_IN_LOG10L:
8200       return fold_builtin_logarithm (exp, &dconst10);
8201
8202     case BUILT_IN_TAN:
8203     case BUILT_IN_TANF:
8204     case BUILT_IN_TANL:
8205       if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8206         {
8207           enum built_in_function fcode;
8208           tree arg = TREE_VALUE (arglist);
8209
8210           /* Optimize tan(0.0) = 0.0.  */
8211           if (real_zerop (arg))
8212             return arg;
8213
8214           /* Optimize tan(atan(x)) = x.  */
8215           fcode = builtin_mathfn_code (arg);
8216           if (flag_unsafe_math_optimizations
8217               && (fcode == BUILT_IN_ATAN
8218                   || fcode == BUILT_IN_ATANF
8219                   || fcode == BUILT_IN_ATANL))
8220             return TREE_VALUE (TREE_OPERAND (arg, 1));
8221         }
8222       break;
8223
8224     case BUILT_IN_ATAN:
8225     case BUILT_IN_ATANF:
8226     case BUILT_IN_ATANL:
8227       if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8228         {
8229           tree arg = TREE_VALUE (arglist);
8230
8231           /* Optimize atan(0.0) = 0.0.  */
8232           if (real_zerop (arg))
8233             return arg;
8234
8235           /* Optimize atan(1.0) = pi/4.  */
8236           if (real_onep (arg))
8237             {
8238               REAL_VALUE_TYPE cst;
8239
8240               real_convert (&cst, TYPE_MODE (type), &dconstpi);
8241               SET_REAL_EXP (&cst, REAL_EXP (&cst) - 2);
8242               return build_real (type, cst);
8243             }
8244         }
8245       break;
8246
8247     case BUILT_IN_POW:
8248     case BUILT_IN_POWF:
8249     case BUILT_IN_POWL:
8250       if (validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
8251         {
8252           enum built_in_function fcode;
8253           tree arg0 = TREE_VALUE (arglist);
8254           tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
8255
8256           /* Optimize pow(1.0,y) = 1.0.  */
8257           if (real_onep (arg0))
8258             return omit_one_operand (type, build_real (type, dconst1), arg1);
8259
8260           if (TREE_CODE (arg1) == REAL_CST
8261               && ! TREE_CONSTANT_OVERFLOW (arg1))
8262             {
8263               REAL_VALUE_TYPE c;
8264               c = TREE_REAL_CST (arg1);
8265
8266               /* Optimize pow(x,0.0) = 1.0.  */
8267               if (REAL_VALUES_EQUAL (c, dconst0))
8268                 return omit_one_operand (type, build_real (type, dconst1),
8269                                          arg0);
8270
8271               /* Optimize pow(x,1.0) = x.  */
8272               if (REAL_VALUES_EQUAL (c, dconst1))
8273                 return arg0;
8274
8275               /* Optimize pow(x,-1.0) = 1.0/x.  */
8276               if (REAL_VALUES_EQUAL (c, dconstm1))
8277                 return fold (build2 (RDIV_EXPR, type,
8278                                      build_real (type, dconst1), arg0));
8279
8280               /* Optimize pow(x,0.5) = sqrt(x).  */
8281               if (flag_unsafe_math_optimizations
8282                   && REAL_VALUES_EQUAL (c, dconsthalf))
8283                 {
8284                   tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
8285
8286                   if (sqrtfn != NULL_TREE)
8287                     {
8288                       tree arglist = build_tree_list (NULL_TREE, arg0);
8289                       return build_function_call_expr (sqrtfn, arglist);
8290                     }
8291                 }
8292
8293               /* Attempt to evaluate pow at compile-time.  */
8294               if (TREE_CODE (arg0) == REAL_CST
8295                   && ! TREE_CONSTANT_OVERFLOW (arg0))
8296                 {
8297                   REAL_VALUE_TYPE cint;
8298                   HOST_WIDE_INT n;
8299
8300                   n = real_to_integer (&c);
8301                   real_from_integer (&cint, VOIDmode, n,
8302                                      n < 0 ? -1 : 0, 0);
8303                   if (real_identical (&c, &cint))
8304                     {
8305                       REAL_VALUE_TYPE x;
8306                       bool inexact;
8307
8308                       x = TREE_REAL_CST (arg0);
8309                       inexact = real_powi (&x, TYPE_MODE (type), &x, n);
8310                       if (flag_unsafe_math_optimizations || !inexact)
8311                         return build_real (type, x);
8312                     }
8313                 }
8314             }
8315
8316           /* Optimize pow(expN(x),y) = expN(x*y).  */
8317           fcode = builtin_mathfn_code (arg0);
8318           if (flag_unsafe_math_optimizations && BUILTIN_EXPONENT_P (fcode))
8319             {
8320               tree expfn = TREE_OPERAND (TREE_OPERAND (arg0, 0), 0);
8321               tree arg = TREE_VALUE (TREE_OPERAND (arg0, 1));
8322               arg = fold (build2 (MULT_EXPR, type, arg, arg1));
8323               arglist = build_tree_list (NULL_TREE, arg);
8324               return build_function_call_expr (expfn, arglist);
8325             }
8326
8327           /* Optimize pow(sqrt(x),y) = pow(x,y*0.5).  */
8328           if (flag_unsafe_math_optimizations && BUILTIN_SQRT_P (fcode))
8329             {
8330               tree narg0 = TREE_VALUE (TREE_OPERAND (arg0, 1));
8331               tree narg1 = fold (build2 (MULT_EXPR, type, arg1,
8332                                          build_real (type, dconsthalf)));
8333
8334               arglist = tree_cons (NULL_TREE, narg0,
8335                                    build_tree_list (NULL_TREE, narg1));
8336               return build_function_call_expr (fndecl, arglist);
8337             }
8338
8339           /* Optimize pow(pow(x,y),z) = pow(x,y*z).  */
8340           if (flag_unsafe_math_optimizations
8341               && (fcode == BUILT_IN_POW
8342                   || fcode == BUILT_IN_POWF
8343                   || fcode == BUILT_IN_POWL))
8344             {
8345               tree arg00 = TREE_VALUE (TREE_OPERAND (arg0, 1));
8346               tree arg01 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg0, 1)));
8347               tree narg1 = fold (build2 (MULT_EXPR, type, arg01, arg1));
8348               arglist = tree_cons (NULL_TREE, arg00,
8349                                    build_tree_list (NULL_TREE, narg1));
8350               return build_function_call_expr (fndecl, arglist);
8351             }
8352         }
8353       break;
8354
8355     case BUILT_IN_INF:
8356     case BUILT_IN_INFF:
8357     case BUILT_IN_INFL:
8358       return fold_builtin_inf (type, true);
8359
8360     case BUILT_IN_HUGE_VAL:
8361     case BUILT_IN_HUGE_VALF:
8362     case BUILT_IN_HUGE_VALL:
8363       return fold_builtin_inf (type, false);
8364
8365     case BUILT_IN_NAN:
8366     case BUILT_IN_NANF:
8367     case BUILT_IN_NANL:
8368       return fold_builtin_nan (arglist, type, true);
8369
8370     case BUILT_IN_NANS:
8371     case BUILT_IN_NANSF:
8372     case BUILT_IN_NANSL:
8373       return fold_builtin_nan (arglist, type, false);
8374
8375     case BUILT_IN_FLOOR:
8376     case BUILT_IN_FLOORF:
8377     case BUILT_IN_FLOORL:
8378       return fold_builtin_floor (exp);
8379
8380     case BUILT_IN_CEIL:
8381     case BUILT_IN_CEILF:
8382     case BUILT_IN_CEILL:
8383       return fold_builtin_ceil (exp);
8384
8385     case BUILT_IN_TRUNC:
8386     case BUILT_IN_TRUNCF:
8387     case BUILT_IN_TRUNCL:
8388       return fold_builtin_trunc (exp);
8389
8390     case BUILT_IN_ROUND:
8391     case BUILT_IN_ROUNDF:
8392     case BUILT_IN_ROUNDL:
8393       return fold_builtin_round (exp);
8394
8395     case BUILT_IN_NEARBYINT:
8396     case BUILT_IN_NEARBYINTF:
8397     case BUILT_IN_NEARBYINTL:
8398     case BUILT_IN_RINT:
8399     case BUILT_IN_RINTF:
8400     case BUILT_IN_RINTL:
8401       return fold_trunc_transparent_mathfn (exp);
8402
8403     case BUILT_IN_LROUND:
8404     case BUILT_IN_LROUNDF:
8405     case BUILT_IN_LROUNDL:
8406     case BUILT_IN_LLROUND:
8407     case BUILT_IN_LLROUNDF:
8408     case BUILT_IN_LLROUNDL:
8409       return fold_builtin_lround (exp);
8410
8411     case BUILT_IN_LRINT:
8412     case BUILT_IN_LRINTF:
8413     case BUILT_IN_LRINTL:
8414     case BUILT_IN_LLRINT:
8415     case BUILT_IN_LLRINTF:
8416     case BUILT_IN_LLRINTL:
8417       return fold_fixed_mathfn (exp);
8418
8419     case BUILT_IN_FFS:
8420     case BUILT_IN_FFSL:
8421     case BUILT_IN_FFSLL:
8422     case BUILT_IN_CLZ:
8423     case BUILT_IN_CLZL:
8424     case BUILT_IN_CLZLL:
8425     case BUILT_IN_CTZ:
8426     case BUILT_IN_CTZL:
8427     case BUILT_IN_CTZLL:
8428     case BUILT_IN_POPCOUNT:
8429     case BUILT_IN_POPCOUNTL:
8430     case BUILT_IN_POPCOUNTLL:
8431     case BUILT_IN_PARITY:
8432     case BUILT_IN_PARITYL:
8433     case BUILT_IN_PARITYLL:
8434       return fold_builtin_bitop (exp);
8435
8436     case BUILT_IN_MEMCPY:
8437       return fold_builtin_memcpy (exp);
8438
8439     case BUILT_IN_MEMPCPY:
8440       return fold_builtin_mempcpy (exp);
8441
8442     case BUILT_IN_MEMMOVE:
8443       return fold_builtin_memmove (exp);
8444
8445     case BUILT_IN_STRCPY:
8446       return fold_builtin_strcpy (exp, NULL_TREE);
8447
8448     case BUILT_IN_STRNCPY:
8449       return fold_builtin_strncpy (exp, NULL_TREE);
8450
8451     case BUILT_IN_INDEX:
8452     case BUILT_IN_STRCHR:
8453       return fold_builtin_strchr (exp, false);
8454
8455     case BUILT_IN_RINDEX:
8456     case BUILT_IN_STRRCHR:
8457       return fold_builtin_strchr (exp, true);
8458
8459     case BUILT_IN_MEMCMP:
8460       return fold_builtin_memcmp (exp);
8461
8462     case BUILT_IN_STRCMP:
8463       return fold_builtin_strcmp (exp);
8464
8465     case BUILT_IN_STRNCMP:
8466       return fold_builtin_strncmp (exp);
8467
8468     case BUILT_IN_SIGNBIT:
8469     case BUILT_IN_SIGNBITF:
8470     case BUILT_IN_SIGNBITL:
8471       return fold_builtin_signbit (exp);
8472
8473     case BUILT_IN_ISASCII:
8474       return fold_builtin_isascii (arglist);
8475
8476     case BUILT_IN_TOASCII:
8477       return fold_builtin_toascii (arglist);
8478
8479     case BUILT_IN_ISDIGIT:
8480       return fold_builtin_isdigit (arglist);
8481
8482     case BUILT_IN_COPYSIGN:
8483     case BUILT_IN_COPYSIGNF:
8484     case BUILT_IN_COPYSIGNL:
8485       return fold_builtin_copysign (arglist, type);
8486
8487     case BUILT_IN_FINITE:
8488     case BUILT_IN_FINITEF:
8489     case BUILT_IN_FINITEL:
8490       return fold_builtin_classify (exp, BUILT_IN_FINITE);
8491
8492     case BUILT_IN_ISINF:
8493     case BUILT_IN_ISINFF:
8494     case BUILT_IN_ISINFL:
8495       return fold_builtin_classify (exp, BUILT_IN_ISINF);
8496
8497     case BUILT_IN_ISNAN:
8498     case BUILT_IN_ISNANF:
8499     case BUILT_IN_ISNANL:
8500       return fold_builtin_classify (exp, BUILT_IN_ISNAN);
8501
8502     case BUILT_IN_ISGREATER:
8503       return fold_builtin_unordered_cmp (exp, UNLE_EXPR, LE_EXPR);
8504     case BUILT_IN_ISGREATEREQUAL:
8505       return fold_builtin_unordered_cmp (exp, UNLT_EXPR, LT_EXPR);
8506     case BUILT_IN_ISLESS:
8507       return fold_builtin_unordered_cmp (exp, UNGE_EXPR, GE_EXPR);
8508     case BUILT_IN_ISLESSEQUAL:
8509       return fold_builtin_unordered_cmp (exp, UNGT_EXPR, GT_EXPR);
8510     case BUILT_IN_ISLESSGREATER:
8511       return fold_builtin_unordered_cmp (exp, UNEQ_EXPR, EQ_EXPR);
8512     case BUILT_IN_ISUNORDERED:
8513       return fold_builtin_unordered_cmp (exp, UNORDERED_EXPR, NOP_EXPR);
8514
8515     case BUILT_IN_FPUTS:
8516       return fold_builtin_fputs (arglist, ignore, false, NULL_TREE);
8517
8518     case BUILT_IN_FPUTS_UNLOCKED:
8519       return fold_builtin_fputs (arglist, ignore, true, NULL_TREE);
8520
8521     default:
8522       break;
8523     }
8524
8525   return 0;
8526 }
8527
8528 /* A wrapper function for builtin folding that prevents warnings for
8529    "statement without effect" and the like, caused by removing the 
8530    call node earlier than the warning is generated.  */
8531
8532 tree
8533 fold_builtin (tree exp, bool ignore)
8534 {
8535   exp = fold_builtin_1 (exp, ignore);
8536   if (exp)
8537     {
8538       /* ??? Don't clobber shared nodes such as integer_zero_node.  */
8539       if (TREE_CODE_CLASS (TREE_CODE (exp)) == 'c')
8540         exp = build1 (NOP_EXPR, TREE_TYPE (exp), exp);
8541       TREE_NO_WARNING (exp) = 1;
8542     }
8543   return exp;
8544 }
8545
8546 /* Conveniently construct a function call expression.  */
8547
8548 tree
8549 build_function_call_expr (tree fn, tree arglist)
8550 {
8551   tree call_expr;
8552
8553   call_expr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
8554   call_expr = build3 (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)),
8555                       call_expr, arglist, NULL_TREE);
8556   return fold (call_expr);
8557 }
8558
8559 /* This function validates the types of a function call argument list
8560    represented as a tree chain of parameters against a specified list
8561    of tree_codes.  If the last specifier is a 0, that represents an
8562    ellipses, otherwise the last specifier must be a VOID_TYPE.  */
8563
8564 static int
8565 validate_arglist (tree arglist, ...)
8566 {
8567   enum tree_code code;
8568   int res = 0;
8569   va_list ap;
8570
8571   va_start (ap, arglist);
8572
8573   do
8574     {
8575       code = va_arg (ap, enum tree_code);
8576       switch (code)
8577         {
8578         case 0:
8579           /* This signifies an ellipses, any further arguments are all ok.  */
8580           res = 1;
8581           goto end;
8582         case VOID_TYPE:
8583           /* This signifies an endlink, if no arguments remain, return
8584              true, otherwise return false.  */
8585           res = arglist == 0;
8586           goto end;
8587         default:
8588           /* If no parameters remain or the parameter's code does not
8589              match the specified code, return false.  Otherwise continue
8590              checking any remaining arguments.  */
8591           if (arglist == 0
8592               || code != TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))))
8593             goto end;
8594           break;
8595         }
8596       arglist = TREE_CHAIN (arglist);
8597     }
8598   while (1);
8599
8600   /* We need gotos here since we can only have one VA_CLOSE in a
8601      function.  */
8602  end: ;
8603   va_end (ap);
8604
8605   return res;
8606 }
8607
8608 /* Default target-specific builtin expander that does nothing.  */
8609
8610 rtx
8611 default_expand_builtin (tree exp ATTRIBUTE_UNUSED,
8612                         rtx target ATTRIBUTE_UNUSED,
8613                         rtx subtarget ATTRIBUTE_UNUSED,
8614                         enum machine_mode mode ATTRIBUTE_UNUSED,
8615                         int ignore ATTRIBUTE_UNUSED)
8616 {
8617   return NULL_RTX;
8618 }
8619
8620 /* Returns true is EXP represents data that would potentially reside
8621    in a readonly section.  */
8622
8623 static bool
8624 readonly_data_expr (tree exp)
8625 {
8626   STRIP_NOPS (exp);
8627
8628   if (TREE_CODE (exp) != ADDR_EXPR)
8629     return false;
8630
8631   exp = get_base_address (TREE_OPERAND (exp, 0));
8632   if (!exp)
8633     return false;
8634
8635   /* Make sure we call decl_readonly_section only for trees it
8636      can handle (since it returns true for everything it doesn't
8637      understand).  */
8638   if (TREE_CODE (exp) == STRING_CST 
8639       || TREE_CODE (exp) == CONSTRUCTOR
8640       || (TREE_CODE (exp) == VAR_DECL && TREE_STATIC (exp)))
8641     return decl_readonly_section (exp, 0);
8642   else
8643     return false;
8644 }
8645
8646 /* Front-end to the simplify_builtin_XXX routines.
8647
8648    EXP is a call to a builtin function.  If possible try to simplify
8649    that into a constant, expression or call to a more efficient
8650    builtin function.
8651
8652    If IGNORE is nonzero, then the result of this builtin function
8653    call is ignored.
8654
8655    If simplification is possible, return the simplified tree, otherwise
8656    return NULL_TREE.  */
8657
8658 tree
8659 simplify_builtin (tree exp, int ignore)
8660 {
8661   tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
8662   tree arglist = TREE_OPERAND (exp, 1);
8663   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
8664   tree val;
8665
8666   switch (fcode)
8667     {
8668     case BUILT_IN_FPUTS:
8669       val = fold_builtin_fputs (arglist, ignore, false, NULL_TREE);
8670       break;
8671     case BUILT_IN_FPUTS_UNLOCKED:
8672       val = fold_builtin_fputs (arglist, ignore, true, NULL_TREE);
8673       break;
8674     case BUILT_IN_STRSTR:
8675       val = simplify_builtin_strstr (arglist);
8676       break;
8677     case BUILT_IN_STRCAT:
8678       val = simplify_builtin_strcat (arglist);
8679       break;
8680     case BUILT_IN_STRNCAT:
8681       val = simplify_builtin_strncat (arglist);
8682       break;
8683     case BUILT_IN_STRSPN:
8684       val = simplify_builtin_strspn (arglist);
8685       break;
8686     case BUILT_IN_STRCSPN:
8687       val = simplify_builtin_strcspn (arglist);
8688       break;
8689     case BUILT_IN_STRCHR:
8690     case BUILT_IN_INDEX:
8691       val = simplify_builtin_strchr (arglist);
8692       break;
8693     case BUILT_IN_STRRCHR:
8694     case BUILT_IN_RINDEX:
8695       val = simplify_builtin_strrchr (arglist);
8696       break;
8697     case BUILT_IN_STRCPY:
8698       val = fold_builtin_strcpy (exp, NULL_TREE);
8699       break;
8700     case BUILT_IN_STRNCPY:
8701       val = fold_builtin_strncpy (exp, NULL_TREE);
8702       break;
8703     case BUILT_IN_STRCMP:
8704       val = simplify_builtin_strcmp (arglist);
8705       break;
8706     case BUILT_IN_STRNCMP:
8707       val = simplify_builtin_strncmp (arglist);
8708       break;
8709     case BUILT_IN_STRPBRK:
8710       val = simplify_builtin_strpbrk (arglist);
8711       break;
8712     case BUILT_IN_BCMP:
8713     case BUILT_IN_MEMCMP:
8714       val = simplify_builtin_memcmp (arglist);
8715       break;
8716     case BUILT_IN_VA_START:
8717       simplify_builtin_va_start (arglist);
8718       val = NULL_TREE;
8719       break;
8720     case BUILT_IN_SPRINTF:
8721       val = simplify_builtin_sprintf (arglist, ignore);
8722       break;
8723     case BUILT_IN_CONSTANT_P:
8724       val = fold_builtin_constant_p (arglist);
8725       /* Gimplification will pull the CALL_EXPR for the builtin out of
8726          an if condition.  When not optimizing, we'll not CSE it back.
8727          To avoid link error types of regressions, return false now.  */
8728       if (!val && !optimize)
8729         val = integer_zero_node;
8730       break;
8731     default:
8732       val = NULL_TREE;
8733       break;
8734     }
8735
8736   if (val)
8737     val = fold_convert (TREE_TYPE (exp), val);
8738   return val;
8739 }
8740
8741 /* Simplify a call to the strstr builtin.
8742
8743    Return 0 if no simplification was possible, otherwise return the
8744    simplified form of the call as a tree.
8745
8746    The simplified form may be a constant or other expression which
8747    computes the same value, but in a more efficient manner (including
8748    calls to other builtin functions).
8749
8750    The call may contain arguments which need to be evaluated, but
8751    which are not useful to determine the result of the call.  In
8752    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
8753    COMPOUND_EXPR will be an argument which must be evaluated.
8754    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
8755    COMPOUND_EXPR in the chain will contain the tree for the simplified
8756    form of the builtin function call.  */
8757
8758 static tree
8759 simplify_builtin_strstr (tree arglist)
8760 {
8761   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
8762     return 0;
8763   else
8764     {
8765       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
8766       tree fn;
8767       const char *p1, *p2;
8768
8769       p2 = c_getstr (s2);
8770       if (p2 == NULL)
8771         return 0;
8772
8773       p1 = c_getstr (s1);
8774       if (p1 != NULL)
8775         {
8776           const char *r = strstr (p1, p2);
8777
8778           if (r == NULL)
8779             return fold_convert (TREE_TYPE (s1), integer_zero_node);
8780
8781           /* Return an offset into the constant string argument.  */
8782           return fold (build2 (PLUS_EXPR, TREE_TYPE (s1),
8783                                s1, fold_convert (TREE_TYPE (s1),
8784                                                  ssize_int (r - p1))));
8785         }
8786
8787       if (p2[0] == '\0')
8788         return s1;
8789
8790       if (p2[1] != '\0')
8791         return 0;
8792
8793       fn = implicit_built_in_decls[BUILT_IN_STRCHR];
8794       if (!fn)
8795         return 0;
8796
8797       /* New argument list transforming strstr(s1, s2) to
8798          strchr(s1, s2[0]).  */
8799       arglist = build_tree_list (NULL_TREE, build_int_2 (p2[0], 0));
8800       arglist = tree_cons (NULL_TREE, s1, arglist);
8801       return build_function_call_expr (fn, arglist);
8802     }
8803 }
8804
8805 /* Simplify a call to the strstr builtin.
8806
8807    Return 0 if no simplification was possible, otherwise return the
8808    simplified form of the call as a tree.
8809
8810    The simplified form may be a constant or other expression which
8811    computes the same value, but in a more efficient manner (including
8812    calls to other builtin functions).
8813
8814    The call may contain arguments which need to be evaluated, but
8815    which are not useful to determine the result of the call.  In
8816    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
8817    COMPOUND_EXPR will be an argument which must be evaluated.
8818    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
8819    COMPOUND_EXPR in the chain will contain the tree for the simplified
8820    form of the builtin function call.  */
8821
8822 static tree
8823 simplify_builtin_strchr (tree arglist)
8824 {
8825   if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8826     return 0;
8827   else
8828     {
8829       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
8830       const char *p1;
8831
8832       if (TREE_CODE (s2) != INTEGER_CST)
8833         return 0;
8834
8835       p1 = c_getstr (s1);
8836       if (p1 != NULL)
8837         {
8838           char c;
8839           const char *r;
8840
8841           if (target_char_cast (s2, &c))
8842             return 0;
8843
8844           r = strchr (p1, c);
8845
8846           if (r == NULL)
8847             return fold_convert (TREE_TYPE (s1), integer_zero_node);
8848
8849           /* Return an offset into the constant string argument.  */
8850           return fold (build2 (PLUS_EXPR, TREE_TYPE (s1),
8851                                s1, fold_convert (TREE_TYPE (s1),
8852                                                  ssize_int (r - p1))));
8853         }
8854
8855       /* FIXME: Should use here strchrM optab so that ports can optimize
8856          this.  */
8857       return 0;
8858     }
8859 }
8860
8861 /* Simplify a call to the strrchr builtin.
8862
8863    Return 0 if no simplification was possible, otherwise return the
8864    simplified form of the call as a tree.
8865
8866    The simplified form may be a constant or other expression which
8867    computes the same value, but in a more efficient manner (including
8868    calls to other builtin functions).
8869
8870    The call may contain arguments which need to be evaluated, but
8871    which are not useful to determine the result of the call.  In
8872    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
8873    COMPOUND_EXPR will be an argument which must be evaluated.
8874    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
8875    COMPOUND_EXPR in the chain will contain the tree for the simplified
8876    form of the builtin function call.  */
8877
8878 static tree
8879 simplify_builtin_strrchr (tree arglist)
8880 {
8881   if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8882     return 0;
8883   else
8884     {
8885       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
8886       tree fn;
8887       const char *p1;
8888
8889       if (TREE_CODE (s2) != INTEGER_CST)
8890         return 0;
8891
8892       p1 = c_getstr (s1);
8893       if (p1 != NULL)
8894         {
8895           char c;
8896           const char *r;
8897
8898           if (target_char_cast (s2, &c))
8899             return 0;
8900
8901           r = strrchr (p1, c);
8902
8903           if (r == NULL)
8904             return fold_convert (TREE_TYPE (s1), integer_zero_node);
8905
8906           /* Return an offset into the constant string argument.  */
8907           return fold (build2 (PLUS_EXPR, TREE_TYPE (s1),
8908                                s1, fold_convert (TREE_TYPE (s1),
8909                                                  ssize_int (r - p1))));
8910         }
8911
8912       if (! integer_zerop (s2))
8913         return 0;
8914
8915       fn = implicit_built_in_decls[BUILT_IN_STRCHR];
8916       if (!fn)
8917         return 0;
8918
8919       /* Transform strrchr(s1, '\0') to strchr(s1, '\0').  */
8920       return build_function_call_expr (fn, arglist);
8921     }
8922 }
8923
8924 /* Simplify a call to the strpbrk builtin.
8925
8926    Return 0 if no simplification was possible, otherwise return the
8927    simplified form of the call as a tree.
8928
8929    The simplified form may be a constant or other expression which
8930    computes the same value, but in a more efficient manner (including
8931    calls to other builtin functions).
8932
8933    The call may contain arguments which need to be evaluated, but
8934    which are not useful to determine the result of the call.  In
8935    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
8936    COMPOUND_EXPR will be an argument which must be evaluated.
8937    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
8938    COMPOUND_EXPR in the chain will contain the tree for the simplified
8939    form of the builtin function call.  */
8940
8941 static tree
8942 simplify_builtin_strpbrk (tree arglist)
8943 {
8944   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
8945     return 0;
8946   else
8947     {
8948       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
8949       tree fn;
8950       const char *p1, *p2;
8951
8952       p2 = c_getstr (s2);
8953       if (p2 == NULL)
8954         return 0;
8955
8956       p1 = c_getstr (s1);
8957       if (p1 != NULL)
8958         {
8959           const char *r = strpbrk (p1, p2);
8960
8961           if (r == NULL)
8962             return fold_convert (TREE_TYPE (s1), integer_zero_node);
8963
8964           /* Return an offset into the constant string argument.  */
8965           return fold (build2 (PLUS_EXPR, TREE_TYPE (s1),
8966                                s1, fold_convert (TREE_TYPE (s1),
8967                                                  ssize_int (r - p1))));
8968         }
8969
8970       if (p2[0] == '\0')
8971         /* strpbrk(x, "") == NULL.
8972            Evaluate and ignore s1 in case it had side-effects.  */
8973         return omit_one_operand (TREE_TYPE (s1), integer_zero_node, s1);
8974
8975       if (p2[1] != '\0')
8976         return 0;  /* Really call strpbrk.  */
8977
8978       fn = implicit_built_in_decls[BUILT_IN_STRCHR];
8979       if (!fn)
8980         return 0;
8981
8982       /* New argument list transforming strpbrk(s1, s2) to
8983          strchr(s1, s2[0]).  */
8984       arglist =
8985         build_tree_list (NULL_TREE, build_int_2 (p2[0], 0));
8986       arglist = tree_cons (NULL_TREE, s1, arglist);
8987       return build_function_call_expr (fn, arglist);
8988     }
8989 }
8990
8991 /* Simplify a call to the memcmp builtin.
8992
8993    Return 0 if no simplification was possible, otherwise return the
8994    simplified form of the call as a tree.
8995
8996    The simplified form may be a constant or other expression which
8997    computes the same value, but in a more efficient manner (including
8998    calls to other builtin functions).
8999
9000    The call may contain arguments which need to be evaluated, but
9001    which are not useful to determine the result of the call.  In
9002    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
9003    COMPOUND_EXPR will be an argument which must be evaluated.
9004    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
9005    COMPOUND_EXPR in the chain will contain the tree for the simplified
9006    form of the builtin function call.  */
9007
9008 static tree
9009 simplify_builtin_memcmp (tree arglist)
9010 {
9011   tree arg1, arg2, len;
9012   const char *p1, *p2;
9013
9014   if (!validate_arglist (arglist,
9015                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9016     return 0;
9017
9018   arg1 = TREE_VALUE (arglist);
9019   arg2 = TREE_VALUE (TREE_CHAIN (arglist));
9020   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
9021
9022   /* If the len parameter is zero, return zero.  */
9023   if (host_integerp (len, 1) && tree_low_cst (len, 1) == 0)
9024     /* Evaluate and ignore arg1 and arg2 in case they have side-effects.  */
9025     return omit_two_operands (integer_type_node, integer_zero_node,
9026                               arg1, arg2);
9027
9028   p1 = c_getstr (arg1);
9029   p2 = c_getstr (arg2);
9030
9031   /* If all arguments are constant, and the value of len is not greater
9032      than the lengths of arg1 and arg2, evaluate at compile-time.  */
9033   if (host_integerp (len, 1) && p1 && p2
9034       && compare_tree_int (len, strlen (p1) + 1) <= 0
9035       && compare_tree_int (len, strlen (p2) + 1) <= 0)
9036     {
9037       const int r = memcmp (p1, p2, tree_low_cst (len, 1));
9038
9039       return (r < 0
9040               ? integer_minus_one_node
9041               : (r > 0 ? integer_one_node : integer_zero_node));
9042     }
9043
9044   /* If len parameter is one, return an expression corresponding to
9045      (*(const unsigned char*)arg1 - (const unsigned char*)arg2).  */
9046   if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
9047     {
9048       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
9049       tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
9050       tree ind1 =
9051       fold (build1 (CONVERT_EXPR, integer_type_node,
9052                     build1 (INDIRECT_REF, cst_uchar_node,
9053                             build1 (NOP_EXPR, cst_uchar_ptr_node, arg1))));
9054       tree ind2 =
9055       fold (build1 (CONVERT_EXPR, integer_type_node,
9056                     build1 (INDIRECT_REF, cst_uchar_node,
9057                             build1 (NOP_EXPR, cst_uchar_ptr_node, arg2))));
9058       return fold (build2 (MINUS_EXPR, integer_type_node, ind1, ind2));
9059     }
9060
9061   return 0;
9062 }
9063
9064 /* Simplify a call to the strcmp builtin.
9065
9066    Return 0 if no simplification was possible, otherwise return the
9067    simplified form of the call as a tree.
9068
9069    The simplified form may be a constant or other expression which
9070    computes the same value, but in a more efficient manner (including
9071    calls to other builtin functions).
9072
9073    The call may contain arguments which need to be evaluated, but
9074    which are not useful to determine the result of the call.  In
9075    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
9076    COMPOUND_EXPR will be an argument which must be evaluated.
9077    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
9078    COMPOUND_EXPR in the chain will contain the tree for the simplified
9079    form of the builtin function call.  */
9080
9081 static tree
9082 simplify_builtin_strcmp (tree arglist)
9083 {
9084   tree arg1, arg2;
9085   const char *p1, *p2;
9086
9087   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9088     return 0;
9089
9090   arg1 = TREE_VALUE (arglist);
9091   arg2 = TREE_VALUE (TREE_CHAIN (arglist));
9092
9093   /* If both arguments are equal (and not volatile), return zero.  */
9094   if (operand_equal_p (arg1, arg2, 0))
9095     return integer_zero_node;
9096
9097   p1 = c_getstr (arg1);
9098   p2 = c_getstr (arg2);
9099
9100   if (p1 && p2)
9101     {
9102       const int i = strcmp (p1, p2);
9103       return (i < 0
9104               ? integer_minus_one_node
9105               : (i > 0 ? integer_one_node : integer_zero_node));
9106     }
9107
9108   /* If either arg is "", return an expression corresponding to
9109      (*(const unsigned char*)arg1 - (const unsigned char*)arg2).  */
9110   if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
9111     {
9112       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
9113       tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
9114       tree ind1 =
9115         fold (build1 (CONVERT_EXPR, integer_type_node,
9116                       build1 (INDIRECT_REF, cst_uchar_node,
9117                               build1 (NOP_EXPR, cst_uchar_ptr_node, arg1))));
9118       tree ind2 =
9119         fold (build1 (CONVERT_EXPR, integer_type_node,
9120                       build1 (INDIRECT_REF, cst_uchar_node,
9121                               build1 (NOP_EXPR, cst_uchar_ptr_node, arg2))));
9122       return fold (build2 (MINUS_EXPR, integer_type_node, ind1, ind2));
9123     }
9124
9125   return 0;
9126 }
9127
9128 /* Simplify a call to the strncmp builtin.
9129
9130    Return 0 if no simplification was possible, otherwise return the
9131    simplified form of the call as a tree.
9132
9133    The simplified form may be a constant or other expression which
9134    computes the same value, but in a more efficient manner (including
9135    calls to other builtin functions).
9136
9137    The call may contain arguments which need to be evaluated, but
9138    which are not useful to determine the result of the call.  In
9139    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
9140    COMPOUND_EXPR will be an argument which must be evaluated.
9141    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
9142    COMPOUND_EXPR in the chain will contain the tree for the simplified
9143    form of the builtin function call.  */
9144
9145 static tree
9146 simplify_builtin_strncmp (tree arglist)
9147 {
9148   tree arg1, arg2, arg3;
9149   const char *p1, *p2;
9150
9151   if (!validate_arglist (arglist,
9152                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9153     return 0;
9154
9155   arg1 = TREE_VALUE (arglist);
9156   arg2 = TREE_VALUE (TREE_CHAIN (arglist));
9157   arg3 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
9158
9159   /* If the len parameter is zero, return zero.  */
9160   if (integer_zerop (arg3))
9161     /* Evaluate and ignore arg1 and arg2 in case they have side-effects.  */
9162     return omit_two_operands (integer_type_node, integer_zero_node,
9163                               arg1, arg2);
9164
9165   /* If arg1 and arg2 are equal (and not volatile), return zero.  */
9166   if (operand_equal_p (arg1, arg2, 0))
9167     /* Evaluate and ignore arg3 in case it has side-effects.  */
9168     return omit_one_operand (integer_type_node, integer_zero_node, arg3);
9169
9170   p1 = c_getstr (arg1);
9171   p2 = c_getstr (arg2);
9172
9173   /* If all arguments are constant, evaluate at compile-time.  */
9174   if (host_integerp (arg3, 1) && p1 && p2)
9175     {
9176       const int r = strncmp (p1, p2, tree_low_cst (arg3, 1));
9177       return (r < 0
9178               ? integer_minus_one_node
9179               : (r > 0 ? integer_one_node : integer_zero_node));
9180     }
9181
9182   /* If len == 1 or (either string parameter is "" and (len >= 1)),
9183       return (*(const u_char*)arg1 - *(const u_char*)arg2).  */
9184   if (host_integerp (arg3, 1)
9185       && (tree_low_cst (arg3, 1) == 1
9186           || (tree_low_cst (arg3, 1) > 1
9187               && ((p1 && *p1 == '\0') || (p2 && *p2 == '\0')))))
9188     {
9189       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
9190       tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
9191       tree ind1 =
9192         fold (build1 (CONVERT_EXPR, integer_type_node,
9193                       build1 (INDIRECT_REF, cst_uchar_node,
9194                               build1 (NOP_EXPR, cst_uchar_ptr_node, arg1))));
9195       tree ind2 =
9196         fold (build1 (CONVERT_EXPR, integer_type_node,
9197                       build1 (INDIRECT_REF, cst_uchar_node,
9198                               build1 (NOP_EXPR, cst_uchar_ptr_node, arg2))));
9199       return fold (build2 (MINUS_EXPR, integer_type_node, ind1, ind2));
9200     }
9201
9202   return 0;
9203 }
9204
9205 /* Simplify a call to the strcat builtin.
9206
9207    Return 0 if no simplification was possible, otherwise return the
9208    simplified form of the call as a tree.
9209
9210    The simplified form may be a constant or other expression which
9211    computes the same value, but in a more efficient manner (including
9212    calls to other builtin functions).
9213
9214    The call may contain arguments which need to be evaluated, but
9215    which are not useful to determine the result of the call.  In
9216    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
9217    COMPOUND_EXPR will be an argument which must be evaluated.
9218    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
9219    COMPOUND_EXPR in the chain will contain the tree for the simplified
9220    form of the builtin function call.  */
9221
9222 static tree
9223 simplify_builtin_strcat (tree arglist)
9224 {
9225   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9226     return 0;
9227   else
9228     {
9229       tree dst = TREE_VALUE (arglist),
9230         src = TREE_VALUE (TREE_CHAIN (arglist));
9231       const char *p = c_getstr (src);
9232
9233       /* If the string length is zero, return the dst parameter.  */
9234       if (p && *p == '\0')
9235         return dst;
9236
9237       return 0;
9238     }
9239 }
9240
9241 /* Simplify a call to the strncat builtin.
9242
9243    Return 0 if no simplification was possible, otherwise return the
9244    simplified form of the call as a tree.
9245
9246    The simplified form may be a constant or other expression which
9247    computes the same value, but in a more efficient manner (including
9248    calls to other builtin functions).
9249
9250    The call may contain arguments which need to be evaluated, but
9251    which are not useful to determine the result of the call.  In
9252    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
9253    COMPOUND_EXPR will be an argument which must be evaluated.
9254    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
9255    COMPOUND_EXPR in the chain will contain the tree for the simplified
9256    form of the builtin function call.  */
9257
9258 static tree
9259 simplify_builtin_strncat (tree arglist)
9260 {
9261   if (!validate_arglist (arglist,
9262                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9263     return 0;
9264   else
9265     {
9266       tree dst = TREE_VALUE (arglist);
9267       tree src = TREE_VALUE (TREE_CHAIN (arglist));
9268       tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
9269       const char *p = c_getstr (src);
9270
9271       /* If the requested length is zero, or the src parameter string
9272           length is zero, return the dst parameter.  */
9273       if (integer_zerop (len) || (p && *p == '\0'))
9274         return omit_two_operands (TREE_TYPE (dst), dst, src, len);
9275
9276       /* If the requested len is greater than or equal to the string
9277          length, call strcat.  */
9278       if (TREE_CODE (len) == INTEGER_CST && p
9279           && compare_tree_int (len, strlen (p)) >= 0)
9280         {
9281           tree newarglist
9282             = tree_cons (NULL_TREE, dst, build_tree_list (NULL_TREE, src));
9283           tree fn = implicit_built_in_decls[BUILT_IN_STRCAT];
9284
9285           /* If the replacement _DECL isn't initialized, don't do the
9286              transformation.  */
9287           if (!fn)
9288             return 0;
9289
9290           return build_function_call_expr (fn, newarglist);
9291         }
9292       return 0;
9293     }
9294 }
9295
9296 /* Simplify a call to the strspn builtin.
9297
9298    Return 0 if no simplification was possible, otherwise return the
9299    simplified form of the call as a tree.
9300
9301    The simplified form may be a constant or other expression which
9302    computes the same value, but in a more efficient manner (including
9303    calls to other builtin functions).
9304
9305    The call may contain arguments which need to be evaluated, but
9306    which are not useful to determine the result of the call.  In
9307    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
9308    COMPOUND_EXPR will be an argument which must be evaluated.
9309    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
9310    COMPOUND_EXPR in the chain will contain the tree for the simplified
9311    form of the builtin function call.  */
9312
9313 static tree
9314 simplify_builtin_strspn (tree arglist)
9315 {
9316   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9317     return 0;
9318   else
9319     {
9320       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9321       const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
9322
9323       /* If both arguments are constants, evaluate at compile-time.  */
9324       if (p1 && p2)
9325         {
9326           const size_t r = strspn (p1, p2);
9327           return size_int (r);
9328         }
9329
9330       /* If either argument is "", return 0.  */
9331       if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
9332         /* Evaluate and ignore both arguments in case either one has
9333            side-effects.  */
9334         return omit_two_operands (integer_type_node, integer_zero_node,
9335                                   s1, s2);
9336       return 0;
9337     }
9338 }
9339
9340 /* Simplify a call to the strcspn builtin.
9341
9342    Return 0 if no simplification was possible, otherwise return the
9343    simplified form of the call as a tree.
9344
9345    The simplified form may be a constant or other expression which
9346    computes the same value, but in a more efficient manner (including
9347    calls to other builtin functions).
9348
9349    The call may contain arguments which need to be evaluated, but
9350    which are not useful to determine the result of the call.  In
9351    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
9352    COMPOUND_EXPR will be an argument which must be evaluated.
9353    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
9354    COMPOUND_EXPR in the chain will contain the tree for the simplified
9355    form of the builtin function call.  */
9356
9357 static tree
9358 simplify_builtin_strcspn (tree arglist)
9359 {
9360   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9361     return 0;
9362   else
9363     {
9364       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9365       const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
9366
9367       /* If both arguments are constants, evaluate at compile-time.  */
9368       if (p1 && p2)
9369         {
9370           const size_t r = strcspn (p1, p2);
9371           return size_int (r);
9372         }
9373
9374       /* If the first argument is "", return 0.  */
9375       if (p1 && *p1 == '\0')
9376         {
9377           /* Evaluate and ignore argument s2 in case it has
9378              side-effects.  */
9379           return omit_one_operand (integer_type_node,
9380                                    integer_zero_node, s2);
9381         }
9382
9383       /* If the second argument is "", return __builtin_strlen(s1).  */
9384       if (p2 && *p2 == '\0')
9385         {
9386           tree newarglist = build_tree_list (NULL_TREE, s1),
9387             fn = implicit_built_in_decls[BUILT_IN_STRLEN];
9388
9389           /* If the replacement _DECL isn't initialized, don't do the
9390              transformation.  */
9391           if (!fn)
9392             return 0;
9393
9394           return build_function_call_expr (fn, newarglist);
9395         }
9396       return 0;
9397     }
9398 }
9399
9400 /* Fold a call to the fputs builtin.  IGNORE is true if the value returned
9401    by the builtin will be ignored.  UNLOCKED is true is true if this
9402    actually a call to fputs_unlocked.  If LEN in non-NULL, it represents
9403    the known length of the string.  Return NULL_TREE if no simplification
9404    was possible.  */
9405
9406 tree
9407 fold_builtin_fputs (tree arglist, bool ignore, bool unlocked, tree len)
9408 {
9409   tree fn;
9410   tree fn_fputc = unlocked ? implicit_built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
9411     : implicit_built_in_decls[BUILT_IN_FPUTC];
9412   tree fn_fwrite = unlocked ? implicit_built_in_decls[BUILT_IN_FWRITE_UNLOCKED]
9413     : implicit_built_in_decls[BUILT_IN_FWRITE];
9414
9415   /* If the return value is used, or the replacement _DECL isn't
9416      initialized, don't do the transformation.  */
9417   if (!ignore || !fn_fputc || !fn_fwrite)
9418     return 0;
9419
9420   /* Verify the arguments in the original call.  */
9421   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9422     return 0;
9423
9424   if (! len)
9425     len = c_strlen (TREE_VALUE (arglist), 0);
9426
9427   /* Get the length of the string passed to fputs.  If the length
9428      can't be determined, punt.  */
9429   if (!len
9430       || TREE_CODE (len) != INTEGER_CST)
9431     return 0;
9432
9433   switch (compare_tree_int (len, 1))
9434     {
9435     case -1: /* length is 0, delete the call entirely .  */
9436       return omit_one_operand (integer_type_node, integer_zero_node,
9437                                TREE_VALUE (TREE_CHAIN (arglist)));
9438
9439     case 0: /* length is 1, call fputc.  */
9440       {
9441         const char *p = c_getstr (TREE_VALUE (arglist));
9442
9443         if (p != NULL)
9444           {
9445             /* New argument list transforming fputs(string, stream) to
9446                fputc(string[0], stream).  */
9447             arglist =
9448               build_tree_list (NULL_TREE, TREE_VALUE (TREE_CHAIN (arglist)));
9449             arglist = tree_cons (NULL_TREE, build_int_2 (p[0], 0), arglist);
9450             fn = fn_fputc;
9451             break;
9452           }
9453       }
9454       /* FALLTHROUGH */
9455     case 1: /* length is greater than 1, call fwrite.  */
9456       {
9457         tree string_arg;
9458
9459         /* If optimizing for size keep fputs.  */
9460         if (optimize_size)
9461           return 0;
9462         string_arg = TREE_VALUE (arglist);
9463         /* New argument list transforming fputs(string, stream) to
9464            fwrite(string, 1, len, stream).  */
9465         arglist = build_tree_list (NULL_TREE,
9466                                    TREE_VALUE (TREE_CHAIN (arglist)));
9467         arglist = tree_cons (NULL_TREE, len, arglist);
9468         arglist = tree_cons (NULL_TREE, size_one_node, arglist);
9469         arglist = tree_cons (NULL_TREE, string_arg, arglist);
9470         fn = fn_fwrite;
9471         break;
9472       }
9473     default:
9474       abort ();
9475     }
9476
9477   /* These optimizations are only performed when the result is ignored,
9478      hence there's no need to cast the result to integer_type_node.  */
9479   return build_function_call_expr (fn, arglist);
9480 }
9481
9482 static void
9483 simplify_builtin_va_start (tree arglist)
9484 {
9485   tree chain = TREE_CHAIN (arglist);
9486
9487   if (TREE_CHAIN (chain))
9488     error ("too many arguments to function `va_start'");
9489
9490   simplify_builtin_next_arg (chain);
9491 }
9492
9493 static void
9494 simplify_builtin_next_arg (tree arglist)
9495 {
9496   tree fntype = TREE_TYPE (current_function_decl);
9497
9498   if (TYPE_ARG_TYPES (fntype) == 0
9499       || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
9500           == void_type_node))
9501     error ("`va_start' used in function with fixed args");
9502   else if (arglist)
9503     {
9504       tree last_parm = tree_last (DECL_ARGUMENTS (current_function_decl));
9505       tree arg = TREE_VALUE (arglist);
9506
9507       /* Strip off all nops for the sake of the comparison.  This
9508          is not quite the same as STRIP_NOPS.  It does more.
9509          We must also strip off INDIRECT_EXPR for C++ reference
9510          parameters.  */
9511       while (TREE_CODE (arg) == NOP_EXPR
9512              || TREE_CODE (arg) == CONVERT_EXPR
9513              || TREE_CODE (arg) == NON_LVALUE_EXPR
9514              || TREE_CODE (arg) == INDIRECT_REF)
9515         arg = TREE_OPERAND (arg, 0);
9516       if (arg != last_parm)
9517         warning ("second parameter of `va_start' not last named argument");
9518       TREE_VALUE (arglist) = arg;
9519     }
9520   else
9521     /* Evidently an out of date version of <stdarg.h>; can't validate
9522        va_start's second argument, but can still work as intended.  */
9523     warning ("`__builtin_next_arg' called without an argument");
9524 }
9525
9526
9527 /* Simplify a call to the sprintf builtin.
9528
9529    Return 0 if no simplification was possible, otherwise return the
9530    simplified form of the call as a tree.  If IGNORED is true, it means that
9531    the caller does not use the returned value of the function.  */
9532
9533 static tree
9534 simplify_builtin_sprintf (tree arglist, int ignored)
9535 {
9536   tree call, retval, dest, fmt;
9537   const char *fmt_str = NULL;
9538
9539   /* Verify the required arguments in the original call.  We deal with two
9540      types of sprintf() calls: 'sprintf (str, fmt)' and
9541      'sprintf (dest, "%s", orig)'.  */
9542   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)
9543       && !validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, POINTER_TYPE,
9544                             VOID_TYPE))
9545     return NULL_TREE;
9546
9547   /* Get the destination string and the format specifier.  */
9548   dest = TREE_VALUE (arglist);
9549   fmt = TREE_VALUE (TREE_CHAIN (arglist));
9550
9551   /* Check whether the format is a literal string constant.  */
9552   fmt_str = c_getstr (fmt);
9553   if (fmt_str == NULL)
9554     return NULL_TREE;
9555
9556   call = NULL_TREE;
9557   retval = NULL_TREE;
9558
9559   /* If the format doesn't contain % args or %%, use strcpy.  */
9560   if (strchr (fmt_str, '%') == NULL)
9561     {
9562       tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
9563
9564       if (!fn)
9565         return NULL_TREE;
9566
9567       /* Convert sprintf (str, fmt) into strcpy (str, fmt) when
9568          'format' is known to contain no % formats.  */
9569       arglist = build_tree_list (NULL_TREE, fmt);
9570       arglist = tree_cons (NULL_TREE, dest, arglist);
9571       call = build_function_call_expr (fn, arglist);
9572       if (!ignored)
9573         retval = build_int_2 (strlen (fmt_str), 0);
9574     }
9575
9576   /* If the format is "%s", use strcpy if the result isn't used.  */
9577   else if (fmt_str && strcmp (fmt_str, "%s") == 0)
9578     {
9579       tree fn, orig;
9580       fn = implicit_built_in_decls[BUILT_IN_STRCPY];
9581
9582       if (!fn)
9583         return NULL_TREE;
9584
9585       /* Convert sprintf (str1, "%s", str2) into strcpy (str1, str2).  */
9586       orig = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
9587       arglist = build_tree_list (NULL_TREE, orig);
9588       arglist = tree_cons (NULL_TREE, dest, arglist);
9589       if (!ignored)
9590         {
9591           retval = c_strlen (orig, 1);
9592           if (!retval || TREE_CODE (retval) != INTEGER_CST)
9593             return NULL_TREE;
9594         }
9595       call = build_function_call_expr (fn, arglist);
9596     }
9597
9598   if (call && retval)
9599     {
9600       retval = convert
9601         (TREE_TYPE (TREE_TYPE (implicit_built_in_decls[BUILT_IN_SPRINTF])),
9602          retval);
9603       return build2 (COMPOUND_EXPR, TREE_TYPE (retval), call, retval);
9604     }
9605   else
9606     return call;
9607 }