builtins.c revision 259563
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 bswap builtin.  The arguments are in ARGLIST.  MODE
4593   is the mode to expand with.  */
4594
4595static rtx
4596expand_builtin_bswap (tree arglist, rtx target, rtx subtarget)
4597{
4598  enum machine_mode mode;
4599  tree arg;
4600  rtx op0;
4601
4602  if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
4603    return 0;
4604
4605  arg = TREE_VALUE (arglist);
4606  mode = TYPE_MODE (TREE_TYPE (arg));
4607  op0 = expand_expr (arg, subtarget, VOIDmode, 0);
4608
4609  target = expand_unop (mode, bswap_optab, op0, target, 1);
4610
4611  gcc_assert (target);
4612
4613  return convert_to_mode (mode, target, 0);
4614}
4615
4616/* Expand a call to a unary builtin.  The arguments are in ARGLIST.
4617   Return 0 if a normal call should be emitted rather than expanding the
4618   function in-line.  If convenient, the result should be placed in TARGET.
4619   SUBTARGET may be used as the target for computing one of EXP's operands.  */
4620
4621static rtx
4622expand_builtin_unop (enum machine_mode target_mode, tree arglist, rtx target,
4623		     rtx subtarget, optab op_optab)
4624{
4625  rtx op0;
4626  if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
4627    return 0;
4628
4629  /* Compute the argument.  */
4630  op0 = expand_expr (TREE_VALUE (arglist), subtarget, VOIDmode, 0);
4631  /* Compute op, into TARGET if possible.
4632     Set TARGET to wherever the result comes back.  */
4633  target = expand_unop (TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist))),
4634			op_optab, op0, target, 1);
4635  gcc_assert (target);
4636
4637  return convert_to_mode (target_mode, target, 0);
4638}
4639
4640/* If the string passed to fputs is a constant and is one character
4641   long, we attempt to transform this call into __builtin_fputc().  */
4642
4643static rtx
4644expand_builtin_fputs (tree arglist, rtx target, bool unlocked)
4645{
4646  /* Verify the arguments in the original call.  */
4647  if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4648    {
4649      tree result = fold_builtin_fputs (arglist, (target == const0_rtx),
4650					unlocked, NULL_TREE);
4651      if (result)
4652	return expand_expr (result, target, VOIDmode, EXPAND_NORMAL);
4653    }
4654  return 0;
4655}
4656
4657/* Expand a call to __builtin_expect.  We return our argument and emit a
4658   NOTE_INSN_EXPECTED_VALUE note.  This is the expansion of __builtin_expect in
4659   a non-jump context.  */
4660
4661static rtx
4662expand_builtin_expect (tree arglist, rtx target)
4663{
4664  tree exp, c;
4665  rtx note, rtx_c;
4666
4667  if (arglist == NULL_TREE
4668      || TREE_CHAIN (arglist) == NULL_TREE)
4669    return const0_rtx;
4670  exp = TREE_VALUE (arglist);
4671  c = TREE_VALUE (TREE_CHAIN (arglist));
4672
4673  if (TREE_CODE (c) != INTEGER_CST)
4674    {
4675      error ("second argument to %<__builtin_expect%> must be a constant");
4676      c = integer_zero_node;
4677    }
4678
4679  target = expand_expr (exp, target, VOIDmode, EXPAND_NORMAL);
4680
4681  /* Don't bother with expected value notes for integral constants.  */
4682  if (flag_guess_branch_prob && GET_CODE (target) != CONST_INT)
4683    {
4684      /* We do need to force this into a register so that we can be
4685	 moderately sure to be able to correctly interpret the branch
4686	 condition later.  */
4687      target = force_reg (GET_MODE (target), target);
4688
4689      rtx_c = expand_expr (c, NULL_RTX, GET_MODE (target), EXPAND_NORMAL);
4690
4691      note = emit_note (NOTE_INSN_EXPECTED_VALUE);
4692      NOTE_EXPECTED_VALUE (note) = gen_rtx_EQ (VOIDmode, target, rtx_c);
4693    }
4694
4695  return target;
4696}
4697
4698/* Like expand_builtin_expect, except do this in a jump context.  This is
4699   called from do_jump if the conditional is a __builtin_expect.  Return either
4700   a list of insns to emit the jump or NULL if we cannot optimize
4701   __builtin_expect.  We need to optimize this at jump time so that machines
4702   like the PowerPC don't turn the test into a SCC operation, and then jump
4703   based on the test being 0/1.  */
4704
4705rtx
4706expand_builtin_expect_jump (tree exp, rtx if_false_label, rtx if_true_label)
4707{
4708  tree arglist = TREE_OPERAND (exp, 1);
4709  tree arg0 = TREE_VALUE (arglist);
4710  tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
4711  rtx ret = NULL_RTX;
4712
4713  /* Only handle __builtin_expect (test, 0) and
4714     __builtin_expect (test, 1).  */
4715  if (TREE_CODE (TREE_TYPE (arg1)) == INTEGER_TYPE
4716      && (integer_zerop (arg1) || integer_onep (arg1)))
4717    {
4718      rtx insn, drop_through_label, temp;
4719
4720      /* Expand the jump insns.  */
4721      start_sequence ();
4722      do_jump (arg0, if_false_label, if_true_label);
4723      ret = get_insns ();
4724
4725      drop_through_label = get_last_insn ();
4726      if (drop_through_label && NOTE_P (drop_through_label))
4727	drop_through_label = prev_nonnote_insn (drop_through_label);
4728      if (drop_through_label && !LABEL_P (drop_through_label))
4729	drop_through_label = NULL_RTX;
4730      end_sequence ();
4731
4732      if (! if_true_label)
4733	if_true_label = drop_through_label;
4734      if (! if_false_label)
4735	if_false_label = drop_through_label;
4736
4737      /* Go through and add the expect's to each of the conditional jumps.  */
4738      insn = ret;
4739      while (insn != NULL_RTX)
4740	{
4741	  rtx next = NEXT_INSN (insn);
4742
4743	  if (JUMP_P (insn) && any_condjump_p (insn))
4744	    {
4745	      rtx ifelse = SET_SRC (pc_set (insn));
4746	      rtx then_dest = XEXP (ifelse, 1);
4747	      rtx else_dest = XEXP (ifelse, 2);
4748	      int taken = -1;
4749
4750	      /* First check if we recognize any of the labels.  */
4751	      if (GET_CODE (then_dest) == LABEL_REF
4752		  && XEXP (then_dest, 0) == if_true_label)
4753		taken = 1;
4754	      else if (GET_CODE (then_dest) == LABEL_REF
4755		       && XEXP (then_dest, 0) == if_false_label)
4756		taken = 0;
4757	      else if (GET_CODE (else_dest) == LABEL_REF
4758		       && XEXP (else_dest, 0) == if_false_label)
4759		taken = 1;
4760	      else if (GET_CODE (else_dest) == LABEL_REF
4761		       && XEXP (else_dest, 0) == if_true_label)
4762		taken = 0;
4763	      /* Otherwise check where we drop through.  */
4764	      else if (else_dest == pc_rtx)
4765		{
4766		  if (next && NOTE_P (next))
4767		    next = next_nonnote_insn (next);
4768
4769		  if (next && JUMP_P (next)
4770		      && any_uncondjump_p (next))
4771		    temp = XEXP (SET_SRC (pc_set (next)), 0);
4772		  else
4773		    temp = next;
4774
4775		  /* TEMP is either a CODE_LABEL, NULL_RTX or something
4776		     else that can't possibly match either target label.  */
4777		  if (temp == if_false_label)
4778		    taken = 1;
4779		  else if (temp == if_true_label)
4780		    taken = 0;
4781		}
4782	      else if (then_dest == pc_rtx)
4783		{
4784		  if (next && NOTE_P (next))
4785		    next = next_nonnote_insn (next);
4786
4787		  if (next && JUMP_P (next)
4788		      && any_uncondjump_p (next))
4789		    temp = XEXP (SET_SRC (pc_set (next)), 0);
4790		  else
4791		    temp = next;
4792
4793		  if (temp == if_false_label)
4794		    taken = 0;
4795		  else if (temp == if_true_label)
4796		    taken = 1;
4797		}
4798
4799	      if (taken != -1)
4800		{
4801		  /* If the test is expected to fail, reverse the
4802		     probabilities.  */
4803		  if (integer_zerop (arg1))
4804		    taken = 1 - taken;
4805		  predict_insn_def (insn, PRED_BUILTIN_EXPECT, taken);
4806		}
4807	    }
4808
4809	  insn = next;
4810	}
4811    }
4812
4813  return ret;
4814}
4815
4816void
4817expand_builtin_trap (void)
4818{
4819#ifdef HAVE_trap
4820  if (HAVE_trap)
4821    emit_insn (gen_trap ());
4822  else
4823#endif
4824    emit_library_call (abort_libfunc, LCT_NORETURN, VOIDmode, 0);
4825  emit_barrier ();
4826}
4827
4828/* Expand a call to fabs, fabsf or fabsl with arguments ARGLIST.
4829   Return 0 if a normal call should be emitted rather than expanding
4830   the function inline.  If convenient, the result should be placed
4831   in TARGET.  SUBTARGET may be used as the target for computing
4832   the operand.  */
4833
4834static rtx
4835expand_builtin_fabs (tree arglist, rtx target, rtx subtarget)
4836{
4837  enum machine_mode mode;
4838  tree arg;
4839  rtx op0;
4840
4841  if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
4842    return 0;
4843
4844  arg = TREE_VALUE (arglist);
4845  mode = TYPE_MODE (TREE_TYPE (arg));
4846  op0 = expand_expr (arg, subtarget, VOIDmode, 0);
4847  return expand_abs (mode, op0, target, 0, safe_from_p (target, arg, 1));
4848}
4849
4850/* Expand a call to copysign, copysignf, or copysignl with arguments ARGLIST.
4851   Return NULL is a normal call should be emitted rather than expanding the
4852   function inline.  If convenient, the result should be placed in TARGET.
4853   SUBTARGET may be used as the target for computing the operand.  */
4854
4855static rtx
4856expand_builtin_copysign (tree arglist, rtx target, rtx subtarget)
4857{
4858  rtx op0, op1;
4859  tree arg;
4860
4861  if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
4862    return 0;
4863
4864  arg = TREE_VALUE (arglist);
4865  op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL);
4866
4867  arg = TREE_VALUE (TREE_CHAIN (arglist));
4868  op1 = expand_normal (arg);
4869
4870  return expand_copysign (op0, op1, target);
4871}
4872
4873/* Create a new constant string literal and return a char* pointer to it.
4874   The STRING_CST value is the LEN characters at STR.  */
4875tree
4876build_string_literal (int len, const char *str)
4877{
4878  tree t, elem, index, type;
4879
4880  t = build_string (len, str);
4881  elem = build_type_variant (char_type_node, 1, 0);
4882  index = build_index_type (build_int_cst (NULL_TREE, len - 1));
4883  type = build_array_type (elem, index);
4884  TREE_TYPE (t) = type;
4885  TREE_CONSTANT (t) = 1;
4886  TREE_INVARIANT (t) = 1;
4887  TREE_READONLY (t) = 1;
4888  TREE_STATIC (t) = 1;
4889
4890  type = build_pointer_type (type);
4891  t = build1 (ADDR_EXPR, type, t);
4892
4893  type = build_pointer_type (elem);
4894  t = build1 (NOP_EXPR, type, t);
4895  return t;
4896}
4897
4898/* Expand EXP, a call to printf or printf_unlocked.
4899   Return 0 if a normal call should be emitted rather than transforming
4900   the function inline.  If convenient, the result should be placed in
4901   TARGET with mode MODE.  UNLOCKED indicates this is a printf_unlocked
4902   call.  */
4903static rtx
4904expand_builtin_printf (tree exp, rtx target, enum machine_mode mode,
4905		       bool unlocked)
4906{
4907  tree arglist = TREE_OPERAND (exp, 1);
4908  /* If we're using an unlocked function, assume the other unlocked
4909     functions exist explicitly.  */
4910  tree const fn_putchar = unlocked ? built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED]
4911    : implicit_built_in_decls[BUILT_IN_PUTCHAR];
4912  tree const fn_puts = unlocked ? built_in_decls[BUILT_IN_PUTS_UNLOCKED]
4913    : implicit_built_in_decls[BUILT_IN_PUTS];
4914  const char *fmt_str;
4915  tree fn, fmt, arg;
4916
4917  /* If the return value is used, don't do the transformation.  */
4918  if (target != const0_rtx)
4919    return 0;
4920
4921  /* Verify the required arguments in the original call.  */
4922  if (! arglist)
4923    return 0;
4924  fmt = TREE_VALUE (arglist);
4925  if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
4926    return 0;
4927  arglist = TREE_CHAIN (arglist);
4928
4929  /* Check whether the format is a literal string constant.  */
4930  fmt_str = c_getstr (fmt);
4931  if (fmt_str == NULL)
4932    return 0;
4933
4934  if (!init_target_chars())
4935    return 0;
4936
4937  /* If the format specifier was "%s\n", call __builtin_puts(arg).  */
4938  if (strcmp (fmt_str, target_percent_s_newline) == 0)
4939    {
4940      if (! arglist
4941	  || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
4942	  || TREE_CHAIN (arglist))
4943	return 0;
4944      fn = fn_puts;
4945    }
4946  /* If the format specifier was "%c", call __builtin_putchar(arg).  */
4947  else if (strcmp (fmt_str, target_percent_c) == 0)
4948    {
4949      if (! arglist
4950	  || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
4951	  || TREE_CHAIN (arglist))
4952	return 0;
4953      fn = fn_putchar;
4954    }
4955  else
4956    {
4957      /* We can't handle anything else with % args or %% ... yet.  */
4958      if (strchr (fmt_str, target_percent))
4959	return 0;
4960
4961      if (arglist)
4962	return 0;
4963
4964      /* If the format specifier was "", printf does nothing.  */
4965      if (fmt_str[0] == '\0')
4966	return const0_rtx;
4967      /* If the format specifier has length of 1, call putchar.  */
4968      if (fmt_str[1] == '\0')
4969	{
4970	  /* Given printf("c"), (where c is any one character,)
4971	     convert "c"[0] to an int and pass that to the replacement
4972	     function.  */
4973	  arg = build_int_cst (NULL_TREE, fmt_str[0]);
4974	  arglist = build_tree_list (NULL_TREE, arg);
4975	  fn = fn_putchar;
4976	}
4977      else
4978	{
4979	  /* If the format specifier was "string\n", call puts("string").  */
4980	  size_t len = strlen (fmt_str);
4981	  if ((unsigned char)fmt_str[len - 1] == target_newline)
4982	    {
4983	      /* Create a NUL-terminated string that's one char shorter
4984		 than the original, stripping off the trailing '\n'.  */
4985	      char *newstr = alloca (len);
4986	      memcpy (newstr, fmt_str, len - 1);
4987	      newstr[len - 1] = 0;
4988
4989	      arg = build_string_literal (len, newstr);
4990	      arglist = build_tree_list (NULL_TREE, arg);
4991	      fn = fn_puts;
4992	    }
4993	  else
4994	    /* We'd like to arrange to call fputs(string,stdout) here,
4995	       but we need stdout and don't have a way to get it yet.  */
4996	    return 0;
4997	}
4998    }
4999
5000  if (!fn)
5001    return 0;
5002  fn = build_function_call_expr (fn, arglist);
5003  if (TREE_CODE (fn) == CALL_EXPR)
5004    CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
5005  return expand_expr (fn, target, mode, EXPAND_NORMAL);
5006}
5007
5008/* Expand EXP, a call to fprintf or fprintf_unlocked.
5009   Return 0 if a normal call should be emitted rather than transforming
5010   the function inline.  If convenient, the result should be placed in
5011   TARGET with mode MODE.  UNLOCKED indicates this is a fprintf_unlocked
5012   call.  */
5013static rtx
5014expand_builtin_fprintf (tree exp, rtx target, enum machine_mode mode,
5015			bool unlocked)
5016{
5017  tree arglist = TREE_OPERAND (exp, 1);
5018  /* If we're using an unlocked function, assume the other unlocked
5019     functions exist explicitly.  */
5020  tree const fn_fputc = unlocked ? built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
5021    : implicit_built_in_decls[BUILT_IN_FPUTC];
5022  tree const fn_fputs = unlocked ? built_in_decls[BUILT_IN_FPUTS_UNLOCKED]
5023    : implicit_built_in_decls[BUILT_IN_FPUTS];
5024  const char *fmt_str;
5025  tree fn, fmt, fp, arg;
5026
5027  /* If the return value is used, don't do the transformation.  */
5028  if (target != const0_rtx)
5029    return 0;
5030
5031  /* Verify the required arguments in the original call.  */
5032  if (! arglist)
5033    return 0;
5034  fp = TREE_VALUE (arglist);
5035  if (! POINTER_TYPE_P (TREE_TYPE (fp)))
5036    return 0;
5037  arglist = TREE_CHAIN (arglist);
5038  if (! arglist)
5039    return 0;
5040  fmt = TREE_VALUE (arglist);
5041  if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
5042    return 0;
5043  arglist = TREE_CHAIN (arglist);
5044
5045  /* Check whether the format is a literal string constant.  */
5046  fmt_str = c_getstr (fmt);
5047  if (fmt_str == NULL)
5048    return 0;
5049
5050  if (!init_target_chars())
5051    return 0;
5052
5053  /* If the format specifier was "%s", call __builtin_fputs(arg,fp).  */
5054  if (strcmp (fmt_str, target_percent_s) == 0)
5055    {
5056      if (! arglist
5057	  || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
5058	  || TREE_CHAIN (arglist))
5059	return 0;
5060      arg = TREE_VALUE (arglist);
5061      arglist = build_tree_list (NULL_TREE, fp);
5062      arglist = tree_cons (NULL_TREE, arg, arglist);
5063      fn = fn_fputs;
5064    }
5065  /* If the format specifier was "%c", call __builtin_fputc(arg,fp).  */
5066  else if (strcmp (fmt_str, target_percent_c) == 0)
5067    {
5068      if (! arglist
5069	  || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
5070	  || TREE_CHAIN (arglist))
5071	return 0;
5072      arg = TREE_VALUE (arglist);
5073      arglist = build_tree_list (NULL_TREE, fp);
5074      arglist = tree_cons (NULL_TREE, arg, arglist);
5075      fn = fn_fputc;
5076    }
5077  else
5078    {
5079      /* We can't handle anything else with % args or %% ... yet.  */
5080      if (strchr (fmt_str, target_percent))
5081	return 0;
5082
5083      if (arglist)
5084	return 0;
5085
5086      /* If the format specifier was "", fprintf does nothing.  */
5087      if (fmt_str[0] == '\0')
5088	{
5089	  /* Evaluate and ignore FILE* argument for side-effects.  */
5090	  expand_expr (fp, const0_rtx, VOIDmode, EXPAND_NORMAL);
5091	  return const0_rtx;
5092	}
5093
5094      /* When "string" doesn't contain %, replace all cases of
5095	 fprintf(stream,string) with fputs(string,stream).  The fputs
5096	 builtin will take care of special cases like length == 1.  */
5097      arglist = build_tree_list (NULL_TREE, fp);
5098      arglist = tree_cons (NULL_TREE, fmt, arglist);
5099      fn = fn_fputs;
5100    }
5101
5102  if (!fn)
5103    return 0;
5104  fn = build_function_call_expr (fn, arglist);
5105  if (TREE_CODE (fn) == CALL_EXPR)
5106    CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
5107  return expand_expr (fn, target, mode, EXPAND_NORMAL);
5108}
5109
5110/* Expand a call to sprintf with argument list ARGLIST.  Return 0 if
5111   a normal call should be emitted rather than expanding the function
5112   inline.  If convenient, the result should be placed in TARGET with
5113   mode MODE.  */
5114
5115static rtx
5116expand_builtin_sprintf (tree arglist, rtx target, enum machine_mode mode)
5117{
5118  tree orig_arglist, dest, fmt;
5119  const char *fmt_str;
5120
5121  orig_arglist = arglist;
5122
5123  /* Verify the required arguments in the original call.  */
5124  if (! arglist)
5125    return 0;
5126  dest = TREE_VALUE (arglist);
5127  if (! POINTER_TYPE_P (TREE_TYPE (dest)))
5128    return 0;
5129  arglist = TREE_CHAIN (arglist);
5130  if (! arglist)
5131    return 0;
5132  fmt = TREE_VALUE (arglist);
5133  if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
5134    return 0;
5135  arglist = TREE_CHAIN (arglist);
5136
5137  /* Check whether the format is a literal string constant.  */
5138  fmt_str = c_getstr (fmt);
5139  if (fmt_str == NULL)
5140    return 0;
5141
5142  if (!init_target_chars())
5143    return 0;
5144
5145  /* If the format doesn't contain % args or %%, use strcpy.  */
5146  if (strchr (fmt_str, target_percent) == 0)
5147    {
5148      tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
5149      tree exp;
5150
5151      if (arglist || ! fn)
5152	return 0;
5153      expand_expr (build_function_call_expr (fn, orig_arglist),
5154		   const0_rtx, VOIDmode, EXPAND_NORMAL);
5155      if (target == const0_rtx)
5156	return const0_rtx;
5157      exp = build_int_cst (NULL_TREE, strlen (fmt_str));
5158      return expand_expr (exp, target, mode, EXPAND_NORMAL);
5159    }
5160  /* If the format is "%s", use strcpy if the result isn't used.  */
5161  else if (strcmp (fmt_str, target_percent_s) == 0)
5162    {
5163      tree fn, arg, len;
5164      fn = implicit_built_in_decls[BUILT_IN_STRCPY];
5165
5166      if (! fn)
5167	return 0;
5168
5169      if (! arglist || TREE_CHAIN (arglist))
5170	return 0;
5171      arg = TREE_VALUE (arglist);
5172      if (! POINTER_TYPE_P (TREE_TYPE (arg)))
5173	return 0;
5174
5175      if (target != const0_rtx)
5176	{
5177	  len = c_strlen (arg, 1);
5178	  if (! len || TREE_CODE (len) != INTEGER_CST)
5179	    return 0;
5180	}
5181      else
5182	len = NULL_TREE;
5183
5184      arglist = build_tree_list (NULL_TREE, arg);
5185      arglist = tree_cons (NULL_TREE, dest, arglist);
5186      expand_expr (build_function_call_expr (fn, arglist),
5187		   const0_rtx, VOIDmode, EXPAND_NORMAL);
5188
5189      if (target == const0_rtx)
5190	return const0_rtx;
5191      return expand_expr (len, target, mode, EXPAND_NORMAL);
5192    }
5193
5194  return 0;
5195}
5196
5197/* Expand a call to either the entry or exit function profiler.  */
5198
5199static rtx
5200expand_builtin_profile_func (bool exitp)
5201{
5202  rtx this, which;
5203
5204  this = DECL_RTL (current_function_decl);
5205  gcc_assert (MEM_P (this));
5206  this = XEXP (this, 0);
5207
5208  if (exitp)
5209    which = profile_function_exit_libfunc;
5210  else
5211    which = profile_function_entry_libfunc;
5212
5213  emit_library_call (which, LCT_NORMAL, VOIDmode, 2, this, Pmode,
5214		     expand_builtin_return_addr (BUILT_IN_RETURN_ADDRESS,
5215						 0),
5216		     Pmode);
5217
5218  return const0_rtx;
5219}
5220
5221/* Given a trampoline address, make sure it satisfies TRAMPOLINE_ALIGNMENT.  */
5222
5223static rtx
5224round_trampoline_addr (rtx tramp)
5225{
5226  rtx temp, addend, mask;
5227
5228  /* If we don't need too much alignment, we'll have been guaranteed
5229     proper alignment by get_trampoline_type.  */
5230  if (TRAMPOLINE_ALIGNMENT <= STACK_BOUNDARY)
5231    return tramp;
5232
5233  /* Round address up to desired boundary.  */
5234  temp = gen_reg_rtx (Pmode);
5235  addend = GEN_INT (TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT - 1);
5236  mask = GEN_INT (-TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT);
5237
5238  temp  = expand_simple_binop (Pmode, PLUS, tramp, addend,
5239			       temp, 0, OPTAB_LIB_WIDEN);
5240  tramp = expand_simple_binop (Pmode, AND, temp, mask,
5241			       temp, 0, OPTAB_LIB_WIDEN);
5242
5243  return tramp;
5244}
5245
5246static rtx
5247expand_builtin_init_trampoline (tree arglist)
5248{
5249  tree t_tramp, t_func, t_chain;
5250  rtx r_tramp, r_func, r_chain;
5251#ifdef TRAMPOLINE_TEMPLATE
5252  rtx blktramp;
5253#endif
5254
5255  if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE,
5256			 POINTER_TYPE, VOID_TYPE))
5257    return NULL_RTX;
5258
5259  t_tramp = TREE_VALUE (arglist);
5260  arglist = TREE_CHAIN (arglist);
5261  t_func = TREE_VALUE (arglist);
5262  arglist = TREE_CHAIN (arglist);
5263  t_chain = TREE_VALUE (arglist);
5264
5265  r_tramp = expand_normal (t_tramp);
5266  r_func = expand_normal (t_func);
5267  r_chain = expand_normal (t_chain);
5268
5269  /* Generate insns to initialize the trampoline.  */
5270  r_tramp = round_trampoline_addr (r_tramp);
5271#ifdef TRAMPOLINE_TEMPLATE
5272  blktramp = gen_rtx_MEM (BLKmode, r_tramp);
5273  set_mem_align (blktramp, TRAMPOLINE_ALIGNMENT);
5274  emit_block_move (blktramp, assemble_trampoline_template (),
5275		   GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL);
5276#endif
5277  trampolines_created = 1;
5278  INITIALIZE_TRAMPOLINE (r_tramp, r_func, r_chain);
5279
5280  return const0_rtx;
5281}
5282
5283static rtx
5284expand_builtin_adjust_trampoline (tree arglist)
5285{
5286  rtx tramp;
5287
5288  if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5289    return NULL_RTX;
5290
5291  tramp = expand_normal (TREE_VALUE (arglist));
5292  tramp = round_trampoline_addr (tramp);
5293#ifdef TRAMPOLINE_ADJUST_ADDRESS
5294  TRAMPOLINE_ADJUST_ADDRESS (tramp);
5295#endif
5296
5297  return tramp;
5298}
5299
5300/* Expand a call to the built-in signbit, signbitf or signbitl function.
5301   Return NULL_RTX if a normal call should be emitted rather than expanding
5302   the function in-line.  EXP is the expression that is a call to the builtin
5303   function; if convenient, the result should be placed in TARGET.  */
5304
5305static rtx
5306expand_builtin_signbit (tree exp, rtx target)
5307{
5308  const struct real_format *fmt;
5309  enum machine_mode fmode, imode, rmode;
5310  HOST_WIDE_INT hi, lo;
5311  tree arg, arglist;
5312  int word, bitpos;
5313  rtx temp;
5314
5315  arglist = TREE_OPERAND (exp, 1);
5316  if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
5317    return 0;
5318
5319  arg = TREE_VALUE (arglist);
5320  fmode = TYPE_MODE (TREE_TYPE (arg));
5321  rmode = TYPE_MODE (TREE_TYPE (exp));
5322  fmt = REAL_MODE_FORMAT (fmode);
5323
5324  /* For floating point formats without a sign bit, implement signbit
5325     as "ARG < 0.0".  */
5326  bitpos = fmt->signbit_ro;
5327  if (bitpos < 0)
5328  {
5329    /* But we can't do this if the format supports signed zero.  */
5330    if (fmt->has_signed_zero && HONOR_SIGNED_ZEROS (fmode))
5331      return 0;
5332
5333    arg = fold_build2 (LT_EXPR, TREE_TYPE (exp), arg,
5334		       build_real (TREE_TYPE (arg), dconst0));
5335    return expand_expr (arg, target, VOIDmode, EXPAND_NORMAL);
5336  }
5337
5338  temp = expand_normal (arg);
5339  if (GET_MODE_SIZE (fmode) <= UNITS_PER_WORD)
5340    {
5341      imode = int_mode_for_mode (fmode);
5342      if (imode == BLKmode)
5343	return 0;
5344      temp = gen_lowpart (imode, temp);
5345    }
5346  else
5347    {
5348      imode = word_mode;
5349      /* Handle targets with different FP word orders.  */
5350      if (FLOAT_WORDS_BIG_ENDIAN)
5351	word = (GET_MODE_BITSIZE (fmode) - bitpos) / BITS_PER_WORD;
5352      else
5353	word = bitpos / BITS_PER_WORD;
5354      temp = operand_subword_force (temp, word, fmode);
5355      bitpos = bitpos % BITS_PER_WORD;
5356    }
5357
5358  /* Force the intermediate word_mode (or narrower) result into a
5359     register.  This avoids attempting to create paradoxical SUBREGs
5360     of floating point modes below.  */
5361  temp = force_reg (imode, temp);
5362
5363  /* If the bitpos is within the "result mode" lowpart, the operation
5364     can be implement with a single bitwise AND.  Otherwise, we need
5365     a right shift and an AND.  */
5366
5367  if (bitpos < GET_MODE_BITSIZE (rmode))
5368    {
5369      if (bitpos < HOST_BITS_PER_WIDE_INT)
5370	{
5371	  hi = 0;
5372	  lo = (HOST_WIDE_INT) 1 << bitpos;
5373	}
5374      else
5375	{
5376	  hi = (HOST_WIDE_INT) 1 << (bitpos - HOST_BITS_PER_WIDE_INT);
5377	  lo = 0;
5378	}
5379
5380      if (imode != rmode)
5381	temp = gen_lowpart (rmode, temp);
5382      temp = expand_binop (rmode, and_optab, temp,
5383			   immed_double_const (lo, hi, rmode),
5384			   NULL_RTX, 1, OPTAB_LIB_WIDEN);
5385    }
5386  else
5387    {
5388      /* Perform a logical right shift to place the signbit in the least
5389	 significant bit, then truncate the result to the desired mode
5390	 and mask just this bit.  */
5391      temp = expand_shift (RSHIFT_EXPR, imode, temp,
5392			   build_int_cst (NULL_TREE, bitpos), NULL_RTX, 1);
5393      temp = gen_lowpart (rmode, temp);
5394      temp = expand_binop (rmode, and_optab, temp, const1_rtx,
5395			   NULL_RTX, 1, OPTAB_LIB_WIDEN);
5396    }
5397
5398  return temp;
5399}
5400
5401/* Expand fork or exec calls.  TARGET is the desired target of the
5402   call.  ARGLIST is the list of arguments of the call.  FN is the
5403   identificator of the actual function.  IGNORE is nonzero if the
5404   value is to be ignored.  */
5405
5406static rtx
5407expand_builtin_fork_or_exec (tree fn, tree arglist, rtx target, int ignore)
5408{
5409  tree id, decl;
5410  tree call;
5411
5412  /* If we are not profiling, just call the function.  */
5413  if (!profile_arc_flag)
5414    return NULL_RTX;
5415
5416  /* Otherwise call the wrapper.  This should be equivalent for the rest of
5417     compiler, so the code does not diverge, and the wrapper may run the
5418     code necessary for keeping the profiling sane.  */
5419
5420  switch (DECL_FUNCTION_CODE (fn))
5421    {
5422    case BUILT_IN_FORK:
5423      id = get_identifier ("__gcov_fork");
5424      break;
5425
5426    case BUILT_IN_EXECL:
5427      id = get_identifier ("__gcov_execl");
5428      break;
5429
5430    case BUILT_IN_EXECV:
5431      id = get_identifier ("__gcov_execv");
5432      break;
5433
5434    case BUILT_IN_EXECLP:
5435      id = get_identifier ("__gcov_execlp");
5436      break;
5437
5438    case BUILT_IN_EXECLE:
5439      id = get_identifier ("__gcov_execle");
5440      break;
5441
5442    case BUILT_IN_EXECVP:
5443      id = get_identifier ("__gcov_execvp");
5444      break;
5445
5446    case BUILT_IN_EXECVE:
5447      id = get_identifier ("__gcov_execve");
5448      break;
5449
5450    default:
5451      gcc_unreachable ();
5452    }
5453
5454  decl = build_decl (FUNCTION_DECL, id, TREE_TYPE (fn));
5455  DECL_EXTERNAL (decl) = 1;
5456  TREE_PUBLIC (decl) = 1;
5457  DECL_ARTIFICIAL (decl) = 1;
5458  TREE_NOTHROW (decl) = 1;
5459  DECL_VISIBILITY (decl) = VISIBILITY_DEFAULT;
5460  DECL_VISIBILITY_SPECIFIED (decl) = 1;
5461  call = build_function_call_expr (decl, arglist);
5462
5463  return expand_call (call, target, ignore);
5464}
5465
5466
5467/* Reconstitute a mode for a __sync intrinsic operation.  Since the type of
5468   the pointer in these functions is void*, the tree optimizers may remove
5469   casts.  The mode computed in expand_builtin isn't reliable either, due
5470   to __sync_bool_compare_and_swap.
5471
5472   FCODE_DIFF should be fcode - base, where base is the FOO_1 code for the
5473   group of builtins.  This gives us log2 of the mode size.  */
5474
5475static inline enum machine_mode
5476get_builtin_sync_mode (int fcode_diff)
5477{
5478  /* The size is not negotiable, so ask not to get BLKmode in return
5479     if the target indicates that a smaller size would be better.  */
5480  return mode_for_size (BITS_PER_UNIT << fcode_diff, MODE_INT, 0);
5481}
5482
5483/* Expand the memory expression LOC and return the appropriate memory operand
5484   for the builtin_sync operations.  */
5485
5486static rtx
5487get_builtin_sync_mem (tree loc, enum machine_mode mode)
5488{
5489  rtx addr, mem;
5490
5491  addr = expand_expr (loc, NULL, Pmode, EXPAND_SUM);
5492
5493  /* Note that we explicitly do not want any alias information for this
5494     memory, so that we kill all other live memories.  Otherwise we don't
5495     satisfy the full barrier semantics of the intrinsic.  */
5496  mem = validize_mem (gen_rtx_MEM (mode, addr));
5497
5498  set_mem_align (mem, get_pointer_alignment (loc, BIGGEST_ALIGNMENT));
5499  set_mem_alias_set (mem, ALIAS_SET_MEMORY_BARRIER);
5500  MEM_VOLATILE_P (mem) = 1;
5501
5502  return mem;
5503}
5504
5505/* Expand the __sync_xxx_and_fetch and __sync_fetch_and_xxx intrinsics.
5506   ARGLIST is the operands list to the function.  CODE is the rtx code
5507   that corresponds to the arithmetic or logical operation from the name;
5508   an exception here is that NOT actually means NAND.  TARGET is an optional
5509   place for us to store the results; AFTER is true if this is the
5510   fetch_and_xxx form.  IGNORE is true if we don't actually care about
5511   the result of the operation at all.  */
5512
5513static rtx
5514expand_builtin_sync_operation (enum machine_mode mode, tree arglist,
5515			       enum rtx_code code, bool after,
5516			       rtx target, bool ignore)
5517{
5518  rtx val, mem;
5519  enum machine_mode old_mode;
5520
5521  /* Expand the operands.  */
5522  mem = get_builtin_sync_mem (TREE_VALUE (arglist), mode);
5523
5524  arglist = TREE_CHAIN (arglist);
5525  val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
5526  /* If VAL is promoted to a wider mode, convert it back to MODE.  Take care
5527     of CONST_INTs, where we know the old_mode only from the call argument.  */
5528  old_mode = GET_MODE (val);
5529  if (old_mode == VOIDmode)
5530    old_mode = TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist)));
5531  val = convert_modes (mode, old_mode, val, 1);
5532
5533  if (ignore)
5534    return expand_sync_operation (mem, val, code);
5535  else
5536    return expand_sync_fetch_operation (mem, val, code, after, target);
5537}
5538
5539/* Expand the __sync_val_compare_and_swap and __sync_bool_compare_and_swap
5540   intrinsics.  ARGLIST is the operands list to the function.  IS_BOOL is
5541   true if this is the boolean form.  TARGET is a place for us to store the
5542   results; this is NOT optional if IS_BOOL is true.  */
5543
5544static rtx
5545expand_builtin_compare_and_swap (enum machine_mode mode, tree arglist,
5546				 bool is_bool, rtx target)
5547{
5548  rtx old_val, new_val, mem;
5549  enum machine_mode old_mode;
5550
5551  /* Expand the operands.  */
5552  mem = get_builtin_sync_mem (TREE_VALUE (arglist), mode);
5553
5554  arglist = TREE_CHAIN (arglist);
5555  old_val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
5556  /* If VAL is promoted to a wider mode, convert it back to MODE.  Take care
5557     of CONST_INTs, where we know the old_mode only from the call argument.  */
5558  old_mode = GET_MODE (old_val);
5559  if (old_mode == VOIDmode)
5560    old_mode = TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist)));
5561  old_val = convert_modes (mode, old_mode, old_val, 1);
5562
5563  arglist = TREE_CHAIN (arglist);
5564  new_val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
5565  /* If VAL is promoted to a wider mode, convert it back to MODE.  Take care
5566     of CONST_INTs, where we know the old_mode only from the call argument.  */
5567  old_mode = GET_MODE (new_val);
5568  if (old_mode == VOIDmode)
5569    old_mode = TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist)));
5570  new_val = convert_modes (mode, old_mode, new_val, 1);
5571
5572  if (is_bool)
5573    return expand_bool_compare_and_swap (mem, old_val, new_val, target);
5574  else
5575    return expand_val_compare_and_swap (mem, old_val, new_val, target);
5576}
5577
5578/* Expand the __sync_lock_test_and_set intrinsic.  Note that the most
5579   general form is actually an atomic exchange, and some targets only
5580   support a reduced form with the second argument being a constant 1.
5581   ARGLIST is the operands list to the function; TARGET is an optional
5582   place for us to store the results.  */
5583
5584static rtx
5585expand_builtin_lock_test_and_set (enum machine_mode mode, tree arglist,
5586				  rtx target)
5587{
5588  rtx val, mem;
5589  enum machine_mode old_mode;
5590
5591  /* Expand the operands.  */
5592  mem = get_builtin_sync_mem (TREE_VALUE (arglist), mode);
5593
5594  arglist = TREE_CHAIN (arglist);
5595  val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
5596  /* If VAL is promoted to a wider mode, convert it back to MODE.  Take care
5597     of CONST_INTs, where we know the old_mode only from the call argument.  */
5598  old_mode = GET_MODE (val);
5599  if (old_mode == VOIDmode)
5600    old_mode = TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist)));
5601  val = convert_modes (mode, old_mode, val, 1);
5602
5603  return expand_sync_lock_test_and_set (mem, val, target);
5604}
5605
5606/* Expand the __sync_synchronize intrinsic.  */
5607
5608static void
5609expand_builtin_synchronize (void)
5610{
5611  tree x;
5612
5613#ifdef HAVE_memory_barrier
5614  if (HAVE_memory_barrier)
5615    {
5616      emit_insn (gen_memory_barrier ());
5617      return;
5618    }
5619#endif
5620
5621  /* If no explicit memory barrier instruction is available, create an
5622     empty asm stmt with a memory clobber.  */
5623  x = build4 (ASM_EXPR, void_type_node, build_string (0, ""), NULL, NULL,
5624	      tree_cons (NULL, build_string (6, "memory"), NULL));
5625  ASM_VOLATILE_P (x) = 1;
5626  expand_asm_expr (x);
5627}
5628
5629/* Expand the __sync_lock_release intrinsic.  ARGLIST is the operands list
5630   to the function.  */
5631
5632static void
5633expand_builtin_lock_release (enum machine_mode mode, tree arglist)
5634{
5635  enum insn_code icode;
5636  rtx mem, insn;
5637  rtx val = const0_rtx;
5638
5639  /* Expand the operands.  */
5640  mem = get_builtin_sync_mem (TREE_VALUE (arglist), mode);
5641
5642  /* If there is an explicit operation in the md file, use it.  */
5643  icode = sync_lock_release[mode];
5644  if (icode != CODE_FOR_nothing)
5645    {
5646      if (!insn_data[icode].operand[1].predicate (val, mode))
5647	val = force_reg (mode, val);
5648
5649      insn = GEN_FCN (icode) (mem, val);
5650      if (insn)
5651	{
5652	  emit_insn (insn);
5653	  return;
5654	}
5655    }
5656
5657  /* Otherwise we can implement this operation by emitting a barrier
5658     followed by a store of zero.  */
5659  expand_builtin_synchronize ();
5660  emit_move_insn (mem, val);
5661}
5662
5663/* Expand an expression EXP that calls a built-in function,
5664   with result going to TARGET if that's convenient
5665   (and in mode MODE if that's convenient).
5666   SUBTARGET may be used as the target for computing one of EXP's operands.
5667   IGNORE is nonzero if the value is to be ignored.  */
5668
5669rtx
5670expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
5671		int ignore)
5672{
5673  tree fndecl = get_callee_fndecl (exp);
5674  tree arglist = TREE_OPERAND (exp, 1);
5675  enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
5676  enum machine_mode target_mode = TYPE_MODE (TREE_TYPE (exp));
5677
5678  if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
5679    return targetm.expand_builtin (exp, target, subtarget, mode, ignore);
5680
5681  /* When not optimizing, generate calls to library functions for a certain
5682     set of builtins.  */
5683  if (!optimize
5684      && !called_as_built_in (fndecl)
5685      && DECL_ASSEMBLER_NAME_SET_P (fndecl)
5686      && fcode != BUILT_IN_ALLOCA)
5687    return expand_call (exp, target, ignore);
5688
5689  /* The built-in function expanders test for target == const0_rtx
5690     to determine whether the function's result will be ignored.  */
5691  if (ignore)
5692    target = const0_rtx;
5693
5694  /* If the result of a pure or const built-in function is ignored, and
5695     none of its arguments are volatile, we can avoid expanding the
5696     built-in call and just evaluate the arguments for side-effects.  */
5697  if (target == const0_rtx
5698      && (DECL_IS_PURE (fndecl) || TREE_READONLY (fndecl)))
5699    {
5700      bool volatilep = false;
5701      tree arg;
5702
5703      for (arg = arglist; arg; arg = TREE_CHAIN (arg))
5704	if (TREE_THIS_VOLATILE (TREE_VALUE (arg)))
5705	  {
5706	    volatilep = true;
5707	    break;
5708	  }
5709
5710      if (! volatilep)
5711	{
5712	  for (arg = arglist; arg; arg = TREE_CHAIN (arg))
5713	    expand_expr (TREE_VALUE (arg), const0_rtx,
5714			 VOIDmode, EXPAND_NORMAL);
5715	  return const0_rtx;
5716	}
5717    }
5718
5719  switch (fcode)
5720    {
5721    CASE_FLT_FN (BUILT_IN_FABS):
5722      target = expand_builtin_fabs (arglist, target, subtarget);
5723      if (target)
5724	return target;
5725      break;
5726
5727    CASE_FLT_FN (BUILT_IN_COPYSIGN):
5728      target = expand_builtin_copysign (arglist, target, subtarget);
5729      if (target)
5730	return target;
5731      break;
5732
5733      /* Just do a normal library call if we were unable to fold
5734	 the values.  */
5735    CASE_FLT_FN (BUILT_IN_CABS):
5736      break;
5737
5738    CASE_FLT_FN (BUILT_IN_EXP):
5739    CASE_FLT_FN (BUILT_IN_EXP10):
5740    CASE_FLT_FN (BUILT_IN_POW10):
5741    CASE_FLT_FN (BUILT_IN_EXP2):
5742    CASE_FLT_FN (BUILT_IN_EXPM1):
5743    CASE_FLT_FN (BUILT_IN_LOGB):
5744    CASE_FLT_FN (BUILT_IN_ILOGB):
5745    CASE_FLT_FN (BUILT_IN_LOG):
5746    CASE_FLT_FN (BUILT_IN_LOG10):
5747    CASE_FLT_FN (BUILT_IN_LOG2):
5748    CASE_FLT_FN (BUILT_IN_LOG1P):
5749    CASE_FLT_FN (BUILT_IN_TAN):
5750    CASE_FLT_FN (BUILT_IN_ASIN):
5751    CASE_FLT_FN (BUILT_IN_ACOS):
5752    CASE_FLT_FN (BUILT_IN_ATAN):
5753      /* Treat these like sqrt only if unsafe math optimizations are allowed,
5754	 because of possible accuracy problems.  */
5755      if (! flag_unsafe_math_optimizations)
5756	break;
5757    CASE_FLT_FN (BUILT_IN_SQRT):
5758    CASE_FLT_FN (BUILT_IN_FLOOR):
5759    CASE_FLT_FN (BUILT_IN_CEIL):
5760    CASE_FLT_FN (BUILT_IN_TRUNC):
5761    CASE_FLT_FN (BUILT_IN_ROUND):
5762    CASE_FLT_FN (BUILT_IN_NEARBYINT):
5763    CASE_FLT_FN (BUILT_IN_RINT):
5764    CASE_FLT_FN (BUILT_IN_LRINT):
5765    CASE_FLT_FN (BUILT_IN_LLRINT):
5766      target = expand_builtin_mathfn (exp, target, subtarget);
5767      if (target)
5768	return target;
5769      break;
5770
5771    CASE_FLT_FN (BUILT_IN_LCEIL):
5772    CASE_FLT_FN (BUILT_IN_LLCEIL):
5773    CASE_FLT_FN (BUILT_IN_LFLOOR):
5774    CASE_FLT_FN (BUILT_IN_LLFLOOR):
5775      target = expand_builtin_int_roundingfn (exp, target, subtarget);
5776      if (target)
5777	return target;
5778      break;
5779
5780    CASE_FLT_FN (BUILT_IN_POW):
5781      target = expand_builtin_pow (exp, target, subtarget);
5782      if (target)
5783	return target;
5784      break;
5785
5786    CASE_FLT_FN (BUILT_IN_POWI):
5787      target = expand_builtin_powi (exp, target, subtarget);
5788      if (target)
5789	return target;
5790      break;
5791
5792    CASE_FLT_FN (BUILT_IN_ATAN2):
5793    CASE_FLT_FN (BUILT_IN_LDEXP):
5794    CASE_FLT_FN (BUILT_IN_FMOD):
5795    CASE_FLT_FN (BUILT_IN_DREM):
5796      if (! flag_unsafe_math_optimizations)
5797	break;
5798      target = expand_builtin_mathfn_2 (exp, target, subtarget);
5799      if (target)
5800	return target;
5801      break;
5802
5803    CASE_FLT_FN (BUILT_IN_SIN):
5804    CASE_FLT_FN (BUILT_IN_COS):
5805      if (! flag_unsafe_math_optimizations)
5806	break;
5807      target = expand_builtin_mathfn_3 (exp, target, subtarget);
5808      if (target)
5809	return target;
5810      break;
5811
5812    CASE_FLT_FN (BUILT_IN_SINCOS):
5813      if (! flag_unsafe_math_optimizations)
5814	break;
5815      target = expand_builtin_sincos (exp);
5816      if (target)
5817	return target;
5818      break;
5819
5820    case BUILT_IN_APPLY_ARGS:
5821      return expand_builtin_apply_args ();
5822
5823      /* __builtin_apply (FUNCTION, ARGUMENTS, ARGSIZE) invokes
5824	 FUNCTION with a copy of the parameters described by
5825	 ARGUMENTS, and ARGSIZE.  It returns a block of memory
5826	 allocated on the stack into which is stored all the registers
5827	 that might possibly be used for returning the result of a
5828	 function.  ARGUMENTS is the value returned by
5829	 __builtin_apply_args.  ARGSIZE is the number of bytes of
5830	 arguments that must be copied.  ??? How should this value be
5831	 computed?  We'll also need a safe worst case value for varargs
5832	 functions.  */
5833    case BUILT_IN_APPLY:
5834      if (!validate_arglist (arglist, POINTER_TYPE,
5835			     POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)
5836	  && !validate_arglist (arglist, REFERENCE_TYPE,
5837				POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
5838	return const0_rtx;
5839      else
5840	{
5841	  int i;
5842	  tree t;
5843	  rtx ops[3];
5844
5845	  for (t = arglist, i = 0; t; t = TREE_CHAIN (t), i++)
5846	    ops[i] = expand_normal (TREE_VALUE (t));
5847
5848	  return expand_builtin_apply (ops[0], ops[1], ops[2]);
5849	}
5850
5851      /* __builtin_return (RESULT) causes the function to return the
5852	 value described by RESULT.  RESULT is address of the block of
5853	 memory returned by __builtin_apply.  */
5854    case BUILT_IN_RETURN:
5855      if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5856	expand_builtin_return (expand_normal (TREE_VALUE (arglist)));
5857      return const0_rtx;
5858
5859    case BUILT_IN_SAVEREGS:
5860      return expand_builtin_saveregs ();
5861
5862    case BUILT_IN_ARGS_INFO:
5863      return expand_builtin_args_info (arglist);
5864
5865      /* Return the address of the first anonymous stack arg.  */
5866    case BUILT_IN_NEXT_ARG:
5867      if (fold_builtin_next_arg (arglist))
5868	return const0_rtx;
5869      return expand_builtin_next_arg ();
5870
5871    case BUILT_IN_CLASSIFY_TYPE:
5872      return expand_builtin_classify_type (arglist);
5873
5874    case BUILT_IN_CONSTANT_P:
5875      return const0_rtx;
5876
5877    case BUILT_IN_FRAME_ADDRESS:
5878    case BUILT_IN_RETURN_ADDRESS:
5879      return expand_builtin_frame_address (fndecl, arglist);
5880
5881    /* Returns the address of the area where the structure is returned.
5882       0 otherwise.  */
5883    case BUILT_IN_AGGREGATE_INCOMING_ADDRESS:
5884      if (arglist != 0
5885	  || ! AGGREGATE_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl)))
5886	  || !MEM_P (DECL_RTL (DECL_RESULT (current_function_decl))))
5887	return const0_rtx;
5888      else
5889	return XEXP (DECL_RTL (DECL_RESULT (current_function_decl)), 0);
5890
5891    case BUILT_IN_ALLOCA:
5892      target = expand_builtin_alloca (arglist, target);
5893      if (target)
5894	return target;
5895      break;
5896
5897    case BUILT_IN_STACK_SAVE:
5898      return expand_stack_save ();
5899
5900    case BUILT_IN_STACK_RESTORE:
5901      expand_stack_restore (TREE_VALUE (arglist));
5902      return const0_rtx;
5903
5904    case BUILT_IN_BSWAP32:
5905    case BUILT_IN_BSWAP64:
5906      target = expand_builtin_bswap (arglist, target, subtarget);
5907
5908      if (target)
5909	return target;
5910      break;
5911
5912    CASE_INT_FN (BUILT_IN_FFS):
5913    case BUILT_IN_FFSIMAX:
5914      target = expand_builtin_unop (target_mode, arglist, target,
5915				    subtarget, ffs_optab);
5916      if (target)
5917	return target;
5918      break;
5919
5920    CASE_INT_FN (BUILT_IN_CLZ):
5921    case BUILT_IN_CLZIMAX:
5922      target = expand_builtin_unop (target_mode, arglist, target,
5923				    subtarget, clz_optab);
5924      if (target)
5925	return target;
5926      break;
5927
5928    CASE_INT_FN (BUILT_IN_CTZ):
5929    case BUILT_IN_CTZIMAX:
5930      target = expand_builtin_unop (target_mode, arglist, target,
5931				    subtarget, ctz_optab);
5932      if (target)
5933	return target;
5934      break;
5935
5936    CASE_INT_FN (BUILT_IN_POPCOUNT):
5937    case BUILT_IN_POPCOUNTIMAX:
5938      target = expand_builtin_unop (target_mode, arglist, target,
5939				    subtarget, popcount_optab);
5940      if (target)
5941	return target;
5942      break;
5943
5944    CASE_INT_FN (BUILT_IN_PARITY):
5945    case BUILT_IN_PARITYIMAX:
5946      target = expand_builtin_unop (target_mode, arglist, target,
5947				    subtarget, parity_optab);
5948      if (target)
5949	return target;
5950      break;
5951
5952    case BUILT_IN_STRLEN:
5953      target = expand_builtin_strlen (arglist, target, target_mode);
5954      if (target)
5955	return target;
5956      break;
5957
5958    case BUILT_IN_STRCPY:
5959      target = expand_builtin_strcpy (fndecl, arglist, target, mode);
5960      if (target)
5961	return target;
5962      break;
5963
5964    case BUILT_IN_STRNCPY:
5965      target = expand_builtin_strncpy (exp, target, mode);
5966      if (target)
5967	return target;
5968      break;
5969
5970    case BUILT_IN_STPCPY:
5971      target = expand_builtin_stpcpy (exp, target, mode);
5972      if (target)
5973	return target;
5974      break;
5975
5976    case BUILT_IN_STRCAT:
5977      target = expand_builtin_strcat (fndecl, arglist, target, mode);
5978      if (target)
5979	return target;
5980      break;
5981
5982    case BUILT_IN_STRNCAT:
5983      target = expand_builtin_strncat (arglist, target, mode);
5984      if (target)
5985	return target;
5986      break;
5987
5988    case BUILT_IN_STRSPN:
5989      target = expand_builtin_strspn (arglist, target, mode);
5990      if (target)
5991	return target;
5992      break;
5993
5994    case BUILT_IN_STRCSPN:
5995      target = expand_builtin_strcspn (arglist, target, mode);
5996      if (target)
5997	return target;
5998      break;
5999
6000    case BUILT_IN_STRSTR:
6001      target = expand_builtin_strstr (arglist, TREE_TYPE (exp), target, mode);
6002      if (target)
6003	return target;
6004      break;
6005
6006    case BUILT_IN_STRPBRK:
6007      target = expand_builtin_strpbrk (arglist, TREE_TYPE (exp), target, mode);
6008      if (target)
6009	return target;
6010      break;
6011
6012    case BUILT_IN_INDEX:
6013    case BUILT_IN_STRCHR:
6014      target = expand_builtin_strchr (arglist, TREE_TYPE (exp), target, mode);
6015      if (target)
6016	return target;
6017      break;
6018
6019    case BUILT_IN_RINDEX:
6020    case BUILT_IN_STRRCHR:
6021      target = expand_builtin_strrchr (arglist, TREE_TYPE (exp), target, mode);
6022      if (target)
6023	return target;
6024      break;
6025
6026    case BUILT_IN_MEMCPY:
6027      target = expand_builtin_memcpy (exp, target, mode);
6028      if (target)
6029	return target;
6030      break;
6031
6032    case BUILT_IN_MEMPCPY:
6033      target = expand_builtin_mempcpy (arglist, TREE_TYPE (exp), target, mode, /*endp=*/ 1);
6034      if (target)
6035	return target;
6036      break;
6037
6038    case BUILT_IN_MEMMOVE:
6039      target = expand_builtin_memmove (arglist, TREE_TYPE (exp), target,
6040				       mode, exp);
6041      if (target)
6042	return target;
6043      break;
6044
6045    case BUILT_IN_BCOPY:
6046      target = expand_builtin_bcopy (exp);
6047      if (target)
6048	return target;
6049      break;
6050
6051    case BUILT_IN_MEMSET:
6052      target = expand_builtin_memset (arglist, target, mode, exp);
6053      if (target)
6054	return target;
6055      break;
6056
6057    case BUILT_IN_BZERO:
6058      target = expand_builtin_bzero (exp);
6059      if (target)
6060	return target;
6061      break;
6062
6063    case BUILT_IN_STRCMP:
6064      target = expand_builtin_strcmp (exp, target, mode);
6065      if (target)
6066	return target;
6067      break;
6068
6069    case BUILT_IN_STRNCMP:
6070      target = expand_builtin_strncmp (exp, target, mode);
6071      if (target)
6072	return target;
6073      break;
6074
6075    case BUILT_IN_BCMP:
6076    case BUILT_IN_MEMCMP:
6077      target = expand_builtin_memcmp (exp, arglist, target, mode);
6078      if (target)
6079	return target;
6080      break;
6081
6082    case BUILT_IN_SETJMP:
6083      /* This should have been lowered to the builtins below.  */
6084      gcc_unreachable ();
6085
6086    case BUILT_IN_SETJMP_SETUP:
6087      /* __builtin_setjmp_setup is passed a pointer to an array of five words
6088          and the receiver label.  */
6089      if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
6090	{
6091	  rtx buf_addr = expand_expr (TREE_VALUE (arglist), subtarget,
6092				      VOIDmode, EXPAND_NORMAL);
6093	  tree label = TREE_OPERAND (TREE_VALUE (TREE_CHAIN (arglist)), 0);
6094	  rtx label_r = label_rtx (label);
6095
6096	  /* This is copied from the handling of non-local gotos.  */
6097	  expand_builtin_setjmp_setup (buf_addr, label_r);
6098	  nonlocal_goto_handler_labels
6099	    = gen_rtx_EXPR_LIST (VOIDmode, label_r,
6100				 nonlocal_goto_handler_labels);
6101	  /* ??? Do not let expand_label treat us as such since we would
6102	     not want to be both on the list of non-local labels and on
6103	     the list of forced labels.  */
6104	  FORCED_LABEL (label) = 0;
6105	  return const0_rtx;
6106	}
6107      break;
6108
6109    case BUILT_IN_SETJMP_DISPATCHER:
6110       /* __builtin_setjmp_dispatcher is passed the dispatcher label.  */
6111      if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6112	{
6113	  tree label = TREE_OPERAND (TREE_VALUE (arglist), 0);
6114	  rtx label_r = label_rtx (label);
6115
6116	  /* Remove the dispatcher label from the list of non-local labels
6117	     since the receiver labels have been added to it above.  */
6118	  remove_node_from_expr_list (label_r, &nonlocal_goto_handler_labels);
6119	  return const0_rtx;
6120	}
6121      break;
6122
6123    case BUILT_IN_SETJMP_RECEIVER:
6124       /* __builtin_setjmp_receiver is passed the receiver label.  */
6125      if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6126	{
6127	  tree label = TREE_OPERAND (TREE_VALUE (arglist), 0);
6128	  rtx label_r = label_rtx (label);
6129
6130	  expand_builtin_setjmp_receiver (label_r);
6131	  return const0_rtx;
6132	}
6133      break;
6134
6135      /* __builtin_longjmp is passed a pointer to an array of five words.
6136	 It's similar to the C library longjmp function but works with
6137	 __builtin_setjmp above.  */
6138    case BUILT_IN_LONGJMP:
6139      if (validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
6140	{
6141	  rtx buf_addr = expand_expr (TREE_VALUE (arglist), subtarget,
6142				      VOIDmode, EXPAND_NORMAL);
6143	  rtx value = expand_normal (TREE_VALUE (TREE_CHAIN (arglist)));
6144
6145	  if (value != const1_rtx)
6146	    {
6147	      error ("%<__builtin_longjmp%> second argument must be 1");
6148	      return const0_rtx;
6149	    }
6150
6151	  expand_builtin_longjmp (buf_addr, value);
6152	  return const0_rtx;
6153	}
6154      break;
6155
6156    case BUILT_IN_NONLOCAL_GOTO:
6157      target = expand_builtin_nonlocal_goto (arglist);
6158      if (target)
6159	return target;
6160      break;
6161
6162      /* This updates the setjmp buffer that is its argument with the value
6163	 of the current stack pointer.  */
6164    case BUILT_IN_UPDATE_SETJMP_BUF:
6165      if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6166	{
6167	  rtx buf_addr
6168	    = expand_normal (TREE_VALUE (arglist));
6169
6170	  expand_builtin_update_setjmp_buf (buf_addr);
6171	  return const0_rtx;
6172	}
6173      break;
6174
6175    case BUILT_IN_TRAP:
6176      expand_builtin_trap ();
6177      return const0_rtx;
6178
6179    case BUILT_IN_PRINTF:
6180      target = expand_builtin_printf (exp, target, mode, false);
6181      if (target)
6182	return target;
6183      break;
6184
6185    case BUILT_IN_PRINTF_UNLOCKED:
6186      target = expand_builtin_printf (exp, target, mode, true);
6187      if (target)
6188	return target;
6189      break;
6190
6191    case BUILT_IN_FPUTS:
6192      target = expand_builtin_fputs (arglist, target, false);
6193      if (target)
6194	return target;
6195      break;
6196    case BUILT_IN_FPUTS_UNLOCKED:
6197      target = expand_builtin_fputs (arglist, target, true);
6198      if (target)
6199	return target;
6200      break;
6201
6202    case BUILT_IN_FPRINTF:
6203      target = expand_builtin_fprintf (exp, target, mode, false);
6204      if (target)
6205	return target;
6206      break;
6207
6208    case BUILT_IN_FPRINTF_UNLOCKED:
6209      target = expand_builtin_fprintf (exp, target, mode, true);
6210      if (target)
6211	return target;
6212      break;
6213
6214    case BUILT_IN_SPRINTF:
6215      target = expand_builtin_sprintf (arglist, target, mode);
6216      if (target)
6217	return target;
6218      break;
6219
6220    CASE_FLT_FN (BUILT_IN_SIGNBIT):
6221      target = expand_builtin_signbit (exp, target);
6222      if (target)
6223	return target;
6224      break;
6225
6226      /* Various hooks for the DWARF 2 __throw routine.  */
6227    case BUILT_IN_UNWIND_INIT:
6228      expand_builtin_unwind_init ();
6229      return const0_rtx;
6230    case BUILT_IN_DWARF_CFA:
6231      return virtual_cfa_rtx;
6232#ifdef DWARF2_UNWIND_INFO
6233    case BUILT_IN_DWARF_SP_COLUMN:
6234      return expand_builtin_dwarf_sp_column ();
6235    case BUILT_IN_INIT_DWARF_REG_SIZES:
6236      expand_builtin_init_dwarf_reg_sizes (TREE_VALUE (arglist));
6237      return const0_rtx;
6238#endif
6239    case BUILT_IN_FROB_RETURN_ADDR:
6240      return expand_builtin_frob_return_addr (TREE_VALUE (arglist));
6241    case BUILT_IN_EXTRACT_RETURN_ADDR:
6242      return expand_builtin_extract_return_addr (TREE_VALUE (arglist));
6243    case BUILT_IN_EH_RETURN:
6244      expand_builtin_eh_return (TREE_VALUE (arglist),
6245				TREE_VALUE (TREE_CHAIN (arglist)));
6246      return const0_rtx;
6247#ifdef EH_RETURN_DATA_REGNO
6248    case BUILT_IN_EH_RETURN_DATA_REGNO:
6249      return expand_builtin_eh_return_data_regno (arglist);
6250#endif
6251    case BUILT_IN_EXTEND_POINTER:
6252      return expand_builtin_extend_pointer (TREE_VALUE (arglist));
6253
6254    case BUILT_IN_VA_START:
6255    case BUILT_IN_STDARG_START:
6256      return expand_builtin_va_start (arglist);
6257    case BUILT_IN_VA_END:
6258      return expand_builtin_va_end (arglist);
6259    case BUILT_IN_VA_COPY:
6260      return expand_builtin_va_copy (arglist);
6261    case BUILT_IN_EXPECT:
6262      return expand_builtin_expect (arglist, target);
6263    case BUILT_IN_PREFETCH:
6264      expand_builtin_prefetch (arglist);
6265      return const0_rtx;
6266
6267    case BUILT_IN_PROFILE_FUNC_ENTER:
6268      return expand_builtin_profile_func (false);
6269    case BUILT_IN_PROFILE_FUNC_EXIT:
6270      return expand_builtin_profile_func (true);
6271
6272    case BUILT_IN_INIT_TRAMPOLINE:
6273      return expand_builtin_init_trampoline (arglist);
6274    case BUILT_IN_ADJUST_TRAMPOLINE:
6275      return expand_builtin_adjust_trampoline (arglist);
6276
6277    case BUILT_IN_FORK:
6278    case BUILT_IN_EXECL:
6279    case BUILT_IN_EXECV:
6280    case BUILT_IN_EXECLP:
6281    case BUILT_IN_EXECLE:
6282    case BUILT_IN_EXECVP:
6283    case BUILT_IN_EXECVE:
6284      target = expand_builtin_fork_or_exec (fndecl, arglist, target, ignore);
6285      if (target)
6286	return target;
6287      break;
6288
6289    case BUILT_IN_FETCH_AND_ADD_1:
6290    case BUILT_IN_FETCH_AND_ADD_2:
6291    case BUILT_IN_FETCH_AND_ADD_4:
6292    case BUILT_IN_FETCH_AND_ADD_8:
6293    case BUILT_IN_FETCH_AND_ADD_16:
6294      mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_ADD_1);
6295      target = expand_builtin_sync_operation (mode, arglist, PLUS,
6296					      false, target, ignore);
6297      if (target)
6298	return target;
6299      break;
6300
6301    case BUILT_IN_FETCH_AND_SUB_1:
6302    case BUILT_IN_FETCH_AND_SUB_2:
6303    case BUILT_IN_FETCH_AND_SUB_4:
6304    case BUILT_IN_FETCH_AND_SUB_8:
6305    case BUILT_IN_FETCH_AND_SUB_16:
6306      mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_SUB_1);
6307      target = expand_builtin_sync_operation (mode, arglist, MINUS,
6308					      false, target, ignore);
6309      if (target)
6310	return target;
6311      break;
6312
6313    case BUILT_IN_FETCH_AND_OR_1:
6314    case BUILT_IN_FETCH_AND_OR_2:
6315    case BUILT_IN_FETCH_AND_OR_4:
6316    case BUILT_IN_FETCH_AND_OR_8:
6317    case BUILT_IN_FETCH_AND_OR_16:
6318      mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_OR_1);
6319      target = expand_builtin_sync_operation (mode, arglist, IOR,
6320					      false, target, ignore);
6321      if (target)
6322	return target;
6323      break;
6324
6325    case BUILT_IN_FETCH_AND_AND_1:
6326    case BUILT_IN_FETCH_AND_AND_2:
6327    case BUILT_IN_FETCH_AND_AND_4:
6328    case BUILT_IN_FETCH_AND_AND_8:
6329    case BUILT_IN_FETCH_AND_AND_16:
6330      mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_AND_1);
6331      target = expand_builtin_sync_operation (mode, arglist, AND,
6332					      false, target, ignore);
6333      if (target)
6334	return target;
6335      break;
6336
6337    case BUILT_IN_FETCH_AND_XOR_1:
6338    case BUILT_IN_FETCH_AND_XOR_2:
6339    case BUILT_IN_FETCH_AND_XOR_4:
6340    case BUILT_IN_FETCH_AND_XOR_8:
6341    case BUILT_IN_FETCH_AND_XOR_16:
6342      mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_XOR_1);
6343      target = expand_builtin_sync_operation (mode, arglist, XOR,
6344					      false, target, ignore);
6345      if (target)
6346	return target;
6347      break;
6348
6349    case BUILT_IN_FETCH_AND_NAND_1:
6350    case BUILT_IN_FETCH_AND_NAND_2:
6351    case BUILT_IN_FETCH_AND_NAND_4:
6352    case BUILT_IN_FETCH_AND_NAND_8:
6353    case BUILT_IN_FETCH_AND_NAND_16:
6354      mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_NAND_1);
6355      target = expand_builtin_sync_operation (mode, arglist, NOT,
6356					      false, target, ignore);
6357      if (target)
6358	return target;
6359      break;
6360
6361    case BUILT_IN_ADD_AND_FETCH_1:
6362    case BUILT_IN_ADD_AND_FETCH_2:
6363    case BUILT_IN_ADD_AND_FETCH_4:
6364    case BUILT_IN_ADD_AND_FETCH_8:
6365    case BUILT_IN_ADD_AND_FETCH_16:
6366      mode = get_builtin_sync_mode (fcode - BUILT_IN_ADD_AND_FETCH_1);
6367      target = expand_builtin_sync_operation (mode, arglist, PLUS,
6368					      true, target, ignore);
6369      if (target)
6370	return target;
6371      break;
6372
6373    case BUILT_IN_SUB_AND_FETCH_1:
6374    case BUILT_IN_SUB_AND_FETCH_2:
6375    case BUILT_IN_SUB_AND_FETCH_4:
6376    case BUILT_IN_SUB_AND_FETCH_8:
6377    case BUILT_IN_SUB_AND_FETCH_16:
6378      mode = get_builtin_sync_mode (fcode - BUILT_IN_SUB_AND_FETCH_1);
6379      target = expand_builtin_sync_operation (mode, arglist, MINUS,
6380					      true, target, ignore);
6381      if (target)
6382	return target;
6383      break;
6384
6385    case BUILT_IN_OR_AND_FETCH_1:
6386    case BUILT_IN_OR_AND_FETCH_2:
6387    case BUILT_IN_OR_AND_FETCH_4:
6388    case BUILT_IN_OR_AND_FETCH_8:
6389    case BUILT_IN_OR_AND_FETCH_16:
6390      mode = get_builtin_sync_mode (fcode - BUILT_IN_OR_AND_FETCH_1);
6391      target = expand_builtin_sync_operation (mode, arglist, IOR,
6392					      true, target, ignore);
6393      if (target)
6394	return target;
6395      break;
6396
6397    case BUILT_IN_AND_AND_FETCH_1:
6398    case BUILT_IN_AND_AND_FETCH_2:
6399    case BUILT_IN_AND_AND_FETCH_4:
6400    case BUILT_IN_AND_AND_FETCH_8:
6401    case BUILT_IN_AND_AND_FETCH_16:
6402      mode = get_builtin_sync_mode (fcode - BUILT_IN_AND_AND_FETCH_1);
6403      target = expand_builtin_sync_operation (mode, arglist, AND,
6404					      true, target, ignore);
6405      if (target)
6406	return target;
6407      break;
6408
6409    case BUILT_IN_XOR_AND_FETCH_1:
6410    case BUILT_IN_XOR_AND_FETCH_2:
6411    case BUILT_IN_XOR_AND_FETCH_4:
6412    case BUILT_IN_XOR_AND_FETCH_8:
6413    case BUILT_IN_XOR_AND_FETCH_16:
6414      mode = get_builtin_sync_mode (fcode - BUILT_IN_XOR_AND_FETCH_1);
6415      target = expand_builtin_sync_operation (mode, arglist, XOR,
6416					      true, target, ignore);
6417      if (target)
6418	return target;
6419      break;
6420
6421    case BUILT_IN_NAND_AND_FETCH_1:
6422    case BUILT_IN_NAND_AND_FETCH_2:
6423    case BUILT_IN_NAND_AND_FETCH_4:
6424    case BUILT_IN_NAND_AND_FETCH_8:
6425    case BUILT_IN_NAND_AND_FETCH_16:
6426      mode = get_builtin_sync_mode (fcode - BUILT_IN_NAND_AND_FETCH_1);
6427      target = expand_builtin_sync_operation (mode, arglist, NOT,
6428					      true, target, ignore);
6429      if (target)
6430	return target;
6431      break;
6432
6433    case BUILT_IN_BOOL_COMPARE_AND_SWAP_1:
6434    case BUILT_IN_BOOL_COMPARE_AND_SWAP_2:
6435    case BUILT_IN_BOOL_COMPARE_AND_SWAP_4:
6436    case BUILT_IN_BOOL_COMPARE_AND_SWAP_8:
6437    case BUILT_IN_BOOL_COMPARE_AND_SWAP_16:
6438      if (mode == VOIDmode)
6439	mode = TYPE_MODE (boolean_type_node);
6440      if (!target || !register_operand (target, mode))
6441	target = gen_reg_rtx (mode);
6442
6443      mode = get_builtin_sync_mode (fcode - BUILT_IN_BOOL_COMPARE_AND_SWAP_1);
6444      target = expand_builtin_compare_and_swap (mode, arglist, true, target);
6445      if (target)
6446	return target;
6447      break;
6448
6449    case BUILT_IN_VAL_COMPARE_AND_SWAP_1:
6450    case BUILT_IN_VAL_COMPARE_AND_SWAP_2:
6451    case BUILT_IN_VAL_COMPARE_AND_SWAP_4:
6452    case BUILT_IN_VAL_COMPARE_AND_SWAP_8:
6453    case BUILT_IN_VAL_COMPARE_AND_SWAP_16:
6454      mode = get_builtin_sync_mode (fcode - BUILT_IN_VAL_COMPARE_AND_SWAP_1);
6455      target = expand_builtin_compare_and_swap (mode, arglist, false, target);
6456      if (target)
6457	return target;
6458      break;
6459
6460    case BUILT_IN_LOCK_TEST_AND_SET_1:
6461    case BUILT_IN_LOCK_TEST_AND_SET_2:
6462    case BUILT_IN_LOCK_TEST_AND_SET_4:
6463    case BUILT_IN_LOCK_TEST_AND_SET_8:
6464    case BUILT_IN_LOCK_TEST_AND_SET_16:
6465      mode = get_builtin_sync_mode (fcode - BUILT_IN_LOCK_TEST_AND_SET_1);
6466      target = expand_builtin_lock_test_and_set (mode, arglist, target);
6467      if (target)
6468	return target;
6469      break;
6470
6471    case BUILT_IN_LOCK_RELEASE_1:
6472    case BUILT_IN_LOCK_RELEASE_2:
6473    case BUILT_IN_LOCK_RELEASE_4:
6474    case BUILT_IN_LOCK_RELEASE_8:
6475    case BUILT_IN_LOCK_RELEASE_16:
6476      mode = get_builtin_sync_mode (fcode - BUILT_IN_LOCK_RELEASE_1);
6477      expand_builtin_lock_release (mode, arglist);
6478      return const0_rtx;
6479
6480    case BUILT_IN_SYNCHRONIZE:
6481      expand_builtin_synchronize ();
6482      return const0_rtx;
6483
6484    case BUILT_IN_OBJECT_SIZE:
6485      return expand_builtin_object_size (exp);
6486
6487    case BUILT_IN_MEMCPY_CHK:
6488    case BUILT_IN_MEMPCPY_CHK:
6489    case BUILT_IN_MEMMOVE_CHK:
6490    case BUILT_IN_MEMSET_CHK:
6491      target = expand_builtin_memory_chk (exp, target, mode, fcode);
6492      if (target)
6493	return target;
6494      break;
6495
6496    case BUILT_IN_STRCPY_CHK:
6497    case BUILT_IN_STPCPY_CHK:
6498    case BUILT_IN_STRNCPY_CHK:
6499    case BUILT_IN_STRCAT_CHK:
6500    case BUILT_IN_SNPRINTF_CHK:
6501    case BUILT_IN_VSNPRINTF_CHK:
6502      maybe_emit_chk_warning (exp, fcode);
6503      break;
6504
6505    case BUILT_IN_SPRINTF_CHK:
6506    case BUILT_IN_VSPRINTF_CHK:
6507      maybe_emit_sprintf_chk_warning (exp, fcode);
6508      break;
6509
6510    default:	/* just do library call, if unknown builtin */
6511      break;
6512    }
6513
6514  /* The switch statement above can drop through to cause the function
6515     to be called normally.  */
6516  return expand_call (exp, target, ignore);
6517}
6518
6519/* Determine whether a tree node represents a call to a built-in
6520   function.  If the tree T is a call to a built-in function with
6521   the right number of arguments of the appropriate types, return
6522   the DECL_FUNCTION_CODE of the call, e.g. BUILT_IN_SQRT.
6523   Otherwise the return value is END_BUILTINS.  */
6524
6525enum built_in_function
6526builtin_mathfn_code (tree t)
6527{
6528  tree fndecl, arglist, parmlist;
6529  tree argtype, parmtype;
6530
6531  if (TREE_CODE (t) != CALL_EXPR
6532      || TREE_CODE (TREE_OPERAND (t, 0)) != ADDR_EXPR)
6533    return END_BUILTINS;
6534
6535  fndecl = get_callee_fndecl (t);
6536  if (fndecl == NULL_TREE
6537      || TREE_CODE (fndecl) != FUNCTION_DECL
6538      || ! DECL_BUILT_IN (fndecl)
6539      || DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
6540    return END_BUILTINS;
6541
6542  arglist = TREE_OPERAND (t, 1);
6543  parmlist = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
6544  for (; parmlist; parmlist = TREE_CHAIN (parmlist))
6545    {
6546      /* If a function doesn't take a variable number of arguments,
6547	 the last element in the list will have type `void'.  */
6548      parmtype = TREE_VALUE (parmlist);
6549      if (VOID_TYPE_P (parmtype))
6550	{
6551	  if (arglist)
6552	    return END_BUILTINS;
6553	  return DECL_FUNCTION_CODE (fndecl);
6554	}
6555
6556      if (! arglist)
6557	return END_BUILTINS;
6558
6559      argtype = TREE_TYPE (TREE_VALUE (arglist));
6560
6561      if (SCALAR_FLOAT_TYPE_P (parmtype))
6562	{
6563	  if (! SCALAR_FLOAT_TYPE_P (argtype))
6564	    return END_BUILTINS;
6565	}
6566      else if (COMPLEX_FLOAT_TYPE_P (parmtype))
6567	{
6568	  if (! COMPLEX_FLOAT_TYPE_P (argtype))
6569	    return END_BUILTINS;
6570	}
6571      else if (POINTER_TYPE_P (parmtype))
6572	{
6573	  if (! POINTER_TYPE_P (argtype))
6574	    return END_BUILTINS;
6575	}
6576      else if (INTEGRAL_TYPE_P (parmtype))
6577	{
6578	  if (! INTEGRAL_TYPE_P (argtype))
6579	    return END_BUILTINS;
6580	}
6581      else
6582	return END_BUILTINS;
6583
6584      arglist = TREE_CHAIN (arglist);
6585    }
6586
6587  /* Variable-length argument list.  */
6588  return DECL_FUNCTION_CODE (fndecl);
6589}
6590
6591/* Fold a call to __builtin_constant_p, if we know it will evaluate to a
6592   constant.  ARGLIST is the argument list of the call.  */
6593
6594static tree
6595fold_builtin_constant_p (tree arglist)
6596{
6597  if (arglist == 0)
6598    return 0;
6599
6600  arglist = TREE_VALUE (arglist);
6601
6602  /* We return 1 for a numeric type that's known to be a constant
6603     value at compile-time or for an aggregate type that's a
6604     literal constant.  */
6605  STRIP_NOPS (arglist);
6606
6607  /* If we know this is a constant, emit the constant of one.  */
6608  if (CONSTANT_CLASS_P (arglist)
6609      || (TREE_CODE (arglist) == CONSTRUCTOR
6610	  && TREE_CONSTANT (arglist)))
6611    return integer_one_node;
6612  if (TREE_CODE (arglist) == ADDR_EXPR)
6613    {
6614       tree op = TREE_OPERAND (arglist, 0);
6615       if (TREE_CODE (op) == STRING_CST
6616	   || (TREE_CODE (op) == ARRAY_REF
6617	       && integer_zerop (TREE_OPERAND (op, 1))
6618	       && TREE_CODE (TREE_OPERAND (op, 0)) == STRING_CST))
6619	 return integer_one_node;
6620    }
6621
6622  /* If this expression has side effects, show we don't know it to be a
6623     constant.  Likewise if it's a pointer or aggregate type since in
6624     those case we only want literals, since those are only optimized
6625     when generating RTL, not later.
6626     And finally, if we are compiling an initializer, not code, we
6627     need to return a definite result now; there's not going to be any
6628     more optimization done.  */
6629  if (TREE_SIDE_EFFECTS (arglist)
6630      || AGGREGATE_TYPE_P (TREE_TYPE (arglist))
6631      || POINTER_TYPE_P (TREE_TYPE (arglist))
6632      || cfun == 0
6633      || folding_initializer)
6634    return integer_zero_node;
6635
6636  return 0;
6637}
6638
6639/* Fold a call to __builtin_expect, if we expect that a comparison against
6640   the argument will fold to a constant.  In practice, this means a true
6641   constant or the address of a non-weak symbol.  ARGLIST is the argument
6642   list of the call.  */
6643
6644static tree
6645fold_builtin_expect (tree arglist)
6646{
6647  tree arg, inner;
6648
6649  if (arglist == 0)
6650    return 0;
6651
6652  arg = TREE_VALUE (arglist);
6653
6654  /* If the argument isn't invariant, then there's nothing we can do.  */
6655  if (!TREE_INVARIANT (arg))
6656    return 0;
6657
6658  /* If we're looking at an address of a weak decl, then do not fold.  */
6659  inner = arg;
6660  STRIP_NOPS (inner);
6661  if (TREE_CODE (inner) == ADDR_EXPR)
6662    {
6663      do
6664	{
6665	  inner = TREE_OPERAND (inner, 0);
6666	}
6667      while (TREE_CODE (inner) == COMPONENT_REF
6668	     || TREE_CODE (inner) == ARRAY_REF);
6669      if (DECL_P (inner) && DECL_WEAK (inner))
6670	return 0;
6671    }
6672
6673  /* Otherwise, ARG already has the proper type for the return value.  */
6674  return arg;
6675}
6676
6677/* Fold a call to __builtin_classify_type.  */
6678
6679static tree
6680fold_builtin_classify_type (tree arglist)
6681{
6682  if (arglist == 0)
6683    return build_int_cst (NULL_TREE, no_type_class);
6684
6685  return build_int_cst (NULL_TREE,
6686			type_to_class (TREE_TYPE (TREE_VALUE (arglist))));
6687}
6688
6689/* Fold a call to __builtin_strlen.  */
6690
6691static tree
6692fold_builtin_strlen (tree arglist)
6693{
6694  if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6695    return NULL_TREE;
6696  else
6697    {
6698      tree len = c_strlen (TREE_VALUE (arglist), 0);
6699
6700      if (len)
6701	{
6702	  /* Convert from the internal "sizetype" type to "size_t".  */
6703	  if (size_type_node)
6704	    len = fold_convert (size_type_node, len);
6705	  return len;
6706	}
6707
6708      return NULL_TREE;
6709    }
6710}
6711
6712/* Fold a call to __builtin_inf or __builtin_huge_val.  */
6713
6714static tree
6715fold_builtin_inf (tree type, int warn)
6716{
6717  REAL_VALUE_TYPE real;
6718
6719  /* __builtin_inff is intended to be usable to define INFINITY on all
6720     targets.  If an infinity is not available, INFINITY expands "to a
6721     positive constant of type float that overflows at translation
6722     time", footnote "In this case, using INFINITY will violate the
6723     constraint in 6.4.4 and thus require a diagnostic." (C99 7.12#4).
6724     Thus we pedwarn to ensure this constraint violation is
6725     diagnosed.  */
6726  if (!MODE_HAS_INFINITIES (TYPE_MODE (type)) && warn)
6727    pedwarn ("target format does not support infinity");
6728
6729  real_inf (&real);
6730  return build_real (type, real);
6731}
6732
6733/* Fold a call to __builtin_nan or __builtin_nans.  */
6734
6735static tree
6736fold_builtin_nan (tree arglist, tree type, int quiet)
6737{
6738  REAL_VALUE_TYPE real;
6739  const char *str;
6740
6741  if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6742    return 0;
6743  str = c_getstr (TREE_VALUE (arglist));
6744  if (!str)
6745    return 0;
6746
6747  if (!real_nan (&real, str, quiet, TYPE_MODE (type)))
6748    return 0;
6749
6750  return build_real (type, real);
6751}
6752
6753/* Return true if the floating point expression T has an integer value.
6754   We also allow +Inf, -Inf and NaN to be considered integer values.  */
6755
6756static bool
6757integer_valued_real_p (tree t)
6758{
6759  switch (TREE_CODE (t))
6760    {
6761    case FLOAT_EXPR:
6762      return true;
6763
6764    case ABS_EXPR:
6765    case SAVE_EXPR:
6766    case NON_LVALUE_EXPR:
6767      return integer_valued_real_p (TREE_OPERAND (t, 0));
6768
6769    case COMPOUND_EXPR:
6770    case MODIFY_EXPR:
6771    case BIND_EXPR:
6772      return integer_valued_real_p (TREE_OPERAND (t, 1));
6773
6774    case PLUS_EXPR:
6775    case MINUS_EXPR:
6776    case MULT_EXPR:
6777    case MIN_EXPR:
6778    case MAX_EXPR:
6779      return integer_valued_real_p (TREE_OPERAND (t, 0))
6780	     && integer_valued_real_p (TREE_OPERAND (t, 1));
6781
6782    case COND_EXPR:
6783      return integer_valued_real_p (TREE_OPERAND (t, 1))
6784	     && integer_valued_real_p (TREE_OPERAND (t, 2));
6785
6786    case REAL_CST:
6787      if (! TREE_CONSTANT_OVERFLOW (t))
6788      {
6789	REAL_VALUE_TYPE c, cint;
6790
6791	c = TREE_REAL_CST (t);
6792	real_trunc (&cint, TYPE_MODE (TREE_TYPE (t)), &c);
6793	return real_identical (&c, &cint);
6794      }
6795      break;
6796
6797    case NOP_EXPR:
6798      {
6799	tree type = TREE_TYPE (TREE_OPERAND (t, 0));
6800	if (TREE_CODE (type) == INTEGER_TYPE)
6801	  return true;
6802	if (TREE_CODE (type) == REAL_TYPE)
6803	  return integer_valued_real_p (TREE_OPERAND (t, 0));
6804	break;
6805      }
6806
6807    case CALL_EXPR:
6808      switch (builtin_mathfn_code (t))
6809	{
6810	CASE_FLT_FN (BUILT_IN_CEIL):
6811	CASE_FLT_FN (BUILT_IN_FLOOR):
6812	CASE_FLT_FN (BUILT_IN_NEARBYINT):
6813	CASE_FLT_FN (BUILT_IN_RINT):
6814	CASE_FLT_FN (BUILT_IN_ROUND):
6815	CASE_FLT_FN (BUILT_IN_TRUNC):
6816	  return true;
6817
6818	default:
6819	  break;
6820	}
6821      break;
6822
6823    default:
6824      break;
6825    }
6826  return false;
6827}
6828
6829/* EXP is assumed to be builtin call where truncation can be propagated
6830   across (for instance floor((double)f) == (double)floorf (f).
6831   Do the transformation.  */
6832
6833static tree
6834fold_trunc_transparent_mathfn (tree fndecl, tree arglist)
6835{
6836  enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
6837  tree arg;
6838
6839  if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6840    return 0;
6841
6842  arg = TREE_VALUE (arglist);
6843  /* Integer rounding functions are idempotent.  */
6844  if (fcode == builtin_mathfn_code (arg))
6845    return arg;
6846
6847  /* If argument is already integer valued, and we don't need to worry
6848     about setting errno, there's no need to perform rounding.  */
6849  if (! flag_errno_math && integer_valued_real_p (arg))
6850    return arg;
6851
6852  if (optimize)
6853    {
6854      tree arg0 = strip_float_extensions (arg);
6855      tree ftype = TREE_TYPE (TREE_TYPE (fndecl));
6856      tree newtype = TREE_TYPE (arg0);
6857      tree decl;
6858
6859      if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
6860	  && (decl = mathfn_built_in (newtype, fcode)))
6861	{
6862	  arglist =
6863	    build_tree_list (NULL_TREE, fold_convert (newtype, arg0));
6864	  return fold_convert (ftype,
6865			       build_function_call_expr (decl, arglist));
6866	}
6867    }
6868  return 0;
6869}
6870
6871/* EXP is assumed to be builtin call which can narrow the FP type of
6872   the argument, for instance lround((double)f) -> lroundf (f).  */
6873
6874static tree
6875fold_fixed_mathfn (tree fndecl, tree arglist)
6876{
6877  enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
6878  tree arg;
6879
6880  if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6881    return 0;
6882
6883  arg = TREE_VALUE (arglist);
6884
6885  /* If argument is already integer valued, and we don't need to worry
6886     about setting errno, there's no need to perform rounding.  */
6887  if (! flag_errno_math && integer_valued_real_p (arg))
6888    return fold_build1 (FIX_TRUNC_EXPR, TREE_TYPE (TREE_TYPE (fndecl)), arg);
6889
6890  if (optimize)
6891    {
6892      tree ftype = TREE_TYPE (arg);
6893      tree arg0 = strip_float_extensions (arg);
6894      tree newtype = TREE_TYPE (arg0);
6895      tree decl;
6896
6897      if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
6898	  && (decl = mathfn_built_in (newtype, fcode)))
6899	{
6900	  arglist =
6901	    build_tree_list (NULL_TREE, fold_convert (newtype, arg0));
6902	  return build_function_call_expr (decl, arglist);
6903	}
6904    }
6905
6906  /* Canonicalize llround (x) to lround (x) on LP64 targets where
6907     sizeof (long long) == sizeof (long).  */
6908  if (TYPE_PRECISION (long_long_integer_type_node)
6909      == TYPE_PRECISION (long_integer_type_node))
6910    {
6911      tree newfn = NULL_TREE;
6912      switch (fcode)
6913	{
6914	CASE_FLT_FN (BUILT_IN_LLCEIL):
6915	  newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LCEIL);
6916	  break;
6917
6918	CASE_FLT_FN (BUILT_IN_LLFLOOR):
6919	  newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LFLOOR);
6920	  break;
6921
6922	CASE_FLT_FN (BUILT_IN_LLROUND):
6923	  newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LROUND);
6924	  break;
6925
6926	CASE_FLT_FN (BUILT_IN_LLRINT):
6927	  newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LRINT);
6928	  break;
6929
6930	default:
6931	  break;
6932	}
6933
6934      if (newfn)
6935	{
6936	  tree newcall = build_function_call_expr (newfn, arglist);
6937	  return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), newcall);
6938	}
6939    }
6940
6941  return 0;
6942}
6943
6944/* Fold function call to builtin cabs, cabsf or cabsl.  ARGLIST
6945   is the argument list, TYPE is the return type and FNDECL is the
6946   original function DECL.  Return NULL_TREE if no if no simplification
6947   can be made.  */
6948
6949static tree
6950fold_builtin_cabs (tree arglist, tree type, tree fndecl)
6951{
6952  tree arg;
6953
6954  if (!arglist || TREE_CHAIN (arglist))
6955    return NULL_TREE;
6956
6957  arg = TREE_VALUE (arglist);
6958  if (TREE_CODE (TREE_TYPE (arg)) != COMPLEX_TYPE
6959      || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) != REAL_TYPE)
6960    return NULL_TREE;
6961
6962  /* Evaluate cabs of a constant at compile-time.  */
6963  if (flag_unsafe_math_optimizations
6964      && TREE_CODE (arg) == COMPLEX_CST
6965      && TREE_CODE (TREE_REALPART (arg)) == REAL_CST
6966      && TREE_CODE (TREE_IMAGPART (arg)) == REAL_CST
6967      && ! TREE_CONSTANT_OVERFLOW (TREE_REALPART (arg))
6968      && ! TREE_CONSTANT_OVERFLOW (TREE_IMAGPART (arg)))
6969    {
6970      REAL_VALUE_TYPE r, i;
6971
6972      r = TREE_REAL_CST (TREE_REALPART (arg));
6973      i = TREE_REAL_CST (TREE_IMAGPART (arg));
6974
6975      real_arithmetic (&r, MULT_EXPR, &r, &r);
6976      real_arithmetic (&i, MULT_EXPR, &i, &i);
6977      real_arithmetic (&r, PLUS_EXPR, &r, &i);
6978      if (real_sqrt (&r, TYPE_MODE (type), &r)
6979	  || ! flag_trapping_math)
6980	return build_real (type, r);
6981    }
6982
6983  /* If either part is zero, cabs is fabs of the other.  */
6984  if (TREE_CODE (arg) == COMPLEX_EXPR
6985      && real_zerop (TREE_OPERAND (arg, 0)))
6986    return fold_build1 (ABS_EXPR, type, TREE_OPERAND (arg, 1));
6987  if (TREE_CODE (arg) == COMPLEX_EXPR
6988      && real_zerop (TREE_OPERAND (arg, 1)))
6989    return fold_build1 (ABS_EXPR, type, TREE_OPERAND (arg, 0));
6990
6991  /* Optimize cabs(-z) and cabs(conj(z)) as cabs(z).  */
6992  if (TREE_CODE (arg) == NEGATE_EXPR
6993      || TREE_CODE (arg) == CONJ_EXPR)
6994    {
6995      tree arglist = build_tree_list (NULL_TREE, TREE_OPERAND (arg, 0));
6996      return build_function_call_expr (fndecl, arglist);
6997    }
6998
6999  /* Don't do this when optimizing for size.  */
7000  if (flag_unsafe_math_optimizations
7001      && optimize && !optimize_size)
7002    {
7003      tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
7004
7005      if (sqrtfn != NULL_TREE)
7006	{
7007	  tree rpart, ipart, result, arglist;
7008
7009	  arg = builtin_save_expr (arg);
7010
7011	  rpart = fold_build1 (REALPART_EXPR, type, arg);
7012	  ipart = fold_build1 (IMAGPART_EXPR, type, arg);
7013
7014	  rpart = builtin_save_expr (rpart);
7015	  ipart = builtin_save_expr (ipart);
7016
7017	  result = fold_build2 (PLUS_EXPR, type,
7018				fold_build2 (MULT_EXPR, type,
7019					     rpart, rpart),
7020				fold_build2 (MULT_EXPR, type,
7021					     ipart, ipart));
7022
7023	  arglist = build_tree_list (NULL_TREE, result);
7024	  return build_function_call_expr (sqrtfn, arglist);
7025	}
7026    }
7027
7028  return NULL_TREE;
7029}
7030
7031/* Fold a builtin function call to sqrt, sqrtf, or sqrtl.  Return
7032   NULL_TREE if no simplification can be made.  */
7033
7034static tree
7035fold_builtin_sqrt (tree arglist, tree type)
7036{
7037
7038  enum built_in_function fcode;
7039  tree arg = TREE_VALUE (arglist);
7040
7041  if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7042    return NULL_TREE;
7043
7044  /* Optimize sqrt of constant value.  */
7045  if (TREE_CODE (arg) == REAL_CST
7046      && ! TREE_CONSTANT_OVERFLOW (arg))
7047    {
7048      REAL_VALUE_TYPE r, x;
7049
7050      x = TREE_REAL_CST (arg);
7051      if (real_sqrt (&r, TYPE_MODE (type), &x)
7052	  || (!flag_trapping_math && !flag_errno_math))
7053	return build_real (type, r);
7054    }
7055
7056  /* Optimize sqrt(expN(x)) = expN(x*0.5).  */
7057  fcode = builtin_mathfn_code (arg);
7058  if (flag_unsafe_math_optimizations && BUILTIN_EXPONENT_P (fcode))
7059    {
7060      tree expfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
7061      arg = fold_build2 (MULT_EXPR, type,
7062			 TREE_VALUE (TREE_OPERAND (arg, 1)),
7063			 build_real (type, dconsthalf));
7064      arglist = build_tree_list (NULL_TREE, arg);
7065      return build_function_call_expr (expfn, arglist);
7066    }
7067
7068  /* Optimize sqrt(Nroot(x)) -> pow(x,1/(2*N)).  */
7069  if (flag_unsafe_math_optimizations && BUILTIN_ROOT_P (fcode))
7070    {
7071      tree powfn = mathfn_built_in (type, BUILT_IN_POW);
7072
7073      if (powfn)
7074	{
7075	  tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
7076	  tree tree_root;
7077	  /* The inner root was either sqrt or cbrt.  */
7078	  REAL_VALUE_TYPE dconstroot =
7079	    BUILTIN_SQRT_P (fcode) ? dconsthalf : dconstthird;
7080
7081	  /* Adjust for the outer root.  */
7082	  SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
7083	  dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
7084	  tree_root = build_real (type, dconstroot);
7085	  arglist = tree_cons (NULL_TREE, arg0,
7086			       build_tree_list (NULL_TREE, tree_root));
7087	  return build_function_call_expr (powfn, arglist);
7088	}
7089    }
7090
7091  /* Optimize sqrt(pow(x,y)) = pow(|x|,y*0.5).  */
7092  if (flag_unsafe_math_optimizations
7093      && (fcode == BUILT_IN_POW
7094	  || fcode == BUILT_IN_POWF
7095	  || fcode == BUILT_IN_POWL))
7096    {
7097      tree powfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
7098      tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
7099      tree arg1 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
7100      tree narg1;
7101      if (!tree_expr_nonnegative_p (arg0))
7102	arg0 = build1 (ABS_EXPR, type, arg0);
7103      narg1 = fold_build2 (MULT_EXPR, type, arg1,
7104			   build_real (type, dconsthalf));
7105      arglist = tree_cons (NULL_TREE, arg0,
7106			   build_tree_list (NULL_TREE, narg1));
7107      return build_function_call_expr (powfn, arglist);
7108    }
7109
7110  return NULL_TREE;
7111}
7112
7113/* Fold a builtin function call to cbrt, cbrtf, or cbrtl.  Return
7114   NULL_TREE if no simplification can be made.  */
7115static tree
7116fold_builtin_cbrt (tree arglist, tree type)
7117{
7118  tree arg = TREE_VALUE (arglist);
7119  const enum built_in_function fcode = builtin_mathfn_code (arg);
7120
7121  if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7122    return NULL_TREE;
7123
7124  /* Optimize cbrt of constant value.  */
7125  if (real_zerop (arg) || real_onep (arg) || real_minus_onep (arg))
7126    return arg;
7127
7128  if (flag_unsafe_math_optimizations)
7129    {
7130      /* Optimize cbrt(expN(x)) -> expN(x/3).  */
7131      if (BUILTIN_EXPONENT_P (fcode))
7132	{
7133	  tree expfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
7134	  const REAL_VALUE_TYPE third_trunc =
7135	    real_value_truncate (TYPE_MODE (type), dconstthird);
7136	  arg = fold_build2 (MULT_EXPR, type,
7137			     TREE_VALUE (TREE_OPERAND (arg, 1)),
7138			     build_real (type, third_trunc));
7139	  arglist = build_tree_list (NULL_TREE, arg);
7140	  return build_function_call_expr (expfn, arglist);
7141	}
7142
7143      /* Optimize cbrt(sqrt(x)) -> pow(x,1/6).  */
7144      if (BUILTIN_SQRT_P (fcode))
7145	{
7146	  tree powfn = mathfn_built_in (type, BUILT_IN_POW);
7147
7148	  if (powfn)
7149	    {
7150	      tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
7151	      tree tree_root;
7152	      REAL_VALUE_TYPE dconstroot = dconstthird;
7153
7154	      SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
7155	      dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
7156	      tree_root = build_real (type, dconstroot);
7157	      arglist = tree_cons (NULL_TREE, arg0,
7158				   build_tree_list (NULL_TREE, tree_root));
7159	      return build_function_call_expr (powfn, arglist);
7160	    }
7161	}
7162
7163      /* Optimize cbrt(cbrt(x)) -> pow(x,1/9) iff x is nonnegative.  */
7164      if (BUILTIN_CBRT_P (fcode))
7165	{
7166	  tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
7167	  if (tree_expr_nonnegative_p (arg0))
7168	    {
7169	      tree powfn = mathfn_built_in (type, BUILT_IN_POW);
7170
7171	      if (powfn)
7172		{
7173		  tree tree_root;
7174		  REAL_VALUE_TYPE dconstroot;
7175
7176		  real_arithmetic (&dconstroot, MULT_EXPR, &dconstthird, &dconstthird);
7177		  dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
7178		  tree_root = build_real (type, dconstroot);
7179		  arglist = tree_cons (NULL_TREE, arg0,
7180				       build_tree_list (NULL_TREE, tree_root));
7181		  return build_function_call_expr (powfn, arglist);
7182		}
7183	    }
7184	}
7185
7186      /* Optimize cbrt(pow(x,y)) -> pow(x,y/3) iff x is nonnegative.  */
7187      if (fcode == BUILT_IN_POW || fcode == BUILT_IN_POWF
7188	  || fcode == BUILT_IN_POWL)
7189	{
7190	  tree arg00 = TREE_VALUE (TREE_OPERAND (arg, 1));
7191	  tree arg01 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
7192	  if (tree_expr_nonnegative_p (arg00))
7193	    {
7194	      tree powfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
7195	      const REAL_VALUE_TYPE dconstroot
7196		= real_value_truncate (TYPE_MODE (type), dconstthird);
7197	      tree narg01 = fold_build2 (MULT_EXPR, type, arg01,
7198					 build_real (type, dconstroot));
7199	      arglist = tree_cons (NULL_TREE, arg00,
7200				   build_tree_list (NULL_TREE, narg01));
7201	      return build_function_call_expr (powfn, arglist);
7202	    }
7203	}
7204    }
7205  return NULL_TREE;
7206}
7207
7208/* Fold function call to builtin sin, sinf, or sinl.  Return
7209   NULL_TREE if no simplification can be made.  */
7210static tree
7211fold_builtin_sin (tree arglist)
7212{
7213  tree arg = TREE_VALUE (arglist);
7214
7215  if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7216    return NULL_TREE;
7217
7218  /* Optimize sin (0.0) = 0.0.  */
7219  if (real_zerop (arg))
7220    return arg;
7221
7222  return NULL_TREE;
7223}
7224
7225/* Fold function call to builtin cos, cosf, or cosl.  Return
7226   NULL_TREE if no simplification can be made.  */
7227static tree
7228fold_builtin_cos (tree arglist, tree type, tree fndecl)
7229{
7230  tree arg = TREE_VALUE (arglist);
7231
7232  if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7233    return NULL_TREE;
7234
7235  /* Optimize cos (0.0) = 1.0.  */
7236  if (real_zerop (arg))
7237    return build_real (type, dconst1);
7238
7239  /* Optimize cos(-x) into cos (x).  */
7240  if (TREE_CODE (arg) == NEGATE_EXPR)
7241    {
7242      tree args = build_tree_list (NULL_TREE,
7243				   TREE_OPERAND (arg, 0));
7244      return build_function_call_expr (fndecl, args);
7245    }
7246
7247  return NULL_TREE;
7248}
7249
7250/* Fold function call to builtin tan, tanf, or tanl.  Return
7251   NULL_TREE if no simplification can be made.  */
7252static tree
7253fold_builtin_tan (tree arglist)
7254{
7255  enum built_in_function fcode;
7256  tree arg = TREE_VALUE (arglist);
7257
7258  if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7259    return NULL_TREE;
7260
7261  /* Optimize tan(0.0) = 0.0.  */
7262  if (real_zerop (arg))
7263    return arg;
7264
7265  /* Optimize tan(atan(x)) = x.  */
7266  fcode = builtin_mathfn_code (arg);
7267  if (flag_unsafe_math_optimizations
7268      && (fcode == BUILT_IN_ATAN
7269	  || fcode == BUILT_IN_ATANF
7270	  || fcode == BUILT_IN_ATANL))
7271    return TREE_VALUE (TREE_OPERAND (arg, 1));
7272
7273  return NULL_TREE;
7274}
7275
7276/* Fold function call to builtin atan, atanf, or atanl.  Return
7277   NULL_TREE if no simplification can be made.  */
7278
7279static tree
7280fold_builtin_atan (tree arglist, tree type)
7281{
7282
7283  tree arg = TREE_VALUE (arglist);
7284
7285  if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7286    return NULL_TREE;
7287
7288  /* Optimize atan(0.0) = 0.0.  */
7289  if (real_zerop (arg))
7290    return arg;
7291
7292  /* Optimize atan(1.0) = pi/4.  */
7293  if (real_onep (arg))
7294    {
7295      REAL_VALUE_TYPE cst;
7296
7297      real_convert (&cst, TYPE_MODE (type), &dconstpi);
7298      SET_REAL_EXP (&cst, REAL_EXP (&cst) - 2);
7299      return build_real (type, cst);
7300    }
7301
7302  return NULL_TREE;
7303}
7304
7305/* Fold function call to builtin trunc, truncf or truncl.  Return
7306   NULL_TREE if no simplification can be made.  */
7307
7308static tree
7309fold_builtin_trunc (tree fndecl, tree arglist)
7310{
7311  tree arg;
7312
7313  if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7314    return 0;
7315
7316  /* Optimize trunc of constant value.  */
7317  arg = TREE_VALUE (arglist);
7318  if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7319    {
7320      REAL_VALUE_TYPE r, x;
7321      tree type = TREE_TYPE (TREE_TYPE (fndecl));
7322
7323      x = TREE_REAL_CST (arg);
7324      real_trunc (&r, TYPE_MODE (type), &x);
7325      return build_real (type, r);
7326    }
7327
7328  return fold_trunc_transparent_mathfn (fndecl, arglist);
7329}
7330
7331/* Fold function call to builtin floor, floorf or floorl.  Return
7332   NULL_TREE if no simplification can be made.  */
7333
7334static tree
7335fold_builtin_floor (tree fndecl, tree arglist)
7336{
7337  tree arg;
7338
7339  if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7340    return 0;
7341
7342  /* Optimize floor of constant value.  */
7343  arg = TREE_VALUE (arglist);
7344  if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7345    {
7346      REAL_VALUE_TYPE x;
7347
7348      x = TREE_REAL_CST (arg);
7349      if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7350	{
7351	  tree type = TREE_TYPE (TREE_TYPE (fndecl));
7352	  REAL_VALUE_TYPE r;
7353
7354	  real_floor (&r, TYPE_MODE (type), &x);
7355	  return build_real (type, r);
7356	}
7357    }
7358
7359  return fold_trunc_transparent_mathfn (fndecl, arglist);
7360}
7361
7362/* Fold function call to builtin ceil, ceilf or ceill.  Return
7363   NULL_TREE if no simplification can be made.  */
7364
7365static tree
7366fold_builtin_ceil (tree fndecl, tree arglist)
7367{
7368  tree arg;
7369
7370  if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7371    return 0;
7372
7373  /* Optimize ceil of constant value.  */
7374  arg = TREE_VALUE (arglist);
7375  if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7376    {
7377      REAL_VALUE_TYPE x;
7378
7379      x = TREE_REAL_CST (arg);
7380      if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7381	{
7382	  tree type = TREE_TYPE (TREE_TYPE (fndecl));
7383	  REAL_VALUE_TYPE r;
7384
7385	  real_ceil (&r, TYPE_MODE (type), &x);
7386	  return build_real (type, r);
7387	}
7388    }
7389
7390  return fold_trunc_transparent_mathfn (fndecl, arglist);
7391}
7392
7393/* Fold function call to builtin round, roundf or roundl.  Return
7394   NULL_TREE if no simplification can be made.  */
7395
7396static tree
7397fold_builtin_round (tree fndecl, tree arglist)
7398{
7399  tree arg;
7400
7401  if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7402    return 0;
7403
7404  /* Optimize round of constant value.  */
7405  arg = TREE_VALUE (arglist);
7406  if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7407    {
7408      REAL_VALUE_TYPE x;
7409
7410      x = TREE_REAL_CST (arg);
7411      if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7412	{
7413	  tree type = TREE_TYPE (TREE_TYPE (fndecl));
7414	  REAL_VALUE_TYPE r;
7415
7416	  real_round (&r, TYPE_MODE (type), &x);
7417	  return build_real (type, r);
7418	}
7419    }
7420
7421  return fold_trunc_transparent_mathfn (fndecl, arglist);
7422}
7423
7424/* Fold function call to builtin lround, lroundf or lroundl (or the
7425   corresponding long long versions) and other rounding functions.
7426   Return NULL_TREE if no simplification can be made.  */
7427
7428static tree
7429fold_builtin_int_roundingfn (tree fndecl, tree arglist)
7430{
7431  tree arg;
7432
7433  if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7434    return 0;
7435
7436  /* Optimize lround of constant value.  */
7437  arg = TREE_VALUE (arglist);
7438  if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7439    {
7440      const REAL_VALUE_TYPE x = TREE_REAL_CST (arg);
7441
7442      if (! REAL_VALUE_ISNAN (x) && ! REAL_VALUE_ISINF (x))
7443	{
7444	  tree itype = TREE_TYPE (TREE_TYPE (fndecl));
7445	  tree ftype = TREE_TYPE (arg), result;
7446	  HOST_WIDE_INT hi, lo;
7447	  REAL_VALUE_TYPE r;
7448
7449	  switch (DECL_FUNCTION_CODE (fndecl))
7450	    {
7451	    CASE_FLT_FN (BUILT_IN_LFLOOR):
7452	    CASE_FLT_FN (BUILT_IN_LLFLOOR):
7453	      real_floor (&r, TYPE_MODE (ftype), &x);
7454	      break;
7455
7456	    CASE_FLT_FN (BUILT_IN_LCEIL):
7457	    CASE_FLT_FN (BUILT_IN_LLCEIL):
7458	      real_ceil (&r, TYPE_MODE (ftype), &x);
7459	      break;
7460
7461	    CASE_FLT_FN (BUILT_IN_LROUND):
7462	    CASE_FLT_FN (BUILT_IN_LLROUND):
7463	      real_round (&r, TYPE_MODE (ftype), &x);
7464	      break;
7465
7466	    default:
7467	      gcc_unreachable ();
7468	    }
7469
7470	  REAL_VALUE_TO_INT (&lo, &hi, r);
7471	  result = build_int_cst_wide (NULL_TREE, lo, hi);
7472	  if (int_fits_type_p (result, itype))
7473	    return fold_convert (itype, result);
7474	}
7475    }
7476
7477  return fold_fixed_mathfn (fndecl, arglist);
7478}
7479
7480/* Fold function call to builtin ffs, clz, ctz, popcount and parity
7481   and their long and long long variants (i.e. ffsl and ffsll).
7482   Return NULL_TREE if no simplification can be made.  */
7483
7484static tree
7485fold_builtin_bitop (tree fndecl, tree arglist)
7486{
7487  tree arg;
7488
7489  if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
7490    return NULL_TREE;
7491
7492  /* Optimize for constant argument.  */
7493  arg = TREE_VALUE (arglist);
7494  if (TREE_CODE (arg) == INTEGER_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7495    {
7496      HOST_WIDE_INT hi, width, result;
7497      unsigned HOST_WIDE_INT lo;
7498      tree type;
7499
7500      type = TREE_TYPE (arg);
7501      width = TYPE_PRECISION (type);
7502      lo = TREE_INT_CST_LOW (arg);
7503
7504      /* Clear all the bits that are beyond the type's precision.  */
7505      if (width > HOST_BITS_PER_WIDE_INT)
7506	{
7507	  hi = TREE_INT_CST_HIGH (arg);
7508	  if (width < 2 * HOST_BITS_PER_WIDE_INT)
7509	    hi &= ~((HOST_WIDE_INT) (-1) >> (width - HOST_BITS_PER_WIDE_INT));
7510	}
7511      else
7512	{
7513	  hi = 0;
7514	  if (width < HOST_BITS_PER_WIDE_INT)
7515	    lo &= ~((unsigned HOST_WIDE_INT) (-1) << width);
7516	}
7517
7518      switch (DECL_FUNCTION_CODE (fndecl))
7519	{
7520	CASE_INT_FN (BUILT_IN_FFS):
7521	  if (lo != 0)
7522	    result = exact_log2 (lo & -lo) + 1;
7523	  else if (hi != 0)
7524	    result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi) + 1;
7525	  else
7526	    result = 0;
7527	  break;
7528
7529	CASE_INT_FN (BUILT_IN_CLZ):
7530	  if (hi != 0)
7531	    result = width - floor_log2 (hi) - 1 - HOST_BITS_PER_WIDE_INT;
7532	  else if (lo != 0)
7533	    result = width - floor_log2 (lo) - 1;
7534	  else if (! CLZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
7535	    result = width;
7536	  break;
7537
7538	CASE_INT_FN (BUILT_IN_CTZ):
7539	  if (lo != 0)
7540	    result = exact_log2 (lo & -lo);
7541	  else if (hi != 0)
7542	    result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi);
7543	  else if (! CTZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
7544	    result = width;
7545	  break;
7546
7547	CASE_INT_FN (BUILT_IN_POPCOUNT):
7548	  result = 0;
7549	  while (lo)
7550	    result++, lo &= lo - 1;
7551	  while (hi)
7552	    result++, hi &= hi - 1;
7553	  break;
7554
7555	CASE_INT_FN (BUILT_IN_PARITY):
7556	  result = 0;
7557	  while (lo)
7558	    result++, lo &= lo - 1;
7559	  while (hi)
7560	    result++, hi &= hi - 1;
7561	  result &= 1;
7562	  break;
7563
7564	default:
7565	  gcc_unreachable ();
7566	}
7567
7568      return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), result);
7569    }
7570
7571  return NULL_TREE;
7572}
7573
7574/* Fold function call to builtin_bswap and the long and long long
7575   variants.  Return NULL_TREE if no simplification can be made.  */
7576static tree
7577fold_builtin_bswap (tree fndecl, tree arglist)
7578{
7579  tree arg;
7580
7581  if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
7582    return 0;
7583
7584  /* Optimize constant value.  */
7585  arg = TREE_VALUE (arglist);
7586  if (TREE_CODE (arg) == INTEGER_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7587    {
7588      HOST_WIDE_INT hi, width, r_hi = 0;
7589      unsigned HOST_WIDE_INT lo, r_lo = 0;
7590      tree type;
7591
7592      type = TREE_TYPE (arg);
7593      width = TYPE_PRECISION (type);
7594      lo = TREE_INT_CST_LOW (arg);
7595      hi = TREE_INT_CST_HIGH (arg);
7596
7597      switch (DECL_FUNCTION_CODE (fndecl))
7598	{
7599	  case BUILT_IN_BSWAP32:
7600	  case BUILT_IN_BSWAP64:
7601	    {
7602	      int s;
7603
7604	      for (s = 0; s < width; s += 8)
7605		{
7606		  int d = width - s - 8;
7607		  unsigned HOST_WIDE_INT byte;
7608
7609		  if (s < HOST_BITS_PER_WIDE_INT)
7610		    byte = (lo >> s) & 0xff;
7611		  else
7612		    byte = (hi >> (s - HOST_BITS_PER_WIDE_INT)) & 0xff;
7613
7614		  if (d < HOST_BITS_PER_WIDE_INT)
7615		    r_lo |= byte << d;
7616		  else
7617		    r_hi |= byte << (d - HOST_BITS_PER_WIDE_INT);
7618		}
7619	    }
7620
7621	    break;
7622
7623	default:
7624	  gcc_unreachable ();
7625	}
7626
7627      if (width < HOST_BITS_PER_WIDE_INT)
7628	return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), r_lo);
7629      else
7630	return build_int_cst_wide (TREE_TYPE (TREE_TYPE (fndecl)), r_lo, r_hi);
7631    }
7632
7633  return NULL_TREE;
7634}
7635/* Return true if EXPR is the real constant contained in VALUE.  */
7636
7637static bool
7638real_dconstp (tree expr, const REAL_VALUE_TYPE *value)
7639{
7640  STRIP_NOPS (expr);
7641
7642  return ((TREE_CODE (expr) == REAL_CST
7643	   && ! TREE_CONSTANT_OVERFLOW (expr)
7644	   && REAL_VALUES_EQUAL (TREE_REAL_CST (expr), *value))
7645	  || (TREE_CODE (expr) == COMPLEX_CST
7646	      && real_dconstp (TREE_REALPART (expr), value)
7647	      && real_zerop (TREE_IMAGPART (expr))));
7648}
7649
7650/* A subroutine of fold_builtin to fold the various logarithmic
7651   functions.  EXP is the CALL_EXPR of a call to a builtin logN
7652   function.  VALUE is the base of the logN function.  */
7653
7654static tree
7655fold_builtin_logarithm (tree fndecl, tree arglist,
7656			const REAL_VALUE_TYPE *value)
7657{
7658  if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7659    {
7660      tree type = TREE_TYPE (TREE_TYPE (fndecl));
7661      tree arg = TREE_VALUE (arglist);
7662      const enum built_in_function fcode = builtin_mathfn_code (arg);
7663
7664      /* Optimize logN(1.0) = 0.0.  */
7665      if (real_onep (arg))
7666	return build_real (type, dconst0);
7667
7668      /* Optimize logN(N) = 1.0.  If N can't be truncated to MODE
7669	 exactly, then only do this if flag_unsafe_math_optimizations.  */
7670      if (exact_real_truncate (TYPE_MODE (type), value)
7671	  || flag_unsafe_math_optimizations)
7672	{
7673	  const REAL_VALUE_TYPE value_truncate =
7674	    real_value_truncate (TYPE_MODE (type), *value);
7675	  if (real_dconstp (arg, &value_truncate))
7676	    return build_real (type, dconst1);
7677	}
7678
7679      /* Special case, optimize logN(expN(x)) = x.  */
7680      if (flag_unsafe_math_optimizations
7681	  && ((value == &dconste
7682	       && (fcode == BUILT_IN_EXP
7683		   || fcode == BUILT_IN_EXPF
7684		   || fcode == BUILT_IN_EXPL))
7685	      || (value == &dconst2
7686		  && (fcode == BUILT_IN_EXP2
7687		      || fcode == BUILT_IN_EXP2F
7688		      || fcode == BUILT_IN_EXP2L))
7689	      || (value == &dconst10 && (BUILTIN_EXP10_P (fcode)))))
7690	return fold_convert (type, TREE_VALUE (TREE_OPERAND (arg, 1)));
7691
7692      /* Optimize logN(func()) for various exponential functions.  We
7693	 want to determine the value "x" and the power "exponent" in
7694	 order to transform logN(x**exponent) into exponent*logN(x).  */
7695      if (flag_unsafe_math_optimizations)
7696	{
7697	  tree exponent = 0, x = 0;
7698
7699	  switch (fcode)
7700	  {
7701	  CASE_FLT_FN (BUILT_IN_EXP):
7702	    /* Prepare to do logN(exp(exponent) -> exponent*logN(e).  */
7703	    x = build_real (type,
7704			    real_value_truncate (TYPE_MODE (type), dconste));
7705	    exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
7706	    break;
7707	  CASE_FLT_FN (BUILT_IN_EXP2):
7708	    /* Prepare to do logN(exp2(exponent) -> exponent*logN(2).  */
7709	    x = build_real (type, dconst2);
7710	    exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
7711	    break;
7712	  CASE_FLT_FN (BUILT_IN_EXP10):
7713	  CASE_FLT_FN (BUILT_IN_POW10):
7714	    /* Prepare to do logN(exp10(exponent) -> exponent*logN(10).  */
7715	    x = build_real (type, dconst10);
7716	    exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
7717	    break;
7718	  CASE_FLT_FN (BUILT_IN_SQRT):
7719	    /* Prepare to do logN(sqrt(x) -> 0.5*logN(x).  */
7720	    x = TREE_VALUE (TREE_OPERAND (arg, 1));
7721	    exponent = build_real (type, dconsthalf);
7722	    break;
7723	  CASE_FLT_FN (BUILT_IN_CBRT):
7724	    /* Prepare to do logN(cbrt(x) -> (1/3)*logN(x).  */
7725	    x = TREE_VALUE (TREE_OPERAND (arg, 1));
7726	    exponent = build_real (type, real_value_truncate (TYPE_MODE (type),
7727							      dconstthird));
7728	    break;
7729	  CASE_FLT_FN (BUILT_IN_POW):
7730	    /* Prepare to do logN(pow(x,exponent) -> exponent*logN(x).  */
7731	    x = TREE_VALUE (TREE_OPERAND (arg, 1));
7732	    exponent = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
7733	    break;
7734	  default:
7735	    break;
7736	  }
7737
7738	  /* Now perform the optimization.  */
7739	  if (x && exponent)
7740	    {
7741	      tree logfn;
7742	      arglist = build_tree_list (NULL_TREE, x);
7743	      logfn = build_function_call_expr (fndecl, arglist);
7744	      return fold_build2 (MULT_EXPR, type, exponent, logfn);
7745	    }
7746	}
7747    }
7748
7749  return 0;
7750}
7751
7752/* Fold a builtin function call to pow, powf, or powl.  Return
7753   NULL_TREE if no simplification can be made.  */
7754static tree
7755fold_builtin_pow (tree fndecl, tree arglist, tree type)
7756{
7757  tree arg0 = TREE_VALUE (arglist);
7758  tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7759
7760  if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
7761    return NULL_TREE;
7762
7763  /* Optimize pow(1.0,y) = 1.0.  */
7764  if (real_onep (arg0))
7765    return omit_one_operand (type, build_real (type, dconst1), arg1);
7766
7767  if (TREE_CODE (arg1) == REAL_CST
7768      && ! TREE_CONSTANT_OVERFLOW (arg1))
7769    {
7770      REAL_VALUE_TYPE cint;
7771      REAL_VALUE_TYPE c;
7772      HOST_WIDE_INT n;
7773
7774      c = TREE_REAL_CST (arg1);
7775
7776      /* Optimize pow(x,0.0) = 1.0.  */
7777      if (REAL_VALUES_EQUAL (c, dconst0))
7778	return omit_one_operand (type, build_real (type, dconst1),
7779				 arg0);
7780
7781      /* Optimize pow(x,1.0) = x.  */
7782      if (REAL_VALUES_EQUAL (c, dconst1))
7783	return arg0;
7784
7785      /* Optimize pow(x,-1.0) = 1.0/x.  */
7786      if (REAL_VALUES_EQUAL (c, dconstm1))
7787	return fold_build2 (RDIV_EXPR, type,
7788			    build_real (type, dconst1), arg0);
7789
7790      /* Optimize pow(x,0.5) = sqrt(x).  */
7791      if (flag_unsafe_math_optimizations
7792	  && REAL_VALUES_EQUAL (c, dconsthalf))
7793	{
7794	  tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
7795
7796	  if (sqrtfn != NULL_TREE)
7797	    {
7798	      tree arglist = build_tree_list (NULL_TREE, arg0);
7799	      return build_function_call_expr (sqrtfn, arglist);
7800	    }
7801	}
7802
7803      /* Check for an integer exponent.  */
7804      n = real_to_integer (&c);
7805      real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
7806      if (real_identical (&c, &cint))
7807	{
7808	  /* Attempt to evaluate pow at compile-time.  */
7809	  if (TREE_CODE (arg0) == REAL_CST
7810	      && ! TREE_CONSTANT_OVERFLOW (arg0))
7811	    {
7812	      REAL_VALUE_TYPE x;
7813	      bool inexact;
7814
7815	      x = TREE_REAL_CST (arg0);
7816	      inexact = real_powi (&x, TYPE_MODE (type), &x, n);
7817	      if (flag_unsafe_math_optimizations || !inexact)
7818		return build_real (type, x);
7819	    }
7820
7821	  /* Strip sign ops from even integer powers.  */
7822	  if ((n & 1) == 0 && flag_unsafe_math_optimizations)
7823	    {
7824	      tree narg0 = fold_strip_sign_ops (arg0);
7825	      if (narg0)
7826		{
7827		  arglist = build_tree_list (NULL_TREE, arg1);
7828		  arglist = tree_cons (NULL_TREE, narg0, arglist);
7829		  return build_function_call_expr (fndecl, arglist);
7830		}
7831	    }
7832	}
7833    }
7834
7835  if (flag_unsafe_math_optimizations)
7836    {
7837      const enum built_in_function fcode = builtin_mathfn_code (arg0);
7838
7839      /* Optimize pow(expN(x),y) = expN(x*y).  */
7840      if (BUILTIN_EXPONENT_P (fcode))
7841	{
7842	  tree expfn = TREE_OPERAND (TREE_OPERAND (arg0, 0), 0);
7843	  tree arg = TREE_VALUE (TREE_OPERAND (arg0, 1));
7844	  arg = fold_build2 (MULT_EXPR, type, arg, arg1);
7845	  arglist = build_tree_list (NULL_TREE, arg);
7846	  return build_function_call_expr (expfn, arglist);
7847	}
7848
7849      /* Optimize pow(sqrt(x),y) = pow(x,y*0.5).  */
7850      if (BUILTIN_SQRT_P (fcode))
7851	{
7852	  tree narg0 = TREE_VALUE (TREE_OPERAND (arg0, 1));
7853	  tree narg1 = fold_build2 (MULT_EXPR, type, arg1,
7854				    build_real (type, dconsthalf));
7855
7856	  arglist = tree_cons (NULL_TREE, narg0,
7857			       build_tree_list (NULL_TREE, narg1));
7858	  return build_function_call_expr (fndecl, arglist);
7859	}
7860
7861      /* Optimize pow(cbrt(x),y) = pow(x,y/3) iff x is nonnegative.  */
7862      if (BUILTIN_CBRT_P (fcode))
7863	{
7864	  tree arg = TREE_VALUE (TREE_OPERAND (arg0, 1));
7865	  if (tree_expr_nonnegative_p (arg))
7866	    {
7867	      const REAL_VALUE_TYPE dconstroot
7868		= real_value_truncate (TYPE_MODE (type), dconstthird);
7869	      tree narg1 = fold_build2 (MULT_EXPR, type, arg1,
7870					build_real (type, dconstroot));
7871	      arglist = tree_cons (NULL_TREE, arg,
7872				   build_tree_list (NULL_TREE, narg1));
7873	      return build_function_call_expr (fndecl, arglist);
7874	    }
7875	}
7876
7877      /* Optimize pow(pow(x,y),z) = pow(x,y*z).  */
7878      if (fcode == BUILT_IN_POW || fcode == BUILT_IN_POWF
7879	   || fcode == BUILT_IN_POWL)
7880	{
7881	  tree arg00 = TREE_VALUE (TREE_OPERAND (arg0, 1));
7882	  tree arg01 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg0, 1)));
7883	  tree narg1 = fold_build2 (MULT_EXPR, type, arg01, arg1);
7884	  arglist = tree_cons (NULL_TREE, arg00,
7885			       build_tree_list (NULL_TREE, narg1));
7886	  return build_function_call_expr (fndecl, arglist);
7887	}
7888    }
7889
7890  return NULL_TREE;
7891}
7892
7893/* Fold a builtin function call to powi, powif, or powil.  Return
7894   NULL_TREE if no simplification can be made.  */
7895static tree
7896fold_builtin_powi (tree fndecl ATTRIBUTE_UNUSED, tree arglist, tree type)
7897{
7898  tree arg0 = TREE_VALUE (arglist);
7899  tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7900
7901  if (!validate_arglist (arglist, REAL_TYPE, INTEGER_TYPE, VOID_TYPE))
7902    return NULL_TREE;
7903
7904  /* Optimize pow(1.0,y) = 1.0.  */
7905  if (real_onep (arg0))
7906    return omit_one_operand (type, build_real (type, dconst1), arg1);
7907
7908  if (host_integerp (arg1, 0))
7909    {
7910      HOST_WIDE_INT c = TREE_INT_CST_LOW (arg1);
7911
7912      /* Evaluate powi at compile-time.  */
7913      if (TREE_CODE (arg0) == REAL_CST
7914	  && ! TREE_CONSTANT_OVERFLOW (arg0))
7915	{
7916	  REAL_VALUE_TYPE x;
7917	  x = TREE_REAL_CST (arg0);
7918	  real_powi (&x, TYPE_MODE (type), &x, c);
7919	  return build_real (type, x);
7920	}
7921
7922      /* Optimize pow(x,0) = 1.0.  */
7923      if (c == 0)
7924	return omit_one_operand (type, build_real (type, dconst1),
7925				 arg0);
7926
7927      /* Optimize pow(x,1) = x.  */
7928      if (c == 1)
7929	return arg0;
7930
7931      /* Optimize pow(x,-1) = 1.0/x.  */
7932      if (c == -1)
7933	return fold_build2 (RDIV_EXPR, type,
7934			   build_real (type, dconst1), arg0);
7935    }
7936
7937  return NULL_TREE;
7938}
7939
7940/* A subroutine of fold_builtin to fold the various exponent
7941   functions.  EXP is the CALL_EXPR of a call to a builtin function.
7942   VALUE is the value which will be raised to a power.  */
7943
7944static tree
7945fold_builtin_exponent (tree fndecl, tree arglist,
7946		       const REAL_VALUE_TYPE *value)
7947{
7948  if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7949    {
7950      tree type = TREE_TYPE (TREE_TYPE (fndecl));
7951      tree arg = TREE_VALUE (arglist);
7952
7953      /* Optimize exp*(0.0) = 1.0.  */
7954      if (real_zerop (arg))
7955	return build_real (type, dconst1);
7956
7957      /* Optimize expN(1.0) = N.  */
7958      if (real_onep (arg))
7959	{
7960	  REAL_VALUE_TYPE cst;
7961
7962	  real_convert (&cst, TYPE_MODE (type), value);
7963	  return build_real (type, cst);
7964	}
7965
7966      /* Attempt to evaluate expN(integer) at compile-time.  */
7967      if (flag_unsafe_math_optimizations
7968	  && TREE_CODE (arg) == REAL_CST
7969	  && ! TREE_CONSTANT_OVERFLOW (arg))
7970	{
7971	  REAL_VALUE_TYPE cint;
7972	  REAL_VALUE_TYPE c;
7973	  HOST_WIDE_INT n;
7974
7975	  c = TREE_REAL_CST (arg);
7976	  n = real_to_integer (&c);
7977	  real_from_integer (&cint, VOIDmode, n,
7978			     n < 0 ? -1 : 0, 0);
7979	  if (real_identical (&c, &cint))
7980	    {
7981	      REAL_VALUE_TYPE x;
7982
7983	      real_powi (&x, TYPE_MODE (type), value, n);
7984	      return build_real (type, x);
7985	    }
7986	}
7987
7988      /* Optimize expN(logN(x)) = x.  */
7989      if (flag_unsafe_math_optimizations)
7990	{
7991	  const enum built_in_function fcode = builtin_mathfn_code (arg);
7992
7993	  if ((value == &dconste
7994	       && (fcode == BUILT_IN_LOG
7995		   || fcode == BUILT_IN_LOGF
7996		   || fcode == BUILT_IN_LOGL))
7997	      || (value == &dconst2
7998		  && (fcode == BUILT_IN_LOG2
7999		      || fcode == BUILT_IN_LOG2F
8000		      || fcode == BUILT_IN_LOG2L))
8001	      || (value == &dconst10
8002		  && (fcode == BUILT_IN_LOG10
8003		      || fcode == BUILT_IN_LOG10F
8004		      || fcode == BUILT_IN_LOG10L)))
8005	    return fold_convert (type, TREE_VALUE (TREE_OPERAND (arg, 1)));
8006	}
8007    }
8008
8009  return 0;
8010}
8011
8012/* Return true if VAR is a VAR_DECL or a component thereof.  */
8013
8014static bool
8015var_decl_component_p (tree var)
8016{
8017  tree inner = var;
8018  while (handled_component_p (inner))
8019    inner = TREE_OPERAND (inner, 0);
8020  return SSA_VAR_P (inner);
8021}
8022
8023/* Fold function call to builtin memset.  Return
8024   NULL_TREE if no simplification can be made.  */
8025
8026static tree
8027fold_builtin_memset (tree arglist, tree type, bool ignore)
8028{
8029  tree dest, c, len, var, ret;
8030  unsigned HOST_WIDE_INT length, cval;
8031
8032  if (!validate_arglist (arglist,
8033			 POINTER_TYPE, INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
8034    return 0;
8035
8036  dest = TREE_VALUE (arglist);
8037  c = TREE_VALUE (TREE_CHAIN (arglist));
8038  len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8039
8040  if (! host_integerp (len, 1))
8041    return 0;
8042
8043  /* If the LEN parameter is zero, return DEST.  */
8044  if (integer_zerop (len))
8045    return omit_one_operand (type, dest, c);
8046
8047  if (! host_integerp (c, 1) || TREE_SIDE_EFFECTS (dest))
8048    return 0;
8049
8050  var = dest;
8051  STRIP_NOPS (var);
8052  if (TREE_CODE (var) != ADDR_EXPR)
8053    return 0;
8054
8055  var = TREE_OPERAND (var, 0);
8056  if (TREE_THIS_VOLATILE (var))
8057    return 0;
8058
8059  if (!INTEGRAL_TYPE_P (TREE_TYPE (var))
8060      && !POINTER_TYPE_P (TREE_TYPE (var)))
8061    return 0;
8062
8063  if (! var_decl_component_p (var))
8064    return 0;
8065
8066  length = tree_low_cst (len, 1);
8067  if (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (var))) != length
8068      || get_pointer_alignment (dest, BIGGEST_ALIGNMENT) / BITS_PER_UNIT
8069	 < (int) length)
8070    return 0;
8071
8072  if (length > HOST_BITS_PER_WIDE_INT / BITS_PER_UNIT)
8073    return 0;
8074
8075  if (integer_zerop (c))
8076    cval = 0;
8077  else
8078    {
8079      if (CHAR_BIT != 8 || BITS_PER_UNIT != 8 || HOST_BITS_PER_WIDE_INT > 64)
8080	return 0;
8081
8082      cval = tree_low_cst (c, 1);
8083      cval &= 0xff;
8084      cval |= cval << 8;
8085      cval |= cval << 16;
8086      cval |= (cval << 31) << 1;
8087    }
8088
8089  ret = build_int_cst_type (TREE_TYPE (var), cval);
8090  ret = build2 (MODIFY_EXPR, TREE_TYPE (var), var, ret);
8091  if (ignore)
8092    return ret;
8093
8094  return omit_one_operand (type, dest, ret);
8095}
8096
8097/* Fold function call to builtin memset.  Return
8098   NULL_TREE if no simplification can be made.  */
8099
8100static tree
8101fold_builtin_bzero (tree arglist, bool ignore)
8102{
8103  tree dest, size, newarglist;
8104
8105  if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8106    return 0;
8107
8108  if (!ignore)
8109    return 0;
8110
8111  dest = TREE_VALUE (arglist);
8112  size = TREE_VALUE (TREE_CHAIN (arglist));
8113
8114  /* New argument list transforming bzero(ptr x, int y) to
8115     memset(ptr x, int 0, size_t y).   This is done this way
8116     so that if it isn't expanded inline, we fallback to
8117     calling bzero instead of memset.  */
8118
8119  newarglist = build_tree_list (NULL_TREE, fold_convert (sizetype, size));
8120  newarglist = tree_cons (NULL_TREE, integer_zero_node, newarglist);
8121  newarglist = tree_cons (NULL_TREE, dest, newarglist);
8122  return fold_builtin_memset (newarglist, void_type_node, ignore);
8123}
8124
8125/* Fold function call to builtin mem{{,p}cpy,move}.  Return
8126   NULL_TREE if no simplification can be made.
8127   If ENDP is 0, return DEST (like memcpy).
8128   If ENDP is 1, return DEST+LEN (like mempcpy).
8129   If ENDP is 2, return DEST+LEN-1 (like stpcpy).
8130   If ENDP is 3, return DEST, additionally *SRC and *DEST may overlap
8131   (memmove).   */
8132
8133static tree
8134fold_builtin_memory_op (tree arglist, tree type, bool ignore, int endp)
8135{
8136  tree dest, src, len, destvar, srcvar, expr;
8137  unsigned HOST_WIDE_INT length;
8138
8139  if (! validate_arglist (arglist,
8140			  POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8141    return 0;
8142
8143  dest = TREE_VALUE (arglist);
8144  src = TREE_VALUE (TREE_CHAIN (arglist));
8145  len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8146
8147  /* If the LEN parameter is zero, return DEST.  */
8148  if (integer_zerop (len))
8149    return omit_one_operand (type, dest, src);
8150
8151  /* If SRC and DEST are the same (and not volatile), return
8152     DEST{,+LEN,+LEN-1}.  */
8153  if (operand_equal_p (src, dest, 0))
8154    expr = len;
8155  else
8156    {
8157      if (! host_integerp (len, 1))
8158	return 0;
8159
8160      if (TREE_SIDE_EFFECTS (dest) || TREE_SIDE_EFFECTS (src))
8161	return 0;
8162
8163      destvar = dest;
8164      STRIP_NOPS (destvar);
8165      if (TREE_CODE (destvar) != ADDR_EXPR)
8166	return 0;
8167
8168      destvar = TREE_OPERAND (destvar, 0);
8169      if (TREE_THIS_VOLATILE (destvar))
8170	return 0;
8171
8172      if (!INTEGRAL_TYPE_P (TREE_TYPE (destvar))
8173	  && !POINTER_TYPE_P (TREE_TYPE (destvar))
8174	  && !SCALAR_FLOAT_TYPE_P (TREE_TYPE (destvar)))
8175	return 0;
8176
8177      if (! var_decl_component_p (destvar))
8178	return 0;
8179
8180      srcvar = src;
8181      STRIP_NOPS (srcvar);
8182      if (TREE_CODE (srcvar) != ADDR_EXPR)
8183	return 0;
8184
8185      srcvar = TREE_OPERAND (srcvar, 0);
8186      if (TREE_THIS_VOLATILE (srcvar))
8187	return 0;
8188
8189      if (!INTEGRAL_TYPE_P (TREE_TYPE (srcvar))
8190	  && !POINTER_TYPE_P (TREE_TYPE (srcvar))
8191	  && !SCALAR_FLOAT_TYPE_P (TREE_TYPE (srcvar)))
8192	return 0;
8193
8194      if (! var_decl_component_p (srcvar))
8195	return 0;
8196
8197      length = tree_low_cst (len, 1);
8198      if (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (destvar))) != length
8199	  || get_pointer_alignment (dest, BIGGEST_ALIGNMENT) / BITS_PER_UNIT
8200	     < (int) length
8201	  || GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (srcvar))) != length
8202	  || get_pointer_alignment (src, BIGGEST_ALIGNMENT) / BITS_PER_UNIT
8203	     < (int) length)
8204	return 0;
8205
8206      if ((INTEGRAL_TYPE_P (TREE_TYPE (srcvar))
8207	   || POINTER_TYPE_P (TREE_TYPE (srcvar)))
8208	  && (INTEGRAL_TYPE_P (TREE_TYPE (destvar))
8209	      || POINTER_TYPE_P (TREE_TYPE (destvar))))
8210	expr = fold_convert (TREE_TYPE (destvar), srcvar);
8211      else
8212	expr = fold_build1 (VIEW_CONVERT_EXPR, TREE_TYPE (destvar), srcvar);
8213      expr = build2 (MODIFY_EXPR, TREE_TYPE (destvar), destvar, expr);
8214    }
8215
8216  if (ignore)
8217    return expr;
8218
8219  if (endp == 0 || endp == 3)
8220    return omit_one_operand (type, dest, expr);
8221
8222  if (expr == len)
8223    expr = 0;
8224
8225  if (endp == 2)
8226    len = fold_build2 (MINUS_EXPR, TREE_TYPE (len), len,
8227		       ssize_int (1));
8228
8229  len = fold_convert (TREE_TYPE (dest), len);
8230  dest = fold_build2 (PLUS_EXPR, TREE_TYPE (dest), dest, len);
8231  dest = fold_convert (type, dest);
8232  if (expr)
8233    dest = omit_one_operand (type, dest, expr);
8234  return dest;
8235}
8236
8237/* Fold function call to builtin bcopy.  Return NULL_TREE if no
8238   simplification can be made.  */
8239
8240static tree
8241fold_builtin_bcopy (tree arglist, bool ignore)
8242{
8243  tree src, dest, size, newarglist;
8244
8245  if (!validate_arglist (arglist,
8246			 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8247    return 0;
8248
8249  if (! ignore)
8250    return 0;
8251
8252  src = TREE_VALUE (arglist);
8253  dest = TREE_VALUE (TREE_CHAIN (arglist));
8254  size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8255
8256  /* New argument list transforming bcopy(ptr x, ptr y, int z) to
8257     memmove(ptr y, ptr x, size_t z).   This is done this way
8258     so that if it isn't expanded inline, we fallback to
8259     calling bcopy instead of memmove.  */
8260
8261  newarglist = build_tree_list (NULL_TREE, fold_convert (sizetype, size));
8262  newarglist = tree_cons (NULL_TREE, src, newarglist);
8263  newarglist = tree_cons (NULL_TREE, dest, newarglist);
8264
8265  return fold_builtin_memory_op (newarglist, void_type_node, true, /*endp=*/3);
8266}
8267
8268/* Fold function call to builtin strcpy.  If LEN is not NULL, it represents
8269   the length of the string to be copied.  Return NULL_TREE if no
8270   simplification can be made.  */
8271
8272tree
8273fold_builtin_strcpy (tree fndecl, tree arglist, tree len)
8274{
8275  tree dest, src, fn;
8276
8277  if (!validate_arglist (arglist,
8278			 POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
8279    return 0;
8280
8281  dest = TREE_VALUE (arglist);
8282  src = TREE_VALUE (TREE_CHAIN (arglist));
8283
8284  /* If SRC and DEST are the same (and not volatile), return DEST.  */
8285  if (operand_equal_p (src, dest, 0))
8286    return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), dest);
8287
8288  if (optimize_size)
8289    return 0;
8290
8291  fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
8292  if (!fn)
8293    return 0;
8294
8295  if (!len)
8296    {
8297      len = c_strlen (src, 1);
8298      if (! len || TREE_SIDE_EFFECTS (len))
8299	return 0;
8300    }
8301
8302  len = size_binop (PLUS_EXPR, len, ssize_int (1));
8303  arglist = build_tree_list (NULL_TREE, len);
8304  arglist = tree_cons (NULL_TREE, src, arglist);
8305  arglist = tree_cons (NULL_TREE, dest, arglist);
8306  return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)),
8307		       build_function_call_expr (fn, arglist));
8308}
8309
8310/* Fold function call to builtin strncpy.  If SLEN is not NULL, it represents
8311   the length of the source string.  Return NULL_TREE if no simplification
8312   can be made.  */
8313
8314tree
8315fold_builtin_strncpy (tree fndecl, tree arglist, tree slen)
8316{
8317  tree dest, src, len, fn;
8318
8319  if (!validate_arglist (arglist,
8320			 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8321    return 0;
8322
8323  dest = TREE_VALUE (arglist);
8324  src = TREE_VALUE (TREE_CHAIN (arglist));
8325  len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8326
8327  /* If the LEN parameter is zero, return DEST.  */
8328  if (integer_zerop (len))
8329    return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
8330
8331  /* We can't compare slen with len as constants below if len is not a
8332     constant.  */
8333  if (len == 0 || TREE_CODE (len) != INTEGER_CST)
8334    return 0;
8335
8336  if (!slen)
8337    slen = c_strlen (src, 1);
8338
8339  /* Now, we must be passed a constant src ptr parameter.  */
8340  if (slen == 0 || TREE_CODE (slen) != INTEGER_CST)
8341    return 0;
8342
8343  slen = size_binop (PLUS_EXPR, slen, ssize_int (1));
8344
8345  /* We do not support simplification of this case, though we do
8346     support it when expanding trees into RTL.  */
8347  /* FIXME: generate a call to __builtin_memset.  */
8348  if (tree_int_cst_lt (slen, len))
8349    return 0;
8350
8351  /* OK transform into builtin memcpy.  */
8352  fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
8353  if (!fn)
8354    return 0;
8355  return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)),
8356		       build_function_call_expr (fn, arglist));
8357}
8358
8359/* Fold function call to builtin memcmp.  Return
8360   NULL_TREE if no simplification can be made.  */
8361
8362static tree
8363fold_builtin_memcmp (tree arglist)
8364{
8365  tree arg1, arg2, len;
8366  const char *p1, *p2;
8367
8368  if (!validate_arglist (arglist,
8369			 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8370    return 0;
8371
8372  arg1 = TREE_VALUE (arglist);
8373  arg2 = TREE_VALUE (TREE_CHAIN (arglist));
8374  len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8375
8376  /* If the LEN parameter is zero, return zero.  */
8377  if (integer_zerop (len))
8378    return omit_two_operands (integer_type_node, integer_zero_node,
8379			      arg1, arg2);
8380
8381  /* If ARG1 and ARG2 are the same (and not volatile), return zero.  */
8382  if (operand_equal_p (arg1, arg2, 0))
8383    return omit_one_operand (integer_type_node, integer_zero_node, len);
8384
8385  p1 = c_getstr (arg1);
8386  p2 = c_getstr (arg2);
8387
8388  /* If all arguments are constant, and the value of len is not greater
8389     than the lengths of arg1 and arg2, evaluate at compile-time.  */
8390  if (host_integerp (len, 1) && p1 && p2
8391      && compare_tree_int (len, strlen (p1) + 1) <= 0
8392      && compare_tree_int (len, strlen (p2) + 1) <= 0)
8393    {
8394      const int r = memcmp (p1, p2, tree_low_cst (len, 1));
8395
8396      if (r > 0)
8397	return integer_one_node;
8398      else if (r < 0)
8399	return integer_minus_one_node;
8400      else
8401	return integer_zero_node;
8402    }
8403
8404  /* If len parameter is one, return an expression corresponding to
8405     (*(const unsigned char*)arg1 - (const unsigned char*)arg2).  */
8406  if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
8407    {
8408      tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8409      tree cst_uchar_ptr_node
8410	= build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8411
8412      tree ind1 = fold_convert (integer_type_node,
8413				build1 (INDIRECT_REF, cst_uchar_node,
8414					fold_convert (cst_uchar_ptr_node,
8415						      arg1)));
8416      tree ind2 = fold_convert (integer_type_node,
8417				build1 (INDIRECT_REF, cst_uchar_node,
8418					fold_convert (cst_uchar_ptr_node,
8419						      arg2)));
8420      return fold_build2 (MINUS_EXPR, integer_type_node, ind1, ind2);
8421    }
8422
8423  return 0;
8424}
8425
8426/* Fold function call to builtin strcmp.  Return
8427   NULL_TREE if no simplification can be made.  */
8428
8429static tree
8430fold_builtin_strcmp (tree arglist)
8431{
8432  tree arg1, arg2;
8433  const char *p1, *p2;
8434
8435  if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
8436    return 0;
8437
8438  arg1 = TREE_VALUE (arglist);
8439  arg2 = TREE_VALUE (TREE_CHAIN (arglist));
8440
8441  /* If ARG1 and ARG2 are the same (and not volatile), return zero.  */
8442  if (operand_equal_p (arg1, arg2, 0))
8443    return integer_zero_node;
8444
8445  p1 = c_getstr (arg1);
8446  p2 = c_getstr (arg2);
8447
8448  if (p1 && p2)
8449    {
8450      const int i = strcmp (p1, p2);
8451      if (i < 0)
8452	return integer_minus_one_node;
8453      else if (i > 0)
8454	return integer_one_node;
8455      else
8456	return integer_zero_node;
8457    }
8458
8459  /* If the second arg is "", return *(const unsigned char*)arg1.  */
8460  if (p2 && *p2 == '\0')
8461    {
8462      tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8463      tree cst_uchar_ptr_node
8464	= build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8465
8466      return fold_convert (integer_type_node,
8467			   build1 (INDIRECT_REF, cst_uchar_node,
8468				   fold_convert (cst_uchar_ptr_node,
8469						 arg1)));
8470    }
8471
8472  /* If the first arg is "", return -*(const unsigned char*)arg2.  */
8473  if (p1 && *p1 == '\0')
8474    {
8475      tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8476      tree cst_uchar_ptr_node
8477	= build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8478
8479      tree temp = fold_convert (integer_type_node,
8480				build1 (INDIRECT_REF, cst_uchar_node,
8481					fold_convert (cst_uchar_ptr_node,
8482						      arg2)));
8483      return fold_build1 (NEGATE_EXPR, integer_type_node, temp);
8484    }
8485
8486  return 0;
8487}
8488
8489/* Fold function call to builtin strncmp.  Return
8490   NULL_TREE if no simplification can be made.  */
8491
8492static tree
8493fold_builtin_strncmp (tree arglist)
8494{
8495  tree arg1, arg2, len;
8496  const char *p1, *p2;
8497
8498  if (!validate_arglist (arglist,
8499			 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8500    return 0;
8501
8502  arg1 = TREE_VALUE (arglist);
8503  arg2 = TREE_VALUE (TREE_CHAIN (arglist));
8504  len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8505
8506  /* If the LEN parameter is zero, return zero.  */
8507  if (integer_zerop (len))
8508    return omit_two_operands (integer_type_node, integer_zero_node,
8509			      arg1, arg2);
8510
8511  /* If ARG1 and ARG2 are the same (and not volatile), return zero.  */
8512  if (operand_equal_p (arg1, arg2, 0))
8513    return omit_one_operand (integer_type_node, integer_zero_node, len);
8514
8515  p1 = c_getstr (arg1);
8516  p2 = c_getstr (arg2);
8517
8518  if (host_integerp (len, 1) && p1 && p2)
8519    {
8520      const int i = strncmp (p1, p2, tree_low_cst (len, 1));
8521      if (i > 0)
8522	return integer_one_node;
8523      else if (i < 0)
8524	return integer_minus_one_node;
8525      else
8526	return integer_zero_node;
8527    }
8528
8529  /* If the second arg is "", and the length is greater than zero,
8530     return *(const unsigned char*)arg1.  */
8531  if (p2 && *p2 == '\0'
8532      && TREE_CODE (len) == INTEGER_CST
8533      && tree_int_cst_sgn (len) == 1)
8534    {
8535      tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8536      tree cst_uchar_ptr_node
8537	= build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8538
8539      return fold_convert (integer_type_node,
8540			   build1 (INDIRECT_REF, cst_uchar_node,
8541				   fold_convert (cst_uchar_ptr_node,
8542						 arg1)));
8543    }
8544
8545  /* If the first arg is "", and the length is greater than zero,
8546     return -*(const unsigned char*)arg2.  */
8547  if (p1 && *p1 == '\0'
8548      && TREE_CODE (len) == INTEGER_CST
8549      && tree_int_cst_sgn (len) == 1)
8550    {
8551      tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8552      tree cst_uchar_ptr_node
8553	= build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8554
8555      tree temp = fold_convert (integer_type_node,
8556				build1 (INDIRECT_REF, cst_uchar_node,
8557					fold_convert (cst_uchar_ptr_node,
8558						      arg2)));
8559      return fold_build1 (NEGATE_EXPR, integer_type_node, temp);
8560    }
8561
8562  /* If len parameter is one, return an expression corresponding to
8563     (*(const unsigned char*)arg1 - (const unsigned char*)arg2).  */
8564  if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
8565    {
8566      tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8567      tree cst_uchar_ptr_node
8568	= build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8569
8570      tree ind1 = fold_convert (integer_type_node,
8571				build1 (INDIRECT_REF, cst_uchar_node,
8572					fold_convert (cst_uchar_ptr_node,
8573						      arg1)));
8574      tree ind2 = fold_convert (integer_type_node,
8575				build1 (INDIRECT_REF, cst_uchar_node,
8576					fold_convert (cst_uchar_ptr_node,
8577						      arg2)));
8578      return fold_build2 (MINUS_EXPR, integer_type_node, ind1, ind2);
8579    }
8580
8581  return 0;
8582}
8583
8584/* Fold function call to builtin signbit, signbitf or signbitl.  Return
8585   NULL_TREE if no simplification can be made.  */
8586
8587static tree
8588fold_builtin_signbit (tree fndecl, tree arglist)
8589{
8590  tree type = TREE_TYPE (TREE_TYPE (fndecl));
8591  tree arg, temp;
8592
8593  if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8594    return NULL_TREE;
8595
8596  arg = TREE_VALUE (arglist);
8597
8598  /* If ARG is a compile-time constant, determine the result.  */
8599  if (TREE_CODE (arg) == REAL_CST
8600      && !TREE_CONSTANT_OVERFLOW (arg))
8601    {
8602      REAL_VALUE_TYPE c;
8603
8604      c = TREE_REAL_CST (arg);
8605      temp = REAL_VALUE_NEGATIVE (c) ? integer_one_node : integer_zero_node;
8606      return fold_convert (type, temp);
8607    }
8608
8609  /* If ARG is non-negative, the result is always zero.  */
8610  if (tree_expr_nonnegative_p (arg))
8611    return omit_one_operand (type, integer_zero_node, arg);
8612
8613  /* If ARG's format doesn't have signed zeros, return "arg < 0.0".  */
8614  if (!HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg))))
8615    return fold_build2 (LT_EXPR, type, arg,
8616			build_real (TREE_TYPE (arg), dconst0));
8617
8618  return NULL_TREE;
8619}
8620
8621/* Fold function call to builtin copysign, copysignf or copysignl.
8622   Return NULL_TREE if no simplification can be made.  */
8623
8624static tree
8625fold_builtin_copysign (tree fndecl, tree arglist, tree type)
8626{
8627  tree arg1, arg2, tem;
8628
8629  if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
8630    return NULL_TREE;
8631
8632  arg1 = TREE_VALUE (arglist);
8633  arg2 = TREE_VALUE (TREE_CHAIN (arglist));
8634
8635  /* copysign(X,X) is X.  */
8636  if (operand_equal_p (arg1, arg2, 0))
8637    return fold_convert (type, arg1);
8638
8639  /* If ARG1 and ARG2 are compile-time constants, determine the result.  */
8640  if (TREE_CODE (arg1) == REAL_CST
8641      && TREE_CODE (arg2) == REAL_CST
8642      && !TREE_CONSTANT_OVERFLOW (arg1)
8643      && !TREE_CONSTANT_OVERFLOW (arg2))
8644    {
8645      REAL_VALUE_TYPE c1, c2;
8646
8647      c1 = TREE_REAL_CST (arg1);
8648      c2 = TREE_REAL_CST (arg2);
8649      /* c1.sign := c2.sign.  */
8650      real_copysign (&c1, &c2);
8651      return build_real (type, c1);
8652    }
8653
8654  /* copysign(X, Y) is fabs(X) when Y is always non-negative.
8655     Remember to evaluate Y for side-effects.  */
8656  if (tree_expr_nonnegative_p (arg2))
8657    return omit_one_operand (type,
8658			     fold_build1 (ABS_EXPR, type, arg1),
8659			     arg2);
8660
8661  /* Strip sign changing operations for the first argument.  */
8662  tem = fold_strip_sign_ops (arg1);
8663  if (tem)
8664    {
8665      arglist = tree_cons (NULL_TREE, tem, TREE_CHAIN (arglist));
8666      return build_function_call_expr (fndecl, arglist);
8667    }
8668
8669  return NULL_TREE;
8670}
8671
8672/* Fold a call to builtin isascii.  */
8673
8674static tree
8675fold_builtin_isascii (tree arglist)
8676{
8677  if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8678    return 0;
8679  else
8680    {
8681      /* Transform isascii(c) -> ((c & ~0x7f) == 0).  */
8682      tree arg = TREE_VALUE (arglist);
8683
8684      arg = build2 (BIT_AND_EXPR, integer_type_node, arg,
8685		    build_int_cst (NULL_TREE,
8686				   ~ (unsigned HOST_WIDE_INT) 0x7f));
8687      arg = fold_build2 (EQ_EXPR, integer_type_node,
8688			 arg, integer_zero_node);
8689
8690      if (in_gimple_form && !TREE_CONSTANT (arg))
8691	return NULL_TREE;
8692      else
8693	return arg;
8694    }
8695}
8696
8697/* Fold a call to builtin toascii.  */
8698
8699static tree
8700fold_builtin_toascii (tree arglist)
8701{
8702  if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8703    return 0;
8704  else
8705    {
8706      /* Transform toascii(c) -> (c & 0x7f).  */
8707      tree arg = TREE_VALUE (arglist);
8708
8709      return fold_build2 (BIT_AND_EXPR, integer_type_node, arg,
8710			  build_int_cst (NULL_TREE, 0x7f));
8711    }
8712}
8713
8714/* Fold a call to builtin isdigit.  */
8715
8716static tree
8717fold_builtin_isdigit (tree arglist)
8718{
8719  if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8720    return 0;
8721  else
8722    {
8723      /* Transform isdigit(c) -> (unsigned)(c) - '0' <= 9.  */
8724      /* According to the C standard, isdigit is unaffected by locale.
8725	 However, it definitely is affected by the target character set.  */
8726      tree arg;
8727      unsigned HOST_WIDE_INT target_digit0
8728	= lang_hooks.to_target_charset ('0');
8729
8730      if (target_digit0 == 0)
8731	return NULL_TREE;
8732
8733      arg = fold_convert (unsigned_type_node, TREE_VALUE (arglist));
8734      arg = build2 (MINUS_EXPR, unsigned_type_node, arg,
8735		    build_int_cst (unsigned_type_node, target_digit0));
8736      arg = fold_build2 (LE_EXPR, integer_type_node, arg,
8737			 build_int_cst (unsigned_type_node, 9));
8738      if (in_gimple_form && !TREE_CONSTANT (arg))
8739	return NULL_TREE;
8740      else
8741	return arg;
8742    }
8743}
8744
8745/* Fold a call to fabs, fabsf or fabsl.  */
8746
8747static tree
8748fold_builtin_fabs (tree arglist, tree type)
8749{
8750  tree arg;
8751
8752  if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8753    return 0;
8754
8755  arg = TREE_VALUE (arglist);
8756  arg = fold_convert (type, arg);
8757  if (TREE_CODE (arg) == REAL_CST)
8758    return fold_abs_const (arg, type);
8759  return fold_build1 (ABS_EXPR, type, arg);
8760}
8761
8762/* Fold a call to abs, labs, llabs or imaxabs.  */
8763
8764static tree
8765fold_builtin_abs (tree arglist, tree type)
8766{
8767  tree arg;
8768
8769  if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8770    return 0;
8771
8772  arg = TREE_VALUE (arglist);
8773  arg = fold_convert (type, arg);
8774  if (TREE_CODE (arg) == INTEGER_CST)
8775    return fold_abs_const (arg, type);
8776  return fold_build1 (ABS_EXPR, type, arg);
8777}
8778
8779/* Fold a call to __builtin_isnan(), __builtin_isinf, __builtin_finite.
8780   EXP is the CALL_EXPR for the call.  */
8781
8782static tree
8783fold_builtin_classify (tree fndecl, tree arglist, int builtin_index)
8784{
8785  tree type = TREE_TYPE (TREE_TYPE (fndecl));
8786  tree arg;
8787  REAL_VALUE_TYPE r;
8788
8789  if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8790    {
8791      /* Check that we have exactly one argument.  */
8792      if (arglist == 0)
8793	{
8794	  error ("too few arguments to function %qs",
8795		 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8796	  return error_mark_node;
8797	}
8798      else if (TREE_CHAIN (arglist) != 0)
8799	{
8800	  error ("too many arguments to function %qs",
8801		 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8802	  return error_mark_node;
8803	}
8804      else
8805	{
8806	  error ("non-floating-point argument to function %qs",
8807		 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8808	  return error_mark_node;
8809	}
8810    }
8811
8812  arg = TREE_VALUE (arglist);
8813  switch (builtin_index)
8814    {
8815    case BUILT_IN_ISINF:
8816      if (!HONOR_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
8817	return omit_one_operand (type, integer_zero_node, arg);
8818
8819      if (TREE_CODE (arg) == REAL_CST)
8820	{
8821	  r = TREE_REAL_CST (arg);
8822	  if (real_isinf (&r))
8823	    return real_compare (GT_EXPR, &r, &dconst0)
8824		   ? integer_one_node : integer_minus_one_node;
8825	  else
8826	    return integer_zero_node;
8827	}
8828
8829      return NULL_TREE;
8830
8831    case BUILT_IN_FINITE:
8832      if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg)))
8833	  && !HONOR_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
8834	return omit_one_operand (type, integer_one_node, arg);
8835
8836      if (TREE_CODE (arg) == REAL_CST)
8837	{
8838	  r = TREE_REAL_CST (arg);
8839	  return real_isinf (&r) || real_isnan (&r)
8840		 ? integer_zero_node : integer_one_node;
8841	}
8842
8843      return NULL_TREE;
8844
8845    case BUILT_IN_ISNAN:
8846      if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg))))
8847	return omit_one_operand (type, integer_zero_node, arg);
8848
8849      if (TREE_CODE (arg) == REAL_CST)
8850	{
8851	  r = TREE_REAL_CST (arg);
8852	  return real_isnan (&r) ? integer_one_node : integer_zero_node;
8853	}
8854
8855      arg = builtin_save_expr (arg);
8856      return fold_build2 (UNORDERED_EXPR, type, arg, arg);
8857
8858    default:
8859      gcc_unreachable ();
8860    }
8861}
8862
8863/* Fold a call to an unordered comparison function such as
8864   __builtin_isgreater().  FNDECL is the FUNCTION_DECL for the function
8865   being called and ARGLIST is the argument list for the call.
8866   UNORDERED_CODE and ORDERED_CODE are comparison codes that give
8867   the opposite of the desired result.  UNORDERED_CODE is used
8868   for modes that can hold NaNs and ORDERED_CODE is used for
8869   the rest.  */
8870
8871static tree
8872fold_builtin_unordered_cmp (tree fndecl, tree arglist,
8873			    enum tree_code unordered_code,
8874			    enum tree_code ordered_code)
8875{
8876  tree type = TREE_TYPE (TREE_TYPE (fndecl));
8877  enum tree_code code;
8878  tree arg0, arg1;
8879  tree type0, type1;
8880  enum tree_code code0, code1;
8881  tree cmp_type = NULL_TREE;
8882
8883  if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
8884    {
8885      /* Check that we have exactly two arguments.  */
8886      if (arglist == 0 || TREE_CHAIN (arglist) == 0)
8887	{
8888	  error ("too few arguments to function %qs",
8889		 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8890	  return error_mark_node;
8891	}
8892      else if (TREE_CHAIN (TREE_CHAIN (arglist)) != 0)
8893	{
8894	  error ("too many arguments to function %qs",
8895		 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8896	  return error_mark_node;
8897	}
8898    }
8899
8900  arg0 = TREE_VALUE (arglist);
8901  arg1 = TREE_VALUE (TREE_CHAIN (arglist));
8902
8903  type0 = TREE_TYPE (arg0);
8904  type1 = TREE_TYPE (arg1);
8905
8906  code0 = TREE_CODE (type0);
8907  code1 = TREE_CODE (type1);
8908
8909  if (code0 == REAL_TYPE && code1 == REAL_TYPE)
8910    /* Choose the wider of two real types.  */
8911    cmp_type = TYPE_PRECISION (type0) >= TYPE_PRECISION (type1)
8912      ? type0 : type1;
8913  else if (code0 == REAL_TYPE && code1 == INTEGER_TYPE)
8914    cmp_type = type0;
8915  else if (code0 == INTEGER_TYPE && code1 == REAL_TYPE)
8916    cmp_type = type1;
8917  else
8918    {
8919      error ("non-floating-point argument to function %qs",
8920		 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8921      return error_mark_node;
8922    }
8923
8924  arg0 = fold_convert (cmp_type, arg0);
8925  arg1 = fold_convert (cmp_type, arg1);
8926
8927  if (unordered_code == UNORDERED_EXPR)
8928    {
8929      if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg0))))
8930	return omit_two_operands (type, integer_zero_node, arg0, arg1);
8931      return fold_build2 (UNORDERED_EXPR, type, arg0, arg1);
8932    }
8933
8934  code = HONOR_NANS (TYPE_MODE (TREE_TYPE (arg0))) ? unordered_code
8935						   : ordered_code;
8936  return fold_build1 (TRUTH_NOT_EXPR, type,
8937		      fold_build2 (code, type, arg0, arg1));
8938}
8939
8940/* Used by constant folding to simplify calls to builtin functions.  EXP is
8941   the CALL_EXPR of a call to a builtin function.  IGNORE is true if the
8942   result of the function call is ignored.  This function returns NULL_TREE
8943   if no simplification was possible.  */
8944
8945static tree
8946fold_builtin_1 (tree fndecl, tree arglist, bool ignore)
8947{
8948  tree type = TREE_TYPE (TREE_TYPE (fndecl));
8949  enum built_in_function fcode;
8950
8951  if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
8952    return targetm.fold_builtin (fndecl, arglist, ignore);
8953
8954  fcode = DECL_FUNCTION_CODE (fndecl);
8955  switch (fcode)
8956    {
8957    case BUILT_IN_FPUTS:
8958      return fold_builtin_fputs (arglist, ignore, false, NULL_TREE);
8959
8960    case BUILT_IN_FPUTS_UNLOCKED:
8961      return fold_builtin_fputs (arglist, ignore, true, NULL_TREE);
8962
8963    case BUILT_IN_STRSTR:
8964      return fold_builtin_strstr (arglist, type);
8965
8966    case BUILT_IN_STRCAT:
8967      return fold_builtin_strcat (arglist);
8968
8969    case BUILT_IN_STRNCAT:
8970      return fold_builtin_strncat (arglist);
8971
8972    case BUILT_IN_STRSPN:
8973      return fold_builtin_strspn (arglist);
8974
8975    case BUILT_IN_STRCSPN:
8976      return fold_builtin_strcspn (arglist);
8977
8978    case BUILT_IN_STRCHR:
8979    case BUILT_IN_INDEX:
8980      return fold_builtin_strchr (arglist, type);
8981
8982    case BUILT_IN_STRRCHR:
8983    case BUILT_IN_RINDEX:
8984      return fold_builtin_strrchr (arglist, type);
8985
8986    case BUILT_IN_STRCPY:
8987      return fold_builtin_strcpy (fndecl, arglist, NULL_TREE);
8988
8989    case BUILT_IN_STRNCPY:
8990      return fold_builtin_strncpy (fndecl, arglist, NULL_TREE);
8991
8992    case BUILT_IN_STRCMP:
8993      return fold_builtin_strcmp (arglist);
8994
8995    case BUILT_IN_STRNCMP:
8996      return fold_builtin_strncmp (arglist);
8997
8998    case BUILT_IN_STRPBRK:
8999      return fold_builtin_strpbrk (arglist, type);
9000
9001    case BUILT_IN_BCMP:
9002    case BUILT_IN_MEMCMP:
9003      return fold_builtin_memcmp (arglist);
9004
9005    case BUILT_IN_SPRINTF:
9006      return fold_builtin_sprintf (arglist, ignore);
9007
9008    case BUILT_IN_CONSTANT_P:
9009      {
9010	tree val;
9011
9012	val = fold_builtin_constant_p (arglist);
9013	/* Gimplification will pull the CALL_EXPR for the builtin out of
9014	   an if condition.  When not optimizing, we'll not CSE it back.
9015	   To avoid link error types of regressions, return false now.  */
9016	if (!val && !optimize)
9017	  val = integer_zero_node;
9018
9019	return val;
9020      }
9021
9022    case BUILT_IN_EXPECT:
9023      return fold_builtin_expect (arglist);
9024
9025    case BUILT_IN_CLASSIFY_TYPE:
9026      return fold_builtin_classify_type (arglist);
9027
9028    case BUILT_IN_STRLEN:
9029      return fold_builtin_strlen (arglist);
9030
9031    CASE_FLT_FN (BUILT_IN_FABS):
9032      return fold_builtin_fabs (arglist, type);
9033
9034    case BUILT_IN_ABS:
9035    case BUILT_IN_LABS:
9036    case BUILT_IN_LLABS:
9037    case BUILT_IN_IMAXABS:
9038      return fold_builtin_abs (arglist, type);
9039
9040    CASE_FLT_FN (BUILT_IN_CONJ):
9041      if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
9042	return fold_build1 (CONJ_EXPR, type, TREE_VALUE (arglist));
9043      break;
9044
9045    CASE_FLT_FN (BUILT_IN_CREAL):
9046      if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
9047	return non_lvalue (fold_build1 (REALPART_EXPR, type,
9048					TREE_VALUE (arglist)));
9049      break;
9050
9051    CASE_FLT_FN (BUILT_IN_CIMAG):
9052      if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
9053	return non_lvalue (fold_build1 (IMAGPART_EXPR, type,
9054					TREE_VALUE (arglist)));
9055      break;
9056
9057    CASE_FLT_FN (BUILT_IN_CABS):
9058      return fold_builtin_cabs (arglist, type, fndecl);
9059
9060    CASE_FLT_FN (BUILT_IN_SQRT):
9061      return fold_builtin_sqrt (arglist, type);
9062
9063    CASE_FLT_FN (BUILT_IN_CBRT):
9064      return fold_builtin_cbrt (arglist, type);
9065
9066    CASE_FLT_FN (BUILT_IN_SIN):
9067      return fold_builtin_sin (arglist);
9068
9069    CASE_FLT_FN (BUILT_IN_COS):
9070      return fold_builtin_cos (arglist, type, fndecl);
9071
9072    CASE_FLT_FN (BUILT_IN_EXP):
9073      return fold_builtin_exponent (fndecl, arglist, &dconste);
9074
9075    CASE_FLT_FN (BUILT_IN_EXP2):
9076      return fold_builtin_exponent (fndecl, arglist, &dconst2);
9077
9078    CASE_FLT_FN (BUILT_IN_EXP10):
9079    CASE_FLT_FN (BUILT_IN_POW10):
9080      return fold_builtin_exponent (fndecl, arglist, &dconst10);
9081
9082    CASE_FLT_FN (BUILT_IN_LOG):
9083      return fold_builtin_logarithm (fndecl, arglist, &dconste);
9084
9085    CASE_FLT_FN (BUILT_IN_LOG2):
9086      return fold_builtin_logarithm (fndecl, arglist, &dconst2);
9087
9088    CASE_FLT_FN (BUILT_IN_LOG10):
9089      return fold_builtin_logarithm (fndecl, arglist, &dconst10);
9090
9091    CASE_FLT_FN (BUILT_IN_TAN):
9092      return fold_builtin_tan (arglist);
9093
9094    CASE_FLT_FN (BUILT_IN_ATAN):
9095      return fold_builtin_atan (arglist, type);
9096
9097    CASE_FLT_FN (BUILT_IN_POW):
9098      return fold_builtin_pow (fndecl, arglist, type);
9099
9100    CASE_FLT_FN (BUILT_IN_POWI):
9101      return fold_builtin_powi (fndecl, arglist, type);
9102
9103    CASE_FLT_FN (BUILT_IN_INF):
9104    case BUILT_IN_INFD32:
9105    case BUILT_IN_INFD64:
9106    case BUILT_IN_INFD128:
9107      return fold_builtin_inf (type, true);
9108
9109    CASE_FLT_FN (BUILT_IN_HUGE_VAL):
9110      return fold_builtin_inf (type, false);
9111
9112    CASE_FLT_FN (BUILT_IN_NAN):
9113    case BUILT_IN_NAND32:
9114    case BUILT_IN_NAND64:
9115    case BUILT_IN_NAND128:
9116      return fold_builtin_nan (arglist, type, true);
9117
9118    CASE_FLT_FN (BUILT_IN_NANS):
9119      return fold_builtin_nan (arglist, type, false);
9120
9121    CASE_FLT_FN (BUILT_IN_FLOOR):
9122      return fold_builtin_floor (fndecl, arglist);
9123
9124    CASE_FLT_FN (BUILT_IN_CEIL):
9125      return fold_builtin_ceil (fndecl, arglist);
9126
9127    CASE_FLT_FN (BUILT_IN_TRUNC):
9128      return fold_builtin_trunc (fndecl, arglist);
9129
9130    CASE_FLT_FN (BUILT_IN_ROUND):
9131      return fold_builtin_round (fndecl, arglist);
9132
9133    CASE_FLT_FN (BUILT_IN_NEARBYINT):
9134    CASE_FLT_FN (BUILT_IN_RINT):
9135      return fold_trunc_transparent_mathfn (fndecl, arglist);
9136
9137    CASE_FLT_FN (BUILT_IN_LCEIL):
9138    CASE_FLT_FN (BUILT_IN_LLCEIL):
9139    CASE_FLT_FN (BUILT_IN_LFLOOR):
9140    CASE_FLT_FN (BUILT_IN_LLFLOOR):
9141    CASE_FLT_FN (BUILT_IN_LROUND):
9142    CASE_FLT_FN (BUILT_IN_LLROUND):
9143      return fold_builtin_int_roundingfn (fndecl, arglist);
9144
9145    CASE_FLT_FN (BUILT_IN_LRINT):
9146    CASE_FLT_FN (BUILT_IN_LLRINT):
9147      return fold_fixed_mathfn (fndecl, arglist);
9148
9149    case BUILT_IN_BSWAP32:
9150    case BUILT_IN_BSWAP64:
9151      return fold_builtin_bswap (fndecl, arglist);
9152
9153    CASE_INT_FN (BUILT_IN_FFS):
9154    CASE_INT_FN (BUILT_IN_CLZ):
9155    CASE_INT_FN (BUILT_IN_CTZ):
9156    CASE_INT_FN (BUILT_IN_POPCOUNT):
9157    CASE_INT_FN (BUILT_IN_PARITY):
9158      return fold_builtin_bitop (fndecl, arglist);
9159
9160    case BUILT_IN_MEMSET:
9161      return fold_builtin_memset (arglist, type, ignore);
9162
9163    case BUILT_IN_MEMCPY:
9164      return fold_builtin_memory_op (arglist, type, ignore, /*endp=*/0);
9165
9166    case BUILT_IN_MEMPCPY:
9167      return fold_builtin_memory_op (arglist, type, ignore, /*endp=*/1);
9168
9169    case BUILT_IN_MEMMOVE:
9170      return fold_builtin_memory_op (arglist, type, ignore, /*endp=*/3);
9171
9172    case BUILT_IN_BZERO:
9173      return fold_builtin_bzero (arglist, ignore);
9174
9175    case BUILT_IN_BCOPY:
9176      return fold_builtin_bcopy (arglist, ignore);
9177
9178    CASE_FLT_FN (BUILT_IN_SIGNBIT):
9179      return fold_builtin_signbit (fndecl, arglist);
9180
9181    case BUILT_IN_ISASCII:
9182      return fold_builtin_isascii (arglist);
9183
9184    case BUILT_IN_TOASCII:
9185      return fold_builtin_toascii (arglist);
9186
9187    case BUILT_IN_ISDIGIT:
9188      return fold_builtin_isdigit (arglist);
9189
9190    CASE_FLT_FN (BUILT_IN_COPYSIGN):
9191      return fold_builtin_copysign (fndecl, arglist, type);
9192
9193    CASE_FLT_FN (BUILT_IN_FINITE):
9194    case BUILT_IN_FINITED32:
9195    case BUILT_IN_FINITED64:
9196    case BUILT_IN_FINITED128:
9197      return fold_builtin_classify (fndecl, arglist, BUILT_IN_FINITE);
9198
9199    CASE_FLT_FN (BUILT_IN_ISINF):
9200    case BUILT_IN_ISINFD32:
9201    case BUILT_IN_ISINFD64:
9202    case BUILT_IN_ISINFD128:
9203      return fold_builtin_classify (fndecl, arglist, BUILT_IN_ISINF);
9204
9205    CASE_FLT_FN (BUILT_IN_ISNAN):
9206    case BUILT_IN_ISNAND32:
9207    case BUILT_IN_ISNAND64:
9208    case BUILT_IN_ISNAND128:
9209      return fold_builtin_classify (fndecl, arglist, BUILT_IN_ISNAN);
9210
9211    case BUILT_IN_ISGREATER:
9212      return fold_builtin_unordered_cmp (fndecl, arglist, UNLE_EXPR, LE_EXPR);
9213    case BUILT_IN_ISGREATEREQUAL:
9214      return fold_builtin_unordered_cmp (fndecl, arglist, UNLT_EXPR, LT_EXPR);
9215    case BUILT_IN_ISLESS:
9216      return fold_builtin_unordered_cmp (fndecl, arglist, UNGE_EXPR, GE_EXPR);
9217    case BUILT_IN_ISLESSEQUAL:
9218      return fold_builtin_unordered_cmp (fndecl, arglist, UNGT_EXPR, GT_EXPR);
9219    case BUILT_IN_ISLESSGREATER:
9220      return fold_builtin_unordered_cmp (fndecl, arglist, UNEQ_EXPR, EQ_EXPR);
9221    case BUILT_IN_ISUNORDERED:
9222      return fold_builtin_unordered_cmp (fndecl, arglist, UNORDERED_EXPR,
9223					 NOP_EXPR);
9224
9225      /* We do the folding for va_start in the expander.  */
9226    case BUILT_IN_VA_START:
9227      break;
9228
9229    case BUILT_IN_OBJECT_SIZE:
9230      return fold_builtin_object_size (arglist);
9231    case BUILT_IN_MEMCPY_CHK:
9232    case BUILT_IN_MEMPCPY_CHK:
9233    case BUILT_IN_MEMMOVE_CHK:
9234    case BUILT_IN_MEMSET_CHK:
9235      return fold_builtin_memory_chk (fndecl, arglist, NULL_TREE, ignore,
9236				      DECL_FUNCTION_CODE (fndecl));
9237    case BUILT_IN_STRCPY_CHK:
9238    case BUILT_IN_STPCPY_CHK:
9239      return fold_builtin_stxcpy_chk (fndecl, arglist, NULL_TREE, ignore,
9240				      DECL_FUNCTION_CODE (fndecl));
9241    case BUILT_IN_STRNCPY_CHK:
9242      return fold_builtin_strncpy_chk (arglist, NULL_TREE);
9243    case BUILT_IN_STRCAT_CHK:
9244      return fold_builtin_strcat_chk (fndecl, arglist);
9245    case BUILT_IN_STRNCAT_CHK:
9246      return fold_builtin_strncat_chk (fndecl, arglist);
9247    case BUILT_IN_SPRINTF_CHK:
9248    case BUILT_IN_VSPRINTF_CHK:
9249      return fold_builtin_sprintf_chk (arglist, DECL_FUNCTION_CODE (fndecl));
9250    case BUILT_IN_SNPRINTF_CHK:
9251    case BUILT_IN_VSNPRINTF_CHK:
9252      return fold_builtin_snprintf_chk (arglist, NULL_TREE,
9253					DECL_FUNCTION_CODE (fndecl));
9254
9255    case BUILT_IN_PRINTF:
9256    case BUILT_IN_PRINTF_UNLOCKED:
9257    case BUILT_IN_VPRINTF:
9258    case BUILT_IN_PRINTF_CHK:
9259    case BUILT_IN_VPRINTF_CHK:
9260      return fold_builtin_printf (fndecl, arglist, ignore,
9261				  DECL_FUNCTION_CODE (fndecl));
9262
9263    case BUILT_IN_FPRINTF:
9264    case BUILT_IN_FPRINTF_UNLOCKED:
9265    case BUILT_IN_VFPRINTF:
9266    case BUILT_IN_FPRINTF_CHK:
9267    case BUILT_IN_VFPRINTF_CHK:
9268      return fold_builtin_fprintf (fndecl, arglist, ignore,
9269				   DECL_FUNCTION_CODE (fndecl));
9270
9271    default:
9272      break;
9273    }
9274
9275  return 0;
9276}
9277
9278/* A wrapper function for builtin folding that prevents warnings for
9279   "statement without effect" and the like, caused by removing the
9280   call node earlier than the warning is generated.  */
9281
9282tree
9283fold_builtin (tree fndecl, tree arglist, bool ignore)
9284{
9285  tree exp = fold_builtin_1 (fndecl, arglist, ignore);
9286  if (exp)
9287    {
9288      exp = build1 (NOP_EXPR, TREE_TYPE (exp), exp);
9289      TREE_NO_WARNING (exp) = 1;
9290    }
9291
9292  return exp;
9293}
9294
9295/* Conveniently construct a function call expression.  */
9296
9297tree
9298build_function_call_expr (tree fn, tree arglist)
9299{
9300  tree call_expr;
9301
9302  call_expr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
9303  return fold_build3 (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)),
9304		      call_expr, arglist, NULL_TREE);
9305}
9306
9307/* This function validates the types of a function call argument list
9308   represented as a tree chain of parameters against a specified list
9309   of tree_codes.  If the last specifier is a 0, that represents an
9310   ellipses, otherwise the last specifier must be a VOID_TYPE.  */
9311
9312static int
9313validate_arglist (tree arglist, ...)
9314{
9315  enum tree_code code;
9316  int res = 0;
9317  va_list ap;
9318
9319  va_start (ap, arglist);
9320
9321  do
9322    {
9323      code = va_arg (ap, enum tree_code);
9324      switch (code)
9325	{
9326	case 0:
9327	  /* This signifies an ellipses, any further arguments are all ok.  */
9328	  res = 1;
9329	  goto end;
9330	case VOID_TYPE:
9331	  /* This signifies an endlink, if no arguments remain, return
9332	     true, otherwise return false.  */
9333	  res = arglist == 0;
9334	  goto end;
9335	default:
9336	  /* If no parameters remain or the parameter's code does not
9337	     match the specified code, return false.  Otherwise continue
9338	     checking any remaining arguments.  */
9339	  if (arglist == 0)
9340	    goto end;
9341	  if (code == POINTER_TYPE)
9342	    {
9343	      if (! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist))))
9344		goto end;
9345	    }
9346	  else if (code != TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))))
9347	    goto end;
9348	  break;
9349	}
9350      arglist = TREE_CHAIN (arglist);
9351    }
9352  while (1);
9353
9354  /* We need gotos here since we can only have one VA_CLOSE in a
9355     function.  */
9356 end: ;
9357  va_end (ap);
9358
9359  return res;
9360}
9361
9362/* Default target-specific builtin expander that does nothing.  */
9363
9364rtx
9365default_expand_builtin (tree exp ATTRIBUTE_UNUSED,
9366			rtx target ATTRIBUTE_UNUSED,
9367			rtx subtarget ATTRIBUTE_UNUSED,
9368			enum machine_mode mode ATTRIBUTE_UNUSED,
9369			int ignore ATTRIBUTE_UNUSED)
9370{
9371  return NULL_RTX;
9372}
9373
9374/* Returns true is EXP represents data that would potentially reside
9375   in a readonly section.  */
9376
9377static bool
9378readonly_data_expr (tree exp)
9379{
9380  STRIP_NOPS (exp);
9381
9382  if (TREE_CODE (exp) != ADDR_EXPR)
9383    return false;
9384
9385  exp = get_base_address (TREE_OPERAND (exp, 0));
9386  if (!exp)
9387    return false;
9388
9389  /* Make sure we call decl_readonly_section only for trees it
9390     can handle (since it returns true for everything it doesn't
9391     understand).  */
9392  if (TREE_CODE (exp) == STRING_CST
9393      || TREE_CODE (exp) == CONSTRUCTOR
9394      || (TREE_CODE (exp) == VAR_DECL && TREE_STATIC (exp)))
9395    return decl_readonly_section (exp, 0);
9396  else
9397    return false;
9398}
9399
9400/* Simplify a call to the strstr builtin.
9401
9402   Return 0 if no simplification was possible, otherwise return the
9403   simplified form of the call as a tree.
9404
9405   The simplified form may be a constant or other expression which
9406   computes the same value, but in a more efficient manner (including
9407   calls to other builtin functions).
9408
9409   The call may contain arguments which need to be evaluated, but
9410   which are not useful to determine the result of the call.  In
9411   this case we return a chain of COMPOUND_EXPRs.  The LHS of each
9412   COMPOUND_EXPR will be an argument which must be evaluated.
9413   COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
9414   COMPOUND_EXPR in the chain will contain the tree for the simplified
9415   form of the builtin function call.  */
9416
9417static tree
9418fold_builtin_strstr (tree arglist, tree type)
9419{
9420  if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9421    return 0;
9422  else
9423    {
9424      tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9425      tree fn;
9426      const char *p1, *p2;
9427
9428      p2 = c_getstr (s2);
9429      if (p2 == NULL)
9430	return 0;
9431
9432      p1 = c_getstr (s1);
9433      if (p1 != NULL)
9434	{
9435	  const char *r = strstr (p1, p2);
9436	  tree tem;
9437
9438	  if (r == NULL)
9439	    return build_int_cst (TREE_TYPE (s1), 0);
9440
9441	  /* Return an offset into the constant string argument.  */
9442	  tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
9443			     s1, build_int_cst (TREE_TYPE (s1), r - p1));
9444	  return fold_convert (type, tem);
9445	}
9446
9447      /* The argument is const char *, and the result is char *, so we need
9448	 a type conversion here to avoid a warning.  */
9449      if (p2[0] == '\0')
9450	return fold_convert (type, s1);
9451
9452      if (p2[1] != '\0')
9453	return 0;
9454
9455      fn = implicit_built_in_decls[BUILT_IN_STRCHR];
9456      if (!fn)
9457	return 0;
9458
9459      /* New argument list transforming strstr(s1, s2) to
9460	 strchr(s1, s2[0]).  */
9461      arglist = build_tree_list (NULL_TREE,
9462				 build_int_cst (NULL_TREE, p2[0]));
9463      arglist = tree_cons (NULL_TREE, s1, arglist);
9464      return build_function_call_expr (fn, arglist);
9465    }
9466}
9467
9468/* Simplify a call to the strchr builtin.
9469
9470   Return 0 if no simplification was possible, otherwise return the
9471   simplified form of the call as a tree.
9472
9473   The simplified form may be a constant or other expression which
9474   computes the same value, but in a more efficient manner (including
9475   calls to other builtin functions).
9476
9477   The call may contain arguments which need to be evaluated, but
9478   which are not useful to determine the result of the call.  In
9479   this case we return a chain of COMPOUND_EXPRs.  The LHS of each
9480   COMPOUND_EXPR will be an argument which must be evaluated.
9481   COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
9482   COMPOUND_EXPR in the chain will contain the tree for the simplified
9483   form of the builtin function call.  */
9484
9485static tree
9486fold_builtin_strchr (tree arglist, tree type)
9487{
9488  if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9489    return 0;
9490  else
9491    {
9492      tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9493      const char *p1;
9494
9495      if (TREE_CODE (s2) != INTEGER_CST)
9496	return 0;
9497
9498      p1 = c_getstr (s1);
9499      if (p1 != NULL)
9500	{
9501	  char c;
9502	  const char *r;
9503	  tree tem;
9504
9505	  if (target_char_cast (s2, &c))
9506	    return 0;
9507
9508	  r = strchr (p1, c);
9509
9510	  if (r == NULL)
9511	    return build_int_cst (TREE_TYPE (s1), 0);
9512
9513	  /* Return an offset into the constant string argument.  */
9514	  tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
9515			     s1, build_int_cst (TREE_TYPE (s1), r - p1));
9516	  return fold_convert (type, tem);
9517	}
9518      return 0;
9519    }
9520}
9521
9522/* Simplify a call to the strrchr builtin.
9523
9524   Return 0 if no simplification was possible, otherwise return the
9525   simplified form of the call as a tree.
9526
9527   The simplified form may be a constant or other expression which
9528   computes the same value, but in a more efficient manner (including
9529   calls to other builtin functions).
9530
9531   The call may contain arguments which need to be evaluated, but
9532   which are not useful to determine the result of the call.  In
9533   this case we return a chain of COMPOUND_EXPRs.  The LHS of each
9534   COMPOUND_EXPR will be an argument which must be evaluated.
9535   COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
9536   COMPOUND_EXPR in the chain will contain the tree for the simplified
9537   form of the builtin function call.  */
9538
9539static tree
9540fold_builtin_strrchr (tree arglist, tree type)
9541{
9542  if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9543    return 0;
9544  else
9545    {
9546      tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9547      tree fn;
9548      const char *p1;
9549
9550      if (TREE_CODE (s2) != INTEGER_CST)
9551	return 0;
9552
9553      p1 = c_getstr (s1);
9554      if (p1 != NULL)
9555	{
9556	  char c;
9557	  const char *r;
9558	  tree tem;
9559
9560	  if (target_char_cast (s2, &c))
9561	    return 0;
9562
9563	  r = strrchr (p1, c);
9564
9565	  if (r == NULL)
9566	    return build_int_cst (TREE_TYPE (s1), 0);
9567
9568	  /* Return an offset into the constant string argument.  */
9569	  tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
9570			     s1, build_int_cst (TREE_TYPE (s1), r - p1));
9571	  return fold_convert (type, tem);
9572	}
9573
9574      if (! integer_zerop (s2))
9575	return 0;
9576
9577      fn = implicit_built_in_decls[BUILT_IN_STRCHR];
9578      if (!fn)
9579	return 0;
9580
9581      /* Transform strrchr(s1, '\0') to strchr(s1, '\0').  */
9582      return build_function_call_expr (fn, arglist);
9583    }
9584}
9585
9586/* Simplify a call to the strpbrk builtin.
9587
9588   Return 0 if no simplification was possible, otherwise return the
9589   simplified form of the call as a tree.
9590
9591   The simplified form may be a constant or other expression which
9592   computes the same value, but in a more efficient manner (including
9593   calls to other builtin functions).
9594
9595   The call may contain arguments which need to be evaluated, but
9596   which are not useful to determine the result of the call.  In
9597   this case we return a chain of COMPOUND_EXPRs.  The LHS of each
9598   COMPOUND_EXPR will be an argument which must be evaluated.
9599   COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
9600   COMPOUND_EXPR in the chain will contain the tree for the simplified
9601   form of the builtin function call.  */
9602
9603static tree
9604fold_builtin_strpbrk (tree arglist, tree type)
9605{
9606  if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9607    return 0;
9608  else
9609    {
9610      tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9611      tree fn;
9612      const char *p1, *p2;
9613
9614      p2 = c_getstr (s2);
9615      if (p2 == NULL)
9616	return 0;
9617
9618      p1 = c_getstr (s1);
9619      if (p1 != NULL)
9620	{
9621	  const char *r = strpbrk (p1, p2);
9622	  tree tem;
9623
9624	  if (r == NULL)
9625	    return build_int_cst (TREE_TYPE (s1), 0);
9626
9627	  /* Return an offset into the constant string argument.  */
9628	  tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
9629			     s1, build_int_cst (TREE_TYPE (s1), r - p1));
9630	  return fold_convert (type, tem);
9631	}
9632
9633      if (p2[0] == '\0')
9634	/* strpbrk(x, "") == NULL.
9635	   Evaluate and ignore s1 in case it had side-effects.  */
9636	return omit_one_operand (TREE_TYPE (s1), integer_zero_node, s1);
9637
9638      if (p2[1] != '\0')
9639	return 0;  /* Really call strpbrk.  */
9640
9641      fn = implicit_built_in_decls[BUILT_IN_STRCHR];
9642      if (!fn)
9643	return 0;
9644
9645      /* New argument list transforming strpbrk(s1, s2) to
9646	 strchr(s1, s2[0]).  */
9647      arglist = build_tree_list (NULL_TREE,
9648				 build_int_cst (NULL_TREE, p2[0]));
9649      arglist = tree_cons (NULL_TREE, s1, arglist);
9650      return build_function_call_expr (fn, arglist);
9651    }
9652}
9653
9654/* Simplify a call to the strcat builtin.
9655
9656   Return 0 if no simplification was possible, otherwise return the
9657   simplified form of the call as a tree.
9658
9659   The simplified form may be a constant or other expression which
9660   computes the same value, but in a more efficient manner (including
9661   calls to other builtin functions).
9662
9663   The call may contain arguments which need to be evaluated, but
9664   which are not useful to determine the result of the call.  In
9665   this case we return a chain of COMPOUND_EXPRs.  The LHS of each
9666   COMPOUND_EXPR will be an argument which must be evaluated.
9667   COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
9668   COMPOUND_EXPR in the chain will contain the tree for the simplified
9669   form of the builtin function call.  */
9670
9671static tree
9672fold_builtin_strcat (tree arglist)
9673{
9674  if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9675    return 0;
9676  else
9677    {
9678      tree dst = TREE_VALUE (arglist),
9679	src = TREE_VALUE (TREE_CHAIN (arglist));
9680      const char *p = c_getstr (src);
9681
9682      /* If the string length is zero, return the dst parameter.  */
9683      if (p && *p == '\0')
9684	return dst;
9685
9686      return 0;
9687    }
9688}
9689
9690/* Simplify a call to the strncat builtin.
9691
9692   Return 0 if no simplification was possible, otherwise return the
9693   simplified form of the call as a tree.
9694
9695   The simplified form may be a constant or other expression which
9696   computes the same value, but in a more efficient manner (including
9697   calls to other builtin functions).
9698
9699   The call may contain arguments which need to be evaluated, but
9700   which are not useful to determine the result of the call.  In
9701   this case we return a chain of COMPOUND_EXPRs.  The LHS of each
9702   COMPOUND_EXPR will be an argument which must be evaluated.
9703   COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
9704   COMPOUND_EXPR in the chain will contain the tree for the simplified
9705   form of the builtin function call.  */
9706
9707static tree
9708fold_builtin_strncat (tree arglist)
9709{
9710  if (!validate_arglist (arglist,
9711			 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9712    return 0;
9713  else
9714    {
9715      tree dst = TREE_VALUE (arglist);
9716      tree src = TREE_VALUE (TREE_CHAIN (arglist));
9717      tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
9718      const char *p = c_getstr (src);
9719
9720      /* If the requested length is zero, or the src parameter string
9721	 length is zero, return the dst parameter.  */
9722      if (integer_zerop (len) || (p && *p == '\0'))
9723	return omit_two_operands (TREE_TYPE (dst), dst, src, len);
9724
9725      /* If the requested len is greater than or equal to the string
9726	 length, call strcat.  */
9727      if (TREE_CODE (len) == INTEGER_CST && p
9728	  && compare_tree_int (len, strlen (p)) >= 0)
9729	{
9730	  tree newarglist
9731	    = tree_cons (NULL_TREE, dst, build_tree_list (NULL_TREE, src));
9732	  tree fn = implicit_built_in_decls[BUILT_IN_STRCAT];
9733
9734	  /* If the replacement _DECL isn't initialized, don't do the
9735	     transformation.  */
9736	  if (!fn)
9737	    return 0;
9738
9739	  return build_function_call_expr (fn, newarglist);
9740	}
9741      return 0;
9742    }
9743}
9744
9745/* Simplify a call to the strspn builtin.
9746
9747   Return 0 if no simplification was possible, otherwise return the
9748   simplified form of the call as a tree.
9749
9750   The simplified form may be a constant or other expression which
9751   computes the same value, but in a more efficient manner (including
9752   calls to other builtin functions).
9753
9754   The call may contain arguments which need to be evaluated, but
9755   which are not useful to determine the result of the call.  In
9756   this case we return a chain of COMPOUND_EXPRs.  The LHS of each
9757   COMPOUND_EXPR will be an argument which must be evaluated.
9758   COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
9759   COMPOUND_EXPR in the chain will contain the tree for the simplified
9760   form of the builtin function call.  */
9761
9762static tree
9763fold_builtin_strspn (tree arglist)
9764{
9765  if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9766    return 0;
9767  else
9768    {
9769      tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9770      const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
9771
9772      /* If both arguments are constants, evaluate at compile-time.  */
9773      if (p1 && p2)
9774	{
9775	  const size_t r = strspn (p1, p2);
9776	  return size_int (r);
9777	}
9778
9779      /* If either argument is "", return 0.  */
9780      if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
9781	/* Evaluate and ignore both arguments in case either one has
9782	   side-effects.  */
9783	return omit_two_operands (integer_type_node, integer_zero_node,
9784				  s1, s2);
9785      return 0;
9786    }
9787}
9788
9789/* Simplify a call to the strcspn builtin.
9790
9791   Return 0 if no simplification was possible, otherwise return the
9792   simplified form of the call as a tree.
9793
9794   The simplified form may be a constant or other expression which
9795   computes the same value, but in a more efficient manner (including
9796   calls to other builtin functions).
9797
9798   The call may contain arguments which need to be evaluated, but
9799   which are not useful to determine the result of the call.  In
9800   this case we return a chain of COMPOUND_EXPRs.  The LHS of each
9801   COMPOUND_EXPR will be an argument which must be evaluated.
9802   COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
9803   COMPOUND_EXPR in the chain will contain the tree for the simplified
9804   form of the builtin function call.  */
9805
9806static tree
9807fold_builtin_strcspn (tree arglist)
9808{
9809  if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9810    return 0;
9811  else
9812    {
9813      tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9814      const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
9815
9816      /* If both arguments are constants, evaluate at compile-time.  */
9817      if (p1 && p2)
9818	{
9819	  const size_t r = strcspn (p1, p2);
9820	  return size_int (r);
9821	}
9822
9823      /* If the first argument is "", return 0.  */
9824      if (p1 && *p1 == '\0')
9825	{
9826	  /* Evaluate and ignore argument s2 in case it has
9827	     side-effects.  */
9828	  return omit_one_operand (integer_type_node,
9829				   integer_zero_node, s2);
9830	}
9831
9832      /* If the second argument is "", return __builtin_strlen(s1).  */
9833      if (p2 && *p2 == '\0')
9834	{
9835	  tree newarglist = build_tree_list (NULL_TREE, s1),
9836	    fn = implicit_built_in_decls[BUILT_IN_STRLEN];
9837
9838	  /* If the replacement _DECL isn't initialized, don't do the
9839	     transformation.  */
9840	  if (!fn)
9841	    return 0;
9842
9843	  return build_function_call_expr (fn, newarglist);
9844	}
9845      return 0;
9846    }
9847}
9848
9849/* Fold a call to the fputs builtin.  IGNORE is true if the value returned
9850   by the builtin will be ignored.  UNLOCKED is true is true if this
9851   actually a call to fputs_unlocked.  If LEN in non-NULL, it represents
9852   the known length of the string.  Return NULL_TREE if no simplification
9853   was possible.  */
9854
9855tree
9856fold_builtin_fputs (tree arglist, bool ignore, bool unlocked, tree len)
9857{
9858  tree fn;
9859  /* If we're using an unlocked function, assume the other unlocked
9860     functions exist explicitly.  */
9861  tree const fn_fputc = unlocked ? built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
9862    : implicit_built_in_decls[BUILT_IN_FPUTC];
9863  tree const fn_fwrite = unlocked ? built_in_decls[BUILT_IN_FWRITE_UNLOCKED]
9864    : implicit_built_in_decls[BUILT_IN_FWRITE];
9865
9866  /* If the return value is used, don't do the transformation.  */
9867  if (!ignore)
9868    return 0;
9869
9870  /* Verify the arguments in the original call.  */
9871  if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9872    return 0;
9873
9874  if (! len)
9875    len = c_strlen (TREE_VALUE (arglist), 0);
9876
9877  /* Get the length of the string passed to fputs.  If the length
9878     can't be determined, punt.  */
9879  if (!len
9880      || TREE_CODE (len) != INTEGER_CST)
9881    return 0;
9882
9883  switch (compare_tree_int (len, 1))
9884    {
9885    case -1: /* length is 0, delete the call entirely .  */
9886      return omit_one_operand (integer_type_node, integer_zero_node,
9887			       TREE_VALUE (TREE_CHAIN (arglist)));
9888
9889    case 0: /* length is 1, call fputc.  */
9890      {
9891	const char *p = c_getstr (TREE_VALUE (arglist));
9892
9893	if (p != NULL)
9894	  {
9895	    /* New argument list transforming fputs(string, stream) to
9896	       fputc(string[0], stream).  */
9897	    arglist = build_tree_list (NULL_TREE,
9898				       TREE_VALUE (TREE_CHAIN (arglist)));
9899	    arglist = tree_cons (NULL_TREE,
9900				 build_int_cst (NULL_TREE, p[0]),
9901				 arglist);
9902	    fn = fn_fputc;
9903	    break;
9904	  }
9905      }
9906      /* FALLTHROUGH */
9907    case 1: /* length is greater than 1, call fwrite.  */
9908      {
9909	tree string_arg;
9910
9911	/* If optimizing for size keep fputs.  */
9912	if (optimize_size)
9913	  return 0;
9914	string_arg = TREE_VALUE (arglist);
9915	/* New argument list transforming fputs(string, stream) to
9916	   fwrite(string, 1, len, stream).  */
9917	arglist = build_tree_list (NULL_TREE,
9918				   TREE_VALUE (TREE_CHAIN (arglist)));
9919	arglist = tree_cons (NULL_TREE, len, arglist);
9920	arglist = tree_cons (NULL_TREE, size_one_node, arglist);
9921	arglist = tree_cons (NULL_TREE, string_arg, arglist);
9922	fn = fn_fwrite;
9923	break;
9924      }
9925    default:
9926      gcc_unreachable ();
9927    }
9928
9929  /* If the replacement _DECL isn't initialized, don't do the
9930     transformation.  */
9931  if (!fn)
9932    return 0;
9933
9934  /* These optimizations are only performed when the result is ignored,
9935     hence there's no need to cast the result to integer_type_node.  */
9936  return build_function_call_expr (fn, arglist);
9937}
9938
9939/* Fold the new_arg's arguments (ARGLIST). Returns true if there was an error
9940   produced.  False otherwise.  This is done so that we don't output the error
9941   or warning twice or three times.  */
9942bool
9943fold_builtin_next_arg (tree arglist)
9944{
9945  tree fntype = TREE_TYPE (current_function_decl);
9946
9947  if (TYPE_ARG_TYPES (fntype) == 0
9948      || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
9949	  == void_type_node))
9950    {
9951      error ("%<va_start%> used in function with fixed args");
9952      return true;
9953    }
9954  else if (!arglist)
9955    {
9956      /* Evidently an out of date version of <stdarg.h>; can't validate
9957	 va_start's second argument, but can still work as intended.  */
9958      warning (0, "%<__builtin_next_arg%> called without an argument");
9959      return true;
9960    }
9961  /* We use __builtin_va_start (ap, 0, 0) or __builtin_next_arg (0, 0)
9962     when we checked the arguments and if needed issued a warning.  */
9963  else if (!TREE_CHAIN (arglist)
9964	   || !integer_zerop (TREE_VALUE (arglist))
9965	   || !integer_zerop (TREE_VALUE (TREE_CHAIN (arglist)))
9966	   || TREE_CHAIN (TREE_CHAIN (arglist)))
9967    {
9968      tree last_parm = tree_last (DECL_ARGUMENTS (current_function_decl));
9969      tree arg = TREE_VALUE (arglist);
9970
9971      if (TREE_CHAIN (arglist))
9972	{
9973	  error ("%<va_start%> used with too many arguments");
9974	  return true;
9975	}
9976
9977      /* Strip off all nops for the sake of the comparison.  This
9978	 is not quite the same as STRIP_NOPS.  It does more.
9979	 We must also strip off INDIRECT_EXPR for C++ reference
9980	 parameters.  */
9981      while (TREE_CODE (arg) == NOP_EXPR
9982	     || TREE_CODE (arg) == CONVERT_EXPR
9983	     || TREE_CODE (arg) == NON_LVALUE_EXPR
9984	     || TREE_CODE (arg) == INDIRECT_REF)
9985	arg = TREE_OPERAND (arg, 0);
9986      if (arg != last_parm)
9987	{
9988	  /* FIXME: Sometimes with the tree optimizers we can get the
9989	     not the last argument even though the user used the last
9990	     argument.  We just warn and set the arg to be the last
9991	     argument so that we will get wrong-code because of
9992	     it.  */
9993	  warning (0, "second parameter of %<va_start%> not last named argument");
9994	}
9995      /* We want to verify the second parameter just once before the tree
9996	 optimizers are run and then avoid keeping it in the tree,
9997	 as otherwise we could warn even for correct code like:
9998	 void foo (int i, ...)
9999	 { va_list ap; i++; va_start (ap, i); va_end (ap); }  */
10000      TREE_VALUE (arglist) = integer_zero_node;
10001      TREE_CHAIN (arglist) = build_tree_list (NULL, integer_zero_node);
10002    }
10003  return false;
10004}
10005
10006
10007/* Simplify a call to the sprintf builtin.
10008
10009   Return 0 if no simplification was possible, otherwise return the
10010   simplified form of the call as a tree.  If IGNORED is true, it means that
10011   the caller does not use the returned value of the function.  */
10012
10013static tree
10014fold_builtin_sprintf (tree arglist, int ignored)
10015{
10016  tree call, retval, dest, fmt;
10017  const char *fmt_str = NULL;
10018
10019  /* Verify the required arguments in the original call.  We deal with two
10020     types of sprintf() calls: 'sprintf (str, fmt)' and
10021     'sprintf (dest, "%s", orig)'.  */
10022  if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)
10023      && !validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, POINTER_TYPE,
10024			    VOID_TYPE))
10025    return NULL_TREE;
10026
10027  /* Get the destination string and the format specifier.  */
10028  dest = TREE_VALUE (arglist);
10029  fmt = TREE_VALUE (TREE_CHAIN (arglist));
10030  arglist = TREE_CHAIN (TREE_CHAIN (arglist));
10031
10032  /* Check whether the format is a literal string constant.  */
10033  fmt_str = c_getstr (fmt);
10034  if (fmt_str == NULL)
10035    return NULL_TREE;
10036
10037  call = NULL_TREE;
10038  retval = NULL_TREE;
10039
10040  if (!init_target_chars())
10041    return 0;
10042
10043  /* If the format doesn't contain % args or %%, use strcpy.  */
10044  if (strchr (fmt_str, target_percent) == NULL)
10045    {
10046      tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
10047
10048      if (!fn)
10049	return NULL_TREE;
10050
10051      /* Don't optimize sprintf (buf, "abc", ptr++).  */
10052      if (arglist)
10053	return NULL_TREE;
10054
10055      /* Convert sprintf (str, fmt) into strcpy (str, fmt) when
10056	 'format' is known to contain no % formats.  */
10057      arglist = build_tree_list (NULL_TREE, fmt);
10058      arglist = tree_cons (NULL_TREE, dest, arglist);
10059      call = build_function_call_expr (fn, arglist);
10060      if (!ignored)
10061	retval = build_int_cst (NULL_TREE, strlen (fmt_str));
10062    }
10063
10064  /* If the format is "%s", use strcpy if the result isn't used.  */
10065  else if (fmt_str && strcmp (fmt_str, target_percent_s) == 0)
10066    {
10067      tree fn, orig;
10068      fn = implicit_built_in_decls[BUILT_IN_STRCPY];
10069
10070      if (!fn)
10071	return NULL_TREE;
10072
10073      /* Don't crash on sprintf (str1, "%s").  */
10074      if (!arglist)
10075	return NULL_TREE;
10076
10077      /* Convert sprintf (str1, "%s", str2) into strcpy (str1, str2).  */
10078      orig = TREE_VALUE (arglist);
10079      arglist = build_tree_list (NULL_TREE, orig);
10080      arglist = tree_cons (NULL_TREE, dest, arglist);
10081      if (!ignored)
10082	{
10083	  retval = c_strlen (orig, 1);
10084	  if (!retval || TREE_CODE (retval) != INTEGER_CST)
10085	    return NULL_TREE;
10086	}
10087      call = build_function_call_expr (fn, arglist);
10088    }
10089
10090  if (call && retval)
10091    {
10092      retval = fold_convert
10093	(TREE_TYPE (TREE_TYPE (implicit_built_in_decls[BUILT_IN_SPRINTF])),
10094	 retval);
10095      return build2 (COMPOUND_EXPR, TREE_TYPE (retval), call, retval);
10096    }
10097  else
10098    return call;
10099}
10100
10101/* Expand a call to __builtin_object_size.  */
10102
10103rtx
10104expand_builtin_object_size (tree exp)
10105{
10106  tree ost;
10107  int object_size_type;
10108  tree fndecl = get_callee_fndecl (exp);
10109  tree arglist = TREE_OPERAND (exp, 1);
10110  location_t locus = EXPR_LOCATION (exp);
10111
10112  if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
10113    {
10114      error ("%Hfirst argument of %D must be a pointer, second integer constant",
10115	     &locus, fndecl);
10116      expand_builtin_trap ();
10117      return const0_rtx;
10118    }
10119
10120  ost = TREE_VALUE (TREE_CHAIN (arglist));
10121  STRIP_NOPS (ost);
10122
10123  if (TREE_CODE (ost) != INTEGER_CST
10124      || tree_int_cst_sgn (ost) < 0
10125      || compare_tree_int (ost, 3) > 0)
10126    {
10127      error ("%Hlast argument of %D is not integer constant between 0 and 3",
10128	     &locus, fndecl);
10129      expand_builtin_trap ();
10130      return const0_rtx;
10131    }
10132
10133  object_size_type = tree_low_cst (ost, 0);
10134
10135  return object_size_type < 2 ? constm1_rtx : const0_rtx;
10136}
10137
10138/* Expand EXP, a call to the __mem{cpy,pcpy,move,set}_chk builtin.
10139   FCODE is the BUILT_IN_* to use.
10140   Return 0 if we failed; the caller should emit a normal call,
10141   otherwise try to get the result in TARGET, if convenient (and in
10142   mode MODE if that's convenient).  */
10143
10144static rtx
10145expand_builtin_memory_chk (tree exp, rtx target, enum machine_mode mode,
10146			   enum built_in_function fcode)
10147{
10148  tree arglist = TREE_OPERAND (exp, 1);
10149  tree dest, src, len, size;
10150
10151  if (!validate_arglist (arglist,
10152			 POINTER_TYPE,
10153			 fcode == BUILT_IN_MEMSET_CHK
10154			 ? INTEGER_TYPE : POINTER_TYPE,
10155			 INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
10156    return 0;
10157
10158  dest = TREE_VALUE (arglist);
10159  src = TREE_VALUE (TREE_CHAIN (arglist));
10160  len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10161  size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
10162
10163  if (! host_integerp (size, 1))
10164    return 0;
10165
10166  if (host_integerp (len, 1) || integer_all_onesp (size))
10167    {
10168      tree fn;
10169
10170      if (! integer_all_onesp (size) && tree_int_cst_lt (size, len))
10171	{
10172	  location_t locus = EXPR_LOCATION (exp);
10173	  warning (0, "%Hcall to %D will always overflow destination buffer",
10174		   &locus, get_callee_fndecl (exp));
10175	  return 0;
10176	}
10177
10178      arglist = build_tree_list (NULL_TREE, len);
10179      arglist = tree_cons (NULL_TREE, src, arglist);
10180      arglist = tree_cons (NULL_TREE, dest, arglist);
10181
10182      fn = NULL_TREE;
10183      /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume
10184	 mem{cpy,pcpy,move,set} is available.  */
10185      switch (fcode)
10186	{
10187	case BUILT_IN_MEMCPY_CHK:
10188	  fn = built_in_decls[BUILT_IN_MEMCPY];
10189	  break;
10190	case BUILT_IN_MEMPCPY_CHK:
10191	  fn = built_in_decls[BUILT_IN_MEMPCPY];
10192	  break;
10193	case BUILT_IN_MEMMOVE_CHK:
10194	  fn = built_in_decls[BUILT_IN_MEMMOVE];
10195	  break;
10196	case BUILT_IN_MEMSET_CHK:
10197	  fn = built_in_decls[BUILT_IN_MEMSET];
10198	  break;
10199	default:
10200	  break;
10201	}
10202
10203      if (! fn)
10204	return 0;
10205
10206      fn = build_function_call_expr (fn, arglist);
10207      if (TREE_CODE (fn) == CALL_EXPR)
10208	CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
10209      return expand_expr (fn, target, mode, EXPAND_NORMAL);
10210    }
10211  else if (fcode == BUILT_IN_MEMSET_CHK)
10212    return 0;
10213  else
10214    {
10215      unsigned int dest_align
10216	= get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
10217
10218      /* If DEST is not a pointer type, call the normal function.  */
10219      if (dest_align == 0)
10220	return 0;
10221
10222      /* If SRC and DEST are the same (and not volatile), do nothing.  */
10223      if (operand_equal_p (src, dest, 0))
10224	{
10225	  tree expr;
10226
10227	  if (fcode != BUILT_IN_MEMPCPY_CHK)
10228	    {
10229	      /* Evaluate and ignore LEN in case it has side-effects.  */
10230	      expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
10231	      return expand_expr (dest, target, mode, EXPAND_NORMAL);
10232	    }
10233
10234	  len = fold_convert (TREE_TYPE (dest), len);
10235	  expr = fold_build2 (PLUS_EXPR, TREE_TYPE (dest), dest, len);
10236	  return expand_expr (expr, target, mode, EXPAND_NORMAL);
10237	}
10238
10239      /* __memmove_chk special case.  */
10240      if (fcode == BUILT_IN_MEMMOVE_CHK)
10241	{
10242	  unsigned int src_align
10243	    = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
10244
10245	  if (src_align == 0)
10246	    return 0;
10247
10248	  /* If src is categorized for a readonly section we can use
10249	     normal __memcpy_chk.  */
10250	  if (readonly_data_expr (src))
10251	    {
10252	      tree fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
10253	      if (!fn)
10254		return 0;
10255	      fn = build_function_call_expr (fn, arglist);
10256	      if (TREE_CODE (fn) == CALL_EXPR)
10257		CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
10258	      return expand_expr (fn, target, mode, EXPAND_NORMAL);
10259	    }
10260	}
10261      return 0;
10262    }
10263}
10264
10265/* Emit warning if a buffer overflow is detected at compile time.  */
10266
10267static void
10268maybe_emit_chk_warning (tree exp, enum built_in_function fcode)
10269{
10270  int arg_mask, is_strlen = 0;
10271  tree arglist = TREE_OPERAND (exp, 1), a;
10272  tree len, size;
10273  location_t locus;
10274
10275  switch (fcode)
10276    {
10277    case BUILT_IN_STRCPY_CHK:
10278    case BUILT_IN_STPCPY_CHK:
10279    /* For __strcat_chk the warning will be emitted only if overflowing
10280       by at least strlen (dest) + 1 bytes.  */
10281    case BUILT_IN_STRCAT_CHK:
10282      arg_mask = 6;
10283      is_strlen = 1;
10284      break;
10285    case BUILT_IN_STRNCPY_CHK:
10286      arg_mask = 12;
10287      break;
10288    case BUILT_IN_SNPRINTF_CHK:
10289    case BUILT_IN_VSNPRINTF_CHK:
10290      arg_mask = 10;
10291      break;
10292    default:
10293      gcc_unreachable ();
10294    }
10295
10296  len = NULL_TREE;
10297  size = NULL_TREE;
10298  for (a = arglist; a && arg_mask; a = TREE_CHAIN (a), arg_mask >>= 1)
10299    if (arg_mask & 1)
10300      {
10301	if (len)
10302	  size = a;
10303	else
10304	  len = a;
10305      }
10306
10307  if (!len || !size)
10308    return;
10309
10310  len = TREE_VALUE (len);
10311  size = TREE_VALUE (size);
10312
10313  if (! host_integerp (size, 1) || integer_all_onesp (size))
10314    return;
10315
10316  if (is_strlen)
10317    {
10318      len = c_strlen (len, 1);
10319      if (! len || ! host_integerp (len, 1) || tree_int_cst_lt (len, size))
10320	return;
10321    }
10322  else if (! host_integerp (len, 1) || ! tree_int_cst_lt (size, len))
10323    return;
10324
10325  locus = EXPR_LOCATION (exp);
10326  warning (0, "%Hcall to %D will always overflow destination buffer",
10327	   &locus, get_callee_fndecl (exp));
10328}
10329
10330/* Emit warning if a buffer overflow is detected at compile time
10331   in __sprintf_chk/__vsprintf_chk calls.  */
10332
10333static void
10334maybe_emit_sprintf_chk_warning (tree exp, enum built_in_function fcode)
10335{
10336  tree arglist = TREE_OPERAND (exp, 1);
10337  tree dest, size, len, fmt, flag;
10338  const char *fmt_str;
10339
10340  /* Verify the required arguments in the original call.  */
10341  if (! arglist)
10342    return;
10343  dest = TREE_VALUE (arglist);
10344  arglist = TREE_CHAIN (arglist);
10345  if (! arglist)
10346    return;
10347  flag = TREE_VALUE (arglist);
10348  arglist = TREE_CHAIN (arglist);
10349  if (! arglist)
10350    return;
10351  size = TREE_VALUE (arglist);
10352  arglist = TREE_CHAIN (arglist);
10353  if (! arglist)
10354    return;
10355  fmt = TREE_VALUE (arglist);
10356  arglist = TREE_CHAIN (arglist);
10357
10358  if (! host_integerp (size, 1) || integer_all_onesp (size))
10359    return;
10360
10361  /* Check whether the format is a literal string constant.  */
10362  fmt_str = c_getstr (fmt);
10363  if (fmt_str == NULL)
10364    return;
10365
10366  if (!init_target_chars())
10367    return;
10368
10369  /* If the format doesn't contain % args or %%, we know its size.  */
10370  if (strchr (fmt_str, target_percent) == 0)
10371    len = build_int_cstu (size_type_node, strlen (fmt_str));
10372  /* If the format is "%s" and first ... argument is a string literal,
10373     we know it too.  */
10374  else if (fcode == BUILT_IN_SPRINTF_CHK && strcmp (fmt_str, target_percent_s) == 0)
10375    {
10376      tree arg;
10377
10378      if (! arglist)
10379	return;
10380      arg = TREE_VALUE (arglist);
10381      if (! POINTER_TYPE_P (TREE_TYPE (arg)))
10382	return;
10383
10384      len = c_strlen (arg, 1);
10385      if (!len || ! host_integerp (len, 1))
10386	return;
10387    }
10388  else
10389    return;
10390
10391  if (! tree_int_cst_lt (len, size))
10392    {
10393      location_t locus = EXPR_LOCATION (exp);
10394      warning (0, "%Hcall to %D will always overflow destination buffer",
10395	       &locus, get_callee_fndecl (exp));
10396    }
10397}
10398
10399/* Fold a call to __builtin_object_size, if possible.  */
10400
10401tree
10402fold_builtin_object_size (tree arglist)
10403{
10404  tree ptr, ost, ret = 0;
10405  int object_size_type;
10406
10407  if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
10408    return 0;
10409
10410  ptr = TREE_VALUE (arglist);
10411  ost = TREE_VALUE (TREE_CHAIN (arglist));
10412  STRIP_NOPS (ost);
10413
10414  if (TREE_CODE (ost) != INTEGER_CST
10415      || tree_int_cst_sgn (ost) < 0
10416      || compare_tree_int (ost, 3) > 0)
10417    return 0;
10418
10419  object_size_type = tree_low_cst (ost, 0);
10420
10421  /* __builtin_object_size doesn't evaluate side-effects in its arguments;
10422     if there are any side-effects, it returns (size_t) -1 for types 0 and 1
10423     and (size_t) 0 for types 2 and 3.  */
10424  if (TREE_SIDE_EFFECTS (ptr))
10425    return fold_convert (size_type_node,
10426			 object_size_type < 2
10427			 ? integer_minus_one_node : integer_zero_node);
10428
10429  if (TREE_CODE (ptr) == ADDR_EXPR)
10430    ret = build_int_cstu (size_type_node,
10431			compute_builtin_object_size (ptr, object_size_type));
10432
10433  else if (TREE_CODE (ptr) == SSA_NAME)
10434    {
10435      unsigned HOST_WIDE_INT bytes;
10436
10437      /* If object size is not known yet, delay folding until
10438       later.  Maybe subsequent passes will help determining
10439       it.  */
10440      bytes = compute_builtin_object_size (ptr, object_size_type);
10441      if (bytes != (unsigned HOST_WIDE_INT) (object_size_type < 2
10442					     ? -1 : 0))
10443	ret = build_int_cstu (size_type_node, bytes);
10444    }
10445
10446  if (ret)
10447    {
10448      ret = force_fit_type (ret, -1, false, false);
10449      if (TREE_CONSTANT_OVERFLOW (ret))
10450	ret = 0;
10451    }
10452
10453  return ret;
10454}
10455
10456/* Fold a call to the __mem{cpy,pcpy,move,set}_chk builtin.
10457   IGNORE is true, if return value can be ignored.  FCODE is the BUILT_IN_*
10458   code of the builtin.  If MAXLEN is not NULL, it is maximum length
10459   passed as third argument.  */
10460
10461tree
10462fold_builtin_memory_chk (tree fndecl, tree arglist, tree maxlen, bool ignore,
10463			 enum built_in_function fcode)
10464{
10465  tree dest, src, len, size, fn;
10466
10467  if (!validate_arglist (arglist,
10468			 POINTER_TYPE,
10469			 fcode == BUILT_IN_MEMSET_CHK
10470			 ? INTEGER_TYPE : POINTER_TYPE,
10471			 INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
10472    return 0;
10473
10474  dest = TREE_VALUE (arglist);
10475  /* Actually val for __memset_chk, but it doesn't matter.  */
10476  src = TREE_VALUE (TREE_CHAIN (arglist));
10477  len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10478  size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
10479
10480  /* If SRC and DEST are the same (and not volatile), return DEST
10481     (resp. DEST+LEN for __mempcpy_chk).  */
10482  if (fcode != BUILT_IN_MEMSET_CHK && operand_equal_p (src, dest, 0))
10483    {
10484      if (fcode != BUILT_IN_MEMPCPY_CHK)
10485	return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, len);
10486      else
10487	{
10488	  tree temp = fold_convert (TREE_TYPE (dest), len);
10489	  temp = fold_build2 (PLUS_EXPR, TREE_TYPE (dest), dest, temp);
10490	  return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), temp);
10491	}
10492    }
10493
10494  if (! host_integerp (size, 1))
10495    return 0;
10496
10497  if (! integer_all_onesp (size))
10498    {
10499      if (! host_integerp (len, 1))
10500	{
10501	  /* If LEN is not constant, try MAXLEN too.
10502	     For MAXLEN only allow optimizing into non-_ocs function
10503	     if SIZE is >= MAXLEN, never convert to __ocs_fail ().  */
10504	  if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
10505	    {
10506	      if (fcode == BUILT_IN_MEMPCPY_CHK && ignore)
10507		{
10508		  /* (void) __mempcpy_chk () can be optimized into
10509		     (void) __memcpy_chk ().  */
10510		  fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
10511		  if (!fn)
10512		    return 0;
10513
10514		  return build_function_call_expr (fn, arglist);
10515		}
10516	      return 0;
10517	    }
10518	}
10519      else
10520	maxlen = len;
10521
10522      if (tree_int_cst_lt (size, maxlen))
10523	return 0;
10524    }
10525
10526  arglist = build_tree_list (NULL_TREE, len);
10527  arglist = tree_cons (NULL_TREE, src, arglist);
10528  arglist = tree_cons (NULL_TREE, dest, arglist);
10529
10530  fn = NULL_TREE;
10531  /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume
10532     mem{cpy,pcpy,move,set} is available.  */
10533  switch (fcode)
10534    {
10535    case BUILT_IN_MEMCPY_CHK:
10536      fn = built_in_decls[BUILT_IN_MEMCPY];
10537      break;
10538    case BUILT_IN_MEMPCPY_CHK:
10539      fn = built_in_decls[BUILT_IN_MEMPCPY];
10540      break;
10541    case BUILT_IN_MEMMOVE_CHK:
10542      fn = built_in_decls[BUILT_IN_MEMMOVE];
10543      break;
10544    case BUILT_IN_MEMSET_CHK:
10545      fn = built_in_decls[BUILT_IN_MEMSET];
10546      break;
10547    default:
10548      break;
10549    }
10550
10551  if (!fn)
10552    return 0;
10553
10554  return build_function_call_expr (fn, arglist);
10555}
10556
10557/* Fold a call to the __st[rp]cpy_chk builtin.
10558   IGNORE is true, if return value can be ignored.  FCODE is the BUILT_IN_*
10559   code of the builtin.  If MAXLEN is not NULL, it is maximum length of
10560   strings passed as second argument.  */
10561
10562tree
10563fold_builtin_stxcpy_chk (tree fndecl, tree arglist, tree maxlen, bool ignore,
10564			 enum built_in_function fcode)
10565{
10566  tree dest, src, size, len, fn;
10567
10568  if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
10569			 VOID_TYPE))
10570    return 0;
10571
10572  dest = TREE_VALUE (arglist);
10573  src = TREE_VALUE (TREE_CHAIN (arglist));
10574  size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10575
10576  /* If SRC and DEST are the same (and not volatile), return DEST.  */
10577  if (fcode == BUILT_IN_STRCPY_CHK && operand_equal_p (src, dest, 0))
10578    return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), dest);
10579
10580  if (! host_integerp (size, 1))
10581    return 0;
10582
10583  if (! integer_all_onesp (size))
10584    {
10585      len = c_strlen (src, 1);
10586      if (! len || ! host_integerp (len, 1))
10587	{
10588	  /* If LEN is not constant, try MAXLEN too.
10589	     For MAXLEN only allow optimizing into non-_ocs function
10590	     if SIZE is >= MAXLEN, never convert to __ocs_fail ().  */
10591	  if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
10592	    {
10593	      if (fcode == BUILT_IN_STPCPY_CHK)
10594		{
10595		  if (! ignore)
10596		    return 0;
10597
10598		  /* If return value of __stpcpy_chk is ignored,
10599		     optimize into __strcpy_chk.  */
10600		  fn = built_in_decls[BUILT_IN_STRCPY_CHK];
10601		  if (!fn)
10602		    return 0;
10603
10604		  return build_function_call_expr (fn, arglist);
10605		}
10606
10607	      if (! len || TREE_SIDE_EFFECTS (len))
10608		return 0;
10609
10610	      /* If c_strlen returned something, but not a constant,
10611		 transform __strcpy_chk into __memcpy_chk.  */
10612	      fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
10613	      if (!fn)
10614		return 0;
10615
10616	      len = size_binop (PLUS_EXPR, len, ssize_int (1));
10617	      arglist = build_tree_list (NULL_TREE, size);
10618	      arglist = tree_cons (NULL_TREE, len, arglist);
10619	      arglist = tree_cons (NULL_TREE, src, arglist);
10620	      arglist = tree_cons (NULL_TREE, dest, arglist);
10621	      return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)),
10622				   build_function_call_expr (fn, arglist));
10623	    }
10624	}
10625      else
10626	maxlen = len;
10627
10628      if (! tree_int_cst_lt (maxlen, size))
10629	return 0;
10630    }
10631
10632  arglist = build_tree_list (NULL_TREE, src);
10633  arglist = tree_cons (NULL_TREE, dest, arglist);
10634
10635  /* If __builtin_st{r,p}cpy_chk is used, assume st{r,p}cpy is available.  */
10636  fn = built_in_decls[fcode == BUILT_IN_STPCPY_CHK
10637		      ? BUILT_IN_STPCPY : BUILT_IN_STRCPY];
10638  if (!fn)
10639    return 0;
10640
10641  return build_function_call_expr (fn, arglist);
10642}
10643
10644/* Fold a call to the __strncpy_chk builtin.
10645   If MAXLEN is not NULL, it is maximum length passed as third argument.  */
10646
10647tree
10648fold_builtin_strncpy_chk (tree arglist, tree maxlen)
10649{
10650  tree dest, src, size, len, fn;
10651
10652  if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
10653			 INTEGER_TYPE, VOID_TYPE))
10654    return 0;
10655
10656  dest = TREE_VALUE (arglist);
10657  src = TREE_VALUE (TREE_CHAIN (arglist));
10658  len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10659  size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
10660
10661  if (! host_integerp (size, 1))
10662    return 0;
10663
10664  if (! integer_all_onesp (size))
10665    {
10666      if (! host_integerp (len, 1))
10667	{
10668	  /* If LEN is not constant, try MAXLEN too.
10669	     For MAXLEN only allow optimizing into non-_ocs function
10670	     if SIZE is >= MAXLEN, never convert to __ocs_fail ().  */
10671	  if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
10672	    return 0;
10673	}
10674      else
10675	maxlen = len;
10676
10677      if (tree_int_cst_lt (size, maxlen))
10678	return 0;
10679    }
10680
10681  arglist = build_tree_list (NULL_TREE, len);
10682  arglist = tree_cons (NULL_TREE, src, arglist);
10683  arglist = tree_cons (NULL_TREE, dest, arglist);
10684
10685  /* If __builtin_strncpy_chk is used, assume strncpy is available.  */
10686  fn = built_in_decls[BUILT_IN_STRNCPY];
10687  if (!fn)
10688    return 0;
10689
10690  return build_function_call_expr (fn, arglist);
10691}
10692
10693/* Fold a call to the __strcat_chk builtin FNDECL with ARGLIST.  */
10694
10695static tree
10696fold_builtin_strcat_chk (tree fndecl, tree arglist)
10697{
10698  tree dest, src, size, fn;
10699  const char *p;
10700
10701  if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
10702			 VOID_TYPE))
10703    return 0;
10704
10705  dest = TREE_VALUE (arglist);
10706  src = TREE_VALUE (TREE_CHAIN (arglist));
10707  size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10708
10709  p = c_getstr (src);
10710  /* If the SRC parameter is "", return DEST.  */
10711  if (p && *p == '\0')
10712    return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
10713
10714  if (! host_integerp (size, 1) || ! integer_all_onesp (size))
10715    return 0;
10716
10717  arglist = build_tree_list (NULL_TREE, src);
10718  arglist = tree_cons (NULL_TREE, dest, arglist);
10719
10720  /* If __builtin_strcat_chk is used, assume strcat is available.  */
10721  fn = built_in_decls[BUILT_IN_STRCAT];
10722  if (!fn)
10723    return 0;
10724
10725  return build_function_call_expr (fn, arglist);
10726}
10727
10728/* Fold a call to the __strncat_chk builtin EXP.  */
10729
10730static tree
10731fold_builtin_strncat_chk (tree fndecl, tree arglist)
10732{
10733  tree dest, src, size, len, fn;
10734  const char *p;
10735
10736  if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
10737			 INTEGER_TYPE, VOID_TYPE))
10738    return 0;
10739
10740  dest = TREE_VALUE (arglist);
10741  src = TREE_VALUE (TREE_CHAIN (arglist));
10742  len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10743  size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
10744
10745  p = c_getstr (src);
10746  /* If the SRC parameter is "" or if LEN is 0, return DEST.  */
10747  if (p && *p == '\0')
10748    return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, len);
10749  else if (integer_zerop (len))
10750    return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
10751
10752  if (! host_integerp (size, 1))
10753    return 0;
10754
10755  if (! integer_all_onesp (size))
10756    {
10757      tree src_len = c_strlen (src, 1);
10758      if (src_len
10759	  && host_integerp (src_len, 1)
10760	  && host_integerp (len, 1)
10761	  && ! tree_int_cst_lt (len, src_len))
10762	{
10763	  /* If LEN >= strlen (SRC), optimize into __strcat_chk.  */
10764	  fn = built_in_decls[BUILT_IN_STRCAT_CHK];
10765	  if (!fn)
10766	    return 0;
10767
10768	  arglist = build_tree_list (NULL_TREE, size);
10769	  arglist = tree_cons (NULL_TREE, src, arglist);
10770	  arglist = tree_cons (NULL_TREE, dest, arglist);
10771	  return build_function_call_expr (fn, arglist);
10772	}
10773      return 0;
10774    }
10775
10776  arglist = build_tree_list (NULL_TREE, len);
10777  arglist = tree_cons (NULL_TREE, src, arglist);
10778  arglist = tree_cons (NULL_TREE, dest, arglist);
10779
10780  /* If __builtin_strncat_chk is used, assume strncat is available.  */
10781  fn = built_in_decls[BUILT_IN_STRNCAT];
10782  if (!fn)
10783    return 0;
10784
10785  return build_function_call_expr (fn, arglist);
10786}
10787
10788/* Fold a call to __{,v}sprintf_chk with argument list ARGLIST.  Return 0 if
10789   a normal call should be emitted rather than expanding the function
10790   inline.  FCODE is either BUILT_IN_SPRINTF_CHK or BUILT_IN_VSPRINTF_CHK.  */
10791
10792static tree
10793fold_builtin_sprintf_chk (tree arglist, enum built_in_function fcode)
10794{
10795  tree dest, size, len, fn, fmt, flag;
10796  const char *fmt_str;
10797
10798  /* Verify the required arguments in the original call.  */
10799  if (! arglist)
10800    return 0;
10801  dest = TREE_VALUE (arglist);
10802  if (! POINTER_TYPE_P (TREE_TYPE (dest)))
10803    return 0;
10804  arglist = TREE_CHAIN (arglist);
10805  if (! arglist)
10806    return 0;
10807  flag = TREE_VALUE (arglist);
10808  if (TREE_CODE (TREE_TYPE (flag)) != INTEGER_TYPE)
10809    return 0;
10810  arglist = TREE_CHAIN (arglist);
10811  if (! arglist)
10812    return 0;
10813  size = TREE_VALUE (arglist);
10814  if (TREE_CODE (TREE_TYPE (size)) != INTEGER_TYPE)
10815    return 0;
10816  arglist = TREE_CHAIN (arglist);
10817  if (! arglist)
10818    return 0;
10819  fmt = TREE_VALUE (arglist);
10820  if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
10821    return 0;
10822  arglist = TREE_CHAIN (arglist);
10823
10824  if (! host_integerp (size, 1))
10825    return 0;
10826
10827  len = NULL_TREE;
10828
10829  if (!init_target_chars())
10830    return 0;
10831
10832  /* Check whether the format is a literal string constant.  */
10833  fmt_str = c_getstr (fmt);
10834  if (fmt_str != NULL)
10835    {
10836      /* If the format doesn't contain % args or %%, we know the size.  */
10837      if (strchr (fmt_str, target_percent) == 0)
10838	{
10839	  if (fcode != BUILT_IN_SPRINTF_CHK || arglist == NULL_TREE)
10840	    len = build_int_cstu (size_type_node, strlen (fmt_str));
10841	}
10842      /* If the format is "%s" and first ... argument is a string literal,
10843	 we know the size too.  */
10844      else if (fcode == BUILT_IN_SPRINTF_CHK && strcmp (fmt_str, target_percent_s) == 0)
10845	{
10846	  tree arg;
10847
10848	  if (arglist && !TREE_CHAIN (arglist))
10849	    {
10850	      arg = TREE_VALUE (arglist);
10851	      if (POINTER_TYPE_P (TREE_TYPE (arg)))
10852		{
10853		  len = c_strlen (arg, 1);
10854		  if (! len || ! host_integerp (len, 1))
10855		    len = NULL_TREE;
10856		}
10857	    }
10858	}
10859    }
10860
10861  if (! integer_all_onesp (size))
10862    {
10863      if (! len || ! tree_int_cst_lt (len, size))
10864	return 0;
10865    }
10866
10867  /* Only convert __{,v}sprintf_chk to {,v}sprintf if flag is 0
10868     or if format doesn't contain % chars or is "%s".  */
10869  if (! integer_zerop (flag))
10870    {
10871      if (fmt_str == NULL)
10872	return 0;
10873      if (strchr (fmt_str, target_percent) != NULL && strcmp (fmt_str, target_percent_s))
10874	return 0;
10875    }
10876
10877  arglist = tree_cons (NULL_TREE, fmt, arglist);
10878  arglist = tree_cons (NULL_TREE, dest, arglist);
10879
10880  /* If __builtin_{,v}sprintf_chk is used, assume {,v}sprintf is available.  */
10881  fn = built_in_decls[fcode == BUILT_IN_VSPRINTF_CHK
10882		      ? BUILT_IN_VSPRINTF : BUILT_IN_SPRINTF];
10883  if (!fn)
10884    return 0;
10885
10886  return build_function_call_expr (fn, arglist);
10887}
10888
10889/* Fold a call to {,v}snprintf with argument list ARGLIST.  Return 0 if
10890   a normal call should be emitted rather than expanding the function
10891   inline.  FCODE is either BUILT_IN_SNPRINTF_CHK or
10892   BUILT_IN_VSNPRINTF_CHK.  If MAXLEN is not NULL, it is maximum length
10893   passed as second argument.  */
10894
10895tree
10896fold_builtin_snprintf_chk (tree arglist, tree maxlen,
10897			   enum built_in_function fcode)
10898{
10899  tree dest, size, len, fn, fmt, flag;
10900  const char *fmt_str;
10901
10902  /* Verify the required arguments in the original call.  */
10903  if (! arglist)
10904    return 0;
10905  dest = TREE_VALUE (arglist);
10906  if (! POINTER_TYPE_P (TREE_TYPE (dest)))
10907    return 0;
10908  arglist = TREE_CHAIN (arglist);
10909  if (! arglist)
10910    return 0;
10911  len = TREE_VALUE (arglist);
10912  if (TREE_CODE (TREE_TYPE (len)) != INTEGER_TYPE)
10913    return 0;
10914  arglist = TREE_CHAIN (arglist);
10915  if (! arglist)
10916    return 0;
10917  flag = TREE_VALUE (arglist);
10918  if (TREE_CODE (TREE_TYPE (len)) != INTEGER_TYPE)
10919    return 0;
10920  arglist = TREE_CHAIN (arglist);
10921  if (! arglist)
10922    return 0;
10923  size = TREE_VALUE (arglist);
10924  if (TREE_CODE (TREE_TYPE (size)) != INTEGER_TYPE)
10925    return 0;
10926  arglist = TREE_CHAIN (arglist);
10927  if (! arglist)
10928    return 0;
10929  fmt = TREE_VALUE (arglist);
10930  if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
10931    return 0;
10932  arglist = TREE_CHAIN (arglist);
10933
10934  if (! host_integerp (size, 1))
10935    return 0;
10936
10937  if (! integer_all_onesp (size))
10938    {
10939      if (! host_integerp (len, 1))
10940	{
10941	  /* If LEN is not constant, try MAXLEN too.
10942	     For MAXLEN only allow optimizing into non-_ocs function
10943	     if SIZE is >= MAXLEN, never convert to __ocs_fail ().  */
10944	  if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
10945	    return 0;
10946	}
10947      else
10948	maxlen = len;
10949
10950      if (tree_int_cst_lt (size, maxlen))
10951	return 0;
10952    }
10953
10954  if (!init_target_chars())
10955    return 0;
10956
10957  /* Only convert __{,v}snprintf_chk to {,v}snprintf if flag is 0
10958     or if format doesn't contain % chars or is "%s".  */
10959  if (! integer_zerop (flag))
10960    {
10961      fmt_str = c_getstr (fmt);
10962      if (fmt_str == NULL)
10963	return 0;
10964      if (strchr (fmt_str, target_percent) != NULL && strcmp (fmt_str, target_percent_s))
10965	return 0;
10966    }
10967
10968  arglist = tree_cons (NULL_TREE, fmt, arglist);
10969  arglist = tree_cons (NULL_TREE, len, arglist);
10970  arglist = tree_cons (NULL_TREE, dest, arglist);
10971
10972  /* If __builtin_{,v}snprintf_chk is used, assume {,v}snprintf is
10973     available.  */
10974  fn = built_in_decls[fcode == BUILT_IN_VSNPRINTF_CHK
10975		      ? BUILT_IN_VSNPRINTF : BUILT_IN_SNPRINTF];
10976  if (!fn)
10977    return 0;
10978
10979  return build_function_call_expr (fn, arglist);
10980}
10981
10982/* Fold a call to the {,v}printf{,_unlocked} and __{,v}printf_chk builtins.
10983
10984   Return 0 if no simplification was possible, otherwise return the
10985   simplified form of the call as a tree.  FCODE is the BUILT_IN_*
10986   code of the function to be simplified.  */
10987
10988static tree
10989fold_builtin_printf (tree fndecl, tree arglist, bool ignore,
10990		     enum built_in_function fcode)
10991{
10992  tree fmt, fn = NULL_TREE, fn_putchar, fn_puts, arg, call;
10993  const char *fmt_str = NULL;
10994
10995  /* If the return value is used, don't do the transformation.  */
10996  if (! ignore)
10997    return 0;
10998
10999  /* Verify the required arguments in the original call.  */
11000  if (fcode == BUILT_IN_PRINTF_CHK || fcode == BUILT_IN_VPRINTF_CHK)
11001    {
11002      tree flag;
11003
11004      if (! arglist)
11005	return 0;
11006      flag = TREE_VALUE (arglist);
11007      if (TREE_CODE (TREE_TYPE (flag)) != INTEGER_TYPE
11008	  || TREE_SIDE_EFFECTS (flag))
11009	return 0;
11010      arglist = TREE_CHAIN (arglist);
11011    }
11012
11013  if (! arglist)
11014    return 0;
11015  fmt = TREE_VALUE (arglist);
11016  if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
11017    return 0;
11018  arglist = TREE_CHAIN (arglist);
11019
11020  /* Check whether the format is a literal string constant.  */
11021  fmt_str = c_getstr (fmt);
11022  if (fmt_str == NULL)
11023    return NULL_TREE;
11024
11025  if (fcode == BUILT_IN_PRINTF_UNLOCKED)
11026    {
11027      /* If we're using an unlocked function, assume the other
11028	 unlocked functions exist explicitly.  */
11029      fn_putchar = built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED];
11030      fn_puts = built_in_decls[BUILT_IN_PUTS_UNLOCKED];
11031    }
11032  else
11033    {
11034      fn_putchar = implicit_built_in_decls[BUILT_IN_PUTCHAR];
11035      fn_puts = implicit_built_in_decls[BUILT_IN_PUTS];
11036    }
11037
11038  if (!init_target_chars())
11039    return 0;
11040
11041  if (strcmp (fmt_str, target_percent_s) == 0 || strchr (fmt_str, target_percent) == NULL)
11042    {
11043      const char *str;
11044
11045      if (strcmp (fmt_str, target_percent_s) == 0)
11046	{
11047	  if (fcode == BUILT_IN_VPRINTF || fcode == BUILT_IN_VPRINTF_CHK)
11048	    return 0;
11049
11050	  if (! arglist
11051	      || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
11052	      || TREE_CHAIN (arglist))
11053	    return 0;
11054
11055	  str = c_getstr (TREE_VALUE (arglist));
11056	  if (str == NULL)
11057	    return 0;
11058	}
11059      else
11060	{
11061	  /* The format specifier doesn't contain any '%' characters.  */
11062	  if (fcode != BUILT_IN_VPRINTF && fcode != BUILT_IN_VPRINTF_CHK
11063	      && arglist)
11064	    return 0;
11065	  str = fmt_str;
11066	}
11067
11068      /* If the string was "", printf does nothing.  */
11069      if (str[0] == '\0')
11070	return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), 0);
11071
11072      /* If the string has length of 1, call putchar.  */
11073      if (str[1] == '\0')
11074	{
11075	  /* Given printf("c"), (where c is any one character,)
11076	     convert "c"[0] to an int and pass that to the replacement
11077	     function.  */
11078	  arg = build_int_cst (NULL_TREE, str[0]);
11079	  arglist = build_tree_list (NULL_TREE, arg);
11080	  fn = fn_putchar;
11081	}
11082      else
11083	{
11084	  /* If the string was "string\n", call puts("string").  */
11085	  size_t len = strlen (str);
11086	  if ((unsigned char)str[len - 1] == target_newline)
11087	    {
11088	      /* Create a NUL-terminated string that's one char shorter
11089		 than the original, stripping off the trailing '\n'.  */
11090	      char *newstr = alloca (len);
11091	      memcpy (newstr, str, len - 1);
11092	      newstr[len - 1] = 0;
11093
11094	      arg = build_string_literal (len, newstr);
11095	      arglist = build_tree_list (NULL_TREE, arg);
11096	      fn = fn_puts;
11097	    }
11098	  else
11099	    /* We'd like to arrange to call fputs(string,stdout) here,
11100	       but we need stdout and don't have a way to get it yet.  */
11101	    return 0;
11102	}
11103    }
11104
11105  /* The other optimizations can be done only on the non-va_list variants.  */
11106  else if (fcode == BUILT_IN_VPRINTF || fcode == BUILT_IN_VPRINTF_CHK)
11107    return 0;
11108
11109  /* If the format specifier was "%s\n", call __builtin_puts(arg).  */
11110  else if (strcmp (fmt_str, target_percent_s_newline) == 0)
11111    {
11112      if (! arglist
11113	  || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
11114	  || TREE_CHAIN (arglist))
11115	return 0;
11116      fn = fn_puts;
11117    }
11118
11119  /* If the format specifier was "%c", call __builtin_putchar(arg).  */
11120  else if (strcmp (fmt_str, target_percent_c) == 0)
11121    {
11122      if (! arglist
11123	  || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
11124	  || TREE_CHAIN (arglist))
11125	return 0;
11126      fn = fn_putchar;
11127    }
11128
11129  if (!fn)
11130    return 0;
11131
11132  call = build_function_call_expr (fn, arglist);
11133  return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), call);
11134}
11135
11136/* Fold a call to the {,v}fprintf{,_unlocked} and __{,v}printf_chk builtins.
11137
11138   Return 0 if no simplification was possible, otherwise return the
11139   simplified form of the call as a tree.  FCODE is the BUILT_IN_*
11140   code of the function to be simplified.  */
11141
11142static tree
11143fold_builtin_fprintf (tree fndecl, tree arglist, bool ignore,
11144		      enum built_in_function fcode)
11145{
11146  tree fp, fmt, fn = NULL_TREE, fn_fputc, fn_fputs, arg, call;
11147  const char *fmt_str = NULL;
11148
11149  /* If the return value is used, don't do the transformation.  */
11150  if (! ignore)
11151    return 0;
11152
11153  /* Verify the required arguments in the original call.  */
11154  if (! arglist)
11155    return 0;
11156  fp = TREE_VALUE (arglist);
11157  if (! POINTER_TYPE_P (TREE_TYPE (fp)))
11158    return 0;
11159  arglist = TREE_CHAIN (arglist);
11160
11161  if (fcode == BUILT_IN_FPRINTF_CHK || fcode == BUILT_IN_VFPRINTF_CHK)
11162    {
11163      tree flag;
11164
11165      if (! arglist)
11166	return 0;
11167      flag = TREE_VALUE (arglist);
11168      if (TREE_CODE (TREE_TYPE (flag)) != INTEGER_TYPE
11169	  || TREE_SIDE_EFFECTS (flag))
11170	return 0;
11171      arglist = TREE_CHAIN (arglist);
11172    }
11173
11174  if (! arglist)
11175    return 0;
11176  fmt = TREE_VALUE (arglist);
11177  if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
11178    return 0;
11179  arglist = TREE_CHAIN (arglist);
11180
11181  /* Check whether the format is a literal string constant.  */
11182  fmt_str = c_getstr (fmt);
11183  if (fmt_str == NULL)
11184    return NULL_TREE;
11185
11186  if (fcode == BUILT_IN_FPRINTF_UNLOCKED)
11187    {
11188      /* If we're using an unlocked function, assume the other
11189	 unlocked functions exist explicitly.  */
11190      fn_fputc = built_in_decls[BUILT_IN_FPUTC_UNLOCKED];
11191      fn_fputs = built_in_decls[BUILT_IN_FPUTS_UNLOCKED];
11192    }
11193  else
11194    {
11195      fn_fputc = implicit_built_in_decls[BUILT_IN_FPUTC];
11196      fn_fputs = implicit_built_in_decls[BUILT_IN_FPUTS];
11197    }
11198
11199  if (!init_target_chars())
11200    return 0;
11201
11202  /* If the format doesn't contain % args or %%, use strcpy.  */
11203  if (strchr (fmt_str, target_percent) == NULL)
11204    {
11205      if (fcode != BUILT_IN_VFPRINTF && fcode != BUILT_IN_VFPRINTF_CHK
11206	  && arglist)
11207	return 0;
11208
11209      /* If the format specifier was "", fprintf does nothing.  */
11210      if (fmt_str[0] == '\0')
11211	{
11212	  /* If FP has side-effects, just wait until gimplification is
11213	     done.  */
11214	  if (TREE_SIDE_EFFECTS (fp))
11215	    return 0;
11216
11217	  return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), 0);
11218	}
11219
11220      /* When "string" doesn't contain %, replace all cases of
11221	 fprintf (fp, string) with fputs (string, fp).  The fputs
11222	 builtin will take care of special cases like length == 1.  */
11223      arglist = build_tree_list (NULL_TREE, fp);
11224      arglist = tree_cons (NULL_TREE, fmt, arglist);
11225      fn = fn_fputs;
11226    }
11227
11228  /* The other optimizations can be done only on the non-va_list variants.  */
11229  else if (fcode == BUILT_IN_VFPRINTF || fcode == BUILT_IN_VFPRINTF_CHK)
11230    return 0;
11231
11232  /* If the format specifier was "%s", call __builtin_fputs (arg, fp).  */
11233  else if (strcmp (fmt_str, target_percent_s) == 0)
11234    {
11235      if (! arglist
11236	  || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
11237	  || TREE_CHAIN (arglist))
11238	return 0;
11239      arg = TREE_VALUE (arglist);
11240      arglist = build_tree_list (NULL_TREE, fp);
11241      arglist = tree_cons (NULL_TREE, arg, arglist);
11242      fn = fn_fputs;
11243    }
11244
11245  /* If the format specifier was "%c", call __builtin_fputc (arg, fp).  */
11246  else if (strcmp (fmt_str, target_percent_c) == 0)
11247    {
11248      if (! arglist
11249	  || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
11250	  || TREE_CHAIN (arglist))
11251	return 0;
11252      arg = TREE_VALUE (arglist);
11253      arglist = build_tree_list (NULL_TREE, fp);
11254      arglist = tree_cons (NULL_TREE, arg, arglist);
11255      fn = fn_fputc;
11256    }
11257
11258  if (!fn)
11259    return 0;
11260
11261  call = build_function_call_expr (fn, arglist);
11262  return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), call);
11263}
11264
11265/* Initialize format string characters in the target charset.  */
11266
11267static bool
11268init_target_chars (void)
11269{
11270  static bool init;
11271  if (!init)
11272    {
11273      target_newline = lang_hooks.to_target_charset ('\n');
11274      target_percent = lang_hooks.to_target_charset ('%');
11275      target_c = lang_hooks.to_target_charset ('c');
11276      target_s = lang_hooks.to_target_charset ('s');
11277      if (target_newline == 0 || target_percent == 0 || target_c == 0
11278	  || target_s == 0)
11279	return false;
11280
11281      target_percent_c[0] = target_percent;
11282      target_percent_c[1] = target_c;
11283      target_percent_c[2] = '\0';
11284
11285      target_percent_s[0] = target_percent;
11286      target_percent_s[1] = target_s;
11287      target_percent_s[2] = '\0';
11288
11289      target_percent_s_newline[0] = target_percent;
11290      target_percent_s_newline[1] = target_s;
11291      target_percent_s_newline[2] = target_newline;
11292      target_percent_s_newline[3] = '\0';
11293
11294      init = true;
11295    }
11296  return true;
11297}
11298