OSDN Git Service

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