OSDN Git Service

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