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