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