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