OSDN Git Service

* config/cris/predicates.md: New file.
[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 ("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 ("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 ("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 ("%qT is promoted to %qT when passed through %<...%>",
4224                type, promoted_type);
4225       if (! gave_help)
4226         {
4227           gave_help = true;
4228           warning ("(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         /* Once most targets are converted this should abort.  */
4266         return GS_ALL_DONE;
4267
4268       *expr_p = targetm.gimplify_va_arg_expr (valist, type, pre_p, post_p);
4269       return GS_OK;
4270     }
4271 }
4272
4273 /* Expand ARGLIST, from a call to __builtin_va_end.  */
4274
4275 static rtx
4276 expand_builtin_va_end (tree arglist)
4277 {
4278   tree valist = TREE_VALUE (arglist);
4279
4280   /* Evaluate for side effects, if needed.  I hate macros that don't
4281      do that.  */
4282   if (TREE_SIDE_EFFECTS (valist))
4283     expand_expr (valist, const0_rtx, VOIDmode, EXPAND_NORMAL);
4284
4285   return const0_rtx;
4286 }
4287
4288 /* Expand ARGLIST, from a call to __builtin_va_copy.  We do this as a
4289    builtin rather than just as an assignment in stdarg.h because of the
4290    nastiness of array-type va_list types.  */
4291
4292 static rtx
4293 expand_builtin_va_copy (tree arglist)
4294 {
4295   tree dst, src, t;
4296
4297   dst = TREE_VALUE (arglist);
4298   src = TREE_VALUE (TREE_CHAIN (arglist));
4299
4300   dst = stabilize_va_list (dst, 1);
4301   src = stabilize_va_list (src, 0);
4302
4303   if (TREE_CODE (va_list_type_node) != ARRAY_TYPE)
4304     {
4305       t = build2 (MODIFY_EXPR, va_list_type_node, dst, src);
4306       TREE_SIDE_EFFECTS (t) = 1;
4307       expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4308     }
4309   else
4310     {
4311       rtx dstb, srcb, size;
4312
4313       /* Evaluate to pointers.  */
4314       dstb = expand_expr (dst, NULL_RTX, Pmode, EXPAND_NORMAL);
4315       srcb = expand_expr (src, NULL_RTX, Pmode, EXPAND_NORMAL);
4316       size = expand_expr (TYPE_SIZE_UNIT (va_list_type_node), NULL_RTX,
4317                           VOIDmode, EXPAND_NORMAL);
4318
4319       dstb = convert_memory_address (Pmode, dstb);
4320       srcb = convert_memory_address (Pmode, srcb);
4321
4322       /* "Dereference" to BLKmode memories.  */
4323       dstb = gen_rtx_MEM (BLKmode, dstb);
4324       set_mem_alias_set (dstb, get_alias_set (TREE_TYPE (TREE_TYPE (dst))));
4325       set_mem_align (dstb, TYPE_ALIGN (va_list_type_node));
4326       srcb = gen_rtx_MEM (BLKmode, srcb);
4327       set_mem_alias_set (srcb, get_alias_set (TREE_TYPE (TREE_TYPE (src))));
4328       set_mem_align (srcb, TYPE_ALIGN (va_list_type_node));
4329
4330       /* Copy.  */
4331       emit_block_move (dstb, srcb, size, BLOCK_OP_NORMAL);
4332     }
4333
4334   return const0_rtx;
4335 }
4336
4337 /* Expand a call to one of the builtin functions __builtin_frame_address or
4338    __builtin_return_address.  */
4339
4340 static rtx
4341 expand_builtin_frame_address (tree fndecl, tree arglist)
4342 {
4343   /* The argument must be a nonnegative integer constant.
4344      It counts the number of frames to scan up the stack.
4345      The value is the return address saved in that frame.  */
4346   if (arglist == 0)
4347     /* Warning about missing arg was already issued.  */
4348     return const0_rtx;
4349   else if (! host_integerp (TREE_VALUE (arglist), 1))
4350     {
4351       if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4352         error ("invalid argument to %<__builtin_frame_address%>");
4353       else
4354         error ("invalid argument to %<__builtin_return_address%>");
4355       return const0_rtx;
4356     }
4357   else
4358     {
4359       rtx tem
4360         = expand_builtin_return_addr (DECL_FUNCTION_CODE (fndecl),
4361                                       tree_low_cst (TREE_VALUE (arglist), 1));
4362
4363       /* Some ports cannot access arbitrary stack frames.  */
4364       if (tem == NULL)
4365         {
4366           if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4367             warning ("unsupported argument to %<__builtin_frame_address%>");
4368           else
4369             warning ("unsupported argument to %<__builtin_return_address%>");
4370           return const0_rtx;
4371         }
4372
4373       /* For __builtin_frame_address, return what we've got.  */
4374       if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4375         return tem;
4376
4377       if (!REG_P (tem)
4378           && ! CONSTANT_P (tem))
4379         tem = copy_to_mode_reg (Pmode, tem);
4380       return tem;
4381     }
4382 }
4383
4384 /* Expand a call to the alloca builtin, with arguments ARGLIST.  Return 0 if
4385    we failed and the caller should emit a normal call, otherwise try to get
4386    the result in TARGET, if convenient.  */
4387
4388 static rtx
4389 expand_builtin_alloca (tree arglist, rtx target)
4390 {
4391   rtx op0;
4392   rtx result;
4393
4394   /* In -fmudflap-instrumented code, alloca() and __builtin_alloca()
4395      should always expand to function calls.  These can be intercepted
4396      in libmudflap.  */
4397   if (flag_mudflap)
4398     return 0;
4399
4400   if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
4401     return 0;
4402
4403   /* Compute the argument.  */
4404   op0 = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
4405
4406   /* Allocate the desired space.  */
4407   result = allocate_dynamic_stack_space (op0, target, BITS_PER_UNIT);
4408   result = convert_memory_address (ptr_mode, result);
4409
4410   return result;
4411 }
4412
4413 /* Expand a call to a unary builtin.  The arguments are in ARGLIST.
4414    Return 0 if a normal call should be emitted rather than expanding the
4415    function in-line.  If convenient, the result should be placed in TARGET.
4416    SUBTARGET may be used as the target for computing one of EXP's operands.  */
4417
4418 static rtx
4419 expand_builtin_unop (enum machine_mode target_mode, tree arglist, rtx target,
4420                      rtx subtarget, optab op_optab)
4421 {
4422   rtx op0;
4423   if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
4424     return 0;
4425
4426   /* Compute the argument.  */
4427   op0 = expand_expr (TREE_VALUE (arglist), subtarget, VOIDmode, 0);
4428   /* Compute op, into TARGET if possible.
4429      Set TARGET to wherever the result comes back.  */
4430   target = expand_unop (TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist))),
4431                         op_optab, op0, target, 1);
4432   gcc_assert (target);
4433
4434   return convert_to_mode (target_mode, target, 0);
4435 }
4436
4437 /* If the string passed to fputs is a constant and is one character
4438    long, we attempt to transform this call into __builtin_fputc().  */
4439
4440 static rtx
4441 expand_builtin_fputs (tree arglist, rtx target, bool unlocked)
4442 {
4443   /* Verify the arguments in the original call.  */
4444   if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4445     {
4446       tree result = fold_builtin_fputs (arglist, (target == const0_rtx),
4447                                         unlocked, NULL_TREE);
4448       if (result)
4449         return expand_expr (result, target, VOIDmode, EXPAND_NORMAL);
4450     }
4451   return 0;
4452 }
4453
4454 /* Expand a call to __builtin_expect.  We return our argument and emit a
4455    NOTE_INSN_EXPECTED_VALUE note.  This is the expansion of __builtin_expect in
4456    a non-jump context.  */
4457
4458 static rtx
4459 expand_builtin_expect (tree arglist, rtx target)
4460 {
4461   tree exp, c;
4462   rtx note, rtx_c;
4463
4464   if (arglist == NULL_TREE
4465       || TREE_CHAIN (arglist) == NULL_TREE)
4466     return const0_rtx;
4467   exp = TREE_VALUE (arglist);
4468   c = TREE_VALUE (TREE_CHAIN (arglist));
4469
4470   if (TREE_CODE (c) != INTEGER_CST)
4471     {
4472       error ("second argument to %<__builtin_expect%> must be a constant");
4473       c = integer_zero_node;
4474     }
4475
4476   target = expand_expr (exp, target, VOIDmode, EXPAND_NORMAL);
4477
4478   /* Don't bother with expected value notes for integral constants.  */
4479   if (flag_guess_branch_prob && GET_CODE (target) != CONST_INT)
4480     {
4481       /* We do need to force this into a register so that we can be
4482          moderately sure to be able to correctly interpret the branch
4483          condition later.  */
4484       target = force_reg (GET_MODE (target), target);
4485
4486       rtx_c = expand_expr (c, NULL_RTX, GET_MODE (target), EXPAND_NORMAL);
4487
4488       note = emit_note (NOTE_INSN_EXPECTED_VALUE);
4489       NOTE_EXPECTED_VALUE (note) = gen_rtx_EQ (VOIDmode, target, rtx_c);
4490     }
4491
4492   return target;
4493 }
4494
4495 /* Like expand_builtin_expect, except do this in a jump context.  This is
4496    called from do_jump if the conditional is a __builtin_expect.  Return either
4497    a list of insns to emit the jump or NULL if we cannot optimize
4498    __builtin_expect.  We need to optimize this at jump time so that machines
4499    like the PowerPC don't turn the test into a SCC operation, and then jump
4500    based on the test being 0/1.  */
4501
4502 rtx
4503 expand_builtin_expect_jump (tree exp, rtx if_false_label, rtx if_true_label)
4504 {
4505   tree arglist = TREE_OPERAND (exp, 1);
4506   tree arg0 = TREE_VALUE (arglist);
4507   tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
4508   rtx ret = NULL_RTX;
4509
4510   /* Only handle __builtin_expect (test, 0) and
4511      __builtin_expect (test, 1).  */
4512   if (TREE_CODE (TREE_TYPE (arg1)) == INTEGER_TYPE
4513       && (integer_zerop (arg1) || integer_onep (arg1)))
4514     {
4515       rtx insn, drop_through_label, temp;
4516
4517       /* Expand the jump insns.  */
4518       start_sequence ();
4519       do_jump (arg0, if_false_label, if_true_label);
4520       ret = get_insns ();
4521
4522       drop_through_label = get_last_insn ();
4523       if (drop_through_label && NOTE_P (drop_through_label))
4524         drop_through_label = prev_nonnote_insn (drop_through_label);
4525       if (drop_through_label && !LABEL_P (drop_through_label))
4526         drop_through_label = NULL_RTX;
4527       end_sequence ();
4528
4529       if (! if_true_label)
4530         if_true_label = drop_through_label;
4531       if (! if_false_label)
4532         if_false_label = drop_through_label;
4533
4534       /* Go through and add the expect's to each of the conditional jumps.  */
4535       insn = ret;
4536       while (insn != NULL_RTX)
4537         {
4538           rtx next = NEXT_INSN (insn);
4539
4540           if (JUMP_P (insn) && any_condjump_p (insn))
4541             {
4542               rtx ifelse = SET_SRC (pc_set (insn));
4543               rtx then_dest = XEXP (ifelse, 1);
4544               rtx else_dest = XEXP (ifelse, 2);
4545               int taken = -1;
4546
4547               /* First check if we recognize any of the labels.  */
4548               if (GET_CODE (then_dest) == LABEL_REF
4549                   && XEXP (then_dest, 0) == if_true_label)
4550                 taken = 1;
4551               else if (GET_CODE (then_dest) == LABEL_REF
4552                        && XEXP (then_dest, 0) == if_false_label)
4553                 taken = 0;
4554               else if (GET_CODE (else_dest) == LABEL_REF
4555                        && XEXP (else_dest, 0) == if_false_label)
4556                 taken = 1;
4557               else if (GET_CODE (else_dest) == LABEL_REF
4558                        && XEXP (else_dest, 0) == if_true_label)
4559                 taken = 0;
4560               /* Otherwise check where we drop through.  */
4561               else if (else_dest == pc_rtx)
4562                 {
4563                   if (next && NOTE_P (next))
4564                     next = next_nonnote_insn (next);
4565
4566                   if (next && JUMP_P (next)
4567                       && any_uncondjump_p (next))
4568                     temp = XEXP (SET_SRC (pc_set (next)), 0);
4569                   else
4570                     temp = next;
4571
4572                   /* TEMP is either a CODE_LABEL, NULL_RTX or something
4573                      else that can't possibly match either target label.  */
4574                   if (temp == if_false_label)
4575                     taken = 1;
4576                   else if (temp == if_true_label)
4577                     taken = 0;
4578                 }
4579               else if (then_dest == pc_rtx)
4580                 {
4581                   if (next && NOTE_P (next))
4582                     next = next_nonnote_insn (next);
4583
4584                   if (next && JUMP_P (next)
4585                       && any_uncondjump_p (next))
4586                     temp = XEXP (SET_SRC (pc_set (next)), 0);
4587                   else
4588                     temp = next;
4589
4590                   if (temp == if_false_label)
4591                     taken = 0;
4592                   else if (temp == if_true_label)
4593                     taken = 1;
4594                 }
4595
4596               if (taken != -1)
4597                 {
4598                   /* If the test is expected to fail, reverse the
4599                      probabilities.  */
4600                   if (integer_zerop (arg1))
4601                     taken = 1 - taken;
4602                   predict_insn_def (insn, PRED_BUILTIN_EXPECT, taken);
4603                 }
4604             }
4605
4606           insn = next;
4607         }
4608     }
4609
4610   return ret;
4611 }
4612
4613 static void
4614 expand_builtin_trap (void)
4615 {
4616 #ifdef HAVE_trap
4617   if (HAVE_trap)
4618     emit_insn (gen_trap ());
4619   else
4620 #endif
4621     emit_library_call (abort_libfunc, LCT_NORETURN, VOIDmode, 0);
4622   emit_barrier ();
4623 }
4624
4625 /* Expand a call to fabs, fabsf or fabsl with arguments ARGLIST.
4626    Return 0 if a normal call should be emitted rather than expanding
4627    the function inline.  If convenient, the result should be placed
4628    in TARGET.  SUBTARGET may be used as the target for computing
4629    the operand.  */
4630
4631 static rtx
4632 expand_builtin_fabs (tree arglist, rtx target, rtx subtarget)
4633 {
4634   enum machine_mode mode;
4635   tree arg;
4636   rtx op0;
4637
4638   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
4639     return 0;
4640
4641   arg = TREE_VALUE (arglist);
4642   mode = TYPE_MODE (TREE_TYPE (arg));
4643   op0 = expand_expr (arg, subtarget, VOIDmode, 0);
4644   return expand_abs (mode, op0, target, 0, safe_from_p (target, arg, 1));
4645 }
4646
4647 /* Expand a call to copysign, copysignf, or copysignl with arguments ARGLIST.
4648    Return NULL is a normal call should be emitted rather than expanding the
4649    function inline.  If convenient, the result should be placed in TARGET.
4650    SUBTARGET may be used as the target for computing the operand.  */
4651
4652 static rtx
4653 expand_builtin_copysign (tree arglist, rtx target, rtx subtarget)
4654 {
4655   rtx op0, op1;
4656   tree arg;
4657
4658   if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
4659     return 0;
4660
4661   arg = TREE_VALUE (arglist);
4662   op0 = expand_expr (arg, subtarget, VOIDmode, 0);
4663
4664   arg = TREE_VALUE (TREE_CHAIN (arglist));
4665   op1 = expand_expr (arg, NULL, VOIDmode, 0);
4666
4667   return expand_copysign (op0, op1, target);
4668 }
4669
4670 /* Create a new constant string literal and return a char* pointer to it.
4671    The STRING_CST value is the LEN characters at STR.  */
4672 static tree
4673 build_string_literal (int len, const char *str)
4674 {
4675   tree t, elem, index, type;
4676
4677   t = build_string (len, str);
4678   elem = build_type_variant (char_type_node, 1, 0);
4679   index = build_index_type (build_int_cst (NULL_TREE, len - 1));
4680   type = build_array_type (elem, index);
4681   TREE_TYPE (t) = type;
4682   TREE_CONSTANT (t) = 1;
4683   TREE_INVARIANT (t) = 1;
4684   TREE_READONLY (t) = 1;
4685   TREE_STATIC (t) = 1;
4686
4687   type = build_pointer_type (type);
4688   t = build1 (ADDR_EXPR, type, t);
4689
4690   type = build_pointer_type (elem);
4691   t = build1 (NOP_EXPR, type, t);
4692   return t;
4693 }
4694
4695 /* Expand a call to printf or printf_unlocked with argument list ARGLIST.
4696    Return 0 if a normal call should be emitted rather than transforming
4697    the function inline.  If convenient, the result should be placed in
4698    TARGET with mode MODE.  UNLOCKED indicates this is a printf_unlocked
4699    call.  */
4700 static rtx
4701 expand_builtin_printf (tree arglist, rtx target, enum machine_mode mode,
4702                        bool unlocked)
4703 {
4704   tree fn_putchar = unlocked
4705                     ? implicit_built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED]
4706                     : implicit_built_in_decls[BUILT_IN_PUTCHAR];
4707   tree fn_puts = unlocked ? implicit_built_in_decls[BUILT_IN_PUTS_UNLOCKED]
4708                           : implicit_built_in_decls[BUILT_IN_PUTS];
4709   const char *fmt_str;
4710   tree fn, fmt, arg;
4711
4712   /* If the return value is used, don't do the transformation.  */
4713   if (target != const0_rtx)
4714     return 0;
4715
4716   /* Verify the required arguments in the original call.  */
4717   if (! arglist)
4718     return 0;
4719   fmt = TREE_VALUE (arglist);
4720   if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
4721     return 0;
4722   arglist = TREE_CHAIN (arglist);
4723
4724   /* Check whether the format is a literal string constant.  */
4725   fmt_str = c_getstr (fmt);
4726   if (fmt_str == NULL)
4727     return 0;
4728
4729   /* If the format specifier was "%s\n", call __builtin_puts(arg).  */
4730   if (strcmp (fmt_str, "%s\n") == 0)
4731     {
4732       if (! arglist
4733           || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
4734           || TREE_CHAIN (arglist))
4735         return 0;
4736       fn = fn_puts;
4737     }
4738   /* If the format specifier was "%c", call __builtin_putchar(arg).  */
4739   else if (strcmp (fmt_str, "%c") == 0)
4740     {
4741       if (! arglist
4742           || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
4743           || TREE_CHAIN (arglist))
4744         return 0;
4745       fn = fn_putchar;
4746     }
4747   else
4748     {
4749       /* We can't handle anything else with % args or %% ... yet.  */
4750       if (strchr (fmt_str, '%'))
4751         return 0;
4752
4753       if (arglist)
4754         return 0;
4755
4756       /* If the format specifier was "", printf does nothing.  */
4757       if (fmt_str[0] == '\0')
4758         return const0_rtx;
4759       /* If the format specifier has length of 1, call putchar.  */
4760       if (fmt_str[1] == '\0')
4761         {
4762           /* Given printf("c"), (where c is any one character,)
4763              convert "c"[0] to an int and pass that to the replacement
4764              function.  */
4765           arg = build_int_cst (NULL_TREE, fmt_str[0]);
4766           arglist = build_tree_list (NULL_TREE, arg);
4767           fn = fn_putchar;
4768         }
4769       else
4770         {
4771           /* If the format specifier was "string\n", call puts("string").  */
4772           size_t len = strlen (fmt_str);
4773           if (fmt_str[len - 1] == '\n')
4774             {
4775               /* Create a NUL-terminated string that's one char shorter
4776                  than the original, stripping off the trailing '\n'.  */
4777               char *newstr = alloca (len);
4778               memcpy (newstr, fmt_str, len - 1);
4779               newstr[len - 1] = 0;
4780
4781               arg = build_string_literal (len, newstr);
4782               arglist = build_tree_list (NULL_TREE, arg);
4783               fn = fn_puts;
4784             }
4785           else
4786             /* We'd like to arrange to call fputs(string,stdout) here,
4787                but we need stdout and don't have a way to get it yet.  */
4788             return 0;
4789         }
4790     }
4791
4792   if (!fn)
4793     return 0;
4794   return expand_expr (build_function_call_expr (fn, arglist),
4795                       target, mode, EXPAND_NORMAL);
4796 }
4797
4798 /* Expand a call to fprintf or fprintf_unlocked with argument list ARGLIST.
4799    Return 0 if a normal call should be emitted rather than transforming
4800    the function inline.  If convenient, the result should be placed in
4801    TARGET with mode MODE.  UNLOCKED indicates this is a fprintf_unlocked
4802    call.  */
4803 static rtx
4804 expand_builtin_fprintf (tree arglist, rtx target, enum machine_mode mode,
4805                         bool unlocked)
4806 {
4807   tree fn_fputc = unlocked ? implicit_built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
4808                            : implicit_built_in_decls[BUILT_IN_FPUTC];
4809   tree fn_fputs = unlocked ? implicit_built_in_decls[BUILT_IN_FPUTS_UNLOCKED]
4810                            : implicit_built_in_decls[BUILT_IN_FPUTS];
4811   const char *fmt_str;
4812   tree fn, fmt, fp, arg;
4813
4814   /* If the return value is used, don't do the transformation.  */
4815   if (target != const0_rtx)
4816     return 0;
4817
4818   /* Verify the required arguments in the original call.  */
4819   if (! arglist)
4820     return 0;
4821   fp = TREE_VALUE (arglist);
4822   if (! POINTER_TYPE_P (TREE_TYPE (fp)))
4823     return 0;
4824   arglist = TREE_CHAIN (arglist);
4825   if (! arglist)
4826     return 0;
4827   fmt = TREE_VALUE (arglist);
4828   if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
4829     return 0;
4830   arglist = TREE_CHAIN (arglist);
4831
4832   /* Check whether the format is a literal string constant.  */
4833   fmt_str = c_getstr (fmt);
4834   if (fmt_str == NULL)
4835     return 0;
4836
4837   /* If the format specifier was "%s", call __builtin_fputs(arg,fp).  */
4838   if (strcmp (fmt_str, "%s") == 0)
4839     {
4840       if (! arglist
4841           || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
4842           || TREE_CHAIN (arglist))
4843         return 0;
4844       arg = TREE_VALUE (arglist);
4845       arglist = build_tree_list (NULL_TREE, fp);
4846       arglist = tree_cons (NULL_TREE, arg, arglist);
4847       fn = fn_fputs;
4848     }
4849   /* If the format specifier was "%c", call __builtin_fputc(arg,fp).  */
4850   else if (strcmp (fmt_str, "%c") == 0)
4851     {
4852       if (! arglist
4853           || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
4854           || TREE_CHAIN (arglist))
4855         return 0;
4856       arg = TREE_VALUE (arglist);
4857       arglist = build_tree_list (NULL_TREE, fp);
4858       arglist = tree_cons (NULL_TREE, arg, arglist);
4859       fn = fn_fputc;
4860     }
4861   else
4862     {
4863       /* We can't handle anything else with % args or %% ... yet.  */
4864       if (strchr (fmt_str, '%'))
4865         return 0;
4866
4867       if (arglist)
4868         return 0;
4869
4870       /* If the format specifier was "", fprintf does nothing.  */
4871       if (fmt_str[0] == '\0')
4872         {
4873           /* Evaluate and ignore FILE* argument for side-effects.  */
4874           expand_expr (fp, const0_rtx, VOIDmode, EXPAND_NORMAL);
4875           return const0_rtx;
4876         }
4877
4878       /* When "string" doesn't contain %, replace all cases of
4879          fprintf(stream,string) with fputs(string,stream).  The fputs
4880          builtin will take care of special cases like length == 1.  */
4881       arglist = build_tree_list (NULL_TREE, fp);
4882       arglist = tree_cons (NULL_TREE, fmt, arglist);
4883       fn = fn_fputs;
4884     }
4885
4886   if (!fn)
4887     return 0;
4888   return expand_expr (build_function_call_expr (fn, arglist),
4889                       target, mode, EXPAND_NORMAL);
4890 }
4891
4892 /* Expand a call to sprintf with argument list ARGLIST.  Return 0 if
4893    a normal call should be emitted rather than expanding the function
4894    inline.  If convenient, the result should be placed in TARGET with
4895    mode MODE.  */
4896
4897 static rtx
4898 expand_builtin_sprintf (tree arglist, rtx target, enum machine_mode mode)
4899 {
4900   tree orig_arglist, dest, fmt;
4901   const char *fmt_str;
4902
4903   orig_arglist = arglist;
4904
4905   /* Verify the required arguments in the original call.  */
4906   if (! arglist)
4907     return 0;
4908   dest = TREE_VALUE (arglist);
4909   if (! POINTER_TYPE_P (TREE_TYPE (dest)))
4910     return 0;
4911   arglist = TREE_CHAIN (arglist);
4912   if (! arglist)
4913     return 0;
4914   fmt = TREE_VALUE (arglist);
4915   if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
4916     return 0;
4917   arglist = TREE_CHAIN (arglist);
4918
4919   /* Check whether the format is a literal string constant.  */
4920   fmt_str = c_getstr (fmt);
4921   if (fmt_str == NULL)
4922     return 0;
4923
4924   /* If the format doesn't contain % args or %%, use strcpy.  */
4925   if (strchr (fmt_str, '%') == 0)
4926     {
4927       tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
4928       tree exp;
4929
4930       if (arglist || ! fn)
4931         return 0;
4932       expand_expr (build_function_call_expr (fn, orig_arglist),
4933                    const0_rtx, VOIDmode, EXPAND_NORMAL);
4934       if (target == const0_rtx)
4935         return const0_rtx;
4936       exp = build_int_cst (NULL_TREE, strlen (fmt_str));
4937       return expand_expr (exp, target, mode, EXPAND_NORMAL);
4938     }
4939   /* If the format is "%s", use strcpy if the result isn't used.  */
4940   else if (strcmp (fmt_str, "%s") == 0)
4941     {
4942       tree fn, arg, len;
4943       fn = implicit_built_in_decls[BUILT_IN_STRCPY];
4944
4945       if (! fn)
4946         return 0;
4947
4948       if (! arglist || TREE_CHAIN (arglist))
4949         return 0;
4950       arg = TREE_VALUE (arglist);
4951       if (! POINTER_TYPE_P (TREE_TYPE (arg)))
4952         return 0;
4953
4954       if (target != const0_rtx)
4955         {
4956           len = c_strlen (arg, 1);
4957           if (! len || TREE_CODE (len) != INTEGER_CST)
4958             return 0;
4959         }
4960       else
4961         len = NULL_TREE;
4962
4963       arglist = build_tree_list (NULL_TREE, arg);
4964       arglist = tree_cons (NULL_TREE, dest, arglist);
4965       expand_expr (build_function_call_expr (fn, arglist),
4966                    const0_rtx, VOIDmode, EXPAND_NORMAL);
4967
4968       if (target == const0_rtx)
4969         return const0_rtx;
4970       return expand_expr (len, target, mode, EXPAND_NORMAL);
4971     }
4972
4973   return 0;
4974 }
4975
4976 /* Expand a call to either the entry or exit function profiler.  */
4977
4978 static rtx
4979 expand_builtin_profile_func (bool exitp)
4980 {
4981   rtx this, which;
4982
4983   this = DECL_RTL (current_function_decl);
4984   gcc_assert (MEM_P (this));
4985   this = XEXP (this, 0);
4986
4987   if (exitp)
4988     which = profile_function_exit_libfunc;
4989   else
4990     which = profile_function_entry_libfunc;
4991
4992   emit_library_call (which, LCT_NORMAL, VOIDmode, 2, this, Pmode,
4993                      expand_builtin_return_addr (BUILT_IN_RETURN_ADDRESS,
4994                                                  0),
4995                      Pmode);
4996
4997   return const0_rtx;
4998 }
4999
5000 /* Given a trampoline address, make sure it satisfies TRAMPOLINE_ALIGNMENT.  */
5001
5002 static rtx
5003 round_trampoline_addr (rtx tramp)
5004 {
5005   rtx temp, addend, mask;
5006
5007   /* If we don't need too much alignment, we'll have been guaranteed
5008      proper alignment by get_trampoline_type.  */
5009   if (TRAMPOLINE_ALIGNMENT <= STACK_BOUNDARY)
5010     return tramp;
5011
5012   /* Round address up to desired boundary.  */
5013   temp = gen_reg_rtx (Pmode);
5014   addend = GEN_INT (TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT - 1);
5015   mask = GEN_INT (-TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT);
5016
5017   temp  = expand_simple_binop (Pmode, PLUS, tramp, addend,
5018                                temp, 0, OPTAB_LIB_WIDEN);
5019   tramp = expand_simple_binop (Pmode, AND, temp, mask,
5020                                temp, 0, OPTAB_LIB_WIDEN);
5021
5022   return tramp;
5023 }
5024
5025 static rtx
5026 expand_builtin_init_trampoline (tree arglist)
5027 {
5028   tree t_tramp, t_func, t_chain;
5029   rtx r_tramp, r_func, r_chain;
5030 #ifdef TRAMPOLINE_TEMPLATE
5031   rtx blktramp;
5032 #endif
5033
5034   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE,
5035                          POINTER_TYPE, VOID_TYPE))
5036     return NULL_RTX;
5037
5038   t_tramp = TREE_VALUE (arglist);
5039   arglist = TREE_CHAIN (arglist);
5040   t_func = TREE_VALUE (arglist);
5041   arglist = TREE_CHAIN (arglist);
5042   t_chain = TREE_VALUE (arglist);
5043
5044   r_tramp = expand_expr (t_tramp, NULL_RTX, VOIDmode, 0);
5045   r_func = expand_expr (t_func, NULL_RTX, VOIDmode, 0);
5046   r_chain = expand_expr (t_chain, NULL_RTX, VOIDmode, 0);
5047
5048   /* Generate insns to initialize the trampoline.  */
5049   r_tramp = round_trampoline_addr (r_tramp);
5050 #ifdef TRAMPOLINE_TEMPLATE
5051   blktramp = gen_rtx_MEM (BLKmode, r_tramp);
5052   set_mem_align (blktramp, TRAMPOLINE_ALIGNMENT);
5053   emit_block_move (blktramp, assemble_trampoline_template (),
5054                    GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL);
5055 #endif
5056   trampolines_created = 1;
5057   INITIALIZE_TRAMPOLINE (r_tramp, r_func, r_chain);
5058
5059   return const0_rtx;
5060 }
5061
5062 static rtx
5063 expand_builtin_adjust_trampoline (tree arglist)
5064 {
5065   rtx tramp;
5066
5067   if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5068     return NULL_RTX;
5069
5070   tramp = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
5071   tramp = round_trampoline_addr (tramp);
5072 #ifdef TRAMPOLINE_ADJUST_ADDRESS
5073   TRAMPOLINE_ADJUST_ADDRESS (tramp);
5074 #endif
5075
5076   return tramp;
5077 }
5078
5079 /* Expand a call to the built-in signbit, signbitf or signbitl function.
5080    Return NULL_RTX if a normal call should be emitted rather than expanding
5081    the function in-line.  EXP is the expression that is a call to the builtin
5082    function; if convenient, the result should be placed in TARGET.  */
5083
5084 static rtx
5085 expand_builtin_signbit (tree exp, rtx target)
5086 {
5087   const struct real_format *fmt;
5088   enum machine_mode fmode, imode, rmode;
5089   HOST_WIDE_INT hi, lo;
5090   tree arg, arglist;
5091   int word, bitpos;
5092   rtx temp;
5093
5094   arglist = TREE_OPERAND (exp, 1);
5095   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
5096     return 0;
5097
5098   arg = TREE_VALUE (arglist);
5099   fmode = TYPE_MODE (TREE_TYPE (arg));
5100   rmode = TYPE_MODE (TREE_TYPE (exp));
5101   fmt = REAL_MODE_FORMAT (fmode);
5102
5103   /* For floating point formats without a sign bit, implement signbit
5104      as "ARG < 0.0".  */
5105   bitpos = fmt->signbit_ro;
5106   if (bitpos < 0)
5107   {
5108     /* But we can't do this if the format supports signed zero.  */
5109     if (fmt->has_signed_zero && HONOR_SIGNED_ZEROS (fmode))
5110       return 0;
5111
5112     arg = fold (build2 (LT_EXPR, TREE_TYPE (exp), arg,
5113                         build_real (TREE_TYPE (arg), dconst0)));
5114     return expand_expr (arg, target, VOIDmode, EXPAND_NORMAL);
5115   }
5116
5117   temp = expand_expr (arg, NULL_RTX, VOIDmode, 0);
5118   if (GET_MODE_SIZE (fmode) <= UNITS_PER_WORD)
5119     {
5120       imode = int_mode_for_mode (fmode);
5121       if (imode == BLKmode)
5122         return 0;
5123       temp = gen_lowpart (imode, temp);
5124     }
5125   else
5126     {
5127       imode = word_mode;
5128       /* Handle targets with different FP word orders.  */
5129       if (FLOAT_WORDS_BIG_ENDIAN)
5130         word = (GET_MODE_BITSIZE (fmode) - bitpos) / BITS_PER_WORD;
5131       else
5132         word = bitpos / BITS_PER_WORD;
5133       temp = operand_subword_force (temp, word, fmode);
5134       bitpos = bitpos % BITS_PER_WORD;
5135     }
5136
5137   /* Force the intermediate word_mode (or narrower) result into a
5138      register.  This avoids attempting to create paradoxical SUBREGs
5139      of floating point modes below.  */
5140   temp = force_reg (imode, temp);
5141
5142   /* If the bitpos is within the "result mode" lowpart, the operation
5143      can be implement with a single bitwise AND.  Otherwise, we need
5144      a right shift and an AND.  */
5145
5146   if (bitpos < GET_MODE_BITSIZE (rmode))
5147     {
5148       if (bitpos < HOST_BITS_PER_WIDE_INT)
5149         {
5150           hi = 0;
5151           lo = (HOST_WIDE_INT) 1 << bitpos;
5152         }
5153       else
5154         {
5155           hi = (HOST_WIDE_INT) 1 << (bitpos - HOST_BITS_PER_WIDE_INT);
5156           lo = 0;
5157         }
5158
5159       if (imode != rmode)
5160         temp = gen_lowpart (rmode, temp);
5161       temp = expand_binop (rmode, and_optab, temp,
5162                            immed_double_const (lo, hi, rmode),
5163                            NULL_RTX, 1, OPTAB_LIB_WIDEN);
5164     }
5165   else
5166     {
5167       /* Perform a logical right shift to place the signbit in the least
5168          significant bit, then truncate the result to the desired mode
5169          and mask just this bit.  */
5170       temp = expand_shift (RSHIFT_EXPR, imode, temp,
5171                            build_int_cst (NULL_TREE, bitpos), NULL_RTX, 1);
5172       temp = gen_lowpart (rmode, temp);
5173       temp = expand_binop (rmode, and_optab, temp, const1_rtx,
5174                            NULL_RTX, 1, OPTAB_LIB_WIDEN);
5175     }
5176
5177   return temp;
5178 }
5179
5180 /* Expand fork or exec calls.  TARGET is the desired target of the
5181    call.  ARGLIST is the list of arguments of the call.  FN is the
5182    identificator of the actual function.  IGNORE is nonzero if the
5183    value is to be ignored.  */
5184
5185 static rtx
5186 expand_builtin_fork_or_exec (tree fn, tree arglist, rtx target, int ignore)
5187 {
5188   tree id, decl;
5189   tree call;
5190
5191   /* If we are not profiling, just call the function.  */
5192   if (!profile_arc_flag)
5193     return NULL_RTX;
5194
5195   /* Otherwise call the wrapper.  This should be equivalent for the rest of
5196      compiler, so the code does not diverge, and the wrapper may run the
5197      code necessary for keeping the profiling sane.  */
5198
5199   switch (DECL_FUNCTION_CODE (fn))
5200     {
5201     case BUILT_IN_FORK:
5202       id = get_identifier ("__gcov_fork");
5203       break;
5204
5205     case BUILT_IN_EXECL:
5206       id = get_identifier ("__gcov_execl");
5207       break;
5208
5209     case BUILT_IN_EXECV:
5210       id = get_identifier ("__gcov_execv");
5211       break;
5212
5213     case BUILT_IN_EXECLP:
5214       id = get_identifier ("__gcov_execlp");
5215       break;
5216
5217     case BUILT_IN_EXECLE:
5218       id = get_identifier ("__gcov_execle");
5219       break;
5220
5221     case BUILT_IN_EXECVP:
5222       id = get_identifier ("__gcov_execvp");
5223       break;
5224
5225     case BUILT_IN_EXECVE:
5226       id = get_identifier ("__gcov_execve");
5227       break;
5228
5229     default:
5230       gcc_unreachable ();
5231     }
5232
5233   decl = build_decl (FUNCTION_DECL, id, TREE_TYPE (fn));
5234   DECL_EXTERNAL (decl) = 1;
5235   TREE_PUBLIC (decl) = 1;
5236   DECL_ARTIFICIAL (decl) = 1;
5237   TREE_NOTHROW (decl) = 1;
5238   call = build_function_call_expr (decl, arglist);
5239
5240   return expand_call (call, target, ignore);
5241 }
5242
5243 \f
5244 /* Expand the __sync_xxx_and_fetch and __sync_fetch_and_xxx intrinsics.
5245    ARGLIST is the operands list to the function.  CODE is the rtx code 
5246    that corresponds to the arithmetic or logical operation from the name;
5247    an exception here is that NOT actually means NAND.  TARGET is an optional
5248    place for us to store the results; AFTER is true if this is the
5249    fetch_and_xxx form.  IGNORE is true if we don't actually care about
5250    the result of the operation at all.  */
5251
5252 static rtx
5253 expand_builtin_sync_operation (tree arglist, enum rtx_code code, bool after,
5254                                rtx target, bool ignore)
5255 {
5256   enum machine_mode mode;
5257   rtx addr, val, mem;
5258
5259   /* Expand the operands.  */
5260   addr = expand_expr (TREE_VALUE (arglist), NULL, Pmode, EXPAND_SUM);
5261   mode = TYPE_MODE (TREE_TYPE (TREE_TYPE (TREE_VALUE (arglist))));
5262
5263   arglist = TREE_CHAIN (arglist);
5264   val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
5265
5266   /* Note that we explicitly do not want any alias information for this
5267      memory, so that we kill all other live memories.  Otherwise we don't
5268      satisfy the full barrier semantics of the intrinsic.  */
5269   mem = validize_mem (gen_rtx_MEM (mode, addr));
5270   MEM_VOLATILE_P (mem) = 1;
5271
5272   if (ignore)
5273     return expand_sync_operation (mem, val, code);
5274   else
5275     return expand_sync_fetch_operation (mem, val, code, after, target);
5276 }
5277
5278 /* Expand the __sync_val_compare_and_swap and __sync_bool_compare_and_swap
5279    intrinsics.  ARGLIST is the operands list to the function.  IS_BOOL is
5280    true if this is the boolean form.  TARGET is a place for us to store the
5281    results; this is NOT optional if IS_BOOL is true.  */
5282
5283 static rtx
5284 expand_builtin_compare_and_swap (tree arglist, bool is_bool, rtx target)
5285 {
5286   enum machine_mode mode;
5287   rtx addr, old_val, new_val, mem;
5288
5289   /* Expand the operands.  */
5290   addr = expand_expr (TREE_VALUE (arglist), NULL, Pmode, EXPAND_SUM);
5291   mode = TYPE_MODE (TREE_TYPE (TREE_TYPE (TREE_VALUE (arglist))));
5292
5293   arglist = TREE_CHAIN (arglist);
5294   old_val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
5295
5296   arglist = TREE_CHAIN (arglist);
5297   new_val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
5298
5299   /* Note that we explicitly do not want any alias information for this
5300      memory, so that we kill all other live memories.  Otherwise we don't
5301      satisfy the full barrier semantics of the intrinsic.  */
5302   mem = validize_mem (gen_rtx_MEM (mode, addr));
5303   MEM_VOLATILE_P (mem) = 1;
5304
5305   if (is_bool)
5306     return expand_bool_compare_and_swap (mem, old_val, new_val, target);
5307   else
5308     return expand_val_compare_and_swap (mem, old_val, new_val, target);
5309 }
5310
5311 /* Expand the __sync_lock_test_and_set intrinsic.  Note that the most
5312    general form is actually an atomic exchange, and some targets only
5313    support a reduced form with the second argument being a constant 1.
5314    ARGLIST is the operands list to the function; TARGET is an optional
5315    place for us to store the results.  */
5316
5317 static rtx
5318 expand_builtin_lock_test_and_set (tree arglist, rtx target)
5319 {
5320   enum machine_mode mode;
5321   rtx addr, val, mem;
5322
5323   /* Expand the operands.  */
5324   addr = expand_expr (TREE_VALUE (arglist), NULL, Pmode, EXPAND_NORMAL);
5325   mode = TYPE_MODE (TREE_TYPE (TREE_TYPE (TREE_VALUE (arglist))));
5326
5327   arglist = TREE_CHAIN (arglist);
5328   val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
5329
5330   /* Note that we explicitly do not want any alias information for this
5331      memory, so that we kill all other live memories.  Otherwise we don't
5332      satisfy the barrier semantics of the intrinsic.  */
5333   mem = validize_mem (gen_rtx_MEM (mode, addr));
5334   MEM_VOLATILE_P (mem) = 1;
5335
5336   return expand_sync_lock_test_and_set (mem, val, target);
5337 }
5338
5339 /* Expand the __sync_synchronize intrinsic.  */
5340
5341 static void
5342 expand_builtin_synchronize (void)
5343 {
5344   rtx body;
5345
5346 #ifdef HAVE_memory_barrier
5347   if (HAVE_memory_barrier)
5348     {
5349       emit_insn (gen_memory_barrier ());
5350       return;
5351     }
5352 #endif
5353
5354   /* If no explicit memory barrier instruction is available, create an empty
5355      asm stmt that will prevent compiler movement across the barrier.  */
5356   body = gen_rtx_ASM_INPUT (VOIDmode, "");
5357   MEM_VOLATILE_P (body) = 1;
5358   emit_insn (body);
5359 }
5360
5361 /* Expand the __sync_lock_release intrinsic.  ARGLIST is the operands list
5362    to the function.  */
5363
5364 static void
5365 expand_builtin_lock_release (tree arglist)
5366 {
5367   enum machine_mode mode;
5368   enum insn_code icode;
5369   rtx addr, val, mem, insn;
5370
5371   /* Expand the operands.  */
5372   addr = expand_expr (TREE_VALUE (arglist), NULL, Pmode, EXPAND_NORMAL);
5373   mode = TYPE_MODE (TREE_TYPE (TREE_TYPE (TREE_VALUE (arglist))));
5374   val = const0_rtx;
5375
5376   /* Note that we explicitly do not want any alias information for this
5377      memory, so that we kill all other live memories.  Otherwise we don't
5378      satisfy the barrier semantics of the intrinsic.  */
5379   mem = validize_mem (gen_rtx_MEM (mode, addr));
5380   MEM_VOLATILE_P (mem) = 1;
5381
5382   /* If there is an explicit operation in the md file, use it.  */
5383   icode = sync_lock_release[mode];
5384   if (icode != CODE_FOR_nothing)
5385     {
5386       if (!insn_data[icode].operand[1].predicate (val, mode))
5387         val = force_reg (mode, val);
5388
5389       insn = GEN_FCN (icode) (mem, val);
5390       if (insn)
5391         {
5392           emit_insn (insn);
5393           return;
5394         }
5395     }
5396
5397   /* Otherwise we can implement this operation by emitting a barrier
5398      followed by a store of zero.  */
5399   expand_builtin_synchronize ();
5400   emit_move_insn (mem, val);
5401 }
5402 \f
5403 /* Expand an expression EXP that calls a built-in function,
5404    with result going to TARGET if that's convenient
5405    (and in mode MODE if that's convenient).
5406    SUBTARGET may be used as the target for computing one of EXP's operands.
5407    IGNORE is nonzero if the value is to be ignored.  */
5408
5409 rtx
5410 expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
5411                 int ignore)
5412 {
5413   tree fndecl = get_callee_fndecl (exp);
5414   tree arglist = TREE_OPERAND (exp, 1);
5415   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
5416   enum machine_mode target_mode = TYPE_MODE (TREE_TYPE (exp));
5417
5418   if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
5419     return targetm.expand_builtin (exp, target, subtarget, mode, ignore);
5420
5421   /* When not optimizing, generate calls to library functions for a certain
5422      set of builtins.  */
5423   if (!optimize
5424       && !called_as_built_in (fndecl)
5425       && DECL_ASSEMBLER_NAME_SET_P (fndecl)
5426       && fcode != BUILT_IN_ALLOCA)
5427     return expand_call (exp, target, ignore);
5428
5429   /* The built-in function expanders test for target == const0_rtx
5430      to determine whether the function's result will be ignored.  */
5431   if (ignore)
5432     target = const0_rtx;
5433
5434   /* If the result of a pure or const built-in function is ignored, and
5435      none of its arguments are volatile, we can avoid expanding the
5436      built-in call and just evaluate the arguments for side-effects.  */
5437   if (target == const0_rtx
5438       && (DECL_IS_PURE (fndecl) || TREE_READONLY (fndecl)))
5439     {
5440       bool volatilep = false;
5441       tree arg;
5442
5443       for (arg = arglist; arg; arg = TREE_CHAIN (arg))
5444         if (TREE_THIS_VOLATILE (TREE_VALUE (arg)))
5445           {
5446             volatilep = true;
5447             break;
5448           }
5449
5450       if (! volatilep)
5451         {
5452           for (arg = arglist; arg; arg = TREE_CHAIN (arg))
5453             expand_expr (TREE_VALUE (arg), const0_rtx,
5454                          VOIDmode, EXPAND_NORMAL);
5455           return const0_rtx;
5456         }
5457     }
5458
5459   switch (fcode)
5460     {
5461     case BUILT_IN_FABS:
5462     case BUILT_IN_FABSF:
5463     case BUILT_IN_FABSL:
5464       target = expand_builtin_fabs (arglist, target, subtarget);
5465       if (target)
5466         return target;
5467       break;
5468
5469     case BUILT_IN_COPYSIGN:
5470     case BUILT_IN_COPYSIGNF:
5471     case BUILT_IN_COPYSIGNL:
5472       target = expand_builtin_copysign (arglist, target, subtarget);
5473       if (target)
5474         return target;
5475       break;
5476
5477       /* Just do a normal library call if we were unable to fold
5478          the values.  */
5479     case BUILT_IN_CABS:
5480     case BUILT_IN_CABSF:
5481     case BUILT_IN_CABSL:
5482       break;
5483
5484     case BUILT_IN_EXP:
5485     case BUILT_IN_EXPF:
5486     case BUILT_IN_EXPL:
5487     case BUILT_IN_EXP10:
5488     case BUILT_IN_EXP10F:
5489     case BUILT_IN_EXP10L:
5490     case BUILT_IN_POW10:
5491     case BUILT_IN_POW10F:
5492     case BUILT_IN_POW10L:
5493     case BUILT_IN_EXP2:
5494     case BUILT_IN_EXP2F:
5495     case BUILT_IN_EXP2L:
5496     case BUILT_IN_EXPM1:
5497     case BUILT_IN_EXPM1F:
5498     case BUILT_IN_EXPM1L:
5499     case BUILT_IN_LOGB:
5500     case BUILT_IN_LOGBF:
5501     case BUILT_IN_LOGBL:
5502     case BUILT_IN_ILOGB:
5503     case BUILT_IN_ILOGBF:
5504     case BUILT_IN_ILOGBL:
5505     case BUILT_IN_LOG:
5506     case BUILT_IN_LOGF:
5507     case BUILT_IN_LOGL:
5508     case BUILT_IN_LOG10:
5509     case BUILT_IN_LOG10F:
5510     case BUILT_IN_LOG10L:
5511     case BUILT_IN_LOG2:
5512     case BUILT_IN_LOG2F:
5513     case BUILT_IN_LOG2L:
5514     case BUILT_IN_LOG1P:
5515     case BUILT_IN_LOG1PF:
5516     case BUILT_IN_LOG1PL:
5517     case BUILT_IN_TAN:
5518     case BUILT_IN_TANF:
5519     case BUILT_IN_TANL:
5520     case BUILT_IN_ASIN:
5521     case BUILT_IN_ASINF:
5522     case BUILT_IN_ASINL:
5523     case BUILT_IN_ACOS:
5524     case BUILT_IN_ACOSF:
5525     case BUILT_IN_ACOSL:
5526     case BUILT_IN_ATAN:
5527     case BUILT_IN_ATANF:
5528     case BUILT_IN_ATANL:
5529       /* Treat these like sqrt only if unsafe math optimizations are allowed,
5530          because of possible accuracy problems.  */
5531       if (! flag_unsafe_math_optimizations)
5532         break;
5533     case BUILT_IN_SQRT:
5534     case BUILT_IN_SQRTF:
5535     case BUILT_IN_SQRTL:
5536     case BUILT_IN_FLOOR:
5537     case BUILT_IN_FLOORF:
5538     case BUILT_IN_FLOORL:
5539     case BUILT_IN_CEIL:
5540     case BUILT_IN_CEILF:
5541     case BUILT_IN_CEILL:
5542     case BUILT_IN_TRUNC:
5543     case BUILT_IN_TRUNCF:
5544     case BUILT_IN_TRUNCL:
5545     case BUILT_IN_ROUND:
5546     case BUILT_IN_ROUNDF:
5547     case BUILT_IN_ROUNDL:
5548     case BUILT_IN_NEARBYINT:
5549     case BUILT_IN_NEARBYINTF:
5550     case BUILT_IN_NEARBYINTL:
5551     case BUILT_IN_RINT:
5552     case BUILT_IN_RINTF:
5553     case BUILT_IN_RINTL:
5554     case BUILT_IN_LRINT:
5555     case BUILT_IN_LRINTF:
5556     case BUILT_IN_LRINTL:
5557     case BUILT_IN_LLRINT:
5558     case BUILT_IN_LLRINTF:
5559     case BUILT_IN_LLRINTL:
5560       target = expand_builtin_mathfn (exp, target, subtarget);
5561       if (target)
5562         return target;
5563       break;
5564
5565     case BUILT_IN_LCEIL:
5566     case BUILT_IN_LCEILF:
5567     case BUILT_IN_LCEILL:
5568     case BUILT_IN_LLCEIL:
5569     case BUILT_IN_LLCEILF:
5570     case BUILT_IN_LLCEILL:
5571     case BUILT_IN_LFLOOR:
5572     case BUILT_IN_LFLOORF:
5573     case BUILT_IN_LFLOORL:
5574     case BUILT_IN_LLFLOOR:
5575     case BUILT_IN_LLFLOORF:
5576     case BUILT_IN_LLFLOORL:
5577       target = expand_builtin_int_roundingfn (exp, target, subtarget);
5578       if (target)
5579         return target;
5580       break;
5581
5582     case BUILT_IN_POW:
5583     case BUILT_IN_POWF:
5584     case BUILT_IN_POWL:
5585       target = expand_builtin_pow (exp, target, subtarget);
5586       if (target)
5587         return target;
5588       break;
5589
5590     case BUILT_IN_POWI:
5591     case BUILT_IN_POWIF:
5592     case BUILT_IN_POWIL:
5593       target = expand_builtin_powi (exp, target, subtarget);
5594       if (target)
5595         return target;
5596       break;
5597
5598     case BUILT_IN_ATAN2:
5599     case BUILT_IN_ATAN2F:
5600     case BUILT_IN_ATAN2L:
5601     case BUILT_IN_LDEXP:
5602     case BUILT_IN_LDEXPF:
5603     case BUILT_IN_LDEXPL:
5604     case BUILT_IN_FMOD:
5605     case BUILT_IN_FMODF:
5606     case BUILT_IN_FMODL:
5607     case BUILT_IN_DREM:
5608     case BUILT_IN_DREMF:
5609     case BUILT_IN_DREML:
5610       if (! flag_unsafe_math_optimizations)
5611         break;
5612       target = expand_builtin_mathfn_2 (exp, target, subtarget);
5613       if (target)
5614         return target;
5615       break;
5616
5617     case BUILT_IN_SIN:
5618     case BUILT_IN_SINF:
5619     case BUILT_IN_SINL:
5620     case BUILT_IN_COS:
5621     case BUILT_IN_COSF:
5622     case BUILT_IN_COSL:
5623       if (! flag_unsafe_math_optimizations)
5624         break;
5625       target = expand_builtin_mathfn_3 (exp, target, subtarget);
5626       if (target)
5627         return target;
5628       break;
5629
5630     case BUILT_IN_APPLY_ARGS:
5631       return expand_builtin_apply_args ();
5632
5633       /* __builtin_apply (FUNCTION, ARGUMENTS, ARGSIZE) invokes
5634          FUNCTION with a copy of the parameters described by
5635          ARGUMENTS, and ARGSIZE.  It returns a block of memory
5636          allocated on the stack into which is stored all the registers
5637          that might possibly be used for returning the result of a
5638          function.  ARGUMENTS is the value returned by
5639          __builtin_apply_args.  ARGSIZE is the number of bytes of
5640          arguments that must be copied.  ??? How should this value be
5641          computed?  We'll also need a safe worst case value for varargs
5642          functions.  */
5643     case BUILT_IN_APPLY:
5644       if (!validate_arglist (arglist, POINTER_TYPE,
5645                              POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)
5646           && !validate_arglist (arglist, REFERENCE_TYPE,
5647                                 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
5648         return const0_rtx;
5649       else
5650         {
5651           int i;
5652           tree t;
5653           rtx ops[3];
5654
5655           for (t = arglist, i = 0; t; t = TREE_CHAIN (t), i++)
5656             ops[i] = expand_expr (TREE_VALUE (t), NULL_RTX, VOIDmode, 0);
5657
5658           return expand_builtin_apply (ops[0], ops[1], ops[2]);
5659         }
5660
5661       /* __builtin_return (RESULT) causes the function to return the
5662          value described by RESULT.  RESULT is address of the block of
5663          memory returned by __builtin_apply.  */
5664     case BUILT_IN_RETURN:
5665       if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5666         expand_builtin_return (expand_expr (TREE_VALUE (arglist),
5667                                             NULL_RTX, VOIDmode, 0));
5668       return const0_rtx;
5669
5670     case BUILT_IN_SAVEREGS:
5671       return expand_builtin_saveregs ();
5672
5673     case BUILT_IN_ARGS_INFO:
5674       return expand_builtin_args_info (arglist);
5675
5676       /* Return the address of the first anonymous stack arg.  */
5677     case BUILT_IN_NEXT_ARG:
5678       if (fold_builtin_next_arg (arglist))
5679         return const0_rtx;
5680       return expand_builtin_next_arg ();
5681
5682     case BUILT_IN_CLASSIFY_TYPE:
5683       return expand_builtin_classify_type (arglist);
5684
5685     case BUILT_IN_CONSTANT_P:
5686       return const0_rtx;
5687
5688     case BUILT_IN_FRAME_ADDRESS:
5689     case BUILT_IN_RETURN_ADDRESS:
5690       return expand_builtin_frame_address (fndecl, arglist);
5691
5692     /* Returns the address of the area where the structure is returned.
5693        0 otherwise.  */
5694     case BUILT_IN_AGGREGATE_INCOMING_ADDRESS:
5695       if (arglist != 0
5696           || ! AGGREGATE_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl)))
5697           || !MEM_P (DECL_RTL (DECL_RESULT (current_function_decl))))
5698         return const0_rtx;
5699       else
5700         return XEXP (DECL_RTL (DECL_RESULT (current_function_decl)), 0);
5701
5702     case BUILT_IN_ALLOCA:
5703       target = expand_builtin_alloca (arglist, target);
5704       if (target)
5705         return target;
5706       break;
5707
5708     case BUILT_IN_STACK_SAVE:
5709       return expand_stack_save ();
5710
5711     case BUILT_IN_STACK_RESTORE:
5712       expand_stack_restore (TREE_VALUE (arglist));
5713       return const0_rtx;
5714
5715     case BUILT_IN_FFS:
5716     case BUILT_IN_FFSL:
5717     case BUILT_IN_FFSLL:
5718     case BUILT_IN_FFSIMAX:
5719       target = expand_builtin_unop (target_mode, arglist, target,
5720                                     subtarget, ffs_optab);
5721       if (target)
5722         return target;
5723       break;
5724
5725     case BUILT_IN_CLZ:
5726     case BUILT_IN_CLZL:
5727     case BUILT_IN_CLZLL:
5728     case BUILT_IN_CLZIMAX:
5729       target = expand_builtin_unop (target_mode, arglist, target,
5730                                     subtarget, clz_optab);
5731       if (target)
5732         return target;
5733       break;
5734
5735     case BUILT_IN_CTZ:
5736     case BUILT_IN_CTZL:
5737     case BUILT_IN_CTZLL:
5738     case BUILT_IN_CTZIMAX:
5739       target = expand_builtin_unop (target_mode, arglist, target,
5740                                     subtarget, ctz_optab);
5741       if (target)
5742         return target;
5743       break;
5744
5745     case BUILT_IN_POPCOUNT:
5746     case BUILT_IN_POPCOUNTL:
5747     case BUILT_IN_POPCOUNTLL:
5748     case BUILT_IN_POPCOUNTIMAX:
5749       target = expand_builtin_unop (target_mode, arglist, target,
5750                                     subtarget, popcount_optab);
5751       if (target)
5752         return target;
5753       break;
5754
5755     case BUILT_IN_PARITY:
5756     case BUILT_IN_PARITYL:
5757     case BUILT_IN_PARITYLL:
5758     case BUILT_IN_PARITYIMAX:
5759       target = expand_builtin_unop (target_mode, arglist, target,
5760                                     subtarget, parity_optab);
5761       if (target)
5762         return target;
5763       break;
5764
5765     case BUILT_IN_STRLEN:
5766       target = expand_builtin_strlen (arglist, target, target_mode);
5767       if (target)
5768         return target;
5769       break;
5770
5771     case BUILT_IN_STRCPY:
5772       target = expand_builtin_strcpy (exp, target, mode);
5773       if (target)
5774         return target;
5775       break;
5776
5777     case BUILT_IN_STRNCPY:
5778       target = expand_builtin_strncpy (exp, target, mode);
5779       if (target)
5780         return target;
5781       break;
5782
5783     case BUILT_IN_STPCPY:
5784       target = expand_builtin_stpcpy (exp, target, mode);
5785       if (target)
5786         return target;
5787       break;
5788
5789     case BUILT_IN_STRCAT:
5790       target = expand_builtin_strcat (arglist, TREE_TYPE (exp), target, mode);
5791       if (target)
5792         return target;
5793       break;
5794
5795     case BUILT_IN_STRNCAT:
5796       target = expand_builtin_strncat (arglist, target, mode);
5797       if (target)
5798         return target;
5799       break;
5800
5801     case BUILT_IN_STRSPN:
5802       target = expand_builtin_strspn (arglist, target, mode);
5803       if (target)
5804         return target;
5805       break;
5806
5807     case BUILT_IN_STRCSPN:
5808       target = expand_builtin_strcspn (arglist, target, mode);
5809       if (target)
5810         return target;
5811       break;
5812
5813     case BUILT_IN_STRSTR:
5814       target = expand_builtin_strstr (arglist, TREE_TYPE (exp), target, mode);
5815       if (target)
5816         return target;
5817       break;
5818
5819     case BUILT_IN_STRPBRK:
5820       target = expand_builtin_strpbrk (arglist, TREE_TYPE (exp), target, mode);
5821       if (target)
5822         return target;
5823       break;
5824
5825     case BUILT_IN_INDEX:
5826     case BUILT_IN_STRCHR:
5827       target = expand_builtin_strchr (arglist, TREE_TYPE (exp), target, mode);
5828       if (target)
5829         return target;
5830       break;
5831
5832     case BUILT_IN_RINDEX:
5833     case BUILT_IN_STRRCHR:
5834       target = expand_builtin_strrchr (arglist, TREE_TYPE (exp), target, mode);
5835       if (target)
5836         return target;
5837       break;
5838
5839     case BUILT_IN_MEMCPY:
5840       target = expand_builtin_memcpy (exp, target, mode);
5841       if (target)
5842         return target;
5843       break;
5844
5845     case BUILT_IN_MEMPCPY:
5846       target = expand_builtin_mempcpy (arglist, TREE_TYPE (exp), target, mode, /*endp=*/ 1);
5847       if (target)
5848         return target;
5849       break;
5850
5851     case BUILT_IN_MEMMOVE:
5852       target = expand_builtin_memmove (arglist, TREE_TYPE (exp), target, mode);
5853       if (target)
5854         return target;
5855       break;
5856
5857     case BUILT_IN_BCOPY:
5858       target = expand_builtin_bcopy (arglist, TREE_TYPE (exp));
5859       if (target)
5860         return target;
5861       break;
5862
5863     case BUILT_IN_MEMSET:
5864       target = expand_builtin_memset (arglist, target, mode);
5865       if (target)
5866         return target;
5867       break;
5868
5869     case BUILT_IN_BZERO:
5870       target = expand_builtin_bzero (arglist);
5871       if (target)
5872         return target;
5873       break;
5874
5875     case BUILT_IN_STRCMP:
5876       target = expand_builtin_strcmp (exp, target, mode);
5877       if (target)
5878         return target;
5879       break;
5880
5881     case BUILT_IN_STRNCMP:
5882       target = expand_builtin_strncmp (exp, target, mode);
5883       if (target)
5884         return target;
5885       break;
5886
5887     case BUILT_IN_BCMP:
5888     case BUILT_IN_MEMCMP:
5889       target = expand_builtin_memcmp (exp, arglist, target, mode);
5890       if (target)
5891         return target;
5892       break;
5893
5894     case BUILT_IN_SETJMP:
5895       target = expand_builtin_setjmp (arglist, target);
5896       if (target)
5897         return target;
5898       break;
5899
5900       /* __builtin_longjmp is passed a pointer to an array of five words.
5901          It's similar to the C library longjmp function but works with
5902          __builtin_setjmp above.  */
5903     case BUILT_IN_LONGJMP:
5904       if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
5905         break;
5906       else
5907         {
5908           rtx buf_addr = expand_expr (TREE_VALUE (arglist), subtarget,
5909                                       VOIDmode, 0);
5910           rtx value = expand_expr (TREE_VALUE (TREE_CHAIN (arglist)),
5911                                    NULL_RTX, VOIDmode, 0);
5912
5913           if (value != const1_rtx)
5914             {
5915               error ("%<__builtin_longjmp%> second argument must be 1");
5916               return const0_rtx;
5917             }
5918
5919           expand_builtin_longjmp (buf_addr, value);
5920           return const0_rtx;
5921         }
5922
5923     case BUILT_IN_NONLOCAL_GOTO:
5924       target = expand_builtin_nonlocal_goto (arglist);
5925       if (target)
5926         return target;
5927       break;
5928
5929       /* This updates the setjmp buffer that is its argument with the value
5930          of the current stack pointer.  */
5931     case BUILT_IN_UPDATE_SETJMP_BUF:
5932       if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5933         {
5934           rtx buf_addr
5935             = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
5936
5937           expand_builtin_update_setjmp_buf (buf_addr);
5938           return const0_rtx;
5939         }
5940       break;
5941
5942     case BUILT_IN_TRAP:
5943       expand_builtin_trap ();
5944       return const0_rtx;
5945
5946     case BUILT_IN_PRINTF:
5947       target = expand_builtin_printf (arglist, target, mode, false);
5948       if (target)
5949         return target;
5950       break;
5951
5952     case BUILT_IN_PRINTF_UNLOCKED:
5953       target = expand_builtin_printf (arglist, target, mode, true);
5954       if (target)
5955         return target;
5956       break;
5957
5958     case BUILT_IN_FPUTS:
5959       target = expand_builtin_fputs (arglist, target, false);
5960       if (target)
5961         return target;
5962       break;
5963     case BUILT_IN_FPUTS_UNLOCKED:
5964       target = expand_builtin_fputs (arglist, target, true);
5965       if (target)
5966         return target;
5967       break;
5968
5969     case BUILT_IN_FPRINTF:
5970       target = expand_builtin_fprintf (arglist, target, mode, false);
5971       if (target)
5972         return target;
5973       break;
5974
5975     case BUILT_IN_FPRINTF_UNLOCKED:
5976       target = expand_builtin_fprintf (arglist, target, mode, true);
5977       if (target)
5978         return target;
5979       break;
5980
5981     case BUILT_IN_SPRINTF:
5982       target = expand_builtin_sprintf (arglist, target, mode);
5983       if (target)
5984         return target;
5985       break;
5986
5987     case BUILT_IN_SIGNBIT:
5988     case BUILT_IN_SIGNBITF:
5989     case BUILT_IN_SIGNBITL:
5990       target = expand_builtin_signbit (exp, target);
5991       if (target)
5992         return target;
5993       break;
5994
5995       /* Various hooks for the DWARF 2 __throw routine.  */
5996     case BUILT_IN_UNWIND_INIT:
5997       expand_builtin_unwind_init ();
5998       return const0_rtx;
5999     case BUILT_IN_DWARF_CFA:
6000       return virtual_cfa_rtx;
6001 #ifdef DWARF2_UNWIND_INFO
6002     case BUILT_IN_DWARF_SP_COLUMN:
6003       return expand_builtin_dwarf_sp_column ();
6004     case BUILT_IN_INIT_DWARF_REG_SIZES:
6005       expand_builtin_init_dwarf_reg_sizes (TREE_VALUE (arglist));
6006       return const0_rtx;
6007 #endif
6008     case BUILT_IN_FROB_RETURN_ADDR:
6009       return expand_builtin_frob_return_addr (TREE_VALUE (arglist));
6010     case BUILT_IN_EXTRACT_RETURN_ADDR:
6011       return expand_builtin_extract_return_addr (TREE_VALUE (arglist));
6012     case BUILT_IN_EH_RETURN:
6013       expand_builtin_eh_return (TREE_VALUE (arglist),
6014                                 TREE_VALUE (TREE_CHAIN (arglist)));
6015       return const0_rtx;
6016 #ifdef EH_RETURN_DATA_REGNO
6017     case BUILT_IN_EH_RETURN_DATA_REGNO:
6018       return expand_builtin_eh_return_data_regno (arglist);
6019 #endif
6020     case BUILT_IN_EXTEND_POINTER:
6021       return expand_builtin_extend_pointer (TREE_VALUE (arglist));
6022
6023     case BUILT_IN_VA_START:
6024     case BUILT_IN_STDARG_START:
6025       return expand_builtin_va_start (arglist);
6026     case BUILT_IN_VA_END:
6027       return expand_builtin_va_end (arglist);
6028     case BUILT_IN_VA_COPY:
6029       return expand_builtin_va_copy (arglist);
6030     case BUILT_IN_EXPECT:
6031       return expand_builtin_expect (arglist, target);
6032     case BUILT_IN_PREFETCH:
6033       expand_builtin_prefetch (arglist);
6034       return const0_rtx;
6035
6036     case BUILT_IN_PROFILE_FUNC_ENTER:
6037       return expand_builtin_profile_func (false);
6038     case BUILT_IN_PROFILE_FUNC_EXIT:
6039       return expand_builtin_profile_func (true);
6040
6041     case BUILT_IN_INIT_TRAMPOLINE:
6042       return expand_builtin_init_trampoline (arglist);
6043     case BUILT_IN_ADJUST_TRAMPOLINE:
6044       return expand_builtin_adjust_trampoline (arglist);
6045
6046     case BUILT_IN_FORK:
6047     case BUILT_IN_EXECL:
6048     case BUILT_IN_EXECV:
6049     case BUILT_IN_EXECLP:
6050     case BUILT_IN_EXECLE:
6051     case BUILT_IN_EXECVP:
6052     case BUILT_IN_EXECVE:
6053       target = expand_builtin_fork_or_exec (fndecl, arglist, target, ignore);
6054       if (target)
6055         return target;
6056       break;
6057
6058     case BUILT_IN_FETCH_AND_ADD_1:
6059     case BUILT_IN_FETCH_AND_ADD_2:
6060     case BUILT_IN_FETCH_AND_ADD_4:
6061     case BUILT_IN_FETCH_AND_ADD_8:
6062       target = expand_builtin_sync_operation (arglist, PLUS,
6063                                               false, target, ignore);
6064       if (target)
6065         return target;
6066       break;
6067
6068     case BUILT_IN_FETCH_AND_SUB_1:
6069     case BUILT_IN_FETCH_AND_SUB_2:
6070     case BUILT_IN_FETCH_AND_SUB_4:
6071     case BUILT_IN_FETCH_AND_SUB_8:
6072       target = expand_builtin_sync_operation (arglist, MINUS,
6073                                               false, target, ignore);
6074       if (target)
6075         return target;
6076       break;
6077
6078     case BUILT_IN_FETCH_AND_OR_1:
6079     case BUILT_IN_FETCH_AND_OR_2:
6080     case BUILT_IN_FETCH_AND_OR_4:
6081     case BUILT_IN_FETCH_AND_OR_8:
6082       target = expand_builtin_sync_operation (arglist, IOR,
6083                                               false, target, ignore);
6084       if (target)
6085         return target;
6086       break;
6087
6088     case BUILT_IN_FETCH_AND_AND_1:
6089     case BUILT_IN_FETCH_AND_AND_2:
6090     case BUILT_IN_FETCH_AND_AND_4:
6091     case BUILT_IN_FETCH_AND_AND_8:
6092       target = expand_builtin_sync_operation (arglist, AND,
6093                                               false, target, ignore);
6094       if (target)
6095         return target;
6096       break;
6097
6098     case BUILT_IN_FETCH_AND_XOR_1:
6099     case BUILT_IN_FETCH_AND_XOR_2:
6100     case BUILT_IN_FETCH_AND_XOR_4:
6101     case BUILT_IN_FETCH_AND_XOR_8:
6102       target = expand_builtin_sync_operation (arglist, XOR,
6103                                               false, target, ignore);
6104       if (target)
6105         return target;
6106       break;
6107
6108     case BUILT_IN_FETCH_AND_NAND_1:
6109     case BUILT_IN_FETCH_AND_NAND_2:
6110     case BUILT_IN_FETCH_AND_NAND_4:
6111     case BUILT_IN_FETCH_AND_NAND_8:
6112       target = expand_builtin_sync_operation (arglist, NOT,
6113                                               false, target, ignore);
6114       if (target)
6115         return target;
6116       break;
6117
6118     case BUILT_IN_ADD_AND_FETCH_1:
6119     case BUILT_IN_ADD_AND_FETCH_2:
6120     case BUILT_IN_ADD_AND_FETCH_4:
6121     case BUILT_IN_ADD_AND_FETCH_8:
6122       target = expand_builtin_sync_operation (arglist, PLUS,
6123                                               true, target, ignore);
6124       if (target)
6125         return target;
6126       break;
6127
6128     case BUILT_IN_SUB_AND_FETCH_1:
6129     case BUILT_IN_SUB_AND_FETCH_2:
6130     case BUILT_IN_SUB_AND_FETCH_4:
6131     case BUILT_IN_SUB_AND_FETCH_8:
6132       target = expand_builtin_sync_operation (arglist, MINUS,
6133                                               true, target, ignore);
6134       if (target)
6135         return target;
6136       break;
6137
6138     case BUILT_IN_OR_AND_FETCH_1:
6139     case BUILT_IN_OR_AND_FETCH_2:
6140     case BUILT_IN_OR_AND_FETCH_4:
6141     case BUILT_IN_OR_AND_FETCH_8:
6142       target = expand_builtin_sync_operation (arglist, IOR,
6143                                               true, target, ignore);
6144       if (target)
6145         return target;
6146       break;
6147
6148     case BUILT_IN_AND_AND_FETCH_1:
6149     case BUILT_IN_AND_AND_FETCH_2:
6150     case BUILT_IN_AND_AND_FETCH_4:
6151     case BUILT_IN_AND_AND_FETCH_8:
6152       target = expand_builtin_sync_operation (arglist, AND,
6153                                               true, target, ignore);
6154       if (target)
6155         return target;
6156       break;
6157
6158     case BUILT_IN_XOR_AND_FETCH_1:
6159     case BUILT_IN_XOR_AND_FETCH_2:
6160     case BUILT_IN_XOR_AND_FETCH_4:
6161     case BUILT_IN_XOR_AND_FETCH_8:
6162       target = expand_builtin_sync_operation (arglist, XOR,
6163                                               true, target, ignore);
6164       if (target)
6165         return target;
6166       break;
6167
6168     case BUILT_IN_NAND_AND_FETCH_1:
6169     case BUILT_IN_NAND_AND_FETCH_2:
6170     case BUILT_IN_NAND_AND_FETCH_4:
6171     case BUILT_IN_NAND_AND_FETCH_8:
6172       target = expand_builtin_sync_operation (arglist, NOT,
6173                                               true, target, ignore);
6174       if (target)
6175         return target;
6176       break;
6177
6178     case BUILT_IN_BOOL_COMPARE_AND_SWAP_1:
6179     case BUILT_IN_BOOL_COMPARE_AND_SWAP_2:
6180     case BUILT_IN_BOOL_COMPARE_AND_SWAP_4:
6181     case BUILT_IN_BOOL_COMPARE_AND_SWAP_8:
6182       if (mode == VOIDmode)
6183         mode = TYPE_MODE (boolean_type_node);
6184       if (!target || !register_operand (target, mode))
6185         target = gen_reg_rtx (mode);
6186       target = expand_builtin_compare_and_swap (arglist, true, target);
6187       if (target)
6188         return target;
6189       break;
6190
6191     case BUILT_IN_VAL_COMPARE_AND_SWAP_1:
6192     case BUILT_IN_VAL_COMPARE_AND_SWAP_2:
6193     case BUILT_IN_VAL_COMPARE_AND_SWAP_4:
6194     case BUILT_IN_VAL_COMPARE_AND_SWAP_8:
6195       target = expand_builtin_compare_and_swap (arglist, false, target);
6196       if (target)
6197         return target;
6198       break;
6199
6200     case BUILT_IN_LOCK_TEST_AND_SET_1:
6201     case BUILT_IN_LOCK_TEST_AND_SET_2:
6202     case BUILT_IN_LOCK_TEST_AND_SET_4:
6203     case BUILT_IN_LOCK_TEST_AND_SET_8:
6204       target = expand_builtin_lock_test_and_set (arglist, target);
6205       if (target)
6206         return target;
6207       break;
6208
6209     case BUILT_IN_LOCK_RELEASE_1:
6210     case BUILT_IN_LOCK_RELEASE_2:
6211     case BUILT_IN_LOCK_RELEASE_4:
6212     case BUILT_IN_LOCK_RELEASE_8:
6213       expand_builtin_lock_release (arglist);
6214       return const0_rtx;
6215
6216     case BUILT_IN_SYNCHRONIZE:
6217       expand_builtin_synchronize ();
6218       return const0_rtx;
6219
6220     default:    /* just do library call, if unknown builtin */
6221       break;
6222     }
6223
6224   /* The switch statement above can drop through to cause the function
6225      to be called normally.  */
6226   return expand_call (exp, target, ignore);
6227 }
6228
6229 /* Determine whether a tree node represents a call to a built-in
6230    function.  If the tree T is a call to a built-in function with
6231    the right number of arguments of the appropriate types, return
6232    the DECL_FUNCTION_CODE of the call, e.g. BUILT_IN_SQRT.
6233    Otherwise the return value is END_BUILTINS.  */
6234
6235 enum built_in_function
6236 builtin_mathfn_code (tree t)
6237 {
6238   tree fndecl, arglist, parmlist;
6239   tree argtype, parmtype;
6240
6241   if (TREE_CODE (t) != CALL_EXPR
6242       || TREE_CODE (TREE_OPERAND (t, 0)) != ADDR_EXPR)
6243     return END_BUILTINS;
6244
6245   fndecl = get_callee_fndecl (t);
6246   if (fndecl == NULL_TREE
6247       || TREE_CODE (fndecl) != FUNCTION_DECL
6248       || ! DECL_BUILT_IN (fndecl)
6249       || DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
6250     return END_BUILTINS;
6251
6252   arglist = TREE_OPERAND (t, 1);
6253   parmlist = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
6254   for (; parmlist; parmlist = TREE_CHAIN (parmlist))
6255     {
6256       /* If a function doesn't take a variable number of arguments,
6257          the last element in the list will have type `void'.  */
6258       parmtype = TREE_VALUE (parmlist);
6259       if (VOID_TYPE_P (parmtype))
6260         {
6261           if (arglist)
6262             return END_BUILTINS;
6263           return DECL_FUNCTION_CODE (fndecl);
6264         }
6265
6266       if (! arglist)
6267         return END_BUILTINS;
6268
6269       argtype = TREE_TYPE (TREE_VALUE (arglist));
6270
6271       if (SCALAR_FLOAT_TYPE_P (parmtype))
6272         {
6273           if (! SCALAR_FLOAT_TYPE_P (argtype))
6274             return END_BUILTINS;
6275         }
6276       else if (COMPLEX_FLOAT_TYPE_P (parmtype))
6277         {
6278           if (! COMPLEX_FLOAT_TYPE_P (argtype))
6279             return END_BUILTINS;
6280         }
6281       else if (POINTER_TYPE_P (parmtype))
6282         {
6283           if (! POINTER_TYPE_P (argtype))
6284             return END_BUILTINS;
6285         }
6286       else if (INTEGRAL_TYPE_P (parmtype))
6287         {
6288           if (! INTEGRAL_TYPE_P (argtype))
6289             return END_BUILTINS;
6290         }
6291       else
6292         return END_BUILTINS;
6293
6294       arglist = TREE_CHAIN (arglist);
6295     }
6296
6297   /* Variable-length argument list.  */
6298   return DECL_FUNCTION_CODE (fndecl);
6299 }
6300
6301 /* Fold a call to __builtin_constant_p, if we know it will evaluate to a
6302    constant.  ARGLIST is the argument list of the call.  */
6303
6304 static tree
6305 fold_builtin_constant_p (tree arglist)
6306 {
6307   if (arglist == 0)
6308     return 0;
6309
6310   arglist = TREE_VALUE (arglist);
6311
6312   /* We return 1 for a numeric type that's known to be a constant
6313      value at compile-time or for an aggregate type that's a
6314      literal constant.  */
6315   STRIP_NOPS (arglist);
6316
6317   /* If we know this is a constant, emit the constant of one.  */
6318   if (CONSTANT_CLASS_P (arglist)
6319       || (TREE_CODE (arglist) == CONSTRUCTOR
6320           && TREE_CONSTANT (arglist))
6321       || (TREE_CODE (arglist) == ADDR_EXPR
6322           && TREE_CODE (TREE_OPERAND (arglist, 0)) == STRING_CST))
6323     return integer_one_node;
6324
6325   /* If this expression has side effects, show we don't know it to be a
6326      constant.  Likewise if it's a pointer or aggregate type since in
6327      those case we only want literals, since those are only optimized
6328      when generating RTL, not later.
6329      And finally, if we are compiling an initializer, not code, we
6330      need to return a definite result now; there's not going to be any
6331      more optimization done.  */
6332   if (TREE_SIDE_EFFECTS (arglist)
6333       || AGGREGATE_TYPE_P (TREE_TYPE (arglist))
6334       || POINTER_TYPE_P (TREE_TYPE (arglist))
6335       || cfun == 0)
6336     return integer_zero_node;
6337
6338   return 0;
6339 }
6340
6341 /* Fold a call to __builtin_expect, if we expect that a comparison against
6342    the argument will fold to a constant.  In practice, this means a true
6343    constant or the address of a non-weak symbol.  ARGLIST is the argument
6344    list of the call.  */
6345
6346 static tree
6347 fold_builtin_expect (tree arglist)
6348 {
6349   tree arg, inner;
6350
6351   if (arglist == 0)
6352     return 0;
6353
6354   arg = TREE_VALUE (arglist);
6355
6356   /* If the argument isn't invariant, then there's nothing we can do.  */
6357   if (!TREE_INVARIANT (arg))
6358     return 0;
6359
6360   /* If we're looking at an address of a weak decl, then do not fold.  */
6361   inner = arg;
6362   STRIP_NOPS (inner);
6363   if (TREE_CODE (inner) == ADDR_EXPR)
6364     {
6365       do
6366         {
6367           inner = TREE_OPERAND (inner, 0);
6368         }
6369       while (TREE_CODE (inner) == COMPONENT_REF
6370              || TREE_CODE (inner) == ARRAY_REF);
6371       if (DECL_P (inner) && DECL_WEAK (inner))
6372         return 0;
6373     }
6374
6375   /* Otherwise, ARG already has the proper type for the return value.  */
6376   return arg;
6377 }
6378
6379 /* Fold a call to __builtin_classify_type.  */
6380
6381 static tree
6382 fold_builtin_classify_type (tree arglist)
6383 {
6384   if (arglist == 0)
6385     return build_int_cst (NULL_TREE, no_type_class);
6386
6387   return build_int_cst (NULL_TREE,
6388                         type_to_class (TREE_TYPE (TREE_VALUE (arglist))));
6389 }
6390
6391 /* Fold a call to __builtin_strlen.  */
6392
6393 static tree
6394 fold_builtin_strlen (tree arglist)
6395 {
6396   if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6397     return NULL_TREE;
6398   else
6399     {
6400       tree len = c_strlen (TREE_VALUE (arglist), 0);
6401
6402       if (len)
6403         {
6404           /* Convert from the internal "sizetype" type to "size_t".  */
6405           if (size_type_node)
6406             len = fold_convert (size_type_node, len);
6407           return len;
6408         }
6409
6410       return NULL_TREE;
6411     }
6412 }
6413
6414 /* Fold a call to __builtin_inf or __builtin_huge_val.  */
6415
6416 static tree
6417 fold_builtin_inf (tree type, int warn)
6418 {
6419   REAL_VALUE_TYPE real;
6420
6421   /* __builtin_inff is intended to be usable to define INFINITY on all
6422      targets.  If an infinity is not available, INFINITY expands "to a
6423      positive constant of type float that overflows at translation
6424      time", footnote "In this case, using INFINITY will violate the
6425      constraint in 6.4.4 and thus require a diagnostic." (C99 7.12#4).
6426      Thus we pedwarn to ensure this constraint violation is
6427      diagnosed.  */
6428   if (!MODE_HAS_INFINITIES (TYPE_MODE (type)) && warn)
6429     pedwarn ("target format does not support infinity");
6430
6431   real_inf (&real);
6432   return build_real (type, real);
6433 }
6434
6435 /* Fold a call to __builtin_nan or __builtin_nans.  */
6436
6437 static tree
6438 fold_builtin_nan (tree arglist, tree type, int quiet)
6439 {
6440   REAL_VALUE_TYPE real;
6441   const char *str;
6442
6443   if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6444     return 0;
6445   str = c_getstr (TREE_VALUE (arglist));
6446   if (!str)
6447     return 0;
6448
6449   if (!real_nan (&real, str, quiet, TYPE_MODE (type)))
6450     return 0;
6451
6452   return build_real (type, real);
6453 }
6454
6455 /* Return true if the floating point expression T has an integer value.
6456    We also allow +Inf, -Inf and NaN to be considered integer values.  */
6457
6458 static bool
6459 integer_valued_real_p (tree t)
6460 {
6461   switch (TREE_CODE (t))
6462     {
6463     case FLOAT_EXPR:
6464       return true;
6465
6466     case ABS_EXPR:
6467     case SAVE_EXPR:
6468     case NON_LVALUE_EXPR:
6469       return integer_valued_real_p (TREE_OPERAND (t, 0));
6470
6471     case COMPOUND_EXPR:
6472     case MODIFY_EXPR:
6473     case BIND_EXPR:
6474       return integer_valued_real_p (TREE_OPERAND (t, 1));
6475
6476     case PLUS_EXPR:
6477     case MINUS_EXPR:
6478     case MULT_EXPR:
6479     case MIN_EXPR:
6480     case MAX_EXPR:
6481       return integer_valued_real_p (TREE_OPERAND (t, 0))
6482              && integer_valued_real_p (TREE_OPERAND (t, 1));
6483
6484     case COND_EXPR:
6485       return integer_valued_real_p (TREE_OPERAND (t, 1))
6486              && integer_valued_real_p (TREE_OPERAND (t, 2));
6487
6488     case REAL_CST:
6489       if (! TREE_CONSTANT_OVERFLOW (t))
6490       {
6491         REAL_VALUE_TYPE c, cint;
6492
6493         c = TREE_REAL_CST (t);
6494         real_trunc (&cint, TYPE_MODE (TREE_TYPE (t)), &c);
6495         return real_identical (&c, &cint);
6496       }
6497
6498     case NOP_EXPR:
6499       {
6500         tree type = TREE_TYPE (TREE_OPERAND (t, 0));
6501         if (TREE_CODE (type) == INTEGER_TYPE)
6502           return true;
6503         if (TREE_CODE (type) == REAL_TYPE)
6504           return integer_valued_real_p (TREE_OPERAND (t, 0));
6505         break;
6506       }
6507
6508     case CALL_EXPR:
6509       switch (builtin_mathfn_code (t))
6510         {
6511         case BUILT_IN_CEIL:
6512         case BUILT_IN_CEILF:
6513         case BUILT_IN_CEILL:
6514         case BUILT_IN_FLOOR:
6515         case BUILT_IN_FLOORF:
6516         case BUILT_IN_FLOORL:
6517         case BUILT_IN_NEARBYINT:
6518         case BUILT_IN_NEARBYINTF:
6519         case BUILT_IN_NEARBYINTL:
6520         case BUILT_IN_RINT:
6521         case BUILT_IN_RINTF:
6522         case BUILT_IN_RINTL:
6523         case BUILT_IN_ROUND:
6524         case BUILT_IN_ROUNDF:
6525         case BUILT_IN_ROUNDL:
6526         case BUILT_IN_TRUNC:
6527         case BUILT_IN_TRUNCF:
6528         case BUILT_IN_TRUNCL:
6529           return true;
6530
6531         default:
6532           break;
6533         }
6534       break;
6535
6536     default:
6537       break;
6538     }
6539   return false;
6540 }
6541
6542 /* EXP is assumed to be builtin call where truncation can be propagated
6543    across (for instance floor((double)f) == (double)floorf (f).
6544    Do the transformation.  */
6545
6546 static tree
6547 fold_trunc_transparent_mathfn (tree fndecl, tree arglist)
6548 {
6549   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
6550   tree arg;
6551
6552   if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6553     return 0;
6554
6555   arg = TREE_VALUE (arglist);
6556   /* Integer rounding functions are idempotent.  */
6557   if (fcode == builtin_mathfn_code (arg))
6558     return arg;
6559
6560   /* If argument is already integer valued, and we don't need to worry
6561      about setting errno, there's no need to perform rounding.  */
6562   if (! flag_errno_math && integer_valued_real_p (arg))
6563     return arg;
6564
6565   if (optimize)
6566     {
6567       tree arg0 = strip_float_extensions (arg);
6568       tree ftype = TREE_TYPE (TREE_TYPE (fndecl));
6569       tree newtype = TREE_TYPE (arg0);
6570       tree decl;
6571
6572       if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
6573           && (decl = mathfn_built_in (newtype, fcode)))
6574         {
6575           arglist =
6576             build_tree_list (NULL_TREE, fold_convert (newtype, arg0));
6577           return fold_convert (ftype,
6578                                build_function_call_expr (decl, arglist));
6579         }
6580     }
6581   return 0;
6582 }
6583
6584 /* EXP is assumed to be builtin call which can narrow the FP type of
6585    the argument, for instance lround((double)f) -> lroundf (f).  */
6586
6587 static tree
6588 fold_fixed_mathfn (tree fndecl, tree arglist)
6589 {
6590   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
6591   tree arg;
6592
6593   if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6594     return 0;
6595
6596   arg = TREE_VALUE (arglist);
6597
6598   /* If argument is already integer valued, and we don't need to worry
6599      about setting errno, there's no need to perform rounding.  */
6600   if (! flag_errno_math && integer_valued_real_p (arg))
6601     return fold (build1 (FIX_TRUNC_EXPR, TREE_TYPE (TREE_TYPE (fndecl)), arg));
6602
6603   if (optimize)
6604     {
6605       tree ftype = TREE_TYPE (arg);
6606       tree arg0 = strip_float_extensions (arg);
6607       tree newtype = TREE_TYPE (arg0);
6608       tree decl;
6609
6610       if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
6611           && (decl = mathfn_built_in (newtype, fcode)))
6612         {
6613           arglist =
6614             build_tree_list (NULL_TREE, fold_convert (newtype, arg0));
6615           return build_function_call_expr (decl, arglist);
6616         }
6617     }
6618   return 0;
6619 }
6620
6621 /* Fold function call to builtin cabs, cabsf or cabsl.  ARGLIST
6622    is the argument list and TYPE is the return type.  Return
6623    NULL_TREE if no if no simplification can be made.  */
6624
6625 static tree
6626 fold_builtin_cabs (tree arglist, tree type)
6627 {
6628   tree arg;
6629
6630   if (!arglist || TREE_CHAIN (arglist))
6631     return NULL_TREE;
6632
6633   arg = TREE_VALUE (arglist);
6634   if (TREE_CODE (TREE_TYPE (arg)) != COMPLEX_TYPE
6635       || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) != REAL_TYPE)
6636     return NULL_TREE;
6637
6638   /* Evaluate cabs of a constant at compile-time.  */
6639   if (flag_unsafe_math_optimizations
6640       && TREE_CODE (arg) == COMPLEX_CST
6641       && TREE_CODE (TREE_REALPART (arg)) == REAL_CST
6642       && TREE_CODE (TREE_IMAGPART (arg)) == REAL_CST
6643       && ! TREE_CONSTANT_OVERFLOW (TREE_REALPART (arg))
6644       && ! TREE_CONSTANT_OVERFLOW (TREE_IMAGPART (arg)))
6645     {
6646       REAL_VALUE_TYPE r, i;
6647
6648       r = TREE_REAL_CST (TREE_REALPART (arg));
6649       i = TREE_REAL_CST (TREE_IMAGPART (arg));
6650
6651       real_arithmetic (&r, MULT_EXPR, &r, &r);
6652       real_arithmetic (&i, MULT_EXPR, &i, &i);
6653       real_arithmetic (&r, PLUS_EXPR, &r, &i);
6654       if (real_sqrt (&r, TYPE_MODE (type), &r)
6655           || ! flag_trapping_math)
6656         return build_real (type, r);
6657     }
6658
6659   /* If either part is zero, cabs is fabs of the other.  */
6660   if (TREE_CODE (arg) == COMPLEX_EXPR
6661       && real_zerop (TREE_OPERAND (arg, 0)))
6662     return fold (build1 (ABS_EXPR, type, TREE_OPERAND (arg, 1)));
6663   if (TREE_CODE (arg) == COMPLEX_EXPR
6664       && real_zerop (TREE_OPERAND (arg, 1)))
6665     return fold (build1 (ABS_EXPR, type, TREE_OPERAND (arg, 0)));
6666
6667   /* Don't do this when optimizing for size.  */
6668   if (flag_unsafe_math_optimizations
6669       && optimize && !optimize_size)
6670     {
6671       tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
6672
6673       if (sqrtfn != NULL_TREE)
6674         {
6675           tree rpart, ipart, result, arglist;
6676
6677           arg = builtin_save_expr (arg);
6678
6679           rpart = fold (build1 (REALPART_EXPR, type, arg));
6680           ipart = fold (build1 (IMAGPART_EXPR, type, arg));
6681
6682           rpart = builtin_save_expr (rpart);
6683           ipart = builtin_save_expr (ipart);
6684
6685           result = fold (build2 (PLUS_EXPR, type,
6686                                  fold (build2 (MULT_EXPR, type,
6687                                                rpart, rpart)),
6688                                  fold (build2 (MULT_EXPR, type,
6689                                                ipart, ipart))));
6690
6691           arglist = build_tree_list (NULL_TREE, result);
6692           return build_function_call_expr (sqrtfn, arglist);
6693         }
6694     }
6695
6696   return NULL_TREE;
6697 }
6698
6699 /* Fold a builtin function call to sqrt, sqrtf, or sqrtl.  Return
6700    NULL_TREE if no simplification can be made.  */
6701
6702 static tree
6703 fold_builtin_sqrt (tree arglist, tree type)
6704 {
6705
6706   enum built_in_function fcode;
6707   tree arg = TREE_VALUE (arglist);
6708
6709   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6710     return NULL_TREE;
6711
6712   /* Optimize sqrt of constant value.  */
6713   if (TREE_CODE (arg) == REAL_CST
6714       && ! TREE_CONSTANT_OVERFLOW (arg))
6715     {
6716       REAL_VALUE_TYPE r, x;
6717
6718       x = TREE_REAL_CST (arg);
6719       if (real_sqrt (&r, TYPE_MODE (type), &x)
6720           || (!flag_trapping_math && !flag_errno_math))
6721         return build_real (type, r);
6722     }
6723
6724   /* Optimize sqrt(expN(x)) = expN(x*0.5).  */
6725   fcode = builtin_mathfn_code (arg);
6726   if (flag_unsafe_math_optimizations && BUILTIN_EXPONENT_P (fcode))
6727     {
6728       tree expfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
6729       arg = fold (build2 (MULT_EXPR, type,
6730                           TREE_VALUE (TREE_OPERAND (arg, 1)),
6731                           build_real (type, dconsthalf)));
6732       arglist = build_tree_list (NULL_TREE, arg);
6733       return build_function_call_expr (expfn, arglist);
6734     }
6735
6736   /* Optimize sqrt(Nroot(x)) -> pow(x,1/(2*N)).  */
6737   if (flag_unsafe_math_optimizations && BUILTIN_ROOT_P (fcode))
6738     {
6739       tree powfn = mathfn_built_in (type, BUILT_IN_POW);
6740
6741       if (powfn)
6742         {
6743           tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
6744           tree tree_root;
6745           /* The inner root was either sqrt or cbrt.  */
6746           REAL_VALUE_TYPE dconstroot =
6747             BUILTIN_SQRT_P (fcode) ? dconsthalf : dconstthird;
6748
6749           /* Adjust for the outer root.  */
6750           SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
6751           dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
6752           tree_root = build_real (type, dconstroot);
6753           arglist = tree_cons (NULL_TREE, arg0,
6754                                build_tree_list (NULL_TREE, tree_root));
6755           return build_function_call_expr (powfn, arglist);
6756         }
6757     }
6758
6759   /* Optimize sqrt(pow(x,y)) = pow(|x|,y*0.5).  */
6760   if (flag_unsafe_math_optimizations
6761       && (fcode == BUILT_IN_POW
6762           || fcode == BUILT_IN_POWF
6763           || fcode == BUILT_IN_POWL))
6764     {
6765       tree powfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
6766       tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
6767       tree arg1 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
6768       tree narg1;
6769       if (!tree_expr_nonnegative_p (arg0))
6770         arg0 = build1 (ABS_EXPR, type, arg0);
6771       narg1 = fold (build2 (MULT_EXPR, type, arg1,
6772                             build_real (type, dconsthalf)));
6773       arglist = tree_cons (NULL_TREE, arg0,
6774                            build_tree_list (NULL_TREE, narg1));
6775       return build_function_call_expr (powfn, arglist);
6776     }
6777
6778   return NULL_TREE;
6779 }
6780
6781 /* Fold a builtin function call to cbrt, cbrtf, or cbrtl.  Return
6782    NULL_TREE if no simplification can be made.  */
6783 static tree
6784 fold_builtin_cbrt (tree arglist, tree type)
6785 {
6786   tree arg = TREE_VALUE (arglist);
6787   const enum built_in_function fcode = builtin_mathfn_code (arg);
6788
6789   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6790     return NULL_TREE;
6791
6792   /* Optimize cbrt of constant value.  */
6793   if (real_zerop (arg) || real_onep (arg) || real_minus_onep (arg))
6794     return arg;
6795
6796   if (flag_unsafe_math_optimizations)
6797     {
6798       /* Optimize cbrt(expN(x)) -> expN(x/3).  */
6799       if (BUILTIN_EXPONENT_P (fcode))
6800         {
6801           tree expfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
6802           const REAL_VALUE_TYPE third_trunc =
6803             real_value_truncate (TYPE_MODE (type), dconstthird);
6804           arg = fold (build2 (MULT_EXPR, type,
6805                               TREE_VALUE (TREE_OPERAND (arg, 1)),
6806                               build_real (type, third_trunc)));
6807           arglist = build_tree_list (NULL_TREE, arg);
6808           return build_function_call_expr (expfn, arglist);
6809         }
6810
6811       /* Optimize cbrt(sqrt(x)) -> pow(x,1/6).  */
6812       if (BUILTIN_SQRT_P (fcode))
6813         {
6814           tree powfn = mathfn_built_in (type, BUILT_IN_POW);
6815
6816           if (powfn)
6817             {
6818               tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
6819               tree tree_root;
6820               REAL_VALUE_TYPE dconstroot = dconstthird;
6821
6822               SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
6823               dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
6824               tree_root = build_real (type, dconstroot);
6825               arglist = tree_cons (NULL_TREE, arg0,
6826                                    build_tree_list (NULL_TREE, tree_root));
6827               return build_function_call_expr (powfn, arglist);
6828             }
6829         }
6830
6831       /* Optimize cbrt(cbrt(x)) -> pow(x,1/9) iff x is nonnegative.  */
6832       if (BUILTIN_CBRT_P (fcode))
6833         {
6834           tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
6835           if (tree_expr_nonnegative_p (arg0))
6836             {
6837               tree powfn = mathfn_built_in (type, BUILT_IN_POW);
6838
6839               if (powfn)
6840                 {
6841                   tree tree_root;
6842                   REAL_VALUE_TYPE dconstroot;
6843               
6844                   real_arithmetic (&dconstroot, MULT_EXPR, &dconstthird, &dconstthird);
6845                   dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
6846                   tree_root = build_real (type, dconstroot);
6847                   arglist = tree_cons (NULL_TREE, arg0,
6848                                        build_tree_list (NULL_TREE, tree_root));
6849                   return build_function_call_expr (powfn, arglist);
6850                 }
6851             }
6852         }
6853       
6854       /* Optimize cbrt(pow(x,y)) -> pow(x,y/3) iff x is nonnegative.  */
6855       if (fcode == BUILT_IN_POW || fcode == BUILT_IN_POWF
6856           || fcode == BUILT_IN_POWL)
6857         {
6858           tree arg00 = TREE_VALUE (TREE_OPERAND (arg, 1));
6859           tree arg01 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
6860           if (tree_expr_nonnegative_p (arg00))
6861             {
6862               tree powfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
6863               const REAL_VALUE_TYPE dconstroot
6864                 = real_value_truncate (TYPE_MODE (type), dconstthird);
6865               tree narg01 = fold (build2 (MULT_EXPR, type, arg01,
6866                                           build_real (type, dconstroot)));
6867               arglist = tree_cons (NULL_TREE, arg00,
6868                                    build_tree_list (NULL_TREE, narg01));
6869               return build_function_call_expr (powfn, arglist);
6870             }
6871         }
6872     }
6873   return NULL_TREE;
6874 }
6875
6876 /* Fold function call to builtin sin, sinf, or sinl.  Return
6877    NULL_TREE if no simplification can be made.  */
6878 static tree
6879 fold_builtin_sin (tree arglist)
6880 {
6881   tree arg = TREE_VALUE (arglist);
6882
6883   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6884     return NULL_TREE;
6885
6886   /* Optimize sin (0.0) = 0.0.  */
6887   if (real_zerop (arg))
6888     return arg;
6889
6890   return NULL_TREE;
6891 }
6892
6893 /* Fold function call to builtin cos, cosf, or cosl.  Return
6894    NULL_TREE if no simplification can be made.  */
6895 static tree
6896 fold_builtin_cos (tree arglist, tree type, tree fndecl)
6897 {
6898   tree arg = TREE_VALUE (arglist);
6899
6900   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6901     return NULL_TREE;
6902
6903   /* Optimize cos (0.0) = 1.0.  */
6904   if (real_zerop (arg))
6905     return build_real (type, dconst1);
6906
6907   /* Optimize cos(-x) into cos (x).  */
6908   if (TREE_CODE (arg) == NEGATE_EXPR)
6909     {
6910       tree args = build_tree_list (NULL_TREE,
6911                                    TREE_OPERAND (arg, 0));
6912       return build_function_call_expr (fndecl, args);
6913     }
6914
6915   return NULL_TREE;
6916 }
6917
6918 /* Fold function call to builtin tan, tanf, or tanl.  Return
6919    NULL_TREE if no simplification can be made.  */
6920 static tree
6921 fold_builtin_tan (tree arglist)
6922 {
6923   enum built_in_function fcode;
6924   tree arg = TREE_VALUE (arglist);
6925
6926   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6927     return NULL_TREE;
6928
6929   /* Optimize tan(0.0) = 0.0.  */
6930   if (real_zerop (arg))
6931     return arg;
6932
6933   /* Optimize tan(atan(x)) = x.  */
6934   fcode = builtin_mathfn_code (arg);
6935   if (flag_unsafe_math_optimizations
6936       && (fcode == BUILT_IN_ATAN
6937           || fcode == BUILT_IN_ATANF
6938           || fcode == BUILT_IN_ATANL))
6939     return TREE_VALUE (TREE_OPERAND (arg, 1));
6940
6941   return NULL_TREE;
6942 }
6943
6944 /* Fold function call to builtin atan, atanf, or atanl.  Return
6945    NULL_TREE if no simplification can be made.  */
6946
6947 static tree
6948 fold_builtin_atan (tree arglist, tree type)
6949 {
6950
6951   tree arg = TREE_VALUE (arglist);
6952
6953   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6954     return NULL_TREE;
6955
6956   /* Optimize atan(0.0) = 0.0.  */
6957   if (real_zerop (arg))
6958     return arg;
6959
6960   /* Optimize atan(1.0) = pi/4.  */
6961   if (real_onep (arg))
6962     {
6963       REAL_VALUE_TYPE cst;
6964
6965       real_convert (&cst, TYPE_MODE (type), &dconstpi);
6966       SET_REAL_EXP (&cst, REAL_EXP (&cst) - 2);
6967       return build_real (type, cst);
6968     }
6969
6970   return NULL_TREE;
6971 }
6972
6973 /* Fold function call to builtin trunc, truncf or truncl.  Return
6974    NULL_TREE if no simplification can be made.  */
6975
6976 static tree
6977 fold_builtin_trunc (tree fndecl, tree arglist)
6978 {
6979   tree arg;
6980
6981   if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6982     return 0;
6983
6984   /* Optimize trunc of constant value.  */
6985   arg = TREE_VALUE (arglist);
6986   if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
6987     {
6988       REAL_VALUE_TYPE r, x;
6989       tree type = TREE_TYPE (TREE_TYPE (fndecl));
6990
6991       x = TREE_REAL_CST (arg);
6992       real_trunc (&r, TYPE_MODE (type), &x);
6993       return build_real (type, r);
6994     }
6995
6996   return fold_trunc_transparent_mathfn (fndecl, arglist);
6997 }
6998
6999 /* Fold function call to builtin floor, floorf or floorl.  Return
7000    NULL_TREE if no simplification can be made.  */
7001
7002 static tree
7003 fold_builtin_floor (tree fndecl, tree arglist)
7004 {
7005   tree arg;
7006
7007   if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7008     return 0;
7009
7010   /* Optimize floor of constant value.  */
7011   arg = TREE_VALUE (arglist);
7012   if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7013     {
7014       REAL_VALUE_TYPE x;
7015
7016       x = TREE_REAL_CST (arg);
7017       if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7018         {
7019           tree type = TREE_TYPE (TREE_TYPE (fndecl));
7020           REAL_VALUE_TYPE r;
7021
7022           real_floor (&r, TYPE_MODE (type), &x);
7023           return build_real (type, r);
7024         }
7025     }
7026
7027   return fold_trunc_transparent_mathfn (fndecl, arglist);
7028 }
7029
7030 /* Fold function call to builtin ceil, ceilf or ceill.  Return
7031    NULL_TREE if no simplification can be made.  */
7032
7033 static tree
7034 fold_builtin_ceil (tree fndecl, tree arglist)
7035 {
7036   tree arg;
7037
7038   if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7039     return 0;
7040
7041   /* Optimize ceil of constant value.  */
7042   arg = TREE_VALUE (arglist);
7043   if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7044     {
7045       REAL_VALUE_TYPE x;
7046
7047       x = TREE_REAL_CST (arg);
7048       if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7049         {
7050           tree type = TREE_TYPE (TREE_TYPE (fndecl));
7051           REAL_VALUE_TYPE r;
7052
7053           real_ceil (&r, TYPE_MODE (type), &x);
7054           return build_real (type, r);
7055         }
7056     }
7057
7058   return fold_trunc_transparent_mathfn (fndecl, arglist);
7059 }
7060
7061 /* Fold function call to builtin round, roundf or roundl.  Return
7062    NULL_TREE if no simplification can be made.  */
7063
7064 static tree
7065 fold_builtin_round (tree fndecl, tree arglist)
7066 {
7067   tree arg;
7068
7069   if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7070     return 0;
7071
7072   /* Optimize round of constant value.  */
7073   arg = TREE_VALUE (arglist);
7074   if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7075     {
7076       REAL_VALUE_TYPE x;
7077
7078       x = TREE_REAL_CST (arg);
7079       if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7080         {
7081           tree type = TREE_TYPE (TREE_TYPE (fndecl));
7082           REAL_VALUE_TYPE r;
7083
7084           real_round (&r, TYPE_MODE (type), &x);
7085           return build_real (type, r);
7086         }
7087     }
7088
7089   return fold_trunc_transparent_mathfn (fndecl, arglist);
7090 }
7091
7092 /* Fold function call to builtin lround, lroundf or lroundl (or the
7093    corresponding long long versions) and other rounding functions.
7094    Return NULL_TREE if no simplification can be made.  */
7095
7096 static tree
7097 fold_builtin_int_roundingfn (tree fndecl, tree arglist)
7098 {
7099   tree arg;
7100
7101   if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7102     return 0;
7103
7104   /* Optimize lround of constant value.  */
7105   arg = TREE_VALUE (arglist);
7106   if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7107     {
7108       const REAL_VALUE_TYPE x = TREE_REAL_CST (arg);
7109
7110       if (! REAL_VALUE_ISNAN (x) && ! REAL_VALUE_ISINF (x))
7111         {
7112           tree itype = TREE_TYPE (TREE_TYPE (fndecl));
7113           tree ftype = TREE_TYPE (arg), result;
7114           HOST_WIDE_INT hi, lo;
7115           REAL_VALUE_TYPE r;
7116
7117           switch (DECL_FUNCTION_CODE (fndecl))
7118             {
7119             case BUILT_IN_LFLOOR:
7120             case BUILT_IN_LFLOORF:
7121             case BUILT_IN_LFLOORL:
7122             case BUILT_IN_LLFLOOR:
7123             case BUILT_IN_LLFLOORF:
7124             case BUILT_IN_LLFLOORL:
7125               real_floor (&r, TYPE_MODE (ftype), &x);
7126               break;
7127
7128             case BUILT_IN_LCEIL:
7129             case BUILT_IN_LCEILF:
7130             case BUILT_IN_LCEILL:
7131             case BUILT_IN_LLCEIL:
7132             case BUILT_IN_LLCEILF:
7133             case BUILT_IN_LLCEILL:
7134               real_ceil (&r, TYPE_MODE (ftype), &x);
7135               break;
7136
7137             case BUILT_IN_LROUND:
7138             case BUILT_IN_LROUNDF:
7139             case BUILT_IN_LROUNDL:
7140             case BUILT_IN_LLROUND:
7141             case BUILT_IN_LLROUNDF:
7142             case BUILT_IN_LLROUNDL:
7143               real_round (&r, TYPE_MODE (ftype), &x);
7144               break;
7145
7146             default:
7147               gcc_unreachable ();
7148             }
7149
7150           REAL_VALUE_TO_INT (&lo, &hi, r);
7151           result = build_int_cst_wide (NULL_TREE, lo, hi);
7152           if (int_fits_type_p (result, itype))
7153             return fold_convert (itype, result);
7154         }
7155     }
7156
7157   return fold_fixed_mathfn (fndecl, arglist);
7158 }
7159
7160 /* Fold function call to builtin ffs, clz, ctz, popcount and parity
7161    and their long and long long variants (i.e. ffsl and ffsll).
7162    Return NULL_TREE if no simplification can be made.  */
7163
7164 static tree
7165 fold_builtin_bitop (tree fndecl, tree arglist)
7166 {
7167   tree arg;
7168
7169   if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
7170     return NULL_TREE;
7171
7172   /* Optimize for constant argument.  */
7173   arg = TREE_VALUE (arglist);
7174   if (TREE_CODE (arg) == INTEGER_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7175     {
7176       HOST_WIDE_INT hi, width, result;
7177       unsigned HOST_WIDE_INT lo;
7178       tree type;
7179
7180       type = TREE_TYPE (arg);
7181       width = TYPE_PRECISION (type);
7182       lo = TREE_INT_CST_LOW (arg);
7183
7184       /* Clear all the bits that are beyond the type's precision.  */
7185       if (width > HOST_BITS_PER_WIDE_INT)
7186         {
7187           hi = TREE_INT_CST_HIGH (arg);
7188           if (width < 2 * HOST_BITS_PER_WIDE_INT)
7189             hi &= ~((HOST_WIDE_INT) (-1) >> (width - HOST_BITS_PER_WIDE_INT));
7190         }
7191       else
7192         {
7193           hi = 0;
7194           if (width < HOST_BITS_PER_WIDE_INT)
7195             lo &= ~((unsigned HOST_WIDE_INT) (-1) << width);
7196         }
7197
7198       switch (DECL_FUNCTION_CODE (fndecl))
7199         {
7200         case BUILT_IN_FFS:
7201         case BUILT_IN_FFSL:
7202         case BUILT_IN_FFSLL:
7203           if (lo != 0)
7204             result = exact_log2 (lo & -lo) + 1;
7205           else if (hi != 0)
7206             result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi) + 1;
7207           else
7208             result = 0;
7209           break;
7210
7211         case BUILT_IN_CLZ:
7212         case BUILT_IN_CLZL:
7213         case BUILT_IN_CLZLL:
7214           if (hi != 0)
7215             result = width - floor_log2 (hi) - 1 - HOST_BITS_PER_WIDE_INT;
7216           else if (lo != 0)
7217             result = width - floor_log2 (lo) - 1;
7218           else if (! CLZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
7219             result = width;
7220           break;
7221
7222         case BUILT_IN_CTZ:
7223         case BUILT_IN_CTZL:
7224         case BUILT_IN_CTZLL:
7225           if (lo != 0)
7226             result = exact_log2 (lo & -lo);
7227           else if (hi != 0)
7228             result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi);
7229           else if (! CTZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
7230             result = width;
7231           break;
7232
7233         case BUILT_IN_POPCOUNT:
7234         case BUILT_IN_POPCOUNTL:
7235         case BUILT_IN_POPCOUNTLL:
7236           result = 0;
7237           while (lo)
7238             result++, lo &= lo - 1;
7239           while (hi)
7240             result++, hi &= hi - 1;
7241           break;
7242
7243         case BUILT_IN_PARITY:
7244         case BUILT_IN_PARITYL:
7245         case BUILT_IN_PARITYLL:
7246           result = 0;
7247           while (lo)
7248             result++, lo &= lo - 1;
7249           while (hi)
7250             result++, hi &= hi - 1;
7251           result &= 1;
7252           break;
7253
7254         default:
7255           gcc_unreachable ();
7256         }
7257
7258       return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), result);
7259     }
7260
7261   return NULL_TREE;
7262 }
7263
7264 /* Return true if EXPR is the real constant contained in VALUE.  */
7265
7266 static bool
7267 real_dconstp (tree expr, const REAL_VALUE_TYPE *value)
7268 {
7269   STRIP_NOPS (expr);
7270
7271   return ((TREE_CODE (expr) == REAL_CST
7272            && ! TREE_CONSTANT_OVERFLOW (expr)
7273            && REAL_VALUES_EQUAL (TREE_REAL_CST (expr), *value))
7274           || (TREE_CODE (expr) == COMPLEX_CST
7275               && real_dconstp (TREE_REALPART (expr), value)
7276               && real_zerop (TREE_IMAGPART (expr))));
7277 }
7278
7279 /* A subroutine of fold_builtin to fold the various logarithmic
7280    functions.  EXP is the CALL_EXPR of a call to a builtin logN
7281    function.  VALUE is the base of the logN function.  */
7282
7283 static tree
7284 fold_builtin_logarithm (tree fndecl, tree arglist,
7285                         const REAL_VALUE_TYPE *value)
7286 {
7287   if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7288     {
7289       tree type = TREE_TYPE (TREE_TYPE (fndecl));
7290       tree arg = TREE_VALUE (arglist);
7291       const enum built_in_function fcode = builtin_mathfn_code (arg);
7292
7293       /* Optimize logN(1.0) = 0.0.  */
7294       if (real_onep (arg))
7295         return build_real (type, dconst0);
7296
7297       /* Optimize logN(N) = 1.0.  If N can't be truncated to MODE
7298          exactly, then only do this if flag_unsafe_math_optimizations.  */
7299       if (exact_real_truncate (TYPE_MODE (type), value)
7300           || flag_unsafe_math_optimizations)
7301         {
7302           const REAL_VALUE_TYPE value_truncate =
7303             real_value_truncate (TYPE_MODE (type), *value);
7304           if (real_dconstp (arg, &value_truncate))
7305             return build_real (type, dconst1);
7306         }
7307
7308       /* Special case, optimize logN(expN(x)) = x.  */
7309       if (flag_unsafe_math_optimizations
7310           && ((value == &dconste
7311                && (fcode == BUILT_IN_EXP
7312                    || fcode == BUILT_IN_EXPF
7313                    || fcode == BUILT_IN_EXPL))
7314               || (value == &dconst2
7315                   && (fcode == BUILT_IN_EXP2
7316                       || fcode == BUILT_IN_EXP2F
7317                       || fcode == BUILT_IN_EXP2L))
7318               || (value == &dconst10 && (BUILTIN_EXP10_P (fcode)))))
7319         return fold_convert (type, TREE_VALUE (TREE_OPERAND (arg, 1)));
7320
7321       /* Optimize logN(func()) for various exponential functions.  We
7322          want to determine the value "x" and the power "exponent" in
7323          order to transform logN(x**exponent) into exponent*logN(x).  */
7324       if (flag_unsafe_math_optimizations)
7325         {
7326           tree exponent = 0, x = 0;
7327
7328           switch (fcode)
7329           {
7330           case BUILT_IN_EXP:
7331           case BUILT_IN_EXPF:
7332           case BUILT_IN_EXPL:
7333             /* Prepare to do logN(exp(exponent) -> exponent*logN(e).  */
7334             x = build_real (type,
7335                             real_value_truncate (TYPE_MODE (type), dconste));
7336             exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
7337             break;
7338           case BUILT_IN_EXP2:
7339           case BUILT_IN_EXP2F:
7340           case BUILT_IN_EXP2L:
7341             /* Prepare to do logN(exp2(exponent) -> exponent*logN(2).  */
7342             x = build_real (type, dconst2);
7343             exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
7344             break;
7345           case BUILT_IN_EXP10:
7346           case BUILT_IN_EXP10F:
7347           case BUILT_IN_EXP10L:
7348           case BUILT_IN_POW10:
7349           case BUILT_IN_POW10F:
7350           case BUILT_IN_POW10L:
7351             /* Prepare to do logN(exp10(exponent) -> exponent*logN(10).  */
7352             x = build_real (type, dconst10);
7353             exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
7354             break;
7355           case BUILT_IN_SQRT:
7356           case BUILT_IN_SQRTF:
7357           case BUILT_IN_SQRTL:
7358             /* Prepare to do logN(sqrt(x) -> 0.5*logN(x).  */
7359             x = TREE_VALUE (TREE_OPERAND (arg, 1));
7360             exponent = build_real (type, dconsthalf);
7361             break;
7362           case BUILT_IN_CBRT:
7363           case BUILT_IN_CBRTF:
7364           case BUILT_IN_CBRTL:
7365             /* Prepare to do logN(cbrt(x) -> (1/3)*logN(x).  */
7366             x = TREE_VALUE (TREE_OPERAND (arg, 1));
7367             exponent = build_real (type, real_value_truncate (TYPE_MODE (type),
7368                                                               dconstthird));
7369             break;
7370           case BUILT_IN_POW:
7371           case BUILT_IN_POWF:
7372           case BUILT_IN_POWL:
7373             /* Prepare to do logN(pow(x,exponent) -> exponent*logN(x).  */
7374             x = TREE_VALUE (TREE_OPERAND (arg, 1));
7375             exponent = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
7376             break;
7377           default:
7378             break;
7379           }
7380
7381           /* Now perform the optimization.  */
7382           if (x && exponent)
7383             {
7384               tree logfn;
7385               arglist = build_tree_list (NULL_TREE, x);
7386               logfn = build_function_call_expr (fndecl, arglist);
7387               return fold (build2 (MULT_EXPR, type, exponent, logfn));
7388             }
7389         }
7390     }
7391
7392   return 0;
7393 }
7394
7395 /* Fold a builtin function call to pow, powf, or powl.  Return
7396    NULL_TREE if no simplification can be made.  */
7397 static tree
7398 fold_builtin_pow (tree fndecl, tree arglist, tree type)
7399 {
7400   tree arg0 = TREE_VALUE (arglist);
7401   tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7402
7403   if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
7404     return NULL_TREE;
7405
7406   /* Optimize pow(1.0,y) = 1.0.  */
7407   if (real_onep (arg0))
7408     return omit_one_operand (type, build_real (type, dconst1), arg1);
7409
7410   if (TREE_CODE (arg1) == REAL_CST
7411       && ! TREE_CONSTANT_OVERFLOW (arg1))
7412     {
7413       REAL_VALUE_TYPE cint;
7414       REAL_VALUE_TYPE c;
7415       HOST_WIDE_INT n;
7416
7417       c = TREE_REAL_CST (arg1);
7418
7419       /* Optimize pow(x,0.0) = 1.0.  */
7420       if (REAL_VALUES_EQUAL (c, dconst0))
7421         return omit_one_operand (type, build_real (type, dconst1),
7422                                  arg0);
7423
7424       /* Optimize pow(x,1.0) = x.  */
7425       if (REAL_VALUES_EQUAL (c, dconst1))
7426         return arg0;
7427
7428       /* Optimize pow(x,-1.0) = 1.0/x.  */
7429       if (REAL_VALUES_EQUAL (c, dconstm1))
7430         return fold (build2 (RDIV_EXPR, type,
7431                              build_real (type, dconst1), arg0));
7432
7433       /* Optimize pow(x,0.5) = sqrt(x).  */
7434       if (flag_unsafe_math_optimizations
7435           && REAL_VALUES_EQUAL (c, dconsthalf))
7436         {
7437           tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
7438
7439           if (sqrtfn != NULL_TREE)
7440             {
7441               tree arglist = build_tree_list (NULL_TREE, arg0);
7442               return build_function_call_expr (sqrtfn, arglist);
7443             }
7444         }
7445
7446       /* Check for an integer exponent.  */
7447       n = real_to_integer (&c);
7448       real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
7449       if (real_identical (&c, &cint))
7450         {
7451           /* Attempt to evaluate pow at compile-time.  */
7452           if (TREE_CODE (arg0) == REAL_CST
7453               && ! TREE_CONSTANT_OVERFLOW (arg0))
7454             {
7455               REAL_VALUE_TYPE x;
7456               bool inexact;
7457
7458               x = TREE_REAL_CST (arg0);
7459               inexact = real_powi (&x, TYPE_MODE (type), &x, n);
7460               if (flag_unsafe_math_optimizations || !inexact)
7461                 return build_real (type, x);
7462             }
7463
7464           /* Strip sign ops from even integer powers.  */
7465           if ((n & 1) == 0 && flag_unsafe_math_optimizations)
7466             {
7467               tree narg0 = fold_strip_sign_ops (arg0);
7468               if (narg0)
7469                 {
7470                   arglist = build_tree_list (NULL_TREE, arg1);
7471                   arglist = tree_cons (NULL_TREE, narg0, arglist);
7472                   return build_function_call_expr (fndecl, arglist);
7473                 }
7474             }
7475         }
7476     }
7477
7478   if (flag_unsafe_math_optimizations)
7479     {
7480       const enum built_in_function fcode = builtin_mathfn_code (arg0);
7481
7482       /* Optimize pow(expN(x),y) = expN(x*y).  */
7483       if (BUILTIN_EXPONENT_P (fcode))
7484         {
7485           tree expfn = TREE_OPERAND (TREE_OPERAND (arg0, 0), 0);
7486           tree arg = TREE_VALUE (TREE_OPERAND (arg0, 1));
7487           arg = fold (build2 (MULT_EXPR, type, arg, arg1));
7488           arglist = build_tree_list (NULL_TREE, arg);
7489           return build_function_call_expr (expfn, arglist);
7490         }
7491
7492       /* Optimize pow(sqrt(x),y) = pow(x,y*0.5).  */
7493       if (BUILTIN_SQRT_P (fcode))
7494         {
7495           tree narg0 = TREE_VALUE (TREE_OPERAND (arg0, 1));
7496           tree narg1 = fold (build2 (MULT_EXPR, type, arg1,
7497                                      build_real (type, dconsthalf)));
7498
7499           arglist = tree_cons (NULL_TREE, narg0,
7500                                build_tree_list (NULL_TREE, narg1));
7501           return build_function_call_expr (fndecl, arglist);
7502         }
7503
7504       /* Optimize pow(cbrt(x),y) = pow(x,y/3) iff x is nonnegative.  */
7505       if (BUILTIN_CBRT_P (fcode))
7506         {
7507           tree arg = TREE_VALUE (TREE_OPERAND (arg0, 1));
7508           if (tree_expr_nonnegative_p (arg))
7509             {
7510               const REAL_VALUE_TYPE dconstroot
7511                 = real_value_truncate (TYPE_MODE (type), dconstthird);
7512               tree narg1 = fold (build2 (MULT_EXPR, type, arg1,
7513                                          build_real (type, dconstroot)));
7514               arglist = tree_cons (NULL_TREE, arg,
7515                                    build_tree_list (NULL_TREE, narg1));
7516               return build_function_call_expr (fndecl, arglist);
7517             }
7518         }
7519       
7520       /* Optimize pow(pow(x,y),z) = pow(x,y*z).  */
7521       if (fcode == BUILT_IN_POW || fcode == BUILT_IN_POWF
7522            || fcode == BUILT_IN_POWL)
7523         {
7524           tree arg00 = TREE_VALUE (TREE_OPERAND (arg0, 1));
7525           tree arg01 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg0, 1)));
7526           tree narg1 = fold (build2 (MULT_EXPR, type, arg01, arg1));
7527           arglist = tree_cons (NULL_TREE, arg00,
7528                                build_tree_list (NULL_TREE, narg1));
7529           return build_function_call_expr (fndecl, arglist);
7530         }
7531     }
7532
7533   return NULL_TREE;
7534 }
7535
7536 /* Fold a builtin function call to powi, powif, or powil.  Return
7537    NULL_TREE if no simplification can be made.  */
7538 static tree
7539 fold_builtin_powi (tree fndecl ATTRIBUTE_UNUSED, tree arglist, tree type)
7540 {
7541   tree arg0 = TREE_VALUE (arglist);
7542   tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7543
7544   if (!validate_arglist (arglist, REAL_TYPE, INTEGER_TYPE, VOID_TYPE))
7545     return NULL_TREE;
7546
7547   /* Optimize pow(1.0,y) = 1.0.  */
7548   if (real_onep (arg0))
7549     return omit_one_operand (type, build_real (type, dconst1), arg1);
7550
7551   if (host_integerp (arg1, 0))
7552     {
7553       HOST_WIDE_INT c = TREE_INT_CST_LOW (arg1);
7554
7555       /* Evaluate powi at compile-time.  */
7556       if (TREE_CODE (arg0) == REAL_CST
7557           && ! TREE_CONSTANT_OVERFLOW (arg0))
7558         {
7559           REAL_VALUE_TYPE x;
7560           x = TREE_REAL_CST (arg0);
7561           real_powi (&x, TYPE_MODE (type), &x, c);
7562           return build_real (type, x);
7563         }
7564
7565       /* Optimize pow(x,0) = 1.0.  */
7566       if (c == 0)
7567         return omit_one_operand (type, build_real (type, dconst1),
7568                                  arg0);
7569
7570       /* Optimize pow(x,1) = x.  */
7571       if (c == 1)
7572         return arg0;
7573
7574       /* Optimize pow(x,-1) = 1.0/x.  */
7575       if (c == -1)
7576         return fold (build2 (RDIV_EXPR, type,
7577                              build_real (type, dconst1), arg0));
7578     }
7579
7580   return NULL_TREE;
7581 }
7582
7583 /* A subroutine of fold_builtin to fold the various exponent
7584    functions.  EXP is the CALL_EXPR of a call to a builtin function.
7585    VALUE is the value which will be raised to a power.  */
7586
7587 static tree
7588 fold_builtin_exponent (tree fndecl, tree arglist,
7589                        const REAL_VALUE_TYPE *value)
7590 {
7591   if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7592     {
7593       tree type = TREE_TYPE (TREE_TYPE (fndecl));
7594       tree arg = TREE_VALUE (arglist);
7595
7596       /* Optimize exp*(0.0) = 1.0.  */
7597       if (real_zerop (arg))
7598         return build_real (type, dconst1);
7599
7600       /* Optimize expN(1.0) = N.  */
7601       if (real_onep (arg))
7602         {
7603           REAL_VALUE_TYPE cst;
7604
7605           real_convert (&cst, TYPE_MODE (type), value);
7606           return build_real (type, cst);
7607         }
7608
7609       /* Attempt to evaluate expN(integer) at compile-time.  */
7610       if (flag_unsafe_math_optimizations
7611           && TREE_CODE (arg) == REAL_CST
7612           && ! TREE_CONSTANT_OVERFLOW (arg))
7613         {
7614           REAL_VALUE_TYPE cint;
7615           REAL_VALUE_TYPE c;
7616           HOST_WIDE_INT n;
7617
7618           c = TREE_REAL_CST (arg);
7619           n = real_to_integer (&c);
7620           real_from_integer (&cint, VOIDmode, n,
7621                              n < 0 ? -1 : 0, 0);
7622           if (real_identical (&c, &cint))
7623             {
7624               REAL_VALUE_TYPE x;
7625
7626               real_powi (&x, TYPE_MODE (type), value, n);
7627               return build_real (type, x);
7628             }
7629         }
7630
7631       /* Optimize expN(logN(x)) = x.  */
7632       if (flag_unsafe_math_optimizations)
7633         {
7634           const enum built_in_function fcode = builtin_mathfn_code (arg);
7635
7636           if ((value == &dconste
7637                && (fcode == BUILT_IN_LOG
7638                    || fcode == BUILT_IN_LOGF
7639                    || fcode == BUILT_IN_LOGL))
7640               || (value == &dconst2
7641                   && (fcode == BUILT_IN_LOG2
7642                       || fcode == BUILT_IN_LOG2F
7643                       || fcode == BUILT_IN_LOG2L))
7644               || (value == &dconst10
7645                   && (fcode == BUILT_IN_LOG10
7646                       || fcode == BUILT_IN_LOG10F
7647                       || fcode == BUILT_IN_LOG10L)))
7648             return fold_convert (type, TREE_VALUE (TREE_OPERAND (arg, 1)));
7649         }
7650     }
7651
7652   return 0;
7653 }
7654
7655 /* Fold function call to builtin memcpy.  Return
7656    NULL_TREE if no simplification can be made.  */
7657
7658 static tree
7659 fold_builtin_memcpy (tree fndecl, tree arglist)
7660 {
7661   tree dest, src, len;
7662
7663   if (!validate_arglist (arglist,
7664                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7665     return 0;
7666
7667   dest = TREE_VALUE (arglist);
7668   src = TREE_VALUE (TREE_CHAIN (arglist));
7669   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7670
7671   /* If the LEN parameter is zero, return DEST.  */
7672   if (integer_zerop (len))
7673     return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
7674
7675   /* If SRC and DEST are the same (and not volatile), return DEST.  */
7676   if (operand_equal_p (src, dest, 0))
7677     return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, len);
7678
7679   return 0;
7680 }
7681
7682 /* Fold function call to builtin mempcpy.  Return
7683    NULL_TREE if no simplification can be made.  */
7684
7685 static tree
7686 fold_builtin_mempcpy (tree arglist, tree type, int endp)
7687 {
7688   if (validate_arglist (arglist,
7689                         POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7690     {
7691       tree dest = TREE_VALUE (arglist);
7692       tree src = TREE_VALUE (TREE_CHAIN (arglist));
7693       tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7694
7695       /* If the LEN parameter is zero, return DEST.  */
7696       if (integer_zerop (len))
7697         return omit_one_operand (type, dest, src);
7698
7699       /* If SRC and DEST are the same (and not volatile), return DEST+LEN.  */
7700       if (operand_equal_p (src, dest, 0))
7701         {
7702           if (endp == 0)
7703             return omit_one_operand (type, dest, len);
7704
7705           if (endp == 2)
7706             len = fold (build2 (MINUS_EXPR, TREE_TYPE (len), len,
7707                                 ssize_int (1)));
7708       
7709           len = fold_convert (TREE_TYPE (dest), len);
7710           len = fold (build2 (PLUS_EXPR, TREE_TYPE (dest), dest, len));
7711           return fold_convert (type, len);
7712         }
7713     }
7714   return 0;
7715 }
7716
7717 /* Fold function call to builtin memmove.  Return
7718    NULL_TREE if no simplification can be made.  */
7719
7720 static tree
7721 fold_builtin_memmove (tree arglist, tree type)
7722 {
7723   tree dest, src, len;
7724
7725   if (!validate_arglist (arglist,
7726                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7727     return 0;
7728
7729   dest = TREE_VALUE (arglist);
7730   src = TREE_VALUE (TREE_CHAIN (arglist));
7731   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7732
7733   /* If the LEN parameter is zero, return DEST.  */
7734   if (integer_zerop (len))
7735     return omit_one_operand (type, dest, src);
7736
7737   /* If SRC and DEST are the same (and not volatile), return DEST.  */
7738   if (operand_equal_p (src, dest, 0))
7739     return omit_one_operand (type, dest, len);
7740
7741   return 0;
7742 }
7743
7744 /* Fold function call to builtin strcpy.  If LEN is not NULL, it represents
7745    the length of the string to be copied.  Return NULL_TREE if no
7746    simplification can be made.  */
7747
7748 tree
7749 fold_builtin_strcpy (tree fndecl, tree arglist, tree len)
7750 {
7751   tree dest, src, fn;
7752
7753   if (!validate_arglist (arglist,
7754                          POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
7755     return 0;
7756
7757   dest = TREE_VALUE (arglist);
7758   src = TREE_VALUE (TREE_CHAIN (arglist));
7759
7760   /* If SRC and DEST are the same (and not volatile), return DEST.  */
7761   if (operand_equal_p (src, dest, 0))
7762     return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), dest);
7763
7764   if (optimize_size)
7765     return 0;
7766
7767   fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
7768   if (!fn)
7769     return 0;
7770
7771   if (!len)
7772     {
7773       len = c_strlen (src, 1);
7774       if (! len || TREE_SIDE_EFFECTS (len))
7775         return 0;
7776     }
7777
7778   len = size_binop (PLUS_EXPR, len, ssize_int (1));
7779   arglist = build_tree_list (NULL_TREE, len);
7780   arglist = tree_cons (NULL_TREE, src, arglist);
7781   arglist = tree_cons (NULL_TREE, dest, arglist);
7782   return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)),
7783                        build_function_call_expr (fn, arglist));
7784 }
7785
7786 /* Fold function call to builtin strncpy.  If SLEN is not NULL, it represents
7787    the length of the source string.  Return NULL_TREE if no simplification
7788    can be made.  */
7789
7790 tree
7791 fold_builtin_strncpy (tree fndecl, tree arglist, tree slen)
7792 {
7793   tree dest, src, len, fn;
7794
7795   if (!validate_arglist (arglist,
7796                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7797     return 0;
7798
7799   dest = TREE_VALUE (arglist);
7800   src = TREE_VALUE (TREE_CHAIN (arglist));
7801   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7802
7803   /* If the LEN parameter is zero, return DEST.  */
7804   if (integer_zerop (len))
7805     return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
7806
7807   /* We can't compare slen with len as constants below if len is not a
7808      constant.  */
7809   if (len == 0 || TREE_CODE (len) != INTEGER_CST)
7810     return 0;
7811
7812   if (!slen)
7813     slen = c_strlen (src, 1);
7814
7815   /* Now, we must be passed a constant src ptr parameter.  */
7816   if (slen == 0 || TREE_CODE (slen) != INTEGER_CST)
7817     return 0;
7818
7819   slen = size_binop (PLUS_EXPR, slen, ssize_int (1));
7820
7821   /* We do not support simplification of this case, though we do
7822      support it when expanding trees into RTL.  */
7823   /* FIXME: generate a call to __builtin_memset.  */
7824   if (tree_int_cst_lt (slen, len))
7825     return 0;
7826
7827   /* OK transform into builtin memcpy.  */
7828   fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
7829   if (!fn)
7830     return 0;
7831   return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)),
7832                        build_function_call_expr (fn, arglist));
7833 }
7834
7835 /* Fold function call to builtin memcmp.  Return
7836    NULL_TREE if no simplification can be made.  */
7837
7838 static tree
7839 fold_builtin_memcmp (tree arglist)
7840 {
7841   tree arg1, arg2, len;
7842   const char *p1, *p2;
7843
7844   if (!validate_arglist (arglist,
7845                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7846     return 0;
7847
7848   arg1 = TREE_VALUE (arglist);
7849   arg2 = TREE_VALUE (TREE_CHAIN (arglist));
7850   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7851
7852   /* If the LEN parameter is zero, return zero.  */
7853   if (integer_zerop (len))
7854     return omit_two_operands (integer_type_node, integer_zero_node,
7855                               arg1, arg2);
7856
7857   /* If ARG1 and ARG2 are the same (and not volatile), return zero.  */
7858   if (operand_equal_p (arg1, arg2, 0))
7859     return omit_one_operand (integer_type_node, integer_zero_node, len);
7860
7861   p1 = c_getstr (arg1);
7862   p2 = c_getstr (arg2);
7863
7864   /* If all arguments are constant, and the value of len is not greater
7865      than the lengths of arg1 and arg2, evaluate at compile-time.  */
7866   if (host_integerp (len, 1) && p1 && p2
7867       && compare_tree_int (len, strlen (p1) + 1) <= 0
7868       && compare_tree_int (len, strlen (p2) + 1) <= 0)
7869     {
7870       const int r = memcmp (p1, p2, tree_low_cst (len, 1));
7871
7872       if (r > 0)
7873         return integer_one_node;
7874       else if (r < 0)
7875         return integer_minus_one_node;
7876       else
7877         return integer_zero_node;
7878     }
7879
7880   /* If len parameter is one, return an expression corresponding to
7881      (*(const unsigned char*)arg1 - (const unsigned char*)arg2).  */
7882   if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
7883     {
7884       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
7885       tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
7886       tree ind1 = fold_convert (integer_type_node,
7887                                 build1 (INDIRECT_REF, cst_uchar_node,
7888                                         fold_convert (cst_uchar_ptr_node,
7889                                                       arg1)));
7890       tree ind2 = fold_convert (integer_type_node,
7891                                 build1 (INDIRECT_REF, cst_uchar_node,
7892                                         fold_convert (cst_uchar_ptr_node,
7893                                                       arg2)));
7894       return fold (build2 (MINUS_EXPR, integer_type_node, ind1, ind2));
7895     }
7896
7897   return 0;
7898 }
7899
7900 /* Fold function call to builtin strcmp.  Return
7901    NULL_TREE if no simplification can be made.  */
7902
7903 static tree
7904 fold_builtin_strcmp (tree arglist)
7905 {
7906   tree arg1, arg2;
7907   const char *p1, *p2;
7908
7909   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
7910     return 0;
7911
7912   arg1 = TREE_VALUE (arglist);
7913   arg2 = TREE_VALUE (TREE_CHAIN (arglist));
7914
7915   /* If ARG1 and ARG2 are the same (and not volatile), return zero.  */
7916   if (operand_equal_p (arg1, arg2, 0))
7917     return integer_zero_node;
7918
7919   p1 = c_getstr (arg1);
7920   p2 = c_getstr (arg2);
7921
7922   if (p1 && p2)
7923     {
7924       const int i = strcmp (p1, p2);
7925       if (i < 0)
7926         return integer_minus_one_node;
7927       else if (i > 0)
7928         return integer_one_node;
7929       else
7930         return integer_zero_node;
7931     }
7932
7933   /* If the second arg is "", return *(const unsigned char*)arg1.  */
7934   if (p2 && *p2 == '\0')
7935     {
7936       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
7937       tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
7938       return fold_convert (integer_type_node,
7939                            build1 (INDIRECT_REF, cst_uchar_node,
7940                                    fold_convert (cst_uchar_ptr_node,
7941                                                  arg1)));
7942     }
7943
7944   /* If the first arg is "", return -*(const unsigned char*)arg2.  */
7945   if (p1 && *p1 == '\0')
7946     {
7947       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
7948       tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
7949       tree temp = fold_convert (integer_type_node,
7950                                 build1 (INDIRECT_REF, cst_uchar_node,
7951                                         fold_convert (cst_uchar_ptr_node,
7952                                                       arg2)));
7953       return fold (build1 (NEGATE_EXPR, integer_type_node, temp));
7954     }
7955
7956   return 0;
7957 }
7958
7959 /* Fold function call to builtin strncmp.  Return
7960    NULL_TREE if no simplification can be made.  */
7961
7962 static tree
7963 fold_builtin_strncmp (tree arglist)
7964 {
7965   tree arg1, arg2, len;
7966   const char *p1, *p2;
7967
7968   if (!validate_arglist (arglist,
7969                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7970     return 0;
7971
7972   arg1 = TREE_VALUE (arglist);
7973   arg2 = TREE_VALUE (TREE_CHAIN (arglist));
7974   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7975
7976   /* If the LEN parameter is zero, return zero.  */
7977   if (integer_zerop (len))
7978     return omit_two_operands (integer_type_node, integer_zero_node,
7979                               arg1, arg2);
7980
7981   /* If ARG1 and ARG2 are the same (and not volatile), return zero.  */
7982   if (operand_equal_p (arg1, arg2, 0))
7983     return omit_one_operand (integer_type_node, integer_zero_node, len);
7984
7985   p1 = c_getstr (arg1);
7986   p2 = c_getstr (arg2);
7987
7988   if (host_integerp (len, 1) && p1 && p2)
7989     {
7990       const int i = strncmp (p1, p2, tree_low_cst (len, 1));
7991       if (i > 0)
7992         return integer_one_node;
7993       else if (i < 0)
7994         return integer_minus_one_node;
7995       else
7996         return integer_zero_node;
7997     }
7998
7999   /* If the second arg is "", and the length is greater than zero,
8000      return *(const unsigned char*)arg1.  */
8001   if (p2 && *p2 == '\0'
8002       && TREE_CODE (len) == INTEGER_CST
8003       && tree_int_cst_sgn (len) == 1)
8004     {
8005       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8006       tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
8007       return fold_convert (integer_type_node,
8008                            build1 (INDIRECT_REF, cst_uchar_node,
8009                                    fold_convert (cst_uchar_ptr_node,
8010                                                  arg1)));
8011     }
8012
8013   /* If the first arg is "", and the length is greater than zero,
8014      return -*(const unsigned char*)arg2.  */
8015   if (p1 && *p1 == '\0'
8016       && TREE_CODE (len) == INTEGER_CST
8017       && tree_int_cst_sgn (len) == 1)
8018     {
8019       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8020       tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
8021       tree temp = fold_convert (integer_type_node,
8022                                 build1 (INDIRECT_REF, cst_uchar_node,
8023                                         fold_convert (cst_uchar_ptr_node,
8024                                                       arg2)));
8025       return fold (build1 (NEGATE_EXPR, integer_type_node, temp));
8026     }
8027
8028   /* If len parameter is one, return an expression corresponding to
8029      (*(const unsigned char*)arg1 - (const unsigned char*)arg2).  */
8030   if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
8031     {
8032       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8033       tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
8034       tree ind1 = fold_convert (integer_type_node,
8035                                 build1 (INDIRECT_REF, cst_uchar_node,
8036                                         fold_convert (cst_uchar_ptr_node,
8037                                                       arg1)));
8038       tree ind2 = fold_convert (integer_type_node,
8039                                 build1 (INDIRECT_REF, cst_uchar_node,
8040                                         fold_convert (cst_uchar_ptr_node,
8041                                                       arg2)));
8042       return fold (build2 (MINUS_EXPR, integer_type_node, ind1, ind2));
8043     }
8044
8045   return 0;
8046 }
8047
8048 /* Fold function call to builtin signbit, signbitf or signbitl.  Return
8049    NULL_TREE if no simplification can be made.  */
8050
8051 static tree
8052 fold_builtin_signbit (tree fndecl, tree arglist)
8053 {
8054   tree type = TREE_TYPE (TREE_TYPE (fndecl));
8055   tree arg, temp;
8056
8057   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8058     return NULL_TREE;
8059
8060   arg = TREE_VALUE (arglist);
8061
8062   /* If ARG is a compile-time constant, determine the result.  */
8063   if (TREE_CODE (arg) == REAL_CST
8064       && !TREE_CONSTANT_OVERFLOW (arg))
8065     {
8066       REAL_VALUE_TYPE c;
8067
8068       c = TREE_REAL_CST (arg);
8069       temp = REAL_VALUE_NEGATIVE (c) ? integer_one_node : integer_zero_node;
8070       return fold_convert (type, temp);
8071     }
8072
8073   /* If ARG is non-negative, the result is always zero.  */
8074   if (tree_expr_nonnegative_p (arg))
8075     return omit_one_operand (type, integer_zero_node, arg);
8076
8077   /* If ARG's format doesn't have signed zeros, return "arg < 0.0".  */
8078   if (!HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg))))
8079     return fold (build2 (LT_EXPR, type, arg,
8080                          build_real (TREE_TYPE (arg), dconst0)));
8081
8082   return NULL_TREE;
8083 }
8084
8085 /* Fold function call to builtin copysign, copysignf or copysignl.
8086    Return NULL_TREE if no simplification can be made.  */
8087
8088 static tree
8089 fold_builtin_copysign (tree fndecl, tree arglist, tree type)
8090 {
8091   tree arg1, arg2, tem;
8092
8093   if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
8094     return NULL_TREE;
8095
8096   arg1 = TREE_VALUE (arglist);
8097   arg2 = TREE_VALUE (TREE_CHAIN (arglist));
8098
8099   /* copysign(X,X) is X.  */
8100   if (operand_equal_p (arg1, arg2, 0))
8101     return fold_convert (type, arg1);
8102
8103   /* If ARG1 and ARG2 are compile-time constants, determine the result.  */
8104   if (TREE_CODE (arg1) == REAL_CST
8105       && TREE_CODE (arg2) == REAL_CST
8106       && !TREE_CONSTANT_OVERFLOW (arg1)
8107       && !TREE_CONSTANT_OVERFLOW (arg2))
8108     {
8109       REAL_VALUE_TYPE c1, c2;
8110
8111       c1 = TREE_REAL_CST (arg1);
8112       c2 = TREE_REAL_CST (arg2);
8113       real_copysign (&c1, &c2);
8114       return build_real (type, c1);
8115       c1.sign = c2.sign;
8116     }
8117
8118   /* copysign(X, Y) is fabs(X) when Y is always non-negative.
8119      Remember to evaluate Y for side-effects.  */
8120   if (tree_expr_nonnegative_p (arg2))
8121     return omit_one_operand (type,
8122                              fold (build1 (ABS_EXPR, type, arg1)),
8123                              arg2);
8124
8125   /* Strip sign changing operations for the first argument.  */
8126   tem = fold_strip_sign_ops (arg1);
8127   if (tem)
8128     {
8129       arglist = tree_cons (NULL_TREE, tem, TREE_CHAIN (arglist));
8130       return build_function_call_expr (fndecl, arglist);
8131     }
8132
8133   return NULL_TREE;
8134 }
8135
8136 /* Fold a call to builtin isascii.  */
8137
8138 static tree
8139 fold_builtin_isascii (tree arglist)
8140 {
8141   if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8142     return 0;
8143   else
8144     {
8145       /* Transform isascii(c) -> ((c & ~0x7f) == 0).  */
8146       tree arg = TREE_VALUE (arglist);
8147
8148       arg = build2 (BIT_AND_EXPR, integer_type_node, arg,
8149                     build_int_cst (NULL_TREE,
8150                                    ~ (unsigned HOST_WIDE_INT) 0x7f));
8151       arg = fold (build2 (EQ_EXPR, integer_type_node,
8152                           arg, integer_zero_node));
8153
8154       if (in_gimple_form && !TREE_CONSTANT (arg))
8155         return NULL_TREE;
8156       else
8157         return arg;
8158     }
8159 }
8160
8161 /* Fold a call to builtin toascii.  */
8162
8163 static tree
8164 fold_builtin_toascii (tree arglist)
8165 {
8166   if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8167     return 0;
8168   else
8169     {
8170       /* Transform toascii(c) -> (c & 0x7f).  */
8171       tree arg = TREE_VALUE (arglist);
8172
8173       return fold (build2 (BIT_AND_EXPR, integer_type_node, arg,
8174                            build_int_cst (NULL_TREE, 0x7f)));
8175     }
8176 }
8177
8178 /* Fold a call to builtin isdigit.  */
8179
8180 static tree
8181 fold_builtin_isdigit (tree arglist)
8182 {
8183   if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8184     return 0;
8185   else
8186     {
8187       /* Transform isdigit(c) -> (unsigned)(c) - '0' <= 9.  */
8188       /* According to the C standard, isdigit is unaffected by locale.
8189          However, it definitely is affected by the target character set.  */
8190       tree arg;
8191       unsigned HOST_WIDE_INT target_digit0
8192         = lang_hooks.to_target_charset ('0');
8193
8194       if (target_digit0 == 0)
8195         return NULL_TREE;
8196
8197       arg = fold_convert (unsigned_type_node, TREE_VALUE (arglist));
8198       arg = build2 (MINUS_EXPR, unsigned_type_node, arg,
8199                     build_int_cst (unsigned_type_node, target_digit0));
8200       arg = build2 (LE_EXPR, integer_type_node, arg,
8201                     build_int_cst (unsigned_type_node, 9));
8202       arg = fold (arg);
8203       if (in_gimple_form && !TREE_CONSTANT (arg))
8204         return NULL_TREE;
8205       else
8206         return arg;
8207     }
8208 }
8209
8210 /* Fold a call to fabs, fabsf or fabsl.  */
8211
8212 static tree
8213 fold_builtin_fabs (tree arglist, tree type)
8214 {
8215   tree arg;
8216
8217   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8218     return 0;
8219
8220   arg = TREE_VALUE (arglist);
8221   arg = fold_convert (type, arg);
8222   if (TREE_CODE (arg) == REAL_CST)
8223     return fold_abs_const (arg, type);
8224   return fold (build1 (ABS_EXPR, type, arg));
8225 }
8226
8227 /* Fold a call to abs, labs, llabs or imaxabs.  */
8228
8229 static tree
8230 fold_builtin_abs (tree arglist, tree type)
8231 {
8232   tree arg;
8233
8234   if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8235     return 0;
8236
8237   arg = TREE_VALUE (arglist);
8238   arg = fold_convert (type, arg);
8239   if (TREE_CODE (arg) == INTEGER_CST)
8240     return fold_abs_const (arg, type);
8241   return fold (build1 (ABS_EXPR, type, arg));
8242 }
8243
8244 /* Fold a call to __builtin_isnan(), __builtin_isinf, __builtin_finite.
8245    EXP is the CALL_EXPR for the call.  */
8246
8247 static tree
8248 fold_builtin_classify (tree fndecl, tree arglist, int builtin_index)
8249 {
8250   tree type = TREE_TYPE (TREE_TYPE (fndecl));
8251   tree arg;
8252   REAL_VALUE_TYPE r;
8253
8254   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8255     {
8256       /* Check that we have exactly one argument.  */
8257       if (arglist == 0)
8258         {
8259           error ("too few arguments to function %qs",
8260                  IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8261           return error_mark_node;
8262         }
8263       else if (TREE_CHAIN (arglist) != 0)
8264         {
8265           error ("too many arguments to function %qs",
8266                  IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8267           return error_mark_node;
8268         }
8269       else
8270         {
8271           error ("non-floating-point argument to function %qs",
8272                  IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8273           return error_mark_node;
8274         }
8275     }
8276
8277   arg = TREE_VALUE (arglist);
8278   switch (builtin_index)
8279     {
8280     case BUILT_IN_ISINF:
8281       if (!MODE_HAS_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
8282         return omit_one_operand (type, integer_zero_node, arg);
8283
8284       if (TREE_CODE (arg) == REAL_CST)
8285         {
8286           r = TREE_REAL_CST (arg);
8287           if (real_isinf (&r))
8288             return real_compare (GT_EXPR, &r, &dconst0)
8289                    ? integer_one_node : integer_minus_one_node;
8290           else
8291             return integer_zero_node;
8292         }
8293
8294       return NULL_TREE;
8295
8296     case BUILT_IN_FINITE:
8297       if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg)))
8298           && !MODE_HAS_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
8299         return omit_one_operand (type, integer_zero_node, arg);
8300
8301       if (TREE_CODE (arg) == REAL_CST)
8302         {
8303           r = TREE_REAL_CST (arg);
8304           return real_isinf (&r) || real_isnan (&r)
8305                  ? integer_zero_node : integer_one_node;
8306         }
8307
8308       return NULL_TREE;
8309
8310     case BUILT_IN_ISNAN:
8311       if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg))))
8312         return omit_one_operand (type, integer_zero_node, arg);
8313
8314       if (TREE_CODE (arg) == REAL_CST)
8315         {
8316           r = TREE_REAL_CST (arg);
8317           return real_isnan (&r) ? integer_one_node : integer_zero_node;
8318         }
8319
8320       arg = builtin_save_expr (arg);
8321       return fold (build2 (UNORDERED_EXPR, type, arg, arg));
8322
8323     default:
8324       gcc_unreachable ();
8325     }
8326 }
8327
8328 /* Fold a call to an unordered comparison function such as
8329    __builtin_isgreater().  FNDECL is the FUNCTION_DECL for the function
8330    being called and ARGLIST is the argument list for the call.
8331    UNORDERED_CODE and ORDERED_CODE are comparison codes that give
8332    the opposite of the desired result.  UNORDERED_CODE is used
8333    for modes that can hold NaNs and ORDERED_CODE is used for
8334    the rest.  */
8335
8336 static tree
8337 fold_builtin_unordered_cmp (tree fndecl, tree arglist,
8338                             enum tree_code unordered_code,
8339                             enum tree_code ordered_code)
8340 {
8341   tree type = TREE_TYPE (TREE_TYPE (fndecl));
8342   enum tree_code code;
8343   tree arg0, arg1;
8344   tree type0, type1;
8345   enum tree_code code0, code1;
8346   tree cmp_type = NULL_TREE;
8347
8348   if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
8349     {
8350       /* Check that we have exactly two arguments.  */
8351       if (arglist == 0 || TREE_CHAIN (arglist) == 0)
8352         {
8353           error ("too few arguments to function %qs",
8354                  IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8355           return error_mark_node;
8356         }
8357       else if (TREE_CHAIN (TREE_CHAIN (arglist)) != 0)
8358         {
8359           error ("too many arguments to function %qs",
8360                  IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8361           return error_mark_node;
8362         }
8363     }
8364
8365   arg0 = TREE_VALUE (arglist);
8366   arg1 = TREE_VALUE (TREE_CHAIN (arglist));
8367   
8368   type0 = TREE_TYPE (arg0);
8369   type1 = TREE_TYPE (arg1);
8370   
8371   code0 = TREE_CODE (type0);
8372   code1 = TREE_CODE (type1);
8373   
8374   if (code0 == REAL_TYPE && code1 == REAL_TYPE)
8375     /* Choose the wider of two real types.  */
8376     cmp_type = TYPE_PRECISION (type0) >= TYPE_PRECISION (type1)
8377       ? type0 : type1;
8378   else if (code0 == REAL_TYPE && code1 == INTEGER_TYPE)
8379     cmp_type = type0;
8380   else if (code0 == INTEGER_TYPE && code1 == REAL_TYPE)
8381     cmp_type = type1;
8382   else
8383     {
8384       error ("non-floating-point argument to function %qs",
8385                  IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8386       return error_mark_node;
8387     }
8388   
8389   arg0 = fold_convert (cmp_type, arg0);
8390   arg1 = fold_convert (cmp_type, arg1);
8391
8392   if (unordered_code == UNORDERED_EXPR)
8393     {
8394       if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg0))))
8395         return omit_two_operands (type, integer_zero_node, arg0, arg1);
8396       return fold (build2 (UNORDERED_EXPR, type, arg0, arg1));
8397     }
8398
8399   code = MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg0))) ? unordered_code
8400                                                       : ordered_code;
8401   return fold (build1 (TRUTH_NOT_EXPR, type,
8402                        fold (build2 (code, type, arg0, arg1))));
8403 }
8404
8405 /* Fold a call to one of the external complex multiply libcalls.  */
8406
8407 static tree
8408 fold_builtin_complex_mul (tree type, tree arglist)
8409 {
8410   tree ar, ai, br, bi;
8411
8412   if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, REAL_TYPE,
8413                          REAL_TYPE, VOID_TYPE))
8414     return NULL;
8415
8416   ar = TREE_VALUE (arglist); arglist = TREE_CHAIN (arglist);
8417   ai = TREE_VALUE (arglist); arglist = TREE_CHAIN (arglist);
8418   br = TREE_VALUE (arglist); arglist = TREE_CHAIN (arglist);
8419   bi = TREE_VALUE (arglist);
8420
8421   return fold_complex_mult_parts (type, ar, ai, br, bi);
8422 }
8423
8424 /* Fold a call to one of the external complex division libcalls.  */
8425
8426 static tree
8427 fold_builtin_complex_div (tree type, tree arglist)
8428 {
8429   tree ar, ai, br, bi;
8430
8431   if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, REAL_TYPE,
8432                          REAL_TYPE, VOID_TYPE))
8433     return NULL;
8434
8435   ar = TREE_VALUE (arglist); arglist = TREE_CHAIN (arglist);
8436   ai = TREE_VALUE (arglist); arglist = TREE_CHAIN (arglist);
8437   br = TREE_VALUE (arglist); arglist = TREE_CHAIN (arglist);
8438   bi = TREE_VALUE (arglist);
8439
8440   return fold_complex_div_parts (type, ar, ai, br, bi, RDIV_EXPR);
8441 }
8442
8443 /* Used by constant folding to simplify calls to builtin functions.  EXP is
8444    the CALL_EXPR of a call to a builtin function.  IGNORE is true if the
8445    result of the function call is ignored.  This function returns NULL_TREE
8446    if no simplification was possible.  */
8447
8448 static tree
8449 fold_builtin_1 (tree fndecl, tree arglist, bool ignore)
8450 {
8451   tree type = TREE_TYPE (TREE_TYPE (fndecl));
8452   enum built_in_function fcode;
8453
8454   if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
8455     return targetm.fold_builtin (fndecl, arglist, ignore);
8456
8457   fcode = DECL_FUNCTION_CODE (fndecl);
8458   switch (fcode)
8459     {
8460     case BUILT_IN_FPUTS:
8461       return fold_builtin_fputs (arglist, ignore, false, NULL_TREE);
8462
8463     case BUILT_IN_FPUTS_UNLOCKED:
8464       return fold_builtin_fputs (arglist, ignore, true, NULL_TREE);
8465
8466     case BUILT_IN_STRSTR:
8467       return fold_builtin_strstr (arglist, type);
8468
8469     case BUILT_IN_STRCAT:
8470       return fold_builtin_strcat (arglist);
8471
8472     case BUILT_IN_STRNCAT:
8473       return fold_builtin_strncat (arglist);
8474
8475     case BUILT_IN_STRSPN:
8476       return fold_builtin_strspn (arglist);
8477
8478     case BUILT_IN_STRCSPN:
8479       return fold_builtin_strcspn (arglist);
8480
8481     case BUILT_IN_STRCHR:
8482     case BUILT_IN_INDEX:
8483       return fold_builtin_strchr (arglist, type);
8484
8485     case BUILT_IN_STRRCHR:
8486     case BUILT_IN_RINDEX:
8487       return fold_builtin_strrchr (arglist, type);
8488
8489     case BUILT_IN_STRCPY:
8490       return fold_builtin_strcpy (fndecl, arglist, NULL_TREE);
8491
8492     case BUILT_IN_STRNCPY:
8493       return fold_builtin_strncpy (fndecl, arglist, NULL_TREE);
8494
8495     case BUILT_IN_STRCMP:
8496       return fold_builtin_strcmp (arglist);
8497
8498     case BUILT_IN_STRNCMP:
8499       return fold_builtin_strncmp (arglist);
8500
8501     case BUILT_IN_STRPBRK:
8502       return fold_builtin_strpbrk (arglist, type);
8503
8504     case BUILT_IN_BCMP:
8505     case BUILT_IN_MEMCMP:
8506       return fold_builtin_memcmp (arglist);
8507
8508     case BUILT_IN_SPRINTF:
8509       return fold_builtin_sprintf (arglist, ignore);
8510
8511     case BUILT_IN_CONSTANT_P:
8512       {
8513         tree val;
8514
8515         val = fold_builtin_constant_p (arglist);
8516         /* Gimplification will pull the CALL_EXPR for the builtin out of
8517            an if condition.  When not optimizing, we'll not CSE it back.
8518            To avoid link error types of regressions, return false now.  */
8519         if (!val && !optimize)
8520           val = integer_zero_node;
8521
8522         return val;
8523       }
8524
8525     case BUILT_IN_EXPECT:
8526       return fold_builtin_expect (arglist);
8527
8528     case BUILT_IN_CLASSIFY_TYPE:
8529       return fold_builtin_classify_type (arglist);
8530
8531     case BUILT_IN_STRLEN:
8532       return fold_builtin_strlen (arglist);
8533
8534     case BUILT_IN_FABS:
8535     case BUILT_IN_FABSF:
8536     case BUILT_IN_FABSL:
8537       return fold_builtin_fabs (arglist, type);
8538
8539     case BUILT_IN_ABS:
8540     case BUILT_IN_LABS:
8541     case BUILT_IN_LLABS:
8542     case BUILT_IN_IMAXABS:
8543       return fold_builtin_abs (arglist, type);
8544
8545     case BUILT_IN_CONJ:
8546     case BUILT_IN_CONJF:
8547     case BUILT_IN_CONJL:
8548       if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
8549         return fold (build1 (CONJ_EXPR, type, TREE_VALUE (arglist)));
8550       break;
8551
8552     case BUILT_IN_CREAL:
8553     case BUILT_IN_CREALF:
8554     case BUILT_IN_CREALL:
8555       if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
8556         return non_lvalue (fold (build1 (REALPART_EXPR, type,
8557                                          TREE_VALUE (arglist))));
8558       break;
8559
8560     case BUILT_IN_CIMAG:
8561     case BUILT_IN_CIMAGF:
8562     case BUILT_IN_CIMAGL:
8563       if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
8564         return non_lvalue (fold (build1 (IMAGPART_EXPR, type,
8565                                          TREE_VALUE (arglist))));
8566       break;
8567
8568     case BUILT_IN_CABS:
8569     case BUILT_IN_CABSF:
8570     case BUILT_IN_CABSL:
8571       return fold_builtin_cabs (arglist, type);
8572
8573     case BUILT_IN_SQRT:
8574     case BUILT_IN_SQRTF:
8575     case BUILT_IN_SQRTL:
8576       return fold_builtin_sqrt (arglist, type);
8577
8578     case BUILT_IN_CBRT:
8579     case BUILT_IN_CBRTF:
8580     case BUILT_IN_CBRTL:
8581       return fold_builtin_cbrt (arglist, type);
8582
8583     case BUILT_IN_SIN:
8584     case BUILT_IN_SINF:
8585     case BUILT_IN_SINL:
8586       return fold_builtin_sin (arglist);
8587
8588     case BUILT_IN_COS:
8589     case BUILT_IN_COSF:
8590     case BUILT_IN_COSL:
8591       return fold_builtin_cos (arglist, type, fndecl);
8592
8593     case BUILT_IN_EXP:
8594     case BUILT_IN_EXPF:
8595     case BUILT_IN_EXPL:
8596       return fold_builtin_exponent (fndecl, arglist, &dconste);
8597
8598     case BUILT_IN_EXP2:
8599     case BUILT_IN_EXP2F:
8600     case BUILT_IN_EXP2L:
8601       return fold_builtin_exponent (fndecl, arglist, &dconst2);
8602
8603     case BUILT_IN_EXP10:
8604     case BUILT_IN_EXP10F:
8605     case BUILT_IN_EXP10L:
8606     case BUILT_IN_POW10:
8607     case BUILT_IN_POW10F:
8608     case BUILT_IN_POW10L:
8609       return fold_builtin_exponent (fndecl, arglist, &dconst10);
8610
8611     case BUILT_IN_LOG:
8612     case BUILT_IN_LOGF:
8613     case BUILT_IN_LOGL:
8614       return fold_builtin_logarithm (fndecl, arglist, &dconste);
8615
8616     case BUILT_IN_LOG2:
8617     case BUILT_IN_LOG2F:
8618     case BUILT_IN_LOG2L:
8619       return fold_builtin_logarithm (fndecl, arglist, &dconst2);
8620
8621     case BUILT_IN_LOG10:
8622     case BUILT_IN_LOG10F:
8623     case BUILT_IN_LOG10L:
8624       return fold_builtin_logarithm (fndecl, arglist, &dconst10);
8625
8626     case BUILT_IN_TAN:
8627     case BUILT_IN_TANF:
8628     case BUILT_IN_TANL:
8629       return fold_builtin_tan (arglist);
8630
8631     case BUILT_IN_ATAN:
8632     case BUILT_IN_ATANF:
8633     case BUILT_IN_ATANL:
8634       return fold_builtin_atan (arglist, type);
8635
8636     case BUILT_IN_POW:
8637     case BUILT_IN_POWF:
8638     case BUILT_IN_POWL:
8639       return fold_builtin_pow (fndecl, arglist, type);
8640
8641     case BUILT_IN_POWI:
8642     case BUILT_IN_POWIF:
8643     case BUILT_IN_POWIL:
8644       return fold_builtin_powi (fndecl, arglist, type);
8645
8646     case BUILT_IN_INF:
8647     case BUILT_IN_INFF:
8648     case BUILT_IN_INFL:
8649       return fold_builtin_inf (type, true);
8650
8651     case BUILT_IN_HUGE_VAL:
8652     case BUILT_IN_HUGE_VALF:
8653     case BUILT_IN_HUGE_VALL:
8654       return fold_builtin_inf (type, false);
8655
8656     case BUILT_IN_NAN:
8657     case BUILT_IN_NANF:
8658     case BUILT_IN_NANL:
8659       return fold_builtin_nan (arglist, type, true);
8660
8661     case BUILT_IN_NANS:
8662     case BUILT_IN_NANSF:
8663     case BUILT_IN_NANSL:
8664       return fold_builtin_nan (arglist, type, false);
8665
8666     case BUILT_IN_FLOOR:
8667     case BUILT_IN_FLOORF:
8668     case BUILT_IN_FLOORL:
8669       return fold_builtin_floor (fndecl, arglist);
8670
8671     case BUILT_IN_CEIL:
8672     case BUILT_IN_CEILF:
8673     case BUILT_IN_CEILL:
8674       return fold_builtin_ceil (fndecl, arglist);
8675
8676     case BUILT_IN_TRUNC:
8677     case BUILT_IN_TRUNCF:
8678     case BUILT_IN_TRUNCL:
8679       return fold_builtin_trunc (fndecl, arglist);
8680
8681     case BUILT_IN_ROUND:
8682     case BUILT_IN_ROUNDF:
8683     case BUILT_IN_ROUNDL:
8684       return fold_builtin_round (fndecl, arglist);
8685
8686     case BUILT_IN_NEARBYINT:
8687     case BUILT_IN_NEARBYINTF:
8688     case BUILT_IN_NEARBYINTL:
8689     case BUILT_IN_RINT:
8690     case BUILT_IN_RINTF:
8691     case BUILT_IN_RINTL:
8692       return fold_trunc_transparent_mathfn (fndecl, arglist);
8693
8694     case BUILT_IN_LCEIL:
8695     case BUILT_IN_LCEILF:
8696     case BUILT_IN_LCEILL:
8697     case BUILT_IN_LLCEIL:
8698     case BUILT_IN_LLCEILF:
8699     case BUILT_IN_LLCEILL:
8700     case BUILT_IN_LFLOOR:
8701     case BUILT_IN_LFLOORF:
8702     case BUILT_IN_LFLOORL:
8703     case BUILT_IN_LLFLOOR:
8704     case BUILT_IN_LLFLOORF:
8705     case BUILT_IN_LLFLOORL:
8706     case BUILT_IN_LROUND:
8707     case BUILT_IN_LROUNDF:
8708     case BUILT_IN_LROUNDL:
8709     case BUILT_IN_LLROUND:
8710     case BUILT_IN_LLROUNDF:
8711     case BUILT_IN_LLROUNDL:
8712       return fold_builtin_int_roundingfn (fndecl, arglist);
8713
8714     case BUILT_IN_LRINT:
8715     case BUILT_IN_LRINTF:
8716     case BUILT_IN_LRINTL:
8717     case BUILT_IN_LLRINT:
8718     case BUILT_IN_LLRINTF:
8719     case BUILT_IN_LLRINTL:
8720       return fold_fixed_mathfn (fndecl, arglist);
8721
8722     case BUILT_IN_FFS:
8723     case BUILT_IN_FFSL:
8724     case BUILT_IN_FFSLL:
8725     case BUILT_IN_CLZ:
8726     case BUILT_IN_CLZL:
8727     case BUILT_IN_CLZLL:
8728     case BUILT_IN_CTZ:
8729     case BUILT_IN_CTZL:
8730     case BUILT_IN_CTZLL:
8731     case BUILT_IN_POPCOUNT:
8732     case BUILT_IN_POPCOUNTL:
8733     case BUILT_IN_POPCOUNTLL:
8734     case BUILT_IN_PARITY:
8735     case BUILT_IN_PARITYL:
8736     case BUILT_IN_PARITYLL:
8737       return fold_builtin_bitop (fndecl, arglist);
8738
8739     case BUILT_IN_MEMCPY:
8740       return fold_builtin_memcpy (fndecl, arglist);
8741
8742     case BUILT_IN_MEMPCPY:
8743       return fold_builtin_mempcpy (arglist, type, /*endp=*/1);
8744
8745     case BUILT_IN_MEMMOVE:
8746       return fold_builtin_memmove (arglist, type);
8747
8748     case BUILT_IN_SIGNBIT:
8749     case BUILT_IN_SIGNBITF:
8750     case BUILT_IN_SIGNBITL:
8751       return fold_builtin_signbit (fndecl, arglist);
8752
8753     case BUILT_IN_ISASCII:
8754       return fold_builtin_isascii (arglist);
8755
8756     case BUILT_IN_TOASCII:
8757       return fold_builtin_toascii (arglist);
8758
8759     case BUILT_IN_ISDIGIT:
8760       return fold_builtin_isdigit (arglist);
8761
8762     case BUILT_IN_COPYSIGN:
8763     case BUILT_IN_COPYSIGNF:
8764     case BUILT_IN_COPYSIGNL:
8765       return fold_builtin_copysign (fndecl, arglist, type);
8766
8767     case BUILT_IN_FINITE:
8768     case BUILT_IN_FINITEF:
8769     case BUILT_IN_FINITEL:
8770       return fold_builtin_classify (fndecl, arglist, BUILT_IN_FINITE);
8771
8772     case BUILT_IN_ISINF:
8773     case BUILT_IN_ISINFF:
8774     case BUILT_IN_ISINFL:
8775       return fold_builtin_classify (fndecl, arglist, BUILT_IN_ISINF);
8776
8777     case BUILT_IN_ISNAN:
8778     case BUILT_IN_ISNANF:
8779     case BUILT_IN_ISNANL:
8780       return fold_builtin_classify (fndecl, arglist, BUILT_IN_ISNAN);
8781
8782     case BUILT_IN_ISGREATER:
8783       return fold_builtin_unordered_cmp (fndecl, arglist, UNLE_EXPR, LE_EXPR);
8784     case BUILT_IN_ISGREATEREQUAL:
8785       return fold_builtin_unordered_cmp (fndecl, arglist, UNLT_EXPR, LT_EXPR);
8786     case BUILT_IN_ISLESS:
8787       return fold_builtin_unordered_cmp (fndecl, arglist, UNGE_EXPR, GE_EXPR);
8788     case BUILT_IN_ISLESSEQUAL:
8789       return fold_builtin_unordered_cmp (fndecl, arglist, UNGT_EXPR, GT_EXPR);
8790     case BUILT_IN_ISLESSGREATER:
8791       return fold_builtin_unordered_cmp (fndecl, arglist, UNEQ_EXPR, EQ_EXPR);
8792     case BUILT_IN_ISUNORDERED:
8793       return fold_builtin_unordered_cmp (fndecl, arglist, UNORDERED_EXPR,
8794                                          NOP_EXPR);
8795
8796       /* We do the folding for va_start in the expander.  */
8797     case BUILT_IN_VA_START:
8798       break;
8799
8800     default:
8801       if (fcode >= BUILT_IN_COMPLEX_MUL_MIN
8802           && fcode <= BUILT_IN_COMPLEX_MUL_MAX)
8803         return fold_builtin_complex_mul (type, arglist);
8804       if (fcode >= BUILT_IN_COMPLEX_DIV_MIN
8805           && fcode <= BUILT_IN_COMPLEX_DIV_MAX)
8806         return fold_builtin_complex_div (type, arglist);
8807       break;
8808     }
8809
8810   return 0;
8811 }
8812
8813 /* A wrapper function for builtin folding that prevents warnings for
8814    "statement without effect" and the like, caused by removing the
8815    call node earlier than the warning is generated.  */
8816
8817 tree
8818 fold_builtin (tree fndecl, tree arglist, bool ignore)
8819 {
8820   tree exp = fold_builtin_1 (fndecl, arglist, ignore);
8821   if (exp)
8822     {
8823       /* ??? Don't clobber shared nodes such as integer_zero_node.  */
8824       if (CONSTANT_CLASS_P (exp))
8825         exp = build1 (NOP_EXPR, TREE_TYPE (exp), exp);
8826       TREE_NO_WARNING (exp) = 1;
8827     }
8828
8829   return exp;
8830 }
8831
8832 /* Conveniently construct a function call expression.  */
8833
8834 tree
8835 build_function_call_expr (tree fn, tree arglist)
8836 {
8837   tree call_expr;
8838
8839   call_expr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
8840   call_expr = build3 (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)),
8841                       call_expr, arglist, NULL_TREE);
8842   return fold (call_expr);
8843 }
8844
8845 /* This function validates the types of a function call argument list
8846    represented as a tree chain of parameters against a specified list
8847    of tree_codes.  If the last specifier is a 0, that represents an
8848    ellipses, otherwise the last specifier must be a VOID_TYPE.  */
8849
8850 static int
8851 validate_arglist (tree arglist, ...)
8852 {
8853   enum tree_code code;
8854   int res = 0;
8855   va_list ap;
8856
8857   va_start (ap, arglist);
8858
8859   do
8860     {
8861       code = va_arg (ap, enum tree_code);
8862       switch (code)
8863         {
8864         case 0:
8865           /* This signifies an ellipses, any further arguments are all ok.  */
8866           res = 1;
8867           goto end;
8868         case VOID_TYPE:
8869           /* This signifies an endlink, if no arguments remain, return
8870              true, otherwise return false.  */
8871           res = arglist == 0;
8872           goto end;
8873         default:
8874           /* If no parameters remain or the parameter's code does not
8875              match the specified code, return false.  Otherwise continue
8876              checking any remaining arguments.  */
8877           if (arglist == 0)
8878             goto end;
8879           if (code == POINTER_TYPE)
8880             {
8881               if (! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist))))
8882                 goto end;
8883             }
8884           else if (code != TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))))
8885             goto end;
8886           break;
8887         }
8888       arglist = TREE_CHAIN (arglist);
8889     }
8890   while (1);
8891
8892   /* We need gotos here since we can only have one VA_CLOSE in a
8893      function.  */
8894  end: ;
8895   va_end (ap);
8896
8897   return res;
8898 }
8899
8900 /* Default target-specific builtin expander that does nothing.  */
8901
8902 rtx
8903 default_expand_builtin (tree exp ATTRIBUTE_UNUSED,
8904                         rtx target ATTRIBUTE_UNUSED,
8905                         rtx subtarget ATTRIBUTE_UNUSED,
8906                         enum machine_mode mode ATTRIBUTE_UNUSED,
8907                         int ignore ATTRIBUTE_UNUSED)
8908 {
8909   return NULL_RTX;
8910 }
8911
8912 /* Returns true is EXP represents data that would potentially reside
8913    in a readonly section.  */
8914
8915 static bool
8916 readonly_data_expr (tree exp)
8917 {
8918   STRIP_NOPS (exp);
8919
8920   if (TREE_CODE (exp) != ADDR_EXPR)
8921     return false;
8922
8923   exp = get_base_address (TREE_OPERAND (exp, 0));
8924   if (!exp)
8925     return false;
8926
8927   /* Make sure we call decl_readonly_section only for trees it
8928      can handle (since it returns true for everything it doesn't
8929      understand).  */
8930   if (TREE_CODE (exp) == STRING_CST
8931       || TREE_CODE (exp) == CONSTRUCTOR
8932       || (TREE_CODE (exp) == VAR_DECL && TREE_STATIC (exp)))
8933     return decl_readonly_section (exp, 0);
8934   else
8935     return false;
8936 }
8937
8938 /* Simplify a call to the strstr builtin.
8939
8940    Return 0 if no simplification was possible, otherwise return the
8941    simplified form of the call as a tree.
8942
8943    The simplified form may be a constant or other expression which
8944    computes the same value, but in a more efficient manner (including
8945    calls to other builtin functions).
8946
8947    The call may contain arguments which need to be evaluated, but
8948    which are not useful to determine the result of the call.  In
8949    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
8950    COMPOUND_EXPR will be an argument which must be evaluated.
8951    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
8952    COMPOUND_EXPR in the chain will contain the tree for the simplified
8953    form of the builtin function call.  */
8954
8955 static tree
8956 fold_builtin_strstr (tree arglist, tree type)
8957 {
8958   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
8959     return 0;
8960   else
8961     {
8962       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
8963       tree fn;
8964       const char *p1, *p2;
8965
8966       p2 = c_getstr (s2);
8967       if (p2 == NULL)
8968         return 0;
8969
8970       p1 = c_getstr (s1);
8971       if (p1 != NULL)
8972         {
8973           const char *r = strstr (p1, p2);
8974           tree tem;
8975
8976           if (r == NULL)
8977             return build_int_cst (TREE_TYPE (s1), 0);
8978
8979           /* Return an offset into the constant string argument.  */
8980           tem = fold (build2 (PLUS_EXPR, TREE_TYPE (s1),
8981                               s1, build_int_cst (TREE_TYPE (s1), r - p1)));
8982           return fold_convert (type, tem);
8983         }
8984
8985       if (p2[0] == '\0')
8986         return s1;
8987
8988       if (p2[1] != '\0')
8989         return 0;
8990
8991       fn = implicit_built_in_decls[BUILT_IN_STRCHR];
8992       if (!fn)
8993         return 0;
8994
8995       /* New argument list transforming strstr(s1, s2) to
8996          strchr(s1, s2[0]).  */
8997       arglist = build_tree_list (NULL_TREE,
8998                                  build_int_cst (NULL_TREE, p2[0]));
8999       arglist = tree_cons (NULL_TREE, s1, arglist);
9000       return build_function_call_expr (fn, arglist);
9001     }
9002 }
9003
9004 /* Simplify a call to the strchr builtin.
9005
9006    Return 0 if no simplification was possible, otherwise return the
9007    simplified form of the call as a tree.
9008
9009    The simplified form may be a constant or other expression which
9010    computes the same value, but in a more efficient manner (including
9011    calls to other builtin functions).
9012
9013    The call may contain arguments which need to be evaluated, but
9014    which are not useful to determine the result of the call.  In
9015    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
9016    COMPOUND_EXPR will be an argument which must be evaluated.
9017    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
9018    COMPOUND_EXPR in the chain will contain the tree for the simplified
9019    form of the builtin function call.  */
9020
9021 static tree
9022 fold_builtin_strchr (tree arglist, tree type)
9023 {
9024   if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9025     return 0;
9026   else
9027     {
9028       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9029       const char *p1;
9030
9031       if (TREE_CODE (s2) != INTEGER_CST)
9032         return 0;
9033
9034       p1 = c_getstr (s1);
9035       if (p1 != NULL)
9036         {
9037           char c;
9038           const char *r;
9039           tree tem;
9040
9041           if (target_char_cast (s2, &c))
9042             return 0;
9043
9044           r = strchr (p1, c);
9045
9046           if (r == NULL)
9047             return build_int_cst (TREE_TYPE (s1), 0);
9048
9049           /* Return an offset into the constant string argument.  */
9050           tem = fold (build2 (PLUS_EXPR, TREE_TYPE (s1),
9051                               s1, build_int_cst (TREE_TYPE (s1), r - p1)));
9052           return fold_convert (type, tem);
9053         }
9054       return 0;
9055     }
9056 }
9057
9058 /* Simplify a call to the strrchr builtin.
9059
9060    Return 0 if no simplification was possible, otherwise return the
9061    simplified form of the call as a tree.
9062
9063    The simplified form may be a constant or other expression which
9064    computes the same value, but in a more efficient manner (including
9065    calls to other builtin functions).
9066
9067    The call may contain arguments which need to be evaluated, but
9068    which are not useful to determine the result of the call.  In
9069    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
9070    COMPOUND_EXPR will be an argument which must be evaluated.
9071    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
9072    COMPOUND_EXPR in the chain will contain the tree for the simplified
9073    form of the builtin function call.  */
9074
9075 static tree
9076 fold_builtin_strrchr (tree arglist, tree type)
9077 {
9078   if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9079     return 0;
9080   else
9081     {
9082       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9083       tree fn;
9084       const char *p1;
9085
9086       if (TREE_CODE (s2) != INTEGER_CST)
9087         return 0;
9088
9089       p1 = c_getstr (s1);
9090       if (p1 != NULL)
9091         {
9092           char c;
9093           const char *r;
9094           tree tem;
9095
9096           if (target_char_cast (s2, &c))
9097             return 0;
9098
9099           r = strrchr (p1, c);
9100
9101           if (r == NULL)
9102             return build_int_cst (TREE_TYPE (s1), 0);
9103
9104           /* Return an offset into the constant string argument.  */
9105           tem = fold (build2 (PLUS_EXPR, TREE_TYPE (s1),
9106                               s1, build_int_cst (TREE_TYPE (s1), r - p1)));
9107           return fold_convert (type, tem);
9108         }
9109
9110       if (! integer_zerop (s2))
9111         return 0;
9112
9113       fn = implicit_built_in_decls[BUILT_IN_STRCHR];
9114       if (!fn)
9115         return 0;
9116
9117       /* Transform strrchr(s1, '\0') to strchr(s1, '\0').  */
9118       return build_function_call_expr (fn, arglist);
9119     }
9120 }
9121
9122 /* Simplify a call to the strpbrk builtin.
9123
9124    Return 0 if no simplification was possible, otherwise return the
9125    simplified form of the call as a tree.
9126
9127    The simplified form may be a constant or other expression which
9128    computes the same value, but in a more efficient manner (including
9129    calls to other builtin functions).
9130
9131    The call may contain arguments which need to be evaluated, but
9132    which are not useful to determine the result of the call.  In
9133    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
9134    COMPOUND_EXPR will be an argument which must be evaluated.
9135    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
9136    COMPOUND_EXPR in the chain will contain the tree for the simplified
9137    form of the builtin function call.  */
9138
9139 static tree
9140 fold_builtin_strpbrk (tree arglist, tree type)
9141 {
9142   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9143     return 0;
9144   else
9145     {
9146       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9147       tree fn;
9148       const char *p1, *p2;
9149
9150       p2 = c_getstr (s2);
9151       if (p2 == NULL)
9152         return 0;
9153
9154       p1 = c_getstr (s1);
9155       if (p1 != NULL)
9156         {
9157           const char *r = strpbrk (p1, p2);
9158           tree tem;
9159
9160           if (r == NULL)
9161             return build_int_cst (TREE_TYPE (s1), 0);
9162
9163           /* Return an offset into the constant string argument.  */
9164           tem = fold (build2 (PLUS_EXPR, TREE_TYPE (s1),
9165                               s1, build_int_cst (TREE_TYPE (s1), r - p1)));
9166           return fold_convert (type, tem);
9167         }
9168
9169       if (p2[0] == '\0')
9170         /* strpbrk(x, "") == NULL.
9171            Evaluate and ignore s1 in case it had side-effects.  */
9172         return omit_one_operand (TREE_TYPE (s1), integer_zero_node, s1);
9173
9174       if (p2[1] != '\0')
9175         return 0;  /* Really call strpbrk.  */
9176
9177       fn = implicit_built_in_decls[BUILT_IN_STRCHR];
9178       if (!fn)
9179         return 0;
9180
9181       /* New argument list transforming strpbrk(s1, s2) to
9182          strchr(s1, s2[0]).  */
9183       arglist = build_tree_list (NULL_TREE,
9184                                  build_int_cst (NULL_TREE, p2[0]));
9185       arglist = tree_cons (NULL_TREE, s1, arglist);
9186       return build_function_call_expr (fn, arglist);
9187     }
9188 }
9189
9190 /* Simplify a call to the strcat builtin.
9191
9192    Return 0 if no simplification was possible, otherwise return the
9193    simplified form of the call as a tree.
9194
9195    The simplified form may be a constant or other expression which
9196    computes the same value, but in a more efficient manner (including
9197    calls to other builtin functions).
9198
9199    The call may contain arguments which need to be evaluated, but
9200    which are not useful to determine the result of the call.  In
9201    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
9202    COMPOUND_EXPR will be an argument which must be evaluated.
9203    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
9204    COMPOUND_EXPR in the chain will contain the tree for the simplified
9205    form of the builtin function call.  */
9206
9207 static tree
9208 fold_builtin_strcat (tree arglist)
9209 {
9210   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9211     return 0;
9212   else
9213     {
9214       tree dst = TREE_VALUE (arglist),
9215         src = TREE_VALUE (TREE_CHAIN (arglist));
9216       const char *p = c_getstr (src);
9217
9218       /* If the string length is zero, return the dst parameter.  */
9219       if (p && *p == '\0')
9220         return dst;
9221
9222       return 0;
9223     }
9224 }
9225
9226 /* Simplify a call to the strncat builtin.
9227
9228    Return 0 if no simplification was possible, otherwise return the
9229    simplified form of the call as a tree.
9230
9231    The simplified form may be a constant or other expression which
9232    computes the same value, but in a more efficient manner (including
9233    calls to other builtin functions).
9234
9235    The call may contain arguments which need to be evaluated, but
9236    which are not useful to determine the result of the call.  In
9237    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
9238    COMPOUND_EXPR will be an argument which must be evaluated.
9239    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
9240    COMPOUND_EXPR in the chain will contain the tree for the simplified
9241    form of the builtin function call.  */
9242
9243 static tree
9244 fold_builtin_strncat (tree arglist)
9245 {
9246   if (!validate_arglist (arglist,
9247                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9248     return 0;
9249   else
9250     {
9251       tree dst = TREE_VALUE (arglist);
9252       tree src = TREE_VALUE (TREE_CHAIN (arglist));
9253       tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
9254       const char *p = c_getstr (src);
9255
9256       /* If the requested length is zero, or the src parameter string
9257           length is zero, return the dst parameter.  */
9258       if (integer_zerop (len) || (p && *p == '\0'))
9259         return omit_two_operands (TREE_TYPE (dst), dst, src, len);
9260
9261       /* If the requested len is greater than or equal to the string
9262          length, call strcat.  */
9263       if (TREE_CODE (len) == INTEGER_CST && p
9264           && compare_tree_int (len, strlen (p)) >= 0)
9265         {
9266           tree newarglist
9267             = tree_cons (NULL_TREE, dst, build_tree_list (NULL_TREE, src));
9268           tree fn = implicit_built_in_decls[BUILT_IN_STRCAT];
9269
9270           /* If the replacement _DECL isn't initialized, don't do the
9271              transformation.  */
9272           if (!fn)
9273             return 0;
9274
9275           return build_function_call_expr (fn, newarglist);
9276         }
9277       return 0;
9278     }
9279 }
9280
9281 /* Simplify a call to the strspn builtin.
9282
9283    Return 0 if no simplification was possible, otherwise return the
9284    simplified form of the call as a tree.
9285
9286    The simplified form may be a constant or other expression which
9287    computes the same value, but in a more efficient manner (including
9288    calls to other builtin functions).
9289
9290    The call may contain arguments which need to be evaluated, but
9291    which are not useful to determine the result of the call.  In
9292    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
9293    COMPOUND_EXPR will be an argument which must be evaluated.
9294    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
9295    COMPOUND_EXPR in the chain will contain the tree for the simplified
9296    form of the builtin function call.  */
9297
9298 static tree
9299 fold_builtin_strspn (tree arglist)
9300 {
9301   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9302     return 0;
9303   else
9304     {
9305       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9306       const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
9307
9308       /* If both arguments are constants, evaluate at compile-time.  */
9309       if (p1 && p2)
9310         {
9311           const size_t r = strspn (p1, p2);
9312           return size_int (r);
9313         }
9314
9315       /* If either argument is "", return 0.  */
9316       if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
9317         /* Evaluate and ignore both arguments in case either one has
9318            side-effects.  */
9319         return omit_two_operands (integer_type_node, integer_zero_node,
9320                                   s1, s2);
9321       return 0;
9322     }
9323 }
9324
9325 /* Simplify a call to the strcspn builtin.
9326
9327    Return 0 if no simplification was possible, otherwise return the
9328    simplified form of the call as a tree.
9329
9330    The simplified form may be a constant or other expression which
9331    computes the same value, but in a more efficient manner (including
9332    calls to other builtin functions).
9333
9334    The call may contain arguments which need to be evaluated, but
9335    which are not useful to determine the result of the call.  In
9336    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
9337    COMPOUND_EXPR will be an argument which must be evaluated.
9338    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
9339    COMPOUND_EXPR in the chain will contain the tree for the simplified
9340    form of the builtin function call.  */
9341
9342 static tree
9343 fold_builtin_strcspn (tree arglist)
9344 {
9345   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9346     return 0;
9347   else
9348     {
9349       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9350       const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
9351
9352       /* If both arguments are constants, evaluate at compile-time.  */
9353       if (p1 && p2)
9354         {
9355           const size_t r = strcspn (p1, p2);
9356           return size_int (r);
9357         }
9358
9359       /* If the first argument is "", return 0.  */
9360       if (p1 && *p1 == '\0')
9361         {
9362           /* Evaluate and ignore argument s2 in case it has
9363              side-effects.  */
9364           return omit_one_operand (integer_type_node,
9365                                    integer_zero_node, s2);
9366         }
9367
9368       /* If the second argument is "", return __builtin_strlen(s1).  */
9369       if (p2 && *p2 == '\0')
9370         {
9371           tree newarglist = build_tree_list (NULL_TREE, s1),
9372             fn = implicit_built_in_decls[BUILT_IN_STRLEN];
9373
9374           /* If the replacement _DECL isn't initialized, don't do the
9375              transformation.  */
9376           if (!fn)
9377             return 0;
9378
9379           return build_function_call_expr (fn, newarglist);
9380         }
9381       return 0;
9382     }
9383 }
9384
9385 /* Fold a call to the fputs builtin.  IGNORE is true if the value returned
9386    by the builtin will be ignored.  UNLOCKED is true is true if this
9387    actually a call to fputs_unlocked.  If LEN in non-NULL, it represents
9388    the known length of the string.  Return NULL_TREE if no simplification
9389    was possible.  */
9390
9391 tree
9392 fold_builtin_fputs (tree arglist, bool ignore, bool unlocked, tree len)
9393 {
9394   tree fn;
9395   tree fn_fputc = unlocked ? implicit_built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
9396     : implicit_built_in_decls[BUILT_IN_FPUTC];
9397   tree fn_fwrite = unlocked ? implicit_built_in_decls[BUILT_IN_FWRITE_UNLOCKED]
9398     : implicit_built_in_decls[BUILT_IN_FWRITE];
9399
9400   /* If the return value is used, or the replacement _DECL isn't
9401      initialized, don't do the transformation.  */
9402   if (!ignore || !fn_fputc || !fn_fwrite)
9403     return 0;
9404
9405   /* Verify the arguments in the original call.  */
9406   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9407     return 0;
9408
9409   if (! len)
9410     len = c_strlen (TREE_VALUE (arglist), 0);
9411
9412   /* Get the length of the string passed to fputs.  If the length
9413      can't be determined, punt.  */
9414   if (!len
9415       || TREE_CODE (len) != INTEGER_CST)
9416     return 0;
9417
9418   switch (compare_tree_int (len, 1))
9419     {
9420     case -1: /* length is 0, delete the call entirely .  */
9421       return omit_one_operand (integer_type_node, integer_zero_node,
9422                                TREE_VALUE (TREE_CHAIN (arglist)));
9423
9424     case 0: /* length is 1, call fputc.  */
9425       {
9426         const char *p = c_getstr (TREE_VALUE (arglist));
9427
9428         if (p != NULL)
9429           {
9430             /* New argument list transforming fputs(string, stream) to
9431                fputc(string[0], stream).  */
9432             arglist = build_tree_list (NULL_TREE,
9433                                        TREE_VALUE (TREE_CHAIN (arglist)));
9434             arglist = tree_cons (NULL_TREE,
9435                                  build_int_cst (NULL_TREE, p[0]),
9436                                  arglist);
9437             fn = fn_fputc;
9438             break;
9439           }
9440       }
9441       /* FALLTHROUGH */
9442     case 1: /* length is greater than 1, call fwrite.  */
9443       {
9444         tree string_arg;
9445
9446         /* If optimizing for size keep fputs.  */
9447         if (optimize_size)
9448           return 0;
9449         string_arg = TREE_VALUE (arglist);
9450         /* New argument list transforming fputs(string, stream) to
9451            fwrite(string, 1, len, stream).  */
9452         arglist = build_tree_list (NULL_TREE,
9453                                    TREE_VALUE (TREE_CHAIN (arglist)));
9454         arglist = tree_cons (NULL_TREE, len, arglist);
9455         arglist = tree_cons (NULL_TREE, size_one_node, arglist);
9456         arglist = tree_cons (NULL_TREE, string_arg, arglist);
9457         fn = fn_fwrite;
9458         break;
9459       }
9460     default:
9461       gcc_unreachable ();
9462     }
9463
9464   /* These optimizations are only performed when the result is ignored,
9465      hence there's no need to cast the result to integer_type_node.  */
9466   return build_function_call_expr (fn, arglist);
9467 }
9468
9469 /* Fold the new_arg's arguments (ARGLIST). Returns true if there was an error
9470    produced.  False otherwise.  This is done so that we don't output the error
9471    or warning twice or three times.  */
9472 bool
9473 fold_builtin_next_arg (tree arglist)
9474 {
9475   tree fntype = TREE_TYPE (current_function_decl);
9476
9477   if (TYPE_ARG_TYPES (fntype) == 0
9478       || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
9479           == void_type_node))
9480     {
9481       error ("%<va_start%> used in function with fixed args");
9482       return true;
9483     }
9484   else if (!arglist)
9485     {
9486       /* Evidently an out of date version of <stdarg.h>; can't validate
9487          va_start's second argument, but can still work as intended.  */
9488       warning ("%<__builtin_next_arg%> called without an argument");
9489       return true;
9490     }
9491   /* We use __builtin_va_start (ap, 0, 0) or __builtin_next_arg (0, 0)
9492      when we checked the arguments and if needed issued a warning.  */
9493   else if (!TREE_CHAIN (arglist)
9494            || !integer_zerop (TREE_VALUE (arglist))
9495            || !integer_zerop (TREE_VALUE (TREE_CHAIN (arglist)))
9496            || TREE_CHAIN (TREE_CHAIN (arglist)))
9497     {
9498       tree last_parm = tree_last (DECL_ARGUMENTS (current_function_decl));
9499       tree arg = TREE_VALUE (arglist);
9500
9501       if (TREE_CHAIN (arglist))
9502         {
9503           error ("%<va_start%> used with too many arguments");
9504           return true;
9505         }
9506
9507       /* Strip off all nops for the sake of the comparison.  This
9508          is not quite the same as STRIP_NOPS.  It does more.
9509          We must also strip off INDIRECT_EXPR for C++ reference
9510          parameters.  */
9511       while (TREE_CODE (arg) == NOP_EXPR
9512              || TREE_CODE (arg) == CONVERT_EXPR
9513              || TREE_CODE (arg) == NON_LVALUE_EXPR
9514              || TREE_CODE (arg) == INDIRECT_REF)
9515         arg = TREE_OPERAND (arg, 0);
9516       if (arg != last_parm)
9517         {
9518           /* FIXME: Sometimes with the tree optimizers we can get the
9519              not the last argument even though the user used the last
9520              argument.  We just warn and set the arg to be the last
9521              argument so that we will get wrong-code because of
9522              it.  */
9523           warning ("second parameter of %<va_start%> not last named argument");
9524         }
9525       /* We want to verify the second parameter just once before the tree
9526          optimizers are run and then avoid keeping it in the tree,
9527          as otherwise we could warn even for correct code like:
9528          void foo (int i, ...)
9529          { va_list ap; i++; va_start (ap, i); va_end (ap); }  */
9530       TREE_VALUE (arglist) = integer_zero_node;
9531       TREE_CHAIN (arglist) = build_tree_list (NULL, integer_zero_node);
9532     }
9533   return false;
9534 }
9535
9536
9537 /* Simplify a call to the sprintf builtin.
9538
9539    Return 0 if no simplification was possible, otherwise return the
9540    simplified form of the call as a tree.  If IGNORED is true, it means that
9541    the caller does not use the returned value of the function.  */
9542
9543 static tree
9544 fold_builtin_sprintf (tree arglist, int ignored)
9545 {
9546   tree call, retval, dest, fmt;
9547   const char *fmt_str = NULL;
9548
9549   /* Verify the required arguments in the original call.  We deal with two
9550      types of sprintf() calls: 'sprintf (str, fmt)' and
9551      'sprintf (dest, "%s", orig)'.  */
9552   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)
9553       && !validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, POINTER_TYPE,
9554                             VOID_TYPE))
9555     return NULL_TREE;
9556
9557   /* Get the destination string and the format specifier.  */
9558   dest = TREE_VALUE (arglist);
9559   fmt = TREE_VALUE (TREE_CHAIN (arglist));
9560
9561   /* Check whether the format is a literal string constant.  */
9562   fmt_str = c_getstr (fmt);
9563   if (fmt_str == NULL)
9564     return NULL_TREE;
9565
9566   call = NULL_TREE;
9567   retval = NULL_TREE;
9568
9569   /* If the format doesn't contain % args or %%, use strcpy.  */
9570   if (strchr (fmt_str, '%') == NULL)
9571     {
9572       tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
9573
9574       if (!fn)
9575         return NULL_TREE;
9576
9577       /* Convert sprintf (str, fmt) into strcpy (str, fmt) when
9578          'format' is known to contain no % formats.  */
9579       arglist = build_tree_list (NULL_TREE, fmt);
9580       arglist = tree_cons (NULL_TREE, dest, arglist);
9581       call = build_function_call_expr (fn, arglist);
9582       if (!ignored)
9583         retval = build_int_cst (NULL_TREE, strlen (fmt_str));
9584     }
9585
9586   /* If the format is "%s", use strcpy if the result isn't used.  */
9587   else if (fmt_str && strcmp (fmt_str, "%s") == 0)
9588     {
9589       tree fn, orig;
9590       fn = implicit_built_in_decls[BUILT_IN_STRCPY];
9591
9592       if (!fn)
9593         return NULL_TREE;
9594
9595       /* Convert sprintf (str1, "%s", str2) into strcpy (str1, str2).  */
9596       orig = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
9597       arglist = build_tree_list (NULL_TREE, orig);
9598       arglist = tree_cons (NULL_TREE, dest, arglist);
9599       if (!ignored)
9600         {
9601           retval = c_strlen (orig, 1);
9602           if (!retval || TREE_CODE (retval) != INTEGER_CST)
9603             return NULL_TREE;
9604         }
9605       call = build_function_call_expr (fn, arglist);
9606     }
9607
9608   if (call && retval)
9609     {
9610       retval = convert
9611         (TREE_TYPE (TREE_TYPE (implicit_built_in_decls[BUILT_IN_SPRINTF])),
9612          retval);
9613       return build2 (COMPOUND_EXPR, TREE_TYPE (retval), call, retval);
9614     }
9615   else
9616     return call;
9617 }