OSDN Git Service

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