OSDN Git Service

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