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