OSDN Git Service

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