OSDN Git Service

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