OSDN Git Service

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