OSDN Git Service

* gcc/config/arm/arm.md: Provide a big-endian version of the
[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     {
4167       t = fold_convert (TREE_TYPE (valist), size_int (boundary - 1));
4168       t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
4169                   build2 (PLUS_EXPR, TREE_TYPE (valist), valist_tmp, t));
4170       gimplify_and_add (t, pre_p);
4171
4172       t = fold_convert (TREE_TYPE (valist), size_int (-boundary));
4173       t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
4174                   build2 (BIT_AND_EXPR, TREE_TYPE (valist), valist_tmp, t));
4175       gimplify_and_add (t, pre_p);
4176     }
4177   else
4178     boundary = align;
4179
4180   /* If the actual alignment is less than the alignment of the type,
4181      adjust the type accordingly so that we don't assume strict alignment
4182      when deferencing the pointer.  */
4183   boundary *= BITS_PER_UNIT;
4184   if (boundary < TYPE_ALIGN (type))
4185     {
4186       type = build_variant_type_copy (type);
4187       TYPE_ALIGN (type) = boundary;
4188     }
4189
4190   /* Compute the rounded size of the type.  */
4191   type_size = size_in_bytes (type);
4192   rounded_size = round_up (type_size, align);
4193
4194   /* Reduce rounded_size so it's sharable with the postqueue.  */
4195   gimplify_expr (&rounded_size, pre_p, post_p, is_gimple_val, fb_rvalue);
4196
4197   /* Get AP.  */
4198   addr = valist_tmp;
4199   if (PAD_VARARGS_DOWN && !integer_zerop (rounded_size))
4200     {
4201       /* Small args are padded downward.  */
4202       t = fold_build2 (GT_EXPR, sizetype, rounded_size, size_int (align));
4203       t = fold_build3 (COND_EXPR, sizetype, t, size_zero_node,
4204                        size_binop (MINUS_EXPR, rounded_size, type_size));
4205       t = fold_convert (TREE_TYPE (addr), t);
4206       addr = fold_build2 (PLUS_EXPR, TREE_TYPE (addr), addr, t);
4207     }
4208
4209   /* Compute new value for AP.  */
4210   t = fold_convert (TREE_TYPE (valist), rounded_size);
4211   t = build2 (PLUS_EXPR, TREE_TYPE (valist), valist_tmp, t);
4212   t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist, t);
4213   gimplify_and_add (t, pre_p);
4214
4215   addr = fold_convert (build_pointer_type (type), addr);
4216
4217   if (indirect)
4218     addr = build_va_arg_indirect_ref (addr);
4219
4220   return build_va_arg_indirect_ref (addr);
4221 }
4222
4223 /* Build an indirect-ref expression over the given TREE, which represents a
4224    piece of a va_arg() expansion.  */
4225 tree
4226 build_va_arg_indirect_ref (tree addr)
4227 {
4228   addr = build_fold_indirect_ref (addr);
4229
4230   if (flag_mudflap) /* Don't instrument va_arg INDIRECT_REF.  */
4231     mf_mark (addr);
4232
4233   return addr;
4234 }
4235
4236 /* Return a dummy expression of type TYPE in order to keep going after an
4237    error.  */
4238
4239 static tree
4240 dummy_object (tree type)
4241 {
4242   tree t = convert (build_pointer_type (type), null_pointer_node);
4243   return build1 (INDIRECT_REF, type, t);
4244 }
4245
4246 /* Gimplify __builtin_va_arg, aka VA_ARG_EXPR, which is not really a
4247    builtin function, but a very special sort of operator.  */
4248
4249 enum gimplify_status
4250 gimplify_va_arg_expr (tree *expr_p, tree *pre_p, tree *post_p)
4251 {
4252   tree promoted_type, want_va_type, have_va_type;
4253   tree valist = TREE_OPERAND (*expr_p, 0);
4254   tree type = TREE_TYPE (*expr_p);
4255   tree t;
4256
4257   /* Verify that valist is of the proper type.  */
4258   want_va_type = va_list_type_node;
4259   have_va_type = TREE_TYPE (valist);
4260
4261   if (have_va_type == error_mark_node)
4262     return GS_ERROR;
4263
4264   if (TREE_CODE (want_va_type) == ARRAY_TYPE)
4265     {
4266       /* If va_list is an array type, the argument may have decayed
4267          to a pointer type, e.g. by being passed to another function.
4268          In that case, unwrap both types so that we can compare the
4269          underlying records.  */
4270       if (TREE_CODE (have_va_type) == ARRAY_TYPE
4271           || POINTER_TYPE_P (have_va_type))
4272         {
4273           want_va_type = TREE_TYPE (want_va_type);
4274           have_va_type = TREE_TYPE (have_va_type);
4275         }
4276     }
4277
4278   if (TYPE_MAIN_VARIANT (want_va_type) != TYPE_MAIN_VARIANT (have_va_type))
4279     {
4280       error ("first argument to %<va_arg%> not of type %<va_list%>");
4281       return GS_ERROR;
4282     }
4283
4284   /* Generate a diagnostic for requesting data of a type that cannot
4285      be passed through `...' due to type promotion at the call site.  */
4286   else if ((promoted_type = lang_hooks.types.type_promotes_to (type))
4287            != type)
4288     {
4289       static bool gave_help;
4290
4291       /* Unfortunately, this is merely undefined, rather than a constraint
4292          violation, so we cannot make this an error.  If this call is never
4293          executed, the program is still strictly conforming.  */
4294       warning (0, "%qT is promoted to %qT when passed through %<...%>",
4295                type, promoted_type);
4296       if (! gave_help)
4297         {
4298           gave_help = true;
4299           warning (0, "(so you should pass %qT not %qT to %<va_arg%>)",
4300                    promoted_type, type);
4301         }
4302
4303       /* We can, however, treat "undefined" any way we please.
4304          Call abort to encourage the user to fix the program.  */
4305       inform ("if this code is reached, the program will abort");
4306       t = build_function_call_expr (implicit_built_in_decls[BUILT_IN_TRAP],
4307                                     NULL);
4308       append_to_statement_list (t, pre_p);
4309
4310       /* This is dead code, but go ahead and finish so that the
4311          mode of the result comes out right.  */
4312       *expr_p = dummy_object (type);
4313       return GS_ALL_DONE;
4314     }
4315   else
4316     {
4317       /* Make it easier for the backends by protecting the valist argument
4318          from multiple evaluations.  */
4319       if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
4320         {
4321           /* For this case, the backends will be expecting a pointer to
4322              TREE_TYPE (va_list_type_node), but it's possible we've
4323              actually been given an array (an actual va_list_type_node).
4324              So fix it.  */
4325           if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
4326             {
4327               tree p1 = build_pointer_type (TREE_TYPE (va_list_type_node));
4328               valist = build_fold_addr_expr_with_type (valist, p1);
4329             }
4330           gimplify_expr (&valist, pre_p, post_p, is_gimple_val, fb_rvalue);
4331         }
4332       else
4333         gimplify_expr (&valist, pre_p, post_p, is_gimple_min_lval, fb_lvalue);
4334
4335       if (!targetm.gimplify_va_arg_expr)
4336         /* FIXME:Once most targets are converted we should merely
4337            assert this is non-null.  */
4338         return GS_ALL_DONE;
4339
4340       *expr_p = targetm.gimplify_va_arg_expr (valist, type, pre_p, post_p);
4341       return GS_OK;
4342     }
4343 }
4344
4345 /* Expand ARGLIST, from a call to __builtin_va_end.  */
4346
4347 static rtx
4348 expand_builtin_va_end (tree arglist)
4349 {
4350   tree valist = TREE_VALUE (arglist);
4351
4352   /* Evaluate for side effects, if needed.  I hate macros that don't
4353      do that.  */
4354   if (TREE_SIDE_EFFECTS (valist))
4355     expand_expr (valist, const0_rtx, VOIDmode, EXPAND_NORMAL);
4356
4357   return const0_rtx;
4358 }
4359
4360 /* Expand ARGLIST, from a call to __builtin_va_copy.  We do this as a
4361    builtin rather than just as an assignment in stdarg.h because of the
4362    nastiness of array-type va_list types.  */
4363
4364 static rtx
4365 expand_builtin_va_copy (tree arglist)
4366 {
4367   tree dst, src, t;
4368
4369   dst = TREE_VALUE (arglist);
4370   src = TREE_VALUE (TREE_CHAIN (arglist));
4371
4372   dst = stabilize_va_list (dst, 1);
4373   src = stabilize_va_list (src, 0);
4374
4375   if (TREE_CODE (va_list_type_node) != ARRAY_TYPE)
4376     {
4377       t = build2 (MODIFY_EXPR, va_list_type_node, dst, src);
4378       TREE_SIDE_EFFECTS (t) = 1;
4379       expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4380     }
4381   else
4382     {
4383       rtx dstb, srcb, size;
4384
4385       /* Evaluate to pointers.  */
4386       dstb = expand_expr (dst, NULL_RTX, Pmode, EXPAND_NORMAL);
4387       srcb = expand_expr (src, NULL_RTX, Pmode, EXPAND_NORMAL);
4388       size = expand_expr (TYPE_SIZE_UNIT (va_list_type_node), NULL_RTX,
4389                           VOIDmode, EXPAND_NORMAL);
4390
4391       dstb = convert_memory_address (Pmode, dstb);
4392       srcb = convert_memory_address (Pmode, srcb);
4393
4394       /* "Dereference" to BLKmode memories.  */
4395       dstb = gen_rtx_MEM (BLKmode, dstb);
4396       set_mem_alias_set (dstb, get_alias_set (TREE_TYPE (TREE_TYPE (dst))));
4397       set_mem_align (dstb, TYPE_ALIGN (va_list_type_node));
4398       srcb = gen_rtx_MEM (BLKmode, srcb);
4399       set_mem_alias_set (srcb, get_alias_set (TREE_TYPE (TREE_TYPE (src))));
4400       set_mem_align (srcb, TYPE_ALIGN (va_list_type_node));
4401
4402       /* Copy.  */
4403       emit_block_move (dstb, srcb, size, BLOCK_OP_NORMAL);
4404     }
4405
4406   return const0_rtx;
4407 }
4408
4409 /* Expand a call to one of the builtin functions __builtin_frame_address or
4410    __builtin_return_address.  */
4411
4412 static rtx
4413 expand_builtin_frame_address (tree fndecl, tree arglist)
4414 {
4415   /* The argument must be a nonnegative integer constant.
4416      It counts the number of frames to scan up the stack.
4417      The value is the return address saved in that frame.  */
4418   if (arglist == 0)
4419     /* Warning about missing arg was already issued.  */
4420     return const0_rtx;
4421   else if (! host_integerp (TREE_VALUE (arglist), 1))
4422     {
4423       if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4424         error ("invalid argument to %<__builtin_frame_address%>");
4425       else
4426         error ("invalid argument to %<__builtin_return_address%>");
4427       return const0_rtx;
4428     }
4429   else
4430     {
4431       rtx tem
4432         = expand_builtin_return_addr (DECL_FUNCTION_CODE (fndecl),
4433                                       tree_low_cst (TREE_VALUE (arglist), 1));
4434
4435       /* Some ports cannot access arbitrary stack frames.  */
4436       if (tem == NULL)
4437         {
4438           if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4439             warning (0, "unsupported argument to %<__builtin_frame_address%>");
4440           else
4441             warning (0, "unsupported argument to %<__builtin_return_address%>");
4442           return const0_rtx;
4443         }
4444
4445       /* For __builtin_frame_address, return what we've got.  */
4446       if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4447         return tem;
4448
4449       if (!REG_P (tem)
4450           && ! CONSTANT_P (tem))
4451         tem = copy_to_mode_reg (Pmode, tem);
4452       return tem;
4453     }
4454 }
4455
4456 /* Expand a call to the alloca builtin, with arguments ARGLIST.  Return 0 if
4457    we failed and the caller should emit a normal call, otherwise try to get
4458    the result in TARGET, if convenient.  */
4459
4460 static rtx
4461 expand_builtin_alloca (tree arglist, rtx target)
4462 {
4463   rtx op0;
4464   rtx result;
4465
4466   /* In -fmudflap-instrumented code, alloca() and __builtin_alloca()
4467      should always expand to function calls.  These can be intercepted
4468      in libmudflap.  */
4469   if (flag_mudflap)
4470     return 0;
4471
4472   if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
4473     return 0;
4474
4475   /* Compute the argument.  */
4476   op0 = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
4477
4478   /* Allocate the desired space.  */
4479   result = allocate_dynamic_stack_space (op0, target, BITS_PER_UNIT);
4480   result = convert_memory_address (ptr_mode, result);
4481
4482   return result;
4483 }
4484
4485 /* Expand a call to a unary builtin.  The arguments are in ARGLIST.
4486    Return 0 if a normal call should be emitted rather than expanding the
4487    function in-line.  If convenient, the result should be placed in TARGET.
4488    SUBTARGET may be used as the target for computing one of EXP's operands.  */
4489
4490 static rtx
4491 expand_builtin_unop (enum machine_mode target_mode, tree arglist, rtx target,
4492                      rtx subtarget, optab op_optab)
4493 {
4494   rtx op0;
4495   if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
4496     return 0;
4497
4498   /* Compute the argument.  */
4499   op0 = expand_expr (TREE_VALUE (arglist), subtarget, VOIDmode, 0);
4500   /* Compute op, into TARGET if possible.
4501      Set TARGET to wherever the result comes back.  */
4502   target = expand_unop (TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist))),
4503                         op_optab, op0, target, 1);
4504   gcc_assert (target);
4505
4506   return convert_to_mode (target_mode, target, 0);
4507 }
4508
4509 /* If the string passed to fputs is a constant and is one character
4510    long, we attempt to transform this call into __builtin_fputc().  */
4511
4512 static rtx
4513 expand_builtin_fputs (tree arglist, rtx target, bool unlocked)
4514 {
4515   /* Verify the arguments in the original call.  */
4516   if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4517     {
4518       tree result = fold_builtin_fputs (arglist, (target == const0_rtx),
4519                                         unlocked, NULL_TREE);
4520       if (result)
4521         return expand_expr (result, target, VOIDmode, EXPAND_NORMAL);
4522     }
4523   return 0;
4524 }
4525
4526 /* Expand a call to __builtin_expect.  We return our argument and emit a
4527    NOTE_INSN_EXPECTED_VALUE note.  This is the expansion of __builtin_expect in
4528    a non-jump context.  */
4529
4530 static rtx
4531 expand_builtin_expect (tree arglist, rtx target)
4532 {
4533   tree exp, c;
4534   rtx note, rtx_c;
4535
4536   if (arglist == NULL_TREE
4537       || TREE_CHAIN (arglist) == NULL_TREE)
4538     return const0_rtx;
4539   exp = TREE_VALUE (arglist);
4540   c = TREE_VALUE (TREE_CHAIN (arglist));
4541
4542   if (TREE_CODE (c) != INTEGER_CST)
4543     {
4544       error ("second argument to %<__builtin_expect%> must be a constant");
4545       c = integer_zero_node;
4546     }
4547
4548   target = expand_expr (exp, target, VOIDmode, EXPAND_NORMAL);
4549
4550   /* Don't bother with expected value notes for integral constants.  */
4551   if (flag_guess_branch_prob && GET_CODE (target) != CONST_INT)
4552     {
4553       /* We do need to force this into a register so that we can be
4554          moderately sure to be able to correctly interpret the branch
4555          condition later.  */
4556       target = force_reg (GET_MODE (target), target);
4557
4558       rtx_c = expand_expr (c, NULL_RTX, GET_MODE (target), EXPAND_NORMAL);
4559
4560       note = emit_note (NOTE_INSN_EXPECTED_VALUE);
4561       NOTE_EXPECTED_VALUE (note) = gen_rtx_EQ (VOIDmode, target, rtx_c);
4562     }
4563
4564   return target;
4565 }
4566
4567 /* Like expand_builtin_expect, except do this in a jump context.  This is
4568    called from do_jump if the conditional is a __builtin_expect.  Return either
4569    a list of insns to emit the jump or NULL if we cannot optimize
4570    __builtin_expect.  We need to optimize this at jump time so that machines
4571    like the PowerPC don't turn the test into a SCC operation, and then jump
4572    based on the test being 0/1.  */
4573
4574 rtx
4575 expand_builtin_expect_jump (tree exp, rtx if_false_label, rtx if_true_label)
4576 {
4577   tree arglist = TREE_OPERAND (exp, 1);
4578   tree arg0 = TREE_VALUE (arglist);
4579   tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
4580   rtx ret = NULL_RTX;
4581
4582   /* Only handle __builtin_expect (test, 0) and
4583      __builtin_expect (test, 1).  */
4584   if (TREE_CODE (TREE_TYPE (arg1)) == INTEGER_TYPE
4585       && (integer_zerop (arg1) || integer_onep (arg1)))
4586     {
4587       rtx insn, drop_through_label, temp;
4588
4589       /* Expand the jump insns.  */
4590       start_sequence ();
4591       do_jump (arg0, if_false_label, if_true_label);
4592       ret = get_insns ();
4593
4594       drop_through_label = get_last_insn ();
4595       if (drop_through_label && NOTE_P (drop_through_label))
4596         drop_through_label = prev_nonnote_insn (drop_through_label);
4597       if (drop_through_label && !LABEL_P (drop_through_label))
4598         drop_through_label = NULL_RTX;
4599       end_sequence ();
4600
4601       if (! if_true_label)
4602         if_true_label = drop_through_label;
4603       if (! if_false_label)
4604         if_false_label = drop_through_label;
4605
4606       /* Go through and add the expect's to each of the conditional jumps.  */
4607       insn = ret;
4608       while (insn != NULL_RTX)
4609         {
4610           rtx next = NEXT_INSN (insn);
4611
4612           if (JUMP_P (insn) && any_condjump_p (insn))
4613             {
4614               rtx ifelse = SET_SRC (pc_set (insn));
4615               rtx then_dest = XEXP (ifelse, 1);
4616               rtx else_dest = XEXP (ifelse, 2);
4617               int taken = -1;
4618
4619               /* First check if we recognize any of the labels.  */
4620               if (GET_CODE (then_dest) == LABEL_REF
4621                   && XEXP (then_dest, 0) == if_true_label)
4622                 taken = 1;
4623               else if (GET_CODE (then_dest) == LABEL_REF
4624                        && XEXP (then_dest, 0) == if_false_label)
4625                 taken = 0;
4626               else if (GET_CODE (else_dest) == LABEL_REF
4627                        && XEXP (else_dest, 0) == if_false_label)
4628                 taken = 1;
4629               else if (GET_CODE (else_dest) == LABEL_REF
4630                        && XEXP (else_dest, 0) == if_true_label)
4631                 taken = 0;
4632               /* Otherwise check where we drop through.  */
4633               else if (else_dest == pc_rtx)
4634                 {
4635                   if (next && NOTE_P (next))
4636                     next = next_nonnote_insn (next);
4637
4638                   if (next && JUMP_P (next)
4639                       && any_uncondjump_p (next))
4640                     temp = XEXP (SET_SRC (pc_set (next)), 0);
4641                   else
4642                     temp = next;
4643
4644                   /* TEMP is either a CODE_LABEL, NULL_RTX or something
4645                      else that can't possibly match either target label.  */
4646                   if (temp == if_false_label)
4647                     taken = 1;
4648                   else if (temp == if_true_label)
4649                     taken = 0;
4650                 }
4651               else if (then_dest == pc_rtx)
4652                 {
4653                   if (next && NOTE_P (next))
4654                     next = next_nonnote_insn (next);
4655
4656                   if (next && JUMP_P (next)
4657                       && any_uncondjump_p (next))
4658                     temp = XEXP (SET_SRC (pc_set (next)), 0);
4659                   else
4660                     temp = next;
4661
4662                   if (temp == if_false_label)
4663                     taken = 0;
4664                   else if (temp == if_true_label)
4665                     taken = 1;
4666                 }
4667
4668               if (taken != -1)
4669                 {
4670                   /* If the test is expected to fail, reverse the
4671                      probabilities.  */
4672                   if (integer_zerop (arg1))
4673                     taken = 1 - taken;
4674                   predict_insn_def (insn, PRED_BUILTIN_EXPECT, taken);
4675                 }
4676             }
4677
4678           insn = next;
4679         }
4680     }
4681
4682   return ret;
4683 }
4684
4685 void
4686 expand_builtin_trap (void)
4687 {
4688 #ifdef HAVE_trap
4689   if (HAVE_trap)
4690     emit_insn (gen_trap ());
4691   else
4692 #endif
4693     emit_library_call (abort_libfunc, LCT_NORETURN, VOIDmode, 0);
4694   emit_barrier ();
4695 }
4696
4697 /* Expand a call to fabs, fabsf or fabsl with arguments ARGLIST.
4698    Return 0 if a normal call should be emitted rather than expanding
4699    the function inline.  If convenient, the result should be placed
4700    in TARGET.  SUBTARGET may be used as the target for computing
4701    the operand.  */
4702
4703 static rtx
4704 expand_builtin_fabs (tree arglist, rtx target, rtx subtarget)
4705 {
4706   enum machine_mode mode;
4707   tree arg;
4708   rtx op0;
4709
4710   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
4711     return 0;
4712
4713   arg = TREE_VALUE (arglist);
4714   mode = TYPE_MODE (TREE_TYPE (arg));
4715   op0 = expand_expr (arg, subtarget, VOIDmode, 0);
4716   return expand_abs (mode, op0, target, 0, safe_from_p (target, arg, 1));
4717 }
4718
4719 /* Expand a call to copysign, copysignf, or copysignl with arguments ARGLIST.
4720    Return NULL is a normal call should be emitted rather than expanding the
4721    function inline.  If convenient, the result should be placed in TARGET.
4722    SUBTARGET may be used as the target for computing the operand.  */
4723
4724 static rtx
4725 expand_builtin_copysign (tree arglist, rtx target, rtx subtarget)
4726 {
4727   rtx op0, op1;
4728   tree arg;
4729
4730   if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
4731     return 0;
4732
4733   arg = TREE_VALUE (arglist);
4734   op0 = expand_expr (arg, subtarget, VOIDmode, 0);
4735
4736   arg = TREE_VALUE (TREE_CHAIN (arglist));
4737   op1 = expand_expr (arg, NULL, VOIDmode, 0);
4738
4739   return expand_copysign (op0, op1, target);
4740 }
4741
4742 /* Create a new constant string literal and return a char* pointer to it.
4743    The STRING_CST value is the LEN characters at STR.  */
4744 static tree
4745 build_string_literal (int len, const char *str)
4746 {
4747   tree t, elem, index, type;
4748
4749   t = build_string (len, str);
4750   elem = build_type_variant (char_type_node, 1, 0);
4751   index = build_index_type (build_int_cst (NULL_TREE, len - 1));
4752   type = build_array_type (elem, index);
4753   TREE_TYPE (t) = type;
4754   TREE_CONSTANT (t) = 1;
4755   TREE_INVARIANT (t) = 1;
4756   TREE_READONLY (t) = 1;
4757   TREE_STATIC (t) = 1;
4758
4759   type = build_pointer_type (type);
4760   t = build1 (ADDR_EXPR, type, t);
4761
4762   type = build_pointer_type (elem);
4763   t = build1 (NOP_EXPR, type, t);
4764   return t;
4765 }
4766
4767 /* Expand EXP, a call to printf or printf_unlocked.
4768    Return 0 if a normal call should be emitted rather than transforming
4769    the function inline.  If convenient, the result should be placed in
4770    TARGET with mode MODE.  UNLOCKED indicates this is a printf_unlocked
4771    call.  */
4772 static rtx
4773 expand_builtin_printf (tree exp, rtx target, enum machine_mode mode,
4774                        bool unlocked)
4775 {
4776   tree arglist = TREE_OPERAND (exp, 1);
4777   /* If we're using an unlocked function, assume the other unlocked
4778      functions exist explicitly.  */
4779   tree const fn_putchar = unlocked ? built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED]
4780     : implicit_built_in_decls[BUILT_IN_PUTCHAR];
4781   tree const fn_puts = unlocked ? built_in_decls[BUILT_IN_PUTS_UNLOCKED]
4782     : implicit_built_in_decls[BUILT_IN_PUTS];
4783   const char *fmt_str;
4784   tree fn, fmt, arg;
4785
4786   /* If the return value is used, don't do the transformation.  */
4787   if (target != const0_rtx)
4788     return 0;
4789
4790   /* Verify the required arguments in the original call.  */
4791   if (! arglist)
4792     return 0;
4793   fmt = TREE_VALUE (arglist);
4794   if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
4795     return 0;
4796   arglist = TREE_CHAIN (arglist);
4797
4798   /* Check whether the format is a literal string constant.  */
4799   fmt_str = c_getstr (fmt);
4800   if (fmt_str == NULL)
4801     return 0;
4802
4803   if (!init_target_chars())
4804     return 0;
4805   
4806   /* If the format specifier was "%s\n", call __builtin_puts(arg).  */
4807   if (strcmp (fmt_str, target_percent_s_newline) == 0)
4808     {
4809       if (! arglist
4810           || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
4811           || TREE_CHAIN (arglist))
4812         return 0;
4813       fn = fn_puts;
4814     }
4815   /* If the format specifier was "%c", call __builtin_putchar(arg).  */
4816   else if (strcmp (fmt_str, target_percent_c) == 0)
4817     {
4818       if (! arglist
4819           || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
4820           || TREE_CHAIN (arglist))
4821         return 0;
4822       fn = fn_putchar;
4823     }
4824   else
4825     {
4826       /* We can't handle anything else with % args or %% ... yet.  */
4827       if (strchr (fmt_str, target_percent))
4828         return 0;
4829
4830       if (arglist)
4831         return 0;
4832
4833       /* If the format specifier was "", printf does nothing.  */
4834       if (fmt_str[0] == '\0')
4835         return const0_rtx;
4836       /* If the format specifier has length of 1, call putchar.  */
4837       if (fmt_str[1] == '\0')
4838         {
4839           /* Given printf("c"), (where c is any one character,)
4840              convert "c"[0] to an int and pass that to the replacement
4841              function.  */
4842           arg = build_int_cst (NULL_TREE, fmt_str[0]);
4843           arglist = build_tree_list (NULL_TREE, arg);
4844           fn = fn_putchar;
4845         }
4846       else
4847         {
4848           /* If the format specifier was "string\n", call puts("string").  */
4849           size_t len = strlen (fmt_str);
4850           if ((unsigned char)fmt_str[len - 1] == target_newline)
4851             {
4852               /* Create a NUL-terminated string that's one char shorter
4853                  than the original, stripping off the trailing '\n'.  */
4854               char *newstr = alloca (len);
4855               memcpy (newstr, fmt_str, len - 1);
4856               newstr[len - 1] = 0;
4857
4858               arg = build_string_literal (len, newstr);
4859               arglist = build_tree_list (NULL_TREE, arg);
4860               fn = fn_puts;
4861             }
4862           else
4863             /* We'd like to arrange to call fputs(string,stdout) here,
4864                but we need stdout and don't have a way to get it yet.  */
4865             return 0;
4866         }
4867     }
4868
4869   if (!fn)
4870     return 0;
4871   fn = build_function_call_expr (fn, arglist);
4872   if (TREE_CODE (fn) == CALL_EXPR)
4873     CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
4874   return expand_expr (fn, target, mode, EXPAND_NORMAL);
4875 }
4876
4877 /* Expand EXP, a call to fprintf or fprintf_unlocked.
4878    Return 0 if a normal call should be emitted rather than transforming
4879    the function inline.  If convenient, the result should be placed in
4880    TARGET with mode MODE.  UNLOCKED indicates this is a fprintf_unlocked
4881    call.  */
4882 static rtx
4883 expand_builtin_fprintf (tree exp, rtx target, enum machine_mode mode,
4884                         bool unlocked)
4885 {
4886   tree arglist = TREE_OPERAND (exp, 1);
4887   /* If we're using an unlocked function, assume the other unlocked
4888      functions exist explicitly.  */
4889   tree const fn_fputc = unlocked ? built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
4890     : implicit_built_in_decls[BUILT_IN_FPUTC];
4891   tree const fn_fputs = unlocked ? built_in_decls[BUILT_IN_FPUTS_UNLOCKED]
4892     : implicit_built_in_decls[BUILT_IN_FPUTS];
4893   const char *fmt_str;
4894   tree fn, fmt, fp, arg;
4895
4896   /* If the return value is used, don't do the transformation.  */
4897   if (target != const0_rtx)
4898     return 0;
4899
4900   /* Verify the required arguments in the original call.  */
4901   if (! arglist)
4902     return 0;
4903   fp = TREE_VALUE (arglist);
4904   if (! POINTER_TYPE_P (TREE_TYPE (fp)))
4905     return 0;
4906   arglist = TREE_CHAIN (arglist);
4907   if (! arglist)
4908     return 0;
4909   fmt = TREE_VALUE (arglist);
4910   if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
4911     return 0;
4912   arglist = TREE_CHAIN (arglist);
4913
4914   /* Check whether the format is a literal string constant.  */
4915   fmt_str = c_getstr (fmt);
4916   if (fmt_str == NULL)
4917     return 0;
4918
4919   if (!init_target_chars())
4920     return 0;
4921   
4922   /* If the format specifier was "%s", call __builtin_fputs(arg,fp).  */
4923   if (strcmp (fmt_str, target_percent_s) == 0)
4924     {
4925       if (! arglist
4926           || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
4927           || TREE_CHAIN (arglist))
4928         return 0;
4929       arg = TREE_VALUE (arglist);
4930       arglist = build_tree_list (NULL_TREE, fp);
4931       arglist = tree_cons (NULL_TREE, arg, arglist);
4932       fn = fn_fputs;
4933     }
4934   /* If the format specifier was "%c", call __builtin_fputc(arg,fp).  */
4935   else if (strcmp (fmt_str, target_percent_c) == 0)
4936     {
4937       if (! arglist
4938           || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
4939           || TREE_CHAIN (arglist))
4940         return 0;
4941       arg = TREE_VALUE (arglist);
4942       arglist = build_tree_list (NULL_TREE, fp);
4943       arglist = tree_cons (NULL_TREE, arg, arglist);
4944       fn = fn_fputc;
4945     }
4946   else
4947     {
4948       /* We can't handle anything else with % args or %% ... yet.  */
4949       if (strchr (fmt_str, target_percent))
4950         return 0;
4951
4952       if (arglist)
4953         return 0;
4954
4955       /* If the format specifier was "", fprintf does nothing.  */
4956       if (fmt_str[0] == '\0')
4957         {
4958           /* Evaluate and ignore FILE* argument for side-effects.  */
4959           expand_expr (fp, const0_rtx, VOIDmode, EXPAND_NORMAL);
4960           return const0_rtx;
4961         }
4962
4963       /* When "string" doesn't contain %, replace all cases of
4964          fprintf(stream,string) with fputs(string,stream).  The fputs
4965          builtin will take care of special cases like length == 1.  */
4966       arglist = build_tree_list (NULL_TREE, fp);
4967       arglist = tree_cons (NULL_TREE, fmt, arglist);
4968       fn = fn_fputs;
4969     }
4970
4971   if (!fn)
4972     return 0;
4973   fn = build_function_call_expr (fn, arglist);
4974   if (TREE_CODE (fn) == CALL_EXPR)
4975     CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
4976   return expand_expr (fn, target, mode, EXPAND_NORMAL);
4977 }
4978
4979 /* Expand a call to sprintf with argument list ARGLIST.  Return 0 if
4980    a normal call should be emitted rather than expanding the function
4981    inline.  If convenient, the result should be placed in TARGET with
4982    mode MODE.  */
4983
4984 static rtx
4985 expand_builtin_sprintf (tree arglist, rtx target, enum machine_mode mode)
4986 {
4987   tree orig_arglist, dest, fmt;
4988   const char *fmt_str;
4989
4990   orig_arglist = arglist;
4991
4992   /* Verify the required arguments in the original call.  */
4993   if (! arglist)
4994     return 0;
4995   dest = TREE_VALUE (arglist);
4996   if (! POINTER_TYPE_P (TREE_TYPE (dest)))
4997     return 0;
4998   arglist = TREE_CHAIN (arglist);
4999   if (! arglist)
5000     return 0;
5001   fmt = TREE_VALUE (arglist);
5002   if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
5003     return 0;
5004   arglist = TREE_CHAIN (arglist);
5005
5006   /* Check whether the format is a literal string constant.  */
5007   fmt_str = c_getstr (fmt);
5008   if (fmt_str == NULL)
5009     return 0;
5010
5011   if (!init_target_chars())
5012     return 0;
5013
5014   /* If the format doesn't contain % args or %%, use strcpy.  */
5015   if (strchr (fmt_str, target_percent) == 0)
5016     {
5017       tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
5018       tree exp;
5019
5020       if (arglist || ! fn)
5021         return 0;
5022       expand_expr (build_function_call_expr (fn, orig_arglist),
5023                    const0_rtx, VOIDmode, EXPAND_NORMAL);
5024       if (target == const0_rtx)
5025         return const0_rtx;
5026       exp = build_int_cst (NULL_TREE, strlen (fmt_str));
5027       return expand_expr (exp, target, mode, EXPAND_NORMAL);
5028     }
5029   /* If the format is "%s", use strcpy if the result isn't used.  */
5030   else if (strcmp (fmt_str, target_percent_s) == 0)
5031     {
5032       tree fn, arg, len;
5033       fn = implicit_built_in_decls[BUILT_IN_STRCPY];
5034
5035       if (! fn)
5036         return 0;
5037
5038       if (! arglist || TREE_CHAIN (arglist))
5039         return 0;
5040       arg = TREE_VALUE (arglist);
5041       if (! POINTER_TYPE_P (TREE_TYPE (arg)))
5042         return 0;
5043
5044       if (target != const0_rtx)
5045         {
5046           len = c_strlen (arg, 1);
5047           if (! len || TREE_CODE (len) != INTEGER_CST)
5048             return 0;
5049         }
5050       else
5051         len = NULL_TREE;
5052
5053       arglist = build_tree_list (NULL_TREE, arg);
5054       arglist = tree_cons (NULL_TREE, dest, arglist);
5055       expand_expr (build_function_call_expr (fn, arglist),
5056                    const0_rtx, VOIDmode, EXPAND_NORMAL);
5057
5058       if (target == const0_rtx)
5059         return const0_rtx;
5060       return expand_expr (len, target, mode, EXPAND_NORMAL);
5061     }
5062
5063   return 0;
5064 }
5065
5066 /* Expand a call to either the entry or exit function profiler.  */
5067
5068 static rtx
5069 expand_builtin_profile_func (bool exitp)
5070 {
5071   rtx this, which;
5072
5073   this = DECL_RTL (current_function_decl);
5074   gcc_assert (MEM_P (this));
5075   this = XEXP (this, 0);
5076
5077   if (exitp)
5078     which = profile_function_exit_libfunc;
5079   else
5080     which = profile_function_entry_libfunc;
5081
5082   emit_library_call (which, LCT_NORMAL, VOIDmode, 2, this, Pmode,
5083                      expand_builtin_return_addr (BUILT_IN_RETURN_ADDRESS,
5084                                                  0),
5085                      Pmode);
5086
5087   return const0_rtx;
5088 }
5089
5090 /* Given a trampoline address, make sure it satisfies TRAMPOLINE_ALIGNMENT.  */
5091
5092 static rtx
5093 round_trampoline_addr (rtx tramp)
5094 {
5095   rtx temp, addend, mask;
5096
5097   /* If we don't need too much alignment, we'll have been guaranteed
5098      proper alignment by get_trampoline_type.  */
5099   if (TRAMPOLINE_ALIGNMENT <= STACK_BOUNDARY)
5100     return tramp;
5101
5102   /* Round address up to desired boundary.  */
5103   temp = gen_reg_rtx (Pmode);
5104   addend = GEN_INT (TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT - 1);
5105   mask = GEN_INT (-TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT);
5106
5107   temp  = expand_simple_binop (Pmode, PLUS, tramp, addend,
5108                                temp, 0, OPTAB_LIB_WIDEN);
5109   tramp = expand_simple_binop (Pmode, AND, temp, mask,
5110                                temp, 0, OPTAB_LIB_WIDEN);
5111
5112   return tramp;
5113 }
5114
5115 static rtx
5116 expand_builtin_init_trampoline (tree arglist)
5117 {
5118   tree t_tramp, t_func, t_chain;
5119   rtx r_tramp, r_func, r_chain;
5120 #ifdef TRAMPOLINE_TEMPLATE
5121   rtx blktramp;
5122 #endif
5123
5124   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE,
5125                          POINTER_TYPE, VOID_TYPE))
5126     return NULL_RTX;
5127
5128   t_tramp = TREE_VALUE (arglist);
5129   arglist = TREE_CHAIN (arglist);
5130   t_func = TREE_VALUE (arglist);
5131   arglist = TREE_CHAIN (arglist);
5132   t_chain = TREE_VALUE (arglist);
5133
5134   r_tramp = expand_expr (t_tramp, NULL_RTX, VOIDmode, 0);
5135   r_func = expand_expr (t_func, NULL_RTX, VOIDmode, 0);
5136   r_chain = expand_expr (t_chain, NULL_RTX, VOIDmode, 0);
5137
5138   /* Generate insns to initialize the trampoline.  */
5139   r_tramp = round_trampoline_addr (r_tramp);
5140 #ifdef TRAMPOLINE_TEMPLATE
5141   blktramp = gen_rtx_MEM (BLKmode, r_tramp);
5142   set_mem_align (blktramp, TRAMPOLINE_ALIGNMENT);
5143   emit_block_move (blktramp, assemble_trampoline_template (),
5144                    GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL);
5145 #endif
5146   trampolines_created = 1;
5147   INITIALIZE_TRAMPOLINE (r_tramp, r_func, r_chain);
5148
5149   return const0_rtx;
5150 }
5151
5152 static rtx
5153 expand_builtin_adjust_trampoline (tree arglist)
5154 {
5155   rtx tramp;
5156
5157   if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5158     return NULL_RTX;
5159
5160   tramp = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
5161   tramp = round_trampoline_addr (tramp);
5162 #ifdef TRAMPOLINE_ADJUST_ADDRESS
5163   TRAMPOLINE_ADJUST_ADDRESS (tramp);
5164 #endif
5165
5166   return tramp;
5167 }
5168
5169 /* Expand a call to the built-in signbit, signbitf or signbitl function.
5170    Return NULL_RTX if a normal call should be emitted rather than expanding
5171    the function in-line.  EXP is the expression that is a call to the builtin
5172    function; if convenient, the result should be placed in TARGET.  */
5173
5174 static rtx
5175 expand_builtin_signbit (tree exp, rtx target)
5176 {
5177   const struct real_format *fmt;
5178   enum machine_mode fmode, imode, rmode;
5179   HOST_WIDE_INT hi, lo;
5180   tree arg, arglist;
5181   int word, bitpos;
5182   rtx temp;
5183
5184   arglist = TREE_OPERAND (exp, 1);
5185   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
5186     return 0;
5187
5188   arg = TREE_VALUE (arglist);
5189   fmode = TYPE_MODE (TREE_TYPE (arg));
5190   rmode = TYPE_MODE (TREE_TYPE (exp));
5191   fmt = REAL_MODE_FORMAT (fmode);
5192
5193   /* For floating point formats without a sign bit, implement signbit
5194      as "ARG < 0.0".  */
5195   bitpos = fmt->signbit_ro;
5196   if (bitpos < 0)
5197   {
5198     /* But we can't do this if the format supports signed zero.  */
5199     if (fmt->has_signed_zero && HONOR_SIGNED_ZEROS (fmode))
5200       return 0;
5201
5202     arg = fold_build2 (LT_EXPR, TREE_TYPE (exp), arg,
5203                        build_real (TREE_TYPE (arg), dconst0));
5204     return expand_expr (arg, target, VOIDmode, EXPAND_NORMAL);
5205   }
5206
5207   temp = expand_expr (arg, NULL_RTX, VOIDmode, 0);
5208   if (GET_MODE_SIZE (fmode) <= UNITS_PER_WORD)
5209     {
5210       imode = int_mode_for_mode (fmode);
5211       if (imode == BLKmode)
5212         return 0;
5213       temp = gen_lowpart (imode, temp);
5214     }
5215   else
5216     {
5217       imode = word_mode;
5218       /* Handle targets with different FP word orders.  */
5219       if (FLOAT_WORDS_BIG_ENDIAN)
5220         word = (GET_MODE_BITSIZE (fmode) - bitpos) / BITS_PER_WORD;
5221       else
5222         word = bitpos / BITS_PER_WORD;
5223       temp = operand_subword_force (temp, word, fmode);
5224       bitpos = bitpos % BITS_PER_WORD;
5225     }
5226
5227   /* Force the intermediate word_mode (or narrower) result into a
5228      register.  This avoids attempting to create paradoxical SUBREGs
5229      of floating point modes below.  */
5230   temp = force_reg (imode, temp);
5231
5232   /* If the bitpos is within the "result mode" lowpart, the operation
5233      can be implement with a single bitwise AND.  Otherwise, we need
5234      a right shift and an AND.  */
5235
5236   if (bitpos < GET_MODE_BITSIZE (rmode))
5237     {
5238       if (bitpos < HOST_BITS_PER_WIDE_INT)
5239         {
5240           hi = 0;
5241           lo = (HOST_WIDE_INT) 1 << bitpos;
5242         }
5243       else
5244         {
5245           hi = (HOST_WIDE_INT) 1 << (bitpos - HOST_BITS_PER_WIDE_INT);
5246           lo = 0;
5247         }
5248
5249       if (imode != rmode)
5250         temp = gen_lowpart (rmode, temp);
5251       temp = expand_binop (rmode, and_optab, temp,
5252                            immed_double_const (lo, hi, rmode),
5253                            NULL_RTX, 1, OPTAB_LIB_WIDEN);
5254     }
5255   else
5256     {
5257       /* Perform a logical right shift to place the signbit in the least
5258          significant bit, then truncate the result to the desired mode
5259          and mask just this bit.  */
5260       temp = expand_shift (RSHIFT_EXPR, imode, temp,
5261                            build_int_cst (NULL_TREE, bitpos), NULL_RTX, 1);
5262       temp = gen_lowpart (rmode, temp);
5263       temp = expand_binop (rmode, and_optab, temp, const1_rtx,
5264                            NULL_RTX, 1, OPTAB_LIB_WIDEN);
5265     }
5266
5267   return temp;
5268 }
5269
5270 /* Expand fork or exec calls.  TARGET is the desired target of the
5271    call.  ARGLIST is the list of arguments of the call.  FN is the
5272    identificator of the actual function.  IGNORE is nonzero if the
5273    value is to be ignored.  */
5274
5275 static rtx
5276 expand_builtin_fork_or_exec (tree fn, tree arglist, rtx target, int ignore)
5277 {
5278   tree id, decl;
5279   tree call;
5280
5281   /* If we are not profiling, just call the function.  */
5282   if (!profile_arc_flag)
5283     return NULL_RTX;
5284
5285   /* Otherwise call the wrapper.  This should be equivalent for the rest of
5286      compiler, so the code does not diverge, and the wrapper may run the
5287      code necessary for keeping the profiling sane.  */
5288
5289   switch (DECL_FUNCTION_CODE (fn))
5290     {
5291     case BUILT_IN_FORK:
5292       id = get_identifier ("__gcov_fork");
5293       break;
5294
5295     case BUILT_IN_EXECL:
5296       id = get_identifier ("__gcov_execl");
5297       break;
5298
5299     case BUILT_IN_EXECV:
5300       id = get_identifier ("__gcov_execv");
5301       break;
5302
5303     case BUILT_IN_EXECLP:
5304       id = get_identifier ("__gcov_execlp");
5305       break;
5306
5307     case BUILT_IN_EXECLE:
5308       id = get_identifier ("__gcov_execle");
5309       break;
5310
5311     case BUILT_IN_EXECVP:
5312       id = get_identifier ("__gcov_execvp");
5313       break;
5314
5315     case BUILT_IN_EXECVE:
5316       id = get_identifier ("__gcov_execve");
5317       break;
5318
5319     default:
5320       gcc_unreachable ();
5321     }
5322
5323   decl = build_decl (FUNCTION_DECL, id, TREE_TYPE (fn));
5324   DECL_EXTERNAL (decl) = 1;
5325   TREE_PUBLIC (decl) = 1;
5326   DECL_ARTIFICIAL (decl) = 1;
5327   TREE_NOTHROW (decl) = 1;
5328   call = build_function_call_expr (decl, arglist);
5329
5330   return expand_call (call, target, ignore);
5331 }
5332
5333 \f
5334 /* Reconstitute a mode for a __sync intrinsic operation.  Since the type of
5335    the pointer in these functions is void*, the tree optimizers may remove
5336    casts.  The mode computed in expand_builtin isn't reliable either, due
5337    to __sync_bool_compare_and_swap.
5338
5339    FCODE_DIFF should be fcode - base, where base is the FOO_1 code for the
5340    group of builtins.  This gives us log2 of the mode size.  */
5341
5342 static inline enum machine_mode
5343 get_builtin_sync_mode (int fcode_diff)
5344 {
5345   /* The size is not negotiable, so ask not to get BLKmode in return
5346      if the target indicates that a smaller size would be better.  */
5347   return mode_for_size (BITS_PER_UNIT << fcode_diff, MODE_INT, 0);
5348 }
5349
5350 /* Expand the __sync_xxx_and_fetch and __sync_fetch_and_xxx intrinsics.
5351    ARGLIST is the operands list to the function.  CODE is the rtx code 
5352    that corresponds to the arithmetic or logical operation from the name;
5353    an exception here is that NOT actually means NAND.  TARGET is an optional
5354    place for us to store the results; AFTER is true if this is the
5355    fetch_and_xxx form.  IGNORE is true if we don't actually care about
5356    the result of the operation at all.  */
5357
5358 static rtx
5359 expand_builtin_sync_operation (enum machine_mode mode, tree arglist,
5360                                enum rtx_code code, bool after,
5361                                rtx target, bool ignore)
5362 {
5363   rtx addr, val, mem;
5364
5365   /* Expand the operands.  */
5366   addr = expand_expr (TREE_VALUE (arglist), NULL, Pmode, EXPAND_SUM);
5367
5368   arglist = TREE_CHAIN (arglist);
5369   val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
5370
5371   /* Note that we explicitly do not want any alias information for this
5372      memory, so that we kill all other live memories.  Otherwise we don't
5373      satisfy the full barrier semantics of the intrinsic.  */
5374   mem = validize_mem (gen_rtx_MEM (mode, addr));
5375   MEM_VOLATILE_P (mem) = 1;
5376
5377   if (ignore)
5378     return expand_sync_operation (mem, val, code);
5379   else
5380     return expand_sync_fetch_operation (mem, val, code, after, target);
5381 }
5382
5383 /* Expand the __sync_val_compare_and_swap and __sync_bool_compare_and_swap
5384    intrinsics.  ARGLIST is the operands list to the function.  IS_BOOL is
5385    true if this is the boolean form.  TARGET is a place for us to store the
5386    results; this is NOT optional if IS_BOOL is true.  */
5387
5388 static rtx
5389 expand_builtin_compare_and_swap (enum machine_mode mode, tree arglist,
5390                                  bool is_bool, rtx target)
5391 {
5392   rtx addr, old_val, new_val, mem;
5393
5394   /* Expand the operands.  */
5395   addr = expand_expr (TREE_VALUE (arglist), NULL, Pmode, EXPAND_SUM);
5396
5397   arglist = TREE_CHAIN (arglist);
5398   old_val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
5399
5400   arglist = TREE_CHAIN (arglist);
5401   new_val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
5402
5403   /* Note that we explicitly do not want any alias information for this
5404      memory, so that we kill all other live memories.  Otherwise we don't
5405      satisfy the full barrier semantics of the intrinsic.  */
5406   mem = validize_mem (gen_rtx_MEM (mode, addr));
5407   MEM_VOLATILE_P (mem) = 1;
5408
5409   if (is_bool)
5410     return expand_bool_compare_and_swap (mem, old_val, new_val, target);
5411   else
5412     return expand_val_compare_and_swap (mem, old_val, new_val, target);
5413 }
5414
5415 /* Expand the __sync_lock_test_and_set intrinsic.  Note that the most
5416    general form is actually an atomic exchange, and some targets only
5417    support a reduced form with the second argument being a constant 1.
5418    ARGLIST is the operands list to the function; TARGET is an optional
5419    place for us to store the results.  */
5420
5421 static rtx
5422 expand_builtin_lock_test_and_set (enum machine_mode mode, tree arglist,
5423                                   rtx target)
5424 {
5425   rtx addr, val, mem;
5426
5427   /* Expand the operands.  */
5428   addr = expand_expr (TREE_VALUE (arglist), NULL, Pmode, EXPAND_NORMAL);
5429
5430   arglist = TREE_CHAIN (arglist);
5431   val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
5432
5433   /* Note that we explicitly do not want any alias information for this
5434      memory, so that we kill all other live memories.  Otherwise we don't
5435      satisfy the barrier semantics of the intrinsic.  */
5436   mem = validize_mem (gen_rtx_MEM (mode, addr));
5437   MEM_VOLATILE_P (mem) = 1;
5438
5439   return expand_sync_lock_test_and_set (mem, val, target);
5440 }
5441
5442 /* Expand the __sync_synchronize intrinsic.  */
5443
5444 static void
5445 expand_builtin_synchronize (void)
5446 {
5447   tree x;
5448
5449 #ifdef HAVE_memory_barrier
5450   if (HAVE_memory_barrier)
5451     {
5452       emit_insn (gen_memory_barrier ());
5453       return;
5454     }
5455 #endif
5456
5457   /* If no explicit memory barrier instruction is available, create an
5458      empty asm stmt with a memory clobber.  */
5459   x = build4 (ASM_EXPR, void_type_node, build_string (0, ""), NULL, NULL,
5460               tree_cons (NULL, build_string (6, "memory"), NULL));
5461   ASM_VOLATILE_P (x) = 1;
5462   expand_asm_expr (x);
5463 }
5464
5465 /* Expand the __sync_lock_release intrinsic.  ARGLIST is the operands list
5466    to the function.  */
5467
5468 static void
5469 expand_builtin_lock_release (enum machine_mode mode, tree arglist)
5470 {
5471   enum insn_code icode;
5472   rtx addr, mem, insn;
5473   rtx val = const0_rtx;
5474
5475   /* Expand the operands.  */
5476   addr = expand_expr (TREE_VALUE (arglist), NULL, Pmode, EXPAND_NORMAL);
5477
5478   /* Note that we explicitly do not want any alias information for this
5479      memory, so that we kill all other live memories.  Otherwise we don't
5480      satisfy the barrier semantics of the intrinsic.  */
5481   mem = validize_mem (gen_rtx_MEM (mode, addr));
5482   MEM_VOLATILE_P (mem) = 1;
5483
5484   /* If there is an explicit operation in the md file, use it.  */
5485   icode = sync_lock_release[mode];
5486   if (icode != CODE_FOR_nothing)
5487     {
5488       if (!insn_data[icode].operand[1].predicate (val, mode))
5489         val = force_reg (mode, val);
5490
5491       insn = GEN_FCN (icode) (mem, val);
5492       if (insn)
5493         {
5494           emit_insn (insn);
5495           return;
5496         }
5497     }
5498
5499   /* Otherwise we can implement this operation by emitting a barrier
5500      followed by a store of zero.  */
5501   expand_builtin_synchronize ();
5502   emit_move_insn (mem, val);
5503 }
5504 \f
5505 /* Expand an expression EXP that calls a built-in function,
5506    with result going to TARGET if that's convenient
5507    (and in mode MODE if that's convenient).
5508    SUBTARGET may be used as the target for computing one of EXP's operands.
5509    IGNORE is nonzero if the value is to be ignored.  */
5510
5511 rtx
5512 expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
5513                 int ignore)
5514 {
5515   tree fndecl = get_callee_fndecl (exp);
5516   tree arglist = TREE_OPERAND (exp, 1);
5517   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
5518   enum machine_mode target_mode = TYPE_MODE (TREE_TYPE (exp));
5519
5520   if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
5521     return targetm.expand_builtin (exp, target, subtarget, mode, ignore);
5522
5523   /* When not optimizing, generate calls to library functions for a certain
5524      set of builtins.  */
5525   if (!optimize
5526       && !called_as_built_in (fndecl)
5527       && DECL_ASSEMBLER_NAME_SET_P (fndecl)
5528       && fcode != BUILT_IN_ALLOCA)
5529     return expand_call (exp, target, ignore);
5530
5531   /* The built-in function expanders test for target == const0_rtx
5532      to determine whether the function's result will be ignored.  */
5533   if (ignore)
5534     target = const0_rtx;
5535
5536   /* If the result of a pure or const built-in function is ignored, and
5537      none of its arguments are volatile, we can avoid expanding the
5538      built-in call and just evaluate the arguments for side-effects.  */
5539   if (target == const0_rtx
5540       && (DECL_IS_PURE (fndecl) || TREE_READONLY (fndecl)))
5541     {
5542       bool volatilep = false;
5543       tree arg;
5544
5545       for (arg = arglist; arg; arg = TREE_CHAIN (arg))
5546         if (TREE_THIS_VOLATILE (TREE_VALUE (arg)))
5547           {
5548             volatilep = true;
5549             break;
5550           }
5551
5552       if (! volatilep)
5553         {
5554           for (arg = arglist; arg; arg = TREE_CHAIN (arg))
5555             expand_expr (TREE_VALUE (arg), const0_rtx,
5556                          VOIDmode, EXPAND_NORMAL);
5557           return const0_rtx;
5558         }
5559     }
5560
5561   switch (fcode)
5562     {
5563     CASE_FLT_FN (BUILT_IN_FABS):
5564       target = expand_builtin_fabs (arglist, target, subtarget);
5565       if (target)
5566         return target;
5567       break;
5568
5569     CASE_FLT_FN (BUILT_IN_COPYSIGN):
5570       target = expand_builtin_copysign (arglist, target, subtarget);
5571       if (target)
5572         return target;
5573       break;
5574
5575       /* Just do a normal library call if we were unable to fold
5576          the values.  */
5577     CASE_FLT_FN (BUILT_IN_CABS):
5578       break;
5579
5580     CASE_FLT_FN (BUILT_IN_EXP):
5581     CASE_FLT_FN (BUILT_IN_EXP10):
5582     CASE_FLT_FN (BUILT_IN_POW10):
5583     CASE_FLT_FN (BUILT_IN_EXP2):
5584     CASE_FLT_FN (BUILT_IN_EXPM1):
5585     CASE_FLT_FN (BUILT_IN_LOGB):
5586     CASE_FLT_FN (BUILT_IN_ILOGB):
5587     CASE_FLT_FN (BUILT_IN_LOG):
5588     CASE_FLT_FN (BUILT_IN_LOG10):
5589     CASE_FLT_FN (BUILT_IN_LOG2):
5590     CASE_FLT_FN (BUILT_IN_LOG1P):
5591     CASE_FLT_FN (BUILT_IN_TAN):
5592     CASE_FLT_FN (BUILT_IN_ASIN):
5593     CASE_FLT_FN (BUILT_IN_ACOS):
5594     CASE_FLT_FN (BUILT_IN_ATAN):
5595       /* Treat these like sqrt only if unsafe math optimizations are allowed,
5596          because of possible accuracy problems.  */
5597       if (! flag_unsafe_math_optimizations)
5598         break;
5599     CASE_FLT_FN (BUILT_IN_SQRT):
5600     CASE_FLT_FN (BUILT_IN_FLOOR):
5601     CASE_FLT_FN (BUILT_IN_CEIL):
5602     CASE_FLT_FN (BUILT_IN_TRUNC):
5603     CASE_FLT_FN (BUILT_IN_ROUND):
5604     CASE_FLT_FN (BUILT_IN_NEARBYINT):
5605     CASE_FLT_FN (BUILT_IN_RINT):
5606     CASE_FLT_FN (BUILT_IN_LRINT):
5607     CASE_FLT_FN (BUILT_IN_LLRINT):
5608       target = expand_builtin_mathfn (exp, target, subtarget);
5609       if (target)
5610         return target;
5611       break;
5612
5613     CASE_FLT_FN (BUILT_IN_LCEIL):
5614     CASE_FLT_FN (BUILT_IN_LLCEIL):
5615     CASE_FLT_FN (BUILT_IN_LFLOOR):
5616     CASE_FLT_FN (BUILT_IN_LLFLOOR):
5617       target = expand_builtin_int_roundingfn (exp, target, subtarget);
5618       if (target)
5619         return target;
5620       break;
5621
5622     CASE_FLT_FN (BUILT_IN_POW):
5623       target = expand_builtin_pow (exp, target, subtarget);
5624       if (target)
5625         return target;
5626       break;
5627
5628     CASE_FLT_FN (BUILT_IN_POWI):
5629       target = expand_builtin_powi (exp, target, subtarget);
5630       if (target)
5631         return target;
5632       break;
5633
5634     CASE_FLT_FN (BUILT_IN_ATAN2):
5635     CASE_FLT_FN (BUILT_IN_LDEXP):
5636     CASE_FLT_FN (BUILT_IN_FMOD):
5637     CASE_FLT_FN (BUILT_IN_DREM):
5638       if (! flag_unsafe_math_optimizations)
5639         break;
5640       target = expand_builtin_mathfn_2 (exp, target, subtarget);
5641       if (target)
5642         return target;
5643       break;
5644
5645     CASE_FLT_FN (BUILT_IN_SIN):
5646     CASE_FLT_FN (BUILT_IN_COS):
5647       if (! flag_unsafe_math_optimizations)
5648         break;
5649       target = expand_builtin_mathfn_3 (exp, target, subtarget);
5650       if (target)
5651         return target;
5652       break;
5653
5654     case BUILT_IN_APPLY_ARGS:
5655       return expand_builtin_apply_args ();
5656
5657       /* __builtin_apply (FUNCTION, ARGUMENTS, ARGSIZE) invokes
5658          FUNCTION with a copy of the parameters described by
5659          ARGUMENTS, and ARGSIZE.  It returns a block of memory
5660          allocated on the stack into which is stored all the registers
5661          that might possibly be used for returning the result of a
5662          function.  ARGUMENTS is the value returned by
5663          __builtin_apply_args.  ARGSIZE is the number of bytes of
5664          arguments that must be copied.  ??? How should this value be
5665          computed?  We'll also need a safe worst case value for varargs
5666          functions.  */
5667     case BUILT_IN_APPLY:
5668       if (!validate_arglist (arglist, POINTER_TYPE,
5669                              POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)
5670           && !validate_arglist (arglist, REFERENCE_TYPE,
5671                                 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
5672         return const0_rtx;
5673       else
5674         {
5675           int i;
5676           tree t;
5677           rtx ops[3];
5678
5679           for (t = arglist, i = 0; t; t = TREE_CHAIN (t), i++)
5680             ops[i] = expand_expr (TREE_VALUE (t), NULL_RTX, VOIDmode, 0);
5681
5682           return expand_builtin_apply (ops[0], ops[1], ops[2]);
5683         }
5684
5685       /* __builtin_return (RESULT) causes the function to return the
5686          value described by RESULT.  RESULT is address of the block of
5687          memory returned by __builtin_apply.  */
5688     case BUILT_IN_RETURN:
5689       if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5690         expand_builtin_return (expand_expr (TREE_VALUE (arglist),
5691                                             NULL_RTX, VOIDmode, 0));
5692       return const0_rtx;
5693
5694     case BUILT_IN_SAVEREGS:
5695       return expand_builtin_saveregs ();
5696
5697     case BUILT_IN_ARGS_INFO:
5698       return expand_builtin_args_info (arglist);
5699
5700       /* Return the address of the first anonymous stack arg.  */
5701     case BUILT_IN_NEXT_ARG:
5702       if (fold_builtin_next_arg (arglist))
5703         return const0_rtx;
5704       return expand_builtin_next_arg ();
5705
5706     case BUILT_IN_CLASSIFY_TYPE:
5707       return expand_builtin_classify_type (arglist);
5708
5709     case BUILT_IN_CONSTANT_P:
5710       return const0_rtx;
5711
5712     case BUILT_IN_FRAME_ADDRESS:
5713     case BUILT_IN_RETURN_ADDRESS:
5714       return expand_builtin_frame_address (fndecl, arglist);
5715
5716     /* Returns the address of the area where the structure is returned.
5717        0 otherwise.  */
5718     case BUILT_IN_AGGREGATE_INCOMING_ADDRESS:
5719       if (arglist != 0
5720           || ! AGGREGATE_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl)))
5721           || !MEM_P (DECL_RTL (DECL_RESULT (current_function_decl))))
5722         return const0_rtx;
5723       else
5724         return XEXP (DECL_RTL (DECL_RESULT (current_function_decl)), 0);
5725
5726     case BUILT_IN_ALLOCA:
5727       target = expand_builtin_alloca (arglist, target);
5728       if (target)
5729         return target;
5730       break;
5731
5732     case BUILT_IN_STACK_SAVE:
5733       return expand_stack_save ();
5734
5735     case BUILT_IN_STACK_RESTORE:
5736       expand_stack_restore (TREE_VALUE (arglist));
5737       return const0_rtx;
5738
5739     CASE_INT_FN (BUILT_IN_FFS):
5740     case BUILT_IN_FFSIMAX:
5741       target = expand_builtin_unop (target_mode, arglist, target,
5742                                     subtarget, ffs_optab);
5743       if (target)
5744         return target;
5745       break;
5746
5747     CASE_INT_FN (BUILT_IN_CLZ):
5748     case BUILT_IN_CLZIMAX:
5749       target = expand_builtin_unop (target_mode, arglist, target,
5750                                     subtarget, clz_optab);
5751       if (target)
5752         return target;
5753       break;
5754
5755     CASE_INT_FN (BUILT_IN_CTZ):
5756     case BUILT_IN_CTZIMAX:
5757       target = expand_builtin_unop (target_mode, arglist, target,
5758                                     subtarget, ctz_optab);
5759       if (target)
5760         return target;
5761       break;
5762
5763     CASE_INT_FN (BUILT_IN_POPCOUNT):
5764     case BUILT_IN_POPCOUNTIMAX:
5765       target = expand_builtin_unop (target_mode, arglist, target,
5766                                     subtarget, popcount_optab);
5767       if (target)
5768         return target;
5769       break;
5770
5771     CASE_INT_FN (BUILT_IN_PARITY):
5772     case BUILT_IN_PARITYIMAX:
5773       target = expand_builtin_unop (target_mode, arglist, target,
5774                                     subtarget, parity_optab);
5775       if (target)
5776         return target;
5777       break;
5778
5779     case BUILT_IN_STRLEN:
5780       target = expand_builtin_strlen (arglist, target, target_mode);
5781       if (target)
5782         return target;
5783       break;
5784
5785     case BUILT_IN_STRCPY:
5786       target = expand_builtin_strcpy (fndecl, arglist, target, mode);
5787       if (target)
5788         return target;
5789       break;
5790
5791     case BUILT_IN_STRNCPY:
5792       target = expand_builtin_strncpy (exp, target, mode);
5793       if (target)
5794         return target;
5795       break;
5796
5797     case BUILT_IN_STPCPY:
5798       target = expand_builtin_stpcpy (exp, target, mode);
5799       if (target)
5800         return target;
5801       break;
5802
5803     case BUILT_IN_STRCAT:
5804       target = expand_builtin_strcat (fndecl, arglist, target, mode);
5805       if (target)
5806         return target;
5807       break;
5808
5809     case BUILT_IN_STRNCAT:
5810       target = expand_builtin_strncat (arglist, target, mode);
5811       if (target)
5812         return target;
5813       break;
5814
5815     case BUILT_IN_STRSPN:
5816       target = expand_builtin_strspn (arglist, target, mode);
5817       if (target)
5818         return target;
5819       break;
5820
5821     case BUILT_IN_STRCSPN:
5822       target = expand_builtin_strcspn (arglist, target, mode);
5823       if (target)
5824         return target;
5825       break;
5826
5827     case BUILT_IN_STRSTR:
5828       target = expand_builtin_strstr (arglist, TREE_TYPE (exp), target, mode);
5829       if (target)
5830         return target;
5831       break;
5832
5833     case BUILT_IN_STRPBRK:
5834       target = expand_builtin_strpbrk (arglist, TREE_TYPE (exp), target, mode);
5835       if (target)
5836         return target;
5837       break;
5838
5839     case BUILT_IN_INDEX:
5840     case BUILT_IN_STRCHR:
5841       target = expand_builtin_strchr (arglist, TREE_TYPE (exp), target, mode);
5842       if (target)
5843         return target;
5844       break;
5845
5846     case BUILT_IN_RINDEX:
5847     case BUILT_IN_STRRCHR:
5848       target = expand_builtin_strrchr (arglist, TREE_TYPE (exp), target, mode);
5849       if (target)
5850         return target;
5851       break;
5852
5853     case BUILT_IN_MEMCPY:
5854       target = expand_builtin_memcpy (exp, target, mode);
5855       if (target)
5856         return target;
5857       break;
5858
5859     case BUILT_IN_MEMPCPY:
5860       target = expand_builtin_mempcpy (arglist, TREE_TYPE (exp), target, mode, /*endp=*/ 1);
5861       if (target)
5862         return target;
5863       break;
5864
5865     case BUILT_IN_MEMMOVE:
5866       target = expand_builtin_memmove (arglist, TREE_TYPE (exp), target,
5867                                        mode, exp);
5868       if (target)
5869         return target;
5870       break;
5871
5872     case BUILT_IN_BCOPY:
5873       target = expand_builtin_bcopy (exp);
5874       if (target)
5875         return target;
5876       break;
5877
5878     case BUILT_IN_MEMSET:
5879       target = expand_builtin_memset (arglist, target, mode, exp);
5880       if (target)
5881         return target;
5882       break;
5883
5884     case BUILT_IN_BZERO:
5885       target = expand_builtin_bzero (exp);
5886       if (target)
5887         return target;
5888       break;
5889
5890     case BUILT_IN_STRCMP:
5891       target = expand_builtin_strcmp (exp, target, mode);
5892       if (target)
5893         return target;
5894       break;
5895
5896     case BUILT_IN_STRNCMP:
5897       target = expand_builtin_strncmp (exp, target, mode);
5898       if (target)
5899         return target;
5900       break;
5901
5902     case BUILT_IN_BCMP:
5903     case BUILT_IN_MEMCMP:
5904       target = expand_builtin_memcmp (exp, arglist, target, mode);
5905       if (target)
5906         return target;
5907       break;
5908
5909     case BUILT_IN_SETJMP:
5910       target = expand_builtin_setjmp (arglist, target);
5911       if (target)
5912         return target;
5913       break;
5914
5915       /* __builtin_longjmp is passed a pointer to an array of five words.
5916          It's similar to the C library longjmp function but works with
5917          __builtin_setjmp above.  */
5918     case BUILT_IN_LONGJMP:
5919       if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
5920         break;
5921       else
5922         {
5923           rtx buf_addr = expand_expr (TREE_VALUE (arglist), subtarget,
5924                                       VOIDmode, 0);
5925           rtx value = expand_expr (TREE_VALUE (TREE_CHAIN (arglist)),
5926                                    NULL_RTX, VOIDmode, 0);
5927
5928           if (value != const1_rtx)
5929             {
5930               error ("%<__builtin_longjmp%> second argument must be 1");
5931               return const0_rtx;
5932             }
5933
5934           expand_builtin_longjmp (buf_addr, value);
5935           return const0_rtx;
5936         }
5937
5938     case BUILT_IN_NONLOCAL_GOTO:
5939       target = expand_builtin_nonlocal_goto (arglist);
5940       if (target)
5941         return target;
5942       break;
5943
5944       /* This updates the setjmp buffer that is its argument with the value
5945          of the current stack pointer.  */
5946     case BUILT_IN_UPDATE_SETJMP_BUF:
5947       if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5948         {
5949           rtx buf_addr
5950             = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
5951
5952           expand_builtin_update_setjmp_buf (buf_addr);
5953           return const0_rtx;
5954         }
5955       break;
5956
5957     case BUILT_IN_TRAP:
5958       expand_builtin_trap ();
5959       return const0_rtx;
5960
5961     case BUILT_IN_PRINTF:
5962       target = expand_builtin_printf (exp, target, mode, false);
5963       if (target)
5964         return target;
5965       break;
5966
5967     case BUILT_IN_PRINTF_UNLOCKED:
5968       target = expand_builtin_printf (exp, target, mode, true);
5969       if (target)
5970         return target;
5971       break;
5972
5973     case BUILT_IN_FPUTS:
5974       target = expand_builtin_fputs (arglist, target, false);
5975       if (target)
5976         return target;
5977       break;
5978     case BUILT_IN_FPUTS_UNLOCKED:
5979       target = expand_builtin_fputs (arglist, target, true);
5980       if (target)
5981         return target;
5982       break;
5983
5984     case BUILT_IN_FPRINTF:
5985       target = expand_builtin_fprintf (exp, target, mode, false);
5986       if (target)
5987         return target;
5988       break;
5989
5990     case BUILT_IN_FPRINTF_UNLOCKED:
5991       target = expand_builtin_fprintf (exp, target, mode, true);
5992       if (target)
5993         return target;
5994       break;
5995
5996     case BUILT_IN_SPRINTF:
5997       target = expand_builtin_sprintf (arglist, target, mode);
5998       if (target)
5999         return target;
6000       break;
6001
6002     CASE_FLT_FN (BUILT_IN_SIGNBIT):
6003       target = expand_builtin_signbit (exp, target);
6004       if (target)
6005         return target;
6006       break;
6007
6008       /* Various hooks for the DWARF 2 __throw routine.  */
6009     case BUILT_IN_UNWIND_INIT:
6010       expand_builtin_unwind_init ();
6011       return const0_rtx;
6012     case BUILT_IN_DWARF_CFA:
6013       return virtual_cfa_rtx;
6014 #ifdef DWARF2_UNWIND_INFO
6015     case BUILT_IN_DWARF_SP_COLUMN:
6016       return expand_builtin_dwarf_sp_column ();
6017     case BUILT_IN_INIT_DWARF_REG_SIZES:
6018       expand_builtin_init_dwarf_reg_sizes (TREE_VALUE (arglist));
6019       return const0_rtx;
6020 #endif
6021     case BUILT_IN_FROB_RETURN_ADDR:
6022       return expand_builtin_frob_return_addr (TREE_VALUE (arglist));
6023     case BUILT_IN_EXTRACT_RETURN_ADDR:
6024       return expand_builtin_extract_return_addr (TREE_VALUE (arglist));
6025     case BUILT_IN_EH_RETURN:
6026       expand_builtin_eh_return (TREE_VALUE (arglist),
6027                                 TREE_VALUE (TREE_CHAIN (arglist)));
6028       return const0_rtx;
6029 #ifdef EH_RETURN_DATA_REGNO
6030     case BUILT_IN_EH_RETURN_DATA_REGNO:
6031       return expand_builtin_eh_return_data_regno (arglist);
6032 #endif
6033     case BUILT_IN_EXTEND_POINTER:
6034       return expand_builtin_extend_pointer (TREE_VALUE (arglist));
6035
6036     case BUILT_IN_VA_START:
6037     case BUILT_IN_STDARG_START:
6038       return expand_builtin_va_start (arglist);
6039     case BUILT_IN_VA_END:
6040       return expand_builtin_va_end (arglist);
6041     case BUILT_IN_VA_COPY:
6042       return expand_builtin_va_copy (arglist);
6043     case BUILT_IN_EXPECT:
6044       return expand_builtin_expect (arglist, target);
6045     case BUILT_IN_PREFETCH:
6046       expand_builtin_prefetch (arglist);
6047       return const0_rtx;
6048
6049     case BUILT_IN_PROFILE_FUNC_ENTER:
6050       return expand_builtin_profile_func (false);
6051     case BUILT_IN_PROFILE_FUNC_EXIT:
6052       return expand_builtin_profile_func (true);
6053
6054     case BUILT_IN_INIT_TRAMPOLINE:
6055       return expand_builtin_init_trampoline (arglist);
6056     case BUILT_IN_ADJUST_TRAMPOLINE:
6057       return expand_builtin_adjust_trampoline (arglist);
6058
6059     case BUILT_IN_FORK:
6060     case BUILT_IN_EXECL:
6061     case BUILT_IN_EXECV:
6062     case BUILT_IN_EXECLP:
6063     case BUILT_IN_EXECLE:
6064     case BUILT_IN_EXECVP:
6065     case BUILT_IN_EXECVE:
6066       target = expand_builtin_fork_or_exec (fndecl, arglist, target, ignore);
6067       if (target)
6068         return target;
6069       break;
6070
6071     case BUILT_IN_FETCH_AND_ADD_1:
6072     case BUILT_IN_FETCH_AND_ADD_2:
6073     case BUILT_IN_FETCH_AND_ADD_4:
6074     case BUILT_IN_FETCH_AND_ADD_8:
6075       mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_ADD_1);
6076       target = expand_builtin_sync_operation (mode, arglist, PLUS,
6077                                               false, target, ignore);
6078       if (target)
6079         return target;
6080       break;
6081
6082     case BUILT_IN_FETCH_AND_SUB_1:
6083     case BUILT_IN_FETCH_AND_SUB_2:
6084     case BUILT_IN_FETCH_AND_SUB_4:
6085     case BUILT_IN_FETCH_AND_SUB_8:
6086       mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_SUB_1);
6087       target = expand_builtin_sync_operation (mode, arglist, MINUS,
6088                                               false, target, ignore);
6089       if (target)
6090         return target;
6091       break;
6092
6093     case BUILT_IN_FETCH_AND_OR_1:
6094     case BUILT_IN_FETCH_AND_OR_2:
6095     case BUILT_IN_FETCH_AND_OR_4:
6096     case BUILT_IN_FETCH_AND_OR_8:
6097       mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_OR_1);
6098       target = expand_builtin_sync_operation (mode, arglist, IOR,
6099                                               false, target, ignore);
6100       if (target)
6101         return target;
6102       break;
6103
6104     case BUILT_IN_FETCH_AND_AND_1:
6105     case BUILT_IN_FETCH_AND_AND_2:
6106     case BUILT_IN_FETCH_AND_AND_4:
6107     case BUILT_IN_FETCH_AND_AND_8:
6108       mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_AND_1);
6109       target = expand_builtin_sync_operation (mode, arglist, AND,
6110                                               false, target, ignore);
6111       if (target)
6112         return target;
6113       break;
6114
6115     case BUILT_IN_FETCH_AND_XOR_1:
6116     case BUILT_IN_FETCH_AND_XOR_2:
6117     case BUILT_IN_FETCH_AND_XOR_4:
6118     case BUILT_IN_FETCH_AND_XOR_8:
6119       mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_XOR_1);
6120       target = expand_builtin_sync_operation (mode, arglist, XOR,
6121                                               false, target, ignore);
6122       if (target)
6123         return target;
6124       break;
6125
6126     case BUILT_IN_FETCH_AND_NAND_1:
6127     case BUILT_IN_FETCH_AND_NAND_2:
6128     case BUILT_IN_FETCH_AND_NAND_4:
6129     case BUILT_IN_FETCH_AND_NAND_8:
6130       mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_NAND_1);
6131       target = expand_builtin_sync_operation (mode, arglist, NOT,
6132                                               false, target, ignore);
6133       if (target)
6134         return target;
6135       break;
6136
6137     case BUILT_IN_ADD_AND_FETCH_1:
6138     case BUILT_IN_ADD_AND_FETCH_2:
6139     case BUILT_IN_ADD_AND_FETCH_4:
6140     case BUILT_IN_ADD_AND_FETCH_8:
6141       mode = get_builtin_sync_mode (fcode - BUILT_IN_ADD_AND_FETCH_1);
6142       target = expand_builtin_sync_operation (mode, arglist, PLUS,
6143                                               true, target, ignore);
6144       if (target)
6145         return target;
6146       break;
6147
6148     case BUILT_IN_SUB_AND_FETCH_1:
6149     case BUILT_IN_SUB_AND_FETCH_2:
6150     case BUILT_IN_SUB_AND_FETCH_4:
6151     case BUILT_IN_SUB_AND_FETCH_8:
6152       mode = get_builtin_sync_mode (fcode - BUILT_IN_SUB_AND_FETCH_1);
6153       target = expand_builtin_sync_operation (mode, arglist, MINUS,
6154                                               true, target, ignore);
6155       if (target)
6156         return target;
6157       break;
6158
6159     case BUILT_IN_OR_AND_FETCH_1:
6160     case BUILT_IN_OR_AND_FETCH_2:
6161     case BUILT_IN_OR_AND_FETCH_4:
6162     case BUILT_IN_OR_AND_FETCH_8:
6163       mode = get_builtin_sync_mode (fcode - BUILT_IN_OR_AND_FETCH_1);
6164       target = expand_builtin_sync_operation (mode, arglist, IOR,
6165                                               true, target, ignore);
6166       if (target)
6167         return target;
6168       break;
6169
6170     case BUILT_IN_AND_AND_FETCH_1:
6171     case BUILT_IN_AND_AND_FETCH_2:
6172     case BUILT_IN_AND_AND_FETCH_4:
6173     case BUILT_IN_AND_AND_FETCH_8:
6174       mode = get_builtin_sync_mode (fcode - BUILT_IN_AND_AND_FETCH_1);
6175       target = expand_builtin_sync_operation (mode, arglist, AND,
6176                                               true, target, ignore);
6177       if (target)
6178         return target;
6179       break;
6180
6181     case BUILT_IN_XOR_AND_FETCH_1:
6182     case BUILT_IN_XOR_AND_FETCH_2:
6183     case BUILT_IN_XOR_AND_FETCH_4:
6184     case BUILT_IN_XOR_AND_FETCH_8:
6185       mode = get_builtin_sync_mode (fcode - BUILT_IN_XOR_AND_FETCH_1);
6186       target = expand_builtin_sync_operation (mode, arglist, XOR,
6187                                               true, target, ignore);
6188       if (target)
6189         return target;
6190       break;
6191
6192     case BUILT_IN_NAND_AND_FETCH_1:
6193     case BUILT_IN_NAND_AND_FETCH_2:
6194     case BUILT_IN_NAND_AND_FETCH_4:
6195     case BUILT_IN_NAND_AND_FETCH_8:
6196       mode = get_builtin_sync_mode (fcode - BUILT_IN_NAND_AND_FETCH_1);
6197       target = expand_builtin_sync_operation (mode, arglist, NOT,
6198                                               true, target, ignore);
6199       if (target)
6200         return target;
6201       break;
6202
6203     case BUILT_IN_BOOL_COMPARE_AND_SWAP_1:
6204     case BUILT_IN_BOOL_COMPARE_AND_SWAP_2:
6205     case BUILT_IN_BOOL_COMPARE_AND_SWAP_4:
6206     case BUILT_IN_BOOL_COMPARE_AND_SWAP_8:
6207       if (mode == VOIDmode)
6208         mode = TYPE_MODE (boolean_type_node);
6209       if (!target || !register_operand (target, mode))
6210         target = gen_reg_rtx (mode);
6211
6212       mode = get_builtin_sync_mode (fcode - BUILT_IN_BOOL_COMPARE_AND_SWAP_1);
6213       target = expand_builtin_compare_and_swap (mode, arglist, true, target);
6214       if (target)
6215         return target;
6216       break;
6217
6218     case BUILT_IN_VAL_COMPARE_AND_SWAP_1:
6219     case BUILT_IN_VAL_COMPARE_AND_SWAP_2:
6220     case BUILT_IN_VAL_COMPARE_AND_SWAP_4:
6221     case BUILT_IN_VAL_COMPARE_AND_SWAP_8:
6222       mode = get_builtin_sync_mode (fcode - BUILT_IN_VAL_COMPARE_AND_SWAP_1);
6223       target = expand_builtin_compare_and_swap (mode, arglist, false, target);
6224       if (target)
6225         return target;
6226       break;
6227
6228     case BUILT_IN_LOCK_TEST_AND_SET_1:
6229     case BUILT_IN_LOCK_TEST_AND_SET_2:
6230     case BUILT_IN_LOCK_TEST_AND_SET_4:
6231     case BUILT_IN_LOCK_TEST_AND_SET_8:
6232       mode = get_builtin_sync_mode (fcode - BUILT_IN_LOCK_TEST_AND_SET_1);
6233       target = expand_builtin_lock_test_and_set (mode, arglist, target);
6234       if (target)
6235         return target;
6236       break;
6237
6238     case BUILT_IN_LOCK_RELEASE_1:
6239     case BUILT_IN_LOCK_RELEASE_2:
6240     case BUILT_IN_LOCK_RELEASE_4:
6241     case BUILT_IN_LOCK_RELEASE_8:
6242       mode = get_builtin_sync_mode (fcode - BUILT_IN_LOCK_RELEASE_1);
6243       expand_builtin_lock_release (mode, arglist);
6244       return const0_rtx;
6245
6246     case BUILT_IN_SYNCHRONIZE:
6247       expand_builtin_synchronize ();
6248       return const0_rtx;
6249
6250     case BUILT_IN_OBJECT_SIZE:
6251       return expand_builtin_object_size (exp);
6252
6253     case BUILT_IN_MEMCPY_CHK:
6254     case BUILT_IN_MEMPCPY_CHK:
6255     case BUILT_IN_MEMMOVE_CHK:
6256     case BUILT_IN_MEMSET_CHK:
6257       target = expand_builtin_memory_chk (exp, target, mode, fcode);
6258       if (target)
6259         return target;
6260       break;
6261
6262     case BUILT_IN_STRCPY_CHK:
6263     case BUILT_IN_STPCPY_CHK:
6264     case BUILT_IN_STRNCPY_CHK:
6265     case BUILT_IN_STRCAT_CHK:
6266     case BUILT_IN_SNPRINTF_CHK:
6267     case BUILT_IN_VSNPRINTF_CHK:
6268       maybe_emit_chk_warning (exp, fcode);
6269       break;
6270
6271     case BUILT_IN_SPRINTF_CHK:
6272     case BUILT_IN_VSPRINTF_CHK:
6273       maybe_emit_sprintf_chk_warning (exp, fcode);
6274       break;
6275
6276     default:    /* just do library call, if unknown builtin */
6277       break;
6278     }
6279
6280   /* The switch statement above can drop through to cause the function
6281      to be called normally.  */
6282   return expand_call (exp, target, ignore);
6283 }
6284
6285 /* Determine whether a tree node represents a call to a built-in
6286    function.  If the tree T is a call to a built-in function with
6287    the right number of arguments of the appropriate types, return
6288    the DECL_FUNCTION_CODE of the call, e.g. BUILT_IN_SQRT.
6289    Otherwise the return value is END_BUILTINS.  */
6290
6291 enum built_in_function
6292 builtin_mathfn_code (tree t)
6293 {
6294   tree fndecl, arglist, parmlist;
6295   tree argtype, parmtype;
6296
6297   if (TREE_CODE (t) != CALL_EXPR
6298       || TREE_CODE (TREE_OPERAND (t, 0)) != ADDR_EXPR)
6299     return END_BUILTINS;
6300
6301   fndecl = get_callee_fndecl (t);
6302   if (fndecl == NULL_TREE
6303       || TREE_CODE (fndecl) != FUNCTION_DECL
6304       || ! DECL_BUILT_IN (fndecl)
6305       || DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
6306     return END_BUILTINS;
6307
6308   arglist = TREE_OPERAND (t, 1);
6309   parmlist = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
6310   for (; parmlist; parmlist = TREE_CHAIN (parmlist))
6311     {
6312       /* If a function doesn't take a variable number of arguments,
6313          the last element in the list will have type `void'.  */
6314       parmtype = TREE_VALUE (parmlist);
6315       if (VOID_TYPE_P (parmtype))
6316         {
6317           if (arglist)
6318             return END_BUILTINS;
6319           return DECL_FUNCTION_CODE (fndecl);
6320         }
6321
6322       if (! arglist)
6323         return END_BUILTINS;
6324
6325       argtype = TREE_TYPE (TREE_VALUE (arglist));
6326
6327       if (SCALAR_FLOAT_TYPE_P (parmtype))
6328         {
6329           if (! SCALAR_FLOAT_TYPE_P (argtype))
6330             return END_BUILTINS;
6331         }
6332       else if (COMPLEX_FLOAT_TYPE_P (parmtype))
6333         {
6334           if (! COMPLEX_FLOAT_TYPE_P (argtype))
6335             return END_BUILTINS;
6336         }
6337       else if (POINTER_TYPE_P (parmtype))
6338         {
6339           if (! POINTER_TYPE_P (argtype))
6340             return END_BUILTINS;
6341         }
6342       else if (INTEGRAL_TYPE_P (parmtype))
6343         {
6344           if (! INTEGRAL_TYPE_P (argtype))
6345             return END_BUILTINS;
6346         }
6347       else
6348         return END_BUILTINS;
6349
6350       arglist = TREE_CHAIN (arglist);
6351     }
6352
6353   /* Variable-length argument list.  */
6354   return DECL_FUNCTION_CODE (fndecl);
6355 }
6356
6357 /* Fold a call to __builtin_constant_p, if we know it will evaluate to a
6358    constant.  ARGLIST is the argument list of the call.  */
6359
6360 static tree
6361 fold_builtin_constant_p (tree arglist)
6362 {
6363   if (arglist == 0)
6364     return 0;
6365
6366   arglist = TREE_VALUE (arglist);
6367
6368   /* We return 1 for a numeric type that's known to be a constant
6369      value at compile-time or for an aggregate type that's a
6370      literal constant.  */
6371   STRIP_NOPS (arglist);
6372
6373   /* If we know this is a constant, emit the constant of one.  */
6374   if (CONSTANT_CLASS_P (arglist)
6375       || (TREE_CODE (arglist) == CONSTRUCTOR
6376           && TREE_CONSTANT (arglist)))
6377     return integer_one_node;
6378   if (TREE_CODE (arglist) == ADDR_EXPR)
6379     {
6380        tree op = TREE_OPERAND (arglist, 0);
6381        if (TREE_CODE (op) == STRING_CST
6382            || (TREE_CODE (op) == ARRAY_REF
6383                && integer_zerop (TREE_OPERAND (op, 1))
6384                && TREE_CODE (TREE_OPERAND (op, 0)) == STRING_CST))
6385          return integer_one_node;
6386     }
6387
6388   /* If this expression has side effects, show we don't know it to be a
6389      constant.  Likewise if it's a pointer or aggregate type since in
6390      those case we only want literals, since those are only optimized
6391      when generating RTL, not later.
6392      And finally, if we are compiling an initializer, not code, we
6393      need to return a definite result now; there's not going to be any
6394      more optimization done.  */
6395   if (TREE_SIDE_EFFECTS (arglist)
6396       || AGGREGATE_TYPE_P (TREE_TYPE (arglist))
6397       || POINTER_TYPE_P (TREE_TYPE (arglist))
6398       || cfun == 0)
6399     return integer_zero_node;
6400
6401   return 0;
6402 }
6403
6404 /* Fold a call to __builtin_expect, if we expect that a comparison against
6405    the argument will fold to a constant.  In practice, this means a true
6406    constant or the address of a non-weak symbol.  ARGLIST is the argument
6407    list of the call.  */
6408
6409 static tree
6410 fold_builtin_expect (tree arglist)
6411 {
6412   tree arg, inner;
6413
6414   if (arglist == 0)
6415     return 0;
6416
6417   arg = TREE_VALUE (arglist);
6418
6419   /* If the argument isn't invariant, then there's nothing we can do.  */
6420   if (!TREE_INVARIANT (arg))
6421     return 0;
6422
6423   /* If we're looking at an address of a weak decl, then do not fold.  */
6424   inner = arg;
6425   STRIP_NOPS (inner);
6426   if (TREE_CODE (inner) == ADDR_EXPR)
6427     {
6428       do
6429         {
6430           inner = TREE_OPERAND (inner, 0);
6431         }
6432       while (TREE_CODE (inner) == COMPONENT_REF
6433              || TREE_CODE (inner) == ARRAY_REF);
6434       if (DECL_P (inner) && DECL_WEAK (inner))
6435         return 0;
6436     }
6437
6438   /* Otherwise, ARG already has the proper type for the return value.  */
6439   return arg;
6440 }
6441
6442 /* Fold a call to __builtin_classify_type.  */
6443
6444 static tree
6445 fold_builtin_classify_type (tree arglist)
6446 {
6447   if (arglist == 0)
6448     return build_int_cst (NULL_TREE, no_type_class);
6449
6450   return build_int_cst (NULL_TREE,
6451                         type_to_class (TREE_TYPE (TREE_VALUE (arglist))));
6452 }
6453
6454 /* Fold a call to __builtin_strlen.  */
6455
6456 static tree
6457 fold_builtin_strlen (tree arglist)
6458 {
6459   if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6460     return NULL_TREE;
6461   else
6462     {
6463       tree len = c_strlen (TREE_VALUE (arglist), 0);
6464
6465       if (len)
6466         {
6467           /* Convert from the internal "sizetype" type to "size_t".  */
6468           if (size_type_node)
6469             len = fold_convert (size_type_node, len);
6470           return len;
6471         }
6472
6473       return NULL_TREE;
6474     }
6475 }
6476
6477 /* Fold a call to __builtin_inf or __builtin_huge_val.  */
6478
6479 static tree
6480 fold_builtin_inf (tree type, int warn)
6481 {
6482   REAL_VALUE_TYPE real;
6483
6484   /* __builtin_inff is intended to be usable to define INFINITY on all
6485      targets.  If an infinity is not available, INFINITY expands "to a
6486      positive constant of type float that overflows at translation
6487      time", footnote "In this case, using INFINITY will violate the
6488      constraint in 6.4.4 and thus require a diagnostic." (C99 7.12#4).
6489      Thus we pedwarn to ensure this constraint violation is
6490      diagnosed.  */
6491   if (!MODE_HAS_INFINITIES (TYPE_MODE (type)) && warn)
6492     pedwarn ("target format does not support infinity");
6493
6494   real_inf (&real);
6495   return build_real (type, real);
6496 }
6497
6498 /* Fold a call to __builtin_nan or __builtin_nans.  */
6499
6500 static tree
6501 fold_builtin_nan (tree arglist, tree type, int quiet)
6502 {
6503   REAL_VALUE_TYPE real;
6504   const char *str;
6505
6506   if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6507     return 0;
6508   str = c_getstr (TREE_VALUE (arglist));
6509   if (!str)
6510     return 0;
6511
6512   if (!real_nan (&real, str, quiet, TYPE_MODE (type)))
6513     return 0;
6514
6515   return build_real (type, real);
6516 }
6517
6518 /* Return true if the floating point expression T has an integer value.
6519    We also allow +Inf, -Inf and NaN to be considered integer values.  */
6520
6521 static bool
6522 integer_valued_real_p (tree t)
6523 {
6524   switch (TREE_CODE (t))
6525     {
6526     case FLOAT_EXPR:
6527       return true;
6528
6529     case ABS_EXPR:
6530     case SAVE_EXPR:
6531     case NON_LVALUE_EXPR:
6532       return integer_valued_real_p (TREE_OPERAND (t, 0));
6533
6534     case COMPOUND_EXPR:
6535     case MODIFY_EXPR:
6536     case BIND_EXPR:
6537       return integer_valued_real_p (TREE_OPERAND (t, 1));
6538
6539     case PLUS_EXPR:
6540     case MINUS_EXPR:
6541     case MULT_EXPR:
6542     case MIN_EXPR:
6543     case MAX_EXPR:
6544       return integer_valued_real_p (TREE_OPERAND (t, 0))
6545              && integer_valued_real_p (TREE_OPERAND (t, 1));
6546
6547     case COND_EXPR:
6548       return integer_valued_real_p (TREE_OPERAND (t, 1))
6549              && integer_valued_real_p (TREE_OPERAND (t, 2));
6550
6551     case REAL_CST:
6552       if (! TREE_CONSTANT_OVERFLOW (t))
6553       {
6554         REAL_VALUE_TYPE c, cint;
6555
6556         c = TREE_REAL_CST (t);
6557         real_trunc (&cint, TYPE_MODE (TREE_TYPE (t)), &c);
6558         return real_identical (&c, &cint);
6559       }
6560       break;
6561
6562     case NOP_EXPR:
6563       {
6564         tree type = TREE_TYPE (TREE_OPERAND (t, 0));
6565         if (TREE_CODE (type) == INTEGER_TYPE)
6566           return true;
6567         if (TREE_CODE (type) == REAL_TYPE)
6568           return integer_valued_real_p (TREE_OPERAND (t, 0));
6569         break;
6570       }
6571
6572     case CALL_EXPR:
6573       switch (builtin_mathfn_code (t))
6574         {
6575         CASE_FLT_FN (BUILT_IN_CEIL):
6576         CASE_FLT_FN (BUILT_IN_FLOOR):
6577         CASE_FLT_FN (BUILT_IN_NEARBYINT):
6578         CASE_FLT_FN (BUILT_IN_RINT):
6579         CASE_FLT_FN (BUILT_IN_ROUND):
6580         CASE_FLT_FN (BUILT_IN_TRUNC):
6581           return true;
6582
6583         default:
6584           break;
6585         }
6586       break;
6587
6588     default:
6589       break;
6590     }
6591   return false;
6592 }
6593
6594 /* EXP is assumed to be builtin call where truncation can be propagated
6595    across (for instance floor((double)f) == (double)floorf (f).
6596    Do the transformation.  */
6597
6598 static tree
6599 fold_trunc_transparent_mathfn (tree fndecl, tree arglist)
6600 {
6601   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
6602   tree arg;
6603
6604   if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6605     return 0;
6606
6607   arg = TREE_VALUE (arglist);
6608   /* Integer rounding functions are idempotent.  */
6609   if (fcode == builtin_mathfn_code (arg))
6610     return arg;
6611
6612   /* If argument is already integer valued, and we don't need to worry
6613      about setting errno, there's no need to perform rounding.  */
6614   if (! flag_errno_math && integer_valued_real_p (arg))
6615     return arg;
6616
6617   if (optimize)
6618     {
6619       tree arg0 = strip_float_extensions (arg);
6620       tree ftype = TREE_TYPE (TREE_TYPE (fndecl));
6621       tree newtype = TREE_TYPE (arg0);
6622       tree decl;
6623
6624       if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
6625           && (decl = mathfn_built_in (newtype, fcode)))
6626         {
6627           arglist =
6628             build_tree_list (NULL_TREE, fold_convert (newtype, arg0));
6629           return fold_convert (ftype,
6630                                build_function_call_expr (decl, arglist));
6631         }
6632     }
6633   return 0;
6634 }
6635
6636 /* EXP is assumed to be builtin call which can narrow the FP type of
6637    the argument, for instance lround((double)f) -> lroundf (f).  */
6638
6639 static tree
6640 fold_fixed_mathfn (tree fndecl, tree arglist)
6641 {
6642   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
6643   tree arg;
6644
6645   if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6646     return 0;
6647
6648   arg = TREE_VALUE (arglist);
6649
6650   /* If argument is already integer valued, and we don't need to worry
6651      about setting errno, there's no need to perform rounding.  */
6652   if (! flag_errno_math && integer_valued_real_p (arg))
6653     return fold_build1 (FIX_TRUNC_EXPR, TREE_TYPE (TREE_TYPE (fndecl)), arg);
6654
6655   if (optimize)
6656     {
6657       tree ftype = TREE_TYPE (arg);
6658       tree arg0 = strip_float_extensions (arg);
6659       tree newtype = TREE_TYPE (arg0);
6660       tree decl;
6661
6662       if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
6663           && (decl = mathfn_built_in (newtype, fcode)))
6664         {
6665           arglist =
6666             build_tree_list (NULL_TREE, fold_convert (newtype, arg0));
6667           return build_function_call_expr (decl, arglist);
6668         }
6669     }
6670   return 0;
6671 }
6672
6673 /* Fold function call to builtin cabs, cabsf or cabsl.  ARGLIST
6674    is the argument list and TYPE is the return type.  Return
6675    NULL_TREE if no if no simplification can be made.  */
6676
6677 static tree
6678 fold_builtin_cabs (tree arglist, tree type)
6679 {
6680   tree arg;
6681
6682   if (!arglist || TREE_CHAIN (arglist))
6683     return NULL_TREE;
6684
6685   arg = TREE_VALUE (arglist);
6686   if (TREE_CODE (TREE_TYPE (arg)) != COMPLEX_TYPE
6687       || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) != REAL_TYPE)
6688     return NULL_TREE;
6689
6690   /* Evaluate cabs of a constant at compile-time.  */
6691   if (flag_unsafe_math_optimizations
6692       && TREE_CODE (arg) == COMPLEX_CST
6693       && TREE_CODE (TREE_REALPART (arg)) == REAL_CST
6694       && TREE_CODE (TREE_IMAGPART (arg)) == REAL_CST
6695       && ! TREE_CONSTANT_OVERFLOW (TREE_REALPART (arg))
6696       && ! TREE_CONSTANT_OVERFLOW (TREE_IMAGPART (arg)))
6697     {
6698       REAL_VALUE_TYPE r, i;
6699
6700       r = TREE_REAL_CST (TREE_REALPART (arg));
6701       i = TREE_REAL_CST (TREE_IMAGPART (arg));
6702
6703       real_arithmetic (&r, MULT_EXPR, &r, &r);
6704       real_arithmetic (&i, MULT_EXPR, &i, &i);
6705       real_arithmetic (&r, PLUS_EXPR, &r, &i);
6706       if (real_sqrt (&r, TYPE_MODE (type), &r)
6707           || ! flag_trapping_math)
6708         return build_real (type, r);
6709     }
6710
6711   /* If either part is zero, cabs is fabs of the other.  */
6712   if (TREE_CODE (arg) == COMPLEX_EXPR
6713       && real_zerop (TREE_OPERAND (arg, 0)))
6714     return fold_build1 (ABS_EXPR, type, TREE_OPERAND (arg, 1));
6715   if (TREE_CODE (arg) == COMPLEX_EXPR
6716       && real_zerop (TREE_OPERAND (arg, 1)))
6717     return fold_build1 (ABS_EXPR, type, TREE_OPERAND (arg, 0));
6718
6719   /* Don't do this when optimizing for size.  */
6720   if (flag_unsafe_math_optimizations
6721       && optimize && !optimize_size)
6722     {
6723       tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
6724
6725       if (sqrtfn != NULL_TREE)
6726         {
6727           tree rpart, ipart, result, arglist;
6728
6729           arg = builtin_save_expr (arg);
6730
6731           rpart = fold_build1 (REALPART_EXPR, type, arg);
6732           ipart = fold_build1 (IMAGPART_EXPR, type, arg);
6733
6734           rpart = builtin_save_expr (rpart);
6735           ipart = builtin_save_expr (ipart);
6736
6737           result = fold_build2 (PLUS_EXPR, type,
6738                                 fold_build2 (MULT_EXPR, type,
6739                                              rpart, rpart),
6740                                 fold_build2 (MULT_EXPR, type,
6741                                              ipart, ipart));
6742
6743           arglist = build_tree_list (NULL_TREE, result);
6744           return build_function_call_expr (sqrtfn, arglist);
6745         }
6746     }
6747
6748   return NULL_TREE;
6749 }
6750
6751 /* Fold a builtin function call to sqrt, sqrtf, or sqrtl.  Return
6752    NULL_TREE if no simplification can be made.  */
6753
6754 static tree
6755 fold_builtin_sqrt (tree arglist, tree type)
6756 {
6757
6758   enum built_in_function fcode;
6759   tree arg = TREE_VALUE (arglist);
6760
6761   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6762     return NULL_TREE;
6763
6764   /* Optimize sqrt of constant value.  */
6765   if (TREE_CODE (arg) == REAL_CST
6766       && ! TREE_CONSTANT_OVERFLOW (arg))
6767     {
6768       REAL_VALUE_TYPE r, x;
6769
6770       x = TREE_REAL_CST (arg);
6771       if (real_sqrt (&r, TYPE_MODE (type), &x)
6772           || (!flag_trapping_math && !flag_errno_math))
6773         return build_real (type, r);
6774     }
6775
6776   /* Optimize sqrt(expN(x)) = expN(x*0.5).  */
6777   fcode = builtin_mathfn_code (arg);
6778   if (flag_unsafe_math_optimizations && BUILTIN_EXPONENT_P (fcode))
6779     {
6780       tree expfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
6781       arg = fold_build2 (MULT_EXPR, type,
6782                          TREE_VALUE (TREE_OPERAND (arg, 1)),
6783                          build_real (type, dconsthalf));
6784       arglist = build_tree_list (NULL_TREE, arg);
6785       return build_function_call_expr (expfn, arglist);
6786     }
6787
6788   /* Optimize sqrt(Nroot(x)) -> pow(x,1/(2*N)).  */
6789   if (flag_unsafe_math_optimizations && BUILTIN_ROOT_P (fcode))
6790     {
6791       tree powfn = mathfn_built_in (type, BUILT_IN_POW);
6792
6793       if (powfn)
6794         {
6795           tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
6796           tree tree_root;
6797           /* The inner root was either sqrt or cbrt.  */
6798           REAL_VALUE_TYPE dconstroot =
6799             BUILTIN_SQRT_P (fcode) ? dconsthalf : dconstthird;
6800
6801           /* Adjust for the outer root.  */
6802           SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
6803           dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
6804           tree_root = build_real (type, dconstroot);
6805           arglist = tree_cons (NULL_TREE, arg0,
6806                                build_tree_list (NULL_TREE, tree_root));
6807           return build_function_call_expr (powfn, arglist);
6808         }
6809     }
6810
6811   /* Optimize sqrt(pow(x,y)) = pow(|x|,y*0.5).  */
6812   if (flag_unsafe_math_optimizations
6813       && (fcode == BUILT_IN_POW
6814           || fcode == BUILT_IN_POWF
6815           || fcode == BUILT_IN_POWL))
6816     {
6817       tree powfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
6818       tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
6819       tree arg1 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
6820       tree narg1;
6821       if (!tree_expr_nonnegative_p (arg0))
6822         arg0 = build1 (ABS_EXPR, type, arg0);
6823       narg1 = fold_build2 (MULT_EXPR, type, arg1,
6824                            build_real (type, dconsthalf));
6825       arglist = tree_cons (NULL_TREE, arg0,
6826                            build_tree_list (NULL_TREE, narg1));
6827       return build_function_call_expr (powfn, arglist);
6828     }
6829
6830   return NULL_TREE;
6831 }
6832
6833 /* Fold a builtin function call to cbrt, cbrtf, or cbrtl.  Return
6834    NULL_TREE if no simplification can be made.  */
6835 static tree
6836 fold_builtin_cbrt (tree arglist, tree type)
6837 {
6838   tree arg = TREE_VALUE (arglist);
6839   const enum built_in_function fcode = builtin_mathfn_code (arg);
6840
6841   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6842     return NULL_TREE;
6843
6844   /* Optimize cbrt of constant value.  */
6845   if (real_zerop (arg) || real_onep (arg) || real_minus_onep (arg))
6846     return arg;
6847
6848   if (flag_unsafe_math_optimizations)
6849     {
6850       /* Optimize cbrt(expN(x)) -> expN(x/3).  */
6851       if (BUILTIN_EXPONENT_P (fcode))
6852         {
6853           tree expfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
6854           const REAL_VALUE_TYPE third_trunc =
6855             real_value_truncate (TYPE_MODE (type), dconstthird);
6856           arg = fold_build2 (MULT_EXPR, type,
6857                              TREE_VALUE (TREE_OPERAND (arg, 1)),
6858                              build_real (type, third_trunc));
6859           arglist = build_tree_list (NULL_TREE, arg);
6860           return build_function_call_expr (expfn, arglist);
6861         }
6862
6863       /* Optimize cbrt(sqrt(x)) -> pow(x,1/6).  */
6864       if (BUILTIN_SQRT_P (fcode))
6865         {
6866           tree powfn = mathfn_built_in (type, BUILT_IN_POW);
6867
6868           if (powfn)
6869             {
6870               tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
6871               tree tree_root;
6872               REAL_VALUE_TYPE dconstroot = dconstthird;
6873
6874               SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
6875               dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
6876               tree_root = build_real (type, dconstroot);
6877               arglist = tree_cons (NULL_TREE, arg0,
6878                                    build_tree_list (NULL_TREE, tree_root));
6879               return build_function_call_expr (powfn, arglist);
6880             }
6881         }
6882
6883       /* Optimize cbrt(cbrt(x)) -> pow(x,1/9) iff x is nonnegative.  */
6884       if (BUILTIN_CBRT_P (fcode))
6885         {
6886           tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
6887           if (tree_expr_nonnegative_p (arg0))
6888             {
6889               tree powfn = mathfn_built_in (type, BUILT_IN_POW);
6890
6891               if (powfn)
6892                 {
6893                   tree tree_root;
6894                   REAL_VALUE_TYPE dconstroot;
6895               
6896                   real_arithmetic (&dconstroot, MULT_EXPR, &dconstthird, &dconstthird);
6897                   dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
6898                   tree_root = build_real (type, dconstroot);
6899                   arglist = tree_cons (NULL_TREE, arg0,
6900                                        build_tree_list (NULL_TREE, tree_root));
6901                   return build_function_call_expr (powfn, arglist);
6902                 }
6903             }
6904         }
6905       
6906       /* Optimize cbrt(pow(x,y)) -> pow(x,y/3) iff x is nonnegative.  */
6907       if (fcode == BUILT_IN_POW || fcode == BUILT_IN_POWF
6908           || fcode == BUILT_IN_POWL)
6909         {
6910           tree arg00 = TREE_VALUE (TREE_OPERAND (arg, 1));
6911           tree arg01 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
6912           if (tree_expr_nonnegative_p (arg00))
6913             {
6914               tree powfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
6915               const REAL_VALUE_TYPE dconstroot
6916                 = real_value_truncate (TYPE_MODE (type), dconstthird);
6917               tree narg01 = fold_build2 (MULT_EXPR, type, arg01,
6918                                          build_real (type, dconstroot));
6919               arglist = tree_cons (NULL_TREE, arg00,
6920                                    build_tree_list (NULL_TREE, narg01));
6921               return build_function_call_expr (powfn, arglist);
6922             }
6923         }
6924     }
6925   return NULL_TREE;
6926 }
6927
6928 /* Fold function call to builtin sin, sinf, or sinl.  Return
6929    NULL_TREE if no simplification can be made.  */
6930 static tree
6931 fold_builtin_sin (tree arglist)
6932 {
6933   tree arg = TREE_VALUE (arglist);
6934
6935   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6936     return NULL_TREE;
6937
6938   /* Optimize sin (0.0) = 0.0.  */
6939   if (real_zerop (arg))
6940     return arg;
6941
6942   return NULL_TREE;
6943 }
6944
6945 /* Fold function call to builtin cos, cosf, or cosl.  Return
6946    NULL_TREE if no simplification can be made.  */
6947 static tree
6948 fold_builtin_cos (tree arglist, tree type, tree fndecl)
6949 {
6950   tree arg = TREE_VALUE (arglist);
6951
6952   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6953     return NULL_TREE;
6954
6955   /* Optimize cos (0.0) = 1.0.  */
6956   if (real_zerop (arg))
6957     return build_real (type, dconst1);
6958
6959   /* Optimize cos(-x) into cos (x).  */
6960   if (TREE_CODE (arg) == NEGATE_EXPR)
6961     {
6962       tree args = build_tree_list (NULL_TREE,
6963                                    TREE_OPERAND (arg, 0));
6964       return build_function_call_expr (fndecl, args);
6965     }
6966
6967   return NULL_TREE;
6968 }
6969
6970 /* Fold function call to builtin tan, tanf, or tanl.  Return
6971    NULL_TREE if no simplification can be made.  */
6972 static tree
6973 fold_builtin_tan (tree arglist)
6974 {
6975   enum built_in_function fcode;
6976   tree arg = TREE_VALUE (arglist);
6977
6978   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6979     return NULL_TREE;
6980
6981   /* Optimize tan(0.0) = 0.0.  */
6982   if (real_zerop (arg))
6983     return arg;
6984
6985   /* Optimize tan(atan(x)) = x.  */
6986   fcode = builtin_mathfn_code (arg);
6987   if (flag_unsafe_math_optimizations
6988       && (fcode == BUILT_IN_ATAN
6989           || fcode == BUILT_IN_ATANF
6990           || fcode == BUILT_IN_ATANL))
6991     return TREE_VALUE (TREE_OPERAND (arg, 1));
6992
6993   return NULL_TREE;
6994 }
6995
6996 /* Fold function call to builtin atan, atanf, or atanl.  Return
6997    NULL_TREE if no simplification can be made.  */
6998
6999 static tree
7000 fold_builtin_atan (tree arglist, tree type)
7001 {
7002
7003   tree arg = TREE_VALUE (arglist);
7004
7005   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7006     return NULL_TREE;
7007
7008   /* Optimize atan(0.0) = 0.0.  */
7009   if (real_zerop (arg))
7010     return arg;
7011
7012   /* Optimize atan(1.0) = pi/4.  */
7013   if (real_onep (arg))
7014     {
7015       REAL_VALUE_TYPE cst;
7016
7017       real_convert (&cst, TYPE_MODE (type), &dconstpi);
7018       SET_REAL_EXP (&cst, REAL_EXP (&cst) - 2);
7019       return build_real (type, cst);
7020     }
7021
7022   return NULL_TREE;
7023 }
7024
7025 /* Fold function call to builtin trunc, truncf or truncl.  Return
7026    NULL_TREE if no simplification can be made.  */
7027
7028 static tree
7029 fold_builtin_trunc (tree fndecl, tree arglist)
7030 {
7031   tree arg;
7032
7033   if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7034     return 0;
7035
7036   /* Optimize trunc of constant value.  */
7037   arg = TREE_VALUE (arglist);
7038   if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7039     {
7040       REAL_VALUE_TYPE r, x;
7041       tree type = TREE_TYPE (TREE_TYPE (fndecl));
7042
7043       x = TREE_REAL_CST (arg);
7044       real_trunc (&r, TYPE_MODE (type), &x);
7045       return build_real (type, r);
7046     }
7047
7048   return fold_trunc_transparent_mathfn (fndecl, arglist);
7049 }
7050
7051 /* Fold function call to builtin floor, floorf or floorl.  Return
7052    NULL_TREE if no simplification can be made.  */
7053
7054 static tree
7055 fold_builtin_floor (tree fndecl, tree arglist)
7056 {
7057   tree arg;
7058
7059   if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7060     return 0;
7061
7062   /* Optimize floor of constant value.  */
7063   arg = TREE_VALUE (arglist);
7064   if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7065     {
7066       REAL_VALUE_TYPE x;
7067
7068       x = TREE_REAL_CST (arg);
7069       if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7070         {
7071           tree type = TREE_TYPE (TREE_TYPE (fndecl));
7072           REAL_VALUE_TYPE r;
7073
7074           real_floor (&r, TYPE_MODE (type), &x);
7075           return build_real (type, r);
7076         }
7077     }
7078
7079   return fold_trunc_transparent_mathfn (fndecl, arglist);
7080 }
7081
7082 /* Fold function call to builtin ceil, ceilf or ceill.  Return
7083    NULL_TREE if no simplification can be made.  */
7084
7085 static tree
7086 fold_builtin_ceil (tree fndecl, tree arglist)
7087 {
7088   tree arg;
7089
7090   if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7091     return 0;
7092
7093   /* Optimize ceil of constant value.  */
7094   arg = TREE_VALUE (arglist);
7095   if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7096     {
7097       REAL_VALUE_TYPE x;
7098
7099       x = TREE_REAL_CST (arg);
7100       if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7101         {
7102           tree type = TREE_TYPE (TREE_TYPE (fndecl));
7103           REAL_VALUE_TYPE r;
7104
7105           real_ceil (&r, TYPE_MODE (type), &x);
7106           return build_real (type, r);
7107         }
7108     }
7109
7110   return fold_trunc_transparent_mathfn (fndecl, arglist);
7111 }
7112
7113 /* Fold function call to builtin round, roundf or roundl.  Return
7114    NULL_TREE if no simplification can be made.  */
7115
7116 static tree
7117 fold_builtin_round (tree fndecl, tree arglist)
7118 {
7119   tree arg;
7120
7121   if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7122     return 0;
7123
7124   /* Optimize round of constant value.  */
7125   arg = TREE_VALUE (arglist);
7126   if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7127     {
7128       REAL_VALUE_TYPE x;
7129
7130       x = TREE_REAL_CST (arg);
7131       if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7132         {
7133           tree type = TREE_TYPE (TREE_TYPE (fndecl));
7134           REAL_VALUE_TYPE r;
7135
7136           real_round (&r, TYPE_MODE (type), &x);
7137           return build_real (type, r);
7138         }
7139     }
7140
7141   return fold_trunc_transparent_mathfn (fndecl, arglist);
7142 }
7143
7144 /* Fold function call to builtin lround, lroundf or lroundl (or the
7145    corresponding long long versions) and other rounding functions.
7146    Return NULL_TREE if no simplification can be made.  */
7147
7148 static tree
7149 fold_builtin_int_roundingfn (tree fndecl, tree arglist)
7150 {
7151   tree arg;
7152
7153   if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7154     return 0;
7155
7156   /* Optimize lround of constant value.  */
7157   arg = TREE_VALUE (arglist);
7158   if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7159     {
7160       const REAL_VALUE_TYPE x = TREE_REAL_CST (arg);
7161
7162       if (! REAL_VALUE_ISNAN (x) && ! REAL_VALUE_ISINF (x))
7163         {
7164           tree itype = TREE_TYPE (TREE_TYPE (fndecl));
7165           tree ftype = TREE_TYPE (arg), result;
7166           HOST_WIDE_INT hi, lo;
7167           REAL_VALUE_TYPE r;
7168
7169           switch (DECL_FUNCTION_CODE (fndecl))
7170             {
7171             CASE_FLT_FN (BUILT_IN_LFLOOR):
7172             CASE_FLT_FN (BUILT_IN_LLFLOOR):
7173               real_floor (&r, TYPE_MODE (ftype), &x);
7174               break;
7175
7176             CASE_FLT_FN (BUILT_IN_LCEIL):
7177             CASE_FLT_FN (BUILT_IN_LLCEIL):
7178               real_ceil (&r, TYPE_MODE (ftype), &x);
7179               break;
7180
7181             CASE_FLT_FN (BUILT_IN_LROUND):
7182             CASE_FLT_FN (BUILT_IN_LLROUND):
7183               real_round (&r, TYPE_MODE (ftype), &x);
7184               break;
7185
7186             default:
7187               gcc_unreachable ();
7188             }
7189
7190           REAL_VALUE_TO_INT (&lo, &hi, r);
7191           result = build_int_cst_wide (NULL_TREE, lo, hi);
7192           if (int_fits_type_p (result, itype))
7193             return fold_convert (itype, result);
7194         }
7195     }
7196
7197   return fold_fixed_mathfn (fndecl, arglist);
7198 }
7199
7200 /* Fold function call to builtin ffs, clz, ctz, popcount and parity
7201    and their long and long long variants (i.e. ffsl and ffsll).
7202    Return NULL_TREE if no simplification can be made.  */
7203
7204 static tree
7205 fold_builtin_bitop (tree fndecl, tree arglist)
7206 {
7207   tree arg;
7208
7209   if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
7210     return NULL_TREE;
7211
7212   /* Optimize for constant argument.  */
7213   arg = TREE_VALUE (arglist);
7214   if (TREE_CODE (arg) == INTEGER_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7215     {
7216       HOST_WIDE_INT hi, width, result;
7217       unsigned HOST_WIDE_INT lo;
7218       tree type;
7219
7220       type = TREE_TYPE (arg);
7221       width = TYPE_PRECISION (type);
7222       lo = TREE_INT_CST_LOW (arg);
7223
7224       /* Clear all the bits that are beyond the type's precision.  */
7225       if (width > HOST_BITS_PER_WIDE_INT)
7226         {
7227           hi = TREE_INT_CST_HIGH (arg);
7228           if (width < 2 * HOST_BITS_PER_WIDE_INT)
7229             hi &= ~((HOST_WIDE_INT) (-1) >> (width - HOST_BITS_PER_WIDE_INT));
7230         }
7231       else
7232         {
7233           hi = 0;
7234           if (width < HOST_BITS_PER_WIDE_INT)
7235             lo &= ~((unsigned HOST_WIDE_INT) (-1) << width);
7236         }
7237
7238       switch (DECL_FUNCTION_CODE (fndecl))
7239         {
7240         CASE_INT_FN (BUILT_IN_FFS):
7241           if (lo != 0)
7242             result = exact_log2 (lo & -lo) + 1;
7243           else if (hi != 0)
7244             result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi) + 1;
7245           else
7246             result = 0;
7247           break;
7248
7249         CASE_INT_FN (BUILT_IN_CLZ):
7250           if (hi != 0)
7251             result = width - floor_log2 (hi) - 1 - HOST_BITS_PER_WIDE_INT;
7252           else if (lo != 0)
7253             result = width - floor_log2 (lo) - 1;
7254           else if (! CLZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
7255             result = width;
7256           break;
7257
7258         CASE_INT_FN (BUILT_IN_CTZ):
7259           if (lo != 0)
7260             result = exact_log2 (lo & -lo);
7261           else if (hi != 0)
7262             result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi);
7263           else if (! CTZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
7264             result = width;
7265           break;
7266
7267         CASE_INT_FN (BUILT_IN_POPCOUNT):
7268           result = 0;
7269           while (lo)
7270             result++, lo &= lo - 1;
7271           while (hi)
7272             result++, hi &= hi - 1;
7273           break;
7274
7275         CASE_INT_FN (BUILT_IN_PARITY):
7276           result = 0;
7277           while (lo)
7278             result++, lo &= lo - 1;
7279           while (hi)
7280             result++, hi &= hi - 1;
7281           result &= 1;
7282           break;
7283
7284         default:
7285           gcc_unreachable ();
7286         }
7287
7288       return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), result);
7289     }
7290
7291   return NULL_TREE;
7292 }
7293
7294 /* Return true if EXPR is the real constant contained in VALUE.  */
7295
7296 static bool
7297 real_dconstp (tree expr, const REAL_VALUE_TYPE *value)
7298 {
7299   STRIP_NOPS (expr);
7300
7301   return ((TREE_CODE (expr) == REAL_CST
7302            && ! TREE_CONSTANT_OVERFLOW (expr)
7303            && REAL_VALUES_EQUAL (TREE_REAL_CST (expr), *value))
7304           || (TREE_CODE (expr) == COMPLEX_CST
7305               && real_dconstp (TREE_REALPART (expr), value)
7306               && real_zerop (TREE_IMAGPART (expr))));
7307 }
7308
7309 /* A subroutine of fold_builtin to fold the various logarithmic
7310    functions.  EXP is the CALL_EXPR of a call to a builtin logN
7311    function.  VALUE is the base of the logN function.  */
7312
7313 static tree
7314 fold_builtin_logarithm (tree fndecl, tree arglist,
7315                         const REAL_VALUE_TYPE *value)
7316 {
7317   if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7318     {
7319       tree type = TREE_TYPE (TREE_TYPE (fndecl));
7320       tree arg = TREE_VALUE (arglist);
7321       const enum built_in_function fcode = builtin_mathfn_code (arg);
7322
7323       /* Optimize logN(1.0) = 0.0.  */
7324       if (real_onep (arg))
7325         return build_real (type, dconst0);
7326
7327       /* Optimize logN(N) = 1.0.  If N can't be truncated to MODE
7328          exactly, then only do this if flag_unsafe_math_optimizations.  */
7329       if (exact_real_truncate (TYPE_MODE (type), value)
7330           || flag_unsafe_math_optimizations)
7331         {
7332           const REAL_VALUE_TYPE value_truncate =
7333             real_value_truncate (TYPE_MODE (type), *value);
7334           if (real_dconstp (arg, &value_truncate))
7335             return build_real (type, dconst1);
7336         }
7337
7338       /* Special case, optimize logN(expN(x)) = x.  */
7339       if (flag_unsafe_math_optimizations
7340           && ((value == &dconste
7341                && (fcode == BUILT_IN_EXP
7342                    || fcode == BUILT_IN_EXPF
7343                    || fcode == BUILT_IN_EXPL))
7344               || (value == &dconst2
7345                   && (fcode == BUILT_IN_EXP2
7346                       || fcode == BUILT_IN_EXP2F
7347                       || fcode == BUILT_IN_EXP2L))
7348               || (value == &dconst10 && (BUILTIN_EXP10_P (fcode)))))
7349         return fold_convert (type, TREE_VALUE (TREE_OPERAND (arg, 1)));
7350
7351       /* Optimize logN(func()) for various exponential functions.  We
7352          want to determine the value "x" and the power "exponent" in
7353          order to transform logN(x**exponent) into exponent*logN(x).  */
7354       if (flag_unsafe_math_optimizations)
7355         {
7356           tree exponent = 0, x = 0;
7357
7358           switch (fcode)
7359           {
7360           CASE_FLT_FN (BUILT_IN_EXP):
7361             /* Prepare to do logN(exp(exponent) -> exponent*logN(e).  */
7362             x = build_real (type,
7363                             real_value_truncate (TYPE_MODE (type), dconste));
7364             exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
7365             break;
7366           CASE_FLT_FN (BUILT_IN_EXP2):
7367             /* Prepare to do logN(exp2(exponent) -> exponent*logN(2).  */
7368             x = build_real (type, dconst2);
7369             exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
7370             break;
7371           CASE_FLT_FN (BUILT_IN_EXP10):
7372           CASE_FLT_FN (BUILT_IN_POW10):
7373             /* Prepare to do logN(exp10(exponent) -> exponent*logN(10).  */
7374             x = build_real (type, dconst10);
7375             exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
7376             break;
7377           CASE_FLT_FN (BUILT_IN_SQRT):
7378             /* Prepare to do logN(sqrt(x) -> 0.5*logN(x).  */
7379             x = TREE_VALUE (TREE_OPERAND (arg, 1));
7380             exponent = build_real (type, dconsthalf);
7381             break;
7382           CASE_FLT_FN (BUILT_IN_CBRT):
7383             /* Prepare to do logN(cbrt(x) -> (1/3)*logN(x).  */
7384             x = TREE_VALUE (TREE_OPERAND (arg, 1));
7385             exponent = build_real (type, real_value_truncate (TYPE_MODE (type),
7386                                                               dconstthird));
7387             break;
7388           CASE_FLT_FN (BUILT_IN_POW):
7389             /* Prepare to do logN(pow(x,exponent) -> exponent*logN(x).  */
7390             x = TREE_VALUE (TREE_OPERAND (arg, 1));
7391             exponent = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
7392             break;
7393           default:
7394             break;
7395           }
7396
7397           /* Now perform the optimization.  */
7398           if (x && exponent)
7399             {
7400               tree logfn;
7401               arglist = build_tree_list (NULL_TREE, x);
7402               logfn = build_function_call_expr (fndecl, arglist);
7403               return fold_build2 (MULT_EXPR, type, exponent, logfn);
7404             }
7405         }
7406     }
7407
7408   return 0;
7409 }
7410
7411 /* Fold a builtin function call to pow, powf, or powl.  Return
7412    NULL_TREE if no simplification can be made.  */
7413 static tree
7414 fold_builtin_pow (tree fndecl, tree arglist, tree type)
7415 {
7416   tree arg0 = TREE_VALUE (arglist);
7417   tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7418
7419   if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
7420     return NULL_TREE;
7421
7422   /* Optimize pow(1.0,y) = 1.0.  */
7423   if (real_onep (arg0))
7424     return omit_one_operand (type, build_real (type, dconst1), arg1);
7425
7426   if (TREE_CODE (arg1) == REAL_CST
7427       && ! TREE_CONSTANT_OVERFLOW (arg1))
7428     {
7429       REAL_VALUE_TYPE cint;
7430       REAL_VALUE_TYPE c;
7431       HOST_WIDE_INT n;
7432
7433       c = TREE_REAL_CST (arg1);
7434
7435       /* Optimize pow(x,0.0) = 1.0.  */
7436       if (REAL_VALUES_EQUAL (c, dconst0))
7437         return omit_one_operand (type, build_real (type, dconst1),
7438                                  arg0);
7439
7440       /* Optimize pow(x,1.0) = x.  */
7441       if (REAL_VALUES_EQUAL (c, dconst1))
7442         return arg0;
7443
7444       /* Optimize pow(x,-1.0) = 1.0/x.  */
7445       if (REAL_VALUES_EQUAL (c, dconstm1))
7446         return fold_build2 (RDIV_EXPR, type,
7447                             build_real (type, dconst1), arg0);
7448
7449       /* Optimize pow(x,0.5) = sqrt(x).  */
7450       if (flag_unsafe_math_optimizations
7451           && REAL_VALUES_EQUAL (c, dconsthalf))
7452         {
7453           tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
7454
7455           if (sqrtfn != NULL_TREE)
7456             {
7457               tree arglist = build_tree_list (NULL_TREE, arg0);
7458               return build_function_call_expr (sqrtfn, arglist);
7459             }
7460         }
7461
7462       /* Check for an integer exponent.  */
7463       n = real_to_integer (&c);
7464       real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
7465       if (real_identical (&c, &cint))
7466         {
7467           /* Attempt to evaluate pow at compile-time.  */
7468           if (TREE_CODE (arg0) == REAL_CST
7469               && ! TREE_CONSTANT_OVERFLOW (arg0))
7470             {
7471               REAL_VALUE_TYPE x;
7472               bool inexact;
7473
7474               x = TREE_REAL_CST (arg0);
7475               inexact = real_powi (&x, TYPE_MODE (type), &x, n);
7476               if (flag_unsafe_math_optimizations || !inexact)
7477                 return build_real (type, x);
7478             }
7479
7480           /* Strip sign ops from even integer powers.  */
7481           if ((n & 1) == 0 && flag_unsafe_math_optimizations)
7482             {
7483               tree narg0 = fold_strip_sign_ops (arg0);
7484               if (narg0)
7485                 {
7486                   arglist = build_tree_list (NULL_TREE, arg1);
7487                   arglist = tree_cons (NULL_TREE, narg0, arglist);
7488                   return build_function_call_expr (fndecl, arglist);
7489                 }
7490             }
7491         }
7492     }
7493
7494   if (flag_unsafe_math_optimizations)
7495     {
7496       const enum built_in_function fcode = builtin_mathfn_code (arg0);
7497
7498       /* Optimize pow(expN(x),y) = expN(x*y).  */
7499       if (BUILTIN_EXPONENT_P (fcode))
7500         {
7501           tree expfn = TREE_OPERAND (TREE_OPERAND (arg0, 0), 0);
7502           tree arg = TREE_VALUE (TREE_OPERAND (arg0, 1));
7503           arg = fold_build2 (MULT_EXPR, type, arg, arg1);
7504           arglist = build_tree_list (NULL_TREE, arg);
7505           return build_function_call_expr (expfn, arglist);
7506         }
7507
7508       /* Optimize pow(sqrt(x),y) = pow(x,y*0.5).  */
7509       if (BUILTIN_SQRT_P (fcode))
7510         {
7511           tree narg0 = TREE_VALUE (TREE_OPERAND (arg0, 1));
7512           tree narg1 = fold_build2 (MULT_EXPR, type, arg1,
7513                                     build_real (type, dconsthalf));
7514
7515           arglist = tree_cons (NULL_TREE, narg0,
7516                                build_tree_list (NULL_TREE, narg1));
7517           return build_function_call_expr (fndecl, arglist);
7518         }
7519
7520       /* Optimize pow(cbrt(x),y) = pow(x,y/3) iff x is nonnegative.  */
7521       if (BUILTIN_CBRT_P (fcode))
7522         {
7523           tree arg = TREE_VALUE (TREE_OPERAND (arg0, 1));
7524           if (tree_expr_nonnegative_p (arg))
7525             {
7526               const REAL_VALUE_TYPE dconstroot
7527                 = real_value_truncate (TYPE_MODE (type), dconstthird);
7528               tree narg1 = fold_build2 (MULT_EXPR, type, arg1,
7529                                         build_real (type, dconstroot));
7530               arglist = tree_cons (NULL_TREE, arg,
7531                                    build_tree_list (NULL_TREE, narg1));
7532               return build_function_call_expr (fndecl, arglist);
7533             }
7534         }
7535       
7536       /* Optimize pow(pow(x,y),z) = pow(x,y*z).  */
7537       if (fcode == BUILT_IN_POW || fcode == BUILT_IN_POWF
7538            || fcode == BUILT_IN_POWL)
7539         {
7540           tree arg00 = TREE_VALUE (TREE_OPERAND (arg0, 1));
7541           tree arg01 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg0, 1)));
7542           tree narg1 = fold_build2 (MULT_EXPR, type, arg01, arg1);
7543           arglist = tree_cons (NULL_TREE, arg00,
7544                                build_tree_list (NULL_TREE, narg1));
7545           return build_function_call_expr (fndecl, arglist);
7546         }
7547     }
7548
7549   return NULL_TREE;
7550 }
7551
7552 /* Fold a builtin function call to powi, powif, or powil.  Return
7553    NULL_TREE if no simplification can be made.  */
7554 static tree
7555 fold_builtin_powi (tree fndecl ATTRIBUTE_UNUSED, tree arglist, tree type)
7556 {
7557   tree arg0 = TREE_VALUE (arglist);
7558   tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7559
7560   if (!validate_arglist (arglist, REAL_TYPE, INTEGER_TYPE, VOID_TYPE))
7561     return NULL_TREE;
7562
7563   /* Optimize pow(1.0,y) = 1.0.  */
7564   if (real_onep (arg0))
7565     return omit_one_operand (type, build_real (type, dconst1), arg1);
7566
7567   if (host_integerp (arg1, 0))
7568     {
7569       HOST_WIDE_INT c = TREE_INT_CST_LOW (arg1);
7570
7571       /* Evaluate powi at compile-time.  */
7572       if (TREE_CODE (arg0) == REAL_CST
7573           && ! TREE_CONSTANT_OVERFLOW (arg0))
7574         {
7575           REAL_VALUE_TYPE x;
7576           x = TREE_REAL_CST (arg0);
7577           real_powi (&x, TYPE_MODE (type), &x, c);
7578           return build_real (type, x);
7579         }
7580
7581       /* Optimize pow(x,0) = 1.0.  */
7582       if (c == 0)
7583         return omit_one_operand (type, build_real (type, dconst1),
7584                                  arg0);
7585
7586       /* Optimize pow(x,1) = x.  */
7587       if (c == 1)
7588         return arg0;
7589
7590       /* Optimize pow(x,-1) = 1.0/x.  */
7591       if (c == -1)
7592         return fold_build2 (RDIV_EXPR, type,
7593                            build_real (type, dconst1), arg0);
7594     }
7595
7596   return NULL_TREE;
7597 }
7598
7599 /* A subroutine of fold_builtin to fold the various exponent
7600    functions.  EXP is the CALL_EXPR of a call to a builtin function.
7601    VALUE is the value which will be raised to a power.  */
7602
7603 static tree
7604 fold_builtin_exponent (tree fndecl, tree arglist,
7605                        const REAL_VALUE_TYPE *value)
7606 {
7607   if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7608     {
7609       tree type = TREE_TYPE (TREE_TYPE (fndecl));
7610       tree arg = TREE_VALUE (arglist);
7611
7612       /* Optimize exp*(0.0) = 1.0.  */
7613       if (real_zerop (arg))
7614         return build_real (type, dconst1);
7615
7616       /* Optimize expN(1.0) = N.  */
7617       if (real_onep (arg))
7618         {
7619           REAL_VALUE_TYPE cst;
7620
7621           real_convert (&cst, TYPE_MODE (type), value);
7622           return build_real (type, cst);
7623         }
7624
7625       /* Attempt to evaluate expN(integer) at compile-time.  */
7626       if (flag_unsafe_math_optimizations
7627           && TREE_CODE (arg) == REAL_CST
7628           && ! TREE_CONSTANT_OVERFLOW (arg))
7629         {
7630           REAL_VALUE_TYPE cint;
7631           REAL_VALUE_TYPE c;
7632           HOST_WIDE_INT n;
7633
7634           c = TREE_REAL_CST (arg);
7635           n = real_to_integer (&c);
7636           real_from_integer (&cint, VOIDmode, n,
7637                              n < 0 ? -1 : 0, 0);
7638           if (real_identical (&c, &cint))
7639             {
7640               REAL_VALUE_TYPE x;
7641
7642               real_powi (&x, TYPE_MODE (type), value, n);
7643               return build_real (type, x);
7644             }
7645         }
7646
7647       /* Optimize expN(logN(x)) = x.  */
7648       if (flag_unsafe_math_optimizations)
7649         {
7650           const enum built_in_function fcode = builtin_mathfn_code (arg);
7651
7652           if ((value == &dconste
7653                && (fcode == BUILT_IN_LOG
7654                    || fcode == BUILT_IN_LOGF
7655                    || fcode == BUILT_IN_LOGL))
7656               || (value == &dconst2
7657                   && (fcode == BUILT_IN_LOG2
7658                       || fcode == BUILT_IN_LOG2F
7659                       || fcode == BUILT_IN_LOG2L))
7660               || (value == &dconst10
7661                   && (fcode == BUILT_IN_LOG10
7662                       || fcode == BUILT_IN_LOG10F
7663                       || fcode == BUILT_IN_LOG10L)))
7664             return fold_convert (type, TREE_VALUE (TREE_OPERAND (arg, 1)));
7665         }
7666     }
7667
7668   return 0;
7669 }
7670
7671 /* Fold function call to builtin memcpy.  Return
7672    NULL_TREE if no simplification can be made.  */
7673
7674 static tree
7675 fold_builtin_memcpy (tree fndecl, tree arglist)
7676 {
7677   tree dest, src, len;
7678
7679   if (!validate_arglist (arglist,
7680                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7681     return 0;
7682
7683   dest = TREE_VALUE (arglist);
7684   src = TREE_VALUE (TREE_CHAIN (arglist));
7685   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7686
7687   /* If the LEN parameter is zero, return DEST.  */
7688   if (integer_zerop (len))
7689     return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
7690
7691   /* If SRC and DEST are the same (and not volatile), return DEST.  */
7692   if (operand_equal_p (src, dest, 0))
7693     return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, len);
7694
7695   return 0;
7696 }
7697
7698 /* Fold function call to builtin mempcpy.  Return
7699    NULL_TREE if no simplification can be made.  */
7700
7701 static tree
7702 fold_builtin_mempcpy (tree arglist, tree type, int endp)
7703 {
7704   if (validate_arglist (arglist,
7705                         POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7706     {
7707       tree dest = TREE_VALUE (arglist);
7708       tree src = TREE_VALUE (TREE_CHAIN (arglist));
7709       tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7710
7711       /* If the LEN parameter is zero, return DEST.  */
7712       if (integer_zerop (len))
7713         return omit_one_operand (type, dest, src);
7714
7715       /* If SRC and DEST are the same (and not volatile), return DEST+LEN.  */
7716       if (operand_equal_p (src, dest, 0))
7717         {
7718           if (endp == 0)
7719             return omit_one_operand (type, dest, len);
7720
7721           if (endp == 2)
7722             len = fold_build2 (MINUS_EXPR, TREE_TYPE (len), len,
7723                                ssize_int (1));
7724       
7725           len = fold_convert (TREE_TYPE (dest), len);
7726           len = fold_build2 (PLUS_EXPR, TREE_TYPE (dest), dest, len);
7727           return fold_convert (type, len);
7728         }
7729     }
7730   return 0;
7731 }
7732
7733 /* Fold function call to builtin memmove.  Return
7734    NULL_TREE if no simplification can be made.  */
7735
7736 static tree
7737 fold_builtin_memmove (tree arglist, tree type)
7738 {
7739   tree dest, src, len;
7740
7741   if (!validate_arglist (arglist,
7742                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7743     return 0;
7744
7745   dest = TREE_VALUE (arglist);
7746   src = TREE_VALUE (TREE_CHAIN (arglist));
7747   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7748
7749   /* If the LEN parameter is zero, return DEST.  */
7750   if (integer_zerop (len))
7751     return omit_one_operand (type, dest, src);
7752
7753   /* If SRC and DEST are the same (and not volatile), return DEST.  */
7754   if (operand_equal_p (src, dest, 0))
7755     return omit_one_operand (type, dest, len);
7756
7757   return 0;
7758 }
7759
7760 /* Fold function call to builtin strcpy.  If LEN is not NULL, it represents
7761    the length of the string to be copied.  Return NULL_TREE if no
7762    simplification can be made.  */
7763
7764 tree
7765 fold_builtin_strcpy (tree fndecl, tree arglist, tree len)
7766 {
7767   tree dest, src, fn;
7768
7769   if (!validate_arglist (arglist,
7770                          POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
7771     return 0;
7772
7773   dest = TREE_VALUE (arglist);
7774   src = TREE_VALUE (TREE_CHAIN (arglist));
7775
7776   /* If SRC and DEST are the same (and not volatile), return DEST.  */
7777   if (operand_equal_p (src, dest, 0))
7778     return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), dest);
7779
7780   if (optimize_size)
7781     return 0;
7782
7783   fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
7784   if (!fn)
7785     return 0;
7786
7787   if (!len)
7788     {
7789       len = c_strlen (src, 1);
7790       if (! len || TREE_SIDE_EFFECTS (len))
7791         return 0;
7792     }
7793
7794   len = size_binop (PLUS_EXPR, len, ssize_int (1));
7795   arglist = build_tree_list (NULL_TREE, len);
7796   arglist = tree_cons (NULL_TREE, src, arglist);
7797   arglist = tree_cons (NULL_TREE, dest, arglist);
7798   return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)),
7799                        build_function_call_expr (fn, arglist));
7800 }
7801
7802 /* Fold function call to builtin strncpy.  If SLEN is not NULL, it represents
7803    the length of the source string.  Return NULL_TREE if no simplification
7804    can be made.  */
7805
7806 tree
7807 fold_builtin_strncpy (tree fndecl, tree arglist, tree slen)
7808 {
7809   tree dest, src, len, fn;
7810
7811   if (!validate_arglist (arglist,
7812                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7813     return 0;
7814
7815   dest = TREE_VALUE (arglist);
7816   src = TREE_VALUE (TREE_CHAIN (arglist));
7817   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7818
7819   /* If the LEN parameter is zero, return DEST.  */
7820   if (integer_zerop (len))
7821     return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
7822
7823   /* We can't compare slen with len as constants below if len is not a
7824      constant.  */
7825   if (len == 0 || TREE_CODE (len) != INTEGER_CST)
7826     return 0;
7827
7828   if (!slen)
7829     slen = c_strlen (src, 1);
7830
7831   /* Now, we must be passed a constant src ptr parameter.  */
7832   if (slen == 0 || TREE_CODE (slen) != INTEGER_CST)
7833     return 0;
7834
7835   slen = size_binop (PLUS_EXPR, slen, ssize_int (1));
7836
7837   /* We do not support simplification of this case, though we do
7838      support it when expanding trees into RTL.  */
7839   /* FIXME: generate a call to __builtin_memset.  */
7840   if (tree_int_cst_lt (slen, len))
7841     return 0;
7842
7843   /* OK transform into builtin memcpy.  */
7844   fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
7845   if (!fn)
7846     return 0;
7847   return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)),
7848                        build_function_call_expr (fn, arglist));
7849 }
7850
7851 /* Fold function call to builtin memcmp.  Return
7852    NULL_TREE if no simplification can be made.  */
7853
7854 static tree
7855 fold_builtin_memcmp (tree arglist)
7856 {
7857   tree arg1, arg2, len;
7858   const char *p1, *p2;
7859
7860   if (!validate_arglist (arglist,
7861                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7862     return 0;
7863
7864   arg1 = TREE_VALUE (arglist);
7865   arg2 = TREE_VALUE (TREE_CHAIN (arglist));
7866   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7867
7868   /* If the LEN parameter is zero, return zero.  */
7869   if (integer_zerop (len))
7870     return omit_two_operands (integer_type_node, integer_zero_node,
7871                               arg1, arg2);
7872
7873   /* If ARG1 and ARG2 are the same (and not volatile), return zero.  */
7874   if (operand_equal_p (arg1, arg2, 0))
7875     return omit_one_operand (integer_type_node, integer_zero_node, len);
7876
7877   p1 = c_getstr (arg1);
7878   p2 = c_getstr (arg2);
7879
7880   /* If all arguments are constant, and the value of len is not greater
7881      than the lengths of arg1 and arg2, evaluate at compile-time.  */
7882   if (host_integerp (len, 1) && p1 && p2
7883       && compare_tree_int (len, strlen (p1) + 1) <= 0
7884       && compare_tree_int (len, strlen (p2) + 1) <= 0)
7885     {
7886       const int r = memcmp (p1, p2, tree_low_cst (len, 1));
7887
7888       if (r > 0)
7889         return integer_one_node;
7890       else if (r < 0)
7891         return integer_minus_one_node;
7892       else
7893         return integer_zero_node;
7894     }
7895
7896   /* If len parameter is one, return an expression corresponding to
7897      (*(const unsigned char*)arg1 - (const unsigned char*)arg2).  */
7898   if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
7899     {
7900       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
7901       tree cst_uchar_ptr_node
7902         = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
7903
7904       tree ind1 = fold_convert (integer_type_node,
7905                                 build1 (INDIRECT_REF, cst_uchar_node,
7906                                         fold_convert (cst_uchar_ptr_node,
7907                                                       arg1)));
7908       tree ind2 = fold_convert (integer_type_node,
7909                                 build1 (INDIRECT_REF, cst_uchar_node,
7910                                         fold_convert (cst_uchar_ptr_node,
7911                                                       arg2)));
7912       return fold_build2 (MINUS_EXPR, integer_type_node, ind1, ind2);
7913     }
7914
7915   return 0;
7916 }
7917
7918 /* Fold function call to builtin strcmp.  Return
7919    NULL_TREE if no simplification can be made.  */
7920
7921 static tree
7922 fold_builtin_strcmp (tree arglist)
7923 {
7924   tree arg1, arg2;
7925   const char *p1, *p2;
7926
7927   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
7928     return 0;
7929
7930   arg1 = TREE_VALUE (arglist);
7931   arg2 = TREE_VALUE (TREE_CHAIN (arglist));
7932
7933   /* If ARG1 and ARG2 are the same (and not volatile), return zero.  */
7934   if (operand_equal_p (arg1, arg2, 0))
7935     return integer_zero_node;
7936
7937   p1 = c_getstr (arg1);
7938   p2 = c_getstr (arg2);
7939
7940   if (p1 && p2)
7941     {
7942       const int i = strcmp (p1, p2);
7943       if (i < 0)
7944         return integer_minus_one_node;
7945       else if (i > 0)
7946         return integer_one_node;
7947       else
7948         return integer_zero_node;
7949     }
7950
7951   /* If the second arg is "", return *(const unsigned char*)arg1.  */
7952   if (p2 && *p2 == '\0')
7953     {
7954       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
7955       tree cst_uchar_ptr_node
7956         = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
7957
7958       return fold_convert (integer_type_node,
7959                            build1 (INDIRECT_REF, cst_uchar_node,
7960                                    fold_convert (cst_uchar_ptr_node,
7961                                                  arg1)));
7962     }
7963
7964   /* If the first arg is "", return -*(const unsigned char*)arg2.  */
7965   if (p1 && *p1 == '\0')
7966     {
7967       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
7968       tree cst_uchar_ptr_node
7969         = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
7970
7971       tree temp = fold_convert (integer_type_node,
7972                                 build1 (INDIRECT_REF, cst_uchar_node,
7973                                         fold_convert (cst_uchar_ptr_node,
7974                                                       arg2)));
7975       return fold_build1 (NEGATE_EXPR, integer_type_node, temp);
7976     }
7977
7978   return 0;
7979 }
7980
7981 /* Fold function call to builtin strncmp.  Return
7982    NULL_TREE if no simplification can be made.  */
7983
7984 static tree
7985 fold_builtin_strncmp (tree arglist)
7986 {
7987   tree arg1, arg2, len;
7988   const char *p1, *p2;
7989
7990   if (!validate_arglist (arglist,
7991                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7992     return 0;
7993
7994   arg1 = TREE_VALUE (arglist);
7995   arg2 = TREE_VALUE (TREE_CHAIN (arglist));
7996   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7997
7998   /* If the LEN parameter is zero, return zero.  */
7999   if (integer_zerop (len))
8000     return omit_two_operands (integer_type_node, integer_zero_node,
8001                               arg1, arg2);
8002
8003   /* If ARG1 and ARG2 are the same (and not volatile), return zero.  */
8004   if (operand_equal_p (arg1, arg2, 0))
8005     return omit_one_operand (integer_type_node, integer_zero_node, len);
8006
8007   p1 = c_getstr (arg1);
8008   p2 = c_getstr (arg2);
8009
8010   if (host_integerp (len, 1) && p1 && p2)
8011     {
8012       const int i = strncmp (p1, p2, tree_low_cst (len, 1));
8013       if (i > 0)
8014         return integer_one_node;
8015       else if (i < 0)
8016         return integer_minus_one_node;
8017       else
8018         return integer_zero_node;
8019     }
8020
8021   /* If the second arg is "", and the length is greater than zero,
8022      return *(const unsigned char*)arg1.  */
8023   if (p2 && *p2 == '\0'
8024       && TREE_CODE (len) == INTEGER_CST
8025       && tree_int_cst_sgn (len) == 1)
8026     {
8027       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8028       tree cst_uchar_ptr_node
8029         = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8030
8031       return fold_convert (integer_type_node,
8032                            build1 (INDIRECT_REF, cst_uchar_node,
8033                                    fold_convert (cst_uchar_ptr_node,
8034                                                  arg1)));
8035     }
8036
8037   /* If the first arg is "", and the length is greater than zero,
8038      return -*(const unsigned char*)arg2.  */
8039   if (p1 && *p1 == '\0'
8040       && TREE_CODE (len) == INTEGER_CST
8041       && tree_int_cst_sgn (len) == 1)
8042     {
8043       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8044       tree cst_uchar_ptr_node
8045         = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8046
8047       tree temp = fold_convert (integer_type_node,
8048                                 build1 (INDIRECT_REF, cst_uchar_node,
8049                                         fold_convert (cst_uchar_ptr_node,
8050                                                       arg2)));
8051       return fold_build1 (NEGATE_EXPR, integer_type_node, temp);
8052     }
8053
8054   /* If len parameter is one, return an expression corresponding to
8055      (*(const unsigned char*)arg1 - (const unsigned char*)arg2).  */
8056   if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
8057     {
8058       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8059       tree cst_uchar_ptr_node
8060         = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8061
8062       tree ind1 = fold_convert (integer_type_node,
8063                                 build1 (INDIRECT_REF, cst_uchar_node,
8064                                         fold_convert (cst_uchar_ptr_node,
8065                                                       arg1)));
8066       tree ind2 = fold_convert (integer_type_node,
8067                                 build1 (INDIRECT_REF, cst_uchar_node,
8068                                         fold_convert (cst_uchar_ptr_node,
8069                                                       arg2)));
8070       return fold_build2 (MINUS_EXPR, integer_type_node, ind1, ind2);
8071     }
8072
8073   return 0;
8074 }
8075
8076 /* Fold function call to builtin signbit, signbitf or signbitl.  Return
8077    NULL_TREE if no simplification can be made.  */
8078
8079 static tree
8080 fold_builtin_signbit (tree fndecl, tree arglist)
8081 {
8082   tree type = TREE_TYPE (TREE_TYPE (fndecl));
8083   tree arg, temp;
8084
8085   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8086     return NULL_TREE;
8087
8088   arg = TREE_VALUE (arglist);
8089
8090   /* If ARG is a compile-time constant, determine the result.  */
8091   if (TREE_CODE (arg) == REAL_CST
8092       && !TREE_CONSTANT_OVERFLOW (arg))
8093     {
8094       REAL_VALUE_TYPE c;
8095
8096       c = TREE_REAL_CST (arg);
8097       temp = REAL_VALUE_NEGATIVE (c) ? integer_one_node : integer_zero_node;
8098       return fold_convert (type, temp);
8099     }
8100
8101   /* If ARG is non-negative, the result is always zero.  */
8102   if (tree_expr_nonnegative_p (arg))
8103     return omit_one_operand (type, integer_zero_node, arg);
8104
8105   /* If ARG's format doesn't have signed zeros, return "arg < 0.0".  */
8106   if (!HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg))))
8107     return fold_build2 (LT_EXPR, type, arg,
8108                         build_real (TREE_TYPE (arg), dconst0));
8109
8110   return NULL_TREE;
8111 }
8112
8113 /* Fold function call to builtin copysign, copysignf or copysignl.
8114    Return NULL_TREE if no simplification can be made.  */
8115
8116 static tree
8117 fold_builtin_copysign (tree fndecl, tree arglist, tree type)
8118 {
8119   tree arg1, arg2, tem;
8120
8121   if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
8122     return NULL_TREE;
8123
8124   arg1 = TREE_VALUE (arglist);
8125   arg2 = TREE_VALUE (TREE_CHAIN (arglist));
8126
8127   /* copysign(X,X) is X.  */
8128   if (operand_equal_p (arg1, arg2, 0))
8129     return fold_convert (type, arg1);
8130
8131   /* If ARG1 and ARG2 are compile-time constants, determine the result.  */
8132   if (TREE_CODE (arg1) == REAL_CST
8133       && TREE_CODE (arg2) == REAL_CST
8134       && !TREE_CONSTANT_OVERFLOW (arg1)
8135       && !TREE_CONSTANT_OVERFLOW (arg2))
8136     {
8137       REAL_VALUE_TYPE c1, c2;
8138
8139       c1 = TREE_REAL_CST (arg1);
8140       c2 = TREE_REAL_CST (arg2);
8141       real_copysign (&c1, &c2);
8142       return build_real (type, c1);
8143       c1.sign = c2.sign;
8144     }
8145
8146   /* copysign(X, Y) is fabs(X) when Y is always non-negative.
8147      Remember to evaluate Y for side-effects.  */
8148   if (tree_expr_nonnegative_p (arg2))
8149     return omit_one_operand (type,
8150                              fold_build1 (ABS_EXPR, type, arg1),
8151                              arg2);
8152
8153   /* Strip sign changing operations for the first argument.  */
8154   tem = fold_strip_sign_ops (arg1);
8155   if (tem)
8156     {
8157       arglist = tree_cons (NULL_TREE, tem, TREE_CHAIN (arglist));
8158       return build_function_call_expr (fndecl, arglist);
8159     }
8160
8161   return NULL_TREE;
8162 }
8163
8164 /* Fold a call to builtin isascii.  */
8165
8166 static tree
8167 fold_builtin_isascii (tree arglist)
8168 {
8169   if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8170     return 0;
8171   else
8172     {
8173       /* Transform isascii(c) -> ((c & ~0x7f) == 0).  */
8174       tree arg = TREE_VALUE (arglist);
8175
8176       arg = build2 (BIT_AND_EXPR, integer_type_node, arg,
8177                     build_int_cst (NULL_TREE,
8178                                    ~ (unsigned HOST_WIDE_INT) 0x7f));
8179       arg = fold_build2 (EQ_EXPR, integer_type_node,
8180                          arg, integer_zero_node);
8181
8182       if (in_gimple_form && !TREE_CONSTANT (arg))
8183         return NULL_TREE;
8184       else
8185         return arg;
8186     }
8187 }
8188
8189 /* Fold a call to builtin toascii.  */
8190
8191 static tree
8192 fold_builtin_toascii (tree arglist)
8193 {
8194   if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8195     return 0;
8196   else
8197     {
8198       /* Transform toascii(c) -> (c & 0x7f).  */
8199       tree arg = TREE_VALUE (arglist);
8200
8201       return fold_build2 (BIT_AND_EXPR, integer_type_node, arg,
8202                           build_int_cst (NULL_TREE, 0x7f));
8203     }
8204 }
8205
8206 /* Fold a call to builtin isdigit.  */
8207
8208 static tree
8209 fold_builtin_isdigit (tree arglist)
8210 {
8211   if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8212     return 0;
8213   else
8214     {
8215       /* Transform isdigit(c) -> (unsigned)(c) - '0' <= 9.  */
8216       /* According to the C standard, isdigit is unaffected by locale.
8217          However, it definitely is affected by the target character set.  */
8218       tree arg;
8219       unsigned HOST_WIDE_INT target_digit0
8220         = lang_hooks.to_target_charset ('0');
8221
8222       if (target_digit0 == 0)
8223         return NULL_TREE;
8224
8225       arg = fold_convert (unsigned_type_node, TREE_VALUE (arglist));
8226       arg = build2 (MINUS_EXPR, unsigned_type_node, arg,
8227                     build_int_cst (unsigned_type_node, target_digit0));
8228       arg = fold_build2 (LE_EXPR, integer_type_node, arg,
8229                          build_int_cst (unsigned_type_node, 9));
8230       if (in_gimple_form && !TREE_CONSTANT (arg))
8231         return NULL_TREE;
8232       else
8233         return arg;
8234     }
8235 }
8236
8237 /* Fold a call to fabs, fabsf or fabsl.  */
8238
8239 static tree
8240 fold_builtin_fabs (tree arglist, tree type)
8241 {
8242   tree arg;
8243
8244   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8245     return 0;
8246
8247   arg = TREE_VALUE (arglist);
8248   arg = fold_convert (type, arg);
8249   if (TREE_CODE (arg) == REAL_CST)
8250     return fold_abs_const (arg, type);
8251   return fold_build1 (ABS_EXPR, type, arg);
8252 }
8253
8254 /* Fold a call to abs, labs, llabs or imaxabs.  */
8255
8256 static tree
8257 fold_builtin_abs (tree arglist, tree type)
8258 {
8259   tree arg;
8260
8261   if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8262     return 0;
8263
8264   arg = TREE_VALUE (arglist);
8265   arg = fold_convert (type, arg);
8266   if (TREE_CODE (arg) == INTEGER_CST)
8267     return fold_abs_const (arg, type);
8268   return fold_build1 (ABS_EXPR, type, arg);
8269 }
8270
8271 /* Fold a call to __builtin_isnan(), __builtin_isinf, __builtin_finite.
8272    EXP is the CALL_EXPR for the call.  */
8273
8274 static tree
8275 fold_builtin_classify (tree fndecl, tree arglist, int builtin_index)
8276 {
8277   tree type = TREE_TYPE (TREE_TYPE (fndecl));
8278   tree arg;
8279   REAL_VALUE_TYPE r;
8280
8281   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8282     {
8283       /* Check that we have exactly one argument.  */
8284       if (arglist == 0)
8285         {
8286           error ("too few arguments to function %qs",
8287                  IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8288           return error_mark_node;
8289         }
8290       else if (TREE_CHAIN (arglist) != 0)
8291         {
8292           error ("too many arguments to function %qs",
8293                  IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8294           return error_mark_node;
8295         }
8296       else
8297         {
8298           error ("non-floating-point argument to function %qs",
8299                  IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8300           return error_mark_node;
8301         }
8302     }
8303
8304   arg = TREE_VALUE (arglist);
8305   switch (builtin_index)
8306     {
8307     case BUILT_IN_ISINF:
8308       if (!MODE_HAS_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
8309         return omit_one_operand (type, integer_zero_node, arg);
8310
8311       if (TREE_CODE (arg) == REAL_CST)
8312         {
8313           r = TREE_REAL_CST (arg);
8314           if (real_isinf (&r))
8315             return real_compare (GT_EXPR, &r, &dconst0)
8316                    ? integer_one_node : integer_minus_one_node;
8317           else
8318             return integer_zero_node;
8319         }
8320
8321       return NULL_TREE;
8322
8323     case BUILT_IN_FINITE:
8324       if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg)))
8325           && !MODE_HAS_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
8326         return omit_one_operand (type, integer_zero_node, arg);
8327
8328       if (TREE_CODE (arg) == REAL_CST)
8329         {
8330           r = TREE_REAL_CST (arg);
8331           return real_isinf (&r) || real_isnan (&r)
8332                  ? integer_zero_node : integer_one_node;
8333         }
8334
8335       return NULL_TREE;
8336
8337     case BUILT_IN_ISNAN:
8338       if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg))))
8339         return omit_one_operand (type, integer_zero_node, arg);
8340
8341       if (TREE_CODE (arg) == REAL_CST)
8342         {
8343           r = TREE_REAL_CST (arg);
8344           return real_isnan (&r) ? integer_one_node : integer_zero_node;
8345         }
8346
8347       arg = builtin_save_expr (arg);
8348       return fold_build2 (UNORDERED_EXPR, type, arg, arg);
8349
8350     default:
8351       gcc_unreachable ();
8352     }
8353 }
8354
8355 /* Fold a call to an unordered comparison function such as
8356    __builtin_isgreater().  FNDECL is the FUNCTION_DECL for the function
8357    being called and ARGLIST is the argument list for the call.
8358    UNORDERED_CODE and ORDERED_CODE are comparison codes that give
8359    the opposite of the desired result.  UNORDERED_CODE is used
8360    for modes that can hold NaNs and ORDERED_CODE is used for
8361    the rest.  */
8362
8363 static tree
8364 fold_builtin_unordered_cmp (tree fndecl, tree arglist,
8365                             enum tree_code unordered_code,
8366                             enum tree_code ordered_code)
8367 {
8368   tree type = TREE_TYPE (TREE_TYPE (fndecl));
8369   enum tree_code code;
8370   tree arg0, arg1;
8371   tree type0, type1;
8372   enum tree_code code0, code1;
8373   tree cmp_type = NULL_TREE;
8374
8375   if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
8376     {
8377       /* Check that we have exactly two arguments.  */
8378       if (arglist == 0 || TREE_CHAIN (arglist) == 0)
8379         {
8380           error ("too few arguments to function %qs",
8381                  IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8382           return error_mark_node;
8383         }
8384       else if (TREE_CHAIN (TREE_CHAIN (arglist)) != 0)
8385         {
8386           error ("too many arguments to function %qs",
8387                  IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8388           return error_mark_node;
8389         }
8390     }
8391
8392   arg0 = TREE_VALUE (arglist);
8393   arg1 = TREE_VALUE (TREE_CHAIN (arglist));
8394   
8395   type0 = TREE_TYPE (arg0);
8396   type1 = TREE_TYPE (arg1);
8397   
8398   code0 = TREE_CODE (type0);
8399   code1 = TREE_CODE (type1);
8400   
8401   if (code0 == REAL_TYPE && code1 == REAL_TYPE)
8402     /* Choose the wider of two real types.  */
8403     cmp_type = TYPE_PRECISION (type0) >= TYPE_PRECISION (type1)
8404       ? type0 : type1;
8405   else if (code0 == REAL_TYPE && code1 == INTEGER_TYPE)
8406     cmp_type = type0;
8407   else if (code0 == INTEGER_TYPE && code1 == REAL_TYPE)
8408     cmp_type = type1;
8409   else
8410     {
8411       error ("non-floating-point argument to function %qs",
8412                  IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8413       return error_mark_node;
8414     }
8415   
8416   arg0 = fold_convert (cmp_type, arg0);
8417   arg1 = fold_convert (cmp_type, arg1);
8418
8419   if (unordered_code == UNORDERED_EXPR)
8420     {
8421       if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg0))))
8422         return omit_two_operands (type, integer_zero_node, arg0, arg1);
8423       return fold_build2 (UNORDERED_EXPR, type, arg0, arg1);
8424     }
8425
8426   code = MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg0))) ? unordered_code
8427                                                       : ordered_code;
8428   return fold_build1 (TRUTH_NOT_EXPR, type,
8429                       fold_build2 (code, type, arg0, arg1));
8430 }
8431
8432 /* Used by constant folding to simplify calls to builtin functions.  EXP is
8433    the CALL_EXPR of a call to a builtin function.  IGNORE is true if the
8434    result of the function call is ignored.  This function returns NULL_TREE
8435    if no simplification was possible.  */
8436
8437 static tree
8438 fold_builtin_1 (tree fndecl, tree arglist, bool ignore)
8439 {
8440   tree type = TREE_TYPE (TREE_TYPE (fndecl));
8441   enum built_in_function fcode;
8442
8443   if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
8444     return targetm.fold_builtin (fndecl, arglist, ignore);
8445
8446   fcode = DECL_FUNCTION_CODE (fndecl);
8447   switch (fcode)
8448     {
8449     case BUILT_IN_FPUTS:
8450       return fold_builtin_fputs (arglist, ignore, false, NULL_TREE);
8451
8452     case BUILT_IN_FPUTS_UNLOCKED:
8453       return fold_builtin_fputs (arglist, ignore, true, NULL_TREE);
8454
8455     case BUILT_IN_STRSTR:
8456       return fold_builtin_strstr (arglist, type);
8457
8458     case BUILT_IN_STRCAT:
8459       return fold_builtin_strcat (arglist);
8460
8461     case BUILT_IN_STRNCAT:
8462       return fold_builtin_strncat (arglist);
8463
8464     case BUILT_IN_STRSPN:
8465       return fold_builtin_strspn (arglist);
8466
8467     case BUILT_IN_STRCSPN:
8468       return fold_builtin_strcspn (arglist);
8469
8470     case BUILT_IN_STRCHR:
8471     case BUILT_IN_INDEX:
8472       return fold_builtin_strchr (arglist, type);
8473
8474     case BUILT_IN_STRRCHR:
8475     case BUILT_IN_RINDEX:
8476       return fold_builtin_strrchr (arglist, type);
8477
8478     case BUILT_IN_STRCPY:
8479       return fold_builtin_strcpy (fndecl, arglist, NULL_TREE);
8480
8481     case BUILT_IN_STRNCPY:
8482       return fold_builtin_strncpy (fndecl, arglist, NULL_TREE);
8483
8484     case BUILT_IN_STRCMP:
8485       return fold_builtin_strcmp (arglist);
8486
8487     case BUILT_IN_STRNCMP:
8488       return fold_builtin_strncmp (arglist);
8489
8490     case BUILT_IN_STRPBRK:
8491       return fold_builtin_strpbrk (arglist, type);
8492
8493     case BUILT_IN_BCMP:
8494     case BUILT_IN_MEMCMP:
8495       return fold_builtin_memcmp (arglist);
8496
8497     case BUILT_IN_SPRINTF:
8498       return fold_builtin_sprintf (arglist, ignore);
8499
8500     case BUILT_IN_CONSTANT_P:
8501       {
8502         tree val;
8503
8504         val = fold_builtin_constant_p (arglist);
8505         /* Gimplification will pull the CALL_EXPR for the builtin out of
8506            an if condition.  When not optimizing, we'll not CSE it back.
8507            To avoid link error types of regressions, return false now.  */
8508         if (!val && !optimize)
8509           val = integer_zero_node;
8510
8511         return val;
8512       }
8513
8514     case BUILT_IN_EXPECT:
8515       return fold_builtin_expect (arglist);
8516
8517     case BUILT_IN_CLASSIFY_TYPE:
8518       return fold_builtin_classify_type (arglist);
8519
8520     case BUILT_IN_STRLEN:
8521       return fold_builtin_strlen (arglist);
8522
8523     CASE_FLT_FN (BUILT_IN_FABS):
8524       return fold_builtin_fabs (arglist, type);
8525
8526     case BUILT_IN_ABS:
8527     case BUILT_IN_LABS:
8528     case BUILT_IN_LLABS:
8529     case BUILT_IN_IMAXABS:
8530       return fold_builtin_abs (arglist, type);
8531
8532     CASE_FLT_FN (BUILT_IN_CONJ):
8533       if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
8534         return fold_build1 (CONJ_EXPR, type, TREE_VALUE (arglist));
8535       break;
8536
8537     CASE_FLT_FN (BUILT_IN_CREAL):
8538       if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
8539         return non_lvalue (fold_build1 (REALPART_EXPR, type,
8540                                         TREE_VALUE (arglist)));
8541       break;
8542
8543     CASE_FLT_FN (BUILT_IN_CIMAG):
8544       if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
8545         return non_lvalue (fold_build1 (IMAGPART_EXPR, type,
8546                                         TREE_VALUE (arglist)));
8547       break;
8548
8549     CASE_FLT_FN (BUILT_IN_CABS):
8550       return fold_builtin_cabs (arglist, type);
8551
8552     CASE_FLT_FN (BUILT_IN_SQRT):
8553       return fold_builtin_sqrt (arglist, type);
8554
8555     CASE_FLT_FN (BUILT_IN_CBRT):
8556       return fold_builtin_cbrt (arglist, type);
8557
8558     CASE_FLT_FN (BUILT_IN_SIN):
8559       return fold_builtin_sin (arglist);
8560
8561     CASE_FLT_FN (BUILT_IN_COS):
8562       return fold_builtin_cos (arglist, type, fndecl);
8563
8564     CASE_FLT_FN (BUILT_IN_EXP):
8565       return fold_builtin_exponent (fndecl, arglist, &dconste);
8566
8567     CASE_FLT_FN (BUILT_IN_EXP2):
8568       return fold_builtin_exponent (fndecl, arglist, &dconst2);
8569
8570     CASE_FLT_FN (BUILT_IN_EXP10):
8571     CASE_FLT_FN (BUILT_IN_POW10):
8572       return fold_builtin_exponent (fndecl, arglist, &dconst10);
8573
8574     CASE_FLT_FN (BUILT_IN_LOG):
8575       return fold_builtin_logarithm (fndecl, arglist, &dconste);
8576
8577     CASE_FLT_FN (BUILT_IN_LOG2):
8578       return fold_builtin_logarithm (fndecl, arglist, &dconst2);
8579
8580     CASE_FLT_FN (BUILT_IN_LOG10):
8581       return fold_builtin_logarithm (fndecl, arglist, &dconst10);
8582
8583     CASE_FLT_FN (BUILT_IN_TAN):
8584       return fold_builtin_tan (arglist);
8585
8586     CASE_FLT_FN (BUILT_IN_ATAN):
8587       return fold_builtin_atan (arglist, type);
8588
8589     CASE_FLT_FN (BUILT_IN_POW):
8590       return fold_builtin_pow (fndecl, arglist, type);
8591
8592     CASE_FLT_FN (BUILT_IN_POWI):
8593       return fold_builtin_powi (fndecl, arglist, type);
8594
8595     CASE_FLT_FN (BUILT_IN_INF):
8596       return fold_builtin_inf (type, true);
8597
8598     CASE_FLT_FN (BUILT_IN_HUGE_VAL):
8599       return fold_builtin_inf (type, false);
8600
8601     CASE_FLT_FN (BUILT_IN_NAN):
8602       return fold_builtin_nan (arglist, type, true);
8603
8604     CASE_FLT_FN (BUILT_IN_NANS):
8605       return fold_builtin_nan (arglist, type, false);
8606
8607     CASE_FLT_FN (BUILT_IN_FLOOR):
8608       return fold_builtin_floor (fndecl, arglist);
8609
8610     CASE_FLT_FN (BUILT_IN_CEIL):
8611       return fold_builtin_ceil (fndecl, arglist);
8612
8613     CASE_FLT_FN (BUILT_IN_TRUNC):
8614       return fold_builtin_trunc (fndecl, arglist);
8615
8616     CASE_FLT_FN (BUILT_IN_ROUND):
8617       return fold_builtin_round (fndecl, arglist);
8618
8619     CASE_FLT_FN (BUILT_IN_NEARBYINT):
8620     CASE_FLT_FN (BUILT_IN_RINT):
8621       return fold_trunc_transparent_mathfn (fndecl, arglist);
8622
8623     CASE_FLT_FN (BUILT_IN_LCEIL):
8624     CASE_FLT_FN (BUILT_IN_LLCEIL):
8625     CASE_FLT_FN (BUILT_IN_LFLOOR):
8626     CASE_FLT_FN (BUILT_IN_LLFLOOR):
8627     CASE_FLT_FN (BUILT_IN_LROUND):   
8628     CASE_FLT_FN (BUILT_IN_LLROUND):
8629       return fold_builtin_int_roundingfn (fndecl, arglist);
8630
8631     CASE_FLT_FN (BUILT_IN_LRINT):
8632     CASE_FLT_FN (BUILT_IN_LLRINT):
8633       return fold_fixed_mathfn (fndecl, arglist);
8634
8635     CASE_INT_FN (BUILT_IN_FFS):
8636     CASE_INT_FN (BUILT_IN_CLZ):
8637     CASE_INT_FN (BUILT_IN_CTZ):
8638     CASE_INT_FN (BUILT_IN_POPCOUNT):
8639     CASE_INT_FN (BUILT_IN_PARITY):
8640       return fold_builtin_bitop (fndecl, arglist);
8641
8642     case BUILT_IN_MEMCPY:
8643       return fold_builtin_memcpy (fndecl, arglist);
8644
8645     case BUILT_IN_MEMPCPY:
8646       return fold_builtin_mempcpy (arglist, type, /*endp=*/1);
8647
8648     case BUILT_IN_MEMMOVE:
8649       return fold_builtin_memmove (arglist, type);
8650
8651     CASE_FLT_FN (BUILT_IN_SIGNBIT):
8652       return fold_builtin_signbit (fndecl, arglist);
8653
8654     case BUILT_IN_ISASCII:
8655       return fold_builtin_isascii (arglist);
8656
8657     case BUILT_IN_TOASCII:
8658       return fold_builtin_toascii (arglist);
8659
8660     case BUILT_IN_ISDIGIT:
8661       return fold_builtin_isdigit (arglist);
8662
8663     CASE_FLT_FN (BUILT_IN_COPYSIGN):
8664       return fold_builtin_copysign (fndecl, arglist, type);
8665
8666     CASE_FLT_FN (BUILT_IN_FINITE):
8667       return fold_builtin_classify (fndecl, arglist, BUILT_IN_FINITE);
8668
8669     CASE_FLT_FN (BUILT_IN_ISINF):
8670       return fold_builtin_classify (fndecl, arglist, BUILT_IN_ISINF);
8671
8672     CASE_FLT_FN (BUILT_IN_ISNAN):
8673       return fold_builtin_classify (fndecl, arglist, BUILT_IN_ISNAN);
8674
8675     case BUILT_IN_ISGREATER:
8676       return fold_builtin_unordered_cmp (fndecl, arglist, UNLE_EXPR, LE_EXPR);
8677     case BUILT_IN_ISGREATEREQUAL:
8678       return fold_builtin_unordered_cmp (fndecl, arglist, UNLT_EXPR, LT_EXPR);
8679     case BUILT_IN_ISLESS:
8680       return fold_builtin_unordered_cmp (fndecl, arglist, UNGE_EXPR, GE_EXPR);
8681     case BUILT_IN_ISLESSEQUAL:
8682       return fold_builtin_unordered_cmp (fndecl, arglist, UNGT_EXPR, GT_EXPR);
8683     case BUILT_IN_ISLESSGREATER:
8684       return fold_builtin_unordered_cmp (fndecl, arglist, UNEQ_EXPR, EQ_EXPR);
8685     case BUILT_IN_ISUNORDERED:
8686       return fold_builtin_unordered_cmp (fndecl, arglist, UNORDERED_EXPR,
8687                                          NOP_EXPR);
8688
8689       /* We do the folding for va_start in the expander.  */
8690     case BUILT_IN_VA_START:
8691       break;
8692
8693     case BUILT_IN_OBJECT_SIZE:
8694       return fold_builtin_object_size (arglist);
8695     case BUILT_IN_MEMCPY_CHK:
8696     case BUILT_IN_MEMPCPY_CHK:
8697     case BUILT_IN_MEMMOVE_CHK:
8698     case BUILT_IN_MEMSET_CHK:
8699       return fold_builtin_memory_chk (fndecl, arglist, NULL_TREE, ignore,
8700                                       DECL_FUNCTION_CODE (fndecl));
8701     case BUILT_IN_STRCPY_CHK:
8702     case BUILT_IN_STPCPY_CHK:
8703       return fold_builtin_stxcpy_chk (fndecl, arglist, NULL_TREE, ignore,
8704                                       DECL_FUNCTION_CODE (fndecl));
8705     case BUILT_IN_STRNCPY_CHK:
8706       return fold_builtin_strncpy_chk (arglist, NULL_TREE);
8707     case BUILT_IN_STRCAT_CHK:
8708       return fold_builtin_strcat_chk (fndecl, arglist);
8709     case BUILT_IN_STRNCAT_CHK:
8710       return fold_builtin_strncat_chk (fndecl, arglist);
8711     case BUILT_IN_SPRINTF_CHK:
8712     case BUILT_IN_VSPRINTF_CHK:
8713       return fold_builtin_sprintf_chk (arglist, DECL_FUNCTION_CODE (fndecl));
8714     case BUILT_IN_SNPRINTF_CHK:
8715     case BUILT_IN_VSNPRINTF_CHK:
8716       return fold_builtin_snprintf_chk (arglist, NULL_TREE,
8717                                         DECL_FUNCTION_CODE (fndecl));
8718
8719     case BUILT_IN_PRINTF:
8720     case BUILT_IN_PRINTF_UNLOCKED:
8721     case BUILT_IN_VPRINTF:
8722     case BUILT_IN_PRINTF_CHK:
8723     case BUILT_IN_VPRINTF_CHK:
8724       return fold_builtin_printf (fndecl, arglist, ignore,
8725                                   DECL_FUNCTION_CODE (fndecl));
8726
8727     case BUILT_IN_FPRINTF:
8728     case BUILT_IN_FPRINTF_UNLOCKED:
8729     case BUILT_IN_VFPRINTF:
8730     case BUILT_IN_FPRINTF_CHK:
8731     case BUILT_IN_VFPRINTF_CHK:
8732       return fold_builtin_fprintf (fndecl, arglist, ignore,
8733                                    DECL_FUNCTION_CODE (fndecl));
8734
8735     default:
8736       break;
8737     }
8738
8739   return 0;
8740 }
8741
8742 /* A wrapper function for builtin folding that prevents warnings for
8743    "statement without effect" and the like, caused by removing the
8744    call node earlier than the warning is generated.  */
8745
8746 tree
8747 fold_builtin (tree fndecl, tree arglist, bool ignore)
8748 {
8749   tree exp = fold_builtin_1 (fndecl, arglist, ignore);
8750   if (exp)
8751     {
8752       exp = build1 (NOP_EXPR, TREE_TYPE (exp), exp);
8753       TREE_NO_WARNING (exp) = 1;
8754     }
8755
8756   return exp;
8757 }
8758
8759 /* Conveniently construct a function call expression.  */
8760
8761 tree
8762 build_function_call_expr (tree fn, tree arglist)
8763 {
8764   tree call_expr;
8765
8766   call_expr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
8767   return fold_build3 (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)),
8768                       call_expr, arglist, NULL_TREE);
8769 }
8770
8771 /* This function validates the types of a function call argument list
8772    represented as a tree chain of parameters against a specified list
8773    of tree_codes.  If the last specifier is a 0, that represents an
8774    ellipses, otherwise the last specifier must be a VOID_TYPE.  */
8775
8776 static int
8777 validate_arglist (tree arglist, ...)
8778 {
8779   enum tree_code code;
8780   int res = 0;
8781   va_list ap;
8782
8783   va_start (ap, arglist);
8784
8785   do
8786     {
8787       code = va_arg (ap, enum tree_code);
8788       switch (code)
8789         {
8790         case 0:
8791           /* This signifies an ellipses, any further arguments are all ok.  */
8792           res = 1;
8793           goto end;
8794         case VOID_TYPE:
8795           /* This signifies an endlink, if no arguments remain, return
8796              true, otherwise return false.  */
8797           res = arglist == 0;
8798           goto end;
8799         default:
8800           /* If no parameters remain or the parameter's code does not
8801              match the specified code, return false.  Otherwise continue
8802              checking any remaining arguments.  */
8803           if (arglist == 0)
8804             goto end;
8805           if (code == POINTER_TYPE)
8806             {
8807               if (! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist))))
8808                 goto end;
8809             }
8810           else if (code != TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))))
8811             goto end;
8812           break;
8813         }
8814       arglist = TREE_CHAIN (arglist);
8815     }
8816   while (1);
8817
8818   /* We need gotos here since we can only have one VA_CLOSE in a
8819      function.  */
8820  end: ;
8821   va_end (ap);
8822
8823   return res;
8824 }
8825
8826 /* Default target-specific builtin expander that does nothing.  */
8827
8828 rtx
8829 default_expand_builtin (tree exp ATTRIBUTE_UNUSED,
8830                         rtx target ATTRIBUTE_UNUSED,
8831                         rtx subtarget ATTRIBUTE_UNUSED,
8832                         enum machine_mode mode ATTRIBUTE_UNUSED,
8833                         int ignore ATTRIBUTE_UNUSED)
8834 {
8835   return NULL_RTX;
8836 }
8837
8838 /* Returns true is EXP represents data that would potentially reside
8839    in a readonly section.  */
8840
8841 static bool
8842 readonly_data_expr (tree exp)
8843 {
8844   STRIP_NOPS (exp);
8845
8846   if (TREE_CODE (exp) != ADDR_EXPR)
8847     return false;
8848
8849   exp = get_base_address (TREE_OPERAND (exp, 0));
8850   if (!exp)
8851     return false;
8852
8853   /* Make sure we call decl_readonly_section only for trees it
8854      can handle (since it returns true for everything it doesn't
8855      understand).  */
8856   if (TREE_CODE (exp) == STRING_CST
8857       || TREE_CODE (exp) == CONSTRUCTOR
8858       || (TREE_CODE (exp) == VAR_DECL && TREE_STATIC (exp)))
8859     return decl_readonly_section (exp, 0);
8860   else
8861     return false;
8862 }
8863
8864 /* Simplify a call to the strstr builtin.
8865
8866    Return 0 if no simplification was possible, otherwise return the
8867    simplified form of the call as a tree.
8868
8869    The simplified form may be a constant or other expression which
8870    computes the same value, but in a more efficient manner (including
8871    calls to other builtin functions).
8872
8873    The call may contain arguments which need to be evaluated, but
8874    which are not useful to determine the result of the call.  In
8875    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
8876    COMPOUND_EXPR will be an argument which must be evaluated.
8877    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
8878    COMPOUND_EXPR in the chain will contain the tree for the simplified
8879    form of the builtin function call.  */
8880
8881 static tree
8882 fold_builtin_strstr (tree arglist, tree type)
8883 {
8884   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
8885     return 0;
8886   else
8887     {
8888       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
8889       tree fn;
8890       const char *p1, *p2;
8891
8892       p2 = c_getstr (s2);
8893       if (p2 == NULL)
8894         return 0;
8895
8896       p1 = c_getstr (s1);
8897       if (p1 != NULL)
8898         {
8899           const char *r = strstr (p1, p2);
8900           tree tem;
8901
8902           if (r == NULL)
8903             return build_int_cst (TREE_TYPE (s1), 0);
8904
8905           /* Return an offset into the constant string argument.  */
8906           tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
8907                              s1, build_int_cst (TREE_TYPE (s1), r - p1));
8908           return fold_convert (type, tem);
8909         }
8910
8911       /* The argument is const char *, and the result is char *, so we need
8912          a type conversion here to avoid a warning.  */
8913       if (p2[0] == '\0')
8914         return fold_convert (type, s1);
8915
8916       if (p2[1] != '\0')
8917         return 0;
8918
8919       fn = implicit_built_in_decls[BUILT_IN_STRCHR];
8920       if (!fn)
8921         return 0;
8922
8923       /* New argument list transforming strstr(s1, s2) to
8924          strchr(s1, s2[0]).  */
8925       arglist = build_tree_list (NULL_TREE,
8926                                  build_int_cst (NULL_TREE, p2[0]));
8927       arglist = tree_cons (NULL_TREE, s1, arglist);
8928       return build_function_call_expr (fn, arglist);
8929     }
8930 }
8931
8932 /* Simplify a call to the strchr builtin.
8933
8934    Return 0 if no simplification was possible, otherwise return the
8935    simplified form of the call as a tree.
8936
8937    The simplified form may be a constant or other expression which
8938    computes the same value, but in a more efficient manner (including
8939    calls to other builtin functions).
8940
8941    The call may contain arguments which need to be evaluated, but
8942    which are not useful to determine the result of the call.  In
8943    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
8944    COMPOUND_EXPR will be an argument which must be evaluated.
8945    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
8946    COMPOUND_EXPR in the chain will contain the tree for the simplified
8947    form of the builtin function call.  */
8948
8949 static tree
8950 fold_builtin_strchr (tree arglist, tree type)
8951 {
8952   if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8953     return 0;
8954   else
8955     {
8956       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
8957       const char *p1;
8958
8959       if (TREE_CODE (s2) != INTEGER_CST)
8960         return 0;
8961
8962       p1 = c_getstr (s1);
8963       if (p1 != NULL)
8964         {
8965           char c;
8966           const char *r;
8967           tree tem;
8968
8969           if (target_char_cast (s2, &c))
8970             return 0;
8971
8972           r = strchr (p1, c);
8973
8974           if (r == NULL)
8975             return build_int_cst (TREE_TYPE (s1), 0);
8976
8977           /* Return an offset into the constant string argument.  */
8978           tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
8979                              s1, build_int_cst (TREE_TYPE (s1), r - p1));
8980           return fold_convert (type, tem);
8981         }
8982       return 0;
8983     }
8984 }
8985
8986 /* Simplify a call to the strrchr builtin.
8987
8988    Return 0 if no simplification was possible, otherwise return the
8989    simplified form of the call as a tree.
8990
8991    The simplified form may be a constant or other expression which
8992    computes the same value, but in a more efficient manner (including
8993    calls to other builtin functions).
8994
8995    The call may contain arguments which need to be evaluated, but
8996    which are not useful to determine the result of the call.  In
8997    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
8998    COMPOUND_EXPR will be an argument which must be evaluated.
8999    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
9000    COMPOUND_EXPR in the chain will contain the tree for the simplified
9001    form of the builtin function call.  */
9002
9003 static tree
9004 fold_builtin_strrchr (tree arglist, tree type)
9005 {
9006   if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9007     return 0;
9008   else
9009     {
9010       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9011       tree fn;
9012       const char *p1;
9013
9014       if (TREE_CODE (s2) != INTEGER_CST)
9015         return 0;
9016
9017       p1 = c_getstr (s1);
9018       if (p1 != NULL)
9019         {
9020           char c;
9021           const char *r;
9022           tree tem;
9023
9024           if (target_char_cast (s2, &c))
9025             return 0;
9026
9027           r = strrchr (p1, c);
9028
9029           if (r == NULL)
9030             return build_int_cst (TREE_TYPE (s1), 0);
9031
9032           /* Return an offset into the constant string argument.  */
9033           tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
9034                              s1, build_int_cst (TREE_TYPE (s1), r - p1));
9035           return fold_convert (type, tem);
9036         }
9037
9038       if (! integer_zerop (s2))
9039         return 0;
9040
9041       fn = implicit_built_in_decls[BUILT_IN_STRCHR];
9042       if (!fn)
9043         return 0;
9044
9045       /* Transform strrchr(s1, '\0') to strchr(s1, '\0').  */
9046       return build_function_call_expr (fn, arglist);
9047     }
9048 }
9049
9050 /* Simplify a call to the strpbrk builtin.
9051
9052    Return 0 if no simplification was possible, otherwise return the
9053    simplified form of the call as a tree.
9054
9055    The simplified form may be a constant or other expression which
9056    computes the same value, but in a more efficient manner (including
9057    calls to other builtin functions).
9058
9059    The call may contain arguments which need to be evaluated, but
9060    which are not useful to determine the result of the call.  In
9061    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
9062    COMPOUND_EXPR will be an argument which must be evaluated.
9063    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
9064    COMPOUND_EXPR in the chain will contain the tree for the simplified
9065    form of the builtin function call.  */
9066
9067 static tree
9068 fold_builtin_strpbrk (tree arglist, tree type)
9069 {
9070   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9071     return 0;
9072   else
9073     {
9074       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9075       tree fn;
9076       const char *p1, *p2;
9077
9078       p2 = c_getstr (s2);
9079       if (p2 == NULL)
9080         return 0;
9081
9082       p1 = c_getstr (s1);
9083       if (p1 != NULL)
9084         {
9085           const char *r = strpbrk (p1, p2);
9086           tree tem;
9087
9088           if (r == NULL)
9089             return build_int_cst (TREE_TYPE (s1), 0);
9090
9091           /* Return an offset into the constant string argument.  */
9092           tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
9093                              s1, build_int_cst (TREE_TYPE (s1), r - p1));
9094           return fold_convert (type, tem);
9095         }
9096
9097       if (p2[0] == '\0')
9098         /* strpbrk(x, "") == NULL.
9099            Evaluate and ignore s1 in case it had side-effects.  */
9100         return omit_one_operand (TREE_TYPE (s1), integer_zero_node, s1);
9101
9102       if (p2[1] != '\0')
9103         return 0;  /* Really call strpbrk.  */
9104
9105       fn = implicit_built_in_decls[BUILT_IN_STRCHR];
9106       if (!fn)
9107         return 0;
9108
9109       /* New argument list transforming strpbrk(s1, s2) to
9110          strchr(s1, s2[0]).  */
9111       arglist = build_tree_list (NULL_TREE,
9112                                  build_int_cst (NULL_TREE, p2[0]));
9113       arglist = tree_cons (NULL_TREE, s1, arglist);
9114       return build_function_call_expr (fn, arglist);
9115     }
9116 }
9117
9118 /* Simplify a call to the strcat builtin.
9119
9120    Return 0 if no simplification was possible, otherwise return the
9121    simplified form of the call as a tree.
9122
9123    The simplified form may be a constant or other expression which
9124    computes the same value, but in a more efficient manner (including
9125    calls to other builtin functions).
9126
9127    The call may contain arguments which need to be evaluated, but
9128    which are not useful to determine the result of the call.  In
9129    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
9130    COMPOUND_EXPR will be an argument which must be evaluated.
9131    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
9132    COMPOUND_EXPR in the chain will contain the tree for the simplified
9133    form of the builtin function call.  */
9134
9135 static tree
9136 fold_builtin_strcat (tree arglist)
9137 {
9138   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9139     return 0;
9140   else
9141     {
9142       tree dst = TREE_VALUE (arglist),
9143         src = TREE_VALUE (TREE_CHAIN (arglist));
9144       const char *p = c_getstr (src);
9145
9146       /* If the string length is zero, return the dst parameter.  */
9147       if (p && *p == '\0')
9148         return dst;
9149
9150       return 0;
9151     }
9152 }
9153
9154 /* Simplify a call to the strncat builtin.
9155
9156    Return 0 if no simplification was possible, otherwise return the
9157    simplified form of the call as a tree.
9158
9159    The simplified form may be a constant or other expression which
9160    computes the same value, but in a more efficient manner (including
9161    calls to other builtin functions).
9162
9163    The call may contain arguments which need to be evaluated, but
9164    which are not useful to determine the result of the call.  In
9165    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
9166    COMPOUND_EXPR will be an argument which must be evaluated.
9167    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
9168    COMPOUND_EXPR in the chain will contain the tree for the simplified
9169    form of the builtin function call.  */
9170
9171 static tree
9172 fold_builtin_strncat (tree arglist)
9173 {
9174   if (!validate_arglist (arglist,
9175                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9176     return 0;
9177   else
9178     {
9179       tree dst = TREE_VALUE (arglist);
9180       tree src = TREE_VALUE (TREE_CHAIN (arglist));
9181       tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
9182       const char *p = c_getstr (src);
9183
9184       /* If the requested length is zero, or the src parameter string
9185          length is zero, return the dst parameter.  */
9186       if (integer_zerop (len) || (p && *p == '\0'))
9187         return omit_two_operands (TREE_TYPE (dst), dst, src, len);
9188
9189       /* If the requested len is greater than or equal to the string
9190          length, call strcat.  */
9191       if (TREE_CODE (len) == INTEGER_CST && p
9192           && compare_tree_int (len, strlen (p)) >= 0)
9193         {
9194           tree newarglist
9195             = tree_cons (NULL_TREE, dst, build_tree_list (NULL_TREE, src));
9196           tree fn = implicit_built_in_decls[BUILT_IN_STRCAT];
9197
9198           /* If the replacement _DECL isn't initialized, don't do the
9199              transformation.  */
9200           if (!fn)
9201             return 0;
9202
9203           return build_function_call_expr (fn, newarglist);
9204         }
9205       return 0;
9206     }
9207 }
9208
9209 /* Simplify a call to the strspn builtin.
9210
9211    Return 0 if no simplification was possible, otherwise return the
9212    simplified form of the call as a tree.
9213
9214    The simplified form may be a constant or other expression which
9215    computes the same value, but in a more efficient manner (including
9216    calls to other builtin functions).
9217
9218    The call may contain arguments which need to be evaluated, but
9219    which are not useful to determine the result of the call.  In
9220    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
9221    COMPOUND_EXPR will be an argument which must be evaluated.
9222    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
9223    COMPOUND_EXPR in the chain will contain the tree for the simplified
9224    form of the builtin function call.  */
9225
9226 static tree
9227 fold_builtin_strspn (tree arglist)
9228 {
9229   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9230     return 0;
9231   else
9232     {
9233       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9234       const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
9235
9236       /* If both arguments are constants, evaluate at compile-time.  */
9237       if (p1 && p2)
9238         {
9239           const size_t r = strspn (p1, p2);
9240           return size_int (r);
9241         }
9242
9243       /* If either argument is "", return 0.  */
9244       if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
9245         /* Evaluate and ignore both arguments in case either one has
9246            side-effects.  */
9247         return omit_two_operands (integer_type_node, integer_zero_node,
9248                                   s1, s2);
9249       return 0;
9250     }
9251 }
9252
9253 /* Simplify a call to the strcspn builtin.
9254
9255    Return 0 if no simplification was possible, otherwise return the
9256    simplified form of the call as a tree.
9257
9258    The simplified form may be a constant or other expression which
9259    computes the same value, but in a more efficient manner (including
9260    calls to other builtin functions).
9261
9262    The call may contain arguments which need to be evaluated, but
9263    which are not useful to determine the result of the call.  In
9264    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
9265    COMPOUND_EXPR will be an argument which must be evaluated.
9266    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
9267    COMPOUND_EXPR in the chain will contain the tree for the simplified
9268    form of the builtin function call.  */
9269
9270 static tree
9271 fold_builtin_strcspn (tree arglist)
9272 {
9273   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9274     return 0;
9275   else
9276     {
9277       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9278       const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
9279
9280       /* If both arguments are constants, evaluate at compile-time.  */
9281       if (p1 && p2)
9282         {
9283           const size_t r = strcspn (p1, p2);
9284           return size_int (r);
9285         }
9286
9287       /* If the first argument is "", return 0.  */
9288       if (p1 && *p1 == '\0')
9289         {
9290           /* Evaluate and ignore argument s2 in case it has
9291              side-effects.  */
9292           return omit_one_operand (integer_type_node,
9293                                    integer_zero_node, s2);
9294         }
9295
9296       /* If the second argument is "", return __builtin_strlen(s1).  */
9297       if (p2 && *p2 == '\0')
9298         {
9299           tree newarglist = build_tree_list (NULL_TREE, s1),
9300             fn = implicit_built_in_decls[BUILT_IN_STRLEN];
9301
9302           /* If the replacement _DECL isn't initialized, don't do the
9303              transformation.  */
9304           if (!fn)
9305             return 0;
9306
9307           return build_function_call_expr (fn, newarglist);
9308         }
9309       return 0;
9310     }
9311 }
9312
9313 /* Fold a call to the fputs builtin.  IGNORE is true if the value returned
9314    by the builtin will be ignored.  UNLOCKED is true is true if this
9315    actually a call to fputs_unlocked.  If LEN in non-NULL, it represents
9316    the known length of the string.  Return NULL_TREE if no simplification
9317    was possible.  */
9318
9319 tree
9320 fold_builtin_fputs (tree arglist, bool ignore, bool unlocked, tree len)
9321 {
9322   tree fn;
9323   /* If we're using an unlocked function, assume the other unlocked
9324      functions exist explicitly.  */
9325   tree const fn_fputc = unlocked ? built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
9326     : implicit_built_in_decls[BUILT_IN_FPUTC];
9327   tree const fn_fwrite = unlocked ? built_in_decls[BUILT_IN_FWRITE_UNLOCKED]
9328     : implicit_built_in_decls[BUILT_IN_FWRITE];
9329
9330   /* If the return value is used, don't do the transformation.  */
9331   if (!ignore)
9332     return 0;
9333
9334   /* Verify the arguments in the original call.  */
9335   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9336     return 0;
9337
9338   if (! len)
9339     len = c_strlen (TREE_VALUE (arglist), 0);
9340
9341   /* Get the length of the string passed to fputs.  If the length
9342      can't be determined, punt.  */
9343   if (!len
9344       || TREE_CODE (len) != INTEGER_CST)
9345     return 0;
9346
9347   switch (compare_tree_int (len, 1))
9348     {
9349     case -1: /* length is 0, delete the call entirely .  */
9350       return omit_one_operand (integer_type_node, integer_zero_node,
9351                                TREE_VALUE (TREE_CHAIN (arglist)));
9352
9353     case 0: /* length is 1, call fputc.  */
9354       {
9355         const char *p = c_getstr (TREE_VALUE (arglist));
9356
9357         if (p != NULL)
9358           {
9359             /* New argument list transforming fputs(string, stream) to
9360                fputc(string[0], stream).  */
9361             arglist = build_tree_list (NULL_TREE,
9362                                        TREE_VALUE (TREE_CHAIN (arglist)));
9363             arglist = tree_cons (NULL_TREE,
9364                                  build_int_cst (NULL_TREE, p[0]),
9365                                  arglist);
9366             fn = fn_fputc;
9367             break;
9368           }
9369       }
9370       /* FALLTHROUGH */
9371     case 1: /* length is greater than 1, call fwrite.  */
9372       {
9373         tree string_arg;
9374
9375         /* If optimizing for size keep fputs.  */
9376         if (optimize_size)
9377           return 0;
9378         string_arg = TREE_VALUE (arglist);
9379         /* New argument list transforming fputs(string, stream) to
9380            fwrite(string, 1, len, stream).  */
9381         arglist = build_tree_list (NULL_TREE,
9382                                    TREE_VALUE (TREE_CHAIN (arglist)));
9383         arglist = tree_cons (NULL_TREE, len, arglist);
9384         arglist = tree_cons (NULL_TREE, size_one_node, arglist);
9385         arglist = tree_cons (NULL_TREE, string_arg, arglist);
9386         fn = fn_fwrite;
9387         break;
9388       }
9389     default:
9390       gcc_unreachable ();
9391     }
9392
9393   /* If the replacement _DECL isn't initialized, don't do the
9394      transformation.  */
9395   if (!fn)
9396     return 0;
9397
9398   /* These optimizations are only performed when the result is ignored,
9399      hence there's no need to cast the result to integer_type_node.  */
9400   return build_function_call_expr (fn, arglist);
9401 }
9402
9403 /* Fold the new_arg's arguments (ARGLIST). Returns true if there was an error
9404    produced.  False otherwise.  This is done so that we don't output the error
9405    or warning twice or three times.  */
9406 bool
9407 fold_builtin_next_arg (tree arglist)
9408 {
9409   tree fntype = TREE_TYPE (current_function_decl);
9410
9411   if (TYPE_ARG_TYPES (fntype) == 0
9412       || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
9413           == void_type_node))
9414     {
9415       error ("%<va_start%> used in function with fixed args");
9416       return true;
9417     }
9418   else if (!arglist)
9419     {
9420       /* Evidently an out of date version of <stdarg.h>; can't validate
9421          va_start's second argument, but can still work as intended.  */
9422       warning (0, "%<__builtin_next_arg%> called without an argument");
9423       return true;
9424     }
9425   /* We use __builtin_va_start (ap, 0, 0) or __builtin_next_arg (0, 0)
9426      when we checked the arguments and if needed issued a warning.  */
9427   else if (!TREE_CHAIN (arglist)
9428            || !integer_zerop (TREE_VALUE (arglist))
9429            || !integer_zerop (TREE_VALUE (TREE_CHAIN (arglist)))
9430            || TREE_CHAIN (TREE_CHAIN (arglist)))
9431     {
9432       tree last_parm = tree_last (DECL_ARGUMENTS (current_function_decl));
9433       tree arg = TREE_VALUE (arglist);
9434
9435       if (TREE_CHAIN (arglist))
9436         {
9437           error ("%<va_start%> used with too many arguments");
9438           return true;
9439         }
9440
9441       /* Strip off all nops for the sake of the comparison.  This
9442          is not quite the same as STRIP_NOPS.  It does more.
9443          We must also strip off INDIRECT_EXPR for C++ reference
9444          parameters.  */
9445       while (TREE_CODE (arg) == NOP_EXPR
9446              || TREE_CODE (arg) == CONVERT_EXPR
9447              || TREE_CODE (arg) == NON_LVALUE_EXPR
9448              || TREE_CODE (arg) == INDIRECT_REF)
9449         arg = TREE_OPERAND (arg, 0);
9450       if (arg != last_parm)
9451         {
9452           /* FIXME: Sometimes with the tree optimizers we can get the
9453              not the last argument even though the user used the last
9454              argument.  We just warn and set the arg to be the last
9455              argument so that we will get wrong-code because of
9456              it.  */
9457           warning (0, "second parameter of %<va_start%> not last named argument");
9458         }
9459       /* We want to verify the second parameter just once before the tree
9460          optimizers are run and then avoid keeping it in the tree,
9461          as otherwise we could warn even for correct code like:
9462          void foo (int i, ...)
9463          { va_list ap; i++; va_start (ap, i); va_end (ap); }  */
9464       TREE_VALUE (arglist) = integer_zero_node;
9465       TREE_CHAIN (arglist) = build_tree_list (NULL, integer_zero_node);
9466     }
9467   return false;
9468 }
9469
9470
9471 /* Simplify a call to the sprintf builtin.
9472
9473    Return 0 if no simplification was possible, otherwise return the
9474    simplified form of the call as a tree.  If IGNORED is true, it means that
9475    the caller does not use the returned value of the function.  */
9476
9477 static tree
9478 fold_builtin_sprintf (tree arglist, int ignored)
9479 {
9480   tree call, retval, dest, fmt;
9481   const char *fmt_str = NULL;
9482
9483   /* Verify the required arguments in the original call.  We deal with two
9484      types of sprintf() calls: 'sprintf (str, fmt)' and
9485      'sprintf (dest, "%s", orig)'.  */
9486   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)
9487       && !validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, POINTER_TYPE,
9488                             VOID_TYPE))
9489     return NULL_TREE;
9490
9491   /* Get the destination string and the format specifier.  */
9492   dest = TREE_VALUE (arglist);
9493   fmt = TREE_VALUE (TREE_CHAIN (arglist));
9494
9495   /* Check whether the format is a literal string constant.  */
9496   fmt_str = c_getstr (fmt);
9497   if (fmt_str == NULL)
9498     return NULL_TREE;
9499
9500   call = NULL_TREE;
9501   retval = NULL_TREE;
9502
9503   if (!init_target_chars())
9504     return 0;
9505
9506   /* If the format doesn't contain % args or %%, use strcpy.  */
9507   if (strchr (fmt_str, target_percent) == NULL)
9508     {
9509       tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
9510
9511       if (!fn)
9512         return NULL_TREE;
9513
9514       /* Convert sprintf (str, fmt) into strcpy (str, fmt) when
9515          'format' is known to contain no % formats.  */
9516       arglist = build_tree_list (NULL_TREE, fmt);
9517       arglist = tree_cons (NULL_TREE, dest, arglist);
9518       call = build_function_call_expr (fn, arglist);
9519       if (!ignored)
9520         retval = build_int_cst (NULL_TREE, strlen (fmt_str));
9521     }
9522
9523   /* If the format is "%s", use strcpy if the result isn't used.  */
9524   else if (fmt_str && strcmp (fmt_str, target_percent_s) == 0)
9525     {
9526       tree fn, orig;
9527       fn = implicit_built_in_decls[BUILT_IN_STRCPY];
9528
9529       if (!fn)
9530         return NULL_TREE;
9531
9532       /* Convert sprintf (str1, "%s", str2) into strcpy (str1, str2).  */
9533       orig = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
9534       arglist = build_tree_list (NULL_TREE, orig);
9535       arglist = tree_cons (NULL_TREE, dest, arglist);
9536       if (!ignored)
9537         {
9538           retval = c_strlen (orig, 1);
9539           if (!retval || TREE_CODE (retval) != INTEGER_CST)
9540             return NULL_TREE;
9541         }
9542       call = build_function_call_expr (fn, arglist);
9543     }
9544
9545   if (call && retval)
9546     {
9547       retval = convert
9548         (TREE_TYPE (TREE_TYPE (implicit_built_in_decls[BUILT_IN_SPRINTF])),
9549          retval);
9550       return build2 (COMPOUND_EXPR, TREE_TYPE (retval), call, retval);
9551     }
9552   else
9553     return call;
9554 }
9555
9556 /* Expand a call to __builtin_object_size.  */
9557
9558 rtx
9559 expand_builtin_object_size (tree exp)
9560 {
9561   tree ost;
9562   int object_size_type;
9563   tree fndecl = get_callee_fndecl (exp);
9564   tree arglist = TREE_OPERAND (exp, 1);
9565   location_t locus = EXPR_LOCATION (exp);
9566
9567   if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9568     {
9569       error ("%Hfirst argument of %D must be a pointer, second integer constant",
9570              &locus, fndecl);
9571       expand_builtin_trap ();
9572       return const0_rtx;
9573     }
9574
9575   ost = TREE_VALUE (TREE_CHAIN (arglist));
9576   STRIP_NOPS (ost);
9577
9578   if (TREE_CODE (ost) != INTEGER_CST
9579       || tree_int_cst_sgn (ost) < 0
9580       || compare_tree_int (ost, 3) > 0)
9581     {
9582       error ("%Hlast argument of %D is not integer constant between 0 and 3",
9583              &locus, fndecl);
9584       expand_builtin_trap ();
9585       return const0_rtx;
9586     }
9587
9588   object_size_type = tree_low_cst (ost, 0);
9589
9590   return object_size_type < 2 ? constm1_rtx : const0_rtx;
9591 }
9592
9593 /* Expand EXP, a call to the __mem{cpy,pcpy,move,set}_chk builtin.
9594    FCODE is the BUILT_IN_* to use.
9595    Return 0 if we failed; the caller should emit a normal call,
9596    otherwise try to get the result in TARGET, if convenient (and in
9597    mode MODE if that's convenient).  */
9598
9599 static rtx
9600 expand_builtin_memory_chk (tree exp, rtx target, enum machine_mode mode,
9601                            enum built_in_function fcode)
9602 {
9603   tree arglist = TREE_OPERAND (exp, 1);
9604   tree dest, src, len, size;
9605
9606   if (!validate_arglist (arglist,
9607                          POINTER_TYPE,
9608                          fcode == BUILT_IN_MEMSET_CHK
9609                          ? INTEGER_TYPE : POINTER_TYPE,
9610                          INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
9611     return 0;
9612
9613   dest = TREE_VALUE (arglist);
9614   src = TREE_VALUE (TREE_CHAIN (arglist));
9615   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
9616   size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
9617
9618   if (! host_integerp (size, 1))
9619     return 0;
9620
9621   if (host_integerp (len, 1) || integer_all_onesp (size))
9622     {
9623       tree fn;
9624
9625       if (! integer_all_onesp (size) && tree_int_cst_lt (size, len))
9626         {
9627           location_t locus = EXPR_LOCATION (exp);
9628           warning (0, "%Hcall to %D will always overflow destination buffer",
9629                    &locus, get_callee_fndecl (exp));
9630           return 0;
9631         }
9632
9633       arglist = build_tree_list (NULL_TREE, len);
9634       arglist = tree_cons (NULL_TREE, src, arglist);
9635       arglist = tree_cons (NULL_TREE, dest, arglist);
9636
9637       fn = NULL_TREE;
9638       /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume
9639          mem{cpy,pcpy,move,set} is available.  */
9640       switch (fcode)
9641         {
9642         case BUILT_IN_MEMCPY_CHK:
9643           fn = built_in_decls[BUILT_IN_MEMCPY];
9644           break;
9645         case BUILT_IN_MEMPCPY_CHK:
9646           fn = built_in_decls[BUILT_IN_MEMPCPY];
9647           break;
9648         case BUILT_IN_MEMMOVE_CHK:
9649           fn = built_in_decls[BUILT_IN_MEMMOVE];
9650           break;
9651         case BUILT_IN_MEMSET_CHK:
9652           fn = built_in_decls[BUILT_IN_MEMSET];
9653           break;
9654         default:
9655           break;
9656         }
9657
9658       if (! fn)
9659         return 0;
9660
9661       fn = build_function_call_expr (fn, arglist);
9662       if (TREE_CODE (fn) == CALL_EXPR)
9663         CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
9664       return expand_expr (fn, target, mode, EXPAND_NORMAL);
9665     }
9666   else if (fcode == BUILT_IN_MEMSET_CHK)
9667     return 0;
9668   else
9669     {
9670       unsigned int dest_align
9671         = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
9672
9673       /* If DEST is not a pointer type, call the normal function.  */
9674       if (dest_align == 0)
9675         return 0;
9676
9677       /* If SRC and DEST are the same (and not volatile), do nothing.  */
9678       if (operand_equal_p (src, dest, 0))
9679         {
9680           tree expr;
9681
9682           if (fcode != BUILT_IN_MEMPCPY_CHK)
9683             {
9684               /* Evaluate and ignore LEN in case it has side-effects.  */
9685               expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
9686               return expand_expr (dest, target, mode, EXPAND_NORMAL);
9687             }
9688
9689           len = fold_convert (TREE_TYPE (dest), len);
9690           expr = fold_build2 (PLUS_EXPR, TREE_TYPE (dest), dest, len);
9691           return expand_expr (expr, target, mode, EXPAND_NORMAL);
9692         }
9693
9694       /* __memmove_chk special case.  */
9695       if (fcode == BUILT_IN_MEMMOVE_CHK)
9696         {
9697           unsigned int src_align
9698             = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
9699
9700           if (src_align == 0)
9701             return 0;
9702
9703           /* If src is categorized for a readonly section we can use
9704              normal __memcpy_chk.  */
9705           if (readonly_data_expr (src))
9706             {
9707               tree fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
9708               if (!fn)
9709                 return 0;
9710               fn = build_function_call_expr (fn, arglist);
9711               if (TREE_CODE (fn) == CALL_EXPR)
9712                 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
9713               return expand_expr (fn, target, mode, EXPAND_NORMAL);
9714             }
9715         }
9716       return 0;
9717     }
9718 }
9719
9720 /* Emit warning if a buffer overflow is detected at compile time.  */
9721
9722 static void
9723 maybe_emit_chk_warning (tree exp, enum built_in_function fcode)
9724 {
9725   int arg_mask, is_strlen = 0;
9726   tree arglist = TREE_OPERAND (exp, 1), a;
9727   tree len, size;
9728   location_t locus;
9729
9730   switch (fcode)
9731     {
9732     case BUILT_IN_STRCPY_CHK:
9733     case BUILT_IN_STPCPY_CHK:
9734     /* For __strcat_chk the warning will be emitted only if overflowing
9735        by at least strlen (dest) + 1 bytes.  */
9736     case BUILT_IN_STRCAT_CHK:
9737       arg_mask = 6;
9738       is_strlen = 1;
9739       break;
9740     case BUILT_IN_STRNCPY_CHK:
9741       arg_mask = 12;
9742       break;
9743     case BUILT_IN_SNPRINTF_CHK:
9744     case BUILT_IN_VSNPRINTF_CHK:
9745       arg_mask = 10;
9746       break;
9747     default:
9748       gcc_unreachable ();
9749     }
9750
9751   len = NULL_TREE;
9752   size = NULL_TREE;
9753   for (a = arglist; a && arg_mask; a = TREE_CHAIN (a), arg_mask >>= 1)
9754     if (arg_mask & 1)
9755       {
9756         if (len)
9757           size = a;
9758         else
9759           len = a;
9760       }
9761
9762   if (!len || !size)
9763     return;
9764
9765   len = TREE_VALUE (len);
9766   size = TREE_VALUE (size);
9767
9768   if (! host_integerp (size, 1) || integer_all_onesp (size))
9769     return;
9770
9771   if (is_strlen)
9772     {
9773       len = c_strlen (len, 1);
9774       if (! len || ! host_integerp (len, 1) || tree_int_cst_lt (len, size))
9775         return;
9776     }
9777   else if (! host_integerp (len, 1) || ! tree_int_cst_lt (size, len))
9778     return;
9779
9780   locus = EXPR_LOCATION (exp);
9781   warning (0, "%Hcall to %D will always overflow destination buffer",
9782            &locus, get_callee_fndecl (exp));
9783 }
9784
9785 /* Emit warning if a buffer overflow is detected at compile time
9786    in __sprintf_chk/__vsprintf_chk calls.  */
9787
9788 static void
9789 maybe_emit_sprintf_chk_warning (tree exp, enum built_in_function fcode)
9790 {
9791   tree arglist = TREE_OPERAND (exp, 1);
9792   tree dest, size, len, fmt, flag;
9793   const char *fmt_str;
9794
9795   /* Verify the required arguments in the original call.  */
9796   if (! arglist)
9797     return;
9798   dest = TREE_VALUE (arglist);
9799   arglist = TREE_CHAIN (arglist);
9800   if (! arglist)
9801     return;
9802   flag = TREE_VALUE (arglist);
9803   arglist = TREE_CHAIN (arglist);
9804   if (! arglist)
9805     return;
9806   size = TREE_VALUE (arglist);
9807   arglist = TREE_CHAIN (arglist);
9808   if (! arglist)
9809     return;
9810   fmt = TREE_VALUE (arglist);
9811   arglist = TREE_CHAIN (arglist);
9812
9813   if (! host_integerp (size, 1) || integer_all_onesp (size))
9814     return;
9815
9816   /* Check whether the format is a literal string constant.  */
9817   fmt_str = c_getstr (fmt);
9818   if (fmt_str == NULL)
9819     return;
9820
9821   if (!init_target_chars())
9822     return;
9823
9824   /* If the format doesn't contain % args or %%, we know its size.  */
9825   if (strchr (fmt_str, target_percent) == 0)
9826     len = build_int_cstu (size_type_node, strlen (fmt_str));
9827   /* If the format is "%s" and first ... argument is a string literal,
9828      we know it too.  */
9829   else if (fcode == BUILT_IN_SPRINTF_CHK && strcmp (fmt_str, target_percent_s) == 0)
9830     {
9831       tree arg;
9832
9833       if (! arglist)
9834         return;
9835       arg = TREE_VALUE (arglist);
9836       if (! POINTER_TYPE_P (TREE_TYPE (arg)))
9837         return;
9838
9839       len = c_strlen (arg, 1);
9840       if (!len || ! host_integerp (len, 1))
9841         return;
9842     }
9843   else
9844     return;
9845
9846   if (! tree_int_cst_lt (len, size))
9847     {
9848       location_t locus = EXPR_LOCATION (exp);
9849       warning (0, "%Hcall to %D will always overflow destination buffer",
9850                &locus, get_callee_fndecl (exp));
9851     }
9852 }
9853
9854 /* Fold a call to __builtin_object_size, if possible.  */
9855
9856 tree
9857 fold_builtin_object_size (tree arglist)
9858 {
9859   tree ptr, ost, ret = 0;
9860   int object_size_type;
9861
9862   if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9863     return 0;
9864
9865   ptr = TREE_VALUE (arglist);
9866   ost = TREE_VALUE (TREE_CHAIN (arglist));
9867   STRIP_NOPS (ost);
9868
9869   if (TREE_CODE (ost) != INTEGER_CST
9870       || tree_int_cst_sgn (ost) < 0
9871       || compare_tree_int (ost, 3) > 0)
9872     return 0;
9873
9874   object_size_type = tree_low_cst (ost, 0);
9875
9876   /* __builtin_object_size doesn't evaluate side-effects in its arguments;
9877      if there are any side-effects, it returns (size_t) -1 for types 0 and 1
9878      and (size_t) 0 for types 2 and 3.  */
9879   if (TREE_SIDE_EFFECTS (ptr))
9880     return fold_convert (size_type_node,
9881                          object_size_type < 2
9882                          ? integer_minus_one_node : integer_zero_node);
9883
9884   if (TREE_CODE (ptr) == ADDR_EXPR)
9885     ret = build_int_cstu (size_type_node,
9886                         compute_builtin_object_size (ptr, object_size_type));
9887
9888   else if (TREE_CODE (ptr) == SSA_NAME)
9889     {
9890       unsigned HOST_WIDE_INT bytes;
9891
9892       /* If object size is not known yet, delay folding until
9893        later.  Maybe subsequent passes will help determining
9894        it.  */
9895       bytes = compute_builtin_object_size (ptr, object_size_type);
9896       if (bytes != (unsigned HOST_WIDE_INT) (object_size_type < 2
9897                                              ? -1 : 0))
9898         ret = build_int_cstu (size_type_node, bytes);
9899     }
9900
9901   if (ret)
9902     {
9903       ret = force_fit_type (ret, -1, false, false);
9904       if (TREE_CONSTANT_OVERFLOW (ret))
9905         ret = 0;
9906     }
9907
9908   return ret;
9909 }
9910
9911 /* Fold a call to the __mem{cpy,pcpy,move,set}_chk builtin.
9912    IGNORE is true, if return value can be ignored.  FCODE is the BUILT_IN_*
9913    code of the builtin.  If MAXLEN is not NULL, it is maximum length
9914    passed as third argument.  */
9915
9916 tree
9917 fold_builtin_memory_chk (tree fndecl, tree arglist, tree maxlen, bool ignore,
9918                          enum built_in_function fcode)
9919 {
9920   tree dest, src, len, size, fn;
9921
9922   if (!validate_arglist (arglist,
9923                          POINTER_TYPE,
9924                          fcode == BUILT_IN_MEMSET_CHK
9925                          ? INTEGER_TYPE : POINTER_TYPE,
9926                          INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
9927     return 0;
9928
9929   dest = TREE_VALUE (arglist);
9930   /* Actually val for __memset_chk, but it doesn't matter.  */
9931   src = TREE_VALUE (TREE_CHAIN (arglist));
9932   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
9933   size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
9934
9935   /* If SRC and DEST are the same (and not volatile), return DEST
9936      (resp. DEST+LEN for __mempcpy_chk).  */
9937   if (fcode != BUILT_IN_MEMSET_CHK && operand_equal_p (src, dest, 0))
9938     {
9939       if (fcode != BUILT_IN_MEMPCPY_CHK)
9940         return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, len);
9941       else
9942         {
9943           tree temp = fold_convert (TREE_TYPE (dest), len);
9944           temp = fold_build2 (PLUS_EXPR, TREE_TYPE (dest), dest, temp);
9945           return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), temp);
9946         }
9947     }
9948
9949   if (! host_integerp (size, 1))
9950     return 0;
9951
9952   if (! integer_all_onesp (size))
9953     {
9954       if (! host_integerp (len, 1))
9955         {
9956           /* If LEN is not constant, try MAXLEN too.
9957              For MAXLEN only allow optimizing into non-_ocs function
9958              if SIZE is >= MAXLEN, never convert to __ocs_fail ().  */
9959           if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
9960             {
9961               if (fcode == BUILT_IN_MEMPCPY_CHK && ignore)
9962                 {
9963                   /* (void) __mempcpy_chk () can be optimized into
9964                      (void) __memcpy_chk ().  */
9965                   fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
9966                   if (!fn)
9967                     return 0;
9968
9969                   return build_function_call_expr (fn, arglist);
9970                 }
9971               return 0;
9972             }
9973         }
9974       else
9975         maxlen = len;
9976
9977       if (tree_int_cst_lt (size, maxlen))
9978         return 0;
9979     }
9980
9981   arglist = build_tree_list (NULL_TREE, len);
9982   arglist = tree_cons (NULL_TREE, src, arglist);
9983   arglist = tree_cons (NULL_TREE, dest, arglist);
9984
9985   fn = NULL_TREE;
9986   /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume
9987      mem{cpy,pcpy,move,set} is available.  */
9988   switch (fcode)
9989     {
9990     case BUILT_IN_MEMCPY_CHK:
9991       fn = built_in_decls[BUILT_IN_MEMCPY];
9992       break;
9993     case BUILT_IN_MEMPCPY_CHK:
9994       fn = built_in_decls[BUILT_IN_MEMPCPY];
9995       break;
9996     case BUILT_IN_MEMMOVE_CHK:
9997       fn = built_in_decls[BUILT_IN_MEMMOVE];
9998       break;
9999     case BUILT_IN_MEMSET_CHK:
10000       fn = built_in_decls[BUILT_IN_MEMSET];
10001       break;
10002     default:
10003       break;
10004     }
10005
10006   if (!fn)
10007     return 0;
10008
10009   return build_function_call_expr (fn, arglist);
10010 }
10011
10012 /* Fold a call to the __st[rp]cpy_chk builtin.
10013    IGNORE is true, if return value can be ignored.  FCODE is the BUILT_IN_*
10014    code of the builtin.  If MAXLEN is not NULL, it is maximum length of
10015    strings passed as second argument.  */
10016
10017 tree
10018 fold_builtin_stxcpy_chk (tree fndecl, tree arglist, tree maxlen, bool ignore,
10019                          enum built_in_function fcode)
10020 {
10021   tree dest, src, size, len, fn;
10022
10023   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
10024                          VOID_TYPE))
10025     return 0;
10026
10027   dest = TREE_VALUE (arglist);
10028   src = TREE_VALUE (TREE_CHAIN (arglist));
10029   size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10030
10031   /* If SRC and DEST are the same (and not volatile), return DEST.  */
10032   if (fcode == BUILT_IN_STRCPY_CHK && operand_equal_p (src, dest, 0))
10033     return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), dest);
10034  
10035   if (! host_integerp (size, 1))
10036     return 0;
10037
10038   if (! integer_all_onesp (size))
10039     {
10040       len = c_strlen (src, 1);
10041       if (! len || ! host_integerp (len, 1))
10042         {
10043           /* If LEN is not constant, try MAXLEN too.
10044              For MAXLEN only allow optimizing into non-_ocs function
10045              if SIZE is >= MAXLEN, never convert to __ocs_fail ().  */
10046           if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
10047             {
10048               if (fcode == BUILT_IN_STPCPY_CHK)
10049                 {
10050                   if (! ignore)
10051                     return 0;
10052
10053                   /* If return value of __stpcpy_chk is ignored,
10054                      optimize into __strcpy_chk.  */
10055                   fn = built_in_decls[BUILT_IN_STRCPY_CHK];
10056                   if (!fn)
10057                     return 0;
10058
10059                   return build_function_call_expr (fn, arglist);
10060                 }
10061
10062               if (! len || TREE_SIDE_EFFECTS (len))
10063                 return 0;
10064
10065               /* If c_strlen returned something, but not a constant,
10066                  transform __strcpy_chk into __memcpy_chk.  */
10067               fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
10068               if (!fn)
10069                 return 0;
10070
10071               len = size_binop (PLUS_EXPR, len, ssize_int (1));
10072               arglist = build_tree_list (NULL_TREE, size);
10073               arglist = tree_cons (NULL_TREE, len, arglist);
10074               arglist = tree_cons (NULL_TREE, src, arglist);
10075               arglist = tree_cons (NULL_TREE, dest, arglist);
10076               return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)),
10077                                    build_function_call_expr (fn, arglist));
10078             }
10079         }
10080       else
10081         maxlen = len;
10082
10083       if (! tree_int_cst_lt (maxlen, size))
10084         return 0;
10085     }
10086
10087   arglist = build_tree_list (NULL_TREE, src);
10088   arglist = tree_cons (NULL_TREE, dest, arglist);
10089
10090   /* If __builtin_st{r,p}cpy_chk is used, assume st{r,p}cpy is available.  */
10091   fn = built_in_decls[fcode == BUILT_IN_STPCPY_CHK
10092                       ? BUILT_IN_STPCPY : BUILT_IN_STRCPY];
10093   if (!fn)
10094     return 0;
10095
10096   return build_function_call_expr (fn, arglist);
10097 }
10098
10099 /* Fold a call to the __strncpy_chk builtin.
10100    If MAXLEN is not NULL, it is maximum length passed as third argument.  */
10101
10102 tree
10103 fold_builtin_strncpy_chk (tree arglist, tree maxlen)
10104 {
10105   tree dest, src, size, len, fn;
10106
10107   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
10108                          INTEGER_TYPE, VOID_TYPE))
10109     return 0;
10110
10111   dest = TREE_VALUE (arglist);
10112   src = TREE_VALUE (TREE_CHAIN (arglist));
10113   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10114   size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
10115
10116   if (! host_integerp (size, 1))
10117     return 0;
10118
10119   if (! integer_all_onesp (size))
10120     {
10121       if (! host_integerp (len, 1))
10122         {
10123           /* If LEN is not constant, try MAXLEN too.
10124              For MAXLEN only allow optimizing into non-_ocs function
10125              if SIZE is >= MAXLEN, never convert to __ocs_fail ().  */
10126           if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
10127             return 0;
10128         }
10129       else
10130         maxlen = len;
10131
10132       if (tree_int_cst_lt (size, maxlen))
10133         return 0;
10134     }
10135
10136   arglist = build_tree_list (NULL_TREE, len);
10137   arglist = tree_cons (NULL_TREE, src, arglist);
10138   arglist = tree_cons (NULL_TREE, dest, arglist);
10139
10140   /* If __builtin_strncpy_chk is used, assume strncpy is available.  */
10141   fn = built_in_decls[BUILT_IN_STRNCPY];
10142   if (!fn)
10143     return 0;
10144
10145   return build_function_call_expr (fn, arglist);
10146 }
10147
10148 /* Fold a call to the __strcat_chk builtin FNDECL with ARGLIST.  */
10149
10150 static tree
10151 fold_builtin_strcat_chk (tree fndecl, tree arglist)
10152 {
10153   tree dest, src, size, fn;
10154   const char *p;
10155
10156   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
10157                          VOID_TYPE))
10158     return 0;
10159
10160   dest = TREE_VALUE (arglist);
10161   src = TREE_VALUE (TREE_CHAIN (arglist));
10162   size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10163
10164   p = c_getstr (src);
10165   /* If the SRC parameter is "", return DEST.  */
10166   if (p && *p == '\0')
10167     return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
10168
10169   if (! host_integerp (size, 1) || ! integer_all_onesp (size))
10170     return 0;
10171
10172   arglist = build_tree_list (NULL_TREE, src);
10173   arglist = tree_cons (NULL_TREE, dest, arglist);
10174
10175   /* If __builtin_strcat_chk is used, assume strcat is available.  */
10176   fn = built_in_decls[BUILT_IN_STRCAT];
10177   if (!fn)
10178     return 0;
10179
10180   return build_function_call_expr (fn, arglist);
10181 }
10182
10183 /* Fold a call to the __strncat_chk builtin EXP.  */
10184
10185 static tree
10186 fold_builtin_strncat_chk (tree fndecl, tree arglist)
10187 {
10188   tree dest, src, size, len, fn;
10189   const char *p;
10190
10191   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
10192                          INTEGER_TYPE, VOID_TYPE))
10193     return 0;
10194
10195   dest = TREE_VALUE (arglist);
10196   src = TREE_VALUE (TREE_CHAIN (arglist));
10197   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10198   size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
10199
10200   p = c_getstr (src);
10201   /* If the SRC parameter is "" or if LEN is 0, return DEST.  */
10202   if (p && *p == '\0')
10203     return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, len);
10204   else if (integer_zerop (len))
10205     return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
10206
10207   if (! host_integerp (size, 1))
10208     return 0;
10209
10210   if (! integer_all_onesp (size))
10211     {
10212       tree src_len = c_strlen (src, 1);
10213       if (src_len
10214           && host_integerp (src_len, 1)
10215           && host_integerp (len, 1)
10216           && ! tree_int_cst_lt (len, src_len))
10217         {
10218           /* If LEN >= strlen (SRC), optimize into __strcat_chk.  */
10219           fn = built_in_decls[BUILT_IN_STRCAT_CHK];
10220           if (!fn)
10221             return 0;
10222
10223           arglist = build_tree_list (NULL_TREE, size);
10224           arglist = tree_cons (NULL_TREE, src, arglist);
10225           arglist = tree_cons (NULL_TREE, dest, arglist);
10226           return build_function_call_expr (fn, arglist);
10227         }
10228       return 0;
10229     }
10230
10231   arglist = build_tree_list (NULL_TREE, len);
10232   arglist = tree_cons (NULL_TREE, src, arglist);
10233   arglist = tree_cons (NULL_TREE, dest, arglist);
10234
10235   /* If __builtin_strncat_chk is used, assume strncat is available.  */
10236   fn = built_in_decls[BUILT_IN_STRNCAT];
10237   if (!fn)
10238     return 0;
10239
10240   return build_function_call_expr (fn, arglist);
10241 }
10242
10243 /* Fold a call to __{,v}sprintf_chk with argument list ARGLIST.  Return 0 if
10244    a normal call should be emitted rather than expanding the function
10245    inline.  FCODE is either BUILT_IN_SPRINTF_CHK or BUILT_IN_VSPRINTF_CHK.  */
10246
10247 static tree
10248 fold_builtin_sprintf_chk (tree arglist, enum built_in_function fcode)
10249 {
10250   tree dest, size, len, fn, fmt, flag;
10251   const char *fmt_str;
10252
10253   /* Verify the required arguments in the original call.  */
10254   if (! arglist)
10255     return 0;
10256   dest = TREE_VALUE (arglist);
10257   if (! POINTER_TYPE_P (TREE_TYPE (dest)))
10258     return 0;
10259   arglist = TREE_CHAIN (arglist);
10260   if (! arglist)
10261     return 0;
10262   flag = TREE_VALUE (arglist);
10263   if (TREE_CODE (TREE_TYPE (flag)) != INTEGER_TYPE)
10264     return 0;
10265   arglist = TREE_CHAIN (arglist);
10266   if (! arglist)
10267     return 0;
10268   size = TREE_VALUE (arglist);
10269   if (TREE_CODE (TREE_TYPE (size)) != INTEGER_TYPE)
10270     return 0;
10271   arglist = TREE_CHAIN (arglist);
10272   if (! arglist)
10273     return 0;
10274   fmt = TREE_VALUE (arglist);
10275   if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
10276     return 0;
10277   arglist = TREE_CHAIN (arglist);
10278
10279   if (! host_integerp (size, 1))
10280     return 0;
10281
10282   len = NULL_TREE;
10283
10284   if (!init_target_chars())
10285     return 0;
10286
10287   /* Check whether the format is a literal string constant.  */
10288   fmt_str = c_getstr (fmt);
10289   if (fmt_str != NULL)
10290     {
10291       /* If the format doesn't contain % args or %%, we know the size.  */
10292       if (strchr (fmt_str, target_percent) == 0)
10293         {
10294           if (fcode != BUILT_IN_SPRINTF_CHK || arglist == NULL_TREE)
10295             len = build_int_cstu (size_type_node, strlen (fmt_str));
10296         }
10297       /* If the format is "%s" and first ... argument is a string literal,
10298          we know the size too.  */
10299       else if (fcode == BUILT_IN_SPRINTF_CHK && strcmp (fmt_str, target_percent_s) == 0)
10300         {
10301           tree arg;
10302
10303           if (arglist && !TREE_CHAIN (arglist))
10304             {
10305               arg = TREE_VALUE (arglist);
10306               if (POINTER_TYPE_P (TREE_TYPE (arg)))
10307                 {
10308                   len = c_strlen (arg, 1);
10309                   if (! len || ! host_integerp (len, 1))
10310                     len = NULL_TREE;
10311                 }
10312             }
10313         }
10314     }
10315
10316   if (! integer_all_onesp (size))
10317     {
10318       if (! len || ! tree_int_cst_lt (len, size))
10319         return 0;
10320     }
10321
10322   /* Only convert __{,v}sprintf_chk to {,v}sprintf if flag is 0
10323      or if format doesn't contain % chars or is "%s".  */
10324   if (! integer_zerop (flag))
10325     {
10326       if (fmt_str == NULL)
10327         return 0;
10328       if (strchr (fmt_str, target_percent) != NULL && strcmp (fmt_str, target_percent_s))
10329         return 0;
10330     }
10331
10332   arglist = tree_cons (NULL_TREE, fmt, arglist);
10333   arglist = tree_cons (NULL_TREE, dest, arglist);
10334
10335   /* If __builtin_{,v}sprintf_chk is used, assume {,v}sprintf is available.  */
10336   fn = built_in_decls[fcode == BUILT_IN_VSPRINTF_CHK
10337                       ? BUILT_IN_VSPRINTF : BUILT_IN_SPRINTF];
10338   if (!fn)
10339     return 0;
10340
10341   return build_function_call_expr (fn, arglist);
10342 }
10343
10344 /* Fold a call to {,v}snprintf with argument list ARGLIST.  Return 0 if
10345    a normal call should be emitted rather than expanding the function
10346    inline.  FCODE is either BUILT_IN_SNPRINTF_CHK or
10347    BUILT_IN_VSNPRINTF_CHK.  If MAXLEN is not NULL, it is maximum length
10348    passed as second argument.  */
10349
10350 tree
10351 fold_builtin_snprintf_chk (tree arglist, tree maxlen,
10352                            enum built_in_function fcode)
10353 {
10354   tree dest, size, len, fn, fmt, flag;
10355   const char *fmt_str;
10356
10357   /* Verify the required arguments in the original call.  */
10358   if (! arglist)
10359     return 0;
10360   dest = TREE_VALUE (arglist);
10361   if (! POINTER_TYPE_P (TREE_TYPE (dest)))
10362     return 0;
10363   arglist = TREE_CHAIN (arglist);
10364   if (! arglist)
10365     return 0;
10366   len = TREE_VALUE (arglist);
10367   if (TREE_CODE (TREE_TYPE (len)) != INTEGER_TYPE)
10368     return 0;
10369   arglist = TREE_CHAIN (arglist);
10370   if (! arglist)
10371     return 0;
10372   flag = TREE_VALUE (arglist);
10373   if (TREE_CODE (TREE_TYPE (len)) != INTEGER_TYPE)
10374     return 0;
10375   arglist = TREE_CHAIN (arglist);
10376   if (! arglist)
10377     return 0;
10378   size = TREE_VALUE (arglist);
10379   if (TREE_CODE (TREE_TYPE (size)) != INTEGER_TYPE)
10380     return 0;
10381   arglist = TREE_CHAIN (arglist);
10382   if (! arglist)
10383     return 0;
10384   fmt = TREE_VALUE (arglist);
10385   if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
10386     return 0;
10387   arglist = TREE_CHAIN (arglist);
10388
10389   if (! host_integerp (size, 1))
10390     return 0;
10391
10392   if (! integer_all_onesp (size))
10393     {
10394       if (! host_integerp (len, 1))
10395         {
10396           /* If LEN is not constant, try MAXLEN too.
10397              For MAXLEN only allow optimizing into non-_ocs function
10398              if SIZE is >= MAXLEN, never convert to __ocs_fail ().  */
10399           if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
10400             return 0;
10401         }
10402       else
10403         maxlen = len;
10404
10405       if (tree_int_cst_lt (size, maxlen))
10406         return 0;
10407     }
10408
10409   if (!init_target_chars())
10410     return 0;
10411
10412   /* Only convert __{,v}snprintf_chk to {,v}snprintf if flag is 0
10413      or if format doesn't contain % chars or is "%s".  */
10414   if (! integer_zerop (flag))
10415     {
10416       fmt_str = c_getstr (fmt);
10417       if (fmt_str == NULL)
10418         return 0;
10419       if (strchr (fmt_str, target_percent) != NULL && strcmp (fmt_str, target_percent_s))
10420         return 0;
10421     }
10422
10423   arglist = tree_cons (NULL_TREE, fmt, arglist);
10424   arglist = tree_cons (NULL_TREE, len, arglist);
10425   arglist = tree_cons (NULL_TREE, dest, arglist);
10426
10427   /* If __builtin_{,v}snprintf_chk is used, assume {,v}snprintf is
10428      available.  */
10429   fn = built_in_decls[fcode == BUILT_IN_VSNPRINTF_CHK
10430                       ? BUILT_IN_VSNPRINTF : BUILT_IN_SNPRINTF];
10431   if (!fn)
10432     return 0;
10433
10434   return build_function_call_expr (fn, arglist);
10435 }
10436
10437 /* Fold a call to the {,v}printf{,_unlocked} and __{,v}printf_chk builtins.
10438
10439    Return 0 if no simplification was possible, otherwise return the
10440    simplified form of the call as a tree.  FCODE is the BUILT_IN_*
10441    code of the function to be simplified.  */
10442
10443 static tree
10444 fold_builtin_printf (tree fndecl, tree arglist, bool ignore,
10445                      enum built_in_function fcode)
10446 {
10447   tree fmt, fn = NULL_TREE, fn_putchar, fn_puts, arg, call;
10448   const char *fmt_str = NULL;
10449
10450   /* If the return value is used, don't do the transformation.  */
10451   if (! ignore)
10452     return 0;
10453
10454   /* Verify the required arguments in the original call.  */
10455   if (fcode == BUILT_IN_PRINTF_CHK || fcode == BUILT_IN_VPRINTF_CHK)
10456     {
10457       tree flag;
10458
10459       if (! arglist)
10460         return 0;
10461       flag = TREE_VALUE (arglist);
10462       if (TREE_CODE (TREE_TYPE (flag)) != INTEGER_TYPE
10463           || TREE_SIDE_EFFECTS (flag))
10464         return 0;
10465       arglist = TREE_CHAIN (arglist);
10466     }
10467
10468   if (! arglist)
10469     return 0;
10470   fmt = TREE_VALUE (arglist);
10471   if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
10472     return 0;
10473   arglist = TREE_CHAIN (arglist);
10474
10475   /* Check whether the format is a literal string constant.  */
10476   fmt_str = c_getstr (fmt);
10477   if (fmt_str == NULL)
10478     return NULL_TREE;
10479
10480   if (fcode == BUILT_IN_PRINTF_UNLOCKED)
10481     {
10482       /* If we're using an unlocked function, assume the other
10483          unlocked functions exist explicitly.  */
10484       fn_putchar = built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED];
10485       fn_puts = built_in_decls[BUILT_IN_PUTS_UNLOCKED];
10486     }
10487   else
10488     {
10489       fn_putchar = implicit_built_in_decls[BUILT_IN_PUTCHAR];
10490       fn_puts = implicit_built_in_decls[BUILT_IN_PUTS];
10491     }
10492
10493   if (!init_target_chars())
10494     return 0;
10495   
10496   if (strcmp (fmt_str, target_percent_s) == 0 || strchr (fmt_str, target_percent) == NULL)
10497     {
10498       const char *str;
10499
10500       if (strcmp (fmt_str, target_percent_s) == 0)
10501         {
10502           if (fcode == BUILT_IN_VPRINTF || fcode == BUILT_IN_VPRINTF_CHK)
10503             return 0;
10504
10505           if (! arglist
10506               || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
10507               || TREE_CHAIN (arglist))
10508             return 0;
10509
10510           str = c_getstr (TREE_VALUE (arglist));
10511           if (str == NULL)
10512             return 0;
10513         }
10514       else
10515         {
10516           /* The format specifier doesn't contain any '%' characters.  */
10517           if (fcode != BUILT_IN_VPRINTF && fcode != BUILT_IN_VPRINTF_CHK
10518               && arglist)
10519             return 0;
10520           str = fmt_str;
10521         }
10522
10523       /* If the string was "", printf does nothing.  */
10524       if (str[0] == '\0')
10525         return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), 0);
10526
10527       /* If the string has length of 1, call putchar.  */
10528       if (str[1] == '\0')
10529         {
10530           /* Given printf("c"), (where c is any one character,)
10531              convert "c"[0] to an int and pass that to the replacement
10532              function.  */
10533           arg = build_int_cst (NULL_TREE, str[0]);
10534           arglist = build_tree_list (NULL_TREE, arg);
10535           fn = fn_putchar;
10536         }
10537       else
10538         {
10539           /* If the string was "string\n", call puts("string").  */
10540           size_t len = strlen (str);
10541           if ((unsigned char)str[len - 1] == target_newline)
10542             {
10543               /* Create a NUL-terminated string that's one char shorter
10544                  than the original, stripping off the trailing '\n'.  */
10545               char *newstr = alloca (len);
10546               memcpy (newstr, str, len - 1);
10547               newstr[len - 1] = 0;
10548
10549               arg = build_string_literal (len, newstr);
10550               arglist = build_tree_list (NULL_TREE, arg);
10551               fn = fn_puts;
10552             }
10553           else
10554             /* We'd like to arrange to call fputs(string,stdout) here,
10555                but we need stdout and don't have a way to get it yet.  */
10556             return 0;
10557         }
10558     }
10559
10560   /* The other optimizations can be done only on the non-va_list variants.  */
10561   else if (fcode == BUILT_IN_VPRINTF || fcode == BUILT_IN_VPRINTF_CHK)
10562     return 0;
10563
10564   /* If the format specifier was "%s\n", call __builtin_puts(arg).  */
10565   else if (strcmp (fmt_str, target_percent_s_newline) == 0)
10566     {
10567       if (! arglist
10568           || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
10569           || TREE_CHAIN (arglist))
10570         return 0;
10571       fn = fn_puts;
10572     }
10573
10574   /* If the format specifier was "%c", call __builtin_putchar(arg).  */
10575   else if (strcmp (fmt_str, target_percent_c) == 0)
10576     {
10577       if (! arglist
10578           || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
10579           || TREE_CHAIN (arglist))
10580         return 0;
10581       fn = fn_putchar;
10582     }
10583
10584   if (!fn)
10585     return 0;
10586
10587   call = build_function_call_expr (fn, arglist);
10588   return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), call);
10589 }
10590
10591 /* Fold a call to the {,v}fprintf{,_unlocked} and __{,v}printf_chk builtins.
10592
10593    Return 0 if no simplification was possible, otherwise return the
10594    simplified form of the call as a tree.  FCODE is the BUILT_IN_*
10595    code of the function to be simplified.  */
10596
10597 static tree
10598 fold_builtin_fprintf (tree fndecl, tree arglist, bool ignore,
10599                       enum built_in_function fcode)
10600 {
10601   tree fp, fmt, fn = NULL_TREE, fn_fputc, fn_fputs, arg, call;
10602   const char *fmt_str = NULL;
10603
10604   /* If the return value is used, don't do the transformation.  */
10605   if (! ignore)
10606     return 0;
10607
10608   /* Verify the required arguments in the original call.  */
10609   if (! arglist)
10610     return 0;
10611   fp = TREE_VALUE (arglist);
10612   if (! POINTER_TYPE_P (TREE_TYPE (fp)))
10613     return 0;
10614   arglist = TREE_CHAIN (arglist);
10615
10616   if (fcode == BUILT_IN_FPRINTF_CHK || fcode == BUILT_IN_VFPRINTF_CHK)
10617     {
10618       tree flag;
10619
10620       if (! arglist)
10621         return 0;
10622       flag = TREE_VALUE (arglist);
10623       if (TREE_CODE (TREE_TYPE (flag)) != INTEGER_TYPE
10624           || TREE_SIDE_EFFECTS (flag))
10625         return 0;
10626       arglist = TREE_CHAIN (arglist);
10627     }
10628
10629   if (! arglist)
10630     return 0;
10631   fmt = TREE_VALUE (arglist);
10632   if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
10633     return 0;
10634   arglist = TREE_CHAIN (arglist);
10635
10636   /* Check whether the format is a literal string constant.  */
10637   fmt_str = c_getstr (fmt);
10638   if (fmt_str == NULL)
10639     return NULL_TREE;
10640
10641   if (fcode == BUILT_IN_FPRINTF_UNLOCKED)
10642     {
10643       /* If we're using an unlocked function, assume the other
10644          unlocked functions exist explicitly.  */
10645       fn_fputc = built_in_decls[BUILT_IN_FPUTC_UNLOCKED];
10646       fn_fputs = built_in_decls[BUILT_IN_FPUTS_UNLOCKED];
10647     }
10648   else
10649     {
10650       fn_fputc = implicit_built_in_decls[BUILT_IN_FPUTC];
10651       fn_fputs = implicit_built_in_decls[BUILT_IN_FPUTS];
10652     }
10653
10654   if (!init_target_chars())
10655     return 0;
10656   
10657   /* If the format doesn't contain % args or %%, use strcpy.  */
10658   if (strchr (fmt_str, target_percent) == NULL)
10659     {
10660       if (fcode != BUILT_IN_VFPRINTF && fcode != BUILT_IN_VFPRINTF_CHK
10661           && arglist)
10662         return 0;
10663
10664       /* If the format specifier was "", fprintf does nothing.  */
10665       if (fmt_str[0] == '\0')
10666         {
10667           /* If FP has side-effects, just wait until gimplification is
10668              done.  */
10669           if (TREE_SIDE_EFFECTS (fp))
10670             return 0;
10671
10672           return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), 0);
10673         }
10674
10675       /* When "string" doesn't contain %, replace all cases of
10676          fprintf (fp, string) with fputs (string, fp).  The fputs
10677          builtin will take care of special cases like length == 1.  */
10678       arglist = build_tree_list (NULL_TREE, fp);
10679       arglist = tree_cons (NULL_TREE, fmt, arglist);
10680       fn = fn_fputs;
10681     }
10682
10683   /* The other optimizations can be done only on the non-va_list variants.  */
10684   else if (fcode == BUILT_IN_VFPRINTF || fcode == BUILT_IN_VFPRINTF_CHK)
10685     return 0;
10686
10687   /* If the format specifier was "%s", call __builtin_fputs (arg, fp).  */
10688   else if (strcmp (fmt_str, target_percent_s) == 0)
10689     {
10690       if (! arglist
10691           || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
10692           || TREE_CHAIN (arglist))
10693         return 0;
10694       arg = TREE_VALUE (arglist);
10695       arglist = build_tree_list (NULL_TREE, fp);
10696       arglist = tree_cons (NULL_TREE, arg, arglist);
10697       fn = fn_fputs;
10698     }
10699
10700   /* If the format specifier was "%c", call __builtin_fputc (arg, fp).  */
10701   else if (strcmp (fmt_str, target_percent_c) == 0)
10702     {
10703       if (! arglist
10704           || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
10705           || TREE_CHAIN (arglist))
10706         return 0;
10707       arg = TREE_VALUE (arglist);
10708       arglist = build_tree_list (NULL_TREE, fp);
10709       arglist = tree_cons (NULL_TREE, arg, arglist);
10710       fn = fn_fputc;
10711     }
10712
10713   if (!fn)
10714     return 0;
10715
10716   call = build_function_call_expr (fn, arglist);
10717   return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), call);
10718 }
10719
10720 /* Initialize format string characters in the target charset.  */
10721
10722 static bool
10723 init_target_chars (void)
10724 {
10725   static bool init;
10726   if (!init)
10727     {
10728       target_newline = lang_hooks.to_target_charset ('\n');
10729       target_percent = lang_hooks.to_target_charset ('%');
10730       target_c = lang_hooks.to_target_charset ('c');
10731       target_s = lang_hooks.to_target_charset ('s');
10732       if (target_newline == 0 || target_percent == 0 || target_c == 0
10733           || target_s == 0)
10734         return false;
10735
10736       target_percent_c[0] = target_percent;
10737       target_percent_c[1] = target_c;
10738       target_percent_c[2] = '\0';
10739
10740       target_percent_s[0] = target_percent;
10741       target_percent_s[1] = target_s;
10742       target_percent_s[2] = '\0';
10743
10744       target_percent_s_newline[0] = target_percent;
10745       target_percent_s_newline[1] = target_s;
10746       target_percent_s_newline[2] = target_newline;
10747       target_percent_s_newline[3] = '\0';
10748       
10749       init = true;
10750     }
10751   return true;
10752 }