OSDN Git Service

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