OSDN Git Service

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