OSDN Git Service

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