OSDN Git Service

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