OSDN Git Service

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