OSDN Git Service

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