OSDN Git Service

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