OSDN Git Service

* lib/target-supports-dg.exp (check-flags): New.
[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   else
5602     {
5603       /* Try expanding the builtin via the generic target hook.  */
5604       rtx tmp = targetm.expand_library_builtin (exp, target, subtarget,
5605                                                 mode, ignore);
5606       if (tmp != NULL_RTX)
5607         return tmp;
5608     }
5609
5610   /* When not optimizing, generate calls to library functions for a certain
5611      set of builtins.  */
5612   if (!optimize
5613       && !called_as_built_in (fndecl)
5614       && DECL_ASSEMBLER_NAME_SET_P (fndecl)
5615       && fcode != BUILT_IN_ALLOCA)
5616     return expand_call (exp, target, ignore);
5617
5618   /* The built-in function expanders test for target == const0_rtx
5619      to determine whether the function's result will be ignored.  */
5620   if (ignore)
5621     target = const0_rtx;
5622
5623   /* If the result of a pure or const built-in function is ignored, and
5624      none of its arguments are volatile, we can avoid expanding the
5625      built-in call and just evaluate the arguments for side-effects.  */
5626   if (target == const0_rtx
5627       && (DECL_IS_PURE (fndecl) || TREE_READONLY (fndecl)))
5628     {
5629       bool volatilep = false;
5630       tree arg;
5631
5632       for (arg = arglist; arg; arg = TREE_CHAIN (arg))
5633         if (TREE_THIS_VOLATILE (TREE_VALUE (arg)))
5634           {
5635             volatilep = true;
5636             break;
5637           }
5638
5639       if (! volatilep)
5640         {
5641           for (arg = arglist; arg; arg = TREE_CHAIN (arg))
5642             expand_expr (TREE_VALUE (arg), const0_rtx,
5643                          VOIDmode, EXPAND_NORMAL);
5644           return const0_rtx;
5645         }
5646     }
5647
5648   switch (fcode)
5649     {
5650     CASE_FLT_FN (BUILT_IN_FABS):
5651       target = expand_builtin_fabs (arglist, target, subtarget);
5652       if (target)
5653         return target;
5654       break;
5655
5656     CASE_FLT_FN (BUILT_IN_COPYSIGN):
5657       target = expand_builtin_copysign (arglist, target, subtarget);
5658       if (target)
5659         return target;
5660       break;
5661
5662       /* Just do a normal library call if we were unable to fold
5663          the values.  */
5664     CASE_FLT_FN (BUILT_IN_CABS):
5665       break;
5666
5667     CASE_FLT_FN (BUILT_IN_EXP):
5668     CASE_FLT_FN (BUILT_IN_EXP10):
5669     CASE_FLT_FN (BUILT_IN_POW10):
5670     CASE_FLT_FN (BUILT_IN_EXP2):
5671     CASE_FLT_FN (BUILT_IN_EXPM1):
5672     CASE_FLT_FN (BUILT_IN_LOGB):
5673     CASE_FLT_FN (BUILT_IN_ILOGB):
5674     CASE_FLT_FN (BUILT_IN_LOG):
5675     CASE_FLT_FN (BUILT_IN_LOG10):
5676     CASE_FLT_FN (BUILT_IN_LOG2):
5677     CASE_FLT_FN (BUILT_IN_LOG1P):
5678     CASE_FLT_FN (BUILT_IN_TAN):
5679     CASE_FLT_FN (BUILT_IN_ASIN):
5680     CASE_FLT_FN (BUILT_IN_ACOS):
5681     CASE_FLT_FN (BUILT_IN_ATAN):
5682       /* Treat these like sqrt only if unsafe math optimizations are allowed,
5683          because of possible accuracy problems.  */
5684       if (! flag_unsafe_math_optimizations)
5685         break;
5686     CASE_FLT_FN (BUILT_IN_SQRT):
5687     CASE_FLT_FN (BUILT_IN_FLOOR):
5688     CASE_FLT_FN (BUILT_IN_CEIL):
5689     CASE_FLT_FN (BUILT_IN_TRUNC):
5690     CASE_FLT_FN (BUILT_IN_ROUND):
5691     CASE_FLT_FN (BUILT_IN_NEARBYINT):
5692     CASE_FLT_FN (BUILT_IN_RINT):
5693     CASE_FLT_FN (BUILT_IN_LRINT):
5694     CASE_FLT_FN (BUILT_IN_LLRINT):
5695       target = expand_builtin_mathfn (exp, target, subtarget);
5696       if (target)
5697         return target;
5698       break;
5699
5700     CASE_FLT_FN (BUILT_IN_LCEIL):
5701     CASE_FLT_FN (BUILT_IN_LLCEIL):
5702     CASE_FLT_FN (BUILT_IN_LFLOOR):
5703     CASE_FLT_FN (BUILT_IN_LLFLOOR):
5704       target = expand_builtin_int_roundingfn (exp, target, subtarget);
5705       if (target)
5706         return target;
5707       break;
5708
5709     CASE_FLT_FN (BUILT_IN_POW):
5710       target = expand_builtin_pow (exp, target, subtarget);
5711       if (target)
5712         return target;
5713       break;
5714
5715     CASE_FLT_FN (BUILT_IN_POWI):
5716       target = expand_builtin_powi (exp, target, subtarget);
5717       if (target)
5718         return target;
5719       break;
5720
5721     CASE_FLT_FN (BUILT_IN_ATAN2):
5722     CASE_FLT_FN (BUILT_IN_LDEXP):
5723     CASE_FLT_FN (BUILT_IN_FMOD):
5724     CASE_FLT_FN (BUILT_IN_DREM):
5725       if (! flag_unsafe_math_optimizations)
5726         break;
5727       target = expand_builtin_mathfn_2 (exp, target, subtarget);
5728       if (target)
5729         return target;
5730       break;
5731
5732     CASE_FLT_FN (BUILT_IN_SIN):
5733     CASE_FLT_FN (BUILT_IN_COS):
5734       if (! flag_unsafe_math_optimizations)
5735         break;
5736       target = expand_builtin_mathfn_3 (exp, target, subtarget);
5737       if (target)
5738         return target;
5739       break;
5740
5741     CASE_FLT_FN (BUILT_IN_SINCOS):
5742       if (! flag_unsafe_math_optimizations)
5743         break;
5744       target = expand_builtin_sincos (exp);
5745       if (target)
5746         return target;
5747       break;
5748
5749     case BUILT_IN_APPLY_ARGS:
5750       return expand_builtin_apply_args ();
5751
5752       /* __builtin_apply (FUNCTION, ARGUMENTS, ARGSIZE) invokes
5753          FUNCTION with a copy of the parameters described by
5754          ARGUMENTS, and ARGSIZE.  It returns a block of memory
5755          allocated on the stack into which is stored all the registers
5756          that might possibly be used for returning the result of a
5757          function.  ARGUMENTS is the value returned by
5758          __builtin_apply_args.  ARGSIZE is the number of bytes of
5759          arguments that must be copied.  ??? How should this value be
5760          computed?  We'll also need a safe worst case value for varargs
5761          functions.  */
5762     case BUILT_IN_APPLY:
5763       if (!validate_arglist (arglist, POINTER_TYPE,
5764                              POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)
5765           && !validate_arglist (arglist, REFERENCE_TYPE,
5766                                 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
5767         return const0_rtx;
5768       else
5769         {
5770           int i;
5771           tree t;
5772           rtx ops[3];
5773
5774           for (t = arglist, i = 0; t; t = TREE_CHAIN (t), i++)
5775             ops[i] = expand_normal (TREE_VALUE (t));
5776
5777           return expand_builtin_apply (ops[0], ops[1], ops[2]);
5778         }
5779
5780       /* __builtin_return (RESULT) causes the function to return the
5781          value described by RESULT.  RESULT is address of the block of
5782          memory returned by __builtin_apply.  */
5783     case BUILT_IN_RETURN:
5784       if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5785         expand_builtin_return (expand_normal (TREE_VALUE (arglist)));
5786       return const0_rtx;
5787
5788     case BUILT_IN_SAVEREGS:
5789       return expand_builtin_saveregs ();
5790
5791     case BUILT_IN_ARGS_INFO:
5792       return expand_builtin_args_info (arglist);
5793
5794       /* Return the address of the first anonymous stack arg.  */
5795     case BUILT_IN_NEXT_ARG:
5796       if (fold_builtin_next_arg (arglist))
5797         return const0_rtx;
5798       return expand_builtin_next_arg ();
5799
5800     case BUILT_IN_CLASSIFY_TYPE:
5801       return expand_builtin_classify_type (arglist);
5802
5803     case BUILT_IN_CONSTANT_P:
5804       return const0_rtx;
5805
5806     case BUILT_IN_FRAME_ADDRESS:
5807     case BUILT_IN_RETURN_ADDRESS:
5808       return expand_builtin_frame_address (fndecl, arglist);
5809
5810     /* Returns the address of the area where the structure is returned.
5811        0 otherwise.  */
5812     case BUILT_IN_AGGREGATE_INCOMING_ADDRESS:
5813       if (arglist != 0
5814           || ! AGGREGATE_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl)))
5815           || !MEM_P (DECL_RTL (DECL_RESULT (current_function_decl))))
5816         return const0_rtx;
5817       else
5818         return XEXP (DECL_RTL (DECL_RESULT (current_function_decl)), 0);
5819
5820     case BUILT_IN_ALLOCA:
5821       target = expand_builtin_alloca (arglist, target);
5822       if (target)
5823         return target;
5824       break;
5825
5826     case BUILT_IN_STACK_SAVE:
5827       return expand_stack_save ();
5828
5829     case BUILT_IN_STACK_RESTORE:
5830       expand_stack_restore (TREE_VALUE (arglist));
5831       return const0_rtx;
5832
5833     CASE_INT_FN (BUILT_IN_FFS):
5834     case BUILT_IN_FFSIMAX:
5835       target = expand_builtin_unop (target_mode, arglist, target,
5836                                     subtarget, ffs_optab);
5837       if (target)
5838         return target;
5839       break;
5840
5841     CASE_INT_FN (BUILT_IN_CLZ):
5842     case BUILT_IN_CLZIMAX:
5843       target = expand_builtin_unop (target_mode, arglist, target,
5844                                     subtarget, clz_optab);
5845       if (target)
5846         return target;
5847       break;
5848
5849     CASE_INT_FN (BUILT_IN_CTZ):
5850     case BUILT_IN_CTZIMAX:
5851       target = expand_builtin_unop (target_mode, arglist, target,
5852                                     subtarget, ctz_optab);
5853       if (target)
5854         return target;
5855       break;
5856
5857     CASE_INT_FN (BUILT_IN_POPCOUNT):
5858     case BUILT_IN_POPCOUNTIMAX:
5859       target = expand_builtin_unop (target_mode, arglist, target,
5860                                     subtarget, popcount_optab);
5861       if (target)
5862         return target;
5863       break;
5864
5865     CASE_INT_FN (BUILT_IN_PARITY):
5866     case BUILT_IN_PARITYIMAX:
5867       target = expand_builtin_unop (target_mode, arglist, target,
5868                                     subtarget, parity_optab);
5869       if (target)
5870         return target;
5871       break;
5872
5873     case BUILT_IN_STRLEN:
5874       target = expand_builtin_strlen (arglist, target, target_mode);
5875       if (target)
5876         return target;
5877       break;
5878
5879     case BUILT_IN_STRCPY:
5880       target = expand_builtin_strcpy (fndecl, arglist, target, mode);
5881       if (target)
5882         return target;
5883       break;
5884
5885     case BUILT_IN_STRNCPY:
5886       target = expand_builtin_strncpy (exp, target, mode);
5887       if (target)
5888         return target;
5889       break;
5890
5891     case BUILT_IN_STPCPY:
5892       target = expand_builtin_stpcpy (exp, target, mode);
5893       if (target)
5894         return target;
5895       break;
5896
5897     case BUILT_IN_STRCAT:
5898       target = expand_builtin_strcat (fndecl, arglist, target, mode);
5899       if (target)
5900         return target;
5901       break;
5902
5903     case BUILT_IN_STRNCAT:
5904       target = expand_builtin_strncat (arglist, target, mode);
5905       if (target)
5906         return target;
5907       break;
5908
5909     case BUILT_IN_STRSPN:
5910       target = expand_builtin_strspn (arglist, target, mode);
5911       if (target)
5912         return target;
5913       break;
5914
5915     case BUILT_IN_STRCSPN:
5916       target = expand_builtin_strcspn (arglist, target, mode);
5917       if (target)
5918         return target;
5919       break;
5920
5921     case BUILT_IN_STRSTR:
5922       target = expand_builtin_strstr (arglist, TREE_TYPE (exp), target, mode);
5923       if (target)
5924         return target;
5925       break;
5926
5927     case BUILT_IN_STRPBRK:
5928       target = expand_builtin_strpbrk (arglist, TREE_TYPE (exp), target, mode);
5929       if (target)
5930         return target;
5931       break;
5932
5933     case BUILT_IN_INDEX:
5934     case BUILT_IN_STRCHR:
5935       target = expand_builtin_strchr (arglist, TREE_TYPE (exp), target, mode);
5936       if (target)
5937         return target;
5938       break;
5939
5940     case BUILT_IN_RINDEX:
5941     case BUILT_IN_STRRCHR:
5942       target = expand_builtin_strrchr (arglist, TREE_TYPE (exp), target, mode);
5943       if (target)
5944         return target;
5945       break;
5946
5947     case BUILT_IN_MEMCPY:
5948       target = expand_builtin_memcpy (exp, target, mode);
5949       if (target)
5950         return target;
5951       break;
5952
5953     case BUILT_IN_MEMPCPY:
5954       target = expand_builtin_mempcpy (arglist, TREE_TYPE (exp), target, mode, /*endp=*/ 1);
5955       if (target)
5956         return target;
5957       break;
5958
5959     case BUILT_IN_MEMMOVE:
5960       target = expand_builtin_memmove (arglist, TREE_TYPE (exp), target,
5961                                        mode, exp);
5962       if (target)
5963         return target;
5964       break;
5965
5966     case BUILT_IN_BCOPY:
5967       target = expand_builtin_bcopy (exp);
5968       if (target)
5969         return target;
5970       break;
5971
5972     case BUILT_IN_MEMSET:
5973       target = expand_builtin_memset (arglist, target, mode, exp);
5974       if (target)
5975         return target;
5976       break;
5977
5978     case BUILT_IN_BZERO:
5979       target = expand_builtin_bzero (exp);
5980       if (target)
5981         return target;
5982       break;
5983
5984     case BUILT_IN_STRCMP:
5985       target = expand_builtin_strcmp (exp, target, mode);
5986       if (target)
5987         return target;
5988       break;
5989
5990     case BUILT_IN_STRNCMP:
5991       target = expand_builtin_strncmp (exp, target, mode);
5992       if (target)
5993         return target;
5994       break;
5995
5996     case BUILT_IN_BCMP:
5997     case BUILT_IN_MEMCMP:
5998       target = expand_builtin_memcmp (exp, arglist, target, mode);
5999       if (target)
6000         return target;
6001       break;
6002
6003     case BUILT_IN_SETJMP:
6004       target = expand_builtin_setjmp (arglist, target);
6005       if (target)
6006         return target;
6007       break;
6008
6009       /* __builtin_longjmp is passed a pointer to an array of five words.
6010          It's similar to the C library longjmp function but works with
6011          __builtin_setjmp above.  */
6012     case BUILT_IN_LONGJMP:
6013       if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
6014         break;
6015       else
6016         {
6017           rtx buf_addr = expand_expr (TREE_VALUE (arglist), subtarget,
6018                                       VOIDmode, EXPAND_NORMAL);
6019           rtx value = expand_normal (TREE_VALUE (TREE_CHAIN (arglist)));
6020
6021           if (value != const1_rtx)
6022             {
6023               error ("%<__builtin_longjmp%> second argument must be 1");
6024               return const0_rtx;
6025             }
6026
6027           expand_builtin_longjmp (buf_addr, value);
6028           return const0_rtx;
6029         }
6030
6031     case BUILT_IN_NONLOCAL_GOTO:
6032       target = expand_builtin_nonlocal_goto (arglist);
6033       if (target)
6034         return target;
6035       break;
6036
6037       /* This updates the setjmp buffer that is its argument with the value
6038          of the current stack pointer.  */
6039     case BUILT_IN_UPDATE_SETJMP_BUF:
6040       if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6041         {
6042           rtx buf_addr
6043             = expand_normal (TREE_VALUE (arglist));
6044
6045           expand_builtin_update_setjmp_buf (buf_addr);
6046           return const0_rtx;
6047         }
6048       break;
6049
6050     case BUILT_IN_TRAP:
6051       expand_builtin_trap ();
6052       return const0_rtx;
6053
6054     case BUILT_IN_PRINTF:
6055       target = expand_builtin_printf (exp, target, mode, false);
6056       if (target)
6057         return target;
6058       break;
6059
6060     case BUILT_IN_PRINTF_UNLOCKED:
6061       target = expand_builtin_printf (exp, target, mode, true);
6062       if (target)
6063         return target;
6064       break;
6065
6066     case BUILT_IN_FPUTS:
6067       target = expand_builtin_fputs (arglist, target, false);
6068       if (target)
6069         return target;
6070       break;
6071     case BUILT_IN_FPUTS_UNLOCKED:
6072       target = expand_builtin_fputs (arglist, target, true);
6073       if (target)
6074         return target;
6075       break;
6076
6077     case BUILT_IN_FPRINTF:
6078       target = expand_builtin_fprintf (exp, target, mode, false);
6079       if (target)
6080         return target;
6081       break;
6082
6083     case BUILT_IN_FPRINTF_UNLOCKED:
6084       target = expand_builtin_fprintf (exp, target, mode, true);
6085       if (target)
6086         return target;
6087       break;
6088
6089     case BUILT_IN_SPRINTF:
6090       target = expand_builtin_sprintf (arglist, target, mode);
6091       if (target)
6092         return target;
6093       break;
6094
6095     CASE_FLT_FN (BUILT_IN_SIGNBIT):
6096       target = expand_builtin_signbit (exp, target);
6097       if (target)
6098         return target;
6099       break;
6100
6101       /* Various hooks for the DWARF 2 __throw routine.  */
6102     case BUILT_IN_UNWIND_INIT:
6103       expand_builtin_unwind_init ();
6104       return const0_rtx;
6105     case BUILT_IN_DWARF_CFA:
6106       return virtual_cfa_rtx;
6107 #ifdef DWARF2_UNWIND_INFO
6108     case BUILT_IN_DWARF_SP_COLUMN:
6109       return expand_builtin_dwarf_sp_column ();
6110     case BUILT_IN_INIT_DWARF_REG_SIZES:
6111       expand_builtin_init_dwarf_reg_sizes (TREE_VALUE (arglist));
6112       return const0_rtx;
6113 #endif
6114     case BUILT_IN_FROB_RETURN_ADDR:
6115       return expand_builtin_frob_return_addr (TREE_VALUE (arglist));
6116     case BUILT_IN_EXTRACT_RETURN_ADDR:
6117       return expand_builtin_extract_return_addr (TREE_VALUE (arglist));
6118     case BUILT_IN_EH_RETURN:
6119       expand_builtin_eh_return (TREE_VALUE (arglist),
6120                                 TREE_VALUE (TREE_CHAIN (arglist)));
6121       return const0_rtx;
6122 #ifdef EH_RETURN_DATA_REGNO
6123     case BUILT_IN_EH_RETURN_DATA_REGNO:
6124       return expand_builtin_eh_return_data_regno (arglist);
6125 #endif
6126     case BUILT_IN_EXTEND_POINTER:
6127       return expand_builtin_extend_pointer (TREE_VALUE (arglist));
6128
6129     case BUILT_IN_VA_START:
6130     case BUILT_IN_STDARG_START:
6131       return expand_builtin_va_start (arglist);
6132     case BUILT_IN_VA_END:
6133       return expand_builtin_va_end (arglist);
6134     case BUILT_IN_VA_COPY:
6135       return expand_builtin_va_copy (arglist);
6136     case BUILT_IN_EXPECT:
6137       return expand_builtin_expect (arglist, target);
6138     case BUILT_IN_PREFETCH:
6139       expand_builtin_prefetch (arglist);
6140       return const0_rtx;
6141
6142     case BUILT_IN_PROFILE_FUNC_ENTER:
6143       return expand_builtin_profile_func (false);
6144     case BUILT_IN_PROFILE_FUNC_EXIT:
6145       return expand_builtin_profile_func (true);
6146
6147     case BUILT_IN_INIT_TRAMPOLINE:
6148       return expand_builtin_init_trampoline (arglist);
6149     case BUILT_IN_ADJUST_TRAMPOLINE:
6150       return expand_builtin_adjust_trampoline (arglist);
6151
6152     case BUILT_IN_FORK:
6153     case BUILT_IN_EXECL:
6154     case BUILT_IN_EXECV:
6155     case BUILT_IN_EXECLP:
6156     case BUILT_IN_EXECLE:
6157     case BUILT_IN_EXECVP:
6158     case BUILT_IN_EXECVE:
6159       target = expand_builtin_fork_or_exec (fndecl, arglist, target, ignore);
6160       if (target)
6161         return target;
6162       break;
6163
6164     case BUILT_IN_FETCH_AND_ADD_1:
6165     case BUILT_IN_FETCH_AND_ADD_2:
6166     case BUILT_IN_FETCH_AND_ADD_4:
6167     case BUILT_IN_FETCH_AND_ADD_8:
6168     case BUILT_IN_FETCH_AND_ADD_16:
6169       mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_ADD_1);
6170       target = expand_builtin_sync_operation (mode, arglist, PLUS,
6171                                               false, target, ignore);
6172       if (target)
6173         return target;
6174       break;
6175
6176     case BUILT_IN_FETCH_AND_SUB_1:
6177     case BUILT_IN_FETCH_AND_SUB_2:
6178     case BUILT_IN_FETCH_AND_SUB_4:
6179     case BUILT_IN_FETCH_AND_SUB_8:
6180     case BUILT_IN_FETCH_AND_SUB_16:
6181       mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_SUB_1);
6182       target = expand_builtin_sync_operation (mode, arglist, MINUS,
6183                                               false, target, ignore);
6184       if (target)
6185         return target;
6186       break;
6187
6188     case BUILT_IN_FETCH_AND_OR_1:
6189     case BUILT_IN_FETCH_AND_OR_2:
6190     case BUILT_IN_FETCH_AND_OR_4:
6191     case BUILT_IN_FETCH_AND_OR_8:
6192     case BUILT_IN_FETCH_AND_OR_16:
6193       mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_OR_1);
6194       target = expand_builtin_sync_operation (mode, arglist, IOR,
6195                                               false, target, ignore);
6196       if (target)
6197         return target;
6198       break;
6199
6200     case BUILT_IN_FETCH_AND_AND_1:
6201     case BUILT_IN_FETCH_AND_AND_2:
6202     case BUILT_IN_FETCH_AND_AND_4:
6203     case BUILT_IN_FETCH_AND_AND_8:
6204     case BUILT_IN_FETCH_AND_AND_16:
6205       mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_AND_1);
6206       target = expand_builtin_sync_operation (mode, arglist, AND,
6207                                               false, target, ignore);
6208       if (target)
6209         return target;
6210       break;
6211
6212     case BUILT_IN_FETCH_AND_XOR_1:
6213     case BUILT_IN_FETCH_AND_XOR_2:
6214     case BUILT_IN_FETCH_AND_XOR_4:
6215     case BUILT_IN_FETCH_AND_XOR_8:
6216     case BUILT_IN_FETCH_AND_XOR_16:
6217       mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_XOR_1);
6218       target = expand_builtin_sync_operation (mode, arglist, XOR,
6219                                               false, target, ignore);
6220       if (target)
6221         return target;
6222       break;
6223
6224     case BUILT_IN_FETCH_AND_NAND_1:
6225     case BUILT_IN_FETCH_AND_NAND_2:
6226     case BUILT_IN_FETCH_AND_NAND_4:
6227     case BUILT_IN_FETCH_AND_NAND_8:
6228     case BUILT_IN_FETCH_AND_NAND_16:
6229       mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_NAND_1);
6230       target = expand_builtin_sync_operation (mode, arglist, NOT,
6231                                               false, target, ignore);
6232       if (target)
6233         return target;
6234       break;
6235
6236     case BUILT_IN_ADD_AND_FETCH_1:
6237     case BUILT_IN_ADD_AND_FETCH_2:
6238     case BUILT_IN_ADD_AND_FETCH_4:
6239     case BUILT_IN_ADD_AND_FETCH_8:
6240     case BUILT_IN_ADD_AND_FETCH_16:
6241       mode = get_builtin_sync_mode (fcode - BUILT_IN_ADD_AND_FETCH_1);
6242       target = expand_builtin_sync_operation (mode, arglist, PLUS,
6243                                               true, target, ignore);
6244       if (target)
6245         return target;
6246       break;
6247
6248     case BUILT_IN_SUB_AND_FETCH_1:
6249     case BUILT_IN_SUB_AND_FETCH_2:
6250     case BUILT_IN_SUB_AND_FETCH_4:
6251     case BUILT_IN_SUB_AND_FETCH_8:
6252     case BUILT_IN_SUB_AND_FETCH_16:
6253       mode = get_builtin_sync_mode (fcode - BUILT_IN_SUB_AND_FETCH_1);
6254       target = expand_builtin_sync_operation (mode, arglist, MINUS,
6255                                               true, target, ignore);
6256       if (target)
6257         return target;
6258       break;
6259
6260     case BUILT_IN_OR_AND_FETCH_1:
6261     case BUILT_IN_OR_AND_FETCH_2:
6262     case BUILT_IN_OR_AND_FETCH_4:
6263     case BUILT_IN_OR_AND_FETCH_8:
6264     case BUILT_IN_OR_AND_FETCH_16:
6265       mode = get_builtin_sync_mode (fcode - BUILT_IN_OR_AND_FETCH_1);
6266       target = expand_builtin_sync_operation (mode, arglist, IOR,
6267                                               true, target, ignore);
6268       if (target)
6269         return target;
6270       break;
6271
6272     case BUILT_IN_AND_AND_FETCH_1:
6273     case BUILT_IN_AND_AND_FETCH_2:
6274     case BUILT_IN_AND_AND_FETCH_4:
6275     case BUILT_IN_AND_AND_FETCH_8:
6276     case BUILT_IN_AND_AND_FETCH_16:
6277       mode = get_builtin_sync_mode (fcode - BUILT_IN_AND_AND_FETCH_1);
6278       target = expand_builtin_sync_operation (mode, arglist, AND,
6279                                               true, target, ignore);
6280       if (target)
6281         return target;
6282       break;
6283
6284     case BUILT_IN_XOR_AND_FETCH_1:
6285     case BUILT_IN_XOR_AND_FETCH_2:
6286     case BUILT_IN_XOR_AND_FETCH_4:
6287     case BUILT_IN_XOR_AND_FETCH_8:
6288     case BUILT_IN_XOR_AND_FETCH_16:
6289       mode = get_builtin_sync_mode (fcode - BUILT_IN_XOR_AND_FETCH_1);
6290       target = expand_builtin_sync_operation (mode, arglist, XOR,
6291                                               true, target, ignore);
6292       if (target)
6293         return target;
6294       break;
6295
6296     case BUILT_IN_NAND_AND_FETCH_1:
6297     case BUILT_IN_NAND_AND_FETCH_2:
6298     case BUILT_IN_NAND_AND_FETCH_4:
6299     case BUILT_IN_NAND_AND_FETCH_8:
6300     case BUILT_IN_NAND_AND_FETCH_16:
6301       mode = get_builtin_sync_mode (fcode - BUILT_IN_NAND_AND_FETCH_1);
6302       target = expand_builtin_sync_operation (mode, arglist, NOT,
6303                                               true, target, ignore);
6304       if (target)
6305         return target;
6306       break;
6307
6308     case BUILT_IN_BOOL_COMPARE_AND_SWAP_1:
6309     case BUILT_IN_BOOL_COMPARE_AND_SWAP_2:
6310     case BUILT_IN_BOOL_COMPARE_AND_SWAP_4:
6311     case BUILT_IN_BOOL_COMPARE_AND_SWAP_8:
6312     case BUILT_IN_BOOL_COMPARE_AND_SWAP_16:
6313       if (mode == VOIDmode)
6314         mode = TYPE_MODE (boolean_type_node);
6315       if (!target || !register_operand (target, mode))
6316         target = gen_reg_rtx (mode);
6317
6318       mode = get_builtin_sync_mode (fcode - BUILT_IN_BOOL_COMPARE_AND_SWAP_1);
6319       target = expand_builtin_compare_and_swap (mode, arglist, true, target);
6320       if (target)
6321         return target;
6322       break;
6323
6324     case BUILT_IN_VAL_COMPARE_AND_SWAP_1:
6325     case BUILT_IN_VAL_COMPARE_AND_SWAP_2:
6326     case BUILT_IN_VAL_COMPARE_AND_SWAP_4:
6327     case BUILT_IN_VAL_COMPARE_AND_SWAP_8:
6328     case BUILT_IN_VAL_COMPARE_AND_SWAP_16:
6329       mode = get_builtin_sync_mode (fcode - BUILT_IN_VAL_COMPARE_AND_SWAP_1);
6330       target = expand_builtin_compare_and_swap (mode, arglist, false, target);
6331       if (target)
6332         return target;
6333       break;
6334
6335     case BUILT_IN_LOCK_TEST_AND_SET_1:
6336     case BUILT_IN_LOCK_TEST_AND_SET_2:
6337     case BUILT_IN_LOCK_TEST_AND_SET_4:
6338     case BUILT_IN_LOCK_TEST_AND_SET_8:
6339     case BUILT_IN_LOCK_TEST_AND_SET_16:
6340       mode = get_builtin_sync_mode (fcode - BUILT_IN_LOCK_TEST_AND_SET_1);
6341       target = expand_builtin_lock_test_and_set (mode, arglist, target);
6342       if (target)
6343         return target;
6344       break;
6345
6346     case BUILT_IN_LOCK_RELEASE_1:
6347     case BUILT_IN_LOCK_RELEASE_2:
6348     case BUILT_IN_LOCK_RELEASE_4:
6349     case BUILT_IN_LOCK_RELEASE_8:
6350     case BUILT_IN_LOCK_RELEASE_16:
6351       mode = get_builtin_sync_mode (fcode - BUILT_IN_LOCK_RELEASE_1);
6352       expand_builtin_lock_release (mode, arglist);
6353       return const0_rtx;
6354
6355     case BUILT_IN_SYNCHRONIZE:
6356       expand_builtin_synchronize ();
6357       return const0_rtx;
6358
6359     case BUILT_IN_OBJECT_SIZE:
6360       return expand_builtin_object_size (exp);
6361
6362     case BUILT_IN_MEMCPY_CHK:
6363     case BUILT_IN_MEMPCPY_CHK:
6364     case BUILT_IN_MEMMOVE_CHK:
6365     case BUILT_IN_MEMSET_CHK:
6366       target = expand_builtin_memory_chk (exp, target, mode, fcode);
6367       if (target)
6368         return target;
6369       break;
6370
6371     case BUILT_IN_STRCPY_CHK:
6372     case BUILT_IN_STPCPY_CHK:
6373     case BUILT_IN_STRNCPY_CHK:
6374     case BUILT_IN_STRCAT_CHK:
6375     case BUILT_IN_SNPRINTF_CHK:
6376     case BUILT_IN_VSNPRINTF_CHK:
6377       maybe_emit_chk_warning (exp, fcode);
6378       break;
6379
6380     case BUILT_IN_SPRINTF_CHK:
6381     case BUILT_IN_VSPRINTF_CHK:
6382       maybe_emit_sprintf_chk_warning (exp, fcode);
6383       break;
6384
6385     default:    /* just do library call, if unknown builtin */
6386       break;
6387     }
6388
6389   /* The switch statement above can drop through to cause the function
6390      to be called normally.  */
6391   return expand_call (exp, target, ignore);
6392 }
6393
6394 /* Determine whether a tree node represents a call to a built-in
6395    function.  If the tree T is a call to a built-in function with
6396    the right number of arguments of the appropriate types, return
6397    the DECL_FUNCTION_CODE of the call, e.g. BUILT_IN_SQRT.
6398    Otherwise the return value is END_BUILTINS.  */
6399
6400 enum built_in_function
6401 builtin_mathfn_code (tree t)
6402 {
6403   tree fndecl, arglist, parmlist;
6404   tree argtype, parmtype;
6405
6406   if (TREE_CODE (t) != CALL_EXPR
6407       || TREE_CODE (TREE_OPERAND (t, 0)) != ADDR_EXPR)
6408     return END_BUILTINS;
6409
6410   fndecl = get_callee_fndecl (t);
6411   if (fndecl == NULL_TREE
6412       || TREE_CODE (fndecl) != FUNCTION_DECL
6413       || ! DECL_BUILT_IN (fndecl)
6414       || DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
6415     return END_BUILTINS;
6416
6417   arglist = TREE_OPERAND (t, 1);
6418   parmlist = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
6419   for (; parmlist; parmlist = TREE_CHAIN (parmlist))
6420     {
6421       /* If a function doesn't take a variable number of arguments,
6422          the last element in the list will have type `void'.  */
6423       parmtype = TREE_VALUE (parmlist);
6424       if (VOID_TYPE_P (parmtype))
6425         {
6426           if (arglist)
6427             return END_BUILTINS;
6428           return DECL_FUNCTION_CODE (fndecl);
6429         }
6430
6431       if (! arglist)
6432         return END_BUILTINS;
6433
6434       argtype = TREE_TYPE (TREE_VALUE (arglist));
6435
6436       if (SCALAR_FLOAT_TYPE_P (parmtype))
6437         {
6438           if (! SCALAR_FLOAT_TYPE_P (argtype))
6439             return END_BUILTINS;
6440         }
6441       else if (COMPLEX_FLOAT_TYPE_P (parmtype))
6442         {
6443           if (! COMPLEX_FLOAT_TYPE_P (argtype))
6444             return END_BUILTINS;
6445         }
6446       else if (POINTER_TYPE_P (parmtype))
6447         {
6448           if (! POINTER_TYPE_P (argtype))
6449             return END_BUILTINS;
6450         }
6451       else if (INTEGRAL_TYPE_P (parmtype))
6452         {
6453           if (! INTEGRAL_TYPE_P (argtype))
6454             return END_BUILTINS;
6455         }
6456       else
6457         return END_BUILTINS;
6458
6459       arglist = TREE_CHAIN (arglist);
6460     }
6461
6462   /* Variable-length argument list.  */
6463   return DECL_FUNCTION_CODE (fndecl);
6464 }
6465
6466 /* Fold a call to __builtin_constant_p, if we know it will evaluate to a
6467    constant.  ARGLIST is the argument list of the call.  */
6468
6469 static tree
6470 fold_builtin_constant_p (tree arglist)
6471 {
6472   if (arglist == 0)
6473     return 0;
6474
6475   arglist = TREE_VALUE (arglist);
6476
6477   /* We return 1 for a numeric type that's known to be a constant
6478      value at compile-time or for an aggregate type that's a
6479      literal constant.  */
6480   STRIP_NOPS (arglist);
6481
6482   /* If we know this is a constant, emit the constant of one.  */
6483   if (CONSTANT_CLASS_P (arglist)
6484       || (TREE_CODE (arglist) == CONSTRUCTOR
6485           && TREE_CONSTANT (arglist)))
6486     return integer_one_node;
6487   if (TREE_CODE (arglist) == ADDR_EXPR)
6488     {
6489        tree op = TREE_OPERAND (arglist, 0);
6490        if (TREE_CODE (op) == STRING_CST
6491            || (TREE_CODE (op) == ARRAY_REF
6492                && integer_zerop (TREE_OPERAND (op, 1))
6493                && TREE_CODE (TREE_OPERAND (op, 0)) == STRING_CST))
6494          return integer_one_node;
6495     }
6496
6497   /* If this expression has side effects, show we don't know it to be a
6498      constant.  Likewise if it's a pointer or aggregate type since in
6499      those case we only want literals, since those are only optimized
6500      when generating RTL, not later.
6501      And finally, if we are compiling an initializer, not code, we
6502      need to return a definite result now; there's not going to be any
6503      more optimization done.  */
6504   if (TREE_SIDE_EFFECTS (arglist)
6505       || AGGREGATE_TYPE_P (TREE_TYPE (arglist))
6506       || POINTER_TYPE_P (TREE_TYPE (arglist))
6507       || cfun == 0)
6508     return integer_zero_node;
6509
6510   return 0;
6511 }
6512
6513 /* Fold a call to __builtin_expect, if we expect that a comparison against
6514    the argument will fold to a constant.  In practice, this means a true
6515    constant or the address of a non-weak symbol.  ARGLIST is the argument
6516    list of the call.  */
6517
6518 static tree
6519 fold_builtin_expect (tree arglist)
6520 {
6521   tree arg, inner;
6522
6523   if (arglist == 0)
6524     return 0;
6525
6526   arg = TREE_VALUE (arglist);
6527
6528   /* If the argument isn't invariant, then there's nothing we can do.  */
6529   if (!TREE_INVARIANT (arg))
6530     return 0;
6531
6532   /* If we're looking at an address of a weak decl, then do not fold.  */
6533   inner = arg;
6534   STRIP_NOPS (inner);
6535   if (TREE_CODE (inner) == ADDR_EXPR)
6536     {
6537       do
6538         {
6539           inner = TREE_OPERAND (inner, 0);
6540         }
6541       while (TREE_CODE (inner) == COMPONENT_REF
6542              || TREE_CODE (inner) == ARRAY_REF);
6543       if (DECL_P (inner) && DECL_WEAK (inner))
6544         return 0;
6545     }
6546
6547   /* Otherwise, ARG already has the proper type for the return value.  */
6548   return arg;
6549 }
6550
6551 /* Fold a call to __builtin_classify_type.  */
6552
6553 static tree
6554 fold_builtin_classify_type (tree arglist)
6555 {
6556   if (arglist == 0)
6557     return build_int_cst (NULL_TREE, no_type_class);
6558
6559   return build_int_cst (NULL_TREE,
6560                         type_to_class (TREE_TYPE (TREE_VALUE (arglist))));
6561 }
6562
6563 /* Fold a call to __builtin_strlen.  */
6564
6565 static tree
6566 fold_builtin_strlen (tree arglist)
6567 {
6568   if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6569     return NULL_TREE;
6570   else
6571     {
6572       tree len = c_strlen (TREE_VALUE (arglist), 0);
6573
6574       if (len)
6575         {
6576           /* Convert from the internal "sizetype" type to "size_t".  */
6577           if (size_type_node)
6578             len = fold_convert (size_type_node, len);
6579           return len;
6580         }
6581
6582       return NULL_TREE;
6583     }
6584 }
6585
6586 /* Fold a call to __builtin_inf or __builtin_huge_val.  */
6587
6588 static tree
6589 fold_builtin_inf (tree type, int warn)
6590 {
6591   REAL_VALUE_TYPE real;
6592
6593   /* __builtin_inff is intended to be usable to define INFINITY on all
6594      targets.  If an infinity is not available, INFINITY expands "to a
6595      positive constant of type float that overflows at translation
6596      time", footnote "In this case, using INFINITY will violate the
6597      constraint in 6.4.4 and thus require a diagnostic." (C99 7.12#4).
6598      Thus we pedwarn to ensure this constraint violation is
6599      diagnosed.  */
6600   if (!MODE_HAS_INFINITIES (TYPE_MODE (type)) && warn)
6601     pedwarn ("target format does not support infinity");
6602
6603   real_inf (&real);
6604   return build_real (type, real);
6605 }
6606
6607 /* Fold a call to __builtin_nan or __builtin_nans.  */
6608
6609 static tree
6610 fold_builtin_nan (tree arglist, tree type, int quiet)
6611 {
6612   REAL_VALUE_TYPE real;
6613   const char *str;
6614
6615   if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6616     return 0;
6617   str = c_getstr (TREE_VALUE (arglist));
6618   if (!str)
6619     return 0;
6620
6621   if (!real_nan (&real, str, quiet, TYPE_MODE (type)))
6622     return 0;
6623
6624   return build_real (type, real);
6625 }
6626
6627 /* Return true if the floating point expression T has an integer value.
6628    We also allow +Inf, -Inf and NaN to be considered integer values.  */
6629
6630 static bool
6631 integer_valued_real_p (tree t)
6632 {
6633   switch (TREE_CODE (t))
6634     {
6635     case FLOAT_EXPR:
6636       return true;
6637
6638     case ABS_EXPR:
6639     case SAVE_EXPR:
6640     case NON_LVALUE_EXPR:
6641       return integer_valued_real_p (TREE_OPERAND (t, 0));
6642
6643     case COMPOUND_EXPR:
6644     case MODIFY_EXPR:
6645     case BIND_EXPR:
6646       return integer_valued_real_p (TREE_OPERAND (t, 1));
6647
6648     case PLUS_EXPR:
6649     case MINUS_EXPR:
6650     case MULT_EXPR:
6651     case MIN_EXPR:
6652     case MAX_EXPR:
6653       return integer_valued_real_p (TREE_OPERAND (t, 0))
6654              && integer_valued_real_p (TREE_OPERAND (t, 1));
6655
6656     case COND_EXPR:
6657       return integer_valued_real_p (TREE_OPERAND (t, 1))
6658              && integer_valued_real_p (TREE_OPERAND (t, 2));
6659
6660     case REAL_CST:
6661       if (! TREE_CONSTANT_OVERFLOW (t))
6662       {
6663         REAL_VALUE_TYPE c, cint;
6664
6665         c = TREE_REAL_CST (t);
6666         real_trunc (&cint, TYPE_MODE (TREE_TYPE (t)), &c);
6667         return real_identical (&c, &cint);
6668       }
6669       break;
6670
6671     case NOP_EXPR:
6672       {
6673         tree type = TREE_TYPE (TREE_OPERAND (t, 0));
6674         if (TREE_CODE (type) == INTEGER_TYPE)
6675           return true;
6676         if (TREE_CODE (type) == REAL_TYPE)
6677           return integer_valued_real_p (TREE_OPERAND (t, 0));
6678         break;
6679       }
6680
6681     case CALL_EXPR:
6682       switch (builtin_mathfn_code (t))
6683         {
6684         CASE_FLT_FN (BUILT_IN_CEIL):
6685         CASE_FLT_FN (BUILT_IN_FLOOR):
6686         CASE_FLT_FN (BUILT_IN_NEARBYINT):
6687         CASE_FLT_FN (BUILT_IN_RINT):
6688         CASE_FLT_FN (BUILT_IN_ROUND):
6689         CASE_FLT_FN (BUILT_IN_TRUNC):
6690           return true;
6691
6692         default:
6693           break;
6694         }
6695       break;
6696
6697     default:
6698       break;
6699     }
6700   return false;
6701 }
6702
6703 /* EXP is assumed to be builtin call where truncation can be propagated
6704    across (for instance floor((double)f) == (double)floorf (f).
6705    Do the transformation.  */
6706
6707 static tree
6708 fold_trunc_transparent_mathfn (tree fndecl, tree arglist)
6709 {
6710   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
6711   tree arg;
6712
6713   if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6714     return 0;
6715
6716   arg = TREE_VALUE (arglist);
6717   /* Integer rounding functions are idempotent.  */
6718   if (fcode == builtin_mathfn_code (arg))
6719     return arg;
6720
6721   /* If argument is already integer valued, and we don't need to worry
6722      about setting errno, there's no need to perform rounding.  */
6723   if (! flag_errno_math && integer_valued_real_p (arg))
6724     return arg;
6725
6726   if (optimize)
6727     {
6728       tree arg0 = strip_float_extensions (arg);
6729       tree ftype = TREE_TYPE (TREE_TYPE (fndecl));
6730       tree newtype = TREE_TYPE (arg0);
6731       tree decl;
6732
6733       if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
6734           && (decl = mathfn_built_in (newtype, fcode)))
6735         {
6736           arglist =
6737             build_tree_list (NULL_TREE, fold_convert (newtype, arg0));
6738           return fold_convert (ftype,
6739                                build_function_call_expr (decl, arglist));
6740         }
6741     }
6742   return 0;
6743 }
6744
6745 /* EXP is assumed to be builtin call which can narrow the FP type of
6746    the argument, for instance lround((double)f) -> lroundf (f).  */
6747
6748 static tree
6749 fold_fixed_mathfn (tree fndecl, tree arglist)
6750 {
6751   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
6752   tree arg;
6753
6754   if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6755     return 0;
6756
6757   arg = TREE_VALUE (arglist);
6758
6759   /* If argument is already integer valued, and we don't need to worry
6760      about setting errno, there's no need to perform rounding.  */
6761   if (! flag_errno_math && integer_valued_real_p (arg))
6762     return fold_build1 (FIX_TRUNC_EXPR, TREE_TYPE (TREE_TYPE (fndecl)), arg);
6763
6764   if (optimize)
6765     {
6766       tree ftype = TREE_TYPE (arg);
6767       tree arg0 = strip_float_extensions (arg);
6768       tree newtype = TREE_TYPE (arg0);
6769       tree decl;
6770
6771       if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
6772           && (decl = mathfn_built_in (newtype, fcode)))
6773         {
6774           arglist =
6775             build_tree_list (NULL_TREE, fold_convert (newtype, arg0));
6776           return build_function_call_expr (decl, arglist);
6777         }
6778     }
6779   return 0;
6780 }
6781
6782 /* Fold function call to builtin cabs, cabsf or cabsl.  ARGLIST
6783    is the argument list and TYPE is the return type.  Return
6784    NULL_TREE if no if no simplification can be made.  */
6785
6786 static tree
6787 fold_builtin_cabs (tree arglist, tree type)
6788 {
6789   tree arg;
6790
6791   if (!arglist || TREE_CHAIN (arglist))
6792     return NULL_TREE;
6793
6794   arg = TREE_VALUE (arglist);
6795   if (TREE_CODE (TREE_TYPE (arg)) != COMPLEX_TYPE
6796       || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) != REAL_TYPE)
6797     return NULL_TREE;
6798
6799   /* Evaluate cabs of a constant at compile-time.  */
6800   if (flag_unsafe_math_optimizations
6801       && TREE_CODE (arg) == COMPLEX_CST
6802       && TREE_CODE (TREE_REALPART (arg)) == REAL_CST
6803       && TREE_CODE (TREE_IMAGPART (arg)) == REAL_CST
6804       && ! TREE_CONSTANT_OVERFLOW (TREE_REALPART (arg))
6805       && ! TREE_CONSTANT_OVERFLOW (TREE_IMAGPART (arg)))
6806     {
6807       REAL_VALUE_TYPE r, i;
6808
6809       r = TREE_REAL_CST (TREE_REALPART (arg));
6810       i = TREE_REAL_CST (TREE_IMAGPART (arg));
6811
6812       real_arithmetic (&r, MULT_EXPR, &r, &r);
6813       real_arithmetic (&i, MULT_EXPR, &i, &i);
6814       real_arithmetic (&r, PLUS_EXPR, &r, &i);
6815       if (real_sqrt (&r, TYPE_MODE (type), &r)
6816           || ! flag_trapping_math)
6817         return build_real (type, r);
6818     }
6819
6820   /* If either part is zero, cabs is fabs of the other.  */
6821   if (TREE_CODE (arg) == COMPLEX_EXPR
6822       && real_zerop (TREE_OPERAND (arg, 0)))
6823     return fold_build1 (ABS_EXPR, type, TREE_OPERAND (arg, 1));
6824   if (TREE_CODE (arg) == COMPLEX_EXPR
6825       && real_zerop (TREE_OPERAND (arg, 1)))
6826     return fold_build1 (ABS_EXPR, type, TREE_OPERAND (arg, 0));
6827
6828   /* Don't do this when optimizing for size.  */
6829   if (flag_unsafe_math_optimizations
6830       && optimize && !optimize_size)
6831     {
6832       tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
6833
6834       if (sqrtfn != NULL_TREE)
6835         {
6836           tree rpart, ipart, result, arglist;
6837
6838           arg = builtin_save_expr (arg);
6839
6840           rpart = fold_build1 (REALPART_EXPR, type, arg);
6841           ipart = fold_build1 (IMAGPART_EXPR, type, arg);
6842
6843           rpart = builtin_save_expr (rpart);
6844           ipart = builtin_save_expr (ipart);
6845
6846           result = fold_build2 (PLUS_EXPR, type,
6847                                 fold_build2 (MULT_EXPR, type,
6848                                              rpart, rpart),
6849                                 fold_build2 (MULT_EXPR, type,
6850                                              ipart, ipart));
6851
6852           arglist = build_tree_list (NULL_TREE, result);
6853           return build_function_call_expr (sqrtfn, arglist);
6854         }
6855     }
6856
6857   return NULL_TREE;
6858 }
6859
6860 /* Fold a builtin function call to sqrt, sqrtf, or sqrtl.  Return
6861    NULL_TREE if no simplification can be made.  */
6862
6863 static tree
6864 fold_builtin_sqrt (tree arglist, tree type)
6865 {
6866
6867   enum built_in_function fcode;
6868   tree arg = TREE_VALUE (arglist);
6869
6870   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6871     return NULL_TREE;
6872
6873   /* Optimize sqrt of constant value.  */
6874   if (TREE_CODE (arg) == REAL_CST
6875       && ! TREE_CONSTANT_OVERFLOW (arg))
6876     {
6877       REAL_VALUE_TYPE r, x;
6878
6879       x = TREE_REAL_CST (arg);
6880       if (real_sqrt (&r, TYPE_MODE (type), &x)
6881           || (!flag_trapping_math && !flag_errno_math))
6882         return build_real (type, r);
6883     }
6884
6885   /* Optimize sqrt(expN(x)) = expN(x*0.5).  */
6886   fcode = builtin_mathfn_code (arg);
6887   if (flag_unsafe_math_optimizations && BUILTIN_EXPONENT_P (fcode))
6888     {
6889       tree expfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
6890       arg = fold_build2 (MULT_EXPR, type,
6891                          TREE_VALUE (TREE_OPERAND (arg, 1)),
6892                          build_real (type, dconsthalf));
6893       arglist = build_tree_list (NULL_TREE, arg);
6894       return build_function_call_expr (expfn, arglist);
6895     }
6896
6897   /* Optimize sqrt(Nroot(x)) -> pow(x,1/(2*N)).  */
6898   if (flag_unsafe_math_optimizations && BUILTIN_ROOT_P (fcode))
6899     {
6900       tree powfn = mathfn_built_in (type, BUILT_IN_POW);
6901
6902       if (powfn)
6903         {
6904           tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
6905           tree tree_root;
6906           /* The inner root was either sqrt or cbrt.  */
6907           REAL_VALUE_TYPE dconstroot =
6908             BUILTIN_SQRT_P (fcode) ? dconsthalf : dconstthird;
6909
6910           /* Adjust for the outer root.  */
6911           SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
6912           dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
6913           tree_root = build_real (type, dconstroot);
6914           arglist = tree_cons (NULL_TREE, arg0,
6915                                build_tree_list (NULL_TREE, tree_root));
6916           return build_function_call_expr (powfn, arglist);
6917         }
6918     }
6919
6920   /* Optimize sqrt(pow(x,y)) = pow(|x|,y*0.5).  */
6921   if (flag_unsafe_math_optimizations
6922       && (fcode == BUILT_IN_POW
6923           || fcode == BUILT_IN_POWF
6924           || fcode == BUILT_IN_POWL))
6925     {
6926       tree powfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
6927       tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
6928       tree arg1 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
6929       tree narg1;
6930       if (!tree_expr_nonnegative_p (arg0))
6931         arg0 = build1 (ABS_EXPR, type, arg0);
6932       narg1 = fold_build2 (MULT_EXPR, type, arg1,
6933                            build_real (type, dconsthalf));
6934       arglist = tree_cons (NULL_TREE, arg0,
6935                            build_tree_list (NULL_TREE, narg1));
6936       return build_function_call_expr (powfn, arglist);
6937     }
6938
6939   return NULL_TREE;
6940 }
6941
6942 /* Fold a builtin function call to cbrt, cbrtf, or cbrtl.  Return
6943    NULL_TREE if no simplification can be made.  */
6944 static tree
6945 fold_builtin_cbrt (tree arglist, tree type)
6946 {
6947   tree arg = TREE_VALUE (arglist);
6948   const enum built_in_function fcode = builtin_mathfn_code (arg);
6949
6950   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6951     return NULL_TREE;
6952
6953   /* Optimize cbrt of constant value.  */
6954   if (real_zerop (arg) || real_onep (arg) || real_minus_onep (arg))
6955     return arg;
6956
6957   if (flag_unsafe_math_optimizations)
6958     {
6959       /* Optimize cbrt(expN(x)) -> expN(x/3).  */
6960       if (BUILTIN_EXPONENT_P (fcode))
6961         {
6962           tree expfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
6963           const REAL_VALUE_TYPE third_trunc =
6964             real_value_truncate (TYPE_MODE (type), dconstthird);
6965           arg = fold_build2 (MULT_EXPR, type,
6966                              TREE_VALUE (TREE_OPERAND (arg, 1)),
6967                              build_real (type, third_trunc));
6968           arglist = build_tree_list (NULL_TREE, arg);
6969           return build_function_call_expr (expfn, arglist);
6970         }
6971
6972       /* Optimize cbrt(sqrt(x)) -> pow(x,1/6).  */
6973       if (BUILTIN_SQRT_P (fcode))
6974         {
6975           tree powfn = mathfn_built_in (type, BUILT_IN_POW);
6976
6977           if (powfn)
6978             {
6979               tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
6980               tree tree_root;
6981               REAL_VALUE_TYPE dconstroot = dconstthird;
6982
6983               SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
6984               dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
6985               tree_root = build_real (type, dconstroot);
6986               arglist = tree_cons (NULL_TREE, arg0,
6987                                    build_tree_list (NULL_TREE, tree_root));
6988               return build_function_call_expr (powfn, arglist);
6989             }
6990         }
6991
6992       /* Optimize cbrt(cbrt(x)) -> pow(x,1/9) iff x is nonnegative.  */
6993       if (BUILTIN_CBRT_P (fcode))
6994         {
6995           tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
6996           if (tree_expr_nonnegative_p (arg0))
6997             {
6998               tree powfn = mathfn_built_in (type, BUILT_IN_POW);
6999
7000               if (powfn)
7001                 {
7002                   tree tree_root;
7003                   REAL_VALUE_TYPE dconstroot;
7004               
7005                   real_arithmetic (&dconstroot, MULT_EXPR, &dconstthird, &dconstthird);
7006                   dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
7007                   tree_root = build_real (type, dconstroot);
7008                   arglist = tree_cons (NULL_TREE, arg0,
7009                                        build_tree_list (NULL_TREE, tree_root));
7010                   return build_function_call_expr (powfn, arglist);
7011                 }
7012             }
7013         }
7014       
7015       /* Optimize cbrt(pow(x,y)) -> pow(x,y/3) iff x is nonnegative.  */
7016       if (fcode == BUILT_IN_POW || fcode == BUILT_IN_POWF
7017           || fcode == BUILT_IN_POWL)
7018         {
7019           tree arg00 = TREE_VALUE (TREE_OPERAND (arg, 1));
7020           tree arg01 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
7021           if (tree_expr_nonnegative_p (arg00))
7022             {
7023               tree powfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
7024               const REAL_VALUE_TYPE dconstroot
7025                 = real_value_truncate (TYPE_MODE (type), dconstthird);
7026               tree narg01 = fold_build2 (MULT_EXPR, type, arg01,
7027                                          build_real (type, dconstroot));
7028               arglist = tree_cons (NULL_TREE, arg00,
7029                                    build_tree_list (NULL_TREE, narg01));
7030               return build_function_call_expr (powfn, arglist);
7031             }
7032         }
7033     }
7034   return NULL_TREE;
7035 }
7036
7037 /* Fold function call to builtin sin, sinf, or sinl.  Return
7038    NULL_TREE if no simplification can be made.  */
7039 static tree
7040 fold_builtin_sin (tree arglist)
7041 {
7042   tree arg = TREE_VALUE (arglist);
7043
7044   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7045     return NULL_TREE;
7046
7047   /* Optimize sin (0.0) = 0.0.  */
7048   if (real_zerop (arg))
7049     return arg;
7050
7051   return NULL_TREE;
7052 }
7053
7054 /* Fold function call to builtin cos, cosf, or cosl.  Return
7055    NULL_TREE if no simplification can be made.  */
7056 static tree
7057 fold_builtin_cos (tree arglist, tree type, tree fndecl)
7058 {
7059   tree arg = TREE_VALUE (arglist);
7060
7061   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7062     return NULL_TREE;
7063
7064   /* Optimize cos (0.0) = 1.0.  */
7065   if (real_zerop (arg))
7066     return build_real (type, dconst1);
7067
7068   /* Optimize cos(-x) into cos (x).  */
7069   if (TREE_CODE (arg) == NEGATE_EXPR)
7070     {
7071       tree args = build_tree_list (NULL_TREE,
7072                                    TREE_OPERAND (arg, 0));
7073       return build_function_call_expr (fndecl, args);
7074     }
7075
7076   return NULL_TREE;
7077 }
7078
7079 /* Fold function call to builtin tan, tanf, or tanl.  Return
7080    NULL_TREE if no simplification can be made.  */
7081 static tree
7082 fold_builtin_tan (tree arglist)
7083 {
7084   enum built_in_function fcode;
7085   tree arg = TREE_VALUE (arglist);
7086
7087   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7088     return NULL_TREE;
7089
7090   /* Optimize tan(0.0) = 0.0.  */
7091   if (real_zerop (arg))
7092     return arg;
7093
7094   /* Optimize tan(atan(x)) = x.  */
7095   fcode = builtin_mathfn_code (arg);
7096   if (flag_unsafe_math_optimizations
7097       && (fcode == BUILT_IN_ATAN
7098           || fcode == BUILT_IN_ATANF
7099           || fcode == BUILT_IN_ATANL))
7100     return TREE_VALUE (TREE_OPERAND (arg, 1));
7101
7102   return NULL_TREE;
7103 }
7104
7105 /* Fold function call to builtin atan, atanf, or atanl.  Return
7106    NULL_TREE if no simplification can be made.  */
7107
7108 static tree
7109 fold_builtin_atan (tree arglist, tree type)
7110 {
7111
7112   tree arg = TREE_VALUE (arglist);
7113
7114   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7115     return NULL_TREE;
7116
7117   /* Optimize atan(0.0) = 0.0.  */
7118   if (real_zerop (arg))
7119     return arg;
7120
7121   /* Optimize atan(1.0) = pi/4.  */
7122   if (real_onep (arg))
7123     {
7124       REAL_VALUE_TYPE cst;
7125
7126       real_convert (&cst, TYPE_MODE (type), &dconstpi);
7127       SET_REAL_EXP (&cst, REAL_EXP (&cst) - 2);
7128       return build_real (type, cst);
7129     }
7130
7131   return NULL_TREE;
7132 }
7133
7134 /* Fold function call to builtin trunc, truncf or truncl.  Return
7135    NULL_TREE if no simplification can be made.  */
7136
7137 static tree
7138 fold_builtin_trunc (tree fndecl, tree arglist)
7139 {
7140   tree arg;
7141
7142   if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7143     return 0;
7144
7145   /* Optimize trunc of constant value.  */
7146   arg = TREE_VALUE (arglist);
7147   if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7148     {
7149       REAL_VALUE_TYPE r, x;
7150       tree type = TREE_TYPE (TREE_TYPE (fndecl));
7151
7152       x = TREE_REAL_CST (arg);
7153       real_trunc (&r, TYPE_MODE (type), &x);
7154       return build_real (type, r);
7155     }
7156
7157   return fold_trunc_transparent_mathfn (fndecl, arglist);
7158 }
7159
7160 /* Fold function call to builtin floor, floorf or floorl.  Return
7161    NULL_TREE if no simplification can be made.  */
7162
7163 static tree
7164 fold_builtin_floor (tree fndecl, tree arglist)
7165 {
7166   tree arg;
7167
7168   if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7169     return 0;
7170
7171   /* Optimize floor of constant value.  */
7172   arg = TREE_VALUE (arglist);
7173   if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7174     {
7175       REAL_VALUE_TYPE x;
7176
7177       x = TREE_REAL_CST (arg);
7178       if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7179         {
7180           tree type = TREE_TYPE (TREE_TYPE (fndecl));
7181           REAL_VALUE_TYPE r;
7182
7183           real_floor (&r, TYPE_MODE (type), &x);
7184           return build_real (type, r);
7185         }
7186     }
7187
7188   return fold_trunc_transparent_mathfn (fndecl, arglist);
7189 }
7190
7191 /* Fold function call to builtin ceil, ceilf or ceill.  Return
7192    NULL_TREE if no simplification can be made.  */
7193
7194 static tree
7195 fold_builtin_ceil (tree fndecl, tree arglist)
7196 {
7197   tree arg;
7198
7199   if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7200     return 0;
7201
7202   /* Optimize ceil of constant value.  */
7203   arg = TREE_VALUE (arglist);
7204   if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7205     {
7206       REAL_VALUE_TYPE x;
7207
7208       x = TREE_REAL_CST (arg);
7209       if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7210         {
7211           tree type = TREE_TYPE (TREE_TYPE (fndecl));
7212           REAL_VALUE_TYPE r;
7213
7214           real_ceil (&r, TYPE_MODE (type), &x);
7215           return build_real (type, r);
7216         }
7217     }
7218
7219   return fold_trunc_transparent_mathfn (fndecl, arglist);
7220 }
7221
7222 /* Fold function call to builtin round, roundf or roundl.  Return
7223    NULL_TREE if no simplification can be made.  */
7224
7225 static tree
7226 fold_builtin_round (tree fndecl, tree arglist)
7227 {
7228   tree arg;
7229
7230   if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7231     return 0;
7232
7233   /* Optimize round of constant value.  */
7234   arg = TREE_VALUE (arglist);
7235   if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7236     {
7237       REAL_VALUE_TYPE x;
7238
7239       x = TREE_REAL_CST (arg);
7240       if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7241         {
7242           tree type = TREE_TYPE (TREE_TYPE (fndecl));
7243           REAL_VALUE_TYPE r;
7244
7245           real_round (&r, TYPE_MODE (type), &x);
7246           return build_real (type, r);
7247         }
7248     }
7249
7250   return fold_trunc_transparent_mathfn (fndecl, arglist);
7251 }
7252
7253 /* Fold function call to builtin lround, lroundf or lroundl (or the
7254    corresponding long long versions) and other rounding functions.
7255    Return NULL_TREE if no simplification can be made.  */
7256
7257 static tree
7258 fold_builtin_int_roundingfn (tree fndecl, tree arglist)
7259 {
7260   tree arg;
7261
7262   if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7263     return 0;
7264
7265   /* Optimize lround of constant value.  */
7266   arg = TREE_VALUE (arglist);
7267   if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7268     {
7269       const REAL_VALUE_TYPE x = TREE_REAL_CST (arg);
7270
7271       if (! REAL_VALUE_ISNAN (x) && ! REAL_VALUE_ISINF (x))
7272         {
7273           tree itype = TREE_TYPE (TREE_TYPE (fndecl));
7274           tree ftype = TREE_TYPE (arg), result;
7275           HOST_WIDE_INT hi, lo;
7276           REAL_VALUE_TYPE r;
7277
7278           switch (DECL_FUNCTION_CODE (fndecl))
7279             {
7280             CASE_FLT_FN (BUILT_IN_LFLOOR):
7281             CASE_FLT_FN (BUILT_IN_LLFLOOR):
7282               real_floor (&r, TYPE_MODE (ftype), &x);
7283               break;
7284
7285             CASE_FLT_FN (BUILT_IN_LCEIL):
7286             CASE_FLT_FN (BUILT_IN_LLCEIL):
7287               real_ceil (&r, TYPE_MODE (ftype), &x);
7288               break;
7289
7290             CASE_FLT_FN (BUILT_IN_LROUND):
7291             CASE_FLT_FN (BUILT_IN_LLROUND):
7292               real_round (&r, TYPE_MODE (ftype), &x);
7293               break;
7294
7295             default:
7296               gcc_unreachable ();
7297             }
7298
7299           REAL_VALUE_TO_INT (&lo, &hi, r);
7300           result = build_int_cst_wide (NULL_TREE, lo, hi);
7301           if (int_fits_type_p (result, itype))
7302             return fold_convert (itype, result);
7303         }
7304     }
7305
7306   return fold_fixed_mathfn (fndecl, arglist);
7307 }
7308
7309 /* Fold function call to builtin ffs, clz, ctz, popcount and parity
7310    and their long and long long variants (i.e. ffsl and ffsll).
7311    Return NULL_TREE if no simplification can be made.  */
7312
7313 static tree
7314 fold_builtin_bitop (tree fndecl, tree arglist)
7315 {
7316   tree arg;
7317
7318   if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
7319     return NULL_TREE;
7320
7321   /* Optimize for constant argument.  */
7322   arg = TREE_VALUE (arglist);
7323   if (TREE_CODE (arg) == INTEGER_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7324     {
7325       HOST_WIDE_INT hi, width, result;
7326       unsigned HOST_WIDE_INT lo;
7327       tree type;
7328
7329       type = TREE_TYPE (arg);
7330       width = TYPE_PRECISION (type);
7331       lo = TREE_INT_CST_LOW (arg);
7332
7333       /* Clear all the bits that are beyond the type's precision.  */
7334       if (width > HOST_BITS_PER_WIDE_INT)
7335         {
7336           hi = TREE_INT_CST_HIGH (arg);
7337           if (width < 2 * HOST_BITS_PER_WIDE_INT)
7338             hi &= ~((HOST_WIDE_INT) (-1) >> (width - HOST_BITS_PER_WIDE_INT));
7339         }
7340       else
7341         {
7342           hi = 0;
7343           if (width < HOST_BITS_PER_WIDE_INT)
7344             lo &= ~((unsigned HOST_WIDE_INT) (-1) << width);
7345         }
7346
7347       switch (DECL_FUNCTION_CODE (fndecl))
7348         {
7349         CASE_INT_FN (BUILT_IN_FFS):
7350           if (lo != 0)
7351             result = exact_log2 (lo & -lo) + 1;
7352           else if (hi != 0)
7353             result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi) + 1;
7354           else
7355             result = 0;
7356           break;
7357
7358         CASE_INT_FN (BUILT_IN_CLZ):
7359           if (hi != 0)
7360             result = width - floor_log2 (hi) - 1 - HOST_BITS_PER_WIDE_INT;
7361           else if (lo != 0)
7362             result = width - floor_log2 (lo) - 1;
7363           else if (! CLZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
7364             result = width;
7365           break;
7366
7367         CASE_INT_FN (BUILT_IN_CTZ):
7368           if (lo != 0)
7369             result = exact_log2 (lo & -lo);
7370           else if (hi != 0)
7371             result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi);
7372           else if (! CTZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
7373             result = width;
7374           break;
7375
7376         CASE_INT_FN (BUILT_IN_POPCOUNT):
7377           result = 0;
7378           while (lo)
7379             result++, lo &= lo - 1;
7380           while (hi)
7381             result++, hi &= hi - 1;
7382           break;
7383
7384         CASE_INT_FN (BUILT_IN_PARITY):
7385           result = 0;
7386           while (lo)
7387             result++, lo &= lo - 1;
7388           while (hi)
7389             result++, hi &= hi - 1;
7390           result &= 1;
7391           break;
7392
7393         default:
7394           gcc_unreachable ();
7395         }
7396
7397       return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), result);
7398     }
7399
7400   return NULL_TREE;
7401 }
7402
7403 /* Return true if EXPR is the real constant contained in VALUE.  */
7404
7405 static bool
7406 real_dconstp (tree expr, const REAL_VALUE_TYPE *value)
7407 {
7408   STRIP_NOPS (expr);
7409
7410   return ((TREE_CODE (expr) == REAL_CST
7411            && ! TREE_CONSTANT_OVERFLOW (expr)
7412            && REAL_VALUES_EQUAL (TREE_REAL_CST (expr), *value))
7413           || (TREE_CODE (expr) == COMPLEX_CST
7414               && real_dconstp (TREE_REALPART (expr), value)
7415               && real_zerop (TREE_IMAGPART (expr))));
7416 }
7417
7418 /* A subroutine of fold_builtin to fold the various logarithmic
7419    functions.  EXP is the CALL_EXPR of a call to a builtin logN
7420    function.  VALUE is the base of the logN function.  */
7421
7422 static tree
7423 fold_builtin_logarithm (tree fndecl, tree arglist,
7424                         const REAL_VALUE_TYPE *value)
7425 {
7426   if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7427     {
7428       tree type = TREE_TYPE (TREE_TYPE (fndecl));
7429       tree arg = TREE_VALUE (arglist);
7430       const enum built_in_function fcode = builtin_mathfn_code (arg);
7431
7432       /* Optimize logN(1.0) = 0.0.  */
7433       if (real_onep (arg))
7434         return build_real (type, dconst0);
7435
7436       /* Optimize logN(N) = 1.0.  If N can't be truncated to MODE
7437          exactly, then only do this if flag_unsafe_math_optimizations.  */
7438       if (exact_real_truncate (TYPE_MODE (type), value)
7439           || flag_unsafe_math_optimizations)
7440         {
7441           const REAL_VALUE_TYPE value_truncate =
7442             real_value_truncate (TYPE_MODE (type), *value);
7443           if (real_dconstp (arg, &value_truncate))
7444             return build_real (type, dconst1);
7445         }
7446
7447       /* Special case, optimize logN(expN(x)) = x.  */
7448       if (flag_unsafe_math_optimizations
7449           && ((value == &dconste
7450                && (fcode == BUILT_IN_EXP
7451                    || fcode == BUILT_IN_EXPF
7452                    || fcode == BUILT_IN_EXPL))
7453               || (value == &dconst2
7454                   && (fcode == BUILT_IN_EXP2
7455                       || fcode == BUILT_IN_EXP2F
7456                       || fcode == BUILT_IN_EXP2L))
7457               || (value == &dconst10 && (BUILTIN_EXP10_P (fcode)))))
7458         return fold_convert (type, TREE_VALUE (TREE_OPERAND (arg, 1)));
7459
7460       /* Optimize logN(func()) for various exponential functions.  We
7461          want to determine the value "x" and the power "exponent" in
7462          order to transform logN(x**exponent) into exponent*logN(x).  */
7463       if (flag_unsafe_math_optimizations)
7464         {
7465           tree exponent = 0, x = 0;
7466
7467           switch (fcode)
7468           {
7469           CASE_FLT_FN (BUILT_IN_EXP):
7470             /* Prepare to do logN(exp(exponent) -> exponent*logN(e).  */
7471             x = build_real (type,
7472                             real_value_truncate (TYPE_MODE (type), dconste));
7473             exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
7474             break;
7475           CASE_FLT_FN (BUILT_IN_EXP2):
7476             /* Prepare to do logN(exp2(exponent) -> exponent*logN(2).  */
7477             x = build_real (type, dconst2);
7478             exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
7479             break;
7480           CASE_FLT_FN (BUILT_IN_EXP10):
7481           CASE_FLT_FN (BUILT_IN_POW10):
7482             /* Prepare to do logN(exp10(exponent) -> exponent*logN(10).  */
7483             x = build_real (type, dconst10);
7484             exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
7485             break;
7486           CASE_FLT_FN (BUILT_IN_SQRT):
7487             /* Prepare to do logN(sqrt(x) -> 0.5*logN(x).  */
7488             x = TREE_VALUE (TREE_OPERAND (arg, 1));
7489             exponent = build_real (type, dconsthalf);
7490             break;
7491           CASE_FLT_FN (BUILT_IN_CBRT):
7492             /* Prepare to do logN(cbrt(x) -> (1/3)*logN(x).  */
7493             x = TREE_VALUE (TREE_OPERAND (arg, 1));
7494             exponent = build_real (type, real_value_truncate (TYPE_MODE (type),
7495                                                               dconstthird));
7496             break;
7497           CASE_FLT_FN (BUILT_IN_POW):
7498             /* Prepare to do logN(pow(x,exponent) -> exponent*logN(x).  */
7499             x = TREE_VALUE (TREE_OPERAND (arg, 1));
7500             exponent = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
7501             break;
7502           default:
7503             break;
7504           }
7505
7506           /* Now perform the optimization.  */
7507           if (x && exponent)
7508             {
7509               tree logfn;
7510               arglist = build_tree_list (NULL_TREE, x);
7511               logfn = build_function_call_expr (fndecl, arglist);
7512               return fold_build2 (MULT_EXPR, type, exponent, logfn);
7513             }
7514         }
7515     }
7516
7517   return 0;
7518 }
7519
7520 /* Fold a builtin function call to pow, powf, or powl.  Return
7521    NULL_TREE if no simplification can be made.  */
7522 static tree
7523 fold_builtin_pow (tree fndecl, tree arglist, tree type)
7524 {
7525   tree arg0 = TREE_VALUE (arglist);
7526   tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7527
7528   if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
7529     return NULL_TREE;
7530
7531   /* Optimize pow(1.0,y) = 1.0.  */
7532   if (real_onep (arg0))
7533     return omit_one_operand (type, build_real (type, dconst1), arg1);
7534
7535   if (TREE_CODE (arg1) == REAL_CST
7536       && ! TREE_CONSTANT_OVERFLOW (arg1))
7537     {
7538       REAL_VALUE_TYPE cint;
7539       REAL_VALUE_TYPE c;
7540       HOST_WIDE_INT n;
7541
7542       c = TREE_REAL_CST (arg1);
7543
7544       /* Optimize pow(x,0.0) = 1.0.  */
7545       if (REAL_VALUES_EQUAL (c, dconst0))
7546         return omit_one_operand (type, build_real (type, dconst1),
7547                                  arg0);
7548
7549       /* Optimize pow(x,1.0) = x.  */
7550       if (REAL_VALUES_EQUAL (c, dconst1))
7551         return arg0;
7552
7553       /* Optimize pow(x,-1.0) = 1.0/x.  */
7554       if (REAL_VALUES_EQUAL (c, dconstm1))
7555         return fold_build2 (RDIV_EXPR, type,
7556                             build_real (type, dconst1), arg0);
7557
7558       /* Optimize pow(x,0.5) = sqrt(x).  */
7559       if (flag_unsafe_math_optimizations
7560           && REAL_VALUES_EQUAL (c, dconsthalf))
7561         {
7562           tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
7563
7564           if (sqrtfn != NULL_TREE)
7565             {
7566               tree arglist = build_tree_list (NULL_TREE, arg0);
7567               return build_function_call_expr (sqrtfn, arglist);
7568             }
7569         }
7570
7571       /* Check for an integer exponent.  */
7572       n = real_to_integer (&c);
7573       real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
7574       if (real_identical (&c, &cint))
7575         {
7576           /* Attempt to evaluate pow at compile-time.  */
7577           if (TREE_CODE (arg0) == REAL_CST
7578               && ! TREE_CONSTANT_OVERFLOW (arg0))
7579             {
7580               REAL_VALUE_TYPE x;
7581               bool inexact;
7582
7583               x = TREE_REAL_CST (arg0);
7584               inexact = real_powi (&x, TYPE_MODE (type), &x, n);
7585               if (flag_unsafe_math_optimizations || !inexact)
7586                 return build_real (type, x);
7587             }
7588
7589           /* Strip sign ops from even integer powers.  */
7590           if ((n & 1) == 0 && flag_unsafe_math_optimizations)
7591             {
7592               tree narg0 = fold_strip_sign_ops (arg0);
7593               if (narg0)
7594                 {
7595                   arglist = build_tree_list (NULL_TREE, arg1);
7596                   arglist = tree_cons (NULL_TREE, narg0, arglist);
7597                   return build_function_call_expr (fndecl, arglist);
7598                 }
7599             }
7600         }
7601     }
7602
7603   if (flag_unsafe_math_optimizations)
7604     {
7605       const enum built_in_function fcode = builtin_mathfn_code (arg0);
7606
7607       /* Optimize pow(expN(x),y) = expN(x*y).  */
7608       if (BUILTIN_EXPONENT_P (fcode))
7609         {
7610           tree expfn = TREE_OPERAND (TREE_OPERAND (arg0, 0), 0);
7611           tree arg = TREE_VALUE (TREE_OPERAND (arg0, 1));
7612           arg = fold_build2 (MULT_EXPR, type, arg, arg1);
7613           arglist = build_tree_list (NULL_TREE, arg);
7614           return build_function_call_expr (expfn, arglist);
7615         }
7616
7617       /* Optimize pow(sqrt(x),y) = pow(x,y*0.5).  */
7618       if (BUILTIN_SQRT_P (fcode))
7619         {
7620           tree narg0 = TREE_VALUE (TREE_OPERAND (arg0, 1));
7621           tree narg1 = fold_build2 (MULT_EXPR, type, arg1,
7622                                     build_real (type, dconsthalf));
7623
7624           arglist = tree_cons (NULL_TREE, narg0,
7625                                build_tree_list (NULL_TREE, narg1));
7626           return build_function_call_expr (fndecl, arglist);
7627         }
7628
7629       /* Optimize pow(cbrt(x),y) = pow(x,y/3) iff x is nonnegative.  */
7630       if (BUILTIN_CBRT_P (fcode))
7631         {
7632           tree arg = TREE_VALUE (TREE_OPERAND (arg0, 1));
7633           if (tree_expr_nonnegative_p (arg))
7634             {
7635               const REAL_VALUE_TYPE dconstroot
7636                 = real_value_truncate (TYPE_MODE (type), dconstthird);
7637               tree narg1 = fold_build2 (MULT_EXPR, type, arg1,
7638                                         build_real (type, dconstroot));
7639               arglist = tree_cons (NULL_TREE, arg,
7640                                    build_tree_list (NULL_TREE, narg1));
7641               return build_function_call_expr (fndecl, arglist);
7642             }
7643         }
7644       
7645       /* Optimize pow(pow(x,y),z) = pow(x,y*z).  */
7646       if (fcode == BUILT_IN_POW || fcode == BUILT_IN_POWF
7647            || fcode == BUILT_IN_POWL)
7648         {
7649           tree arg00 = TREE_VALUE (TREE_OPERAND (arg0, 1));
7650           tree arg01 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg0, 1)));
7651           tree narg1 = fold_build2 (MULT_EXPR, type, arg01, arg1);
7652           arglist = tree_cons (NULL_TREE, arg00,
7653                                build_tree_list (NULL_TREE, narg1));
7654           return build_function_call_expr (fndecl, arglist);
7655         }
7656     }
7657
7658   return NULL_TREE;
7659 }
7660
7661 /* Fold a builtin function call to powi, powif, or powil.  Return
7662    NULL_TREE if no simplification can be made.  */
7663 static tree
7664 fold_builtin_powi (tree fndecl ATTRIBUTE_UNUSED, tree arglist, tree type)
7665 {
7666   tree arg0 = TREE_VALUE (arglist);
7667   tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7668
7669   if (!validate_arglist (arglist, REAL_TYPE, INTEGER_TYPE, VOID_TYPE))
7670     return NULL_TREE;
7671
7672   /* Optimize pow(1.0,y) = 1.0.  */
7673   if (real_onep (arg0))
7674     return omit_one_operand (type, build_real (type, dconst1), arg1);
7675
7676   if (host_integerp (arg1, 0))
7677     {
7678       HOST_WIDE_INT c = TREE_INT_CST_LOW (arg1);
7679
7680       /* Evaluate powi at compile-time.  */
7681       if (TREE_CODE (arg0) == REAL_CST
7682           && ! TREE_CONSTANT_OVERFLOW (arg0))
7683         {
7684           REAL_VALUE_TYPE x;
7685           x = TREE_REAL_CST (arg0);
7686           real_powi (&x, TYPE_MODE (type), &x, c);
7687           return build_real (type, x);
7688         }
7689
7690       /* Optimize pow(x,0) = 1.0.  */
7691       if (c == 0)
7692         return omit_one_operand (type, build_real (type, dconst1),
7693                                  arg0);
7694
7695       /* Optimize pow(x,1) = x.  */
7696       if (c == 1)
7697         return arg0;
7698
7699       /* Optimize pow(x,-1) = 1.0/x.  */
7700       if (c == -1)
7701         return fold_build2 (RDIV_EXPR, type,
7702                            build_real (type, dconst1), arg0);
7703     }
7704
7705   return NULL_TREE;
7706 }
7707
7708 /* A subroutine of fold_builtin to fold the various exponent
7709    functions.  EXP is the CALL_EXPR of a call to a builtin function.
7710    VALUE is the value which will be raised to a power.  */
7711
7712 static tree
7713 fold_builtin_exponent (tree fndecl, tree arglist,
7714                        const REAL_VALUE_TYPE *value)
7715 {
7716   if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7717     {
7718       tree type = TREE_TYPE (TREE_TYPE (fndecl));
7719       tree arg = TREE_VALUE (arglist);
7720
7721       /* Optimize exp*(0.0) = 1.0.  */
7722       if (real_zerop (arg))
7723         return build_real (type, dconst1);
7724
7725       /* Optimize expN(1.0) = N.  */
7726       if (real_onep (arg))
7727         {
7728           REAL_VALUE_TYPE cst;
7729
7730           real_convert (&cst, TYPE_MODE (type), value);
7731           return build_real (type, cst);
7732         }
7733
7734       /* Attempt to evaluate expN(integer) at compile-time.  */
7735       if (flag_unsafe_math_optimizations
7736           && TREE_CODE (arg) == REAL_CST
7737           && ! TREE_CONSTANT_OVERFLOW (arg))
7738         {
7739           REAL_VALUE_TYPE cint;
7740           REAL_VALUE_TYPE c;
7741           HOST_WIDE_INT n;
7742
7743           c = TREE_REAL_CST (arg);
7744           n = real_to_integer (&c);
7745           real_from_integer (&cint, VOIDmode, n,
7746                              n < 0 ? -1 : 0, 0);
7747           if (real_identical (&c, &cint))
7748             {
7749               REAL_VALUE_TYPE x;
7750
7751               real_powi (&x, TYPE_MODE (type), value, n);
7752               return build_real (type, x);
7753             }
7754         }
7755
7756       /* Optimize expN(logN(x)) = x.  */
7757       if (flag_unsafe_math_optimizations)
7758         {
7759           const enum built_in_function fcode = builtin_mathfn_code (arg);
7760
7761           if ((value == &dconste
7762                && (fcode == BUILT_IN_LOG
7763                    || fcode == BUILT_IN_LOGF
7764                    || fcode == BUILT_IN_LOGL))
7765               || (value == &dconst2
7766                   && (fcode == BUILT_IN_LOG2
7767                       || fcode == BUILT_IN_LOG2F
7768                       || fcode == BUILT_IN_LOG2L))
7769               || (value == &dconst10
7770                   && (fcode == BUILT_IN_LOG10
7771                       || fcode == BUILT_IN_LOG10F
7772                       || fcode == BUILT_IN_LOG10L)))
7773             return fold_convert (type, TREE_VALUE (TREE_OPERAND (arg, 1)));
7774         }
7775     }
7776
7777   return 0;
7778 }
7779
7780 /* Fold function call to builtin memcpy.  Return
7781    NULL_TREE if no simplification can be made.  */
7782
7783 static tree
7784 fold_builtin_memcpy (tree fndecl, tree arglist)
7785 {
7786   tree dest, src, len;
7787
7788   if (!validate_arglist (arglist,
7789                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7790     return 0;
7791
7792   dest = TREE_VALUE (arglist);
7793   src = TREE_VALUE (TREE_CHAIN (arglist));
7794   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7795
7796   /* If the LEN parameter is zero, return DEST.  */
7797   if (integer_zerop (len))
7798     return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
7799
7800   /* If SRC and DEST are the same (and not volatile), return DEST.  */
7801   if (operand_equal_p (src, dest, 0))
7802     return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, len);
7803
7804   return 0;
7805 }
7806
7807 /* Fold function call to builtin mempcpy.  Return
7808    NULL_TREE if no simplification can be made.  */
7809
7810 static tree
7811 fold_builtin_mempcpy (tree arglist, tree type, int endp)
7812 {
7813   if (validate_arglist (arglist,
7814                         POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7815     {
7816       tree dest = TREE_VALUE (arglist);
7817       tree src = TREE_VALUE (TREE_CHAIN (arglist));
7818       tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7819
7820       /* If the LEN parameter is zero, return DEST.  */
7821       if (integer_zerop (len))
7822         return omit_one_operand (type, dest, src);
7823
7824       /* If SRC and DEST are the same (and not volatile), return DEST+LEN.  */
7825       if (operand_equal_p (src, dest, 0))
7826         {
7827           if (endp == 0)
7828             return omit_one_operand (type, dest, len);
7829
7830           if (endp == 2)
7831             len = fold_build2 (MINUS_EXPR, TREE_TYPE (len), len,
7832                                ssize_int (1));
7833       
7834           len = fold_convert (TREE_TYPE (dest), len);
7835           len = fold_build2 (PLUS_EXPR, TREE_TYPE (dest), dest, len);
7836           return fold_convert (type, len);
7837         }
7838     }
7839   return 0;
7840 }
7841
7842 /* Fold function call to builtin memmove.  Return
7843    NULL_TREE if no simplification can be made.  */
7844
7845 static tree
7846 fold_builtin_memmove (tree arglist, tree type)
7847 {
7848   tree dest, src, len;
7849
7850   if (!validate_arglist (arglist,
7851                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7852     return 0;
7853
7854   dest = TREE_VALUE (arglist);
7855   src = TREE_VALUE (TREE_CHAIN (arglist));
7856   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7857
7858   /* If the LEN parameter is zero, return DEST.  */
7859   if (integer_zerop (len))
7860     return omit_one_operand (type, dest, src);
7861
7862   /* If SRC and DEST are the same (and not volatile), return DEST.  */
7863   if (operand_equal_p (src, dest, 0))
7864     return omit_one_operand (type, dest, len);
7865
7866   return 0;
7867 }
7868
7869 /* Fold function call to builtin strcpy.  If LEN is not NULL, it represents
7870    the length of the string to be copied.  Return NULL_TREE if no
7871    simplification can be made.  */
7872
7873 tree
7874 fold_builtin_strcpy (tree fndecl, tree arglist, tree len)
7875 {
7876   tree dest, src, fn;
7877
7878   if (!validate_arglist (arglist,
7879                          POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
7880     return 0;
7881
7882   dest = TREE_VALUE (arglist);
7883   src = TREE_VALUE (TREE_CHAIN (arglist));
7884
7885   /* If SRC and DEST are the same (and not volatile), return DEST.  */
7886   if (operand_equal_p (src, dest, 0))
7887     return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), dest);
7888
7889   if (optimize_size)
7890     return 0;
7891
7892   fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
7893   if (!fn)
7894     return 0;
7895
7896   if (!len)
7897     {
7898       len = c_strlen (src, 1);
7899       if (! len || TREE_SIDE_EFFECTS (len))
7900         return 0;
7901     }
7902
7903   len = size_binop (PLUS_EXPR, len, ssize_int (1));
7904   arglist = build_tree_list (NULL_TREE, len);
7905   arglist = tree_cons (NULL_TREE, src, arglist);
7906   arglist = tree_cons (NULL_TREE, dest, arglist);
7907   return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)),
7908                        build_function_call_expr (fn, arglist));
7909 }
7910
7911 /* Fold function call to builtin strncpy.  If SLEN is not NULL, it represents
7912    the length of the source string.  Return NULL_TREE if no simplification
7913    can be made.  */
7914
7915 tree
7916 fold_builtin_strncpy (tree fndecl, tree arglist, tree slen)
7917 {
7918   tree dest, src, len, fn;
7919
7920   if (!validate_arglist (arglist,
7921                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7922     return 0;
7923
7924   dest = TREE_VALUE (arglist);
7925   src = TREE_VALUE (TREE_CHAIN (arglist));
7926   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7927
7928   /* If the LEN parameter is zero, return DEST.  */
7929   if (integer_zerop (len))
7930     return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
7931
7932   /* We can't compare slen with len as constants below if len is not a
7933      constant.  */
7934   if (len == 0 || TREE_CODE (len) != INTEGER_CST)
7935     return 0;
7936
7937   if (!slen)
7938     slen = c_strlen (src, 1);
7939
7940   /* Now, we must be passed a constant src ptr parameter.  */
7941   if (slen == 0 || TREE_CODE (slen) != INTEGER_CST)
7942     return 0;
7943
7944   slen = size_binop (PLUS_EXPR, slen, ssize_int (1));
7945
7946   /* We do not support simplification of this case, though we do
7947      support it when expanding trees into RTL.  */
7948   /* FIXME: generate a call to __builtin_memset.  */
7949   if (tree_int_cst_lt (slen, len))
7950     return 0;
7951
7952   /* OK transform into builtin memcpy.  */
7953   fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
7954   if (!fn)
7955     return 0;
7956   return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)),
7957                        build_function_call_expr (fn, arglist));
7958 }
7959
7960 /* Fold function call to builtin memcmp.  Return
7961    NULL_TREE if no simplification can be made.  */
7962
7963 static tree
7964 fold_builtin_memcmp (tree arglist)
7965 {
7966   tree arg1, arg2, len;
7967   const char *p1, *p2;
7968
7969   if (!validate_arglist (arglist,
7970                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7971     return 0;
7972
7973   arg1 = TREE_VALUE (arglist);
7974   arg2 = TREE_VALUE (TREE_CHAIN (arglist));
7975   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7976
7977   /* If the LEN parameter is zero, return zero.  */
7978   if (integer_zerop (len))
7979     return omit_two_operands (integer_type_node, integer_zero_node,
7980                               arg1, arg2);
7981
7982   /* If ARG1 and ARG2 are the same (and not volatile), return zero.  */
7983   if (operand_equal_p (arg1, arg2, 0))
7984     return omit_one_operand (integer_type_node, integer_zero_node, len);
7985
7986   p1 = c_getstr (arg1);
7987   p2 = c_getstr (arg2);
7988
7989   /* If all arguments are constant, and the value of len is not greater
7990      than the lengths of arg1 and arg2, evaluate at compile-time.  */
7991   if (host_integerp (len, 1) && p1 && p2
7992       && compare_tree_int (len, strlen (p1) + 1) <= 0
7993       && compare_tree_int (len, strlen (p2) + 1) <= 0)
7994     {
7995       const int r = memcmp (p1, p2, tree_low_cst (len, 1));
7996
7997       if (r > 0)
7998         return integer_one_node;
7999       else if (r < 0)
8000         return integer_minus_one_node;
8001       else
8002         return integer_zero_node;
8003     }
8004
8005   /* If len parameter is one, return an expression corresponding to
8006      (*(const unsigned char*)arg1 - (const unsigned char*)arg2).  */
8007   if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
8008     {
8009       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8010       tree cst_uchar_ptr_node
8011         = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8012
8013       tree ind1 = fold_convert (integer_type_node,
8014                                 build1 (INDIRECT_REF, cst_uchar_node,
8015                                         fold_convert (cst_uchar_ptr_node,
8016                                                       arg1)));
8017       tree ind2 = fold_convert (integer_type_node,
8018                                 build1 (INDIRECT_REF, cst_uchar_node,
8019                                         fold_convert (cst_uchar_ptr_node,
8020                                                       arg2)));
8021       return fold_build2 (MINUS_EXPR, integer_type_node, ind1, ind2);
8022     }
8023
8024   return 0;
8025 }
8026
8027 /* Fold function call to builtin strcmp.  Return
8028    NULL_TREE if no simplification can be made.  */
8029
8030 static tree
8031 fold_builtin_strcmp (tree arglist)
8032 {
8033   tree arg1, arg2;
8034   const char *p1, *p2;
8035
8036   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
8037     return 0;
8038
8039   arg1 = TREE_VALUE (arglist);
8040   arg2 = TREE_VALUE (TREE_CHAIN (arglist));
8041
8042   /* If ARG1 and ARG2 are the same (and not volatile), return zero.  */
8043   if (operand_equal_p (arg1, arg2, 0))
8044     return integer_zero_node;
8045
8046   p1 = c_getstr (arg1);
8047   p2 = c_getstr (arg2);
8048
8049   if (p1 && p2)
8050     {
8051       const int i = strcmp (p1, p2);
8052       if (i < 0)
8053         return integer_minus_one_node;
8054       else if (i > 0)
8055         return integer_one_node;
8056       else
8057         return integer_zero_node;
8058     }
8059
8060   /* If the second arg is "", return *(const unsigned char*)arg1.  */
8061   if (p2 && *p2 == '\0')
8062     {
8063       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8064       tree cst_uchar_ptr_node
8065         = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8066
8067       return fold_convert (integer_type_node,
8068                            build1 (INDIRECT_REF, cst_uchar_node,
8069                                    fold_convert (cst_uchar_ptr_node,
8070                                                  arg1)));
8071     }
8072
8073   /* If the first arg is "", return -*(const unsigned char*)arg2.  */
8074   if (p1 && *p1 == '\0')
8075     {
8076       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8077       tree cst_uchar_ptr_node
8078         = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8079
8080       tree temp = fold_convert (integer_type_node,
8081                                 build1 (INDIRECT_REF, cst_uchar_node,
8082                                         fold_convert (cst_uchar_ptr_node,
8083                                                       arg2)));
8084       return fold_build1 (NEGATE_EXPR, integer_type_node, temp);
8085     }
8086
8087   return 0;
8088 }
8089
8090 /* Fold function call to builtin strncmp.  Return
8091    NULL_TREE if no simplification can be made.  */
8092
8093 static tree
8094 fold_builtin_strncmp (tree arglist)
8095 {
8096   tree arg1, arg2, len;
8097   const char *p1, *p2;
8098
8099   if (!validate_arglist (arglist,
8100                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8101     return 0;
8102
8103   arg1 = TREE_VALUE (arglist);
8104   arg2 = TREE_VALUE (TREE_CHAIN (arglist));
8105   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8106
8107   /* If the LEN parameter is zero, return zero.  */
8108   if (integer_zerop (len))
8109     return omit_two_operands (integer_type_node, integer_zero_node,
8110                               arg1, arg2);
8111
8112   /* If ARG1 and ARG2 are the same (and not volatile), return zero.  */
8113   if (operand_equal_p (arg1, arg2, 0))
8114     return omit_one_operand (integer_type_node, integer_zero_node, len);
8115
8116   p1 = c_getstr (arg1);
8117   p2 = c_getstr (arg2);
8118
8119   if (host_integerp (len, 1) && p1 && p2)
8120     {
8121       const int i = strncmp (p1, p2, tree_low_cst (len, 1));
8122       if (i > 0)
8123         return integer_one_node;
8124       else if (i < 0)
8125         return integer_minus_one_node;
8126       else
8127         return integer_zero_node;
8128     }
8129
8130   /* If the second arg is "", and the length is greater than zero,
8131      return *(const unsigned char*)arg1.  */
8132   if (p2 && *p2 == '\0'
8133       && TREE_CODE (len) == INTEGER_CST
8134       && tree_int_cst_sgn (len) == 1)
8135     {
8136       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8137       tree cst_uchar_ptr_node
8138         = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8139
8140       return fold_convert (integer_type_node,
8141                            build1 (INDIRECT_REF, cst_uchar_node,
8142                                    fold_convert (cst_uchar_ptr_node,
8143                                                  arg1)));
8144     }
8145
8146   /* If the first arg is "", and the length is greater than zero,
8147      return -*(const unsigned char*)arg2.  */
8148   if (p1 && *p1 == '\0'
8149       && TREE_CODE (len) == INTEGER_CST
8150       && tree_int_cst_sgn (len) == 1)
8151     {
8152       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8153       tree cst_uchar_ptr_node
8154         = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8155
8156       tree temp = fold_convert (integer_type_node,
8157                                 build1 (INDIRECT_REF, cst_uchar_node,
8158                                         fold_convert (cst_uchar_ptr_node,
8159                                                       arg2)));
8160       return fold_build1 (NEGATE_EXPR, integer_type_node, temp);
8161     }
8162
8163   /* If len parameter is one, return an expression corresponding to
8164      (*(const unsigned char*)arg1 - (const unsigned char*)arg2).  */
8165   if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
8166     {
8167       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8168       tree cst_uchar_ptr_node
8169         = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8170
8171       tree ind1 = fold_convert (integer_type_node,
8172                                 build1 (INDIRECT_REF, cst_uchar_node,
8173                                         fold_convert (cst_uchar_ptr_node,
8174                                                       arg1)));
8175       tree ind2 = fold_convert (integer_type_node,
8176                                 build1 (INDIRECT_REF, cst_uchar_node,
8177                                         fold_convert (cst_uchar_ptr_node,
8178                                                       arg2)));
8179       return fold_build2 (MINUS_EXPR, integer_type_node, ind1, ind2);
8180     }
8181
8182   return 0;
8183 }
8184
8185 /* Fold function call to builtin signbit, signbitf or signbitl.  Return
8186    NULL_TREE if no simplification can be made.  */
8187
8188 static tree
8189 fold_builtin_signbit (tree fndecl, tree arglist)
8190 {
8191   tree type = TREE_TYPE (TREE_TYPE (fndecl));
8192   tree arg, temp;
8193
8194   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8195     return NULL_TREE;
8196
8197   arg = TREE_VALUE (arglist);
8198
8199   /* If ARG is a compile-time constant, determine the result.  */
8200   if (TREE_CODE (arg) == REAL_CST
8201       && !TREE_CONSTANT_OVERFLOW (arg))
8202     {
8203       REAL_VALUE_TYPE c;
8204
8205       c = TREE_REAL_CST (arg);
8206       temp = REAL_VALUE_NEGATIVE (c) ? integer_one_node : integer_zero_node;
8207       return fold_convert (type, temp);
8208     }
8209
8210   /* If ARG is non-negative, the result is always zero.  */
8211   if (tree_expr_nonnegative_p (arg))
8212     return omit_one_operand (type, integer_zero_node, arg);
8213
8214   /* If ARG's format doesn't have signed zeros, return "arg < 0.0".  */
8215   if (!HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg))))
8216     return fold_build2 (LT_EXPR, type, arg,
8217                         build_real (TREE_TYPE (arg), dconst0));
8218
8219   return NULL_TREE;
8220 }
8221
8222 /* Fold function call to builtin copysign, copysignf or copysignl.
8223    Return NULL_TREE if no simplification can be made.  */
8224
8225 static tree
8226 fold_builtin_copysign (tree fndecl, tree arglist, tree type)
8227 {
8228   tree arg1, arg2, tem;
8229
8230   if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
8231     return NULL_TREE;
8232
8233   arg1 = TREE_VALUE (arglist);
8234   arg2 = TREE_VALUE (TREE_CHAIN (arglist));
8235
8236   /* copysign(X,X) is X.  */
8237   if (operand_equal_p (arg1, arg2, 0))
8238     return fold_convert (type, arg1);
8239
8240   /* If ARG1 and ARG2 are compile-time constants, determine the result.  */
8241   if (TREE_CODE (arg1) == REAL_CST
8242       && TREE_CODE (arg2) == REAL_CST
8243       && !TREE_CONSTANT_OVERFLOW (arg1)
8244       && !TREE_CONSTANT_OVERFLOW (arg2))
8245     {
8246       REAL_VALUE_TYPE c1, c2;
8247
8248       c1 = TREE_REAL_CST (arg1);
8249       c2 = TREE_REAL_CST (arg2);
8250       /* c1.sign := c2.sign.  */
8251       real_copysign (&c1, &c2);
8252       return build_real (type, c1);
8253     }
8254
8255   /* copysign(X, Y) is fabs(X) when Y is always non-negative.
8256      Remember to evaluate Y for side-effects.  */
8257   if (tree_expr_nonnegative_p (arg2))
8258     return omit_one_operand (type,
8259                              fold_build1 (ABS_EXPR, type, arg1),
8260                              arg2);
8261
8262   /* Strip sign changing operations for the first argument.  */
8263   tem = fold_strip_sign_ops (arg1);
8264   if (tem)
8265     {
8266       arglist = tree_cons (NULL_TREE, tem, TREE_CHAIN (arglist));
8267       return build_function_call_expr (fndecl, arglist);
8268     }
8269
8270   return NULL_TREE;
8271 }
8272
8273 /* Fold a call to builtin isascii.  */
8274
8275 static tree
8276 fold_builtin_isascii (tree arglist)
8277 {
8278   if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8279     return 0;
8280   else
8281     {
8282       /* Transform isascii(c) -> ((c & ~0x7f) == 0).  */
8283       tree arg = TREE_VALUE (arglist);
8284
8285       arg = build2 (BIT_AND_EXPR, integer_type_node, arg,
8286                     build_int_cst (NULL_TREE,
8287                                    ~ (unsigned HOST_WIDE_INT) 0x7f));
8288       arg = fold_build2 (EQ_EXPR, integer_type_node,
8289                          arg, integer_zero_node);
8290
8291       if (in_gimple_form && !TREE_CONSTANT (arg))
8292         return NULL_TREE;
8293       else
8294         return arg;
8295     }
8296 }
8297
8298 /* Fold a call to builtin toascii.  */
8299
8300 static tree
8301 fold_builtin_toascii (tree arglist)
8302 {
8303   if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8304     return 0;
8305   else
8306     {
8307       /* Transform toascii(c) -> (c & 0x7f).  */
8308       tree arg = TREE_VALUE (arglist);
8309
8310       return fold_build2 (BIT_AND_EXPR, integer_type_node, arg,
8311                           build_int_cst (NULL_TREE, 0x7f));
8312     }
8313 }
8314
8315 /* Fold a call to builtin isdigit.  */
8316
8317 static tree
8318 fold_builtin_isdigit (tree arglist)
8319 {
8320   if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8321     return 0;
8322   else
8323     {
8324       /* Transform isdigit(c) -> (unsigned)(c) - '0' <= 9.  */
8325       /* According to the C standard, isdigit is unaffected by locale.
8326          However, it definitely is affected by the target character set.  */
8327       tree arg;
8328       unsigned HOST_WIDE_INT target_digit0
8329         = lang_hooks.to_target_charset ('0');
8330
8331       if (target_digit0 == 0)
8332         return NULL_TREE;
8333
8334       arg = fold_convert (unsigned_type_node, TREE_VALUE (arglist));
8335       arg = build2 (MINUS_EXPR, unsigned_type_node, arg,
8336                     build_int_cst (unsigned_type_node, target_digit0));
8337       arg = fold_build2 (LE_EXPR, integer_type_node, arg,
8338                          build_int_cst (unsigned_type_node, 9));
8339       if (in_gimple_form && !TREE_CONSTANT (arg))
8340         return NULL_TREE;
8341       else
8342         return arg;
8343     }
8344 }
8345
8346 /* Fold a call to fabs, fabsf or fabsl.  */
8347
8348 static tree
8349 fold_builtin_fabs (tree arglist, tree type)
8350 {
8351   tree arg;
8352
8353   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8354     return 0;
8355
8356   arg = TREE_VALUE (arglist);
8357   arg = fold_convert (type, arg);
8358   if (TREE_CODE (arg) == REAL_CST)
8359     return fold_abs_const (arg, type);
8360   return fold_build1 (ABS_EXPR, type, arg);
8361 }
8362
8363 /* Fold a call to abs, labs, llabs or imaxabs.  */
8364
8365 static tree
8366 fold_builtin_abs (tree arglist, tree type)
8367 {
8368   tree arg;
8369
8370   if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8371     return 0;
8372
8373   arg = TREE_VALUE (arglist);
8374   arg = fold_convert (type, arg);
8375   if (TREE_CODE (arg) == INTEGER_CST)
8376     return fold_abs_const (arg, type);
8377   return fold_build1 (ABS_EXPR, type, arg);
8378 }
8379
8380 /* Fold a call to __builtin_isnan(), __builtin_isinf, __builtin_finite.
8381    EXP is the CALL_EXPR for the call.  */
8382
8383 static tree
8384 fold_builtin_classify (tree fndecl, tree arglist, int builtin_index)
8385 {
8386   tree type = TREE_TYPE (TREE_TYPE (fndecl));
8387   tree arg;
8388   REAL_VALUE_TYPE r;
8389
8390   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8391     {
8392       /* Check that we have exactly one argument.  */
8393       if (arglist == 0)
8394         {
8395           error ("too few arguments to function %qs",
8396                  IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8397           return error_mark_node;
8398         }
8399       else if (TREE_CHAIN (arglist) != 0)
8400         {
8401           error ("too many arguments to function %qs",
8402                  IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8403           return error_mark_node;
8404         }
8405       else
8406         {
8407           error ("non-floating-point argument to function %qs",
8408                  IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8409           return error_mark_node;
8410         }
8411     }
8412
8413   arg = TREE_VALUE (arglist);
8414   switch (builtin_index)
8415     {
8416     case BUILT_IN_ISINF:
8417       if (!MODE_HAS_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
8418         return omit_one_operand (type, integer_zero_node, arg);
8419
8420       if (TREE_CODE (arg) == REAL_CST)
8421         {
8422           r = TREE_REAL_CST (arg);
8423           if (real_isinf (&r))
8424             return real_compare (GT_EXPR, &r, &dconst0)
8425                    ? integer_one_node : integer_minus_one_node;
8426           else
8427             return integer_zero_node;
8428         }
8429
8430       return NULL_TREE;
8431
8432     case BUILT_IN_FINITE:
8433       if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg)))
8434           && !MODE_HAS_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
8435         return omit_one_operand (type, integer_zero_node, arg);
8436
8437       if (TREE_CODE (arg) == REAL_CST)
8438         {
8439           r = TREE_REAL_CST (arg);
8440           return real_isinf (&r) || real_isnan (&r)
8441                  ? integer_zero_node : integer_one_node;
8442         }
8443
8444       return NULL_TREE;
8445
8446     case BUILT_IN_ISNAN:
8447       if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg))))
8448         return omit_one_operand (type, integer_zero_node, arg);
8449
8450       if (TREE_CODE (arg) == REAL_CST)
8451         {
8452           r = TREE_REAL_CST (arg);
8453           return real_isnan (&r) ? integer_one_node : integer_zero_node;
8454         }
8455
8456       arg = builtin_save_expr (arg);
8457       return fold_build2 (UNORDERED_EXPR, type, arg, arg);
8458
8459     default:
8460       gcc_unreachable ();
8461     }
8462 }
8463
8464 /* Fold a call to an unordered comparison function such as
8465    __builtin_isgreater().  FNDECL is the FUNCTION_DECL for the function
8466    being called and ARGLIST is the argument list for the call.
8467    UNORDERED_CODE and ORDERED_CODE are comparison codes that give
8468    the opposite of the desired result.  UNORDERED_CODE is used
8469    for modes that can hold NaNs and ORDERED_CODE is used for
8470    the rest.  */
8471
8472 static tree
8473 fold_builtin_unordered_cmp (tree fndecl, tree arglist,
8474                             enum tree_code unordered_code,
8475                             enum tree_code ordered_code)
8476 {
8477   tree type = TREE_TYPE (TREE_TYPE (fndecl));
8478   enum tree_code code;
8479   tree arg0, arg1;
8480   tree type0, type1;
8481   enum tree_code code0, code1;
8482   tree cmp_type = NULL_TREE;
8483
8484   if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
8485     {
8486       /* Check that we have exactly two arguments.  */
8487       if (arglist == 0 || TREE_CHAIN (arglist) == 0)
8488         {
8489           error ("too few arguments to function %qs",
8490                  IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8491           return error_mark_node;
8492         }
8493       else if (TREE_CHAIN (TREE_CHAIN (arglist)) != 0)
8494         {
8495           error ("too many arguments to function %qs",
8496                  IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8497           return error_mark_node;
8498         }
8499     }
8500
8501   arg0 = TREE_VALUE (arglist);
8502   arg1 = TREE_VALUE (TREE_CHAIN (arglist));
8503   
8504   type0 = TREE_TYPE (arg0);
8505   type1 = TREE_TYPE (arg1);
8506   
8507   code0 = TREE_CODE (type0);
8508   code1 = TREE_CODE (type1);
8509   
8510   if (code0 == REAL_TYPE && code1 == REAL_TYPE)
8511     /* Choose the wider of two real types.  */
8512     cmp_type = TYPE_PRECISION (type0) >= TYPE_PRECISION (type1)
8513       ? type0 : type1;
8514   else if (code0 == REAL_TYPE && code1 == INTEGER_TYPE)
8515     cmp_type = type0;
8516   else if (code0 == INTEGER_TYPE && code1 == REAL_TYPE)
8517     cmp_type = type1;
8518   else
8519     {
8520       error ("non-floating-point argument to function %qs",
8521                  IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8522       return error_mark_node;
8523     }
8524   
8525   arg0 = fold_convert (cmp_type, arg0);
8526   arg1 = fold_convert (cmp_type, arg1);
8527
8528   if (unordered_code == UNORDERED_EXPR)
8529     {
8530       if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg0))))
8531         return omit_two_operands (type, integer_zero_node, arg0, arg1);
8532       return fold_build2 (UNORDERED_EXPR, type, arg0, arg1);
8533     }
8534
8535   code = MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg0))) ? unordered_code
8536                                                       : ordered_code;
8537   return fold_build1 (TRUTH_NOT_EXPR, type,
8538                       fold_build2 (code, type, arg0, arg1));
8539 }
8540
8541 /* Used by constant folding to simplify calls to builtin functions.  EXP is
8542    the CALL_EXPR of a call to a builtin function.  IGNORE is true if the
8543    result of the function call is ignored.  This function returns NULL_TREE
8544    if no simplification was possible.  */
8545
8546 static tree
8547 fold_builtin_1 (tree fndecl, tree arglist, bool ignore)
8548 {
8549   tree type = TREE_TYPE (TREE_TYPE (fndecl));
8550   enum built_in_function fcode;
8551
8552   if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
8553     return targetm.fold_builtin (fndecl, arglist, ignore);
8554
8555   fcode = DECL_FUNCTION_CODE (fndecl);
8556   switch (fcode)
8557     {
8558     case BUILT_IN_FPUTS:
8559       return fold_builtin_fputs (arglist, ignore, false, NULL_TREE);
8560
8561     case BUILT_IN_FPUTS_UNLOCKED:
8562       return fold_builtin_fputs (arglist, ignore, true, NULL_TREE);
8563
8564     case BUILT_IN_STRSTR:
8565       return fold_builtin_strstr (arglist, type);
8566
8567     case BUILT_IN_STRCAT:
8568       return fold_builtin_strcat (arglist);
8569
8570     case BUILT_IN_STRNCAT:
8571       return fold_builtin_strncat (arglist);
8572
8573     case BUILT_IN_STRSPN:
8574       return fold_builtin_strspn (arglist);
8575
8576     case BUILT_IN_STRCSPN:
8577       return fold_builtin_strcspn (arglist);
8578
8579     case BUILT_IN_STRCHR:
8580     case BUILT_IN_INDEX:
8581       return fold_builtin_strchr (arglist, type);
8582
8583     case BUILT_IN_STRRCHR:
8584     case BUILT_IN_RINDEX:
8585       return fold_builtin_strrchr (arglist, type);
8586
8587     case BUILT_IN_STRCPY:
8588       return fold_builtin_strcpy (fndecl, arglist, NULL_TREE);
8589
8590     case BUILT_IN_STRNCPY:
8591       return fold_builtin_strncpy (fndecl, arglist, NULL_TREE);
8592
8593     case BUILT_IN_STRCMP:
8594       return fold_builtin_strcmp (arglist);
8595
8596     case BUILT_IN_STRNCMP:
8597       return fold_builtin_strncmp (arglist);
8598
8599     case BUILT_IN_STRPBRK:
8600       return fold_builtin_strpbrk (arglist, type);
8601
8602     case BUILT_IN_BCMP:
8603     case BUILT_IN_MEMCMP:
8604       return fold_builtin_memcmp (arglist);
8605
8606     case BUILT_IN_SPRINTF:
8607       return fold_builtin_sprintf (arglist, ignore);
8608
8609     case BUILT_IN_CONSTANT_P:
8610       {
8611         tree val;
8612
8613         val = fold_builtin_constant_p (arglist);
8614         /* Gimplification will pull the CALL_EXPR for the builtin out of
8615            an if condition.  When not optimizing, we'll not CSE it back.
8616            To avoid link error types of regressions, return false now.  */
8617         if (!val && !optimize)
8618           val = integer_zero_node;
8619
8620         return val;
8621       }
8622
8623     case BUILT_IN_EXPECT:
8624       return fold_builtin_expect (arglist);
8625
8626     case BUILT_IN_CLASSIFY_TYPE:
8627       return fold_builtin_classify_type (arglist);
8628
8629     case BUILT_IN_STRLEN:
8630       return fold_builtin_strlen (arglist);
8631
8632     CASE_FLT_FN (BUILT_IN_FABS):
8633       return fold_builtin_fabs (arglist, type);
8634
8635     case BUILT_IN_ABS:
8636     case BUILT_IN_LABS:
8637     case BUILT_IN_LLABS:
8638     case BUILT_IN_IMAXABS:
8639       return fold_builtin_abs (arglist, type);
8640
8641     CASE_FLT_FN (BUILT_IN_CONJ):
8642       if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
8643         return fold_build1 (CONJ_EXPR, type, TREE_VALUE (arglist));
8644       break;
8645
8646     CASE_FLT_FN (BUILT_IN_CREAL):
8647       if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
8648         return non_lvalue (fold_build1 (REALPART_EXPR, type,
8649                                         TREE_VALUE (arglist)));
8650       break;
8651
8652     CASE_FLT_FN (BUILT_IN_CIMAG):
8653       if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
8654         return non_lvalue (fold_build1 (IMAGPART_EXPR, type,
8655                                         TREE_VALUE (arglist)));
8656       break;
8657
8658     CASE_FLT_FN (BUILT_IN_CABS):
8659       return fold_builtin_cabs (arglist, type);
8660
8661     CASE_FLT_FN (BUILT_IN_SQRT):
8662       return fold_builtin_sqrt (arglist, type);
8663
8664     CASE_FLT_FN (BUILT_IN_CBRT):
8665       return fold_builtin_cbrt (arglist, type);
8666
8667     CASE_FLT_FN (BUILT_IN_SIN):
8668       return fold_builtin_sin (arglist);
8669
8670     CASE_FLT_FN (BUILT_IN_COS):
8671       return fold_builtin_cos (arglist, type, fndecl);
8672
8673     CASE_FLT_FN (BUILT_IN_EXP):
8674       return fold_builtin_exponent (fndecl, arglist, &dconste);
8675
8676     CASE_FLT_FN (BUILT_IN_EXP2):
8677       return fold_builtin_exponent (fndecl, arglist, &dconst2);
8678
8679     CASE_FLT_FN (BUILT_IN_EXP10):
8680     CASE_FLT_FN (BUILT_IN_POW10):
8681       return fold_builtin_exponent (fndecl, arglist, &dconst10);
8682
8683     CASE_FLT_FN (BUILT_IN_LOG):
8684       return fold_builtin_logarithm (fndecl, arglist, &dconste);
8685
8686     CASE_FLT_FN (BUILT_IN_LOG2):
8687       return fold_builtin_logarithm (fndecl, arglist, &dconst2);
8688
8689     CASE_FLT_FN (BUILT_IN_LOG10):
8690       return fold_builtin_logarithm (fndecl, arglist, &dconst10);
8691
8692     CASE_FLT_FN (BUILT_IN_TAN):
8693       return fold_builtin_tan (arglist);
8694
8695     CASE_FLT_FN (BUILT_IN_ATAN):
8696       return fold_builtin_atan (arglist, type);
8697
8698     CASE_FLT_FN (BUILT_IN_POW):
8699       return fold_builtin_pow (fndecl, arglist, type);
8700
8701     CASE_FLT_FN (BUILT_IN_POWI):
8702       return fold_builtin_powi (fndecl, arglist, type);
8703
8704     CASE_FLT_FN (BUILT_IN_INF):
8705     case BUILT_IN_INFD32:
8706     case BUILT_IN_INFD64:
8707     case BUILT_IN_INFD128:
8708       return fold_builtin_inf (type, true);
8709
8710     CASE_FLT_FN (BUILT_IN_HUGE_VAL):
8711       return fold_builtin_inf (type, false);
8712
8713     CASE_FLT_FN (BUILT_IN_NAN):
8714     case BUILT_IN_NAND32:
8715     case BUILT_IN_NAND64:
8716     case BUILT_IN_NAND128:
8717       return fold_builtin_nan (arglist, type, true);
8718
8719     CASE_FLT_FN (BUILT_IN_NANS):
8720       return fold_builtin_nan (arglist, type, false);
8721
8722     CASE_FLT_FN (BUILT_IN_FLOOR):
8723       return fold_builtin_floor (fndecl, arglist);
8724
8725     CASE_FLT_FN (BUILT_IN_CEIL):
8726       return fold_builtin_ceil (fndecl, arglist);
8727
8728     CASE_FLT_FN (BUILT_IN_TRUNC):
8729       return fold_builtin_trunc (fndecl, arglist);
8730
8731     CASE_FLT_FN (BUILT_IN_ROUND):
8732       return fold_builtin_round (fndecl, arglist);
8733
8734     CASE_FLT_FN (BUILT_IN_NEARBYINT):
8735     CASE_FLT_FN (BUILT_IN_RINT):
8736       return fold_trunc_transparent_mathfn (fndecl, arglist);
8737
8738     CASE_FLT_FN (BUILT_IN_LCEIL):
8739     CASE_FLT_FN (BUILT_IN_LLCEIL):
8740     CASE_FLT_FN (BUILT_IN_LFLOOR):
8741     CASE_FLT_FN (BUILT_IN_LLFLOOR):
8742     CASE_FLT_FN (BUILT_IN_LROUND):   
8743     CASE_FLT_FN (BUILT_IN_LLROUND):
8744       return fold_builtin_int_roundingfn (fndecl, arglist);
8745
8746     CASE_FLT_FN (BUILT_IN_LRINT):
8747     CASE_FLT_FN (BUILT_IN_LLRINT):
8748       return fold_fixed_mathfn (fndecl, arglist);
8749
8750     CASE_INT_FN (BUILT_IN_FFS):
8751     CASE_INT_FN (BUILT_IN_CLZ):
8752     CASE_INT_FN (BUILT_IN_CTZ):
8753     CASE_INT_FN (BUILT_IN_POPCOUNT):
8754     CASE_INT_FN (BUILT_IN_PARITY):
8755       return fold_builtin_bitop (fndecl, arglist);
8756
8757     case BUILT_IN_MEMCPY:
8758       return fold_builtin_memcpy (fndecl, arglist);
8759
8760     case BUILT_IN_MEMPCPY:
8761       return fold_builtin_mempcpy (arglist, type, /*endp=*/1);
8762
8763     case BUILT_IN_MEMMOVE:
8764       return fold_builtin_memmove (arglist, type);
8765
8766     CASE_FLT_FN (BUILT_IN_SIGNBIT):
8767       return fold_builtin_signbit (fndecl, arglist);
8768
8769     case BUILT_IN_ISASCII:
8770       return fold_builtin_isascii (arglist);
8771
8772     case BUILT_IN_TOASCII:
8773       return fold_builtin_toascii (arglist);
8774
8775     case BUILT_IN_ISDIGIT:
8776       return fold_builtin_isdigit (arglist);
8777
8778     CASE_FLT_FN (BUILT_IN_COPYSIGN):
8779       return fold_builtin_copysign (fndecl, arglist, type);
8780
8781     CASE_FLT_FN (BUILT_IN_FINITE):
8782     case BUILT_IN_FINITED32:
8783     case BUILT_IN_FINITED64:
8784     case BUILT_IN_FINITED128:
8785       return fold_builtin_classify (fndecl, arglist, BUILT_IN_FINITE);
8786
8787     CASE_FLT_FN (BUILT_IN_ISINF):
8788     case BUILT_IN_ISINFD32:
8789     case BUILT_IN_ISINFD64:
8790     case BUILT_IN_ISINFD128:
8791       return fold_builtin_classify (fndecl, arglist, BUILT_IN_ISINF);
8792
8793     CASE_FLT_FN (BUILT_IN_ISNAN):
8794     case BUILT_IN_ISNAND32:
8795     case BUILT_IN_ISNAND64:
8796     case BUILT_IN_ISNAND128:
8797       return fold_builtin_classify (fndecl, arglist, BUILT_IN_ISNAN);
8798
8799     case BUILT_IN_ISGREATER:
8800       return fold_builtin_unordered_cmp (fndecl, arglist, UNLE_EXPR, LE_EXPR);
8801     case BUILT_IN_ISGREATEREQUAL:
8802       return fold_builtin_unordered_cmp (fndecl, arglist, UNLT_EXPR, LT_EXPR);
8803     case BUILT_IN_ISLESS:
8804       return fold_builtin_unordered_cmp (fndecl, arglist, UNGE_EXPR, GE_EXPR);
8805     case BUILT_IN_ISLESSEQUAL:
8806       return fold_builtin_unordered_cmp (fndecl, arglist, UNGT_EXPR, GT_EXPR);
8807     case BUILT_IN_ISLESSGREATER:
8808       return fold_builtin_unordered_cmp (fndecl, arglist, UNEQ_EXPR, EQ_EXPR);
8809     case BUILT_IN_ISUNORDERED:
8810       return fold_builtin_unordered_cmp (fndecl, arglist, UNORDERED_EXPR,
8811                                          NOP_EXPR);
8812
8813       /* We do the folding for va_start in the expander.  */
8814     case BUILT_IN_VA_START:
8815       break;
8816
8817     case BUILT_IN_OBJECT_SIZE:
8818       return fold_builtin_object_size (arglist);
8819     case BUILT_IN_MEMCPY_CHK:
8820     case BUILT_IN_MEMPCPY_CHK:
8821     case BUILT_IN_MEMMOVE_CHK:
8822     case BUILT_IN_MEMSET_CHK:
8823       return fold_builtin_memory_chk (fndecl, arglist, NULL_TREE, ignore,
8824                                       DECL_FUNCTION_CODE (fndecl));
8825     case BUILT_IN_STRCPY_CHK:
8826     case BUILT_IN_STPCPY_CHK:
8827       return fold_builtin_stxcpy_chk (fndecl, arglist, NULL_TREE, ignore,
8828                                       DECL_FUNCTION_CODE (fndecl));
8829     case BUILT_IN_STRNCPY_CHK:
8830       return fold_builtin_strncpy_chk (arglist, NULL_TREE);
8831     case BUILT_IN_STRCAT_CHK:
8832       return fold_builtin_strcat_chk (fndecl, arglist);
8833     case BUILT_IN_STRNCAT_CHK:
8834       return fold_builtin_strncat_chk (fndecl, arglist);
8835     case BUILT_IN_SPRINTF_CHK:
8836     case BUILT_IN_VSPRINTF_CHK:
8837       return fold_builtin_sprintf_chk (arglist, DECL_FUNCTION_CODE (fndecl));
8838     case BUILT_IN_SNPRINTF_CHK:
8839     case BUILT_IN_VSNPRINTF_CHK:
8840       return fold_builtin_snprintf_chk (arglist, NULL_TREE,
8841                                         DECL_FUNCTION_CODE (fndecl));
8842
8843     case BUILT_IN_PRINTF:
8844     case BUILT_IN_PRINTF_UNLOCKED:
8845     case BUILT_IN_VPRINTF:
8846     case BUILT_IN_PRINTF_CHK:
8847     case BUILT_IN_VPRINTF_CHK:
8848       return fold_builtin_printf (fndecl, arglist, ignore,
8849                                   DECL_FUNCTION_CODE (fndecl));
8850
8851     case BUILT_IN_FPRINTF:
8852     case BUILT_IN_FPRINTF_UNLOCKED:
8853     case BUILT_IN_VFPRINTF:
8854     case BUILT_IN_FPRINTF_CHK:
8855     case BUILT_IN_VFPRINTF_CHK:
8856       return fold_builtin_fprintf (fndecl, arglist, ignore,
8857                                    DECL_FUNCTION_CODE (fndecl));
8858
8859     default:
8860       break;
8861     }
8862
8863   return 0;
8864 }
8865
8866 /* A wrapper function for builtin folding that prevents warnings for
8867    "statement without effect" and the like, caused by removing the
8868    call node earlier than the warning is generated.  */
8869
8870 tree
8871 fold_builtin (tree fndecl, tree arglist, bool ignore)
8872 {
8873   tree exp = fold_builtin_1 (fndecl, arglist, ignore);
8874   if (exp)
8875     {
8876       exp = build1 (NOP_EXPR, TREE_TYPE (exp), exp);
8877       TREE_NO_WARNING (exp) = 1;
8878     }
8879
8880   return exp;
8881 }
8882
8883 /* Conveniently construct a function call expression.  */
8884
8885 tree
8886 build_function_call_expr (tree fn, tree arglist)
8887 {
8888   tree call_expr;
8889
8890   call_expr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
8891   return fold_build3 (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)),
8892                       call_expr, arglist, NULL_TREE);
8893 }
8894
8895 /* This function validates the types of a function call argument list
8896    represented as a tree chain of parameters against a specified list
8897    of tree_codes.  If the last specifier is a 0, that represents an
8898    ellipses, otherwise the last specifier must be a VOID_TYPE.  */
8899
8900 static int
8901 validate_arglist (tree arglist, ...)
8902 {
8903   enum tree_code code;
8904   int res = 0;
8905   va_list ap;
8906
8907   va_start (ap, arglist);
8908
8909   do
8910     {
8911       code = va_arg (ap, enum tree_code);
8912       switch (code)
8913         {
8914         case 0:
8915           /* This signifies an ellipses, any further arguments are all ok.  */
8916           res = 1;
8917           goto end;
8918         case VOID_TYPE:
8919           /* This signifies an endlink, if no arguments remain, return
8920              true, otherwise return false.  */
8921           res = arglist == 0;
8922           goto end;
8923         default:
8924           /* If no parameters remain or the parameter's code does not
8925              match the specified code, return false.  Otherwise continue
8926              checking any remaining arguments.  */
8927           if (arglist == 0)
8928             goto end;
8929           if (code == POINTER_TYPE)
8930             {
8931               if (! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist))))
8932                 goto end;
8933             }
8934           else if (code != TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))))
8935             goto end;
8936           break;
8937         }
8938       arglist = TREE_CHAIN (arglist);
8939     }
8940   while (1);
8941
8942   /* We need gotos here since we can only have one VA_CLOSE in a
8943      function.  */
8944  end: ;
8945   va_end (ap);
8946
8947   return res;
8948 }
8949
8950 /* Default target-specific builtin expander that does nothing.  */
8951
8952 rtx
8953 default_expand_builtin (tree exp ATTRIBUTE_UNUSED,
8954                         rtx target ATTRIBUTE_UNUSED,
8955                         rtx subtarget ATTRIBUTE_UNUSED,
8956                         enum machine_mode mode ATTRIBUTE_UNUSED,
8957                         int ignore ATTRIBUTE_UNUSED)
8958 {
8959   return NULL_RTX;
8960 }
8961
8962 /* Default target-specific library builtin expander that does nothing.  */
8963
8964 rtx
8965 default_expand_library_builtin (tree exp ATTRIBUTE_UNUSED,
8966                         rtx target ATTRIBUTE_UNUSED,
8967                         rtx subtarget ATTRIBUTE_UNUSED,
8968                         enum machine_mode mode ATTRIBUTE_UNUSED,
8969                         int ignore ATTRIBUTE_UNUSED)
8970 {
8971   return NULL_RTX;
8972 }
8973
8974 /* Returns true is EXP represents data that would potentially reside
8975    in a readonly section.  */
8976
8977 static bool
8978 readonly_data_expr (tree exp)
8979 {
8980   STRIP_NOPS (exp);
8981
8982   if (TREE_CODE (exp) != ADDR_EXPR)
8983     return false;
8984
8985   exp = get_base_address (TREE_OPERAND (exp, 0));
8986   if (!exp)
8987     return false;
8988
8989   /* Make sure we call decl_readonly_section only for trees it
8990      can handle (since it returns true for everything it doesn't
8991      understand).  */
8992   if (TREE_CODE (exp) == STRING_CST
8993       || TREE_CODE (exp) == CONSTRUCTOR
8994       || (TREE_CODE (exp) == VAR_DECL && TREE_STATIC (exp)))
8995     return decl_readonly_section (exp, 0);
8996   else
8997     return false;
8998 }
8999
9000 /* Simplify a call to the strstr builtin.
9001
9002    Return 0 if no simplification was possible, otherwise return the
9003    simplified form of the call as a tree.
9004
9005    The simplified form may be a constant or other expression which
9006    computes the same value, but in a more efficient manner (including
9007    calls to other builtin functions).
9008
9009    The call may contain arguments which need to be evaluated, but
9010    which are not useful to determine the result of the call.  In
9011    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
9012    COMPOUND_EXPR will be an argument which must be evaluated.
9013    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
9014    COMPOUND_EXPR in the chain will contain the tree for the simplified
9015    form of the builtin function call.  */
9016
9017 static tree
9018 fold_builtin_strstr (tree arglist, tree type)
9019 {
9020   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9021     return 0;
9022   else
9023     {
9024       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9025       tree fn;
9026       const char *p1, *p2;
9027
9028       p2 = c_getstr (s2);
9029       if (p2 == NULL)
9030         return 0;
9031
9032       p1 = c_getstr (s1);
9033       if (p1 != NULL)
9034         {
9035           const char *r = strstr (p1, p2);
9036           tree tem;
9037
9038           if (r == NULL)
9039             return build_int_cst (TREE_TYPE (s1), 0);
9040
9041           /* Return an offset into the constant string argument.  */
9042           tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
9043                              s1, build_int_cst (TREE_TYPE (s1), r - p1));
9044           return fold_convert (type, tem);
9045         }
9046
9047       /* The argument is const char *, and the result is char *, so we need
9048          a type conversion here to avoid a warning.  */
9049       if (p2[0] == '\0')
9050         return fold_convert (type, s1);
9051
9052       if (p2[1] != '\0')
9053         return 0;
9054
9055       fn = implicit_built_in_decls[BUILT_IN_STRCHR];
9056       if (!fn)
9057         return 0;
9058
9059       /* New argument list transforming strstr(s1, s2) to
9060          strchr(s1, s2[0]).  */
9061       arglist = build_tree_list (NULL_TREE,
9062                                  build_int_cst (NULL_TREE, p2[0]));
9063       arglist = tree_cons (NULL_TREE, s1, arglist);
9064       return build_function_call_expr (fn, arglist);
9065     }
9066 }
9067
9068 /* Simplify a call to the strchr builtin.
9069
9070    Return 0 if no simplification was possible, otherwise return the
9071    simplified form of the call as a tree.
9072
9073    The simplified form may be a constant or other expression which
9074    computes the same value, but in a more efficient manner (including
9075    calls to other builtin functions).
9076
9077    The call may contain arguments which need to be evaluated, but
9078    which are not useful to determine the result of the call.  In
9079    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
9080    COMPOUND_EXPR will be an argument which must be evaluated.
9081    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
9082    COMPOUND_EXPR in the chain will contain the tree for the simplified
9083    form of the builtin function call.  */
9084
9085 static tree
9086 fold_builtin_strchr (tree arglist, tree type)
9087 {
9088   if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9089     return 0;
9090   else
9091     {
9092       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9093       const char *p1;
9094
9095       if (TREE_CODE (s2) != INTEGER_CST)
9096         return 0;
9097
9098       p1 = c_getstr (s1);
9099       if (p1 != NULL)
9100         {
9101           char c;
9102           const char *r;
9103           tree tem;
9104
9105           if (target_char_cast (s2, &c))
9106             return 0;
9107
9108           r = strchr (p1, c);
9109
9110           if (r == NULL)
9111             return build_int_cst (TREE_TYPE (s1), 0);
9112
9113           /* Return an offset into the constant string argument.  */
9114           tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
9115                              s1, build_int_cst (TREE_TYPE (s1), r - p1));
9116           return fold_convert (type, tem);
9117         }
9118       return 0;
9119     }
9120 }
9121
9122 /* Simplify a call to the strrchr builtin.
9123
9124    Return 0 if no simplification was possible, otherwise return the
9125    simplified form of the call as a tree.
9126
9127    The simplified form may be a constant or other expression which
9128    computes the same value, but in a more efficient manner (including
9129    calls to other builtin functions).
9130
9131    The call may contain arguments which need to be evaluated, but
9132    which are not useful to determine the result of the call.  In
9133    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
9134    COMPOUND_EXPR will be an argument which must be evaluated.
9135    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
9136    COMPOUND_EXPR in the chain will contain the tree for the simplified
9137    form of the builtin function call.  */
9138
9139 static tree
9140 fold_builtin_strrchr (tree arglist, tree type)
9141 {
9142   if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9143     return 0;
9144   else
9145     {
9146       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9147       tree fn;
9148       const char *p1;
9149
9150       if (TREE_CODE (s2) != INTEGER_CST)
9151         return 0;
9152
9153       p1 = c_getstr (s1);
9154       if (p1 != NULL)
9155         {
9156           char c;
9157           const char *r;
9158           tree tem;
9159
9160           if (target_char_cast (s2, &c))
9161             return 0;
9162
9163           r = strrchr (p1, c);
9164
9165           if (r == NULL)
9166             return build_int_cst (TREE_TYPE (s1), 0);
9167
9168           /* Return an offset into the constant string argument.  */
9169           tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
9170                              s1, build_int_cst (TREE_TYPE (s1), r - p1));
9171           return fold_convert (type, tem);
9172         }
9173
9174       if (! integer_zerop (s2))
9175         return 0;
9176
9177       fn = implicit_built_in_decls[BUILT_IN_STRCHR];
9178       if (!fn)
9179         return 0;
9180
9181       /* Transform strrchr(s1, '\0') to strchr(s1, '\0').  */
9182       return build_function_call_expr (fn, arglist);
9183     }
9184 }
9185
9186 /* Simplify a call to the strpbrk builtin.
9187
9188    Return 0 if no simplification was possible, otherwise return the
9189    simplified form of the call as a tree.
9190
9191    The simplified form may be a constant or other expression which
9192    computes the same value, but in a more efficient manner (including
9193    calls to other builtin functions).
9194
9195    The call may contain arguments which need to be evaluated, but
9196    which are not useful to determine the result of the call.  In
9197    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
9198    COMPOUND_EXPR will be an argument which must be evaluated.
9199    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
9200    COMPOUND_EXPR in the chain will contain the tree for the simplified
9201    form of the builtin function call.  */
9202
9203 static tree
9204 fold_builtin_strpbrk (tree arglist, tree type)
9205 {
9206   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9207     return 0;
9208   else
9209     {
9210       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9211       tree fn;
9212       const char *p1, *p2;
9213
9214       p2 = c_getstr (s2);
9215       if (p2 == NULL)
9216         return 0;
9217
9218       p1 = c_getstr (s1);
9219       if (p1 != NULL)
9220         {
9221           const char *r = strpbrk (p1, p2);
9222           tree tem;
9223
9224           if (r == NULL)
9225             return build_int_cst (TREE_TYPE (s1), 0);
9226
9227           /* Return an offset into the constant string argument.  */
9228           tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
9229                              s1, build_int_cst (TREE_TYPE (s1), r - p1));
9230           return fold_convert (type, tem);
9231         }
9232
9233       if (p2[0] == '\0')
9234         /* strpbrk(x, "") == NULL.
9235            Evaluate and ignore s1 in case it had side-effects.  */
9236         return omit_one_operand (TREE_TYPE (s1), integer_zero_node, s1);
9237
9238       if (p2[1] != '\0')
9239         return 0;  /* Really call strpbrk.  */
9240
9241       fn = implicit_built_in_decls[BUILT_IN_STRCHR];
9242       if (!fn)
9243         return 0;
9244
9245       /* New argument list transforming strpbrk(s1, s2) to
9246          strchr(s1, s2[0]).  */
9247       arglist = build_tree_list (NULL_TREE,
9248                                  build_int_cst (NULL_TREE, p2[0]));
9249       arglist = tree_cons (NULL_TREE, s1, arglist);
9250       return build_function_call_expr (fn, arglist);
9251     }
9252 }
9253
9254 /* Simplify a call to the strcat builtin.
9255
9256    Return 0 if no simplification was possible, otherwise return the
9257    simplified form of the call as a tree.
9258
9259    The simplified form may be a constant or other expression which
9260    computes the same value, but in a more efficient manner (including
9261    calls to other builtin functions).
9262
9263    The call may contain arguments which need to be evaluated, but
9264    which are not useful to determine the result of the call.  In
9265    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
9266    COMPOUND_EXPR will be an argument which must be evaluated.
9267    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
9268    COMPOUND_EXPR in the chain will contain the tree for the simplified
9269    form of the builtin function call.  */
9270
9271 static tree
9272 fold_builtin_strcat (tree arglist)
9273 {
9274   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9275     return 0;
9276   else
9277     {
9278       tree dst = TREE_VALUE (arglist),
9279         src = TREE_VALUE (TREE_CHAIN (arglist));
9280       const char *p = c_getstr (src);
9281
9282       /* If the string length is zero, return the dst parameter.  */
9283       if (p && *p == '\0')
9284         return dst;
9285
9286       return 0;
9287     }
9288 }
9289
9290 /* Simplify a call to the strncat builtin.
9291
9292    Return 0 if no simplification was possible, otherwise return the
9293    simplified form of the call as a tree.
9294
9295    The simplified form may be a constant or other expression which
9296    computes the same value, but in a more efficient manner (including
9297    calls to other builtin functions).
9298
9299    The call may contain arguments which need to be evaluated, but
9300    which are not useful to determine the result of the call.  In
9301    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
9302    COMPOUND_EXPR will be an argument which must be evaluated.
9303    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
9304    COMPOUND_EXPR in the chain will contain the tree for the simplified
9305    form of the builtin function call.  */
9306
9307 static tree
9308 fold_builtin_strncat (tree arglist)
9309 {
9310   if (!validate_arglist (arglist,
9311                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9312     return 0;
9313   else
9314     {
9315       tree dst = TREE_VALUE (arglist);
9316       tree src = TREE_VALUE (TREE_CHAIN (arglist));
9317       tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
9318       const char *p = c_getstr (src);
9319
9320       /* If the requested length is zero, or the src parameter string
9321          length is zero, return the dst parameter.  */
9322       if (integer_zerop (len) || (p && *p == '\0'))
9323         return omit_two_operands (TREE_TYPE (dst), dst, src, len);
9324
9325       /* If the requested len is greater than or equal to the string
9326          length, call strcat.  */
9327       if (TREE_CODE (len) == INTEGER_CST && p
9328           && compare_tree_int (len, strlen (p)) >= 0)
9329         {
9330           tree newarglist
9331             = tree_cons (NULL_TREE, dst, build_tree_list (NULL_TREE, src));
9332           tree fn = implicit_built_in_decls[BUILT_IN_STRCAT];
9333
9334           /* If the replacement _DECL isn't initialized, don't do the
9335              transformation.  */
9336           if (!fn)
9337             return 0;
9338
9339           return build_function_call_expr (fn, newarglist);
9340         }
9341       return 0;
9342     }
9343 }
9344
9345 /* Simplify a call to the strspn builtin.
9346
9347    Return 0 if no simplification was possible, otherwise return the
9348    simplified form of the call as a tree.
9349
9350    The simplified form may be a constant or other expression which
9351    computes the same value, but in a more efficient manner (including
9352    calls to other builtin functions).
9353
9354    The call may contain arguments which need to be evaluated, but
9355    which are not useful to determine the result of the call.  In
9356    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
9357    COMPOUND_EXPR will be an argument which must be evaluated.
9358    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
9359    COMPOUND_EXPR in the chain will contain the tree for the simplified
9360    form of the builtin function call.  */
9361
9362 static tree
9363 fold_builtin_strspn (tree arglist)
9364 {
9365   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9366     return 0;
9367   else
9368     {
9369       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9370       const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
9371
9372       /* If both arguments are constants, evaluate at compile-time.  */
9373       if (p1 && p2)
9374         {
9375           const size_t r = strspn (p1, p2);
9376           return size_int (r);
9377         }
9378
9379       /* If either argument is "", return 0.  */
9380       if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
9381         /* Evaluate and ignore both arguments in case either one has
9382            side-effects.  */
9383         return omit_two_operands (integer_type_node, integer_zero_node,
9384                                   s1, s2);
9385       return 0;
9386     }
9387 }
9388
9389 /* Simplify a call to the strcspn builtin.
9390
9391    Return 0 if no simplification was possible, otherwise return the
9392    simplified form of the call as a tree.
9393
9394    The simplified form may be a constant or other expression which
9395    computes the same value, but in a more efficient manner (including
9396    calls to other builtin functions).
9397
9398    The call may contain arguments which need to be evaluated, but
9399    which are not useful to determine the result of the call.  In
9400    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
9401    COMPOUND_EXPR will be an argument which must be evaluated.
9402    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
9403    COMPOUND_EXPR in the chain will contain the tree for the simplified
9404    form of the builtin function call.  */
9405
9406 static tree
9407 fold_builtin_strcspn (tree arglist)
9408 {
9409   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9410     return 0;
9411   else
9412     {
9413       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9414       const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
9415
9416       /* If both arguments are constants, evaluate at compile-time.  */
9417       if (p1 && p2)
9418         {
9419           const size_t r = strcspn (p1, p2);
9420           return size_int (r);
9421         }
9422
9423       /* If the first argument is "", return 0.  */
9424       if (p1 && *p1 == '\0')
9425         {
9426           /* Evaluate and ignore argument s2 in case it has
9427              side-effects.  */
9428           return omit_one_operand (integer_type_node,
9429                                    integer_zero_node, s2);
9430         }
9431
9432       /* If the second argument is "", return __builtin_strlen(s1).  */
9433       if (p2 && *p2 == '\0')
9434         {
9435           tree newarglist = build_tree_list (NULL_TREE, s1),
9436             fn = implicit_built_in_decls[BUILT_IN_STRLEN];
9437
9438           /* If the replacement _DECL isn't initialized, don't do the
9439              transformation.  */
9440           if (!fn)
9441             return 0;
9442
9443           return build_function_call_expr (fn, newarglist);
9444         }
9445       return 0;
9446     }
9447 }
9448
9449 /* Fold a call to the fputs builtin.  IGNORE is true if the value returned
9450    by the builtin will be ignored.  UNLOCKED is true is true if this
9451    actually a call to fputs_unlocked.  If LEN in non-NULL, it represents
9452    the known length of the string.  Return NULL_TREE if no simplification
9453    was possible.  */
9454
9455 tree
9456 fold_builtin_fputs (tree arglist, bool ignore, bool unlocked, tree len)
9457 {
9458   tree fn;
9459   /* If we're using an unlocked function, assume the other unlocked
9460      functions exist explicitly.  */
9461   tree const fn_fputc = unlocked ? built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
9462     : implicit_built_in_decls[BUILT_IN_FPUTC];
9463   tree const fn_fwrite = unlocked ? built_in_decls[BUILT_IN_FWRITE_UNLOCKED]
9464     : implicit_built_in_decls[BUILT_IN_FWRITE];
9465
9466   /* If the return value is used, don't do the transformation.  */
9467   if (!ignore)
9468     return 0;
9469
9470   /* Verify the arguments in the original call.  */
9471   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9472     return 0;
9473
9474   if (! len)
9475     len = c_strlen (TREE_VALUE (arglist), 0);
9476
9477   /* Get the length of the string passed to fputs.  If the length
9478      can't be determined, punt.  */
9479   if (!len
9480       || TREE_CODE (len) != INTEGER_CST)
9481     return 0;
9482
9483   switch (compare_tree_int (len, 1))
9484     {
9485     case -1: /* length is 0, delete the call entirely .  */
9486       return omit_one_operand (integer_type_node, integer_zero_node,
9487                                TREE_VALUE (TREE_CHAIN (arglist)));
9488
9489     case 0: /* length is 1, call fputc.  */
9490       {
9491         const char *p = c_getstr (TREE_VALUE (arglist));
9492
9493         if (p != NULL)
9494           {
9495             /* New argument list transforming fputs(string, stream) to
9496                fputc(string[0], stream).  */
9497             arglist = build_tree_list (NULL_TREE,
9498                                        TREE_VALUE (TREE_CHAIN (arglist)));
9499             arglist = tree_cons (NULL_TREE,
9500                                  build_int_cst (NULL_TREE, p[0]),
9501                                  arglist);
9502             fn = fn_fputc;
9503             break;
9504           }
9505       }
9506       /* FALLTHROUGH */
9507     case 1: /* length is greater than 1, call fwrite.  */
9508       {
9509         tree string_arg;
9510
9511         /* If optimizing for size keep fputs.  */
9512         if (optimize_size)
9513           return 0;
9514         string_arg = TREE_VALUE (arglist);
9515         /* New argument list transforming fputs(string, stream) to
9516            fwrite(string, 1, len, stream).  */
9517         arglist = build_tree_list (NULL_TREE,
9518                                    TREE_VALUE (TREE_CHAIN (arglist)));
9519         arglist = tree_cons (NULL_TREE, len, arglist);
9520         arglist = tree_cons (NULL_TREE, size_one_node, arglist);
9521         arglist = tree_cons (NULL_TREE, string_arg, arglist);
9522         fn = fn_fwrite;
9523         break;
9524       }
9525     default:
9526       gcc_unreachable ();
9527     }
9528
9529   /* If the replacement _DECL isn't initialized, don't do the
9530      transformation.  */
9531   if (!fn)
9532     return 0;
9533
9534   /* These optimizations are only performed when the result is ignored,
9535      hence there's no need to cast the result to integer_type_node.  */
9536   return build_function_call_expr (fn, arglist);
9537 }
9538
9539 /* Fold the new_arg's arguments (ARGLIST). Returns true if there was an error
9540    produced.  False otherwise.  This is done so that we don't output the error
9541    or warning twice or three times.  */
9542 bool
9543 fold_builtin_next_arg (tree arglist)
9544 {
9545   tree fntype = TREE_TYPE (current_function_decl);
9546
9547   if (TYPE_ARG_TYPES (fntype) == 0
9548       || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
9549           == void_type_node))
9550     {
9551       error ("%<va_start%> used in function with fixed args");
9552       return true;
9553     }
9554   else if (!arglist)
9555     {
9556       /* Evidently an out of date version of <stdarg.h>; can't validate
9557          va_start's second argument, but can still work as intended.  */
9558       warning (0, "%<__builtin_next_arg%> called without an argument");
9559       return true;
9560     }
9561   /* We use __builtin_va_start (ap, 0, 0) or __builtin_next_arg (0, 0)
9562      when we checked the arguments and if needed issued a warning.  */
9563   else if (!TREE_CHAIN (arglist)
9564            || !integer_zerop (TREE_VALUE (arglist))
9565            || !integer_zerop (TREE_VALUE (TREE_CHAIN (arglist)))
9566            || TREE_CHAIN (TREE_CHAIN (arglist)))
9567     {
9568       tree last_parm = tree_last (DECL_ARGUMENTS (current_function_decl));
9569       tree arg = TREE_VALUE (arglist);
9570
9571       if (TREE_CHAIN (arglist))
9572         {
9573           error ("%<va_start%> used with too many arguments");
9574           return true;
9575         }
9576
9577       /* Strip off all nops for the sake of the comparison.  This
9578          is not quite the same as STRIP_NOPS.  It does more.
9579          We must also strip off INDIRECT_EXPR for C++ reference
9580          parameters.  */
9581       while (TREE_CODE (arg) == NOP_EXPR
9582              || TREE_CODE (arg) == CONVERT_EXPR
9583              || TREE_CODE (arg) == NON_LVALUE_EXPR
9584              || TREE_CODE (arg) == INDIRECT_REF)
9585         arg = TREE_OPERAND (arg, 0);
9586       if (arg != last_parm)
9587         {
9588           /* FIXME: Sometimes with the tree optimizers we can get the
9589              not the last argument even though the user used the last
9590              argument.  We just warn and set the arg to be the last
9591              argument so that we will get wrong-code because of
9592              it.  */
9593           warning (0, "second parameter of %<va_start%> not last named argument");
9594         }
9595       /* We want to verify the second parameter just once before the tree
9596          optimizers are run and then avoid keeping it in the tree,
9597          as otherwise we could warn even for correct code like:
9598          void foo (int i, ...)
9599          { va_list ap; i++; va_start (ap, i); va_end (ap); }  */
9600       TREE_VALUE (arglist) = integer_zero_node;
9601       TREE_CHAIN (arglist) = build_tree_list (NULL, integer_zero_node);
9602     }
9603   return false;
9604 }
9605
9606
9607 /* Simplify a call to the sprintf builtin.
9608
9609    Return 0 if no simplification was possible, otherwise return the
9610    simplified form of the call as a tree.  If IGNORED is true, it means that
9611    the caller does not use the returned value of the function.  */
9612
9613 static tree
9614 fold_builtin_sprintf (tree arglist, int ignored)
9615 {
9616   tree call, retval, dest, fmt;
9617   const char *fmt_str = NULL;
9618
9619   /* Verify the required arguments in the original call.  We deal with two
9620      types of sprintf() calls: 'sprintf (str, fmt)' and
9621      'sprintf (dest, "%s", orig)'.  */
9622   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)
9623       && !validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, POINTER_TYPE,
9624                             VOID_TYPE))
9625     return NULL_TREE;
9626
9627   /* Get the destination string and the format specifier.  */
9628   dest = TREE_VALUE (arglist);
9629   fmt = TREE_VALUE (TREE_CHAIN (arglist));
9630
9631   /* Check whether the format is a literal string constant.  */
9632   fmt_str = c_getstr (fmt);
9633   if (fmt_str == NULL)
9634     return NULL_TREE;
9635
9636   call = NULL_TREE;
9637   retval = NULL_TREE;
9638
9639   if (!init_target_chars())
9640     return 0;
9641
9642   /* If the format doesn't contain % args or %%, use strcpy.  */
9643   if (strchr (fmt_str, target_percent) == NULL)
9644     {
9645       tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
9646
9647       if (!fn)
9648         return NULL_TREE;
9649
9650       /* Convert sprintf (str, fmt) into strcpy (str, fmt) when
9651          'format' is known to contain no % formats.  */
9652       arglist = build_tree_list (NULL_TREE, fmt);
9653       arglist = tree_cons (NULL_TREE, dest, arglist);
9654       call = build_function_call_expr (fn, arglist);
9655       if (!ignored)
9656         retval = build_int_cst (NULL_TREE, strlen (fmt_str));
9657     }
9658
9659   /* If the format is "%s", use strcpy if the result isn't used.  */
9660   else if (fmt_str && strcmp (fmt_str, target_percent_s) == 0)
9661     {
9662       tree fn, orig;
9663       fn = implicit_built_in_decls[BUILT_IN_STRCPY];
9664
9665       if (!fn)
9666         return NULL_TREE;
9667
9668       /* Convert sprintf (str1, "%s", str2) into strcpy (str1, str2).  */
9669       orig = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
9670       arglist = build_tree_list (NULL_TREE, orig);
9671       arglist = tree_cons (NULL_TREE, dest, arglist);
9672       if (!ignored)
9673         {
9674           retval = c_strlen (orig, 1);
9675           if (!retval || TREE_CODE (retval) != INTEGER_CST)
9676             return NULL_TREE;
9677         }
9678       call = build_function_call_expr (fn, arglist);
9679     }
9680
9681   if (call && retval)
9682     {
9683       retval = fold_convert
9684         (TREE_TYPE (TREE_TYPE (implicit_built_in_decls[BUILT_IN_SPRINTF])),
9685          retval);
9686       return build2 (COMPOUND_EXPR, TREE_TYPE (retval), call, retval);
9687     }
9688   else
9689     return call;
9690 }
9691
9692 /* Expand a call to __builtin_object_size.  */
9693
9694 rtx
9695 expand_builtin_object_size (tree exp)
9696 {
9697   tree ost;
9698   int object_size_type;
9699   tree fndecl = get_callee_fndecl (exp);
9700   tree arglist = TREE_OPERAND (exp, 1);
9701   location_t locus = EXPR_LOCATION (exp);
9702
9703   if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9704     {
9705       error ("%Hfirst argument of %D must be a pointer, second integer constant",
9706              &locus, fndecl);
9707       expand_builtin_trap ();
9708       return const0_rtx;
9709     }
9710
9711   ost = TREE_VALUE (TREE_CHAIN (arglist));
9712   STRIP_NOPS (ost);
9713
9714   if (TREE_CODE (ost) != INTEGER_CST
9715       || tree_int_cst_sgn (ost) < 0
9716       || compare_tree_int (ost, 3) > 0)
9717     {
9718       error ("%Hlast argument of %D is not integer constant between 0 and 3",
9719              &locus, fndecl);
9720       expand_builtin_trap ();
9721       return const0_rtx;
9722     }
9723
9724   object_size_type = tree_low_cst (ost, 0);
9725
9726   return object_size_type < 2 ? constm1_rtx : const0_rtx;
9727 }
9728
9729 /* Expand EXP, a call to the __mem{cpy,pcpy,move,set}_chk builtin.
9730    FCODE is the BUILT_IN_* to use.
9731    Return 0 if we failed; the caller should emit a normal call,
9732    otherwise try to get the result in TARGET, if convenient (and in
9733    mode MODE if that's convenient).  */
9734
9735 static rtx
9736 expand_builtin_memory_chk (tree exp, rtx target, enum machine_mode mode,
9737                            enum built_in_function fcode)
9738 {
9739   tree arglist = TREE_OPERAND (exp, 1);
9740   tree dest, src, len, size;
9741
9742   if (!validate_arglist (arglist,
9743                          POINTER_TYPE,
9744                          fcode == BUILT_IN_MEMSET_CHK
9745                          ? INTEGER_TYPE : POINTER_TYPE,
9746                          INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
9747     return 0;
9748
9749   dest = TREE_VALUE (arglist);
9750   src = TREE_VALUE (TREE_CHAIN (arglist));
9751   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
9752   size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
9753
9754   if (! host_integerp (size, 1))
9755     return 0;
9756
9757   if (host_integerp (len, 1) || integer_all_onesp (size))
9758     {
9759       tree fn;
9760
9761       if (! integer_all_onesp (size) && tree_int_cst_lt (size, len))
9762         {
9763           location_t locus = EXPR_LOCATION (exp);
9764           warning (0, "%Hcall to %D will always overflow destination buffer",
9765                    &locus, get_callee_fndecl (exp));
9766           return 0;
9767         }
9768
9769       arglist = build_tree_list (NULL_TREE, len);
9770       arglist = tree_cons (NULL_TREE, src, arglist);
9771       arglist = tree_cons (NULL_TREE, dest, arglist);
9772
9773       fn = NULL_TREE;
9774       /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume
9775          mem{cpy,pcpy,move,set} is available.  */
9776       switch (fcode)
9777         {
9778         case BUILT_IN_MEMCPY_CHK:
9779           fn = built_in_decls[BUILT_IN_MEMCPY];
9780           break;
9781         case BUILT_IN_MEMPCPY_CHK:
9782           fn = built_in_decls[BUILT_IN_MEMPCPY];
9783           break;
9784         case BUILT_IN_MEMMOVE_CHK:
9785           fn = built_in_decls[BUILT_IN_MEMMOVE];
9786           break;
9787         case BUILT_IN_MEMSET_CHK:
9788           fn = built_in_decls[BUILT_IN_MEMSET];
9789           break;
9790         default:
9791           break;
9792         }
9793
9794       if (! fn)
9795         return 0;
9796
9797       fn = build_function_call_expr (fn, arglist);
9798       if (TREE_CODE (fn) == CALL_EXPR)
9799         CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
9800       return expand_expr (fn, target, mode, EXPAND_NORMAL);
9801     }
9802   else if (fcode == BUILT_IN_MEMSET_CHK)
9803     return 0;
9804   else
9805     {
9806       unsigned int dest_align
9807         = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
9808
9809       /* If DEST is not a pointer type, call the normal function.  */
9810       if (dest_align == 0)
9811         return 0;
9812
9813       /* If SRC and DEST are the same (and not volatile), do nothing.  */
9814       if (operand_equal_p (src, dest, 0))
9815         {
9816           tree expr;
9817
9818           if (fcode != BUILT_IN_MEMPCPY_CHK)
9819             {
9820               /* Evaluate and ignore LEN in case it has side-effects.  */
9821               expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
9822               return expand_expr (dest, target, mode, EXPAND_NORMAL);
9823             }
9824
9825           len = fold_convert (TREE_TYPE (dest), len);
9826           expr = fold_build2 (PLUS_EXPR, TREE_TYPE (dest), dest, len);
9827           return expand_expr (expr, target, mode, EXPAND_NORMAL);
9828         }
9829
9830       /* __memmove_chk special case.  */
9831       if (fcode == BUILT_IN_MEMMOVE_CHK)
9832         {
9833           unsigned int src_align
9834             = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
9835
9836           if (src_align == 0)
9837             return 0;
9838
9839           /* If src is categorized for a readonly section we can use
9840              normal __memcpy_chk.  */
9841           if (readonly_data_expr (src))
9842             {
9843               tree fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
9844               if (!fn)
9845                 return 0;
9846               fn = build_function_call_expr (fn, arglist);
9847               if (TREE_CODE (fn) == CALL_EXPR)
9848                 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
9849               return expand_expr (fn, target, mode, EXPAND_NORMAL);
9850             }
9851         }
9852       return 0;
9853     }
9854 }
9855
9856 /* Emit warning if a buffer overflow is detected at compile time.  */
9857
9858 static void
9859 maybe_emit_chk_warning (tree exp, enum built_in_function fcode)
9860 {
9861   int arg_mask, is_strlen = 0;
9862   tree arglist = TREE_OPERAND (exp, 1), a;
9863   tree len, size;
9864   location_t locus;
9865
9866   switch (fcode)
9867     {
9868     case BUILT_IN_STRCPY_CHK:
9869     case BUILT_IN_STPCPY_CHK:
9870     /* For __strcat_chk the warning will be emitted only if overflowing
9871        by at least strlen (dest) + 1 bytes.  */
9872     case BUILT_IN_STRCAT_CHK:
9873       arg_mask = 6;
9874       is_strlen = 1;
9875       break;
9876     case BUILT_IN_STRNCPY_CHK:
9877       arg_mask = 12;
9878       break;
9879     case BUILT_IN_SNPRINTF_CHK:
9880     case BUILT_IN_VSNPRINTF_CHK:
9881       arg_mask = 10;
9882       break;
9883     default:
9884       gcc_unreachable ();
9885     }
9886
9887   len = NULL_TREE;
9888   size = NULL_TREE;
9889   for (a = arglist; a && arg_mask; a = TREE_CHAIN (a), arg_mask >>= 1)
9890     if (arg_mask & 1)
9891       {
9892         if (len)
9893           size = a;
9894         else
9895           len = a;
9896       }
9897
9898   if (!len || !size)
9899     return;
9900
9901   len = TREE_VALUE (len);
9902   size = TREE_VALUE (size);
9903
9904   if (! host_integerp (size, 1) || integer_all_onesp (size))
9905     return;
9906
9907   if (is_strlen)
9908     {
9909       len = c_strlen (len, 1);
9910       if (! len || ! host_integerp (len, 1) || tree_int_cst_lt (len, size))
9911         return;
9912     }
9913   else if (! host_integerp (len, 1) || ! tree_int_cst_lt (size, len))
9914     return;
9915
9916   locus = EXPR_LOCATION (exp);
9917   warning (0, "%Hcall to %D will always overflow destination buffer",
9918            &locus, get_callee_fndecl (exp));
9919 }
9920
9921 /* Emit warning if a buffer overflow is detected at compile time
9922    in __sprintf_chk/__vsprintf_chk calls.  */
9923
9924 static void
9925 maybe_emit_sprintf_chk_warning (tree exp, enum built_in_function fcode)
9926 {
9927   tree arglist = TREE_OPERAND (exp, 1);
9928   tree dest, size, len, fmt, flag;
9929   const char *fmt_str;
9930
9931   /* Verify the required arguments in the original call.  */
9932   if (! arglist)
9933     return;
9934   dest = TREE_VALUE (arglist);
9935   arglist = TREE_CHAIN (arglist);
9936   if (! arglist)
9937     return;
9938   flag = TREE_VALUE (arglist);
9939   arglist = TREE_CHAIN (arglist);
9940   if (! arglist)
9941     return;
9942   size = TREE_VALUE (arglist);
9943   arglist = TREE_CHAIN (arglist);
9944   if (! arglist)
9945     return;
9946   fmt = TREE_VALUE (arglist);
9947   arglist = TREE_CHAIN (arglist);
9948
9949   if (! host_integerp (size, 1) || integer_all_onesp (size))
9950     return;
9951
9952   /* Check whether the format is a literal string constant.  */
9953   fmt_str = c_getstr (fmt);
9954   if (fmt_str == NULL)
9955     return;
9956
9957   if (!init_target_chars())
9958     return;
9959
9960   /* If the format doesn't contain % args or %%, we know its size.  */
9961   if (strchr (fmt_str, target_percent) == 0)
9962     len = build_int_cstu (size_type_node, strlen (fmt_str));
9963   /* If the format is "%s" and first ... argument is a string literal,
9964      we know it too.  */
9965   else if (fcode == BUILT_IN_SPRINTF_CHK && strcmp (fmt_str, target_percent_s) == 0)
9966     {
9967       tree arg;
9968
9969       if (! arglist)
9970         return;
9971       arg = TREE_VALUE (arglist);
9972       if (! POINTER_TYPE_P (TREE_TYPE (arg)))
9973         return;
9974
9975       len = c_strlen (arg, 1);
9976       if (!len || ! host_integerp (len, 1))
9977         return;
9978     }
9979   else
9980     return;
9981
9982   if (! tree_int_cst_lt (len, size))
9983     {
9984       location_t locus = EXPR_LOCATION (exp);
9985       warning (0, "%Hcall to %D will always overflow destination buffer",
9986                &locus, get_callee_fndecl (exp));
9987     }
9988 }
9989
9990 /* Fold a call to __builtin_object_size, if possible.  */
9991
9992 tree
9993 fold_builtin_object_size (tree arglist)
9994 {
9995   tree ptr, ost, ret = 0;
9996   int object_size_type;
9997
9998   if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9999     return 0;
10000
10001   ptr = TREE_VALUE (arglist);
10002   ost = TREE_VALUE (TREE_CHAIN (arglist));
10003   STRIP_NOPS (ost);
10004
10005   if (TREE_CODE (ost) != INTEGER_CST
10006       || tree_int_cst_sgn (ost) < 0
10007       || compare_tree_int (ost, 3) > 0)
10008     return 0;
10009
10010   object_size_type = tree_low_cst (ost, 0);
10011
10012   /* __builtin_object_size doesn't evaluate side-effects in its arguments;
10013      if there are any side-effects, it returns (size_t) -1 for types 0 and 1
10014      and (size_t) 0 for types 2 and 3.  */
10015   if (TREE_SIDE_EFFECTS (ptr))
10016     return fold_convert (size_type_node,
10017                          object_size_type < 2
10018                          ? integer_minus_one_node : integer_zero_node);
10019
10020   if (TREE_CODE (ptr) == ADDR_EXPR)
10021     ret = build_int_cstu (size_type_node,
10022                         compute_builtin_object_size (ptr, object_size_type));
10023
10024   else if (TREE_CODE (ptr) == SSA_NAME)
10025     {
10026       unsigned HOST_WIDE_INT bytes;
10027
10028       /* If object size is not known yet, delay folding until
10029        later.  Maybe subsequent passes will help determining
10030        it.  */
10031       bytes = compute_builtin_object_size (ptr, object_size_type);
10032       if (bytes != (unsigned HOST_WIDE_INT) (object_size_type < 2
10033                                              ? -1 : 0))
10034         ret = build_int_cstu (size_type_node, bytes);
10035     }
10036
10037   if (ret)
10038     {
10039       ret = force_fit_type (ret, -1, false, false);
10040       if (TREE_CONSTANT_OVERFLOW (ret))
10041         ret = 0;
10042     }
10043
10044   return ret;
10045 }
10046
10047 /* Fold a call to the __mem{cpy,pcpy,move,set}_chk builtin.
10048    IGNORE is true, if return value can be ignored.  FCODE is the BUILT_IN_*
10049    code of the builtin.  If MAXLEN is not NULL, it is maximum length
10050    passed as third argument.  */
10051
10052 tree
10053 fold_builtin_memory_chk (tree fndecl, tree arglist, tree maxlen, bool ignore,
10054                          enum built_in_function fcode)
10055 {
10056   tree dest, src, len, size, fn;
10057
10058   if (!validate_arglist (arglist,
10059                          POINTER_TYPE,
10060                          fcode == BUILT_IN_MEMSET_CHK
10061                          ? INTEGER_TYPE : POINTER_TYPE,
10062                          INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
10063     return 0;
10064
10065   dest = TREE_VALUE (arglist);
10066   /* Actually val for __memset_chk, but it doesn't matter.  */
10067   src = TREE_VALUE (TREE_CHAIN (arglist));
10068   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10069   size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
10070
10071   /* If SRC and DEST are the same (and not volatile), return DEST
10072      (resp. DEST+LEN for __mempcpy_chk).  */
10073   if (fcode != BUILT_IN_MEMSET_CHK && operand_equal_p (src, dest, 0))
10074     {
10075       if (fcode != BUILT_IN_MEMPCPY_CHK)
10076         return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, len);
10077       else
10078         {
10079           tree temp = fold_convert (TREE_TYPE (dest), len);
10080           temp = fold_build2 (PLUS_EXPR, TREE_TYPE (dest), dest, temp);
10081           return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), temp);
10082         }
10083     }
10084
10085   if (! host_integerp (size, 1))
10086     return 0;
10087
10088   if (! integer_all_onesp (size))
10089     {
10090       if (! host_integerp (len, 1))
10091         {
10092           /* If LEN is not constant, try MAXLEN too.
10093              For MAXLEN only allow optimizing into non-_ocs function
10094              if SIZE is >= MAXLEN, never convert to __ocs_fail ().  */
10095           if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
10096             {
10097               if (fcode == BUILT_IN_MEMPCPY_CHK && ignore)
10098                 {
10099                   /* (void) __mempcpy_chk () can be optimized into
10100                      (void) __memcpy_chk ().  */
10101                   fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
10102                   if (!fn)
10103                     return 0;
10104
10105                   return build_function_call_expr (fn, arglist);
10106                 }
10107               return 0;
10108             }
10109         }
10110       else
10111         maxlen = len;
10112
10113       if (tree_int_cst_lt (size, maxlen))
10114         return 0;
10115     }
10116
10117   arglist = build_tree_list (NULL_TREE, len);
10118   arglist = tree_cons (NULL_TREE, src, arglist);
10119   arglist = tree_cons (NULL_TREE, dest, arglist);
10120
10121   fn = NULL_TREE;
10122   /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume
10123      mem{cpy,pcpy,move,set} is available.  */
10124   switch (fcode)
10125     {
10126     case BUILT_IN_MEMCPY_CHK:
10127       fn = built_in_decls[BUILT_IN_MEMCPY];
10128       break;
10129     case BUILT_IN_MEMPCPY_CHK:
10130       fn = built_in_decls[BUILT_IN_MEMPCPY];
10131       break;
10132     case BUILT_IN_MEMMOVE_CHK:
10133       fn = built_in_decls[BUILT_IN_MEMMOVE];
10134       break;
10135     case BUILT_IN_MEMSET_CHK:
10136       fn = built_in_decls[BUILT_IN_MEMSET];
10137       break;
10138     default:
10139       break;
10140     }
10141
10142   if (!fn)
10143     return 0;
10144
10145   return build_function_call_expr (fn, arglist);
10146 }
10147
10148 /* Fold a call to the __st[rp]cpy_chk builtin.
10149    IGNORE is true, if return value can be ignored.  FCODE is the BUILT_IN_*
10150    code of the builtin.  If MAXLEN is not NULL, it is maximum length of
10151    strings passed as second argument.  */
10152
10153 tree
10154 fold_builtin_stxcpy_chk (tree fndecl, tree arglist, tree maxlen, bool ignore,
10155                          enum built_in_function fcode)
10156 {
10157   tree dest, src, size, len, fn;
10158
10159   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
10160                          VOID_TYPE))
10161     return 0;
10162
10163   dest = TREE_VALUE (arglist);
10164   src = TREE_VALUE (TREE_CHAIN (arglist));
10165   size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10166
10167   /* If SRC and DEST are the same (and not volatile), return DEST.  */
10168   if (fcode == BUILT_IN_STRCPY_CHK && operand_equal_p (src, dest, 0))
10169     return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), dest);
10170  
10171   if (! host_integerp (size, 1))
10172     return 0;
10173
10174   if (! integer_all_onesp (size))
10175     {
10176       len = c_strlen (src, 1);
10177       if (! len || ! host_integerp (len, 1))
10178         {
10179           /* If LEN is not constant, try MAXLEN too.
10180              For MAXLEN only allow optimizing into non-_ocs function
10181              if SIZE is >= MAXLEN, never convert to __ocs_fail ().  */
10182           if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
10183             {
10184               if (fcode == BUILT_IN_STPCPY_CHK)
10185                 {
10186                   if (! ignore)
10187                     return 0;
10188
10189                   /* If return value of __stpcpy_chk is ignored,
10190                      optimize into __strcpy_chk.  */
10191                   fn = built_in_decls[BUILT_IN_STRCPY_CHK];
10192                   if (!fn)
10193                     return 0;
10194
10195                   return build_function_call_expr (fn, arglist);
10196                 }
10197
10198               if (! len || TREE_SIDE_EFFECTS (len))
10199                 return 0;
10200
10201               /* If c_strlen returned something, but not a constant,
10202                  transform __strcpy_chk into __memcpy_chk.  */
10203               fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
10204               if (!fn)
10205                 return 0;
10206
10207               len = size_binop (PLUS_EXPR, len, ssize_int (1));
10208               arglist = build_tree_list (NULL_TREE, size);
10209               arglist = tree_cons (NULL_TREE, len, arglist);
10210               arglist = tree_cons (NULL_TREE, src, arglist);
10211               arglist = tree_cons (NULL_TREE, dest, arglist);
10212               return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)),
10213                                    build_function_call_expr (fn, arglist));
10214             }
10215         }
10216       else
10217         maxlen = len;
10218
10219       if (! tree_int_cst_lt (maxlen, size))
10220         return 0;
10221     }
10222
10223   arglist = build_tree_list (NULL_TREE, src);
10224   arglist = tree_cons (NULL_TREE, dest, arglist);
10225
10226   /* If __builtin_st{r,p}cpy_chk is used, assume st{r,p}cpy is available.  */
10227   fn = built_in_decls[fcode == BUILT_IN_STPCPY_CHK
10228                       ? BUILT_IN_STPCPY : BUILT_IN_STRCPY];
10229   if (!fn)
10230     return 0;
10231
10232   return build_function_call_expr (fn, arglist);
10233 }
10234
10235 /* Fold a call to the __strncpy_chk builtin.
10236    If MAXLEN is not NULL, it is maximum length passed as third argument.  */
10237
10238 tree
10239 fold_builtin_strncpy_chk (tree arglist, tree maxlen)
10240 {
10241   tree dest, src, size, len, fn;
10242
10243   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
10244                          INTEGER_TYPE, VOID_TYPE))
10245     return 0;
10246
10247   dest = TREE_VALUE (arglist);
10248   src = TREE_VALUE (TREE_CHAIN (arglist));
10249   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10250   size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
10251
10252   if (! host_integerp (size, 1))
10253     return 0;
10254
10255   if (! integer_all_onesp (size))
10256     {
10257       if (! host_integerp (len, 1))
10258         {
10259           /* If LEN is not constant, try MAXLEN too.
10260              For MAXLEN only allow optimizing into non-_ocs function
10261              if SIZE is >= MAXLEN, never convert to __ocs_fail ().  */
10262           if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
10263             return 0;
10264         }
10265       else
10266         maxlen = len;
10267
10268       if (tree_int_cst_lt (size, maxlen))
10269         return 0;
10270     }
10271
10272   arglist = build_tree_list (NULL_TREE, len);
10273   arglist = tree_cons (NULL_TREE, src, arglist);
10274   arglist = tree_cons (NULL_TREE, dest, arglist);
10275
10276   /* If __builtin_strncpy_chk is used, assume strncpy is available.  */
10277   fn = built_in_decls[BUILT_IN_STRNCPY];
10278   if (!fn)
10279     return 0;
10280
10281   return build_function_call_expr (fn, arglist);
10282 }
10283
10284 /* Fold a call to the __strcat_chk builtin FNDECL with ARGLIST.  */
10285
10286 static tree
10287 fold_builtin_strcat_chk (tree fndecl, tree arglist)
10288 {
10289   tree dest, src, size, fn;
10290   const char *p;
10291
10292   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
10293                          VOID_TYPE))
10294     return 0;
10295
10296   dest = TREE_VALUE (arglist);
10297   src = TREE_VALUE (TREE_CHAIN (arglist));
10298   size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10299
10300   p = c_getstr (src);
10301   /* If the SRC parameter is "", return DEST.  */
10302   if (p && *p == '\0')
10303     return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
10304
10305   if (! host_integerp (size, 1) || ! integer_all_onesp (size))
10306     return 0;
10307
10308   arglist = build_tree_list (NULL_TREE, src);
10309   arglist = tree_cons (NULL_TREE, dest, arglist);
10310
10311   /* If __builtin_strcat_chk is used, assume strcat is available.  */
10312   fn = built_in_decls[BUILT_IN_STRCAT];
10313   if (!fn)
10314     return 0;
10315
10316   return build_function_call_expr (fn, arglist);
10317 }
10318
10319 /* Fold a call to the __strncat_chk builtin EXP.  */
10320
10321 static tree
10322 fold_builtin_strncat_chk (tree fndecl, tree arglist)
10323 {
10324   tree dest, src, size, len, fn;
10325   const char *p;
10326
10327   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
10328                          INTEGER_TYPE, VOID_TYPE))
10329     return 0;
10330
10331   dest = TREE_VALUE (arglist);
10332   src = TREE_VALUE (TREE_CHAIN (arglist));
10333   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10334   size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
10335
10336   p = c_getstr (src);
10337   /* If the SRC parameter is "" or if LEN is 0, return DEST.  */
10338   if (p && *p == '\0')
10339     return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, len);
10340   else if (integer_zerop (len))
10341     return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
10342
10343   if (! host_integerp (size, 1))
10344     return 0;
10345
10346   if (! integer_all_onesp (size))
10347     {
10348       tree src_len = c_strlen (src, 1);
10349       if (src_len
10350           && host_integerp (src_len, 1)
10351           && host_integerp (len, 1)
10352           && ! tree_int_cst_lt (len, src_len))
10353         {
10354           /* If LEN >= strlen (SRC), optimize into __strcat_chk.  */
10355           fn = built_in_decls[BUILT_IN_STRCAT_CHK];
10356           if (!fn)
10357             return 0;
10358
10359           arglist = build_tree_list (NULL_TREE, size);
10360           arglist = tree_cons (NULL_TREE, src, arglist);
10361           arglist = tree_cons (NULL_TREE, dest, arglist);
10362           return build_function_call_expr (fn, arglist);
10363         }
10364       return 0;
10365     }
10366
10367   arglist = build_tree_list (NULL_TREE, len);
10368   arglist = tree_cons (NULL_TREE, src, arglist);
10369   arglist = tree_cons (NULL_TREE, dest, arglist);
10370
10371   /* If __builtin_strncat_chk is used, assume strncat is available.  */
10372   fn = built_in_decls[BUILT_IN_STRNCAT];
10373   if (!fn)
10374     return 0;
10375
10376   return build_function_call_expr (fn, arglist);
10377 }
10378
10379 /* Fold a call to __{,v}sprintf_chk with argument list ARGLIST.  Return 0 if
10380    a normal call should be emitted rather than expanding the function
10381    inline.  FCODE is either BUILT_IN_SPRINTF_CHK or BUILT_IN_VSPRINTF_CHK.  */
10382
10383 static tree
10384 fold_builtin_sprintf_chk (tree arglist, enum built_in_function fcode)
10385 {
10386   tree dest, size, len, fn, fmt, flag;
10387   const char *fmt_str;
10388
10389   /* Verify the required arguments in the original call.  */
10390   if (! arglist)
10391     return 0;
10392   dest = TREE_VALUE (arglist);
10393   if (! POINTER_TYPE_P (TREE_TYPE (dest)))
10394     return 0;
10395   arglist = TREE_CHAIN (arglist);
10396   if (! arglist)
10397     return 0;
10398   flag = TREE_VALUE (arglist);
10399   if (TREE_CODE (TREE_TYPE (flag)) != INTEGER_TYPE)
10400     return 0;
10401   arglist = TREE_CHAIN (arglist);
10402   if (! arglist)
10403     return 0;
10404   size = TREE_VALUE (arglist);
10405   if (TREE_CODE (TREE_TYPE (size)) != INTEGER_TYPE)
10406     return 0;
10407   arglist = TREE_CHAIN (arglist);
10408   if (! arglist)
10409     return 0;
10410   fmt = TREE_VALUE (arglist);
10411   if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
10412     return 0;
10413   arglist = TREE_CHAIN (arglist);
10414
10415   if (! host_integerp (size, 1))
10416     return 0;
10417
10418   len = NULL_TREE;
10419
10420   if (!init_target_chars())
10421     return 0;
10422
10423   /* Check whether the format is a literal string constant.  */
10424   fmt_str = c_getstr (fmt);
10425   if (fmt_str != NULL)
10426     {
10427       /* If the format doesn't contain % args or %%, we know the size.  */
10428       if (strchr (fmt_str, target_percent) == 0)
10429         {
10430           if (fcode != BUILT_IN_SPRINTF_CHK || arglist == NULL_TREE)
10431             len = build_int_cstu (size_type_node, strlen (fmt_str));
10432         }
10433       /* If the format is "%s" and first ... argument is a string literal,
10434          we know the size too.  */
10435       else if (fcode == BUILT_IN_SPRINTF_CHK && strcmp (fmt_str, target_percent_s) == 0)
10436         {
10437           tree arg;
10438
10439           if (arglist && !TREE_CHAIN (arglist))
10440             {
10441               arg = TREE_VALUE (arglist);
10442               if (POINTER_TYPE_P (TREE_TYPE (arg)))
10443                 {
10444                   len = c_strlen (arg, 1);
10445                   if (! len || ! host_integerp (len, 1))
10446                     len = NULL_TREE;
10447                 }
10448             }
10449         }
10450     }
10451
10452   if (! integer_all_onesp (size))
10453     {
10454       if (! len || ! tree_int_cst_lt (len, size))
10455         return 0;
10456     }
10457
10458   /* Only convert __{,v}sprintf_chk to {,v}sprintf if flag is 0
10459      or if format doesn't contain % chars or is "%s".  */
10460   if (! integer_zerop (flag))
10461     {
10462       if (fmt_str == NULL)
10463         return 0;
10464       if (strchr (fmt_str, target_percent) != NULL && strcmp (fmt_str, target_percent_s))
10465         return 0;
10466     }
10467
10468   arglist = tree_cons (NULL_TREE, fmt, arglist);
10469   arglist = tree_cons (NULL_TREE, dest, arglist);
10470
10471   /* If __builtin_{,v}sprintf_chk is used, assume {,v}sprintf is available.  */
10472   fn = built_in_decls[fcode == BUILT_IN_VSPRINTF_CHK
10473                       ? BUILT_IN_VSPRINTF : BUILT_IN_SPRINTF];
10474   if (!fn)
10475     return 0;
10476
10477   return build_function_call_expr (fn, arglist);
10478 }
10479
10480 /* Fold a call to {,v}snprintf with argument list ARGLIST.  Return 0 if
10481    a normal call should be emitted rather than expanding the function
10482    inline.  FCODE is either BUILT_IN_SNPRINTF_CHK or
10483    BUILT_IN_VSNPRINTF_CHK.  If MAXLEN is not NULL, it is maximum length
10484    passed as second argument.  */
10485
10486 tree
10487 fold_builtin_snprintf_chk (tree arglist, tree maxlen,
10488                            enum built_in_function fcode)
10489 {
10490   tree dest, size, len, fn, fmt, flag;
10491   const char *fmt_str;
10492
10493   /* Verify the required arguments in the original call.  */
10494   if (! arglist)
10495     return 0;
10496   dest = TREE_VALUE (arglist);
10497   if (! POINTER_TYPE_P (TREE_TYPE (dest)))
10498     return 0;
10499   arglist = TREE_CHAIN (arglist);
10500   if (! arglist)
10501     return 0;
10502   len = TREE_VALUE (arglist);
10503   if (TREE_CODE (TREE_TYPE (len)) != INTEGER_TYPE)
10504     return 0;
10505   arglist = TREE_CHAIN (arglist);
10506   if (! arglist)
10507     return 0;
10508   flag = TREE_VALUE (arglist);
10509   if (TREE_CODE (TREE_TYPE (len)) != INTEGER_TYPE)
10510     return 0;
10511   arglist = TREE_CHAIN (arglist);
10512   if (! arglist)
10513     return 0;
10514   size = TREE_VALUE (arglist);
10515   if (TREE_CODE (TREE_TYPE (size)) != INTEGER_TYPE)
10516     return 0;
10517   arglist = TREE_CHAIN (arglist);
10518   if (! arglist)
10519     return 0;
10520   fmt = TREE_VALUE (arglist);
10521   if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
10522     return 0;
10523   arglist = TREE_CHAIN (arglist);
10524
10525   if (! host_integerp (size, 1))
10526     return 0;
10527
10528   if (! integer_all_onesp (size))
10529     {
10530       if (! host_integerp (len, 1))
10531         {
10532           /* If LEN is not constant, try MAXLEN too.
10533              For MAXLEN only allow optimizing into non-_ocs function
10534              if SIZE is >= MAXLEN, never convert to __ocs_fail ().  */
10535           if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
10536             return 0;
10537         }
10538       else
10539         maxlen = len;
10540
10541       if (tree_int_cst_lt (size, maxlen))
10542         return 0;
10543     }
10544
10545   if (!init_target_chars())
10546     return 0;
10547
10548   /* Only convert __{,v}snprintf_chk to {,v}snprintf if flag is 0
10549      or if format doesn't contain % chars or is "%s".  */
10550   if (! integer_zerop (flag))
10551     {
10552       fmt_str = c_getstr (fmt);
10553       if (fmt_str == NULL)
10554         return 0;
10555       if (strchr (fmt_str, target_percent) != NULL && strcmp (fmt_str, target_percent_s))
10556         return 0;
10557     }
10558
10559   arglist = tree_cons (NULL_TREE, fmt, arglist);
10560   arglist = tree_cons (NULL_TREE, len, arglist);
10561   arglist = tree_cons (NULL_TREE, dest, arglist);
10562
10563   /* If __builtin_{,v}snprintf_chk is used, assume {,v}snprintf is
10564      available.  */
10565   fn = built_in_decls[fcode == BUILT_IN_VSNPRINTF_CHK
10566                       ? BUILT_IN_VSNPRINTF : BUILT_IN_SNPRINTF];
10567   if (!fn)
10568     return 0;
10569
10570   return build_function_call_expr (fn, arglist);
10571 }
10572
10573 /* Fold a call to the {,v}printf{,_unlocked} and __{,v}printf_chk builtins.
10574
10575    Return 0 if no simplification was possible, otherwise return the
10576    simplified form of the call as a tree.  FCODE is the BUILT_IN_*
10577    code of the function to be simplified.  */
10578
10579 static tree
10580 fold_builtin_printf (tree fndecl, tree arglist, bool ignore,
10581                      enum built_in_function fcode)
10582 {
10583   tree fmt, fn = NULL_TREE, fn_putchar, fn_puts, arg, call;
10584   const char *fmt_str = NULL;
10585
10586   /* If the return value is used, don't do the transformation.  */
10587   if (! ignore)
10588     return 0;
10589
10590   /* Verify the required arguments in the original call.  */
10591   if (fcode == BUILT_IN_PRINTF_CHK || fcode == BUILT_IN_VPRINTF_CHK)
10592     {
10593       tree flag;
10594
10595       if (! arglist)
10596         return 0;
10597       flag = TREE_VALUE (arglist);
10598       if (TREE_CODE (TREE_TYPE (flag)) != INTEGER_TYPE
10599           || TREE_SIDE_EFFECTS (flag))
10600         return 0;
10601       arglist = TREE_CHAIN (arglist);
10602     }
10603
10604   if (! arglist)
10605     return 0;
10606   fmt = TREE_VALUE (arglist);
10607   if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
10608     return 0;
10609   arglist = TREE_CHAIN (arglist);
10610
10611   /* Check whether the format is a literal string constant.  */
10612   fmt_str = c_getstr (fmt);
10613   if (fmt_str == NULL)
10614     return NULL_TREE;
10615
10616   if (fcode == BUILT_IN_PRINTF_UNLOCKED)
10617     {
10618       /* If we're using an unlocked function, assume the other
10619          unlocked functions exist explicitly.  */
10620       fn_putchar = built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED];
10621       fn_puts = built_in_decls[BUILT_IN_PUTS_UNLOCKED];
10622     }
10623   else
10624     {
10625       fn_putchar = implicit_built_in_decls[BUILT_IN_PUTCHAR];
10626       fn_puts = implicit_built_in_decls[BUILT_IN_PUTS];
10627     }
10628
10629   if (!init_target_chars())
10630     return 0;
10631   
10632   if (strcmp (fmt_str, target_percent_s) == 0 || strchr (fmt_str, target_percent) == NULL)
10633     {
10634       const char *str;
10635
10636       if (strcmp (fmt_str, target_percent_s) == 0)
10637         {
10638           if (fcode == BUILT_IN_VPRINTF || fcode == BUILT_IN_VPRINTF_CHK)
10639             return 0;
10640
10641           if (! arglist
10642               || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
10643               || TREE_CHAIN (arglist))
10644             return 0;
10645
10646           str = c_getstr (TREE_VALUE (arglist));
10647           if (str == NULL)
10648             return 0;
10649         }
10650       else
10651         {
10652           /* The format specifier doesn't contain any '%' characters.  */
10653           if (fcode != BUILT_IN_VPRINTF && fcode != BUILT_IN_VPRINTF_CHK
10654               && arglist)
10655             return 0;
10656           str = fmt_str;
10657         }
10658
10659       /* If the string was "", printf does nothing.  */
10660       if (str[0] == '\0')
10661         return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), 0);
10662
10663       /* If the string has length of 1, call putchar.  */
10664       if (str[1] == '\0')
10665         {
10666           /* Given printf("c"), (where c is any one character,)
10667              convert "c"[0] to an int and pass that to the replacement
10668              function.  */
10669           arg = build_int_cst (NULL_TREE, str[0]);
10670           arglist = build_tree_list (NULL_TREE, arg);
10671           fn = fn_putchar;
10672         }
10673       else
10674         {
10675           /* If the string was "string\n", call puts("string").  */
10676           size_t len = strlen (str);
10677           if ((unsigned char)str[len - 1] == target_newline)
10678             {
10679               /* Create a NUL-terminated string that's one char shorter
10680                  than the original, stripping off the trailing '\n'.  */
10681               char *newstr = alloca (len);
10682               memcpy (newstr, str, len - 1);
10683               newstr[len - 1] = 0;
10684
10685               arg = build_string_literal (len, newstr);
10686               arglist = build_tree_list (NULL_TREE, arg);
10687               fn = fn_puts;
10688             }
10689           else
10690             /* We'd like to arrange to call fputs(string,stdout) here,
10691                but we need stdout and don't have a way to get it yet.  */
10692             return 0;
10693         }
10694     }
10695
10696   /* The other optimizations can be done only on the non-va_list variants.  */
10697   else if (fcode == BUILT_IN_VPRINTF || fcode == BUILT_IN_VPRINTF_CHK)
10698     return 0;
10699
10700   /* If the format specifier was "%s\n", call __builtin_puts(arg).  */
10701   else if (strcmp (fmt_str, target_percent_s_newline) == 0)
10702     {
10703       if (! arglist
10704           || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
10705           || TREE_CHAIN (arglist))
10706         return 0;
10707       fn = fn_puts;
10708     }
10709
10710   /* If the format specifier was "%c", call __builtin_putchar(arg).  */
10711   else if (strcmp (fmt_str, target_percent_c) == 0)
10712     {
10713       if (! arglist
10714           || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
10715           || TREE_CHAIN (arglist))
10716         return 0;
10717       fn = fn_putchar;
10718     }
10719
10720   if (!fn)
10721     return 0;
10722
10723   call = build_function_call_expr (fn, arglist);
10724   return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), call);
10725 }
10726
10727 /* Fold a call to the {,v}fprintf{,_unlocked} and __{,v}printf_chk builtins.
10728
10729    Return 0 if no simplification was possible, otherwise return the
10730    simplified form of the call as a tree.  FCODE is the BUILT_IN_*
10731    code of the function to be simplified.  */
10732
10733 static tree
10734 fold_builtin_fprintf (tree fndecl, tree arglist, bool ignore,
10735                       enum built_in_function fcode)
10736 {
10737   tree fp, fmt, fn = NULL_TREE, fn_fputc, fn_fputs, arg, call;
10738   const char *fmt_str = NULL;
10739
10740   /* If the return value is used, don't do the transformation.  */
10741   if (! ignore)
10742     return 0;
10743
10744   /* Verify the required arguments in the original call.  */
10745   if (! arglist)
10746     return 0;
10747   fp = TREE_VALUE (arglist);
10748   if (! POINTER_TYPE_P (TREE_TYPE (fp)))
10749     return 0;
10750   arglist = TREE_CHAIN (arglist);
10751
10752   if (fcode == BUILT_IN_FPRINTF_CHK || fcode == BUILT_IN_VFPRINTF_CHK)
10753     {
10754       tree flag;
10755
10756       if (! arglist)
10757         return 0;
10758       flag = TREE_VALUE (arglist);
10759       if (TREE_CODE (TREE_TYPE (flag)) != INTEGER_TYPE
10760           || TREE_SIDE_EFFECTS (flag))
10761         return 0;
10762       arglist = TREE_CHAIN (arglist);
10763     }
10764
10765   if (! arglist)
10766     return 0;
10767   fmt = TREE_VALUE (arglist);
10768   if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
10769     return 0;
10770   arglist = TREE_CHAIN (arglist);
10771
10772   /* Check whether the format is a literal string constant.  */
10773   fmt_str = c_getstr (fmt);
10774   if (fmt_str == NULL)
10775     return NULL_TREE;
10776
10777   if (fcode == BUILT_IN_FPRINTF_UNLOCKED)
10778     {
10779       /* If we're using an unlocked function, assume the other
10780          unlocked functions exist explicitly.  */
10781       fn_fputc = built_in_decls[BUILT_IN_FPUTC_UNLOCKED];
10782       fn_fputs = built_in_decls[BUILT_IN_FPUTS_UNLOCKED];
10783     }
10784   else
10785     {
10786       fn_fputc = implicit_built_in_decls[BUILT_IN_FPUTC];
10787       fn_fputs = implicit_built_in_decls[BUILT_IN_FPUTS];
10788     }
10789
10790   if (!init_target_chars())
10791     return 0;
10792   
10793   /* If the format doesn't contain % args or %%, use strcpy.  */
10794   if (strchr (fmt_str, target_percent) == NULL)
10795     {
10796       if (fcode != BUILT_IN_VFPRINTF && fcode != BUILT_IN_VFPRINTF_CHK
10797           && arglist)
10798         return 0;
10799
10800       /* If the format specifier was "", fprintf does nothing.  */
10801       if (fmt_str[0] == '\0')
10802         {
10803           /* If FP has side-effects, just wait until gimplification is
10804              done.  */
10805           if (TREE_SIDE_EFFECTS (fp))
10806             return 0;
10807
10808           return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), 0);
10809         }
10810
10811       /* When "string" doesn't contain %, replace all cases of
10812          fprintf (fp, string) with fputs (string, fp).  The fputs
10813          builtin will take care of special cases like length == 1.  */
10814       arglist = build_tree_list (NULL_TREE, fp);
10815       arglist = tree_cons (NULL_TREE, fmt, arglist);
10816       fn = fn_fputs;
10817     }
10818
10819   /* The other optimizations can be done only on the non-va_list variants.  */
10820   else if (fcode == BUILT_IN_VFPRINTF || fcode == BUILT_IN_VFPRINTF_CHK)
10821     return 0;
10822
10823   /* If the format specifier was "%s", call __builtin_fputs (arg, fp).  */
10824   else if (strcmp (fmt_str, target_percent_s) == 0)
10825     {
10826       if (! arglist
10827           || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
10828           || TREE_CHAIN (arglist))
10829         return 0;
10830       arg = TREE_VALUE (arglist);
10831       arglist = build_tree_list (NULL_TREE, fp);
10832       arglist = tree_cons (NULL_TREE, arg, arglist);
10833       fn = fn_fputs;
10834     }
10835
10836   /* If the format specifier was "%c", call __builtin_fputc (arg, fp).  */
10837   else if (strcmp (fmt_str, target_percent_c) == 0)
10838     {
10839       if (! arglist
10840           || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
10841           || TREE_CHAIN (arglist))
10842         return 0;
10843       arg = TREE_VALUE (arglist);
10844       arglist = build_tree_list (NULL_TREE, fp);
10845       arglist = tree_cons (NULL_TREE, arg, arglist);
10846       fn = fn_fputc;
10847     }
10848
10849   if (!fn)
10850     return 0;
10851
10852   call = build_function_call_expr (fn, arglist);
10853   return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), call);
10854 }
10855
10856 /* Initialize format string characters in the target charset.  */
10857
10858 static bool
10859 init_target_chars (void)
10860 {
10861   static bool init;
10862   if (!init)
10863     {
10864       target_newline = lang_hooks.to_target_charset ('\n');
10865       target_percent = lang_hooks.to_target_charset ('%');
10866       target_c = lang_hooks.to_target_charset ('c');
10867       target_s = lang_hooks.to_target_charset ('s');
10868       if (target_newline == 0 || target_percent == 0 || target_c == 0
10869           || target_s == 0)
10870         return false;
10871
10872       target_percent_c[0] = target_percent;
10873       target_percent_c[1] = target_c;
10874       target_percent_c[2] = '\0';
10875
10876       target_percent_s[0] = target_percent;
10877       target_percent_s[1] = target_s;
10878       target_percent_s[2] = '\0';
10879
10880       target_percent_s_newline[0] = target_percent;
10881       target_percent_s_newline[1] = target_s;
10882       target_percent_s_newline[2] = target_newline;
10883       target_percent_s_newline[3] = '\0';
10884       
10885       init = true;
10886     }
10887   return true;
10888 }