OSDN Git Service

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