OSDN Git Service

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