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