OSDN Git Service

* flags.h (flag_short_enums): Update comment.
[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_EXPM1:
1604     case BUILT_IN_EXPM1F:
1605     case BUILT_IN_EXPM1L:
1606       errno_set = true; builtin_optab = expm1_optab; break;
1607     case BUILT_IN_LOGB:
1608     case BUILT_IN_LOGBF:
1609     case BUILT_IN_LOGBL:
1610       errno_set = true; builtin_optab = logb_optab; break;
1611     case BUILT_IN_ILOGB:
1612     case BUILT_IN_ILOGBF:
1613     case BUILT_IN_ILOGBL:
1614       errno_set = true; builtin_optab = ilogb_optab; break;
1615     case BUILT_IN_LOG:
1616     case BUILT_IN_LOGF:
1617     case BUILT_IN_LOGL:
1618       errno_set = true; builtin_optab = log_optab; break;
1619     case BUILT_IN_LOG10:
1620     case BUILT_IN_LOG10F:
1621     case BUILT_IN_LOG10L:
1622       errno_set = true; builtin_optab = log10_optab; break;
1623     case BUILT_IN_LOG2:
1624     case BUILT_IN_LOG2F:
1625     case BUILT_IN_LOG2L:
1626       errno_set = true; builtin_optab = log2_optab; break;
1627     case BUILT_IN_LOG1P:
1628     case BUILT_IN_LOG1PF:
1629     case BUILT_IN_LOG1PL:
1630       errno_set = true; builtin_optab = log1p_optab; break;
1631     case BUILT_IN_ASIN:
1632     case BUILT_IN_ASINF:
1633     case BUILT_IN_ASINL:
1634       builtin_optab = asin_optab; break;
1635     case BUILT_IN_ACOS:
1636     case BUILT_IN_ACOSF:
1637     case BUILT_IN_ACOSL:
1638       builtin_optab = acos_optab; break;
1639     case BUILT_IN_TAN:
1640     case BUILT_IN_TANF:
1641     case BUILT_IN_TANL:
1642       builtin_optab = tan_optab; break;
1643     case BUILT_IN_ATAN:
1644     case BUILT_IN_ATANF:
1645     case BUILT_IN_ATANL:
1646       builtin_optab = atan_optab; break;
1647     case BUILT_IN_FLOOR:
1648     case BUILT_IN_FLOORF:
1649     case BUILT_IN_FLOORL:
1650       builtin_optab = floor_optab; break;
1651     case BUILT_IN_CEIL:
1652     case BUILT_IN_CEILF:
1653     case BUILT_IN_CEILL:
1654       builtin_optab = ceil_optab; break;
1655     case BUILT_IN_TRUNC:
1656     case BUILT_IN_TRUNCF:
1657     case BUILT_IN_TRUNCL:
1658       builtin_optab = btrunc_optab; break;
1659     case BUILT_IN_ROUND:
1660     case BUILT_IN_ROUNDF:
1661     case BUILT_IN_ROUNDL:
1662       builtin_optab = round_optab; break;
1663     case BUILT_IN_NEARBYINT:
1664     case BUILT_IN_NEARBYINTF:
1665     case BUILT_IN_NEARBYINTL:
1666       builtin_optab = nearbyint_optab; break;
1667     default:
1668       abort ();
1669     }
1670
1671   /* Make a suitable register to place result in.  */
1672   mode = TYPE_MODE (TREE_TYPE (exp));
1673
1674   if (! flag_errno_math || ! HONOR_NANS (mode))
1675     errno_set = false;
1676
1677   /* Before working hard, check whether the instruction is available.  */
1678   if (builtin_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1679     {
1680       target = gen_reg_rtx (mode);
1681
1682       /* Wrap the computation of the argument in a SAVE_EXPR, as we may
1683          need to expand the argument again.  This way, we will not perform
1684          side-effects more the once.  */
1685       narg = save_expr (arg);
1686       if (narg != arg)
1687         {
1688           arglist = build_tree_list (NULL_TREE, arg);
1689           exp = build_function_call_expr (fndecl, arglist);
1690         }
1691
1692       op0 = expand_expr (arg, subtarget, VOIDmode, 0);
1693
1694       emit_queue ();
1695       start_sequence ();
1696
1697       /* Compute into TARGET.
1698          Set TARGET to wherever the result comes back.  */
1699       target = expand_unop (mode, builtin_optab, op0, target, 0);
1700
1701       if (target != 0)
1702         {
1703           if (errno_set)
1704             expand_errno_check (exp, target);
1705
1706           /* Output the entire sequence.  */
1707           insns = get_insns ();
1708           end_sequence ();
1709           emit_insn (insns);
1710           return target;
1711         }
1712
1713       /* If we were unable to expand via the builtin, stop the sequence
1714          (without outputting the insns) and call to the library function
1715          with the stabilized argument list.  */
1716       end_sequence ();
1717     }
1718
1719   before_call = get_last_insn ();
1720
1721   target = expand_call (exp, target, target == const0_rtx);
1722
1723   /* If this is a sqrt operation and we don't care about errno, try to
1724      attach a REG_EQUAL note with a SQRT rtx to the emitted libcall.
1725      This allows the semantics of the libcall to be visible to the RTL
1726      optimizers.  */
1727   if (builtin_optab == sqrt_optab && !errno_set)
1728     {
1729       /* Search backwards through the insns emitted by expand_call looking
1730          for the instruction with the REG_RETVAL note.  */
1731       rtx last = get_last_insn ();
1732       while (last != before_call)
1733         {
1734           if (find_reg_note (last, REG_RETVAL, NULL))
1735             {
1736               rtx note = find_reg_note (last, REG_EQUAL, NULL);
1737               /* Check that the REQ_EQUAL note is an EXPR_LIST with
1738                  two elements, i.e. symbol_ref(sqrt) and the operand.  */
1739               if (note
1740                   && GET_CODE (note) == EXPR_LIST
1741                   && GET_CODE (XEXP (note, 0)) == EXPR_LIST
1742                   && XEXP (XEXP (note, 0), 1) != NULL_RTX
1743                   && XEXP (XEXP (XEXP (note, 0), 1), 1) == NULL_RTX)
1744                 {
1745                   rtx operand = XEXP (XEXP (XEXP (note, 0), 1), 0);
1746                   /* Check operand is a register with expected mode.  */
1747                   if (operand
1748                       && GET_CODE (operand) == REG
1749                       && GET_MODE (operand) == mode)
1750                     {
1751                       /* Replace the REG_EQUAL note with a SQRT rtx.  */
1752                       rtx equiv = gen_rtx_SQRT (mode, operand);
1753                       set_unique_reg_note (last, REG_EQUAL, equiv);
1754                     }
1755                 }
1756               break;
1757             }
1758           last = PREV_INSN (last);
1759         }
1760     }
1761
1762   return target;
1763 }
1764
1765 /* Expand a call to the builtin binary math functions (pow and atan2).
1766    Return 0 if a normal call should be emitted rather than expanding the
1767    function in-line.  EXP is the expression that is a call to the builtin
1768    function; if convenient, the result should be placed in TARGET.
1769    SUBTARGET may be used as the target for computing one of EXP's
1770    operands.  */
1771
1772 static rtx
1773 expand_builtin_mathfn_2 (tree exp, rtx target, rtx subtarget)
1774 {
1775   optab builtin_optab;
1776   rtx op0, op1, insns;
1777   tree fndecl = get_callee_fndecl (exp);
1778   tree arglist = TREE_OPERAND (exp, 1);
1779   tree arg0, arg1, temp, narg;
1780   enum machine_mode mode;
1781   bool errno_set = true;
1782   bool stable = true;
1783
1784   if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
1785     return 0;
1786
1787   arg0 = TREE_VALUE (arglist);
1788   arg1 = TREE_VALUE (TREE_CHAIN (arglist));
1789
1790   switch (DECL_FUNCTION_CODE (fndecl))
1791     {
1792     case BUILT_IN_POW:
1793     case BUILT_IN_POWF:
1794     case BUILT_IN_POWL:
1795       builtin_optab = pow_optab; break;
1796     case BUILT_IN_ATAN2:
1797     case BUILT_IN_ATAN2F:
1798     case BUILT_IN_ATAN2L:
1799       builtin_optab = atan2_optab; break;
1800     case BUILT_IN_FMOD:
1801     case BUILT_IN_FMODF:
1802     case BUILT_IN_FMODL:
1803       builtin_optab = fmod_optab; break;
1804     case BUILT_IN_DREM:
1805     case BUILT_IN_DREMF:
1806     case BUILT_IN_DREML:
1807       builtin_optab = drem_optab; break;
1808     default:
1809       abort ();
1810     }
1811
1812   /* Make a suitable register to place result in.  */
1813   mode = TYPE_MODE (TREE_TYPE (exp));
1814
1815   /* Before working hard, check whether the instruction is available.  */
1816   if (builtin_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing)
1817     return 0;
1818
1819   target = gen_reg_rtx (mode);
1820
1821   if (! flag_errno_math || ! HONOR_NANS (mode))
1822     errno_set = false;
1823
1824   /* Alway stabilize the argument list.  */
1825   narg = save_expr (arg1);
1826   if (narg != arg1)
1827     {
1828       temp = build_tree_list (NULL_TREE, narg);
1829       stable = false;
1830     }
1831   else
1832     temp = TREE_CHAIN (arglist);
1833
1834   narg = save_expr (arg0);
1835   if (narg != arg0)
1836     {
1837       arglist = tree_cons (NULL_TREE, narg, temp);
1838       stable = false;
1839     }
1840   else if (! stable)
1841     arglist = tree_cons (NULL_TREE, arg0, temp);
1842
1843   if (! stable)
1844     exp = build_function_call_expr (fndecl, arglist);
1845
1846   op0 = expand_expr (arg0, subtarget, VOIDmode, 0);
1847   op1 = expand_expr (arg1, 0, VOIDmode, 0);
1848
1849   emit_queue ();
1850   start_sequence ();
1851
1852   /* Compute into TARGET.
1853      Set TARGET to wherever the result comes back.  */
1854   target = expand_binop (mode, builtin_optab, op0, op1,
1855                          target, 0, OPTAB_DIRECT);
1856
1857   /* If we were unable to expand via the builtin, stop the sequence
1858      (without outputting the insns) and call to the library function
1859      with the stabilized argument list.  */
1860   if (target == 0)
1861     {
1862       end_sequence ();
1863       return expand_call (exp, target, target == const0_rtx);
1864     }
1865
1866   if (errno_set)
1867     expand_errno_check (exp, target);
1868
1869   /* Output the entire sequence.  */
1870   insns = get_insns ();
1871   end_sequence ();
1872   emit_insn (insns);
1873
1874   return target;
1875 }
1876
1877 /* Expand a call to the builtin sin and cos math functions.
1878    Return 0 if a normal call should be emitted rather than expanding the
1879    function in-line.  EXP is the expression that is a call to the builtin
1880    function; if convenient, the result should be placed in TARGET.
1881    SUBTARGET may be used as the target for computing one of EXP's
1882    operands.  */
1883
1884 static rtx
1885 expand_builtin_mathfn_3 (tree exp, rtx target, rtx subtarget)
1886 {
1887   optab builtin_optab;
1888   rtx op0, insns, before_call;
1889   tree fndecl = get_callee_fndecl (exp);
1890   tree arglist = TREE_OPERAND (exp, 1);
1891   enum machine_mode mode;
1892   bool errno_set = false;
1893   tree arg, narg;
1894
1895   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
1896     return 0;
1897
1898   arg = TREE_VALUE (arglist);
1899
1900   switch (DECL_FUNCTION_CODE (fndecl))
1901     {
1902     case BUILT_IN_SIN:
1903     case BUILT_IN_SINF:
1904     case BUILT_IN_SINL:
1905     case BUILT_IN_COS:
1906     case BUILT_IN_COSF:
1907     case BUILT_IN_COSL:
1908       builtin_optab = sincos_optab; break;
1909     default:
1910       abort ();
1911     }
1912
1913   /* Make a suitable register to place result in.  */
1914   mode = TYPE_MODE (TREE_TYPE (exp));
1915
1916   if (! flag_errno_math || ! HONOR_NANS (mode))
1917     errno_set = false;
1918
1919   /* Check if sincos insn is available, otherwise fallback
1920      to sin or cos insn. */
1921   if (builtin_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing) {
1922     switch (DECL_FUNCTION_CODE (fndecl))
1923       {
1924       case BUILT_IN_SIN:
1925       case BUILT_IN_SINF:
1926       case BUILT_IN_SINL:
1927         builtin_optab = sin_optab; break;
1928       case BUILT_IN_COS:
1929       case BUILT_IN_COSF:
1930       case BUILT_IN_COSL:
1931         builtin_optab = cos_optab; break;
1932       default:
1933         abort();
1934       }
1935   }
1936
1937   /* Before working hard, check whether the instruction is available.  */
1938   if (builtin_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1939     {
1940       target = gen_reg_rtx (mode);
1941
1942       /* Wrap the computation of the argument in a SAVE_EXPR, as we may
1943          need to expand the argument again.  This way, we will not perform
1944          side-effects more the once.  */
1945       narg = save_expr (arg);
1946       if (narg != arg)
1947         {
1948           arglist = build_tree_list (NULL_TREE, arg);
1949           exp = build_function_call_expr (fndecl, arglist);
1950         }
1951
1952       op0 = expand_expr (arg, subtarget, VOIDmode, 0);
1953
1954       emit_queue ();
1955       start_sequence ();
1956
1957       /* Compute into TARGET.
1958          Set TARGET to wherever the result comes back.  */
1959       if (builtin_optab == sincos_optab)
1960         {
1961           switch (DECL_FUNCTION_CODE (fndecl))
1962             {
1963             case BUILT_IN_SIN:
1964             case BUILT_IN_SINF:
1965             case BUILT_IN_SINL:
1966               if (!expand_twoval_unop (builtin_optab, op0, 0, target, 0))    
1967                 abort();
1968               break;
1969             case BUILT_IN_COS:
1970             case BUILT_IN_COSF:
1971             case BUILT_IN_COSL:
1972               if (!expand_twoval_unop (builtin_optab, op0, target, 0, 0))
1973                 abort();
1974               break;
1975             default:
1976               abort();
1977             }
1978         }
1979       else
1980         {
1981           target = expand_unop (mode, builtin_optab, op0, target, 0);
1982         }
1983
1984       if (target != 0)
1985         {
1986           if (errno_set)
1987             expand_errno_check (exp, target);
1988
1989           /* Output the entire sequence.  */
1990           insns = get_insns ();
1991           end_sequence ();
1992           emit_insn (insns);
1993           return target;
1994         }
1995
1996       /* If we were unable to expand via the builtin, stop the sequence
1997          (without outputting the insns) and call to the library function
1998          with the stabilized argument list.  */
1999       end_sequence ();
2000     }
2001
2002   before_call = get_last_insn ();
2003
2004   target = expand_call (exp, target, target == const0_rtx);
2005
2006   return target;
2007 }
2008
2009 /* To evaluate powi(x,n), the floating point value x raised to the
2010    constant integer exponent n, we use a hybrid algorithm that
2011    combines the "window method" with look-up tables.  For an
2012    introduction to exponentiation algorithms and "addition chains",
2013    see section 4.6.3, "Evaluation of Powers" of Donald E. Knuth,
2014    "Seminumerical Algorithms", Vol. 2, "The Art of Computer Programming",
2015    3rd Edition, 1998, and Daniel M. Gordon, "A Survey of Fast Exponentiation
2016    Methods", Journal of Algorithms, Vol. 27, pp. 129-146, 1998.  */
2017
2018 /* Provide a default value for POWI_MAX_MULTS, the maximum number of
2019    multiplications to inline before calling the system library's pow
2020    function.  powi(x,n) requires at worst 2*bits(n)-2 multiplications,
2021    so this default never requires calling pow, powf or powl.  */
2022
2023 #ifndef POWI_MAX_MULTS
2024 #define POWI_MAX_MULTS  (2*HOST_BITS_PER_WIDE_INT-2)
2025 #endif
2026
2027 /* The size of the "optimal power tree" lookup table.  All
2028    exponents less than this value are simply looked up in the
2029    powi_table below.  This threshold is also used to size the
2030    cache of pseudo registers that hold intermediate results.  */
2031 #define POWI_TABLE_SIZE 256
2032
2033 /* The size, in bits of the window, used in the "window method"
2034    exponentiation algorithm.  This is equivalent to a radix of
2035    (1<<POWI_WINDOW_SIZE) in the corresponding "m-ary method".  */
2036 #define POWI_WINDOW_SIZE 3
2037
2038 /* The following table is an efficient representation of an
2039    "optimal power tree".  For each value, i, the corresponding
2040    value, j, in the table states than an optimal evaluation
2041    sequence for calculating pow(x,i) can be found by evaluating
2042    pow(x,j)*pow(x,i-j).  An optimal power tree for the first
2043    100 integers is given in Knuth's "Seminumerical algorithms".  */
2044
2045 static const unsigned char powi_table[POWI_TABLE_SIZE] =
2046   {
2047       0,   1,   1,   2,   2,   3,   3,   4,  /*   0 -   7 */
2048       4,   6,   5,   6,   6,  10,   7,   9,  /*   8 -  15 */
2049       8,  16,   9,  16,  10,  12,  11,  13,  /*  16 -  23 */
2050      12,  17,  13,  18,  14,  24,  15,  26,  /*  24 -  31 */
2051      16,  17,  17,  19,  18,  33,  19,  26,  /*  32 -  39 */
2052      20,  25,  21,  40,  22,  27,  23,  44,  /*  40 -  47 */
2053      24,  32,  25,  34,  26,  29,  27,  44,  /*  48 -  55 */
2054      28,  31,  29,  34,  30,  60,  31,  36,  /*  56 -  63 */
2055      32,  64,  33,  34,  34,  46,  35,  37,  /*  64 -  71 */
2056      36,  65,  37,  50,  38,  48,  39,  69,  /*  72 -  79 */
2057      40,  49,  41,  43,  42,  51,  43,  58,  /*  80 -  87 */
2058      44,  64,  45,  47,  46,  59,  47,  76,  /*  88 -  95 */
2059      48,  65,  49,  66,  50,  67,  51,  66,  /*  96 - 103 */
2060      52,  70,  53,  74,  54, 104,  55,  74,  /* 104 - 111 */
2061      56,  64,  57,  69,  58,  78,  59,  68,  /* 112 - 119 */
2062      60,  61,  61,  80,  62,  75,  63,  68,  /* 120 - 127 */
2063      64,  65,  65, 128,  66, 129,  67,  90,  /* 128 - 135 */
2064      68,  73,  69, 131,  70,  94,  71,  88,  /* 136 - 143 */
2065      72, 128,  73,  98,  74, 132,  75, 121,  /* 144 - 151 */
2066      76, 102,  77, 124,  78, 132,  79, 106,  /* 152 - 159 */
2067      80,  97,  81, 160,  82,  99,  83, 134,  /* 160 - 167 */
2068      84,  86,  85,  95,  86, 160,  87, 100,  /* 168 - 175 */
2069      88, 113,  89,  98,  90, 107,  91, 122,  /* 176 - 183 */
2070      92, 111,  93, 102,  94, 126,  95, 150,  /* 184 - 191 */
2071      96, 128,  97, 130,  98, 133,  99, 195,  /* 192 - 199 */
2072     100, 128, 101, 123, 102, 164, 103, 138,  /* 200 - 207 */
2073     104, 145, 105, 146, 106, 109, 107, 149,  /* 208 - 215 */
2074     108, 200, 109, 146, 110, 170, 111, 157,  /* 216 - 223 */
2075     112, 128, 113, 130, 114, 182, 115, 132,  /* 224 - 231 */
2076     116, 200, 117, 132, 118, 158, 119, 206,  /* 232 - 239 */
2077     120, 240, 121, 162, 122, 147, 123, 152,  /* 240 - 247 */
2078     124, 166, 125, 214, 126, 138, 127, 153,  /* 248 - 255 */
2079   };
2080
2081
2082 /* Return the number of multiplications required to calculate
2083    powi(x,n) where n is less than POWI_TABLE_SIZE.  This is a
2084    subroutine of powi_cost.  CACHE is an array indicating
2085    which exponents have already been calculated.  */
2086
2087 static int
2088 powi_lookup_cost (unsigned HOST_WIDE_INT n, bool *cache)
2089 {
2090   /* If we've already calculated this exponent, then this evaluation
2091      doesn't require any additional multiplications.  */
2092   if (cache[n])
2093     return 0;
2094
2095   cache[n] = true;
2096   return powi_lookup_cost (n - powi_table[n], cache)
2097          + powi_lookup_cost (powi_table[n], cache) + 1;
2098 }
2099
2100 /* Return the number of multiplications required to calculate
2101    powi(x,n) for an arbitrary x, given the exponent N.  This
2102    function needs to be kept in sync with expand_powi below.  */
2103
2104 static int
2105 powi_cost (HOST_WIDE_INT n)
2106 {
2107   bool cache[POWI_TABLE_SIZE];
2108   unsigned HOST_WIDE_INT digit;
2109   unsigned HOST_WIDE_INT val;
2110   int result;
2111
2112   if (n == 0)
2113     return 0;
2114
2115   /* Ignore the reciprocal when calculating the cost.  */
2116   val = (n < 0) ? -n : n;
2117
2118   /* Initialize the exponent cache.  */
2119   memset (cache, 0, POWI_TABLE_SIZE * sizeof (bool));
2120   cache[1] = true;
2121
2122   result = 0;
2123
2124   while (val >= POWI_TABLE_SIZE)
2125     {
2126       if (val & 1)
2127         {
2128           digit = val & ((1 << POWI_WINDOW_SIZE) - 1);
2129           result += powi_lookup_cost (digit, cache)
2130                     + POWI_WINDOW_SIZE + 1;
2131           val >>= POWI_WINDOW_SIZE;
2132         }
2133       else
2134         {
2135           val >>= 1;
2136           result++;
2137         }
2138     }
2139
2140   return result + powi_lookup_cost (val, cache);
2141 }
2142
2143 /* Recursive subroutine of expand_powi.  This function takes the array,
2144    CACHE, of already calculated exponents and an exponent N and returns
2145    an RTX that corresponds to CACHE[1]**N, as calculated in mode MODE.  */
2146
2147 static rtx
2148 expand_powi_1 (enum machine_mode mode, unsigned HOST_WIDE_INT n, rtx *cache)
2149 {
2150   unsigned HOST_WIDE_INT digit;
2151   rtx target, result;
2152   rtx op0, op1;
2153
2154   if (n < POWI_TABLE_SIZE)
2155     {
2156       if (cache[n])
2157         return cache[n];
2158
2159       target = gen_reg_rtx (mode);
2160       cache[n] = target;
2161
2162       op0 = expand_powi_1 (mode, n - powi_table[n], cache);
2163       op1 = expand_powi_1 (mode, powi_table[n], cache);
2164     }
2165   else if (n & 1)
2166     {
2167       target = gen_reg_rtx (mode);
2168       digit = n & ((1 << POWI_WINDOW_SIZE) - 1);
2169       op0 = expand_powi_1 (mode, n - digit, cache);
2170       op1 = expand_powi_1 (mode, digit, cache);
2171     }
2172   else
2173     {
2174       target = gen_reg_rtx (mode);
2175       op0 = expand_powi_1 (mode, n >> 1, cache);
2176       op1 = op0;
2177     }
2178
2179   result = expand_mult (mode, op0, op1, target, 0);
2180   if (result != target)
2181     emit_move_insn (target, result);
2182   return target;
2183 }
2184
2185 /* Expand the RTL to evaluate powi(x,n) in mode MODE.  X is the
2186    floating point operand in mode MODE, and N is the exponent.  This
2187    function needs to be kept in sync with powi_cost above.  */
2188
2189 static rtx
2190 expand_powi (rtx x, enum machine_mode mode, HOST_WIDE_INT n)
2191 {
2192   unsigned HOST_WIDE_INT val;
2193   rtx cache[POWI_TABLE_SIZE];
2194   rtx result;
2195
2196   if (n == 0)
2197     return CONST1_RTX (mode);
2198
2199   val = (n < 0) ? -n : n;
2200
2201   memset (cache, 0, sizeof (cache));
2202   cache[1] = x;
2203
2204   result = expand_powi_1 (mode, (n < 0) ? -n : n, cache);
2205
2206   /* If the original exponent was negative, reciprocate the result.  */
2207   if (n < 0)
2208     result = expand_binop (mode, sdiv_optab, CONST1_RTX (mode),
2209                            result, NULL_RTX, 0, OPTAB_LIB_WIDEN);
2210
2211   return result;
2212 }
2213
2214 /* Expand a call to the pow built-in mathematical function.  Return 0 if
2215    a normal call should be emitted rather than expanding the function
2216    in-line.  EXP is the expression that is a call to the builtin
2217    function; if convenient, the result should be placed in TARGET.  */
2218
2219 static rtx
2220 expand_builtin_pow (tree exp, rtx target, rtx subtarget)
2221 {
2222   tree arglist = TREE_OPERAND (exp, 1);
2223   tree arg0, arg1;
2224
2225   if (! validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
2226     return 0;
2227
2228   arg0 = TREE_VALUE (arglist);
2229   arg1 = TREE_VALUE (TREE_CHAIN (arglist));
2230
2231   if (TREE_CODE (arg1) == REAL_CST
2232       && ! TREE_CONSTANT_OVERFLOW (arg1))
2233     {
2234       REAL_VALUE_TYPE cint;
2235       REAL_VALUE_TYPE c;
2236       HOST_WIDE_INT n;
2237
2238       c = TREE_REAL_CST (arg1);
2239       n = real_to_integer (&c);
2240       real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
2241       if (real_identical (&c, &cint))
2242         {
2243           /* If the exponent is -1, 0, 1 or 2, then expand_powi is exact.
2244              Otherwise, check the number of multiplications required.
2245              Note that pow never sets errno for an integer exponent.  */
2246           if ((n >= -1 && n <= 2)
2247               || (flag_unsafe_math_optimizations
2248                   && ! optimize_size
2249                   && powi_cost (n) <= POWI_MAX_MULTS))
2250             {
2251               enum machine_mode mode = TYPE_MODE (TREE_TYPE (exp));
2252               rtx op = expand_expr (arg0, subtarget, VOIDmode, 0);
2253               op = force_reg (mode, op);
2254               return expand_powi (op, mode, n);
2255             }
2256         }
2257     }
2258
2259   if (! flag_unsafe_math_optimizations)
2260     return NULL_RTX;
2261   return expand_builtin_mathfn_2 (exp, target, subtarget);
2262 }
2263
2264 /* Expand expression EXP which is a call to the strlen builtin.  Return 0
2265    if we failed the caller should emit a normal call, otherwise
2266    try to get the result in TARGET, if convenient.  */
2267
2268 static rtx
2269 expand_builtin_strlen (tree arglist, rtx target,
2270                        enum machine_mode target_mode)
2271 {
2272   if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
2273     return 0;
2274   else
2275     {
2276       rtx pat;
2277       tree len, src = TREE_VALUE (arglist);
2278       rtx result, src_reg, char_rtx, before_strlen;
2279       enum machine_mode insn_mode = target_mode, char_mode;
2280       enum insn_code icode = CODE_FOR_nothing;
2281       int align;
2282
2283       /* If the length can be computed at compile-time, return it.  */
2284       len = c_strlen (src, 0);
2285       if (len)
2286         return expand_expr (len, target, target_mode, EXPAND_NORMAL);
2287
2288       /* If the length can be computed at compile-time and is constant
2289          integer, but there are side-effects in src, evaluate
2290          src for side-effects, then return len.
2291          E.g. x = strlen (i++ ? "xfoo" + 1 : "bar");
2292          can be optimized into: i++; x = 3;  */
2293       len = c_strlen (src, 1);
2294       if (len && TREE_CODE (len) == INTEGER_CST)
2295         {
2296           expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
2297           return expand_expr (len, target, target_mode, EXPAND_NORMAL);
2298         }
2299
2300       align = get_pointer_alignment (src, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
2301
2302       /* If SRC is not a pointer type, don't do this operation inline.  */
2303       if (align == 0)
2304         return 0;
2305
2306       /* Bail out if we can't compute strlen in the right mode.  */
2307       while (insn_mode != VOIDmode)
2308         {
2309           icode = strlen_optab->handlers[(int) insn_mode].insn_code;
2310           if (icode != CODE_FOR_nothing)
2311             break;
2312
2313           insn_mode = GET_MODE_WIDER_MODE (insn_mode);
2314         }
2315       if (insn_mode == VOIDmode)
2316         return 0;
2317
2318       /* Make a place to write the result of the instruction.  */
2319       result = target;
2320       if (! (result != 0
2321              && GET_CODE (result) == REG
2322              && GET_MODE (result) == insn_mode
2323              && REGNO (result) >= FIRST_PSEUDO_REGISTER))
2324         result = gen_reg_rtx (insn_mode);
2325
2326       /* Make a place to hold the source address.  We will not expand
2327          the actual source until we are sure that the expansion will
2328          not fail -- there are trees that cannot be expanded twice.  */
2329       src_reg = gen_reg_rtx (Pmode);
2330
2331       /* Mark the beginning of the strlen sequence so we can emit the
2332          source operand later.  */
2333       before_strlen = get_last_insn ();
2334
2335       char_rtx = const0_rtx;
2336       char_mode = insn_data[(int) icode].operand[2].mode;
2337       if (! (*insn_data[(int) icode].operand[2].predicate) (char_rtx,
2338                                                             char_mode))
2339         char_rtx = copy_to_mode_reg (char_mode, char_rtx);
2340
2341       pat = GEN_FCN (icode) (result, gen_rtx_MEM (BLKmode, src_reg),
2342                              char_rtx, GEN_INT (align));
2343       if (! pat)
2344         return 0;
2345       emit_insn (pat);
2346
2347       /* Now that we are assured of success, expand the source.  */
2348       start_sequence ();
2349       pat = memory_address (BLKmode,
2350                             expand_expr (src, src_reg, ptr_mode, EXPAND_SUM));
2351       if (pat != src_reg)
2352         emit_move_insn (src_reg, pat);
2353       pat = get_insns ();
2354       end_sequence ();
2355
2356       if (before_strlen)
2357         emit_insn_after (pat, before_strlen);
2358       else
2359         emit_insn_before (pat, get_insns ());
2360
2361       /* Return the value in the proper mode for this function.  */
2362       if (GET_MODE (result) == target_mode)
2363         target = result;
2364       else if (target != 0)
2365         convert_move (target, result, 0);
2366       else
2367         target = convert_to_mode (target_mode, result, 0);
2368
2369       return target;
2370     }
2371 }
2372
2373 /* Expand a call to the strstr builtin.  Return 0 if we failed the
2374    caller should emit a normal call, otherwise try to get the result
2375    in TARGET, if convenient (and in mode MODE if that's convenient).  */
2376
2377 static rtx
2378 expand_builtin_strstr (tree arglist, rtx target, enum machine_mode mode)
2379 {
2380   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2381     return 0;
2382   else
2383     {
2384       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
2385       tree fn;
2386       const char *p1, *p2;
2387
2388       p2 = c_getstr (s2);
2389       if (p2 == NULL)
2390         return 0;
2391
2392       p1 = c_getstr (s1);
2393       if (p1 != NULL)
2394         {
2395           const char *r = strstr (p1, p2);
2396
2397           if (r == NULL)
2398             return const0_rtx;
2399
2400           /* Return an offset into the constant string argument.  */
2401           return expand_expr (fold (build (PLUS_EXPR, TREE_TYPE (s1), s1,
2402                                            fold_convert (TREE_TYPE (s1),
2403                                                          ssize_int (r - p1)))),
2404                               target, mode, EXPAND_NORMAL);
2405         }
2406
2407       if (p2[0] == '\0')
2408         return expand_expr (s1, target, mode, EXPAND_NORMAL);
2409
2410       if (p2[1] != '\0')
2411         return 0;
2412
2413       fn = implicit_built_in_decls[BUILT_IN_STRCHR];
2414       if (!fn)
2415         return 0;
2416
2417       /* New argument list transforming strstr(s1, s2) to
2418          strchr(s1, s2[0]).  */
2419       arglist =
2420         build_tree_list (NULL_TREE, build_int_2 (p2[0], 0));
2421       arglist = tree_cons (NULL_TREE, s1, arglist);
2422       return expand_expr (build_function_call_expr (fn, arglist),
2423                           target, mode, EXPAND_NORMAL);
2424     }
2425 }
2426
2427 /* Expand a call to the strchr builtin.  Return 0 if we failed the
2428    caller should emit a normal call, otherwise try to get the result
2429    in TARGET, if convenient (and in mode MODE if that's convenient).  */
2430
2431 static rtx
2432 expand_builtin_strchr (tree arglist, rtx target, enum machine_mode mode)
2433 {
2434   if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2435     return 0;
2436   else
2437     {
2438       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
2439       const char *p1;
2440
2441       if (TREE_CODE (s2) != INTEGER_CST)
2442         return 0;
2443
2444       p1 = c_getstr (s1);
2445       if (p1 != NULL)
2446         {
2447           char c;
2448           const char *r;
2449
2450           if (target_char_cast (s2, &c))
2451             return 0;
2452
2453           r = strchr (p1, c);
2454
2455           if (r == NULL)
2456             return const0_rtx;
2457
2458           /* Return an offset into the constant string argument.  */
2459           return expand_expr (fold (build (PLUS_EXPR, TREE_TYPE (s1), s1,
2460                                            fold_convert (TREE_TYPE (s1),
2461                                                          ssize_int (r - p1)))),
2462                               target, mode, EXPAND_NORMAL);
2463         }
2464
2465       /* FIXME: Should use here strchrM optab so that ports can optimize
2466          this.  */
2467       return 0;
2468     }
2469 }
2470
2471 /* Expand a call to the strrchr builtin.  Return 0 if we failed the
2472    caller should emit a normal call, otherwise try to get the result
2473    in TARGET, if convenient (and in mode MODE if that's convenient).  */
2474
2475 static rtx
2476 expand_builtin_strrchr (tree arglist, rtx target, enum machine_mode mode)
2477 {
2478   if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2479     return 0;
2480   else
2481     {
2482       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
2483       tree fn;
2484       const char *p1;
2485
2486       if (TREE_CODE (s2) != INTEGER_CST)
2487         return 0;
2488
2489       p1 = c_getstr (s1);
2490       if (p1 != NULL)
2491         {
2492           char c;
2493           const char *r;
2494
2495           if (target_char_cast (s2, &c))
2496             return 0;
2497
2498           r = strrchr (p1, c);
2499
2500           if (r == NULL)
2501             return const0_rtx;
2502
2503           /* Return an offset into the constant string argument.  */
2504           return expand_expr (fold (build (PLUS_EXPR, TREE_TYPE (s1), s1,
2505                                            fold_convert (TREE_TYPE (s1),
2506                                                          ssize_int (r - p1)))),
2507                               target, mode, EXPAND_NORMAL);
2508         }
2509
2510       if (! integer_zerop (s2))
2511         return 0;
2512
2513       fn = implicit_built_in_decls[BUILT_IN_STRCHR];
2514       if (!fn)
2515         return 0;
2516
2517       /* Transform strrchr(s1, '\0') to strchr(s1, '\0').  */
2518       return expand_expr (build_function_call_expr (fn, arglist),
2519                           target, mode, EXPAND_NORMAL);
2520     }
2521 }
2522
2523 /* Expand a call to the strpbrk builtin.  Return 0 if we failed the
2524    caller should emit a normal call, otherwise try to get the result
2525    in TARGET, if convenient (and in mode MODE if that's convenient).  */
2526
2527 static rtx
2528 expand_builtin_strpbrk (tree arglist, rtx target, enum machine_mode mode)
2529 {
2530   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2531     return 0;
2532   else
2533     {
2534       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
2535       tree fn;
2536       const char *p1, *p2;
2537
2538       p2 = c_getstr (s2);
2539       if (p2 == NULL)
2540         return 0;
2541
2542       p1 = c_getstr (s1);
2543       if (p1 != NULL)
2544         {
2545           const char *r = strpbrk (p1, p2);
2546
2547           if (r == NULL)
2548             return const0_rtx;
2549
2550           /* Return an offset into the constant string argument.  */
2551           return expand_expr (fold (build (PLUS_EXPR, TREE_TYPE (s1), s1,
2552                                            fold_convert (TREE_TYPE (s1),
2553                                                          ssize_int (r - p1)))),
2554                               target, mode, EXPAND_NORMAL);
2555         }
2556
2557       if (p2[0] == '\0')
2558         {
2559           /* strpbrk(x, "") == NULL.
2560              Evaluate and ignore the arguments in case they had
2561              side-effects.  */
2562           expand_expr (s1, const0_rtx, VOIDmode, EXPAND_NORMAL);
2563           return const0_rtx;
2564         }
2565
2566       if (p2[1] != '\0')
2567         return 0;  /* Really call strpbrk.  */
2568
2569       fn = implicit_built_in_decls[BUILT_IN_STRCHR];
2570       if (!fn)
2571         return 0;
2572
2573       /* New argument list transforming strpbrk(s1, s2) to
2574          strchr(s1, s2[0]).  */
2575       arglist =
2576         build_tree_list (NULL_TREE, build_int_2 (p2[0], 0));
2577       arglist = tree_cons (NULL_TREE, s1, arglist);
2578       return expand_expr (build_function_call_expr (fn, arglist),
2579                           target, mode, EXPAND_NORMAL);
2580     }
2581 }
2582
2583 /* Callback routine for store_by_pieces.  Read GET_MODE_BITSIZE (MODE)
2584    bytes from constant string DATA + OFFSET and return it as target
2585    constant.  */
2586
2587 static rtx
2588 builtin_memcpy_read_str (void *data, HOST_WIDE_INT offset,
2589                          enum machine_mode mode)
2590 {
2591   const char *str = (const char *) data;
2592
2593   if (offset < 0
2594       || ((unsigned HOST_WIDE_INT) offset + GET_MODE_SIZE (mode)
2595           > strlen (str) + 1))
2596     abort ();  /* Attempt to read past the end of constant string.  */
2597
2598   return c_readstr (str + offset, mode);
2599 }
2600
2601 /* Expand a call to the memcpy builtin, with arguments in ARGLIST.
2602    Return 0 if we failed, the caller should emit a normal call,
2603    otherwise try to get the result in TARGET, if convenient (and in
2604    mode MODE if that's convenient).  */
2605 static rtx
2606 expand_builtin_memcpy (tree arglist, rtx target, enum machine_mode mode)
2607 {
2608   if (!validate_arglist (arglist,
2609                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2610     return 0;
2611   else
2612     {
2613       tree dest = TREE_VALUE (arglist);
2614       tree src = TREE_VALUE (TREE_CHAIN (arglist));
2615       tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2616       const char *src_str;
2617       unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
2618       unsigned int dest_align
2619         = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2620       rtx dest_mem, src_mem, dest_addr, len_rtx;
2621
2622       /* If DEST is not a pointer type, call the normal function.  */
2623       if (dest_align == 0)
2624         return 0;
2625
2626       /* If the LEN parameter is zero, return DEST.  */
2627       if (integer_zerop (len))
2628         {
2629           /* Evaluate and ignore SRC in case it has side-effects.  */
2630           expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
2631           return expand_expr (dest, target, mode, EXPAND_NORMAL);
2632         }
2633
2634       /* If SRC and DEST are the same (and not volatile), return DEST.  */
2635       if (operand_equal_p (src, dest, 0))
2636         {
2637           /* Evaluate and ignore LEN in case it has side-effects.  */
2638           expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
2639           return expand_expr (dest, target, mode, EXPAND_NORMAL);
2640         }
2641
2642       /* If either SRC is not a pointer type, don't do this
2643          operation in-line.  */
2644       if (src_align == 0)
2645         return 0;
2646
2647       dest_mem = get_memory_rtx (dest);
2648       set_mem_align (dest_mem, dest_align);
2649       len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
2650       src_str = c_getstr (src);
2651
2652       /* If SRC is a string constant and block move would be done
2653          by pieces, we can avoid loading the string from memory
2654          and only stored the computed constants.  */
2655       if (src_str
2656           && GET_CODE (len_rtx) == CONST_INT
2657           && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
2658           && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
2659                                   (void *) src_str, dest_align))
2660         {
2661           dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
2662                                       builtin_memcpy_read_str,
2663                                       (void *) src_str, dest_align, 0);
2664           dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2665           dest_mem = convert_memory_address (ptr_mode, dest_mem);
2666           return dest_mem;
2667         }
2668
2669       src_mem = get_memory_rtx (src);
2670       set_mem_align (src_mem, src_align);
2671
2672       /* Copy word part most expediently.  */
2673       dest_addr = emit_block_move (dest_mem, src_mem, len_rtx,
2674                                    BLOCK_OP_NORMAL);
2675
2676       if (dest_addr == 0)
2677         {
2678           dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2679           dest_addr = convert_memory_address (ptr_mode, dest_addr);
2680         }
2681       return dest_addr;
2682     }
2683 }
2684
2685 /* Expand a call to the mempcpy builtin, with arguments in ARGLIST.
2686    Return 0 if we failed the caller should emit a normal call,
2687    otherwise try to get the result in TARGET, if convenient (and in
2688    mode MODE if that's convenient).  If ENDP is 0 return the
2689    destination pointer, if ENDP is 1 return the end pointer ala
2690    mempcpy, and if ENDP is 2 return the end pointer minus one ala
2691    stpcpy.  */
2692
2693 static rtx
2694 expand_builtin_mempcpy (tree arglist, rtx target, enum machine_mode mode,
2695                         int endp)
2696 {
2697   if (!validate_arglist (arglist,
2698                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2699     return 0;
2700   /* If return value is ignored, transform mempcpy into memcpy.  */
2701   else if (target == const0_rtx)
2702     {
2703       tree fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
2704
2705       if (!fn)
2706         return 0;
2707
2708       return expand_expr (build_function_call_expr (fn, arglist),
2709                           target, mode, EXPAND_NORMAL);
2710     }
2711   else
2712     {
2713       tree dest = TREE_VALUE (arglist);
2714       tree src = TREE_VALUE (TREE_CHAIN (arglist));
2715       tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2716       const char *src_str;
2717       unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
2718       unsigned int dest_align
2719         = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2720       rtx dest_mem, src_mem, len_rtx;
2721
2722       /* If DEST is not a pointer type, call the normal function.  */
2723       if (dest_align == 0)
2724         return 0;
2725
2726       /* If SRC and DEST are the same (and not volatile), do nothing.  */
2727       if (operand_equal_p (src, dest, 0))
2728         {
2729           tree expr;
2730
2731           if (endp == 0)
2732             {
2733               /* Evaluate and ignore LEN in case it has side-effects.  */
2734               expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
2735               return expand_expr (dest, target, mode, EXPAND_NORMAL);
2736             }
2737
2738           if (endp == 2)
2739             len = fold (build (MINUS_EXPR, TREE_TYPE (len), dest,
2740                                integer_one_node));
2741           len = fold_convert (TREE_TYPE (dest), len);
2742           expr = fold (build (PLUS_EXPR, TREE_TYPE (dest), dest, len));
2743           return expand_expr (expr, target, mode, EXPAND_NORMAL);
2744         }
2745
2746       /* If LEN is not constant, call the normal function.  */
2747       if (! host_integerp (len, 1))
2748         return 0;
2749
2750       /* If the LEN parameter is zero, return DEST.  */
2751       if (tree_low_cst (len, 1) == 0)
2752         {
2753           /* Evaluate and ignore SRC in case it has side-effects.  */
2754           expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
2755           return expand_expr (dest, target, mode, EXPAND_NORMAL);
2756         }
2757
2758       /* If either SRC is not a pointer type, don't do this
2759          operation in-line.  */
2760       if (src_align == 0)
2761         return 0;
2762
2763       len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
2764       src_str = c_getstr (src);
2765
2766       /* If SRC is a string constant and block move would be done
2767          by pieces, we can avoid loading the string from memory
2768          and only stored the computed constants.  */
2769       if (src_str
2770           && GET_CODE (len_rtx) == CONST_INT
2771           && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
2772           && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
2773                                   (void *) src_str, dest_align))
2774         {
2775           dest_mem = get_memory_rtx (dest);
2776           set_mem_align (dest_mem, dest_align);
2777           dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
2778                                       builtin_memcpy_read_str,
2779                                       (void *) src_str, dest_align, endp);
2780           dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2781           dest_mem = convert_memory_address (ptr_mode, dest_mem);
2782           return dest_mem;
2783         }
2784
2785       if (GET_CODE (len_rtx) == CONST_INT
2786           && can_move_by_pieces (INTVAL (len_rtx),
2787                                  MIN (dest_align, src_align)))
2788         {
2789           dest_mem = get_memory_rtx (dest);
2790           set_mem_align (dest_mem, dest_align);
2791           src_mem = get_memory_rtx (src);
2792           set_mem_align (src_mem, src_align);
2793           dest_mem = move_by_pieces (dest_mem, src_mem, INTVAL (len_rtx),
2794                                      MIN (dest_align, src_align), endp);
2795           dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2796           dest_mem = convert_memory_address (ptr_mode, dest_mem);
2797           return dest_mem;
2798         }
2799
2800       return 0;
2801     }
2802 }
2803
2804 /* Expand expression EXP, which is a call to the memmove builtin.  Return 0
2805    if we failed the caller should emit a normal call.  */
2806
2807 static rtx
2808 expand_builtin_memmove (tree arglist, rtx target, enum machine_mode mode)
2809 {
2810   if (!validate_arglist (arglist,
2811                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2812     return 0;
2813   else
2814     {
2815       tree dest = TREE_VALUE (arglist);
2816       tree src = TREE_VALUE (TREE_CHAIN (arglist));
2817       tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2818
2819       unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
2820       unsigned int dest_align
2821         = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2822
2823       /* If DEST is not a pointer type, call the normal function.  */
2824       if (dest_align == 0)
2825         return 0;
2826
2827       /* If the LEN parameter is zero, return DEST.  */
2828       if (integer_zerop (len))
2829         {
2830           /* Evaluate and ignore SRC in case it has side-effects.  */
2831           expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
2832           return expand_expr (dest, target, mode, EXPAND_NORMAL);
2833         }
2834
2835       /* If SRC and DEST are the same (and not volatile), return DEST.  */
2836       if (operand_equal_p (src, dest, 0))
2837         {
2838           /* Evaluate and ignore LEN in case it has side-effects.  */
2839           expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
2840           return expand_expr (dest, target, mode, EXPAND_NORMAL);
2841         }
2842
2843       /* If either SRC is not a pointer type, don't do this
2844          operation in-line.  */
2845       if (src_align == 0)
2846         return 0;
2847
2848       /* If src is categorized for a readonly section we can use
2849          normal memcpy.  */
2850       if (readonly_data_expr (src))
2851         {
2852           tree const fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
2853           if (!fn)
2854             return 0;
2855           return expand_expr (build_function_call_expr (fn, arglist),
2856                               target, mode, EXPAND_NORMAL);
2857         }
2858
2859       /* Otherwise, call the normal function.  */
2860       return 0;
2861    }
2862 }
2863
2864 /* Expand expression EXP, which is a call to the bcopy builtin.  Return 0
2865    if we failed the caller should emit a normal call.  */
2866
2867 static rtx
2868 expand_builtin_bcopy (tree arglist)
2869 {
2870   tree src, dest, size, newarglist;
2871
2872   if (!validate_arglist (arglist,
2873                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2874     return NULL_RTX;
2875
2876   src = TREE_VALUE (arglist);
2877   dest = TREE_VALUE (TREE_CHAIN (arglist));
2878   size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2879
2880   /* New argument list transforming bcopy(ptr x, ptr y, int z) to
2881      memmove(ptr y, ptr x, size_t z).   This is done this way
2882      so that if it isn't expanded inline, we fallback to
2883      calling bcopy instead of memmove.  */
2884
2885   newarglist = build_tree_list (NULL_TREE, fold_convert (sizetype, size));
2886   newarglist = tree_cons (NULL_TREE, src, newarglist);
2887   newarglist = tree_cons (NULL_TREE, dest, newarglist);
2888
2889   return expand_builtin_memmove (newarglist, const0_rtx, VOIDmode);
2890 }
2891
2892 /* Expand expression EXP, which is a call to the strcpy builtin.  Return 0
2893    if we failed the caller should emit a normal call, otherwise try to get
2894    the result in TARGET, if convenient (and in mode MODE if that's
2895    convenient).  */
2896
2897 static rtx
2898 expand_builtin_strcpy (tree arglist, rtx target, enum machine_mode mode)
2899 {
2900   tree fn, len, src, dst;
2901
2902   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2903     return 0;
2904
2905   src = TREE_VALUE (TREE_CHAIN (arglist));
2906   dst = TREE_VALUE (arglist);
2907
2908   /* If SRC and DST are equal (and not volatile), return DST.  */
2909   if (operand_equal_p (src, dst, 0))
2910     return expand_expr (dst, target, mode, EXPAND_NORMAL);
2911
2912   fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
2913   if (!fn)
2914     return 0;
2915
2916   len = c_strlen (src, 1);
2917   if (len == 0 || TREE_SIDE_EFFECTS (len))
2918     return 0;
2919
2920   len = size_binop (PLUS_EXPR, len, ssize_int (1));
2921   arglist = build_tree_list (NULL_TREE, len);
2922   arglist = tree_cons (NULL_TREE, src, arglist);
2923   arglist = tree_cons (NULL_TREE, dst, arglist);
2924   return expand_expr (build_function_call_expr (fn, arglist),
2925                       target, mode, EXPAND_NORMAL);
2926 }
2927
2928 /* Expand a call to the stpcpy builtin, with arguments in ARGLIST.
2929    Return 0 if we failed the caller should emit a normal call,
2930    otherwise try to get the result in TARGET, if convenient (and in
2931    mode MODE if that's convenient).  */
2932
2933 static rtx
2934 expand_builtin_stpcpy (tree arglist, rtx target, enum machine_mode mode)
2935 {
2936   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2937     return 0;
2938   else
2939     {
2940       tree dst, src, len;
2941
2942       /* If return value is ignored, transform stpcpy into strcpy.  */
2943       if (target == const0_rtx)
2944         {
2945           tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
2946           if (!fn)
2947             return 0;
2948
2949           return expand_expr (build_function_call_expr (fn, arglist),
2950                               target, mode, EXPAND_NORMAL);
2951         }
2952
2953       /* Ensure we get an actual string whose length can be evaluated at
2954          compile-time, not an expression containing a string.  This is
2955          because the latter will potentially produce pessimized code
2956          when used to produce the return value.  */
2957       src = TREE_VALUE (TREE_CHAIN (arglist));
2958       if (! c_getstr (src) || ! (len = c_strlen (src, 0)))
2959         return 0;
2960
2961       dst = TREE_VALUE (arglist);
2962       len = fold (size_binop (PLUS_EXPR, len, ssize_int (1)));
2963       arglist = build_tree_list (NULL_TREE, len);
2964       arglist = tree_cons (NULL_TREE, src, arglist);
2965       arglist = tree_cons (NULL_TREE, dst, arglist);
2966       return expand_builtin_mempcpy (arglist, target, mode, /*endp=*/2);
2967     }
2968 }
2969
2970 /* Callback routine for store_by_pieces.  Read GET_MODE_BITSIZE (MODE)
2971    bytes from constant string DATA + OFFSET and return it as target
2972    constant.  */
2973
2974 static rtx
2975 builtin_strncpy_read_str (void *data, HOST_WIDE_INT offset,
2976                           enum machine_mode mode)
2977 {
2978   const char *str = (const char *) data;
2979
2980   if ((unsigned HOST_WIDE_INT) offset > strlen (str))
2981     return const0_rtx;
2982
2983   return c_readstr (str + offset, mode);
2984 }
2985
2986 /* Expand expression EXP, which is a call to the strncpy builtin.  Return 0
2987    if we failed the caller should emit a normal call.  */
2988
2989 static rtx
2990 expand_builtin_strncpy (tree arglist, rtx target, enum machine_mode mode)
2991 {
2992   if (!validate_arglist (arglist,
2993                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2994     return 0;
2995   else
2996     {
2997       tree slen = c_strlen (TREE_VALUE (TREE_CHAIN (arglist)), 1);
2998       tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2999       tree fn;
3000
3001       /* We must be passed a constant len parameter.  */
3002       if (TREE_CODE (len) != INTEGER_CST)
3003         return 0;
3004
3005       /* If the len parameter is zero, return the dst parameter.  */
3006       if (integer_zerop (len))
3007         {
3008           /* Evaluate and ignore the src argument in case it has
3009              side-effects.  */
3010           expand_expr (TREE_VALUE (TREE_CHAIN (arglist)), const0_rtx,
3011                        VOIDmode, EXPAND_NORMAL);
3012           /* Return the dst parameter.  */
3013           return expand_expr (TREE_VALUE (arglist), target, mode,
3014                               EXPAND_NORMAL);
3015         }
3016
3017       /* Now, we must be passed a constant src ptr parameter.  */
3018       if (slen == 0 || TREE_CODE (slen) != INTEGER_CST)
3019         return 0;
3020
3021       slen = size_binop (PLUS_EXPR, slen, ssize_int (1));
3022
3023       /* We're required to pad with trailing zeros if the requested
3024          len is greater than strlen(s2)+1.  In that case try to
3025          use store_by_pieces, if it fails, punt.  */
3026       if (tree_int_cst_lt (slen, len))
3027         {
3028           tree dest = TREE_VALUE (arglist);
3029           unsigned int dest_align
3030             = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
3031           const char *p = c_getstr (TREE_VALUE (TREE_CHAIN (arglist)));
3032           rtx dest_mem;
3033
3034           if (!p || dest_align == 0 || !host_integerp (len, 1)
3035               || !can_store_by_pieces (tree_low_cst (len, 1),
3036                                        builtin_strncpy_read_str,
3037                                        (void *) p, dest_align))
3038             return 0;
3039
3040           dest_mem = get_memory_rtx (dest);
3041           store_by_pieces (dest_mem, tree_low_cst (len, 1),
3042                            builtin_strncpy_read_str,
3043                            (void *) p, dest_align, 0);
3044           dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3045           dest_mem = convert_memory_address (ptr_mode, dest_mem);
3046           return dest_mem;
3047         }
3048
3049       /* OK transform into builtin memcpy.  */
3050       fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
3051       if (!fn)
3052         return 0;
3053       return expand_expr (build_function_call_expr (fn, arglist),
3054                           target, mode, EXPAND_NORMAL);
3055     }
3056 }
3057
3058 /* Callback routine for store_by_pieces.  Read GET_MODE_BITSIZE (MODE)
3059    bytes from constant string DATA + OFFSET and return it as target
3060    constant.  */
3061
3062 static rtx
3063 builtin_memset_read_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
3064                          enum machine_mode mode)
3065 {
3066   const char *c = (const char *) data;
3067   char *p = alloca (GET_MODE_SIZE (mode));
3068
3069   memset (p, *c, GET_MODE_SIZE (mode));
3070
3071   return c_readstr (p, mode);
3072 }
3073
3074 /* Callback routine for store_by_pieces.  Return the RTL of a register
3075    containing GET_MODE_SIZE (MODE) consecutive copies of the unsigned
3076    char value given in the RTL register data.  For example, if mode is
3077    4 bytes wide, return the RTL for 0x01010101*data.  */
3078
3079 static rtx
3080 builtin_memset_gen_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
3081                         enum machine_mode mode)
3082 {
3083   rtx target, coeff;
3084   size_t size;
3085   char *p;
3086
3087   size = GET_MODE_SIZE (mode);
3088   if (size == 1)
3089     return (rtx) data;
3090
3091   p = alloca (size);
3092   memset (p, 1, size);
3093   coeff = c_readstr (p, mode);
3094
3095   target = convert_to_mode (mode, (rtx) data, 1);
3096   target = expand_mult (mode, target, coeff, NULL_RTX, 1);
3097   return force_reg (mode, target);
3098 }
3099
3100 /* Expand expression EXP, which is a call to the memset builtin.  Return 0
3101    if we failed the caller should emit a normal call, otherwise try to get
3102    the result in TARGET, if convenient (and in mode MODE if that's
3103    convenient).  */
3104
3105 static rtx
3106 expand_builtin_memset (tree arglist, rtx target, enum machine_mode mode)
3107 {
3108   if (!validate_arglist (arglist,
3109                          POINTER_TYPE, INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
3110     return 0;
3111   else
3112     {
3113       tree dest = TREE_VALUE (arglist);
3114       tree val = TREE_VALUE (TREE_CHAIN (arglist));
3115       tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3116       char c;
3117
3118       unsigned int dest_align
3119         = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
3120       rtx dest_mem, dest_addr, len_rtx;
3121
3122       /* If DEST is not a pointer type, don't do this
3123          operation in-line.  */
3124       if (dest_align == 0)
3125         return 0;
3126
3127       /* If the LEN parameter is zero, return DEST.  */
3128       if (integer_zerop (len))
3129         {
3130           /* Evaluate and ignore VAL in case it has side-effects.  */
3131           expand_expr (val, const0_rtx, VOIDmode, EXPAND_NORMAL);
3132           return expand_expr (dest, target, mode, EXPAND_NORMAL);
3133         }
3134
3135       if (TREE_CODE (val) != INTEGER_CST)
3136         {
3137           rtx val_rtx;
3138
3139           if (!host_integerp (len, 1))
3140             return 0;
3141
3142           if (optimize_size && tree_low_cst (len, 1) > 1)
3143             return 0;
3144
3145           /* Assume that we can memset by pieces if we can store the
3146            * the coefficients by pieces (in the required modes).
3147            * We can't pass builtin_memset_gen_str as that emits RTL.  */
3148           c = 1;
3149           if (!can_store_by_pieces (tree_low_cst (len, 1),
3150                                     builtin_memset_read_str,
3151                                     &c, dest_align))
3152             return 0;
3153
3154           val = fold (build1 (CONVERT_EXPR, unsigned_char_type_node, val));
3155           val_rtx = expand_expr (val, NULL_RTX, VOIDmode, 0);
3156           val_rtx = force_reg (TYPE_MODE (unsigned_char_type_node),
3157                                val_rtx);
3158           dest_mem = get_memory_rtx (dest);
3159           store_by_pieces (dest_mem, tree_low_cst (len, 1),
3160                            builtin_memset_gen_str,
3161                            val_rtx, dest_align, 0);
3162           dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3163           dest_mem = convert_memory_address (ptr_mode, dest_mem);
3164           return dest_mem;
3165         }
3166
3167       if (target_char_cast (val, &c))
3168         return 0;
3169
3170       if (c)
3171         {
3172           if (!host_integerp (len, 1))
3173             return 0;
3174           if (!can_store_by_pieces (tree_low_cst (len, 1),
3175                                     builtin_memset_read_str, &c,
3176                                     dest_align))
3177             return 0;
3178
3179           dest_mem = get_memory_rtx (dest);
3180           store_by_pieces (dest_mem, tree_low_cst (len, 1),
3181                            builtin_memset_read_str,
3182                            &c, dest_align, 0);
3183           dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3184           dest_mem = convert_memory_address (ptr_mode, dest_mem);
3185           return dest_mem;
3186         }
3187
3188       len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
3189
3190       dest_mem = get_memory_rtx (dest);
3191       set_mem_align (dest_mem, dest_align);
3192       dest_addr = clear_storage (dest_mem, len_rtx);
3193
3194       if (dest_addr == 0)
3195         {
3196           dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3197           dest_addr = convert_memory_address (ptr_mode, dest_addr);
3198         }
3199
3200       return dest_addr;
3201     }
3202 }
3203
3204 /* Expand expression EXP, which is a call to the bzero builtin.  Return 0
3205    if we failed the caller should emit a normal call.  */
3206
3207 static rtx
3208 expand_builtin_bzero (tree arglist)
3209 {
3210   tree dest, size, newarglist;
3211
3212   if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3213     return NULL_RTX;
3214
3215   dest = TREE_VALUE (arglist);
3216   size = TREE_VALUE (TREE_CHAIN (arglist));
3217
3218   /* New argument list transforming bzero(ptr x, int y) to
3219      memset(ptr x, int 0, size_t y).   This is done this way
3220      so that if it isn't expanded inline, we fallback to
3221      calling bzero instead of memset.  */
3222
3223   newarglist = build_tree_list (NULL_TREE, fold_convert (sizetype, size));
3224   newarglist = tree_cons (NULL_TREE, integer_zero_node, newarglist);
3225   newarglist = tree_cons (NULL_TREE, dest, newarglist);
3226
3227   return expand_builtin_memset (newarglist, const0_rtx, VOIDmode);
3228 }
3229
3230 /* Expand expression EXP, which is a call to the memcmp built-in function.
3231    ARGLIST is the argument list for this call.  Return 0 if we failed and the
3232    caller should emit a normal call, otherwise try to get the result in
3233    TARGET, if convenient (and in mode MODE, if that's convenient).  */
3234
3235 static rtx
3236 expand_builtin_memcmp (tree exp ATTRIBUTE_UNUSED, tree arglist, rtx target,
3237                        enum machine_mode mode)
3238 {
3239   tree arg1, arg2, len;
3240   const char *p1, *p2;
3241
3242   if (!validate_arglist (arglist,
3243                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3244     return 0;
3245
3246   arg1 = TREE_VALUE (arglist);
3247   arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3248   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3249
3250   /* If the len parameter is zero, return zero.  */
3251   if (integer_zerop (len))
3252     {
3253       /* Evaluate and ignore arg1 and arg2 in case they have
3254          side-effects.  */
3255       expand_expr (arg1, const0_rtx, VOIDmode, EXPAND_NORMAL);
3256       expand_expr (arg2, const0_rtx, VOIDmode, EXPAND_NORMAL);
3257       return const0_rtx;
3258     }
3259
3260   /* If both arguments are equal (and not volatile), return zero.  */
3261   if (operand_equal_p (arg1, arg2, 0))
3262     {
3263       /* Evaluate and ignore len in case it has side-effects.  */
3264       expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
3265       return const0_rtx;
3266     }
3267
3268   p1 = c_getstr (arg1);
3269   p2 = c_getstr (arg2);
3270
3271   /* If all arguments are constant, and the value of len is not greater
3272      than the lengths of arg1 and arg2, evaluate at compile-time.  */
3273   if (host_integerp (len, 1) && p1 && p2
3274       && compare_tree_int (len, strlen (p1) + 1) <= 0
3275       && compare_tree_int (len, strlen (p2) + 1) <= 0)
3276     {
3277       const int r = memcmp (p1, p2, tree_low_cst (len, 1));
3278
3279       return (r < 0 ? constm1_rtx : (r > 0 ? const1_rtx : const0_rtx));
3280     }
3281
3282   /* If len parameter is one, return an expression corresponding to
3283      (*(const unsigned char*)arg1 - (const unsigned char*)arg2).  */
3284   if (integer_onep (len))
3285     {
3286       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
3287       tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
3288       tree ind1 =
3289       fold (build1 (CONVERT_EXPR, integer_type_node,
3290                     build1 (INDIRECT_REF, cst_uchar_node,
3291                             fold_convert (cst_uchar_ptr_node, arg1))));
3292       tree ind2 =
3293       fold (build1 (CONVERT_EXPR, integer_type_node,
3294                     build1 (INDIRECT_REF, cst_uchar_node,
3295                             fold_convert (cst_uchar_ptr_node, arg2))));
3296       tree result = fold (build (MINUS_EXPR, integer_type_node, ind1, ind2));
3297       return expand_expr (result, target, mode, EXPAND_NORMAL);
3298     }
3299
3300 #if defined HAVE_cmpmemsi || defined HAVE_cmpstrsi
3301   {
3302     rtx arg1_rtx, arg2_rtx, arg3_rtx;
3303     rtx result;
3304     rtx insn;
3305
3306     int arg1_align
3307       = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3308     int arg2_align
3309       = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3310     enum machine_mode insn_mode;
3311
3312 #ifdef HAVE_cmpmemsi
3313     if (HAVE_cmpmemsi)
3314       insn_mode = insn_data[(int) CODE_FOR_cmpmemsi].operand[0].mode;
3315     else
3316 #endif
3317 #ifdef HAVE_cmpstrsi
3318     if (HAVE_cmpstrsi)
3319       insn_mode = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
3320     else
3321 #endif
3322       return 0;
3323
3324     /* If we don't have POINTER_TYPE, call the function.  */
3325     if (arg1_align == 0 || arg2_align == 0)
3326       return 0;
3327
3328     /* Make a place to write the result of the instruction.  */
3329     result = target;
3330     if (! (result != 0
3331            && GET_CODE (result) == REG && GET_MODE (result) == insn_mode
3332            && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3333       result = gen_reg_rtx (insn_mode);
3334
3335     arg1_rtx = get_memory_rtx (arg1);
3336     arg2_rtx = get_memory_rtx (arg2);
3337     arg3_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
3338 #ifdef HAVE_cmpmemsi
3339     if (HAVE_cmpmemsi)
3340       insn = gen_cmpmemsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3341                            GEN_INT (MIN (arg1_align, arg2_align)));
3342     else
3343 #endif
3344 #ifdef HAVE_cmpstrsi
3345     if (HAVE_cmpstrsi)
3346       insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3347                            GEN_INT (MIN (arg1_align, arg2_align)));
3348     else
3349 #endif
3350       abort ();
3351
3352     if (insn)
3353       emit_insn (insn);
3354     else
3355       emit_library_call_value (memcmp_libfunc, result, LCT_PURE_MAKE_BLOCK,
3356                                TYPE_MODE (integer_type_node), 3,
3357                                XEXP (arg1_rtx, 0), Pmode,
3358                                XEXP (arg2_rtx, 0), Pmode,
3359                                convert_to_mode (TYPE_MODE (sizetype), arg3_rtx,
3360                                                 TYPE_UNSIGNED (sizetype)),
3361                                TYPE_MODE (sizetype));
3362
3363     /* Return the value in the proper mode for this function.  */
3364     mode = TYPE_MODE (TREE_TYPE (exp));
3365     if (GET_MODE (result) == mode)
3366       return result;
3367     else if (target != 0)
3368       {
3369         convert_move (target, result, 0);
3370         return target;
3371       }
3372     else
3373       return convert_to_mode (mode, result, 0);
3374   }
3375 #endif
3376
3377   return 0;
3378 }
3379
3380 /* Expand expression EXP, which is a call to the strcmp builtin.  Return 0
3381    if we failed the caller should emit a normal call, otherwise try to get
3382    the result in TARGET, if convenient.  */
3383
3384 static rtx
3385 expand_builtin_strcmp (tree exp, rtx target, enum machine_mode mode)
3386 {
3387   tree arglist = TREE_OPERAND (exp, 1);
3388   tree arg1, arg2;
3389   const char *p1, *p2;
3390
3391   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3392     return 0;
3393
3394   arg1 = TREE_VALUE (arglist);
3395   arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3396
3397   /* If both arguments are equal (and not volatile), return zero.  */
3398   if (operand_equal_p (arg1, arg2, 0))
3399     return const0_rtx;
3400
3401   p1 = c_getstr (arg1);
3402   p2 = c_getstr (arg2);
3403
3404   if (p1 && p2)
3405     {
3406       const int i = strcmp (p1, p2);
3407       return (i < 0 ? constm1_rtx : (i > 0 ? const1_rtx : const0_rtx));
3408     }
3409
3410   /* If either arg is "", return an expression corresponding to
3411      (*(const unsigned char*)arg1 - (const unsigned char*)arg2).  */
3412   if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
3413     {
3414       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
3415       tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
3416       tree ind1 =
3417         fold (build1 (CONVERT_EXPR, integer_type_node,
3418                       build1 (INDIRECT_REF, cst_uchar_node,
3419                               fold_convert (cst_uchar_ptr_node, arg1))));
3420       tree ind2 =
3421         fold (build1 (CONVERT_EXPR, integer_type_node,
3422                       build1 (INDIRECT_REF, cst_uchar_node,
3423                               fold_convert (cst_uchar_ptr_node, arg2))));
3424       tree result = fold (build (MINUS_EXPR, integer_type_node, ind1, ind2));
3425       return expand_expr (result, target, mode, EXPAND_NORMAL);
3426     }
3427
3428 #ifdef HAVE_cmpstrsi
3429   if (HAVE_cmpstrsi)
3430   {
3431     tree len, len1, len2;
3432     rtx arg1_rtx, arg2_rtx, arg3_rtx;
3433     rtx result, insn;
3434     tree fndecl;
3435
3436     int arg1_align
3437       = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3438     int arg2_align
3439       = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3440     enum machine_mode insn_mode
3441       = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
3442
3443     len1 = c_strlen (arg1, 1);
3444     len2 = c_strlen (arg2, 1);
3445
3446     if (len1)
3447       len1 = size_binop (PLUS_EXPR, ssize_int (1), len1);
3448     if (len2)
3449       len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
3450
3451     /* If we don't have a constant length for the first, use the length
3452        of the second, if we know it.  We don't require a constant for
3453        this case; some cost analysis could be done if both are available
3454        but neither is constant.  For now, assume they're equally cheap,
3455        unless one has side effects.  If both strings have constant lengths,
3456        use the smaller.  */
3457
3458     if (!len1)
3459       len = len2;
3460     else if (!len2)
3461       len = len1;
3462     else if (TREE_SIDE_EFFECTS (len1))
3463       len = len2;
3464     else if (TREE_SIDE_EFFECTS (len2))
3465       len = len1;
3466     else if (TREE_CODE (len1) != INTEGER_CST)
3467       len = len2;
3468     else if (TREE_CODE (len2) != INTEGER_CST)
3469       len = len1;
3470     else if (tree_int_cst_lt (len1, len2))
3471       len = len1;
3472     else
3473       len = len2;
3474
3475     /* If both arguments have side effects, we cannot optimize.  */
3476     if (!len || TREE_SIDE_EFFECTS (len))
3477       return 0;
3478
3479     /* If we don't have POINTER_TYPE, call the function.  */
3480     if (arg1_align == 0 || arg2_align == 0)
3481       return 0;
3482
3483     /* Make a place to write the result of the instruction.  */
3484     result = target;
3485     if (! (result != 0
3486            && GET_CODE (result) == REG && GET_MODE (result) == insn_mode
3487            && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3488       result = gen_reg_rtx (insn_mode);
3489
3490     /* Stabilize the arguments in case gen_cmpstrsi fails.  */
3491     arg1 = save_expr (arg1);
3492     arg2 = save_expr (arg2);
3493
3494     arg1_rtx = get_memory_rtx (arg1);
3495     arg2_rtx = get_memory_rtx (arg2);
3496     arg3_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
3497     insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3498                          GEN_INT (MIN (arg1_align, arg2_align)));
3499     if (insn)
3500       {
3501         emit_insn (insn);
3502
3503         /* Return the value in the proper mode for this function.  */
3504         mode = TYPE_MODE (TREE_TYPE (exp));
3505         if (GET_MODE (result) == mode)
3506           return result;
3507         if (target == 0)
3508           return convert_to_mode (mode, result, 0);
3509         convert_move (target, result, 0);
3510         return target;
3511       }
3512
3513     /* Expand the library call ourselves using a stabilized argument
3514        list to avoid re-evaluating the function's arguments twice.  */
3515     arglist = build_tree_list (NULL_TREE, arg2);
3516     arglist = tree_cons (NULL_TREE, arg1, arglist);
3517     fndecl = get_callee_fndecl (exp);
3518     exp = build_function_call_expr (fndecl, arglist);
3519     return expand_call (exp, target, target == const0_rtx);
3520   }
3521 #endif
3522   return 0;
3523 }
3524
3525 /* Expand expression EXP, which is a call to the strncmp builtin.  Return 0
3526    if we failed the caller should emit a normal call, otherwise try to get
3527    the result in TARGET, if convenient.  */
3528
3529 static rtx
3530 expand_builtin_strncmp (tree exp, rtx target, enum machine_mode mode)
3531 {
3532   tree arglist = TREE_OPERAND (exp, 1);
3533   tree arg1, arg2, arg3;
3534   const char *p1, *p2;
3535
3536   if (!validate_arglist (arglist,
3537                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3538     return 0;
3539
3540   arg1 = TREE_VALUE (arglist);
3541   arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3542   arg3 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3543
3544   /* If the len parameter is zero, return zero.  */
3545   if (integer_zerop (arg3))
3546     {
3547       /* Evaluate and ignore arg1 and arg2 in case they have
3548          side-effects.  */
3549       expand_expr (arg1, const0_rtx, VOIDmode, EXPAND_NORMAL);
3550       expand_expr (arg2, const0_rtx, VOIDmode, EXPAND_NORMAL);
3551       return const0_rtx;
3552     }
3553
3554   /* If arg1 and arg2 are equal (and not volatile), return zero.  */
3555   if (operand_equal_p (arg1, arg2, 0))
3556     {
3557       /* Evaluate and ignore arg3 in case it has side-effects.  */
3558       expand_expr (arg3, const0_rtx, VOIDmode, EXPAND_NORMAL);
3559       return const0_rtx;
3560     }
3561
3562   p1 = c_getstr (arg1);
3563   p2 = c_getstr (arg2);
3564
3565   /* If all arguments are constant, evaluate at compile-time.  */
3566   if (host_integerp (arg3, 1) && p1 && p2)
3567     {
3568       const int r = strncmp (p1, p2, tree_low_cst (arg3, 1));
3569       return (r < 0 ? constm1_rtx : (r > 0 ? const1_rtx : const0_rtx));
3570     }
3571
3572   /* If len == 1 or (either string parameter is "" and (len >= 1)),
3573       return (*(const u_char*)arg1 - *(const u_char*)arg2).  */
3574   if (host_integerp (arg3, 1)
3575       && (tree_low_cst (arg3, 1) == 1
3576           || (tree_low_cst (arg3, 1) > 1
3577               && ((p1 && *p1 == '\0') || (p2 && *p2 == '\0')))))
3578     {
3579       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
3580       tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
3581       tree ind1 =
3582         fold (build1 (CONVERT_EXPR, integer_type_node,
3583                       build1 (INDIRECT_REF, cst_uchar_node,
3584                               fold_convert (cst_uchar_ptr_node, arg1))));
3585       tree ind2 =
3586         fold (build1 (CONVERT_EXPR, integer_type_node,
3587                       build1 (INDIRECT_REF, cst_uchar_node,
3588                               fold_convert (cst_uchar_ptr_node, arg2))));
3589       tree result = fold (build (MINUS_EXPR, integer_type_node, ind1, ind2));
3590       return expand_expr (result, target, mode, EXPAND_NORMAL);
3591     }
3592
3593   /* If c_strlen can determine an expression for one of the string
3594      lengths, and it doesn't have side effects, then emit cmpstrsi
3595      using length MIN(strlen(string)+1, arg3).  */
3596 #ifdef HAVE_cmpstrsi
3597   if (HAVE_cmpstrsi)
3598   {
3599     tree len, len1, len2;
3600     rtx arg1_rtx, arg2_rtx, arg3_rtx;
3601     rtx result, insn;
3602     tree fndecl;
3603
3604     int arg1_align
3605       = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3606     int arg2_align
3607       = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3608     enum machine_mode insn_mode
3609       = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
3610
3611     len1 = c_strlen (arg1, 1);
3612     len2 = c_strlen (arg2, 1);
3613
3614     if (len1)
3615       len1 = size_binop (PLUS_EXPR, ssize_int (1), len1);
3616     if (len2)
3617       len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
3618
3619     /* If we don't have a constant length for the first, use the length
3620        of the second, if we know it.  We don't require a constant for
3621        this case; some cost analysis could be done if both are available
3622        but neither is constant.  For now, assume they're equally cheap,
3623        unless one has side effects.  If both strings have constant lengths,
3624        use the smaller.  */
3625
3626     if (!len1)
3627       len = len2;
3628     else if (!len2)
3629       len = len1;
3630     else if (TREE_SIDE_EFFECTS (len1))
3631       len = len2;
3632     else if (TREE_SIDE_EFFECTS (len2))
3633       len = len1;
3634     else if (TREE_CODE (len1) != INTEGER_CST)
3635       len = len2;
3636     else if (TREE_CODE (len2) != INTEGER_CST)
3637       len = len1;
3638     else if (tree_int_cst_lt (len1, len2))
3639       len = len1;
3640     else
3641       len = len2;
3642
3643     /* If both arguments have side effects, we cannot optimize.  */
3644     if (!len || TREE_SIDE_EFFECTS (len))
3645       return 0;
3646
3647     /* The actual new length parameter is MIN(len,arg3).  */
3648     len = fold (build (MIN_EXPR, TREE_TYPE (len), len, arg3));
3649
3650     /* If we don't have POINTER_TYPE, call the function.  */
3651     if (arg1_align == 0 || arg2_align == 0)
3652       return 0;
3653
3654     /* Make a place to write the result of the instruction.  */
3655     result = target;
3656     if (! (result != 0
3657            && GET_CODE (result) == REG && GET_MODE (result) == insn_mode
3658            && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3659       result = gen_reg_rtx (insn_mode);
3660
3661     /* Stabilize the arguments in case gen_cmpstrsi fails.  */
3662     arg1 = save_expr (arg1);
3663     arg2 = save_expr (arg2);
3664     len = save_expr (len);
3665
3666     arg1_rtx = get_memory_rtx (arg1);
3667     arg2_rtx = get_memory_rtx (arg2);
3668     arg3_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
3669     insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3670                          GEN_INT (MIN (arg1_align, arg2_align)));
3671     if (insn)
3672       {
3673         emit_insn (insn);
3674
3675         /* Return the value in the proper mode for this function.  */
3676         mode = TYPE_MODE (TREE_TYPE (exp));
3677         if (GET_MODE (result) == mode)
3678           return result;
3679         if (target == 0)
3680           return convert_to_mode (mode, result, 0);
3681         convert_move (target, result, 0);
3682         return target;
3683       }
3684
3685     /* Expand the library call ourselves using a stabilized argument
3686        list to avoid re-evaluating the function's arguments twice.  */
3687     arglist = build_tree_list (NULL_TREE, len);
3688     arglist = tree_cons (NULL_TREE, arg2, arglist);
3689     arglist = tree_cons (NULL_TREE, arg1, arglist);
3690     fndecl = get_callee_fndecl (exp);
3691     exp = build_function_call_expr (fndecl, arglist);
3692     return expand_call (exp, target, target == const0_rtx);
3693   }
3694 #endif
3695   return 0;
3696 }
3697
3698 /* Expand expression EXP, which is a call to the strcat builtin.
3699    Return 0 if we failed the caller should emit a normal call,
3700    otherwise try to get the result in TARGET, if convenient.  */
3701
3702 static rtx
3703 expand_builtin_strcat (tree arglist, rtx target, enum machine_mode mode)
3704 {
3705   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3706     return 0;
3707   else
3708     {
3709       tree dst = TREE_VALUE (arglist),
3710         src = TREE_VALUE (TREE_CHAIN (arglist));
3711       const char *p = c_getstr (src);
3712
3713       if (p)
3714         {
3715           /* If the string length is zero, return the dst parameter.  */
3716           if (*p == '\0')
3717             return expand_expr (dst, target, mode, EXPAND_NORMAL);
3718           else if (!optimize_size)
3719             {
3720               /* Otherwise if !optimize_size, see if we can store by
3721                  pieces into (dst + strlen(dst)).  */
3722               tree newdst, arglist,
3723                 strlen_fn = implicit_built_in_decls[BUILT_IN_STRLEN];
3724
3725               /* This is the length argument.  */
3726               arglist = build_tree_list (NULL_TREE,
3727                                          fold (size_binop (PLUS_EXPR,
3728                                                            c_strlen (src, 0),
3729                                                            ssize_int (1))));
3730               /* Prepend src argument.  */
3731               arglist = tree_cons (NULL_TREE, src, arglist);
3732
3733               /* We're going to use dst more than once.  */
3734               dst = save_expr (dst);
3735
3736               /* Create strlen (dst).  */
3737               newdst =
3738                 fold (build_function_call_expr (strlen_fn,
3739                                                 build_tree_list (NULL_TREE,
3740                                                                  dst)));
3741               /* Create (dst + strlen (dst)).  */
3742               newdst = fold (build (PLUS_EXPR, TREE_TYPE (dst), dst, newdst));
3743
3744               /* Prepend the new dst argument.  */
3745               arglist = tree_cons (NULL_TREE, newdst, arglist);
3746
3747               /* We don't want to get turned into a memcpy if the
3748                  target is const0_rtx, i.e. when the return value
3749                  isn't used.  That would produce pessimized code so
3750                  pass in a target of zero, it should never actually be
3751                  used.  If this was successful return the original
3752                  dst, not the result of mempcpy.  */
3753               if (expand_builtin_mempcpy (arglist, /*target=*/0, mode, /*endp=*/0))
3754                 return expand_expr (dst, target, mode, EXPAND_NORMAL);
3755               else
3756                 return 0;
3757             }
3758         }
3759
3760       return 0;
3761     }
3762 }
3763
3764 /* Expand expression EXP, which is a call to the strncat builtin.
3765    Return 0 if we failed the caller should emit a normal call,
3766    otherwise try to get the result in TARGET, if convenient.  */
3767
3768 static rtx
3769 expand_builtin_strncat (tree arglist, rtx target, enum machine_mode mode)
3770 {
3771   if (!validate_arglist (arglist,
3772                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3773     return 0;
3774   else
3775     {
3776       tree dst = TREE_VALUE (arglist),
3777         src = TREE_VALUE (TREE_CHAIN (arglist)),
3778         len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3779       const char *p = c_getstr (src);
3780
3781       /* If the requested length is zero, or the src parameter string
3782           length is zero, return the dst parameter.  */
3783       if (integer_zerop (len) || (p && *p == '\0'))
3784         {
3785           /* Evaluate and ignore the src and len parameters in case
3786              they have side-effects.  */
3787           expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
3788           expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
3789           return expand_expr (dst, target, mode, EXPAND_NORMAL);
3790         }
3791
3792       /* If the requested len is greater than or equal to the string
3793          length, call strcat.  */
3794       if (TREE_CODE (len) == INTEGER_CST && p
3795           && compare_tree_int (len, strlen (p)) >= 0)
3796         {
3797           tree newarglist
3798             = tree_cons (NULL_TREE, dst, build_tree_list (NULL_TREE, src));
3799           tree fn = implicit_built_in_decls[BUILT_IN_STRCAT];
3800
3801           /* If the replacement _DECL isn't initialized, don't do the
3802              transformation.  */
3803           if (!fn)
3804             return 0;
3805
3806           return expand_expr (build_function_call_expr (fn, newarglist),
3807                               target, mode, EXPAND_NORMAL);
3808         }
3809       return 0;
3810     }
3811 }
3812
3813 /* Expand expression EXP, which is a call to the strspn builtin.
3814    Return 0 if we failed the caller should emit a normal call,
3815    otherwise try to get the result in TARGET, if convenient.  */
3816
3817 static rtx
3818 expand_builtin_strspn (tree arglist, rtx target, enum machine_mode mode)
3819 {
3820   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3821     return 0;
3822   else
3823     {
3824       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
3825       const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
3826
3827       /* If both arguments are constants, evaluate at compile-time.  */
3828       if (p1 && p2)
3829         {
3830           const size_t r = strspn (p1, p2);
3831           return expand_expr (size_int (r), target, mode, EXPAND_NORMAL);
3832         }
3833
3834       /* If either argument is "", return 0.  */
3835       if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
3836         {
3837           /* Evaluate and ignore both arguments in case either one has
3838              side-effects.  */
3839           expand_expr (s1, const0_rtx, VOIDmode, EXPAND_NORMAL);
3840           expand_expr (s2, const0_rtx, VOIDmode, EXPAND_NORMAL);
3841           return const0_rtx;
3842         }
3843       return 0;
3844     }
3845 }
3846
3847 /* Expand expression EXP, which is a call to the strcspn builtin.
3848    Return 0 if we failed the caller should emit a normal call,
3849    otherwise try to get the result in TARGET, if convenient.  */
3850
3851 static rtx
3852 expand_builtin_strcspn (tree arglist, rtx target, enum machine_mode mode)
3853 {
3854   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3855     return 0;
3856   else
3857     {
3858       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
3859       const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
3860
3861       /* If both arguments are constants, evaluate at compile-time.  */
3862       if (p1 && p2)
3863         {
3864           const size_t r = strcspn (p1, p2);
3865           return expand_expr (size_int (r), target, mode, EXPAND_NORMAL);
3866         }
3867
3868       /* If the first argument is "", return 0.  */
3869       if (p1 && *p1 == '\0')
3870         {
3871           /* Evaluate and ignore argument s2 in case it has
3872              side-effects.  */
3873           expand_expr (s2, const0_rtx, VOIDmode, EXPAND_NORMAL);
3874           return const0_rtx;
3875         }
3876
3877       /* If the second argument is "", return __builtin_strlen(s1).  */
3878       if (p2 && *p2 == '\0')
3879         {
3880           tree newarglist = build_tree_list (NULL_TREE, s1),
3881             fn = implicit_built_in_decls[BUILT_IN_STRLEN];
3882
3883           /* If the replacement _DECL isn't initialized, don't do the
3884              transformation.  */
3885           if (!fn)
3886             return 0;
3887
3888           return expand_expr (build_function_call_expr (fn, newarglist),
3889                               target, mode, EXPAND_NORMAL);
3890         }
3891       return 0;
3892     }
3893 }
3894
3895 /* Expand a call to __builtin_saveregs, generating the result in TARGET,
3896    if that's convenient.  */
3897
3898 rtx
3899 expand_builtin_saveregs (void)
3900 {
3901   rtx val, seq;
3902
3903   /* Don't do __builtin_saveregs more than once in a function.
3904      Save the result of the first call and reuse it.  */
3905   if (saveregs_value != 0)
3906     return saveregs_value;
3907
3908   /* When this function is called, it means that registers must be
3909      saved on entry to this function.  So we migrate the call to the
3910      first insn of this function.  */
3911
3912   start_sequence ();
3913
3914   /* Do whatever the machine needs done in this case.  */
3915   val = targetm.calls.expand_builtin_saveregs ();
3916
3917   seq = get_insns ();
3918   end_sequence ();
3919
3920   saveregs_value = val;
3921
3922   /* Put the insns after the NOTE that starts the function.  If this
3923      is inside a start_sequence, make the outer-level insn chain current, so
3924      the code is placed at the start of the function.  */
3925   push_topmost_sequence ();
3926   emit_insn_after (seq, get_insns ());
3927   pop_topmost_sequence ();
3928
3929   return val;
3930 }
3931
3932 /* __builtin_args_info (N) returns word N of the arg space info
3933    for the current function.  The number and meanings of words
3934    is controlled by the definition of CUMULATIVE_ARGS.  */
3935
3936 static rtx
3937 expand_builtin_args_info (tree arglist)
3938 {
3939   int nwords = sizeof (CUMULATIVE_ARGS) / sizeof (int);
3940   int *word_ptr = (int *) &current_function_args_info;
3941
3942   if (sizeof (CUMULATIVE_ARGS) % sizeof (int) != 0)
3943     abort ();
3944
3945   if (arglist != 0)
3946     {
3947       if (!host_integerp (TREE_VALUE (arglist), 0))
3948         error ("argument of `__builtin_args_info' must be constant");
3949       else
3950         {
3951           HOST_WIDE_INT wordnum = tree_low_cst (TREE_VALUE (arglist), 0);
3952
3953           if (wordnum < 0 || wordnum >= nwords)
3954             error ("argument of `__builtin_args_info' out of range");
3955           else
3956             return GEN_INT (word_ptr[wordnum]);
3957         }
3958     }
3959   else
3960     error ("missing argument in `__builtin_args_info'");
3961
3962   return const0_rtx;
3963 }
3964
3965 /* Expand ARGLIST, from a call to __builtin_next_arg.  */
3966
3967 static rtx
3968 expand_builtin_next_arg (tree arglist)
3969 {
3970   tree fntype = TREE_TYPE (current_function_decl);
3971
3972   if (TYPE_ARG_TYPES (fntype) == 0
3973       || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
3974           == void_type_node))
3975     {
3976       error ("`va_start' used in function with fixed args");
3977       return const0_rtx;
3978     }
3979
3980   if (arglist)
3981     {
3982       tree last_parm = tree_last (DECL_ARGUMENTS (current_function_decl));
3983       tree arg = TREE_VALUE (arglist);
3984
3985       /* Strip off all nops for the sake of the comparison.  This
3986          is not quite the same as STRIP_NOPS.  It does more.
3987          We must also strip off INDIRECT_EXPR for C++ reference
3988          parameters.  */
3989       while (TREE_CODE (arg) == NOP_EXPR
3990              || TREE_CODE (arg) == CONVERT_EXPR
3991              || TREE_CODE (arg) == NON_LVALUE_EXPR
3992              || TREE_CODE (arg) == INDIRECT_REF)
3993         arg = TREE_OPERAND (arg, 0);
3994       if (arg != last_parm)
3995         warning ("second parameter of `va_start' not last named argument");
3996     }
3997   else
3998     /* Evidently an out of date version of <stdarg.h>; can't validate
3999        va_start's second argument, but can still work as intended.  */
4000     warning ("`__builtin_next_arg' called without an argument");
4001
4002   return expand_binop (Pmode, add_optab,
4003                        current_function_internal_arg_pointer,
4004                        current_function_arg_offset_rtx,
4005                        NULL_RTX, 0, OPTAB_LIB_WIDEN);
4006 }
4007
4008 /* Make it easier for the backends by protecting the valist argument
4009    from multiple evaluations.  */
4010
4011 static tree
4012 stabilize_va_list (tree valist, int needs_lvalue)
4013 {
4014   if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
4015     {
4016       if (TREE_SIDE_EFFECTS (valist))
4017         valist = save_expr (valist);
4018
4019       /* For this case, the backends will be expecting a pointer to
4020          TREE_TYPE (va_list_type_node), but it's possible we've
4021          actually been given an array (an actual va_list_type_node).
4022          So fix it.  */
4023       if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
4024         {
4025           tree p1 = build_pointer_type (TREE_TYPE (va_list_type_node));
4026           tree p2 = build_pointer_type (va_list_type_node);
4027
4028           valist = build1 (ADDR_EXPR, p2, valist);
4029           valist = fold_convert (p1, valist);
4030         }
4031     }
4032   else
4033     {
4034       tree pt;
4035
4036       if (! needs_lvalue)
4037         {
4038           if (! TREE_SIDE_EFFECTS (valist))
4039             return valist;
4040
4041           pt = build_pointer_type (va_list_type_node);
4042           valist = fold (build1 (ADDR_EXPR, pt, valist));
4043           TREE_SIDE_EFFECTS (valist) = 1;
4044         }
4045
4046       if (TREE_SIDE_EFFECTS (valist))
4047         valist = save_expr (valist);
4048       valist = fold (build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (valist)),
4049                              valist));
4050     }
4051
4052   return valist;
4053 }
4054
4055 /* The "standard" definition of va_list is void*.  */
4056
4057 tree
4058 std_build_builtin_va_list (void)
4059 {
4060   return ptr_type_node;
4061 }
4062
4063 /* The "standard" implementation of va_start: just assign `nextarg' to
4064    the variable.  */
4065
4066 void
4067 std_expand_builtin_va_start (tree valist, rtx nextarg)
4068 {
4069   tree t;
4070
4071   t = build (MODIFY_EXPR, TREE_TYPE (valist), valist,
4072              make_tree (ptr_type_node, nextarg));
4073   TREE_SIDE_EFFECTS (t) = 1;
4074
4075   expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4076 }
4077
4078 /* Expand ARGLIST, from a call to __builtin_va_start.  */
4079
4080 static rtx
4081 expand_builtin_va_start (tree arglist)
4082 {
4083   rtx nextarg;
4084   tree chain, valist;
4085
4086   chain = TREE_CHAIN (arglist);
4087
4088   if (TREE_CHAIN (chain))
4089     error ("too many arguments to function `va_start'");
4090
4091   nextarg = expand_builtin_next_arg (chain);
4092   valist = stabilize_va_list (TREE_VALUE (arglist), 1);
4093
4094 #ifdef EXPAND_BUILTIN_VA_START
4095   EXPAND_BUILTIN_VA_START (valist, nextarg);
4096 #else
4097   std_expand_builtin_va_start (valist, nextarg);
4098 #endif
4099
4100   return const0_rtx;
4101 }
4102
4103 /* The "standard" implementation of va_arg: read the value from the
4104    current (padded) address and increment by the (padded) size.  */
4105
4106 rtx
4107 std_expand_builtin_va_arg (tree valist, tree type)
4108 {
4109   tree addr_tree, t, type_size = NULL;
4110   tree align, alignm1;
4111   tree rounded_size;
4112   rtx addr;
4113   HOST_WIDE_INT boundary;
4114
4115   /* Compute the rounded size of the type.  */
4116   align = size_int (PARM_BOUNDARY / BITS_PER_UNIT);
4117   alignm1 = size_int (PARM_BOUNDARY / BITS_PER_UNIT - 1);
4118   boundary = FUNCTION_ARG_BOUNDARY (TYPE_MODE (type), type);
4119
4120   /* va_list pointer is aligned to PARM_BOUNDARY.  If argument actually
4121      requires greater alignment, we must perform dynamic alignment.  */
4122
4123   if (boundary > PARM_BOUNDARY)
4124     {
4125       if (!PAD_VARARGS_DOWN)
4126         {
4127           t = build (MODIFY_EXPR, TREE_TYPE (valist), valist,
4128                      build (PLUS_EXPR, TREE_TYPE (valist), valist,
4129                             build_int_2 (boundary / BITS_PER_UNIT - 1, 0)));
4130           TREE_SIDE_EFFECTS (t) = 1;
4131           expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4132         }
4133       t = build (MODIFY_EXPR, TREE_TYPE (valist), valist,
4134                  build (BIT_AND_EXPR, TREE_TYPE (valist), valist,
4135                         build_int_2 (~(boundary / BITS_PER_UNIT - 1), -1)));
4136       TREE_SIDE_EFFECTS (t) = 1;
4137       expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4138     }
4139   if (type == error_mark_node
4140       || (type_size = TYPE_SIZE_UNIT (TYPE_MAIN_VARIANT (type))) == NULL
4141       || TREE_OVERFLOW (type_size))
4142     rounded_size = size_zero_node;
4143   else
4144     rounded_size = fold (build (MULT_EXPR, sizetype,
4145                                 fold (build (TRUNC_DIV_EXPR, sizetype,
4146                                              fold (build (PLUS_EXPR, sizetype,
4147                                                           type_size, alignm1)),
4148                                              align)),
4149                                 align));
4150
4151   /* Get AP.  */
4152   addr_tree = valist;
4153   if (PAD_VARARGS_DOWN && ! integer_zerop (rounded_size))
4154     {
4155       /* Small args are padded downward.  */
4156       addr_tree = fold (build (PLUS_EXPR, TREE_TYPE (addr_tree), addr_tree,
4157                                fold (build (COND_EXPR, sizetype,
4158                                             fold (build (GT_EXPR, sizetype,
4159                                                          rounded_size,
4160                                                          align)),
4161                                             size_zero_node,
4162                                             fold (build (MINUS_EXPR, sizetype,
4163                                                          rounded_size,
4164                                                          type_size))))));
4165     }
4166
4167   addr = expand_expr (addr_tree, NULL_RTX, Pmode, EXPAND_NORMAL);
4168   addr = copy_to_reg (addr);
4169
4170   /* Compute new value for AP.  */
4171   if (! integer_zerop (rounded_size))
4172     {
4173       t = build (MODIFY_EXPR, TREE_TYPE (valist), valist,
4174                  build (PLUS_EXPR, TREE_TYPE (valist), valist,
4175                         rounded_size));
4176       TREE_SIDE_EFFECTS (t) = 1;
4177       expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4178     }
4179
4180   return addr;
4181 }
4182
4183 /* Expand __builtin_va_arg, which is not really a builtin function, but
4184    a very special sort of operator.  */
4185
4186 rtx
4187 expand_builtin_va_arg (tree valist, tree type)
4188 {
4189   rtx addr, result;
4190   tree promoted_type, want_va_type, have_va_type;
4191
4192   /* Verify that valist is of the proper type.  */
4193
4194   want_va_type = va_list_type_node;
4195   have_va_type = TREE_TYPE (valist);
4196   if (TREE_CODE (want_va_type) == ARRAY_TYPE)
4197     {
4198       /* If va_list is an array type, the argument may have decayed
4199          to a pointer type, e.g. by being passed to another function.
4200          In that case, unwrap both types so that we can compare the
4201          underlying records.  */
4202       if (TREE_CODE (have_va_type) == ARRAY_TYPE
4203           || TREE_CODE (have_va_type) == POINTER_TYPE)
4204         {
4205           want_va_type = TREE_TYPE (want_va_type);
4206           have_va_type = TREE_TYPE (have_va_type);
4207         }
4208     }
4209   if (TYPE_MAIN_VARIANT (want_va_type) != TYPE_MAIN_VARIANT (have_va_type))
4210     {
4211       error ("first argument to `va_arg' not of type `va_list'");
4212       addr = const0_rtx;
4213     }
4214
4215   /* Generate a diagnostic for requesting data of a type that cannot
4216      be passed through `...' due to type promotion at the call site.  */
4217   else if ((promoted_type = lang_hooks.types.type_promotes_to (type))
4218            != type)
4219     {
4220       const char *name = "<anonymous type>", *pname = 0;
4221       static bool gave_help;
4222
4223       if (TYPE_NAME (type))
4224         {
4225           if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE)
4226             name = IDENTIFIER_POINTER (TYPE_NAME (type));
4227           else if (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
4228                    && DECL_NAME (TYPE_NAME (type)))
4229             name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type)));
4230         }
4231       if (TYPE_NAME (promoted_type))
4232         {
4233           if (TREE_CODE (TYPE_NAME (promoted_type)) == IDENTIFIER_NODE)
4234             pname = IDENTIFIER_POINTER (TYPE_NAME (promoted_type));
4235           else if (TREE_CODE (TYPE_NAME (promoted_type)) == TYPE_DECL
4236                    && DECL_NAME (TYPE_NAME (promoted_type)))
4237             pname = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (promoted_type)));
4238         }
4239
4240       /* Unfortunately, this is merely undefined, rather than a constraint
4241          violation, so we cannot make this an error.  If this call is never
4242          executed, the program is still strictly conforming.  */
4243       warning ("`%s' is promoted to `%s' when passed through `...'",
4244                name, pname);
4245       if (! gave_help)
4246         {
4247           gave_help = true;
4248           warning ("(so you should pass `%s' not `%s' to `va_arg')",
4249                    pname, name);
4250         }
4251
4252       /* We can, however, treat "undefined" any way we please.
4253          Call abort to encourage the user to fix the program.  */
4254       inform ("if this code is reached, the program will abort");
4255       expand_builtin_trap ();
4256
4257       /* This is dead code, but go ahead and finish so that the
4258          mode of the result comes out right.  */
4259       addr = const0_rtx;
4260     }
4261   else
4262     {
4263       /* Make it easier for the backends by protecting the valist argument
4264          from multiple evaluations.  */
4265       valist = stabilize_va_list (valist, 0);
4266
4267 #ifdef EXPAND_BUILTIN_VA_ARG
4268       addr = EXPAND_BUILTIN_VA_ARG (valist, type);
4269 #else
4270       addr = std_expand_builtin_va_arg (valist, type);
4271 #endif
4272     }
4273
4274   addr = convert_memory_address (Pmode, addr);
4275
4276   result = gen_rtx_MEM (TYPE_MODE (type), addr);
4277   set_mem_alias_set (result, get_varargs_alias_set ());
4278
4279   return result;
4280 }
4281
4282 /* Expand ARGLIST, from a call to __builtin_va_end.  */
4283
4284 static rtx
4285 expand_builtin_va_end (tree arglist)
4286 {
4287   tree valist = TREE_VALUE (arglist);
4288
4289   /* Evaluate for side effects, if needed.  I hate macros that don't
4290      do that.  */
4291   if (TREE_SIDE_EFFECTS (valist))
4292     expand_expr (valist, const0_rtx, VOIDmode, EXPAND_NORMAL);
4293
4294   return const0_rtx;
4295 }
4296
4297 /* Expand ARGLIST, from a call to __builtin_va_copy.  We do this as a
4298    builtin rather than just as an assignment in stdarg.h because of the
4299    nastiness of array-type va_list types.  */
4300
4301 static rtx
4302 expand_builtin_va_copy (tree arglist)
4303 {
4304   tree dst, src, t;
4305
4306   dst = TREE_VALUE (arglist);
4307   src = TREE_VALUE (TREE_CHAIN (arglist));
4308
4309   dst = stabilize_va_list (dst, 1);
4310   src = stabilize_va_list (src, 0);
4311
4312   if (TREE_CODE (va_list_type_node) != ARRAY_TYPE)
4313     {
4314       t = build (MODIFY_EXPR, va_list_type_node, dst, src);
4315       TREE_SIDE_EFFECTS (t) = 1;
4316       expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4317     }
4318   else
4319     {
4320       rtx dstb, srcb, size;
4321
4322       /* Evaluate to pointers.  */
4323       dstb = expand_expr (dst, NULL_RTX, Pmode, EXPAND_NORMAL);
4324       srcb = expand_expr (src, NULL_RTX, Pmode, EXPAND_NORMAL);
4325       size = expand_expr (TYPE_SIZE_UNIT (va_list_type_node), NULL_RTX,
4326                           VOIDmode, EXPAND_NORMAL);
4327
4328       dstb = convert_memory_address (Pmode, dstb);
4329       srcb = convert_memory_address (Pmode, srcb);
4330
4331       /* "Dereference" to BLKmode memories.  */
4332       dstb = gen_rtx_MEM (BLKmode, dstb);
4333       set_mem_alias_set (dstb, get_alias_set (TREE_TYPE (TREE_TYPE (dst))));
4334       set_mem_align (dstb, TYPE_ALIGN (va_list_type_node));
4335       srcb = gen_rtx_MEM (BLKmode, srcb);
4336       set_mem_alias_set (srcb, get_alias_set (TREE_TYPE (TREE_TYPE (src))));
4337       set_mem_align (srcb, TYPE_ALIGN (va_list_type_node));
4338
4339       /* Copy.  */
4340       emit_block_move (dstb, srcb, size, BLOCK_OP_NORMAL);
4341     }
4342
4343   return const0_rtx;
4344 }
4345
4346 /* Expand a call to one of the builtin functions __builtin_frame_address or
4347    __builtin_return_address.  */
4348
4349 static rtx
4350 expand_builtin_frame_address (tree fndecl, tree arglist)
4351 {
4352   /* The argument must be a nonnegative integer constant.
4353      It counts the number of frames to scan up the stack.
4354      The value is the return address saved in that frame.  */
4355   if (arglist == 0)
4356     /* Warning about missing arg was already issued.  */
4357     return const0_rtx;
4358   else if (! host_integerp (TREE_VALUE (arglist), 1))
4359     {
4360       if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4361         error ("invalid arg to `__builtin_frame_address'");
4362       else
4363         error ("invalid arg to `__builtin_return_address'");
4364       return const0_rtx;
4365     }
4366   else
4367     {
4368       rtx tem
4369         = expand_builtin_return_addr (DECL_FUNCTION_CODE (fndecl),
4370                                       tree_low_cst (TREE_VALUE (arglist), 1),
4371                                       hard_frame_pointer_rtx);
4372
4373       /* Some ports cannot access arbitrary stack frames.  */
4374       if (tem == NULL)
4375         {
4376           if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4377             warning ("unsupported arg to `__builtin_frame_address'");
4378           else
4379             warning ("unsupported arg to `__builtin_return_address'");
4380           return const0_rtx;
4381         }
4382
4383       /* For __builtin_frame_address, return what we've got.  */
4384       if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4385         return tem;
4386
4387       if (GET_CODE (tem) != REG
4388           && ! CONSTANT_P (tem))
4389         tem = copy_to_mode_reg (Pmode, tem);
4390       return tem;
4391     }
4392 }
4393
4394 /* Expand a call to the alloca builtin, with arguments ARGLIST.  Return 0 if
4395    we failed and the caller should emit a normal call, otherwise try to get
4396    the result in TARGET, if convenient.  */
4397
4398 static rtx
4399 expand_builtin_alloca (tree arglist, rtx target)
4400 {
4401   rtx op0;
4402   rtx result;
4403
4404   if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
4405     return 0;
4406
4407   /* Compute the argument.  */
4408   op0 = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
4409
4410   /* Allocate the desired space.  */
4411   result = allocate_dynamic_stack_space (op0, target, BITS_PER_UNIT);
4412   result = convert_memory_address (ptr_mode, result);
4413
4414   return result;
4415 }
4416
4417 /* Expand a call to a unary builtin.  The arguments are in ARGLIST.
4418    Return 0 if a normal call should be emitted rather than expanding the
4419    function in-line.  If convenient, the result should be placed in TARGET.
4420    SUBTARGET may be used as the target for computing one of EXP's operands.  */
4421
4422 static rtx
4423 expand_builtin_unop (enum machine_mode target_mode, tree arglist, rtx target,
4424                      rtx subtarget, optab op_optab)
4425 {
4426   rtx op0;
4427   if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
4428     return 0;
4429
4430   /* Compute the argument.  */
4431   op0 = expand_expr (TREE_VALUE (arglist), subtarget, VOIDmode, 0);
4432   /* Compute op, into TARGET if possible.
4433      Set TARGET to wherever the result comes back.  */
4434   target = expand_unop (TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist))),
4435                         op_optab, op0, target, 1);
4436   if (target == 0)
4437     abort ();
4438
4439   return convert_to_mode (target_mode, target, 0);
4440 }
4441
4442 /* If the string passed to fputs is a constant and is one character
4443    long, we attempt to transform this call into __builtin_fputc().  */
4444
4445 static rtx
4446 expand_builtin_fputs (tree arglist, rtx target, bool unlocked)
4447 {
4448   tree len, fn;
4449   tree fn_fputc = unlocked ? implicit_built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
4450     : implicit_built_in_decls[BUILT_IN_FPUTC];
4451   tree fn_fwrite = unlocked ? implicit_built_in_decls[BUILT_IN_FWRITE_UNLOCKED]
4452     : implicit_built_in_decls[BUILT_IN_FWRITE];
4453
4454   /* If the return value is used, or the replacement _DECL isn't
4455      initialized, don't do the transformation.  */
4456   if (target != const0_rtx || !fn_fputc || !fn_fwrite)
4457     return 0;
4458
4459   /* Verify the arguments in the original call.  */
4460   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4461     return 0;
4462
4463   /* Get the length of the string passed to fputs.  If the length
4464      can't be determined, punt.  */
4465   if (!(len = c_strlen (TREE_VALUE (arglist), 1))
4466       || TREE_CODE (len) != INTEGER_CST)
4467     return 0;
4468
4469   switch (compare_tree_int (len, 1))
4470     {
4471     case -1: /* length is 0, delete the call entirely .  */
4472       {
4473         /* Evaluate and ignore the argument in case it has
4474            side-effects.  */
4475         expand_expr (TREE_VALUE (TREE_CHAIN (arglist)), const0_rtx,
4476                      VOIDmode, EXPAND_NORMAL);
4477         return const0_rtx;
4478       }
4479     case 0: /* length is 1, call fputc.  */
4480       {
4481         const char *p = c_getstr (TREE_VALUE (arglist));
4482
4483         if (p != NULL)
4484           {
4485             /* New argument list transforming fputs(string, stream) to
4486                fputc(string[0], stream).  */
4487             arglist =
4488               build_tree_list (NULL_TREE, TREE_VALUE (TREE_CHAIN (arglist)));
4489             arglist =
4490               tree_cons (NULL_TREE, build_int_2 (p[0], 0), arglist);
4491             fn = fn_fputc;
4492             break;
4493           }
4494       }
4495       /* Fall through.  */
4496     case 1: /* length is greater than 1, call fwrite.  */
4497       {
4498         tree string_arg;
4499
4500         /* If optimizing for size keep fputs.  */
4501         if (optimize_size)
4502           return 0;
4503         string_arg = TREE_VALUE (arglist);
4504         /* New argument list transforming fputs(string, stream) to
4505            fwrite(string, 1, len, stream).  */
4506         arglist = build_tree_list (NULL_TREE, TREE_VALUE (TREE_CHAIN (arglist)));
4507         arglist = tree_cons (NULL_TREE, len, arglist);
4508         arglist = tree_cons (NULL_TREE, size_one_node, arglist);
4509         arglist = tree_cons (NULL_TREE, string_arg, arglist);
4510         fn = fn_fwrite;
4511         break;
4512       }
4513     default:
4514       abort ();
4515     }
4516
4517   return expand_expr (build_function_call_expr (fn, arglist),
4518                       const0_rtx, VOIDmode, EXPAND_NORMAL);
4519 }
4520
4521 /* Expand a call to __builtin_expect.  We return our argument and emit a
4522    NOTE_INSN_EXPECTED_VALUE note.  This is the expansion of __builtin_expect in
4523    a non-jump context.  */
4524
4525 static rtx
4526 expand_builtin_expect (tree arglist, rtx target)
4527 {
4528   tree exp, c;
4529   rtx note, rtx_c;
4530
4531   if (arglist == NULL_TREE
4532       || TREE_CHAIN (arglist) == NULL_TREE)
4533     return const0_rtx;
4534   exp = TREE_VALUE (arglist);
4535   c = TREE_VALUE (TREE_CHAIN (arglist));
4536
4537   if (TREE_CODE (c) != INTEGER_CST)
4538     {
4539       error ("second arg to `__builtin_expect' must be a constant");
4540       c = integer_zero_node;
4541     }
4542
4543   target = expand_expr (exp, target, VOIDmode, EXPAND_NORMAL);
4544
4545   /* Don't bother with expected value notes for integral constants.  */
4546   if (flag_guess_branch_prob && GET_CODE (target) != CONST_INT)
4547     {
4548       /* We do need to force this into a register so that we can be
4549          moderately sure to be able to correctly interpret the branch
4550          condition later.  */
4551       target = force_reg (GET_MODE (target), target);
4552
4553       rtx_c = expand_expr (c, NULL_RTX, GET_MODE (target), EXPAND_NORMAL);
4554
4555       note = emit_note (NOTE_INSN_EXPECTED_VALUE);
4556       NOTE_EXPECTED_VALUE (note) = gen_rtx_EQ (VOIDmode, target, rtx_c);
4557     }
4558
4559   return target;
4560 }
4561
4562 /* Like expand_builtin_expect, except do this in a jump context.  This is
4563    called from do_jump if the conditional is a __builtin_expect.  Return either
4564    a list of insns to emit the jump or NULL if we cannot optimize
4565    __builtin_expect.  We need to optimize this at jump time so that machines
4566    like the PowerPC don't turn the test into a SCC operation, and then jump
4567    based on the test being 0/1.  */
4568
4569 rtx
4570 expand_builtin_expect_jump (tree exp, rtx if_false_label, rtx if_true_label)
4571 {
4572   tree arglist = TREE_OPERAND (exp, 1);
4573   tree arg0 = TREE_VALUE (arglist);
4574   tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
4575   rtx ret = NULL_RTX;
4576
4577   /* Only handle __builtin_expect (test, 0) and
4578      __builtin_expect (test, 1).  */
4579   if (TREE_CODE (TREE_TYPE (arg1)) == INTEGER_TYPE
4580       && (integer_zerop (arg1) || integer_onep (arg1)))
4581     {
4582       rtx insn, drop_through_label, temp;
4583
4584       /* Expand the jump insns.  */
4585       start_sequence ();
4586       do_jump (arg0, if_false_label, if_true_label);
4587       ret = get_insns ();
4588
4589       drop_through_label = get_last_insn ();
4590       if (drop_through_label && GET_CODE (drop_through_label) == NOTE)
4591         drop_through_label = prev_nonnote_insn (drop_through_label);
4592       if (drop_through_label && GET_CODE (drop_through_label) != CODE_LABEL)
4593         drop_through_label = NULL_RTX;
4594       end_sequence ();
4595
4596       if (! if_true_label)
4597         if_true_label = drop_through_label;
4598       if (! if_false_label)
4599         if_false_label = drop_through_label;
4600
4601       /* Go through and add the expect's to each of the conditional jumps.  */
4602       insn = ret;
4603       while (insn != NULL_RTX)
4604         {
4605           rtx next = NEXT_INSN (insn);
4606
4607           if (GET_CODE (insn) == JUMP_INSN && any_condjump_p (insn))
4608             {
4609               rtx ifelse = SET_SRC (pc_set (insn));
4610               rtx then_dest = XEXP (ifelse, 1);
4611               rtx else_dest = XEXP (ifelse, 2);
4612               int taken = -1;
4613
4614               /* First check if we recognize any of the labels.  */
4615               if (GET_CODE (then_dest) == LABEL_REF
4616                   && XEXP (then_dest, 0) == if_true_label)
4617                 taken = 1;
4618               else if (GET_CODE (then_dest) == LABEL_REF
4619                        && XEXP (then_dest, 0) == if_false_label)
4620                 taken = 0;
4621               else if (GET_CODE (else_dest) == LABEL_REF
4622                        && XEXP (else_dest, 0) == if_false_label)
4623                 taken = 1;
4624               else if (GET_CODE (else_dest) == LABEL_REF
4625                        && XEXP (else_dest, 0) == if_true_label)
4626                 taken = 0;
4627               /* Otherwise check where we drop through.  */
4628               else if (else_dest == pc_rtx)
4629                 {
4630                   if (next && GET_CODE (next) == NOTE)
4631                     next = next_nonnote_insn (next);
4632
4633                   if (next && GET_CODE (next) == JUMP_INSN
4634                       && any_uncondjump_p (next))
4635                     temp = XEXP (SET_SRC (pc_set (next)), 0);
4636                   else
4637                     temp = next;
4638
4639                   /* TEMP is either a CODE_LABEL, NULL_RTX or something
4640                      else that can't possibly match either target label.  */
4641                   if (temp == if_false_label)
4642                     taken = 1;
4643                   else if (temp == if_true_label)
4644                     taken = 0;
4645                 }
4646               else if (then_dest == pc_rtx)
4647                 {
4648                   if (next && GET_CODE (next) == NOTE)
4649                     next = next_nonnote_insn (next);
4650
4651                   if (next && GET_CODE (next) == JUMP_INSN
4652                       && any_uncondjump_p (next))
4653                     temp = XEXP (SET_SRC (pc_set (next)), 0);
4654                   else
4655                     temp = next;
4656
4657                   if (temp == if_false_label)
4658                     taken = 0;
4659                   else if (temp == if_true_label)
4660                     taken = 1;
4661                 }
4662
4663               if (taken != -1)
4664                 {
4665                   /* If the test is expected to fail, reverse the
4666                      probabilities.  */
4667                   if (integer_zerop (arg1))
4668                     taken = 1 - taken;
4669                   predict_insn_def (insn, PRED_BUILTIN_EXPECT, taken);
4670                 }
4671             }
4672
4673           insn = next;
4674         }
4675     }
4676
4677   return ret;
4678 }
4679
4680 void
4681 expand_builtin_trap (void)
4682 {
4683 #ifdef HAVE_trap
4684   if (HAVE_trap)
4685     emit_insn (gen_trap ());
4686   else
4687 #endif
4688     emit_library_call (abort_libfunc, LCT_NORETURN, VOIDmode, 0);
4689   emit_barrier ();
4690 }
4691
4692 /* Expand a call to fabs, fabsf or fabsl with arguments ARGLIST.
4693    Return 0 if a normal call should be emitted rather than expanding
4694    the function inline.  If convenient, the result should be placed
4695    in TARGET.  SUBTARGET may be used as the target for computing
4696    the operand.  */
4697
4698 static rtx
4699 expand_builtin_fabs (tree arglist, rtx target, rtx subtarget)
4700 {
4701   enum machine_mode mode;
4702   tree arg;
4703   rtx op0;
4704
4705   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
4706     return 0;
4707
4708   arg = TREE_VALUE (arglist);
4709   mode = TYPE_MODE (TREE_TYPE (arg));
4710   op0 = expand_expr (arg, subtarget, VOIDmode, 0);
4711   return expand_abs (mode, op0, target, 0, safe_from_p (target, arg, 1));
4712 }
4713
4714 /* Expand a call to cabs, cabsf or cabsl with arguments ARGLIST.
4715    Return 0 if a normal call should be emitted rather than expanding
4716    the function inline.  If convenient, the result should be placed
4717    in target.  */
4718
4719 static rtx
4720 expand_builtin_cabs (tree arglist, rtx target)
4721 {
4722   enum machine_mode mode;
4723   tree arg;
4724   rtx op0;
4725
4726   if (arglist == 0 || TREE_CHAIN (arglist))
4727     return 0;
4728   arg = TREE_VALUE (arglist);
4729   if (TREE_CODE (TREE_TYPE (arg)) != COMPLEX_TYPE
4730       || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) != REAL_TYPE)
4731     return 0;
4732
4733   mode = TYPE_MODE (TREE_TYPE (arg));
4734   op0 = expand_expr (arg, NULL_RTX, VOIDmode, 0);
4735   return expand_complex_abs (mode, op0, target, 0);
4736 }
4737
4738 /* Create a new constant string literal and return a char* pointer to it.
4739    The STRING_CST value is the LEN characters at STR.  */
4740 static tree
4741 build_string_literal (int len, const char *str)
4742 {
4743   tree t, elem, index, type;
4744
4745   t = build_string (len, str);
4746   elem = build_type_variant (char_type_node, 1, 0);
4747   index = build_index_type (build_int_2 (len - 1, 0));
4748   type = build_array_type (elem, index);
4749   TREE_TYPE (t) = type;
4750   TREE_CONSTANT (t) = 1;
4751   TREE_READONLY (t) = 1;
4752   TREE_STATIC (t) = 1;
4753
4754   type = build_pointer_type (type);
4755   t = build1 (ADDR_EXPR, type, t);
4756
4757   type = build_pointer_type (elem);
4758   t = build1 (NOP_EXPR, type, t);
4759   return t;
4760 }
4761
4762 /* Expand a call to printf or printf_unlocked with argument list ARGLIST.
4763    Return 0 if a normal call should be emitted rather than transforming
4764    the function inline.  If convenient, the result should be placed in
4765    TARGET with mode MODE.  UNLOCKED indicates this is a printf_unlocked
4766    call.  */
4767 static rtx
4768 expand_builtin_printf (tree arglist, rtx target, enum machine_mode mode,
4769                        bool unlocked)
4770 {
4771   tree fn_putchar = unlocked
4772                     ? implicit_built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED]
4773                     : implicit_built_in_decls[BUILT_IN_PUTCHAR];
4774   tree fn_puts = unlocked ? implicit_built_in_decls[BUILT_IN_PUTS_UNLOCKED]
4775                           : implicit_built_in_decls[BUILT_IN_PUTS];
4776   const char *fmt_str;
4777   tree fn, fmt, arg;
4778
4779   /* If the return value is used, don't do the transformation.  */
4780   if (target != const0_rtx)
4781     return 0;
4782
4783   /* Verify the required arguments in the original call.  */
4784   if (! arglist)
4785     return 0;
4786   fmt = TREE_VALUE (arglist);
4787   if (TREE_CODE (TREE_TYPE (fmt)) != POINTER_TYPE)
4788     return 0;
4789   arglist = TREE_CHAIN (arglist);
4790
4791   /* Check whether the format is a literal string constant.  */
4792   fmt_str = c_getstr (fmt);
4793   if (fmt_str == NULL)
4794     return 0;
4795
4796   /* If the format specifier was "%s\n", call __builtin_puts(arg).  */
4797   if (strcmp (fmt_str, "%s\n") == 0)
4798     {
4799       if (! arglist
4800           || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE
4801           || TREE_CHAIN (arglist))
4802         return 0;
4803       fn = fn_puts;
4804     }
4805   /* If the format specifier was "%c", call __builtin_putchar(arg).  */
4806   else if (strcmp (fmt_str, "%c") == 0)
4807     {
4808       if (! arglist
4809           || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
4810           || TREE_CHAIN (arglist))
4811         return 0;
4812       fn = fn_putchar;
4813     }
4814   else
4815     {
4816       /* We can't handle anything else with % args or %% ... yet.  */
4817       if (strchr (fmt_str, '%'))
4818         return 0;
4819
4820       if (arglist)
4821         return 0;
4822
4823       /* If the format specifier was "", printf does nothing.  */
4824       if (fmt_str[0] == '\0')
4825         return const0_rtx;
4826       /* If the format specifier has length of 1, call putchar.  */
4827       if (fmt_str[1] == '\0')
4828         {
4829           /* Given printf("c"), (where c is any one character,)
4830              convert "c"[0] to an int and pass that to the replacement
4831              function.  */
4832           arg = build_int_2 (fmt_str[0], 0);
4833           arglist = build_tree_list (NULL_TREE, arg);
4834           fn = fn_putchar;
4835         }
4836       else
4837         {
4838           /* If the format specifier was "string\n", call puts("string").  */
4839           size_t len = strlen (fmt_str);
4840           if (fmt_str[len - 1] == '\n')
4841             {
4842               /* Create a NUL-terminated string that's one char shorter
4843                  than the original, stripping off the trailing '\n'.  */
4844               char *newstr = alloca (len);
4845               memcpy (newstr, fmt_str, len - 1);
4846               newstr[len - 1] = 0;
4847
4848               arg = build_string_literal (len, newstr);
4849               arglist = build_tree_list (NULL_TREE, arg);
4850               fn = fn_puts;
4851             }
4852           else
4853             /* We'd like to arrange to call fputs(string,stdout) here,
4854                but we need stdout and don't have a way to get it yet.  */
4855             return 0;
4856         }
4857     }
4858
4859   if (!fn)
4860     return 0;
4861   return expand_expr (build_function_call_expr (fn, arglist),
4862                       target, mode, EXPAND_NORMAL);
4863 }
4864
4865 /* Expand a call to fprintf or fprintf_unlocked with argument list ARGLIST.
4866    Return 0 if a normal call should be emitted rather than transforming
4867    the function inline.  If convenient, the result should be placed in
4868    TARGET with mode MODE.  UNLOCKED indicates this is a fprintf_unlocked
4869    call.  */
4870 static rtx
4871 expand_builtin_fprintf (tree arglist, rtx target, enum machine_mode mode,
4872                         bool unlocked)
4873 {
4874   tree fn_fputc = unlocked ? implicit_built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
4875                            : implicit_built_in_decls[BUILT_IN_FPUTC];
4876   tree fn_fputs = unlocked ? implicit_built_in_decls[BUILT_IN_FPUTS_UNLOCKED]
4877                            : implicit_built_in_decls[BUILT_IN_FPUTS];
4878   const char *fmt_str;
4879   tree fn, fmt, fp, arg;
4880
4881   /* If the return value is used, don't do the transformation.  */
4882   if (target != const0_rtx)
4883     return 0;
4884
4885   /* Verify the required arguments in the original call.  */
4886   if (! arglist)
4887     return 0;
4888   fp = TREE_VALUE (arglist);
4889   if (TREE_CODE (TREE_TYPE (fp)) != POINTER_TYPE)
4890     return 0;
4891   arglist = TREE_CHAIN (arglist);
4892   if (! arglist)
4893     return 0;
4894   fmt = TREE_VALUE (arglist);
4895   if (TREE_CODE (TREE_TYPE (fmt)) != POINTER_TYPE)
4896     return 0;
4897   arglist = TREE_CHAIN (arglist);
4898
4899   /* Check whether the format is a literal string constant.  */
4900   fmt_str = c_getstr (fmt);
4901   if (fmt_str == NULL)
4902     return 0;
4903
4904   /* If the format specifier was "%s", call __builtin_fputs(arg,fp).  */
4905   if (strcmp (fmt_str, "%s") == 0)
4906     {
4907       if (! arglist
4908           || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE
4909           || TREE_CHAIN (arglist))
4910         return 0;
4911       arg = TREE_VALUE (arglist);
4912       arglist = build_tree_list (NULL_TREE, fp);
4913       arglist = tree_cons (NULL_TREE, arg, arglist);
4914       fn = fn_fputs;
4915     }
4916   /* If the format specifier was "%c", call __builtin_fputc(arg,fp).  */
4917   else if (strcmp (fmt_str, "%c") == 0)
4918     {
4919       if (! arglist
4920           || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
4921           || TREE_CHAIN (arglist))
4922         return 0;
4923       arg = TREE_VALUE (arglist);
4924       arglist = build_tree_list (NULL_TREE, fp);
4925       arglist = tree_cons (NULL_TREE, arg, arglist);
4926       fn = fn_fputc;
4927     }
4928   else
4929     {
4930       /* We can't handle anything else with % args or %% ... yet.  */
4931       if (strchr (fmt_str, '%'))
4932         return 0;
4933
4934       if (arglist)
4935         return 0;
4936
4937       /* If the format specifier was "", fprintf does nothing.  */
4938       if (fmt_str[0] == '\0')
4939         {
4940           /* Evaluate and ignore FILE* argument for side-effects.  */
4941           expand_expr (fp, const0_rtx, VOIDmode, EXPAND_NORMAL);
4942           return const0_rtx;
4943         }
4944
4945       /* When "string" doesn't contain %, replace all cases of
4946          fprintf(stream,string) with fputs(string,stream).  The fputs
4947          builtin will take care of special cases like length == 1.  */
4948       arglist = build_tree_list (NULL_TREE, fp);
4949       arglist = tree_cons (NULL_TREE, fmt, arglist);
4950       fn = fn_fputs;
4951     }
4952
4953   if (!fn)
4954     return 0;
4955   return expand_expr (build_function_call_expr (fn, arglist),
4956                       target, mode, EXPAND_NORMAL);
4957 }
4958
4959 /* Expand a call to sprintf with argument list ARGLIST.  Return 0 if
4960    a normal call should be emitted rather than expanding the function
4961    inline.  If convenient, the result should be placed in TARGET with
4962    mode MODE.  */
4963
4964 static rtx
4965 expand_builtin_sprintf (tree arglist, rtx target, enum machine_mode mode)
4966 {
4967   tree orig_arglist, dest, fmt;
4968   const char *fmt_str;
4969
4970   orig_arglist = arglist;
4971
4972   /* Verify the required arguments in the original call.  */
4973   if (! arglist)
4974     return 0;
4975   dest = TREE_VALUE (arglist);
4976   if (TREE_CODE (TREE_TYPE (dest)) != POINTER_TYPE)
4977     return 0;
4978   arglist = TREE_CHAIN (arglist);
4979   if (! arglist)
4980     return 0;
4981   fmt = TREE_VALUE (arglist);
4982   if (TREE_CODE (TREE_TYPE (fmt)) != POINTER_TYPE)
4983     return 0;
4984   arglist = TREE_CHAIN (arglist);
4985
4986   /* Check whether the format is a literal string constant.  */
4987   fmt_str = c_getstr (fmt);
4988   if (fmt_str == NULL)
4989     return 0;
4990
4991   /* If the format doesn't contain % args or %%, use strcpy.  */
4992   if (strchr (fmt_str, '%') == 0)
4993     {
4994       tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
4995       tree exp;
4996
4997       if (arglist || ! fn)
4998         return 0;
4999       expand_expr (build_function_call_expr (fn, orig_arglist),
5000                    const0_rtx, VOIDmode, EXPAND_NORMAL);
5001       if (target == const0_rtx)
5002         return const0_rtx;
5003       exp = build_int_2 (strlen (fmt_str), 0);
5004       exp = fold_convert (integer_type_node, exp);
5005       return expand_expr (exp, target, mode, EXPAND_NORMAL);
5006     }
5007   /* If the format is "%s", use strcpy if the result isn't used.  */
5008   else if (strcmp (fmt_str, "%s") == 0)
5009     {
5010       tree fn, arg, len;
5011       fn = implicit_built_in_decls[BUILT_IN_STRCPY];
5012
5013       if (! fn)
5014         return 0;
5015
5016       if (! arglist || TREE_CHAIN (arglist))
5017         return 0;
5018       arg = TREE_VALUE (arglist);
5019       if (TREE_CODE (TREE_TYPE (arg)) != POINTER_TYPE)
5020         return 0;
5021
5022       if (target != const0_rtx)
5023         {
5024           len = c_strlen (arg, 1);
5025           if (! len || TREE_CODE (len) != INTEGER_CST)
5026             return 0;
5027         }
5028       else
5029         len = NULL_TREE;
5030
5031       arglist = build_tree_list (NULL_TREE, arg);
5032       arglist = tree_cons (NULL_TREE, dest, arglist);
5033       expand_expr (build_function_call_expr (fn, arglist),
5034                    const0_rtx, VOIDmode, EXPAND_NORMAL);
5035
5036       if (target == const0_rtx)
5037         return const0_rtx;
5038       return expand_expr (len, target, mode, EXPAND_NORMAL);
5039     }
5040
5041   return 0;
5042 }
5043
5044 /* Expand a call to the built-in signbit, signbitf or signbitl function.
5045    Return NULL_RTX if a normal call should be emitted rather than expanding
5046    the function in-line.  EXP is the expression that is a call to the builtin
5047    function; if convenient, the result should be placed in TARGET.  */
5048
5049 static rtx
5050 expand_builtin_signbit (tree exp, rtx target)
5051 {
5052   const struct real_format *fmt;
5053   enum machine_mode fmode, imode, rmode;
5054   HOST_WIDE_INT hi, lo;
5055   tree arg, arglist;
5056   int bitpos;
5057   rtx temp;
5058
5059   arglist = TREE_OPERAND (exp, 1);
5060   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
5061     return 0;
5062
5063   arg = TREE_VALUE (arglist);
5064   fmode = TYPE_MODE (TREE_TYPE (arg));
5065   rmode = TYPE_MODE (TREE_TYPE (exp));
5066   fmt = REAL_MODE_FORMAT (fmode);
5067
5068   /* For floating point formats without a sign bit, implement signbit
5069      as "ARG < 0.0".  */
5070   if (fmt->signbit < 0)
5071   {
5072     /* But we can't do this if the format supports signed zero.  */
5073     if (fmt->has_signed_zero && HONOR_SIGNED_ZEROS (fmode))
5074       return 0;
5075
5076     arg = fold (build (LT_EXPR, TREE_TYPE (exp), arg,
5077                 build_real (TREE_TYPE (arg), dconst0)));
5078     return expand_expr (arg, target, VOIDmode, EXPAND_NORMAL);
5079   }
5080
5081   imode = int_mode_for_mode (fmode);
5082   if (imode == BLKmode)
5083     return 0;
5084
5085   bitpos = fmt->signbit;
5086   /* Handle targets with different FP word orders.  */
5087   if (FLOAT_WORDS_BIG_ENDIAN != WORDS_BIG_ENDIAN)
5088     {
5089       int nwords = GET_MODE_BITSIZE (fmode) / BITS_PER_WORD;
5090       int word = nwords - (bitpos / BITS_PER_WORD) - 1;
5091       bitpos = word * BITS_PER_WORD + bitpos % BITS_PER_WORD;
5092     }
5093
5094   /* If the sign bit is not in the lowpart and the floating point format
5095      is wider than an integer, check that is twice the size of an integer
5096      so that we can use gen_highpart below.  */
5097   if (bitpos >= GET_MODE_BITSIZE (rmode)
5098       && GET_MODE_BITSIZE (imode) != 2 * GET_MODE_BITSIZE (rmode))
5099     return 0;
5100
5101   temp = expand_expr (arg, NULL_RTX, VOIDmode, 0);
5102   temp = gen_lowpart (imode, temp);
5103
5104   if (GET_MODE_BITSIZE (imode) > GET_MODE_BITSIZE (rmode))
5105     {
5106       if (BYTES_BIG_ENDIAN)
5107         bitpos = GET_MODE_BITSIZE (imode) - 1 - bitpos;
5108       temp = copy_to_mode_reg (imode, temp);
5109       temp = extract_bit_field (temp, 1, bitpos, 1,
5110                                 NULL_RTX, rmode, rmode,
5111                                 GET_MODE_SIZE (imode));
5112     }
5113   else
5114     {
5115       if (GET_MODE_BITSIZE (imode) < GET_MODE_BITSIZE (rmode))
5116         temp = gen_lowpart (rmode, temp);
5117       if (bitpos < HOST_BITS_PER_WIDE_INT)
5118         {
5119           hi = 0;
5120           lo = (HOST_WIDE_INT) 1 << bitpos;
5121         }
5122       else
5123         {
5124           hi = (HOST_WIDE_INT) 1 << (bitpos - HOST_BITS_PER_WIDE_INT);
5125           lo = 0;
5126         }
5127
5128       temp = force_reg (rmode, temp);
5129       temp = expand_binop (rmode, and_optab, temp,
5130                            immed_double_const (lo, hi, rmode),
5131                            target, 1, OPTAB_LIB_WIDEN);
5132     }
5133   return temp;
5134 }
5135
5136 /* Expand fork or exec calls.  TARGET is the desired target of the
5137    call.  ARGLIST is the list of arguments of the call.  FN is the
5138    identificator of the actual function.  IGNORE is nonzero if the
5139    value is to be ignored.  */
5140
5141 static rtx
5142 expand_builtin_fork_or_exec (tree fn, tree arglist, rtx target, int ignore)
5143 {
5144   tree id, decl;
5145   tree call;
5146
5147   /* If we are not profiling, just call the function.  */
5148   if (!profile_arc_flag)
5149     return NULL_RTX;
5150
5151   /* Otherwise call the wrapper.  This should be equivalent for the rest of
5152      compiler, so the code does not diverge, and the wrapper may run the
5153      code necessary for keeping the profiling sane.  */
5154
5155   switch (DECL_FUNCTION_CODE (fn))
5156     {
5157     case BUILT_IN_FORK:
5158       id = get_identifier ("__gcov_fork");
5159       break;
5160
5161     case BUILT_IN_EXECL:
5162       id = get_identifier ("__gcov_execl");
5163       break;
5164
5165     case BUILT_IN_EXECV:
5166       id = get_identifier ("__gcov_execv");
5167       break;
5168
5169     case BUILT_IN_EXECLP:
5170       id = get_identifier ("__gcov_execlp");
5171       break;
5172
5173     case BUILT_IN_EXECLE:
5174       id = get_identifier ("__gcov_execle");
5175       break;
5176
5177     case BUILT_IN_EXECVP:
5178       id = get_identifier ("__gcov_execvp");
5179       break;
5180
5181     case BUILT_IN_EXECVE:
5182       id = get_identifier ("__gcov_execve");
5183       break;
5184
5185     default:
5186       abort ();
5187     }
5188
5189   decl = build_decl (FUNCTION_DECL, id, TREE_TYPE (fn));
5190   DECL_EXTERNAL (decl) = 1;
5191   TREE_PUBLIC (decl) = 1;
5192   DECL_ARTIFICIAL (decl) = 1;
5193   TREE_NOTHROW (decl) = 1;
5194   call = build_function_call_expr (decl, arglist);
5195
5196   return expand_call (call, target, ignore);
5197 }
5198 \f
5199 /* Expand an expression EXP that calls a built-in function,
5200    with result going to TARGET if that's convenient
5201    (and in mode MODE if that's convenient).
5202    SUBTARGET may be used as the target for computing one of EXP's operands.
5203    IGNORE is nonzero if the value is to be ignored.  */
5204
5205 rtx
5206 expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
5207                 int ignore)
5208 {
5209   tree fndecl = get_callee_fndecl (exp);
5210   tree arglist = TREE_OPERAND (exp, 1);
5211   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
5212   enum machine_mode target_mode = TYPE_MODE (TREE_TYPE (exp));
5213
5214   /* Perform postincrements before expanding builtin functions.  */
5215   emit_queue ();
5216
5217   if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
5218     return targetm.expand_builtin (exp, target, subtarget, mode, ignore);
5219
5220   /* When not optimizing, generate calls to library functions for a certain
5221      set of builtins.  */
5222   if (!optimize
5223       && !CALLED_AS_BUILT_IN (fndecl)
5224       && DECL_ASSEMBLER_NAME_SET_P (fndecl)
5225       && fcode != BUILT_IN_ALLOCA)
5226     return expand_call (exp, target, ignore);
5227
5228   /* The built-in function expanders test for target == const0_rtx
5229      to determine whether the function's result will be ignored.  */
5230   if (ignore)
5231     target = const0_rtx;
5232
5233   /* If the result of a pure or const built-in function is ignored, and
5234      none of its arguments are volatile, we can avoid expanding the
5235      built-in call and just evaluate the arguments for side-effects.  */
5236   if (target == const0_rtx
5237       && (DECL_IS_PURE (fndecl) || TREE_READONLY (fndecl)))
5238     {
5239       bool volatilep = false;
5240       tree arg;
5241
5242       for (arg = arglist; arg; arg = TREE_CHAIN (arg))
5243         if (TREE_THIS_VOLATILE (TREE_VALUE (arg)))
5244           {
5245             volatilep = true;
5246             break;
5247           }
5248
5249       if (! volatilep)
5250         {
5251           for (arg = arglist; arg; arg = TREE_CHAIN (arg))
5252             expand_expr (TREE_VALUE (arg), const0_rtx,
5253                          VOIDmode, EXPAND_NORMAL);
5254           return const0_rtx;
5255         }
5256     }
5257
5258   switch (fcode)
5259     {
5260     case BUILT_IN_ABS:
5261     case BUILT_IN_LABS:
5262     case BUILT_IN_LLABS:
5263     case BUILT_IN_IMAXABS:
5264       /* build_function_call changes these into ABS_EXPR.  */
5265       abort ();
5266
5267     case BUILT_IN_FABS:
5268     case BUILT_IN_FABSF:
5269     case BUILT_IN_FABSL:
5270       target = expand_builtin_fabs (arglist, target, subtarget);
5271       if (target)
5272         return target;
5273       break;
5274
5275     case BUILT_IN_CABS:
5276     case BUILT_IN_CABSF:
5277     case BUILT_IN_CABSL:
5278       if (flag_unsafe_math_optimizations)
5279         {
5280           target = expand_builtin_cabs (arglist, target);
5281           if (target)
5282             return target;
5283         }
5284       break;
5285
5286     case BUILT_IN_CONJ:
5287     case BUILT_IN_CONJF:
5288     case BUILT_IN_CONJL:
5289     case BUILT_IN_CREAL:
5290     case BUILT_IN_CREALF:
5291     case BUILT_IN_CREALL:
5292     case BUILT_IN_CIMAG:
5293     case BUILT_IN_CIMAGF:
5294     case BUILT_IN_CIMAGL:
5295       /* expand_tree_builtin changes these into CONJ_EXPR, REALPART_EXPR
5296          and IMAGPART_EXPR.  */
5297       abort ();
5298
5299     case BUILT_IN_EXP:
5300     case BUILT_IN_EXPF:
5301     case BUILT_IN_EXPL:
5302     case BUILT_IN_EXP10:
5303     case BUILT_IN_EXP10F:
5304     case BUILT_IN_EXP10L:
5305     case BUILT_IN_POW10:
5306     case BUILT_IN_POW10F:
5307     case BUILT_IN_POW10L:
5308     case BUILT_IN_EXP2:
5309     case BUILT_IN_EXP2F:
5310     case BUILT_IN_EXP2L:
5311     case BUILT_IN_EXPM1:
5312     case BUILT_IN_EXPM1F:
5313     case BUILT_IN_EXPM1L:
5314     case BUILT_IN_LOGB:
5315     case BUILT_IN_LOGBF:
5316     case BUILT_IN_LOGBL:
5317     case BUILT_IN_ILOGB:
5318     case BUILT_IN_ILOGBF:
5319     case BUILT_IN_ILOGBL:
5320     case BUILT_IN_LOG:
5321     case BUILT_IN_LOGF:
5322     case BUILT_IN_LOGL:
5323     case BUILT_IN_LOG10:
5324     case BUILT_IN_LOG10F:
5325     case BUILT_IN_LOG10L:
5326     case BUILT_IN_LOG2:
5327     case BUILT_IN_LOG2F:
5328     case BUILT_IN_LOG2L:
5329     case BUILT_IN_LOG1P:
5330     case BUILT_IN_LOG1PF:
5331     case BUILT_IN_LOG1PL:
5332     case BUILT_IN_TAN:
5333     case BUILT_IN_TANF:
5334     case BUILT_IN_TANL:
5335     case BUILT_IN_ASIN:
5336     case BUILT_IN_ASINF:
5337     case BUILT_IN_ASINL:
5338     case BUILT_IN_ACOS:
5339     case BUILT_IN_ACOSF:
5340     case BUILT_IN_ACOSL:
5341     case BUILT_IN_ATAN:
5342     case BUILT_IN_ATANF:
5343     case BUILT_IN_ATANL:
5344       /* Treat these like sqrt only if unsafe math optimizations are allowed,
5345          because of possible accuracy problems.  */
5346       if (! flag_unsafe_math_optimizations)
5347         break;
5348     case BUILT_IN_SQRT:
5349     case BUILT_IN_SQRTF:
5350     case BUILT_IN_SQRTL:
5351     case BUILT_IN_FLOOR:
5352     case BUILT_IN_FLOORF:
5353     case BUILT_IN_FLOORL:
5354     case BUILT_IN_CEIL:
5355     case BUILT_IN_CEILF:
5356     case BUILT_IN_CEILL:
5357     case BUILT_IN_TRUNC:
5358     case BUILT_IN_TRUNCF:
5359     case BUILT_IN_TRUNCL:
5360     case BUILT_IN_ROUND:
5361     case BUILT_IN_ROUNDF:
5362     case BUILT_IN_ROUNDL:
5363     case BUILT_IN_NEARBYINT:
5364     case BUILT_IN_NEARBYINTF:
5365     case BUILT_IN_NEARBYINTL:
5366       target = expand_builtin_mathfn (exp, target, subtarget);
5367       if (target)
5368         return target;
5369       break;
5370
5371     case BUILT_IN_POW:
5372     case BUILT_IN_POWF:
5373     case BUILT_IN_POWL:
5374       target = expand_builtin_pow (exp, target, subtarget);
5375       if (target)
5376         return target;
5377       break;
5378
5379     case BUILT_IN_ATAN2:
5380     case BUILT_IN_ATAN2F:
5381     case BUILT_IN_ATAN2L:
5382     case BUILT_IN_FMOD:
5383     case BUILT_IN_FMODF:
5384     case BUILT_IN_FMODL:
5385     case BUILT_IN_DREM:
5386     case BUILT_IN_DREMF:
5387     case BUILT_IN_DREML:
5388       if (! flag_unsafe_math_optimizations)
5389         break;
5390       target = expand_builtin_mathfn_2 (exp, target, subtarget);
5391       if (target)
5392         return target;
5393       break;
5394
5395     case BUILT_IN_SIN:
5396     case BUILT_IN_SINF:
5397     case BUILT_IN_SINL:
5398     case BUILT_IN_COS:
5399     case BUILT_IN_COSF:
5400     case BUILT_IN_COSL:
5401       if (! flag_unsafe_math_optimizations)
5402         break;
5403       target = expand_builtin_mathfn_3 (exp, target, subtarget);
5404       if (target)
5405         return target;
5406       break;
5407
5408     case BUILT_IN_APPLY_ARGS:
5409       return expand_builtin_apply_args ();
5410
5411       /* __builtin_apply (FUNCTION, ARGUMENTS, ARGSIZE) invokes
5412          FUNCTION with a copy of the parameters described by
5413          ARGUMENTS, and ARGSIZE.  It returns a block of memory
5414          allocated on the stack into which is stored all the registers
5415          that might possibly be used for returning the result of a
5416          function.  ARGUMENTS is the value returned by
5417          __builtin_apply_args.  ARGSIZE is the number of bytes of
5418          arguments that must be copied.  ??? How should this value be
5419          computed?  We'll also need a safe worst case value for varargs
5420          functions.  */
5421     case BUILT_IN_APPLY:
5422       if (!validate_arglist (arglist, POINTER_TYPE,
5423                              POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)
5424           && !validate_arglist (arglist, REFERENCE_TYPE,
5425                                 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
5426         return const0_rtx;
5427       else
5428         {
5429           int i;
5430           tree t;
5431           rtx ops[3];
5432
5433           for (t = arglist, i = 0; t; t = TREE_CHAIN (t), i++)
5434             ops[i] = expand_expr (TREE_VALUE (t), NULL_RTX, VOIDmode, 0);
5435
5436           return expand_builtin_apply (ops[0], ops[1], ops[2]);
5437         }
5438
5439       /* __builtin_return (RESULT) causes the function to return the
5440          value described by RESULT.  RESULT is address of the block of
5441          memory returned by __builtin_apply.  */
5442     case BUILT_IN_RETURN:
5443       if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5444         expand_builtin_return (expand_expr (TREE_VALUE (arglist),
5445                                             NULL_RTX, VOIDmode, 0));
5446       return const0_rtx;
5447
5448     case BUILT_IN_SAVEREGS:
5449       return expand_builtin_saveregs ();
5450
5451     case BUILT_IN_ARGS_INFO:
5452       return expand_builtin_args_info (arglist);
5453
5454       /* Return the address of the first anonymous stack arg.  */
5455     case BUILT_IN_NEXT_ARG:
5456       return expand_builtin_next_arg (arglist);
5457
5458     case BUILT_IN_CLASSIFY_TYPE:
5459       return expand_builtin_classify_type (arglist);
5460
5461     case BUILT_IN_CONSTANT_P:
5462       return expand_builtin_constant_p (arglist, target_mode);
5463
5464     case BUILT_IN_FRAME_ADDRESS:
5465     case BUILT_IN_RETURN_ADDRESS:
5466       return expand_builtin_frame_address (fndecl, arglist);
5467
5468     /* Returns the address of the area where the structure is returned.
5469        0 otherwise.  */
5470     case BUILT_IN_AGGREGATE_INCOMING_ADDRESS:
5471       if (arglist != 0
5472           || ! AGGREGATE_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl)))
5473           || GET_CODE (DECL_RTL (DECL_RESULT (current_function_decl))) != MEM)
5474         return const0_rtx;
5475       else
5476         return XEXP (DECL_RTL (DECL_RESULT (current_function_decl)), 0);
5477
5478     case BUILT_IN_ALLOCA:
5479       target = expand_builtin_alloca (arglist, target);
5480       if (target)
5481         return target;
5482       break;
5483
5484     case BUILT_IN_FFS:
5485     case BUILT_IN_FFSL:
5486     case BUILT_IN_FFSLL:
5487       target = expand_builtin_unop (target_mode, arglist, target,
5488                                     subtarget, ffs_optab);
5489       if (target)
5490         return target;
5491       break;
5492
5493     case BUILT_IN_CLZ:
5494     case BUILT_IN_CLZL:
5495     case BUILT_IN_CLZLL:
5496       target = expand_builtin_unop (target_mode, arglist, target,
5497                                     subtarget, clz_optab);
5498       if (target)
5499         return target;
5500       break;
5501
5502     case BUILT_IN_CTZ:
5503     case BUILT_IN_CTZL:
5504     case BUILT_IN_CTZLL:
5505       target = expand_builtin_unop (target_mode, arglist, target,
5506                                     subtarget, ctz_optab);
5507       if (target)
5508         return target;
5509       break;
5510
5511     case BUILT_IN_POPCOUNT:
5512     case BUILT_IN_POPCOUNTL:
5513     case BUILT_IN_POPCOUNTLL:
5514       target = expand_builtin_unop (target_mode, arglist, target,
5515                                     subtarget, popcount_optab);
5516       if (target)
5517         return target;
5518       break;
5519
5520     case BUILT_IN_PARITY:
5521     case BUILT_IN_PARITYL:
5522     case BUILT_IN_PARITYLL:
5523       target = expand_builtin_unop (target_mode, arglist, target,
5524                                     subtarget, parity_optab);
5525       if (target)
5526         return target;
5527       break;
5528
5529     case BUILT_IN_STRLEN:
5530       target = expand_builtin_strlen (arglist, target, target_mode);
5531       if (target)
5532         return target;
5533       break;
5534
5535     case BUILT_IN_STRCPY:
5536       target = expand_builtin_strcpy (arglist, target, mode);
5537       if (target)
5538         return target;
5539       break;
5540
5541     case BUILT_IN_STRNCPY:
5542       target = expand_builtin_strncpy (arglist, target, mode);
5543       if (target)
5544         return target;
5545       break;
5546
5547     case BUILT_IN_STPCPY:
5548       target = expand_builtin_stpcpy (arglist, target, mode);
5549       if (target)
5550         return target;
5551       break;
5552
5553     case BUILT_IN_STRCAT:
5554       target = expand_builtin_strcat (arglist, target, mode);
5555       if (target)
5556         return target;
5557       break;
5558
5559     case BUILT_IN_STRNCAT:
5560       target = expand_builtin_strncat (arglist, target, mode);
5561       if (target)
5562         return target;
5563       break;
5564
5565     case BUILT_IN_STRSPN:
5566       target = expand_builtin_strspn (arglist, target, mode);
5567       if (target)
5568         return target;
5569       break;
5570
5571     case BUILT_IN_STRCSPN:
5572       target = expand_builtin_strcspn (arglist, target, mode);
5573       if (target)
5574         return target;
5575       break;
5576
5577     case BUILT_IN_STRSTR:
5578       target = expand_builtin_strstr (arglist, target, mode);
5579       if (target)
5580         return target;
5581       break;
5582
5583     case BUILT_IN_STRPBRK:
5584       target = expand_builtin_strpbrk (arglist, target, mode);
5585       if (target)
5586         return target;
5587       break;
5588
5589     case BUILT_IN_INDEX:
5590     case BUILT_IN_STRCHR:
5591       target = expand_builtin_strchr (arglist, target, mode);
5592       if (target)
5593         return target;
5594       break;
5595
5596     case BUILT_IN_RINDEX:
5597     case BUILT_IN_STRRCHR:
5598       target = expand_builtin_strrchr (arglist, target, mode);
5599       if (target)
5600         return target;
5601       break;
5602
5603     case BUILT_IN_MEMCPY:
5604       target = expand_builtin_memcpy (arglist, target, mode);
5605       if (target)
5606         return target;
5607       break;
5608
5609     case BUILT_IN_MEMPCPY:
5610       target = expand_builtin_mempcpy (arglist, target, mode, /*endp=*/ 1);
5611       if (target)
5612         return target;
5613       break;
5614
5615     case BUILT_IN_MEMMOVE:
5616       target = expand_builtin_memmove (arglist, target, mode);
5617       if (target)
5618         return target;
5619       break;
5620
5621     case BUILT_IN_BCOPY:
5622       target = expand_builtin_bcopy (arglist);
5623       if (target)
5624         return target;
5625       break;
5626
5627     case BUILT_IN_MEMSET:
5628       target = expand_builtin_memset (arglist, target, mode);
5629       if (target)
5630         return target;
5631       break;
5632
5633     case BUILT_IN_BZERO:
5634       target = expand_builtin_bzero (arglist);
5635       if (target)
5636         return target;
5637       break;
5638
5639     case BUILT_IN_STRCMP:
5640       target = expand_builtin_strcmp (exp, target, mode);
5641       if (target)
5642         return target;
5643       break;
5644
5645     case BUILT_IN_STRNCMP:
5646       target = expand_builtin_strncmp (exp, target, mode);
5647       if (target)
5648         return target;
5649       break;
5650
5651     case BUILT_IN_BCMP:
5652     case BUILT_IN_MEMCMP:
5653       target = expand_builtin_memcmp (exp, arglist, target, mode);
5654       if (target)
5655         return target;
5656       break;
5657
5658     case BUILT_IN_SETJMP:
5659       target = expand_builtin_setjmp (arglist, target);
5660       if (target)
5661         return target;
5662       break;
5663
5664       /* __builtin_longjmp is passed a pointer to an array of five words.
5665          It's similar to the C library longjmp function but works with
5666          __builtin_setjmp above.  */
5667     case BUILT_IN_LONGJMP:
5668       if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
5669         break;
5670       else
5671         {
5672           rtx buf_addr = expand_expr (TREE_VALUE (arglist), subtarget,
5673                                       VOIDmode, 0);
5674           rtx value = expand_expr (TREE_VALUE (TREE_CHAIN (arglist)),
5675                                    NULL_RTX, VOIDmode, 0);
5676
5677           if (value != const1_rtx)
5678             {
5679               error ("__builtin_longjmp second argument must be 1");
5680               return const0_rtx;
5681             }
5682
5683           expand_builtin_longjmp (buf_addr, value);
5684           return const0_rtx;
5685         }
5686
5687       /* This updates the setjmp buffer that is its argument with the value
5688          of the current stack pointer.  */
5689     case BUILT_IN_UPDATE_SETJMP_BUF:
5690       if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5691         {
5692           rtx buf_addr
5693             = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
5694
5695           expand_builtin_update_setjmp_buf (buf_addr);
5696           return const0_rtx;
5697         }
5698       break;
5699
5700     case BUILT_IN_TRAP:
5701       expand_builtin_trap ();
5702       return const0_rtx;
5703
5704     case BUILT_IN_PRINTF:
5705       target = expand_builtin_printf (arglist, target, mode, false);
5706       if (target)
5707         return target;
5708       break;
5709
5710     case BUILT_IN_PRINTF_UNLOCKED:
5711       target = expand_builtin_printf (arglist, target, mode, true);
5712       if (target)
5713         return target;
5714       break;
5715
5716     case BUILT_IN_FPUTS:
5717       target = expand_builtin_fputs (arglist, target, false);
5718       if (target)
5719         return target;
5720       break;
5721
5722     case BUILT_IN_FPUTS_UNLOCKED:
5723       target = expand_builtin_fputs (arglist, target, true);
5724       if (target)
5725         return target;
5726       break;
5727
5728     case BUILT_IN_FPRINTF:
5729       target = expand_builtin_fprintf (arglist, target, mode, false);
5730       if (target)
5731         return target;
5732       break;
5733
5734     case BUILT_IN_FPRINTF_UNLOCKED:
5735       target = expand_builtin_fprintf (arglist, target, mode, true);
5736       if (target)
5737         return target;
5738       break;
5739
5740     case BUILT_IN_SPRINTF:
5741       target = expand_builtin_sprintf (arglist, target, mode);
5742       if (target)
5743         return target;
5744       break;
5745
5746     case BUILT_IN_SIGNBIT:
5747     case BUILT_IN_SIGNBITF:
5748     case BUILT_IN_SIGNBITL:
5749       target = expand_builtin_signbit (exp, target);
5750       if (target)
5751         return target;
5752       break;
5753
5754       /* Various hooks for the DWARF 2 __throw routine.  */
5755     case BUILT_IN_UNWIND_INIT:
5756       expand_builtin_unwind_init ();
5757       return const0_rtx;
5758     case BUILT_IN_DWARF_CFA:
5759       return virtual_cfa_rtx;
5760 #ifdef DWARF2_UNWIND_INFO
5761     case BUILT_IN_DWARF_SP_COLUMN:
5762       return expand_builtin_dwarf_sp_column ();
5763     case BUILT_IN_INIT_DWARF_REG_SIZES:
5764       expand_builtin_init_dwarf_reg_sizes (TREE_VALUE (arglist));
5765       return const0_rtx;
5766 #endif
5767     case BUILT_IN_FROB_RETURN_ADDR:
5768       return expand_builtin_frob_return_addr (TREE_VALUE (arglist));
5769     case BUILT_IN_EXTRACT_RETURN_ADDR:
5770       return expand_builtin_extract_return_addr (TREE_VALUE (arglist));
5771     case BUILT_IN_EH_RETURN:
5772       expand_builtin_eh_return (TREE_VALUE (arglist),
5773                                 TREE_VALUE (TREE_CHAIN (arglist)));
5774       return const0_rtx;
5775 #ifdef EH_RETURN_DATA_REGNO
5776     case BUILT_IN_EH_RETURN_DATA_REGNO:
5777       return expand_builtin_eh_return_data_regno (arglist);
5778 #endif
5779     case BUILT_IN_EXTEND_POINTER:
5780       return expand_builtin_extend_pointer (TREE_VALUE (arglist));
5781
5782     case BUILT_IN_VA_START:
5783     case BUILT_IN_STDARG_START:
5784       return expand_builtin_va_start (arglist);
5785     case BUILT_IN_VA_END:
5786       return expand_builtin_va_end (arglist);
5787     case BUILT_IN_VA_COPY:
5788       return expand_builtin_va_copy (arglist);
5789     case BUILT_IN_EXPECT:
5790       return expand_builtin_expect (arglist, target);
5791     case BUILT_IN_PREFETCH:
5792       expand_builtin_prefetch (arglist);
5793       return const0_rtx;
5794
5795     case BUILT_IN_FORK:
5796     case BUILT_IN_EXECL:
5797     case BUILT_IN_EXECV:
5798     case BUILT_IN_EXECLP:
5799     case BUILT_IN_EXECLE:
5800     case BUILT_IN_EXECVP:
5801     case BUILT_IN_EXECVE:
5802       target = expand_builtin_fork_or_exec (fndecl, arglist, target, ignore);
5803       if (target)
5804         return target;
5805       break;
5806
5807     default:    /* just do library call, if unknown builtin */
5808       if (!DECL_ASSEMBLER_NAME_SET_P (fndecl))
5809         error ("built-in function `%s' not currently supported",
5810                IDENTIFIER_POINTER (DECL_NAME (fndecl)));
5811     }
5812
5813   /* The switch statement above can drop through to cause the function
5814      to be called normally.  */
5815   return expand_call (exp, target, ignore);
5816 }
5817
5818 /* Determine whether a tree node represents a call to a built-in
5819    function.  If the tree T is a call to a built-in function with
5820    the right number of arguments of the appropriate types, return
5821    the DECL_FUNCTION_CODE of the call, e.g. BUILT_IN_SQRT.
5822    Otherwise the return value is END_BUILTINS.  */
5823
5824 enum built_in_function
5825 builtin_mathfn_code (tree t)
5826 {
5827   tree fndecl, arglist, parmlist;
5828   tree argtype, parmtype;
5829
5830   if (TREE_CODE (t) != CALL_EXPR
5831       || TREE_CODE (TREE_OPERAND (t, 0)) != ADDR_EXPR)
5832     return END_BUILTINS;
5833
5834   fndecl = get_callee_fndecl (t);
5835   if (fndecl == NULL_TREE
5836       || TREE_CODE (fndecl) != FUNCTION_DECL
5837       || ! DECL_BUILT_IN (fndecl)
5838       || DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
5839     return END_BUILTINS;
5840
5841   arglist = TREE_OPERAND (t, 1);
5842   parmlist = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
5843   for (; parmlist; parmlist = TREE_CHAIN (parmlist))
5844     {
5845       /* If a function doesn't take a variable number of arguments,
5846          the last element in the list will have type `void'.  */
5847       parmtype = TREE_VALUE (parmlist);
5848       if (VOID_TYPE_P (parmtype))
5849         {
5850           if (arglist)
5851             return END_BUILTINS;
5852           return DECL_FUNCTION_CODE (fndecl);
5853         }
5854
5855       if (! arglist)
5856         return END_BUILTINS;
5857
5858       argtype = TREE_TYPE (TREE_VALUE (arglist));
5859
5860       if (SCALAR_FLOAT_TYPE_P (parmtype))
5861         {
5862           if (! SCALAR_FLOAT_TYPE_P (argtype))
5863             return END_BUILTINS;
5864         }
5865       else if (COMPLEX_FLOAT_TYPE_P (parmtype))
5866         {
5867           if (! COMPLEX_FLOAT_TYPE_P (argtype))
5868             return END_BUILTINS;
5869         }
5870       else if (POINTER_TYPE_P (parmtype))
5871         {
5872           if (! POINTER_TYPE_P (argtype))
5873             return END_BUILTINS;
5874         }
5875       else if (INTEGRAL_TYPE_P (parmtype))
5876         {
5877           if (! INTEGRAL_TYPE_P (argtype))
5878             return END_BUILTINS;
5879         }
5880       else
5881         return END_BUILTINS;
5882
5883       arglist = TREE_CHAIN (arglist);
5884     }
5885
5886   /* Variable-length argument list.  */
5887   return DECL_FUNCTION_CODE (fndecl);
5888 }
5889
5890 /* Fold a call to __builtin_constant_p, if we know it will evaluate to a
5891    constant.  ARGLIST is the argument list of the call.  */
5892
5893 static tree
5894 fold_builtin_constant_p (tree arglist)
5895 {
5896   if (arglist == 0)
5897     return 0;
5898
5899   arglist = TREE_VALUE (arglist);
5900
5901   /* We return 1 for a numeric type that's known to be a constant
5902      value at compile-time or for an aggregate type that's a
5903      literal constant.  */
5904   STRIP_NOPS (arglist);
5905
5906   /* If we know this is a constant, emit the constant of one.  */
5907   if (TREE_CODE_CLASS (TREE_CODE (arglist)) == 'c'
5908       || (TREE_CODE (arglist) == CONSTRUCTOR
5909           && TREE_CONSTANT (arglist))
5910       || (TREE_CODE (arglist) == ADDR_EXPR
5911           && TREE_CODE (TREE_OPERAND (arglist, 0)) == STRING_CST))
5912     return integer_one_node;
5913
5914   /* If this expression has side effects, show we don't know it to be a
5915      constant.  Likewise if it's a pointer or aggregate type since in
5916      those case we only want literals, since those are only optimized
5917      when generating RTL, not later.
5918      And finally, if we are compiling an initializer, not code, we
5919      need to return a definite result now; there's not going to be any
5920      more optimization done.  */
5921   if (TREE_SIDE_EFFECTS (arglist)
5922       || AGGREGATE_TYPE_P (TREE_TYPE (arglist))
5923       || POINTER_TYPE_P (TREE_TYPE (arglist))
5924       || cfun == 0)
5925     return integer_zero_node;
5926
5927   return 0;
5928 }
5929
5930 /* Fold a call to __builtin_classify_type.  */
5931
5932 static tree
5933 fold_builtin_classify_type (tree arglist)
5934 {
5935   if (arglist == 0)
5936     return build_int_2 (no_type_class, 0);
5937
5938   return build_int_2 (type_to_class (TREE_TYPE (TREE_VALUE (arglist))), 0);
5939 }
5940
5941 /* Fold a call to __builtin_inf or __builtin_huge_val.  */
5942
5943 static tree
5944 fold_builtin_inf (tree type, int warn)
5945 {
5946   REAL_VALUE_TYPE real;
5947
5948   if (!MODE_HAS_INFINITIES (TYPE_MODE (type)) && warn)
5949     warning ("target format does not support infinity");
5950
5951   real_inf (&real);
5952   return build_real (type, real);
5953 }
5954
5955 /* Fold a call to __builtin_nan or __builtin_nans.  */
5956
5957 static tree
5958 fold_builtin_nan (tree arglist, tree type, int quiet)
5959 {
5960   REAL_VALUE_TYPE real;
5961   const char *str;
5962
5963   if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5964     return 0;
5965   str = c_getstr (TREE_VALUE (arglist));
5966   if (!str)
5967     return 0;
5968
5969   if (!real_nan (&real, str, quiet, TYPE_MODE (type)))
5970     return 0;
5971
5972   return build_real (type, real);
5973 }
5974
5975 /* Return true if the floating point expression T has an integer value.
5976    We also allow +Inf, -Inf and NaN to be considered integer values.  */
5977
5978 static bool
5979 integer_valued_real_p (tree t)
5980 {
5981   switch (TREE_CODE (t))
5982     {
5983     case FLOAT_EXPR:
5984       return true;
5985
5986     case ABS_EXPR:
5987     case SAVE_EXPR:
5988     case NON_LVALUE_EXPR:
5989       return integer_valued_real_p (TREE_OPERAND (t, 0));
5990
5991     case COMPOUND_EXPR:
5992     case MODIFY_EXPR:
5993     case BIND_EXPR:
5994       return integer_valued_real_p (TREE_OPERAND (t, 1));
5995
5996     case PLUS_EXPR:
5997     case MINUS_EXPR:
5998     case MULT_EXPR:
5999     case MIN_EXPR:
6000     case MAX_EXPR:
6001       return integer_valued_real_p (TREE_OPERAND (t, 0))
6002              && integer_valued_real_p (TREE_OPERAND (t, 1));
6003
6004     case COND_EXPR:
6005       return integer_valued_real_p (TREE_OPERAND (t, 1))
6006              && integer_valued_real_p (TREE_OPERAND (t, 2));
6007
6008     case REAL_CST:
6009       if (! TREE_CONSTANT_OVERFLOW (t))
6010       {
6011         REAL_VALUE_TYPE c, cint;
6012
6013         c = TREE_REAL_CST (t);
6014         real_trunc (&cint, TYPE_MODE (TREE_TYPE (t)), &c);
6015         return real_identical (&c, &cint);
6016       }
6017
6018     case NOP_EXPR:
6019       {
6020         tree type = TREE_TYPE (TREE_OPERAND (t, 0));
6021         if (TREE_CODE (type) == INTEGER_TYPE)
6022           return true;
6023         if (TREE_CODE (type) == REAL_TYPE)
6024           return integer_valued_real_p (TREE_OPERAND (t, 0));
6025         break;
6026       }
6027
6028     case CALL_EXPR:
6029       switch (builtin_mathfn_code (t))
6030         {
6031         case BUILT_IN_CEIL:
6032         case BUILT_IN_CEILF:
6033         case BUILT_IN_CEILL:
6034         case BUILT_IN_FLOOR:
6035         case BUILT_IN_FLOORF:
6036         case BUILT_IN_FLOORL:
6037         case BUILT_IN_NEARBYINT:
6038         case BUILT_IN_NEARBYINTF:
6039         case BUILT_IN_NEARBYINTL:
6040         case BUILT_IN_RINT:
6041         case BUILT_IN_RINTF:
6042         case BUILT_IN_RINTL:
6043         case BUILT_IN_ROUND:
6044         case BUILT_IN_ROUNDF:
6045         case BUILT_IN_ROUNDL:
6046         case BUILT_IN_TRUNC:
6047         case BUILT_IN_TRUNCF:
6048         case BUILT_IN_TRUNCL:
6049           return true;
6050
6051         default:
6052           break;
6053         }
6054       break;
6055
6056     default:
6057       break;
6058     }
6059   return false;
6060 }
6061
6062 /* EXP is assumed to be builtin call where truncation can be propagated
6063    across (for instance floor((double)f) == (double)floorf (f).
6064    Do the transformation.  */
6065
6066 static tree
6067 fold_trunc_transparent_mathfn (tree exp)
6068 {
6069   tree fndecl = get_callee_fndecl (exp);
6070   tree arglist = TREE_OPERAND (exp, 1);
6071   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
6072   tree arg;
6073
6074   if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6075     return 0;
6076
6077   arg = TREE_VALUE (arglist);
6078   /* Integer rounding functions are idempotent.  */
6079   if (fcode == builtin_mathfn_code (arg))
6080     return arg;
6081
6082   /* If argument is already integer valued, and we don't need to worry
6083      about setting errno, there's no need to perform rounding.  */
6084   if (! flag_errno_math && integer_valued_real_p (arg))
6085     return arg;
6086
6087   if (optimize)
6088     {
6089       tree arg0 = strip_float_extensions (arg);
6090       tree ftype = TREE_TYPE (exp);
6091       tree newtype = TREE_TYPE (arg0);
6092       tree decl;
6093
6094       if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
6095           && (decl = mathfn_built_in (newtype, fcode)))
6096         {
6097           arglist =
6098             build_tree_list (NULL_TREE, fold_convert (newtype, arg0));
6099           return fold_convert (ftype,
6100                                build_function_call_expr (decl, arglist));
6101         }
6102     }
6103   return 0;
6104 }
6105
6106 /* EXP is assumed to be builtin call which can narrow the FP type of
6107    the argument, for instance lround((double)f) -> lroundf (f).  */
6108
6109 static tree
6110 fold_fixed_mathfn (tree exp)
6111 {
6112   tree fndecl = get_callee_fndecl (exp);
6113   tree arglist = TREE_OPERAND (exp, 1);
6114   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
6115   tree arg;
6116
6117   if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6118     return 0;
6119
6120   arg = TREE_VALUE (arglist);
6121
6122   /* If argument is already integer valued, and we don't need to worry
6123      about setting errno, there's no need to perform rounding.  */
6124   if (! flag_errno_math && integer_valued_real_p (arg))
6125     return fold (build1 (FIX_TRUNC_EXPR, TREE_TYPE (exp), arg));
6126
6127   if (optimize)
6128     {
6129       tree ftype = TREE_TYPE (arg);
6130       tree arg0 = strip_float_extensions (arg);
6131       tree newtype = TREE_TYPE (arg0);
6132       tree decl;
6133
6134       if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
6135           && (decl = mathfn_built_in (newtype, fcode)))
6136         {
6137           arglist =
6138             build_tree_list (NULL_TREE, fold_convert (newtype, arg0));
6139           return build_function_call_expr (decl, arglist);
6140         }
6141     }
6142   return 0;
6143 }
6144
6145 /* Fold function call to builtin cabs, cabsf or cabsl.  ARGLIST
6146    is the argument list and TYPE is the return type.  Return
6147    NULL_TREE if no if no simplification can be made.  */
6148
6149 static tree
6150 fold_builtin_cabs (tree arglist, tree type)
6151 {
6152   tree arg;
6153
6154   if (!arglist || TREE_CHAIN (arglist))
6155     return NULL_TREE;
6156
6157   arg = TREE_VALUE (arglist);
6158   if (TREE_CODE (TREE_TYPE (arg)) != COMPLEX_TYPE
6159       || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) != REAL_TYPE)
6160     return NULL_TREE;
6161
6162   /* Evaluate cabs of a constant at compile-time.  */
6163   if (flag_unsafe_math_optimizations
6164       && TREE_CODE (arg) == COMPLEX_CST
6165       && TREE_CODE (TREE_REALPART (arg)) == REAL_CST
6166       && TREE_CODE (TREE_IMAGPART (arg)) == REAL_CST
6167       && ! TREE_CONSTANT_OVERFLOW (TREE_REALPART (arg))
6168       && ! TREE_CONSTANT_OVERFLOW (TREE_IMAGPART (arg)))
6169     {
6170       REAL_VALUE_TYPE r, i;
6171
6172       r = TREE_REAL_CST (TREE_REALPART (arg));
6173       i = TREE_REAL_CST (TREE_IMAGPART (arg));
6174
6175       real_arithmetic (&r, MULT_EXPR, &r, &r);
6176       real_arithmetic (&i, MULT_EXPR, &i, &i);
6177       real_arithmetic (&r, PLUS_EXPR, &r, &i);
6178       if (real_sqrt (&r, TYPE_MODE (type), &r)
6179           || ! flag_trapping_math)
6180         return build_real (type, r);
6181     }
6182
6183   /* If either part is zero, cabs is fabs of the other.  */
6184   if (TREE_CODE (arg) == COMPLEX_EXPR
6185       && real_zerop (TREE_OPERAND (arg, 0)))
6186     return fold (build1 (ABS_EXPR, type, TREE_OPERAND (arg, 1)));
6187   if (TREE_CODE (arg) == COMPLEX_EXPR
6188       && real_zerop (TREE_OPERAND (arg, 1)))
6189     return fold (build1 (ABS_EXPR, type, TREE_OPERAND (arg, 0)));
6190
6191   if (flag_unsafe_math_optimizations)
6192     {
6193       tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
6194
6195       if (sqrtfn != NULL_TREE)
6196         {
6197           tree rpart, ipart, result, arglist;
6198
6199           arg = save_expr (arg);
6200
6201           rpart = fold (build1 (REALPART_EXPR, type, arg));
6202           ipart = fold (build1 (IMAGPART_EXPR, type, arg));
6203
6204           rpart = save_expr (rpart);
6205           ipart = save_expr (ipart);
6206
6207           result = fold (build (PLUS_EXPR, type,
6208                                 fold (build (MULT_EXPR, type,
6209                                              rpart, rpart)),
6210                                 fold (build (MULT_EXPR, type,
6211                                              ipart, ipart))));
6212
6213           arglist = build_tree_list (NULL_TREE, result);
6214           return build_function_call_expr (sqrtfn, arglist);
6215         }
6216     }
6217
6218   return NULL_TREE;
6219 }
6220
6221 /* Fold function call to builtin trunc, truncf or truncl.  Return
6222    NULL_TREE if no simplification can be made.  */
6223
6224 static tree
6225 fold_builtin_trunc (tree exp)
6226 {
6227   tree arglist = TREE_OPERAND (exp, 1);
6228   tree arg;
6229
6230   if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6231     return 0;
6232
6233   /* Optimize trunc of constant value.  */
6234   arg = TREE_VALUE (arglist);
6235   if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
6236     {
6237       REAL_VALUE_TYPE r, x;
6238       tree type = TREE_TYPE (exp);
6239
6240       x = TREE_REAL_CST (arg);
6241       real_trunc (&r, TYPE_MODE (type), &x);
6242       return build_real (type, r);
6243     }
6244
6245   return fold_trunc_transparent_mathfn (exp);
6246 }
6247
6248 /* Fold function call to builtin floor, floorf or floorl.  Return
6249    NULL_TREE if no simplification can be made.  */
6250
6251 static tree
6252 fold_builtin_floor (tree exp)
6253 {
6254   tree arglist = TREE_OPERAND (exp, 1);
6255   tree arg;
6256
6257   if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6258     return 0;
6259
6260   /* Optimize floor of constant value.  */
6261   arg = TREE_VALUE (arglist);
6262   if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
6263     {
6264       REAL_VALUE_TYPE x;
6265
6266       x = TREE_REAL_CST (arg);
6267       if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
6268         {
6269           tree type = TREE_TYPE (exp);
6270           REAL_VALUE_TYPE r;
6271
6272           real_floor (&r, TYPE_MODE (type), &x);
6273           return build_real (type, r);
6274         }
6275     }
6276
6277   return fold_trunc_transparent_mathfn (exp);
6278 }
6279
6280 /* Fold function call to builtin ceil, ceilf or ceill.  Return
6281    NULL_TREE if no simplification can be made.  */
6282
6283 static tree
6284 fold_builtin_ceil (tree exp)
6285 {
6286   tree arglist = TREE_OPERAND (exp, 1);
6287   tree arg;
6288
6289   if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6290     return 0;
6291
6292   /* Optimize ceil of constant value.  */
6293   arg = TREE_VALUE (arglist);
6294   if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
6295     {
6296       REAL_VALUE_TYPE x;
6297
6298       x = TREE_REAL_CST (arg);
6299       if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
6300         {
6301           tree type = TREE_TYPE (exp);
6302           REAL_VALUE_TYPE r;
6303
6304           real_ceil (&r, TYPE_MODE (type), &x);
6305           return build_real (type, r);
6306         }
6307     }
6308
6309   return fold_trunc_transparent_mathfn (exp);
6310 }
6311
6312 /* Fold function call to builtin round, roundf or roundl.  Return
6313    NULL_TREE if no simplification can be made.  */
6314
6315 static tree
6316 fold_builtin_round (tree exp)
6317 {
6318   tree arglist = TREE_OPERAND (exp, 1);
6319   tree arg;
6320
6321   if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6322     return 0;
6323
6324   /* Optimize round of constant value.  */
6325   arg = TREE_VALUE (arglist);
6326   if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
6327     {
6328       REAL_VALUE_TYPE x;
6329
6330       x = TREE_REAL_CST (arg);
6331       if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
6332         {
6333           tree type = TREE_TYPE (exp);
6334           REAL_VALUE_TYPE r;
6335
6336           real_round (&r, TYPE_MODE (type), &x);
6337           return build_real (type, r);
6338         }
6339     }
6340
6341   return fold_trunc_transparent_mathfn (exp);
6342 }
6343
6344 /* Fold function call to builtin lround, lroundf or lroundl (or the
6345    corresponding long long versions).  Return NULL_TREE if no
6346    simplification can be made.  */
6347
6348 static tree
6349 fold_builtin_lround (tree exp)
6350 {
6351   tree arglist = TREE_OPERAND (exp, 1);
6352   tree arg;
6353
6354   if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6355     return 0;
6356
6357   /* Optimize lround of constant value.  */
6358   arg = TREE_VALUE (arglist);
6359   if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
6360     {
6361       const REAL_VALUE_TYPE x = TREE_REAL_CST (arg);
6362
6363       if (! REAL_VALUE_ISNAN (x) && ! REAL_VALUE_ISINF (x))
6364         {
6365           tree itype = TREE_TYPE (exp), ftype = TREE_TYPE (arg), result;
6366           HOST_WIDE_INT hi, lo;
6367           REAL_VALUE_TYPE r;
6368
6369           real_round (&r, TYPE_MODE (ftype), &x);
6370           REAL_VALUE_TO_INT (&lo, &hi, r);
6371           result = build_int_2 (lo, hi);
6372           if (int_fits_type_p (result, itype))
6373             return fold_convert (itype, result);
6374         }
6375     }
6376
6377   return fold_fixed_mathfn (exp);
6378 }
6379
6380 /* Fold function call to builtin ffs, clz, ctz, popcount and parity
6381    and their long and long long variants (i.e. ffsl and ffsll).
6382    Return NULL_TREE if no simplification can be made.  */
6383
6384 static tree
6385 fold_builtin_bitop (tree exp)
6386 {
6387   tree fndecl = get_callee_fndecl (exp);
6388   tree arglist = TREE_OPERAND (exp, 1);
6389   tree arg;
6390
6391   if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
6392     return NULL_TREE;
6393
6394   /* Optimize for constant argument.  */
6395   arg = TREE_VALUE (arglist);
6396   if (TREE_CODE (arg) == INTEGER_CST && ! TREE_CONSTANT_OVERFLOW (arg))
6397     {
6398       HOST_WIDE_INT hi, width, result;
6399       unsigned HOST_WIDE_INT lo;
6400       tree type, t;
6401
6402       type = TREE_TYPE (arg);
6403       width = TYPE_PRECISION (type);
6404       lo = TREE_INT_CST_LOW (arg);
6405
6406       /* Clear all the bits that are beyond the type's precision.  */
6407       if (width > HOST_BITS_PER_WIDE_INT)
6408         {
6409           hi = TREE_INT_CST_HIGH (arg);
6410           if (width < 2 * HOST_BITS_PER_WIDE_INT)
6411             hi &= ~((HOST_WIDE_INT) (-1) >> (width - HOST_BITS_PER_WIDE_INT));
6412         }
6413       else
6414         {
6415           hi = 0;
6416           if (width < HOST_BITS_PER_WIDE_INT)
6417             lo &= ~((unsigned HOST_WIDE_INT) (-1) << width);
6418         }
6419
6420       switch (DECL_FUNCTION_CODE (fndecl))
6421         {
6422         case BUILT_IN_FFS:
6423         case BUILT_IN_FFSL:
6424         case BUILT_IN_FFSLL:
6425           if (lo != 0)
6426             result = exact_log2 (lo & -lo) + 1;
6427           else if (hi != 0)
6428             result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi) + 1;
6429           else
6430             result = 0;
6431           break;
6432
6433         case BUILT_IN_CLZ:
6434         case BUILT_IN_CLZL:
6435         case BUILT_IN_CLZLL:
6436           if (hi != 0)
6437             result = width - floor_log2 (hi) - 1 - HOST_BITS_PER_WIDE_INT;
6438           else if (lo != 0)
6439             result = width - floor_log2 (lo) - 1;
6440           else if (! CLZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
6441             result = width;
6442           break;
6443
6444         case BUILT_IN_CTZ:
6445         case BUILT_IN_CTZL:
6446         case BUILT_IN_CTZLL:
6447           if (lo != 0)
6448             result = exact_log2 (lo & -lo);
6449           else if (hi != 0)
6450             result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi);
6451           else if (! CTZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
6452             result = width;
6453           break;
6454
6455         case BUILT_IN_POPCOUNT:
6456         case BUILT_IN_POPCOUNTL:
6457         case BUILT_IN_POPCOUNTLL:
6458           result = 0;
6459           while (lo)
6460             result++, lo &= lo - 1;
6461           while (hi)
6462             result++, hi &= hi - 1;
6463           break;
6464
6465         case BUILT_IN_PARITY:
6466         case BUILT_IN_PARITYL:
6467         case BUILT_IN_PARITYLL:
6468           result = 0;
6469           while (lo)
6470             result++, lo &= lo - 1;
6471           while (hi)
6472             result++, hi &= hi - 1;
6473           result &= 1;
6474           break;
6475
6476         default:
6477           abort();
6478         }
6479
6480       t = build_int_2 (result, 0);
6481       TREE_TYPE (t) = TREE_TYPE (exp);
6482       return t;
6483     }
6484
6485   return NULL_TREE;
6486 }
6487
6488 /* Return true if EXPR is the real constant contained in VALUE.  */
6489
6490 static bool
6491 real_dconstp (tree expr, const REAL_VALUE_TYPE *value)
6492 {
6493   STRIP_NOPS (expr);
6494
6495   return ((TREE_CODE (expr) == REAL_CST
6496            && ! TREE_CONSTANT_OVERFLOW (expr)
6497            && REAL_VALUES_EQUAL (TREE_REAL_CST (expr), *value))
6498           || (TREE_CODE (expr) == COMPLEX_CST
6499               && real_dconstp (TREE_REALPART (expr), value)
6500               && real_zerop (TREE_IMAGPART (expr))));
6501 }
6502
6503 /* A subroutine of fold_builtin to fold the various logarithmic
6504    functions.  EXP is the CALL_EXPR of a call to a builtin logN
6505    function.  VALUE is the base of the logN function.  */
6506
6507 static tree
6508 fold_builtin_logarithm (tree exp, const REAL_VALUE_TYPE *value)
6509 {
6510   tree arglist = TREE_OPERAND (exp, 1);
6511
6512   if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6513     {
6514       tree fndecl = get_callee_fndecl (exp);
6515       tree type = TREE_TYPE (TREE_TYPE (fndecl));
6516       tree arg = TREE_VALUE (arglist);
6517       const enum built_in_function fcode = builtin_mathfn_code (arg);
6518
6519       /* Optimize logN(1.0) = 0.0.  */
6520       if (real_onep (arg))
6521         return build_real (type, dconst0);
6522
6523       /* Optimize logN(N) = 1.0.  If N can't be truncated to MODE
6524          exactly, then only do this if flag_unsafe_math_optimizations.  */
6525       if (exact_real_truncate (TYPE_MODE (type), value)
6526           || flag_unsafe_math_optimizations)
6527         {
6528           const REAL_VALUE_TYPE value_truncate =
6529             real_value_truncate (TYPE_MODE (type), *value);
6530           if (real_dconstp (arg, &value_truncate))
6531             return build_real (type, dconst1);
6532         }
6533
6534       /* Special case, optimize logN(expN(x)) = x.  */
6535       if (flag_unsafe_math_optimizations
6536           && ((value == &dconste
6537                && (fcode == BUILT_IN_EXP
6538                    || fcode == BUILT_IN_EXPF
6539                    || fcode == BUILT_IN_EXPL))
6540               || (value == &dconst2
6541                   && (fcode == BUILT_IN_EXP2
6542                       || fcode == BUILT_IN_EXP2F
6543                       || fcode == BUILT_IN_EXP2L))
6544               || (value == &dconst10 && (BUILTIN_EXP10_P (fcode)))))
6545         return fold_convert (type, TREE_VALUE (TREE_OPERAND (arg, 1)));
6546
6547       /* Optimize logN(func()) for various exponential functions.  We
6548          want to determine the value "x" and the power "exponent" in
6549          order to transform logN(x**exponent) into exponent*logN(x).  */
6550       if (flag_unsafe_math_optimizations)
6551         {
6552           tree exponent = 0, x = 0;
6553
6554           switch (fcode)
6555           {
6556           case BUILT_IN_EXP:
6557           case BUILT_IN_EXPF:
6558           case BUILT_IN_EXPL:
6559             /* Prepare to do logN(exp(exponent) -> exponent*logN(e).  */
6560             x = build_real (type,
6561                             real_value_truncate (TYPE_MODE (type), dconste));
6562             exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
6563             break;
6564           case BUILT_IN_EXP2:
6565           case BUILT_IN_EXP2F:
6566           case BUILT_IN_EXP2L:
6567             /* Prepare to do logN(exp2(exponent) -> exponent*logN(2).  */
6568             x = build_real (type, dconst2);
6569             exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
6570             break;
6571           case BUILT_IN_EXP10:
6572           case BUILT_IN_EXP10F:
6573           case BUILT_IN_EXP10L:
6574           case BUILT_IN_POW10:
6575           case BUILT_IN_POW10F:
6576           case BUILT_IN_POW10L:
6577             /* Prepare to do logN(exp10(exponent) -> exponent*logN(10).  */
6578             x = build_real (type, dconst10);
6579             exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
6580             break;
6581           case BUILT_IN_SQRT:
6582           case BUILT_IN_SQRTF:
6583           case BUILT_IN_SQRTL:
6584             /* Prepare to do logN(sqrt(x) -> 0.5*logN(x).  */
6585             x = TREE_VALUE (TREE_OPERAND (arg, 1));
6586             exponent = build_real (type, dconsthalf);
6587             break;
6588           case BUILT_IN_CBRT:
6589           case BUILT_IN_CBRTF:
6590           case BUILT_IN_CBRTL:
6591             /* Prepare to do logN(cbrt(x) -> (1/3)*logN(x).  */
6592             x = TREE_VALUE (TREE_OPERAND (arg, 1));
6593             exponent = build_real (type, real_value_truncate (TYPE_MODE (type),
6594                                                               dconstthird));
6595             break;
6596           case BUILT_IN_POW:
6597           case BUILT_IN_POWF:
6598           case BUILT_IN_POWL:
6599             /* Prepare to do logN(pow(x,exponent) -> exponent*logN(x).  */
6600             x = TREE_VALUE (TREE_OPERAND (arg, 1));
6601             exponent = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
6602             break;
6603           default:
6604             break;
6605           }
6606
6607           /* Now perform the optimization.  */
6608           if (x && exponent)
6609             {
6610               tree logfn;
6611               arglist = build_tree_list (NULL_TREE, x);
6612               logfn = build_function_call_expr (fndecl, arglist);
6613               return fold (build (MULT_EXPR, type, exponent, logfn));
6614             }
6615         }
6616     }
6617
6618   return 0;
6619 }
6620
6621 /* A subroutine of fold_builtin to fold the various exponent
6622    functions.  EXP is the CALL_EXPR of a call to a builtin function.
6623    VALUE is the value which will be raised to a power.  */
6624
6625 static tree
6626 fold_builtin_exponent (tree exp, const REAL_VALUE_TYPE *value)
6627 {
6628   tree arglist = TREE_OPERAND (exp, 1);
6629
6630   if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6631     {
6632       tree fndecl = get_callee_fndecl (exp);
6633       tree type = TREE_TYPE (TREE_TYPE (fndecl));
6634       tree arg = TREE_VALUE (arglist);
6635
6636       /* Optimize exp*(0.0) = 1.0.  */
6637       if (real_zerop (arg))
6638         return build_real (type, dconst1);
6639
6640       /* Optimize expN(1.0) = N.  */
6641       if (real_onep (arg))
6642         {
6643           REAL_VALUE_TYPE cst;
6644
6645           real_convert (&cst, TYPE_MODE (type), value);
6646           return build_real (type, cst);
6647         }
6648
6649       /* Attempt to evaluate expN(integer) at compile-time.  */
6650       if (flag_unsafe_math_optimizations
6651           && TREE_CODE (arg) == REAL_CST
6652           && ! TREE_CONSTANT_OVERFLOW (arg))
6653         {
6654           REAL_VALUE_TYPE cint;
6655           REAL_VALUE_TYPE c;
6656           HOST_WIDE_INT n;
6657
6658           c = TREE_REAL_CST (arg);
6659           n = real_to_integer (&c);
6660           real_from_integer (&cint, VOIDmode, n,
6661                              n < 0 ? -1 : 0, 0);
6662           if (real_identical (&c, &cint))
6663             {
6664               REAL_VALUE_TYPE x;
6665
6666               real_powi (&x, TYPE_MODE (type), value, n);
6667               return build_real (type, x);
6668             }
6669         }
6670
6671       /* Optimize expN(logN(x)) = x.  */
6672       if (flag_unsafe_math_optimizations)
6673         {
6674           const enum built_in_function fcode = builtin_mathfn_code (arg);
6675
6676           if ((value == &dconste
6677                && (fcode == BUILT_IN_LOG
6678                    || fcode == BUILT_IN_LOGF
6679                    || fcode == BUILT_IN_LOGL))
6680               || (value == &dconst2
6681                   && (fcode == BUILT_IN_LOG2
6682                       || fcode == BUILT_IN_LOG2F
6683                       || fcode == BUILT_IN_LOG2L))
6684               || (value == &dconst10
6685                   && (fcode == BUILT_IN_LOG10
6686                       || fcode == BUILT_IN_LOG10F
6687                       || fcode == BUILT_IN_LOG10L)))
6688             return fold_convert (type, TREE_VALUE (TREE_OPERAND (arg, 1)));
6689         }
6690     }
6691
6692   return 0;
6693 }
6694
6695 /* Fold function call to builtin memcpy.  Return
6696    NULL_TREE if no simplification can be made.  */
6697
6698 static tree
6699 fold_builtin_memcpy (tree exp)
6700 {
6701   tree arglist = TREE_OPERAND (exp, 1);
6702   tree dest, src, len;
6703
6704   if (!validate_arglist (arglist,
6705                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
6706     return 0;
6707
6708   dest = TREE_VALUE (arglist);
6709   src = TREE_VALUE (TREE_CHAIN (arglist));
6710   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
6711
6712   /* If the LEN parameter is zero, return DEST.  */
6713   if (integer_zerop (len))
6714     return omit_one_operand (TREE_TYPE (exp), dest, src);
6715
6716   /* If SRC and DEST are the same (and not volatile), return DEST.  */
6717   if (operand_equal_p (src, dest, 0))
6718     return omit_one_operand (TREE_TYPE (exp), dest, len);
6719
6720   return 0;
6721 }
6722
6723 /* Fold function call to builtin mempcpy.  Return
6724    NULL_TREE if no simplification can be made.  */
6725
6726 static tree
6727 fold_builtin_mempcpy (tree exp)
6728 {
6729   tree arglist = TREE_OPERAND (exp, 1);
6730   tree dest, src, len;
6731
6732   if (!validate_arglist (arglist,
6733                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
6734     return 0;
6735
6736   dest = TREE_VALUE (arglist);
6737   src = TREE_VALUE (TREE_CHAIN (arglist));
6738   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
6739
6740   /* If the LEN parameter is zero, return DEST.  */
6741   if (integer_zerop (len))
6742     return omit_one_operand (TREE_TYPE (exp), dest, src);
6743
6744   /* If SRC and DEST are the same (and not volatile), return DEST+LEN.  */
6745   if (operand_equal_p (src, dest, 0))
6746     {
6747       tree temp = fold_convert (TREE_TYPE (dest), len);
6748       temp = fold (build (PLUS_EXPR, TREE_TYPE (dest), dest, temp));
6749       return fold_convert (TREE_TYPE (exp), temp);
6750     }
6751
6752   return 0;
6753 }
6754
6755 /* Fold function call to builtin memmove.  Return
6756    NULL_TREE if no simplification can be made.  */
6757
6758 static tree
6759 fold_builtin_memmove (tree exp)
6760 {
6761   tree arglist = TREE_OPERAND (exp, 1);
6762   tree dest, src, len;
6763
6764   if (!validate_arglist (arglist,
6765                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
6766     return 0;
6767
6768   dest = TREE_VALUE (arglist);
6769   src = TREE_VALUE (TREE_CHAIN (arglist));
6770   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
6771
6772   /* If the LEN parameter is zero, return DEST.  */
6773   if (integer_zerop (len))
6774     return omit_one_operand (TREE_TYPE (exp), dest, src);
6775
6776   /* If SRC and DEST are the same (and not volatile), return DEST.  */
6777   if (operand_equal_p (src, dest, 0))
6778     return omit_one_operand (TREE_TYPE (exp), dest, len);
6779
6780   return 0;
6781 }
6782
6783 /* Fold function call to builtin strcpy.  Return
6784    NULL_TREE if no simplification can be made.  */
6785
6786 static tree
6787 fold_builtin_strcpy (tree exp)
6788 {
6789   tree arglist = TREE_OPERAND (exp, 1);
6790   tree dest, src;
6791
6792   if (!validate_arglist (arglist,
6793                          POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
6794     return 0;
6795
6796   dest = TREE_VALUE (arglist);
6797   src = TREE_VALUE (TREE_CHAIN (arglist));
6798
6799   /* If SRC and DEST are the same (and not volatile), return DEST.  */
6800   if (operand_equal_p (src, dest, 0))
6801     return fold_convert (TREE_TYPE (exp), dest);
6802
6803   return 0;
6804 }
6805
6806 /* Fold function call to builtin strncpy.  Return
6807    NULL_TREE if no simplification can be made.  */
6808
6809 static tree
6810 fold_builtin_strncpy (tree exp)
6811 {
6812   tree arglist = TREE_OPERAND (exp, 1);
6813   tree dest, src, len;
6814
6815   if (!validate_arglist (arglist,
6816                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
6817     return 0;
6818
6819   dest = TREE_VALUE (arglist);
6820   src = TREE_VALUE (TREE_CHAIN (arglist));
6821   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
6822
6823   /* If the LEN parameter is zero, return DEST.  */
6824   if (integer_zerop (len))
6825     return omit_one_operand (TREE_TYPE (exp), dest, src);
6826
6827   return 0;
6828 }
6829
6830 /* Fold function call to builtin memcmp.  Return
6831    NULL_TREE if no simplification can be made.  */
6832
6833 static tree
6834 fold_builtin_memcmp (tree exp)
6835 {
6836   tree arglist = TREE_OPERAND (exp, 1);
6837   tree arg1, arg2, len;
6838
6839   if (!validate_arglist (arglist,
6840                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
6841     return 0;
6842
6843   arg1 = TREE_VALUE (arglist);
6844   arg2 = TREE_VALUE (TREE_CHAIN (arglist));
6845   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
6846
6847   /* If the LEN parameter is zero, return zero.  */
6848   if (integer_zerop (len))
6849     {
6850       tree temp = omit_one_operand (TREE_TYPE (exp), integer_zero_node, arg2);
6851       return omit_one_operand (TREE_TYPE (exp), temp, arg1);
6852     }
6853
6854   /* If ARG1 and ARG2 are the same (and not volatile), return zero.  */
6855   if (operand_equal_p (arg1, arg2, 0))
6856     return omit_one_operand (TREE_TYPE (exp), integer_zero_node, len);
6857
6858   return 0;
6859 }
6860
6861 /* Fold function call to builtin strcmp.  Return
6862    NULL_TREE if no simplification can be made.  */
6863
6864 static tree
6865 fold_builtin_strcmp (tree exp)
6866 {
6867   tree arglist = TREE_OPERAND (exp, 1);
6868   tree arg1, arg2;
6869   const char *p1, *p2;
6870
6871   if (!validate_arglist (arglist,
6872                          POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
6873     return 0;
6874
6875   arg1 = TREE_VALUE (arglist);
6876   arg2 = TREE_VALUE (TREE_CHAIN (arglist));
6877
6878   /* If ARG1 and ARG2 are the same (and not volatile), return zero.  */
6879   if (operand_equal_p (arg1, arg2, 0))
6880     return fold_convert (TREE_TYPE (exp), integer_zero_node);
6881
6882   p1 = c_getstr (arg1);
6883   p2 = c_getstr (arg2);
6884
6885   if (p1 && p2)
6886     {
6887       tree temp;
6888       const int i = strcmp (p1, p2);
6889       if (i < 0)
6890         temp = integer_minus_one_node;
6891       else if (i > 0)
6892         temp = integer_one_node;
6893       else
6894         temp = integer_zero_node;
6895       return fold_convert (TREE_TYPE (exp), temp);
6896     }
6897
6898   return 0;
6899 }
6900
6901 /* Fold function call to builtin strncmp.  Return
6902    NULL_TREE if no simplification can be made.  */
6903
6904 static tree
6905 fold_builtin_strncmp (tree exp)
6906 {
6907   tree arglist = TREE_OPERAND (exp, 1);
6908   tree arg1, arg2, len;
6909   const char *p1, *p2;
6910
6911   if (!validate_arglist (arglist,
6912                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
6913     return 0;
6914
6915   arg1 = TREE_VALUE (arglist);
6916   arg2 = TREE_VALUE (TREE_CHAIN (arglist));
6917   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
6918
6919   /* If the LEN parameter is zero, return zero.  */
6920   if (integer_zerop (len))
6921     {
6922       tree temp = omit_one_operand (TREE_TYPE (exp), integer_zero_node, arg2);
6923       return omit_one_operand (TREE_TYPE (exp), temp, arg1);
6924     }
6925
6926   /* If ARG1 and ARG2 are the same (and not volatile), return zero.  */
6927   if (operand_equal_p (arg1, arg2, 0))
6928     return omit_one_operand (TREE_TYPE (exp), integer_zero_node, len);
6929
6930   p1 = c_getstr (arg1);
6931   p2 = c_getstr (arg2);
6932
6933   if (host_integerp (len, 1) && p1 && p2)
6934     {
6935       tree temp;
6936       const int i = strncmp (p1, p2, tree_low_cst (len, 1));
6937       if (i < 0)
6938         temp = integer_minus_one_node;
6939       else if (i > 0)
6940         temp = integer_one_node;
6941       else
6942         temp = integer_zero_node;
6943       return fold_convert (TREE_TYPE (exp), temp);
6944     }
6945
6946   return 0;
6947 }
6948
6949 /* Fold function call to builtin signbit, signbitf or signbitl.  Return
6950    NULL_TREE if no simplification can be made.  */
6951
6952 static tree
6953 fold_builtin_signbit (tree exp)
6954 {
6955   tree arglist = TREE_OPERAND (exp, 1);
6956   tree arg, temp;
6957
6958   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6959     return NULL_TREE;
6960
6961   arg = TREE_VALUE (arglist);
6962
6963   /* If ARG is a compile-time constant, determine the result.  */
6964   if (TREE_CODE (arg) == REAL_CST
6965       && !TREE_CONSTANT_OVERFLOW (arg))
6966     {
6967       REAL_VALUE_TYPE c;
6968
6969       c = TREE_REAL_CST (arg);
6970       temp = REAL_VALUE_NEGATIVE (c) ? integer_one_node : integer_zero_node;
6971       return fold_convert (TREE_TYPE (exp), temp);
6972     }
6973
6974   /* If ARG is non-negative, the result is always zero.  */
6975   if (tree_expr_nonnegative_p (arg))
6976     return omit_one_operand (TREE_TYPE (exp), integer_zero_node, arg);
6977
6978   /* If ARG's format doesn't have signed zeros, return "arg < 0.0".  */
6979   if (!HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg))))
6980     return fold (build (LT_EXPR, TREE_TYPE (exp), arg,
6981                         build_real (TREE_TYPE (arg), dconst0)));
6982
6983   return NULL_TREE;
6984 }
6985
6986 /* Fold a call to builtin isascii.  */
6987
6988 static tree
6989 fold_builtin_isascii (tree arglist)
6990 {
6991   if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
6992     return 0;
6993   else
6994     {
6995       /* Transform isascii(c) -> ((c & ~0x7f) == 0).  */
6996       tree arg = TREE_VALUE (arglist);
6997       
6998       return fold (build (EQ_EXPR, integer_type_node,
6999                           build (BIT_AND_EXPR, integer_type_node, arg,
7000                                  build_int_2 (~ (unsigned HOST_WIDE_INT) 0x7f,
7001                                               ~ (HOST_WIDE_INT) 0)),
7002                           integer_zero_node));
7003     }
7004 }
7005
7006 /* Fold a call to builtin toascii.  */
7007
7008 static tree
7009 fold_builtin_toascii (tree arglist)
7010 {
7011   if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
7012     return 0;
7013   else
7014     {
7015       /* Transform toascii(c) -> (c & 0x7f).  */
7016       tree arg = TREE_VALUE (arglist);
7017       
7018       return fold (build (BIT_AND_EXPR, integer_type_node, arg,
7019                           build_int_2 (0x7f, 0)));
7020     }
7021 }
7022
7023 /* Fold a call to builtin isdigit.  */
7024
7025 static tree
7026 fold_builtin_isdigit (tree arglist)
7027 {
7028   if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
7029     return 0;
7030   else
7031     {
7032       /* Transform isdigit(c) -> (unsigned)(c) - '0' <= 9.  */
7033       /* According to the C standard, isdigit is unaffected by locale.  */
7034       tree arg = TREE_VALUE (arglist);
7035       arg = fold_convert (unsigned_type_node, arg);
7036       arg = build (MINUS_EXPR, unsigned_type_node, arg,
7037                    fold_convert (unsigned_type_node,
7038                                  build_int_2 (TARGET_DIGIT0, 0)));
7039       arg = build (LE_EXPR, integer_type_node, arg,
7040                    fold_convert (unsigned_type_node, build_int_2 (9, 0)));
7041       return fold (arg);
7042     }
7043 }
7044
7045 /* Used by constant folding to eliminate some builtin calls early.  EXP is
7046    the CALL_EXPR of a call to a builtin function.  */
7047
7048 tree
7049 fold_builtin (tree exp)
7050 {
7051   tree fndecl = get_callee_fndecl (exp);
7052   tree arglist = TREE_OPERAND (exp, 1);
7053   tree type = TREE_TYPE (TREE_TYPE (fndecl));
7054
7055   if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
7056     return 0;
7057
7058   switch (DECL_FUNCTION_CODE (fndecl))
7059     {
7060     case BUILT_IN_CONSTANT_P:
7061       return fold_builtin_constant_p (arglist);
7062
7063     case BUILT_IN_CLASSIFY_TYPE:
7064       return fold_builtin_classify_type (arglist);
7065
7066     case BUILT_IN_STRLEN:
7067       if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
7068         {
7069           tree len = c_strlen (TREE_VALUE (arglist), 0);
7070           if (len)
7071             {
7072               /* Convert from the internal "sizetype" type to "size_t".  */
7073               if (size_type_node)
7074                 len = fold_convert (size_type_node, len);
7075               return len;
7076             }
7077         }
7078       break;
7079
7080     case BUILT_IN_FABS:
7081     case BUILT_IN_FABSF:
7082     case BUILT_IN_FABSL:
7083       if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7084         return fold (build1 (ABS_EXPR, type, TREE_VALUE (arglist)));
7085       break;
7086
7087     case BUILT_IN_CABS:
7088     case BUILT_IN_CABSF:
7089     case BUILT_IN_CABSL:
7090       return fold_builtin_cabs (arglist, type);
7091
7092     case BUILT_IN_SQRT:
7093     case BUILT_IN_SQRTF:
7094     case BUILT_IN_SQRTL:
7095       if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7096         {
7097           enum built_in_function fcode;
7098           tree arg = TREE_VALUE (arglist);
7099
7100           /* Optimize sqrt of constant value.  */
7101           if (TREE_CODE (arg) == REAL_CST
7102               && ! TREE_CONSTANT_OVERFLOW (arg))
7103             {
7104               REAL_VALUE_TYPE r, x;
7105
7106               x = TREE_REAL_CST (arg);
7107               if (real_sqrt (&r, TYPE_MODE (type), &x)
7108                   || (!flag_trapping_math && !flag_errno_math))
7109                 return build_real (type, r);
7110             }
7111
7112           /* Optimize sqrt(expN(x)) = expN(x*0.5).  */
7113           fcode = builtin_mathfn_code (arg);
7114           if (flag_unsafe_math_optimizations && BUILTIN_EXPONENT_P (fcode))
7115             {
7116               tree expfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
7117               arg = fold (build (MULT_EXPR, type,
7118                                  TREE_VALUE (TREE_OPERAND (arg, 1)),
7119                                  build_real (type, dconsthalf)));
7120               arglist = build_tree_list (NULL_TREE, arg);
7121               return build_function_call_expr (expfn, arglist);
7122             }
7123
7124           /* Optimize sqrt(Nroot(x)) -> pow(x,1/(2*N)).  */
7125           if (flag_unsafe_math_optimizations && BUILTIN_ROOT_P (fcode))
7126             {
7127               tree powfn = mathfn_built_in (type, BUILT_IN_POW);
7128               
7129               if (powfn)
7130                 {
7131                   tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
7132                   tree tree_root;
7133                   /* The inner root was either sqrt or cbrt.  */
7134                   REAL_VALUE_TYPE dconstroot =
7135                     BUILTIN_SQRT_P (fcode) ? dconsthalf : dconstthird;
7136                   
7137                   /* Adjust for the outer root.  */
7138                   SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
7139                   dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
7140                   tree_root = build_real (type, dconstroot);
7141                   arglist = tree_cons (NULL_TREE, arg0,
7142                                        build_tree_list (NULL_TREE, tree_root));
7143                   return build_function_call_expr (powfn, arglist);
7144                 }
7145             }
7146
7147           /* Optimize sqrt(pow(x,y)) = pow(x,y*0.5).  */
7148           if (flag_unsafe_math_optimizations
7149               && (fcode == BUILT_IN_POW
7150                   || fcode == BUILT_IN_POWF
7151                   || fcode == BUILT_IN_POWL))
7152             {
7153               tree powfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
7154               tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
7155               tree arg1 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
7156               tree narg1 = fold (build (MULT_EXPR, type, arg1,
7157                                         build_real (type, dconsthalf)));
7158               arglist = tree_cons (NULL_TREE, arg0,
7159                                    build_tree_list (NULL_TREE, narg1));
7160               return build_function_call_expr (powfn, arglist);
7161             }
7162         }
7163       break;
7164
7165     case BUILT_IN_CBRT:
7166     case BUILT_IN_CBRTF:
7167     case BUILT_IN_CBRTL:
7168       if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7169         {
7170           tree arg = TREE_VALUE (arglist);
7171           const enum built_in_function fcode = builtin_mathfn_code (arg);
7172
7173           /* Optimize cbrt of constant value.  */
7174           if (real_zerop (arg) || real_onep (arg) || real_minus_onep (arg))
7175             return arg;
7176
7177           /* Optimize cbrt(expN(x)) -> expN(x/3).  */
7178           if (flag_unsafe_math_optimizations && BUILTIN_EXPONENT_P (fcode))
7179             {
7180               tree expfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
7181               const REAL_VALUE_TYPE third_trunc =
7182                 real_value_truncate (TYPE_MODE (type), dconstthird);
7183               arg = fold (build (MULT_EXPR, type,
7184                                  TREE_VALUE (TREE_OPERAND (arg, 1)),
7185                                  build_real (type, third_trunc)));
7186               arglist = build_tree_list (NULL_TREE, arg);
7187               return build_function_call_expr (expfn, arglist);
7188             }
7189
7190           /* Optimize cbrt(sqrt(x)) -> pow(x,1/6).  */
7191           /* We don't optimize cbrt(cbrt(x)) -> pow(x,1/9) because if
7192              x is negative pow will error but cbrt won't.  */
7193           if (flag_unsafe_math_optimizations && BUILTIN_SQRT_P (fcode))
7194             {
7195               tree powfn = mathfn_built_in (type, BUILT_IN_POW);
7196
7197               if (powfn)
7198                 {
7199                   tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
7200                   tree tree_root;
7201                   REAL_VALUE_TYPE dconstroot = dconstthird;
7202
7203                   SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
7204                   dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
7205                   tree_root = build_real (type, dconstroot);
7206                   arglist = tree_cons (NULL_TREE, arg0,
7207                                        build_tree_list (NULL_TREE, tree_root));
7208                   return build_function_call_expr (powfn, arglist);
7209                 }
7210               
7211             }
7212         }
7213       break;
7214
7215     case BUILT_IN_SIN:
7216     case BUILT_IN_SINF:
7217     case BUILT_IN_SINL:
7218       if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7219         {
7220           tree arg = TREE_VALUE (arglist);
7221
7222           /* Optimize sin(0.0) = 0.0.  */
7223           if (real_zerop (arg))
7224             return arg;
7225         }
7226       break;
7227
7228     case BUILT_IN_COS:
7229     case BUILT_IN_COSF:
7230     case BUILT_IN_COSL:
7231       if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7232         {
7233           tree arg = TREE_VALUE (arglist);
7234
7235           /* Optimize cos(0.0) = 1.0.  */
7236           if (real_zerop (arg))
7237             return build_real (type, dconst1);
7238
7239           /* Optimize cos(-x) into cos(x).  */
7240           if (TREE_CODE (arg) == NEGATE_EXPR)
7241             {
7242               tree arglist = build_tree_list (NULL_TREE,
7243                                               TREE_OPERAND (arg, 0));
7244               return build_function_call_expr (fndecl, arglist);
7245             }
7246         }
7247       break;
7248
7249     case BUILT_IN_EXP:
7250     case BUILT_IN_EXPF:
7251     case BUILT_IN_EXPL:
7252       return fold_builtin_exponent (exp, &dconste);
7253     case BUILT_IN_EXP2:
7254     case BUILT_IN_EXP2F:
7255     case BUILT_IN_EXP2L:
7256       return fold_builtin_exponent (exp, &dconst2);
7257     case BUILT_IN_EXP10:
7258     case BUILT_IN_EXP10F:
7259     case BUILT_IN_EXP10L:
7260     case BUILT_IN_POW10:
7261     case BUILT_IN_POW10F:
7262     case BUILT_IN_POW10L:
7263       return fold_builtin_exponent (exp, &dconst10);
7264     case BUILT_IN_LOG:
7265     case BUILT_IN_LOGF:
7266     case BUILT_IN_LOGL:
7267       return fold_builtin_logarithm (exp, &dconste);
7268       break;
7269     case BUILT_IN_LOG2:
7270     case BUILT_IN_LOG2F:
7271     case BUILT_IN_LOG2L:
7272       return fold_builtin_logarithm (exp, &dconst2);
7273       break;
7274     case BUILT_IN_LOG10:
7275     case BUILT_IN_LOG10F:
7276     case BUILT_IN_LOG10L:
7277       return fold_builtin_logarithm (exp, &dconst10);
7278       break;
7279
7280     case BUILT_IN_TAN:
7281     case BUILT_IN_TANF:
7282     case BUILT_IN_TANL:
7283       if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7284         {
7285           enum built_in_function fcode;
7286           tree arg = TREE_VALUE (arglist);
7287
7288           /* Optimize tan(0.0) = 0.0.  */
7289           if (real_zerop (arg))
7290             return arg;
7291
7292           /* Optimize tan(atan(x)) = x.  */
7293           fcode = builtin_mathfn_code (arg);
7294           if (flag_unsafe_math_optimizations
7295               && (fcode == BUILT_IN_ATAN
7296                   || fcode == BUILT_IN_ATANF
7297                   || fcode == BUILT_IN_ATANL))
7298             return TREE_VALUE (TREE_OPERAND (arg, 1));
7299         }
7300       break;
7301
7302     case BUILT_IN_ATAN:
7303     case BUILT_IN_ATANF:
7304     case BUILT_IN_ATANL:
7305       if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7306         {
7307           tree arg = TREE_VALUE (arglist);
7308
7309           /* Optimize atan(0.0) = 0.0.  */
7310           if (real_zerop (arg))
7311             return arg;
7312
7313           /* Optimize atan(1.0) = pi/4.  */
7314           if (real_onep (arg))
7315             {
7316               REAL_VALUE_TYPE cst;
7317
7318               real_convert (&cst, TYPE_MODE (type), &dconstpi);
7319               SET_REAL_EXP (&cst, REAL_EXP (&cst) - 2);
7320               return build_real (type, cst);
7321             }
7322         }
7323       break;
7324
7325     case BUILT_IN_POW:
7326     case BUILT_IN_POWF:
7327     case BUILT_IN_POWL:
7328       if (validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
7329         {
7330           enum built_in_function fcode;
7331           tree arg0 = TREE_VALUE (arglist);
7332           tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7333
7334           /* Optimize pow(1.0,y) = 1.0.  */
7335           if (real_onep (arg0))
7336             return omit_one_operand (type, build_real (type, dconst1), arg1);
7337
7338           if (TREE_CODE (arg1) == REAL_CST
7339               && ! TREE_CONSTANT_OVERFLOW (arg1))
7340             {
7341               REAL_VALUE_TYPE c;
7342               c = TREE_REAL_CST (arg1);
7343
7344               /* Optimize pow(x,0.0) = 1.0.  */
7345               if (REAL_VALUES_EQUAL (c, dconst0))
7346                 return omit_one_operand (type, build_real (type, dconst1),
7347                                          arg0);
7348
7349               /* Optimize pow(x,1.0) = x.  */
7350               if (REAL_VALUES_EQUAL (c, dconst1))
7351                 return arg0;
7352
7353               /* Optimize pow(x,-1.0) = 1.0/x.  */
7354               if (REAL_VALUES_EQUAL (c, dconstm1))
7355                 return fold (build (RDIV_EXPR, type,
7356                                     build_real (type, dconst1),
7357                                     arg0));
7358
7359               /* Optimize pow(x,0.5) = sqrt(x).  */
7360               if (flag_unsafe_math_optimizations
7361                   && REAL_VALUES_EQUAL (c, dconsthalf))
7362                 {
7363                   tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
7364
7365                   if (sqrtfn != NULL_TREE)
7366                     {
7367                       tree arglist = build_tree_list (NULL_TREE, arg0);
7368                       return build_function_call_expr (sqrtfn, arglist);
7369                     }
7370                 }
7371
7372               /* Attempt to evaluate pow at compile-time.  */
7373               if (TREE_CODE (arg0) == REAL_CST
7374                   && ! TREE_CONSTANT_OVERFLOW (arg0))
7375                 {
7376                   REAL_VALUE_TYPE cint;
7377                   HOST_WIDE_INT n;
7378
7379                   n = real_to_integer (&c);
7380                   real_from_integer (&cint, VOIDmode, n,
7381                                      n < 0 ? -1 : 0, 0);
7382                   if (real_identical (&c, &cint))
7383                     {
7384                       REAL_VALUE_TYPE x;
7385                       bool inexact;
7386
7387                       x = TREE_REAL_CST (arg0);
7388                       inexact = real_powi (&x, TYPE_MODE (type), &x, n);
7389                       if (flag_unsafe_math_optimizations || !inexact)
7390                         return build_real (type, x);
7391                     }
7392                 }
7393             }
7394
7395           /* Optimize pow(expN(x),y) = expN(x*y).  */
7396           fcode = builtin_mathfn_code (arg0);
7397           if (flag_unsafe_math_optimizations && BUILTIN_EXPONENT_P (fcode))
7398             {
7399               tree expfn = TREE_OPERAND (TREE_OPERAND (arg0, 0), 0);
7400               tree arg = TREE_VALUE (TREE_OPERAND (arg0, 1));
7401               arg = fold (build (MULT_EXPR, type, arg, arg1));
7402               arglist = build_tree_list (NULL_TREE, arg);
7403               return build_function_call_expr (expfn, arglist);
7404             }
7405
7406           /* Optimize pow(sqrt(x),y) = pow(x,y*0.5).  */
7407           if (flag_unsafe_math_optimizations && BUILTIN_SQRT_P (fcode))
7408             {
7409               tree narg0 = TREE_VALUE (TREE_OPERAND (arg0, 1));
7410               tree narg1 = fold (build (MULT_EXPR, type, arg1,
7411                                         build_real (type, dconsthalf)));
7412
7413               arglist = tree_cons (NULL_TREE, narg0,
7414                                    build_tree_list (NULL_TREE, narg1));
7415               return build_function_call_expr (fndecl, arglist);
7416             }
7417
7418           /* Optimize pow(pow(x,y),z) = pow(x,y*z).  */
7419           if (flag_unsafe_math_optimizations
7420               && (fcode == BUILT_IN_POW
7421                   || fcode == BUILT_IN_POWF
7422                   || fcode == BUILT_IN_POWL))
7423             {
7424               tree arg00 = TREE_VALUE (TREE_OPERAND (arg0, 1));
7425               tree arg01 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg0, 1)));
7426               tree narg1 = fold (build (MULT_EXPR, type, arg01, arg1));
7427               arglist = tree_cons (NULL_TREE, arg00,
7428                                    build_tree_list (NULL_TREE, narg1));
7429               return build_function_call_expr (fndecl, arglist);
7430             }
7431         }
7432       break;
7433
7434     case BUILT_IN_INF:
7435     case BUILT_IN_INFF:
7436     case BUILT_IN_INFL:
7437       return fold_builtin_inf (type, true);
7438
7439     case BUILT_IN_HUGE_VAL:
7440     case BUILT_IN_HUGE_VALF:
7441     case BUILT_IN_HUGE_VALL:
7442       return fold_builtin_inf (type, false);
7443
7444     case BUILT_IN_NAN:
7445     case BUILT_IN_NANF:
7446     case BUILT_IN_NANL:
7447       return fold_builtin_nan (arglist, type, true);
7448
7449     case BUILT_IN_NANS:
7450     case BUILT_IN_NANSF:
7451     case BUILT_IN_NANSL:
7452       return fold_builtin_nan (arglist, type, false);
7453
7454     case BUILT_IN_FLOOR:
7455     case BUILT_IN_FLOORF:
7456     case BUILT_IN_FLOORL:
7457       return fold_builtin_floor (exp);
7458
7459     case BUILT_IN_CEIL:
7460     case BUILT_IN_CEILF:
7461     case BUILT_IN_CEILL:
7462       return fold_builtin_ceil (exp);
7463
7464     case BUILT_IN_TRUNC:
7465     case BUILT_IN_TRUNCF:
7466     case BUILT_IN_TRUNCL:
7467       return fold_builtin_trunc (exp);
7468
7469     case BUILT_IN_ROUND:
7470     case BUILT_IN_ROUNDF:
7471     case BUILT_IN_ROUNDL:
7472       return fold_builtin_round (exp);
7473
7474     case BUILT_IN_NEARBYINT:
7475     case BUILT_IN_NEARBYINTF:
7476     case BUILT_IN_NEARBYINTL:
7477     case BUILT_IN_RINT:
7478     case BUILT_IN_RINTF:
7479     case BUILT_IN_RINTL:
7480       return fold_trunc_transparent_mathfn (exp);
7481
7482     case BUILT_IN_LROUND:
7483     case BUILT_IN_LROUNDF:
7484     case BUILT_IN_LROUNDL:
7485     case BUILT_IN_LLROUND:
7486     case BUILT_IN_LLROUNDF:
7487     case BUILT_IN_LLROUNDL:
7488       return fold_builtin_lround (exp);
7489
7490     case BUILT_IN_LRINT:
7491     case BUILT_IN_LRINTF:
7492     case BUILT_IN_LRINTL:
7493     case BUILT_IN_LLRINT:
7494     case BUILT_IN_LLRINTF:
7495     case BUILT_IN_LLRINTL:
7496       return fold_fixed_mathfn (exp);
7497
7498     case BUILT_IN_FFS:
7499     case BUILT_IN_FFSL:
7500     case BUILT_IN_FFSLL:
7501     case BUILT_IN_CLZ:
7502     case BUILT_IN_CLZL:
7503     case BUILT_IN_CLZLL:
7504     case BUILT_IN_CTZ:
7505     case BUILT_IN_CTZL:
7506     case BUILT_IN_CTZLL:
7507     case BUILT_IN_POPCOUNT:
7508     case BUILT_IN_POPCOUNTL:
7509     case BUILT_IN_POPCOUNTLL:
7510     case BUILT_IN_PARITY:
7511     case BUILT_IN_PARITYL:
7512     case BUILT_IN_PARITYLL:
7513       return fold_builtin_bitop (exp);
7514
7515     case BUILT_IN_MEMCPY:
7516       return fold_builtin_memcpy (exp);
7517
7518     case BUILT_IN_MEMPCPY:
7519       return fold_builtin_mempcpy (exp);
7520
7521     case BUILT_IN_MEMMOVE:
7522       return fold_builtin_memmove (exp);
7523
7524     case BUILT_IN_STRCPY:
7525       return fold_builtin_strcpy (exp);
7526
7527     case BUILT_IN_STRNCPY:
7528       return fold_builtin_strncpy (exp);
7529
7530     case BUILT_IN_MEMCMP:
7531       return fold_builtin_memcmp (exp);
7532
7533     case BUILT_IN_STRCMP:
7534       return fold_builtin_strcmp (exp);
7535
7536     case BUILT_IN_STRNCMP:
7537       return fold_builtin_strncmp (exp);
7538
7539     case BUILT_IN_SIGNBIT:
7540     case BUILT_IN_SIGNBITF:
7541     case BUILT_IN_SIGNBITL:
7542       return fold_builtin_signbit (exp);
7543
7544     case BUILT_IN_ISASCII:
7545       return fold_builtin_isascii (arglist);
7546
7547     case BUILT_IN_TOASCII:
7548       return fold_builtin_toascii (arglist);
7549
7550     case BUILT_IN_ISDIGIT:
7551       return fold_builtin_isdigit (arglist);
7552
7553     default:
7554       break;
7555     }
7556
7557   return 0;
7558 }
7559
7560 /* Conveniently construct a function call expression.  */
7561
7562 tree
7563 build_function_call_expr (tree fn, tree arglist)
7564 {
7565   tree call_expr;
7566
7567   call_expr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
7568   call_expr = build (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)),
7569                      call_expr, arglist);
7570   return fold (call_expr);
7571 }
7572
7573 /* This function validates the types of a function call argument list
7574    represented as a tree chain of parameters against a specified list
7575    of tree_codes.  If the last specifier is a 0, that represents an
7576    ellipses, otherwise the last specifier must be a VOID_TYPE.  */
7577
7578 static int
7579 validate_arglist (tree arglist, ...)
7580 {
7581   enum tree_code code;
7582   int res = 0;
7583   va_list ap;
7584
7585   va_start (ap, arglist);
7586
7587   do
7588     {
7589       code = va_arg (ap, enum tree_code);
7590       switch (code)
7591         {
7592         case 0:
7593           /* This signifies an ellipses, any further arguments are all ok.  */
7594           res = 1;
7595           goto end;
7596         case VOID_TYPE:
7597           /* This signifies an endlink, if no arguments remain, return
7598              true, otherwise return false.  */
7599           res = arglist == 0;
7600           goto end;
7601         default:
7602           /* If no parameters remain or the parameter's code does not
7603              match the specified code, return false.  Otherwise continue
7604              checking any remaining arguments.  */
7605           if (arglist == 0
7606               || code != TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))))
7607             goto end;
7608           break;
7609         }
7610       arglist = TREE_CHAIN (arglist);
7611     }
7612   while (1);
7613
7614   /* We need gotos here since we can only have one VA_CLOSE in a
7615      function.  */
7616  end: ;
7617   va_end (ap);
7618
7619   return res;
7620 }
7621
7622 /* Default target-specific builtin expander that does nothing.  */
7623
7624 rtx
7625 default_expand_builtin (tree exp ATTRIBUTE_UNUSED,
7626                         rtx target ATTRIBUTE_UNUSED,
7627                         rtx subtarget ATTRIBUTE_UNUSED,
7628                         enum machine_mode mode ATTRIBUTE_UNUSED,
7629                         int ignore ATTRIBUTE_UNUSED)
7630 {
7631   return NULL_RTX;
7632 }
7633
7634 /* Instantiate all remaining CONSTANT_P_RTX nodes.  */
7635
7636 void
7637 purge_builtin_constant_p (void)
7638 {
7639   rtx insn, set, arg, new, note;
7640
7641   for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
7642     if (INSN_P (insn)
7643         && (set = single_set (insn)) != NULL_RTX
7644         && (GET_CODE (arg = SET_SRC (set)) == CONSTANT_P_RTX
7645             || (GET_CODE (arg) == SUBREG
7646                 && (GET_CODE (arg = SUBREG_REG (arg))
7647                     == CONSTANT_P_RTX))))
7648       {
7649         arg = XEXP (arg, 0);
7650         new = CONSTANT_P (arg) ? const1_rtx : const0_rtx;
7651         validate_change (insn, &SET_SRC (set), new, 0);
7652
7653         /* Remove the REG_EQUAL note from the insn.  */
7654         if ((note = find_reg_note (insn, REG_EQUAL, NULL_RTX)) != 0)
7655           remove_note (insn, note);
7656       }
7657 }
7658
7659 /* Returns true is EXP represents data that would potentially reside
7660    in a readonly section.  */
7661
7662 static bool
7663 readonly_data_expr (tree exp)
7664 {
7665   STRIP_NOPS (exp);
7666
7667   if (TREE_CODE (exp) == ADDR_EXPR)
7668     return decl_readonly_section (TREE_OPERAND (exp, 0), 0);
7669   else
7670     return false;
7671 }