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