OSDN Git Service

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