builtins.c revision 237021
1/* Expand builtin functions.
2   Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3   2000, 2001, 2002, 2003, 2004, 2005, 2006 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, 51 Franklin Street, Fifth Floor, Boston, MA
2002110-1301, 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 "tree-gimple.h"
31#include "flags.h"
32#include "regs.h"
33#include "hard-reg-set.h"
34#include "except.h"
35#include "function.h"
36#include "insn-config.h"
37#include "expr.h"
38#include "optabs.h"
39#include "libfuncs.h"
40#include "recog.h"
41#include "output.h"
42#include "typeclass.h"
43#include "toplev.h"
44#include "predict.h"
45#include "tm_p.h"
46#include "target.h"
47#include "langhooks.h"
48#include "basic-block.h"
49#include "tree-mudflap.h"
50
51#ifndef PAD_VARARGS_DOWN
52#define PAD_VARARGS_DOWN BYTES_BIG_ENDIAN
53#endif
54
55/* Define the names of the builtin function types and codes.  */
56const char *const built_in_class_names[4]
57  = {"NOT_BUILT_IN", "BUILT_IN_FRONTEND", "BUILT_IN_MD", "BUILT_IN_NORMAL"};
58
59#define DEF_BUILTIN(X, N, C, T, LT, B, F, NA, AT, IM, COND) #X,
60const char * built_in_names[(int) END_BUILTINS] =
61{
62#include "builtins.def"
63};
64#undef DEF_BUILTIN
65
66/* Setup an array of _DECL trees, make sure each element is
67   initialized to NULL_TREE.  */
68tree built_in_decls[(int) END_BUILTINS];
69/* Declarations used when constructing the builtin implicitly in the compiler.
70   It may be NULL_TREE when this is invalid (for instance runtime is not
71   required to implement the function call in all cases).  */
72tree implicit_built_in_decls[(int) END_BUILTINS];
73
74static int get_pointer_alignment (tree, unsigned int);
75static const char *c_getstr (tree);
76static rtx c_readstr (const char *, enum machine_mode);
77static int target_char_cast (tree, char *);
78static rtx get_memory_rtx (tree, tree);
79static int apply_args_size (void);
80static int apply_result_size (void);
81#if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
82static rtx result_vector (int, rtx);
83#endif
84static void expand_builtin_update_setjmp_buf (rtx);
85static void expand_builtin_prefetch (tree);
86static rtx expand_builtin_apply_args (void);
87static rtx expand_builtin_apply_args_1 (void);
88static rtx expand_builtin_apply (rtx, rtx, rtx);
89static void expand_builtin_return (rtx);
90static enum type_class type_to_class (tree);
91static rtx expand_builtin_classify_type (tree);
92static void expand_errno_check (tree, rtx);
93static rtx expand_builtin_mathfn (tree, rtx, rtx);
94static rtx expand_builtin_mathfn_2 (tree, rtx, rtx);
95static rtx expand_builtin_mathfn_3 (tree, rtx, rtx);
96static rtx expand_builtin_sincos (tree);
97static rtx expand_builtin_int_roundingfn (tree, rtx, rtx);
98static rtx expand_builtin_args_info (tree);
99static rtx expand_builtin_next_arg (void);
100static rtx expand_builtin_va_start (tree);
101static rtx expand_builtin_va_end (tree);
102static rtx expand_builtin_va_copy (tree);
103static rtx expand_builtin_memcmp (tree, tree, rtx, enum machine_mode);
104static rtx expand_builtin_strcmp (tree, rtx, enum machine_mode);
105static rtx expand_builtin_strncmp (tree, rtx, enum machine_mode);
106static rtx builtin_memcpy_read_str (void *, HOST_WIDE_INT, enum machine_mode);
107static rtx expand_builtin_strcat (tree, tree, rtx, enum machine_mode);
108static rtx expand_builtin_strncat (tree, rtx, enum machine_mode);
109static rtx expand_builtin_strspn (tree, rtx, enum machine_mode);
110static rtx expand_builtin_strcspn (tree, rtx, enum machine_mode);
111static rtx expand_builtin_memcpy (tree, rtx, enum machine_mode);
112static rtx expand_builtin_mempcpy (tree, tree, rtx, enum machine_mode, int);
113static rtx expand_builtin_memmove (tree, tree, rtx, enum machine_mode, tree);
114static rtx expand_builtin_bcopy (tree);
115static rtx expand_builtin_strcpy (tree, tree, rtx, enum machine_mode);
116static rtx expand_builtin_stpcpy (tree, rtx, enum machine_mode);
117static rtx builtin_strncpy_read_str (void *, HOST_WIDE_INT, enum machine_mode);
118static rtx expand_builtin_strncpy (tree, rtx, enum machine_mode);
119static rtx builtin_memset_read_str (void *, HOST_WIDE_INT, enum machine_mode);
120static rtx builtin_memset_gen_str (void *, HOST_WIDE_INT, enum machine_mode);
121static rtx expand_builtin_memset (tree, rtx, enum machine_mode, tree);
122static rtx expand_builtin_bzero (tree);
123static rtx expand_builtin_strlen (tree, rtx, enum machine_mode);
124static rtx expand_builtin_strstr (tree, tree, rtx, enum machine_mode);
125static rtx expand_builtin_strpbrk (tree, tree, rtx, enum machine_mode);
126static rtx expand_builtin_strchr (tree, tree, rtx, enum machine_mode);
127static rtx expand_builtin_strrchr (tree, tree, rtx, enum machine_mode);
128static rtx expand_builtin_alloca (tree, rtx);
129static rtx expand_builtin_unop (enum machine_mode, tree, rtx, rtx, optab);
130static rtx expand_builtin_frame_address (tree, tree);
131static rtx expand_builtin_fputs (tree, rtx, bool);
132static rtx expand_builtin_printf (tree, rtx, enum machine_mode, bool);
133static rtx expand_builtin_fprintf (tree, rtx, enum machine_mode, bool);
134static rtx expand_builtin_sprintf (tree, rtx, enum machine_mode);
135static tree stabilize_va_list (tree, int);
136static rtx expand_builtin_expect (tree, rtx);
137static tree fold_builtin_constant_p (tree);
138static tree fold_builtin_classify_type (tree);
139static tree fold_builtin_strlen (tree);
140static tree fold_builtin_inf (tree, int);
141static tree fold_builtin_nan (tree, tree, int);
142static int validate_arglist (tree, ...);
143static bool integer_valued_real_p (tree);
144static tree fold_trunc_transparent_mathfn (tree, tree);
145static bool readonly_data_expr (tree);
146static rtx expand_builtin_fabs (tree, rtx, rtx);
147static rtx expand_builtin_signbit (tree, rtx);
148static tree fold_builtin_sqrt (tree, tree);
149static tree fold_builtin_cbrt (tree, tree);
150static tree fold_builtin_pow (tree, tree, tree);
151static tree fold_builtin_powi (tree, tree, tree);
152static tree fold_builtin_sin (tree);
153static tree fold_builtin_cos (tree, tree, tree);
154static tree fold_builtin_tan (tree);
155static tree fold_builtin_atan (tree, tree);
156static tree fold_builtin_trunc (tree, tree);
157static tree fold_builtin_floor (tree, tree);
158static tree fold_builtin_ceil (tree, tree);
159static tree fold_builtin_round (tree, tree);
160static tree fold_builtin_int_roundingfn (tree, tree);
161static tree fold_builtin_bitop (tree, tree);
162static tree fold_builtin_memory_op (tree, tree, bool, int);
163static tree fold_builtin_strchr (tree, tree);
164static tree fold_builtin_memcmp (tree);
165static tree fold_builtin_strcmp (tree);
166static tree fold_builtin_strncmp (tree);
167static tree fold_builtin_signbit (tree, tree);
168static tree fold_builtin_copysign (tree, tree, tree);
169static tree fold_builtin_isascii (tree);
170static tree fold_builtin_toascii (tree);
171static tree fold_builtin_isdigit (tree);
172static tree fold_builtin_fabs (tree, tree);
173static tree fold_builtin_abs (tree, tree);
174static tree fold_builtin_unordered_cmp (tree, tree, enum tree_code,
175					enum tree_code);
176static tree fold_builtin_1 (tree, tree, bool);
177
178static tree fold_builtin_strpbrk (tree, tree);
179static tree fold_builtin_strstr (tree, tree);
180static tree fold_builtin_strrchr (tree, tree);
181static tree fold_builtin_strcat (tree);
182static tree fold_builtin_strncat (tree);
183static tree fold_builtin_strspn (tree);
184static tree fold_builtin_strcspn (tree);
185static tree fold_builtin_sprintf (tree, int);
186
187static rtx expand_builtin_object_size (tree);
188static rtx expand_builtin_memory_chk (tree, rtx, enum machine_mode,
189				      enum built_in_function);
190static void maybe_emit_chk_warning (tree, enum built_in_function);
191static void maybe_emit_sprintf_chk_warning (tree, enum built_in_function);
192static tree fold_builtin_object_size (tree);
193static tree fold_builtin_strcat_chk (tree, tree);
194static tree fold_builtin_strncat_chk (tree, tree);
195static tree fold_builtin_sprintf_chk (tree, enum built_in_function);
196static tree fold_builtin_printf (tree, tree, bool, enum built_in_function);
197static tree fold_builtin_fprintf (tree, tree, bool, enum built_in_function);
198static bool init_target_chars (void);
199
200static unsigned HOST_WIDE_INT target_newline;
201static unsigned HOST_WIDE_INT target_percent;
202static unsigned HOST_WIDE_INT target_c;
203static unsigned HOST_WIDE_INT target_s;
204static char target_percent_c[3];
205static char target_percent_s[3];
206static char target_percent_s_newline[4];
207
208/* Return true if NODE should be considered for inline expansion regardless
209   of the optimization level.  This means whenever a function is invoked with
210   its "internal" name, which normally contains the prefix "__builtin".  */
211
212static bool called_as_built_in (tree node)
213{
214  const char *name = IDENTIFIER_POINTER (DECL_NAME (node));
215  if (strncmp (name, "__builtin_", 10) == 0)
216    return true;
217  if (strncmp (name, "__sync_", 7) == 0)
218    return true;
219  return false;
220}
221
222/* Return the alignment in bits of EXP, a pointer valued expression.
223   But don't return more than MAX_ALIGN no matter what.
224   The alignment returned is, by default, the alignment of the thing that
225   EXP points to.  If it is not a POINTER_TYPE, 0 is returned.
226
227   Otherwise, look at the expression to see if we can do better, i.e., if the
228   expression is actually pointing at an object whose alignment is tighter.  */
229
230static int
231get_pointer_alignment (tree exp, unsigned int max_align)
232{
233  unsigned int align, inner;
234
235  /* We rely on TER to compute accurate alignment information.  */
236  if (!(optimize && flag_tree_ter))
237    return 0;
238
239  if (!POINTER_TYPE_P (TREE_TYPE (exp)))
240    return 0;
241
242  align = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
243  align = MIN (align, max_align);
244
245  while (1)
246    {
247      switch (TREE_CODE (exp))
248	{
249	case NOP_EXPR:
250	case CONVERT_EXPR:
251	case NON_LVALUE_EXPR:
252	  exp = TREE_OPERAND (exp, 0);
253	  if (! POINTER_TYPE_P (TREE_TYPE (exp)))
254	    return align;
255
256	  inner = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
257	  align = MIN (inner, max_align);
258	  break;
259
260	case PLUS_EXPR:
261	  /* If sum of pointer + int, restrict our maximum alignment to that
262	     imposed by the integer.  If not, we can't do any better than
263	     ALIGN.  */
264	  if (! host_integerp (TREE_OPERAND (exp, 1), 1))
265	    return align;
266
267	  while (((tree_low_cst (TREE_OPERAND (exp, 1), 1))
268		  & (max_align / BITS_PER_UNIT - 1))
269		 != 0)
270	    max_align >>= 1;
271
272	  exp = TREE_OPERAND (exp, 0);
273	  break;
274
275	case ADDR_EXPR:
276	  /* See what we are pointing at and look at its alignment.  */
277	  exp = TREE_OPERAND (exp, 0);
278	  inner = max_align;
279	  if (handled_component_p (exp))
280	    {
281	      HOST_WIDE_INT bitsize, bitpos;
282	      tree offset;
283	      enum machine_mode mode;
284	      int unsignedp, volatilep;
285
286	      exp = get_inner_reference (exp, &bitsize, &bitpos, &offset,
287					 &mode, &unsignedp, &volatilep, true);
288	      if (bitpos)
289		inner = MIN (inner, (unsigned) (bitpos & -bitpos));
290	      if (offset && TREE_CODE (offset) == PLUS_EXPR
291		  && host_integerp (TREE_OPERAND (offset, 1), 1))
292	        {
293		  /* Any overflow in calculating offset_bits won't change
294		     the alignment.  */
295		  unsigned offset_bits
296		    = ((unsigned) tree_low_cst (TREE_OPERAND (offset, 1), 1)
297		       * BITS_PER_UNIT);
298
299		  if (offset_bits)
300		    inner = MIN (inner, (offset_bits & -offset_bits));
301		  offset = TREE_OPERAND (offset, 0);
302		}
303	      if (offset && TREE_CODE (offset) == MULT_EXPR
304		  && host_integerp (TREE_OPERAND (offset, 1), 1))
305	        {
306		  /* Any overflow in calculating offset_factor won't change
307		     the alignment.  */
308		  unsigned offset_factor
309		    = ((unsigned) tree_low_cst (TREE_OPERAND (offset, 1), 1)
310		       * BITS_PER_UNIT);
311
312		  if (offset_factor)
313		    inner = MIN (inner, (offset_factor & -offset_factor));
314		}
315	      else if (offset)
316		inner = MIN (inner, BITS_PER_UNIT);
317	    }
318	  if (TREE_CODE (exp) == FUNCTION_DECL)
319	    align = FUNCTION_BOUNDARY;
320	  else if (DECL_P (exp))
321	    align = MIN (inner, DECL_ALIGN (exp));
322#ifdef CONSTANT_ALIGNMENT
323	  else if (CONSTANT_CLASS_P (exp))
324	    align = MIN (inner, (unsigned)CONSTANT_ALIGNMENT (exp, align));
325#endif
326	  else if (TREE_CODE (exp) == VIEW_CONVERT_EXPR
327		   || TREE_CODE (exp) == INDIRECT_REF)
328	    align = MIN (TYPE_ALIGN (TREE_TYPE (exp)), inner);
329	  else
330	    align = MIN (align, inner);
331	  return MIN (align, max_align);
332
333	default:
334	  return align;
335	}
336    }
337}
338
339/* Compute the length of a C string.  TREE_STRING_LENGTH is not the right
340   way, because it could contain a zero byte in the middle.
341   TREE_STRING_LENGTH is the size of the character array, not the string.
342
343   ONLY_VALUE should be nonzero if the result is not going to be emitted
344   into the instruction stream and zero if it is going to be expanded.
345   E.g. with i++ ? "foo" : "bar", if ONLY_VALUE is nonzero, constant 3
346   is returned, otherwise NULL, since
347   len = c_strlen (src, 1); if (len) expand_expr (len, ...); would not
348   evaluate the side-effects.
349
350   The value returned is of type `ssizetype'.
351
352   Unfortunately, string_constant can't access the values of const char
353   arrays with initializers, so neither can we do so here.  */
354
355tree
356c_strlen (tree src, int only_value)
357{
358  tree offset_node;
359  HOST_WIDE_INT offset;
360  int max;
361  const char *ptr;
362
363  STRIP_NOPS (src);
364  if (TREE_CODE (src) == COND_EXPR
365      && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0))))
366    {
367      tree len1, len2;
368
369      len1 = c_strlen (TREE_OPERAND (src, 1), only_value);
370      len2 = c_strlen (TREE_OPERAND (src, 2), only_value);
371      if (tree_int_cst_equal (len1, len2))
372	return len1;
373    }
374
375  if (TREE_CODE (src) == COMPOUND_EXPR
376      && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0))))
377    return c_strlen (TREE_OPERAND (src, 1), only_value);
378
379  src = string_constant (src, &offset_node);
380  if (src == 0)
381    return 0;
382
383  max = TREE_STRING_LENGTH (src) - 1;
384  ptr = TREE_STRING_POINTER (src);
385
386  if (offset_node && TREE_CODE (offset_node) != INTEGER_CST)
387    {
388      /* If the string has an internal zero byte (e.g., "foo\0bar"), we can't
389	 compute the offset to the following null if we don't know where to
390	 start searching for it.  */
391      int i;
392
393      for (i = 0; i < max; i++)
394	if (ptr[i] == 0)
395	  return 0;
396
397      /* We don't know the starting offset, but we do know that the string
398	 has no internal zero bytes.  We can assume that the offset falls
399	 within the bounds of the string; otherwise, the programmer deserves
400	 what he gets.  Subtract the offset from the length of the string,
401	 and return that.  This would perhaps not be valid if we were dealing
402	 with named arrays in addition to literal string constants.  */
403
404      return size_diffop (size_int (max), offset_node);
405    }
406
407  /* We have a known offset into the string.  Start searching there for
408     a null character if we can represent it as a single HOST_WIDE_INT.  */
409  if (offset_node == 0)
410    offset = 0;
411  else if (! host_integerp (offset_node, 0))
412    offset = -1;
413  else
414    offset = tree_low_cst (offset_node, 0);
415
416  /* If the offset is known to be out of bounds, warn, and call strlen at
417     runtime.  */
418  if (offset < 0 || offset > max)
419    {
420      warning (0, "offset outside bounds of constant string");
421      return 0;
422    }
423
424  /* Use strlen to search for the first zero byte.  Since any strings
425     constructed with build_string will have nulls appended, we win even
426     if we get handed something like (char[4])"abcd".
427
428     Since OFFSET is our starting index into the string, no further
429     calculation is needed.  */
430  return ssize_int (strlen (ptr + offset));
431}
432
433/* Return a char pointer for a C string if it is a string constant
434   or sum of string constant and integer constant.  */
435
436static const char *
437c_getstr (tree src)
438{
439  tree offset_node;
440
441  src = string_constant (src, &offset_node);
442  if (src == 0)
443    return 0;
444
445  if (offset_node == 0)
446    return TREE_STRING_POINTER (src);
447  else if (!host_integerp (offset_node, 1)
448	   || compare_tree_int (offset_node, TREE_STRING_LENGTH (src) - 1) > 0)
449    return 0;
450
451  return TREE_STRING_POINTER (src) + tree_low_cst (offset_node, 1);
452}
453
454/* Return a CONST_INT or CONST_DOUBLE corresponding to target reading
455   GET_MODE_BITSIZE (MODE) bits from string constant STR.  */
456
457static rtx
458c_readstr (const char *str, enum machine_mode mode)
459{
460  HOST_WIDE_INT c[2];
461  HOST_WIDE_INT ch;
462  unsigned int i, j;
463
464  gcc_assert (GET_MODE_CLASS (mode) == MODE_INT);
465
466  c[0] = 0;
467  c[1] = 0;
468  ch = 1;
469  for (i = 0; i < GET_MODE_SIZE (mode); i++)
470    {
471      j = i;
472      if (WORDS_BIG_ENDIAN)
473	j = GET_MODE_SIZE (mode) - i - 1;
474      if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN
475	  && GET_MODE_SIZE (mode) > UNITS_PER_WORD)
476	j = j + UNITS_PER_WORD - 2 * (j % UNITS_PER_WORD) - 1;
477      j *= BITS_PER_UNIT;
478      gcc_assert (j <= 2 * HOST_BITS_PER_WIDE_INT);
479
480      if (ch)
481	ch = (unsigned char) str[i];
482      c[j / HOST_BITS_PER_WIDE_INT] |= ch << (j % HOST_BITS_PER_WIDE_INT);
483    }
484  return immed_double_const (c[0], c[1], mode);
485}
486
487/* Cast a target constant CST to target CHAR and if that value fits into
488   host char type, return zero and put that value into variable pointed to by
489   P.  */
490
491static int
492target_char_cast (tree cst, char *p)
493{
494  unsigned HOST_WIDE_INT val, hostval;
495
496  if (!host_integerp (cst, 1)
497      || CHAR_TYPE_SIZE > HOST_BITS_PER_WIDE_INT)
498    return 1;
499
500  val = tree_low_cst (cst, 1);
501  if (CHAR_TYPE_SIZE < HOST_BITS_PER_WIDE_INT)
502    val &= (((unsigned HOST_WIDE_INT) 1) << CHAR_TYPE_SIZE) - 1;
503
504  hostval = val;
505  if (HOST_BITS_PER_CHAR < HOST_BITS_PER_WIDE_INT)
506    hostval &= (((unsigned HOST_WIDE_INT) 1) << HOST_BITS_PER_CHAR) - 1;
507
508  if (val != hostval)
509    return 1;
510
511  *p = hostval;
512  return 0;
513}
514
515/* Similar to save_expr, but assumes that arbitrary code is not executed
516   in between the multiple evaluations.  In particular, we assume that a
517   non-addressable local variable will not be modified.  */
518
519static tree
520builtin_save_expr (tree exp)
521{
522  if (TREE_ADDRESSABLE (exp) == 0
523      && (TREE_CODE (exp) == PARM_DECL
524	  || (TREE_CODE (exp) == VAR_DECL && !TREE_STATIC (exp))))
525    return exp;
526
527  return save_expr (exp);
528}
529
530/* Given TEM, a pointer to a stack frame, follow the dynamic chain COUNT
531   times to get the address of either a higher stack frame, or a return
532   address located within it (depending on FNDECL_CODE).  */
533
534static rtx
535expand_builtin_return_addr (enum built_in_function fndecl_code, int count)
536{
537  int i;
538
539#ifdef INITIAL_FRAME_ADDRESS_RTX
540  rtx tem = INITIAL_FRAME_ADDRESS_RTX;
541#else
542  rtx tem;
543
544  /* For a zero count with __builtin_return_address, we don't care what
545     frame address we return, because target-specific definitions will
546     override us.  Therefore frame pointer elimination is OK, and using
547     the soft frame pointer is OK.
548
549     For a non-zero count, or a zero count with __builtin_frame_address,
550     we require a stable offset from the current frame pointer to the
551     previous one, so we must use the hard frame pointer, and
552     we must disable frame pointer elimination.  */
553  if (count == 0 && fndecl_code == BUILT_IN_RETURN_ADDRESS)
554    tem = frame_pointer_rtx;
555  else
556    {
557      tem = hard_frame_pointer_rtx;
558
559      /* Tell reload not to eliminate the frame pointer.  */
560      current_function_accesses_prior_frames = 1;
561    }
562#endif
563
564  /* Some machines need special handling before we can access
565     arbitrary frames.  For example, on the SPARC, we must first flush
566     all register windows to the stack.  */
567#ifdef SETUP_FRAME_ADDRESSES
568  if (count > 0)
569    SETUP_FRAME_ADDRESSES ();
570#endif
571
572  /* On the SPARC, the return address is not in the frame, it is in a
573     register.  There is no way to access it off of the current frame
574     pointer, but it can be accessed off the previous frame pointer by
575     reading the value from the register window save area.  */
576#ifdef RETURN_ADDR_IN_PREVIOUS_FRAME
577  if (fndecl_code == BUILT_IN_RETURN_ADDRESS)
578    count--;
579#endif
580
581  /* Scan back COUNT frames to the specified frame.  */
582  for (i = 0; i < count; i++)
583    {
584      /* Assume the dynamic chain pointer is in the word that the
585	 frame address points to, unless otherwise specified.  */
586#ifdef DYNAMIC_CHAIN_ADDRESS
587      tem = DYNAMIC_CHAIN_ADDRESS (tem);
588#endif
589      tem = memory_address (Pmode, tem);
590      tem = gen_frame_mem (Pmode, tem);
591      tem = copy_to_reg (tem);
592    }
593
594  /* For __builtin_frame_address, return what we've got.  But, on
595     the SPARC for example, we may have to add a bias.  */
596  if (fndecl_code == BUILT_IN_FRAME_ADDRESS)
597#ifdef FRAME_ADDR_RTX
598    return FRAME_ADDR_RTX (tem);
599#else
600    return tem;
601#endif
602
603  /* For __builtin_return_address, get the return address from that frame.  */
604#ifdef RETURN_ADDR_RTX
605  tem = RETURN_ADDR_RTX (count, tem);
606#else
607  tem = memory_address (Pmode,
608			plus_constant (tem, GET_MODE_SIZE (Pmode)));
609  tem = gen_frame_mem (Pmode, tem);
610#endif
611  return tem;
612}
613
614/* Alias set used for setjmp buffer.  */
615static HOST_WIDE_INT setjmp_alias_set = -1;
616
617/* Construct the leading half of a __builtin_setjmp call.  Control will
618   return to RECEIVER_LABEL.  This is also called directly by the SJLJ
619   exception handling code.  */
620
621void
622expand_builtin_setjmp_setup (rtx buf_addr, rtx receiver_label)
623{
624  enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
625  rtx stack_save;
626  rtx mem;
627
628  if (setjmp_alias_set == -1)
629    setjmp_alias_set = new_alias_set ();
630
631  buf_addr = convert_memory_address (Pmode, buf_addr);
632
633  buf_addr = force_reg (Pmode, force_operand (buf_addr, NULL_RTX));
634
635  /* We store the frame pointer and the address of receiver_label in
636     the buffer and use the rest of it for the stack save area, which
637     is machine-dependent.  */
638
639  mem = gen_rtx_MEM (Pmode, buf_addr);
640  set_mem_alias_set (mem, setjmp_alias_set);
641  emit_move_insn (mem, targetm.builtin_setjmp_frame_value ());
642
643  mem = gen_rtx_MEM (Pmode, plus_constant (buf_addr, GET_MODE_SIZE (Pmode))),
644  set_mem_alias_set (mem, setjmp_alias_set);
645
646  emit_move_insn (validize_mem (mem),
647		  force_reg (Pmode, gen_rtx_LABEL_REF (Pmode, receiver_label)));
648
649  stack_save = gen_rtx_MEM (sa_mode,
650			    plus_constant (buf_addr,
651					   2 * GET_MODE_SIZE (Pmode)));
652  set_mem_alias_set (stack_save, setjmp_alias_set);
653  emit_stack_save (SAVE_NONLOCAL, &stack_save, NULL_RTX);
654
655  /* If there is further processing to do, do it.  */
656#ifdef HAVE_builtin_setjmp_setup
657  if (HAVE_builtin_setjmp_setup)
658    emit_insn (gen_builtin_setjmp_setup (buf_addr));
659#endif
660
661  /* Tell optimize_save_area_alloca that extra work is going to
662     need to go on during alloca.  */
663  current_function_calls_setjmp = 1;
664
665  /* Set this so all the registers get saved in our frame; we need to be
666     able to copy the saved values for any registers from frames we unwind.  */
667  current_function_has_nonlocal_label = 1;
668}
669
670/* Construct the trailing part of a __builtin_setjmp call.  This is
671   also called directly by the SJLJ exception handling code.  */
672
673void
674expand_builtin_setjmp_receiver (rtx receiver_label ATTRIBUTE_UNUSED)
675{
676  /* Clobber the FP when we get here, so we have to make sure it's
677     marked as used by this function.  */
678  emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
679
680  /* Mark the static chain as clobbered here so life information
681     doesn't get messed up for it.  */
682  emit_insn (gen_rtx_CLOBBER (VOIDmode, static_chain_rtx));
683
684  /* Now put in the code to restore the frame pointer, and argument
685     pointer, if needed.  */
686#ifdef HAVE_nonlocal_goto
687  if (! HAVE_nonlocal_goto)
688#endif
689    {
690      emit_move_insn (virtual_stack_vars_rtx, hard_frame_pointer_rtx);
691      /* This might change the hard frame pointer in ways that aren't
692	 apparent to early optimization passes, so force a clobber.  */
693      emit_insn (gen_rtx_CLOBBER (VOIDmode, hard_frame_pointer_rtx));
694    }
695
696#if ARG_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
697  if (fixed_regs[ARG_POINTER_REGNUM])
698    {
699#ifdef ELIMINABLE_REGS
700      size_t i;
701      static const struct elims {const int from, to;} elim_regs[] = ELIMINABLE_REGS;
702
703      for (i = 0; i < ARRAY_SIZE (elim_regs); i++)
704	if (elim_regs[i].from == ARG_POINTER_REGNUM
705	    && elim_regs[i].to == HARD_FRAME_POINTER_REGNUM)
706	  break;
707
708      if (i == ARRAY_SIZE (elim_regs))
709#endif
710	{
711	  /* Now restore our arg pointer from the address at which it
712	     was saved in our stack frame.  */
713	  emit_move_insn (virtual_incoming_args_rtx,
714			  copy_to_reg (get_arg_pointer_save_area (cfun)));
715	}
716    }
717#endif
718
719#ifdef HAVE_builtin_setjmp_receiver
720  if (HAVE_builtin_setjmp_receiver)
721    emit_insn (gen_builtin_setjmp_receiver (receiver_label));
722  else
723#endif
724#ifdef HAVE_nonlocal_goto_receiver
725    if (HAVE_nonlocal_goto_receiver)
726      emit_insn (gen_nonlocal_goto_receiver ());
727    else
728#endif
729      { /* Nothing */ }
730
731  /* @@@ This is a kludge.  Not all machine descriptions define a blockage
732     insn, but we must not allow the code we just generated to be reordered
733     by scheduling.  Specifically, the update of the frame pointer must
734     happen immediately, not later.  So emit an ASM_INPUT to act as blockage
735     insn.  */
736  emit_insn (gen_rtx_ASM_INPUT (VOIDmode, ""));
737}
738
739/* __builtin_longjmp is passed a pointer to an array of five words (not
740   all will be used on all machines).  It operates similarly to the C
741   library function of the same name, but is more efficient.  Much of
742   the code below is copied from the handling of non-local gotos.  */
743
744static void
745expand_builtin_longjmp (rtx buf_addr, rtx value)
746{
747  rtx fp, lab, stack, insn, last;
748  enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
749
750  if (setjmp_alias_set == -1)
751    setjmp_alias_set = new_alias_set ();
752
753  buf_addr = convert_memory_address (Pmode, buf_addr);
754
755  buf_addr = force_reg (Pmode, buf_addr);
756
757  /* We used to store value in static_chain_rtx, but that fails if pointers
758     are smaller than integers.  We instead require that the user must pass
759     a second argument of 1, because that is what builtin_setjmp will
760     return.  This also makes EH slightly more efficient, since we are no
761     longer copying around a value that we don't care about.  */
762  gcc_assert (value == const1_rtx);
763
764  last = get_last_insn ();
765#ifdef HAVE_builtin_longjmp
766  if (HAVE_builtin_longjmp)
767    emit_insn (gen_builtin_longjmp (buf_addr));
768  else
769#endif
770    {
771      fp = gen_rtx_MEM (Pmode, buf_addr);
772      lab = gen_rtx_MEM (Pmode, plus_constant (buf_addr,
773					       GET_MODE_SIZE (Pmode)));
774
775      stack = gen_rtx_MEM (sa_mode, plus_constant (buf_addr,
776						   2 * GET_MODE_SIZE (Pmode)));
777      set_mem_alias_set (fp, setjmp_alias_set);
778      set_mem_alias_set (lab, setjmp_alias_set);
779      set_mem_alias_set (stack, setjmp_alias_set);
780
781      /* Pick up FP, label, and SP from the block and jump.  This code is
782	 from expand_goto in stmt.c; see there for detailed comments.  */
783#ifdef HAVE_nonlocal_goto
784      if (HAVE_nonlocal_goto)
785	/* We have to pass a value to the nonlocal_goto pattern that will
786	   get copied into the static_chain pointer, but it does not matter
787	   what that value is, because builtin_setjmp does not use it.  */
788	emit_insn (gen_nonlocal_goto (value, lab, stack, fp));
789      else
790#endif
791	{
792	  lab = copy_to_reg (lab);
793
794	  emit_insn (gen_rtx_CLOBBER (VOIDmode,
795				      gen_rtx_MEM (BLKmode,
796						   gen_rtx_SCRATCH (VOIDmode))));
797	  emit_insn (gen_rtx_CLOBBER (VOIDmode,
798				      gen_rtx_MEM (BLKmode,
799						   hard_frame_pointer_rtx)));
800
801	  emit_move_insn (hard_frame_pointer_rtx, fp);
802	  emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
803
804	  emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
805	  emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
806	  emit_indirect_jump (lab);
807	}
808    }
809
810  /* Search backwards and mark the jump insn as a non-local goto.
811     Note that this precludes the use of __builtin_longjmp to a
812     __builtin_setjmp target in the same function.  However, we've
813     already cautioned the user that these functions are for
814     internal exception handling use only.  */
815  for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
816    {
817      gcc_assert (insn != last);
818
819      if (JUMP_P (insn))
820	{
821	  REG_NOTES (insn) = alloc_EXPR_LIST (REG_NON_LOCAL_GOTO, const0_rtx,
822					      REG_NOTES (insn));
823	  break;
824	}
825      else if (CALL_P (insn))
826	break;
827    }
828}
829
830/* Expand a call to __builtin_nonlocal_goto.  We're passed the target label
831   and the address of the save area.  */
832
833static rtx
834expand_builtin_nonlocal_goto (tree arglist)
835{
836  tree t_label, t_save_area;
837  rtx r_label, r_save_area, r_fp, r_sp, insn;
838
839  if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
840    return NULL_RTX;
841
842  t_label = TREE_VALUE (arglist);
843  arglist = TREE_CHAIN (arglist);
844  t_save_area = TREE_VALUE (arglist);
845
846  r_label = expand_normal (t_label);
847  r_label = convert_memory_address (Pmode, r_label);
848  r_save_area = expand_normal (t_save_area);
849  r_save_area = convert_memory_address (Pmode, r_save_area);
850  r_fp = gen_rtx_MEM (Pmode, r_save_area);
851  r_sp = gen_rtx_MEM (STACK_SAVEAREA_MODE (SAVE_NONLOCAL),
852		      plus_constant (r_save_area, GET_MODE_SIZE (Pmode)));
853
854  current_function_has_nonlocal_goto = 1;
855
856#ifdef HAVE_nonlocal_goto
857  /* ??? We no longer need to pass the static chain value, afaik.  */
858  if (HAVE_nonlocal_goto)
859    emit_insn (gen_nonlocal_goto (const0_rtx, r_label, r_sp, r_fp));
860  else
861#endif
862    {
863      r_label = copy_to_reg (r_label);
864
865      emit_insn (gen_rtx_CLOBBER (VOIDmode,
866				  gen_rtx_MEM (BLKmode,
867					       gen_rtx_SCRATCH (VOIDmode))));
868
869      emit_insn (gen_rtx_CLOBBER (VOIDmode,
870				  gen_rtx_MEM (BLKmode,
871					       hard_frame_pointer_rtx)));
872
873      /* Restore frame pointer for containing function.
874	 This sets the actual hard register used for the frame pointer
875	 to the location of the function's incoming static chain info.
876	 The non-local goto handler will then adjust it to contain the
877	 proper value and reload the argument pointer, if needed.  */
878      emit_move_insn (hard_frame_pointer_rtx, r_fp);
879      emit_stack_restore (SAVE_NONLOCAL, r_sp, NULL_RTX);
880
881      /* USE of hard_frame_pointer_rtx added for consistency;
882	 not clear if really needed.  */
883      emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
884      emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
885      emit_indirect_jump (r_label);
886    }
887
888  /* Search backwards to the jump insn and mark it as a
889     non-local goto.  */
890  for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
891    {
892      if (JUMP_P (insn))
893	{
894	  REG_NOTES (insn) = alloc_EXPR_LIST (REG_NON_LOCAL_GOTO,
895					      const0_rtx, REG_NOTES (insn));
896	  break;
897	}
898      else if (CALL_P (insn))
899	break;
900    }
901
902  return const0_rtx;
903}
904
905/* __builtin_update_setjmp_buf is passed a pointer to an array of five words
906   (not all will be used on all machines) that was passed to __builtin_setjmp.
907   It updates the stack pointer in that block to correspond to the current
908   stack pointer.  */
909
910static void
911expand_builtin_update_setjmp_buf (rtx buf_addr)
912{
913  enum machine_mode sa_mode = Pmode;
914  rtx stack_save;
915
916
917#ifdef HAVE_save_stack_nonlocal
918  if (HAVE_save_stack_nonlocal)
919    sa_mode = insn_data[(int) CODE_FOR_save_stack_nonlocal].operand[0].mode;
920#endif
921#ifdef STACK_SAVEAREA_MODE
922  sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
923#endif
924
925  stack_save
926    = gen_rtx_MEM (sa_mode,
927		   memory_address
928		   (sa_mode,
929		    plus_constant (buf_addr, 2 * GET_MODE_SIZE (Pmode))));
930
931#ifdef HAVE_setjmp
932  if (HAVE_setjmp)
933    emit_insn (gen_setjmp ());
934#endif
935
936  emit_stack_save (SAVE_NONLOCAL, &stack_save, NULL_RTX);
937}
938
939/* Expand a call to __builtin_prefetch.  For a target that does not support
940   data prefetch, evaluate the memory address argument in case it has side
941   effects.  */
942
943static void
944expand_builtin_prefetch (tree arglist)
945{
946  tree arg0, arg1, arg2;
947  rtx op0, op1, op2;
948
949  if (!validate_arglist (arglist, POINTER_TYPE, 0))
950    return;
951
952  arg0 = TREE_VALUE (arglist);
953  /* Arguments 1 and 2 are optional; argument 1 (read/write) defaults to
954     zero (read) and argument 2 (locality) defaults to 3 (high degree of
955     locality).  */
956  if (TREE_CHAIN (arglist))
957    {
958      arg1 = TREE_VALUE (TREE_CHAIN (arglist));
959      if (TREE_CHAIN (TREE_CHAIN (arglist)))
960	arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
961      else
962	arg2 = build_int_cst (NULL_TREE, 3);
963    }
964  else
965    {
966      arg1 = integer_zero_node;
967      arg2 = build_int_cst (NULL_TREE, 3);
968    }
969
970  /* Argument 0 is an address.  */
971  op0 = expand_expr (arg0, NULL_RTX, Pmode, EXPAND_NORMAL);
972
973  /* Argument 1 (read/write flag) must be a compile-time constant int.  */
974  if (TREE_CODE (arg1) != INTEGER_CST)
975    {
976      error ("second argument to %<__builtin_prefetch%> must be a constant");
977      arg1 = integer_zero_node;
978    }
979  op1 = expand_normal (arg1);
980  /* Argument 1 must be either zero or one.  */
981  if (INTVAL (op1) != 0 && INTVAL (op1) != 1)
982    {
983      warning (0, "invalid second argument to %<__builtin_prefetch%>;"
984	       " using zero");
985      op1 = const0_rtx;
986    }
987
988  /* Argument 2 (locality) must be a compile-time constant int.  */
989  if (TREE_CODE (arg2) != INTEGER_CST)
990    {
991      error ("third argument to %<__builtin_prefetch%> must be a constant");
992      arg2 = integer_zero_node;
993    }
994  op2 = expand_normal (arg2);
995  /* Argument 2 must be 0, 1, 2, or 3.  */
996  if (INTVAL (op2) < 0 || INTVAL (op2) > 3)
997    {
998      warning (0, "invalid third argument to %<__builtin_prefetch%>; using zero");
999      op2 = const0_rtx;
1000    }
1001
1002#ifdef HAVE_prefetch
1003  if (HAVE_prefetch)
1004    {
1005      if ((! (*insn_data[(int) CODE_FOR_prefetch].operand[0].predicate)
1006	     (op0,
1007	      insn_data[(int) CODE_FOR_prefetch].operand[0].mode))
1008	  || (GET_MODE (op0) != Pmode))
1009	{
1010	  op0 = convert_memory_address (Pmode, op0);
1011	  op0 = force_reg (Pmode, op0);
1012	}
1013      emit_insn (gen_prefetch (op0, op1, op2));
1014    }
1015#endif
1016
1017  /* Don't do anything with direct references to volatile memory, but
1018     generate code to handle other side effects.  */
1019  if (!MEM_P (op0) && side_effects_p (op0))
1020    emit_insn (op0);
1021}
1022
1023/* Get a MEM rtx for expression EXP which is the address of an operand
1024   to be used in a string instruction (cmpstrsi, movmemsi, ..).  LEN is
1025   the maximum length of the block of memory that might be accessed or
1026   NULL if unknown.  */
1027
1028static rtx
1029get_memory_rtx (tree exp, tree len)
1030{
1031  rtx addr = expand_expr (exp, NULL_RTX, ptr_mode, EXPAND_NORMAL);
1032  rtx mem = gen_rtx_MEM (BLKmode, memory_address (BLKmode, addr));
1033
1034  /* Get an expression we can use to find the attributes to assign to MEM.
1035     If it is an ADDR_EXPR, use the operand.  Otherwise, dereference it if
1036     we can.  First remove any nops.  */
1037  while ((TREE_CODE (exp) == NOP_EXPR || TREE_CODE (exp) == CONVERT_EXPR
1038	  || TREE_CODE (exp) == NON_LVALUE_EXPR)
1039	 && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (exp, 0))))
1040    exp = TREE_OPERAND (exp, 0);
1041
1042  if (TREE_CODE (exp) == ADDR_EXPR)
1043    exp = TREE_OPERAND (exp, 0);
1044  else if (POINTER_TYPE_P (TREE_TYPE (exp)))
1045    exp = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (exp)), exp);
1046  else
1047    exp = NULL;
1048
1049  /* Honor attributes derived from exp, except for the alias set
1050     (as builtin stringops may alias with anything) and the size
1051     (as stringops may access multiple array elements).  */
1052  if (exp)
1053    {
1054      set_mem_attributes (mem, exp, 0);
1055
1056      /* Allow the string and memory builtins to overflow from one
1057	 field into another, see http://gcc.gnu.org/PR23561.
1058	 Thus avoid COMPONENT_REFs in MEM_EXPR unless we know the whole
1059	 memory accessed by the string or memory builtin will fit
1060	 within the field.  */
1061      if (MEM_EXPR (mem) && TREE_CODE (MEM_EXPR (mem)) == COMPONENT_REF)
1062	{
1063	  tree mem_expr = MEM_EXPR (mem);
1064	  HOST_WIDE_INT offset = -1, length = -1;
1065	  tree inner = exp;
1066
1067	  while (TREE_CODE (inner) == ARRAY_REF
1068		 || TREE_CODE (inner) == NOP_EXPR
1069		 || TREE_CODE (inner) == CONVERT_EXPR
1070		 || TREE_CODE (inner) == NON_LVALUE_EXPR
1071		 || TREE_CODE (inner) == VIEW_CONVERT_EXPR
1072		 || TREE_CODE (inner) == SAVE_EXPR)
1073	    inner = TREE_OPERAND (inner, 0);
1074
1075	  gcc_assert (TREE_CODE (inner) == COMPONENT_REF);
1076
1077	  if (MEM_OFFSET (mem)
1078	      && GET_CODE (MEM_OFFSET (mem)) == CONST_INT)
1079	    offset = INTVAL (MEM_OFFSET (mem));
1080
1081	  if (offset >= 0 && len && host_integerp (len, 0))
1082	    length = tree_low_cst (len, 0);
1083
1084	  while (TREE_CODE (inner) == COMPONENT_REF)
1085	    {
1086	      tree field = TREE_OPERAND (inner, 1);
1087	      gcc_assert (! DECL_BIT_FIELD (field));
1088	      gcc_assert (TREE_CODE (mem_expr) == COMPONENT_REF);
1089	      gcc_assert (field == TREE_OPERAND (mem_expr, 1));
1090
1091	      if (length >= 0
1092		  && TYPE_SIZE_UNIT (TREE_TYPE (inner))
1093		  && host_integerp (TYPE_SIZE_UNIT (TREE_TYPE (inner)), 0))
1094		{
1095		  HOST_WIDE_INT size
1096		    = tree_low_cst (TYPE_SIZE_UNIT (TREE_TYPE (inner)), 0);
1097		  /* If we can prove the memory starting at XEXP (mem, 0)
1098		     and ending at XEXP (mem, 0) + LENGTH will fit into
1099		     this field, we can keep that COMPONENT_REF in MEM_EXPR.  */
1100		  if (offset <= size
1101		      && length <= size
1102		      && offset + length <= size)
1103		    break;
1104		}
1105
1106	      if (offset >= 0
1107		  && host_integerp (DECL_FIELD_OFFSET (field), 0))
1108		offset += tree_low_cst (DECL_FIELD_OFFSET (field), 0)
1109			  + tree_low_cst (DECL_FIELD_BIT_OFFSET (field), 1)
1110			    / BITS_PER_UNIT;
1111	      else
1112		{
1113		  offset = -1;
1114		  length = -1;
1115		}
1116
1117	      mem_expr = TREE_OPERAND (mem_expr, 0);
1118	      inner = TREE_OPERAND (inner, 0);
1119	    }
1120
1121	  if (mem_expr == NULL)
1122	    offset = -1;
1123	  if (mem_expr != MEM_EXPR (mem))
1124	    {
1125	      set_mem_expr (mem, mem_expr);
1126	      set_mem_offset (mem, offset >= 0 ? GEN_INT (offset) : NULL_RTX);
1127	    }
1128	}
1129      set_mem_alias_set (mem, 0);
1130      set_mem_size (mem, NULL_RTX);
1131    }
1132
1133  return mem;
1134}
1135
1136/* Built-in functions to perform an untyped call and return.  */
1137
1138/* For each register that may be used for calling a function, this
1139   gives a mode used to copy the register's value.  VOIDmode indicates
1140   the register is not used for calling a function.  If the machine
1141   has register windows, this gives only the outbound registers.
1142   INCOMING_REGNO gives the corresponding inbound register.  */
1143static enum machine_mode apply_args_mode[FIRST_PSEUDO_REGISTER];
1144
1145/* For each register that may be used for returning values, this gives
1146   a mode used to copy the register's value.  VOIDmode indicates the
1147   register is not used for returning values.  If the machine has
1148   register windows, this gives only the outbound registers.
1149   INCOMING_REGNO gives the corresponding inbound register.  */
1150static enum machine_mode apply_result_mode[FIRST_PSEUDO_REGISTER];
1151
1152/* For each register that may be used for calling a function, this
1153   gives the offset of that register into the block returned by
1154   __builtin_apply_args.  0 indicates that the register is not
1155   used for calling a function.  */
1156static int apply_args_reg_offset[FIRST_PSEUDO_REGISTER];
1157
1158/* Return the size required for the block returned by __builtin_apply_args,
1159   and initialize apply_args_mode.  */
1160
1161static int
1162apply_args_size (void)
1163{
1164  static int size = -1;
1165  int align;
1166  unsigned int regno;
1167  enum machine_mode mode;
1168
1169  /* The values computed by this function never change.  */
1170  if (size < 0)
1171    {
1172      /* The first value is the incoming arg-pointer.  */
1173      size = GET_MODE_SIZE (Pmode);
1174
1175      /* The second value is the structure value address unless this is
1176	 passed as an "invisible" first argument.  */
1177      if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0))
1178	size += GET_MODE_SIZE (Pmode);
1179
1180      for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1181	if (FUNCTION_ARG_REGNO_P (regno))
1182	  {
1183	    mode = reg_raw_mode[regno];
1184
1185	    gcc_assert (mode != VOIDmode);
1186
1187	    align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1188	    if (size % align != 0)
1189	      size = CEIL (size, align) * align;
1190	    apply_args_reg_offset[regno] = size;
1191	    size += GET_MODE_SIZE (mode);
1192	    apply_args_mode[regno] = mode;
1193	  }
1194	else
1195	  {
1196	    apply_args_mode[regno] = VOIDmode;
1197	    apply_args_reg_offset[regno] = 0;
1198	  }
1199    }
1200  return size;
1201}
1202
1203/* Return the size required for the block returned by __builtin_apply,
1204   and initialize apply_result_mode.  */
1205
1206static int
1207apply_result_size (void)
1208{
1209  static int size = -1;
1210  int align, regno;
1211  enum machine_mode mode;
1212
1213  /* The values computed by this function never change.  */
1214  if (size < 0)
1215    {
1216      size = 0;
1217
1218      for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1219	if (FUNCTION_VALUE_REGNO_P (regno))
1220	  {
1221	    mode = reg_raw_mode[regno];
1222
1223	    gcc_assert (mode != VOIDmode);
1224
1225	    align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1226	    if (size % align != 0)
1227	      size = CEIL (size, align) * align;
1228	    size += GET_MODE_SIZE (mode);
1229	    apply_result_mode[regno] = mode;
1230	  }
1231	else
1232	  apply_result_mode[regno] = VOIDmode;
1233
1234      /* Allow targets that use untyped_call and untyped_return to override
1235	 the size so that machine-specific information can be stored here.  */
1236#ifdef APPLY_RESULT_SIZE
1237      size = APPLY_RESULT_SIZE;
1238#endif
1239    }
1240  return size;
1241}
1242
1243#if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
1244/* Create a vector describing the result block RESULT.  If SAVEP is true,
1245   the result block is used to save the values; otherwise it is used to
1246   restore the values.  */
1247
1248static rtx
1249result_vector (int savep, rtx result)
1250{
1251  int regno, size, align, nelts;
1252  enum machine_mode mode;
1253  rtx reg, mem;
1254  rtx *savevec = alloca (FIRST_PSEUDO_REGISTER * sizeof (rtx));
1255
1256  size = nelts = 0;
1257  for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1258    if ((mode = apply_result_mode[regno]) != VOIDmode)
1259      {
1260	align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1261	if (size % align != 0)
1262	  size = CEIL (size, align) * align;
1263	reg = gen_rtx_REG (mode, savep ? regno : INCOMING_REGNO (regno));
1264	mem = adjust_address (result, mode, size);
1265	savevec[nelts++] = (savep
1266			    ? gen_rtx_SET (VOIDmode, mem, reg)
1267			    : gen_rtx_SET (VOIDmode, reg, mem));
1268	size += GET_MODE_SIZE (mode);
1269      }
1270  return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (nelts, savevec));
1271}
1272#endif /* HAVE_untyped_call or HAVE_untyped_return */
1273
1274/* Save the state required to perform an untyped call with the same
1275   arguments as were passed to the current function.  */
1276
1277static rtx
1278expand_builtin_apply_args_1 (void)
1279{
1280  rtx registers, tem;
1281  int size, align, regno;
1282  enum machine_mode mode;
1283  rtx struct_incoming_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 1);
1284
1285  /* Create a block where the arg-pointer, structure value address,
1286     and argument registers can be saved.  */
1287  registers = assign_stack_local (BLKmode, apply_args_size (), -1);
1288
1289  /* Walk past the arg-pointer and structure value address.  */
1290  size = GET_MODE_SIZE (Pmode);
1291  if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0))
1292    size += GET_MODE_SIZE (Pmode);
1293
1294  /* Save each register used in calling a function to the block.  */
1295  for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1296    if ((mode = apply_args_mode[regno]) != VOIDmode)
1297      {
1298	align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1299	if (size % align != 0)
1300	  size = CEIL (size, align) * align;
1301
1302	tem = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1303
1304	emit_move_insn (adjust_address (registers, mode, size), tem);
1305	size += GET_MODE_SIZE (mode);
1306      }
1307
1308  /* Save the arg pointer to the block.  */
1309  tem = copy_to_reg (virtual_incoming_args_rtx);
1310#ifdef STACK_GROWS_DOWNWARD
1311  /* We need the pointer as the caller actually passed them to us, not
1312     as we might have pretended they were passed.  Make sure it's a valid
1313     operand, as emit_move_insn isn't expected to handle a PLUS.  */
1314  tem
1315    = force_operand (plus_constant (tem, current_function_pretend_args_size),
1316		     NULL_RTX);
1317#endif
1318  emit_move_insn (adjust_address (registers, Pmode, 0), tem);
1319
1320  size = GET_MODE_SIZE (Pmode);
1321
1322  /* Save the structure value address unless this is passed as an
1323     "invisible" first argument.  */
1324  if (struct_incoming_value)
1325    {
1326      emit_move_insn (adjust_address (registers, Pmode, size),
1327		      copy_to_reg (struct_incoming_value));
1328      size += GET_MODE_SIZE (Pmode);
1329    }
1330
1331  /* Return the address of the block.  */
1332  return copy_addr_to_reg (XEXP (registers, 0));
1333}
1334
1335/* __builtin_apply_args returns block of memory allocated on
1336   the stack into which is stored the arg pointer, structure
1337   value address, static chain, and all the registers that might
1338   possibly be used in performing a function call.  The code is
1339   moved to the start of the function so the incoming values are
1340   saved.  */
1341
1342static rtx
1343expand_builtin_apply_args (void)
1344{
1345  /* Don't do __builtin_apply_args more than once in a function.
1346     Save the result of the first call and reuse it.  */
1347  if (apply_args_value != 0)
1348    return apply_args_value;
1349  {
1350    /* When this function is called, it means that registers must be
1351       saved on entry to this function.  So we migrate the
1352       call to the first insn of this function.  */
1353    rtx temp;
1354    rtx seq;
1355
1356    start_sequence ();
1357    temp = expand_builtin_apply_args_1 ();
1358    seq = get_insns ();
1359    end_sequence ();
1360
1361    apply_args_value = temp;
1362
1363    /* Put the insns after the NOTE that starts the function.
1364       If this is inside a start_sequence, make the outer-level insn
1365       chain current, so the code is placed at the start of the
1366       function.  */
1367    push_topmost_sequence ();
1368    emit_insn_before (seq, NEXT_INSN (entry_of_function ()));
1369    pop_topmost_sequence ();
1370    return temp;
1371  }
1372}
1373
1374/* Perform an untyped call and save the state required to perform an
1375   untyped return of whatever value was returned by the given function.  */
1376
1377static rtx
1378expand_builtin_apply (rtx function, rtx arguments, rtx argsize)
1379{
1380  int size, align, regno;
1381  enum machine_mode mode;
1382  rtx incoming_args, result, reg, dest, src, call_insn;
1383  rtx old_stack_level = 0;
1384  rtx call_fusage = 0;
1385  rtx struct_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0);
1386
1387  arguments = convert_memory_address (Pmode, arguments);
1388
1389  /* Create a block where the return registers can be saved.  */
1390  result = assign_stack_local (BLKmode, apply_result_size (), -1);
1391
1392  /* Fetch the arg pointer from the ARGUMENTS block.  */
1393  incoming_args = gen_reg_rtx (Pmode);
1394  emit_move_insn (incoming_args, gen_rtx_MEM (Pmode, arguments));
1395#ifndef STACK_GROWS_DOWNWARD
1396  incoming_args = expand_simple_binop (Pmode, MINUS, incoming_args, argsize,
1397				       incoming_args, 0, OPTAB_LIB_WIDEN);
1398#endif
1399
1400  /* Push a new argument block and copy the arguments.  Do not allow
1401     the (potential) memcpy call below to interfere with our stack
1402     manipulations.  */
1403  do_pending_stack_adjust ();
1404  NO_DEFER_POP;
1405
1406  /* Save the stack with nonlocal if available.  */
1407#ifdef HAVE_save_stack_nonlocal
1408  if (HAVE_save_stack_nonlocal)
1409    emit_stack_save (SAVE_NONLOCAL, &old_stack_level, NULL_RTX);
1410  else
1411#endif
1412    emit_stack_save (SAVE_BLOCK, &old_stack_level, NULL_RTX);
1413
1414  /* Allocate a block of memory onto the stack and copy the memory
1415     arguments to the outgoing arguments address.  */
1416  allocate_dynamic_stack_space (argsize, 0, BITS_PER_UNIT);
1417  dest = virtual_outgoing_args_rtx;
1418#ifndef STACK_GROWS_DOWNWARD
1419  if (GET_CODE (argsize) == CONST_INT)
1420    dest = plus_constant (dest, -INTVAL (argsize));
1421  else
1422    dest = gen_rtx_PLUS (Pmode, dest, negate_rtx (Pmode, argsize));
1423#endif
1424  dest = gen_rtx_MEM (BLKmode, dest);
1425  set_mem_align (dest, PARM_BOUNDARY);
1426  src = gen_rtx_MEM (BLKmode, incoming_args);
1427  set_mem_align (src, PARM_BOUNDARY);
1428  emit_block_move (dest, src, argsize, BLOCK_OP_NORMAL);
1429
1430  /* Refer to the argument block.  */
1431  apply_args_size ();
1432  arguments = gen_rtx_MEM (BLKmode, arguments);
1433  set_mem_align (arguments, PARM_BOUNDARY);
1434
1435  /* Walk past the arg-pointer and structure value address.  */
1436  size = GET_MODE_SIZE (Pmode);
1437  if (struct_value)
1438    size += GET_MODE_SIZE (Pmode);
1439
1440  /* Restore each of the registers previously saved.  Make USE insns
1441     for each of these registers for use in making the call.  */
1442  for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1443    if ((mode = apply_args_mode[regno]) != VOIDmode)
1444      {
1445	align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1446	if (size % align != 0)
1447	  size = CEIL (size, align) * align;
1448	reg = gen_rtx_REG (mode, regno);
1449	emit_move_insn (reg, adjust_address (arguments, mode, size));
1450	use_reg (&call_fusage, reg);
1451	size += GET_MODE_SIZE (mode);
1452      }
1453
1454  /* Restore the structure value address unless this is passed as an
1455     "invisible" first argument.  */
1456  size = GET_MODE_SIZE (Pmode);
1457  if (struct_value)
1458    {
1459      rtx value = gen_reg_rtx (Pmode);
1460      emit_move_insn (value, adjust_address (arguments, Pmode, size));
1461      emit_move_insn (struct_value, value);
1462      if (REG_P (struct_value))
1463	use_reg (&call_fusage, struct_value);
1464      size += GET_MODE_SIZE (Pmode);
1465    }
1466
1467  /* All arguments and registers used for the call are set up by now!  */
1468  function = prepare_call_address (function, NULL, &call_fusage, 0, 0);
1469
1470  /* Ensure address is valid.  SYMBOL_REF is already valid, so no need,
1471     and we don't want to load it into a register as an optimization,
1472     because prepare_call_address already did it if it should be done.  */
1473  if (GET_CODE (function) != SYMBOL_REF)
1474    function = memory_address (FUNCTION_MODE, function);
1475
1476  /* Generate the actual call instruction and save the return value.  */
1477#ifdef HAVE_untyped_call
1478  if (HAVE_untyped_call)
1479    emit_call_insn (gen_untyped_call (gen_rtx_MEM (FUNCTION_MODE, function),
1480				      result, result_vector (1, result)));
1481  else
1482#endif
1483#ifdef HAVE_call_value
1484  if (HAVE_call_value)
1485    {
1486      rtx valreg = 0;
1487
1488      /* Locate the unique return register.  It is not possible to
1489	 express a call that sets more than one return register using
1490	 call_value; use untyped_call for that.  In fact, untyped_call
1491	 only needs to save the return registers in the given block.  */
1492      for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1493	if ((mode = apply_result_mode[regno]) != VOIDmode)
1494	  {
1495	    gcc_assert (!valreg); /* HAVE_untyped_call required.  */
1496
1497	    valreg = gen_rtx_REG (mode, regno);
1498	  }
1499
1500      emit_call_insn (GEN_CALL_VALUE (valreg,
1501				      gen_rtx_MEM (FUNCTION_MODE, function),
1502				      const0_rtx, NULL_RTX, const0_rtx));
1503
1504      emit_move_insn (adjust_address (result, GET_MODE (valreg), 0), valreg);
1505    }
1506  else
1507#endif
1508    gcc_unreachable ();
1509
1510  /* Find the CALL insn we just emitted, and attach the register usage
1511     information.  */
1512  call_insn = last_call_insn ();
1513  add_function_usage_to (call_insn, call_fusage);
1514
1515  /* Restore the stack.  */
1516#ifdef HAVE_save_stack_nonlocal
1517  if (HAVE_save_stack_nonlocal)
1518    emit_stack_restore (SAVE_NONLOCAL, old_stack_level, NULL_RTX);
1519  else
1520#endif
1521    emit_stack_restore (SAVE_BLOCK, old_stack_level, NULL_RTX);
1522
1523  OK_DEFER_POP;
1524
1525  /* Return the address of the result block.  */
1526  result = copy_addr_to_reg (XEXP (result, 0));
1527  return convert_memory_address (ptr_mode, result);
1528}
1529
1530/* Perform an untyped return.  */
1531
1532static void
1533expand_builtin_return (rtx result)
1534{
1535  int size, align, regno;
1536  enum machine_mode mode;
1537  rtx reg;
1538  rtx call_fusage = 0;
1539
1540  result = convert_memory_address (Pmode, result);
1541
1542  apply_result_size ();
1543  result = gen_rtx_MEM (BLKmode, result);
1544
1545#ifdef HAVE_untyped_return
1546  if (HAVE_untyped_return)
1547    {
1548      emit_jump_insn (gen_untyped_return (result, result_vector (0, result)));
1549      emit_barrier ();
1550      return;
1551    }
1552#endif
1553
1554  /* Restore the return value and note that each value is used.  */
1555  size = 0;
1556  for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1557    if ((mode = apply_result_mode[regno]) != VOIDmode)
1558      {
1559	align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1560	if (size % align != 0)
1561	  size = CEIL (size, align) * align;
1562	reg = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1563	emit_move_insn (reg, adjust_address (result, mode, size));
1564
1565	push_to_sequence (call_fusage);
1566	emit_insn (gen_rtx_USE (VOIDmode, reg));
1567	call_fusage = get_insns ();
1568	end_sequence ();
1569	size += GET_MODE_SIZE (mode);
1570      }
1571
1572  /* Put the USE insns before the return.  */
1573  emit_insn (call_fusage);
1574
1575  /* Return whatever values was restored by jumping directly to the end
1576     of the function.  */
1577  expand_naked_return ();
1578}
1579
1580/* Used by expand_builtin_classify_type and fold_builtin_classify_type.  */
1581
1582static enum type_class
1583type_to_class (tree type)
1584{
1585  switch (TREE_CODE (type))
1586    {
1587    case VOID_TYPE:	   return void_type_class;
1588    case INTEGER_TYPE:	   return integer_type_class;
1589    case ENUMERAL_TYPE:	   return enumeral_type_class;
1590    case BOOLEAN_TYPE:	   return boolean_type_class;
1591    case POINTER_TYPE:	   return pointer_type_class;
1592    case REFERENCE_TYPE:   return reference_type_class;
1593    case OFFSET_TYPE:	   return offset_type_class;
1594    case REAL_TYPE:	   return real_type_class;
1595    case COMPLEX_TYPE:	   return complex_type_class;
1596    case FUNCTION_TYPE:	   return function_type_class;
1597    case METHOD_TYPE:	   return method_type_class;
1598    case RECORD_TYPE:	   return record_type_class;
1599    case UNION_TYPE:
1600    case QUAL_UNION_TYPE:  return union_type_class;
1601    case ARRAY_TYPE:	   return (TYPE_STRING_FLAG (type)
1602				   ? string_type_class : array_type_class);
1603    case LANG_TYPE:	   return lang_type_class;
1604    default:		   return no_type_class;
1605    }
1606}
1607
1608/* Expand a call to __builtin_classify_type with arguments found in
1609   ARGLIST.  */
1610
1611static rtx
1612expand_builtin_classify_type (tree arglist)
1613{
1614  if (arglist != 0)
1615    return GEN_INT (type_to_class (TREE_TYPE (TREE_VALUE (arglist))));
1616  return GEN_INT (no_type_class);
1617}
1618
1619/* This helper macro, meant to be used in mathfn_built_in below,
1620   determines which among a set of three builtin math functions is
1621   appropriate for a given type mode.  The `F' and `L' cases are
1622   automatically generated from the `double' case.  */
1623#define CASE_MATHFN(BUILT_IN_MATHFN) \
1624  case BUILT_IN_MATHFN: case BUILT_IN_MATHFN##F: case BUILT_IN_MATHFN##L: \
1625  fcode = BUILT_IN_MATHFN; fcodef = BUILT_IN_MATHFN##F ; \
1626  fcodel = BUILT_IN_MATHFN##L ; break;
1627
1628/* Return mathematic function equivalent to FN but operating directly
1629   on TYPE, if available.  If we can't do the conversion, return zero.  */
1630tree
1631mathfn_built_in (tree type, enum built_in_function fn)
1632{
1633  enum built_in_function fcode, fcodef, fcodel;
1634
1635  switch (fn)
1636    {
1637      CASE_MATHFN (BUILT_IN_ACOS)
1638      CASE_MATHFN (BUILT_IN_ACOSH)
1639      CASE_MATHFN (BUILT_IN_ASIN)
1640      CASE_MATHFN (BUILT_IN_ASINH)
1641      CASE_MATHFN (BUILT_IN_ATAN)
1642      CASE_MATHFN (BUILT_IN_ATAN2)
1643      CASE_MATHFN (BUILT_IN_ATANH)
1644      CASE_MATHFN (BUILT_IN_CBRT)
1645      CASE_MATHFN (BUILT_IN_CEIL)
1646      CASE_MATHFN (BUILT_IN_COPYSIGN)
1647      CASE_MATHFN (BUILT_IN_COS)
1648      CASE_MATHFN (BUILT_IN_COSH)
1649      CASE_MATHFN (BUILT_IN_DREM)
1650      CASE_MATHFN (BUILT_IN_ERF)
1651      CASE_MATHFN (BUILT_IN_ERFC)
1652      CASE_MATHFN (BUILT_IN_EXP)
1653      CASE_MATHFN (BUILT_IN_EXP10)
1654      CASE_MATHFN (BUILT_IN_EXP2)
1655      CASE_MATHFN (BUILT_IN_EXPM1)
1656      CASE_MATHFN (BUILT_IN_FABS)
1657      CASE_MATHFN (BUILT_IN_FDIM)
1658      CASE_MATHFN (BUILT_IN_FLOOR)
1659      CASE_MATHFN (BUILT_IN_FMA)
1660      CASE_MATHFN (BUILT_IN_FMAX)
1661      CASE_MATHFN (BUILT_IN_FMIN)
1662      CASE_MATHFN (BUILT_IN_FMOD)
1663      CASE_MATHFN (BUILT_IN_FREXP)
1664      CASE_MATHFN (BUILT_IN_GAMMA)
1665      CASE_MATHFN (BUILT_IN_HUGE_VAL)
1666      CASE_MATHFN (BUILT_IN_HYPOT)
1667      CASE_MATHFN (BUILT_IN_ILOGB)
1668      CASE_MATHFN (BUILT_IN_INF)
1669      CASE_MATHFN (BUILT_IN_J0)
1670      CASE_MATHFN (BUILT_IN_J1)
1671      CASE_MATHFN (BUILT_IN_JN)
1672      CASE_MATHFN (BUILT_IN_LCEIL)
1673      CASE_MATHFN (BUILT_IN_LDEXP)
1674      CASE_MATHFN (BUILT_IN_LFLOOR)
1675      CASE_MATHFN (BUILT_IN_LGAMMA)
1676      CASE_MATHFN (BUILT_IN_LLCEIL)
1677      CASE_MATHFN (BUILT_IN_LLFLOOR)
1678      CASE_MATHFN (BUILT_IN_LLRINT)
1679      CASE_MATHFN (BUILT_IN_LLROUND)
1680      CASE_MATHFN (BUILT_IN_LOG)
1681      CASE_MATHFN (BUILT_IN_LOG10)
1682      CASE_MATHFN (BUILT_IN_LOG1P)
1683      CASE_MATHFN (BUILT_IN_LOG2)
1684      CASE_MATHFN (BUILT_IN_LOGB)
1685      CASE_MATHFN (BUILT_IN_LRINT)
1686      CASE_MATHFN (BUILT_IN_LROUND)
1687      CASE_MATHFN (BUILT_IN_MODF)
1688      CASE_MATHFN (BUILT_IN_NAN)
1689      CASE_MATHFN (BUILT_IN_NANS)
1690      CASE_MATHFN (BUILT_IN_NEARBYINT)
1691      CASE_MATHFN (BUILT_IN_NEXTAFTER)
1692      CASE_MATHFN (BUILT_IN_NEXTTOWARD)
1693      CASE_MATHFN (BUILT_IN_POW)
1694      CASE_MATHFN (BUILT_IN_POWI)
1695      CASE_MATHFN (BUILT_IN_POW10)
1696      CASE_MATHFN (BUILT_IN_REMAINDER)
1697      CASE_MATHFN (BUILT_IN_REMQUO)
1698      CASE_MATHFN (BUILT_IN_RINT)
1699      CASE_MATHFN (BUILT_IN_ROUND)
1700      CASE_MATHFN (BUILT_IN_SCALB)
1701      CASE_MATHFN (BUILT_IN_SCALBLN)
1702      CASE_MATHFN (BUILT_IN_SCALBN)
1703      CASE_MATHFN (BUILT_IN_SIGNIFICAND)
1704      CASE_MATHFN (BUILT_IN_SIN)
1705      CASE_MATHFN (BUILT_IN_SINCOS)
1706      CASE_MATHFN (BUILT_IN_SINH)
1707      CASE_MATHFN (BUILT_IN_SQRT)
1708      CASE_MATHFN (BUILT_IN_TAN)
1709      CASE_MATHFN (BUILT_IN_TANH)
1710      CASE_MATHFN (BUILT_IN_TGAMMA)
1711      CASE_MATHFN (BUILT_IN_TRUNC)
1712      CASE_MATHFN (BUILT_IN_Y0)
1713      CASE_MATHFN (BUILT_IN_Y1)
1714      CASE_MATHFN (BUILT_IN_YN)
1715
1716      default:
1717	return 0;
1718      }
1719
1720  if (TYPE_MAIN_VARIANT (type) == double_type_node)
1721    return implicit_built_in_decls[fcode];
1722  else if (TYPE_MAIN_VARIANT (type) == float_type_node)
1723    return implicit_built_in_decls[fcodef];
1724  else if (TYPE_MAIN_VARIANT (type) == long_double_type_node)
1725    return implicit_built_in_decls[fcodel];
1726  else
1727    return 0;
1728}
1729
1730/* If errno must be maintained, expand the RTL to check if the result,
1731   TARGET, of a built-in function call, EXP, is NaN, and if so set
1732   errno to EDOM.  */
1733
1734static void
1735expand_errno_check (tree exp, rtx target)
1736{
1737  rtx lab = gen_label_rtx ();
1738
1739  /* Test the result; if it is NaN, set errno=EDOM because
1740     the argument was not in the domain.  */
1741  emit_cmp_and_jump_insns (target, target, EQ, 0, GET_MODE (target),
1742			   0, lab);
1743
1744#ifdef TARGET_EDOM
1745  /* If this built-in doesn't throw an exception, set errno directly.  */
1746  if (TREE_NOTHROW (TREE_OPERAND (TREE_OPERAND (exp, 0), 0)))
1747    {
1748#ifdef GEN_ERRNO_RTX
1749      rtx errno_rtx = GEN_ERRNO_RTX;
1750#else
1751      rtx errno_rtx
1752	  = gen_rtx_MEM (word_mode, gen_rtx_SYMBOL_REF (Pmode, "errno"));
1753#endif
1754      emit_move_insn (errno_rtx, GEN_INT (TARGET_EDOM));
1755      emit_label (lab);
1756      return;
1757    }
1758#endif
1759
1760  /* We can't set errno=EDOM directly; let the library call do it.
1761     Pop the arguments right away in case the call gets deleted.  */
1762  NO_DEFER_POP;
1763  expand_call (exp, target, 0);
1764  OK_DEFER_POP;
1765  emit_label (lab);
1766}
1767
1768
1769/* Expand a call to one of the builtin math functions (sqrt, exp, or log).
1770   Return 0 if a normal call should be emitted rather than expanding the
1771   function in-line.  EXP is the expression that is a call to the builtin
1772   function; if convenient, the result should be placed in TARGET.
1773   SUBTARGET may be used as the target for computing one of EXP's operands.  */
1774
1775static rtx
1776expand_builtin_mathfn (tree exp, rtx target, rtx subtarget)
1777{
1778  optab builtin_optab;
1779  rtx op0, insns, before_call;
1780  tree fndecl = get_callee_fndecl (exp);
1781  tree arglist = TREE_OPERAND (exp, 1);
1782  enum machine_mode mode;
1783  bool errno_set = false;
1784  tree arg, narg;
1785
1786  if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
1787    return 0;
1788
1789  arg = TREE_VALUE (arglist);
1790
1791  switch (DECL_FUNCTION_CODE (fndecl))
1792    {
1793    CASE_FLT_FN (BUILT_IN_SQRT):
1794      errno_set = ! tree_expr_nonnegative_p (arg);
1795      builtin_optab = sqrt_optab;
1796      break;
1797    CASE_FLT_FN (BUILT_IN_EXP):
1798      errno_set = true; builtin_optab = exp_optab; break;
1799    CASE_FLT_FN (BUILT_IN_EXP10):
1800    CASE_FLT_FN (BUILT_IN_POW10):
1801      errno_set = true; builtin_optab = exp10_optab; break;
1802    CASE_FLT_FN (BUILT_IN_EXP2):
1803      errno_set = true; builtin_optab = exp2_optab; break;
1804    CASE_FLT_FN (BUILT_IN_EXPM1):
1805      errno_set = true; builtin_optab = expm1_optab; break;
1806    CASE_FLT_FN (BUILT_IN_LOGB):
1807      errno_set = true; builtin_optab = logb_optab; break;
1808    CASE_FLT_FN (BUILT_IN_ILOGB):
1809      errno_set = true; builtin_optab = ilogb_optab; break;
1810    CASE_FLT_FN (BUILT_IN_LOG):
1811      errno_set = true; builtin_optab = log_optab; break;
1812    CASE_FLT_FN (BUILT_IN_LOG10):
1813      errno_set = true; builtin_optab = log10_optab; break;
1814    CASE_FLT_FN (BUILT_IN_LOG2):
1815      errno_set = true; builtin_optab = log2_optab; break;
1816    CASE_FLT_FN (BUILT_IN_LOG1P):
1817      errno_set = true; builtin_optab = log1p_optab; break;
1818    CASE_FLT_FN (BUILT_IN_ASIN):
1819      builtin_optab = asin_optab; break;
1820    CASE_FLT_FN (BUILT_IN_ACOS):
1821      builtin_optab = acos_optab; break;
1822    CASE_FLT_FN (BUILT_IN_TAN):
1823      builtin_optab = tan_optab; break;
1824    CASE_FLT_FN (BUILT_IN_ATAN):
1825      builtin_optab = atan_optab; break;
1826    CASE_FLT_FN (BUILT_IN_FLOOR):
1827      builtin_optab = floor_optab; break;
1828    CASE_FLT_FN (BUILT_IN_CEIL):
1829      builtin_optab = ceil_optab; break;
1830    CASE_FLT_FN (BUILT_IN_TRUNC):
1831      builtin_optab = btrunc_optab; break;
1832    CASE_FLT_FN (BUILT_IN_ROUND):
1833      builtin_optab = round_optab; break;
1834    CASE_FLT_FN (BUILT_IN_NEARBYINT):
1835      builtin_optab = nearbyint_optab; break;
1836    CASE_FLT_FN (BUILT_IN_RINT):
1837      builtin_optab = rint_optab; break;
1838    CASE_FLT_FN (BUILT_IN_LRINT):
1839    CASE_FLT_FN (BUILT_IN_LLRINT):
1840      builtin_optab = lrint_optab; break;
1841    default:
1842      gcc_unreachable ();
1843    }
1844
1845  /* Make a suitable register to place result in.  */
1846  mode = TYPE_MODE (TREE_TYPE (exp));
1847
1848  if (! flag_errno_math || ! HONOR_NANS (mode))
1849    errno_set = false;
1850
1851  /* Before working hard, check whether the instruction is available.  */
1852  if (builtin_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1853    {
1854      target = gen_reg_rtx (mode);
1855
1856      /* Wrap the computation of the argument in a SAVE_EXPR, as we may
1857	 need to expand the argument again.  This way, we will not perform
1858	 side-effects more the once.  */
1859      narg = builtin_save_expr (arg);
1860      if (narg != arg)
1861	{
1862	  arg = narg;
1863	  arglist = build_tree_list (NULL_TREE, arg);
1864	  exp = build_function_call_expr (fndecl, arglist);
1865	}
1866
1867      op0 = expand_expr (arg, subtarget, VOIDmode, 0);
1868
1869      start_sequence ();
1870
1871      /* Compute into TARGET.
1872	 Set TARGET to wherever the result comes back.  */
1873      target = expand_unop (mode, builtin_optab, op0, target, 0);
1874
1875      if (target != 0)
1876	{
1877	  if (errno_set)
1878	    expand_errno_check (exp, target);
1879
1880	  /* Output the entire sequence.  */
1881	  insns = get_insns ();
1882	  end_sequence ();
1883	  emit_insn (insns);
1884	  return target;
1885	}
1886
1887      /* If we were unable to expand via the builtin, stop the sequence
1888	 (without outputting the insns) and call to the library function
1889	 with the stabilized argument list.  */
1890      end_sequence ();
1891    }
1892
1893  before_call = get_last_insn ();
1894
1895  target = expand_call (exp, target, target == const0_rtx);
1896
1897  /* If this is a sqrt operation and we don't care about errno, try to
1898     attach a REG_EQUAL note with a SQRT rtx to the emitted libcall.
1899     This allows the semantics of the libcall to be visible to the RTL
1900     optimizers.  */
1901  if (builtin_optab == sqrt_optab && !errno_set)
1902    {
1903      /* Search backwards through the insns emitted by expand_call looking
1904	 for the instruction with the REG_RETVAL note.  */
1905      rtx last = get_last_insn ();
1906      while (last != before_call)
1907	{
1908	  if (find_reg_note (last, REG_RETVAL, NULL))
1909	    {
1910	      rtx note = find_reg_note (last, REG_EQUAL, NULL);
1911	      /* Check that the REQ_EQUAL note is an EXPR_LIST with
1912		 two elements, i.e. symbol_ref(sqrt) and the operand.  */
1913	      if (note
1914		  && GET_CODE (note) == EXPR_LIST
1915		  && GET_CODE (XEXP (note, 0)) == EXPR_LIST
1916		  && XEXP (XEXP (note, 0), 1) != NULL_RTX
1917		  && XEXP (XEXP (XEXP (note, 0), 1), 1) == NULL_RTX)
1918		{
1919		  rtx operand = XEXP (XEXP (XEXP (note, 0), 1), 0);
1920		  /* Check operand is a register with expected mode.  */
1921		  if (operand
1922		      && REG_P (operand)
1923		      && GET_MODE (operand) == mode)
1924		    {
1925		      /* Replace the REG_EQUAL note with a SQRT rtx.  */
1926		      rtx equiv = gen_rtx_SQRT (mode, operand);
1927		      set_unique_reg_note (last, REG_EQUAL, equiv);
1928		    }
1929		}
1930	      break;
1931	    }
1932	  last = PREV_INSN (last);
1933	}
1934    }
1935
1936  return target;
1937}
1938
1939/* Expand a call to the builtin binary math functions (pow and atan2).
1940   Return 0 if a normal call should be emitted rather than expanding the
1941   function in-line.  EXP is the expression that is a call to the builtin
1942   function; if convenient, the result should be placed in TARGET.
1943   SUBTARGET may be used as the target for computing one of EXP's
1944   operands.  */
1945
1946static rtx
1947expand_builtin_mathfn_2 (tree exp, rtx target, rtx subtarget)
1948{
1949  optab builtin_optab;
1950  rtx op0, op1, insns;
1951  int op1_type = REAL_TYPE;
1952  tree fndecl = get_callee_fndecl (exp);
1953  tree arglist = TREE_OPERAND (exp, 1);
1954  tree arg0, arg1, temp, narg;
1955  enum machine_mode mode;
1956  bool errno_set = true;
1957  bool stable = true;
1958
1959  if ((DECL_FUNCTION_CODE (fndecl) == BUILT_IN_LDEXP)
1960      || (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_LDEXPF)
1961      || (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_LDEXPL))
1962    op1_type = INTEGER_TYPE;
1963
1964  if (!validate_arglist (arglist, REAL_TYPE, op1_type, VOID_TYPE))
1965    return 0;
1966
1967  arg0 = TREE_VALUE (arglist);
1968  arg1 = TREE_VALUE (TREE_CHAIN (arglist));
1969
1970  switch (DECL_FUNCTION_CODE (fndecl))
1971    {
1972    CASE_FLT_FN (BUILT_IN_POW):
1973      builtin_optab = pow_optab; break;
1974    CASE_FLT_FN (BUILT_IN_ATAN2):
1975      builtin_optab = atan2_optab; break;
1976    CASE_FLT_FN (BUILT_IN_LDEXP):
1977      builtin_optab = ldexp_optab; break;
1978    CASE_FLT_FN (BUILT_IN_FMOD):
1979      builtin_optab = fmod_optab; break;
1980    CASE_FLT_FN (BUILT_IN_DREM):
1981      builtin_optab = drem_optab; break;
1982    default:
1983      gcc_unreachable ();
1984    }
1985
1986  /* Make a suitable register to place result in.  */
1987  mode = TYPE_MODE (TREE_TYPE (exp));
1988
1989  /* Before working hard, check whether the instruction is available.  */
1990  if (builtin_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing)
1991    return 0;
1992
1993  target = gen_reg_rtx (mode);
1994
1995  if (! flag_errno_math || ! HONOR_NANS (mode))
1996    errno_set = false;
1997
1998  /* Always stabilize the argument list.  */
1999  narg = builtin_save_expr (arg1);
2000  if (narg != arg1)
2001    {
2002      arg1 = narg;
2003      temp = build_tree_list (NULL_TREE, narg);
2004      stable = false;
2005    }
2006  else
2007    temp = TREE_CHAIN (arglist);
2008
2009  narg = builtin_save_expr (arg0);
2010  if (narg != arg0)
2011    {
2012      arg0 = narg;
2013      arglist = tree_cons (NULL_TREE, narg, temp);
2014      stable = false;
2015    }
2016  else if (! stable)
2017    arglist = tree_cons (NULL_TREE, arg0, temp);
2018
2019  if (! stable)
2020    exp = build_function_call_expr (fndecl, arglist);
2021
2022  op0 = expand_expr (arg0, subtarget, VOIDmode, EXPAND_NORMAL);
2023  op1 = expand_normal (arg1);
2024
2025  start_sequence ();
2026
2027  /* Compute into TARGET.
2028     Set TARGET to wherever the result comes back.  */
2029  target = expand_binop (mode, builtin_optab, op0, op1,
2030			 target, 0, OPTAB_DIRECT);
2031
2032  /* If we were unable to expand via the builtin, stop the sequence
2033     (without outputting the insns) and call to the library function
2034     with the stabilized argument list.  */
2035  if (target == 0)
2036    {
2037      end_sequence ();
2038      return expand_call (exp, target, target == const0_rtx);
2039    }
2040
2041  if (errno_set)
2042    expand_errno_check (exp, target);
2043
2044  /* Output the entire sequence.  */
2045  insns = get_insns ();
2046  end_sequence ();
2047  emit_insn (insns);
2048
2049  return target;
2050}
2051
2052/* Expand a call to the builtin sin and cos math functions.
2053   Return 0 if a normal call should be emitted rather than expanding the
2054   function in-line.  EXP is the expression that is a call to the builtin
2055   function; if convenient, the result should be placed in TARGET.
2056   SUBTARGET may be used as the target for computing one of EXP's
2057   operands.  */
2058
2059static rtx
2060expand_builtin_mathfn_3 (tree exp, rtx target, rtx subtarget)
2061{
2062  optab builtin_optab;
2063  rtx op0, insns;
2064  tree fndecl = get_callee_fndecl (exp);
2065  tree arglist = TREE_OPERAND (exp, 1);
2066  enum machine_mode mode;
2067  tree arg, narg;
2068
2069  if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
2070    return 0;
2071
2072  arg = TREE_VALUE (arglist);
2073
2074  switch (DECL_FUNCTION_CODE (fndecl))
2075    {
2076    CASE_FLT_FN (BUILT_IN_SIN):
2077    CASE_FLT_FN (BUILT_IN_COS):
2078      builtin_optab = sincos_optab; break;
2079    default:
2080      gcc_unreachable ();
2081    }
2082
2083  /* Make a suitable register to place result in.  */
2084  mode = TYPE_MODE (TREE_TYPE (exp));
2085
2086  /* Check if sincos insn is available, otherwise fallback
2087     to sin or cos insn.  */
2088  if (builtin_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing) {
2089    switch (DECL_FUNCTION_CODE (fndecl))
2090      {
2091      CASE_FLT_FN (BUILT_IN_SIN):
2092	builtin_optab = sin_optab; break;
2093      CASE_FLT_FN (BUILT_IN_COS):
2094	builtin_optab = cos_optab; break;
2095      default:
2096	gcc_unreachable ();
2097      }
2098  }
2099
2100  /* Before working hard, check whether the instruction is available.  */
2101  if (builtin_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2102    {
2103      target = gen_reg_rtx (mode);
2104
2105      /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2106	 need to expand the argument again.  This way, we will not perform
2107	 side-effects more the once.  */
2108      narg = save_expr (arg);
2109      if (narg != arg)
2110	{
2111	  arg = narg;
2112	  arglist = build_tree_list (NULL_TREE, arg);
2113	  exp = build_function_call_expr (fndecl, arglist);
2114	}
2115
2116      op0 = expand_expr (arg, subtarget, VOIDmode, 0);
2117
2118      start_sequence ();
2119
2120      /* Compute into TARGET.
2121	 Set TARGET to wherever the result comes back.  */
2122      if (builtin_optab == sincos_optab)
2123	{
2124	  int result;
2125
2126	  switch (DECL_FUNCTION_CODE (fndecl))
2127	    {
2128	    CASE_FLT_FN (BUILT_IN_SIN):
2129	      result = expand_twoval_unop (builtin_optab, op0, 0, target, 0);
2130	      break;
2131	    CASE_FLT_FN (BUILT_IN_COS):
2132	      result = expand_twoval_unop (builtin_optab, op0, target, 0, 0);
2133	      break;
2134	    default:
2135	      gcc_unreachable ();
2136	    }
2137	  gcc_assert (result);
2138	}
2139      else
2140	{
2141	  target = expand_unop (mode, builtin_optab, op0, target, 0);
2142	}
2143
2144      if (target != 0)
2145	{
2146	  /* Output the entire sequence.  */
2147	  insns = get_insns ();
2148	  end_sequence ();
2149	  emit_insn (insns);
2150	  return target;
2151	}
2152
2153      /* If we were unable to expand via the builtin, stop the sequence
2154	 (without outputting the insns) and call to the library function
2155	 with the stabilized argument list.  */
2156      end_sequence ();
2157    }
2158
2159  target = expand_call (exp, target, target == const0_rtx);
2160
2161  return target;
2162}
2163
2164/* Expand a call to the builtin sincos math function.
2165   Return 0 if a normal call should be emitted rather than expanding the
2166   function in-line.  EXP is the expression that is a call to the builtin
2167   function.  */
2168
2169static rtx
2170expand_builtin_sincos (tree exp)
2171{
2172  rtx op0, op1, op2, target1, target2;
2173  tree arglist = TREE_OPERAND (exp, 1);
2174  enum machine_mode mode;
2175  tree arg, sinp, cosp;
2176  int result;
2177
2178  if (!validate_arglist (arglist, REAL_TYPE,
2179			 POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2180    return 0;
2181
2182  arg = TREE_VALUE (arglist);
2183  sinp = TREE_VALUE (TREE_CHAIN (arglist));
2184  cosp = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2185
2186  /* Make a suitable register to place result in.  */
2187  mode = TYPE_MODE (TREE_TYPE (arg));
2188
2189  /* Check if sincos insn is available, otherwise emit the call.  */
2190  if (sincos_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing)
2191    return NULL_RTX;
2192
2193  target1 = gen_reg_rtx (mode);
2194  target2 = gen_reg_rtx (mode);
2195
2196  op0 = expand_normal (arg);
2197  op1 = expand_normal (build_fold_indirect_ref (sinp));
2198  op2 = expand_normal (build_fold_indirect_ref (cosp));
2199
2200  /* Compute into target1 and target2.
2201     Set TARGET to wherever the result comes back.  */
2202  result = expand_twoval_unop (sincos_optab, op0, target2, target1, 0);
2203  gcc_assert (result);
2204
2205  /* Move target1 and target2 to the memory locations indicated
2206     by op1 and op2.  */
2207  emit_move_insn (op1, target1);
2208  emit_move_insn (op2, target2);
2209
2210  return const0_rtx;
2211}
2212
2213/* Expand a call to one of the builtin rounding functions (lfloor).
2214   If expanding via optab fails, lower expression to (int)(floor(x)).
2215   EXP is the expression that is a call to the builtin function;
2216   if convenient, the result should be placed in TARGET.  SUBTARGET may
2217   be used as the target for computing one of EXP's operands.  */
2218
2219static rtx
2220expand_builtin_int_roundingfn (tree exp, rtx target, rtx subtarget)
2221{
2222  optab builtin_optab;
2223  rtx op0, insns, tmp;
2224  tree fndecl = get_callee_fndecl (exp);
2225  tree arglist = TREE_OPERAND (exp, 1);
2226  enum built_in_function fallback_fn;
2227  tree fallback_fndecl;
2228  enum machine_mode mode;
2229  tree arg, narg;
2230
2231  if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
2232    gcc_unreachable ();
2233
2234  arg = TREE_VALUE (arglist);
2235
2236  switch (DECL_FUNCTION_CODE (fndecl))
2237    {
2238    CASE_FLT_FN (BUILT_IN_LCEIL):
2239    CASE_FLT_FN (BUILT_IN_LLCEIL):
2240      builtin_optab = lceil_optab;
2241      fallback_fn = BUILT_IN_CEIL;
2242      break;
2243
2244    CASE_FLT_FN (BUILT_IN_LFLOOR):
2245    CASE_FLT_FN (BUILT_IN_LLFLOOR):
2246      builtin_optab = lfloor_optab;
2247      fallback_fn = BUILT_IN_FLOOR;
2248      break;
2249
2250    default:
2251      gcc_unreachable ();
2252    }
2253
2254  /* Make a suitable register to place result in.  */
2255  mode = TYPE_MODE (TREE_TYPE (exp));
2256
2257  /* Before working hard, check whether the instruction is available.  */
2258  if (builtin_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2259    {
2260      target = gen_reg_rtx (mode);
2261
2262      /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2263	 need to expand the argument again.  This way, we will not perform
2264	 side-effects more the once.  */
2265      narg = builtin_save_expr (arg);
2266      if (narg != arg)
2267	{
2268	  arg = narg;
2269	  arglist = build_tree_list (NULL_TREE, arg);
2270	  exp = build_function_call_expr (fndecl, arglist);
2271	}
2272
2273      op0 = expand_expr (arg, subtarget, VOIDmode, 0);
2274
2275      start_sequence ();
2276
2277      /* Compute into TARGET.
2278	 Set TARGET to wherever the result comes back.  */
2279      target = expand_unop (mode, builtin_optab, op0, target, 0);
2280
2281      if (target != 0)
2282	{
2283	  /* Output the entire sequence.  */
2284	  insns = get_insns ();
2285	  end_sequence ();
2286	  emit_insn (insns);
2287	  return target;
2288	}
2289
2290      /* If we were unable to expand via the builtin, stop the sequence
2291	 (without outputting the insns).  */
2292      end_sequence ();
2293    }
2294
2295  /* Fall back to floating point rounding optab.  */
2296  fallback_fndecl = mathfn_built_in (TREE_TYPE (arg), fallback_fn);
2297  /* We shouldn't get here on targets without TARGET_C99_FUNCTIONS.
2298     ??? Perhaps convert (int)floorf(x) into (int)floor((double)x).  */
2299  gcc_assert (fallback_fndecl != NULL_TREE);
2300  exp = build_function_call_expr (fallback_fndecl, arglist);
2301
2302  tmp = expand_normal (exp);
2303
2304  /* Truncate the result of floating point optab to integer
2305     via expand_fix ().  */
2306  target = gen_reg_rtx (mode);
2307  expand_fix (target, tmp, 0);
2308
2309  return target;
2310}
2311
2312/* To evaluate powi(x,n), the floating point value x raised to the
2313   constant integer exponent n, we use a hybrid algorithm that
2314   combines the "window method" with look-up tables.  For an
2315   introduction to exponentiation algorithms and "addition chains",
2316   see section 4.6.3, "Evaluation of Powers" of Donald E. Knuth,
2317   "Seminumerical Algorithms", Vol. 2, "The Art of Computer Programming",
2318   3rd Edition, 1998, and Daniel M. Gordon, "A Survey of Fast Exponentiation
2319   Methods", Journal of Algorithms, Vol. 27, pp. 129-146, 1998.  */
2320
2321/* Provide a default value for POWI_MAX_MULTS, the maximum number of
2322   multiplications to inline before calling the system library's pow
2323   function.  powi(x,n) requires at worst 2*bits(n)-2 multiplications,
2324   so this default never requires calling pow, powf or powl.  */
2325
2326#ifndef POWI_MAX_MULTS
2327#define POWI_MAX_MULTS  (2*HOST_BITS_PER_WIDE_INT-2)
2328#endif
2329
2330/* The size of the "optimal power tree" lookup table.  All
2331   exponents less than this value are simply looked up in the
2332   powi_table below.  This threshold is also used to size the
2333   cache of pseudo registers that hold intermediate results.  */
2334#define POWI_TABLE_SIZE 256
2335
2336/* The size, in bits of the window, used in the "window method"
2337   exponentiation algorithm.  This is equivalent to a radix of
2338   (1<<POWI_WINDOW_SIZE) in the corresponding "m-ary method".  */
2339#define POWI_WINDOW_SIZE 3
2340
2341/* The following table is an efficient representation of an
2342   "optimal power tree".  For each value, i, the corresponding
2343   value, j, in the table states than an optimal evaluation
2344   sequence for calculating pow(x,i) can be found by evaluating
2345   pow(x,j)*pow(x,i-j).  An optimal power tree for the first
2346   100 integers is given in Knuth's "Seminumerical algorithms".  */
2347
2348static const unsigned char powi_table[POWI_TABLE_SIZE] =
2349  {
2350      0,   1,   1,   2,   2,   3,   3,   4,  /*   0 -   7 */
2351      4,   6,   5,   6,   6,  10,   7,   9,  /*   8 -  15 */
2352      8,  16,   9,  16,  10,  12,  11,  13,  /*  16 -  23 */
2353     12,  17,  13,  18,  14,  24,  15,  26,  /*  24 -  31 */
2354     16,  17,  17,  19,  18,  33,  19,  26,  /*  32 -  39 */
2355     20,  25,  21,  40,  22,  27,  23,  44,  /*  40 -  47 */
2356     24,  32,  25,  34,  26,  29,  27,  44,  /*  48 -  55 */
2357     28,  31,  29,  34,  30,  60,  31,  36,  /*  56 -  63 */
2358     32,  64,  33,  34,  34,  46,  35,  37,  /*  64 -  71 */
2359     36,  65,  37,  50,  38,  48,  39,  69,  /*  72 -  79 */
2360     40,  49,  41,  43,  42,  51,  43,  58,  /*  80 -  87 */
2361     44,  64,  45,  47,  46,  59,  47,  76,  /*  88 -  95 */
2362     48,  65,  49,  66,  50,  67,  51,  66,  /*  96 - 103 */
2363     52,  70,  53,  74,  54, 104,  55,  74,  /* 104 - 111 */
2364     56,  64,  57,  69,  58,  78,  59,  68,  /* 112 - 119 */
2365     60,  61,  61,  80,  62,  75,  63,  68,  /* 120 - 127 */
2366     64,  65,  65, 128,  66, 129,  67,  90,  /* 128 - 135 */
2367     68,  73,  69, 131,  70,  94,  71,  88,  /* 136 - 143 */
2368     72, 128,  73,  98,  74, 132,  75, 121,  /* 144 - 151 */
2369     76, 102,  77, 124,  78, 132,  79, 106,  /* 152 - 159 */
2370     80,  97,  81, 160,  82,  99,  83, 134,  /* 160 - 167 */
2371     84,  86,  85,  95,  86, 160,  87, 100,  /* 168 - 175 */
2372     88, 113,  89,  98,  90, 107,  91, 122,  /* 176 - 183 */
2373     92, 111,  93, 102,  94, 126,  95, 150,  /* 184 - 191 */
2374     96, 128,  97, 130,  98, 133,  99, 195,  /* 192 - 199 */
2375    100, 128, 101, 123, 102, 164, 103, 138,  /* 200 - 207 */
2376    104, 145, 105, 146, 106, 109, 107, 149,  /* 208 - 215 */
2377    108, 200, 109, 146, 110, 170, 111, 157,  /* 216 - 223 */
2378    112, 128, 113, 130, 114, 182, 115, 132,  /* 224 - 231 */
2379    116, 200, 117, 132, 118, 158, 119, 206,  /* 232 - 239 */
2380    120, 240, 121, 162, 122, 147, 123, 152,  /* 240 - 247 */
2381    124, 166, 125, 214, 126, 138, 127, 153,  /* 248 - 255 */
2382  };
2383
2384
2385/* Return the number of multiplications required to calculate
2386   powi(x,n) where n is less than POWI_TABLE_SIZE.  This is a
2387   subroutine of powi_cost.  CACHE is an array indicating
2388   which exponents have already been calculated.  */
2389
2390static int
2391powi_lookup_cost (unsigned HOST_WIDE_INT n, bool *cache)
2392{
2393  /* If we've already calculated this exponent, then this evaluation
2394     doesn't require any additional multiplications.  */
2395  if (cache[n])
2396    return 0;
2397
2398  cache[n] = true;
2399  return powi_lookup_cost (n - powi_table[n], cache)
2400	 + powi_lookup_cost (powi_table[n], cache) + 1;
2401}
2402
2403/* Return the number of multiplications required to calculate
2404   powi(x,n) for an arbitrary x, given the exponent N.  This
2405   function needs to be kept in sync with expand_powi below.  */
2406
2407static int
2408powi_cost (HOST_WIDE_INT n)
2409{
2410  bool cache[POWI_TABLE_SIZE];
2411  unsigned HOST_WIDE_INT digit;
2412  unsigned HOST_WIDE_INT val;
2413  int result;
2414
2415  if (n == 0)
2416    return 0;
2417
2418  /* Ignore the reciprocal when calculating the cost.  */
2419  val = (n < 0) ? -n : n;
2420
2421  /* Initialize the exponent cache.  */
2422  memset (cache, 0, POWI_TABLE_SIZE * sizeof (bool));
2423  cache[1] = true;
2424
2425  result = 0;
2426
2427  while (val >= POWI_TABLE_SIZE)
2428    {
2429      if (val & 1)
2430	{
2431	  digit = val & ((1 << POWI_WINDOW_SIZE) - 1);
2432	  result += powi_lookup_cost (digit, cache)
2433		    + POWI_WINDOW_SIZE + 1;
2434	  val >>= POWI_WINDOW_SIZE;
2435	}
2436      else
2437	{
2438	  val >>= 1;
2439	  result++;
2440	}
2441    }
2442
2443  return result + powi_lookup_cost (val, cache);
2444}
2445
2446/* Recursive subroutine of expand_powi.  This function takes the array,
2447   CACHE, of already calculated exponents and an exponent N and returns
2448   an RTX that corresponds to CACHE[1]**N, as calculated in mode MODE.  */
2449
2450static rtx
2451expand_powi_1 (enum machine_mode mode, unsigned HOST_WIDE_INT n, rtx *cache)
2452{
2453  unsigned HOST_WIDE_INT digit;
2454  rtx target, result;
2455  rtx op0, op1;
2456
2457  if (n < POWI_TABLE_SIZE)
2458    {
2459      if (cache[n])
2460	return cache[n];
2461
2462      target = gen_reg_rtx (mode);
2463      cache[n] = target;
2464
2465      op0 = expand_powi_1 (mode, n - powi_table[n], cache);
2466      op1 = expand_powi_1 (mode, powi_table[n], cache);
2467    }
2468  else if (n & 1)
2469    {
2470      target = gen_reg_rtx (mode);
2471      digit = n & ((1 << POWI_WINDOW_SIZE) - 1);
2472      op0 = expand_powi_1 (mode, n - digit, cache);
2473      op1 = expand_powi_1 (mode, digit, cache);
2474    }
2475  else
2476    {
2477      target = gen_reg_rtx (mode);
2478      op0 = expand_powi_1 (mode, n >> 1, cache);
2479      op1 = op0;
2480    }
2481
2482  result = expand_mult (mode, op0, op1, target, 0);
2483  if (result != target)
2484    emit_move_insn (target, result);
2485  return target;
2486}
2487
2488/* Expand the RTL to evaluate powi(x,n) in mode MODE.  X is the
2489   floating point operand in mode MODE, and N is the exponent.  This
2490   function needs to be kept in sync with powi_cost above.  */
2491
2492static rtx
2493expand_powi (rtx x, enum machine_mode mode, HOST_WIDE_INT n)
2494{
2495  unsigned HOST_WIDE_INT val;
2496  rtx cache[POWI_TABLE_SIZE];
2497  rtx result;
2498
2499  if (n == 0)
2500    return CONST1_RTX (mode);
2501
2502  val = (n < 0) ? -n : n;
2503
2504  memset (cache, 0, sizeof (cache));
2505  cache[1] = x;
2506
2507  result = expand_powi_1 (mode, (n < 0) ? -n : n, cache);
2508
2509  /* If the original exponent was negative, reciprocate the result.  */
2510  if (n < 0)
2511    result = expand_binop (mode, sdiv_optab, CONST1_RTX (mode),
2512			   result, NULL_RTX, 0, OPTAB_LIB_WIDEN);
2513
2514  return result;
2515}
2516
2517/* Expand a call to the pow built-in mathematical function.  Return 0 if
2518   a normal call should be emitted rather than expanding the function
2519   in-line.  EXP is the expression that is a call to the builtin
2520   function; if convenient, the result should be placed in TARGET.  */
2521
2522static rtx
2523expand_builtin_pow (tree exp, rtx target, rtx subtarget)
2524{
2525  tree arglist = TREE_OPERAND (exp, 1);
2526  tree arg0, arg1;
2527
2528  if (! validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
2529    return 0;
2530
2531  arg0 = TREE_VALUE (arglist);
2532  arg1 = TREE_VALUE (TREE_CHAIN (arglist));
2533
2534  if (TREE_CODE (arg1) == REAL_CST
2535      && ! TREE_CONSTANT_OVERFLOW (arg1))
2536    {
2537      REAL_VALUE_TYPE cint;
2538      REAL_VALUE_TYPE c;
2539      HOST_WIDE_INT n;
2540
2541      c = TREE_REAL_CST (arg1);
2542      n = real_to_integer (&c);
2543      real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
2544      if (real_identical (&c, &cint))
2545	{
2546	  /* If the exponent is -1, 0, 1 or 2, then expand_powi is exact.
2547	     Otherwise, check the number of multiplications required.
2548	     Note that pow never sets errno for an integer exponent.  */
2549	  if ((n >= -1 && n <= 2)
2550	      || (flag_unsafe_math_optimizations
2551		  && ! optimize_size
2552		  && powi_cost (n) <= POWI_MAX_MULTS))
2553	    {
2554	      enum machine_mode mode = TYPE_MODE (TREE_TYPE (exp));
2555	      rtx op = expand_expr (arg0, subtarget, VOIDmode, 0);
2556	      op = force_reg (mode, op);
2557	      return expand_powi (op, mode, n);
2558	    }
2559	}
2560    }
2561
2562  if (! flag_unsafe_math_optimizations)
2563    return NULL_RTX;
2564  return expand_builtin_mathfn_2 (exp, target, subtarget);
2565}
2566
2567/* Expand a call to the powi built-in mathematical function.  Return 0 if
2568   a normal call should be emitted rather than expanding the function
2569   in-line.  EXP is the expression that is a call to the builtin
2570   function; if convenient, the result should be placed in TARGET.  */
2571
2572static rtx
2573expand_builtin_powi (tree exp, rtx target, rtx subtarget)
2574{
2575  tree arglist = TREE_OPERAND (exp, 1);
2576  tree arg0, arg1;
2577  rtx op0, op1;
2578  enum machine_mode mode;
2579  enum machine_mode mode2;
2580
2581  if (! validate_arglist (arglist, REAL_TYPE, INTEGER_TYPE, VOID_TYPE))
2582    return 0;
2583
2584  arg0 = TREE_VALUE (arglist);
2585  arg1 = TREE_VALUE (TREE_CHAIN (arglist));
2586  mode = TYPE_MODE (TREE_TYPE (exp));
2587
2588  /* Handle constant power.  */
2589
2590  if (TREE_CODE (arg1) == INTEGER_CST
2591      && ! TREE_CONSTANT_OVERFLOW (arg1))
2592    {
2593      HOST_WIDE_INT n = TREE_INT_CST_LOW (arg1);
2594
2595      /* If the exponent is -1, 0, 1 or 2, then expand_powi is exact.
2596	 Otherwise, check the number of multiplications required.  */
2597      if ((TREE_INT_CST_HIGH (arg1) == 0
2598	   || TREE_INT_CST_HIGH (arg1) == -1)
2599	  && ((n >= -1 && n <= 2)
2600	      || (! optimize_size
2601		  && powi_cost (n) <= POWI_MAX_MULTS)))
2602	{
2603	  op0 = expand_expr (arg0, subtarget, VOIDmode, 0);
2604	  op0 = force_reg (mode, op0);
2605	  return expand_powi (op0, mode, n);
2606	}
2607    }
2608
2609  /* Emit a libcall to libgcc.  */
2610
2611  /* Mode of the 2nd argument must match that of an int. */
2612  mode2 = mode_for_size (INT_TYPE_SIZE, MODE_INT, 0);
2613
2614  if (target == NULL_RTX)
2615    target = gen_reg_rtx (mode);
2616
2617  op0 = expand_expr (arg0, subtarget, mode, 0);
2618  if (GET_MODE (op0) != mode)
2619    op0 = convert_to_mode (mode, op0, 0);
2620  op1 = expand_expr (arg1, 0, mode2, 0);
2621  if (GET_MODE (op1) != mode2)
2622    op1 = convert_to_mode (mode2, op1, 0);
2623
2624  target = emit_library_call_value (powi_optab->handlers[(int) mode].libfunc,
2625				    target, LCT_CONST_MAKE_BLOCK, mode, 2,
2626				    op0, mode, op1, mode2);
2627
2628  return target;
2629}
2630
2631/* Expand expression EXP which is a call to the strlen builtin.  Return 0
2632   if we failed the caller should emit a normal call, otherwise
2633   try to get the result in TARGET, if convenient.  */
2634
2635static rtx
2636expand_builtin_strlen (tree arglist, rtx target,
2637		       enum machine_mode target_mode)
2638{
2639  if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
2640    return 0;
2641  else
2642    {
2643      rtx pat;
2644      tree len, src = TREE_VALUE (arglist);
2645      rtx result, src_reg, char_rtx, before_strlen;
2646      enum machine_mode insn_mode = target_mode, char_mode;
2647      enum insn_code icode = CODE_FOR_nothing;
2648      int align;
2649
2650      /* If the length can be computed at compile-time, return it.  */
2651      len = c_strlen (src, 0);
2652      if (len)
2653	return expand_expr (len, target, target_mode, EXPAND_NORMAL);
2654
2655      /* If the length can be computed at compile-time and is constant
2656	 integer, but there are side-effects in src, evaluate
2657	 src for side-effects, then return len.
2658	 E.g. x = strlen (i++ ? "xfoo" + 1 : "bar");
2659	 can be optimized into: i++; x = 3;  */
2660      len = c_strlen (src, 1);
2661      if (len && TREE_CODE (len) == INTEGER_CST)
2662	{
2663	  expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
2664	  return expand_expr (len, target, target_mode, EXPAND_NORMAL);
2665	}
2666
2667      align = get_pointer_alignment (src, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
2668
2669      /* If SRC is not a pointer type, don't do this operation inline.  */
2670      if (align == 0)
2671	return 0;
2672
2673      /* Bail out if we can't compute strlen in the right mode.  */
2674      while (insn_mode != VOIDmode)
2675	{
2676	  icode = strlen_optab->handlers[(int) insn_mode].insn_code;
2677	  if (icode != CODE_FOR_nothing)
2678	    break;
2679
2680	  insn_mode = GET_MODE_WIDER_MODE (insn_mode);
2681	}
2682      if (insn_mode == VOIDmode)
2683	return 0;
2684
2685      /* Make a place to write the result of the instruction.  */
2686      result = target;
2687      if (! (result != 0
2688	     && REG_P (result)
2689	     && GET_MODE (result) == insn_mode
2690	     && REGNO (result) >= FIRST_PSEUDO_REGISTER))
2691	result = gen_reg_rtx (insn_mode);
2692
2693      /* Make a place to hold the source address.  We will not expand
2694	 the actual source until we are sure that the expansion will
2695	 not fail -- there are trees that cannot be expanded twice.  */
2696      src_reg = gen_reg_rtx (Pmode);
2697
2698      /* Mark the beginning of the strlen sequence so we can emit the
2699	 source operand later.  */
2700      before_strlen = get_last_insn ();
2701
2702      char_rtx = const0_rtx;
2703      char_mode = insn_data[(int) icode].operand[2].mode;
2704      if (! (*insn_data[(int) icode].operand[2].predicate) (char_rtx,
2705							    char_mode))
2706	char_rtx = copy_to_mode_reg (char_mode, char_rtx);
2707
2708      pat = GEN_FCN (icode) (result, gen_rtx_MEM (BLKmode, src_reg),
2709			     char_rtx, GEN_INT (align));
2710      if (! pat)
2711	return 0;
2712      emit_insn (pat);
2713
2714      /* Now that we are assured of success, expand the source.  */
2715      start_sequence ();
2716      pat = expand_expr (src, src_reg, ptr_mode, EXPAND_NORMAL);
2717      if (pat != src_reg)
2718	emit_move_insn (src_reg, pat);
2719      pat = get_insns ();
2720      end_sequence ();
2721
2722      if (before_strlen)
2723	emit_insn_after (pat, before_strlen);
2724      else
2725	emit_insn_before (pat, get_insns ());
2726
2727      /* Return the value in the proper mode for this function.  */
2728      if (GET_MODE (result) == target_mode)
2729	target = result;
2730      else if (target != 0)
2731	convert_move (target, result, 0);
2732      else
2733	target = convert_to_mode (target_mode, result, 0);
2734
2735      return target;
2736    }
2737}
2738
2739/* Expand a call to the strstr builtin.  Return 0 if we failed the
2740   caller should emit a normal call, otherwise try to get the result
2741   in TARGET, if convenient (and in mode MODE if that's convenient).  */
2742
2743static rtx
2744expand_builtin_strstr (tree arglist, tree type, rtx target, enum machine_mode mode)
2745{
2746  if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2747    {
2748      tree result = fold_builtin_strstr (arglist, type);
2749      if (result)
2750	return expand_expr (result, target, mode, EXPAND_NORMAL);
2751    }
2752  return 0;
2753}
2754
2755/* Expand a call to the strchr builtin.  Return 0 if we failed the
2756   caller should emit a normal call, otherwise try to get the result
2757   in TARGET, if convenient (and in mode MODE if that's convenient).  */
2758
2759static rtx
2760expand_builtin_strchr (tree arglist, tree type, rtx target, enum machine_mode mode)
2761{
2762  if (validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2763    {
2764      tree result = fold_builtin_strchr (arglist, type);
2765      if (result)
2766	return expand_expr (result, target, mode, EXPAND_NORMAL);
2767
2768      /* FIXME: Should use strchrM optab so that ports can optimize this.  */
2769    }
2770  return 0;
2771}
2772
2773/* Expand a call to the strrchr builtin.  Return 0 if we failed the
2774   caller should emit a normal call, otherwise try to get the result
2775   in TARGET, if convenient (and in mode MODE if that's convenient).  */
2776
2777static rtx
2778expand_builtin_strrchr (tree arglist, tree type, rtx target, enum machine_mode mode)
2779{
2780  if (validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2781    {
2782      tree result = fold_builtin_strrchr (arglist, type);
2783      if (result)
2784	return expand_expr (result, target, mode, EXPAND_NORMAL);
2785    }
2786  return 0;
2787}
2788
2789/* Expand a call to the strpbrk builtin.  Return 0 if we failed the
2790   caller should emit a normal call, otherwise try to get the result
2791   in TARGET, if convenient (and in mode MODE if that's convenient).  */
2792
2793static rtx
2794expand_builtin_strpbrk (tree arglist, tree type, rtx target, enum machine_mode mode)
2795{
2796  if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2797    {
2798      tree result = fold_builtin_strpbrk (arglist, type);
2799      if (result)
2800	return expand_expr (result, target, mode, EXPAND_NORMAL);
2801    }
2802  return 0;
2803}
2804
2805/* Callback routine for store_by_pieces.  Read GET_MODE_BITSIZE (MODE)
2806   bytes from constant string DATA + OFFSET and return it as target
2807   constant.  */
2808
2809static rtx
2810builtin_memcpy_read_str (void *data, HOST_WIDE_INT offset,
2811			 enum machine_mode mode)
2812{
2813  const char *str = (const char *) data;
2814
2815  gcc_assert (offset >= 0
2816	      && ((unsigned HOST_WIDE_INT) offset + GET_MODE_SIZE (mode)
2817		  <= strlen (str) + 1));
2818
2819  return c_readstr (str + offset, mode);
2820}
2821
2822/* Expand a call to the memcpy builtin, with arguments in ARGLIST.
2823   Return 0 if we failed, the caller should emit a normal call,
2824   otherwise try to get the result in TARGET, if convenient (and in
2825   mode MODE if that's convenient).  */
2826static rtx
2827expand_builtin_memcpy (tree exp, rtx target, enum machine_mode mode)
2828{
2829  tree fndecl = get_callee_fndecl (exp);
2830  tree arglist = TREE_OPERAND (exp, 1);
2831  if (!validate_arglist (arglist,
2832			 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2833    return 0;
2834  else
2835    {
2836      tree dest = TREE_VALUE (arglist);
2837      tree src = TREE_VALUE (TREE_CHAIN (arglist));
2838      tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2839      const char *src_str;
2840      unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
2841      unsigned int dest_align
2842	= get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2843      rtx dest_mem, src_mem, dest_addr, len_rtx;
2844      tree result = fold_builtin_memory_op (arglist, TREE_TYPE (TREE_TYPE (fndecl)),
2845					    false, /*endp=*/0);
2846
2847      if (result)
2848	{
2849	  while (TREE_CODE (result) == COMPOUND_EXPR)
2850	    {
2851	      expand_expr (TREE_OPERAND (result, 0), const0_rtx, VOIDmode,
2852			   EXPAND_NORMAL);
2853	      result = TREE_OPERAND (result, 1);
2854	    }
2855	  return expand_expr (result, target, mode, EXPAND_NORMAL);
2856	}
2857
2858      /* If DEST is not a pointer type, call the normal function.  */
2859      if (dest_align == 0)
2860	return 0;
2861
2862      /* If either SRC is not a pointer type, don't do this
2863	 operation in-line.  */
2864      if (src_align == 0)
2865	return 0;
2866
2867      dest_mem = get_memory_rtx (dest, len);
2868      set_mem_align (dest_mem, dest_align);
2869      len_rtx = expand_normal (len);
2870      src_str = c_getstr (src);
2871
2872      /* If SRC is a string constant and block move would be done
2873	 by pieces, we can avoid loading the string from memory
2874	 and only stored the computed constants.  */
2875      if (src_str
2876	  && GET_CODE (len_rtx) == CONST_INT
2877	  && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
2878	  && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
2879				  (void *) src_str, dest_align))
2880	{
2881	  dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
2882				      builtin_memcpy_read_str,
2883				      (void *) src_str, dest_align, 0);
2884	  dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2885	  dest_mem = convert_memory_address (ptr_mode, dest_mem);
2886	  return dest_mem;
2887	}
2888
2889      src_mem = get_memory_rtx (src, len);
2890      set_mem_align (src_mem, src_align);
2891
2892      /* Copy word part most expediently.  */
2893      dest_addr = emit_block_move (dest_mem, src_mem, len_rtx,
2894				   CALL_EXPR_TAILCALL (exp)
2895				   ? BLOCK_OP_TAILCALL : BLOCK_OP_NORMAL);
2896
2897      if (dest_addr == 0)
2898	{
2899	  dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2900	  dest_addr = convert_memory_address (ptr_mode, dest_addr);
2901	}
2902      return dest_addr;
2903    }
2904}
2905
2906/* Expand a call to the mempcpy builtin, with arguments in ARGLIST.
2907   Return 0 if we failed; the caller should emit a normal call,
2908   otherwise try to get the result in TARGET, if convenient (and in
2909   mode MODE if that's convenient).  If ENDP is 0 return the
2910   destination pointer, if ENDP is 1 return the end pointer ala
2911   mempcpy, and if ENDP is 2 return the end pointer minus one ala
2912   stpcpy.  */
2913
2914static rtx
2915expand_builtin_mempcpy (tree arglist, tree type, rtx target, enum machine_mode mode,
2916			int endp)
2917{
2918  if (!validate_arglist (arglist,
2919			 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2920    return 0;
2921  /* If return value is ignored, transform mempcpy into memcpy.  */
2922  else if (target == const0_rtx)
2923    {
2924      tree fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
2925
2926      if (!fn)
2927	return 0;
2928
2929      return expand_expr (build_function_call_expr (fn, arglist),
2930			  target, mode, EXPAND_NORMAL);
2931    }
2932  else
2933    {
2934      tree dest = TREE_VALUE (arglist);
2935      tree src = TREE_VALUE (TREE_CHAIN (arglist));
2936      tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2937      const char *src_str;
2938      unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
2939      unsigned int dest_align
2940	= get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2941      rtx dest_mem, src_mem, len_rtx;
2942      tree result = fold_builtin_memory_op (arglist, type, false, endp);
2943
2944      if (result)
2945	{
2946	  while (TREE_CODE (result) == COMPOUND_EXPR)
2947	    {
2948	      expand_expr (TREE_OPERAND (result, 0), const0_rtx, VOIDmode,
2949			   EXPAND_NORMAL);
2950	      result = TREE_OPERAND (result, 1);
2951	    }
2952	  return expand_expr (result, target, mode, EXPAND_NORMAL);
2953	}
2954
2955      /* If either SRC or DEST is not a pointer type, don't do this
2956	 operation in-line.  */
2957      if (dest_align == 0 || src_align == 0)
2958	return 0;
2959
2960      /* If LEN is not constant, call the normal function.  */
2961      if (! host_integerp (len, 1))
2962	return 0;
2963
2964      len_rtx = expand_normal (len);
2965      src_str = c_getstr (src);
2966
2967      /* If SRC is a string constant and block move would be done
2968	 by pieces, we can avoid loading the string from memory
2969	 and only stored the computed constants.  */
2970      if (src_str
2971	  && GET_CODE (len_rtx) == CONST_INT
2972	  && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
2973	  && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
2974				  (void *) src_str, dest_align))
2975	{
2976	  dest_mem = get_memory_rtx (dest, len);
2977	  set_mem_align (dest_mem, dest_align);
2978	  dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
2979				      builtin_memcpy_read_str,
2980				      (void *) src_str, dest_align, endp);
2981	  dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2982	  dest_mem = convert_memory_address (ptr_mode, dest_mem);
2983	  return dest_mem;
2984	}
2985
2986      if (GET_CODE (len_rtx) == CONST_INT
2987	  && can_move_by_pieces (INTVAL (len_rtx),
2988				 MIN (dest_align, src_align)))
2989	{
2990	  dest_mem = get_memory_rtx (dest, len);
2991	  set_mem_align (dest_mem, dest_align);
2992	  src_mem = get_memory_rtx (src, len);
2993	  set_mem_align (src_mem, src_align);
2994	  dest_mem = move_by_pieces (dest_mem, src_mem, INTVAL (len_rtx),
2995				     MIN (dest_align, src_align), endp);
2996	  dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2997	  dest_mem = convert_memory_address (ptr_mode, dest_mem);
2998	  return dest_mem;
2999	}
3000
3001      return 0;
3002    }
3003}
3004
3005/* Expand expression EXP, which is a call to the memmove builtin.  Return 0
3006   if we failed; the caller should emit a normal call.  */
3007
3008static rtx
3009expand_builtin_memmove (tree arglist, tree type, rtx target,
3010			enum machine_mode mode, tree orig_exp)
3011{
3012  if (!validate_arglist (arglist,
3013			 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3014    return 0;
3015  else
3016    {
3017      tree dest = TREE_VALUE (arglist);
3018      tree src = TREE_VALUE (TREE_CHAIN (arglist));
3019      tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3020
3021      unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
3022      unsigned int dest_align
3023	= get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
3024      tree result = fold_builtin_memory_op (arglist, type, false, /*endp=*/3);
3025
3026      if (result)
3027	{
3028	  while (TREE_CODE (result) == COMPOUND_EXPR)
3029	    {
3030	      expand_expr (TREE_OPERAND (result, 0), const0_rtx, VOIDmode,
3031			   EXPAND_NORMAL);
3032	      result = TREE_OPERAND (result, 1);
3033	    }
3034	  return expand_expr (result, target, mode, EXPAND_NORMAL);
3035	}
3036
3037      /* If DEST is not a pointer type, call the normal function.  */
3038      if (dest_align == 0)
3039	return 0;
3040
3041      /* If either SRC is not a pointer type, don't do this
3042	 operation in-line.  */
3043      if (src_align == 0)
3044	return 0;
3045
3046      /* If src is categorized for a readonly section we can use
3047	 normal memcpy.  */
3048      if (readonly_data_expr (src))
3049	{
3050	  tree fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
3051	  if (!fn)
3052	    return 0;
3053	  fn = build_function_call_expr (fn, arglist);
3054	  if (TREE_CODE (fn) == CALL_EXPR)
3055	    CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (orig_exp);
3056	  return expand_expr (fn, target, mode, EXPAND_NORMAL);
3057	}
3058
3059      /* If length is 1 and we can expand memcpy call inline,
3060	 it is ok to use memcpy as well.  */
3061      if (integer_onep (len))
3062	{
3063	  rtx ret = expand_builtin_mempcpy (arglist, type, target, mode,
3064					    /*endp=*/0);
3065	  if (ret)
3066	    return ret;
3067	}
3068
3069      /* Otherwise, call the normal function.  */
3070      return 0;
3071   }
3072}
3073
3074/* Expand expression EXP, which is a call to the bcopy builtin.  Return 0
3075   if we failed the caller should emit a normal call.  */
3076
3077static rtx
3078expand_builtin_bcopy (tree exp)
3079{
3080  tree arglist = TREE_OPERAND (exp, 1);
3081  tree type = TREE_TYPE (exp);
3082  tree src, dest, size, newarglist;
3083
3084  if (!validate_arglist (arglist,
3085			 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3086    return NULL_RTX;
3087
3088  src = TREE_VALUE (arglist);
3089  dest = TREE_VALUE (TREE_CHAIN (arglist));
3090  size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3091
3092  /* New argument list transforming bcopy(ptr x, ptr y, int z) to
3093     memmove(ptr y, ptr x, size_t z).   This is done this way
3094     so that if it isn't expanded inline, we fallback to
3095     calling bcopy instead of memmove.  */
3096
3097  newarglist = build_tree_list (NULL_TREE, fold_convert (sizetype, size));
3098  newarglist = tree_cons (NULL_TREE, src, newarglist);
3099  newarglist = tree_cons (NULL_TREE, dest, newarglist);
3100
3101  return expand_builtin_memmove (newarglist, type, const0_rtx, VOIDmode, exp);
3102}
3103
3104#ifndef HAVE_movstr
3105# define HAVE_movstr 0
3106# define CODE_FOR_movstr CODE_FOR_nothing
3107#endif
3108
3109/* Expand into a movstr instruction, if one is available.  Return 0 if
3110   we failed, the caller should emit a normal call, otherwise try to
3111   get the result in TARGET, if convenient.  If ENDP is 0 return the
3112   destination pointer, if ENDP is 1 return the end pointer ala
3113   mempcpy, and if ENDP is 2 return the end pointer minus one ala
3114   stpcpy.  */
3115
3116static rtx
3117expand_movstr (tree dest, tree src, rtx target, int endp)
3118{
3119  rtx end;
3120  rtx dest_mem;
3121  rtx src_mem;
3122  rtx insn;
3123  const struct insn_data * data;
3124
3125  if (!HAVE_movstr)
3126    return 0;
3127
3128  dest_mem = get_memory_rtx (dest, NULL);
3129  src_mem = get_memory_rtx (src, NULL);
3130  if (!endp)
3131    {
3132      target = force_reg (Pmode, XEXP (dest_mem, 0));
3133      dest_mem = replace_equiv_address (dest_mem, target);
3134      end = gen_reg_rtx (Pmode);
3135    }
3136  else
3137    {
3138      if (target == 0 || target == const0_rtx)
3139	{
3140	  end = gen_reg_rtx (Pmode);
3141	  if (target == 0)
3142	    target = end;
3143	}
3144      else
3145	end = target;
3146    }
3147
3148  data = insn_data + CODE_FOR_movstr;
3149
3150  if (data->operand[0].mode != VOIDmode)
3151    end = gen_lowpart (data->operand[0].mode, end);
3152
3153  insn = data->genfun (end, dest_mem, src_mem);
3154
3155  gcc_assert (insn);
3156
3157  emit_insn (insn);
3158
3159  /* movstr is supposed to set end to the address of the NUL
3160     terminator.  If the caller requested a mempcpy-like return value,
3161     adjust it.  */
3162  if (endp == 1 && target != const0_rtx)
3163    {
3164      rtx tem = plus_constant (gen_lowpart (GET_MODE (target), end), 1);
3165      emit_move_insn (target, force_operand (tem, NULL_RTX));
3166    }
3167
3168  return target;
3169}
3170
3171/* Expand expression EXP, which is a call to the strcpy builtin.  Return 0
3172   if we failed the caller should emit a normal call, otherwise try to get
3173   the result in TARGET, if convenient (and in mode MODE if that's
3174   convenient).  */
3175
3176static rtx
3177expand_builtin_strcpy (tree fndecl, tree arglist, rtx target, enum machine_mode mode)
3178{
3179  if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3180    {
3181      tree result = fold_builtin_strcpy (fndecl, arglist, 0);
3182      if (result)
3183	{
3184	  while (TREE_CODE (result) == COMPOUND_EXPR)
3185	    {
3186	      expand_expr (TREE_OPERAND (result, 0), const0_rtx, VOIDmode,
3187			   EXPAND_NORMAL);
3188	      result = TREE_OPERAND (result, 1);
3189	    }
3190	  return expand_expr (result, target, mode, EXPAND_NORMAL);
3191	}
3192
3193      return expand_movstr (TREE_VALUE (arglist),
3194			    TREE_VALUE (TREE_CHAIN (arglist)),
3195			    target, /*endp=*/0);
3196    }
3197  return 0;
3198}
3199
3200/* Expand a call to the stpcpy builtin, with arguments in ARGLIST.
3201   Return 0 if we failed the caller should emit a normal call,
3202   otherwise try to get the result in TARGET, if convenient (and in
3203   mode MODE if that's convenient).  */
3204
3205static rtx
3206expand_builtin_stpcpy (tree exp, rtx target, enum machine_mode mode)
3207{
3208  tree arglist = TREE_OPERAND (exp, 1);
3209  /* If return value is ignored, transform stpcpy into strcpy.  */
3210  if (target == const0_rtx)
3211    {
3212      tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
3213      if (!fn)
3214	return 0;
3215
3216      return expand_expr (build_function_call_expr (fn, arglist),
3217			  target, mode, EXPAND_NORMAL);
3218    }
3219
3220  if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3221    return 0;
3222  else
3223    {
3224      tree dst, src, len, lenp1;
3225      tree narglist;
3226      rtx ret;
3227
3228      /* Ensure we get an actual string whose length can be evaluated at
3229	 compile-time, not an expression containing a string.  This is
3230	 because the latter will potentially produce pessimized code
3231	 when used to produce the return value.  */
3232      src = TREE_VALUE (TREE_CHAIN (arglist));
3233      if (! c_getstr (src) || ! (len = c_strlen (src, 0)))
3234	return expand_movstr (TREE_VALUE (arglist),
3235			      TREE_VALUE (TREE_CHAIN (arglist)),
3236			      target, /*endp=*/2);
3237
3238      dst = TREE_VALUE (arglist);
3239      lenp1 = size_binop (PLUS_EXPR, len, ssize_int (1));
3240      narglist = build_tree_list (NULL_TREE, lenp1);
3241      narglist = tree_cons (NULL_TREE, src, narglist);
3242      narglist = tree_cons (NULL_TREE, dst, narglist);
3243      ret = expand_builtin_mempcpy (narglist, TREE_TYPE (exp),
3244				    target, mode, /*endp=*/2);
3245
3246      if (ret)
3247	return ret;
3248
3249      if (TREE_CODE (len) == INTEGER_CST)
3250	{
3251	  rtx len_rtx = expand_normal (len);
3252
3253	  if (GET_CODE (len_rtx) == CONST_INT)
3254	    {
3255	      ret = expand_builtin_strcpy (get_callee_fndecl (exp),
3256					   arglist, target, mode);
3257
3258	      if (ret)
3259		{
3260		  if (! target)
3261		    {
3262		      if (mode != VOIDmode)
3263			target = gen_reg_rtx (mode);
3264		      else
3265			target = gen_reg_rtx (GET_MODE (ret));
3266		    }
3267		  if (GET_MODE (target) != GET_MODE (ret))
3268		    ret = gen_lowpart (GET_MODE (target), ret);
3269
3270		  ret = plus_constant (ret, INTVAL (len_rtx));
3271		  ret = emit_move_insn (target, force_operand (ret, NULL_RTX));
3272		  gcc_assert (ret);
3273
3274		  return target;
3275		}
3276	    }
3277	}
3278
3279      return expand_movstr (TREE_VALUE (arglist),
3280			    TREE_VALUE (TREE_CHAIN (arglist)),
3281			    target, /*endp=*/2);
3282    }
3283}
3284
3285/* Callback routine for store_by_pieces.  Read GET_MODE_BITSIZE (MODE)
3286   bytes from constant string DATA + OFFSET and return it as target
3287   constant.  */
3288
3289static rtx
3290builtin_strncpy_read_str (void *data, HOST_WIDE_INT offset,
3291			  enum machine_mode mode)
3292{
3293  const char *str = (const char *) data;
3294
3295  if ((unsigned HOST_WIDE_INT) offset > strlen (str))
3296    return const0_rtx;
3297
3298  return c_readstr (str + offset, mode);
3299}
3300
3301/* Expand expression EXP, which is a call to the strncpy builtin.  Return 0
3302   if we failed the caller should emit a normal call.  */
3303
3304static rtx
3305expand_builtin_strncpy (tree exp, rtx target, enum machine_mode mode)
3306{
3307  tree fndecl = get_callee_fndecl (exp);
3308  tree arglist = TREE_OPERAND (exp, 1);
3309  if (validate_arglist (arglist,
3310			POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3311    {
3312      tree slen = c_strlen (TREE_VALUE (TREE_CHAIN (arglist)), 1);
3313      tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3314      tree result = fold_builtin_strncpy (fndecl, arglist, slen);
3315
3316      if (result)
3317	{
3318	  while (TREE_CODE (result) == COMPOUND_EXPR)
3319	    {
3320	      expand_expr (TREE_OPERAND (result, 0), const0_rtx, VOIDmode,
3321			   EXPAND_NORMAL);
3322	      result = TREE_OPERAND (result, 1);
3323	    }
3324	  return expand_expr (result, target, mode, EXPAND_NORMAL);
3325	}
3326
3327      /* We must be passed a constant len and src parameter.  */
3328      if (!host_integerp (len, 1) || !slen || !host_integerp (slen, 1))
3329	return 0;
3330
3331      slen = size_binop (PLUS_EXPR, slen, ssize_int (1));
3332
3333      /* We're required to pad with trailing zeros if the requested
3334	 len is greater than strlen(s2)+1.  In that case try to
3335	 use store_by_pieces, if it fails, punt.  */
3336      if (tree_int_cst_lt (slen, len))
3337	{
3338	  tree dest = TREE_VALUE (arglist);
3339	  unsigned int dest_align
3340	    = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
3341	  const char *p = c_getstr (TREE_VALUE (TREE_CHAIN (arglist)));
3342	  rtx dest_mem;
3343
3344	  if (!p || dest_align == 0 || !host_integerp (len, 1)
3345	      || !can_store_by_pieces (tree_low_cst (len, 1),
3346				       builtin_strncpy_read_str,
3347				       (void *) p, dest_align))
3348	    return 0;
3349
3350	  dest_mem = get_memory_rtx (dest, len);
3351	  store_by_pieces (dest_mem, tree_low_cst (len, 1),
3352			   builtin_strncpy_read_str,
3353			   (void *) p, dest_align, 0);
3354	  dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3355	  dest_mem = convert_memory_address (ptr_mode, dest_mem);
3356	  return dest_mem;
3357	}
3358    }
3359  return 0;
3360}
3361
3362/* Callback routine for store_by_pieces.  Read GET_MODE_BITSIZE (MODE)
3363   bytes from constant string DATA + OFFSET and return it as target
3364   constant.  */
3365
3366static rtx
3367builtin_memset_read_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
3368			 enum machine_mode mode)
3369{
3370  const char *c = (const char *) data;
3371  char *p = alloca (GET_MODE_SIZE (mode));
3372
3373  memset (p, *c, GET_MODE_SIZE (mode));
3374
3375  return c_readstr (p, mode);
3376}
3377
3378/* Callback routine for store_by_pieces.  Return the RTL of a register
3379   containing GET_MODE_SIZE (MODE) consecutive copies of the unsigned
3380   char value given in the RTL register data.  For example, if mode is
3381   4 bytes wide, return the RTL for 0x01010101*data.  */
3382
3383static rtx
3384builtin_memset_gen_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
3385			enum machine_mode mode)
3386{
3387  rtx target, coeff;
3388  size_t size;
3389  char *p;
3390
3391  size = GET_MODE_SIZE (mode);
3392  if (size == 1)
3393    return (rtx) data;
3394
3395  p = alloca (size);
3396  memset (p, 1, size);
3397  coeff = c_readstr (p, mode);
3398
3399  target = convert_to_mode (mode, (rtx) data, 1);
3400  target = expand_mult (mode, target, coeff, NULL_RTX, 1);
3401  return force_reg (mode, target);
3402}
3403
3404/* Expand expression EXP, which is a call to the memset builtin.  Return 0
3405   if we failed the caller should emit a normal call, otherwise try to get
3406   the result in TARGET, if convenient (and in mode MODE if that's
3407   convenient).  */
3408
3409static rtx
3410expand_builtin_memset (tree arglist, rtx target, enum machine_mode mode,
3411		       tree orig_exp)
3412{
3413  if (!validate_arglist (arglist,
3414			 POINTER_TYPE, INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
3415    return 0;
3416  else
3417    {
3418      tree dest = TREE_VALUE (arglist);
3419      tree val = TREE_VALUE (TREE_CHAIN (arglist));
3420      tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3421      tree fndecl, fn;
3422      enum built_in_function fcode;
3423      char c;
3424      unsigned int dest_align;
3425      rtx dest_mem, dest_addr, len_rtx;
3426
3427      dest_align = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
3428
3429      /* If DEST is not a pointer type, don't do this
3430	 operation in-line.  */
3431      if (dest_align == 0)
3432	return 0;
3433
3434      /* If the LEN parameter is zero, return DEST.  */
3435      if (integer_zerop (len))
3436	{
3437	  /* Evaluate and ignore VAL in case it has side-effects.  */
3438	  expand_expr (val, const0_rtx, VOIDmode, EXPAND_NORMAL);
3439	  return expand_expr (dest, target, mode, EXPAND_NORMAL);
3440	}
3441
3442      /* Stabilize the arguments in case we fail.  */
3443      dest = builtin_save_expr (dest);
3444      val = builtin_save_expr (val);
3445      len = builtin_save_expr (len);
3446
3447      len_rtx = expand_normal (len);
3448      dest_mem = get_memory_rtx (dest, len);
3449
3450      if (TREE_CODE (val) != INTEGER_CST)
3451	{
3452	  rtx val_rtx;
3453
3454	  val_rtx = expand_normal (val);
3455	  val_rtx = convert_to_mode (TYPE_MODE (unsigned_char_type_node),
3456				     val_rtx, 0);
3457
3458	  /* Assume that we can memset by pieces if we can store the
3459	   * the coefficients by pieces (in the required modes).
3460	   * We can't pass builtin_memset_gen_str as that emits RTL.  */
3461	  c = 1;
3462	  if (host_integerp (len, 1)
3463	      && !(optimize_size && tree_low_cst (len, 1) > 1)
3464	      && can_store_by_pieces (tree_low_cst (len, 1),
3465				      builtin_memset_read_str, &c, dest_align))
3466	    {
3467	      val_rtx = force_reg (TYPE_MODE (unsigned_char_type_node),
3468				   val_rtx);
3469	      store_by_pieces (dest_mem, tree_low_cst (len, 1),
3470			       builtin_memset_gen_str, val_rtx, dest_align, 0);
3471	    }
3472	  else if (!set_storage_via_setmem (dest_mem, len_rtx, val_rtx,
3473					    dest_align))
3474	    goto do_libcall;
3475
3476	  dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3477	  dest_mem = convert_memory_address (ptr_mode, dest_mem);
3478	  return dest_mem;
3479	}
3480
3481      if (target_char_cast (val, &c))
3482	goto do_libcall;
3483
3484      if (c)
3485	{
3486	  if (host_integerp (len, 1)
3487	      && !(optimize_size && tree_low_cst (len, 1) > 1)
3488	      && can_store_by_pieces (tree_low_cst (len, 1),
3489				      builtin_memset_read_str, &c, dest_align))
3490	    store_by_pieces (dest_mem, tree_low_cst (len, 1),
3491			     builtin_memset_read_str, &c, dest_align, 0);
3492	  else if (!set_storage_via_setmem (dest_mem, len_rtx, GEN_INT (c),
3493					    dest_align))
3494	    goto do_libcall;
3495
3496	  dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3497	  dest_mem = convert_memory_address (ptr_mode, dest_mem);
3498	  return dest_mem;
3499	}
3500
3501      set_mem_align (dest_mem, dest_align);
3502      dest_addr = clear_storage (dest_mem, len_rtx,
3503				 CALL_EXPR_TAILCALL (orig_exp)
3504				 ? BLOCK_OP_TAILCALL : BLOCK_OP_NORMAL);
3505
3506      if (dest_addr == 0)
3507	{
3508	  dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3509	  dest_addr = convert_memory_address (ptr_mode, dest_addr);
3510	}
3511
3512      return dest_addr;
3513
3514    do_libcall:
3515      fndecl = get_callee_fndecl (orig_exp);
3516      fcode = DECL_FUNCTION_CODE (fndecl);
3517      gcc_assert (fcode == BUILT_IN_MEMSET || fcode == BUILT_IN_BZERO);
3518      arglist = build_tree_list (NULL_TREE, len);
3519      if (fcode == BUILT_IN_MEMSET)
3520	arglist = tree_cons (NULL_TREE, val, arglist);
3521      arglist = tree_cons (NULL_TREE, dest, arglist);
3522      fn = build_function_call_expr (fndecl, arglist);
3523      if (TREE_CODE (fn) == CALL_EXPR)
3524	CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (orig_exp);
3525      return expand_call (fn, target, target == const0_rtx);
3526    }
3527}
3528
3529/* Expand expression EXP, which is a call to the bzero builtin.  Return 0
3530   if we failed the caller should emit a normal call.  */
3531
3532static rtx
3533expand_builtin_bzero (tree exp)
3534{
3535  tree arglist = TREE_OPERAND (exp, 1);
3536  tree dest, size, newarglist;
3537
3538  if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3539    return NULL_RTX;
3540
3541  dest = TREE_VALUE (arglist);
3542  size = TREE_VALUE (TREE_CHAIN (arglist));
3543
3544  /* New argument list transforming bzero(ptr x, int y) to
3545     memset(ptr x, int 0, size_t y).   This is done this way
3546     so that if it isn't expanded inline, we fallback to
3547     calling bzero instead of memset.  */
3548
3549  newarglist = build_tree_list (NULL_TREE, fold_convert (sizetype, size));
3550  newarglist = tree_cons (NULL_TREE, integer_zero_node, newarglist);
3551  newarglist = tree_cons (NULL_TREE, dest, newarglist);
3552
3553  return expand_builtin_memset (newarglist, const0_rtx, VOIDmode, exp);
3554}
3555
3556/* Expand expression EXP, which is a call to the memcmp built-in function.
3557   ARGLIST is the argument list for this call.  Return 0 if we failed and the
3558   caller should emit a normal call, otherwise try to get the result in
3559   TARGET, if convenient (and in mode MODE, if that's convenient).  */
3560
3561static rtx
3562expand_builtin_memcmp (tree exp ATTRIBUTE_UNUSED, tree arglist, rtx target,
3563		       enum machine_mode mode)
3564{
3565  if (!validate_arglist (arglist,
3566			 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3567    return 0;
3568  else
3569    {
3570      tree result = fold_builtin_memcmp (arglist);
3571      if (result)
3572	return expand_expr (result, target, mode, EXPAND_NORMAL);
3573    }
3574
3575#if defined HAVE_cmpmemsi || defined HAVE_cmpstrnsi
3576  {
3577    tree arg1 = TREE_VALUE (arglist);
3578    tree arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3579    tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3580    rtx arg1_rtx, arg2_rtx, arg3_rtx;
3581    rtx result;
3582    rtx insn;
3583
3584    int arg1_align
3585      = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3586    int arg2_align
3587      = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3588    enum machine_mode insn_mode;
3589
3590#ifdef HAVE_cmpmemsi
3591    if (HAVE_cmpmemsi)
3592      insn_mode = insn_data[(int) CODE_FOR_cmpmemsi].operand[0].mode;
3593    else
3594#endif
3595#ifdef HAVE_cmpstrnsi
3596    if (HAVE_cmpstrnsi)
3597      insn_mode = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode;
3598    else
3599#endif
3600      return 0;
3601
3602    /* If we don't have POINTER_TYPE, call the function.  */
3603    if (arg1_align == 0 || arg2_align == 0)
3604      return 0;
3605
3606    /* Make a place to write the result of the instruction.  */
3607    result = target;
3608    if (! (result != 0
3609	   && REG_P (result) && GET_MODE (result) == insn_mode
3610	   && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3611      result = gen_reg_rtx (insn_mode);
3612
3613    arg1_rtx = get_memory_rtx (arg1, len);
3614    arg2_rtx = get_memory_rtx (arg2, len);
3615    arg3_rtx = expand_normal (len);
3616
3617    /* Set MEM_SIZE as appropriate.  */
3618    if (GET_CODE (arg3_rtx) == CONST_INT)
3619      {
3620	set_mem_size (arg1_rtx, arg3_rtx);
3621	set_mem_size (arg2_rtx, arg3_rtx);
3622      }
3623
3624#ifdef HAVE_cmpmemsi
3625    if (HAVE_cmpmemsi)
3626      insn = gen_cmpmemsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3627			   GEN_INT (MIN (arg1_align, arg2_align)));
3628    else
3629#endif
3630#ifdef HAVE_cmpstrnsi
3631    if (HAVE_cmpstrnsi)
3632      insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3633			    GEN_INT (MIN (arg1_align, arg2_align)));
3634    else
3635#endif
3636      gcc_unreachable ();
3637
3638    if (insn)
3639      emit_insn (insn);
3640    else
3641      emit_library_call_value (memcmp_libfunc, result, LCT_PURE_MAKE_BLOCK,
3642			       TYPE_MODE (integer_type_node), 3,
3643			       XEXP (arg1_rtx, 0), Pmode,
3644			       XEXP (arg2_rtx, 0), Pmode,
3645			       convert_to_mode (TYPE_MODE (sizetype), arg3_rtx,
3646						TYPE_UNSIGNED (sizetype)),
3647			       TYPE_MODE (sizetype));
3648
3649    /* Return the value in the proper mode for this function.  */
3650    mode = TYPE_MODE (TREE_TYPE (exp));
3651    if (GET_MODE (result) == mode)
3652      return result;
3653    else if (target != 0)
3654      {
3655	convert_move (target, result, 0);
3656	return target;
3657      }
3658    else
3659      return convert_to_mode (mode, result, 0);
3660  }
3661#endif
3662
3663  return 0;
3664}
3665
3666/* Expand expression EXP, which is a call to the strcmp builtin.  Return 0
3667   if we failed the caller should emit a normal call, otherwise try to get
3668   the result in TARGET, if convenient.  */
3669
3670static rtx
3671expand_builtin_strcmp (tree exp, rtx target, enum machine_mode mode)
3672{
3673  tree arglist = TREE_OPERAND (exp, 1);
3674
3675  if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3676    return 0;
3677  else
3678    {
3679      tree result = fold_builtin_strcmp (arglist);
3680      if (result)
3681	return expand_expr (result, target, mode, EXPAND_NORMAL);
3682    }
3683
3684#if defined HAVE_cmpstrsi || defined HAVE_cmpstrnsi
3685  if (cmpstr_optab[SImode] != CODE_FOR_nothing
3686      || cmpstrn_optab[SImode] != CODE_FOR_nothing)
3687    {
3688      rtx arg1_rtx, arg2_rtx;
3689      rtx result, insn = NULL_RTX;
3690      tree fndecl, fn;
3691
3692      tree arg1 = TREE_VALUE (arglist);
3693      tree arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3694      int arg1_align
3695	= get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3696      int arg2_align
3697	= get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3698
3699      /* If we don't have POINTER_TYPE, call the function.  */
3700      if (arg1_align == 0 || arg2_align == 0)
3701	return 0;
3702
3703      /* Stabilize the arguments in case gen_cmpstr(n)si fail.  */
3704      arg1 = builtin_save_expr (arg1);
3705      arg2 = builtin_save_expr (arg2);
3706
3707      arg1_rtx = get_memory_rtx (arg1, NULL);
3708      arg2_rtx = get_memory_rtx (arg2, NULL);
3709
3710#ifdef HAVE_cmpstrsi
3711      /* Try to call cmpstrsi.  */
3712      if (HAVE_cmpstrsi)
3713	{
3714	  enum machine_mode insn_mode
3715	    = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
3716
3717	  /* Make a place to write the result of the instruction.  */
3718	  result = target;
3719	  if (! (result != 0
3720		 && REG_P (result) && GET_MODE (result) == insn_mode
3721		 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3722	    result = gen_reg_rtx (insn_mode);
3723
3724	  insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx,
3725			       GEN_INT (MIN (arg1_align, arg2_align)));
3726	}
3727#endif
3728#ifdef HAVE_cmpstrnsi
3729      /* Try to determine at least one length and call cmpstrnsi.  */
3730      if (!insn && HAVE_cmpstrnsi)
3731	{
3732	  tree len;
3733	  rtx arg3_rtx;
3734
3735	  enum machine_mode insn_mode
3736	    = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode;
3737	  tree len1 = c_strlen (arg1, 1);
3738	  tree len2 = c_strlen (arg2, 1);
3739
3740	  if (len1)
3741	    len1 = size_binop (PLUS_EXPR, ssize_int (1), len1);
3742	  if (len2)
3743	    len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
3744
3745	  /* If we don't have a constant length for the first, use the length
3746	     of the second, if we know it.  We don't require a constant for
3747	     this case; some cost analysis could be done if both are available
3748	     but neither is constant.  For now, assume they're equally cheap,
3749	     unless one has side effects.  If both strings have constant lengths,
3750	     use the smaller.  */
3751
3752	  if (!len1)
3753	    len = len2;
3754	  else if (!len2)
3755	    len = len1;
3756	  else if (TREE_SIDE_EFFECTS (len1))
3757	    len = len2;
3758	  else if (TREE_SIDE_EFFECTS (len2))
3759	    len = len1;
3760	  else if (TREE_CODE (len1) != INTEGER_CST)
3761	    len = len2;
3762	  else if (TREE_CODE (len2) != INTEGER_CST)
3763	    len = len1;
3764	  else if (tree_int_cst_lt (len1, len2))
3765	    len = len1;
3766	  else
3767	    len = len2;
3768
3769	  /* If both arguments have side effects, we cannot optimize.  */
3770	  if (!len || TREE_SIDE_EFFECTS (len))
3771	    goto do_libcall;
3772
3773	  arg3_rtx = expand_normal (len);
3774
3775	  /* Make a place to write the result of the instruction.  */
3776	  result = target;
3777	  if (! (result != 0
3778		 && REG_P (result) && GET_MODE (result) == insn_mode
3779		 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3780	    result = gen_reg_rtx (insn_mode);
3781
3782	  insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3783				GEN_INT (MIN (arg1_align, arg2_align)));
3784	}
3785#endif
3786
3787      if (insn)
3788	{
3789	  emit_insn (insn);
3790
3791	  /* Return the value in the proper mode for this function.  */
3792	  mode = TYPE_MODE (TREE_TYPE (exp));
3793	  if (GET_MODE (result) == mode)
3794	    return result;
3795	  if (target == 0)
3796	    return convert_to_mode (mode, result, 0);
3797	  convert_move (target, result, 0);
3798	  return target;
3799	}
3800
3801      /* Expand the library call ourselves using a stabilized argument
3802	 list to avoid re-evaluating the function's arguments twice.  */
3803#ifdef HAVE_cmpstrnsi
3804    do_libcall:
3805#endif
3806      arglist = build_tree_list (NULL_TREE, arg2);
3807      arglist = tree_cons (NULL_TREE, arg1, arglist);
3808      fndecl = get_callee_fndecl (exp);
3809      fn = build_function_call_expr (fndecl, arglist);
3810      if (TREE_CODE (fn) == CALL_EXPR)
3811	CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
3812      return expand_call (fn, target, target == const0_rtx);
3813    }
3814#endif
3815  return 0;
3816}
3817
3818/* Expand expression EXP, which is a call to the strncmp builtin.  Return 0
3819   if we failed the caller should emit a normal call, otherwise try to get
3820   the result in TARGET, if convenient.  */
3821
3822static rtx
3823expand_builtin_strncmp (tree exp, rtx target, enum machine_mode mode)
3824{
3825  tree arglist = TREE_OPERAND (exp, 1);
3826
3827  if (!validate_arglist (arglist,
3828			 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3829    return 0;
3830  else
3831    {
3832      tree result = fold_builtin_strncmp (arglist);
3833      if (result)
3834	return expand_expr (result, target, mode, EXPAND_NORMAL);
3835    }
3836
3837  /* If c_strlen can determine an expression for one of the string
3838     lengths, and it doesn't have side effects, then emit cmpstrnsi
3839     using length MIN(strlen(string)+1, arg3).  */
3840#ifdef HAVE_cmpstrnsi
3841  if (HAVE_cmpstrnsi)
3842  {
3843    tree arg1 = TREE_VALUE (arglist);
3844    tree arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3845    tree arg3 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3846    tree len, len1, len2;
3847    rtx arg1_rtx, arg2_rtx, arg3_rtx;
3848    rtx result, insn;
3849    tree fndecl, fn;
3850
3851    int arg1_align
3852      = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3853    int arg2_align
3854      = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3855    enum machine_mode insn_mode
3856      = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode;
3857
3858    len1 = c_strlen (arg1, 1);
3859    len2 = c_strlen (arg2, 1);
3860
3861    if (len1)
3862      len1 = size_binop (PLUS_EXPR, ssize_int (1), len1);
3863    if (len2)
3864      len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
3865
3866    /* If we don't have a constant length for the first, use the length
3867       of the second, if we know it.  We don't require a constant for
3868       this case; some cost analysis could be done if both are available
3869       but neither is constant.  For now, assume they're equally cheap,
3870       unless one has side effects.  If both strings have constant lengths,
3871       use the smaller.  */
3872
3873    if (!len1)
3874      len = len2;
3875    else if (!len2)
3876      len = len1;
3877    else if (TREE_SIDE_EFFECTS (len1))
3878      len = len2;
3879    else if (TREE_SIDE_EFFECTS (len2))
3880      len = len1;
3881    else if (TREE_CODE (len1) != INTEGER_CST)
3882      len = len2;
3883    else if (TREE_CODE (len2) != INTEGER_CST)
3884      len = len1;
3885    else if (tree_int_cst_lt (len1, len2))
3886      len = len1;
3887    else
3888      len = len2;
3889
3890    /* If both arguments have side effects, we cannot optimize.  */
3891    if (!len || TREE_SIDE_EFFECTS (len))
3892      return 0;
3893
3894    /* The actual new length parameter is MIN(len,arg3).  */
3895    len = fold_build2 (MIN_EXPR, TREE_TYPE (len), len,
3896		       fold_convert (TREE_TYPE (len), arg3));
3897
3898    /* If we don't have POINTER_TYPE, call the function.  */
3899    if (arg1_align == 0 || arg2_align == 0)
3900      return 0;
3901
3902    /* Make a place to write the result of the instruction.  */
3903    result = target;
3904    if (! (result != 0
3905	   && REG_P (result) && GET_MODE (result) == insn_mode
3906	   && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3907      result = gen_reg_rtx (insn_mode);
3908
3909    /* Stabilize the arguments in case gen_cmpstrnsi fails.  */
3910    arg1 = builtin_save_expr (arg1);
3911    arg2 = builtin_save_expr (arg2);
3912    len = builtin_save_expr (len);
3913
3914    arg1_rtx = get_memory_rtx (arg1, len);
3915    arg2_rtx = get_memory_rtx (arg2, len);
3916    arg3_rtx = expand_normal (len);
3917    insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3918			  GEN_INT (MIN (arg1_align, arg2_align)));
3919    if (insn)
3920      {
3921	emit_insn (insn);
3922
3923	/* Return the value in the proper mode for this function.  */
3924	mode = TYPE_MODE (TREE_TYPE (exp));
3925	if (GET_MODE (result) == mode)
3926	  return result;
3927	if (target == 0)
3928	  return convert_to_mode (mode, result, 0);
3929	convert_move (target, result, 0);
3930	return target;
3931      }
3932
3933    /* Expand the library call ourselves using a stabilized argument
3934       list to avoid re-evaluating the function's arguments twice.  */
3935    arglist = build_tree_list (NULL_TREE, len);
3936    arglist = tree_cons (NULL_TREE, arg2, arglist);
3937    arglist = tree_cons (NULL_TREE, arg1, arglist);
3938    fndecl = get_callee_fndecl (exp);
3939    fn = build_function_call_expr (fndecl, arglist);
3940    if (TREE_CODE (fn) == CALL_EXPR)
3941      CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
3942    return expand_call (fn, target, target == const0_rtx);
3943  }
3944#endif
3945  return 0;
3946}
3947
3948/* Expand expression EXP, which is a call to the strcat builtin.
3949   Return 0 if we failed the caller should emit a normal call,
3950   otherwise try to get the result in TARGET, if convenient.  */
3951
3952static rtx
3953expand_builtin_strcat (tree fndecl, tree arglist, rtx target, enum machine_mode mode)
3954{
3955  if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3956    return 0;
3957  else
3958    {
3959      tree dst = TREE_VALUE (arglist),
3960      src = TREE_VALUE (TREE_CHAIN (arglist));
3961      const char *p = c_getstr (src);
3962
3963      /* If the string length is zero, return the dst parameter.  */
3964      if (p && *p == '\0')
3965	return expand_expr (dst, target, mode, EXPAND_NORMAL);
3966
3967      if (!optimize_size)
3968	{
3969	  /* See if we can store by pieces into (dst + strlen(dst)).  */
3970	  tree newsrc, newdst,
3971	    strlen_fn = implicit_built_in_decls[BUILT_IN_STRLEN];
3972	  rtx insns;
3973
3974	  /* Stabilize the argument list.  */
3975	  newsrc = builtin_save_expr (src);
3976	  if (newsrc != src)
3977	    arglist = build_tree_list (NULL_TREE, newsrc);
3978	  else
3979	    arglist = TREE_CHAIN (arglist); /* Reusing arglist if safe.  */
3980
3981	  dst = builtin_save_expr (dst);
3982
3983	  start_sequence ();
3984
3985	  /* Create strlen (dst).  */
3986	  newdst =
3987	    build_function_call_expr (strlen_fn,
3988				      build_tree_list (NULL_TREE, dst));
3989	  /* Create (dst + (cast) strlen (dst)).  */
3990	  newdst = fold_convert (TREE_TYPE (dst), newdst);
3991	  newdst = fold_build2 (PLUS_EXPR, TREE_TYPE (dst), dst, newdst);
3992
3993	  newdst = builtin_save_expr (newdst);
3994	  arglist = tree_cons (NULL_TREE, newdst, arglist);
3995
3996	  if (!expand_builtin_strcpy (fndecl, arglist, target, mode))
3997	    {
3998	      end_sequence (); /* Stop sequence.  */
3999	      return 0;
4000	    }
4001
4002	  /* Output the entire sequence.  */
4003	  insns = get_insns ();
4004	  end_sequence ();
4005	  emit_insn (insns);
4006
4007	  return expand_expr (dst, target, mode, EXPAND_NORMAL);
4008	}
4009
4010      return 0;
4011    }
4012}
4013
4014/* Expand expression EXP, which is a call to the strncat builtin.
4015   Return 0 if we failed the caller should emit a normal call,
4016   otherwise try to get the result in TARGET, if convenient.  */
4017
4018static rtx
4019expand_builtin_strncat (tree arglist, rtx target, enum machine_mode mode)
4020{
4021  if (validate_arglist (arglist,
4022			POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
4023    {
4024      tree result = fold_builtin_strncat (arglist);
4025      if (result)
4026	return expand_expr (result, target, mode, EXPAND_NORMAL);
4027    }
4028  return 0;
4029}
4030
4031/* Expand expression EXP, which is a call to the strspn builtin.
4032   Return 0 if we failed the caller should emit a normal call,
4033   otherwise try to get the result in TARGET, if convenient.  */
4034
4035static rtx
4036expand_builtin_strspn (tree arglist, rtx target, enum machine_mode mode)
4037{
4038  if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4039    {
4040      tree result = fold_builtin_strspn (arglist);
4041      if (result)
4042	return expand_expr (result, target, mode, EXPAND_NORMAL);
4043    }
4044  return 0;
4045}
4046
4047/* Expand expression EXP, which is a call to the strcspn builtin.
4048   Return 0 if we failed the caller should emit a normal call,
4049   otherwise try to get the result in TARGET, if convenient.  */
4050
4051static rtx
4052expand_builtin_strcspn (tree arglist, rtx target, enum machine_mode mode)
4053{
4054  if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4055    {
4056      tree result = fold_builtin_strcspn (arglist);
4057      if (result)
4058	return expand_expr (result, target, mode, EXPAND_NORMAL);
4059    }
4060  return 0;
4061}
4062
4063/* Expand a call to __builtin_saveregs, generating the result in TARGET,
4064   if that's convenient.  */
4065
4066rtx
4067expand_builtin_saveregs (void)
4068{
4069  rtx val, seq;
4070
4071  /* Don't do __builtin_saveregs more than once in a function.
4072     Save the result of the first call and reuse it.  */
4073  if (saveregs_value != 0)
4074    return saveregs_value;
4075
4076  /* When this function is called, it means that registers must be
4077     saved on entry to this function.  So we migrate the call to the
4078     first insn of this function.  */
4079
4080  start_sequence ();
4081
4082  /* Do whatever the machine needs done in this case.  */
4083  val = targetm.calls.expand_builtin_saveregs ();
4084
4085  seq = get_insns ();
4086  end_sequence ();
4087
4088  saveregs_value = val;
4089
4090  /* Put the insns after the NOTE that starts the function.  If this
4091     is inside a start_sequence, make the outer-level insn chain current, so
4092     the code is placed at the start of the function.  */
4093  push_topmost_sequence ();
4094  emit_insn_after (seq, entry_of_function ());
4095  pop_topmost_sequence ();
4096
4097  return val;
4098}
4099
4100/* __builtin_args_info (N) returns word N of the arg space info
4101   for the current function.  The number and meanings of words
4102   is controlled by the definition of CUMULATIVE_ARGS.  */
4103
4104static rtx
4105expand_builtin_args_info (tree arglist)
4106{
4107  int nwords = sizeof (CUMULATIVE_ARGS) / sizeof (int);
4108  int *word_ptr = (int *) &current_function_args_info;
4109
4110  gcc_assert (sizeof (CUMULATIVE_ARGS) % sizeof (int) == 0);
4111
4112  if (arglist != 0)
4113    {
4114      if (!host_integerp (TREE_VALUE (arglist), 0))
4115	error ("argument of %<__builtin_args_info%> must be constant");
4116      else
4117	{
4118	  HOST_WIDE_INT wordnum = tree_low_cst (TREE_VALUE (arglist), 0);
4119
4120	  if (wordnum < 0 || wordnum >= nwords)
4121	    error ("argument of %<__builtin_args_info%> out of range");
4122	  else
4123	    return GEN_INT (word_ptr[wordnum]);
4124	}
4125    }
4126  else
4127    error ("missing argument in %<__builtin_args_info%>");
4128
4129  return const0_rtx;
4130}
4131
4132/* Expand a call to __builtin_next_arg.  */
4133
4134static rtx
4135expand_builtin_next_arg (void)
4136{
4137  /* Checking arguments is already done in fold_builtin_next_arg
4138     that must be called before this function.  */
4139  return expand_binop (Pmode, add_optab,
4140		       current_function_internal_arg_pointer,
4141		       current_function_arg_offset_rtx,
4142		       NULL_RTX, 0, OPTAB_LIB_WIDEN);
4143}
4144
4145/* Make it easier for the backends by protecting the valist argument
4146   from multiple evaluations.  */
4147
4148static tree
4149stabilize_va_list (tree valist, int needs_lvalue)
4150{
4151  if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
4152    {
4153      if (TREE_SIDE_EFFECTS (valist))
4154	valist = save_expr (valist);
4155
4156      /* For this case, the backends will be expecting a pointer to
4157	 TREE_TYPE (va_list_type_node), but it's possible we've
4158	 actually been given an array (an actual va_list_type_node).
4159	 So fix it.  */
4160      if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
4161	{
4162	  tree p1 = build_pointer_type (TREE_TYPE (va_list_type_node));
4163	  valist = build_fold_addr_expr_with_type (valist, p1);
4164	}
4165    }
4166  else
4167    {
4168      tree pt;
4169
4170      if (! needs_lvalue)
4171	{
4172	  if (! TREE_SIDE_EFFECTS (valist))
4173	    return valist;
4174
4175	  pt = build_pointer_type (va_list_type_node);
4176	  valist = fold_build1 (ADDR_EXPR, pt, valist);
4177	  TREE_SIDE_EFFECTS (valist) = 1;
4178	}
4179
4180      if (TREE_SIDE_EFFECTS (valist))
4181	valist = save_expr (valist);
4182      valist = build_fold_indirect_ref (valist);
4183    }
4184
4185  return valist;
4186}
4187
4188/* The "standard" definition of va_list is void*.  */
4189
4190tree
4191std_build_builtin_va_list (void)
4192{
4193  return ptr_type_node;
4194}
4195
4196/* The "standard" implementation of va_start: just assign `nextarg' to
4197   the variable.  */
4198
4199void
4200std_expand_builtin_va_start (tree valist, rtx nextarg)
4201{
4202  tree t;
4203
4204  t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist,
4205	      make_tree (ptr_type_node, nextarg));
4206  TREE_SIDE_EFFECTS (t) = 1;
4207
4208  expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4209}
4210
4211/* Expand ARGLIST, from a call to __builtin_va_start.  */
4212
4213static rtx
4214expand_builtin_va_start (tree arglist)
4215{
4216  rtx nextarg;
4217  tree chain, valist;
4218
4219  chain = TREE_CHAIN (arglist);
4220
4221  if (!chain)
4222    {
4223      error ("too few arguments to function %<va_start%>");
4224      return const0_rtx;
4225    }
4226
4227  if (fold_builtin_next_arg (chain))
4228    return const0_rtx;
4229
4230  nextarg = expand_builtin_next_arg ();
4231  valist = stabilize_va_list (TREE_VALUE (arglist), 1);
4232
4233#ifdef EXPAND_BUILTIN_VA_START
4234  EXPAND_BUILTIN_VA_START (valist, nextarg);
4235#else
4236  std_expand_builtin_va_start (valist, nextarg);
4237#endif
4238
4239  return const0_rtx;
4240}
4241
4242/* The "standard" implementation of va_arg: read the value from the
4243   current (padded) address and increment by the (padded) size.  */
4244
4245tree
4246std_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p, tree *post_p)
4247{
4248  tree addr, t, type_size, rounded_size, valist_tmp;
4249  unsigned HOST_WIDE_INT align, boundary;
4250  bool indirect;
4251
4252#ifdef ARGS_GROW_DOWNWARD
4253  /* All of the alignment and movement below is for args-grow-up machines.
4254     As of 2004, there are only 3 ARGS_GROW_DOWNWARD targets, and they all
4255     implement their own specialized gimplify_va_arg_expr routines.  */
4256  gcc_unreachable ();
4257#endif
4258
4259  indirect = pass_by_reference (NULL, TYPE_MODE (type), type, false);
4260  if (indirect)
4261    type = build_pointer_type (type);
4262
4263  align = PARM_BOUNDARY / BITS_PER_UNIT;
4264  boundary = FUNCTION_ARG_BOUNDARY (TYPE_MODE (type), type) / BITS_PER_UNIT;
4265
4266  /* Hoist the valist value into a temporary for the moment.  */
4267  valist_tmp = get_initialized_tmp_var (valist, pre_p, NULL);
4268
4269  /* va_list pointer is aligned to PARM_BOUNDARY.  If argument actually
4270     requires greater alignment, we must perform dynamic alignment.  */
4271  if (boundary > align
4272      && !integer_zerop (TYPE_SIZE (type)))
4273    {
4274      t = fold_convert (TREE_TYPE (valist), size_int (boundary - 1));
4275      t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
4276		  build2 (PLUS_EXPR, TREE_TYPE (valist), valist_tmp, t));
4277      gimplify_and_add (t, pre_p);
4278
4279      t = fold_convert (TREE_TYPE (valist), size_int (-boundary));
4280      t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
4281		  build2 (BIT_AND_EXPR, TREE_TYPE (valist), valist_tmp, t));
4282      gimplify_and_add (t, pre_p);
4283    }
4284  else
4285    boundary = align;
4286
4287  /* If the actual alignment is less than the alignment of the type,
4288     adjust the type accordingly so that we don't assume strict alignment
4289     when deferencing the pointer.  */
4290  boundary *= BITS_PER_UNIT;
4291  if (boundary < TYPE_ALIGN (type))
4292    {
4293      type = build_variant_type_copy (type);
4294      TYPE_ALIGN (type) = boundary;
4295    }
4296
4297  /* Compute the rounded size of the type.  */
4298  type_size = size_in_bytes (type);
4299  rounded_size = round_up (type_size, align);
4300
4301  /* Reduce rounded_size so it's sharable with the postqueue.  */
4302  gimplify_expr (&rounded_size, pre_p, post_p, is_gimple_val, fb_rvalue);
4303
4304  /* Get AP.  */
4305  addr = valist_tmp;
4306  if (PAD_VARARGS_DOWN && !integer_zerop (rounded_size))
4307    {
4308      /* Small args are padded downward.  */
4309      t = fold_build2 (GT_EXPR, sizetype, rounded_size, size_int (align));
4310      t = fold_build3 (COND_EXPR, sizetype, t, size_zero_node,
4311		       size_binop (MINUS_EXPR, rounded_size, type_size));
4312      t = fold_convert (TREE_TYPE (addr), t);
4313      addr = fold_build2 (PLUS_EXPR, TREE_TYPE (addr), addr, t);
4314    }
4315
4316  /* Compute new value for AP.  */
4317  t = fold_convert (TREE_TYPE (valist), rounded_size);
4318  t = build2 (PLUS_EXPR, TREE_TYPE (valist), valist_tmp, t);
4319  t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist, t);
4320  gimplify_and_add (t, pre_p);
4321
4322  addr = fold_convert (build_pointer_type (type), addr);
4323
4324  if (indirect)
4325    addr = build_va_arg_indirect_ref (addr);
4326
4327  return build_va_arg_indirect_ref (addr);
4328}
4329
4330/* Build an indirect-ref expression over the given TREE, which represents a
4331   piece of a va_arg() expansion.  */
4332tree
4333build_va_arg_indirect_ref (tree addr)
4334{
4335  addr = build_fold_indirect_ref (addr);
4336
4337  if (flag_mudflap) /* Don't instrument va_arg INDIRECT_REF.  */
4338    mf_mark (addr);
4339
4340  return addr;
4341}
4342
4343/* Return a dummy expression of type TYPE in order to keep going after an
4344   error.  */
4345
4346static tree
4347dummy_object (tree type)
4348{
4349  tree t = build_int_cst (build_pointer_type (type), 0);
4350  return build1 (INDIRECT_REF, type, t);
4351}
4352
4353/* Gimplify __builtin_va_arg, aka VA_ARG_EXPR, which is not really a
4354   builtin function, but a very special sort of operator.  */
4355
4356enum gimplify_status
4357gimplify_va_arg_expr (tree *expr_p, tree *pre_p, tree *post_p)
4358{
4359  tree promoted_type, want_va_type, have_va_type;
4360  tree valist = TREE_OPERAND (*expr_p, 0);
4361  tree type = TREE_TYPE (*expr_p);
4362  tree t;
4363
4364  /* Verify that valist is of the proper type.  */
4365  want_va_type = va_list_type_node;
4366  have_va_type = TREE_TYPE (valist);
4367
4368  if (have_va_type == error_mark_node)
4369    return GS_ERROR;
4370
4371  if (TREE_CODE (want_va_type) == ARRAY_TYPE)
4372    {
4373      /* If va_list is an array type, the argument may have decayed
4374	 to a pointer type, e.g. by being passed to another function.
4375	 In that case, unwrap both types so that we can compare the
4376	 underlying records.  */
4377      if (TREE_CODE (have_va_type) == ARRAY_TYPE
4378	  || POINTER_TYPE_P (have_va_type))
4379	{
4380	  want_va_type = TREE_TYPE (want_va_type);
4381	  have_va_type = TREE_TYPE (have_va_type);
4382	}
4383    }
4384
4385  if (TYPE_MAIN_VARIANT (want_va_type) != TYPE_MAIN_VARIANT (have_va_type))
4386    {
4387      error ("first argument to %<va_arg%> not of type %<va_list%>");
4388      return GS_ERROR;
4389    }
4390
4391  /* Generate a diagnostic for requesting data of a type that cannot
4392     be passed through `...' due to type promotion at the call site.  */
4393  else if ((promoted_type = lang_hooks.types.type_promotes_to (type))
4394	   != type)
4395    {
4396      static bool gave_help;
4397
4398      /* Unfortunately, this is merely undefined, rather than a constraint
4399	 violation, so we cannot make this an error.  If this call is never
4400	 executed, the program is still strictly conforming.  */
4401      warning (0, "%qT is promoted to %qT when passed through %<...%>",
4402	       type, promoted_type);
4403      if (! gave_help)
4404	{
4405	  gave_help = true;
4406	  warning (0, "(so you should pass %qT not %qT to %<va_arg%>)",
4407		   promoted_type, type);
4408	}
4409
4410      /* We can, however, treat "undefined" any way we please.
4411	 Call abort to encourage the user to fix the program.  */
4412      inform ("if this code is reached, the program will abort");
4413      t = build_function_call_expr (implicit_built_in_decls[BUILT_IN_TRAP],
4414				    NULL);
4415      append_to_statement_list (t, pre_p);
4416
4417      /* This is dead code, but go ahead and finish so that the
4418	 mode of the result comes out right.  */
4419      *expr_p = dummy_object (type);
4420      return GS_ALL_DONE;
4421    }
4422  else
4423    {
4424      /* Make it easier for the backends by protecting the valist argument
4425	 from multiple evaluations.  */
4426      if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
4427	{
4428	  /* For this case, the backends will be expecting a pointer to
4429	     TREE_TYPE (va_list_type_node), but it's possible we've
4430	     actually been given an array (an actual va_list_type_node).
4431	     So fix it.  */
4432	  if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
4433	    {
4434	      tree p1 = build_pointer_type (TREE_TYPE (va_list_type_node));
4435	      valist = build_fold_addr_expr_with_type (valist, p1);
4436	    }
4437	  gimplify_expr (&valist, pre_p, post_p, is_gimple_val, fb_rvalue);
4438	}
4439      else
4440	gimplify_expr (&valist, pre_p, post_p, is_gimple_min_lval, fb_lvalue);
4441
4442      if (!targetm.gimplify_va_arg_expr)
4443	/* FIXME:Once most targets are converted we should merely
4444	   assert this is non-null.  */
4445	return GS_ALL_DONE;
4446
4447      *expr_p = targetm.gimplify_va_arg_expr (valist, type, pre_p, post_p);
4448      return GS_OK;
4449    }
4450}
4451
4452/* Expand ARGLIST, from a call to __builtin_va_end.  */
4453
4454static rtx
4455expand_builtin_va_end (tree arglist)
4456{
4457  tree valist = TREE_VALUE (arglist);
4458
4459  /* Evaluate for side effects, if needed.  I hate macros that don't
4460     do that.  */
4461  if (TREE_SIDE_EFFECTS (valist))
4462    expand_expr (valist, const0_rtx, VOIDmode, EXPAND_NORMAL);
4463
4464  return const0_rtx;
4465}
4466
4467/* Expand ARGLIST, from a call to __builtin_va_copy.  We do this as a
4468   builtin rather than just as an assignment in stdarg.h because of the
4469   nastiness of array-type va_list types.  */
4470
4471static rtx
4472expand_builtin_va_copy (tree arglist)
4473{
4474  tree dst, src, t;
4475
4476  dst = TREE_VALUE (arglist);
4477  src = TREE_VALUE (TREE_CHAIN (arglist));
4478
4479  dst = stabilize_va_list (dst, 1);
4480  src = stabilize_va_list (src, 0);
4481
4482  if (TREE_CODE (va_list_type_node) != ARRAY_TYPE)
4483    {
4484      t = build2 (MODIFY_EXPR, va_list_type_node, dst, src);
4485      TREE_SIDE_EFFECTS (t) = 1;
4486      expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4487    }
4488  else
4489    {
4490      rtx dstb, srcb, size;
4491
4492      /* Evaluate to pointers.  */
4493      dstb = expand_expr (dst, NULL_RTX, Pmode, EXPAND_NORMAL);
4494      srcb = expand_expr (src, NULL_RTX, Pmode, EXPAND_NORMAL);
4495      size = expand_expr (TYPE_SIZE_UNIT (va_list_type_node), NULL_RTX,
4496			  VOIDmode, EXPAND_NORMAL);
4497
4498      dstb = convert_memory_address (Pmode, dstb);
4499      srcb = convert_memory_address (Pmode, srcb);
4500
4501      /* "Dereference" to BLKmode memories.  */
4502      dstb = gen_rtx_MEM (BLKmode, dstb);
4503      set_mem_alias_set (dstb, get_alias_set (TREE_TYPE (TREE_TYPE (dst))));
4504      set_mem_align (dstb, TYPE_ALIGN (va_list_type_node));
4505      srcb = gen_rtx_MEM (BLKmode, srcb);
4506      set_mem_alias_set (srcb, get_alias_set (TREE_TYPE (TREE_TYPE (src))));
4507      set_mem_align (srcb, TYPE_ALIGN (va_list_type_node));
4508
4509      /* Copy.  */
4510      emit_block_move (dstb, srcb, size, BLOCK_OP_NORMAL);
4511    }
4512
4513  return const0_rtx;
4514}
4515
4516/* Expand a call to one of the builtin functions __builtin_frame_address or
4517   __builtin_return_address.  */
4518
4519static rtx
4520expand_builtin_frame_address (tree fndecl, tree arglist)
4521{
4522  /* The argument must be a nonnegative integer constant.
4523     It counts the number of frames to scan up the stack.
4524     The value is the return address saved in that frame.  */
4525  if (arglist == 0)
4526    /* Warning about missing arg was already issued.  */
4527    return const0_rtx;
4528  else if (! host_integerp (TREE_VALUE (arglist), 1))
4529    {
4530      if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4531	error ("invalid argument to %<__builtin_frame_address%>");
4532      else
4533	error ("invalid argument to %<__builtin_return_address%>");
4534      return const0_rtx;
4535    }
4536  else
4537    {
4538      rtx tem
4539	= expand_builtin_return_addr (DECL_FUNCTION_CODE (fndecl),
4540				      tree_low_cst (TREE_VALUE (arglist), 1));
4541
4542      /* Some ports cannot access arbitrary stack frames.  */
4543      if (tem == NULL)
4544	{
4545	  if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4546	    warning (0, "unsupported argument to %<__builtin_frame_address%>");
4547	  else
4548	    warning (0, "unsupported argument to %<__builtin_return_address%>");
4549	  return const0_rtx;
4550	}
4551
4552      /* For __builtin_frame_address, return what we've got.  */
4553      if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4554	return tem;
4555
4556      if (!REG_P (tem)
4557	  && ! CONSTANT_P (tem))
4558	tem = copy_to_mode_reg (Pmode, tem);
4559      return tem;
4560    }
4561}
4562
4563/* Expand a call to the alloca builtin, with arguments ARGLIST.  Return 0 if
4564   we failed and the caller should emit a normal call, otherwise try to get
4565   the result in TARGET, if convenient.  */
4566
4567static rtx
4568expand_builtin_alloca (tree arglist, rtx target)
4569{
4570  rtx op0;
4571  rtx result;
4572
4573  /* In -fmudflap-instrumented code, alloca() and __builtin_alloca()
4574     should always expand to function calls.  These can be intercepted
4575     in libmudflap.  */
4576  if (flag_mudflap)
4577    return 0;
4578
4579  if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
4580    return 0;
4581
4582  /* Compute the argument.  */
4583  op0 = expand_normal (TREE_VALUE (arglist));
4584
4585  /* Allocate the desired space.  */
4586  result = allocate_dynamic_stack_space (op0, target, BITS_PER_UNIT);
4587  result = convert_memory_address (ptr_mode, result);
4588
4589  return result;
4590}
4591
4592/* Expand a call to a unary builtin.  The arguments are in ARGLIST.
4593   Return 0 if a normal call should be emitted rather than expanding the
4594   function in-line.  If convenient, the result should be placed in TARGET.
4595   SUBTARGET may be used as the target for computing one of EXP's operands.  */
4596
4597static rtx
4598expand_builtin_unop (enum machine_mode target_mode, tree arglist, rtx target,
4599		     rtx subtarget, optab op_optab)
4600{
4601  rtx op0;
4602  if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
4603    return 0;
4604
4605  /* Compute the argument.  */
4606  op0 = expand_expr (TREE_VALUE (arglist), subtarget, VOIDmode, 0);
4607  /* Compute op, into TARGET if possible.
4608     Set TARGET to wherever the result comes back.  */
4609  target = expand_unop (TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist))),
4610			op_optab, op0, target, 1);
4611  gcc_assert (target);
4612
4613  return convert_to_mode (target_mode, target, 0);
4614}
4615
4616/* If the string passed to fputs is a constant and is one character
4617   long, we attempt to transform this call into __builtin_fputc().  */
4618
4619static rtx
4620expand_builtin_fputs (tree arglist, rtx target, bool unlocked)
4621{
4622  /* Verify the arguments in the original call.  */
4623  if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4624    {
4625      tree result = fold_builtin_fputs (arglist, (target == const0_rtx),
4626					unlocked, NULL_TREE);
4627      if (result)
4628	return expand_expr (result, target, VOIDmode, EXPAND_NORMAL);
4629    }
4630  return 0;
4631}
4632
4633/* Expand a call to __builtin_expect.  We return our argument and emit a
4634   NOTE_INSN_EXPECTED_VALUE note.  This is the expansion of __builtin_expect in
4635   a non-jump context.  */
4636
4637static rtx
4638expand_builtin_expect (tree arglist, rtx target)
4639{
4640  tree exp, c;
4641  rtx note, rtx_c;
4642
4643  if (arglist == NULL_TREE
4644      || TREE_CHAIN (arglist) == NULL_TREE)
4645    return const0_rtx;
4646  exp = TREE_VALUE (arglist);
4647  c = TREE_VALUE (TREE_CHAIN (arglist));
4648
4649  if (TREE_CODE (c) != INTEGER_CST)
4650    {
4651      error ("second argument to %<__builtin_expect%> must be a constant");
4652      c = integer_zero_node;
4653    }
4654
4655  target = expand_expr (exp, target, VOIDmode, EXPAND_NORMAL);
4656
4657  /* Don't bother with expected value notes for integral constants.  */
4658  if (flag_guess_branch_prob && GET_CODE (target) != CONST_INT)
4659    {
4660      /* We do need to force this into a register so that we can be
4661	 moderately sure to be able to correctly interpret the branch
4662	 condition later.  */
4663      target = force_reg (GET_MODE (target), target);
4664
4665      rtx_c = expand_expr (c, NULL_RTX, GET_MODE (target), EXPAND_NORMAL);
4666
4667      note = emit_note (NOTE_INSN_EXPECTED_VALUE);
4668      NOTE_EXPECTED_VALUE (note) = gen_rtx_EQ (VOIDmode, target, rtx_c);
4669    }
4670
4671  return target;
4672}
4673
4674/* Like expand_builtin_expect, except do this in a jump context.  This is
4675   called from do_jump if the conditional is a __builtin_expect.  Return either
4676   a list of insns to emit the jump or NULL if we cannot optimize
4677   __builtin_expect.  We need to optimize this at jump time so that machines
4678   like the PowerPC don't turn the test into a SCC operation, and then jump
4679   based on the test being 0/1.  */
4680
4681rtx
4682expand_builtin_expect_jump (tree exp, rtx if_false_label, rtx if_true_label)
4683{
4684  tree arglist = TREE_OPERAND (exp, 1);
4685  tree arg0 = TREE_VALUE (arglist);
4686  tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
4687  rtx ret = NULL_RTX;
4688
4689  /* Only handle __builtin_expect (test, 0) and
4690     __builtin_expect (test, 1).  */
4691  if (TREE_CODE (TREE_TYPE (arg1)) == INTEGER_TYPE
4692      && (integer_zerop (arg1) || integer_onep (arg1)))
4693    {
4694      rtx insn, drop_through_label, temp;
4695
4696      /* Expand the jump insns.  */
4697      start_sequence ();
4698      do_jump (arg0, if_false_label, if_true_label);
4699      ret = get_insns ();
4700
4701      drop_through_label = get_last_insn ();
4702      if (drop_through_label && NOTE_P (drop_through_label))
4703	drop_through_label = prev_nonnote_insn (drop_through_label);
4704      if (drop_through_label && !LABEL_P (drop_through_label))
4705	drop_through_label = NULL_RTX;
4706      end_sequence ();
4707
4708      if (! if_true_label)
4709	if_true_label = drop_through_label;
4710      if (! if_false_label)
4711	if_false_label = drop_through_label;
4712
4713      /* Go through and add the expect's to each of the conditional jumps.  */
4714      insn = ret;
4715      while (insn != NULL_RTX)
4716	{
4717	  rtx next = NEXT_INSN (insn);
4718
4719	  if (JUMP_P (insn) && any_condjump_p (insn))
4720	    {
4721	      rtx ifelse = SET_SRC (pc_set (insn));
4722	      rtx then_dest = XEXP (ifelse, 1);
4723	      rtx else_dest = XEXP (ifelse, 2);
4724	      int taken = -1;
4725
4726	      /* First check if we recognize any of the labels.  */
4727	      if (GET_CODE (then_dest) == LABEL_REF
4728		  && XEXP (then_dest, 0) == if_true_label)
4729		taken = 1;
4730	      else if (GET_CODE (then_dest) == LABEL_REF
4731		       && XEXP (then_dest, 0) == if_false_label)
4732		taken = 0;
4733	      else if (GET_CODE (else_dest) == LABEL_REF
4734		       && XEXP (else_dest, 0) == if_false_label)
4735		taken = 1;
4736	      else if (GET_CODE (else_dest) == LABEL_REF
4737		       && XEXP (else_dest, 0) == if_true_label)
4738		taken = 0;
4739	      /* Otherwise check where we drop through.  */
4740	      else if (else_dest == pc_rtx)
4741		{
4742		  if (next && NOTE_P (next))
4743		    next = next_nonnote_insn (next);
4744
4745		  if (next && JUMP_P (next)
4746		      && any_uncondjump_p (next))
4747		    temp = XEXP (SET_SRC (pc_set (next)), 0);
4748		  else
4749		    temp = next;
4750
4751		  /* TEMP is either a CODE_LABEL, NULL_RTX or something
4752		     else that can't possibly match either target label.  */
4753		  if (temp == if_false_label)
4754		    taken = 1;
4755		  else if (temp == if_true_label)
4756		    taken = 0;
4757		}
4758	      else if (then_dest == pc_rtx)
4759		{
4760		  if (next && NOTE_P (next))
4761		    next = next_nonnote_insn (next);
4762
4763		  if (next && JUMP_P (next)
4764		      && any_uncondjump_p (next))
4765		    temp = XEXP (SET_SRC (pc_set (next)), 0);
4766		  else
4767		    temp = next;
4768
4769		  if (temp == if_false_label)
4770		    taken = 0;
4771		  else if (temp == if_true_label)
4772		    taken = 1;
4773		}
4774
4775	      if (taken != -1)
4776		{
4777		  /* If the test is expected to fail, reverse the
4778		     probabilities.  */
4779		  if (integer_zerop (arg1))
4780		    taken = 1 - taken;
4781		  predict_insn_def (insn, PRED_BUILTIN_EXPECT, taken);
4782		}
4783	    }
4784
4785	  insn = next;
4786	}
4787    }
4788
4789  return ret;
4790}
4791
4792void
4793expand_builtin_trap (void)
4794{
4795#ifdef HAVE_trap
4796  if (HAVE_trap)
4797    emit_insn (gen_trap ());
4798  else
4799#endif
4800    emit_library_call (abort_libfunc, LCT_NORETURN, VOIDmode, 0);
4801  emit_barrier ();
4802}
4803
4804/* Expand a call to fabs, fabsf or fabsl with arguments ARGLIST.
4805   Return 0 if a normal call should be emitted rather than expanding
4806   the function inline.  If convenient, the result should be placed
4807   in TARGET.  SUBTARGET may be used as the target for computing
4808   the operand.  */
4809
4810static rtx
4811expand_builtin_fabs (tree arglist, rtx target, rtx subtarget)
4812{
4813  enum machine_mode mode;
4814  tree arg;
4815  rtx op0;
4816
4817  if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
4818    return 0;
4819
4820  arg = TREE_VALUE (arglist);
4821  mode = TYPE_MODE (TREE_TYPE (arg));
4822  op0 = expand_expr (arg, subtarget, VOIDmode, 0);
4823  return expand_abs (mode, op0, target, 0, safe_from_p (target, arg, 1));
4824}
4825
4826/* Expand a call to copysign, copysignf, or copysignl with arguments ARGLIST.
4827   Return NULL is a normal call should be emitted rather than expanding the
4828   function inline.  If convenient, the result should be placed in TARGET.
4829   SUBTARGET may be used as the target for computing the operand.  */
4830
4831static rtx
4832expand_builtin_copysign (tree arglist, rtx target, rtx subtarget)
4833{
4834  rtx op0, op1;
4835  tree arg;
4836
4837  if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
4838    return 0;
4839
4840  arg = TREE_VALUE (arglist);
4841  op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL);
4842
4843  arg = TREE_VALUE (TREE_CHAIN (arglist));
4844  op1 = expand_normal (arg);
4845
4846  return expand_copysign (op0, op1, target);
4847}
4848
4849/* Create a new constant string literal and return a char* pointer to it.
4850   The STRING_CST value is the LEN characters at STR.  */
4851tree
4852build_string_literal (int len, const char *str)
4853{
4854  tree t, elem, index, type;
4855
4856  t = build_string (len, str);
4857  elem = build_type_variant (char_type_node, 1, 0);
4858  index = build_index_type (build_int_cst (NULL_TREE, len - 1));
4859  type = build_array_type (elem, index);
4860  TREE_TYPE (t) = type;
4861  TREE_CONSTANT (t) = 1;
4862  TREE_INVARIANT (t) = 1;
4863  TREE_READONLY (t) = 1;
4864  TREE_STATIC (t) = 1;
4865
4866  type = build_pointer_type (type);
4867  t = build1 (ADDR_EXPR, type, t);
4868
4869  type = build_pointer_type (elem);
4870  t = build1 (NOP_EXPR, type, t);
4871  return t;
4872}
4873
4874/* Expand EXP, a call to printf or printf_unlocked.
4875   Return 0 if a normal call should be emitted rather than transforming
4876   the function inline.  If convenient, the result should be placed in
4877   TARGET with mode MODE.  UNLOCKED indicates this is a printf_unlocked
4878   call.  */
4879static rtx
4880expand_builtin_printf (tree exp, rtx target, enum machine_mode mode,
4881		       bool unlocked)
4882{
4883  tree arglist = TREE_OPERAND (exp, 1);
4884  /* If we're using an unlocked function, assume the other unlocked
4885     functions exist explicitly.  */
4886  tree const fn_putchar = unlocked ? built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED]
4887    : implicit_built_in_decls[BUILT_IN_PUTCHAR];
4888  tree const fn_puts = unlocked ? built_in_decls[BUILT_IN_PUTS_UNLOCKED]
4889    : implicit_built_in_decls[BUILT_IN_PUTS];
4890  const char *fmt_str;
4891  tree fn, fmt, arg;
4892
4893  /* If the return value is used, don't do the transformation.  */
4894  if (target != const0_rtx)
4895    return 0;
4896
4897  /* Verify the required arguments in the original call.  */
4898  if (! arglist)
4899    return 0;
4900  fmt = TREE_VALUE (arglist);
4901  if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
4902    return 0;
4903  arglist = TREE_CHAIN (arglist);
4904
4905  /* Check whether the format is a literal string constant.  */
4906  fmt_str = c_getstr (fmt);
4907  if (fmt_str == NULL)
4908    return 0;
4909
4910  if (!init_target_chars())
4911    return 0;
4912
4913  /* If the format specifier was "%s\n", call __builtin_puts(arg).  */
4914  if (strcmp (fmt_str, target_percent_s_newline) == 0)
4915    {
4916      if (! arglist
4917	  || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
4918	  || TREE_CHAIN (arglist))
4919	return 0;
4920      fn = fn_puts;
4921    }
4922  /* If the format specifier was "%c", call __builtin_putchar(arg).  */
4923  else if (strcmp (fmt_str, target_percent_c) == 0)
4924    {
4925      if (! arglist
4926	  || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
4927	  || TREE_CHAIN (arglist))
4928	return 0;
4929      fn = fn_putchar;
4930    }
4931  else
4932    {
4933      /* We can't handle anything else with % args or %% ... yet.  */
4934      if (strchr (fmt_str, target_percent))
4935	return 0;
4936
4937      if (arglist)
4938	return 0;
4939
4940      /* If the format specifier was "", printf does nothing.  */
4941      if (fmt_str[0] == '\0')
4942	return const0_rtx;
4943      /* If the format specifier has length of 1, call putchar.  */
4944      if (fmt_str[1] == '\0')
4945	{
4946	  /* Given printf("c"), (where c is any one character,)
4947	     convert "c"[0] to an int and pass that to the replacement
4948	     function.  */
4949	  arg = build_int_cst (NULL_TREE, fmt_str[0]);
4950	  arglist = build_tree_list (NULL_TREE, arg);
4951	  fn = fn_putchar;
4952	}
4953      else
4954	{
4955	  /* If the format specifier was "string\n", call puts("string").  */
4956	  size_t len = strlen (fmt_str);
4957	  if ((unsigned char)fmt_str[len - 1] == target_newline)
4958	    {
4959	      /* Create a NUL-terminated string that's one char shorter
4960		 than the original, stripping off the trailing '\n'.  */
4961	      char *newstr = alloca (len);
4962	      memcpy (newstr, fmt_str, len - 1);
4963	      newstr[len - 1] = 0;
4964
4965	      arg = build_string_literal (len, newstr);
4966	      arglist = build_tree_list (NULL_TREE, arg);
4967	      fn = fn_puts;
4968	    }
4969	  else
4970	    /* We'd like to arrange to call fputs(string,stdout) here,
4971	       but we need stdout and don't have a way to get it yet.  */
4972	    return 0;
4973	}
4974    }
4975
4976  if (!fn)
4977    return 0;
4978  fn = build_function_call_expr (fn, arglist);
4979  if (TREE_CODE (fn) == CALL_EXPR)
4980    CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
4981  return expand_expr (fn, target, mode, EXPAND_NORMAL);
4982}
4983
4984/* Expand EXP, a call to fprintf or fprintf_unlocked.
4985   Return 0 if a normal call should be emitted rather than transforming
4986   the function inline.  If convenient, the result should be placed in
4987   TARGET with mode MODE.  UNLOCKED indicates this is a fprintf_unlocked
4988   call.  */
4989static rtx
4990expand_builtin_fprintf (tree exp, rtx target, enum machine_mode mode,
4991			bool unlocked)
4992{
4993  tree arglist = TREE_OPERAND (exp, 1);
4994  /* If we're using an unlocked function, assume the other unlocked
4995     functions exist explicitly.  */
4996  tree const fn_fputc = unlocked ? built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
4997    : implicit_built_in_decls[BUILT_IN_FPUTC];
4998  tree const fn_fputs = unlocked ? built_in_decls[BUILT_IN_FPUTS_UNLOCKED]
4999    : implicit_built_in_decls[BUILT_IN_FPUTS];
5000  const char *fmt_str;
5001  tree fn, fmt, fp, arg;
5002
5003  /* If the return value is used, don't do the transformation.  */
5004  if (target != const0_rtx)
5005    return 0;
5006
5007  /* Verify the required arguments in the original call.  */
5008  if (! arglist)
5009    return 0;
5010  fp = TREE_VALUE (arglist);
5011  if (! POINTER_TYPE_P (TREE_TYPE (fp)))
5012    return 0;
5013  arglist = TREE_CHAIN (arglist);
5014  if (! arglist)
5015    return 0;
5016  fmt = TREE_VALUE (arglist);
5017  if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
5018    return 0;
5019  arglist = TREE_CHAIN (arglist);
5020
5021  /* Check whether the format is a literal string constant.  */
5022  fmt_str = c_getstr (fmt);
5023  if (fmt_str == NULL)
5024    return 0;
5025
5026  if (!init_target_chars())
5027    return 0;
5028
5029  /* If the format specifier was "%s", call __builtin_fputs(arg,fp).  */
5030  if (strcmp (fmt_str, target_percent_s) == 0)
5031    {
5032      if (! arglist
5033	  || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
5034	  || TREE_CHAIN (arglist))
5035	return 0;
5036      arg = TREE_VALUE (arglist);
5037      arglist = build_tree_list (NULL_TREE, fp);
5038      arglist = tree_cons (NULL_TREE, arg, arglist);
5039      fn = fn_fputs;
5040    }
5041  /* If the format specifier was "%c", call __builtin_fputc(arg,fp).  */
5042  else if (strcmp (fmt_str, target_percent_c) == 0)
5043    {
5044      if (! arglist
5045	  || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
5046	  || TREE_CHAIN (arglist))
5047	return 0;
5048      arg = TREE_VALUE (arglist);
5049      arglist = build_tree_list (NULL_TREE, fp);
5050      arglist = tree_cons (NULL_TREE, arg, arglist);
5051      fn = fn_fputc;
5052    }
5053  else
5054    {
5055      /* We can't handle anything else with % args or %% ... yet.  */
5056      if (strchr (fmt_str, target_percent))
5057	return 0;
5058
5059      if (arglist)
5060	return 0;
5061
5062      /* If the format specifier was "", fprintf does nothing.  */
5063      if (fmt_str[0] == '\0')
5064	{
5065	  /* Evaluate and ignore FILE* argument for side-effects.  */
5066	  expand_expr (fp, const0_rtx, VOIDmode, EXPAND_NORMAL);
5067	  return const0_rtx;
5068	}
5069
5070      /* When "string" doesn't contain %, replace all cases of
5071	 fprintf(stream,string) with fputs(string,stream).  The fputs
5072	 builtin will take care of special cases like length == 1.  */
5073      arglist = build_tree_list (NULL_TREE, fp);
5074      arglist = tree_cons (NULL_TREE, fmt, arglist);
5075      fn = fn_fputs;
5076    }
5077
5078  if (!fn)
5079    return 0;
5080  fn = build_function_call_expr (fn, arglist);
5081  if (TREE_CODE (fn) == CALL_EXPR)
5082    CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
5083  return expand_expr (fn, target, mode, EXPAND_NORMAL);
5084}
5085
5086/* Expand a call to sprintf with argument list ARGLIST.  Return 0 if
5087   a normal call should be emitted rather than expanding the function
5088   inline.  If convenient, the result should be placed in TARGET with
5089   mode MODE.  */
5090
5091static rtx
5092expand_builtin_sprintf (tree arglist, rtx target, enum machine_mode mode)
5093{
5094  tree orig_arglist, dest, fmt;
5095  const char *fmt_str;
5096
5097  orig_arglist = arglist;
5098
5099  /* Verify the required arguments in the original call.  */
5100  if (! arglist)
5101    return 0;
5102  dest = TREE_VALUE (arglist);
5103  if (! POINTER_TYPE_P (TREE_TYPE (dest)))
5104    return 0;
5105  arglist = TREE_CHAIN (arglist);
5106  if (! arglist)
5107    return 0;
5108  fmt = TREE_VALUE (arglist);
5109  if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
5110    return 0;
5111  arglist = TREE_CHAIN (arglist);
5112
5113  /* Check whether the format is a literal string constant.  */
5114  fmt_str = c_getstr (fmt);
5115  if (fmt_str == NULL)
5116    return 0;
5117
5118  if (!init_target_chars())
5119    return 0;
5120
5121  /* If the format doesn't contain % args or %%, use strcpy.  */
5122  if (strchr (fmt_str, target_percent) == 0)
5123    {
5124      tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
5125      tree exp;
5126
5127      if (arglist || ! fn)
5128	return 0;
5129      expand_expr (build_function_call_expr (fn, orig_arglist),
5130		   const0_rtx, VOIDmode, EXPAND_NORMAL);
5131      if (target == const0_rtx)
5132	return const0_rtx;
5133      exp = build_int_cst (NULL_TREE, strlen (fmt_str));
5134      return expand_expr (exp, target, mode, EXPAND_NORMAL);
5135    }
5136  /* If the format is "%s", use strcpy if the result isn't used.  */
5137  else if (strcmp (fmt_str, target_percent_s) == 0)
5138    {
5139      tree fn, arg, len;
5140      fn = implicit_built_in_decls[BUILT_IN_STRCPY];
5141
5142      if (! fn)
5143	return 0;
5144
5145      if (! arglist || TREE_CHAIN (arglist))
5146	return 0;
5147      arg = TREE_VALUE (arglist);
5148      if (! POINTER_TYPE_P (TREE_TYPE (arg)))
5149	return 0;
5150
5151      if (target != const0_rtx)
5152	{
5153	  len = c_strlen (arg, 1);
5154	  if (! len || TREE_CODE (len) != INTEGER_CST)
5155	    return 0;
5156	}
5157      else
5158	len = NULL_TREE;
5159
5160      arglist = build_tree_list (NULL_TREE, arg);
5161      arglist = tree_cons (NULL_TREE, dest, arglist);
5162      expand_expr (build_function_call_expr (fn, arglist),
5163		   const0_rtx, VOIDmode, EXPAND_NORMAL);
5164
5165      if (target == const0_rtx)
5166	return const0_rtx;
5167      return expand_expr (len, target, mode, EXPAND_NORMAL);
5168    }
5169
5170  return 0;
5171}
5172
5173/* Expand a call to either the entry or exit function profiler.  */
5174
5175static rtx
5176expand_builtin_profile_func (bool exitp)
5177{
5178  rtx this, which;
5179
5180  this = DECL_RTL (current_function_decl);
5181  gcc_assert (MEM_P (this));
5182  this = XEXP (this, 0);
5183
5184  if (exitp)
5185    which = profile_function_exit_libfunc;
5186  else
5187    which = profile_function_entry_libfunc;
5188
5189  emit_library_call (which, LCT_NORMAL, VOIDmode, 2, this, Pmode,
5190		     expand_builtin_return_addr (BUILT_IN_RETURN_ADDRESS,
5191						 0),
5192		     Pmode);
5193
5194  return const0_rtx;
5195}
5196
5197/* Given a trampoline address, make sure it satisfies TRAMPOLINE_ALIGNMENT.  */
5198
5199static rtx
5200round_trampoline_addr (rtx tramp)
5201{
5202  rtx temp, addend, mask;
5203
5204  /* If we don't need too much alignment, we'll have been guaranteed
5205     proper alignment by get_trampoline_type.  */
5206  if (TRAMPOLINE_ALIGNMENT <= STACK_BOUNDARY)
5207    return tramp;
5208
5209  /* Round address up to desired boundary.  */
5210  temp = gen_reg_rtx (Pmode);
5211  addend = GEN_INT (TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT - 1);
5212  mask = GEN_INT (-TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT);
5213
5214  temp  = expand_simple_binop (Pmode, PLUS, tramp, addend,
5215			       temp, 0, OPTAB_LIB_WIDEN);
5216  tramp = expand_simple_binop (Pmode, AND, temp, mask,
5217			       temp, 0, OPTAB_LIB_WIDEN);
5218
5219  return tramp;
5220}
5221
5222static rtx
5223expand_builtin_init_trampoline (tree arglist)
5224{
5225  tree t_tramp, t_func, t_chain;
5226  rtx r_tramp, r_func, r_chain;
5227#ifdef TRAMPOLINE_TEMPLATE
5228  rtx blktramp;
5229#endif
5230
5231  if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE,
5232			 POINTER_TYPE, VOID_TYPE))
5233    return NULL_RTX;
5234
5235  t_tramp = TREE_VALUE (arglist);
5236  arglist = TREE_CHAIN (arglist);
5237  t_func = TREE_VALUE (arglist);
5238  arglist = TREE_CHAIN (arglist);
5239  t_chain = TREE_VALUE (arglist);
5240
5241  r_tramp = expand_normal (t_tramp);
5242  r_func = expand_normal (t_func);
5243  r_chain = expand_normal (t_chain);
5244
5245  /* Generate insns to initialize the trampoline.  */
5246  r_tramp = round_trampoline_addr (r_tramp);
5247#ifdef TRAMPOLINE_TEMPLATE
5248  blktramp = gen_rtx_MEM (BLKmode, r_tramp);
5249  set_mem_align (blktramp, TRAMPOLINE_ALIGNMENT);
5250  emit_block_move (blktramp, assemble_trampoline_template (),
5251		   GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL);
5252#endif
5253  trampolines_created = 1;
5254  INITIALIZE_TRAMPOLINE (r_tramp, r_func, r_chain);
5255
5256  return const0_rtx;
5257}
5258
5259static rtx
5260expand_builtin_adjust_trampoline (tree arglist)
5261{
5262  rtx tramp;
5263
5264  if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5265    return NULL_RTX;
5266
5267  tramp = expand_normal (TREE_VALUE (arglist));
5268  tramp = round_trampoline_addr (tramp);
5269#ifdef TRAMPOLINE_ADJUST_ADDRESS
5270  TRAMPOLINE_ADJUST_ADDRESS (tramp);
5271#endif
5272
5273  return tramp;
5274}
5275
5276/* Expand a call to the built-in signbit, signbitf or signbitl function.
5277   Return NULL_RTX if a normal call should be emitted rather than expanding
5278   the function in-line.  EXP is the expression that is a call to the builtin
5279   function; if convenient, the result should be placed in TARGET.  */
5280
5281static rtx
5282expand_builtin_signbit (tree exp, rtx target)
5283{
5284  const struct real_format *fmt;
5285  enum machine_mode fmode, imode, rmode;
5286  HOST_WIDE_INT hi, lo;
5287  tree arg, arglist;
5288  int word, bitpos;
5289  rtx temp;
5290
5291  arglist = TREE_OPERAND (exp, 1);
5292  if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
5293    return 0;
5294
5295  arg = TREE_VALUE (arglist);
5296  fmode = TYPE_MODE (TREE_TYPE (arg));
5297  rmode = TYPE_MODE (TREE_TYPE (exp));
5298  fmt = REAL_MODE_FORMAT (fmode);
5299
5300  /* For floating point formats without a sign bit, implement signbit
5301     as "ARG < 0.0".  */
5302  bitpos = fmt->signbit_ro;
5303  if (bitpos < 0)
5304  {
5305    /* But we can't do this if the format supports signed zero.  */
5306    if (fmt->has_signed_zero && HONOR_SIGNED_ZEROS (fmode))
5307      return 0;
5308
5309    arg = fold_build2 (LT_EXPR, TREE_TYPE (exp), arg,
5310		       build_real (TREE_TYPE (arg), dconst0));
5311    return expand_expr (arg, target, VOIDmode, EXPAND_NORMAL);
5312  }
5313
5314  temp = expand_normal (arg);
5315  if (GET_MODE_SIZE (fmode) <= UNITS_PER_WORD)
5316    {
5317      imode = int_mode_for_mode (fmode);
5318      if (imode == BLKmode)
5319	return 0;
5320      temp = gen_lowpart (imode, temp);
5321    }
5322  else
5323    {
5324      imode = word_mode;
5325      /* Handle targets with different FP word orders.  */
5326      if (FLOAT_WORDS_BIG_ENDIAN)
5327	word = (GET_MODE_BITSIZE (fmode) - bitpos) / BITS_PER_WORD;
5328      else
5329	word = bitpos / BITS_PER_WORD;
5330      temp = operand_subword_force (temp, word, fmode);
5331      bitpos = bitpos % BITS_PER_WORD;
5332    }
5333
5334  /* Force the intermediate word_mode (or narrower) result into a
5335     register.  This avoids attempting to create paradoxical SUBREGs
5336     of floating point modes below.  */
5337  temp = force_reg (imode, temp);
5338
5339  /* If the bitpos is within the "result mode" lowpart, the operation
5340     can be implement with a single bitwise AND.  Otherwise, we need
5341     a right shift and an AND.  */
5342
5343  if (bitpos < GET_MODE_BITSIZE (rmode))
5344    {
5345      if (bitpos < HOST_BITS_PER_WIDE_INT)
5346	{
5347	  hi = 0;
5348	  lo = (HOST_WIDE_INT) 1 << bitpos;
5349	}
5350      else
5351	{
5352	  hi = (HOST_WIDE_INT) 1 << (bitpos - HOST_BITS_PER_WIDE_INT);
5353	  lo = 0;
5354	}
5355
5356      if (imode != rmode)
5357	temp = gen_lowpart (rmode, temp);
5358      temp = expand_binop (rmode, and_optab, temp,
5359			   immed_double_const (lo, hi, rmode),
5360			   NULL_RTX, 1, OPTAB_LIB_WIDEN);
5361    }
5362  else
5363    {
5364      /* Perform a logical right shift to place the signbit in the least
5365	 significant bit, then truncate the result to the desired mode
5366	 and mask just this bit.  */
5367      temp = expand_shift (RSHIFT_EXPR, imode, temp,
5368			   build_int_cst (NULL_TREE, bitpos), NULL_RTX, 1);
5369      temp = gen_lowpart (rmode, temp);
5370      temp = expand_binop (rmode, and_optab, temp, const1_rtx,
5371			   NULL_RTX, 1, OPTAB_LIB_WIDEN);
5372    }
5373
5374  return temp;
5375}
5376
5377/* Expand fork or exec calls.  TARGET is the desired target of the
5378   call.  ARGLIST is the list of arguments of the call.  FN is the
5379   identificator of the actual function.  IGNORE is nonzero if the
5380   value is to be ignored.  */
5381
5382static rtx
5383expand_builtin_fork_or_exec (tree fn, tree arglist, rtx target, int ignore)
5384{
5385  tree id, decl;
5386  tree call;
5387
5388  /* If we are not profiling, just call the function.  */
5389  if (!profile_arc_flag)
5390    return NULL_RTX;
5391
5392  /* Otherwise call the wrapper.  This should be equivalent for the rest of
5393     compiler, so the code does not diverge, and the wrapper may run the
5394     code necessary for keeping the profiling sane.  */
5395
5396  switch (DECL_FUNCTION_CODE (fn))
5397    {
5398    case BUILT_IN_FORK:
5399      id = get_identifier ("__gcov_fork");
5400      break;
5401
5402    case BUILT_IN_EXECL:
5403      id = get_identifier ("__gcov_execl");
5404      break;
5405
5406    case BUILT_IN_EXECV:
5407      id = get_identifier ("__gcov_execv");
5408      break;
5409
5410    case BUILT_IN_EXECLP:
5411      id = get_identifier ("__gcov_execlp");
5412      break;
5413
5414    case BUILT_IN_EXECLE:
5415      id = get_identifier ("__gcov_execle");
5416      break;
5417
5418    case BUILT_IN_EXECVP:
5419      id = get_identifier ("__gcov_execvp");
5420      break;
5421
5422    case BUILT_IN_EXECVE:
5423      id = get_identifier ("__gcov_execve");
5424      break;
5425
5426    default:
5427      gcc_unreachable ();
5428    }
5429
5430  decl = build_decl (FUNCTION_DECL, id, TREE_TYPE (fn));
5431  DECL_EXTERNAL (decl) = 1;
5432  TREE_PUBLIC (decl) = 1;
5433  DECL_ARTIFICIAL (decl) = 1;
5434  TREE_NOTHROW (decl) = 1;
5435  DECL_VISIBILITY (decl) = VISIBILITY_DEFAULT;
5436  DECL_VISIBILITY_SPECIFIED (decl) = 1;
5437  call = build_function_call_expr (decl, arglist);
5438
5439  return expand_call (call, target, ignore);
5440}
5441
5442
5443/* Reconstitute a mode for a __sync intrinsic operation.  Since the type of
5444   the pointer in these functions is void*, the tree optimizers may remove
5445   casts.  The mode computed in expand_builtin isn't reliable either, due
5446   to __sync_bool_compare_and_swap.
5447
5448   FCODE_DIFF should be fcode - base, where base is the FOO_1 code for the
5449   group of builtins.  This gives us log2 of the mode size.  */
5450
5451static inline enum machine_mode
5452get_builtin_sync_mode (int fcode_diff)
5453{
5454  /* The size is not negotiable, so ask not to get BLKmode in return
5455     if the target indicates that a smaller size would be better.  */
5456  return mode_for_size (BITS_PER_UNIT << fcode_diff, MODE_INT, 0);
5457}
5458
5459/* Expand the memory expression LOC and return the appropriate memory operand
5460   for the builtin_sync operations.  */
5461
5462static rtx
5463get_builtin_sync_mem (tree loc, enum machine_mode mode)
5464{
5465  rtx addr, mem;
5466
5467  addr = expand_expr (loc, NULL, Pmode, EXPAND_SUM);
5468
5469  /* Note that we explicitly do not want any alias information for this
5470     memory, so that we kill all other live memories.  Otherwise we don't
5471     satisfy the full barrier semantics of the intrinsic.  */
5472  mem = validize_mem (gen_rtx_MEM (mode, addr));
5473
5474  set_mem_align (mem, get_pointer_alignment (loc, BIGGEST_ALIGNMENT));
5475  set_mem_alias_set (mem, ALIAS_SET_MEMORY_BARRIER);
5476  MEM_VOLATILE_P (mem) = 1;
5477
5478  return mem;
5479}
5480
5481/* Expand the __sync_xxx_and_fetch and __sync_fetch_and_xxx intrinsics.
5482   ARGLIST is the operands list to the function.  CODE is the rtx code
5483   that corresponds to the arithmetic or logical operation from the name;
5484   an exception here is that NOT actually means NAND.  TARGET is an optional
5485   place for us to store the results; AFTER is true if this is the
5486   fetch_and_xxx form.  IGNORE is true if we don't actually care about
5487   the result of the operation at all.  */
5488
5489static rtx
5490expand_builtin_sync_operation (enum machine_mode mode, tree arglist,
5491			       enum rtx_code code, bool after,
5492			       rtx target, bool ignore)
5493{
5494  rtx val, mem;
5495  enum machine_mode old_mode;
5496
5497  /* Expand the operands.  */
5498  mem = get_builtin_sync_mem (TREE_VALUE (arglist), mode);
5499
5500  arglist = TREE_CHAIN (arglist);
5501  val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
5502  /* If VAL is promoted to a wider mode, convert it back to MODE.  Take care
5503     of CONST_INTs, where we know the old_mode only from the call argument.  */
5504  old_mode = GET_MODE (val);
5505  if (old_mode == VOIDmode)
5506    old_mode = TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist)));
5507  val = convert_modes (mode, old_mode, val, 1);
5508
5509  if (ignore)
5510    return expand_sync_operation (mem, val, code);
5511  else
5512    return expand_sync_fetch_operation (mem, val, code, after, target);
5513}
5514
5515/* Expand the __sync_val_compare_and_swap and __sync_bool_compare_and_swap
5516   intrinsics.  ARGLIST is the operands list to the function.  IS_BOOL is
5517   true if this is the boolean form.  TARGET is a place for us to store the
5518   results; this is NOT optional if IS_BOOL is true.  */
5519
5520static rtx
5521expand_builtin_compare_and_swap (enum machine_mode mode, tree arglist,
5522				 bool is_bool, rtx target)
5523{
5524  rtx old_val, new_val, mem;
5525  enum machine_mode old_mode;
5526
5527  /* Expand the operands.  */
5528  mem = get_builtin_sync_mem (TREE_VALUE (arglist), mode);
5529
5530  arglist = TREE_CHAIN (arglist);
5531  old_val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
5532  /* If VAL is promoted to a wider mode, convert it back to MODE.  Take care
5533     of CONST_INTs, where we know the old_mode only from the call argument.  */
5534  old_mode = GET_MODE (old_val);
5535  if (old_mode == VOIDmode)
5536    old_mode = TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist)));
5537  old_val = convert_modes (mode, old_mode, old_val, 1);
5538
5539  arglist = TREE_CHAIN (arglist);
5540  new_val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
5541  /* If VAL is promoted to a wider mode, convert it back to MODE.  Take care
5542     of CONST_INTs, where we know the old_mode only from the call argument.  */
5543  old_mode = GET_MODE (new_val);
5544  if (old_mode == VOIDmode)
5545    old_mode = TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist)));
5546  new_val = convert_modes (mode, old_mode, new_val, 1);
5547
5548  if (is_bool)
5549    return expand_bool_compare_and_swap (mem, old_val, new_val, target);
5550  else
5551    return expand_val_compare_and_swap (mem, old_val, new_val, target);
5552}
5553
5554/* Expand the __sync_lock_test_and_set intrinsic.  Note that the most
5555   general form is actually an atomic exchange, and some targets only
5556   support a reduced form with the second argument being a constant 1.
5557   ARGLIST is the operands list to the function; TARGET is an optional
5558   place for us to store the results.  */
5559
5560static rtx
5561expand_builtin_lock_test_and_set (enum machine_mode mode, tree arglist,
5562				  rtx target)
5563{
5564  rtx val, mem;
5565  enum machine_mode old_mode;
5566
5567  /* Expand the operands.  */
5568  mem = get_builtin_sync_mem (TREE_VALUE (arglist), mode);
5569
5570  arglist = TREE_CHAIN (arglist);
5571  val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
5572  /* If VAL is promoted to a wider mode, convert it back to MODE.  Take care
5573     of CONST_INTs, where we know the old_mode only from the call argument.  */
5574  old_mode = GET_MODE (val);
5575  if (old_mode == VOIDmode)
5576    old_mode = TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist)));
5577  val = convert_modes (mode, old_mode, val, 1);
5578
5579  return expand_sync_lock_test_and_set (mem, val, target);
5580}
5581
5582/* Expand the __sync_synchronize intrinsic.  */
5583
5584static void
5585expand_builtin_synchronize (void)
5586{
5587  tree x;
5588
5589#ifdef HAVE_memory_barrier
5590  if (HAVE_memory_barrier)
5591    {
5592      emit_insn (gen_memory_barrier ());
5593      return;
5594    }
5595#endif
5596
5597  /* If no explicit memory barrier instruction is available, create an
5598     empty asm stmt with a memory clobber.  */
5599  x = build4 (ASM_EXPR, void_type_node, build_string (0, ""), NULL, NULL,
5600	      tree_cons (NULL, build_string (6, "memory"), NULL));
5601  ASM_VOLATILE_P (x) = 1;
5602  expand_asm_expr (x);
5603}
5604
5605/* Expand the __sync_lock_release intrinsic.  ARGLIST is the operands list
5606   to the function.  */
5607
5608static void
5609expand_builtin_lock_release (enum machine_mode mode, tree arglist)
5610{
5611  enum insn_code icode;
5612  rtx mem, insn;
5613  rtx val = const0_rtx;
5614
5615  /* Expand the operands.  */
5616  mem = get_builtin_sync_mem (TREE_VALUE (arglist), mode);
5617
5618  /* If there is an explicit operation in the md file, use it.  */
5619  icode = sync_lock_release[mode];
5620  if (icode != CODE_FOR_nothing)
5621    {
5622      if (!insn_data[icode].operand[1].predicate (val, mode))
5623	val = force_reg (mode, val);
5624
5625      insn = GEN_FCN (icode) (mem, val);
5626      if (insn)
5627	{
5628	  emit_insn (insn);
5629	  return;
5630	}
5631    }
5632
5633  /* Otherwise we can implement this operation by emitting a barrier
5634     followed by a store of zero.  */
5635  expand_builtin_synchronize ();
5636  emit_move_insn (mem, val);
5637}
5638
5639/* Expand an expression EXP that calls a built-in function,
5640   with result going to TARGET if that's convenient
5641   (and in mode MODE if that's convenient).
5642   SUBTARGET may be used as the target for computing one of EXP's operands.
5643   IGNORE is nonzero if the value is to be ignored.  */
5644
5645rtx
5646expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
5647		int ignore)
5648{
5649  tree fndecl = get_callee_fndecl (exp);
5650  tree arglist = TREE_OPERAND (exp, 1);
5651  enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
5652  enum machine_mode target_mode = TYPE_MODE (TREE_TYPE (exp));
5653
5654  if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
5655    return targetm.expand_builtin (exp, target, subtarget, mode, ignore);
5656
5657  /* When not optimizing, generate calls to library functions for a certain
5658     set of builtins.  */
5659  if (!optimize
5660      && !called_as_built_in (fndecl)
5661      && DECL_ASSEMBLER_NAME_SET_P (fndecl)
5662      && fcode != BUILT_IN_ALLOCA)
5663    return expand_call (exp, target, ignore);
5664
5665  /* The built-in function expanders test for target == const0_rtx
5666     to determine whether the function's result will be ignored.  */
5667  if (ignore)
5668    target = const0_rtx;
5669
5670  /* If the result of a pure or const built-in function is ignored, and
5671     none of its arguments are volatile, we can avoid expanding the
5672     built-in call and just evaluate the arguments for side-effects.  */
5673  if (target == const0_rtx
5674      && (DECL_IS_PURE (fndecl) || TREE_READONLY (fndecl)))
5675    {
5676      bool volatilep = false;
5677      tree arg;
5678
5679      for (arg = arglist; arg; arg = TREE_CHAIN (arg))
5680	if (TREE_THIS_VOLATILE (TREE_VALUE (arg)))
5681	  {
5682	    volatilep = true;
5683	    break;
5684	  }
5685
5686      if (! volatilep)
5687	{
5688	  for (arg = arglist; arg; arg = TREE_CHAIN (arg))
5689	    expand_expr (TREE_VALUE (arg), const0_rtx,
5690			 VOIDmode, EXPAND_NORMAL);
5691	  return const0_rtx;
5692	}
5693    }
5694
5695  switch (fcode)
5696    {
5697    CASE_FLT_FN (BUILT_IN_FABS):
5698      target = expand_builtin_fabs (arglist, target, subtarget);
5699      if (target)
5700	return target;
5701      break;
5702
5703    CASE_FLT_FN (BUILT_IN_COPYSIGN):
5704      target = expand_builtin_copysign (arglist, target, subtarget);
5705      if (target)
5706	return target;
5707      break;
5708
5709      /* Just do a normal library call if we were unable to fold
5710	 the values.  */
5711    CASE_FLT_FN (BUILT_IN_CABS):
5712      break;
5713
5714    CASE_FLT_FN (BUILT_IN_EXP):
5715    CASE_FLT_FN (BUILT_IN_EXP10):
5716    CASE_FLT_FN (BUILT_IN_POW10):
5717    CASE_FLT_FN (BUILT_IN_EXP2):
5718    CASE_FLT_FN (BUILT_IN_EXPM1):
5719    CASE_FLT_FN (BUILT_IN_LOGB):
5720    CASE_FLT_FN (BUILT_IN_ILOGB):
5721    CASE_FLT_FN (BUILT_IN_LOG):
5722    CASE_FLT_FN (BUILT_IN_LOG10):
5723    CASE_FLT_FN (BUILT_IN_LOG2):
5724    CASE_FLT_FN (BUILT_IN_LOG1P):
5725    CASE_FLT_FN (BUILT_IN_TAN):
5726    CASE_FLT_FN (BUILT_IN_ASIN):
5727    CASE_FLT_FN (BUILT_IN_ACOS):
5728    CASE_FLT_FN (BUILT_IN_ATAN):
5729      /* Treat these like sqrt only if unsafe math optimizations are allowed,
5730	 because of possible accuracy problems.  */
5731      if (! flag_unsafe_math_optimizations)
5732	break;
5733    CASE_FLT_FN (BUILT_IN_SQRT):
5734    CASE_FLT_FN (BUILT_IN_FLOOR):
5735    CASE_FLT_FN (BUILT_IN_CEIL):
5736    CASE_FLT_FN (BUILT_IN_TRUNC):
5737    CASE_FLT_FN (BUILT_IN_ROUND):
5738    CASE_FLT_FN (BUILT_IN_NEARBYINT):
5739    CASE_FLT_FN (BUILT_IN_RINT):
5740    CASE_FLT_FN (BUILT_IN_LRINT):
5741    CASE_FLT_FN (BUILT_IN_LLRINT):
5742      target = expand_builtin_mathfn (exp, target, subtarget);
5743      if (target)
5744	return target;
5745      break;
5746
5747    CASE_FLT_FN (BUILT_IN_LCEIL):
5748    CASE_FLT_FN (BUILT_IN_LLCEIL):
5749    CASE_FLT_FN (BUILT_IN_LFLOOR):
5750    CASE_FLT_FN (BUILT_IN_LLFLOOR):
5751      target = expand_builtin_int_roundingfn (exp, target, subtarget);
5752      if (target)
5753	return target;
5754      break;
5755
5756    CASE_FLT_FN (BUILT_IN_POW):
5757      target = expand_builtin_pow (exp, target, subtarget);
5758      if (target)
5759	return target;
5760      break;
5761
5762    CASE_FLT_FN (BUILT_IN_POWI):
5763      target = expand_builtin_powi (exp, target, subtarget);
5764      if (target)
5765	return target;
5766      break;
5767
5768    CASE_FLT_FN (BUILT_IN_ATAN2):
5769    CASE_FLT_FN (BUILT_IN_LDEXP):
5770    CASE_FLT_FN (BUILT_IN_FMOD):
5771    CASE_FLT_FN (BUILT_IN_DREM):
5772      if (! flag_unsafe_math_optimizations)
5773	break;
5774      target = expand_builtin_mathfn_2 (exp, target, subtarget);
5775      if (target)
5776	return target;
5777      break;
5778
5779    CASE_FLT_FN (BUILT_IN_SIN):
5780    CASE_FLT_FN (BUILT_IN_COS):
5781      if (! flag_unsafe_math_optimizations)
5782	break;
5783      target = expand_builtin_mathfn_3 (exp, target, subtarget);
5784      if (target)
5785	return target;
5786      break;
5787
5788    CASE_FLT_FN (BUILT_IN_SINCOS):
5789      if (! flag_unsafe_math_optimizations)
5790	break;
5791      target = expand_builtin_sincos (exp);
5792      if (target)
5793	return target;
5794      break;
5795
5796    case BUILT_IN_APPLY_ARGS:
5797      return expand_builtin_apply_args ();
5798
5799      /* __builtin_apply (FUNCTION, ARGUMENTS, ARGSIZE) invokes
5800	 FUNCTION with a copy of the parameters described by
5801	 ARGUMENTS, and ARGSIZE.  It returns a block of memory
5802	 allocated on the stack into which is stored all the registers
5803	 that might possibly be used for returning the result of a
5804	 function.  ARGUMENTS is the value returned by
5805	 __builtin_apply_args.  ARGSIZE is the number of bytes of
5806	 arguments that must be copied.  ??? How should this value be
5807	 computed?  We'll also need a safe worst case value for varargs
5808	 functions.  */
5809    case BUILT_IN_APPLY:
5810      if (!validate_arglist (arglist, POINTER_TYPE,
5811			     POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)
5812	  && !validate_arglist (arglist, REFERENCE_TYPE,
5813				POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
5814	return const0_rtx;
5815      else
5816	{
5817	  int i;
5818	  tree t;
5819	  rtx ops[3];
5820
5821	  for (t = arglist, i = 0; t; t = TREE_CHAIN (t), i++)
5822	    ops[i] = expand_normal (TREE_VALUE (t));
5823
5824	  return expand_builtin_apply (ops[0], ops[1], ops[2]);
5825	}
5826
5827      /* __builtin_return (RESULT) causes the function to return the
5828	 value described by RESULT.  RESULT is address of the block of
5829	 memory returned by __builtin_apply.  */
5830    case BUILT_IN_RETURN:
5831      if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5832	expand_builtin_return (expand_normal (TREE_VALUE (arglist)));
5833      return const0_rtx;
5834
5835    case BUILT_IN_SAVEREGS:
5836      return expand_builtin_saveregs ();
5837
5838    case BUILT_IN_ARGS_INFO:
5839      return expand_builtin_args_info (arglist);
5840
5841      /* Return the address of the first anonymous stack arg.  */
5842    case BUILT_IN_NEXT_ARG:
5843      if (fold_builtin_next_arg (arglist))
5844	return const0_rtx;
5845      return expand_builtin_next_arg ();
5846
5847    case BUILT_IN_CLASSIFY_TYPE:
5848      return expand_builtin_classify_type (arglist);
5849
5850    case BUILT_IN_CONSTANT_P:
5851      return const0_rtx;
5852
5853    case BUILT_IN_FRAME_ADDRESS:
5854    case BUILT_IN_RETURN_ADDRESS:
5855      return expand_builtin_frame_address (fndecl, arglist);
5856
5857    /* Returns the address of the area where the structure is returned.
5858       0 otherwise.  */
5859    case BUILT_IN_AGGREGATE_INCOMING_ADDRESS:
5860      if (arglist != 0
5861	  || ! AGGREGATE_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl)))
5862	  || !MEM_P (DECL_RTL (DECL_RESULT (current_function_decl))))
5863	return const0_rtx;
5864      else
5865	return XEXP (DECL_RTL (DECL_RESULT (current_function_decl)), 0);
5866
5867    case BUILT_IN_ALLOCA:
5868      target = expand_builtin_alloca (arglist, target);
5869      if (target)
5870	return target;
5871      break;
5872
5873    case BUILT_IN_STACK_SAVE:
5874      return expand_stack_save ();
5875
5876    case BUILT_IN_STACK_RESTORE:
5877      expand_stack_restore (TREE_VALUE (arglist));
5878      return const0_rtx;
5879
5880    CASE_INT_FN (BUILT_IN_FFS):
5881    case BUILT_IN_FFSIMAX:
5882      target = expand_builtin_unop (target_mode, arglist, target,
5883				    subtarget, ffs_optab);
5884      if (target)
5885	return target;
5886      break;
5887
5888    CASE_INT_FN (BUILT_IN_CLZ):
5889    case BUILT_IN_CLZIMAX:
5890      target = expand_builtin_unop (target_mode, arglist, target,
5891				    subtarget, clz_optab);
5892      if (target)
5893	return target;
5894      break;
5895
5896    CASE_INT_FN (BUILT_IN_CTZ):
5897    case BUILT_IN_CTZIMAX:
5898      target = expand_builtin_unop (target_mode, arglist, target,
5899				    subtarget, ctz_optab);
5900      if (target)
5901	return target;
5902      break;
5903
5904    CASE_INT_FN (BUILT_IN_POPCOUNT):
5905    case BUILT_IN_POPCOUNTIMAX:
5906      target = expand_builtin_unop (target_mode, arglist, target,
5907				    subtarget, popcount_optab);
5908      if (target)
5909	return target;
5910      break;
5911
5912    CASE_INT_FN (BUILT_IN_PARITY):
5913    case BUILT_IN_PARITYIMAX:
5914      target = expand_builtin_unop (target_mode, arglist, target,
5915				    subtarget, parity_optab);
5916      if (target)
5917	return target;
5918      break;
5919
5920    case BUILT_IN_STRLEN:
5921      target = expand_builtin_strlen (arglist, target, target_mode);
5922      if (target)
5923	return target;
5924      break;
5925
5926    case BUILT_IN_STRCPY:
5927      target = expand_builtin_strcpy (fndecl, arglist, target, mode);
5928      if (target)
5929	return target;
5930      break;
5931
5932    case BUILT_IN_STRNCPY:
5933      target = expand_builtin_strncpy (exp, target, mode);
5934      if (target)
5935	return target;
5936      break;
5937
5938    case BUILT_IN_STPCPY:
5939      target = expand_builtin_stpcpy (exp, target, mode);
5940      if (target)
5941	return target;
5942      break;
5943
5944    case BUILT_IN_STRCAT:
5945      target = expand_builtin_strcat (fndecl, arglist, target, mode);
5946      if (target)
5947	return target;
5948      break;
5949
5950    case BUILT_IN_STRNCAT:
5951      target = expand_builtin_strncat (arglist, target, mode);
5952      if (target)
5953	return target;
5954      break;
5955
5956    case BUILT_IN_STRSPN:
5957      target = expand_builtin_strspn (arglist, target, mode);
5958      if (target)
5959	return target;
5960      break;
5961
5962    case BUILT_IN_STRCSPN:
5963      target = expand_builtin_strcspn (arglist, target, mode);
5964      if (target)
5965	return target;
5966      break;
5967
5968    case BUILT_IN_STRSTR:
5969      target = expand_builtin_strstr (arglist, TREE_TYPE (exp), target, mode);
5970      if (target)
5971	return target;
5972      break;
5973
5974    case BUILT_IN_STRPBRK:
5975      target = expand_builtin_strpbrk (arglist, TREE_TYPE (exp), target, mode);
5976      if (target)
5977	return target;
5978      break;
5979
5980    case BUILT_IN_INDEX:
5981    case BUILT_IN_STRCHR:
5982      target = expand_builtin_strchr (arglist, TREE_TYPE (exp), target, mode);
5983      if (target)
5984	return target;
5985      break;
5986
5987    case BUILT_IN_RINDEX:
5988    case BUILT_IN_STRRCHR:
5989      target = expand_builtin_strrchr (arglist, TREE_TYPE (exp), target, mode);
5990      if (target)
5991	return target;
5992      break;
5993
5994    case BUILT_IN_MEMCPY:
5995      target = expand_builtin_memcpy (exp, target, mode);
5996      if (target)
5997	return target;
5998      break;
5999
6000    case BUILT_IN_MEMPCPY:
6001      target = expand_builtin_mempcpy (arglist, TREE_TYPE (exp), target, mode, /*endp=*/ 1);
6002      if (target)
6003	return target;
6004      break;
6005
6006    case BUILT_IN_MEMMOVE:
6007      target = expand_builtin_memmove (arglist, TREE_TYPE (exp), target,
6008				       mode, exp);
6009      if (target)
6010	return target;
6011      break;
6012
6013    case BUILT_IN_BCOPY:
6014      target = expand_builtin_bcopy (exp);
6015      if (target)
6016	return target;
6017      break;
6018
6019    case BUILT_IN_MEMSET:
6020      target = expand_builtin_memset (arglist, target, mode, exp);
6021      if (target)
6022	return target;
6023      break;
6024
6025    case BUILT_IN_BZERO:
6026      target = expand_builtin_bzero (exp);
6027      if (target)
6028	return target;
6029      break;
6030
6031    case BUILT_IN_STRCMP:
6032      target = expand_builtin_strcmp (exp, target, mode);
6033      if (target)
6034	return target;
6035      break;
6036
6037    case BUILT_IN_STRNCMP:
6038      target = expand_builtin_strncmp (exp, target, mode);
6039      if (target)
6040	return target;
6041      break;
6042
6043    case BUILT_IN_BCMP:
6044    case BUILT_IN_MEMCMP:
6045      target = expand_builtin_memcmp (exp, arglist, target, mode);
6046      if (target)
6047	return target;
6048      break;
6049
6050    case BUILT_IN_SETJMP:
6051      /* This should have been lowered to the builtins below.  */
6052      gcc_unreachable ();
6053
6054    case BUILT_IN_SETJMP_SETUP:
6055      /* __builtin_setjmp_setup is passed a pointer to an array of five words
6056          and the receiver label.  */
6057      if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
6058	{
6059	  rtx buf_addr = expand_expr (TREE_VALUE (arglist), subtarget,
6060				      VOIDmode, EXPAND_NORMAL);
6061	  tree label = TREE_OPERAND (TREE_VALUE (TREE_CHAIN (arglist)), 0);
6062	  rtx label_r = label_rtx (label);
6063
6064	  /* This is copied from the handling of non-local gotos.  */
6065	  expand_builtin_setjmp_setup (buf_addr, label_r);
6066	  nonlocal_goto_handler_labels
6067	    = gen_rtx_EXPR_LIST (VOIDmode, label_r,
6068				 nonlocal_goto_handler_labels);
6069	  /* ??? Do not let expand_label treat us as such since we would
6070	     not want to be both on the list of non-local labels and on
6071	     the list of forced labels.  */
6072	  FORCED_LABEL (label) = 0;
6073	  return const0_rtx;
6074	}
6075      break;
6076
6077    case BUILT_IN_SETJMP_DISPATCHER:
6078       /* __builtin_setjmp_dispatcher is passed the dispatcher label.  */
6079      if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6080	{
6081	  tree label = TREE_OPERAND (TREE_VALUE (arglist), 0);
6082	  rtx label_r = label_rtx (label);
6083
6084	  /* Remove the dispatcher label from the list of non-local labels
6085	     since the receiver labels have been added to it above.  */
6086	  remove_node_from_expr_list (label_r, &nonlocal_goto_handler_labels);
6087	  return const0_rtx;
6088	}
6089      break;
6090
6091    case BUILT_IN_SETJMP_RECEIVER:
6092       /* __builtin_setjmp_receiver is passed the receiver label.  */
6093      if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6094	{
6095	  tree label = TREE_OPERAND (TREE_VALUE (arglist), 0);
6096	  rtx label_r = label_rtx (label);
6097
6098	  expand_builtin_setjmp_receiver (label_r);
6099	  return const0_rtx;
6100	}
6101      break;
6102
6103      /* __builtin_longjmp is passed a pointer to an array of five words.
6104	 It's similar to the C library longjmp function but works with
6105	 __builtin_setjmp above.  */
6106    case BUILT_IN_LONGJMP:
6107      if (validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
6108	{
6109	  rtx buf_addr = expand_expr (TREE_VALUE (arglist), subtarget,
6110				      VOIDmode, EXPAND_NORMAL);
6111	  rtx value = expand_normal (TREE_VALUE (TREE_CHAIN (arglist)));
6112
6113	  if (value != const1_rtx)
6114	    {
6115	      error ("%<__builtin_longjmp%> second argument must be 1");
6116	      return const0_rtx;
6117	    }
6118
6119	  expand_builtin_longjmp (buf_addr, value);
6120	  return const0_rtx;
6121	}
6122      break;
6123
6124    case BUILT_IN_NONLOCAL_GOTO:
6125      target = expand_builtin_nonlocal_goto (arglist);
6126      if (target)
6127	return target;
6128      break;
6129
6130      /* This updates the setjmp buffer that is its argument with the value
6131	 of the current stack pointer.  */
6132    case BUILT_IN_UPDATE_SETJMP_BUF:
6133      if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6134	{
6135	  rtx buf_addr
6136	    = expand_normal (TREE_VALUE (arglist));
6137
6138	  expand_builtin_update_setjmp_buf (buf_addr);
6139	  return const0_rtx;
6140	}
6141      break;
6142
6143    case BUILT_IN_TRAP:
6144      expand_builtin_trap ();
6145      return const0_rtx;
6146
6147    case BUILT_IN_PRINTF:
6148      target = expand_builtin_printf (exp, target, mode, false);
6149      if (target)
6150	return target;
6151      break;
6152
6153    case BUILT_IN_PRINTF_UNLOCKED:
6154      target = expand_builtin_printf (exp, target, mode, true);
6155      if (target)
6156	return target;
6157      break;
6158
6159    case BUILT_IN_FPUTS:
6160      target = expand_builtin_fputs (arglist, target, false);
6161      if (target)
6162	return target;
6163      break;
6164    case BUILT_IN_FPUTS_UNLOCKED:
6165      target = expand_builtin_fputs (arglist, target, true);
6166      if (target)
6167	return target;
6168      break;
6169
6170    case BUILT_IN_FPRINTF:
6171      target = expand_builtin_fprintf (exp, target, mode, false);
6172      if (target)
6173	return target;
6174      break;
6175
6176    case BUILT_IN_FPRINTF_UNLOCKED:
6177      target = expand_builtin_fprintf (exp, target, mode, true);
6178      if (target)
6179	return target;
6180      break;
6181
6182    case BUILT_IN_SPRINTF:
6183      target = expand_builtin_sprintf (arglist, target, mode);
6184      if (target)
6185	return target;
6186      break;
6187
6188    CASE_FLT_FN (BUILT_IN_SIGNBIT):
6189      target = expand_builtin_signbit (exp, target);
6190      if (target)
6191	return target;
6192      break;
6193
6194      /* Various hooks for the DWARF 2 __throw routine.  */
6195    case BUILT_IN_UNWIND_INIT:
6196      expand_builtin_unwind_init ();
6197      return const0_rtx;
6198    case BUILT_IN_DWARF_CFA:
6199      return virtual_cfa_rtx;
6200#ifdef DWARF2_UNWIND_INFO
6201    case BUILT_IN_DWARF_SP_COLUMN:
6202      return expand_builtin_dwarf_sp_column ();
6203    case BUILT_IN_INIT_DWARF_REG_SIZES:
6204      expand_builtin_init_dwarf_reg_sizes (TREE_VALUE (arglist));
6205      return const0_rtx;
6206#endif
6207    case BUILT_IN_FROB_RETURN_ADDR:
6208      return expand_builtin_frob_return_addr (TREE_VALUE (arglist));
6209    case BUILT_IN_EXTRACT_RETURN_ADDR:
6210      return expand_builtin_extract_return_addr (TREE_VALUE (arglist));
6211    case BUILT_IN_EH_RETURN:
6212      expand_builtin_eh_return (TREE_VALUE (arglist),
6213				TREE_VALUE (TREE_CHAIN (arglist)));
6214      return const0_rtx;
6215#ifdef EH_RETURN_DATA_REGNO
6216    case BUILT_IN_EH_RETURN_DATA_REGNO:
6217      return expand_builtin_eh_return_data_regno (arglist);
6218#endif
6219    case BUILT_IN_EXTEND_POINTER:
6220      return expand_builtin_extend_pointer (TREE_VALUE (arglist));
6221
6222    case BUILT_IN_VA_START:
6223    case BUILT_IN_STDARG_START:
6224      return expand_builtin_va_start (arglist);
6225    case BUILT_IN_VA_END:
6226      return expand_builtin_va_end (arglist);
6227    case BUILT_IN_VA_COPY:
6228      return expand_builtin_va_copy (arglist);
6229    case BUILT_IN_EXPECT:
6230      return expand_builtin_expect (arglist, target);
6231    case BUILT_IN_PREFETCH:
6232      expand_builtin_prefetch (arglist);
6233      return const0_rtx;
6234
6235    case BUILT_IN_PROFILE_FUNC_ENTER:
6236      return expand_builtin_profile_func (false);
6237    case BUILT_IN_PROFILE_FUNC_EXIT:
6238      return expand_builtin_profile_func (true);
6239
6240    case BUILT_IN_INIT_TRAMPOLINE:
6241      return expand_builtin_init_trampoline (arglist);
6242    case BUILT_IN_ADJUST_TRAMPOLINE:
6243      return expand_builtin_adjust_trampoline (arglist);
6244
6245    case BUILT_IN_FORK:
6246    case BUILT_IN_EXECL:
6247    case BUILT_IN_EXECV:
6248    case BUILT_IN_EXECLP:
6249    case BUILT_IN_EXECLE:
6250    case BUILT_IN_EXECVP:
6251    case BUILT_IN_EXECVE:
6252      target = expand_builtin_fork_or_exec (fndecl, arglist, target, ignore);
6253      if (target)
6254	return target;
6255      break;
6256
6257    case BUILT_IN_FETCH_AND_ADD_1:
6258    case BUILT_IN_FETCH_AND_ADD_2:
6259    case BUILT_IN_FETCH_AND_ADD_4:
6260    case BUILT_IN_FETCH_AND_ADD_8:
6261    case BUILT_IN_FETCH_AND_ADD_16:
6262      mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_ADD_1);
6263      target = expand_builtin_sync_operation (mode, arglist, PLUS,
6264					      false, target, ignore);
6265      if (target)
6266	return target;
6267      break;
6268
6269    case BUILT_IN_FETCH_AND_SUB_1:
6270    case BUILT_IN_FETCH_AND_SUB_2:
6271    case BUILT_IN_FETCH_AND_SUB_4:
6272    case BUILT_IN_FETCH_AND_SUB_8:
6273    case BUILT_IN_FETCH_AND_SUB_16:
6274      mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_SUB_1);
6275      target = expand_builtin_sync_operation (mode, arglist, MINUS,
6276					      false, target, ignore);
6277      if (target)
6278	return target;
6279      break;
6280
6281    case BUILT_IN_FETCH_AND_OR_1:
6282    case BUILT_IN_FETCH_AND_OR_2:
6283    case BUILT_IN_FETCH_AND_OR_4:
6284    case BUILT_IN_FETCH_AND_OR_8:
6285    case BUILT_IN_FETCH_AND_OR_16:
6286      mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_OR_1);
6287      target = expand_builtin_sync_operation (mode, arglist, IOR,
6288					      false, target, ignore);
6289      if (target)
6290	return target;
6291      break;
6292
6293    case BUILT_IN_FETCH_AND_AND_1:
6294    case BUILT_IN_FETCH_AND_AND_2:
6295    case BUILT_IN_FETCH_AND_AND_4:
6296    case BUILT_IN_FETCH_AND_AND_8:
6297    case BUILT_IN_FETCH_AND_AND_16:
6298      mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_AND_1);
6299      target = expand_builtin_sync_operation (mode, arglist, AND,
6300					      false, target, ignore);
6301      if (target)
6302	return target;
6303      break;
6304
6305    case BUILT_IN_FETCH_AND_XOR_1:
6306    case BUILT_IN_FETCH_AND_XOR_2:
6307    case BUILT_IN_FETCH_AND_XOR_4:
6308    case BUILT_IN_FETCH_AND_XOR_8:
6309    case BUILT_IN_FETCH_AND_XOR_16:
6310      mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_XOR_1);
6311      target = expand_builtin_sync_operation (mode, arglist, XOR,
6312					      false, target, ignore);
6313      if (target)
6314	return target;
6315      break;
6316
6317    case BUILT_IN_FETCH_AND_NAND_1:
6318    case BUILT_IN_FETCH_AND_NAND_2:
6319    case BUILT_IN_FETCH_AND_NAND_4:
6320    case BUILT_IN_FETCH_AND_NAND_8:
6321    case BUILT_IN_FETCH_AND_NAND_16:
6322      mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_NAND_1);
6323      target = expand_builtin_sync_operation (mode, arglist, NOT,
6324					      false, target, ignore);
6325      if (target)
6326	return target;
6327      break;
6328
6329    case BUILT_IN_ADD_AND_FETCH_1:
6330    case BUILT_IN_ADD_AND_FETCH_2:
6331    case BUILT_IN_ADD_AND_FETCH_4:
6332    case BUILT_IN_ADD_AND_FETCH_8:
6333    case BUILT_IN_ADD_AND_FETCH_16:
6334      mode = get_builtin_sync_mode (fcode - BUILT_IN_ADD_AND_FETCH_1);
6335      target = expand_builtin_sync_operation (mode, arglist, PLUS,
6336					      true, target, ignore);
6337      if (target)
6338	return target;
6339      break;
6340
6341    case BUILT_IN_SUB_AND_FETCH_1:
6342    case BUILT_IN_SUB_AND_FETCH_2:
6343    case BUILT_IN_SUB_AND_FETCH_4:
6344    case BUILT_IN_SUB_AND_FETCH_8:
6345    case BUILT_IN_SUB_AND_FETCH_16:
6346      mode = get_builtin_sync_mode (fcode - BUILT_IN_SUB_AND_FETCH_1);
6347      target = expand_builtin_sync_operation (mode, arglist, MINUS,
6348					      true, target, ignore);
6349      if (target)
6350	return target;
6351      break;
6352
6353    case BUILT_IN_OR_AND_FETCH_1:
6354    case BUILT_IN_OR_AND_FETCH_2:
6355    case BUILT_IN_OR_AND_FETCH_4:
6356    case BUILT_IN_OR_AND_FETCH_8:
6357    case BUILT_IN_OR_AND_FETCH_16:
6358      mode = get_builtin_sync_mode (fcode - BUILT_IN_OR_AND_FETCH_1);
6359      target = expand_builtin_sync_operation (mode, arglist, IOR,
6360					      true, target, ignore);
6361      if (target)
6362	return target;
6363      break;
6364
6365    case BUILT_IN_AND_AND_FETCH_1:
6366    case BUILT_IN_AND_AND_FETCH_2:
6367    case BUILT_IN_AND_AND_FETCH_4:
6368    case BUILT_IN_AND_AND_FETCH_8:
6369    case BUILT_IN_AND_AND_FETCH_16:
6370      mode = get_builtin_sync_mode (fcode - BUILT_IN_AND_AND_FETCH_1);
6371      target = expand_builtin_sync_operation (mode, arglist, AND,
6372					      true, target, ignore);
6373      if (target)
6374	return target;
6375      break;
6376
6377    case BUILT_IN_XOR_AND_FETCH_1:
6378    case BUILT_IN_XOR_AND_FETCH_2:
6379    case BUILT_IN_XOR_AND_FETCH_4:
6380    case BUILT_IN_XOR_AND_FETCH_8:
6381    case BUILT_IN_XOR_AND_FETCH_16:
6382      mode = get_builtin_sync_mode (fcode - BUILT_IN_XOR_AND_FETCH_1);
6383      target = expand_builtin_sync_operation (mode, arglist, XOR,
6384					      true, target, ignore);
6385      if (target)
6386	return target;
6387      break;
6388
6389    case BUILT_IN_NAND_AND_FETCH_1:
6390    case BUILT_IN_NAND_AND_FETCH_2:
6391    case BUILT_IN_NAND_AND_FETCH_4:
6392    case BUILT_IN_NAND_AND_FETCH_8:
6393    case BUILT_IN_NAND_AND_FETCH_16:
6394      mode = get_builtin_sync_mode (fcode - BUILT_IN_NAND_AND_FETCH_1);
6395      target = expand_builtin_sync_operation (mode, arglist, NOT,
6396					      true, target, ignore);
6397      if (target)
6398	return target;
6399      break;
6400
6401    case BUILT_IN_BOOL_COMPARE_AND_SWAP_1:
6402    case BUILT_IN_BOOL_COMPARE_AND_SWAP_2:
6403    case BUILT_IN_BOOL_COMPARE_AND_SWAP_4:
6404    case BUILT_IN_BOOL_COMPARE_AND_SWAP_8:
6405    case BUILT_IN_BOOL_COMPARE_AND_SWAP_16:
6406      if (mode == VOIDmode)
6407	mode = TYPE_MODE (boolean_type_node);
6408      if (!target || !register_operand (target, mode))
6409	target = gen_reg_rtx (mode);
6410
6411      mode = get_builtin_sync_mode (fcode - BUILT_IN_BOOL_COMPARE_AND_SWAP_1);
6412      target = expand_builtin_compare_and_swap (mode, arglist, true, target);
6413      if (target)
6414	return target;
6415      break;
6416
6417    case BUILT_IN_VAL_COMPARE_AND_SWAP_1:
6418    case BUILT_IN_VAL_COMPARE_AND_SWAP_2:
6419    case BUILT_IN_VAL_COMPARE_AND_SWAP_4:
6420    case BUILT_IN_VAL_COMPARE_AND_SWAP_8:
6421    case BUILT_IN_VAL_COMPARE_AND_SWAP_16:
6422      mode = get_builtin_sync_mode (fcode - BUILT_IN_VAL_COMPARE_AND_SWAP_1);
6423      target = expand_builtin_compare_and_swap (mode, arglist, false, target);
6424      if (target)
6425	return target;
6426      break;
6427
6428    case BUILT_IN_LOCK_TEST_AND_SET_1:
6429    case BUILT_IN_LOCK_TEST_AND_SET_2:
6430    case BUILT_IN_LOCK_TEST_AND_SET_4:
6431    case BUILT_IN_LOCK_TEST_AND_SET_8:
6432    case BUILT_IN_LOCK_TEST_AND_SET_16:
6433      mode = get_builtin_sync_mode (fcode - BUILT_IN_LOCK_TEST_AND_SET_1);
6434      target = expand_builtin_lock_test_and_set (mode, arglist, target);
6435      if (target)
6436	return target;
6437      break;
6438
6439    case BUILT_IN_LOCK_RELEASE_1:
6440    case BUILT_IN_LOCK_RELEASE_2:
6441    case BUILT_IN_LOCK_RELEASE_4:
6442    case BUILT_IN_LOCK_RELEASE_8:
6443    case BUILT_IN_LOCK_RELEASE_16:
6444      mode = get_builtin_sync_mode (fcode - BUILT_IN_LOCK_RELEASE_1);
6445      expand_builtin_lock_release (mode, arglist);
6446      return const0_rtx;
6447
6448    case BUILT_IN_SYNCHRONIZE:
6449      expand_builtin_synchronize ();
6450      return const0_rtx;
6451
6452    case BUILT_IN_OBJECT_SIZE:
6453      return expand_builtin_object_size (exp);
6454
6455    case BUILT_IN_MEMCPY_CHK:
6456    case BUILT_IN_MEMPCPY_CHK:
6457    case BUILT_IN_MEMMOVE_CHK:
6458    case BUILT_IN_MEMSET_CHK:
6459      target = expand_builtin_memory_chk (exp, target, mode, fcode);
6460      if (target)
6461	return target;
6462      break;
6463
6464    case BUILT_IN_STRCPY_CHK:
6465    case BUILT_IN_STPCPY_CHK:
6466    case BUILT_IN_STRNCPY_CHK:
6467    case BUILT_IN_STRCAT_CHK:
6468    case BUILT_IN_SNPRINTF_CHK:
6469    case BUILT_IN_VSNPRINTF_CHK:
6470      maybe_emit_chk_warning (exp, fcode);
6471      break;
6472
6473    case BUILT_IN_SPRINTF_CHK:
6474    case BUILT_IN_VSPRINTF_CHK:
6475      maybe_emit_sprintf_chk_warning (exp, fcode);
6476      break;
6477
6478    default:	/* just do library call, if unknown builtin */
6479      break;
6480    }
6481
6482  /* The switch statement above can drop through to cause the function
6483     to be called normally.  */
6484  return expand_call (exp, target, ignore);
6485}
6486
6487/* Determine whether a tree node represents a call to a built-in
6488   function.  If the tree T is a call to a built-in function with
6489   the right number of arguments of the appropriate types, return
6490   the DECL_FUNCTION_CODE of the call, e.g. BUILT_IN_SQRT.
6491   Otherwise the return value is END_BUILTINS.  */
6492
6493enum built_in_function
6494builtin_mathfn_code (tree t)
6495{
6496  tree fndecl, arglist, parmlist;
6497  tree argtype, parmtype;
6498
6499  if (TREE_CODE (t) != CALL_EXPR
6500      || TREE_CODE (TREE_OPERAND (t, 0)) != ADDR_EXPR)
6501    return END_BUILTINS;
6502
6503  fndecl = get_callee_fndecl (t);
6504  if (fndecl == NULL_TREE
6505      || TREE_CODE (fndecl) != FUNCTION_DECL
6506      || ! DECL_BUILT_IN (fndecl)
6507      || DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
6508    return END_BUILTINS;
6509
6510  arglist = TREE_OPERAND (t, 1);
6511  parmlist = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
6512  for (; parmlist; parmlist = TREE_CHAIN (parmlist))
6513    {
6514      /* If a function doesn't take a variable number of arguments,
6515	 the last element in the list will have type `void'.  */
6516      parmtype = TREE_VALUE (parmlist);
6517      if (VOID_TYPE_P (parmtype))
6518	{
6519	  if (arglist)
6520	    return END_BUILTINS;
6521	  return DECL_FUNCTION_CODE (fndecl);
6522	}
6523
6524      if (! arglist)
6525	return END_BUILTINS;
6526
6527      argtype = TREE_TYPE (TREE_VALUE (arglist));
6528
6529      if (SCALAR_FLOAT_TYPE_P (parmtype))
6530	{
6531	  if (! SCALAR_FLOAT_TYPE_P (argtype))
6532	    return END_BUILTINS;
6533	}
6534      else if (COMPLEX_FLOAT_TYPE_P (parmtype))
6535	{
6536	  if (! COMPLEX_FLOAT_TYPE_P (argtype))
6537	    return END_BUILTINS;
6538	}
6539      else if (POINTER_TYPE_P (parmtype))
6540	{
6541	  if (! POINTER_TYPE_P (argtype))
6542	    return END_BUILTINS;
6543	}
6544      else if (INTEGRAL_TYPE_P (parmtype))
6545	{
6546	  if (! INTEGRAL_TYPE_P (argtype))
6547	    return END_BUILTINS;
6548	}
6549      else
6550	return END_BUILTINS;
6551
6552      arglist = TREE_CHAIN (arglist);
6553    }
6554
6555  /* Variable-length argument list.  */
6556  return DECL_FUNCTION_CODE (fndecl);
6557}
6558
6559/* Fold a call to __builtin_constant_p, if we know it will evaluate to a
6560   constant.  ARGLIST is the argument list of the call.  */
6561
6562static tree
6563fold_builtin_constant_p (tree arglist)
6564{
6565  if (arglist == 0)
6566    return 0;
6567
6568  arglist = TREE_VALUE (arglist);
6569
6570  /* We return 1 for a numeric type that's known to be a constant
6571     value at compile-time or for an aggregate type that's a
6572     literal constant.  */
6573  STRIP_NOPS (arglist);
6574
6575  /* If we know this is a constant, emit the constant of one.  */
6576  if (CONSTANT_CLASS_P (arglist)
6577      || (TREE_CODE (arglist) == CONSTRUCTOR
6578	  && TREE_CONSTANT (arglist)))
6579    return integer_one_node;
6580  if (TREE_CODE (arglist) == ADDR_EXPR)
6581    {
6582       tree op = TREE_OPERAND (arglist, 0);
6583       if (TREE_CODE (op) == STRING_CST
6584	   || (TREE_CODE (op) == ARRAY_REF
6585	       && integer_zerop (TREE_OPERAND (op, 1))
6586	       && TREE_CODE (TREE_OPERAND (op, 0)) == STRING_CST))
6587	 return integer_one_node;
6588    }
6589
6590  /* If this expression has side effects, show we don't know it to be a
6591     constant.  Likewise if it's a pointer or aggregate type since in
6592     those case we only want literals, since those are only optimized
6593     when generating RTL, not later.
6594     And finally, if we are compiling an initializer, not code, we
6595     need to return a definite result now; there's not going to be any
6596     more optimization done.  */
6597  if (TREE_SIDE_EFFECTS (arglist)
6598      || AGGREGATE_TYPE_P (TREE_TYPE (arglist))
6599      || POINTER_TYPE_P (TREE_TYPE (arglist))
6600      || cfun == 0
6601      || folding_initializer)
6602    return integer_zero_node;
6603
6604  return 0;
6605}
6606
6607/* Fold a call to __builtin_expect, if we expect that a comparison against
6608   the argument will fold to a constant.  In practice, this means a true
6609   constant or the address of a non-weak symbol.  ARGLIST is the argument
6610   list of the call.  */
6611
6612static tree
6613fold_builtin_expect (tree arglist)
6614{
6615  tree arg, inner;
6616
6617  if (arglist == 0)
6618    return 0;
6619
6620  arg = TREE_VALUE (arglist);
6621
6622  /* If the argument isn't invariant, then there's nothing we can do.  */
6623  if (!TREE_INVARIANT (arg))
6624    return 0;
6625
6626  /* If we're looking at an address of a weak decl, then do not fold.  */
6627  inner = arg;
6628  STRIP_NOPS (inner);
6629  if (TREE_CODE (inner) == ADDR_EXPR)
6630    {
6631      do
6632	{
6633	  inner = TREE_OPERAND (inner, 0);
6634	}
6635      while (TREE_CODE (inner) == COMPONENT_REF
6636	     || TREE_CODE (inner) == ARRAY_REF);
6637      if (DECL_P (inner) && DECL_WEAK (inner))
6638	return 0;
6639    }
6640
6641  /* Otherwise, ARG already has the proper type for the return value.  */
6642  return arg;
6643}
6644
6645/* Fold a call to __builtin_classify_type.  */
6646
6647static tree
6648fold_builtin_classify_type (tree arglist)
6649{
6650  if (arglist == 0)
6651    return build_int_cst (NULL_TREE, no_type_class);
6652
6653  return build_int_cst (NULL_TREE,
6654			type_to_class (TREE_TYPE (TREE_VALUE (arglist))));
6655}
6656
6657/* Fold a call to __builtin_strlen.  */
6658
6659static tree
6660fold_builtin_strlen (tree arglist)
6661{
6662  if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6663    return NULL_TREE;
6664  else
6665    {
6666      tree len = c_strlen (TREE_VALUE (arglist), 0);
6667
6668      if (len)
6669	{
6670	  /* Convert from the internal "sizetype" type to "size_t".  */
6671	  if (size_type_node)
6672	    len = fold_convert (size_type_node, len);
6673	  return len;
6674	}
6675
6676      return NULL_TREE;
6677    }
6678}
6679
6680/* Fold a call to __builtin_inf or __builtin_huge_val.  */
6681
6682static tree
6683fold_builtin_inf (tree type, int warn)
6684{
6685  REAL_VALUE_TYPE real;
6686
6687  /* __builtin_inff is intended to be usable to define INFINITY on all
6688     targets.  If an infinity is not available, INFINITY expands "to a
6689     positive constant of type float that overflows at translation
6690     time", footnote "In this case, using INFINITY will violate the
6691     constraint in 6.4.4 and thus require a diagnostic." (C99 7.12#4).
6692     Thus we pedwarn to ensure this constraint violation is
6693     diagnosed.  */
6694  if (!MODE_HAS_INFINITIES (TYPE_MODE (type)) && warn)
6695    pedwarn ("target format does not support infinity");
6696
6697  real_inf (&real);
6698  return build_real (type, real);
6699}
6700
6701/* Fold a call to __builtin_nan or __builtin_nans.  */
6702
6703static tree
6704fold_builtin_nan (tree arglist, tree type, int quiet)
6705{
6706  REAL_VALUE_TYPE real;
6707  const char *str;
6708
6709  if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6710    return 0;
6711  str = c_getstr (TREE_VALUE (arglist));
6712  if (!str)
6713    return 0;
6714
6715  if (!real_nan (&real, str, quiet, TYPE_MODE (type)))
6716    return 0;
6717
6718  return build_real (type, real);
6719}
6720
6721/* Return true if the floating point expression T has an integer value.
6722   We also allow +Inf, -Inf and NaN to be considered integer values.  */
6723
6724static bool
6725integer_valued_real_p (tree t)
6726{
6727  switch (TREE_CODE (t))
6728    {
6729    case FLOAT_EXPR:
6730      return true;
6731
6732    case ABS_EXPR:
6733    case SAVE_EXPR:
6734    case NON_LVALUE_EXPR:
6735      return integer_valued_real_p (TREE_OPERAND (t, 0));
6736
6737    case COMPOUND_EXPR:
6738    case MODIFY_EXPR:
6739    case BIND_EXPR:
6740      return integer_valued_real_p (TREE_OPERAND (t, 1));
6741
6742    case PLUS_EXPR:
6743    case MINUS_EXPR:
6744    case MULT_EXPR:
6745    case MIN_EXPR:
6746    case MAX_EXPR:
6747      return integer_valued_real_p (TREE_OPERAND (t, 0))
6748	     && integer_valued_real_p (TREE_OPERAND (t, 1));
6749
6750    case COND_EXPR:
6751      return integer_valued_real_p (TREE_OPERAND (t, 1))
6752	     && integer_valued_real_p (TREE_OPERAND (t, 2));
6753
6754    case REAL_CST:
6755      if (! TREE_CONSTANT_OVERFLOW (t))
6756      {
6757	REAL_VALUE_TYPE c, cint;
6758
6759	c = TREE_REAL_CST (t);
6760	real_trunc (&cint, TYPE_MODE (TREE_TYPE (t)), &c);
6761	return real_identical (&c, &cint);
6762      }
6763      break;
6764
6765    case NOP_EXPR:
6766      {
6767	tree type = TREE_TYPE (TREE_OPERAND (t, 0));
6768	if (TREE_CODE (type) == INTEGER_TYPE)
6769	  return true;
6770	if (TREE_CODE (type) == REAL_TYPE)
6771	  return integer_valued_real_p (TREE_OPERAND (t, 0));
6772	break;
6773      }
6774
6775    case CALL_EXPR:
6776      switch (builtin_mathfn_code (t))
6777	{
6778	CASE_FLT_FN (BUILT_IN_CEIL):
6779	CASE_FLT_FN (BUILT_IN_FLOOR):
6780	CASE_FLT_FN (BUILT_IN_NEARBYINT):
6781	CASE_FLT_FN (BUILT_IN_RINT):
6782	CASE_FLT_FN (BUILT_IN_ROUND):
6783	CASE_FLT_FN (BUILT_IN_TRUNC):
6784	  return true;
6785
6786	default:
6787	  break;
6788	}
6789      break;
6790
6791    default:
6792      break;
6793    }
6794  return false;
6795}
6796
6797/* EXP is assumed to be builtin call where truncation can be propagated
6798   across (for instance floor((double)f) == (double)floorf (f).
6799   Do the transformation.  */
6800
6801static tree
6802fold_trunc_transparent_mathfn (tree fndecl, tree arglist)
6803{
6804  enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
6805  tree arg;
6806
6807  if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6808    return 0;
6809
6810  arg = TREE_VALUE (arglist);
6811  /* Integer rounding functions are idempotent.  */
6812  if (fcode == builtin_mathfn_code (arg))
6813    return arg;
6814
6815  /* If argument is already integer valued, and we don't need to worry
6816     about setting errno, there's no need to perform rounding.  */
6817  if (! flag_errno_math && integer_valued_real_p (arg))
6818    return arg;
6819
6820  if (optimize)
6821    {
6822      tree arg0 = strip_float_extensions (arg);
6823      tree ftype = TREE_TYPE (TREE_TYPE (fndecl));
6824      tree newtype = TREE_TYPE (arg0);
6825      tree decl;
6826
6827      if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
6828	  && (decl = mathfn_built_in (newtype, fcode)))
6829	{
6830	  arglist =
6831	    build_tree_list (NULL_TREE, fold_convert (newtype, arg0));
6832	  return fold_convert (ftype,
6833			       build_function_call_expr (decl, arglist));
6834	}
6835    }
6836  return 0;
6837}
6838
6839/* EXP is assumed to be builtin call which can narrow the FP type of
6840   the argument, for instance lround((double)f) -> lroundf (f).  */
6841
6842static tree
6843fold_fixed_mathfn (tree fndecl, tree arglist)
6844{
6845  enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
6846  tree arg;
6847
6848  if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6849    return 0;
6850
6851  arg = TREE_VALUE (arglist);
6852
6853  /* If argument is already integer valued, and we don't need to worry
6854     about setting errno, there's no need to perform rounding.  */
6855  if (! flag_errno_math && integer_valued_real_p (arg))
6856    return fold_build1 (FIX_TRUNC_EXPR, TREE_TYPE (TREE_TYPE (fndecl)), arg);
6857
6858  if (optimize)
6859    {
6860      tree ftype = TREE_TYPE (arg);
6861      tree arg0 = strip_float_extensions (arg);
6862      tree newtype = TREE_TYPE (arg0);
6863      tree decl;
6864
6865      if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
6866	  && (decl = mathfn_built_in (newtype, fcode)))
6867	{
6868	  arglist =
6869	    build_tree_list (NULL_TREE, fold_convert (newtype, arg0));
6870	  return build_function_call_expr (decl, arglist);
6871	}
6872    }
6873
6874  /* Canonicalize llround (x) to lround (x) on LP64 targets where
6875     sizeof (long long) == sizeof (long).  */
6876  if (TYPE_PRECISION (long_long_integer_type_node)
6877      == TYPE_PRECISION (long_integer_type_node))
6878    {
6879      tree newfn = NULL_TREE;
6880      switch (fcode)
6881	{
6882	CASE_FLT_FN (BUILT_IN_LLCEIL):
6883	  newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LCEIL);
6884	  break;
6885
6886	CASE_FLT_FN (BUILT_IN_LLFLOOR):
6887	  newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LFLOOR);
6888	  break;
6889
6890	CASE_FLT_FN (BUILT_IN_LLROUND):
6891	  newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LROUND);
6892	  break;
6893
6894	CASE_FLT_FN (BUILT_IN_LLRINT):
6895	  newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LRINT);
6896	  break;
6897
6898	default:
6899	  break;
6900	}
6901
6902      if (newfn)
6903	{
6904	  tree newcall = build_function_call_expr (newfn, arglist);
6905	  return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), newcall);
6906	}
6907    }
6908
6909  return 0;
6910}
6911
6912/* Fold function call to builtin cabs, cabsf or cabsl.  ARGLIST
6913   is the argument list, TYPE is the return type and FNDECL is the
6914   original function DECL.  Return NULL_TREE if no if no simplification
6915   can be made.  */
6916
6917static tree
6918fold_builtin_cabs (tree arglist, tree type, tree fndecl)
6919{
6920  tree arg;
6921
6922  if (!arglist || TREE_CHAIN (arglist))
6923    return NULL_TREE;
6924
6925  arg = TREE_VALUE (arglist);
6926  if (TREE_CODE (TREE_TYPE (arg)) != COMPLEX_TYPE
6927      || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) != REAL_TYPE)
6928    return NULL_TREE;
6929
6930  /* Evaluate cabs of a constant at compile-time.  */
6931  if (flag_unsafe_math_optimizations
6932      && TREE_CODE (arg) == COMPLEX_CST
6933      && TREE_CODE (TREE_REALPART (arg)) == REAL_CST
6934      && TREE_CODE (TREE_IMAGPART (arg)) == REAL_CST
6935      && ! TREE_CONSTANT_OVERFLOW (TREE_REALPART (arg))
6936      && ! TREE_CONSTANT_OVERFLOW (TREE_IMAGPART (arg)))
6937    {
6938      REAL_VALUE_TYPE r, i;
6939
6940      r = TREE_REAL_CST (TREE_REALPART (arg));
6941      i = TREE_REAL_CST (TREE_IMAGPART (arg));
6942
6943      real_arithmetic (&r, MULT_EXPR, &r, &r);
6944      real_arithmetic (&i, MULT_EXPR, &i, &i);
6945      real_arithmetic (&r, PLUS_EXPR, &r, &i);
6946      if (real_sqrt (&r, TYPE_MODE (type), &r)
6947	  || ! flag_trapping_math)
6948	return build_real (type, r);
6949    }
6950
6951  /* If either part is zero, cabs is fabs of the other.  */
6952  if (TREE_CODE (arg) == COMPLEX_EXPR
6953      && real_zerop (TREE_OPERAND (arg, 0)))
6954    return fold_build1 (ABS_EXPR, type, TREE_OPERAND (arg, 1));
6955  if (TREE_CODE (arg) == COMPLEX_EXPR
6956      && real_zerop (TREE_OPERAND (arg, 1)))
6957    return fold_build1 (ABS_EXPR, type, TREE_OPERAND (arg, 0));
6958
6959  /* Optimize cabs(-z) and cabs(conj(z)) as cabs(z).  */
6960  if (TREE_CODE (arg) == NEGATE_EXPR
6961      || TREE_CODE (arg) == CONJ_EXPR)
6962    {
6963      tree arglist = build_tree_list (NULL_TREE, TREE_OPERAND (arg, 0));
6964      return build_function_call_expr (fndecl, arglist);
6965    }
6966
6967  /* Don't do this when optimizing for size.  */
6968  if (flag_unsafe_math_optimizations
6969      && optimize && !optimize_size)
6970    {
6971      tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
6972
6973      if (sqrtfn != NULL_TREE)
6974	{
6975	  tree rpart, ipart, result, arglist;
6976
6977	  arg = builtin_save_expr (arg);
6978
6979	  rpart = fold_build1 (REALPART_EXPR, type, arg);
6980	  ipart = fold_build1 (IMAGPART_EXPR, type, arg);
6981
6982	  rpart = builtin_save_expr (rpart);
6983	  ipart = builtin_save_expr (ipart);
6984
6985	  result = fold_build2 (PLUS_EXPR, type,
6986				fold_build2 (MULT_EXPR, type,
6987					     rpart, rpart),
6988				fold_build2 (MULT_EXPR, type,
6989					     ipart, ipart));
6990
6991	  arglist = build_tree_list (NULL_TREE, result);
6992	  return build_function_call_expr (sqrtfn, arglist);
6993	}
6994    }
6995
6996  return NULL_TREE;
6997}
6998
6999/* Fold a builtin function call to sqrt, sqrtf, or sqrtl.  Return
7000   NULL_TREE if no simplification can be made.  */
7001
7002static tree
7003fold_builtin_sqrt (tree arglist, tree type)
7004{
7005
7006  enum built_in_function fcode;
7007  tree arg = TREE_VALUE (arglist);
7008
7009  if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7010    return NULL_TREE;
7011
7012  /* Optimize sqrt of constant value.  */
7013  if (TREE_CODE (arg) == REAL_CST
7014      && ! TREE_CONSTANT_OVERFLOW (arg))
7015    {
7016      REAL_VALUE_TYPE r, x;
7017
7018      x = TREE_REAL_CST (arg);
7019      if (real_sqrt (&r, TYPE_MODE (type), &x)
7020	  || (!flag_trapping_math && !flag_errno_math))
7021	return build_real (type, r);
7022    }
7023
7024  /* Optimize sqrt(expN(x)) = expN(x*0.5).  */
7025  fcode = builtin_mathfn_code (arg);
7026  if (flag_unsafe_math_optimizations && BUILTIN_EXPONENT_P (fcode))
7027    {
7028      tree expfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
7029      arg = fold_build2 (MULT_EXPR, type,
7030			 TREE_VALUE (TREE_OPERAND (arg, 1)),
7031			 build_real (type, dconsthalf));
7032      arglist = build_tree_list (NULL_TREE, arg);
7033      return build_function_call_expr (expfn, arglist);
7034    }
7035
7036  /* Optimize sqrt(Nroot(x)) -> pow(x,1/(2*N)).  */
7037  if (flag_unsafe_math_optimizations && BUILTIN_ROOT_P (fcode))
7038    {
7039      tree powfn = mathfn_built_in (type, BUILT_IN_POW);
7040
7041      if (powfn)
7042	{
7043	  tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
7044	  tree tree_root;
7045	  /* The inner root was either sqrt or cbrt.  */
7046	  REAL_VALUE_TYPE dconstroot =
7047	    BUILTIN_SQRT_P (fcode) ? dconsthalf : dconstthird;
7048
7049	  /* Adjust for the outer root.  */
7050	  SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
7051	  dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
7052	  tree_root = build_real (type, dconstroot);
7053	  arglist = tree_cons (NULL_TREE, arg0,
7054			       build_tree_list (NULL_TREE, tree_root));
7055	  return build_function_call_expr (powfn, arglist);
7056	}
7057    }
7058
7059  /* Optimize sqrt(pow(x,y)) = pow(|x|,y*0.5).  */
7060  if (flag_unsafe_math_optimizations
7061      && (fcode == BUILT_IN_POW
7062	  || fcode == BUILT_IN_POWF
7063	  || fcode == BUILT_IN_POWL))
7064    {
7065      tree powfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
7066      tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
7067      tree arg1 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
7068      tree narg1;
7069      if (!tree_expr_nonnegative_p (arg0))
7070	arg0 = build1 (ABS_EXPR, type, arg0);
7071      narg1 = fold_build2 (MULT_EXPR, type, arg1,
7072			   build_real (type, dconsthalf));
7073      arglist = tree_cons (NULL_TREE, arg0,
7074			   build_tree_list (NULL_TREE, narg1));
7075      return build_function_call_expr (powfn, arglist);
7076    }
7077
7078  return NULL_TREE;
7079}
7080
7081/* Fold a builtin function call to cbrt, cbrtf, or cbrtl.  Return
7082   NULL_TREE if no simplification can be made.  */
7083static tree
7084fold_builtin_cbrt (tree arglist, tree type)
7085{
7086  tree arg = TREE_VALUE (arglist);
7087  const enum built_in_function fcode = builtin_mathfn_code (arg);
7088
7089  if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7090    return NULL_TREE;
7091
7092  /* Optimize cbrt of constant value.  */
7093  if (real_zerop (arg) || real_onep (arg) || real_minus_onep (arg))
7094    return arg;
7095
7096  if (flag_unsafe_math_optimizations)
7097    {
7098      /* Optimize cbrt(expN(x)) -> expN(x/3).  */
7099      if (BUILTIN_EXPONENT_P (fcode))
7100	{
7101	  tree expfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
7102	  const REAL_VALUE_TYPE third_trunc =
7103	    real_value_truncate (TYPE_MODE (type), dconstthird);
7104	  arg = fold_build2 (MULT_EXPR, type,
7105			     TREE_VALUE (TREE_OPERAND (arg, 1)),
7106			     build_real (type, third_trunc));
7107	  arglist = build_tree_list (NULL_TREE, arg);
7108	  return build_function_call_expr (expfn, arglist);
7109	}
7110
7111      /* Optimize cbrt(sqrt(x)) -> pow(x,1/6).  */
7112      if (BUILTIN_SQRT_P (fcode))
7113	{
7114	  tree powfn = mathfn_built_in (type, BUILT_IN_POW);
7115
7116	  if (powfn)
7117	    {
7118	      tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
7119	      tree tree_root;
7120	      REAL_VALUE_TYPE dconstroot = dconstthird;
7121
7122	      SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
7123	      dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
7124	      tree_root = build_real (type, dconstroot);
7125	      arglist = tree_cons (NULL_TREE, arg0,
7126				   build_tree_list (NULL_TREE, tree_root));
7127	      return build_function_call_expr (powfn, arglist);
7128	    }
7129	}
7130
7131      /* Optimize cbrt(cbrt(x)) -> pow(x,1/9) iff x is nonnegative.  */
7132      if (BUILTIN_CBRT_P (fcode))
7133	{
7134	  tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
7135	  if (tree_expr_nonnegative_p (arg0))
7136	    {
7137	      tree powfn = mathfn_built_in (type, BUILT_IN_POW);
7138
7139	      if (powfn)
7140		{
7141		  tree tree_root;
7142		  REAL_VALUE_TYPE dconstroot;
7143
7144		  real_arithmetic (&dconstroot, MULT_EXPR, &dconstthird, &dconstthird);
7145		  dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
7146		  tree_root = build_real (type, dconstroot);
7147		  arglist = tree_cons (NULL_TREE, arg0,
7148				       build_tree_list (NULL_TREE, tree_root));
7149		  return build_function_call_expr (powfn, arglist);
7150		}
7151	    }
7152	}
7153
7154      /* Optimize cbrt(pow(x,y)) -> pow(x,y/3) iff x is nonnegative.  */
7155      if (fcode == BUILT_IN_POW || fcode == BUILT_IN_POWF
7156	  || fcode == BUILT_IN_POWL)
7157	{
7158	  tree arg00 = TREE_VALUE (TREE_OPERAND (arg, 1));
7159	  tree arg01 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
7160	  if (tree_expr_nonnegative_p (arg00))
7161	    {
7162	      tree powfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
7163	      const REAL_VALUE_TYPE dconstroot
7164		= real_value_truncate (TYPE_MODE (type), dconstthird);
7165	      tree narg01 = fold_build2 (MULT_EXPR, type, arg01,
7166					 build_real (type, dconstroot));
7167	      arglist = tree_cons (NULL_TREE, arg00,
7168				   build_tree_list (NULL_TREE, narg01));
7169	      return build_function_call_expr (powfn, arglist);
7170	    }
7171	}
7172    }
7173  return NULL_TREE;
7174}
7175
7176/* Fold function call to builtin sin, sinf, or sinl.  Return
7177   NULL_TREE if no simplification can be made.  */
7178static tree
7179fold_builtin_sin (tree arglist)
7180{
7181  tree arg = TREE_VALUE (arglist);
7182
7183  if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7184    return NULL_TREE;
7185
7186  /* Optimize sin (0.0) = 0.0.  */
7187  if (real_zerop (arg))
7188    return arg;
7189
7190  return NULL_TREE;
7191}
7192
7193/* Fold function call to builtin cos, cosf, or cosl.  Return
7194   NULL_TREE if no simplification can be made.  */
7195static tree
7196fold_builtin_cos (tree arglist, tree type, tree fndecl)
7197{
7198  tree arg = TREE_VALUE (arglist);
7199
7200  if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7201    return NULL_TREE;
7202
7203  /* Optimize cos (0.0) = 1.0.  */
7204  if (real_zerop (arg))
7205    return build_real (type, dconst1);
7206
7207  /* Optimize cos(-x) into cos (x).  */
7208  if (TREE_CODE (arg) == NEGATE_EXPR)
7209    {
7210      tree args = build_tree_list (NULL_TREE,
7211				   TREE_OPERAND (arg, 0));
7212      return build_function_call_expr (fndecl, args);
7213    }
7214
7215  return NULL_TREE;
7216}
7217
7218/* Fold function call to builtin tan, tanf, or tanl.  Return
7219   NULL_TREE if no simplification can be made.  */
7220static tree
7221fold_builtin_tan (tree arglist)
7222{
7223  enum built_in_function fcode;
7224  tree arg = TREE_VALUE (arglist);
7225
7226  if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7227    return NULL_TREE;
7228
7229  /* Optimize tan(0.0) = 0.0.  */
7230  if (real_zerop (arg))
7231    return arg;
7232
7233  /* Optimize tan(atan(x)) = x.  */
7234  fcode = builtin_mathfn_code (arg);
7235  if (flag_unsafe_math_optimizations
7236      && (fcode == BUILT_IN_ATAN
7237	  || fcode == BUILT_IN_ATANF
7238	  || fcode == BUILT_IN_ATANL))
7239    return TREE_VALUE (TREE_OPERAND (arg, 1));
7240
7241  return NULL_TREE;
7242}
7243
7244/* Fold function call to builtin atan, atanf, or atanl.  Return
7245   NULL_TREE if no simplification can be made.  */
7246
7247static tree
7248fold_builtin_atan (tree arglist, tree type)
7249{
7250
7251  tree arg = TREE_VALUE (arglist);
7252
7253  if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7254    return NULL_TREE;
7255
7256  /* Optimize atan(0.0) = 0.0.  */
7257  if (real_zerop (arg))
7258    return arg;
7259
7260  /* Optimize atan(1.0) = pi/4.  */
7261  if (real_onep (arg))
7262    {
7263      REAL_VALUE_TYPE cst;
7264
7265      real_convert (&cst, TYPE_MODE (type), &dconstpi);
7266      SET_REAL_EXP (&cst, REAL_EXP (&cst) - 2);
7267      return build_real (type, cst);
7268    }
7269
7270  return NULL_TREE;
7271}
7272
7273/* Fold function call to builtin trunc, truncf or truncl.  Return
7274   NULL_TREE if no simplification can be made.  */
7275
7276static tree
7277fold_builtin_trunc (tree fndecl, tree arglist)
7278{
7279  tree arg;
7280
7281  if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7282    return 0;
7283
7284  /* Optimize trunc of constant value.  */
7285  arg = TREE_VALUE (arglist);
7286  if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7287    {
7288      REAL_VALUE_TYPE r, x;
7289      tree type = TREE_TYPE (TREE_TYPE (fndecl));
7290
7291      x = TREE_REAL_CST (arg);
7292      real_trunc (&r, TYPE_MODE (type), &x);
7293      return build_real (type, r);
7294    }
7295
7296  return fold_trunc_transparent_mathfn (fndecl, arglist);
7297}
7298
7299/* Fold function call to builtin floor, floorf or floorl.  Return
7300   NULL_TREE if no simplification can be made.  */
7301
7302static tree
7303fold_builtin_floor (tree fndecl, tree arglist)
7304{
7305  tree arg;
7306
7307  if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7308    return 0;
7309
7310  /* Optimize floor of constant value.  */
7311  arg = TREE_VALUE (arglist);
7312  if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7313    {
7314      REAL_VALUE_TYPE x;
7315
7316      x = TREE_REAL_CST (arg);
7317      if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7318	{
7319	  tree type = TREE_TYPE (TREE_TYPE (fndecl));
7320	  REAL_VALUE_TYPE r;
7321
7322	  real_floor (&r, TYPE_MODE (type), &x);
7323	  return build_real (type, r);
7324	}
7325    }
7326
7327  return fold_trunc_transparent_mathfn (fndecl, arglist);
7328}
7329
7330/* Fold function call to builtin ceil, ceilf or ceill.  Return
7331   NULL_TREE if no simplification can be made.  */
7332
7333static tree
7334fold_builtin_ceil (tree fndecl, tree arglist)
7335{
7336  tree arg;
7337
7338  if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7339    return 0;
7340
7341  /* Optimize ceil of constant value.  */
7342  arg = TREE_VALUE (arglist);
7343  if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7344    {
7345      REAL_VALUE_TYPE x;
7346
7347      x = TREE_REAL_CST (arg);
7348      if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7349	{
7350	  tree type = TREE_TYPE (TREE_TYPE (fndecl));
7351	  REAL_VALUE_TYPE r;
7352
7353	  real_ceil (&r, TYPE_MODE (type), &x);
7354	  return build_real (type, r);
7355	}
7356    }
7357
7358  return fold_trunc_transparent_mathfn (fndecl, arglist);
7359}
7360
7361/* Fold function call to builtin round, roundf or roundl.  Return
7362   NULL_TREE if no simplification can be made.  */
7363
7364static tree
7365fold_builtin_round (tree fndecl, tree arglist)
7366{
7367  tree arg;
7368
7369  if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7370    return 0;
7371
7372  /* Optimize round of constant value.  */
7373  arg = TREE_VALUE (arglist);
7374  if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7375    {
7376      REAL_VALUE_TYPE x;
7377
7378      x = TREE_REAL_CST (arg);
7379      if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7380	{
7381	  tree type = TREE_TYPE (TREE_TYPE (fndecl));
7382	  REAL_VALUE_TYPE r;
7383
7384	  real_round (&r, TYPE_MODE (type), &x);
7385	  return build_real (type, r);
7386	}
7387    }
7388
7389  return fold_trunc_transparent_mathfn (fndecl, arglist);
7390}
7391
7392/* Fold function call to builtin lround, lroundf or lroundl (or the
7393   corresponding long long versions) and other rounding functions.
7394   Return NULL_TREE if no simplification can be made.  */
7395
7396static tree
7397fold_builtin_int_roundingfn (tree fndecl, tree arglist)
7398{
7399  tree arg;
7400
7401  if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7402    return 0;
7403
7404  /* Optimize lround of constant value.  */
7405  arg = TREE_VALUE (arglist);
7406  if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7407    {
7408      const REAL_VALUE_TYPE x = TREE_REAL_CST (arg);
7409
7410      if (! REAL_VALUE_ISNAN (x) && ! REAL_VALUE_ISINF (x))
7411	{
7412	  tree itype = TREE_TYPE (TREE_TYPE (fndecl));
7413	  tree ftype = TREE_TYPE (arg), result;
7414	  HOST_WIDE_INT hi, lo;
7415	  REAL_VALUE_TYPE r;
7416
7417	  switch (DECL_FUNCTION_CODE (fndecl))
7418	    {
7419	    CASE_FLT_FN (BUILT_IN_LFLOOR):
7420	    CASE_FLT_FN (BUILT_IN_LLFLOOR):
7421	      real_floor (&r, TYPE_MODE (ftype), &x);
7422	      break;
7423
7424	    CASE_FLT_FN (BUILT_IN_LCEIL):
7425	    CASE_FLT_FN (BUILT_IN_LLCEIL):
7426	      real_ceil (&r, TYPE_MODE (ftype), &x);
7427	      break;
7428
7429	    CASE_FLT_FN (BUILT_IN_LROUND):
7430	    CASE_FLT_FN (BUILT_IN_LLROUND):
7431	      real_round (&r, TYPE_MODE (ftype), &x);
7432	      break;
7433
7434	    default:
7435	      gcc_unreachable ();
7436	    }
7437
7438	  REAL_VALUE_TO_INT (&lo, &hi, r);
7439	  result = build_int_cst_wide (NULL_TREE, lo, hi);
7440	  if (int_fits_type_p (result, itype))
7441	    return fold_convert (itype, result);
7442	}
7443    }
7444
7445  return fold_fixed_mathfn (fndecl, arglist);
7446}
7447
7448/* Fold function call to builtin ffs, clz, ctz, popcount and parity
7449   and their long and long long variants (i.e. ffsl and ffsll).
7450   Return NULL_TREE if no simplification can be made.  */
7451
7452static tree
7453fold_builtin_bitop (tree fndecl, tree arglist)
7454{
7455  tree arg;
7456
7457  if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
7458    return NULL_TREE;
7459
7460  /* Optimize for constant argument.  */
7461  arg = TREE_VALUE (arglist);
7462  if (TREE_CODE (arg) == INTEGER_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7463    {
7464      HOST_WIDE_INT hi, width, result;
7465      unsigned HOST_WIDE_INT lo;
7466      tree type;
7467
7468      type = TREE_TYPE (arg);
7469      width = TYPE_PRECISION (type);
7470      lo = TREE_INT_CST_LOW (arg);
7471
7472      /* Clear all the bits that are beyond the type's precision.  */
7473      if (width > HOST_BITS_PER_WIDE_INT)
7474	{
7475	  hi = TREE_INT_CST_HIGH (arg);
7476	  if (width < 2 * HOST_BITS_PER_WIDE_INT)
7477	    hi &= ~((HOST_WIDE_INT) (-1) >> (width - HOST_BITS_PER_WIDE_INT));
7478	}
7479      else
7480	{
7481	  hi = 0;
7482	  if (width < HOST_BITS_PER_WIDE_INT)
7483	    lo &= ~((unsigned HOST_WIDE_INT) (-1) << width);
7484	}
7485
7486      switch (DECL_FUNCTION_CODE (fndecl))
7487	{
7488	CASE_INT_FN (BUILT_IN_FFS):
7489	  if (lo != 0)
7490	    result = exact_log2 (lo & -lo) + 1;
7491	  else if (hi != 0)
7492	    result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi) + 1;
7493	  else
7494	    result = 0;
7495	  break;
7496
7497	CASE_INT_FN (BUILT_IN_CLZ):
7498	  if (hi != 0)
7499	    result = width - floor_log2 (hi) - 1 - HOST_BITS_PER_WIDE_INT;
7500	  else if (lo != 0)
7501	    result = width - floor_log2 (lo) - 1;
7502	  else if (! CLZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
7503	    result = width;
7504	  break;
7505
7506	CASE_INT_FN (BUILT_IN_CTZ):
7507	  if (lo != 0)
7508	    result = exact_log2 (lo & -lo);
7509	  else if (hi != 0)
7510	    result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi);
7511	  else if (! CTZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
7512	    result = width;
7513	  break;
7514
7515	CASE_INT_FN (BUILT_IN_POPCOUNT):
7516	  result = 0;
7517	  while (lo)
7518	    result++, lo &= lo - 1;
7519	  while (hi)
7520	    result++, hi &= hi - 1;
7521	  break;
7522
7523	CASE_INT_FN (BUILT_IN_PARITY):
7524	  result = 0;
7525	  while (lo)
7526	    result++, lo &= lo - 1;
7527	  while (hi)
7528	    result++, hi &= hi - 1;
7529	  result &= 1;
7530	  break;
7531
7532	default:
7533	  gcc_unreachable ();
7534	}
7535
7536      return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), result);
7537    }
7538
7539  return NULL_TREE;
7540}
7541
7542/* Return true if EXPR is the real constant contained in VALUE.  */
7543
7544static bool
7545real_dconstp (tree expr, const REAL_VALUE_TYPE *value)
7546{
7547  STRIP_NOPS (expr);
7548
7549  return ((TREE_CODE (expr) == REAL_CST
7550	   && ! TREE_CONSTANT_OVERFLOW (expr)
7551	   && REAL_VALUES_EQUAL (TREE_REAL_CST (expr), *value))
7552	  || (TREE_CODE (expr) == COMPLEX_CST
7553	      && real_dconstp (TREE_REALPART (expr), value)
7554	      && real_zerop (TREE_IMAGPART (expr))));
7555}
7556
7557/* A subroutine of fold_builtin to fold the various logarithmic
7558   functions.  EXP is the CALL_EXPR of a call to a builtin logN
7559   function.  VALUE is the base of the logN function.  */
7560
7561static tree
7562fold_builtin_logarithm (tree fndecl, tree arglist,
7563			const REAL_VALUE_TYPE *value)
7564{
7565  if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7566    {
7567      tree type = TREE_TYPE (TREE_TYPE (fndecl));
7568      tree arg = TREE_VALUE (arglist);
7569      const enum built_in_function fcode = builtin_mathfn_code (arg);
7570
7571      /* Optimize logN(1.0) = 0.0.  */
7572      if (real_onep (arg))
7573	return build_real (type, dconst0);
7574
7575      /* Optimize logN(N) = 1.0.  If N can't be truncated to MODE
7576	 exactly, then only do this if flag_unsafe_math_optimizations.  */
7577      if (exact_real_truncate (TYPE_MODE (type), value)
7578	  || flag_unsafe_math_optimizations)
7579	{
7580	  const REAL_VALUE_TYPE value_truncate =
7581	    real_value_truncate (TYPE_MODE (type), *value);
7582	  if (real_dconstp (arg, &value_truncate))
7583	    return build_real (type, dconst1);
7584	}
7585
7586      /* Special case, optimize logN(expN(x)) = x.  */
7587      if (flag_unsafe_math_optimizations
7588	  && ((value == &dconste
7589	       && (fcode == BUILT_IN_EXP
7590		   || fcode == BUILT_IN_EXPF
7591		   || fcode == BUILT_IN_EXPL))
7592	      || (value == &dconst2
7593		  && (fcode == BUILT_IN_EXP2
7594		      || fcode == BUILT_IN_EXP2F
7595		      || fcode == BUILT_IN_EXP2L))
7596	      || (value == &dconst10 && (BUILTIN_EXP10_P (fcode)))))
7597	return fold_convert (type, TREE_VALUE (TREE_OPERAND (arg, 1)));
7598
7599      /* Optimize logN(func()) for various exponential functions.  We
7600	 want to determine the value "x" and the power "exponent" in
7601	 order to transform logN(x**exponent) into exponent*logN(x).  */
7602      if (flag_unsafe_math_optimizations)
7603	{
7604	  tree exponent = 0, x = 0;
7605
7606	  switch (fcode)
7607	  {
7608	  CASE_FLT_FN (BUILT_IN_EXP):
7609	    /* Prepare to do logN(exp(exponent) -> exponent*logN(e).  */
7610	    x = build_real (type,
7611			    real_value_truncate (TYPE_MODE (type), dconste));
7612	    exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
7613	    break;
7614	  CASE_FLT_FN (BUILT_IN_EXP2):
7615	    /* Prepare to do logN(exp2(exponent) -> exponent*logN(2).  */
7616	    x = build_real (type, dconst2);
7617	    exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
7618	    break;
7619	  CASE_FLT_FN (BUILT_IN_EXP10):
7620	  CASE_FLT_FN (BUILT_IN_POW10):
7621	    /* Prepare to do logN(exp10(exponent) -> exponent*logN(10).  */
7622	    x = build_real (type, dconst10);
7623	    exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
7624	    break;
7625	  CASE_FLT_FN (BUILT_IN_SQRT):
7626	    /* Prepare to do logN(sqrt(x) -> 0.5*logN(x).  */
7627	    x = TREE_VALUE (TREE_OPERAND (arg, 1));
7628	    exponent = build_real (type, dconsthalf);
7629	    break;
7630	  CASE_FLT_FN (BUILT_IN_CBRT):
7631	    /* Prepare to do logN(cbrt(x) -> (1/3)*logN(x).  */
7632	    x = TREE_VALUE (TREE_OPERAND (arg, 1));
7633	    exponent = build_real (type, real_value_truncate (TYPE_MODE (type),
7634							      dconstthird));
7635	    break;
7636	  CASE_FLT_FN (BUILT_IN_POW):
7637	    /* Prepare to do logN(pow(x,exponent) -> exponent*logN(x).  */
7638	    x = TREE_VALUE (TREE_OPERAND (arg, 1));
7639	    exponent = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
7640	    break;
7641	  default:
7642	    break;
7643	  }
7644
7645	  /* Now perform the optimization.  */
7646	  if (x && exponent)
7647	    {
7648	      tree logfn;
7649	      arglist = build_tree_list (NULL_TREE, x);
7650	      logfn = build_function_call_expr (fndecl, arglist);
7651	      return fold_build2 (MULT_EXPR, type, exponent, logfn);
7652	    }
7653	}
7654    }
7655
7656  return 0;
7657}
7658
7659/* Fold a builtin function call to pow, powf, or powl.  Return
7660   NULL_TREE if no simplification can be made.  */
7661static tree
7662fold_builtin_pow (tree fndecl, tree arglist, tree type)
7663{
7664  tree arg0 = TREE_VALUE (arglist);
7665  tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7666
7667  if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
7668    return NULL_TREE;
7669
7670  /* Optimize pow(1.0,y) = 1.0.  */
7671  if (real_onep (arg0))
7672    return omit_one_operand (type, build_real (type, dconst1), arg1);
7673
7674  if (TREE_CODE (arg1) == REAL_CST
7675      && ! TREE_CONSTANT_OVERFLOW (arg1))
7676    {
7677      REAL_VALUE_TYPE cint;
7678      REAL_VALUE_TYPE c;
7679      HOST_WIDE_INT n;
7680
7681      c = TREE_REAL_CST (arg1);
7682
7683      /* Optimize pow(x,0.0) = 1.0.  */
7684      if (REAL_VALUES_EQUAL (c, dconst0))
7685	return omit_one_operand (type, build_real (type, dconst1),
7686				 arg0);
7687
7688      /* Optimize pow(x,1.0) = x.  */
7689      if (REAL_VALUES_EQUAL (c, dconst1))
7690	return arg0;
7691
7692      /* Optimize pow(x,-1.0) = 1.0/x.  */
7693      if (REAL_VALUES_EQUAL (c, dconstm1))
7694	return fold_build2 (RDIV_EXPR, type,
7695			    build_real (type, dconst1), arg0);
7696
7697      /* Optimize pow(x,0.5) = sqrt(x).  */
7698      if (flag_unsafe_math_optimizations
7699	  && REAL_VALUES_EQUAL (c, dconsthalf))
7700	{
7701	  tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
7702
7703	  if (sqrtfn != NULL_TREE)
7704	    {
7705	      tree arglist = build_tree_list (NULL_TREE, arg0);
7706	      return build_function_call_expr (sqrtfn, arglist);
7707	    }
7708	}
7709
7710      /* Check for an integer exponent.  */
7711      n = real_to_integer (&c);
7712      real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
7713      if (real_identical (&c, &cint))
7714	{
7715	  /* Attempt to evaluate pow at compile-time.  */
7716	  if (TREE_CODE (arg0) == REAL_CST
7717	      && ! TREE_CONSTANT_OVERFLOW (arg0))
7718	    {
7719	      REAL_VALUE_TYPE x;
7720	      bool inexact;
7721
7722	      x = TREE_REAL_CST (arg0);
7723	      inexact = real_powi (&x, TYPE_MODE (type), &x, n);
7724	      if (flag_unsafe_math_optimizations || !inexact)
7725		return build_real (type, x);
7726	    }
7727
7728	  /* Strip sign ops from even integer powers.  */
7729	  if ((n & 1) == 0 && flag_unsafe_math_optimizations)
7730	    {
7731	      tree narg0 = fold_strip_sign_ops (arg0);
7732	      if (narg0)
7733		{
7734		  arglist = build_tree_list (NULL_TREE, arg1);
7735		  arglist = tree_cons (NULL_TREE, narg0, arglist);
7736		  return build_function_call_expr (fndecl, arglist);
7737		}
7738	    }
7739	}
7740    }
7741
7742  if (flag_unsafe_math_optimizations)
7743    {
7744      const enum built_in_function fcode = builtin_mathfn_code (arg0);
7745
7746      /* Optimize pow(expN(x),y) = expN(x*y).  */
7747      if (BUILTIN_EXPONENT_P (fcode))
7748	{
7749	  tree expfn = TREE_OPERAND (TREE_OPERAND (arg0, 0), 0);
7750	  tree arg = TREE_VALUE (TREE_OPERAND (arg0, 1));
7751	  arg = fold_build2 (MULT_EXPR, type, arg, arg1);
7752	  arglist = build_tree_list (NULL_TREE, arg);
7753	  return build_function_call_expr (expfn, arglist);
7754	}
7755
7756      /* Optimize pow(sqrt(x),y) = pow(x,y*0.5).  */
7757      if (BUILTIN_SQRT_P (fcode))
7758	{
7759	  tree narg0 = TREE_VALUE (TREE_OPERAND (arg0, 1));
7760	  tree narg1 = fold_build2 (MULT_EXPR, type, arg1,
7761				    build_real (type, dconsthalf));
7762
7763	  arglist = tree_cons (NULL_TREE, narg0,
7764			       build_tree_list (NULL_TREE, narg1));
7765	  return build_function_call_expr (fndecl, arglist);
7766	}
7767
7768      /* Optimize pow(cbrt(x),y) = pow(x,y/3) iff x is nonnegative.  */
7769      if (BUILTIN_CBRT_P (fcode))
7770	{
7771	  tree arg = TREE_VALUE (TREE_OPERAND (arg0, 1));
7772	  if (tree_expr_nonnegative_p (arg))
7773	    {
7774	      const REAL_VALUE_TYPE dconstroot
7775		= real_value_truncate (TYPE_MODE (type), dconstthird);
7776	      tree narg1 = fold_build2 (MULT_EXPR, type, arg1,
7777					build_real (type, dconstroot));
7778	      arglist = tree_cons (NULL_TREE, arg,
7779				   build_tree_list (NULL_TREE, narg1));
7780	      return build_function_call_expr (fndecl, arglist);
7781	    }
7782	}
7783
7784      /* Optimize pow(pow(x,y),z) = pow(x,y*z).  */
7785      if (fcode == BUILT_IN_POW || fcode == BUILT_IN_POWF
7786	   || fcode == BUILT_IN_POWL)
7787	{
7788	  tree arg00 = TREE_VALUE (TREE_OPERAND (arg0, 1));
7789	  tree arg01 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg0, 1)));
7790	  tree narg1 = fold_build2 (MULT_EXPR, type, arg01, arg1);
7791	  arglist = tree_cons (NULL_TREE, arg00,
7792			       build_tree_list (NULL_TREE, narg1));
7793	  return build_function_call_expr (fndecl, arglist);
7794	}
7795    }
7796
7797  return NULL_TREE;
7798}
7799
7800/* Fold a builtin function call to powi, powif, or powil.  Return
7801   NULL_TREE if no simplification can be made.  */
7802static tree
7803fold_builtin_powi (tree fndecl ATTRIBUTE_UNUSED, tree arglist, tree type)
7804{
7805  tree arg0 = TREE_VALUE (arglist);
7806  tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7807
7808  if (!validate_arglist (arglist, REAL_TYPE, INTEGER_TYPE, VOID_TYPE))
7809    return NULL_TREE;
7810
7811  /* Optimize pow(1.0,y) = 1.0.  */
7812  if (real_onep (arg0))
7813    return omit_one_operand (type, build_real (type, dconst1), arg1);
7814
7815  if (host_integerp (arg1, 0))
7816    {
7817      HOST_WIDE_INT c = TREE_INT_CST_LOW (arg1);
7818
7819      /* Evaluate powi at compile-time.  */
7820      if (TREE_CODE (arg0) == REAL_CST
7821	  && ! TREE_CONSTANT_OVERFLOW (arg0))
7822	{
7823	  REAL_VALUE_TYPE x;
7824	  x = TREE_REAL_CST (arg0);
7825	  real_powi (&x, TYPE_MODE (type), &x, c);
7826	  return build_real (type, x);
7827	}
7828
7829      /* Optimize pow(x,0) = 1.0.  */
7830      if (c == 0)
7831	return omit_one_operand (type, build_real (type, dconst1),
7832				 arg0);
7833
7834      /* Optimize pow(x,1) = x.  */
7835      if (c == 1)
7836	return arg0;
7837
7838      /* Optimize pow(x,-1) = 1.0/x.  */
7839      if (c == -1)
7840	return fold_build2 (RDIV_EXPR, type,
7841			   build_real (type, dconst1), arg0);
7842    }
7843
7844  return NULL_TREE;
7845}
7846
7847/* A subroutine of fold_builtin to fold the various exponent
7848   functions.  EXP is the CALL_EXPR of a call to a builtin function.
7849   VALUE is the value which will be raised to a power.  */
7850
7851static tree
7852fold_builtin_exponent (tree fndecl, tree arglist,
7853		       const REAL_VALUE_TYPE *value)
7854{
7855  if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7856    {
7857      tree type = TREE_TYPE (TREE_TYPE (fndecl));
7858      tree arg = TREE_VALUE (arglist);
7859
7860      /* Optimize exp*(0.0) = 1.0.  */
7861      if (real_zerop (arg))
7862	return build_real (type, dconst1);
7863
7864      /* Optimize expN(1.0) = N.  */
7865      if (real_onep (arg))
7866	{
7867	  REAL_VALUE_TYPE cst;
7868
7869	  real_convert (&cst, TYPE_MODE (type), value);
7870	  return build_real (type, cst);
7871	}
7872
7873      /* Attempt to evaluate expN(integer) at compile-time.  */
7874      if (flag_unsafe_math_optimizations
7875	  && TREE_CODE (arg) == REAL_CST
7876	  && ! TREE_CONSTANT_OVERFLOW (arg))
7877	{
7878	  REAL_VALUE_TYPE cint;
7879	  REAL_VALUE_TYPE c;
7880	  HOST_WIDE_INT n;
7881
7882	  c = TREE_REAL_CST (arg);
7883	  n = real_to_integer (&c);
7884	  real_from_integer (&cint, VOIDmode, n,
7885			     n < 0 ? -1 : 0, 0);
7886	  if (real_identical (&c, &cint))
7887	    {
7888	      REAL_VALUE_TYPE x;
7889
7890	      real_powi (&x, TYPE_MODE (type), value, n);
7891	      return build_real (type, x);
7892	    }
7893	}
7894
7895      /* Optimize expN(logN(x)) = x.  */
7896      if (flag_unsafe_math_optimizations)
7897	{
7898	  const enum built_in_function fcode = builtin_mathfn_code (arg);
7899
7900	  if ((value == &dconste
7901	       && (fcode == BUILT_IN_LOG
7902		   || fcode == BUILT_IN_LOGF
7903		   || fcode == BUILT_IN_LOGL))
7904	      || (value == &dconst2
7905		  && (fcode == BUILT_IN_LOG2
7906		      || fcode == BUILT_IN_LOG2F
7907		      || fcode == BUILT_IN_LOG2L))
7908	      || (value == &dconst10
7909		  && (fcode == BUILT_IN_LOG10
7910		      || fcode == BUILT_IN_LOG10F
7911		      || fcode == BUILT_IN_LOG10L)))
7912	    return fold_convert (type, TREE_VALUE (TREE_OPERAND (arg, 1)));
7913	}
7914    }
7915
7916  return 0;
7917}
7918
7919/* Return true if VAR is a VAR_DECL or a component thereof.  */
7920
7921static bool
7922var_decl_component_p (tree var)
7923{
7924  tree inner = var;
7925  while (handled_component_p (inner))
7926    inner = TREE_OPERAND (inner, 0);
7927  return SSA_VAR_P (inner);
7928}
7929
7930/* Fold function call to builtin memset.  Return
7931   NULL_TREE if no simplification can be made.  */
7932
7933static tree
7934fold_builtin_memset (tree arglist, tree type, bool ignore)
7935{
7936  tree dest, c, len, var, ret;
7937  unsigned HOST_WIDE_INT length, cval;
7938
7939  if (!validate_arglist (arglist,
7940			 POINTER_TYPE, INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
7941    return 0;
7942
7943  dest = TREE_VALUE (arglist);
7944  c = TREE_VALUE (TREE_CHAIN (arglist));
7945  len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7946
7947  if (! host_integerp (len, 1))
7948    return 0;
7949
7950  /* If the LEN parameter is zero, return DEST.  */
7951  if (integer_zerop (len))
7952    return omit_one_operand (type, dest, c);
7953
7954  if (! host_integerp (c, 1) || TREE_SIDE_EFFECTS (dest))
7955    return 0;
7956
7957  var = dest;
7958  STRIP_NOPS (var);
7959  if (TREE_CODE (var) != ADDR_EXPR)
7960    return 0;
7961
7962  var = TREE_OPERAND (var, 0);
7963  if (TREE_THIS_VOLATILE (var))
7964    return 0;
7965
7966  if (!INTEGRAL_TYPE_P (TREE_TYPE (var))
7967      && !POINTER_TYPE_P (TREE_TYPE (var)))
7968    return 0;
7969
7970  if (! var_decl_component_p (var))
7971    return 0;
7972
7973  length = tree_low_cst (len, 1);
7974  if (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (var))) != length
7975      || get_pointer_alignment (dest, BIGGEST_ALIGNMENT) / BITS_PER_UNIT
7976	 < (int) length)
7977    return 0;
7978
7979  if (length > HOST_BITS_PER_WIDE_INT / BITS_PER_UNIT)
7980    return 0;
7981
7982  if (integer_zerop (c))
7983    cval = 0;
7984  else
7985    {
7986      if (CHAR_BIT != 8 || BITS_PER_UNIT != 8 || HOST_BITS_PER_WIDE_INT > 64)
7987	return 0;
7988
7989      cval = tree_low_cst (c, 1);
7990      cval &= 0xff;
7991      cval |= cval << 8;
7992      cval |= cval << 16;
7993      cval |= (cval << 31) << 1;
7994    }
7995
7996  ret = build_int_cst_type (TREE_TYPE (var), cval);
7997  ret = build2 (MODIFY_EXPR, TREE_TYPE (var), var, ret);
7998  if (ignore)
7999    return ret;
8000
8001  return omit_one_operand (type, dest, ret);
8002}
8003
8004/* Fold function call to builtin memset.  Return
8005   NULL_TREE if no simplification can be made.  */
8006
8007static tree
8008fold_builtin_bzero (tree arglist, bool ignore)
8009{
8010  tree dest, size, newarglist;
8011
8012  if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8013    return 0;
8014
8015  if (!ignore)
8016    return 0;
8017
8018  dest = TREE_VALUE (arglist);
8019  size = TREE_VALUE (TREE_CHAIN (arglist));
8020
8021  /* New argument list transforming bzero(ptr x, int y) to
8022     memset(ptr x, int 0, size_t y).   This is done this way
8023     so that if it isn't expanded inline, we fallback to
8024     calling bzero instead of memset.  */
8025
8026  newarglist = build_tree_list (NULL_TREE, fold_convert (sizetype, size));
8027  newarglist = tree_cons (NULL_TREE, integer_zero_node, newarglist);
8028  newarglist = tree_cons (NULL_TREE, dest, newarglist);
8029  return fold_builtin_memset (newarglist, void_type_node, ignore);
8030}
8031
8032/* Fold function call to builtin mem{{,p}cpy,move}.  Return
8033   NULL_TREE if no simplification can be made.
8034   If ENDP is 0, return DEST (like memcpy).
8035   If ENDP is 1, return DEST+LEN (like mempcpy).
8036   If ENDP is 2, return DEST+LEN-1 (like stpcpy).
8037   If ENDP is 3, return DEST, additionally *SRC and *DEST may overlap
8038   (memmove).   */
8039
8040static tree
8041fold_builtin_memory_op (tree arglist, tree type, bool ignore, int endp)
8042{
8043  tree dest, src, len, destvar, srcvar, expr;
8044  unsigned HOST_WIDE_INT length;
8045
8046  if (! validate_arglist (arglist,
8047			  POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8048    return 0;
8049
8050  dest = TREE_VALUE (arglist);
8051  src = TREE_VALUE (TREE_CHAIN (arglist));
8052  len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8053
8054  /* If the LEN parameter is zero, return DEST.  */
8055  if (integer_zerop (len))
8056    return omit_one_operand (type, dest, src);
8057
8058  /* If SRC and DEST are the same (and not volatile), return
8059     DEST{,+LEN,+LEN-1}.  */
8060  if (operand_equal_p (src, dest, 0))
8061    expr = len;
8062  else
8063    {
8064      if (! host_integerp (len, 1))
8065	return 0;
8066
8067      if (TREE_SIDE_EFFECTS (dest) || TREE_SIDE_EFFECTS (src))
8068	return 0;
8069
8070      destvar = dest;
8071      STRIP_NOPS (destvar);
8072      if (TREE_CODE (destvar) != ADDR_EXPR)
8073	return 0;
8074
8075      destvar = TREE_OPERAND (destvar, 0);
8076      if (TREE_THIS_VOLATILE (destvar))
8077	return 0;
8078
8079      if (!INTEGRAL_TYPE_P (TREE_TYPE (destvar))
8080	  && !POINTER_TYPE_P (TREE_TYPE (destvar))
8081	  && !SCALAR_FLOAT_TYPE_P (TREE_TYPE (destvar)))
8082	return 0;
8083
8084      if (! var_decl_component_p (destvar))
8085	return 0;
8086
8087      srcvar = src;
8088      STRIP_NOPS (srcvar);
8089      if (TREE_CODE (srcvar) != ADDR_EXPR)
8090	return 0;
8091
8092      srcvar = TREE_OPERAND (srcvar, 0);
8093      if (TREE_THIS_VOLATILE (srcvar))
8094	return 0;
8095
8096      if (!INTEGRAL_TYPE_P (TREE_TYPE (srcvar))
8097	  && !POINTER_TYPE_P (TREE_TYPE (srcvar))
8098	  && !SCALAR_FLOAT_TYPE_P (TREE_TYPE (srcvar)))
8099	return 0;
8100
8101      if (! var_decl_component_p (srcvar))
8102	return 0;
8103
8104      length = tree_low_cst (len, 1);
8105      if (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (destvar))) != length
8106	  || get_pointer_alignment (dest, BIGGEST_ALIGNMENT) / BITS_PER_UNIT
8107	     < (int) length
8108	  || GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (srcvar))) != length
8109	  || get_pointer_alignment (src, BIGGEST_ALIGNMENT) / BITS_PER_UNIT
8110	     < (int) length)
8111	return 0;
8112
8113      if ((INTEGRAL_TYPE_P (TREE_TYPE (srcvar))
8114	   || POINTER_TYPE_P (TREE_TYPE (srcvar)))
8115	  && (INTEGRAL_TYPE_P (TREE_TYPE (destvar))
8116	      || POINTER_TYPE_P (TREE_TYPE (destvar))))
8117	expr = fold_convert (TREE_TYPE (destvar), srcvar);
8118      else
8119	expr = fold_build1 (VIEW_CONVERT_EXPR, TREE_TYPE (destvar), srcvar);
8120      expr = build2 (MODIFY_EXPR, TREE_TYPE (destvar), destvar, expr);
8121    }
8122
8123  if (ignore)
8124    return expr;
8125
8126  if (endp == 0 || endp == 3)
8127    return omit_one_operand (type, dest, expr);
8128
8129  if (expr == len)
8130    expr = 0;
8131
8132  if (endp == 2)
8133    len = fold_build2 (MINUS_EXPR, TREE_TYPE (len), len,
8134		       ssize_int (1));
8135
8136  len = fold_convert (TREE_TYPE (dest), len);
8137  dest = fold_build2 (PLUS_EXPR, TREE_TYPE (dest), dest, len);
8138  dest = fold_convert (type, dest);
8139  if (expr)
8140    dest = omit_one_operand (type, dest, expr);
8141  return dest;
8142}
8143
8144/* Fold function call to builtin bcopy.  Return NULL_TREE if no
8145   simplification can be made.  */
8146
8147static tree
8148fold_builtin_bcopy (tree arglist, bool ignore)
8149{
8150  tree src, dest, size, newarglist;
8151
8152  if (!validate_arglist (arglist,
8153			 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8154    return 0;
8155
8156  if (! ignore)
8157    return 0;
8158
8159  src = TREE_VALUE (arglist);
8160  dest = TREE_VALUE (TREE_CHAIN (arglist));
8161  size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8162
8163  /* New argument list transforming bcopy(ptr x, ptr y, int z) to
8164     memmove(ptr y, ptr x, size_t z).   This is done this way
8165     so that if it isn't expanded inline, we fallback to
8166     calling bcopy instead of memmove.  */
8167
8168  newarglist = build_tree_list (NULL_TREE, fold_convert (sizetype, size));
8169  newarglist = tree_cons (NULL_TREE, src, newarglist);
8170  newarglist = tree_cons (NULL_TREE, dest, newarglist);
8171
8172  return fold_builtin_memory_op (newarglist, void_type_node, true, /*endp=*/3);
8173}
8174
8175/* Fold function call to builtin strcpy.  If LEN is not NULL, it represents
8176   the length of the string to be copied.  Return NULL_TREE if no
8177   simplification can be made.  */
8178
8179tree
8180fold_builtin_strcpy (tree fndecl, tree arglist, tree len)
8181{
8182  tree dest, src, fn;
8183
8184  if (!validate_arglist (arglist,
8185			 POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
8186    return 0;
8187
8188  dest = TREE_VALUE (arglist);
8189  src = TREE_VALUE (TREE_CHAIN (arglist));
8190
8191  /* If SRC and DEST are the same (and not volatile), return DEST.  */
8192  if (operand_equal_p (src, dest, 0))
8193    return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), dest);
8194
8195  if (optimize_size)
8196    return 0;
8197
8198  fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
8199  if (!fn)
8200    return 0;
8201
8202  if (!len)
8203    {
8204      len = c_strlen (src, 1);
8205      if (! len || TREE_SIDE_EFFECTS (len))
8206	return 0;
8207    }
8208
8209  len = size_binop (PLUS_EXPR, len, ssize_int (1));
8210  arglist = build_tree_list (NULL_TREE, len);
8211  arglist = tree_cons (NULL_TREE, src, arglist);
8212  arglist = tree_cons (NULL_TREE, dest, arglist);
8213  return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)),
8214		       build_function_call_expr (fn, arglist));
8215}
8216
8217/* Fold function call to builtin strncpy.  If SLEN is not NULL, it represents
8218   the length of the source string.  Return NULL_TREE if no simplification
8219   can be made.  */
8220
8221tree
8222fold_builtin_strncpy (tree fndecl, tree arglist, tree slen)
8223{
8224  tree dest, src, len, fn;
8225
8226  if (!validate_arglist (arglist,
8227			 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8228    return 0;
8229
8230  dest = TREE_VALUE (arglist);
8231  src = TREE_VALUE (TREE_CHAIN (arglist));
8232  len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8233
8234  /* If the LEN parameter is zero, return DEST.  */
8235  if (integer_zerop (len))
8236    return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
8237
8238  /* We can't compare slen with len as constants below if len is not a
8239     constant.  */
8240  if (len == 0 || TREE_CODE (len) != INTEGER_CST)
8241    return 0;
8242
8243  if (!slen)
8244    slen = c_strlen (src, 1);
8245
8246  /* Now, we must be passed a constant src ptr parameter.  */
8247  if (slen == 0 || TREE_CODE (slen) != INTEGER_CST)
8248    return 0;
8249
8250  slen = size_binop (PLUS_EXPR, slen, ssize_int (1));
8251
8252  /* We do not support simplification of this case, though we do
8253     support it when expanding trees into RTL.  */
8254  /* FIXME: generate a call to __builtin_memset.  */
8255  if (tree_int_cst_lt (slen, len))
8256    return 0;
8257
8258  /* OK transform into builtin memcpy.  */
8259  fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
8260  if (!fn)
8261    return 0;
8262  return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)),
8263		       build_function_call_expr (fn, arglist));
8264}
8265
8266/* Fold function call to builtin memcmp.  Return
8267   NULL_TREE if no simplification can be made.  */
8268
8269static tree
8270fold_builtin_memcmp (tree arglist)
8271{
8272  tree arg1, arg2, len;
8273  const char *p1, *p2;
8274
8275  if (!validate_arglist (arglist,
8276			 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8277    return 0;
8278
8279  arg1 = TREE_VALUE (arglist);
8280  arg2 = TREE_VALUE (TREE_CHAIN (arglist));
8281  len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8282
8283  /* If the LEN parameter is zero, return zero.  */
8284  if (integer_zerop (len))
8285    return omit_two_operands (integer_type_node, integer_zero_node,
8286			      arg1, arg2);
8287
8288  /* If ARG1 and ARG2 are the same (and not volatile), return zero.  */
8289  if (operand_equal_p (arg1, arg2, 0))
8290    return omit_one_operand (integer_type_node, integer_zero_node, len);
8291
8292  p1 = c_getstr (arg1);
8293  p2 = c_getstr (arg2);
8294
8295  /* If all arguments are constant, and the value of len is not greater
8296     than the lengths of arg1 and arg2, evaluate at compile-time.  */
8297  if (host_integerp (len, 1) && p1 && p2
8298      && compare_tree_int (len, strlen (p1) + 1) <= 0
8299      && compare_tree_int (len, strlen (p2) + 1) <= 0)
8300    {
8301      const int r = memcmp (p1, p2, tree_low_cst (len, 1));
8302
8303      if (r > 0)
8304	return integer_one_node;
8305      else if (r < 0)
8306	return integer_minus_one_node;
8307      else
8308	return integer_zero_node;
8309    }
8310
8311  /* If len parameter is one, return an expression corresponding to
8312     (*(const unsigned char*)arg1 - (const unsigned char*)arg2).  */
8313  if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
8314    {
8315      tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8316      tree cst_uchar_ptr_node
8317	= build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8318
8319      tree ind1 = fold_convert (integer_type_node,
8320				build1 (INDIRECT_REF, cst_uchar_node,
8321					fold_convert (cst_uchar_ptr_node,
8322						      arg1)));
8323      tree ind2 = fold_convert (integer_type_node,
8324				build1 (INDIRECT_REF, cst_uchar_node,
8325					fold_convert (cst_uchar_ptr_node,
8326						      arg2)));
8327      return fold_build2 (MINUS_EXPR, integer_type_node, ind1, ind2);
8328    }
8329
8330  return 0;
8331}
8332
8333/* Fold function call to builtin strcmp.  Return
8334   NULL_TREE if no simplification can be made.  */
8335
8336static tree
8337fold_builtin_strcmp (tree arglist)
8338{
8339  tree arg1, arg2;
8340  const char *p1, *p2;
8341
8342  if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
8343    return 0;
8344
8345  arg1 = TREE_VALUE (arglist);
8346  arg2 = TREE_VALUE (TREE_CHAIN (arglist));
8347
8348  /* If ARG1 and ARG2 are the same (and not volatile), return zero.  */
8349  if (operand_equal_p (arg1, arg2, 0))
8350    return integer_zero_node;
8351
8352  p1 = c_getstr (arg1);
8353  p2 = c_getstr (arg2);
8354
8355  if (p1 && p2)
8356    {
8357      const int i = strcmp (p1, p2);
8358      if (i < 0)
8359	return integer_minus_one_node;
8360      else if (i > 0)
8361	return integer_one_node;
8362      else
8363	return integer_zero_node;
8364    }
8365
8366  /* If the second arg is "", return *(const unsigned char*)arg1.  */
8367  if (p2 && *p2 == '\0')
8368    {
8369      tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8370      tree cst_uchar_ptr_node
8371	= build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8372
8373      return fold_convert (integer_type_node,
8374			   build1 (INDIRECT_REF, cst_uchar_node,
8375				   fold_convert (cst_uchar_ptr_node,
8376						 arg1)));
8377    }
8378
8379  /* If the first arg is "", return -*(const unsigned char*)arg2.  */
8380  if (p1 && *p1 == '\0')
8381    {
8382      tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8383      tree cst_uchar_ptr_node
8384	= build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8385
8386      tree temp = fold_convert (integer_type_node,
8387				build1 (INDIRECT_REF, cst_uchar_node,
8388					fold_convert (cst_uchar_ptr_node,
8389						      arg2)));
8390      return fold_build1 (NEGATE_EXPR, integer_type_node, temp);
8391    }
8392
8393  return 0;
8394}
8395
8396/* Fold function call to builtin strncmp.  Return
8397   NULL_TREE if no simplification can be made.  */
8398
8399static tree
8400fold_builtin_strncmp (tree arglist)
8401{
8402  tree arg1, arg2, len;
8403  const char *p1, *p2;
8404
8405  if (!validate_arglist (arglist,
8406			 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8407    return 0;
8408
8409  arg1 = TREE_VALUE (arglist);
8410  arg2 = TREE_VALUE (TREE_CHAIN (arglist));
8411  len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8412
8413  /* If the LEN parameter is zero, return zero.  */
8414  if (integer_zerop (len))
8415    return omit_two_operands (integer_type_node, integer_zero_node,
8416			      arg1, arg2);
8417
8418  /* If ARG1 and ARG2 are the same (and not volatile), return zero.  */
8419  if (operand_equal_p (arg1, arg2, 0))
8420    return omit_one_operand (integer_type_node, integer_zero_node, len);
8421
8422  p1 = c_getstr (arg1);
8423  p2 = c_getstr (arg2);
8424
8425  if (host_integerp (len, 1) && p1 && p2)
8426    {
8427      const int i = strncmp (p1, p2, tree_low_cst (len, 1));
8428      if (i > 0)
8429	return integer_one_node;
8430      else if (i < 0)
8431	return integer_minus_one_node;
8432      else
8433	return integer_zero_node;
8434    }
8435
8436  /* If the second arg is "", and the length is greater than zero,
8437     return *(const unsigned char*)arg1.  */
8438  if (p2 && *p2 == '\0'
8439      && TREE_CODE (len) == INTEGER_CST
8440      && tree_int_cst_sgn (len) == 1)
8441    {
8442      tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8443      tree cst_uchar_ptr_node
8444	= build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8445
8446      return fold_convert (integer_type_node,
8447			   build1 (INDIRECT_REF, cst_uchar_node,
8448				   fold_convert (cst_uchar_ptr_node,
8449						 arg1)));
8450    }
8451
8452  /* If the first arg is "", and the length is greater than zero,
8453     return -*(const unsigned char*)arg2.  */
8454  if (p1 && *p1 == '\0'
8455      && TREE_CODE (len) == INTEGER_CST
8456      && tree_int_cst_sgn (len) == 1)
8457    {
8458      tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8459      tree cst_uchar_ptr_node
8460	= build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8461
8462      tree temp = fold_convert (integer_type_node,
8463				build1 (INDIRECT_REF, cst_uchar_node,
8464					fold_convert (cst_uchar_ptr_node,
8465						      arg2)));
8466      return fold_build1 (NEGATE_EXPR, integer_type_node, temp);
8467    }
8468
8469  /* If len parameter is one, return an expression corresponding to
8470     (*(const unsigned char*)arg1 - (const unsigned char*)arg2).  */
8471  if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
8472    {
8473      tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8474      tree cst_uchar_ptr_node
8475	= build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8476
8477      tree ind1 = fold_convert (integer_type_node,
8478				build1 (INDIRECT_REF, cst_uchar_node,
8479					fold_convert (cst_uchar_ptr_node,
8480						      arg1)));
8481      tree ind2 = fold_convert (integer_type_node,
8482				build1 (INDIRECT_REF, cst_uchar_node,
8483					fold_convert (cst_uchar_ptr_node,
8484						      arg2)));
8485      return fold_build2 (MINUS_EXPR, integer_type_node, ind1, ind2);
8486    }
8487
8488  return 0;
8489}
8490
8491/* Fold function call to builtin signbit, signbitf or signbitl.  Return
8492   NULL_TREE if no simplification can be made.  */
8493
8494static tree
8495fold_builtin_signbit (tree fndecl, tree arglist)
8496{
8497  tree type = TREE_TYPE (TREE_TYPE (fndecl));
8498  tree arg, temp;
8499
8500  if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8501    return NULL_TREE;
8502
8503  arg = TREE_VALUE (arglist);
8504
8505  /* If ARG is a compile-time constant, determine the result.  */
8506  if (TREE_CODE (arg) == REAL_CST
8507      && !TREE_CONSTANT_OVERFLOW (arg))
8508    {
8509      REAL_VALUE_TYPE c;
8510
8511      c = TREE_REAL_CST (arg);
8512      temp = REAL_VALUE_NEGATIVE (c) ? integer_one_node : integer_zero_node;
8513      return fold_convert (type, temp);
8514    }
8515
8516  /* If ARG is non-negative, the result is always zero.  */
8517  if (tree_expr_nonnegative_p (arg))
8518    return omit_one_operand (type, integer_zero_node, arg);
8519
8520  /* If ARG's format doesn't have signed zeros, return "arg < 0.0".  */
8521  if (!HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg))))
8522    return fold_build2 (LT_EXPR, type, arg,
8523			build_real (TREE_TYPE (arg), dconst0));
8524
8525  return NULL_TREE;
8526}
8527
8528/* Fold function call to builtin copysign, copysignf or copysignl.
8529   Return NULL_TREE if no simplification can be made.  */
8530
8531static tree
8532fold_builtin_copysign (tree fndecl, tree arglist, tree type)
8533{
8534  tree arg1, arg2, tem;
8535
8536  if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
8537    return NULL_TREE;
8538
8539  arg1 = TREE_VALUE (arglist);
8540  arg2 = TREE_VALUE (TREE_CHAIN (arglist));
8541
8542  /* copysign(X,X) is X.  */
8543  if (operand_equal_p (arg1, arg2, 0))
8544    return fold_convert (type, arg1);
8545
8546  /* If ARG1 and ARG2 are compile-time constants, determine the result.  */
8547  if (TREE_CODE (arg1) == REAL_CST
8548      && TREE_CODE (arg2) == REAL_CST
8549      && !TREE_CONSTANT_OVERFLOW (arg1)
8550      && !TREE_CONSTANT_OVERFLOW (arg2))
8551    {
8552      REAL_VALUE_TYPE c1, c2;
8553
8554      c1 = TREE_REAL_CST (arg1);
8555      c2 = TREE_REAL_CST (arg2);
8556      /* c1.sign := c2.sign.  */
8557      real_copysign (&c1, &c2);
8558      return build_real (type, c1);
8559    }
8560
8561  /* copysign(X, Y) is fabs(X) when Y is always non-negative.
8562     Remember to evaluate Y for side-effects.  */
8563  if (tree_expr_nonnegative_p (arg2))
8564    return omit_one_operand (type,
8565			     fold_build1 (ABS_EXPR, type, arg1),
8566			     arg2);
8567
8568  /* Strip sign changing operations for the first argument.  */
8569  tem = fold_strip_sign_ops (arg1);
8570  if (tem)
8571    {
8572      arglist = tree_cons (NULL_TREE, tem, TREE_CHAIN (arglist));
8573      return build_function_call_expr (fndecl, arglist);
8574    }
8575
8576  return NULL_TREE;
8577}
8578
8579/* Fold a call to builtin isascii.  */
8580
8581static tree
8582fold_builtin_isascii (tree arglist)
8583{
8584  if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8585    return 0;
8586  else
8587    {
8588      /* Transform isascii(c) -> ((c & ~0x7f) == 0).  */
8589      tree arg = TREE_VALUE (arglist);
8590
8591      arg = build2 (BIT_AND_EXPR, integer_type_node, arg,
8592		    build_int_cst (NULL_TREE,
8593				   ~ (unsigned HOST_WIDE_INT) 0x7f));
8594      arg = fold_build2 (EQ_EXPR, integer_type_node,
8595			 arg, integer_zero_node);
8596
8597      if (in_gimple_form && !TREE_CONSTANT (arg))
8598	return NULL_TREE;
8599      else
8600	return arg;
8601    }
8602}
8603
8604/* Fold a call to builtin toascii.  */
8605
8606static tree
8607fold_builtin_toascii (tree arglist)
8608{
8609  if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8610    return 0;
8611  else
8612    {
8613      /* Transform toascii(c) -> (c & 0x7f).  */
8614      tree arg = TREE_VALUE (arglist);
8615
8616      return fold_build2 (BIT_AND_EXPR, integer_type_node, arg,
8617			  build_int_cst (NULL_TREE, 0x7f));
8618    }
8619}
8620
8621/* Fold a call to builtin isdigit.  */
8622
8623static tree
8624fold_builtin_isdigit (tree arglist)
8625{
8626  if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8627    return 0;
8628  else
8629    {
8630      /* Transform isdigit(c) -> (unsigned)(c) - '0' <= 9.  */
8631      /* According to the C standard, isdigit is unaffected by locale.
8632	 However, it definitely is affected by the target character set.  */
8633      tree arg;
8634      unsigned HOST_WIDE_INT target_digit0
8635	= lang_hooks.to_target_charset ('0');
8636
8637      if (target_digit0 == 0)
8638	return NULL_TREE;
8639
8640      arg = fold_convert (unsigned_type_node, TREE_VALUE (arglist));
8641      arg = build2 (MINUS_EXPR, unsigned_type_node, arg,
8642		    build_int_cst (unsigned_type_node, target_digit0));
8643      arg = fold_build2 (LE_EXPR, integer_type_node, arg,
8644			 build_int_cst (unsigned_type_node, 9));
8645      if (in_gimple_form && !TREE_CONSTANT (arg))
8646	return NULL_TREE;
8647      else
8648	return arg;
8649    }
8650}
8651
8652/* Fold a call to fabs, fabsf or fabsl.  */
8653
8654static tree
8655fold_builtin_fabs (tree arglist, tree type)
8656{
8657  tree arg;
8658
8659  if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8660    return 0;
8661
8662  arg = TREE_VALUE (arglist);
8663  arg = fold_convert (type, arg);
8664  if (TREE_CODE (arg) == REAL_CST)
8665    return fold_abs_const (arg, type);
8666  return fold_build1 (ABS_EXPR, type, arg);
8667}
8668
8669/* Fold a call to abs, labs, llabs or imaxabs.  */
8670
8671static tree
8672fold_builtin_abs (tree arglist, tree type)
8673{
8674  tree arg;
8675
8676  if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8677    return 0;
8678
8679  arg = TREE_VALUE (arglist);
8680  arg = fold_convert (type, arg);
8681  if (TREE_CODE (arg) == INTEGER_CST)
8682    return fold_abs_const (arg, type);
8683  return fold_build1 (ABS_EXPR, type, arg);
8684}
8685
8686/* Fold a call to __builtin_isnan(), __builtin_isinf, __builtin_finite.
8687   EXP is the CALL_EXPR for the call.  */
8688
8689static tree
8690fold_builtin_classify (tree fndecl, tree arglist, int builtin_index)
8691{
8692  tree type = TREE_TYPE (TREE_TYPE (fndecl));
8693  tree arg;
8694  REAL_VALUE_TYPE r;
8695
8696  if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8697    {
8698      /* Check that we have exactly one argument.  */
8699      if (arglist == 0)
8700	{
8701	  error ("too few arguments to function %qs",
8702		 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8703	  return error_mark_node;
8704	}
8705      else if (TREE_CHAIN (arglist) != 0)
8706	{
8707	  error ("too many arguments to function %qs",
8708		 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8709	  return error_mark_node;
8710	}
8711      else
8712	{
8713	  error ("non-floating-point argument to function %qs",
8714		 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8715	  return error_mark_node;
8716	}
8717    }
8718
8719  arg = TREE_VALUE (arglist);
8720  switch (builtin_index)
8721    {
8722    case BUILT_IN_ISINF:
8723      if (!HONOR_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
8724	return omit_one_operand (type, integer_zero_node, arg);
8725
8726      if (TREE_CODE (arg) == REAL_CST)
8727	{
8728	  r = TREE_REAL_CST (arg);
8729	  if (real_isinf (&r))
8730	    return real_compare (GT_EXPR, &r, &dconst0)
8731		   ? integer_one_node : integer_minus_one_node;
8732	  else
8733	    return integer_zero_node;
8734	}
8735
8736      return NULL_TREE;
8737
8738    case BUILT_IN_FINITE:
8739      if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg)))
8740	  && !HONOR_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
8741	return omit_one_operand (type, integer_one_node, arg);
8742
8743      if (TREE_CODE (arg) == REAL_CST)
8744	{
8745	  r = TREE_REAL_CST (arg);
8746	  return real_isinf (&r) || real_isnan (&r)
8747		 ? integer_zero_node : integer_one_node;
8748	}
8749
8750      return NULL_TREE;
8751
8752    case BUILT_IN_ISNAN:
8753      if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg))))
8754	return omit_one_operand (type, integer_zero_node, arg);
8755
8756      if (TREE_CODE (arg) == REAL_CST)
8757	{
8758	  r = TREE_REAL_CST (arg);
8759	  return real_isnan (&r) ? integer_one_node : integer_zero_node;
8760	}
8761
8762      arg = builtin_save_expr (arg);
8763      return fold_build2 (UNORDERED_EXPR, type, arg, arg);
8764
8765    default:
8766      gcc_unreachable ();
8767    }
8768}
8769
8770/* Fold a call to an unordered comparison function such as
8771   __builtin_isgreater().  FNDECL is the FUNCTION_DECL for the function
8772   being called and ARGLIST is the argument list for the call.
8773   UNORDERED_CODE and ORDERED_CODE are comparison codes that give
8774   the opposite of the desired result.  UNORDERED_CODE is used
8775   for modes that can hold NaNs and ORDERED_CODE is used for
8776   the rest.  */
8777
8778static tree
8779fold_builtin_unordered_cmp (tree fndecl, tree arglist,
8780			    enum tree_code unordered_code,
8781			    enum tree_code ordered_code)
8782{
8783  tree type = TREE_TYPE (TREE_TYPE (fndecl));
8784  enum tree_code code;
8785  tree arg0, arg1;
8786  tree type0, type1;
8787  enum tree_code code0, code1;
8788  tree cmp_type = NULL_TREE;
8789
8790  if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
8791    {
8792      /* Check that we have exactly two arguments.  */
8793      if (arglist == 0 || TREE_CHAIN (arglist) == 0)
8794	{
8795	  error ("too few arguments to function %qs",
8796		 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8797	  return error_mark_node;
8798	}
8799      else if (TREE_CHAIN (TREE_CHAIN (arglist)) != 0)
8800	{
8801	  error ("too many arguments to function %qs",
8802		 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8803	  return error_mark_node;
8804	}
8805    }
8806
8807  arg0 = TREE_VALUE (arglist);
8808  arg1 = TREE_VALUE (TREE_CHAIN (arglist));
8809
8810  type0 = TREE_TYPE (arg0);
8811  type1 = TREE_TYPE (arg1);
8812
8813  code0 = TREE_CODE (type0);
8814  code1 = TREE_CODE (type1);
8815
8816  if (code0 == REAL_TYPE && code1 == REAL_TYPE)
8817    /* Choose the wider of two real types.  */
8818    cmp_type = TYPE_PRECISION (type0) >= TYPE_PRECISION (type1)
8819      ? type0 : type1;
8820  else if (code0 == REAL_TYPE && code1 == INTEGER_TYPE)
8821    cmp_type = type0;
8822  else if (code0 == INTEGER_TYPE && code1 == REAL_TYPE)
8823    cmp_type = type1;
8824  else
8825    {
8826      error ("non-floating-point argument to function %qs",
8827		 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8828      return error_mark_node;
8829    }
8830
8831  arg0 = fold_convert (cmp_type, arg0);
8832  arg1 = fold_convert (cmp_type, arg1);
8833
8834  if (unordered_code == UNORDERED_EXPR)
8835    {
8836      if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg0))))
8837	return omit_two_operands (type, integer_zero_node, arg0, arg1);
8838      return fold_build2 (UNORDERED_EXPR, type, arg0, arg1);
8839    }
8840
8841  code = HONOR_NANS (TYPE_MODE (TREE_TYPE (arg0))) ? unordered_code
8842						   : ordered_code;
8843  return fold_build1 (TRUTH_NOT_EXPR, type,
8844		      fold_build2 (code, type, arg0, arg1));
8845}
8846
8847/* Used by constant folding to simplify calls to builtin functions.  EXP is
8848   the CALL_EXPR of a call to a builtin function.  IGNORE is true if the
8849   result of the function call is ignored.  This function returns NULL_TREE
8850   if no simplification was possible.  */
8851
8852static tree
8853fold_builtin_1 (tree fndecl, tree arglist, bool ignore)
8854{
8855  tree type = TREE_TYPE (TREE_TYPE (fndecl));
8856  enum built_in_function fcode;
8857
8858  if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
8859    return targetm.fold_builtin (fndecl, arglist, ignore);
8860
8861  fcode = DECL_FUNCTION_CODE (fndecl);
8862  switch (fcode)
8863    {
8864    case BUILT_IN_FPUTS:
8865      return fold_builtin_fputs (arglist, ignore, false, NULL_TREE);
8866
8867    case BUILT_IN_FPUTS_UNLOCKED:
8868      return fold_builtin_fputs (arglist, ignore, true, NULL_TREE);
8869
8870    case BUILT_IN_STRSTR:
8871      return fold_builtin_strstr (arglist, type);
8872
8873    case BUILT_IN_STRCAT:
8874      return fold_builtin_strcat (arglist);
8875
8876    case BUILT_IN_STRNCAT:
8877      return fold_builtin_strncat (arglist);
8878
8879    case BUILT_IN_STRSPN:
8880      return fold_builtin_strspn (arglist);
8881
8882    case BUILT_IN_STRCSPN:
8883      return fold_builtin_strcspn (arglist);
8884
8885    case BUILT_IN_STRCHR:
8886    case BUILT_IN_INDEX:
8887      return fold_builtin_strchr (arglist, type);
8888
8889    case BUILT_IN_STRRCHR:
8890    case BUILT_IN_RINDEX:
8891      return fold_builtin_strrchr (arglist, type);
8892
8893    case BUILT_IN_STRCPY:
8894      return fold_builtin_strcpy (fndecl, arglist, NULL_TREE);
8895
8896    case BUILT_IN_STRNCPY:
8897      return fold_builtin_strncpy (fndecl, arglist, NULL_TREE);
8898
8899    case BUILT_IN_STRCMP:
8900      return fold_builtin_strcmp (arglist);
8901
8902    case BUILT_IN_STRNCMP:
8903      return fold_builtin_strncmp (arglist);
8904
8905    case BUILT_IN_STRPBRK:
8906      return fold_builtin_strpbrk (arglist, type);
8907
8908    case BUILT_IN_BCMP:
8909    case BUILT_IN_MEMCMP:
8910      return fold_builtin_memcmp (arglist);
8911
8912    case BUILT_IN_SPRINTF:
8913      return fold_builtin_sprintf (arglist, ignore);
8914
8915    case BUILT_IN_CONSTANT_P:
8916      {
8917	tree val;
8918
8919	val = fold_builtin_constant_p (arglist);
8920	/* Gimplification will pull the CALL_EXPR for the builtin out of
8921	   an if condition.  When not optimizing, we'll not CSE it back.
8922	   To avoid link error types of regressions, return false now.  */
8923	if (!val && !optimize)
8924	  val = integer_zero_node;
8925
8926	return val;
8927      }
8928
8929    case BUILT_IN_EXPECT:
8930      return fold_builtin_expect (arglist);
8931
8932    case BUILT_IN_CLASSIFY_TYPE:
8933      return fold_builtin_classify_type (arglist);
8934
8935    case BUILT_IN_STRLEN:
8936      return fold_builtin_strlen (arglist);
8937
8938    CASE_FLT_FN (BUILT_IN_FABS):
8939      return fold_builtin_fabs (arglist, type);
8940
8941    case BUILT_IN_ABS:
8942    case BUILT_IN_LABS:
8943    case BUILT_IN_LLABS:
8944    case BUILT_IN_IMAXABS:
8945      return fold_builtin_abs (arglist, type);
8946
8947    CASE_FLT_FN (BUILT_IN_CONJ):
8948      if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
8949	return fold_build1 (CONJ_EXPR, type, TREE_VALUE (arglist));
8950      break;
8951
8952    CASE_FLT_FN (BUILT_IN_CREAL):
8953      if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
8954	return non_lvalue (fold_build1 (REALPART_EXPR, type,
8955					TREE_VALUE (arglist)));
8956      break;
8957
8958    CASE_FLT_FN (BUILT_IN_CIMAG):
8959      if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
8960	return non_lvalue (fold_build1 (IMAGPART_EXPR, type,
8961					TREE_VALUE (arglist)));
8962      break;
8963
8964    CASE_FLT_FN (BUILT_IN_CABS):
8965      return fold_builtin_cabs (arglist, type, fndecl);
8966
8967    CASE_FLT_FN (BUILT_IN_SQRT):
8968      return fold_builtin_sqrt (arglist, type);
8969
8970    CASE_FLT_FN (BUILT_IN_CBRT):
8971      return fold_builtin_cbrt (arglist, type);
8972
8973    CASE_FLT_FN (BUILT_IN_SIN):
8974      return fold_builtin_sin (arglist);
8975
8976    CASE_FLT_FN (BUILT_IN_COS):
8977      return fold_builtin_cos (arglist, type, fndecl);
8978
8979    CASE_FLT_FN (BUILT_IN_EXP):
8980      return fold_builtin_exponent (fndecl, arglist, &dconste);
8981
8982    CASE_FLT_FN (BUILT_IN_EXP2):
8983      return fold_builtin_exponent (fndecl, arglist, &dconst2);
8984
8985    CASE_FLT_FN (BUILT_IN_EXP10):
8986    CASE_FLT_FN (BUILT_IN_POW10):
8987      return fold_builtin_exponent (fndecl, arglist, &dconst10);
8988
8989    CASE_FLT_FN (BUILT_IN_LOG):
8990      return fold_builtin_logarithm (fndecl, arglist, &dconste);
8991
8992    CASE_FLT_FN (BUILT_IN_LOG2):
8993      return fold_builtin_logarithm (fndecl, arglist, &dconst2);
8994
8995    CASE_FLT_FN (BUILT_IN_LOG10):
8996      return fold_builtin_logarithm (fndecl, arglist, &dconst10);
8997
8998    CASE_FLT_FN (BUILT_IN_TAN):
8999      return fold_builtin_tan (arglist);
9000
9001    CASE_FLT_FN (BUILT_IN_ATAN):
9002      return fold_builtin_atan (arglist, type);
9003
9004    CASE_FLT_FN (BUILT_IN_POW):
9005      return fold_builtin_pow (fndecl, arglist, type);
9006
9007    CASE_FLT_FN (BUILT_IN_POWI):
9008      return fold_builtin_powi (fndecl, arglist, type);
9009
9010    CASE_FLT_FN (BUILT_IN_INF):
9011    case BUILT_IN_INFD32:
9012    case BUILT_IN_INFD64:
9013    case BUILT_IN_INFD128:
9014      return fold_builtin_inf (type, true);
9015
9016    CASE_FLT_FN (BUILT_IN_HUGE_VAL):
9017      return fold_builtin_inf (type, false);
9018
9019    CASE_FLT_FN (BUILT_IN_NAN):
9020    case BUILT_IN_NAND32:
9021    case BUILT_IN_NAND64:
9022    case BUILT_IN_NAND128:
9023      return fold_builtin_nan (arglist, type, true);
9024
9025    CASE_FLT_FN (BUILT_IN_NANS):
9026      return fold_builtin_nan (arglist, type, false);
9027
9028    CASE_FLT_FN (BUILT_IN_FLOOR):
9029      return fold_builtin_floor (fndecl, arglist);
9030
9031    CASE_FLT_FN (BUILT_IN_CEIL):
9032      return fold_builtin_ceil (fndecl, arglist);
9033
9034    CASE_FLT_FN (BUILT_IN_TRUNC):
9035      return fold_builtin_trunc (fndecl, arglist);
9036
9037    CASE_FLT_FN (BUILT_IN_ROUND):
9038      return fold_builtin_round (fndecl, arglist);
9039
9040    CASE_FLT_FN (BUILT_IN_NEARBYINT):
9041    CASE_FLT_FN (BUILT_IN_RINT):
9042      return fold_trunc_transparent_mathfn (fndecl, arglist);
9043
9044    CASE_FLT_FN (BUILT_IN_LCEIL):
9045    CASE_FLT_FN (BUILT_IN_LLCEIL):
9046    CASE_FLT_FN (BUILT_IN_LFLOOR):
9047    CASE_FLT_FN (BUILT_IN_LLFLOOR):
9048    CASE_FLT_FN (BUILT_IN_LROUND):
9049    CASE_FLT_FN (BUILT_IN_LLROUND):
9050      return fold_builtin_int_roundingfn (fndecl, arglist);
9051
9052    CASE_FLT_FN (BUILT_IN_LRINT):
9053    CASE_FLT_FN (BUILT_IN_LLRINT):
9054      return fold_fixed_mathfn (fndecl, arglist);
9055
9056    CASE_INT_FN (BUILT_IN_FFS):
9057    CASE_INT_FN (BUILT_IN_CLZ):
9058    CASE_INT_FN (BUILT_IN_CTZ):
9059    CASE_INT_FN (BUILT_IN_POPCOUNT):
9060    CASE_INT_FN (BUILT_IN_PARITY):
9061      return fold_builtin_bitop (fndecl, arglist);
9062
9063    case BUILT_IN_MEMSET:
9064      return fold_builtin_memset (arglist, type, ignore);
9065
9066    case BUILT_IN_MEMCPY:
9067      return fold_builtin_memory_op (arglist, type, ignore, /*endp=*/0);
9068
9069    case BUILT_IN_MEMPCPY:
9070      return fold_builtin_memory_op (arglist, type, ignore, /*endp=*/1);
9071
9072    case BUILT_IN_MEMMOVE:
9073      return fold_builtin_memory_op (arglist, type, ignore, /*endp=*/3);
9074
9075    case BUILT_IN_BZERO:
9076      return fold_builtin_bzero (arglist, ignore);
9077
9078    case BUILT_IN_BCOPY:
9079      return fold_builtin_bcopy (arglist, ignore);
9080
9081    CASE_FLT_FN (BUILT_IN_SIGNBIT):
9082      return fold_builtin_signbit (fndecl, arglist);
9083
9084    case BUILT_IN_ISASCII:
9085      return fold_builtin_isascii (arglist);
9086
9087    case BUILT_IN_TOASCII:
9088      return fold_builtin_toascii (arglist);
9089
9090    case BUILT_IN_ISDIGIT:
9091      return fold_builtin_isdigit (arglist);
9092
9093    CASE_FLT_FN (BUILT_IN_COPYSIGN):
9094      return fold_builtin_copysign (fndecl, arglist, type);
9095
9096    CASE_FLT_FN (BUILT_IN_FINITE):
9097    case BUILT_IN_FINITED32:
9098    case BUILT_IN_FINITED64:
9099    case BUILT_IN_FINITED128:
9100      return fold_builtin_classify (fndecl, arglist, BUILT_IN_FINITE);
9101
9102    CASE_FLT_FN (BUILT_IN_ISINF):
9103    case BUILT_IN_ISINFD32:
9104    case BUILT_IN_ISINFD64:
9105    case BUILT_IN_ISINFD128:
9106      return fold_builtin_classify (fndecl, arglist, BUILT_IN_ISINF);
9107
9108    CASE_FLT_FN (BUILT_IN_ISNAN):
9109    case BUILT_IN_ISNAND32:
9110    case BUILT_IN_ISNAND64:
9111    case BUILT_IN_ISNAND128:
9112      return fold_builtin_classify (fndecl, arglist, BUILT_IN_ISNAN);
9113
9114    case BUILT_IN_ISGREATER:
9115      return fold_builtin_unordered_cmp (fndecl, arglist, UNLE_EXPR, LE_EXPR);
9116    case BUILT_IN_ISGREATEREQUAL:
9117      return fold_builtin_unordered_cmp (fndecl, arglist, UNLT_EXPR, LT_EXPR);
9118    case BUILT_IN_ISLESS:
9119      return fold_builtin_unordered_cmp (fndecl, arglist, UNGE_EXPR, GE_EXPR);
9120    case BUILT_IN_ISLESSEQUAL:
9121      return fold_builtin_unordered_cmp (fndecl, arglist, UNGT_EXPR, GT_EXPR);
9122    case BUILT_IN_ISLESSGREATER:
9123      return fold_builtin_unordered_cmp (fndecl, arglist, UNEQ_EXPR, EQ_EXPR);
9124    case BUILT_IN_ISUNORDERED:
9125      return fold_builtin_unordered_cmp (fndecl, arglist, UNORDERED_EXPR,
9126					 NOP_EXPR);
9127
9128      /* We do the folding for va_start in the expander.  */
9129    case BUILT_IN_VA_START:
9130      break;
9131
9132    case BUILT_IN_OBJECT_SIZE:
9133      return fold_builtin_object_size (arglist);
9134    case BUILT_IN_MEMCPY_CHK:
9135    case BUILT_IN_MEMPCPY_CHK:
9136    case BUILT_IN_MEMMOVE_CHK:
9137    case BUILT_IN_MEMSET_CHK:
9138      return fold_builtin_memory_chk (fndecl, arglist, NULL_TREE, ignore,
9139				      DECL_FUNCTION_CODE (fndecl));
9140    case BUILT_IN_STRCPY_CHK:
9141    case BUILT_IN_STPCPY_CHK:
9142      return fold_builtin_stxcpy_chk (fndecl, arglist, NULL_TREE, ignore,
9143				      DECL_FUNCTION_CODE (fndecl));
9144    case BUILT_IN_STRNCPY_CHK:
9145      return fold_builtin_strncpy_chk (arglist, NULL_TREE);
9146    case BUILT_IN_STRCAT_CHK:
9147      return fold_builtin_strcat_chk (fndecl, arglist);
9148    case BUILT_IN_STRNCAT_CHK:
9149      return fold_builtin_strncat_chk (fndecl, arglist);
9150    case BUILT_IN_SPRINTF_CHK:
9151    case BUILT_IN_VSPRINTF_CHK:
9152      return fold_builtin_sprintf_chk (arglist, DECL_FUNCTION_CODE (fndecl));
9153    case BUILT_IN_SNPRINTF_CHK:
9154    case BUILT_IN_VSNPRINTF_CHK:
9155      return fold_builtin_snprintf_chk (arglist, NULL_TREE,
9156					DECL_FUNCTION_CODE (fndecl));
9157
9158    case BUILT_IN_PRINTF:
9159    case BUILT_IN_PRINTF_UNLOCKED:
9160    case BUILT_IN_VPRINTF:
9161    case BUILT_IN_PRINTF_CHK:
9162    case BUILT_IN_VPRINTF_CHK:
9163      return fold_builtin_printf (fndecl, arglist, ignore,
9164				  DECL_FUNCTION_CODE (fndecl));
9165
9166    case BUILT_IN_FPRINTF:
9167    case BUILT_IN_FPRINTF_UNLOCKED:
9168    case BUILT_IN_VFPRINTF:
9169    case BUILT_IN_FPRINTF_CHK:
9170    case BUILT_IN_VFPRINTF_CHK:
9171      return fold_builtin_fprintf (fndecl, arglist, ignore,
9172				   DECL_FUNCTION_CODE (fndecl));
9173
9174    default:
9175      break;
9176    }
9177
9178  return 0;
9179}
9180
9181/* A wrapper function for builtin folding that prevents warnings for
9182   "statement without effect" and the like, caused by removing the
9183   call node earlier than the warning is generated.  */
9184
9185tree
9186fold_builtin (tree fndecl, tree arglist, bool ignore)
9187{
9188  tree exp = fold_builtin_1 (fndecl, arglist, ignore);
9189  if (exp)
9190    {
9191      exp = build1 (NOP_EXPR, TREE_TYPE (exp), exp);
9192      TREE_NO_WARNING (exp) = 1;
9193    }
9194
9195  return exp;
9196}
9197
9198/* Conveniently construct a function call expression.  */
9199
9200tree
9201build_function_call_expr (tree fn, tree arglist)
9202{
9203  tree call_expr;
9204
9205  call_expr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
9206  return fold_build3 (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)),
9207		      call_expr, arglist, NULL_TREE);
9208}
9209
9210/* This function validates the types of a function call argument list
9211   represented as a tree chain of parameters against a specified list
9212   of tree_codes.  If the last specifier is a 0, that represents an
9213   ellipses, otherwise the last specifier must be a VOID_TYPE.  */
9214
9215static int
9216validate_arglist (tree arglist, ...)
9217{
9218  enum tree_code code;
9219  int res = 0;
9220  va_list ap;
9221
9222  va_start (ap, arglist);
9223
9224  do
9225    {
9226      code = va_arg (ap, enum tree_code);
9227      switch (code)
9228	{
9229	case 0:
9230	  /* This signifies an ellipses, any further arguments are all ok.  */
9231	  res = 1;
9232	  goto end;
9233	case VOID_TYPE:
9234	  /* This signifies an endlink, if no arguments remain, return
9235	     true, otherwise return false.  */
9236	  res = arglist == 0;
9237	  goto end;
9238	default:
9239	  /* If no parameters remain or the parameter's code does not
9240	     match the specified code, return false.  Otherwise continue
9241	     checking any remaining arguments.  */
9242	  if (arglist == 0)
9243	    goto end;
9244	  if (code == POINTER_TYPE)
9245	    {
9246	      if (! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist))))
9247		goto end;
9248	    }
9249	  else if (code != TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))))
9250	    goto end;
9251	  break;
9252	}
9253      arglist = TREE_CHAIN (arglist);
9254    }
9255  while (1);
9256
9257  /* We need gotos here since we can only have one VA_CLOSE in a
9258     function.  */
9259 end: ;
9260  va_end (ap);
9261
9262  return res;
9263}
9264
9265/* Default target-specific builtin expander that does nothing.  */
9266
9267rtx
9268default_expand_builtin (tree exp ATTRIBUTE_UNUSED,
9269			rtx target ATTRIBUTE_UNUSED,
9270			rtx subtarget ATTRIBUTE_UNUSED,
9271			enum machine_mode mode ATTRIBUTE_UNUSED,
9272			int ignore ATTRIBUTE_UNUSED)
9273{
9274  return NULL_RTX;
9275}
9276
9277/* Returns true is EXP represents data that would potentially reside
9278   in a readonly section.  */
9279
9280static bool
9281readonly_data_expr (tree exp)
9282{
9283  STRIP_NOPS (exp);
9284
9285  if (TREE_CODE (exp) != ADDR_EXPR)
9286    return false;
9287
9288  exp = get_base_address (TREE_OPERAND (exp, 0));
9289  if (!exp)
9290    return false;
9291
9292  /* Make sure we call decl_readonly_section only for trees it
9293     can handle (since it returns true for everything it doesn't
9294     understand).  */
9295  if (TREE_CODE (exp) == STRING_CST
9296      || TREE_CODE (exp) == CONSTRUCTOR
9297      || (TREE_CODE (exp) == VAR_DECL && TREE_STATIC (exp)))
9298    return decl_readonly_section (exp, 0);
9299  else
9300    return false;
9301}
9302
9303/* Simplify a call to the strstr builtin.
9304
9305   Return 0 if no simplification was possible, otherwise return the
9306   simplified form of the call as a tree.
9307
9308   The simplified form may be a constant or other expression which
9309   computes the same value, but in a more efficient manner (including
9310   calls to other builtin functions).
9311
9312   The call may contain arguments which need to be evaluated, but
9313   which are not useful to determine the result of the call.  In
9314   this case we return a chain of COMPOUND_EXPRs.  The LHS of each
9315   COMPOUND_EXPR will be an argument which must be evaluated.
9316   COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
9317   COMPOUND_EXPR in the chain will contain the tree for the simplified
9318   form of the builtin function call.  */
9319
9320static tree
9321fold_builtin_strstr (tree arglist, tree type)
9322{
9323  if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9324    return 0;
9325  else
9326    {
9327      tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9328      tree fn;
9329      const char *p1, *p2;
9330
9331      p2 = c_getstr (s2);
9332      if (p2 == NULL)
9333	return 0;
9334
9335      p1 = c_getstr (s1);
9336      if (p1 != NULL)
9337	{
9338	  const char *r = strstr (p1, p2);
9339	  tree tem;
9340
9341	  if (r == NULL)
9342	    return build_int_cst (TREE_TYPE (s1), 0);
9343
9344	  /* Return an offset into the constant string argument.  */
9345	  tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
9346			     s1, build_int_cst (TREE_TYPE (s1), r - p1));
9347	  return fold_convert (type, tem);
9348	}
9349
9350      /* The argument is const char *, and the result is char *, so we need
9351	 a type conversion here to avoid a warning.  */
9352      if (p2[0] == '\0')
9353	return fold_convert (type, s1);
9354
9355      if (p2[1] != '\0')
9356	return 0;
9357
9358      fn = implicit_built_in_decls[BUILT_IN_STRCHR];
9359      if (!fn)
9360	return 0;
9361
9362      /* New argument list transforming strstr(s1, s2) to
9363	 strchr(s1, s2[0]).  */
9364      arglist = build_tree_list (NULL_TREE,
9365				 build_int_cst (NULL_TREE, p2[0]));
9366      arglist = tree_cons (NULL_TREE, s1, arglist);
9367      return build_function_call_expr (fn, arglist);
9368    }
9369}
9370
9371/* Simplify a call to the strchr builtin.
9372
9373   Return 0 if no simplification was possible, otherwise return the
9374   simplified form of the call as a tree.
9375
9376   The simplified form may be a constant or other expression which
9377   computes the same value, but in a more efficient manner (including
9378   calls to other builtin functions).
9379
9380   The call may contain arguments which need to be evaluated, but
9381   which are not useful to determine the result of the call.  In
9382   this case we return a chain of COMPOUND_EXPRs.  The LHS of each
9383   COMPOUND_EXPR will be an argument which must be evaluated.
9384   COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
9385   COMPOUND_EXPR in the chain will contain the tree for the simplified
9386   form of the builtin function call.  */
9387
9388static tree
9389fold_builtin_strchr (tree arglist, tree type)
9390{
9391  if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9392    return 0;
9393  else
9394    {
9395      tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9396      const char *p1;
9397
9398      if (TREE_CODE (s2) != INTEGER_CST)
9399	return 0;
9400
9401      p1 = c_getstr (s1);
9402      if (p1 != NULL)
9403	{
9404	  char c;
9405	  const char *r;
9406	  tree tem;
9407
9408	  if (target_char_cast (s2, &c))
9409	    return 0;
9410
9411	  r = strchr (p1, c);
9412
9413	  if (r == NULL)
9414	    return build_int_cst (TREE_TYPE (s1), 0);
9415
9416	  /* Return an offset into the constant string argument.  */
9417	  tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
9418			     s1, build_int_cst (TREE_TYPE (s1), r - p1));
9419	  return fold_convert (type, tem);
9420	}
9421      return 0;
9422    }
9423}
9424
9425/* Simplify a call to the strrchr builtin.
9426
9427   Return 0 if no simplification was possible, otherwise return the
9428   simplified form of the call as a tree.
9429
9430   The simplified form may be a constant or other expression which
9431   computes the same value, but in a more efficient manner (including
9432   calls to other builtin functions).
9433
9434   The call may contain arguments which need to be evaluated, but
9435   which are not useful to determine the result of the call.  In
9436   this case we return a chain of COMPOUND_EXPRs.  The LHS of each
9437   COMPOUND_EXPR will be an argument which must be evaluated.
9438   COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
9439   COMPOUND_EXPR in the chain will contain the tree for the simplified
9440   form of the builtin function call.  */
9441
9442static tree
9443fold_builtin_strrchr (tree arglist, tree type)
9444{
9445  if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9446    return 0;
9447  else
9448    {
9449      tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9450      tree fn;
9451      const char *p1;
9452
9453      if (TREE_CODE (s2) != INTEGER_CST)
9454	return 0;
9455
9456      p1 = c_getstr (s1);
9457      if (p1 != NULL)
9458	{
9459	  char c;
9460	  const char *r;
9461	  tree tem;
9462
9463	  if (target_char_cast (s2, &c))
9464	    return 0;
9465
9466	  r = strrchr (p1, c);
9467
9468	  if (r == NULL)
9469	    return build_int_cst (TREE_TYPE (s1), 0);
9470
9471	  /* Return an offset into the constant string argument.  */
9472	  tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
9473			     s1, build_int_cst (TREE_TYPE (s1), r - p1));
9474	  return fold_convert (type, tem);
9475	}
9476
9477      if (! integer_zerop (s2))
9478	return 0;
9479
9480      fn = implicit_built_in_decls[BUILT_IN_STRCHR];
9481      if (!fn)
9482	return 0;
9483
9484      /* Transform strrchr(s1, '\0') to strchr(s1, '\0').  */
9485      return build_function_call_expr (fn, arglist);
9486    }
9487}
9488
9489/* Simplify a call to the strpbrk builtin.
9490
9491   Return 0 if no simplification was possible, otherwise return the
9492   simplified form of the call as a tree.
9493
9494   The simplified form may be a constant or other expression which
9495   computes the same value, but in a more efficient manner (including
9496   calls to other builtin functions).
9497
9498   The call may contain arguments which need to be evaluated, but
9499   which are not useful to determine the result of the call.  In
9500   this case we return a chain of COMPOUND_EXPRs.  The LHS of each
9501   COMPOUND_EXPR will be an argument which must be evaluated.
9502   COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
9503   COMPOUND_EXPR in the chain will contain the tree for the simplified
9504   form of the builtin function call.  */
9505
9506static tree
9507fold_builtin_strpbrk (tree arglist, tree type)
9508{
9509  if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9510    return 0;
9511  else
9512    {
9513      tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9514      tree fn;
9515      const char *p1, *p2;
9516
9517      p2 = c_getstr (s2);
9518      if (p2 == NULL)
9519	return 0;
9520
9521      p1 = c_getstr (s1);
9522      if (p1 != NULL)
9523	{
9524	  const char *r = strpbrk (p1, p2);
9525	  tree tem;
9526
9527	  if (r == NULL)
9528	    return build_int_cst (TREE_TYPE (s1), 0);
9529
9530	  /* Return an offset into the constant string argument.  */
9531	  tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
9532			     s1, build_int_cst (TREE_TYPE (s1), r - p1));
9533	  return fold_convert (type, tem);
9534	}
9535
9536      if (p2[0] == '\0')
9537	/* strpbrk(x, "") == NULL.
9538	   Evaluate and ignore s1 in case it had side-effects.  */
9539	return omit_one_operand (TREE_TYPE (s1), integer_zero_node, s1);
9540
9541      if (p2[1] != '\0')
9542	return 0;  /* Really call strpbrk.  */
9543
9544      fn = implicit_built_in_decls[BUILT_IN_STRCHR];
9545      if (!fn)
9546	return 0;
9547
9548      /* New argument list transforming strpbrk(s1, s2) to
9549	 strchr(s1, s2[0]).  */
9550      arglist = build_tree_list (NULL_TREE,
9551				 build_int_cst (NULL_TREE, p2[0]));
9552      arglist = tree_cons (NULL_TREE, s1, arglist);
9553      return build_function_call_expr (fn, arglist);
9554    }
9555}
9556
9557/* Simplify a call to the strcat builtin.
9558
9559   Return 0 if no simplification was possible, otherwise return the
9560   simplified form of the call as a tree.
9561
9562   The simplified form may be a constant or other expression which
9563   computes the same value, but in a more efficient manner (including
9564   calls to other builtin functions).
9565
9566   The call may contain arguments which need to be evaluated, but
9567   which are not useful to determine the result of the call.  In
9568   this case we return a chain of COMPOUND_EXPRs.  The LHS of each
9569   COMPOUND_EXPR will be an argument which must be evaluated.
9570   COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
9571   COMPOUND_EXPR in the chain will contain the tree for the simplified
9572   form of the builtin function call.  */
9573
9574static tree
9575fold_builtin_strcat (tree arglist)
9576{
9577  if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9578    return 0;
9579  else
9580    {
9581      tree dst = TREE_VALUE (arglist),
9582	src = TREE_VALUE (TREE_CHAIN (arglist));
9583      const char *p = c_getstr (src);
9584
9585      /* If the string length is zero, return the dst parameter.  */
9586      if (p && *p == '\0')
9587	return dst;
9588
9589      return 0;
9590    }
9591}
9592
9593/* Simplify a call to the strncat builtin.
9594
9595   Return 0 if no simplification was possible, otherwise return the
9596   simplified form of the call as a tree.
9597
9598   The simplified form may be a constant or other expression which
9599   computes the same value, but in a more efficient manner (including
9600   calls to other builtin functions).
9601
9602   The call may contain arguments which need to be evaluated, but
9603   which are not useful to determine the result of the call.  In
9604   this case we return a chain of COMPOUND_EXPRs.  The LHS of each
9605   COMPOUND_EXPR will be an argument which must be evaluated.
9606   COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
9607   COMPOUND_EXPR in the chain will contain the tree for the simplified
9608   form of the builtin function call.  */
9609
9610static tree
9611fold_builtin_strncat (tree arglist)
9612{
9613  if (!validate_arglist (arglist,
9614			 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9615    return 0;
9616  else
9617    {
9618      tree dst = TREE_VALUE (arglist);
9619      tree src = TREE_VALUE (TREE_CHAIN (arglist));
9620      tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
9621      const char *p = c_getstr (src);
9622
9623      /* If the requested length is zero, or the src parameter string
9624	 length is zero, return the dst parameter.  */
9625      if (integer_zerop (len) || (p && *p == '\0'))
9626	return omit_two_operands (TREE_TYPE (dst), dst, src, len);
9627
9628      /* If the requested len is greater than or equal to the string
9629	 length, call strcat.  */
9630      if (TREE_CODE (len) == INTEGER_CST && p
9631	  && compare_tree_int (len, strlen (p)) >= 0)
9632	{
9633	  tree newarglist
9634	    = tree_cons (NULL_TREE, dst, build_tree_list (NULL_TREE, src));
9635	  tree fn = implicit_built_in_decls[BUILT_IN_STRCAT];
9636
9637	  /* If the replacement _DECL isn't initialized, don't do the
9638	     transformation.  */
9639	  if (!fn)
9640	    return 0;
9641
9642	  return build_function_call_expr (fn, newarglist);
9643	}
9644      return 0;
9645    }
9646}
9647
9648/* Simplify a call to the strspn builtin.
9649
9650   Return 0 if no simplification was possible, otherwise return the
9651   simplified form of the call as a tree.
9652
9653   The simplified form may be a constant or other expression which
9654   computes the same value, but in a more efficient manner (including
9655   calls to other builtin functions).
9656
9657   The call may contain arguments which need to be evaluated, but
9658   which are not useful to determine the result of the call.  In
9659   this case we return a chain of COMPOUND_EXPRs.  The LHS of each
9660   COMPOUND_EXPR will be an argument which must be evaluated.
9661   COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
9662   COMPOUND_EXPR in the chain will contain the tree for the simplified
9663   form of the builtin function call.  */
9664
9665static tree
9666fold_builtin_strspn (tree arglist)
9667{
9668  if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9669    return 0;
9670  else
9671    {
9672      tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9673      const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
9674
9675      /* If both arguments are constants, evaluate at compile-time.  */
9676      if (p1 && p2)
9677	{
9678	  const size_t r = strspn (p1, p2);
9679	  return size_int (r);
9680	}
9681
9682      /* If either argument is "", return 0.  */
9683      if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
9684	/* Evaluate and ignore both arguments in case either one has
9685	   side-effects.  */
9686	return omit_two_operands (integer_type_node, integer_zero_node,
9687				  s1, s2);
9688      return 0;
9689    }
9690}
9691
9692/* Simplify a call to the strcspn builtin.
9693
9694   Return 0 if no simplification was possible, otherwise return the
9695   simplified form of the call as a tree.
9696
9697   The simplified form may be a constant or other expression which
9698   computes the same value, but in a more efficient manner (including
9699   calls to other builtin functions).
9700
9701   The call may contain arguments which need to be evaluated, but
9702   which are not useful to determine the result of the call.  In
9703   this case we return a chain of COMPOUND_EXPRs.  The LHS of each
9704   COMPOUND_EXPR will be an argument which must be evaluated.
9705   COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
9706   COMPOUND_EXPR in the chain will contain the tree for the simplified
9707   form of the builtin function call.  */
9708
9709static tree
9710fold_builtin_strcspn (tree arglist)
9711{
9712  if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9713    return 0;
9714  else
9715    {
9716      tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9717      const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
9718
9719      /* If both arguments are constants, evaluate at compile-time.  */
9720      if (p1 && p2)
9721	{
9722	  const size_t r = strcspn (p1, p2);
9723	  return size_int (r);
9724	}
9725
9726      /* If the first argument is "", return 0.  */
9727      if (p1 && *p1 == '\0')
9728	{
9729	  /* Evaluate and ignore argument s2 in case it has
9730	     side-effects.  */
9731	  return omit_one_operand (integer_type_node,
9732				   integer_zero_node, s2);
9733	}
9734
9735      /* If the second argument is "", return __builtin_strlen(s1).  */
9736      if (p2 && *p2 == '\0')
9737	{
9738	  tree newarglist = build_tree_list (NULL_TREE, s1),
9739	    fn = implicit_built_in_decls[BUILT_IN_STRLEN];
9740
9741	  /* If the replacement _DECL isn't initialized, don't do the
9742	     transformation.  */
9743	  if (!fn)
9744	    return 0;
9745
9746	  return build_function_call_expr (fn, newarglist);
9747	}
9748      return 0;
9749    }
9750}
9751
9752/* Fold a call to the fputs builtin.  IGNORE is true if the value returned
9753   by the builtin will be ignored.  UNLOCKED is true is true if this
9754   actually a call to fputs_unlocked.  If LEN in non-NULL, it represents
9755   the known length of the string.  Return NULL_TREE if no simplification
9756   was possible.  */
9757
9758tree
9759fold_builtin_fputs (tree arglist, bool ignore, bool unlocked, tree len)
9760{
9761  tree fn;
9762  /* If we're using an unlocked function, assume the other unlocked
9763     functions exist explicitly.  */
9764  tree const fn_fputc = unlocked ? built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
9765    : implicit_built_in_decls[BUILT_IN_FPUTC];
9766  tree const fn_fwrite = unlocked ? built_in_decls[BUILT_IN_FWRITE_UNLOCKED]
9767    : implicit_built_in_decls[BUILT_IN_FWRITE];
9768
9769  /* If the return value is used, don't do the transformation.  */
9770  if (!ignore)
9771    return 0;
9772
9773  /* Verify the arguments in the original call.  */
9774  if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9775    return 0;
9776
9777  if (! len)
9778    len = c_strlen (TREE_VALUE (arglist), 0);
9779
9780  /* Get the length of the string passed to fputs.  If the length
9781     can't be determined, punt.  */
9782  if (!len
9783      || TREE_CODE (len) != INTEGER_CST)
9784    return 0;
9785
9786  switch (compare_tree_int (len, 1))
9787    {
9788    case -1: /* length is 0, delete the call entirely .  */
9789      return omit_one_operand (integer_type_node, integer_zero_node,
9790			       TREE_VALUE (TREE_CHAIN (arglist)));
9791
9792    case 0: /* length is 1, call fputc.  */
9793      {
9794	const char *p = c_getstr (TREE_VALUE (arglist));
9795
9796	if (p != NULL)
9797	  {
9798	    /* New argument list transforming fputs(string, stream) to
9799	       fputc(string[0], stream).  */
9800	    arglist = build_tree_list (NULL_TREE,
9801				       TREE_VALUE (TREE_CHAIN (arglist)));
9802	    arglist = tree_cons (NULL_TREE,
9803				 build_int_cst (NULL_TREE, p[0]),
9804				 arglist);
9805	    fn = fn_fputc;
9806	    break;
9807	  }
9808      }
9809      /* FALLTHROUGH */
9810    case 1: /* length is greater than 1, call fwrite.  */
9811      {
9812	tree string_arg;
9813
9814	/* If optimizing for size keep fputs.  */
9815	if (optimize_size)
9816	  return 0;
9817	string_arg = TREE_VALUE (arglist);
9818	/* New argument list transforming fputs(string, stream) to
9819	   fwrite(string, 1, len, stream).  */
9820	arglist = build_tree_list (NULL_TREE,
9821				   TREE_VALUE (TREE_CHAIN (arglist)));
9822	arglist = tree_cons (NULL_TREE, len, arglist);
9823	arglist = tree_cons (NULL_TREE, size_one_node, arglist);
9824	arglist = tree_cons (NULL_TREE, string_arg, arglist);
9825	fn = fn_fwrite;
9826	break;
9827      }
9828    default:
9829      gcc_unreachable ();
9830    }
9831
9832  /* If the replacement _DECL isn't initialized, don't do the
9833     transformation.  */
9834  if (!fn)
9835    return 0;
9836
9837  /* These optimizations are only performed when the result is ignored,
9838     hence there's no need to cast the result to integer_type_node.  */
9839  return build_function_call_expr (fn, arglist);
9840}
9841
9842/* Fold the new_arg's arguments (ARGLIST). Returns true if there was an error
9843   produced.  False otherwise.  This is done so that we don't output the error
9844   or warning twice or three times.  */
9845bool
9846fold_builtin_next_arg (tree arglist)
9847{
9848  tree fntype = TREE_TYPE (current_function_decl);
9849
9850  if (TYPE_ARG_TYPES (fntype) == 0
9851      || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
9852	  == void_type_node))
9853    {
9854      error ("%<va_start%> used in function with fixed args");
9855      return true;
9856    }
9857  else if (!arglist)
9858    {
9859      /* Evidently an out of date version of <stdarg.h>; can't validate
9860	 va_start's second argument, but can still work as intended.  */
9861      warning (0, "%<__builtin_next_arg%> called without an argument");
9862      return true;
9863    }
9864  /* We use __builtin_va_start (ap, 0, 0) or __builtin_next_arg (0, 0)
9865     when we checked the arguments and if needed issued a warning.  */
9866  else if (!TREE_CHAIN (arglist)
9867	   || !integer_zerop (TREE_VALUE (arglist))
9868	   || !integer_zerop (TREE_VALUE (TREE_CHAIN (arglist)))
9869	   || TREE_CHAIN (TREE_CHAIN (arglist)))
9870    {
9871      tree last_parm = tree_last (DECL_ARGUMENTS (current_function_decl));
9872      tree arg = TREE_VALUE (arglist);
9873
9874      if (TREE_CHAIN (arglist))
9875	{
9876	  error ("%<va_start%> used with too many arguments");
9877	  return true;
9878	}
9879
9880      /* Strip off all nops for the sake of the comparison.  This
9881	 is not quite the same as STRIP_NOPS.  It does more.
9882	 We must also strip off INDIRECT_EXPR for C++ reference
9883	 parameters.  */
9884      while (TREE_CODE (arg) == NOP_EXPR
9885	     || TREE_CODE (arg) == CONVERT_EXPR
9886	     || TREE_CODE (arg) == NON_LVALUE_EXPR
9887	     || TREE_CODE (arg) == INDIRECT_REF)
9888	arg = TREE_OPERAND (arg, 0);
9889      if (arg != last_parm)
9890	{
9891	  /* FIXME: Sometimes with the tree optimizers we can get the
9892	     not the last argument even though the user used the last
9893	     argument.  We just warn and set the arg to be the last
9894	     argument so that we will get wrong-code because of
9895	     it.  */
9896	  warning (0, "second parameter of %<va_start%> not last named argument");
9897	}
9898      /* We want to verify the second parameter just once before the tree
9899	 optimizers are run and then avoid keeping it in the tree,
9900	 as otherwise we could warn even for correct code like:
9901	 void foo (int i, ...)
9902	 { va_list ap; i++; va_start (ap, i); va_end (ap); }  */
9903      TREE_VALUE (arglist) = integer_zero_node;
9904      TREE_CHAIN (arglist) = build_tree_list (NULL, integer_zero_node);
9905    }
9906  return false;
9907}
9908
9909
9910/* Simplify a call to the sprintf builtin.
9911
9912   Return 0 if no simplification was possible, otherwise return the
9913   simplified form of the call as a tree.  If IGNORED is true, it means that
9914   the caller does not use the returned value of the function.  */
9915
9916static tree
9917fold_builtin_sprintf (tree arglist, int ignored)
9918{
9919  tree call, retval, dest, fmt;
9920  const char *fmt_str = NULL;
9921
9922  /* Verify the required arguments in the original call.  We deal with two
9923     types of sprintf() calls: 'sprintf (str, fmt)' and
9924     'sprintf (dest, "%s", orig)'.  */
9925  if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)
9926      && !validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, POINTER_TYPE,
9927			    VOID_TYPE))
9928    return NULL_TREE;
9929
9930  /* Get the destination string and the format specifier.  */
9931  dest = TREE_VALUE (arglist);
9932  fmt = TREE_VALUE (TREE_CHAIN (arglist));
9933  arglist = TREE_CHAIN (TREE_CHAIN (arglist));
9934
9935  /* Check whether the format is a literal string constant.  */
9936  fmt_str = c_getstr (fmt);
9937  if (fmt_str == NULL)
9938    return NULL_TREE;
9939
9940  call = NULL_TREE;
9941  retval = NULL_TREE;
9942
9943  if (!init_target_chars())
9944    return 0;
9945
9946  /* If the format doesn't contain % args or %%, use strcpy.  */
9947  if (strchr (fmt_str, target_percent) == NULL)
9948    {
9949      tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
9950
9951      if (!fn)
9952	return NULL_TREE;
9953
9954      /* Don't optimize sprintf (buf, "abc", ptr++).  */
9955      if (arglist)
9956	return NULL_TREE;
9957
9958      /* Convert sprintf (str, fmt) into strcpy (str, fmt) when
9959	 'format' is known to contain no % formats.  */
9960      arglist = build_tree_list (NULL_TREE, fmt);
9961      arglist = tree_cons (NULL_TREE, dest, arglist);
9962      call = build_function_call_expr (fn, arglist);
9963      if (!ignored)
9964	retval = build_int_cst (NULL_TREE, strlen (fmt_str));
9965    }
9966
9967  /* If the format is "%s", use strcpy if the result isn't used.  */
9968  else if (fmt_str && strcmp (fmt_str, target_percent_s) == 0)
9969    {
9970      tree fn, orig;
9971      fn = implicit_built_in_decls[BUILT_IN_STRCPY];
9972
9973      if (!fn)
9974	return NULL_TREE;
9975
9976      /* Don't crash on sprintf (str1, "%s").  */
9977      if (!arglist)
9978	return NULL_TREE;
9979
9980      /* Convert sprintf (str1, "%s", str2) into strcpy (str1, str2).  */
9981      orig = TREE_VALUE (arglist);
9982      arglist = build_tree_list (NULL_TREE, orig);
9983      arglist = tree_cons (NULL_TREE, dest, arglist);
9984      if (!ignored)
9985	{
9986	  retval = c_strlen (orig, 1);
9987	  if (!retval || TREE_CODE (retval) != INTEGER_CST)
9988	    return NULL_TREE;
9989	}
9990      call = build_function_call_expr (fn, arglist);
9991    }
9992
9993  if (call && retval)
9994    {
9995      retval = fold_convert
9996	(TREE_TYPE (TREE_TYPE (implicit_built_in_decls[BUILT_IN_SPRINTF])),
9997	 retval);
9998      return build2 (COMPOUND_EXPR, TREE_TYPE (retval), call, retval);
9999    }
10000  else
10001    return call;
10002}
10003
10004/* Expand a call to __builtin_object_size.  */
10005
10006rtx
10007expand_builtin_object_size (tree exp)
10008{
10009  tree ost;
10010  int object_size_type;
10011  tree fndecl = get_callee_fndecl (exp);
10012  tree arglist = TREE_OPERAND (exp, 1);
10013  location_t locus = EXPR_LOCATION (exp);
10014
10015  if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
10016    {
10017      error ("%Hfirst argument of %D must be a pointer, second integer constant",
10018	     &locus, fndecl);
10019      expand_builtin_trap ();
10020      return const0_rtx;
10021    }
10022
10023  ost = TREE_VALUE (TREE_CHAIN (arglist));
10024  STRIP_NOPS (ost);
10025
10026  if (TREE_CODE (ost) != INTEGER_CST
10027      || tree_int_cst_sgn (ost) < 0
10028      || compare_tree_int (ost, 3) > 0)
10029    {
10030      error ("%Hlast argument of %D is not integer constant between 0 and 3",
10031	     &locus, fndecl);
10032      expand_builtin_trap ();
10033      return const0_rtx;
10034    }
10035
10036  object_size_type = tree_low_cst (ost, 0);
10037
10038  return object_size_type < 2 ? constm1_rtx : const0_rtx;
10039}
10040
10041/* Expand EXP, a call to the __mem{cpy,pcpy,move,set}_chk builtin.
10042   FCODE is the BUILT_IN_* to use.
10043   Return 0 if we failed; the caller should emit a normal call,
10044   otherwise try to get the result in TARGET, if convenient (and in
10045   mode MODE if that's convenient).  */
10046
10047static rtx
10048expand_builtin_memory_chk (tree exp, rtx target, enum machine_mode mode,
10049			   enum built_in_function fcode)
10050{
10051  tree arglist = TREE_OPERAND (exp, 1);
10052  tree dest, src, len, size;
10053
10054  if (!validate_arglist (arglist,
10055			 POINTER_TYPE,
10056			 fcode == BUILT_IN_MEMSET_CHK
10057			 ? INTEGER_TYPE : POINTER_TYPE,
10058			 INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
10059    return 0;
10060
10061  dest = TREE_VALUE (arglist);
10062  src = TREE_VALUE (TREE_CHAIN (arglist));
10063  len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10064  size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
10065
10066  if (! host_integerp (size, 1))
10067    return 0;
10068
10069  if (host_integerp (len, 1) || integer_all_onesp (size))
10070    {
10071      tree fn;
10072
10073      if (! integer_all_onesp (size) && tree_int_cst_lt (size, len))
10074	{
10075	  location_t locus = EXPR_LOCATION (exp);
10076	  warning (0, "%Hcall to %D will always overflow destination buffer",
10077		   &locus, get_callee_fndecl (exp));
10078	  return 0;
10079	}
10080
10081      arglist = build_tree_list (NULL_TREE, len);
10082      arglist = tree_cons (NULL_TREE, src, arglist);
10083      arglist = tree_cons (NULL_TREE, dest, arglist);
10084
10085      fn = NULL_TREE;
10086      /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume
10087	 mem{cpy,pcpy,move,set} is available.  */
10088      switch (fcode)
10089	{
10090	case BUILT_IN_MEMCPY_CHK:
10091	  fn = built_in_decls[BUILT_IN_MEMCPY];
10092	  break;
10093	case BUILT_IN_MEMPCPY_CHK:
10094	  fn = built_in_decls[BUILT_IN_MEMPCPY];
10095	  break;
10096	case BUILT_IN_MEMMOVE_CHK:
10097	  fn = built_in_decls[BUILT_IN_MEMMOVE];
10098	  break;
10099	case BUILT_IN_MEMSET_CHK:
10100	  fn = built_in_decls[BUILT_IN_MEMSET];
10101	  break;
10102	default:
10103	  break;
10104	}
10105
10106      if (! fn)
10107	return 0;
10108
10109      fn = build_function_call_expr (fn, arglist);
10110      if (TREE_CODE (fn) == CALL_EXPR)
10111	CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
10112      return expand_expr (fn, target, mode, EXPAND_NORMAL);
10113    }
10114  else if (fcode == BUILT_IN_MEMSET_CHK)
10115    return 0;
10116  else
10117    {
10118      unsigned int dest_align
10119	= get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
10120
10121      /* If DEST is not a pointer type, call the normal function.  */
10122      if (dest_align == 0)
10123	return 0;
10124
10125      /* If SRC and DEST are the same (and not volatile), do nothing.  */
10126      if (operand_equal_p (src, dest, 0))
10127	{
10128	  tree expr;
10129
10130	  if (fcode != BUILT_IN_MEMPCPY_CHK)
10131	    {
10132	      /* Evaluate and ignore LEN in case it has side-effects.  */
10133	      expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
10134	      return expand_expr (dest, target, mode, EXPAND_NORMAL);
10135	    }
10136
10137	  len = fold_convert (TREE_TYPE (dest), len);
10138	  expr = fold_build2 (PLUS_EXPR, TREE_TYPE (dest), dest, len);
10139	  return expand_expr (expr, target, mode, EXPAND_NORMAL);
10140	}
10141
10142      /* __memmove_chk special case.  */
10143      if (fcode == BUILT_IN_MEMMOVE_CHK)
10144	{
10145	  unsigned int src_align
10146	    = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
10147
10148	  if (src_align == 0)
10149	    return 0;
10150
10151	  /* If src is categorized for a readonly section we can use
10152	     normal __memcpy_chk.  */
10153	  if (readonly_data_expr (src))
10154	    {
10155	      tree fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
10156	      if (!fn)
10157		return 0;
10158	      fn = build_function_call_expr (fn, arglist);
10159	      if (TREE_CODE (fn) == CALL_EXPR)
10160		CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
10161	      return expand_expr (fn, target, mode, EXPAND_NORMAL);
10162	    }
10163	}
10164      return 0;
10165    }
10166}
10167
10168/* Emit warning if a buffer overflow is detected at compile time.  */
10169
10170static void
10171maybe_emit_chk_warning (tree exp, enum built_in_function fcode)
10172{
10173  int arg_mask, is_strlen = 0;
10174  tree arglist = TREE_OPERAND (exp, 1), a;
10175  tree len, size;
10176  location_t locus;
10177
10178  switch (fcode)
10179    {
10180    case BUILT_IN_STRCPY_CHK:
10181    case BUILT_IN_STPCPY_CHK:
10182    /* For __strcat_chk the warning will be emitted only if overflowing
10183       by at least strlen (dest) + 1 bytes.  */
10184    case BUILT_IN_STRCAT_CHK:
10185      arg_mask = 6;
10186      is_strlen = 1;
10187      break;
10188    case BUILT_IN_STRNCPY_CHK:
10189      arg_mask = 12;
10190      break;
10191    case BUILT_IN_SNPRINTF_CHK:
10192    case BUILT_IN_VSNPRINTF_CHK:
10193      arg_mask = 10;
10194      break;
10195    default:
10196      gcc_unreachable ();
10197    }
10198
10199  len = NULL_TREE;
10200  size = NULL_TREE;
10201  for (a = arglist; a && arg_mask; a = TREE_CHAIN (a), arg_mask >>= 1)
10202    if (arg_mask & 1)
10203      {
10204	if (len)
10205	  size = a;
10206	else
10207	  len = a;
10208      }
10209
10210  if (!len || !size)
10211    return;
10212
10213  len = TREE_VALUE (len);
10214  size = TREE_VALUE (size);
10215
10216  if (! host_integerp (size, 1) || integer_all_onesp (size))
10217    return;
10218
10219  if (is_strlen)
10220    {
10221      len = c_strlen (len, 1);
10222      if (! len || ! host_integerp (len, 1) || tree_int_cst_lt (len, size))
10223	return;
10224    }
10225  else if (! host_integerp (len, 1) || ! tree_int_cst_lt (size, len))
10226    return;
10227
10228  locus = EXPR_LOCATION (exp);
10229  warning (0, "%Hcall to %D will always overflow destination buffer",
10230	   &locus, get_callee_fndecl (exp));
10231}
10232
10233/* Emit warning if a buffer overflow is detected at compile time
10234   in __sprintf_chk/__vsprintf_chk calls.  */
10235
10236static void
10237maybe_emit_sprintf_chk_warning (tree exp, enum built_in_function fcode)
10238{
10239  tree arglist = TREE_OPERAND (exp, 1);
10240  tree dest, size, len, fmt, flag;
10241  const char *fmt_str;
10242
10243  /* Verify the required arguments in the original call.  */
10244  if (! arglist)
10245    return;
10246  dest = TREE_VALUE (arglist);
10247  arglist = TREE_CHAIN (arglist);
10248  if (! arglist)
10249    return;
10250  flag = TREE_VALUE (arglist);
10251  arglist = TREE_CHAIN (arglist);
10252  if (! arglist)
10253    return;
10254  size = TREE_VALUE (arglist);
10255  arglist = TREE_CHAIN (arglist);
10256  if (! arglist)
10257    return;
10258  fmt = TREE_VALUE (arglist);
10259  arglist = TREE_CHAIN (arglist);
10260
10261  if (! host_integerp (size, 1) || integer_all_onesp (size))
10262    return;
10263
10264  /* Check whether the format is a literal string constant.  */
10265  fmt_str = c_getstr (fmt);
10266  if (fmt_str == NULL)
10267    return;
10268
10269  if (!init_target_chars())
10270    return;
10271
10272  /* If the format doesn't contain % args or %%, we know its size.  */
10273  if (strchr (fmt_str, target_percent) == 0)
10274    len = build_int_cstu (size_type_node, strlen (fmt_str));
10275  /* If the format is "%s" and first ... argument is a string literal,
10276     we know it too.  */
10277  else if (fcode == BUILT_IN_SPRINTF_CHK && strcmp (fmt_str, target_percent_s) == 0)
10278    {
10279      tree arg;
10280
10281      if (! arglist)
10282	return;
10283      arg = TREE_VALUE (arglist);
10284      if (! POINTER_TYPE_P (TREE_TYPE (arg)))
10285	return;
10286
10287      len = c_strlen (arg, 1);
10288      if (!len || ! host_integerp (len, 1))
10289	return;
10290    }
10291  else
10292    return;
10293
10294  if (! tree_int_cst_lt (len, size))
10295    {
10296      location_t locus = EXPR_LOCATION (exp);
10297      warning (0, "%Hcall to %D will always overflow destination buffer",
10298	       &locus, get_callee_fndecl (exp));
10299    }
10300}
10301
10302/* Fold a call to __builtin_object_size, if possible.  */
10303
10304tree
10305fold_builtin_object_size (tree arglist)
10306{
10307  tree ptr, ost, ret = 0;
10308  int object_size_type;
10309
10310  if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
10311    return 0;
10312
10313  ptr = TREE_VALUE (arglist);
10314  ost = TREE_VALUE (TREE_CHAIN (arglist));
10315  STRIP_NOPS (ost);
10316
10317  if (TREE_CODE (ost) != INTEGER_CST
10318      || tree_int_cst_sgn (ost) < 0
10319      || compare_tree_int (ost, 3) > 0)
10320    return 0;
10321
10322  object_size_type = tree_low_cst (ost, 0);
10323
10324  /* __builtin_object_size doesn't evaluate side-effects in its arguments;
10325     if there are any side-effects, it returns (size_t) -1 for types 0 and 1
10326     and (size_t) 0 for types 2 and 3.  */
10327  if (TREE_SIDE_EFFECTS (ptr))
10328    return fold_convert (size_type_node,
10329			 object_size_type < 2
10330			 ? integer_minus_one_node : integer_zero_node);
10331
10332  if (TREE_CODE (ptr) == ADDR_EXPR)
10333    ret = build_int_cstu (size_type_node,
10334			compute_builtin_object_size (ptr, object_size_type));
10335
10336  else if (TREE_CODE (ptr) == SSA_NAME)
10337    {
10338      unsigned HOST_WIDE_INT bytes;
10339
10340      /* If object size is not known yet, delay folding until
10341       later.  Maybe subsequent passes will help determining
10342       it.  */
10343      bytes = compute_builtin_object_size (ptr, object_size_type);
10344      if (bytes != (unsigned HOST_WIDE_INT) (object_size_type < 2
10345					     ? -1 : 0))
10346	ret = build_int_cstu (size_type_node, bytes);
10347    }
10348
10349  if (ret)
10350    {
10351      ret = force_fit_type (ret, -1, false, false);
10352      if (TREE_CONSTANT_OVERFLOW (ret))
10353	ret = 0;
10354    }
10355
10356  return ret;
10357}
10358
10359/* Fold a call to the __mem{cpy,pcpy,move,set}_chk builtin.
10360   IGNORE is true, if return value can be ignored.  FCODE is the BUILT_IN_*
10361   code of the builtin.  If MAXLEN is not NULL, it is maximum length
10362   passed as third argument.  */
10363
10364tree
10365fold_builtin_memory_chk (tree fndecl, tree arglist, tree maxlen, bool ignore,
10366			 enum built_in_function fcode)
10367{
10368  tree dest, src, len, size, fn;
10369
10370  if (!validate_arglist (arglist,
10371			 POINTER_TYPE,
10372			 fcode == BUILT_IN_MEMSET_CHK
10373			 ? INTEGER_TYPE : POINTER_TYPE,
10374			 INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
10375    return 0;
10376
10377  dest = TREE_VALUE (arglist);
10378  /* Actually val for __memset_chk, but it doesn't matter.  */
10379  src = TREE_VALUE (TREE_CHAIN (arglist));
10380  len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10381  size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
10382
10383  /* If SRC and DEST are the same (and not volatile), return DEST
10384     (resp. DEST+LEN for __mempcpy_chk).  */
10385  if (fcode != BUILT_IN_MEMSET_CHK && operand_equal_p (src, dest, 0))
10386    {
10387      if (fcode != BUILT_IN_MEMPCPY_CHK)
10388	return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, len);
10389      else
10390	{
10391	  tree temp = fold_convert (TREE_TYPE (dest), len);
10392	  temp = fold_build2 (PLUS_EXPR, TREE_TYPE (dest), dest, temp);
10393	  return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), temp);
10394	}
10395    }
10396
10397  if (! host_integerp (size, 1))
10398    return 0;
10399
10400  if (! integer_all_onesp (size))
10401    {
10402      if (! host_integerp (len, 1))
10403	{
10404	  /* If LEN is not constant, try MAXLEN too.
10405	     For MAXLEN only allow optimizing into non-_ocs function
10406	     if SIZE is >= MAXLEN, never convert to __ocs_fail ().  */
10407	  if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
10408	    {
10409	      if (fcode == BUILT_IN_MEMPCPY_CHK && ignore)
10410		{
10411		  /* (void) __mempcpy_chk () can be optimized into
10412		     (void) __memcpy_chk ().  */
10413		  fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
10414		  if (!fn)
10415		    return 0;
10416
10417		  return build_function_call_expr (fn, arglist);
10418		}
10419	      return 0;
10420	    }
10421	}
10422      else
10423	maxlen = len;
10424
10425      if (tree_int_cst_lt (size, maxlen))
10426	return 0;
10427    }
10428
10429  arglist = build_tree_list (NULL_TREE, len);
10430  arglist = tree_cons (NULL_TREE, src, arglist);
10431  arglist = tree_cons (NULL_TREE, dest, arglist);
10432
10433  fn = NULL_TREE;
10434  /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume
10435     mem{cpy,pcpy,move,set} is available.  */
10436  switch (fcode)
10437    {
10438    case BUILT_IN_MEMCPY_CHK:
10439      fn = built_in_decls[BUILT_IN_MEMCPY];
10440      break;
10441    case BUILT_IN_MEMPCPY_CHK:
10442      fn = built_in_decls[BUILT_IN_MEMPCPY];
10443      break;
10444    case BUILT_IN_MEMMOVE_CHK:
10445      fn = built_in_decls[BUILT_IN_MEMMOVE];
10446      break;
10447    case BUILT_IN_MEMSET_CHK:
10448      fn = built_in_decls[BUILT_IN_MEMSET];
10449      break;
10450    default:
10451      break;
10452    }
10453
10454  if (!fn)
10455    return 0;
10456
10457  return build_function_call_expr (fn, arglist);
10458}
10459
10460/* Fold a call to the __st[rp]cpy_chk builtin.
10461   IGNORE is true, if return value can be ignored.  FCODE is the BUILT_IN_*
10462   code of the builtin.  If MAXLEN is not NULL, it is maximum length of
10463   strings passed as second argument.  */
10464
10465tree
10466fold_builtin_stxcpy_chk (tree fndecl, tree arglist, tree maxlen, bool ignore,
10467			 enum built_in_function fcode)
10468{
10469  tree dest, src, size, len, fn;
10470
10471  if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
10472			 VOID_TYPE))
10473    return 0;
10474
10475  dest = TREE_VALUE (arglist);
10476  src = TREE_VALUE (TREE_CHAIN (arglist));
10477  size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10478
10479  /* If SRC and DEST are the same (and not volatile), return DEST.  */
10480  if (fcode == BUILT_IN_STRCPY_CHK && operand_equal_p (src, dest, 0))
10481    return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), dest);
10482
10483  if (! host_integerp (size, 1))
10484    return 0;
10485
10486  if (! integer_all_onesp (size))
10487    {
10488      len = c_strlen (src, 1);
10489      if (! len || ! host_integerp (len, 1))
10490	{
10491	  /* If LEN is not constant, try MAXLEN too.
10492	     For MAXLEN only allow optimizing into non-_ocs function
10493	     if SIZE is >= MAXLEN, never convert to __ocs_fail ().  */
10494	  if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
10495	    {
10496	      if (fcode == BUILT_IN_STPCPY_CHK)
10497		{
10498		  if (! ignore)
10499		    return 0;
10500
10501		  /* If return value of __stpcpy_chk is ignored,
10502		     optimize into __strcpy_chk.  */
10503		  fn = built_in_decls[BUILT_IN_STRCPY_CHK];
10504		  if (!fn)
10505		    return 0;
10506
10507		  return build_function_call_expr (fn, arglist);
10508		}
10509
10510	      if (! len || TREE_SIDE_EFFECTS (len))
10511		return 0;
10512
10513	      /* If c_strlen returned something, but not a constant,
10514		 transform __strcpy_chk into __memcpy_chk.  */
10515	      fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
10516	      if (!fn)
10517		return 0;
10518
10519	      len = size_binop (PLUS_EXPR, len, ssize_int (1));
10520	      arglist = build_tree_list (NULL_TREE, size);
10521	      arglist = tree_cons (NULL_TREE, len, arglist);
10522	      arglist = tree_cons (NULL_TREE, src, arglist);
10523	      arglist = tree_cons (NULL_TREE, dest, arglist);
10524	      return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)),
10525				   build_function_call_expr (fn, arglist));
10526	    }
10527	}
10528      else
10529	maxlen = len;
10530
10531      if (! tree_int_cst_lt (maxlen, size))
10532	return 0;
10533    }
10534
10535  arglist = build_tree_list (NULL_TREE, src);
10536  arglist = tree_cons (NULL_TREE, dest, arglist);
10537
10538  /* If __builtin_st{r,p}cpy_chk is used, assume st{r,p}cpy is available.  */
10539  fn = built_in_decls[fcode == BUILT_IN_STPCPY_CHK
10540		      ? BUILT_IN_STPCPY : BUILT_IN_STRCPY];
10541  if (!fn)
10542    return 0;
10543
10544  return build_function_call_expr (fn, arglist);
10545}
10546
10547/* Fold a call to the __strncpy_chk builtin.
10548   If MAXLEN is not NULL, it is maximum length passed as third argument.  */
10549
10550tree
10551fold_builtin_strncpy_chk (tree arglist, tree maxlen)
10552{
10553  tree dest, src, size, len, fn;
10554
10555  if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
10556			 INTEGER_TYPE, VOID_TYPE))
10557    return 0;
10558
10559  dest = TREE_VALUE (arglist);
10560  src = TREE_VALUE (TREE_CHAIN (arglist));
10561  len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10562  size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
10563
10564  if (! host_integerp (size, 1))
10565    return 0;
10566
10567  if (! integer_all_onesp (size))
10568    {
10569      if (! host_integerp (len, 1))
10570	{
10571	  /* If LEN is not constant, try MAXLEN too.
10572	     For MAXLEN only allow optimizing into non-_ocs function
10573	     if SIZE is >= MAXLEN, never convert to __ocs_fail ().  */
10574	  if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
10575	    return 0;
10576	}
10577      else
10578	maxlen = len;
10579
10580      if (tree_int_cst_lt (size, maxlen))
10581	return 0;
10582    }
10583
10584  arglist = build_tree_list (NULL_TREE, len);
10585  arglist = tree_cons (NULL_TREE, src, arglist);
10586  arglist = tree_cons (NULL_TREE, dest, arglist);
10587
10588  /* If __builtin_strncpy_chk is used, assume strncpy is available.  */
10589  fn = built_in_decls[BUILT_IN_STRNCPY];
10590  if (!fn)
10591    return 0;
10592
10593  return build_function_call_expr (fn, arglist);
10594}
10595
10596/* Fold a call to the __strcat_chk builtin FNDECL with ARGLIST.  */
10597
10598static tree
10599fold_builtin_strcat_chk (tree fndecl, tree arglist)
10600{
10601  tree dest, src, size, fn;
10602  const char *p;
10603
10604  if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
10605			 VOID_TYPE))
10606    return 0;
10607
10608  dest = TREE_VALUE (arglist);
10609  src = TREE_VALUE (TREE_CHAIN (arglist));
10610  size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10611
10612  p = c_getstr (src);
10613  /* If the SRC parameter is "", return DEST.  */
10614  if (p && *p == '\0')
10615    return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
10616
10617  if (! host_integerp (size, 1) || ! integer_all_onesp (size))
10618    return 0;
10619
10620  arglist = build_tree_list (NULL_TREE, src);
10621  arglist = tree_cons (NULL_TREE, dest, arglist);
10622
10623  /* If __builtin_strcat_chk is used, assume strcat is available.  */
10624  fn = built_in_decls[BUILT_IN_STRCAT];
10625  if (!fn)
10626    return 0;
10627
10628  return build_function_call_expr (fn, arglist);
10629}
10630
10631/* Fold a call to the __strncat_chk builtin EXP.  */
10632
10633static tree
10634fold_builtin_strncat_chk (tree fndecl, tree arglist)
10635{
10636  tree dest, src, size, len, fn;
10637  const char *p;
10638
10639  if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
10640			 INTEGER_TYPE, VOID_TYPE))
10641    return 0;
10642
10643  dest = TREE_VALUE (arglist);
10644  src = TREE_VALUE (TREE_CHAIN (arglist));
10645  len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10646  size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
10647
10648  p = c_getstr (src);
10649  /* If the SRC parameter is "" or if LEN is 0, return DEST.  */
10650  if (p && *p == '\0')
10651    return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, len);
10652  else if (integer_zerop (len))
10653    return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
10654
10655  if (! host_integerp (size, 1))
10656    return 0;
10657
10658  if (! integer_all_onesp (size))
10659    {
10660      tree src_len = c_strlen (src, 1);
10661      if (src_len
10662	  && host_integerp (src_len, 1)
10663	  && host_integerp (len, 1)
10664	  && ! tree_int_cst_lt (len, src_len))
10665	{
10666	  /* If LEN >= strlen (SRC), optimize into __strcat_chk.  */
10667	  fn = built_in_decls[BUILT_IN_STRCAT_CHK];
10668	  if (!fn)
10669	    return 0;
10670
10671	  arglist = build_tree_list (NULL_TREE, size);
10672	  arglist = tree_cons (NULL_TREE, src, arglist);
10673	  arglist = tree_cons (NULL_TREE, dest, arglist);
10674	  return build_function_call_expr (fn, arglist);
10675	}
10676      return 0;
10677    }
10678
10679  arglist = build_tree_list (NULL_TREE, len);
10680  arglist = tree_cons (NULL_TREE, src, arglist);
10681  arglist = tree_cons (NULL_TREE, dest, arglist);
10682
10683  /* If __builtin_strncat_chk is used, assume strncat is available.  */
10684  fn = built_in_decls[BUILT_IN_STRNCAT];
10685  if (!fn)
10686    return 0;
10687
10688  return build_function_call_expr (fn, arglist);
10689}
10690
10691/* Fold a call to __{,v}sprintf_chk with argument list ARGLIST.  Return 0 if
10692   a normal call should be emitted rather than expanding the function
10693   inline.  FCODE is either BUILT_IN_SPRINTF_CHK or BUILT_IN_VSPRINTF_CHK.  */
10694
10695static tree
10696fold_builtin_sprintf_chk (tree arglist, enum built_in_function fcode)
10697{
10698  tree dest, size, len, fn, fmt, flag;
10699  const char *fmt_str;
10700
10701  /* Verify the required arguments in the original call.  */
10702  if (! arglist)
10703    return 0;
10704  dest = TREE_VALUE (arglist);
10705  if (! POINTER_TYPE_P (TREE_TYPE (dest)))
10706    return 0;
10707  arglist = TREE_CHAIN (arglist);
10708  if (! arglist)
10709    return 0;
10710  flag = TREE_VALUE (arglist);
10711  if (TREE_CODE (TREE_TYPE (flag)) != INTEGER_TYPE)
10712    return 0;
10713  arglist = TREE_CHAIN (arglist);
10714  if (! arglist)
10715    return 0;
10716  size = TREE_VALUE (arglist);
10717  if (TREE_CODE (TREE_TYPE (size)) != INTEGER_TYPE)
10718    return 0;
10719  arglist = TREE_CHAIN (arglist);
10720  if (! arglist)
10721    return 0;
10722  fmt = TREE_VALUE (arglist);
10723  if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
10724    return 0;
10725  arglist = TREE_CHAIN (arglist);
10726
10727  if (! host_integerp (size, 1))
10728    return 0;
10729
10730  len = NULL_TREE;
10731
10732  if (!init_target_chars())
10733    return 0;
10734
10735  /* Check whether the format is a literal string constant.  */
10736  fmt_str = c_getstr (fmt);
10737  if (fmt_str != NULL)
10738    {
10739      /* If the format doesn't contain % args or %%, we know the size.  */
10740      if (strchr (fmt_str, target_percent) == 0)
10741	{
10742	  if (fcode != BUILT_IN_SPRINTF_CHK || arglist == NULL_TREE)
10743	    len = build_int_cstu (size_type_node, strlen (fmt_str));
10744	}
10745      /* If the format is "%s" and first ... argument is a string literal,
10746	 we know the size too.  */
10747      else if (fcode == BUILT_IN_SPRINTF_CHK && strcmp (fmt_str, target_percent_s) == 0)
10748	{
10749	  tree arg;
10750
10751	  if (arglist && !TREE_CHAIN (arglist))
10752	    {
10753	      arg = TREE_VALUE (arglist);
10754	      if (POINTER_TYPE_P (TREE_TYPE (arg)))
10755		{
10756		  len = c_strlen (arg, 1);
10757		  if (! len || ! host_integerp (len, 1))
10758		    len = NULL_TREE;
10759		}
10760	    }
10761	}
10762    }
10763
10764  if (! integer_all_onesp (size))
10765    {
10766      if (! len || ! tree_int_cst_lt (len, size))
10767	return 0;
10768    }
10769
10770  /* Only convert __{,v}sprintf_chk to {,v}sprintf if flag is 0
10771     or if format doesn't contain % chars or is "%s".  */
10772  if (! integer_zerop (flag))
10773    {
10774      if (fmt_str == NULL)
10775	return 0;
10776      if (strchr (fmt_str, target_percent) != NULL && strcmp (fmt_str, target_percent_s))
10777	return 0;
10778    }
10779
10780  arglist = tree_cons (NULL_TREE, fmt, arglist);
10781  arglist = tree_cons (NULL_TREE, dest, arglist);
10782
10783  /* If __builtin_{,v}sprintf_chk is used, assume {,v}sprintf is available.  */
10784  fn = built_in_decls[fcode == BUILT_IN_VSPRINTF_CHK
10785		      ? BUILT_IN_VSPRINTF : BUILT_IN_SPRINTF];
10786  if (!fn)
10787    return 0;
10788
10789  return build_function_call_expr (fn, arglist);
10790}
10791
10792/* Fold a call to {,v}snprintf with argument list ARGLIST.  Return 0 if
10793   a normal call should be emitted rather than expanding the function
10794   inline.  FCODE is either BUILT_IN_SNPRINTF_CHK or
10795   BUILT_IN_VSNPRINTF_CHK.  If MAXLEN is not NULL, it is maximum length
10796   passed as second argument.  */
10797
10798tree
10799fold_builtin_snprintf_chk (tree arglist, tree maxlen,
10800			   enum built_in_function fcode)
10801{
10802  tree dest, size, len, fn, fmt, flag;
10803  const char *fmt_str;
10804
10805  /* Verify the required arguments in the original call.  */
10806  if (! arglist)
10807    return 0;
10808  dest = TREE_VALUE (arglist);
10809  if (! POINTER_TYPE_P (TREE_TYPE (dest)))
10810    return 0;
10811  arglist = TREE_CHAIN (arglist);
10812  if (! arglist)
10813    return 0;
10814  len = TREE_VALUE (arglist);
10815  if (TREE_CODE (TREE_TYPE (len)) != INTEGER_TYPE)
10816    return 0;
10817  arglist = TREE_CHAIN (arglist);
10818  if (! arglist)
10819    return 0;
10820  flag = TREE_VALUE (arglist);
10821  if (TREE_CODE (TREE_TYPE (len)) != INTEGER_TYPE)
10822    return 0;
10823  arglist = TREE_CHAIN (arglist);
10824  if (! arglist)
10825    return 0;
10826  size = TREE_VALUE (arglist);
10827  if (TREE_CODE (TREE_TYPE (size)) != INTEGER_TYPE)
10828    return 0;
10829  arglist = TREE_CHAIN (arglist);
10830  if (! arglist)
10831    return 0;
10832  fmt = TREE_VALUE (arglist);
10833  if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
10834    return 0;
10835  arglist = TREE_CHAIN (arglist);
10836
10837  if (! host_integerp (size, 1))
10838    return 0;
10839
10840  if (! integer_all_onesp (size))
10841    {
10842      if (! host_integerp (len, 1))
10843	{
10844	  /* If LEN is not constant, try MAXLEN too.
10845	     For MAXLEN only allow optimizing into non-_ocs function
10846	     if SIZE is >= MAXLEN, never convert to __ocs_fail ().  */
10847	  if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
10848	    return 0;
10849	}
10850      else
10851	maxlen = len;
10852
10853      if (tree_int_cst_lt (size, maxlen))
10854	return 0;
10855    }
10856
10857  if (!init_target_chars())
10858    return 0;
10859
10860  /* Only convert __{,v}snprintf_chk to {,v}snprintf if flag is 0
10861     or if format doesn't contain % chars or is "%s".  */
10862  if (! integer_zerop (flag))
10863    {
10864      fmt_str = c_getstr (fmt);
10865      if (fmt_str == NULL)
10866	return 0;
10867      if (strchr (fmt_str, target_percent) != NULL && strcmp (fmt_str, target_percent_s))
10868	return 0;
10869    }
10870
10871  arglist = tree_cons (NULL_TREE, fmt, arglist);
10872  arglist = tree_cons (NULL_TREE, len, arglist);
10873  arglist = tree_cons (NULL_TREE, dest, arglist);
10874
10875  /* If __builtin_{,v}snprintf_chk is used, assume {,v}snprintf is
10876     available.  */
10877  fn = built_in_decls[fcode == BUILT_IN_VSNPRINTF_CHK
10878		      ? BUILT_IN_VSNPRINTF : BUILT_IN_SNPRINTF];
10879  if (!fn)
10880    return 0;
10881
10882  return build_function_call_expr (fn, arglist);
10883}
10884
10885/* Fold a call to the {,v}printf{,_unlocked} and __{,v}printf_chk builtins.
10886
10887   Return 0 if no simplification was possible, otherwise return the
10888   simplified form of the call as a tree.  FCODE is the BUILT_IN_*
10889   code of the function to be simplified.  */
10890
10891static tree
10892fold_builtin_printf (tree fndecl, tree arglist, bool ignore,
10893		     enum built_in_function fcode)
10894{
10895  tree fmt, fn = NULL_TREE, fn_putchar, fn_puts, arg, call;
10896  const char *fmt_str = NULL;
10897
10898  /* If the return value is used, don't do the transformation.  */
10899  if (! ignore)
10900    return 0;
10901
10902  /* Verify the required arguments in the original call.  */
10903  if (fcode == BUILT_IN_PRINTF_CHK || fcode == BUILT_IN_VPRINTF_CHK)
10904    {
10905      tree flag;
10906
10907      if (! arglist)
10908	return 0;
10909      flag = TREE_VALUE (arglist);
10910      if (TREE_CODE (TREE_TYPE (flag)) != INTEGER_TYPE
10911	  || TREE_SIDE_EFFECTS (flag))
10912	return 0;
10913      arglist = TREE_CHAIN (arglist);
10914    }
10915
10916  if (! arglist)
10917    return 0;
10918  fmt = TREE_VALUE (arglist);
10919  if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
10920    return 0;
10921  arglist = TREE_CHAIN (arglist);
10922
10923  /* Check whether the format is a literal string constant.  */
10924  fmt_str = c_getstr (fmt);
10925  if (fmt_str == NULL)
10926    return NULL_TREE;
10927
10928  if (fcode == BUILT_IN_PRINTF_UNLOCKED)
10929    {
10930      /* If we're using an unlocked function, assume the other
10931	 unlocked functions exist explicitly.  */
10932      fn_putchar = built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED];
10933      fn_puts = built_in_decls[BUILT_IN_PUTS_UNLOCKED];
10934    }
10935  else
10936    {
10937      fn_putchar = implicit_built_in_decls[BUILT_IN_PUTCHAR];
10938      fn_puts = implicit_built_in_decls[BUILT_IN_PUTS];
10939    }
10940
10941  if (!init_target_chars())
10942    return 0;
10943
10944  if (strcmp (fmt_str, target_percent_s) == 0 || strchr (fmt_str, target_percent) == NULL)
10945    {
10946      const char *str;
10947
10948      if (strcmp (fmt_str, target_percent_s) == 0)
10949	{
10950	  if (fcode == BUILT_IN_VPRINTF || fcode == BUILT_IN_VPRINTF_CHK)
10951	    return 0;
10952
10953	  if (! arglist
10954	      || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
10955	      || TREE_CHAIN (arglist))
10956	    return 0;
10957
10958	  str = c_getstr (TREE_VALUE (arglist));
10959	  if (str == NULL)
10960	    return 0;
10961	}
10962      else
10963	{
10964	  /* The format specifier doesn't contain any '%' characters.  */
10965	  if (fcode != BUILT_IN_VPRINTF && fcode != BUILT_IN_VPRINTF_CHK
10966	      && arglist)
10967	    return 0;
10968	  str = fmt_str;
10969	}
10970
10971      /* If the string was "", printf does nothing.  */
10972      if (str[0] == '\0')
10973	return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), 0);
10974
10975      /* If the string has length of 1, call putchar.  */
10976      if (str[1] == '\0')
10977	{
10978	  /* Given printf("c"), (where c is any one character,)
10979	     convert "c"[0] to an int and pass that to the replacement
10980	     function.  */
10981	  arg = build_int_cst (NULL_TREE, str[0]);
10982	  arglist = build_tree_list (NULL_TREE, arg);
10983	  fn = fn_putchar;
10984	}
10985      else
10986	{
10987	  /* If the string was "string\n", call puts("string").  */
10988	  size_t len = strlen (str);
10989	  if ((unsigned char)str[len - 1] == target_newline)
10990	    {
10991	      /* Create a NUL-terminated string that's one char shorter
10992		 than the original, stripping off the trailing '\n'.  */
10993	      char *newstr = alloca (len);
10994	      memcpy (newstr, str, len - 1);
10995	      newstr[len - 1] = 0;
10996
10997	      arg = build_string_literal (len, newstr);
10998	      arglist = build_tree_list (NULL_TREE, arg);
10999	      fn = fn_puts;
11000	    }
11001	  else
11002	    /* We'd like to arrange to call fputs(string,stdout) here,
11003	       but we need stdout and don't have a way to get it yet.  */
11004	    return 0;
11005	}
11006    }
11007
11008  /* The other optimizations can be done only on the non-va_list variants.  */
11009  else if (fcode == BUILT_IN_VPRINTF || fcode == BUILT_IN_VPRINTF_CHK)
11010    return 0;
11011
11012  /* If the format specifier was "%s\n", call __builtin_puts(arg).  */
11013  else if (strcmp (fmt_str, target_percent_s_newline) == 0)
11014    {
11015      if (! arglist
11016	  || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
11017	  || TREE_CHAIN (arglist))
11018	return 0;
11019      fn = fn_puts;
11020    }
11021
11022  /* If the format specifier was "%c", call __builtin_putchar(arg).  */
11023  else if (strcmp (fmt_str, target_percent_c) == 0)
11024    {
11025      if (! arglist
11026	  || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
11027	  || TREE_CHAIN (arglist))
11028	return 0;
11029      fn = fn_putchar;
11030    }
11031
11032  if (!fn)
11033    return 0;
11034
11035  call = build_function_call_expr (fn, arglist);
11036  return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), call);
11037}
11038
11039/* Fold a call to the {,v}fprintf{,_unlocked} and __{,v}printf_chk builtins.
11040
11041   Return 0 if no simplification was possible, otherwise return the
11042   simplified form of the call as a tree.  FCODE is the BUILT_IN_*
11043   code of the function to be simplified.  */
11044
11045static tree
11046fold_builtin_fprintf (tree fndecl, tree arglist, bool ignore,
11047		      enum built_in_function fcode)
11048{
11049  tree fp, fmt, fn = NULL_TREE, fn_fputc, fn_fputs, arg, call;
11050  const char *fmt_str = NULL;
11051
11052  /* If the return value is used, don't do the transformation.  */
11053  if (! ignore)
11054    return 0;
11055
11056  /* Verify the required arguments in the original call.  */
11057  if (! arglist)
11058    return 0;
11059  fp = TREE_VALUE (arglist);
11060  if (! POINTER_TYPE_P (TREE_TYPE (fp)))
11061    return 0;
11062  arglist = TREE_CHAIN (arglist);
11063
11064  if (fcode == BUILT_IN_FPRINTF_CHK || fcode == BUILT_IN_VFPRINTF_CHK)
11065    {
11066      tree flag;
11067
11068      if (! arglist)
11069	return 0;
11070      flag = TREE_VALUE (arglist);
11071      if (TREE_CODE (TREE_TYPE (flag)) != INTEGER_TYPE
11072	  || TREE_SIDE_EFFECTS (flag))
11073	return 0;
11074      arglist = TREE_CHAIN (arglist);
11075    }
11076
11077  if (! arglist)
11078    return 0;
11079  fmt = TREE_VALUE (arglist);
11080  if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
11081    return 0;
11082  arglist = TREE_CHAIN (arglist);
11083
11084  /* Check whether the format is a literal string constant.  */
11085  fmt_str = c_getstr (fmt);
11086  if (fmt_str == NULL)
11087    return NULL_TREE;
11088
11089  if (fcode == BUILT_IN_FPRINTF_UNLOCKED)
11090    {
11091      /* If we're using an unlocked function, assume the other
11092	 unlocked functions exist explicitly.  */
11093      fn_fputc = built_in_decls[BUILT_IN_FPUTC_UNLOCKED];
11094      fn_fputs = built_in_decls[BUILT_IN_FPUTS_UNLOCKED];
11095    }
11096  else
11097    {
11098      fn_fputc = implicit_built_in_decls[BUILT_IN_FPUTC];
11099      fn_fputs = implicit_built_in_decls[BUILT_IN_FPUTS];
11100    }
11101
11102  if (!init_target_chars())
11103    return 0;
11104
11105  /* If the format doesn't contain % args or %%, use strcpy.  */
11106  if (strchr (fmt_str, target_percent) == NULL)
11107    {
11108      if (fcode != BUILT_IN_VFPRINTF && fcode != BUILT_IN_VFPRINTF_CHK
11109	  && arglist)
11110	return 0;
11111
11112      /* If the format specifier was "", fprintf does nothing.  */
11113      if (fmt_str[0] == '\0')
11114	{
11115	  /* If FP has side-effects, just wait until gimplification is
11116	     done.  */
11117	  if (TREE_SIDE_EFFECTS (fp))
11118	    return 0;
11119
11120	  return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), 0);
11121	}
11122
11123      /* When "string" doesn't contain %, replace all cases of
11124	 fprintf (fp, string) with fputs (string, fp).  The fputs
11125	 builtin will take care of special cases like length == 1.  */
11126      arglist = build_tree_list (NULL_TREE, fp);
11127      arglist = tree_cons (NULL_TREE, fmt, arglist);
11128      fn = fn_fputs;
11129    }
11130
11131  /* The other optimizations can be done only on the non-va_list variants.  */
11132  else if (fcode == BUILT_IN_VFPRINTF || fcode == BUILT_IN_VFPRINTF_CHK)
11133    return 0;
11134
11135  /* If the format specifier was "%s", call __builtin_fputs (arg, fp).  */
11136  else if (strcmp (fmt_str, target_percent_s) == 0)
11137    {
11138      if (! arglist
11139	  || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
11140	  || TREE_CHAIN (arglist))
11141	return 0;
11142      arg = TREE_VALUE (arglist);
11143      arglist = build_tree_list (NULL_TREE, fp);
11144      arglist = tree_cons (NULL_TREE, arg, arglist);
11145      fn = fn_fputs;
11146    }
11147
11148  /* If the format specifier was "%c", call __builtin_fputc (arg, fp).  */
11149  else if (strcmp (fmt_str, target_percent_c) == 0)
11150    {
11151      if (! arglist
11152	  || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
11153	  || TREE_CHAIN (arglist))
11154	return 0;
11155      arg = TREE_VALUE (arglist);
11156      arglist = build_tree_list (NULL_TREE, fp);
11157      arglist = tree_cons (NULL_TREE, arg, arglist);
11158      fn = fn_fputc;
11159    }
11160
11161  if (!fn)
11162    return 0;
11163
11164  call = build_function_call_expr (fn, arglist);
11165  return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), call);
11166}
11167
11168/* Initialize format string characters in the target charset.  */
11169
11170static bool
11171init_target_chars (void)
11172{
11173  static bool init;
11174  if (!init)
11175    {
11176      target_newline = lang_hooks.to_target_charset ('\n');
11177      target_percent = lang_hooks.to_target_charset ('%');
11178      target_c = lang_hooks.to_target_charset ('c');
11179      target_s = lang_hooks.to_target_charset ('s');
11180      if (target_newline == 0 || target_percent == 0 || target_c == 0
11181	  || target_s == 0)
11182	return false;
11183
11184      target_percent_c[0] = target_percent;
11185      target_percent_c[1] = target_c;
11186      target_percent_c[2] = '\0';
11187
11188      target_percent_s[0] = target_percent;
11189      target_percent_s[1] = target_s;
11190      target_percent_s[2] = '\0';
11191
11192      target_percent_s_newline[0] = target_percent;
11193      target_percent_s_newline[1] = target_s;
11194      target_percent_s_newline[2] = target_newline;
11195      target_percent_s_newline[3] = '\0';
11196
11197      init = true;
11198    }
11199  return true;
11200}
11201