OSDN Git Service

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