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