OSDN Git Service

* builtins.c (build_function_call_expr): Don't set
[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, before_call;
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   if (! flag_errno_math || ! HONOR_NANS (mode))
1640     errno_set = false;
1641
1642   /* Before working hard, check whether the instruction is available.  */
1643   if (builtin_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1644     {
1645       target = gen_reg_rtx (mode);
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 (target != 0)
1667         {
1668           if (errno_set)
1669             expand_errno_check (exp, target);
1670
1671           /* Output the entire sequence.  */
1672           insns = get_insns ();
1673           end_sequence ();
1674           emit_insn (insns);
1675           return target;
1676         }
1677
1678       /* If we were unable to expand via the builtin, stop the sequence
1679          (without outputting the insns) and call to the library function
1680          with the stabilized argument list.  */
1681       end_sequence ();
1682     }
1683
1684   before_call = get_last_insn ();
1685
1686   target = expand_call (exp, target, target == const0_rtx);
1687
1688   /* If this is a sqrt operation and we don't care about errno, try to
1689      attach a REG_EQUAL note with a SQRT rtx to the emitted libcall.
1690      This allows the semantics of the libcall to be visible to the RTL
1691      optimizers.  */
1692   if (builtin_optab == sqrt_optab && !errno_set)
1693     {
1694       /* Search backwards through the insns emitted by expand_call looking
1695          for the instruction with the REG_RETVAL note.  */
1696       rtx last = get_last_insn ();
1697       while (last != before_call)
1698         {
1699           if (find_reg_note (last, REG_RETVAL, NULL))
1700             {
1701               rtx note = find_reg_note (last, REG_EQUAL, NULL);
1702               /* Check that the REQ_EQUAL note is an EXPR_LIST with
1703                  two elements, i.e. symbol_ref(sqrt) and the operand.  */
1704               if (note
1705                   && GET_CODE (note) == EXPR_LIST
1706                   && GET_CODE (XEXP (note, 0)) == EXPR_LIST
1707                   && XEXP (XEXP (note, 0), 1) != NULL_RTX
1708                   && XEXP (XEXP (XEXP (note, 0), 1), 1) == NULL_RTX)
1709                 {
1710                   rtx operand = XEXP (XEXP (XEXP (note, 0), 1), 0);
1711                   /* Check operand is a register with expected mode.  */
1712                   if (operand
1713                       && GET_CODE (operand) == REG
1714                       && GET_MODE (operand) == mode)
1715                     {
1716                       /* Replace the REG_EQUAL note with a SQRT rtx.  */
1717                       rtx equiv = gen_rtx_SQRT (mode, operand);
1718                       set_unique_reg_note (last, REG_EQUAL, equiv);
1719                     }
1720                 }
1721               break;
1722             }
1723           last = PREV_INSN (last);
1724         }
1725     }
1726
1727   return target;
1728 }
1729
1730 /* Expand a call to the builtin binary math functions (pow and atan2).
1731    Return 0 if a normal call should be emitted rather than expanding the
1732    function in-line.  EXP is the expression that is a call to the builtin
1733    function; if convenient, the result should be placed in TARGET.
1734    SUBTARGET may be used as the target for computing one of EXP's
1735    operands.  */
1736
1737 static rtx
1738 expand_builtin_mathfn_2 (tree exp, rtx target, rtx subtarget)
1739 {
1740   optab builtin_optab;
1741   rtx op0, op1, insns;
1742   tree fndecl = get_callee_fndecl (exp);
1743   tree arglist = TREE_OPERAND (exp, 1);
1744   tree arg0, arg1, temp, narg;
1745   enum machine_mode mode;
1746   bool errno_set = true;
1747   bool stable = true;
1748
1749   if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
1750     return 0;
1751
1752   arg0 = TREE_VALUE (arglist);
1753   arg1 = TREE_VALUE (TREE_CHAIN (arglist));
1754
1755   switch (DECL_FUNCTION_CODE (fndecl))
1756     {
1757     case BUILT_IN_POW:
1758     case BUILT_IN_POWF:
1759     case BUILT_IN_POWL:
1760       builtin_optab = pow_optab; break;
1761     case BUILT_IN_ATAN2:
1762     case BUILT_IN_ATAN2F:
1763     case BUILT_IN_ATAN2L:
1764       builtin_optab = atan2_optab; break;
1765     default:
1766       abort ();
1767     }
1768
1769   /* Make a suitable register to place result in.  */
1770   mode = TYPE_MODE (TREE_TYPE (exp));
1771
1772   /* Before working hard, check whether the instruction is available.  */
1773   if (builtin_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing)
1774     return 0;
1775
1776   target = gen_reg_rtx (mode);
1777
1778   if (! flag_errno_math || ! HONOR_NANS (mode))
1779     errno_set = false;
1780
1781   /* Alway stabilize the argument list.  */
1782   narg = save_expr (arg1);
1783   if (narg != arg1)
1784     {
1785       temp = build_tree_list (NULL_TREE, narg);
1786       stable = false;
1787     }
1788   else
1789     temp = TREE_CHAIN (arglist);
1790
1791   narg = save_expr (arg0);
1792   if (narg != arg0)
1793     {
1794       arglist = tree_cons (NULL_TREE, narg, temp);
1795       stable = false;
1796     }
1797   else if (! stable)
1798     arglist = tree_cons (NULL_TREE, arg0, temp);
1799
1800   if (! stable)
1801     exp = build_function_call_expr (fndecl, arglist);
1802
1803   op0 = expand_expr (arg0, subtarget, VOIDmode, 0);
1804   op1 = expand_expr (arg1, 0, VOIDmode, 0);
1805
1806   emit_queue ();
1807   start_sequence ();
1808
1809   /* Compute into TARGET.
1810      Set TARGET to wherever the result comes back.  */
1811   target = expand_binop (mode, builtin_optab, op0, op1,
1812                          target, 0, OPTAB_DIRECT);
1813
1814   /* If we were unable to expand via the builtin, stop the sequence
1815      (without outputting the insns) and call to the library function
1816      with the stabilized argument list.  */
1817   if (target == 0)
1818     {
1819       end_sequence ();
1820       return expand_call (exp, target, target == const0_rtx);
1821     }
1822
1823   if (errno_set)
1824     expand_errno_check (exp, target);
1825
1826   /* Output the entire sequence.  */
1827   insns = get_insns ();
1828   end_sequence ();
1829   emit_insn (insns);
1830
1831   return target;
1832 }
1833
1834 /* To evaluate powi(x,n), the floating point value x raised to the
1835    constant integer exponent n, we use a hybrid algorithm that
1836    combines the "window method" with look-up tables.  For an
1837    introduction to exponentiation algorithms and "addition chains",
1838    see section 4.6.3, "Evaluation of Powers" of Donald E. Knuth,
1839    "Seminumerical Algorithms", Vol. 2, "The Art of Computer Programming",
1840    3rd Edition, 1998, and Daniel M. Gordon, "A Survey of Fast Exponentiation
1841    Methods", Journal of Algorithms, Vol. 27, pp. 129-146, 1998.  */
1842
1843 /* Provide a default value for POWI_MAX_MULTS, the maximum number of
1844    multiplications to inline before calling the system library's pow
1845    function.  powi(x,n) requires at worst 2*bits(n)-2 multiplications,
1846    so this default never requires calling pow, powf or powl.  */
1847  
1848 #ifndef POWI_MAX_MULTS
1849 #define POWI_MAX_MULTS  (2*HOST_BITS_PER_WIDE_INT-2)
1850 #endif
1851
1852 /* The size of the "optimal power tree" lookup table.  All
1853    exponents less than this value are simply looked up in the
1854    powi_table below.  This threshold is also used to size the
1855    cache of pseudo registers that hold intermediate results.  */
1856 #define POWI_TABLE_SIZE 256
1857
1858 /* The size, in bits of the window, used in the "window method"
1859    exponentiation algorithm.  This is equivalent to a radix of
1860    (1<<POWI_WINDOW_SIZE) in the corresponding "m-ary method".  */
1861 #define POWI_WINDOW_SIZE 3
1862
1863 /* The following table is an efficient representation of an
1864    "optimal power tree".  For each value, i, the corresponding
1865    value, j, in the table states than an optimal evaluation
1866    sequence for calculating pow(x,i) can be found by evaluating
1867    pow(x,j)*pow(x,i-j).  An optimal power tree for the first
1868    100 integers is given in Knuth's "Seminumerical algorithms".  */
1869
1870 static const unsigned char powi_table[POWI_TABLE_SIZE] =
1871   {
1872       0,   1,   1,   2,   2,   3,   3,   4,  /*   0 -   7 */
1873       4,   6,   5,   6,   6,  10,   7,   9,  /*   8 -  15 */
1874       8,  16,   9,  16,  10,  12,  11,  13,  /*  16 -  23 */
1875      12,  17,  13,  18,  14,  24,  15,  26,  /*  24 -  31 */
1876      16,  17,  17,  19,  18,  33,  19,  26,  /*  32 -  39 */
1877      20,  25,  21,  40,  22,  27,  23,  44,  /*  40 -  47 */
1878      24,  32,  25,  34,  26,  29,  27,  44,  /*  48 -  55 */
1879      28,  31,  29,  34,  30,  60,  31,  36,  /*  56 -  63 */
1880      32,  64,  33,  34,  34,  46,  35,  37,  /*  64 -  71 */
1881      36,  65,  37,  50,  38,  48,  39,  69,  /*  72 -  79 */
1882      40,  49,  41,  43,  42,  51,  43,  58,  /*  80 -  87 */
1883      44,  64,  45,  47,  46,  59,  47,  76,  /*  88 -  95 */
1884      48,  65,  49,  66,  50,  67,  51,  66,  /*  96 - 103 */
1885      52,  70,  53,  74,  54, 104,  55,  74,  /* 104 - 111 */
1886      56,  64,  57,  69,  58,  78,  59,  68,  /* 112 - 119 */
1887      60,  61,  61,  80,  62,  75,  63,  68,  /* 120 - 127 */
1888      64,  65,  65, 128,  66, 129,  67,  90,  /* 128 - 135 */
1889      68,  73,  69, 131,  70,  94,  71,  88,  /* 136 - 143 */
1890      72, 128,  73,  98,  74, 132,  75, 121,  /* 144 - 151 */
1891      76, 102,  77, 124,  78, 132,  79, 106,  /* 152 - 159 */
1892      80,  97,  81, 160,  82,  99,  83, 134,  /* 160 - 167 */
1893      84,  86,  85,  95,  86, 160,  87, 100,  /* 168 - 175 */
1894      88, 113,  89,  98,  90, 107,  91, 122,  /* 176 - 183 */
1895      92, 111,  93, 102,  94, 126,  95, 150,  /* 184 - 191 */
1896      96, 128,  97, 130,  98, 133,  99, 195,  /* 192 - 199 */
1897     100, 128, 101, 123, 102, 164, 103, 138,  /* 200 - 207 */
1898     104, 145, 105, 146, 106, 109, 107, 149,  /* 208 - 215 */
1899     108, 200, 109, 146, 110, 170, 111, 157,  /* 216 - 223 */
1900     112, 128, 113, 130, 114, 182, 115, 132,  /* 224 - 231 */
1901     116, 200, 117, 132, 118, 158, 119, 206,  /* 232 - 239 */
1902     120, 240, 121, 162, 122, 147, 123, 152,  /* 240 - 247 */
1903     124, 166, 125, 214, 126, 138, 127, 153,  /* 248 - 255 */
1904   };
1905
1906
1907 /* Return the number of multiplications required to calculate
1908    powi(x,n) where n is less than POWI_TABLE_SIZE.  This is a
1909    subroutine of powi_cost.  CACHE is an array indicating
1910    which exponents have already been calculated.  */
1911
1912 static int
1913 powi_lookup_cost (unsigned HOST_WIDE_INT n, bool *cache)
1914 {
1915   /* If we've already calculated this exponent, then this evaluation
1916      doesn't require any additional multiplications.  */
1917   if (cache[n])
1918     return 0;
1919
1920   cache[n] = true;
1921   return powi_lookup_cost (n - powi_table[n], cache)
1922          + powi_lookup_cost (powi_table[n], cache) + 1;
1923 }
1924
1925 /* Return the number of multiplications required to calculate
1926    powi(x,n) for an arbitrary x, given the exponent N.  This
1927    function needs to be kept in sync with expand_powi below.  */
1928
1929 static int
1930 powi_cost (HOST_WIDE_INT n)
1931 {
1932   bool cache[POWI_TABLE_SIZE];
1933   unsigned HOST_WIDE_INT digit;
1934   unsigned HOST_WIDE_INT val;
1935   int result;
1936
1937   if (n == 0)
1938     return 0;
1939
1940   /* Ignore the reciprocal when calculating the cost.  */
1941   val = (n < 0) ? -n : n;
1942
1943   /* Initialize the exponent cache.  */
1944   memset (cache, 0, POWI_TABLE_SIZE * sizeof (bool));
1945   cache[1] = true;
1946
1947   result = 0;
1948
1949   while (val >= POWI_TABLE_SIZE)
1950     {
1951       if (val & 1)
1952         {
1953           digit = val & ((1 << POWI_WINDOW_SIZE) - 1);
1954           result += powi_lookup_cost (digit, cache)
1955                     + POWI_WINDOW_SIZE + 1;
1956           val >>= POWI_WINDOW_SIZE;
1957         }
1958       else
1959         {
1960           val >>= 1;
1961           result++;
1962         }
1963     }
1964   
1965   return result + powi_lookup_cost (val, cache);
1966 }
1967
1968 /* Recursive subroutine of expand_powi.  This function takes the array,
1969    CACHE, of already calculated exponents and an exponent N and returns
1970    an RTX that corresponds to CACHE[1]**N, as calculated in mode MODE.  */
1971
1972 static rtx
1973 expand_powi_1 (enum machine_mode mode, unsigned HOST_WIDE_INT n, rtx *cache)
1974 {
1975   unsigned HOST_WIDE_INT digit;
1976   rtx target, result;
1977   rtx op0, op1;
1978
1979   if (n < POWI_TABLE_SIZE)
1980     {
1981       if (cache[n])
1982         return cache[n];
1983
1984       target = gen_reg_rtx (mode);
1985       cache[n] = target;
1986
1987       op0 = expand_powi_1 (mode, n - powi_table[n], cache);
1988       op1 = expand_powi_1 (mode, powi_table[n], cache);
1989     }
1990   else if (n & 1)
1991     {
1992       target = gen_reg_rtx (mode);
1993       digit = n & ((1 << POWI_WINDOW_SIZE) - 1);
1994       op0 = expand_powi_1 (mode, n - digit, cache);
1995       op1 = expand_powi_1 (mode, digit, cache);
1996     }
1997   else
1998     {
1999       target = gen_reg_rtx (mode);
2000       op0 = expand_powi_1 (mode, n >> 1, cache);
2001       op1 = op0;
2002     }
2003
2004   result = expand_mult (mode, op0, op1, target, 0);
2005   if (result != target)
2006     emit_move_insn (target, result);
2007   return target;
2008 }
2009
2010 /* Expand the RTL to evaluate powi(x,n) in mode MODE.  X is the
2011    floating point operand in mode MODE, and N is the exponent.  This
2012    function needs to be kept in sync with powi_cost above.  */
2013    
2014 static rtx
2015 expand_powi (rtx x, enum machine_mode mode, HOST_WIDE_INT n)
2016 {
2017   unsigned HOST_WIDE_INT val;
2018   rtx cache[POWI_TABLE_SIZE];
2019   rtx result;
2020
2021   if (n == 0)
2022     return CONST1_RTX (mode);
2023
2024   val = (n < 0) ? -n : n;
2025
2026   memset (cache, 0, sizeof (cache));
2027   cache[1] = x;
2028
2029   result = expand_powi_1 (mode, (n < 0) ? -n : n, cache);
2030
2031   /* If the original exponent was negative, reciprocate the result.  */
2032   if (n < 0)
2033     result = expand_binop (mode, sdiv_optab, CONST1_RTX (mode),
2034                            result, NULL_RTX, 0, OPTAB_LIB_WIDEN);
2035
2036   return result;
2037 }
2038
2039 /* Expand a call to the pow built-in mathematical function.  Return 0 if
2040    a normal call should be emitted rather than expanding the function
2041    in-line.  EXP is the expression that is a call to the builtin
2042    function; if convenient, the result should be placed in TARGET.  */
2043
2044 static rtx
2045 expand_builtin_pow (tree exp, rtx target, rtx subtarget)
2046 {
2047   tree arglist = TREE_OPERAND (exp, 1);
2048   tree arg0, arg1;
2049
2050   if (! validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
2051     return 0;
2052
2053   arg0 = TREE_VALUE (arglist);
2054   arg1 = TREE_VALUE (TREE_CHAIN (arglist));
2055
2056   if (TREE_CODE (arg1) == REAL_CST
2057       && ! TREE_CONSTANT_OVERFLOW (arg1))
2058     {
2059       REAL_VALUE_TYPE cint;
2060       REAL_VALUE_TYPE c;
2061       HOST_WIDE_INT n;
2062
2063       c = TREE_REAL_CST (arg1);
2064       n = real_to_integer (&c);
2065       real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
2066       if (real_identical (&c, &cint))
2067         {
2068           /* If the exponent is -1, 0, 1 or 2, then expand_powi is exact.
2069              Otherwise, check the number of multiplications required.
2070              Note that pow never sets errno for an integer exponent.  */
2071           if ((n >= -1 && n <= 2)
2072               || (flag_unsafe_math_optimizations
2073                   && ! optimize_size
2074                   && powi_cost (n) <= POWI_MAX_MULTS))
2075             {
2076               enum machine_mode mode = TYPE_MODE (TREE_TYPE (exp));
2077               rtx op = expand_expr (arg0, subtarget, VOIDmode, 0);
2078               op = force_reg (mode, op);
2079               return expand_powi (op, mode, n);
2080             }
2081         }
2082     }
2083   return expand_builtin_mathfn_2 (exp, target, NULL_RTX);
2084 }
2085
2086 /* Expand expression EXP which is a call to the strlen builtin.  Return 0
2087    if we failed the caller should emit a normal call, otherwise
2088    try to get the result in TARGET, if convenient.  */
2089
2090 static rtx
2091 expand_builtin_strlen (tree arglist, rtx target,
2092                        enum machine_mode target_mode)
2093 {
2094   if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
2095     return 0;
2096   else
2097     {
2098       rtx pat;
2099       tree len, src = TREE_VALUE (arglist);
2100       rtx result, src_reg, char_rtx, before_strlen;
2101       enum machine_mode insn_mode = target_mode, char_mode;
2102       enum insn_code icode = CODE_FOR_nothing;
2103       int align;
2104
2105       /* If the length can be computed at compile-time, return it.  */
2106       len = c_strlen (src, 0);
2107       if (len)
2108         return expand_expr (len, target, target_mode, EXPAND_NORMAL);
2109
2110       /* If the length can be computed at compile-time and is constant
2111          integer, but there are side-effects in src, evaluate
2112          src for side-effects, then return len.
2113          E.g. x = strlen (i++ ? "xfoo" + 1 : "bar");
2114          can be optimized into: i++; x = 3;  */
2115       len = c_strlen (src, 1);
2116       if (len && TREE_CODE (len) == INTEGER_CST)
2117         {
2118           expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
2119           return expand_expr (len, target, target_mode, EXPAND_NORMAL);
2120         }
2121
2122       align = get_pointer_alignment (src, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
2123
2124       /* If SRC is not a pointer type, don't do this operation inline.  */
2125       if (align == 0)
2126         return 0;
2127
2128       /* Bail out if we can't compute strlen in the right mode.  */
2129       while (insn_mode != VOIDmode)
2130         {
2131           icode = strlen_optab->handlers[(int) insn_mode].insn_code;
2132           if (icode != CODE_FOR_nothing)
2133             break;
2134
2135           insn_mode = GET_MODE_WIDER_MODE (insn_mode);
2136         }
2137       if (insn_mode == VOIDmode)
2138         return 0;
2139
2140       /* Make a place to write the result of the instruction.  */
2141       result = target;
2142       if (! (result != 0
2143              && GET_CODE (result) == REG
2144              && GET_MODE (result) == insn_mode
2145              && REGNO (result) >= FIRST_PSEUDO_REGISTER))
2146         result = gen_reg_rtx (insn_mode);
2147
2148       /* Make a place to hold the source address.  We will not expand
2149          the actual source until we are sure that the expansion will
2150          not fail -- there are trees that cannot be expanded twice.  */
2151       src_reg = gen_reg_rtx (Pmode);
2152
2153       /* Mark the beginning of the strlen sequence so we can emit the
2154          source operand later.  */
2155       before_strlen = get_last_insn ();
2156
2157       char_rtx = const0_rtx;
2158       char_mode = insn_data[(int) icode].operand[2].mode;
2159       if (! (*insn_data[(int) icode].operand[2].predicate) (char_rtx,
2160                                                             char_mode))
2161         char_rtx = copy_to_mode_reg (char_mode, char_rtx);
2162
2163       pat = GEN_FCN (icode) (result, gen_rtx_MEM (BLKmode, src_reg),
2164                              char_rtx, GEN_INT (align));
2165       if (! pat)
2166         return 0;
2167       emit_insn (pat);
2168
2169       /* Now that we are assured of success, expand the source.  */
2170       start_sequence ();
2171       pat = memory_address (BLKmode,
2172                             expand_expr (src, src_reg, ptr_mode, EXPAND_SUM));
2173       if (pat != src_reg)
2174         emit_move_insn (src_reg, pat);
2175       pat = get_insns ();
2176       end_sequence ();
2177
2178       if (before_strlen)
2179         emit_insn_after (pat, before_strlen);
2180       else
2181         emit_insn_before (pat, get_insns ());
2182
2183       /* Return the value in the proper mode for this function.  */
2184       if (GET_MODE (result) == target_mode)
2185         target = result;
2186       else if (target != 0)
2187         convert_move (target, result, 0);
2188       else
2189         target = convert_to_mode (target_mode, result, 0);
2190
2191       return target;
2192     }
2193 }
2194
2195 /* Expand a call to the strstr builtin.  Return 0 if we failed the
2196    caller should emit a normal call, otherwise try to get the result
2197    in TARGET, if convenient (and in mode MODE if that's convenient).  */
2198
2199 static rtx
2200 expand_builtin_strstr (tree arglist, rtx target, enum machine_mode mode)
2201 {
2202   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2203     return 0;
2204   else
2205     {
2206       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
2207       tree fn;
2208       const char *p1, *p2;
2209
2210       p2 = c_getstr (s2);
2211       if (p2 == NULL)
2212         return 0;
2213
2214       p1 = c_getstr (s1);
2215       if (p1 != NULL)
2216         {
2217           const char *r = strstr (p1, p2);
2218
2219           if (r == NULL)
2220             return const0_rtx;
2221
2222           /* Return an offset into the constant string argument.  */
2223           return expand_expr (fold (build (PLUS_EXPR, TREE_TYPE (s1),
2224                                            s1, ssize_int (r - p1))),
2225                               target, mode, EXPAND_NORMAL);
2226         }
2227
2228       if (p2[0] == '\0')
2229         return expand_expr (s1, target, mode, EXPAND_NORMAL);
2230
2231       if (p2[1] != '\0')
2232         return 0;
2233
2234       fn = implicit_built_in_decls[BUILT_IN_STRCHR];
2235       if (!fn)
2236         return 0;
2237
2238       /* New argument list transforming strstr(s1, s2) to
2239          strchr(s1, s2[0]).  */
2240       arglist =
2241         build_tree_list (NULL_TREE, build_int_2 (p2[0], 0));
2242       arglist = tree_cons (NULL_TREE, s1, arglist);
2243       return expand_expr (build_function_call_expr (fn, arglist),
2244                           target, mode, EXPAND_NORMAL);
2245     }
2246 }
2247
2248 /* Expand a call to the strchr builtin.  Return 0 if we failed the
2249    caller should emit a normal call, otherwise try to get the result
2250    in TARGET, if convenient (and in mode MODE if that's convenient).  */
2251
2252 static rtx
2253 expand_builtin_strchr (tree arglist, rtx target, enum machine_mode mode)
2254 {
2255   if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2256     return 0;
2257   else
2258     {
2259       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
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 = strchr (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       /* FIXME: Should use here strchrM optab so that ports can optimize
2286          this.  */
2287       return 0;
2288     }
2289 }
2290
2291 /* Expand a call to the strrchr builtin.  Return 0 if we failed the
2292    caller should emit a normal call, otherwise try to get the result
2293    in TARGET, if convenient (and in mode MODE if that's convenient).  */
2294
2295 static rtx
2296 expand_builtin_strrchr (tree arglist, rtx target, enum machine_mode mode)
2297 {
2298   if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2299     return 0;
2300   else
2301     {
2302       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
2303       tree fn;
2304       const char *p1;
2305
2306       if (TREE_CODE (s2) != INTEGER_CST)
2307         return 0;
2308
2309       p1 = c_getstr (s1);
2310       if (p1 != NULL)
2311         {
2312           char c;
2313           const char *r;
2314
2315           if (target_char_cast (s2, &c))
2316             return 0;
2317
2318           r = strrchr (p1, c);
2319
2320           if (r == NULL)
2321             return const0_rtx;
2322
2323           /* Return an offset into the constant string argument.  */
2324           return expand_expr (fold (build (PLUS_EXPR, TREE_TYPE (s1),
2325                                            s1, ssize_int (r - p1))),
2326                               target, mode, EXPAND_NORMAL);
2327         }
2328
2329       if (! integer_zerop (s2))
2330         return 0;
2331
2332       fn = implicit_built_in_decls[BUILT_IN_STRCHR];
2333       if (!fn)
2334         return 0;
2335
2336       /* Transform strrchr(s1, '\0') to strchr(s1, '\0').  */
2337       return expand_expr (build_function_call_expr (fn, arglist),
2338                           target, mode, EXPAND_NORMAL);
2339     }
2340 }
2341
2342 /* Expand a call to the strpbrk builtin.  Return 0 if we failed the
2343    caller should emit a normal call, otherwise try to get the result
2344    in TARGET, if convenient (and in mode MODE if that's convenient).  */
2345
2346 static rtx
2347 expand_builtin_strpbrk (tree arglist, rtx target, enum machine_mode mode)
2348 {
2349   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2350     return 0;
2351   else
2352     {
2353       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
2354       tree fn;
2355       const char *p1, *p2;
2356
2357       p2 = c_getstr (s2);
2358       if (p2 == NULL)
2359         return 0;
2360
2361       p1 = c_getstr (s1);
2362       if (p1 != NULL)
2363         {
2364           const char *r = strpbrk (p1, p2);
2365
2366           if (r == NULL)
2367             return const0_rtx;
2368
2369           /* Return an offset into the constant string argument.  */
2370           return expand_expr (fold (build (PLUS_EXPR, TREE_TYPE (s1),
2371                                            s1, ssize_int (r - p1))),
2372                               target, mode, EXPAND_NORMAL);
2373         }
2374
2375       if (p2[0] == '\0')
2376         {
2377           /* strpbrk(x, "") == NULL.
2378              Evaluate and ignore the arguments in case they had
2379              side-effects.  */
2380           expand_expr (s1, const0_rtx, VOIDmode, EXPAND_NORMAL);
2381           return const0_rtx;
2382         }
2383
2384       if (p2[1] != '\0')
2385         return 0;  /* Really call strpbrk.  */
2386
2387       fn = implicit_built_in_decls[BUILT_IN_STRCHR];
2388       if (!fn)
2389         return 0;
2390
2391       /* New argument list transforming strpbrk(s1, s2) to
2392          strchr(s1, s2[0]).  */
2393       arglist =
2394         build_tree_list (NULL_TREE, build_int_2 (p2[0], 0));
2395       arglist = tree_cons (NULL_TREE, s1, arglist);
2396       return expand_expr (build_function_call_expr (fn, arglist),
2397                           target, mode, EXPAND_NORMAL);
2398     }
2399 }
2400
2401 /* Callback routine for store_by_pieces.  Read GET_MODE_BITSIZE (MODE)
2402    bytes from constant string DATA + OFFSET and return it as target
2403    constant.  */
2404
2405 static rtx
2406 builtin_memcpy_read_str (void *data, HOST_WIDE_INT offset,
2407                          enum machine_mode mode)
2408 {
2409   const char *str = (const char *) data;
2410
2411   if (offset < 0
2412       || ((unsigned HOST_WIDE_INT) offset + GET_MODE_SIZE (mode)
2413           > strlen (str) + 1))
2414     abort ();  /* Attempt to read past the end of constant string.  */
2415
2416   return c_readstr (str + offset, mode);
2417 }
2418
2419 /* Expand a call to the memcpy builtin, with arguments in ARGLIST.
2420    Return 0 if we failed, the caller should emit a normal call,
2421    otherwise try to get the result in TARGET, if convenient (and in
2422    mode MODE if that's convenient).  */
2423 static rtx
2424 expand_builtin_memcpy (tree arglist, rtx target, enum machine_mode mode)
2425 {
2426   if (!validate_arglist (arglist,
2427                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2428     return 0;
2429   else
2430     {
2431       tree dest = TREE_VALUE (arglist);
2432       tree src = TREE_VALUE (TREE_CHAIN (arglist));
2433       tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2434       const char *src_str;
2435       unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
2436       unsigned int dest_align
2437         = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2438       rtx dest_mem, src_mem, dest_addr, len_rtx;
2439
2440       /* If DEST is not a pointer type, call the normal function.  */
2441       if (dest_align == 0)
2442         return 0;
2443
2444       /* If the LEN parameter is zero, return DEST.  */
2445       if (host_integerp (len, 1) && tree_low_cst (len, 1) == 0)
2446         {
2447           /* Evaluate and ignore SRC in case it has side-effects.  */
2448           expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
2449           return expand_expr (dest, target, mode, EXPAND_NORMAL);
2450         }
2451
2452       /* If either SRC is not a pointer type, don't do this
2453          operation in-line.  */
2454       if (src_align == 0)
2455         return 0;
2456
2457       dest_mem = get_memory_rtx (dest);
2458       set_mem_align (dest_mem, dest_align);
2459       len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
2460       src_str = c_getstr (src);
2461
2462       /* If SRC is a string constant and block move would be done
2463          by pieces, we can avoid loading the string from memory
2464          and only stored the computed constants.  */
2465       if (src_str
2466           && GET_CODE (len_rtx) == CONST_INT
2467           && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
2468           && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
2469                                   (void *) src_str, dest_align))
2470         {
2471           dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
2472                                       builtin_memcpy_read_str,
2473                                       (void *) src_str, dest_align, 0);
2474           dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2475 #ifdef POINTERS_EXTEND_UNSIGNED
2476           if (GET_MODE (dest_mem) != ptr_mode)
2477             dest_mem = convert_memory_address (ptr_mode, dest_mem);
2478 #endif
2479           return dest_mem;
2480         }
2481
2482       src_mem = get_memory_rtx (src);
2483       set_mem_align (src_mem, src_align);
2484
2485       /* Copy word part most expediently.  */
2486       dest_addr = emit_block_move (dest_mem, src_mem, len_rtx,
2487                                    BLOCK_OP_NORMAL);
2488
2489       if (dest_addr == 0)
2490         {
2491           dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2492 #ifdef POINTERS_EXTEND_UNSIGNED
2493           if (GET_MODE (dest_addr) != ptr_mode)
2494             dest_addr = convert_memory_address (ptr_mode, dest_addr);
2495 #endif
2496         }
2497       return dest_addr;
2498     }
2499 }
2500
2501 /* Expand a call to the mempcpy builtin, with arguments in ARGLIST.
2502    Return 0 if we failed the caller should emit a normal call,
2503    otherwise try to get the result in TARGET, if convenient (and in
2504    mode MODE if that's convenient).  If ENDP is 0 return the
2505    destination pointer, if ENDP is 1 return the end pointer ala
2506    mempcpy, and if ENDP is 2 return the end pointer minus one ala
2507    stpcpy.  */
2508
2509 static rtx
2510 expand_builtin_mempcpy (tree arglist, rtx target, enum machine_mode mode,
2511                         int endp)
2512 {
2513   if (!validate_arglist (arglist,
2514                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2515     return 0;
2516   /* If return value is ignored, transform mempcpy into memcpy.  */
2517   else if (target == const0_rtx)
2518     {
2519       tree fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
2520
2521       if (!fn)
2522         return 0;
2523
2524       return expand_expr (build_function_call_expr (fn, arglist),
2525                           target, mode, EXPAND_NORMAL);
2526     }
2527   else
2528     {
2529       tree dest = TREE_VALUE (arglist);
2530       tree src = TREE_VALUE (TREE_CHAIN (arglist));
2531       tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2532       const char *src_str;
2533       unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
2534       unsigned int dest_align
2535         = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2536       rtx dest_mem, src_mem, len_rtx;
2537
2538       /* If DEST is not a pointer type or LEN is not constant,
2539          call the normal function.  */
2540       if (dest_align == 0 || !host_integerp (len, 1))
2541         return 0;
2542
2543       /* If the LEN parameter is zero, return DEST.  */
2544       if (tree_low_cst (len, 1) == 0)
2545         {
2546           /* Evaluate and ignore SRC in case it has side-effects.  */
2547           expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
2548           return expand_expr (dest, target, mode, EXPAND_NORMAL);
2549         }
2550
2551       /* If either SRC is not a pointer type, don't do this
2552          operation in-line.  */
2553       if (src_align == 0)
2554         return 0;
2555
2556       len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
2557       src_str = c_getstr (src);
2558
2559       /* If SRC is a string constant and block move would be done
2560          by pieces, we can avoid loading the string from memory
2561          and only stored the computed constants.  */
2562       if (src_str
2563           && GET_CODE (len_rtx) == CONST_INT
2564           && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
2565           && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
2566                                   (void *) src_str, dest_align))
2567         {
2568           dest_mem = get_memory_rtx (dest);
2569           set_mem_align (dest_mem, dest_align);
2570           dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
2571                                       builtin_memcpy_read_str,
2572                                       (void *) src_str, dest_align, endp);
2573           dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2574 #ifdef POINTERS_EXTEND_UNSIGNED
2575           if (GET_MODE (dest_mem) != ptr_mode)
2576             dest_mem = convert_memory_address (ptr_mode, dest_mem);
2577 #endif
2578           return dest_mem;
2579         }
2580
2581       if (GET_CODE (len_rtx) == CONST_INT
2582           && can_move_by_pieces (INTVAL (len_rtx),
2583                                  MIN (dest_align, src_align)))
2584         {
2585           dest_mem = get_memory_rtx (dest);
2586           set_mem_align (dest_mem, dest_align);
2587           src_mem = get_memory_rtx (src);
2588           set_mem_align (src_mem, src_align);
2589           dest_mem = move_by_pieces (dest_mem, src_mem, INTVAL (len_rtx),
2590                                      MIN (dest_align, src_align), endp);
2591           dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2592 #ifdef POINTERS_EXTEND_UNSIGNED
2593           if (GET_MODE (dest_mem) != ptr_mode)
2594             dest_mem = convert_memory_address (ptr_mode, dest_mem);
2595 #endif
2596           return dest_mem;
2597         }
2598
2599       return 0;
2600     }
2601 }
2602
2603 /* Expand expression EXP, which is a call to the memmove builtin.  Return 0
2604    if we failed the caller should emit a normal call.  */
2605
2606 static rtx
2607 expand_builtin_memmove (tree arglist, rtx target, enum machine_mode mode)
2608 {
2609   if (!validate_arglist (arglist,
2610                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2611     return 0;
2612   else
2613     {
2614       tree dest = TREE_VALUE (arglist);
2615       tree src = TREE_VALUE (TREE_CHAIN (arglist));
2616       tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2617
2618       unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
2619       unsigned int dest_align
2620         = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2621
2622       /* If DEST is not a pointer type, call the normal function.  */
2623       if (dest_align == 0)
2624         return 0;
2625
2626       /* If the LEN parameter is zero, return DEST.  */
2627       if (host_integerp (len, 1) && tree_low_cst (len, 1) == 0)
2628         {
2629           /* Evaluate and ignore SRC in case it has side-effects.  */
2630           expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
2631           return expand_expr (dest, target, mode, EXPAND_NORMAL);
2632         }
2633
2634       /* If either SRC is not a pointer type, don't do this
2635          operation in-line.  */
2636       if (src_align == 0)
2637         return 0;
2638
2639       /* If src is categorized for a readonly section we can use
2640          normal memcpy.  */
2641       if (readonly_data_expr (src))
2642         {
2643           tree const fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
2644           if (!fn)
2645             return 0;
2646           return expand_expr (build_function_call_expr (fn, arglist),
2647                               target, mode, EXPAND_NORMAL);
2648         }
2649
2650       /* Otherwise, call the normal function.  */
2651       return 0;
2652    }
2653 }
2654
2655 /* Expand expression EXP, which is a call to the bcopy builtin.  Return 0
2656    if we failed the caller should emit a normal call.  */
2657
2658 static rtx
2659 expand_builtin_bcopy (tree arglist)
2660 {
2661   tree src, dest, size, newarglist;
2662
2663   if (!validate_arglist (arglist,
2664                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2665     return NULL_RTX;
2666
2667   src = TREE_VALUE (arglist);
2668   dest = TREE_VALUE (TREE_CHAIN (arglist));
2669   size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2670
2671   /* New argument list transforming bcopy(ptr x, ptr y, int z) to
2672      memmove(ptr y, ptr x, size_t z).   This is done this way
2673      so that if it isn't expanded inline, we fallback to
2674      calling bcopy instead of memmove.  */
2675
2676   newarglist = build_tree_list (NULL_TREE, convert (sizetype, size));
2677   newarglist = tree_cons (NULL_TREE, src, newarglist);
2678   newarglist = tree_cons (NULL_TREE, dest, newarglist);
2679
2680   return expand_builtin_memmove (newarglist, const0_rtx, VOIDmode);
2681 }
2682
2683 /* Expand expression EXP, which is a call to the strcpy builtin.  Return 0
2684    if we failed the caller should emit a normal call, otherwise try to get
2685    the result in TARGET, if convenient (and in mode MODE if that's
2686    convenient).  */
2687
2688 static rtx
2689 expand_builtin_strcpy (tree arglist, rtx target, enum machine_mode mode)
2690 {
2691   tree fn, len, src, dst;
2692
2693   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2694     return 0;
2695
2696   fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
2697   if (!fn)
2698     return 0;
2699
2700   src = TREE_VALUE (TREE_CHAIN (arglist));
2701   len = c_strlen (src, 1);
2702   if (len == 0 || TREE_SIDE_EFFECTS (len))
2703     return 0;
2704
2705   dst = TREE_VALUE (arglist);
2706   len = size_binop (PLUS_EXPR, len, ssize_int (1));
2707   arglist = build_tree_list (NULL_TREE, len);
2708   arglist = tree_cons (NULL_TREE, src, arglist);
2709   arglist = tree_cons (NULL_TREE, dst, arglist);
2710   return expand_expr (build_function_call_expr (fn, arglist),
2711                       target, mode, EXPAND_NORMAL);
2712 }
2713
2714 /* Expand a call to the stpcpy builtin, with arguments in ARGLIST.
2715    Return 0 if we failed the caller should emit a normal call,
2716    otherwise try to get the result in TARGET, if convenient (and in
2717    mode MODE if that's convenient).  */
2718
2719 static rtx
2720 expand_builtin_stpcpy (tree arglist, rtx target, enum machine_mode mode)
2721 {
2722   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2723     return 0;
2724   else
2725     {
2726       tree dst, src, len;
2727
2728       /* If return value is ignored, transform stpcpy into strcpy.  */
2729       if (target == const0_rtx)
2730         {
2731           tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
2732           if (!fn)
2733             return 0;
2734
2735           return expand_expr (build_function_call_expr (fn, arglist),
2736                               target, mode, EXPAND_NORMAL);
2737         }
2738
2739       /* Ensure we get an actual string whose length can be evaluated at
2740          compile-time, not an expression containing a string.  This is
2741          because the latter will potentially produce pessimized code
2742          when used to produce the return value.  */
2743       src = TREE_VALUE (TREE_CHAIN (arglist));
2744       if (! c_getstr (src) || ! (len = c_strlen (src, 0)))
2745         return 0;
2746
2747       dst = TREE_VALUE (arglist);
2748       len = fold (size_binop (PLUS_EXPR, len, ssize_int (1)));
2749       arglist = build_tree_list (NULL_TREE, len);
2750       arglist = tree_cons (NULL_TREE, src, arglist);
2751       arglist = tree_cons (NULL_TREE, dst, arglist);
2752       return expand_builtin_mempcpy (arglist, target, mode, /*endp=*/2);
2753     }
2754 }
2755
2756 /* Callback routine for store_by_pieces.  Read GET_MODE_BITSIZE (MODE)
2757    bytes from constant string DATA + OFFSET and return it as target
2758    constant.  */
2759
2760 static rtx
2761 builtin_strncpy_read_str (void *data, HOST_WIDE_INT offset,
2762                           enum machine_mode mode)
2763 {
2764   const char *str = (const char *) data;
2765
2766   if ((unsigned HOST_WIDE_INT) offset > strlen (str))
2767     return const0_rtx;
2768
2769   return c_readstr (str + offset, mode);
2770 }
2771
2772 /* Expand expression EXP, which is a call to the strncpy builtin.  Return 0
2773    if we failed the caller should emit a normal call.  */
2774
2775 static rtx
2776 expand_builtin_strncpy (tree arglist, rtx target, enum machine_mode mode)
2777 {
2778   if (!validate_arglist (arglist,
2779                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2780     return 0;
2781   else
2782     {
2783       tree slen = c_strlen (TREE_VALUE (TREE_CHAIN (arglist)), 1);
2784       tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2785       tree fn;
2786
2787       /* We must be passed a constant len parameter.  */
2788       if (TREE_CODE (len) != INTEGER_CST)
2789         return 0;
2790
2791       /* If the len parameter is zero, return the dst parameter.  */
2792       if (integer_zerop (len))
2793         {
2794           /* Evaluate and ignore the src argument in case it has
2795              side-effects.  */
2796           expand_expr (TREE_VALUE (TREE_CHAIN (arglist)), const0_rtx,
2797                        VOIDmode, EXPAND_NORMAL);
2798           /* Return the dst parameter.  */
2799           return expand_expr (TREE_VALUE (arglist), target, mode,
2800                               EXPAND_NORMAL);
2801         }
2802
2803       /* Now, we must be passed a constant src ptr parameter.  */
2804       if (slen == 0 || TREE_CODE (slen) != INTEGER_CST)
2805         return 0;
2806
2807       slen = size_binop (PLUS_EXPR, slen, ssize_int (1));
2808
2809       /* We're required to pad with trailing zeros if the requested
2810          len is greater than strlen(s2)+1.  In that case try to
2811          use store_by_pieces, if it fails, punt.  */
2812       if (tree_int_cst_lt (slen, len))
2813         {
2814           tree dest = TREE_VALUE (arglist);
2815           unsigned int dest_align
2816             = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2817           const char *p = c_getstr (TREE_VALUE (TREE_CHAIN (arglist)));
2818           rtx dest_mem;
2819
2820           if (!p || dest_align == 0 || !host_integerp (len, 1)
2821               || !can_store_by_pieces (tree_low_cst (len, 1),
2822                                        builtin_strncpy_read_str,
2823                                        (void *) p, dest_align))
2824             return 0;
2825
2826           dest_mem = get_memory_rtx (dest);
2827           store_by_pieces (dest_mem, tree_low_cst (len, 1),
2828                            builtin_strncpy_read_str,
2829                            (void *) p, dest_align, 0);
2830           dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2831 #ifdef POINTERS_EXTEND_UNSIGNED
2832           if (GET_MODE (dest_mem) != ptr_mode)
2833             dest_mem = convert_memory_address (ptr_mode, dest_mem);
2834 #endif
2835           return dest_mem;
2836         }
2837
2838       /* OK transform into builtin memcpy.  */
2839       fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
2840       if (!fn)
2841         return 0;
2842       return expand_expr (build_function_call_expr (fn, arglist),
2843                           target, mode, EXPAND_NORMAL);
2844     }
2845 }
2846
2847 /* Callback routine for store_by_pieces.  Read GET_MODE_BITSIZE (MODE)
2848    bytes from constant string DATA + OFFSET and return it as target
2849    constant.  */
2850
2851 static rtx
2852 builtin_memset_read_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
2853                          enum machine_mode mode)
2854 {
2855   const char *c = (const char *) data;
2856   char *p = alloca (GET_MODE_SIZE (mode));
2857
2858   memset (p, *c, GET_MODE_SIZE (mode));
2859
2860   return c_readstr (p, mode);
2861 }
2862
2863 /* Callback routine for store_by_pieces.  Return the RTL of a register
2864    containing GET_MODE_SIZE (MODE) consecutive copies of the unsigned
2865    char value given in the RTL register data.  For example, if mode is
2866    4 bytes wide, return the RTL for 0x01010101*data.  */
2867
2868 static rtx
2869 builtin_memset_gen_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
2870                         enum machine_mode mode)
2871 {
2872   rtx target, coeff;
2873   size_t size;
2874   char *p;
2875
2876   size = GET_MODE_SIZE (mode);
2877   if (size == 1)
2878     return (rtx) data;
2879
2880   p = alloca (size);
2881   memset (p, 1, size);
2882   coeff = c_readstr (p, mode);
2883
2884   target = convert_to_mode (mode, (rtx) data, 1);
2885   target = expand_mult (mode, target, coeff, NULL_RTX, 1);
2886   return force_reg (mode, target);
2887 }
2888
2889 /* Expand expression EXP, which is a call to the memset builtin.  Return 0
2890    if we failed the caller should emit a normal call, otherwise try to get
2891    the result in TARGET, if convenient (and in mode MODE if that's
2892    convenient).  */
2893
2894 static rtx
2895 expand_builtin_memset (tree arglist, rtx target, enum machine_mode mode)
2896 {
2897   if (!validate_arglist (arglist,
2898                          POINTER_TYPE, INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
2899     return 0;
2900   else
2901     {
2902       tree dest = TREE_VALUE (arglist);
2903       tree val = TREE_VALUE (TREE_CHAIN (arglist));
2904       tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2905       char c;
2906
2907       unsigned int dest_align
2908         = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2909       rtx dest_mem, dest_addr, len_rtx;
2910
2911       /* If DEST is not a pointer type, don't do this
2912          operation in-line.  */
2913       if (dest_align == 0)
2914         return 0;
2915
2916       /* If the LEN parameter is zero, return DEST.  */
2917       if (host_integerp (len, 1) && tree_low_cst (len, 1) == 0)
2918         {
2919           /* Evaluate and ignore VAL in case it has side-effects.  */
2920           expand_expr (val, const0_rtx, VOIDmode, EXPAND_NORMAL);
2921           return expand_expr (dest, target, mode, EXPAND_NORMAL);
2922         }
2923
2924       if (TREE_CODE (val) != INTEGER_CST)
2925         {
2926           rtx val_rtx;
2927
2928           if (!host_integerp (len, 1))
2929             return 0;
2930
2931           if (optimize_size && tree_low_cst (len, 1) > 1)
2932             return 0;
2933
2934           /* Assume that we can memset by pieces if we can store the
2935            * the coefficients by pieces (in the required modes).
2936            * We can't pass builtin_memset_gen_str as that emits RTL.  */
2937           c = 1;
2938           if (!can_store_by_pieces (tree_low_cst (len, 1),
2939                                     builtin_memset_read_str,
2940                                     &c, dest_align))
2941             return 0;
2942
2943           val = fold (build1 (CONVERT_EXPR, unsigned_char_type_node, val));
2944           val_rtx = expand_expr (val, NULL_RTX, VOIDmode, 0);
2945           val_rtx = force_reg (TYPE_MODE (unsigned_char_type_node),
2946                                val_rtx);
2947           dest_mem = get_memory_rtx (dest);
2948           store_by_pieces (dest_mem, tree_low_cst (len, 1),
2949                            builtin_memset_gen_str,
2950                            val_rtx, dest_align, 0);
2951           dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2952 #ifdef POINTERS_EXTEND_UNSIGNED
2953           if (GET_MODE (dest_mem) != ptr_mode)
2954             dest_mem = convert_memory_address (ptr_mode, dest_mem);
2955 #endif
2956           return dest_mem;
2957         }
2958
2959       if (target_char_cast (val, &c))
2960         return 0;
2961
2962       if (c)
2963         {
2964           if (!host_integerp (len, 1))
2965             return 0;
2966           if (!can_store_by_pieces (tree_low_cst (len, 1),
2967                                     builtin_memset_read_str, &c,
2968                                     dest_align))
2969             return 0;
2970
2971           dest_mem = get_memory_rtx (dest);
2972           store_by_pieces (dest_mem, tree_low_cst (len, 1),
2973                            builtin_memset_read_str,
2974                            &c, dest_align, 0);
2975           dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2976 #ifdef POINTERS_EXTEND_UNSIGNED
2977           if (GET_MODE (dest_mem) != ptr_mode)
2978             dest_mem = convert_memory_address (ptr_mode, dest_mem);
2979 #endif
2980           return dest_mem;
2981         }
2982
2983       len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
2984
2985       dest_mem = get_memory_rtx (dest);
2986       set_mem_align (dest_mem, dest_align);
2987       dest_addr = clear_storage (dest_mem, len_rtx);
2988
2989       if (dest_addr == 0)
2990         {
2991           dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2992 #ifdef POINTERS_EXTEND_UNSIGNED
2993           if (GET_MODE (dest_addr) != ptr_mode)
2994             dest_addr = convert_memory_address (ptr_mode, dest_addr);
2995 #endif
2996         }
2997
2998       return dest_addr;
2999     }
3000 }
3001
3002 /* Expand expression EXP, which is a call to the bzero builtin.  Return 0
3003    if we failed the caller should emit a normal call.  */
3004
3005 static rtx
3006 expand_builtin_bzero (tree arglist)
3007 {
3008   tree dest, size, newarglist;
3009
3010   if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3011     return NULL_RTX;
3012
3013   dest = TREE_VALUE (arglist);
3014   size = TREE_VALUE (TREE_CHAIN (arglist));
3015
3016   /* New argument list transforming bzero(ptr x, int y) to
3017      memset(ptr x, int 0, size_t y).   This is done this way
3018      so that if it isn't expanded inline, we fallback to
3019      calling bzero instead of memset.  */
3020
3021   newarglist = build_tree_list (NULL_TREE, convert (sizetype, size));
3022   newarglist = tree_cons (NULL_TREE, integer_zero_node, newarglist);
3023   newarglist = tree_cons (NULL_TREE, dest, newarglist);
3024
3025   return expand_builtin_memset (newarglist, const0_rtx, VOIDmode);
3026 }
3027
3028 /* Expand expression EXP, which is a call to the memcmp built-in function.
3029    ARGLIST is the argument list for this call.  Return 0 if we failed and the
3030    caller should emit a normal call, otherwise try to get the result in
3031    TARGET, if convenient (and in mode MODE, if that's convenient).  */
3032
3033 static rtx
3034 expand_builtin_memcmp (tree exp ATTRIBUTE_UNUSED, tree arglist, rtx target,
3035                        enum machine_mode mode)
3036 {
3037   tree arg1, arg2, len;
3038   const char *p1, *p2;
3039
3040   if (!validate_arglist (arglist,
3041                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3042     return 0;
3043
3044   arg1 = TREE_VALUE (arglist);
3045   arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3046   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3047
3048   /* If the len parameter is zero, return zero.  */
3049   if (host_integerp (len, 1) && tree_low_cst (len, 1) == 0)
3050     {
3051       /* Evaluate and ignore arg1 and arg2 in case they have
3052          side-effects.  */
3053       expand_expr (arg1, const0_rtx, VOIDmode, EXPAND_NORMAL);
3054       expand_expr (arg2, const0_rtx, VOIDmode, EXPAND_NORMAL);
3055       return const0_rtx;
3056     }
3057
3058   p1 = c_getstr (arg1);
3059   p2 = c_getstr (arg2);
3060
3061   /* If all arguments are constant, and the value of len is not greater
3062      than the lengths of arg1 and arg2, evaluate at compile-time.  */
3063   if (host_integerp (len, 1) && p1 && p2
3064       && compare_tree_int (len, strlen (p1) + 1) <= 0
3065       && compare_tree_int (len, strlen (p2) + 1) <= 0)
3066     {
3067       const int r = memcmp (p1, p2, tree_low_cst (len, 1));
3068
3069       return (r < 0 ? constm1_rtx : (r > 0 ? const1_rtx : const0_rtx));
3070     }
3071
3072   /* If len parameter is one, return an expression corresponding to
3073      (*(const unsigned char*)arg1 - (const unsigned char*)arg2).  */
3074   if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
3075     {
3076       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
3077       tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
3078       tree ind1 =
3079       fold (build1 (CONVERT_EXPR, integer_type_node,
3080                     build1 (INDIRECT_REF, cst_uchar_node,
3081                             build1 (NOP_EXPR, cst_uchar_ptr_node, arg1))));
3082       tree ind2 =
3083       fold (build1 (CONVERT_EXPR, integer_type_node,
3084                     build1 (INDIRECT_REF, cst_uchar_node,
3085                             build1 (NOP_EXPR, cst_uchar_ptr_node, arg2))));
3086       tree result = fold (build (MINUS_EXPR, integer_type_node, ind1, ind2));
3087       return expand_expr (result, target, mode, EXPAND_NORMAL);
3088     }
3089
3090 #if defined HAVE_cmpmemsi || defined HAVE_cmpstrsi
3091   {
3092     rtx arg1_rtx, arg2_rtx, arg3_rtx;
3093     rtx result;
3094     rtx insn;
3095
3096     int arg1_align
3097       = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3098     int arg2_align
3099       = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3100     enum machine_mode insn_mode;
3101
3102 #ifdef HAVE_cmpmemsi
3103     if (HAVE_cmpmemsi)
3104       insn_mode = insn_data[(int) CODE_FOR_cmpmemsi].operand[0].mode;
3105     else
3106 #endif
3107 #ifdef HAVE_cmpstrsi
3108     if (HAVE_cmpstrsi)
3109       insn_mode = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
3110     else
3111 #endif
3112       return 0;     
3113
3114     /* If we don't have POINTER_TYPE, call the function.  */
3115     if (arg1_align == 0 || arg2_align == 0)
3116       return 0;
3117
3118     /* Make a place to write the result of the instruction.  */
3119     result = target;
3120     if (! (result != 0
3121            && GET_CODE (result) == REG && GET_MODE (result) == insn_mode
3122            && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3123       result = gen_reg_rtx (insn_mode);
3124
3125     arg1_rtx = get_memory_rtx (arg1);
3126     arg2_rtx = get_memory_rtx (arg2);
3127     arg3_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
3128 #ifdef HAVE_cmpmemsi
3129     if (HAVE_cmpmemsi)
3130       insn = gen_cmpmemsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3131                            GEN_INT (MIN (arg1_align, arg2_align)));
3132     else
3133 #endif
3134 #ifdef HAVE_cmpstrsi
3135     if (HAVE_cmpstrsi)
3136       insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3137                            GEN_INT (MIN (arg1_align, arg2_align)));
3138     else
3139 #endif
3140       abort ();
3141
3142     if (insn)
3143       emit_insn (insn);
3144     else
3145       emit_library_call_value (memcmp_libfunc, result, LCT_PURE_MAKE_BLOCK,
3146                                TYPE_MODE (integer_type_node), 3,
3147                                XEXP (arg1_rtx, 0), Pmode,
3148                                XEXP (arg2_rtx, 0), Pmode,
3149                                convert_to_mode (TYPE_MODE (sizetype), arg3_rtx,
3150                                                 TREE_UNSIGNED (sizetype)),
3151                                TYPE_MODE (sizetype));
3152
3153     /* Return the value in the proper mode for this function.  */
3154     mode = TYPE_MODE (TREE_TYPE (exp));
3155     if (GET_MODE (result) == mode)
3156       return result;
3157     else if (target != 0)
3158       {
3159         convert_move (target, result, 0);
3160         return target;
3161       }
3162     else
3163       return convert_to_mode (mode, result, 0);
3164   }
3165 #endif
3166
3167   return 0;
3168 }
3169
3170 /* Expand expression EXP, which is a call to the strcmp builtin.  Return 0
3171    if we failed the caller should emit a normal call, otherwise try to get
3172    the result in TARGET, if convenient.  */
3173
3174 static rtx
3175 expand_builtin_strcmp (tree exp, rtx target, enum machine_mode mode)
3176 {
3177   tree arglist = TREE_OPERAND (exp, 1);
3178   tree arg1, arg2;
3179   const char *p1, *p2;
3180
3181   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3182     return 0;
3183
3184   arg1 = TREE_VALUE (arglist);
3185   arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3186
3187   p1 = c_getstr (arg1);
3188   p2 = c_getstr (arg2);
3189
3190   if (p1 && p2)
3191     {
3192       const int i = strcmp (p1, p2);
3193       return (i < 0 ? constm1_rtx : (i > 0 ? const1_rtx : const0_rtx));
3194     }
3195
3196   /* If either arg is "", return an expression corresponding to
3197      (*(const unsigned char*)arg1 - (const unsigned char*)arg2).  */
3198   if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
3199     {
3200       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
3201       tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
3202       tree ind1 =
3203         fold (build1 (CONVERT_EXPR, integer_type_node,
3204                       build1 (INDIRECT_REF, cst_uchar_node,
3205                               build1 (NOP_EXPR, cst_uchar_ptr_node, arg1))));
3206       tree ind2 =
3207         fold (build1 (CONVERT_EXPR, integer_type_node,
3208                       build1 (INDIRECT_REF, cst_uchar_node,
3209                               build1 (NOP_EXPR, cst_uchar_ptr_node, arg2))));
3210       tree result = fold (build (MINUS_EXPR, integer_type_node, ind1, ind2));
3211       return expand_expr (result, target, mode, EXPAND_NORMAL);
3212     }
3213
3214 #ifdef HAVE_cmpstrsi
3215   if (HAVE_cmpstrsi)
3216   {
3217     tree len, len1, len2;
3218     rtx arg1_rtx, arg2_rtx, arg3_rtx;
3219     rtx result, insn;
3220
3221     int arg1_align
3222       = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3223     int arg2_align
3224       = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3225     enum machine_mode insn_mode
3226       = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
3227
3228     len1 = c_strlen (arg1, 1);
3229     len2 = c_strlen (arg2, 1);
3230
3231     if (len1)
3232       len1 = size_binop (PLUS_EXPR, ssize_int (1), len1);
3233     if (len2)
3234       len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
3235
3236     /* If we don't have a constant length for the first, use the length
3237        of the second, if we know it.  We don't require a constant for
3238        this case; some cost analysis could be done if both are available
3239        but neither is constant.  For now, assume they're equally cheap,
3240        unless one has side effects.  If both strings have constant lengths,
3241        use the smaller.  */
3242
3243     if (!len1)
3244       len = len2;
3245     else if (!len2)
3246       len = len1;
3247     else if (TREE_SIDE_EFFECTS (len1))
3248       len = len2;
3249     else if (TREE_SIDE_EFFECTS (len2))
3250       len = len1;
3251     else if (TREE_CODE (len1) != INTEGER_CST)
3252       len = len2;
3253     else if (TREE_CODE (len2) != INTEGER_CST)
3254       len = len1;
3255     else if (tree_int_cst_lt (len1, len2))
3256       len = len1;
3257     else
3258       len = len2;
3259
3260     /* If both arguments have side effects, we cannot optimize.  */
3261     if (!len || TREE_SIDE_EFFECTS (len))
3262       return 0;
3263
3264     /* If we don't have POINTER_TYPE, call the function.  */
3265     if (arg1_align == 0 || arg2_align == 0)
3266       return 0;
3267
3268     /* Make a place to write the result of the instruction.  */
3269     result = target;
3270     if (! (result != 0
3271            && GET_CODE (result) == REG && GET_MODE (result) == insn_mode
3272            && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3273       result = gen_reg_rtx (insn_mode);
3274
3275     arg1_rtx = get_memory_rtx (arg1);
3276     arg2_rtx = get_memory_rtx (arg2);
3277     arg3_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
3278     insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3279                          GEN_INT (MIN (arg1_align, arg2_align)));
3280     if (!insn)
3281       return 0;
3282
3283     emit_insn (insn);
3284
3285     /* Return the value in the proper mode for this function.  */
3286     mode = TYPE_MODE (TREE_TYPE (exp));
3287     if (GET_MODE (result) == mode)
3288       return result;
3289     if (target == 0)
3290       return convert_to_mode (mode, result, 0);
3291     convert_move (target, result, 0);
3292     return target;
3293   }
3294 #endif
3295   return 0;
3296 }
3297
3298 /* Expand expression EXP, which is a call to the strncmp builtin.  Return 0
3299    if we failed the caller should emit a normal call, otherwise try to get
3300    the result in TARGET, if convenient.  */
3301
3302 static rtx
3303 expand_builtin_strncmp (tree exp, rtx target, enum machine_mode mode)
3304 {
3305   tree arglist = TREE_OPERAND (exp, 1);
3306   tree arg1, arg2, arg3;
3307   const char *p1, *p2;
3308
3309   if (!validate_arglist (arglist,
3310                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3311     return 0;
3312
3313   arg1 = TREE_VALUE (arglist);
3314   arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3315   arg3 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3316
3317   /* If the len parameter is zero, return zero.  */
3318   if (host_integerp (arg3, 1) && tree_low_cst (arg3, 1) == 0)
3319     {
3320       /* Evaluate and ignore arg1 and arg2 in case they have
3321          side-effects.  */
3322       expand_expr (arg1, const0_rtx, VOIDmode, EXPAND_NORMAL);
3323       expand_expr (arg2, const0_rtx, VOIDmode, EXPAND_NORMAL);
3324       return const0_rtx;
3325     }
3326
3327   p1 = c_getstr (arg1);
3328   p2 = c_getstr (arg2);
3329
3330   /* If all arguments are constant, evaluate at compile-time.  */
3331   if (host_integerp (arg3, 1) && p1 && p2)
3332     {
3333       const int r = strncmp (p1, p2, tree_low_cst (arg3, 1));
3334       return (r < 0 ? constm1_rtx : (r > 0 ? const1_rtx : const0_rtx));
3335     }
3336
3337   /* If len == 1 or (either string parameter is "" and (len >= 1)),
3338       return (*(const u_char*)arg1 - *(const u_char*)arg2).  */
3339   if (host_integerp (arg3, 1)
3340       && (tree_low_cst (arg3, 1) == 1
3341           || (tree_low_cst (arg3, 1) > 1
3342               && ((p1 && *p1 == '\0') || (p2 && *p2 == '\0')))))
3343     {
3344       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
3345       tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
3346       tree ind1 =
3347         fold (build1 (CONVERT_EXPR, integer_type_node,
3348                       build1 (INDIRECT_REF, cst_uchar_node,
3349                               build1 (NOP_EXPR, cst_uchar_ptr_node, arg1))));
3350       tree ind2 =
3351         fold (build1 (CONVERT_EXPR, integer_type_node,
3352                       build1 (INDIRECT_REF, cst_uchar_node,
3353                               build1 (NOP_EXPR, cst_uchar_ptr_node, arg2))));
3354       tree result = fold (build (MINUS_EXPR, integer_type_node, ind1, ind2));
3355       return expand_expr (result, target, mode, EXPAND_NORMAL);
3356     }
3357
3358   /* If c_strlen can determine an expression for one of the string
3359      lengths, and it doesn't have side effects, then emit cmpstrsi
3360      using length MIN(strlen(string)+1, arg3).  */
3361 #ifdef HAVE_cmpstrsi
3362   if (HAVE_cmpstrsi)
3363   {
3364     tree len, len1, len2;
3365     rtx arg1_rtx, arg2_rtx, arg3_rtx;
3366     rtx result, insn;
3367
3368     int arg1_align
3369       = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3370     int arg2_align
3371       = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3372     enum machine_mode insn_mode
3373       = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
3374
3375     len1 = c_strlen (arg1, 1);
3376     len2 = c_strlen (arg2, 1);
3377
3378     if (len1)
3379       len1 = size_binop (PLUS_EXPR, ssize_int (1), len1);
3380     if (len2)
3381       len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
3382
3383     /* If we don't have a constant length for the first, use the length
3384        of the second, if we know it.  We don't require a constant for
3385        this case; some cost analysis could be done if both are available
3386        but neither is constant.  For now, assume they're equally cheap,
3387        unless one has side effects.  If both strings have constant lengths,
3388        use the smaller.  */
3389
3390     if (!len1)
3391       len = len2;
3392     else if (!len2)
3393       len = len1;
3394     else if (TREE_SIDE_EFFECTS (len1))
3395       len = len2;
3396     else if (TREE_SIDE_EFFECTS (len2))
3397       len = len1;
3398     else if (TREE_CODE (len1) != INTEGER_CST)
3399       len = len2;
3400     else if (TREE_CODE (len2) != INTEGER_CST)
3401       len = len1;
3402     else if (tree_int_cst_lt (len1, len2))
3403       len = len1;
3404     else
3405       len = len2;
3406
3407     /* If both arguments have side effects, we cannot optimize.  */
3408     if (!len || TREE_SIDE_EFFECTS (len))
3409       return 0;
3410
3411     /* The actual new length parameter is MIN(len,arg3).  */
3412     len = fold (build (MIN_EXPR, TREE_TYPE (len), len, arg3));
3413
3414     /* If we don't have POINTER_TYPE, call the function.  */
3415     if (arg1_align == 0 || arg2_align == 0)
3416       return 0;
3417
3418     /* Make a place to write the result of the instruction.  */
3419     result = target;
3420     if (! (result != 0
3421            && GET_CODE (result) == REG && GET_MODE (result) == insn_mode
3422            && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3423       result = gen_reg_rtx (insn_mode);
3424
3425     arg1_rtx = get_memory_rtx (arg1);
3426     arg2_rtx = get_memory_rtx (arg2);
3427     arg3_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
3428     insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3429                          GEN_INT (MIN (arg1_align, arg2_align)));
3430     if (!insn)
3431       return 0;
3432
3433     emit_insn (insn);
3434
3435     /* Return the value in the proper mode for this function.  */
3436     mode = TYPE_MODE (TREE_TYPE (exp));
3437     if (GET_MODE (result) == mode)
3438       return result;
3439     if (target == 0)
3440       return convert_to_mode (mode, result, 0);
3441     convert_move (target, result, 0);
3442     return target;
3443   }
3444 #endif
3445   return 0;
3446 }
3447
3448 /* Expand expression EXP, which is a call to the strcat builtin.
3449    Return 0 if we failed the caller should emit a normal call,
3450    otherwise try to get the result in TARGET, if convenient.  */
3451
3452 static rtx
3453 expand_builtin_strcat (tree arglist, rtx target, enum machine_mode mode)
3454 {
3455   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3456     return 0;
3457   else
3458     {
3459       tree dst = TREE_VALUE (arglist),
3460         src = TREE_VALUE (TREE_CHAIN (arglist));
3461       const char *p = c_getstr (src);
3462
3463       if (p)
3464         {
3465           /* If the string length is zero, return the dst parameter.  */
3466           if (*p == '\0')
3467             return expand_expr (dst, target, mode, EXPAND_NORMAL);
3468           else if (!optimize_size)
3469             {
3470               /* Otherwise if !optimize_size, see if we can store by
3471                  pieces into (dst + strlen(dst)).  */
3472               tree newdst, arglist,
3473                 strlen_fn = implicit_built_in_decls[BUILT_IN_STRLEN];
3474               
3475               /* This is the length argument.  */
3476               arglist = build_tree_list (NULL_TREE,
3477                                          fold (size_binop (PLUS_EXPR,
3478                                                            c_strlen (src, 0),
3479                                                            ssize_int (1))));
3480               /* Prepend src argument.  */
3481               arglist = tree_cons (NULL_TREE, src, arglist);
3482               
3483               /* We're going to use dst more than once.  */
3484               dst = save_expr (dst);
3485
3486               /* Create strlen (dst).  */
3487               newdst =
3488                 fold (build_function_call_expr (strlen_fn,
3489                                                 build_tree_list (NULL_TREE,
3490                                                                  dst)));
3491               /* Create (dst + strlen (dst)).  */
3492               newdst = fold (build (PLUS_EXPR, TREE_TYPE (dst), dst, newdst));
3493
3494               /* Prepend the new dst argument.  */
3495               arglist = tree_cons (NULL_TREE, newdst, arglist);
3496               
3497               /* We don't want to get turned into a memcpy if the
3498                  target is const0_rtx, i.e. when the return value
3499                  isn't used.  That would produce pessimized code so
3500                  pass in a target of zero, it should never actually be
3501                  used.  If this was successful return the original
3502                  dst, not the result of mempcpy.  */
3503               if (expand_builtin_mempcpy (arglist, /*target=*/0, mode, /*endp=*/0))
3504                 return expand_expr (dst, target, mode, EXPAND_NORMAL);
3505               else
3506                 return 0;
3507             }
3508         }
3509
3510       return 0;
3511     }
3512 }
3513
3514 /* Expand expression EXP, which is a call to the strncat builtin.
3515    Return 0 if we failed the caller should emit a normal call,
3516    otherwise try to get the result in TARGET, if convenient.  */
3517
3518 static rtx
3519 expand_builtin_strncat (tree arglist, rtx target, enum machine_mode mode)
3520 {
3521   if (!validate_arglist (arglist,
3522                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3523     return 0;
3524   else
3525     {
3526       tree dst = TREE_VALUE (arglist),
3527         src = TREE_VALUE (TREE_CHAIN (arglist)),
3528         len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3529       const char *p = c_getstr (src);
3530
3531       /* If the requested length is zero, or the src parameter string
3532           length is zero, return the dst parameter.  */
3533       if (integer_zerop (len) || (p && *p == '\0'))
3534         {
3535           /* Evaluate and ignore the src and len parameters in case
3536              they have side-effects.  */
3537           expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
3538           expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
3539           return expand_expr (dst, target, mode, EXPAND_NORMAL);
3540         }
3541
3542       /* If the requested len is greater than or equal to the string
3543          length, call strcat.  */
3544       if (TREE_CODE (len) == INTEGER_CST && p
3545           && compare_tree_int (len, strlen (p)) >= 0)
3546         {
3547           tree newarglist
3548             = tree_cons (NULL_TREE, dst, build_tree_list (NULL_TREE, src));
3549           tree fn = implicit_built_in_decls[BUILT_IN_STRCAT];
3550
3551           /* If the replacement _DECL isn't initialized, don't do the
3552              transformation.  */
3553           if (!fn)
3554             return 0;
3555
3556           return expand_expr (build_function_call_expr (fn, newarglist),
3557                               target, mode, EXPAND_NORMAL);
3558         }
3559       return 0;
3560     }
3561 }
3562
3563 /* Expand expression EXP, which is a call to the strspn builtin.
3564    Return 0 if we failed the caller should emit a normal call,
3565    otherwise try to get the result in TARGET, if convenient.  */
3566
3567 static rtx
3568 expand_builtin_strspn (tree arglist, rtx target, enum machine_mode mode)
3569 {
3570   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3571     return 0;
3572   else
3573     {
3574       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
3575       const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
3576
3577       /* If both arguments are constants, evaluate at compile-time.  */
3578       if (p1 && p2)
3579         {
3580           const size_t r = strspn (p1, p2);
3581           return expand_expr (size_int (r), target, mode, EXPAND_NORMAL);
3582         }
3583
3584       /* If either argument is "", return 0.  */
3585       if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
3586         {
3587           /* Evaluate and ignore both arguments in case either one has
3588              side-effects.  */
3589           expand_expr (s1, const0_rtx, VOIDmode, EXPAND_NORMAL);
3590           expand_expr (s2, const0_rtx, VOIDmode, EXPAND_NORMAL);
3591           return const0_rtx;
3592         }
3593       return 0;
3594     }
3595 }
3596
3597 /* Expand expression EXP, which is a call to the strcspn builtin.
3598    Return 0 if we failed the caller should emit a normal call,
3599    otherwise try to get the result in TARGET, if convenient.  */
3600
3601 static rtx
3602 expand_builtin_strcspn (tree arglist, rtx target, enum machine_mode mode)
3603 {
3604   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3605     return 0;
3606   else
3607     {
3608       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
3609       const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
3610
3611       /* If both arguments are constants, evaluate at compile-time.  */
3612       if (p1 && p2)
3613         {
3614           const size_t r = strcspn (p1, p2);
3615           return expand_expr (size_int (r), target, mode, EXPAND_NORMAL);
3616         }
3617
3618       /* If the first argument is "", return 0.  */
3619       if (p1 && *p1 == '\0')
3620         {
3621           /* Evaluate and ignore argument s2 in case it has
3622              side-effects.  */
3623           expand_expr (s2, const0_rtx, VOIDmode, EXPAND_NORMAL);
3624           return const0_rtx;
3625         }
3626
3627       /* If the second argument is "", return __builtin_strlen(s1).  */
3628       if (p2 && *p2 == '\0')
3629         {
3630           tree newarglist = build_tree_list (NULL_TREE, s1),
3631             fn = implicit_built_in_decls[BUILT_IN_STRLEN];
3632
3633           /* If the replacement _DECL isn't initialized, don't do the
3634              transformation.  */
3635           if (!fn)
3636             return 0;
3637
3638           return expand_expr (build_function_call_expr (fn, newarglist),
3639                               target, mode, EXPAND_NORMAL);
3640         }
3641       return 0;
3642     }
3643 }
3644
3645 /* Expand a call to __builtin_saveregs, generating the result in TARGET,
3646    if that's convenient.  */
3647
3648 rtx
3649 expand_builtin_saveregs (void)
3650 {
3651   rtx val, seq;
3652
3653   /* Don't do __builtin_saveregs more than once in a function.
3654      Save the result of the first call and reuse it.  */
3655   if (saveregs_value != 0)
3656     return saveregs_value;
3657
3658   /* When this function is called, it means that registers must be
3659      saved on entry to this function.  So we migrate the call to the
3660      first insn of this function.  */
3661
3662   start_sequence ();
3663
3664 #ifdef EXPAND_BUILTIN_SAVEREGS
3665   /* Do whatever the machine needs done in this case.  */
3666   val = EXPAND_BUILTIN_SAVEREGS ();
3667 #else
3668   /* ??? We used to try and build up a call to the out of line function,
3669      guessing about what registers needed saving etc.  This became much
3670      harder with __builtin_va_start, since we don't have a tree for a
3671      call to __builtin_saveregs to fall back on.  There was exactly one
3672      port (i860) that used this code, and I'm unconvinced it could actually
3673      handle the general case.  So we no longer try to handle anything
3674      weird and make the backend absorb the evil.  */
3675
3676   error ("__builtin_saveregs not supported by this target");
3677   val = const0_rtx;
3678 #endif
3679
3680   seq = get_insns ();
3681   end_sequence ();
3682
3683   saveregs_value = val;
3684
3685   /* Put the insns after the NOTE that starts the function.  If this
3686      is inside a start_sequence, make the outer-level insn chain current, so
3687      the code is placed at the start of the function.  */
3688   push_topmost_sequence ();
3689   emit_insn_after (seq, get_insns ());
3690   pop_topmost_sequence ();
3691
3692   return val;
3693 }
3694
3695 /* __builtin_args_info (N) returns word N of the arg space info
3696    for the current function.  The number and meanings of words
3697    is controlled by the definition of CUMULATIVE_ARGS.  */
3698
3699 static rtx
3700 expand_builtin_args_info (tree arglist)
3701 {
3702   int nwords = sizeof (CUMULATIVE_ARGS) / sizeof (int);
3703   int *word_ptr = (int *) &current_function_args_info;
3704
3705   if (sizeof (CUMULATIVE_ARGS) % sizeof (int) != 0)
3706     abort ();
3707
3708   if (arglist != 0)
3709     {
3710       if (!host_integerp (TREE_VALUE (arglist), 0))
3711         error ("argument of `__builtin_args_info' must be constant");
3712       else
3713         {
3714           HOST_WIDE_INT wordnum = tree_low_cst (TREE_VALUE (arglist), 0);
3715
3716           if (wordnum < 0 || wordnum >= nwords)
3717             error ("argument of `__builtin_args_info' out of range");
3718           else
3719             return GEN_INT (word_ptr[wordnum]);
3720         }
3721     }
3722   else
3723     error ("missing argument in `__builtin_args_info'");
3724
3725   return const0_rtx;
3726 }
3727
3728 /* Expand ARGLIST, from a call to __builtin_next_arg.  */
3729
3730 static rtx
3731 expand_builtin_next_arg (tree arglist)
3732 {
3733   tree fntype = TREE_TYPE (current_function_decl);
3734
3735   if (TYPE_ARG_TYPES (fntype) == 0
3736       || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
3737           == void_type_node))
3738     {
3739       error ("`va_start' used in function with fixed args");
3740       return const0_rtx;
3741     }
3742
3743   if (arglist)
3744     {
3745       tree last_parm = tree_last (DECL_ARGUMENTS (current_function_decl));
3746       tree arg = TREE_VALUE (arglist);
3747
3748       /* Strip off all nops for the sake of the comparison.  This
3749          is not quite the same as STRIP_NOPS.  It does more.
3750          We must also strip off INDIRECT_EXPR for C++ reference
3751          parameters.  */
3752       while (TREE_CODE (arg) == NOP_EXPR
3753              || TREE_CODE (arg) == CONVERT_EXPR
3754              || TREE_CODE (arg) == NON_LVALUE_EXPR
3755              || TREE_CODE (arg) == INDIRECT_REF)
3756         arg = TREE_OPERAND (arg, 0);
3757       if (arg != last_parm)
3758         warning ("second parameter of `va_start' not last named argument");
3759     }
3760   else
3761     /* Evidently an out of date version of <stdarg.h>; can't validate
3762        va_start's second argument, but can still work as intended.  */
3763     warning ("`__builtin_next_arg' called without an argument");
3764
3765   return expand_binop (Pmode, add_optab,
3766                        current_function_internal_arg_pointer,
3767                        current_function_arg_offset_rtx,
3768                        NULL_RTX, 0, OPTAB_LIB_WIDEN);
3769 }
3770
3771 /* Make it easier for the backends by protecting the valist argument
3772    from multiple evaluations.  */
3773
3774 static tree
3775 stabilize_va_list (tree valist, int needs_lvalue)
3776 {
3777   if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
3778     {
3779       if (TREE_SIDE_EFFECTS (valist))
3780         valist = save_expr (valist);
3781
3782       /* For this case, the backends will be expecting a pointer to
3783          TREE_TYPE (va_list_type_node), but it's possible we've
3784          actually been given an array (an actual va_list_type_node).
3785          So fix it.  */
3786       if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
3787         {
3788           tree p1 = build_pointer_type (TREE_TYPE (va_list_type_node));
3789           tree p2 = build_pointer_type (va_list_type_node);
3790
3791           valist = build1 (ADDR_EXPR, p2, valist);
3792           valist = fold (build1 (NOP_EXPR, p1, valist));
3793         }
3794     }
3795   else
3796     {
3797       tree pt;
3798
3799       if (! needs_lvalue)
3800         {
3801           if (! TREE_SIDE_EFFECTS (valist))
3802             return valist;
3803
3804           pt = build_pointer_type (va_list_type_node);
3805           valist = fold (build1 (ADDR_EXPR, pt, valist));
3806           TREE_SIDE_EFFECTS (valist) = 1;
3807         }
3808
3809       if (TREE_SIDE_EFFECTS (valist))
3810         valist = save_expr (valist);
3811       valist = fold (build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (valist)),
3812                              valist));
3813     }
3814
3815   return valist;
3816 }
3817
3818 /* The "standard" implementation of va_start: just assign `nextarg' to
3819    the variable.  */
3820
3821 void
3822 std_expand_builtin_va_start (tree valist, rtx nextarg)
3823 {
3824   tree t;
3825
3826   t = build (MODIFY_EXPR, TREE_TYPE (valist), valist,
3827              make_tree (ptr_type_node, nextarg));
3828   TREE_SIDE_EFFECTS (t) = 1;
3829
3830   expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
3831 }
3832
3833 /* Expand ARGLIST, from a call to __builtin_va_start.  */
3834
3835 static rtx
3836 expand_builtin_va_start (tree arglist)
3837 {
3838   rtx nextarg;
3839   tree chain, valist;
3840
3841   chain = TREE_CHAIN (arglist);
3842
3843   if (TREE_CHAIN (chain))
3844     error ("too many arguments to function `va_start'");
3845
3846   nextarg = expand_builtin_next_arg (chain);
3847   valist = stabilize_va_list (TREE_VALUE (arglist), 1);
3848
3849 #ifdef EXPAND_BUILTIN_VA_START
3850   EXPAND_BUILTIN_VA_START (valist, nextarg);
3851 #else
3852   std_expand_builtin_va_start (valist, nextarg);
3853 #endif
3854
3855   return const0_rtx;
3856 }
3857
3858 /* The "standard" implementation of va_arg: read the value from the
3859    current (padded) address and increment by the (padded) size.  */
3860
3861 rtx
3862 std_expand_builtin_va_arg (tree valist, tree type)
3863 {
3864   tree addr_tree, t, type_size = NULL;
3865   tree align, alignm1;
3866   tree rounded_size;
3867   rtx addr;
3868
3869   /* Compute the rounded size of the type.  */
3870   align = size_int (PARM_BOUNDARY / BITS_PER_UNIT);
3871   alignm1 = size_int (PARM_BOUNDARY / BITS_PER_UNIT - 1);
3872   if (type == error_mark_node
3873       || (type_size = TYPE_SIZE_UNIT (TYPE_MAIN_VARIANT (type))) == NULL
3874       || TREE_OVERFLOW (type_size))
3875     rounded_size = size_zero_node;
3876   else
3877     rounded_size = fold (build (MULT_EXPR, sizetype,
3878                                 fold (build (TRUNC_DIV_EXPR, sizetype,
3879                                              fold (build (PLUS_EXPR, sizetype,
3880                                                           type_size, alignm1)),
3881                                              align)),
3882                                 align));
3883
3884   /* Get AP.  */
3885   addr_tree = valist;
3886   if (PAD_VARARGS_DOWN && ! integer_zerop (rounded_size))
3887     {
3888       /* Small args are padded downward.  */
3889       addr_tree = fold (build (PLUS_EXPR, TREE_TYPE (addr_tree), addr_tree,
3890                                fold (build (COND_EXPR, sizetype,
3891                                             fold (build (GT_EXPR, sizetype,
3892                                                          rounded_size,
3893                                                          align)),
3894                                             size_zero_node,
3895                                             fold (build (MINUS_EXPR, sizetype,
3896                                                          rounded_size,
3897                                                          type_size))))));
3898     }
3899
3900   addr = expand_expr (addr_tree, NULL_RTX, Pmode, EXPAND_NORMAL);
3901   addr = copy_to_reg (addr);
3902
3903   /* Compute new value for AP.  */
3904   if (! integer_zerop (rounded_size))
3905     {
3906       t = build (MODIFY_EXPR, TREE_TYPE (valist), valist,
3907                  build (PLUS_EXPR, TREE_TYPE (valist), valist,
3908                         rounded_size));
3909       TREE_SIDE_EFFECTS (t) = 1;
3910       expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
3911     }
3912
3913   return addr;
3914 }
3915
3916 /* Expand __builtin_va_arg, which is not really a builtin function, but
3917    a very special sort of operator.  */
3918
3919 rtx
3920 expand_builtin_va_arg (tree valist, tree type)
3921 {
3922   rtx addr, result;
3923   tree promoted_type, want_va_type, have_va_type;
3924
3925   /* Verify that valist is of the proper type.  */
3926
3927   want_va_type = va_list_type_node;
3928   have_va_type = TREE_TYPE (valist);
3929   if (TREE_CODE (want_va_type) == ARRAY_TYPE)
3930     {
3931       /* If va_list is an array type, the argument may have decayed
3932          to a pointer type, e.g. by being passed to another function.
3933          In that case, unwrap both types so that we can compare the
3934          underlying records.  */
3935       if (TREE_CODE (have_va_type) == ARRAY_TYPE
3936           || TREE_CODE (have_va_type) == POINTER_TYPE)
3937         {
3938           want_va_type = TREE_TYPE (want_va_type);
3939           have_va_type = TREE_TYPE (have_va_type);
3940         }
3941     }
3942   if (TYPE_MAIN_VARIANT (want_va_type) != TYPE_MAIN_VARIANT (have_va_type))
3943     {
3944       error ("first argument to `va_arg' not of type `va_list'");
3945       addr = const0_rtx;
3946     }
3947
3948   /* Generate a diagnostic for requesting data of a type that cannot
3949      be passed through `...' due to type promotion at the call site.  */
3950   else if ((promoted_type = (*lang_hooks.types.type_promotes_to) (type))
3951            != type)
3952     {
3953       const char *name = "<anonymous type>", *pname = 0;
3954       static bool gave_help;
3955
3956       if (TYPE_NAME (type))
3957         {
3958           if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE)
3959             name = IDENTIFIER_POINTER (TYPE_NAME (type));
3960           else if (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
3961                    && DECL_NAME (TYPE_NAME (type)))
3962             name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type)));
3963         }
3964       if (TYPE_NAME (promoted_type))
3965         {
3966           if (TREE_CODE (TYPE_NAME (promoted_type)) == IDENTIFIER_NODE)
3967             pname = IDENTIFIER_POINTER (TYPE_NAME (promoted_type));
3968           else if (TREE_CODE (TYPE_NAME (promoted_type)) == TYPE_DECL
3969                    && DECL_NAME (TYPE_NAME (promoted_type)))
3970             pname = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (promoted_type)));
3971         }
3972
3973       /* Unfortunately, this is merely undefined, rather than a constraint
3974          violation, so we cannot make this an error.  If this call is never
3975          executed, the program is still strictly conforming.  */
3976       warning ("`%s' is promoted to `%s' when passed through `...'",
3977                name, pname);
3978       if (! gave_help)
3979         {
3980           gave_help = true;
3981           warning ("(so you should pass `%s' not `%s' to `va_arg')",
3982                    pname, name);
3983         }
3984
3985       /* We can, however, treat "undefined" any way we please.
3986          Call abort to encourage the user to fix the program.  */
3987       expand_builtin_trap ();
3988
3989       /* This is dead code, but go ahead and finish so that the
3990          mode of the result comes out right.  */
3991       addr = const0_rtx;
3992     }
3993   else
3994     {
3995       /* Make it easier for the backends by protecting the valist argument
3996          from multiple evaluations.  */
3997       valist = stabilize_va_list (valist, 0);
3998
3999 #ifdef EXPAND_BUILTIN_VA_ARG
4000       addr = EXPAND_BUILTIN_VA_ARG (valist, type);
4001 #else
4002       addr = std_expand_builtin_va_arg (valist, type);
4003 #endif
4004     }
4005
4006 #ifdef POINTERS_EXTEND_UNSIGNED
4007   if (GET_MODE (addr) != Pmode)
4008     addr = convert_memory_address (Pmode, addr);
4009 #endif
4010
4011   result = gen_rtx_MEM (TYPE_MODE (type), addr);
4012   set_mem_alias_set (result, get_varargs_alias_set ());
4013
4014   return result;
4015 }
4016
4017 /* Expand ARGLIST, from a call to __builtin_va_end.  */
4018
4019 static rtx
4020 expand_builtin_va_end (tree arglist)
4021 {
4022   tree valist = TREE_VALUE (arglist);
4023
4024 #ifdef EXPAND_BUILTIN_VA_END
4025   valist = stabilize_va_list (valist, 0);
4026   EXPAND_BUILTIN_VA_END (arglist);
4027 #else
4028   /* Evaluate for side effects, if needed.  I hate macros that don't
4029      do that.  */
4030   if (TREE_SIDE_EFFECTS (valist))
4031     expand_expr (valist, const0_rtx, VOIDmode, EXPAND_NORMAL);
4032 #endif
4033
4034   return const0_rtx;
4035 }
4036
4037 /* Expand ARGLIST, from a call to __builtin_va_copy.  We do this as a
4038    builtin rather than just as an assignment in stdarg.h because of the
4039    nastiness of array-type va_list types.  */
4040
4041 static rtx
4042 expand_builtin_va_copy (tree arglist)
4043 {
4044   tree dst, src, t;
4045
4046   dst = TREE_VALUE (arglist);
4047   src = TREE_VALUE (TREE_CHAIN (arglist));
4048
4049   dst = stabilize_va_list (dst, 1);
4050   src = stabilize_va_list (src, 0);
4051
4052   if (TREE_CODE (va_list_type_node) != ARRAY_TYPE)
4053     {
4054       t = build (MODIFY_EXPR, va_list_type_node, dst, src);
4055       TREE_SIDE_EFFECTS (t) = 1;
4056       expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4057     }
4058   else
4059     {
4060       rtx dstb, srcb, size;
4061
4062       /* Evaluate to pointers.  */
4063       dstb = expand_expr (dst, NULL_RTX, Pmode, EXPAND_NORMAL);
4064       srcb = expand_expr (src, NULL_RTX, Pmode, EXPAND_NORMAL);
4065       size = expand_expr (TYPE_SIZE_UNIT (va_list_type_node), NULL_RTX,
4066                           VOIDmode, EXPAND_NORMAL);
4067
4068 #ifdef POINTERS_EXTEND_UNSIGNED
4069       if (GET_MODE (dstb) != Pmode)
4070         dstb = convert_memory_address (Pmode, dstb);
4071
4072       if (GET_MODE (srcb) != Pmode)
4073         srcb = convert_memory_address (Pmode, srcb);
4074 #endif
4075
4076       /* "Dereference" to BLKmode memories.  */
4077       dstb = gen_rtx_MEM (BLKmode, dstb);
4078       set_mem_alias_set (dstb, get_alias_set (TREE_TYPE (TREE_TYPE (dst))));
4079       set_mem_align (dstb, TYPE_ALIGN (va_list_type_node));
4080       srcb = gen_rtx_MEM (BLKmode, srcb);
4081       set_mem_alias_set (srcb, get_alias_set (TREE_TYPE (TREE_TYPE (src))));
4082       set_mem_align (srcb, TYPE_ALIGN (va_list_type_node));
4083
4084       /* Copy.  */
4085       emit_block_move (dstb, srcb, size, BLOCK_OP_NORMAL);
4086     }
4087
4088   return const0_rtx;
4089 }
4090
4091 /* Expand a call to one of the builtin functions __builtin_frame_address or
4092    __builtin_return_address.  */
4093
4094 static rtx
4095 expand_builtin_frame_address (tree fndecl, tree arglist)
4096 {
4097   /* The argument must be a nonnegative integer constant.
4098      It counts the number of frames to scan up the stack.
4099      The value is the return address saved in that frame.  */
4100   if (arglist == 0)
4101     /* Warning about missing arg was already issued.  */
4102     return const0_rtx;
4103   else if (! host_integerp (TREE_VALUE (arglist), 1))
4104     {
4105       if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4106         error ("invalid arg to `__builtin_frame_address'");
4107       else
4108         error ("invalid arg to `__builtin_return_address'");
4109       return const0_rtx;
4110     }
4111   else
4112     {
4113       rtx tem
4114         = expand_builtin_return_addr (DECL_FUNCTION_CODE (fndecl),
4115                                       tree_low_cst (TREE_VALUE (arglist), 1),
4116                                       hard_frame_pointer_rtx);
4117
4118       /* Some ports cannot access arbitrary stack frames.  */
4119       if (tem == NULL)
4120         {
4121           if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4122             warning ("unsupported arg to `__builtin_frame_address'");
4123           else
4124             warning ("unsupported arg to `__builtin_return_address'");
4125           return const0_rtx;
4126         }
4127
4128       /* For __builtin_frame_address, return what we've got.  */
4129       if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4130         return tem;
4131
4132       if (GET_CODE (tem) != REG
4133           && ! CONSTANT_P (tem))
4134         tem = copy_to_mode_reg (Pmode, tem);
4135       return tem;
4136     }
4137 }
4138
4139 /* Expand a call to the alloca builtin, with arguments ARGLIST.  Return 0 if
4140    we failed and the caller should emit a normal call, otherwise try to get
4141    the result in TARGET, if convenient.  */
4142
4143 static rtx
4144 expand_builtin_alloca (tree arglist, rtx target)
4145 {
4146   rtx op0;
4147   rtx result;
4148
4149   if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
4150     return 0;
4151
4152   /* Compute the argument.  */
4153   op0 = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
4154
4155   /* Allocate the desired space.  */
4156   result = allocate_dynamic_stack_space (op0, target, BITS_PER_UNIT);
4157
4158 #ifdef POINTERS_EXTEND_UNSIGNED
4159   if (GET_MODE (result) != ptr_mode)
4160     result = convert_memory_address (ptr_mode, result);
4161 #endif
4162
4163   return result;
4164 }
4165
4166 /* Expand a call to a unary builtin.  The arguments are in ARGLIST.
4167    Return 0 if a normal call should be emitted rather than expanding the
4168    function in-line.  If convenient, the result should be placed in TARGET.
4169    SUBTARGET may be used as the target for computing one of EXP's operands.  */
4170
4171 static rtx
4172 expand_builtin_unop (enum machine_mode target_mode, tree arglist, rtx target,
4173                      rtx subtarget, optab op_optab)
4174 {
4175   rtx op0;
4176   if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
4177     return 0;
4178
4179   /* Compute the argument.  */
4180   op0 = expand_expr (TREE_VALUE (arglist), subtarget, VOIDmode, 0);
4181   /* Compute op, into TARGET if possible.
4182      Set TARGET to wherever the result comes back.  */
4183   target = expand_unop (TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist))),
4184                         op_optab, op0, target, 1);
4185   if (target == 0)
4186     abort ();
4187
4188   return convert_to_mode (target_mode, target, 0);
4189 }
4190
4191 /* If the string passed to fputs is a constant and is one character
4192    long, we attempt to transform this call into __builtin_fputc().  */
4193
4194 static rtx
4195 expand_builtin_fputs (tree arglist, rtx target, bool unlocked)
4196 {
4197   tree len, fn;
4198   tree fn_fputc = unlocked ? implicit_built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
4199     : implicit_built_in_decls[BUILT_IN_FPUTC];
4200   tree fn_fwrite = unlocked ? implicit_built_in_decls[BUILT_IN_FWRITE_UNLOCKED]
4201     : implicit_built_in_decls[BUILT_IN_FWRITE];
4202
4203   /* If the return value is used, or the replacement _DECL isn't
4204      initialized, don't do the transformation.  */
4205   if (target != const0_rtx || !fn_fputc || !fn_fwrite)
4206     return 0;
4207
4208   /* Verify the arguments in the original call.  */
4209   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4210     return 0;
4211
4212   /* Get the length of the string passed to fputs.  If the length
4213      can't be determined, punt.  */
4214   if (!(len = c_strlen (TREE_VALUE (arglist), 1))
4215       || TREE_CODE (len) != INTEGER_CST)
4216     return 0;
4217
4218   switch (compare_tree_int (len, 1))
4219     {
4220     case -1: /* length is 0, delete the call entirely .  */
4221       {
4222         /* Evaluate and ignore the argument in case it has
4223            side-effects.  */
4224         expand_expr (TREE_VALUE (TREE_CHAIN (arglist)), const0_rtx,
4225                      VOIDmode, EXPAND_NORMAL);
4226         return const0_rtx;
4227       }
4228     case 0: /* length is 1, call fputc.  */
4229       {
4230         const char *p = c_getstr (TREE_VALUE (arglist));
4231
4232         if (p != NULL)
4233           {
4234             /* New argument list transforming fputs(string, stream) to
4235                fputc(string[0], stream).  */
4236             arglist =
4237               build_tree_list (NULL_TREE, TREE_VALUE (TREE_CHAIN (arglist)));
4238             arglist =
4239               tree_cons (NULL_TREE, build_int_2 (p[0], 0), arglist);
4240             fn = fn_fputc;
4241             break;
4242           }
4243       }
4244       /* FALLTHROUGH */
4245     case 1: /* length is greater than 1, call fwrite.  */
4246       {
4247         tree string_arg;
4248
4249         /* If optimizing for size keep fputs.  */
4250         if (optimize_size)
4251           return 0;
4252         string_arg = TREE_VALUE (arglist);
4253         /* New argument list transforming fputs(string, stream) to
4254            fwrite(string, 1, len, stream).  */
4255         arglist = build_tree_list (NULL_TREE, TREE_VALUE (TREE_CHAIN (arglist)));
4256         arglist = tree_cons (NULL_TREE, len, arglist);
4257         arglist = tree_cons (NULL_TREE, size_one_node, arglist);
4258         arglist = tree_cons (NULL_TREE, string_arg, arglist);
4259         fn = fn_fwrite;
4260         break;
4261       }
4262     default:
4263       abort ();
4264     }
4265
4266   return expand_expr (build_function_call_expr (fn, arglist),
4267                       const0_rtx, VOIDmode, EXPAND_NORMAL);
4268 }
4269
4270 /* Expand a call to __builtin_expect.  We return our argument and emit a
4271    NOTE_INSN_EXPECTED_VALUE note.  This is the expansion of __builtin_expect in
4272    a non-jump context.  */
4273
4274 static rtx
4275 expand_builtin_expect (tree arglist, rtx target)
4276 {
4277   tree exp, c;
4278   rtx note, rtx_c;
4279
4280   if (arglist == NULL_TREE
4281       || TREE_CHAIN (arglist) == NULL_TREE)
4282     return const0_rtx;
4283   exp = TREE_VALUE (arglist);
4284   c = TREE_VALUE (TREE_CHAIN (arglist));
4285
4286   if (TREE_CODE (c) != INTEGER_CST)
4287     {
4288       error ("second arg to `__builtin_expect' must be a constant");
4289       c = integer_zero_node;
4290     }
4291
4292   target = expand_expr (exp, target, VOIDmode, EXPAND_NORMAL);
4293
4294   /* Don't bother with expected value notes for integral constants.  */
4295   if (flag_guess_branch_prob && GET_CODE (target) != CONST_INT)
4296     {
4297       /* We do need to force this into a register so that we can be
4298          moderately sure to be able to correctly interpret the branch
4299          condition later.  */
4300       target = force_reg (GET_MODE (target), target);
4301
4302       rtx_c = expand_expr (c, NULL_RTX, GET_MODE (target), EXPAND_NORMAL);
4303
4304       note = emit_note (NOTE_INSN_EXPECTED_VALUE);
4305       NOTE_EXPECTED_VALUE (note) = gen_rtx_EQ (VOIDmode, target, rtx_c);
4306     }
4307
4308   return target;
4309 }
4310
4311 /* Like expand_builtin_expect, except do this in a jump context.  This is
4312    called from do_jump if the conditional is a __builtin_expect.  Return either
4313    a list of insns to emit the jump or NULL if we cannot optimize
4314    __builtin_expect.  We need to optimize this at jump time so that machines
4315    like the PowerPC don't turn the test into a SCC operation, and then jump
4316    based on the test being 0/1.  */
4317
4318 rtx
4319 expand_builtin_expect_jump (tree exp, rtx if_false_label, rtx if_true_label)
4320 {
4321   tree arglist = TREE_OPERAND (exp, 1);
4322   tree arg0 = TREE_VALUE (arglist);
4323   tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
4324   rtx ret = NULL_RTX;
4325
4326   /* Only handle __builtin_expect (test, 0) and
4327      __builtin_expect (test, 1).  */
4328   if (TREE_CODE (TREE_TYPE (arg1)) == INTEGER_TYPE
4329       && (integer_zerop (arg1) || integer_onep (arg1)))
4330     {
4331       int num_jumps = 0;
4332       rtx insn;
4333
4334       /* If we fail to locate an appropriate conditional jump, we'll
4335          fall back to normal evaluation.  Ensure that the expression
4336          can be re-evaluated.  */
4337       switch (unsafe_for_reeval (arg0))
4338         {
4339         case 0: /* Safe.  */
4340           break;
4341
4342         case 1: /* Mildly unsafe.  */
4343           arg0 = unsave_expr (arg0);
4344           break;
4345
4346         case 2: /* Wildly unsafe.  */
4347           return NULL_RTX;
4348         }
4349
4350       /* Expand the jump insns.  */
4351       start_sequence ();
4352       do_jump (arg0, if_false_label, if_true_label);
4353       ret = get_insns ();
4354       end_sequence ();
4355
4356       /* Now that the __builtin_expect has been validated, go through and add
4357          the expect's to each of the conditional jumps.  If we run into an
4358          error, just give up and generate the 'safe' code of doing a SCC
4359          operation and then doing a branch on that.  */
4360       insn = ret;
4361       while (insn != NULL_RTX)
4362         {
4363           rtx next = NEXT_INSN (insn);
4364
4365           if (GET_CODE (insn) == JUMP_INSN && any_condjump_p (insn))
4366             {
4367               rtx ifelse = SET_SRC (pc_set (insn));
4368               rtx label;
4369               int taken;
4370
4371               if (GET_CODE (XEXP (ifelse, 1)) == LABEL_REF)
4372                 {
4373                   taken = 1;
4374                   label = XEXP (XEXP (ifelse, 1), 0);
4375                 }
4376               /* An inverted jump reverses the probabilities.  */
4377               else if (GET_CODE (XEXP (ifelse, 2)) == LABEL_REF)
4378                 {
4379                   taken = 0;
4380                   label = XEXP (XEXP (ifelse, 2), 0);
4381                 }
4382               /* We shouldn't have to worry about conditional returns during
4383                  the expansion stage, but handle it gracefully anyway.  */
4384               else if (GET_CODE (XEXP (ifelse, 1)) == RETURN)
4385                 {
4386                   taken = 1;
4387                   label = NULL_RTX;
4388                 }
4389               /* An inverted return reverses the probabilities.  */
4390               else if (GET_CODE (XEXP (ifelse, 2)) == RETURN)
4391                 {
4392                   taken = 0;
4393                   label = NULL_RTX;
4394                 }
4395               else
4396                 goto do_next_insn;
4397
4398               /* If the test is expected to fail, reverse the
4399                  probabilities.  */
4400               if (integer_zerop (arg1))
4401                 taken = 1 - taken;
4402
4403               /* If we are jumping to the false label, reverse the
4404                  probabilities.  */
4405               if (label == NULL_RTX)
4406                 ;               /* conditional return */
4407               else if (label == if_false_label)
4408                 taken = 1 - taken;
4409               else if (label != if_true_label)
4410                 goto do_next_insn;
4411
4412               num_jumps++;
4413               predict_insn_def (insn, PRED_BUILTIN_EXPECT, taken);
4414             }
4415
4416         do_next_insn:
4417           insn = next;
4418         }
4419
4420       /* If no jumps were modified, fail and do __builtin_expect the normal
4421          way.  */
4422       if (num_jumps == 0)
4423         ret = NULL_RTX;
4424     }
4425
4426   return ret;
4427 }
4428
4429 void
4430 expand_builtin_trap (void)
4431 {
4432 #ifdef HAVE_trap
4433   if (HAVE_trap)
4434     emit_insn (gen_trap ());
4435   else
4436 #endif
4437     emit_library_call (abort_libfunc, LCT_NORETURN, VOIDmode, 0);
4438   emit_barrier ();
4439 }
4440
4441 /* Expand a call to fabs, fabsf or fabsl with arguments ARGLIST.
4442    Return 0 if a normal call should be emitted rather than expanding
4443    the function inline.  If convenient, the result should be placed
4444    in TARGET.  SUBTARGET may be used as the target for computing
4445    the operand.  */
4446
4447 static rtx
4448 expand_builtin_fabs (tree arglist, rtx target, rtx subtarget)
4449 {
4450   enum machine_mode mode;
4451   tree arg;
4452   rtx op0;
4453
4454   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
4455     return 0;
4456
4457   arg = TREE_VALUE (arglist);
4458   mode = TYPE_MODE (TREE_TYPE (arg));
4459   op0 = expand_expr (arg, subtarget, VOIDmode, 0);
4460   return expand_abs (mode, op0, target, 0, safe_from_p (target, arg, 1));
4461 }
4462
4463 /* Expand a call to cabs, cabsf or cabsl with arguments ARGLIST.
4464    Return 0 if a normal call should be emitted rather than expanding
4465    the function inline.  If convenient, the result should be placed
4466    in target.  */
4467
4468 static rtx
4469 expand_builtin_cabs (tree arglist, rtx target)
4470 {
4471   enum machine_mode mode;
4472   tree arg;
4473   rtx op0;
4474
4475   if (arglist == 0 || TREE_CHAIN (arglist))
4476     return 0;
4477   arg = TREE_VALUE (arglist);
4478   if (TREE_CODE (TREE_TYPE (arg)) != COMPLEX_TYPE
4479       || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) != REAL_TYPE)
4480     return 0;
4481
4482   mode = TYPE_MODE (TREE_TYPE (arg));
4483   op0 = expand_expr (arg, NULL_RTX, VOIDmode, 0);
4484   return expand_complex_abs (mode, op0, target, 0);
4485 }
4486
4487 /* Create a new constant string literal and return a char* pointer to it.
4488    The STRING_CST value is the LEN characters at STR.  */
4489 static tree
4490 build_string_literal (int len, const char *str)
4491 {
4492   tree t, elem, index, type;
4493
4494   t = build_string (len, str);
4495   elem = build_type_variant (char_type_node, 1, 0);
4496   index = build_index_type (build_int_2 (len - 1, 0));
4497   type = build_array_type (elem, index);
4498   TREE_TYPE (t) = type;
4499   TREE_CONSTANT (t) = 1;
4500   TREE_READONLY (t) = 1;
4501   TREE_STATIC (t) = 1;
4502
4503   type = build_pointer_type (type);
4504   t = build1 (ADDR_EXPR, type, t);
4505
4506   type = build_pointer_type (elem);
4507   t = build1 (NOP_EXPR, type, t);
4508   return t;
4509 }
4510
4511 /* Expand a call to printf or printf_unlocked with argument list ARGLIST.
4512    Return 0 if a normal call should be emitted rather than transforming
4513    the function inline.  If convenient, the result should be placed in
4514    TARGET with mode MODE.  UNLOCKED indicates this is a printf_unlocked 
4515    call.  */
4516 static rtx
4517 expand_builtin_printf (tree arglist, rtx target, enum machine_mode mode,
4518                        bool unlocked)
4519 {
4520   tree fn_putchar = unlocked
4521                     ? implicit_built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED]
4522                     : implicit_built_in_decls[BUILT_IN_PUTCHAR];
4523   tree fn_puts = unlocked ? implicit_built_in_decls[BUILT_IN_PUTS_UNLOCKED]
4524                           : implicit_built_in_decls[BUILT_IN_PUTS];
4525   const char *fmt_str;
4526   tree fn, fmt, arg;
4527
4528   /* If the return value is used, don't do the transformation.  */
4529   if (target != const0_rtx)
4530     return 0;
4531
4532   /* Verify the required arguments in the original call.  */
4533   if (! arglist)
4534     return 0;
4535   fmt = TREE_VALUE (arglist);
4536   if (TREE_CODE (TREE_TYPE (fmt)) != POINTER_TYPE)
4537     return 0;
4538   arglist = TREE_CHAIN (arglist);
4539
4540   /* Check whether the format is a literal string constant.  */
4541   fmt_str = c_getstr (fmt);
4542   if (fmt_str == NULL)
4543     return 0;
4544
4545   /* If the format specifier was "%s\n", call __builtin_puts(arg).  */
4546   if (strcmp (fmt_str, "%s\n") == 0)
4547     {
4548       if (! arglist
4549           || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE
4550           || TREE_CHAIN (arglist))
4551         return 0;
4552       fn = fn_puts;
4553     }
4554   /* If the format specifier was "%c", call __builtin_putchar(arg).  */
4555   else if (strcmp (fmt_str, "%c") == 0)
4556     {
4557       if (! arglist
4558           || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
4559           || TREE_CHAIN (arglist))
4560         return 0;
4561       fn = fn_putchar;
4562     }
4563   else
4564     {
4565       /* We can't handle anything else with % args or %% ... yet.  */
4566       if (strchr (fmt_str, '%'))
4567         return 0;
4568
4569       if (arglist)
4570         return 0;
4571
4572       /* If the format specifier was "", printf does nothing.  */
4573       if (fmt_str[0] == '\0')
4574         return const0_rtx;
4575       /* If the format specifier has length of 1, call putchar.  */
4576       if (fmt_str[1] == '\0')
4577         {
4578           /* Given printf("c"), (where c is any one character,)
4579              convert "c"[0] to an int and pass that to the replacement
4580              function.  */
4581           arg = build_int_2 (fmt_str[0], 0);
4582           arglist = build_tree_list (NULL_TREE, arg);
4583           fn = fn_putchar;
4584         }
4585       else
4586         {
4587           /* If the format specifier was "string\n", call puts("string").  */
4588           size_t len = strlen (fmt_str);
4589           if (fmt_str[len - 1] == '\n')
4590             {
4591               /* Create a NUL-terminated string that's one char shorter
4592                  than the original, stripping off the trailing '\n'.  */
4593               char *newstr = (char *) alloca (len);
4594               memcpy (newstr, fmt_str, len - 1);
4595               newstr[len - 1] = 0;
4596
4597               arg = build_string_literal (len, newstr);
4598               arglist = build_tree_list (NULL_TREE, arg);
4599               fn = fn_puts;
4600             }
4601           else
4602             /* We'd like to arrange to call fputs(string,stdout) here,
4603                but we need stdout and don't have a way to get it yet.  */
4604             return 0;
4605         }
4606     }
4607
4608   if (!fn)
4609     return 0;
4610   return expand_expr (build_function_call_expr (fn, arglist),
4611                       target, mode, EXPAND_NORMAL);
4612 }
4613
4614 /* Expand a call to fprintf or fprintf_unlocked with argument list ARGLIST.
4615    Return 0 if a normal call should be emitted rather than transforming
4616    the function inline.  If convenient, the result should be placed in
4617    TARGET with mode MODE.  UNLOCKED indicates this is a fprintf_unlocked 
4618    call.  */
4619 static rtx
4620 expand_builtin_fprintf (tree arglist, rtx target, enum machine_mode mode,
4621                         bool unlocked)
4622 {
4623   tree fn_fputc = unlocked ? implicit_built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
4624                            : implicit_built_in_decls[BUILT_IN_FPUTC];
4625   tree fn_fputs = unlocked ? implicit_built_in_decls[BUILT_IN_FPUTS_UNLOCKED]
4626                            : implicit_built_in_decls[BUILT_IN_FPUTS];
4627   const char *fmt_str;
4628   tree fn, fmt, fp, arg;
4629
4630   /* If the return value is used, don't do the transformation.  */
4631   if (target != const0_rtx)
4632     return 0;
4633
4634   /* Verify the required arguments in the original call.  */
4635   if (! arglist)
4636     return 0;
4637   fp = TREE_VALUE (arglist);
4638   if (TREE_CODE (TREE_TYPE (fp)) != POINTER_TYPE)
4639     return 0;
4640   arglist = TREE_CHAIN (arglist);
4641   if (! arglist)
4642     return 0;
4643   fmt = TREE_VALUE (arglist);
4644   if (TREE_CODE (TREE_TYPE (fmt)) != POINTER_TYPE)
4645     return 0;
4646   arglist = TREE_CHAIN (arglist);
4647
4648   /* Check whether the format is a literal string constant.  */
4649   fmt_str = c_getstr (fmt);
4650   if (fmt_str == NULL)
4651     return 0;
4652
4653   /* If the format specifier was "%s", call __builtin_fputs(arg,fp).  */
4654   if (strcmp (fmt_str, "%s") == 0)
4655     {
4656       if (! arglist
4657           || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE
4658           || TREE_CHAIN (arglist))
4659         return 0;
4660       arg = TREE_VALUE (arglist);
4661       arglist = build_tree_list (NULL_TREE, fp);
4662       arglist = tree_cons (NULL_TREE, arg, arglist);
4663       fn = fn_fputs;
4664     }
4665   /* If the format specifier was "%c", call __builtin_fputc(arg,fp).  */
4666   else if (strcmp (fmt_str, "%c") == 0)
4667     {
4668       if (! arglist
4669           || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
4670           || TREE_CHAIN (arglist))
4671         return 0;
4672       arg = TREE_VALUE (arglist);
4673       arglist = build_tree_list (NULL_TREE, fp);
4674       arglist = tree_cons (NULL_TREE, arg, arglist);
4675       fn = fn_fputc;
4676     }
4677   else
4678     {
4679       /* We can't handle anything else with % args or %% ... yet.  */
4680       if (strchr (fmt_str, '%'))
4681         return 0;
4682
4683       if (arglist)
4684         return 0;
4685
4686       /* If the format specifier was "", fprintf does nothing.  */
4687       if (fmt_str[0] == '\0')
4688         {
4689           /* Evaluate and ignore FILE* argument for side-effects.  */
4690           expand_expr (fp, const0_rtx, VOIDmode, EXPAND_NORMAL);
4691           return const0_rtx;
4692         }
4693
4694       /* When "string" doesn't contain %, replace all cases of
4695          fprintf(stream,string) with fputs(string,stream).  The fputs
4696          builtin will take care of special cases like length == 1.  */
4697       arglist = build_tree_list (NULL_TREE, fp);
4698       arglist = tree_cons (NULL_TREE, fmt, arglist);
4699       fn = fn_fputs;
4700     }
4701
4702   if (!fn)
4703     return 0;
4704   return expand_expr (build_function_call_expr (fn, arglist),
4705                       target, mode, EXPAND_NORMAL);
4706 }
4707
4708 /* Expand a call to sprintf with argument list ARGLIST.  Return 0 if
4709    a normal call should be emitted rather than expanding the function
4710    inline.  If convenient, the result should be placed in TARGET with
4711    mode MODE.  */
4712
4713 static rtx
4714 expand_builtin_sprintf (tree arglist, rtx target, enum machine_mode mode)
4715 {
4716   tree orig_arglist, dest, fmt;
4717   const char *fmt_str;
4718
4719   orig_arglist = arglist;
4720
4721   /* Verify the required arguments in the original call.  */
4722   if (! arglist)
4723     return 0;
4724   dest = TREE_VALUE (arglist);
4725   if (TREE_CODE (TREE_TYPE (dest)) != POINTER_TYPE)
4726     return 0;
4727   arglist = TREE_CHAIN (arglist);
4728   if (! arglist)
4729     return 0;
4730   fmt = TREE_VALUE (arglist);
4731   if (TREE_CODE (TREE_TYPE (fmt)) != POINTER_TYPE)
4732     return 0;
4733   arglist = TREE_CHAIN (arglist);
4734
4735   /* Check whether the format is a literal string constant.  */
4736   fmt_str = c_getstr (fmt);
4737   if (fmt_str == NULL)
4738     return 0;
4739
4740   /* If the format doesn't contain % args or %%, use strcpy.  */
4741   if (strchr (fmt_str, '%') == 0)
4742     {
4743       tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
4744       tree exp;
4745
4746       if (arglist || ! fn)
4747         return 0;
4748       expand_expr (build_function_call_expr (fn, orig_arglist),
4749                    const0_rtx, VOIDmode, EXPAND_NORMAL);
4750       if (target == const0_rtx)
4751         return const0_rtx;
4752       exp = build_int_2 (strlen (fmt_str), 0);
4753       exp = fold (build1 (NOP_EXPR, integer_type_node, exp));
4754       return expand_expr (exp, target, mode, EXPAND_NORMAL);
4755     }
4756   /* If the format is "%s", use strcpy if the result isn't used.  */
4757   else if (strcmp (fmt_str, "%s") == 0)
4758     {
4759       tree fn, arg, len;
4760       fn = implicit_built_in_decls[BUILT_IN_STRCPY];
4761
4762       if (! fn)
4763         return 0;
4764
4765       if (! arglist || TREE_CHAIN (arglist))
4766         return 0;
4767       arg = TREE_VALUE (arglist);
4768       if (TREE_CODE (TREE_TYPE (arg)) != POINTER_TYPE)
4769         return 0;
4770
4771       if (target != const0_rtx)
4772         {
4773           len = c_strlen (arg, 1);
4774           if (! len || TREE_CODE (len) != INTEGER_CST)
4775             return 0;
4776         }
4777       else
4778         len = NULL_TREE;
4779
4780       arglist = build_tree_list (NULL_TREE, arg);
4781       arglist = tree_cons (NULL_TREE, dest, arglist);
4782       expand_expr (build_function_call_expr (fn, arglist),
4783                    const0_rtx, VOIDmode, EXPAND_NORMAL);
4784
4785       if (target == const0_rtx)
4786         return const0_rtx;
4787       return expand_expr (len, target, mode, EXPAND_NORMAL);
4788     }
4789
4790   return 0;
4791 }
4792 \f
4793 /* Expand an expression EXP that calls a built-in function,
4794    with result going to TARGET if that's convenient
4795    (and in mode MODE if that's convenient).
4796    SUBTARGET may be used as the target for computing one of EXP's operands.
4797    IGNORE is nonzero if the value is to be ignored.  */
4798
4799 rtx
4800 expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
4801                 int ignore)
4802 {
4803   tree fndecl = get_callee_fndecl (exp);
4804   tree arglist = TREE_OPERAND (exp, 1);
4805   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
4806   enum machine_mode target_mode = TYPE_MODE (TREE_TYPE (exp));
4807
4808   /* Perform postincrements before expanding builtin functions.  */
4809   emit_queue ();
4810
4811   if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
4812     return (*targetm.expand_builtin) (exp, target, subtarget, mode, ignore);
4813
4814   /* When not optimizing, generate calls to library functions for a certain
4815      set of builtins.  */
4816   if (!optimize
4817       && !CALLED_AS_BUILT_IN (fndecl)
4818       && DECL_ASSEMBLER_NAME_SET_P (fndecl)
4819       && fcode != BUILT_IN_ALLOCA)
4820     return expand_call (exp, target, ignore);
4821
4822   /* The built-in function expanders test for target == const0_rtx
4823      to determine whether the function's result will be ignored.  */
4824   if (ignore)
4825     target = const0_rtx;
4826
4827   /* If the result of a pure or const built-in function is ignored, and
4828      none of its arguments are volatile, we can avoid expanding the
4829      built-in call and just evaluate the arguments for side-effects.  */
4830   if (target == const0_rtx
4831       && (DECL_IS_PURE (fndecl) || TREE_READONLY (fndecl)))
4832     {
4833       bool volatilep = false;
4834       tree arg;
4835
4836       for (arg = arglist; arg; arg = TREE_CHAIN (arg))
4837         if (TREE_THIS_VOLATILE (TREE_VALUE (arg)))
4838           {
4839             volatilep = true;
4840             break;
4841           }
4842
4843       if (! volatilep)
4844         {
4845           for (arg = arglist; arg; arg = TREE_CHAIN (arg))
4846             expand_expr (TREE_VALUE (arg), const0_rtx,
4847                          VOIDmode, EXPAND_NORMAL);
4848           return const0_rtx;
4849         }
4850     }
4851
4852   switch (fcode)
4853     {
4854     case BUILT_IN_ABS:
4855     case BUILT_IN_LABS:
4856     case BUILT_IN_LLABS:
4857     case BUILT_IN_IMAXABS:
4858       /* build_function_call changes these into ABS_EXPR.  */
4859       abort ();
4860
4861     case BUILT_IN_FABS:
4862     case BUILT_IN_FABSF:
4863     case BUILT_IN_FABSL:
4864       target = expand_builtin_fabs (arglist, target, subtarget);
4865       if (target)
4866         return target;
4867       break;
4868
4869     case BUILT_IN_CABS:
4870     case BUILT_IN_CABSF:
4871     case BUILT_IN_CABSL:
4872       if (flag_unsafe_math_optimizations)
4873         {
4874           target = expand_builtin_cabs (arglist, target);
4875           if (target)
4876             return target;
4877         }
4878       break;
4879
4880     case BUILT_IN_CONJ:
4881     case BUILT_IN_CONJF:
4882     case BUILT_IN_CONJL:
4883     case BUILT_IN_CREAL:
4884     case BUILT_IN_CREALF:
4885     case BUILT_IN_CREALL:
4886     case BUILT_IN_CIMAG:
4887     case BUILT_IN_CIMAGF:
4888     case BUILT_IN_CIMAGL:
4889       /* expand_tree_builtin changes these into CONJ_EXPR, REALPART_EXPR
4890          and IMAGPART_EXPR.  */
4891       abort ();
4892
4893     case BUILT_IN_SIN:
4894     case BUILT_IN_SINF:
4895     case BUILT_IN_SINL:
4896     case BUILT_IN_COS:
4897     case BUILT_IN_COSF:
4898     case BUILT_IN_COSL:
4899     case BUILT_IN_EXP:
4900     case BUILT_IN_EXPF:
4901     case BUILT_IN_EXPL:
4902     case BUILT_IN_LOG:
4903     case BUILT_IN_LOGF:
4904     case BUILT_IN_LOGL:
4905     case BUILT_IN_TAN:
4906     case BUILT_IN_TANF:
4907     case BUILT_IN_TANL:
4908     case BUILT_IN_ATAN:
4909     case BUILT_IN_ATANF:
4910     case BUILT_IN_ATANL:
4911       /* Treat these like sqrt only if unsafe math optimizations are allowed,
4912          because of possible accuracy problems.  */
4913       if (! flag_unsafe_math_optimizations)
4914         break;
4915     case BUILT_IN_SQRT:
4916     case BUILT_IN_SQRTF:
4917     case BUILT_IN_SQRTL:
4918     case BUILT_IN_FLOOR:
4919     case BUILT_IN_FLOORF:
4920     case BUILT_IN_FLOORL:
4921     case BUILT_IN_CEIL:
4922     case BUILT_IN_CEILF:
4923     case BUILT_IN_CEILL:
4924     case BUILT_IN_TRUNC:
4925     case BUILT_IN_TRUNCF:
4926     case BUILT_IN_TRUNCL:
4927     case BUILT_IN_ROUND:
4928     case BUILT_IN_ROUNDF:
4929     case BUILT_IN_ROUNDL:
4930     case BUILT_IN_NEARBYINT:
4931     case BUILT_IN_NEARBYINTF:
4932     case BUILT_IN_NEARBYINTL:
4933       target = expand_builtin_mathfn (exp, target, subtarget);
4934       if (target)
4935         return target;
4936       break;
4937
4938     case BUILT_IN_POW:
4939     case BUILT_IN_POWF:
4940     case BUILT_IN_POWL:
4941       if (! flag_unsafe_math_optimizations)
4942         break;
4943       target = expand_builtin_pow (exp, target, subtarget);
4944       if (target)
4945         return target;
4946       break;
4947
4948     case BUILT_IN_ATAN2:
4949     case BUILT_IN_ATAN2F:
4950     case BUILT_IN_ATAN2L:
4951       if (! flag_unsafe_math_optimizations)
4952         break;
4953       target = expand_builtin_mathfn_2 (exp, target, subtarget);
4954       if (target)
4955         return target;
4956       break;
4957
4958     case BUILT_IN_APPLY_ARGS:
4959       return expand_builtin_apply_args ();
4960
4961       /* __builtin_apply (FUNCTION, ARGUMENTS, ARGSIZE) invokes
4962          FUNCTION with a copy of the parameters described by
4963          ARGUMENTS, and ARGSIZE.  It returns a block of memory
4964          allocated on the stack into which is stored all the registers
4965          that might possibly be used for returning the result of a
4966          function.  ARGUMENTS is the value returned by
4967          __builtin_apply_args.  ARGSIZE is the number of bytes of
4968          arguments that must be copied.  ??? How should this value be
4969          computed?  We'll also need a safe worst case value for varargs
4970          functions.  */
4971     case BUILT_IN_APPLY:
4972       if (!validate_arglist (arglist, POINTER_TYPE,
4973                              POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)
4974           && !validate_arglist (arglist, REFERENCE_TYPE,
4975                                 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
4976         return const0_rtx;
4977       else
4978         {
4979           int i;
4980           tree t;
4981           rtx ops[3];
4982
4983           for (t = arglist, i = 0; t; t = TREE_CHAIN (t), i++)
4984             ops[i] = expand_expr (TREE_VALUE (t), NULL_RTX, VOIDmode, 0);
4985
4986           return expand_builtin_apply (ops[0], ops[1], ops[2]);
4987         }
4988
4989       /* __builtin_return (RESULT) causes the function to return the
4990          value described by RESULT.  RESULT is address of the block of
4991          memory returned by __builtin_apply.  */
4992     case BUILT_IN_RETURN:
4993       if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
4994         expand_builtin_return (expand_expr (TREE_VALUE (arglist),
4995                                             NULL_RTX, VOIDmode, 0));
4996       return const0_rtx;
4997
4998     case BUILT_IN_SAVEREGS:
4999       return expand_builtin_saveregs ();
5000
5001     case BUILT_IN_ARGS_INFO:
5002       return expand_builtin_args_info (arglist);
5003
5004       /* Return the address of the first anonymous stack arg.  */
5005     case BUILT_IN_NEXT_ARG:
5006       return expand_builtin_next_arg (arglist);
5007
5008     case BUILT_IN_CLASSIFY_TYPE:
5009       return expand_builtin_classify_type (arglist);
5010
5011     case BUILT_IN_CONSTANT_P:
5012       return expand_builtin_constant_p (arglist, target_mode);
5013
5014     case BUILT_IN_FRAME_ADDRESS:
5015     case BUILT_IN_RETURN_ADDRESS:
5016       return expand_builtin_frame_address (fndecl, arglist);
5017
5018     /* Returns the address of the area where the structure is returned.
5019        0 otherwise.  */
5020     case BUILT_IN_AGGREGATE_INCOMING_ADDRESS:
5021       if (arglist != 0
5022           || ! AGGREGATE_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl)))
5023           || GET_CODE (DECL_RTL (DECL_RESULT (current_function_decl))) != MEM)
5024         return const0_rtx;
5025       else
5026         return XEXP (DECL_RTL (DECL_RESULT (current_function_decl)), 0);
5027
5028     case BUILT_IN_ALLOCA:
5029       target = expand_builtin_alloca (arglist, target);
5030       if (target)
5031         return target;
5032       break;
5033
5034     case BUILT_IN_FFS:
5035     case BUILT_IN_FFSL:
5036     case BUILT_IN_FFSLL:
5037       target = expand_builtin_unop (target_mode, arglist, target,
5038                                     subtarget, ffs_optab);
5039       if (target)
5040         return target;
5041       break;
5042
5043     case BUILT_IN_CLZ:
5044     case BUILT_IN_CLZL:
5045     case BUILT_IN_CLZLL:
5046       target = expand_builtin_unop (target_mode, arglist, target,
5047                                     subtarget, clz_optab);
5048       if (target)
5049         return target;
5050       break;
5051
5052     case BUILT_IN_CTZ:
5053     case BUILT_IN_CTZL:
5054     case BUILT_IN_CTZLL:
5055       target = expand_builtin_unop (target_mode, arglist, target,
5056                                     subtarget, ctz_optab);
5057       if (target)
5058         return target;
5059       break;
5060
5061     case BUILT_IN_POPCOUNT:
5062     case BUILT_IN_POPCOUNTL:
5063     case BUILT_IN_POPCOUNTLL:
5064       target = expand_builtin_unop (target_mode, arglist, target,
5065                                     subtarget, popcount_optab);
5066       if (target)
5067         return target;
5068       break;
5069
5070     case BUILT_IN_PARITY:
5071     case BUILT_IN_PARITYL:
5072     case BUILT_IN_PARITYLL:
5073       target = expand_builtin_unop (target_mode, arglist, target,
5074                                     subtarget, parity_optab);
5075       if (target)
5076         return target;
5077       break;
5078
5079     case BUILT_IN_STRLEN:
5080       target = expand_builtin_strlen (arglist, target, target_mode);
5081       if (target)
5082         return target;
5083       break;
5084
5085     case BUILT_IN_STRCPY:
5086       target = expand_builtin_strcpy (arglist, target, mode);
5087       if (target)
5088         return target;
5089       break;
5090
5091     case BUILT_IN_STRNCPY:
5092       target = expand_builtin_strncpy (arglist, target, mode);
5093       if (target)
5094         return target;
5095       break;
5096
5097     case BUILT_IN_STPCPY:
5098       target = expand_builtin_stpcpy (arglist, target, mode);
5099       if (target)
5100         return target;
5101       break;
5102
5103     case BUILT_IN_STRCAT:
5104       target = expand_builtin_strcat (arglist, target, mode);
5105       if (target)
5106         return target;
5107       break;
5108
5109     case BUILT_IN_STRNCAT:
5110       target = expand_builtin_strncat (arglist, target, mode);
5111       if (target)
5112         return target;
5113       break;
5114
5115     case BUILT_IN_STRSPN:
5116       target = expand_builtin_strspn (arglist, target, mode);
5117       if (target)
5118         return target;
5119       break;
5120
5121     case BUILT_IN_STRCSPN:
5122       target = expand_builtin_strcspn (arglist, target, mode);
5123       if (target)
5124         return target;
5125       break;
5126
5127     case BUILT_IN_STRSTR:
5128       target = expand_builtin_strstr (arglist, target, mode);
5129       if (target)
5130         return target;
5131       break;
5132
5133     case BUILT_IN_STRPBRK:
5134       target = expand_builtin_strpbrk (arglist, target, mode);
5135       if (target)
5136         return target;
5137       break;
5138
5139     case BUILT_IN_INDEX:
5140     case BUILT_IN_STRCHR:
5141       target = expand_builtin_strchr (arglist, target, mode);
5142       if (target)
5143         return target;
5144       break;
5145
5146     case BUILT_IN_RINDEX:
5147     case BUILT_IN_STRRCHR:
5148       target = expand_builtin_strrchr (arglist, target, mode);
5149       if (target)
5150         return target;
5151       break;
5152
5153     case BUILT_IN_MEMCPY:
5154       target = expand_builtin_memcpy (arglist, target, mode);
5155       if (target)
5156         return target;
5157       break;
5158
5159     case BUILT_IN_MEMPCPY:
5160       target = expand_builtin_mempcpy (arglist, target, mode, /*endp=*/ 1);
5161       if (target)
5162         return target;
5163       break;
5164
5165     case BUILT_IN_MEMMOVE:
5166       target = expand_builtin_memmove (arglist, target, mode);
5167       if (target)
5168         return target;
5169       break;
5170
5171     case BUILT_IN_BCOPY:
5172       target = expand_builtin_bcopy (arglist);
5173       if (target)
5174         return target;
5175       break;
5176
5177     case BUILT_IN_MEMSET:
5178       target = expand_builtin_memset (arglist, target, mode);
5179       if (target)
5180         return target;
5181       break;
5182
5183     case BUILT_IN_BZERO:
5184       target = expand_builtin_bzero (arglist);
5185       if (target)
5186         return target;
5187       break;
5188
5189     case BUILT_IN_STRCMP:
5190       target = expand_builtin_strcmp (exp, target, mode);
5191       if (target)
5192         return target;
5193       break;
5194
5195     case BUILT_IN_STRNCMP:
5196       target = expand_builtin_strncmp (exp, target, mode);
5197       if (target)
5198         return target;
5199       break;
5200
5201     case BUILT_IN_BCMP:
5202     case BUILT_IN_MEMCMP:
5203       target = expand_builtin_memcmp (exp, arglist, target, mode);
5204       if (target)
5205         return target;
5206       break;
5207
5208     case BUILT_IN_SETJMP:
5209       target = expand_builtin_setjmp (arglist, target);
5210       if (target)
5211         return target;
5212       break;
5213
5214       /* __builtin_longjmp is passed a pointer to an array of five words.
5215          It's similar to the C library longjmp function but works with
5216          __builtin_setjmp above.  */
5217     case BUILT_IN_LONGJMP:
5218       if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
5219         break;
5220       else
5221         {
5222           rtx buf_addr = expand_expr (TREE_VALUE (arglist), subtarget,
5223                                       VOIDmode, 0);
5224           rtx value = expand_expr (TREE_VALUE (TREE_CHAIN (arglist)),
5225                                    NULL_RTX, VOIDmode, 0);
5226
5227           if (value != const1_rtx)
5228             {
5229               error ("__builtin_longjmp second argument must be 1");
5230               return const0_rtx;
5231             }
5232
5233           expand_builtin_longjmp (buf_addr, value);
5234           return const0_rtx;
5235         }
5236
5237     case BUILT_IN_TRAP:
5238       expand_builtin_trap ();
5239       return const0_rtx;
5240
5241     case BUILT_IN_PRINTF:
5242       target = expand_builtin_printf (arglist, target, mode, false);
5243       if (target)
5244         return target;
5245       break;
5246
5247     case BUILT_IN_PRINTF_UNLOCKED:
5248       target = expand_builtin_printf (arglist, target, mode, true);
5249       if (target)
5250         return target;
5251       break;
5252
5253     case BUILT_IN_FPUTS:
5254       target = expand_builtin_fputs (arglist, target, false);
5255       if (target)
5256         return target;
5257       break;
5258
5259     case BUILT_IN_FPUTS_UNLOCKED:
5260       target = expand_builtin_fputs (arglist, target, true);
5261       if (target)
5262         return target;
5263       break;
5264
5265     case BUILT_IN_FPRINTF:
5266       target = expand_builtin_fprintf (arglist, target, mode, false);
5267       if (target)
5268         return target;
5269       break;
5270
5271     case BUILT_IN_FPRINTF_UNLOCKED:
5272       target = expand_builtin_fprintf (arglist, target, mode, true);
5273       if (target)
5274         return target;
5275       break;
5276
5277     case BUILT_IN_SPRINTF:
5278       target = expand_builtin_sprintf (arglist, target, mode);
5279       if (target)
5280         return target;
5281       break;
5282
5283       /* Various hooks for the DWARF 2 __throw routine.  */
5284     case BUILT_IN_UNWIND_INIT:
5285       expand_builtin_unwind_init ();
5286       return const0_rtx;
5287     case BUILT_IN_DWARF_CFA:
5288       return virtual_cfa_rtx;
5289 #ifdef DWARF2_UNWIND_INFO
5290     case BUILT_IN_DWARF_SP_COLUMN:
5291       return expand_builtin_dwarf_sp_column ();
5292     case BUILT_IN_INIT_DWARF_REG_SIZES:
5293       expand_builtin_init_dwarf_reg_sizes (TREE_VALUE (arglist));
5294       return const0_rtx;
5295 #endif
5296     case BUILT_IN_FROB_RETURN_ADDR:
5297       return expand_builtin_frob_return_addr (TREE_VALUE (arglist));
5298     case BUILT_IN_EXTRACT_RETURN_ADDR:
5299       return expand_builtin_extract_return_addr (TREE_VALUE (arglist));
5300     case BUILT_IN_EH_RETURN:
5301       expand_builtin_eh_return (TREE_VALUE (arglist),
5302                                 TREE_VALUE (TREE_CHAIN (arglist)));
5303       return const0_rtx;
5304 #ifdef EH_RETURN_DATA_REGNO
5305     case BUILT_IN_EH_RETURN_DATA_REGNO:
5306       return expand_builtin_eh_return_data_regno (arglist);
5307 #endif
5308     case BUILT_IN_VA_START:
5309     case BUILT_IN_STDARG_START:
5310       return expand_builtin_va_start (arglist);
5311     case BUILT_IN_VA_END:
5312       return expand_builtin_va_end (arglist);
5313     case BUILT_IN_VA_COPY:
5314       return expand_builtin_va_copy (arglist);
5315     case BUILT_IN_EXPECT:
5316       return expand_builtin_expect (arglist, target);
5317     case BUILT_IN_PREFETCH:
5318       expand_builtin_prefetch (arglist);
5319       return const0_rtx;
5320
5321
5322     default:    /* just do library call, if unknown builtin */
5323       if (!DECL_ASSEMBLER_NAME_SET_P (fndecl))
5324         error ("built-in function `%s' not currently supported",
5325                IDENTIFIER_POINTER (DECL_NAME (fndecl)));
5326     }
5327
5328   /* The switch statement above can drop through to cause the function
5329      to be called normally.  */
5330   return expand_call (exp, target, ignore);
5331 }
5332
5333 /* Determine whether a tree node represents a call to a built-in
5334    math function.  If the tree T is a call to a built-in function
5335    taking a single real argument, then the return value is the
5336    DECL_FUNCTION_CODE of the call, e.g. BUILT_IN_SQRT.  Otherwise
5337    the return value is END_BUILTINS.  */
5338
5339 enum built_in_function
5340 builtin_mathfn_code (tree t)
5341 {
5342   tree fndecl, arglist;
5343
5344   if (TREE_CODE (t) != CALL_EXPR
5345       || TREE_CODE (TREE_OPERAND (t, 0)) != ADDR_EXPR)
5346     return END_BUILTINS;
5347
5348   fndecl = get_callee_fndecl (t);
5349   if (fndecl == NULL_TREE
5350       || ! DECL_BUILT_IN (fndecl)
5351       || DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
5352     return END_BUILTINS;
5353
5354   arglist = TREE_OPERAND (t, 1);
5355   if (! arglist
5356       || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != REAL_TYPE)
5357     return END_BUILTINS;
5358
5359   arglist = TREE_CHAIN (arglist);
5360   switch (DECL_FUNCTION_CODE (fndecl))
5361     {
5362     case BUILT_IN_POW:
5363     case BUILT_IN_POWF:
5364     case BUILT_IN_POWL:
5365     case BUILT_IN_ATAN2:
5366     case BUILT_IN_ATAN2F:
5367     case BUILT_IN_ATAN2L:
5368       if (! arglist
5369           || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != REAL_TYPE
5370           || TREE_CHAIN (arglist))
5371         return END_BUILTINS;
5372       break;
5373
5374     default:
5375       if (arglist)
5376         return END_BUILTINS;
5377       break;
5378     }
5379
5380   return DECL_FUNCTION_CODE (fndecl);
5381 }
5382
5383 /* Fold a call to __builtin_constant_p, if we know it will evaluate to a
5384    constant.  ARGLIST is the argument list of the call.  */
5385
5386 static tree
5387 fold_builtin_constant_p (tree arglist)
5388 {
5389   if (arglist == 0)
5390     return 0;
5391
5392   arglist = TREE_VALUE (arglist);
5393
5394   /* We return 1 for a numeric type that's known to be a constant
5395      value at compile-time or for an aggregate type that's a
5396      literal constant.  */
5397   STRIP_NOPS (arglist);
5398
5399   /* If we know this is a constant, emit the constant of one.  */
5400   if (TREE_CODE_CLASS (TREE_CODE (arglist)) == 'c'
5401       || (TREE_CODE (arglist) == CONSTRUCTOR
5402           && TREE_CONSTANT (arglist))
5403       || (TREE_CODE (arglist) == ADDR_EXPR
5404           && TREE_CODE (TREE_OPERAND (arglist, 0)) == STRING_CST))
5405     return integer_one_node;
5406
5407   /* If we aren't going to be running CSE or this expression
5408      has side effects, show we don't know it to be a constant.
5409      Likewise if it's a pointer or aggregate type since in those
5410      case we only want literals, since those are only optimized
5411      when generating RTL, not later.
5412      And finally, if we are compiling an initializer, not code, we
5413      need to return a definite result now; there's not going to be any
5414      more optimization done.  */
5415   if (TREE_SIDE_EFFECTS (arglist) || cse_not_expected
5416       || AGGREGATE_TYPE_P (TREE_TYPE (arglist))
5417       || POINTER_TYPE_P (TREE_TYPE (arglist))
5418       || cfun == 0)
5419     return integer_zero_node;
5420
5421   return 0;
5422 }
5423
5424 /* Fold a call to __builtin_classify_type.  */
5425
5426 static tree
5427 fold_builtin_classify_type (tree arglist)
5428 {
5429   if (arglist == 0)
5430     return build_int_2 (no_type_class, 0);
5431
5432   return build_int_2 (type_to_class (TREE_TYPE (TREE_VALUE (arglist))), 0);
5433 }
5434
5435 /* Fold a call to __builtin_inf or __builtin_huge_val.  */
5436
5437 static tree
5438 fold_builtin_inf (tree type, int warn)
5439 {
5440   REAL_VALUE_TYPE real;
5441
5442   if (!MODE_HAS_INFINITIES (TYPE_MODE (type)) && warn)
5443     warning ("target format does not support infinity");
5444
5445   real_inf (&real);
5446   return build_real (type, real);
5447 }
5448
5449 /* Fold a call to __builtin_nan or __builtin_nans.  */
5450
5451 static tree
5452 fold_builtin_nan (tree arglist, tree type, int quiet)
5453 {
5454   REAL_VALUE_TYPE real;
5455   const char *str;
5456
5457   if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5458     return 0;
5459   str = c_getstr (TREE_VALUE (arglist));
5460   if (!str)
5461     return 0;
5462
5463   if (!real_nan (&real, str, quiet, TYPE_MODE (type)))
5464     return 0;
5465
5466   return build_real (type, real);
5467 }
5468
5469 /* Return true if the floating point expression T has an integer value.
5470    We also allow +Inf, -Inf and NaN to be considered integer values.  */
5471
5472 static bool
5473 integer_valued_real_p (tree t)
5474 {
5475   switch (TREE_CODE (t))
5476     {
5477     case FLOAT_EXPR:
5478       return true;
5479
5480     case ABS_EXPR:
5481     case SAVE_EXPR:
5482     case NON_LVALUE_EXPR:
5483       return integer_valued_real_p (TREE_OPERAND (t, 0));
5484
5485     case COMPOUND_EXPR:
5486     case MODIFY_EXPR:
5487     case BIND_EXPR:
5488       return integer_valued_real_p (TREE_OPERAND (t, 1));
5489
5490     case PLUS_EXPR:
5491     case MINUS_EXPR:
5492     case MULT_EXPR:
5493     case MIN_EXPR:
5494     case MAX_EXPR:
5495       return integer_valued_real_p (TREE_OPERAND (t, 0))
5496              && integer_valued_real_p (TREE_OPERAND (t, 1));
5497
5498     case COND_EXPR:
5499       return integer_valued_real_p (TREE_OPERAND (t, 1))
5500              && integer_valued_real_p (TREE_OPERAND (t, 2));
5501
5502     case REAL_CST:
5503       if (! TREE_CONSTANT_OVERFLOW (t))
5504       {
5505         REAL_VALUE_TYPE c, cint;
5506
5507         c = TREE_REAL_CST (t);
5508         real_trunc (&cint, TYPE_MODE (TREE_TYPE (t)), &c);
5509         return real_identical (&c, &cint);
5510       }
5511
5512     case NOP_EXPR:
5513       {
5514         tree type = TREE_TYPE (TREE_OPERAND (t, 0));
5515         if (TREE_CODE (type) == INTEGER_TYPE)
5516           return true;
5517         if (TREE_CODE (type) == REAL_TYPE)
5518           return integer_valued_real_p (TREE_OPERAND (t, 0));
5519         break;
5520       }
5521
5522     case CALL_EXPR:
5523       switch (builtin_mathfn_code (t))
5524         {
5525         case BUILT_IN_CEIL:
5526         case BUILT_IN_CEILF:
5527         case BUILT_IN_CEILL:
5528         case BUILT_IN_FLOOR:
5529         case BUILT_IN_FLOORF:
5530         case BUILT_IN_FLOORL:
5531         case BUILT_IN_NEARBYINT:
5532         case BUILT_IN_NEARBYINTF:
5533         case BUILT_IN_NEARBYINTL:
5534         case BUILT_IN_ROUND:
5535         case BUILT_IN_ROUNDF:
5536         case BUILT_IN_ROUNDL:
5537         case BUILT_IN_TRUNC:
5538         case BUILT_IN_TRUNCF:
5539         case BUILT_IN_TRUNCL:
5540           return true;
5541
5542         default:
5543           break;
5544         }
5545       break;
5546
5547     default:
5548       break;
5549     }
5550   return false;
5551 }
5552
5553 /* EXP is assumed to be builtin call where truncation can be propagated
5554    across (for instance floor((double)f) == (double)floorf (f).
5555    Do the transformation.  */
5556
5557 static tree
5558 fold_trunc_transparent_mathfn (tree exp)
5559 {
5560   tree fndecl = get_callee_fndecl (exp);
5561   tree arglist = TREE_OPERAND (exp, 1);
5562   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
5563   tree arg;
5564
5565   if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
5566     return 0;
5567
5568   arg = TREE_VALUE (arglist);
5569   /* Integer rounding functions are idempotent.  */
5570   if (fcode == builtin_mathfn_code (arg))
5571     return arg;
5572
5573   /* If argument is already integer valued, and we don't need to worry
5574      about setting errno, there's no need to perform rounding.  */
5575   if (! flag_errno_math && integer_valued_real_p (arg))
5576     return arg;
5577
5578   if (optimize)
5579     {
5580       tree arg0 = strip_float_extensions (arg);
5581       tree ftype = TREE_TYPE (exp);
5582       tree newtype = TREE_TYPE (arg0);
5583       tree decl;
5584
5585       if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
5586           && (decl = mathfn_built_in (newtype, fcode)))
5587         {
5588           arglist =
5589             build_tree_list (NULL_TREE, fold (convert (newtype, arg0)));
5590           return convert (ftype,
5591                           build_function_call_expr (decl, arglist));
5592         }
5593     }
5594   return 0;
5595 }
5596
5597 /* Fold function call to builtin cabs, cabsf or cabsl.  FNDECL is the
5598    function's DECL, ARGLIST is the argument list and TYPE is the return
5599    type.  Return NULL_TREE if no simplification can be made.  */
5600
5601 static tree
5602 fold_builtin_cabs (tree fndecl, tree arglist, tree type)
5603 {
5604   tree arg;
5605
5606   if (!arglist || TREE_CHAIN (arglist))
5607     return NULL_TREE;
5608
5609   arg = TREE_VALUE (arglist);
5610   if (TREE_CODE (TREE_TYPE (arg)) != COMPLEX_TYPE
5611       || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) != REAL_TYPE)
5612     return NULL_TREE;
5613
5614   /* Evaluate cabs of a constant at compile-time.  */
5615   if (flag_unsafe_math_optimizations
5616       && TREE_CODE (arg) == COMPLEX_CST
5617       && TREE_CODE (TREE_REALPART (arg)) == REAL_CST
5618       && TREE_CODE (TREE_IMAGPART (arg)) == REAL_CST
5619       && ! TREE_CONSTANT_OVERFLOW (TREE_REALPART (arg))
5620       && ! TREE_CONSTANT_OVERFLOW (TREE_IMAGPART (arg)))
5621     {
5622       REAL_VALUE_TYPE r, i;
5623
5624       r = TREE_REAL_CST (TREE_REALPART (arg));
5625       i = TREE_REAL_CST (TREE_IMAGPART (arg));
5626
5627       real_arithmetic (&r, MULT_EXPR, &r, &r);
5628       real_arithmetic (&i, MULT_EXPR, &i, &i);
5629       real_arithmetic (&r, PLUS_EXPR, &r, &i);
5630       if (real_sqrt (&r, TYPE_MODE (type), &r)
5631           || ! flag_trapping_math)
5632         return build_real (type, r);
5633     }
5634
5635   /* If either part is zero, cabs is fabs of the other.  */
5636   if (TREE_CODE (arg) == COMPLEX_EXPR
5637       && real_zerop (TREE_OPERAND (arg, 0)))
5638     return fold (build1 (ABS_EXPR, type, TREE_OPERAND (arg, 1)));
5639   if (TREE_CODE (arg) == COMPLEX_EXPR
5640       && real_zerop (TREE_OPERAND (arg, 1)))
5641     return fold (build1 (ABS_EXPR, type, TREE_OPERAND (arg, 0)));
5642
5643   if (flag_unsafe_math_optimizations)
5644     {
5645       enum built_in_function fcode;
5646       tree sqrtfn;
5647
5648       fcode = DECL_FUNCTION_CODE (fndecl);
5649       if (fcode == BUILT_IN_CABS)
5650         sqrtfn = implicit_built_in_decls[BUILT_IN_SQRT];
5651       else if (fcode == BUILT_IN_CABSF)
5652         sqrtfn = implicit_built_in_decls[BUILT_IN_SQRTF];
5653       else if (fcode == BUILT_IN_CABSL)
5654         sqrtfn = implicit_built_in_decls[BUILT_IN_SQRTL];
5655       else
5656         sqrtfn = NULL_TREE;
5657
5658       if (sqrtfn != NULL_TREE)
5659         {
5660           tree rpart, ipart, result, arglist;
5661
5662           rpart = fold (build1 (REALPART_EXPR, type, arg));
5663           ipart = fold (build1 (IMAGPART_EXPR, type, arg));
5664
5665           rpart = save_expr (rpart);
5666           ipart = save_expr (ipart);
5667
5668           result = fold (build (PLUS_EXPR, type,
5669                                 fold (build (MULT_EXPR, type,
5670                                              rpart, rpart)),
5671                                 fold (build (MULT_EXPR, type,
5672                                              ipart, ipart))));
5673
5674           arglist = build_tree_list (NULL_TREE, result);
5675           return build_function_call_expr (sqrtfn, arglist);
5676         }
5677     }
5678
5679   return NULL_TREE;
5680 }
5681
5682 /* Fold function call to builtin trunc, truncf or truncl.  Return
5683    NULL_TREE if no simplification can be made.  */
5684
5685 static tree
5686 fold_builtin_trunc (tree exp)
5687 {
5688   tree arglist = TREE_OPERAND (exp, 1);
5689   tree arg;
5690
5691   if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
5692     return 0;
5693
5694   /* Optimize trunc of constant value.  */
5695   arg = TREE_VALUE (arglist);
5696   if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
5697     {
5698       REAL_VALUE_TYPE r, x;
5699       tree type = TREE_TYPE (exp);
5700
5701       x = TREE_REAL_CST (arg);
5702       real_trunc (&r, TYPE_MODE (type), &x);
5703       return build_real (type, r);
5704     }
5705
5706   return fold_trunc_transparent_mathfn (exp);
5707 }
5708
5709 /* Fold function call to builtin floor, floorf or floorl.  Return
5710    NULL_TREE if no simplification can be made.  */
5711
5712 static tree
5713 fold_builtin_floor (tree exp)
5714 {
5715   tree arglist = TREE_OPERAND (exp, 1);
5716   tree arg;
5717
5718   if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
5719     return 0;
5720
5721   /* Optimize floor of constant value.  */
5722   arg = TREE_VALUE (arglist);
5723   if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
5724     {
5725       REAL_VALUE_TYPE x;
5726
5727       x = TREE_REAL_CST (arg);
5728       if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
5729         {
5730           tree type = TREE_TYPE (exp);
5731           REAL_VALUE_TYPE r;
5732
5733           real_floor (&r, TYPE_MODE (type), &x);
5734           return build_real (type, r);
5735         }
5736     }
5737
5738   return fold_trunc_transparent_mathfn (exp);
5739 }
5740
5741 /* Fold function call to builtin ceil, ceilf or ceill.  Return
5742    NULL_TREE if no simplification can be made.  */
5743
5744 static tree
5745 fold_builtin_ceil (tree exp)
5746 {
5747   tree arglist = TREE_OPERAND (exp, 1);
5748   tree arg;
5749
5750   if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
5751     return 0;
5752
5753   /* Optimize ceil of constant value.  */
5754   arg = TREE_VALUE (arglist);
5755   if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
5756     {
5757       REAL_VALUE_TYPE x;
5758
5759       x = TREE_REAL_CST (arg);
5760       if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
5761         {
5762           tree type = TREE_TYPE (exp);
5763           REAL_VALUE_TYPE r;
5764
5765           real_ceil (&r, TYPE_MODE (type), &x);
5766           return build_real (type, r);
5767         }
5768     }
5769
5770   return fold_trunc_transparent_mathfn (exp);
5771 }
5772
5773 /* Used by constant folding to eliminate some builtin calls early.  EXP is
5774    the CALL_EXPR of a call to a builtin function.  */
5775
5776 tree
5777 fold_builtin (tree exp)
5778 {
5779   tree fndecl = get_callee_fndecl (exp);
5780   tree arglist = TREE_OPERAND (exp, 1);
5781   tree type = TREE_TYPE (TREE_TYPE (fndecl));
5782
5783   if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
5784     return 0;
5785
5786   switch (DECL_FUNCTION_CODE (fndecl))
5787     {
5788     case BUILT_IN_CONSTANT_P:
5789       return fold_builtin_constant_p (arglist);
5790
5791     case BUILT_IN_CLASSIFY_TYPE:
5792       return fold_builtin_classify_type (arglist);
5793
5794     case BUILT_IN_STRLEN:
5795       if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5796         {
5797           tree len = c_strlen (TREE_VALUE (arglist), 0);
5798           if (len)
5799             {
5800               /* Convert from the internal "sizetype" type to "size_t".  */
5801               if (size_type_node)
5802                 len = convert (size_type_node, len);
5803               return len;
5804             }
5805         }
5806       break;
5807
5808     case BUILT_IN_FABS:
5809     case BUILT_IN_FABSF:
5810     case BUILT_IN_FABSL:
5811       if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
5812         return fold (build1 (ABS_EXPR, type, TREE_VALUE (arglist)));
5813       break;
5814
5815     case BUILT_IN_CABS:
5816     case BUILT_IN_CABSF:
5817     case BUILT_IN_CABSL:
5818       return fold_builtin_cabs (fndecl, arglist, type);
5819
5820     case BUILT_IN_SQRT:
5821     case BUILT_IN_SQRTF:
5822     case BUILT_IN_SQRTL:
5823       if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
5824         {
5825           enum built_in_function fcode;
5826           tree arg = TREE_VALUE (arglist);
5827
5828           /* Optimize sqrt of constant value.  */
5829           if (TREE_CODE (arg) == REAL_CST
5830               && ! TREE_CONSTANT_OVERFLOW (arg))
5831             {
5832               REAL_VALUE_TYPE r, x;
5833
5834               x = TREE_REAL_CST (arg);
5835               if (real_sqrt (&r, TYPE_MODE (type), &x)
5836                   || (!flag_trapping_math && !flag_errno_math))
5837                 return build_real (type, r);
5838             }
5839
5840           /* Optimize sqrt(exp(x)) = exp(x*0.5).  */
5841           fcode = builtin_mathfn_code (arg);
5842           if (flag_unsafe_math_optimizations
5843               && (fcode == BUILT_IN_EXP
5844                   || fcode == BUILT_IN_EXPF
5845                   || fcode == BUILT_IN_EXPL))
5846             {
5847               tree expfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
5848               arg = fold (build (MULT_EXPR, type,
5849                                  TREE_VALUE (TREE_OPERAND (arg, 1)),
5850                                  build_real (type, dconsthalf)));
5851               arglist = build_tree_list (NULL_TREE, arg);
5852               return build_function_call_expr (expfn, arglist);
5853             }
5854
5855           /* Optimize sqrt(pow(x,y)) = pow(x,y*0.5).  */
5856           if (flag_unsafe_math_optimizations
5857               && (fcode == BUILT_IN_POW
5858                   || fcode == BUILT_IN_POWF
5859                   || fcode == BUILT_IN_POWL))
5860             {
5861               tree powfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
5862               tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
5863               tree arg1 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
5864               tree narg1 = fold (build (MULT_EXPR, type, arg1,
5865                                         build_real (type, dconsthalf)));
5866               arglist = tree_cons (NULL_TREE, arg0,
5867                                    build_tree_list (NULL_TREE, narg1));
5868               return build_function_call_expr (powfn, arglist);
5869             }
5870         }
5871       break;
5872
5873     case BUILT_IN_SIN:
5874     case BUILT_IN_SINF:
5875     case BUILT_IN_SINL:
5876       if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
5877         {
5878           tree arg = TREE_VALUE (arglist);
5879
5880           /* Optimize sin(0.0) = 0.0.  */
5881           if (real_zerop (arg))
5882             return arg;
5883         }
5884       break;
5885
5886     case BUILT_IN_COS:
5887     case BUILT_IN_COSF:
5888     case BUILT_IN_COSL:
5889       if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
5890         {
5891           tree arg = TREE_VALUE (arglist);
5892
5893           /* Optimize cos(0.0) = 1.0.  */
5894           if (real_zerop (arg))
5895             return build_real (type, dconst1);
5896
5897           /* Optimize cos(-x) into cos(x).  */
5898           if (TREE_CODE (arg) == NEGATE_EXPR)
5899             {
5900               tree arglist = build_tree_list (NULL_TREE,
5901                                               TREE_OPERAND (arg, 0));
5902               return build_function_call_expr (fndecl, arglist);
5903             }
5904         }
5905       break;
5906
5907     case BUILT_IN_EXP:
5908     case BUILT_IN_EXPF:
5909     case BUILT_IN_EXPL:
5910       if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
5911         {
5912           enum built_in_function fcode;
5913           tree arg = TREE_VALUE (arglist);
5914
5915           /* Optimize exp(0.0) = 1.0.  */
5916           if (real_zerop (arg))
5917             return build_real (type, dconst1);
5918
5919           /* Optimize exp(1.0) = e.  */
5920           if (real_onep (arg))
5921             {
5922               REAL_VALUE_TYPE cst;
5923
5924               if (! builtin_dconsts_init)
5925                 init_builtin_dconsts ();
5926               real_convert (&cst, TYPE_MODE (type), &dconste);
5927               return build_real (type, cst);
5928             }
5929
5930           /* Attempt to evaluate exp at compile-time.  */
5931           if (flag_unsafe_math_optimizations
5932               && TREE_CODE (arg) == REAL_CST
5933               && ! TREE_CONSTANT_OVERFLOW (arg))
5934             {
5935               REAL_VALUE_TYPE cint;
5936               REAL_VALUE_TYPE c;
5937               HOST_WIDE_INT n;
5938
5939               c = TREE_REAL_CST (arg);
5940               n = real_to_integer (&c);
5941               real_from_integer (&cint, VOIDmode, n,
5942                                  n < 0 ? -1 : 0, 0);
5943               if (real_identical (&c, &cint))
5944                 {
5945                   REAL_VALUE_TYPE x;
5946
5947                   if (! builtin_dconsts_init)
5948                     init_builtin_dconsts ();
5949                   real_powi (&x, TYPE_MODE (type), &dconste, n);
5950                   return build_real (type, x);
5951                 }
5952             }
5953
5954           /* Optimize exp(log(x)) = x.  */
5955           fcode = builtin_mathfn_code (arg);
5956           if (flag_unsafe_math_optimizations
5957               && (fcode == BUILT_IN_LOG
5958                   || fcode == BUILT_IN_LOGF
5959                   || fcode == BUILT_IN_LOGL))
5960             return TREE_VALUE (TREE_OPERAND (arg, 1));
5961         }
5962       break;
5963
5964     case BUILT_IN_LOG:
5965     case BUILT_IN_LOGF:
5966     case BUILT_IN_LOGL:
5967       if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
5968         {
5969           enum built_in_function fcode;
5970           tree arg = TREE_VALUE (arglist);
5971
5972           /* Optimize log(1.0) = 0.0.  */
5973           if (real_onep (arg))
5974             return build_real (type, dconst0);
5975
5976           /* Optimize log(exp(x)) = x.  */
5977           fcode = builtin_mathfn_code (arg);
5978           if (flag_unsafe_math_optimizations
5979               && (fcode == BUILT_IN_EXP
5980                   || fcode == BUILT_IN_EXPF
5981                   || fcode == BUILT_IN_EXPL))
5982             return TREE_VALUE (TREE_OPERAND (arg, 1));
5983
5984           /* Optimize log(sqrt(x)) = log(x)*0.5.  */
5985           if (flag_unsafe_math_optimizations
5986               && (fcode == BUILT_IN_SQRT
5987                   || fcode == BUILT_IN_SQRTF
5988                   || fcode == BUILT_IN_SQRTL))
5989             {
5990               tree logfn = build_function_call_expr (fndecl,
5991                                                      TREE_OPERAND (arg, 1));
5992               return fold (build (MULT_EXPR, type, logfn,
5993                                   build_real (type, dconsthalf)));
5994             }
5995
5996           /* Optimize log(pow(x,y)) = y*log(x).  */
5997           if (flag_unsafe_math_optimizations
5998               && (fcode == BUILT_IN_POW
5999                   || fcode == BUILT_IN_POWF
6000                   || fcode == BUILT_IN_POWL))
6001             {
6002               tree arg0, arg1, logfn;
6003
6004               arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
6005               arg1 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
6006               arglist = build_tree_list (NULL_TREE, arg0);
6007               logfn = build_function_call_expr (fndecl, arglist);
6008               return fold (build (MULT_EXPR, type, arg1, logfn));
6009             }
6010         }
6011       break;
6012
6013     case BUILT_IN_TAN:
6014     case BUILT_IN_TANF:
6015     case BUILT_IN_TANL:
6016       if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6017         {
6018           enum built_in_function fcode;
6019           tree arg = TREE_VALUE (arglist);
6020
6021           /* Optimize tan(0.0) = 0.0.  */
6022           if (real_zerop (arg))
6023             return arg;
6024
6025           /* Optimize tan(atan(x)) = x.  */
6026           fcode = builtin_mathfn_code (arg);
6027           if (flag_unsafe_math_optimizations
6028               && (fcode == BUILT_IN_ATAN
6029                   || fcode == BUILT_IN_ATANF
6030                   || fcode == BUILT_IN_ATANL))
6031             return TREE_VALUE (TREE_OPERAND (arg, 1));
6032         }
6033       break;
6034
6035     case BUILT_IN_ATAN:
6036     case BUILT_IN_ATANF:
6037     case BUILT_IN_ATANL:
6038       if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6039         {
6040           tree arg = TREE_VALUE (arglist);
6041
6042           /* Optimize atan(0.0) = 0.0.  */
6043           if (real_zerop (arg))
6044             return arg;
6045
6046           /* Optimize atan(1.0) = pi/4.  */
6047           if (real_onep (arg))
6048             {
6049               REAL_VALUE_TYPE cst;
6050
6051               if (! builtin_dconsts_init)
6052                 init_builtin_dconsts ();
6053               real_convert (&cst, TYPE_MODE (type), &dconstpi);
6054               cst.exp -= 2;
6055               return build_real (type, cst);
6056             }
6057         }
6058       break;
6059
6060     case BUILT_IN_POW:
6061     case BUILT_IN_POWF:
6062     case BUILT_IN_POWL:
6063       if (validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
6064         {
6065           enum built_in_function fcode;
6066           tree arg0 = TREE_VALUE (arglist);
6067           tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
6068
6069           /* Optimize pow(1.0,y) = 1.0.  */
6070           if (real_onep (arg0))
6071             return omit_one_operand (type, build_real (type, dconst1), arg1);
6072
6073           if (TREE_CODE (arg1) == REAL_CST
6074               && ! TREE_CONSTANT_OVERFLOW (arg1))
6075             {
6076               REAL_VALUE_TYPE c;
6077               c = TREE_REAL_CST (arg1);
6078
6079               /* Optimize pow(x,0.0) = 1.0.  */
6080               if (REAL_VALUES_EQUAL (c, dconst0))
6081                 return omit_one_operand (type, build_real (type, dconst1),
6082                                          arg0);
6083
6084               /* Optimize pow(x,1.0) = x.  */
6085               if (REAL_VALUES_EQUAL (c, dconst1))
6086                 return arg0;
6087
6088               /* Optimize pow(x,-1.0) = 1.0/x.  */
6089               if (REAL_VALUES_EQUAL (c, dconstm1))
6090                 return fold (build (RDIV_EXPR, type,
6091                                     build_real (type, dconst1),
6092                                     arg0));
6093
6094               /* Optimize pow(x,0.5) = sqrt(x).  */
6095               if (flag_unsafe_math_optimizations
6096                   && REAL_VALUES_EQUAL (c, dconsthalf))
6097                 {
6098                   tree sqrtfn;
6099
6100                   fcode = DECL_FUNCTION_CODE (fndecl);
6101                   if (fcode == BUILT_IN_POW)
6102                     sqrtfn = implicit_built_in_decls[BUILT_IN_SQRT];
6103                   else if (fcode == BUILT_IN_POWF)
6104                     sqrtfn = implicit_built_in_decls[BUILT_IN_SQRTF];
6105                   else if (fcode == BUILT_IN_POWL)
6106                     sqrtfn = implicit_built_in_decls[BUILT_IN_SQRTL];
6107                   else
6108                     sqrtfn = NULL_TREE;
6109
6110                   if (sqrtfn != NULL_TREE)
6111                     {
6112                       tree arglist = build_tree_list (NULL_TREE, arg0);
6113                       return build_function_call_expr (sqrtfn, arglist);
6114                     }
6115                 }
6116
6117               /* Attempt to evaluate pow at compile-time.  */
6118               if (TREE_CODE (arg0) == REAL_CST
6119                   && ! TREE_CONSTANT_OVERFLOW (arg0))
6120                 {
6121                   REAL_VALUE_TYPE cint;
6122                   HOST_WIDE_INT n;
6123
6124                   n = real_to_integer (&c);
6125                   real_from_integer (&cint, VOIDmode, n,
6126                                      n < 0 ? -1 : 0, 0);
6127                   if (real_identical (&c, &cint))
6128                     {
6129                       REAL_VALUE_TYPE x;
6130                       bool inexact;
6131
6132                       x = TREE_REAL_CST (arg0);
6133                       inexact = real_powi (&x, TYPE_MODE (type), &x, n);
6134                       if (flag_unsafe_math_optimizations || !inexact)
6135                         return build_real (type, x);
6136                     }
6137                 }
6138             }
6139
6140           /* Optimize pow(exp(x),y) = exp(x*y).  */
6141           fcode = builtin_mathfn_code (arg0);
6142           if (flag_unsafe_math_optimizations
6143               && (fcode == BUILT_IN_EXP
6144                   || fcode == BUILT_IN_EXPF
6145                   || fcode == BUILT_IN_EXPL))
6146             {
6147               tree expfn = TREE_OPERAND (TREE_OPERAND (arg0, 0), 0);
6148               tree arg = TREE_VALUE (TREE_OPERAND (arg0, 1));
6149               arg = fold (build (MULT_EXPR, type, arg, arg1));
6150               arglist = build_tree_list (NULL_TREE, arg);
6151               return build_function_call_expr (expfn, arglist);
6152             }
6153
6154           /* Optimize pow(sqrt(x),y) = pow(x,y*0.5).  */
6155           if (flag_unsafe_math_optimizations
6156               && (fcode == BUILT_IN_SQRT
6157                   || fcode == BUILT_IN_SQRTF
6158                   || fcode == BUILT_IN_SQRTL))
6159             {
6160               tree narg0 = TREE_VALUE (TREE_OPERAND (arg0, 1));
6161               tree narg1 = fold (build (MULT_EXPR, type, arg1,
6162                                         build_real (type, dconsthalf)));
6163
6164               arglist = tree_cons (NULL_TREE, narg0,
6165                                    build_tree_list (NULL_TREE, narg1));
6166               return build_function_call_expr (fndecl, arglist);
6167             }
6168
6169           /* Optimize pow(pow(x,y),z) = pow(x,y*z).  */
6170           if (flag_unsafe_math_optimizations
6171               && (fcode == BUILT_IN_POW
6172                   || fcode == BUILT_IN_POWF
6173                   || fcode == BUILT_IN_POWL))
6174             {
6175               tree arg00 = TREE_VALUE (TREE_OPERAND (arg0, 1));
6176               tree arg01 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg0, 1)));
6177               tree narg1 = fold (build (MULT_EXPR, type, arg01, arg1));
6178               arglist = tree_cons (NULL_TREE, arg00,
6179                                    build_tree_list (NULL_TREE, narg1));
6180               return build_function_call_expr (fndecl, arglist);
6181             }
6182         }
6183       break;
6184
6185     case BUILT_IN_INF:
6186     case BUILT_IN_INFF:
6187     case BUILT_IN_INFL:
6188       return fold_builtin_inf (type, true);
6189
6190     case BUILT_IN_HUGE_VAL:
6191     case BUILT_IN_HUGE_VALF:
6192     case BUILT_IN_HUGE_VALL:
6193       return fold_builtin_inf (type, false);
6194
6195     case BUILT_IN_NAN:
6196     case BUILT_IN_NANF:
6197     case BUILT_IN_NANL:
6198       return fold_builtin_nan (arglist, type, true);
6199
6200     case BUILT_IN_NANS:
6201     case BUILT_IN_NANSF:
6202     case BUILT_IN_NANSL:
6203       return fold_builtin_nan (arglist, type, false);
6204
6205     case BUILT_IN_FLOOR:
6206     case BUILT_IN_FLOORF:
6207     case BUILT_IN_FLOORL:
6208       return fold_builtin_floor (exp);
6209
6210     case BUILT_IN_CEIL:
6211     case BUILT_IN_CEILF:
6212     case BUILT_IN_CEILL:
6213       return fold_builtin_ceil (exp);
6214
6215     case BUILT_IN_TRUNC:
6216     case BUILT_IN_TRUNCF:
6217     case BUILT_IN_TRUNCL:
6218       return fold_builtin_trunc (exp);
6219
6220     case BUILT_IN_ROUND:
6221     case BUILT_IN_ROUNDF:
6222     case BUILT_IN_ROUNDL:
6223     case BUILT_IN_NEARBYINT:
6224     case BUILT_IN_NEARBYINTF:
6225     case BUILT_IN_NEARBYINTL:
6226       return fold_trunc_transparent_mathfn (exp);
6227
6228     default:
6229       break;
6230     }
6231
6232   return 0;
6233 }
6234
6235 /* Conveniently construct a function call expression.  */
6236
6237 tree
6238 build_function_call_expr (tree fn, tree arglist)
6239 {
6240   tree call_expr;
6241
6242   call_expr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
6243   call_expr = build (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)),
6244                      call_expr, arglist);
6245   return fold (call_expr);
6246 }
6247
6248 /* This function validates the types of a function call argument list
6249    represented as a tree chain of parameters against a specified list
6250    of tree_codes.  If the last specifier is a 0, that represents an
6251    ellipses, otherwise the last specifier must be a VOID_TYPE.  */
6252
6253 static int
6254 validate_arglist (tree arglist, ...)
6255 {
6256   enum tree_code code;
6257   int res = 0;
6258   va_list ap;
6259
6260   va_start (ap, arglist);
6261
6262   do
6263     {
6264       code = va_arg (ap, enum tree_code);
6265       switch (code)
6266         {
6267         case 0:
6268           /* This signifies an ellipses, any further arguments are all ok.  */
6269           res = 1;
6270           goto end;
6271         case VOID_TYPE:
6272           /* This signifies an endlink, if no arguments remain, return
6273              true, otherwise return false.  */
6274           res = arglist == 0;
6275           goto end;
6276         default:
6277           /* If no parameters remain or the parameter's code does not
6278              match the specified code, return false.  Otherwise continue
6279              checking any remaining arguments.  */
6280           if (arglist == 0
6281               || code != TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))))
6282             goto end;
6283           break;
6284         }
6285       arglist = TREE_CHAIN (arglist);
6286     }
6287   while (1);
6288
6289   /* We need gotos here since we can only have one VA_CLOSE in a
6290      function.  */
6291  end: ;
6292   va_end (ap);
6293
6294   return res;
6295 }
6296
6297 /* Default version of target-specific builtin setup that does nothing.  */
6298
6299 void
6300 default_init_builtins (void)
6301 {
6302 }
6303
6304 /* Default target-specific builtin expander that does nothing.  */
6305
6306 rtx
6307 default_expand_builtin (tree exp ATTRIBUTE_UNUSED,
6308                         rtx target ATTRIBUTE_UNUSED,
6309                         rtx subtarget ATTRIBUTE_UNUSED,
6310                         enum machine_mode mode ATTRIBUTE_UNUSED,
6311                         int ignore ATTRIBUTE_UNUSED)
6312 {
6313   return NULL_RTX;
6314 }
6315
6316 /* Instantiate all remaining CONSTANT_P_RTX nodes.  */
6317
6318 void
6319 purge_builtin_constant_p (void)
6320 {
6321   rtx insn, set, arg, new, note;
6322
6323   for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
6324     if (INSN_P (insn)
6325         && (set = single_set (insn)) != NULL_RTX
6326         && (GET_CODE (arg = SET_SRC (set)) == CONSTANT_P_RTX
6327             || (GET_CODE (arg) == SUBREG
6328                 && (GET_CODE (arg = SUBREG_REG (arg))
6329                     == CONSTANT_P_RTX))))
6330       {
6331         arg = XEXP (arg, 0);
6332         new = CONSTANT_P (arg) ? const1_rtx : const0_rtx;
6333         validate_change (insn, &SET_SRC (set), new, 0);
6334
6335         /* Remove the REG_EQUAL note from the insn.  */
6336         if ((note = find_reg_note (insn, REG_EQUAL, NULL_RTX)) != 0)
6337           remove_note (insn, note);
6338       }
6339 }
6340
6341 /* Returns true is EXP represents data that would potentially reside
6342    in a readonly section.  */
6343
6344 static bool
6345 readonly_data_expr (tree exp)
6346 {
6347   STRIP_NOPS (exp);
6348
6349   if (TREE_CODE (exp) == ADDR_EXPR)
6350     return decl_readonly_section (TREE_OPERAND (exp, 0), 0);
6351   else
6352     return false;
6353 }