OSDN Git Service

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