OSDN Git Service

1f62dcaaf00b346e5aae7605d0c0fd56487ac25e
[pf3gnuchains/gcc-fork.git] / gcc / builtins.c
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
5 This file is part of GCC.
6
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
10 version.
11
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15 for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING.  If not, write to the Free
19 Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
20 02110-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.  */
56 const 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,
60 const 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.  */
68 tree 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).  */
72 tree implicit_built_in_decls[(int) END_BUILTINS];
73
74 static int get_pointer_alignment (tree, unsigned int);
75 static const char *c_getstr (tree);
76 static rtx c_readstr (const char *, enum machine_mode);
77 static int target_char_cast (tree, char *);
78 static rtx get_memory_rtx (tree, tree);
79 static int apply_args_size (void);
80 static int apply_result_size (void);
81 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
82 static rtx result_vector (int, rtx);
83 #endif
84 static rtx expand_builtin_setjmp (tree, rtx);
85 static void expand_builtin_update_setjmp_buf (rtx);
86 static void expand_builtin_prefetch (tree);
87 static rtx expand_builtin_apply_args (void);
88 static rtx expand_builtin_apply_args_1 (void);
89 static rtx expand_builtin_apply (rtx, rtx, rtx);
90 static void expand_builtin_return (rtx);
91 static enum type_class type_to_class (tree);
92 static rtx expand_builtin_classify_type (tree);
93 static void expand_errno_check (tree, rtx);
94 static rtx expand_builtin_mathfn (tree, rtx, rtx);
95 static rtx expand_builtin_mathfn_2 (tree, rtx, rtx);
96 static rtx expand_builtin_mathfn_3 (tree, rtx, rtx);
97 static rtx expand_builtin_sincos (tree);
98 static rtx expand_builtin_int_roundingfn (tree, rtx, rtx);
99 static rtx expand_builtin_args_info (tree);
100 static rtx expand_builtin_next_arg (void);
101 static rtx expand_builtin_va_start (tree);
102 static rtx expand_builtin_va_end (tree);
103 static rtx expand_builtin_va_copy (tree);
104 static rtx expand_builtin_memcmp (tree, tree, rtx, enum machine_mode);
105 static rtx expand_builtin_strcmp (tree, rtx, enum machine_mode);
106 static rtx expand_builtin_strncmp (tree, rtx, enum machine_mode);
107 static rtx builtin_memcpy_read_str (void *, HOST_WIDE_INT, enum machine_mode);
108 static rtx expand_builtin_strcat (tree, tree, rtx, enum machine_mode);
109 static rtx expand_builtin_strncat (tree, rtx, enum machine_mode);
110 static rtx expand_builtin_strspn (tree, rtx, enum machine_mode);
111 static rtx expand_builtin_strcspn (tree, rtx, enum machine_mode);
112 static rtx expand_builtin_memcpy (tree, rtx, enum machine_mode);
113 static rtx expand_builtin_mempcpy (tree, tree, rtx, enum machine_mode, int);
114 static rtx expand_builtin_memmove (tree, tree, rtx, enum machine_mode, tree);
115 static rtx expand_builtin_bcopy (tree);
116 static rtx expand_builtin_strcpy (tree, tree, rtx, enum machine_mode);
117 static rtx expand_builtin_stpcpy (tree, rtx, enum machine_mode);
118 static rtx builtin_strncpy_read_str (void *, HOST_WIDE_INT, enum machine_mode);
119 static rtx expand_builtin_strncpy (tree, rtx, enum machine_mode);
120 static rtx builtin_memset_read_str (void *, HOST_WIDE_INT, enum machine_mode);
121 static rtx builtin_memset_gen_str (void *, HOST_WIDE_INT, enum machine_mode);
122 static rtx expand_builtin_memset (tree, rtx, enum machine_mode, tree);
123 static rtx expand_builtin_bzero (tree);
124 static rtx expand_builtin_strlen (tree, rtx, enum machine_mode);
125 static rtx expand_builtin_strstr (tree, tree, rtx, enum machine_mode);
126 static rtx expand_builtin_strpbrk (tree, tree, rtx, enum machine_mode);
127 static rtx expand_builtin_strchr (tree, tree, rtx, enum machine_mode);
128 static rtx expand_builtin_strrchr (tree, tree, rtx, enum machine_mode);
129 static rtx expand_builtin_alloca (tree, rtx);
130 static rtx expand_builtin_unop (enum machine_mode, tree, rtx, rtx, optab);
131 static rtx expand_builtin_frame_address (tree, tree);
132 static rtx expand_builtin_fputs (tree, rtx, bool);
133 static rtx expand_builtin_printf (tree, rtx, enum machine_mode, bool);
134 static rtx expand_builtin_fprintf (tree, rtx, enum machine_mode, bool);
135 static rtx expand_builtin_sprintf (tree, rtx, enum machine_mode);
136 static tree stabilize_va_list (tree, int);
137 static rtx expand_builtin_expect (tree, rtx);
138 static tree fold_builtin_constant_p (tree);
139 static tree fold_builtin_classify_type (tree);
140 static tree fold_builtin_strlen (tree);
141 static tree fold_builtin_inf (tree, int);
142 static tree fold_builtin_nan (tree, tree, int);
143 static int validate_arglist (tree, ...);
144 static bool integer_valued_real_p (tree);
145 static tree fold_trunc_transparent_mathfn (tree, tree);
146 static bool readonly_data_expr (tree);
147 static rtx expand_builtin_fabs (tree, rtx, rtx);
148 static rtx expand_builtin_signbit (tree, rtx);
149 static tree fold_builtin_sqrt (tree, tree);
150 static tree fold_builtin_cbrt (tree, tree);
151 static tree fold_builtin_pow (tree, tree, tree);
152 static tree fold_builtin_powi (tree, tree, tree);
153 static tree fold_builtin_sin (tree);
154 static tree fold_builtin_cos (tree, tree, tree);
155 static tree fold_builtin_tan (tree);
156 static tree fold_builtin_atan (tree, tree);
157 static tree fold_builtin_trunc (tree, tree);
158 static tree fold_builtin_floor (tree, tree);
159 static tree fold_builtin_ceil (tree, tree);
160 static tree fold_builtin_round (tree, tree);
161 static tree fold_builtin_int_roundingfn (tree, tree);
162 static tree fold_builtin_bitop (tree, tree);
163 static tree fold_builtin_memory_op (tree, tree, bool, int);
164 static tree fold_builtin_strchr (tree, tree);
165 static tree fold_builtin_memcmp (tree);
166 static tree fold_builtin_strcmp (tree);
167 static tree fold_builtin_strncmp (tree);
168 static tree fold_builtin_signbit (tree, tree);
169 static tree fold_builtin_copysign (tree, tree, tree);
170 static tree fold_builtin_isascii (tree);
171 static tree fold_builtin_toascii (tree);
172 static tree fold_builtin_isdigit (tree);
173 static tree fold_builtin_fabs (tree, tree);
174 static tree fold_builtin_abs (tree, tree);
175 static tree fold_builtin_unordered_cmp (tree, tree, enum tree_code,
176                                         enum tree_code);
177 static tree fold_builtin_1 (tree, tree, bool);
178
179 static tree fold_builtin_strpbrk (tree, tree);
180 static tree fold_builtin_strstr (tree, tree);
181 static tree fold_builtin_strrchr (tree, tree);
182 static tree fold_builtin_strcat (tree);
183 static tree fold_builtin_strncat (tree);
184 static tree fold_builtin_strspn (tree);
185 static tree fold_builtin_strcspn (tree);
186 static tree fold_builtin_sprintf (tree, int);
187
188 static rtx expand_builtin_object_size (tree);
189 static rtx expand_builtin_memory_chk (tree, rtx, enum machine_mode,
190                                       enum built_in_function);
191 static void maybe_emit_chk_warning (tree, enum built_in_function);
192 static void maybe_emit_sprintf_chk_warning (tree, enum built_in_function);
193 static tree fold_builtin_object_size (tree);
194 static tree fold_builtin_strcat_chk (tree, tree);
195 static tree fold_builtin_strncat_chk (tree, tree);
196 static tree fold_builtin_sprintf_chk (tree, enum built_in_function);
197 static tree fold_builtin_printf (tree, tree, bool, enum built_in_function);
198 static tree fold_builtin_fprintf (tree, tree, bool, enum built_in_function);
199 static bool init_target_chars (void);
200
201 static unsigned HOST_WIDE_INT target_newline;
202 static unsigned HOST_WIDE_INT target_percent;
203 static unsigned HOST_WIDE_INT target_c;
204 static unsigned HOST_WIDE_INT target_s;
205 static char target_percent_c[3];
206 static char target_percent_s[3];
207 static char target_percent_s_newline[4];
208
209 /* Return true if NODE should be considered for inline expansion regardless
210    of the optimization level.  This means whenever a function is invoked with
211    its "internal" name, which normally contains the prefix "__builtin".  */
212
213 static bool called_as_built_in (tree node)
214 {
215   const char *name = IDENTIFIER_POINTER (DECL_NAME (node));
216   if (strncmp (name, "__builtin_", 10) == 0)
217     return true;
218   if (strncmp (name, "__sync_", 7) == 0)
219     return true;
220   return false;
221 }
222
223 /* Return the alignment in bits of EXP, a pointer valued expression.
224    But don't return more than MAX_ALIGN no matter what.
225    The alignment returned is, by default, the alignment of the thing that
226    EXP points to.  If it is not a POINTER_TYPE, 0 is returned.
227
228    Otherwise, look at the expression to see if we can do better, i.e., if the
229    expression is actually pointing at an object whose alignment is tighter.  */
230
231 static int
232 get_pointer_alignment (tree exp, unsigned int max_align)
233 {
234   unsigned int align, inner;
235
236   if (! POINTER_TYPE_P (TREE_TYPE (exp)))
237     return 0;
238
239   align = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
240   align = MIN (align, max_align);
241
242   while (1)
243     {
244       switch (TREE_CODE (exp))
245         {
246         case NOP_EXPR:
247         case CONVERT_EXPR:
248         case NON_LVALUE_EXPR:
249           exp = TREE_OPERAND (exp, 0);
250           if (! POINTER_TYPE_P (TREE_TYPE (exp)))
251             return align;
252
253           inner = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
254           align = MIN (inner, max_align);
255           break;
256
257         case PLUS_EXPR:
258           /* If sum of pointer + int, restrict our maximum alignment to that
259              imposed by the integer.  If not, we can't do any better than
260              ALIGN.  */
261           if (! host_integerp (TREE_OPERAND (exp, 1), 1))
262             return align;
263
264           while (((tree_low_cst (TREE_OPERAND (exp, 1), 1))
265                   & (max_align / BITS_PER_UNIT - 1))
266                  != 0)
267             max_align >>= 1;
268
269           exp = TREE_OPERAND (exp, 0);
270           break;
271
272         case ADDR_EXPR:
273           /* See what we are pointing at and look at its alignment.  */
274           exp = TREE_OPERAND (exp, 0);
275           inner = max_align;
276           if (handled_component_p (exp))
277             {
278               HOST_WIDE_INT bitsize, bitpos;
279               tree offset;
280               enum machine_mode mode; 
281               int unsignedp, volatilep;
282
283               exp = get_inner_reference (exp, &bitsize, &bitpos, &offset,
284                                          &mode, &unsignedp, &volatilep, true);
285               if (bitpos)
286                 inner = MIN (inner, (unsigned) (bitpos & -bitpos));
287               if (offset && TREE_CODE (offset) == PLUS_EXPR
288                   && host_integerp (TREE_OPERAND (offset, 1), 1))
289                 {
290                   /* Any overflow in calculating offset_bits won't change
291                      the alignment.  */
292                   unsigned offset_bits
293                     = ((unsigned) tree_low_cst (TREE_OPERAND (offset, 1), 1)
294                        * BITS_PER_UNIT);
295
296                   if (offset_bits)
297                     inner = MIN (inner, (offset_bits & -offset_bits));
298                   offset = TREE_OPERAND (offset, 0);
299                 }
300               if (offset && TREE_CODE (offset) == MULT_EXPR
301                   && host_integerp (TREE_OPERAND (offset, 1), 1))
302                 {
303                   /* Any overflow in calculating offset_factor won't change
304                      the alignment.  */
305                   unsigned offset_factor
306                     = ((unsigned) tree_low_cst (TREE_OPERAND (offset, 1), 1)
307                        * BITS_PER_UNIT);
308
309                   if (offset_factor)
310                     inner = MIN (inner, (offset_factor & -offset_factor));
311                 }
312               else if (offset)
313                 inner = MIN (inner, BITS_PER_UNIT);
314             }
315           if (TREE_CODE (exp) == FUNCTION_DECL)
316             align = FUNCTION_BOUNDARY;
317           else if (DECL_P (exp))
318             align = MIN (inner, DECL_ALIGN (exp));
319 #ifdef CONSTANT_ALIGNMENT
320           else if (CONSTANT_CLASS_P (exp))
321             align = MIN (inner, (unsigned)CONSTANT_ALIGNMENT (exp, align));
322 #endif
323           else if (TREE_CODE (exp) == VIEW_CONVERT_EXPR
324                    || TREE_CODE (exp) == INDIRECT_REF)
325             align = MIN (TYPE_ALIGN (TREE_TYPE (exp)), inner);
326           else
327             align = MIN (align, inner);
328           return MIN (align, max_align);
329
330         default:
331           return align;
332         }
333     }
334 }
335
336 /* Compute the length of a C string.  TREE_STRING_LENGTH is not the right
337    way, because it could contain a zero byte in the middle.
338    TREE_STRING_LENGTH is the size of the character array, not the string.
339
340    ONLY_VALUE should be nonzero if the result is not going to be emitted
341    into the instruction stream and zero if it is going to be expanded.
342    E.g. with i++ ? "foo" : "bar", if ONLY_VALUE is nonzero, constant 3
343    is returned, otherwise NULL, since
344    len = c_strlen (src, 1); if (len) expand_expr (len, ...); would not
345    evaluate the side-effects.
346
347    The value returned is of type `ssizetype'.
348
349    Unfortunately, string_constant can't access the values of const char
350    arrays with initializers, so neither can we do so here.  */
351
352 tree
353 c_strlen (tree src, int only_value)
354 {
355   tree offset_node;
356   HOST_WIDE_INT offset;
357   int max;
358   const char *ptr;
359
360   STRIP_NOPS (src);
361   if (TREE_CODE (src) == COND_EXPR
362       && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0))))
363     {
364       tree len1, len2;
365
366       len1 = c_strlen (TREE_OPERAND (src, 1), only_value);
367       len2 = c_strlen (TREE_OPERAND (src, 2), only_value);
368       if (tree_int_cst_equal (len1, len2))
369         return len1;
370     }
371
372   if (TREE_CODE (src) == COMPOUND_EXPR
373       && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0))))
374     return c_strlen (TREE_OPERAND (src, 1), only_value);
375
376   src = string_constant (src, &offset_node);
377   if (src == 0)
378     return 0;
379
380   max = TREE_STRING_LENGTH (src) - 1;
381   ptr = TREE_STRING_POINTER (src);
382
383   if (offset_node && TREE_CODE (offset_node) != INTEGER_CST)
384     {
385       /* If the string has an internal zero byte (e.g., "foo\0bar"), we can't
386          compute the offset to the following null if we don't know where to
387          start searching for it.  */
388       int i;
389
390       for (i = 0; i < max; i++)
391         if (ptr[i] == 0)
392           return 0;
393
394       /* We don't know the starting offset, but we do know that the string
395          has no internal zero bytes.  We can assume that the offset falls
396          within the bounds of the string; otherwise, the programmer deserves
397          what he gets.  Subtract the offset from the length of the string,
398          and return that.  This would perhaps not be valid if we were dealing
399          with named arrays in addition to literal string constants.  */
400
401       return size_diffop (size_int (max), offset_node);
402     }
403
404   /* We have a known offset into the string.  Start searching there for
405      a null character if we can represent it as a single HOST_WIDE_INT.  */
406   if (offset_node == 0)
407     offset = 0;
408   else if (! host_integerp (offset_node, 0))
409     offset = -1;
410   else
411     offset = tree_low_cst (offset_node, 0);
412
413   /* If the offset is known to be out of bounds, warn, and call strlen at
414      runtime.  */
415   if (offset < 0 || offset > max)
416     {
417       warning (0, "offset outside bounds of constant string");
418       return 0;
419     }
420
421   /* Use strlen to search for the first zero byte.  Since any strings
422      constructed with build_string will have nulls appended, we win even
423      if we get handed something like (char[4])"abcd".
424
425      Since OFFSET is our starting index into the string, no further
426      calculation is needed.  */
427   return ssize_int (strlen (ptr + offset));
428 }
429
430 /* Return a char pointer for a C string if it is a string constant
431    or sum of string constant and integer constant.  */
432
433 static const char *
434 c_getstr (tree src)
435 {
436   tree offset_node;
437
438   src = string_constant (src, &offset_node);
439   if (src == 0)
440     return 0;
441
442   if (offset_node == 0)
443     return TREE_STRING_POINTER (src);
444   else if (!host_integerp (offset_node, 1)
445            || compare_tree_int (offset_node, TREE_STRING_LENGTH (src) - 1) > 0)
446     return 0;
447
448   return TREE_STRING_POINTER (src) + tree_low_cst (offset_node, 1);
449 }
450
451 /* Return a CONST_INT or CONST_DOUBLE corresponding to target reading
452    GET_MODE_BITSIZE (MODE) bits from string constant STR.  */
453
454 static rtx
455 c_readstr (const char *str, enum machine_mode mode)
456 {
457   HOST_WIDE_INT c[2];
458   HOST_WIDE_INT ch;
459   unsigned int i, j;
460
461   gcc_assert (GET_MODE_CLASS (mode) == MODE_INT);
462
463   c[0] = 0;
464   c[1] = 0;
465   ch = 1;
466   for (i = 0; i < GET_MODE_SIZE (mode); i++)
467     {
468       j = i;
469       if (WORDS_BIG_ENDIAN)
470         j = GET_MODE_SIZE (mode) - i - 1;
471       if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN
472           && GET_MODE_SIZE (mode) > UNITS_PER_WORD)
473         j = j + UNITS_PER_WORD - 2 * (j % UNITS_PER_WORD) - 1;
474       j *= BITS_PER_UNIT;
475       gcc_assert (j <= 2 * HOST_BITS_PER_WIDE_INT);
476
477       if (ch)
478         ch = (unsigned char) str[i];
479       c[j / HOST_BITS_PER_WIDE_INT] |= ch << (j % HOST_BITS_PER_WIDE_INT);
480     }
481   return immed_double_const (c[0], c[1], mode);
482 }
483
484 /* Cast a target constant CST to target CHAR and if that value fits into
485    host char type, return zero and put that value into variable pointed to by
486    P.  */
487
488 static int
489 target_char_cast (tree cst, char *p)
490 {
491   unsigned HOST_WIDE_INT val, hostval;
492
493   if (!host_integerp (cst, 1)
494       || CHAR_TYPE_SIZE > HOST_BITS_PER_WIDE_INT)
495     return 1;
496
497   val = tree_low_cst (cst, 1);
498   if (CHAR_TYPE_SIZE < HOST_BITS_PER_WIDE_INT)
499     val &= (((unsigned HOST_WIDE_INT) 1) << CHAR_TYPE_SIZE) - 1;
500
501   hostval = val;
502   if (HOST_BITS_PER_CHAR < HOST_BITS_PER_WIDE_INT)
503     hostval &= (((unsigned HOST_WIDE_INT) 1) << HOST_BITS_PER_CHAR) - 1;
504
505   if (val != hostval)
506     return 1;
507
508   *p = hostval;
509   return 0;
510 }
511
512 /* Similar to save_expr, but assumes that arbitrary code is not executed
513    in between the multiple evaluations.  In particular, we assume that a
514    non-addressable local variable will not be modified.  */
515
516 static tree
517 builtin_save_expr (tree exp)
518 {
519   if (TREE_ADDRESSABLE (exp) == 0
520       && (TREE_CODE (exp) == PARM_DECL
521           || (TREE_CODE (exp) == VAR_DECL && !TREE_STATIC (exp))))
522     return exp;
523
524   return save_expr (exp);
525 }
526
527 /* Given TEM, a pointer to a stack frame, follow the dynamic chain COUNT
528    times to get the address of either a higher stack frame, or a return
529    address located within it (depending on FNDECL_CODE).  */
530
531 static rtx
532 expand_builtin_return_addr (enum built_in_function fndecl_code, int count)
533 {
534   int i;
535
536 #ifdef INITIAL_FRAME_ADDRESS_RTX
537   rtx tem = INITIAL_FRAME_ADDRESS_RTX;
538 #else
539   rtx tem;
540
541   /* For a zero count with __builtin_return_address, we don't care what
542      frame address we return, because target-specific definitions will
543      override us.  Therefore frame pointer elimination is OK, and using
544      the soft frame pointer is OK.
545
546      For a non-zero count, or a zero count with __builtin_frame_address,
547      we require a stable offset from the current frame pointer to the
548      previous one, so we must use the hard frame pointer, and
549      we must disable frame pointer elimination.  */
550   if (count == 0 && fndecl_code == BUILT_IN_RETURN_ADDRESS)
551     tem = frame_pointer_rtx;
552   else
553     {
554       tem = hard_frame_pointer_rtx;
555
556       /* Tell reload not to eliminate the frame pointer.  */
557       current_function_accesses_prior_frames = 1;
558     }
559 #endif
560
561   /* Some machines need special handling before we can access
562      arbitrary frames.  For example, on the sparc, we must first flush
563      all register windows to the stack.  */
564 #ifdef SETUP_FRAME_ADDRESSES
565   if (count > 0)
566     SETUP_FRAME_ADDRESSES ();
567 #endif
568
569   /* On the sparc, the return address is not in the frame, it is in a
570      register.  There is no way to access it off of the current frame
571      pointer, but it can be accessed off the previous frame pointer by
572      reading the value from the register window save area.  */
573 #ifdef RETURN_ADDR_IN_PREVIOUS_FRAME
574   if (fndecl_code == BUILT_IN_RETURN_ADDRESS)
575     count--;
576 #endif
577
578   /* Scan back COUNT frames to the specified frame.  */
579   for (i = 0; i < count; i++)
580     {
581       /* Assume the dynamic chain pointer is in the word that the
582          frame address points to, unless otherwise specified.  */
583 #ifdef DYNAMIC_CHAIN_ADDRESS
584       tem = DYNAMIC_CHAIN_ADDRESS (tem);
585 #endif
586       tem = memory_address (Pmode, tem);
587       tem = gen_frame_mem (Pmode, tem);
588       tem = copy_to_reg (tem);
589     }
590
591   /* For __builtin_frame_address, return what we've got.  */
592   if (fndecl_code == BUILT_IN_FRAME_ADDRESS)
593     return tem;
594
595   /* For __builtin_return_address, Get the return address from that
596      frame.  */
597 #ifdef RETURN_ADDR_RTX
598   tem = RETURN_ADDR_RTX (count, tem);
599 #else
600   tem = memory_address (Pmode,
601                         plus_constant (tem, GET_MODE_SIZE (Pmode)));
602   tem = gen_frame_mem (Pmode, tem);
603 #endif
604   return tem;
605 }
606
607 /* Alias set used for setjmp buffer.  */
608 static HOST_WIDE_INT setjmp_alias_set = -1;
609
610 /* Construct the leading half of a __builtin_setjmp call.  Control will
611    return to RECEIVER_LABEL.  This is used directly by sjlj exception
612    handling code.  */
613
614 void
615 expand_builtin_setjmp_setup (rtx buf_addr, rtx receiver_label)
616 {
617   enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
618   rtx stack_save;
619   rtx mem;
620
621   if (setjmp_alias_set == -1)
622     setjmp_alias_set = new_alias_set ();
623
624   buf_addr = convert_memory_address (Pmode, buf_addr);
625
626   buf_addr = force_reg (Pmode, force_operand (buf_addr, NULL_RTX));
627
628   /* We store the frame pointer and the address of receiver_label in
629      the buffer and use the rest of it for the stack save area, which
630      is machine-dependent.  */
631
632   mem = gen_rtx_MEM (Pmode, buf_addr);
633   set_mem_alias_set (mem, setjmp_alias_set);
634   emit_move_insn (mem, targetm.builtin_setjmp_frame_value ());
635
636   mem = gen_rtx_MEM (Pmode, plus_constant (buf_addr, GET_MODE_SIZE (Pmode))),
637   set_mem_alias_set (mem, setjmp_alias_set);
638
639   emit_move_insn (validize_mem (mem),
640                   force_reg (Pmode, gen_rtx_LABEL_REF (Pmode, receiver_label)));
641
642   stack_save = gen_rtx_MEM (sa_mode,
643                             plus_constant (buf_addr,
644                                            2 * GET_MODE_SIZE (Pmode)));
645   set_mem_alias_set (stack_save, setjmp_alias_set);
646   emit_stack_save (SAVE_NONLOCAL, &stack_save, NULL_RTX);
647
648   /* If there is further processing to do, do it.  */
649 #ifdef HAVE_builtin_setjmp_setup
650   if (HAVE_builtin_setjmp_setup)
651     emit_insn (gen_builtin_setjmp_setup (buf_addr));
652 #endif
653
654   /* Tell optimize_save_area_alloca that extra work is going to
655      need to go on during alloca.  */
656   current_function_calls_setjmp = 1;
657
658   /* Set this so all the registers get saved in our frame; we need to be
659      able to copy the saved values for any registers from frames we unwind.  */
660   current_function_has_nonlocal_label = 1;
661 }
662
663 /* Construct the trailing part of a __builtin_setjmp call.
664    This is used directly by sjlj exception handling code.  */
665
666 void
667 expand_builtin_setjmp_receiver (rtx receiver_label ATTRIBUTE_UNUSED)
668 {
669   /* Clobber the FP when we get here, so we have to make sure it's
670      marked as used by this function.  */
671   emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
672
673   /* Mark the static chain as clobbered here so life information
674      doesn't get messed up for it.  */
675   emit_insn (gen_rtx_CLOBBER (VOIDmode, static_chain_rtx));
676
677   /* Now put in the code to restore the frame pointer, and argument
678      pointer, if needed.  */
679 #ifdef HAVE_nonlocal_goto
680   if (! HAVE_nonlocal_goto)
681 #endif
682     emit_move_insn (virtual_stack_vars_rtx, hard_frame_pointer_rtx);
683
684 #if ARG_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
685   if (fixed_regs[ARG_POINTER_REGNUM])
686     {
687 #ifdef ELIMINABLE_REGS
688       size_t i;
689       static const struct elims {const int from, to;} elim_regs[] = ELIMINABLE_REGS;
690
691       for (i = 0; i < ARRAY_SIZE (elim_regs); i++)
692         if (elim_regs[i].from == ARG_POINTER_REGNUM
693             && elim_regs[i].to == HARD_FRAME_POINTER_REGNUM)
694           break;
695
696       if (i == ARRAY_SIZE (elim_regs))
697 #endif
698         {
699           /* Now restore our arg pointer from the address at which it
700              was saved in our stack frame.  */
701           emit_move_insn (virtual_incoming_args_rtx,
702                           copy_to_reg (get_arg_pointer_save_area (cfun)));
703         }
704     }
705 #endif
706
707 #ifdef HAVE_builtin_setjmp_receiver
708   if (HAVE_builtin_setjmp_receiver)
709     emit_insn (gen_builtin_setjmp_receiver (receiver_label));
710   else
711 #endif
712 #ifdef HAVE_nonlocal_goto_receiver
713     if (HAVE_nonlocal_goto_receiver)
714       emit_insn (gen_nonlocal_goto_receiver ());
715     else
716 #endif
717       { /* Nothing */ }
718
719   /* @@@ This is a kludge.  Not all machine descriptions define a blockage
720      insn, but we must not allow the code we just generated to be reordered
721      by scheduling.  Specifically, the update of the frame pointer must
722      happen immediately, not later.  So emit an ASM_INPUT to act as blockage
723      insn.  */
724   emit_insn (gen_rtx_ASM_INPUT (VOIDmode, ""));
725 }
726
727 /* __builtin_setjmp is passed a pointer to an array of five words (not
728    all will be used on all machines).  It operates similarly to the C
729    library function of the same name, but is more efficient.  Much of
730    the code below (and for longjmp) is copied from the handling of
731    non-local gotos.
732
733    NOTE: This is intended for use by GNAT and the exception handling
734    scheme in the compiler and will only work in the method used by
735    them.  */
736
737 static rtx
738 expand_builtin_setjmp (tree arglist, rtx target)
739 {
740   rtx buf_addr, next_lab, cont_lab;
741
742   if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
743     return NULL_RTX;
744
745   if (target == 0 || !REG_P (target)
746       || REGNO (target) < FIRST_PSEUDO_REGISTER)
747     target = gen_reg_rtx (TYPE_MODE (integer_type_node));
748
749   buf_addr = expand_normal (TREE_VALUE (arglist));
750
751   next_lab = gen_label_rtx ();
752   cont_lab = gen_label_rtx ();
753
754   expand_builtin_setjmp_setup (buf_addr, next_lab);
755
756   /* Set TARGET to zero and branch to the continue label.  Use emit_jump to
757      ensure that pending stack adjustments are flushed.  */
758   emit_move_insn (target, const0_rtx);
759   emit_jump (cont_lab);
760
761   emit_label (next_lab);
762
763   expand_builtin_setjmp_receiver (next_lab);
764
765   /* Set TARGET to one.  */
766   emit_move_insn (target, const1_rtx);
767   emit_label (cont_lab);
768
769   /* Tell flow about the strange goings on.  Putting `next_lab' on
770      `nonlocal_goto_handler_labels' to indicates that function
771      calls may traverse the arc back to this label.  */
772
773   current_function_has_nonlocal_label = 1;
774   nonlocal_goto_handler_labels
775     = gen_rtx_EXPR_LIST (VOIDmode, next_lab, nonlocal_goto_handler_labels);
776
777   return target;
778 }
779
780 /* __builtin_longjmp is passed a pointer to an array of five words (not
781    all will be used on all machines).  It operates similarly to the C
782    library function of the same name, but is more efficient.  Much of
783    the code below is copied from the handling of non-local gotos.
784
785    NOTE: This is intended for use by GNAT and the exception handling
786    scheme in the compiler and will only work in the method used by
787    them.  */
788
789 static void
790 expand_builtin_longjmp (rtx buf_addr, rtx value)
791 {
792   rtx fp, lab, stack, insn, last;
793   enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
794
795   if (setjmp_alias_set == -1)
796     setjmp_alias_set = new_alias_set ();
797
798   buf_addr = convert_memory_address (Pmode, buf_addr);
799
800   buf_addr = force_reg (Pmode, buf_addr);
801
802   /* We used to store value in static_chain_rtx, but that fails if pointers
803      are smaller than integers.  We instead require that the user must pass
804      a second argument of 1, because that is what builtin_setjmp will
805      return.  This also makes EH slightly more efficient, since we are no
806      longer copying around a value that we don't care about.  */
807   gcc_assert (value == const1_rtx);
808
809   last = get_last_insn ();
810 #ifdef HAVE_builtin_longjmp
811   if (HAVE_builtin_longjmp)
812     emit_insn (gen_builtin_longjmp (buf_addr));
813   else
814 #endif
815     {
816       fp = gen_rtx_MEM (Pmode, buf_addr);
817       lab = gen_rtx_MEM (Pmode, plus_constant (buf_addr,
818                                                GET_MODE_SIZE (Pmode)));
819
820       stack = gen_rtx_MEM (sa_mode, plus_constant (buf_addr,
821                                                    2 * GET_MODE_SIZE (Pmode)));
822       set_mem_alias_set (fp, setjmp_alias_set);
823       set_mem_alias_set (lab, setjmp_alias_set);
824       set_mem_alias_set (stack, setjmp_alias_set);
825
826       /* Pick up FP, label, and SP from the block and jump.  This code is
827          from expand_goto in stmt.c; see there for detailed comments.  */
828 #ifdef HAVE_nonlocal_goto
829       if (HAVE_nonlocal_goto)
830         /* We have to pass a value to the nonlocal_goto pattern that will
831            get copied into the static_chain pointer, but it does not matter
832            what that value is, because builtin_setjmp does not use it.  */
833         emit_insn (gen_nonlocal_goto (value, lab, stack, fp));
834       else
835 #endif
836         {
837           lab = copy_to_reg (lab);
838
839           emit_insn (gen_rtx_CLOBBER (VOIDmode,
840                                       gen_rtx_MEM (BLKmode,
841                                                    gen_rtx_SCRATCH (VOIDmode))));
842           emit_insn (gen_rtx_CLOBBER (VOIDmode,
843                                       gen_rtx_MEM (BLKmode,
844                                                    hard_frame_pointer_rtx)));
845
846           emit_move_insn (hard_frame_pointer_rtx, fp);
847           emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
848
849           emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
850           emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
851           emit_indirect_jump (lab);
852         }
853     }
854
855   /* Search backwards and mark the jump insn as a non-local goto.
856      Note that this precludes the use of __builtin_longjmp to a
857      __builtin_setjmp target in the same function.  However, we've
858      already cautioned the user that these functions are for
859      internal exception handling use only.  */
860   for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
861     {
862       gcc_assert (insn != last);
863
864       if (JUMP_P (insn))
865         {
866           REG_NOTES (insn) = alloc_EXPR_LIST (REG_NON_LOCAL_GOTO, const0_rtx,
867                                               REG_NOTES (insn));
868           break;
869         }
870       else if (CALL_P (insn))
871         break;
872     }
873 }
874
875 /* Expand a call to __builtin_nonlocal_goto.  We're passed the target label
876    and the address of the save area.  */
877
878 static rtx
879 expand_builtin_nonlocal_goto (tree arglist)
880 {
881   tree t_label, t_save_area;
882   rtx r_label, r_save_area, r_fp, r_sp, insn;
883
884   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
885     return NULL_RTX;
886
887   t_label = TREE_VALUE (arglist);
888   arglist = TREE_CHAIN (arglist);
889   t_save_area = TREE_VALUE (arglist);
890
891   r_label = expand_normal (t_label);
892   r_label = convert_memory_address (Pmode, r_label);
893   r_save_area = expand_normal (t_save_area);
894   r_save_area = convert_memory_address (Pmode, r_save_area);
895   r_fp = gen_rtx_MEM (Pmode, r_save_area);
896   r_sp = gen_rtx_MEM (STACK_SAVEAREA_MODE (SAVE_NONLOCAL),
897                       plus_constant (r_save_area, GET_MODE_SIZE (Pmode)));
898
899   current_function_has_nonlocal_goto = 1;
900
901 #ifdef HAVE_nonlocal_goto
902   /* ??? We no longer need to pass the static chain value, afaik.  */
903   if (HAVE_nonlocal_goto)
904     emit_insn (gen_nonlocal_goto (const0_rtx, r_label, r_sp, r_fp));
905   else
906 #endif
907     {
908       r_label = copy_to_reg (r_label);
909
910       emit_insn (gen_rtx_CLOBBER (VOIDmode,
911                                   gen_rtx_MEM (BLKmode,
912                                                gen_rtx_SCRATCH (VOIDmode))));
913
914       emit_insn (gen_rtx_CLOBBER (VOIDmode,
915                                   gen_rtx_MEM (BLKmode,
916                                                hard_frame_pointer_rtx)));
917
918       /* Restore frame pointer for containing function.
919          This sets the actual hard register used for the frame pointer
920          to the location of the function's incoming static chain info.
921          The non-local goto handler will then adjust it to contain the
922          proper value and reload the argument pointer, if needed.  */
923       emit_move_insn (hard_frame_pointer_rtx, r_fp);
924       emit_stack_restore (SAVE_NONLOCAL, r_sp, NULL_RTX);
925
926       /* USE of hard_frame_pointer_rtx added for consistency;
927          not clear if really needed.  */
928       emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
929       emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
930       emit_indirect_jump (r_label);
931     }
932
933   /* Search backwards to the jump insn and mark it as a
934      non-local goto.  */
935   for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
936     {
937       if (JUMP_P (insn))
938         {
939           REG_NOTES (insn) = alloc_EXPR_LIST (REG_NON_LOCAL_GOTO,
940                                               const0_rtx, REG_NOTES (insn));
941           break;
942         }
943       else if (CALL_P (insn))
944         break;
945     }
946
947   return const0_rtx;
948 }
949
950 /* __builtin_update_setjmp_buf is passed a pointer to an array of five words
951    (not all will be used on all machines) that was passed to __builtin_setjmp.
952    It updates the stack pointer in that block to correspond to the current
953    stack pointer.  */
954
955 static void
956 expand_builtin_update_setjmp_buf (rtx buf_addr)
957 {
958   enum machine_mode sa_mode = Pmode;
959   rtx stack_save;
960
961
962 #ifdef HAVE_save_stack_nonlocal
963   if (HAVE_save_stack_nonlocal)
964     sa_mode = insn_data[(int) CODE_FOR_save_stack_nonlocal].operand[0].mode;
965 #endif
966 #ifdef STACK_SAVEAREA_MODE
967   sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
968 #endif
969
970   stack_save
971     = gen_rtx_MEM (sa_mode,
972                    memory_address
973                    (sa_mode,
974                     plus_constant (buf_addr, 2 * GET_MODE_SIZE (Pmode))));
975
976 #ifdef HAVE_setjmp
977   if (HAVE_setjmp)
978     emit_insn (gen_setjmp ());
979 #endif
980
981   emit_stack_save (SAVE_NONLOCAL, &stack_save, NULL_RTX);
982 }
983
984 /* Expand a call to __builtin_prefetch.  For a target that does not support
985    data prefetch, evaluate the memory address argument in case it has side
986    effects.  */
987
988 static void
989 expand_builtin_prefetch (tree arglist)
990 {
991   tree arg0, arg1, arg2;
992   rtx op0, op1, op2;
993
994   if (!validate_arglist (arglist, POINTER_TYPE, 0))
995     return;
996
997   arg0 = TREE_VALUE (arglist);
998   /* Arguments 1 and 2 are optional; argument 1 (read/write) defaults to
999      zero (read) and argument 2 (locality) defaults to 3 (high degree of
1000      locality).  */
1001   if (TREE_CHAIN (arglist))
1002     {
1003       arg1 = TREE_VALUE (TREE_CHAIN (arglist));
1004       if (TREE_CHAIN (TREE_CHAIN (arglist)))
1005         arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
1006       else
1007         arg2 = build_int_cst (NULL_TREE, 3);
1008     }
1009   else
1010     {
1011       arg1 = integer_zero_node;
1012       arg2 = build_int_cst (NULL_TREE, 3);
1013     }
1014
1015   /* Argument 0 is an address.  */
1016   op0 = expand_expr (arg0, NULL_RTX, Pmode, EXPAND_NORMAL);
1017
1018   /* Argument 1 (read/write flag) must be a compile-time constant int.  */
1019   if (TREE_CODE (arg1) != INTEGER_CST)
1020     {
1021       error ("second argument to %<__builtin_prefetch%> must be a constant");
1022       arg1 = integer_zero_node;
1023     }
1024   op1 = expand_normal (arg1);
1025   /* Argument 1 must be either zero or one.  */
1026   if (INTVAL (op1) != 0 && INTVAL (op1) != 1)
1027     {
1028       warning (0, "invalid second argument to %<__builtin_prefetch%>;"
1029                " using zero");
1030       op1 = const0_rtx;
1031     }
1032
1033   /* Argument 2 (locality) must be a compile-time constant int.  */
1034   if (TREE_CODE (arg2) != INTEGER_CST)
1035     {
1036       error ("third argument to %<__builtin_prefetch%> must be a constant");
1037       arg2 = integer_zero_node;
1038     }
1039   op2 = expand_normal (arg2);
1040   /* Argument 2 must be 0, 1, 2, or 3.  */
1041   if (INTVAL (op2) < 0 || INTVAL (op2) > 3)
1042     {
1043       warning (0, "invalid third argument to %<__builtin_prefetch%>; using zero");
1044       op2 = const0_rtx;
1045     }
1046
1047 #ifdef HAVE_prefetch
1048   if (HAVE_prefetch)
1049     {
1050       if ((! (*insn_data[(int) CODE_FOR_prefetch].operand[0].predicate)
1051              (op0,
1052               insn_data[(int) CODE_FOR_prefetch].operand[0].mode))
1053           || (GET_MODE (op0) != Pmode))
1054         {
1055           op0 = convert_memory_address (Pmode, op0);
1056           op0 = force_reg (Pmode, op0);
1057         }
1058       emit_insn (gen_prefetch (op0, op1, op2));
1059     }
1060 #endif
1061
1062   /* Don't do anything with direct references to volatile memory, but
1063      generate code to handle other side effects.  */
1064   if (!MEM_P (op0) && side_effects_p (op0))
1065     emit_insn (op0);
1066 }
1067
1068 /* Get a MEM rtx for expression EXP which is the address of an operand
1069    to be used in a string instruction (cmpstrsi, movmemsi, ..).  LEN is
1070    the maximum length of the block of memory that might be accessed or
1071    NULL if unknown.  */
1072
1073 static rtx
1074 get_memory_rtx (tree exp, tree len)
1075 {
1076   rtx addr = expand_expr (exp, NULL_RTX, ptr_mode, EXPAND_NORMAL);
1077   rtx mem = gen_rtx_MEM (BLKmode, memory_address (BLKmode, addr));
1078
1079   /* Get an expression we can use to find the attributes to assign to MEM.
1080      If it is an ADDR_EXPR, use the operand.  Otherwise, dereference it if
1081      we can.  First remove any nops.  */
1082   while ((TREE_CODE (exp) == NOP_EXPR || TREE_CODE (exp) == CONVERT_EXPR
1083           || TREE_CODE (exp) == NON_LVALUE_EXPR)
1084          && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (exp, 0))))
1085     exp = TREE_OPERAND (exp, 0);
1086
1087   if (TREE_CODE (exp) == ADDR_EXPR)
1088     exp = TREE_OPERAND (exp, 0);
1089   else if (POINTER_TYPE_P (TREE_TYPE (exp)))
1090     exp = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (exp)), exp);
1091   else
1092     exp = NULL;
1093
1094   /* Honor attributes derived from exp, except for the alias set
1095      (as builtin stringops may alias with anything) and the size
1096      (as stringops may access multiple array elements).  */
1097   if (exp)
1098     {
1099       set_mem_attributes (mem, exp, 0);
1100
1101       /* Allow the string and memory builtins to overflow from one
1102          field into another, see http://gcc.gnu.org/PR23561.
1103          Thus avoid COMPONENT_REFs in MEM_EXPR unless we know the whole
1104          memory accessed by the string or memory builtin will fit
1105          within the field.  */
1106       if (MEM_EXPR (mem) && TREE_CODE (MEM_EXPR (mem)) == COMPONENT_REF)
1107         {
1108           tree mem_expr = MEM_EXPR (mem);
1109           HOST_WIDE_INT offset = -1, length = -1;
1110           tree inner = exp;
1111
1112           while (TREE_CODE (inner) == ARRAY_REF
1113                  || TREE_CODE (inner) == NOP_EXPR
1114                  || TREE_CODE (inner) == CONVERT_EXPR
1115                  || TREE_CODE (inner) == NON_LVALUE_EXPR
1116                  || TREE_CODE (inner) == VIEW_CONVERT_EXPR
1117                  || TREE_CODE (inner) == SAVE_EXPR)
1118             inner = TREE_OPERAND (inner, 0);
1119
1120           gcc_assert (TREE_CODE (inner) == COMPONENT_REF);
1121
1122           if (MEM_OFFSET (mem)
1123               && GET_CODE (MEM_OFFSET (mem)) == CONST_INT)
1124             offset = INTVAL (MEM_OFFSET (mem));
1125
1126           if (offset >= 0 && len && host_integerp (len, 0))
1127             length = tree_low_cst (len, 0);
1128
1129           while (TREE_CODE (inner) == COMPONENT_REF)
1130             {
1131               tree field = TREE_OPERAND (inner, 1);
1132               gcc_assert (! DECL_BIT_FIELD (field));
1133               gcc_assert (TREE_CODE (mem_expr) == COMPONENT_REF);
1134               gcc_assert (field == TREE_OPERAND (mem_expr, 1));
1135
1136               if (length >= 0
1137                   && TYPE_SIZE_UNIT (TREE_TYPE (inner))
1138                   && host_integerp (TYPE_SIZE_UNIT (TREE_TYPE (inner)), 0))
1139                 {
1140                   HOST_WIDE_INT size
1141                     = tree_low_cst (TYPE_SIZE_UNIT (TREE_TYPE (inner)), 0);
1142                   /* If we can prove the memory starting at XEXP (mem, 0)
1143                      and ending at XEXP (mem, 0) + LENGTH will fit into
1144                      this field, we can keep that COMPONENT_REF in MEM_EXPR.  */
1145                   if (offset <= size
1146                       && length <= size
1147                       && offset + length <= size)
1148                     break;
1149                 }
1150
1151               if (offset >= 0
1152                   && host_integerp (DECL_FIELD_OFFSET (field), 0))
1153                 offset += tree_low_cst (DECL_FIELD_OFFSET (field), 0)
1154                           + tree_low_cst (DECL_FIELD_BIT_OFFSET (field), 1)
1155                             / BITS_PER_UNIT;
1156               else
1157                 {
1158                   offset = -1;
1159                   length = -1;
1160                 }
1161
1162               mem_expr = TREE_OPERAND (mem_expr, 0);
1163               inner = TREE_OPERAND (inner, 0);
1164             }
1165
1166           if (mem_expr == NULL)
1167             offset = -1;
1168           if (mem_expr != MEM_EXPR (mem))
1169             {
1170               set_mem_expr (mem, mem_expr);
1171               set_mem_offset (mem, offset >= 0 ? GEN_INT (offset) : NULL_RTX);
1172             }
1173         }
1174       set_mem_alias_set (mem, 0);
1175       set_mem_size (mem, NULL_RTX);
1176     }
1177
1178   return mem;
1179 }
1180 \f
1181 /* Built-in functions to perform an untyped call and return.  */
1182
1183 /* For each register that may be used for calling a function, this
1184    gives a mode used to copy the register's value.  VOIDmode indicates
1185    the register is not used for calling a function.  If the machine
1186    has register windows, this gives only the outbound registers.
1187    INCOMING_REGNO gives the corresponding inbound register.  */
1188 static enum machine_mode apply_args_mode[FIRST_PSEUDO_REGISTER];
1189
1190 /* For each register that may be used for returning values, this gives
1191    a mode used to copy the register's value.  VOIDmode indicates the
1192    register is not used for returning values.  If the machine has
1193    register windows, this gives only the outbound registers.
1194    INCOMING_REGNO gives the corresponding inbound register.  */
1195 static enum machine_mode apply_result_mode[FIRST_PSEUDO_REGISTER];
1196
1197 /* For each register that may be used for calling a function, this
1198    gives the offset of that register into the block returned by
1199    __builtin_apply_args.  0 indicates that the register is not
1200    used for calling a function.  */
1201 static int apply_args_reg_offset[FIRST_PSEUDO_REGISTER];
1202
1203 /* Return the size required for the block returned by __builtin_apply_args,
1204    and initialize apply_args_mode.  */
1205
1206 static int
1207 apply_args_size (void)
1208 {
1209   static int size = -1;
1210   int align;
1211   unsigned int regno;
1212   enum machine_mode mode;
1213
1214   /* The values computed by this function never change.  */
1215   if (size < 0)
1216     {
1217       /* The first value is the incoming arg-pointer.  */
1218       size = GET_MODE_SIZE (Pmode);
1219
1220       /* The second value is the structure value address unless this is
1221          passed as an "invisible" first argument.  */
1222       if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0))
1223         size += GET_MODE_SIZE (Pmode);
1224
1225       for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1226         if (FUNCTION_ARG_REGNO_P (regno))
1227           {
1228             mode = reg_raw_mode[regno];
1229
1230             gcc_assert (mode != VOIDmode);
1231
1232             align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1233             if (size % align != 0)
1234               size = CEIL (size, align) * align;
1235             apply_args_reg_offset[regno] = size;
1236             size += GET_MODE_SIZE (mode);
1237             apply_args_mode[regno] = mode;
1238           }
1239         else
1240           {
1241             apply_args_mode[regno] = VOIDmode;
1242             apply_args_reg_offset[regno] = 0;
1243           }
1244     }
1245   return size;
1246 }
1247
1248 /* Return the size required for the block returned by __builtin_apply,
1249    and initialize apply_result_mode.  */
1250
1251 static int
1252 apply_result_size (void)
1253 {
1254   static int size = -1;
1255   int align, regno;
1256   enum machine_mode mode;
1257
1258   /* The values computed by this function never change.  */
1259   if (size < 0)
1260     {
1261       size = 0;
1262
1263       for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1264         if (FUNCTION_VALUE_REGNO_P (regno))
1265           {
1266             mode = reg_raw_mode[regno];
1267
1268             gcc_assert (mode != VOIDmode);
1269
1270             align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1271             if (size % align != 0)
1272               size = CEIL (size, align) * align;
1273             size += GET_MODE_SIZE (mode);
1274             apply_result_mode[regno] = mode;
1275           }
1276         else
1277           apply_result_mode[regno] = VOIDmode;
1278
1279       /* Allow targets that use untyped_call and untyped_return to override
1280          the size so that machine-specific information can be stored here.  */
1281 #ifdef APPLY_RESULT_SIZE
1282       size = APPLY_RESULT_SIZE;
1283 #endif
1284     }
1285   return size;
1286 }
1287
1288 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
1289 /* Create a vector describing the result block RESULT.  If SAVEP is true,
1290    the result block is used to save the values; otherwise it is used to
1291    restore the values.  */
1292
1293 static rtx
1294 result_vector (int savep, rtx result)
1295 {
1296   int regno, size, align, nelts;
1297   enum machine_mode mode;
1298   rtx reg, mem;
1299   rtx *savevec = alloca (FIRST_PSEUDO_REGISTER * sizeof (rtx));
1300
1301   size = nelts = 0;
1302   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1303     if ((mode = apply_result_mode[regno]) != VOIDmode)
1304       {
1305         align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1306         if (size % align != 0)
1307           size = CEIL (size, align) * align;
1308         reg = gen_rtx_REG (mode, savep ? regno : INCOMING_REGNO (regno));
1309         mem = adjust_address (result, mode, size);
1310         savevec[nelts++] = (savep
1311                             ? gen_rtx_SET (VOIDmode, mem, reg)
1312                             : gen_rtx_SET (VOIDmode, reg, mem));
1313         size += GET_MODE_SIZE (mode);
1314       }
1315   return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (nelts, savevec));
1316 }
1317 #endif /* HAVE_untyped_call or HAVE_untyped_return */
1318
1319 /* Save the state required to perform an untyped call with the same
1320    arguments as were passed to the current function.  */
1321
1322 static rtx
1323 expand_builtin_apply_args_1 (void)
1324 {
1325   rtx registers, tem;
1326   int size, align, regno;
1327   enum machine_mode mode;
1328   rtx struct_incoming_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 1);
1329
1330   /* Create a block where the arg-pointer, structure value address,
1331      and argument registers can be saved.  */
1332   registers = assign_stack_local (BLKmode, apply_args_size (), -1);
1333
1334   /* Walk past the arg-pointer and structure value address.  */
1335   size = GET_MODE_SIZE (Pmode);
1336   if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0))
1337     size += GET_MODE_SIZE (Pmode);
1338
1339   /* Save each register used in calling a function to the block.  */
1340   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1341     if ((mode = apply_args_mode[regno]) != VOIDmode)
1342       {
1343         align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1344         if (size % align != 0)
1345           size = CEIL (size, align) * align;
1346
1347         tem = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1348
1349         emit_move_insn (adjust_address (registers, mode, size), tem);
1350         size += GET_MODE_SIZE (mode);
1351       }
1352
1353   /* Save the arg pointer to the block.  */
1354   tem = copy_to_reg (virtual_incoming_args_rtx);
1355 #ifdef STACK_GROWS_DOWNWARD
1356   /* We need the pointer as the caller actually passed them to us, not
1357      as we might have pretended they were passed.  Make sure it's a valid
1358      operand, as emit_move_insn isn't expected to handle a PLUS.  */
1359   tem
1360     = force_operand (plus_constant (tem, current_function_pretend_args_size),
1361                      NULL_RTX);
1362 #endif
1363   emit_move_insn (adjust_address (registers, Pmode, 0), tem);
1364
1365   size = GET_MODE_SIZE (Pmode);
1366
1367   /* Save the structure value address unless this is passed as an
1368      "invisible" first argument.  */
1369   if (struct_incoming_value)
1370     {
1371       emit_move_insn (adjust_address (registers, Pmode, size),
1372                       copy_to_reg (struct_incoming_value));
1373       size += GET_MODE_SIZE (Pmode);
1374     }
1375
1376   /* Return the address of the block.  */
1377   return copy_addr_to_reg (XEXP (registers, 0));
1378 }
1379
1380 /* __builtin_apply_args returns block of memory allocated on
1381    the stack into which is stored the arg pointer, structure
1382    value address, static chain, and all the registers that might
1383    possibly be used in performing a function call.  The code is
1384    moved to the start of the function so the incoming values are
1385    saved.  */
1386
1387 static rtx
1388 expand_builtin_apply_args (void)
1389 {
1390   /* Don't do __builtin_apply_args more than once in a function.
1391      Save the result of the first call and reuse it.  */
1392   if (apply_args_value != 0)
1393     return apply_args_value;
1394   {
1395     /* When this function is called, it means that registers must be
1396        saved on entry to this function.  So we migrate the
1397        call to the first insn of this function.  */
1398     rtx temp;
1399     rtx seq;
1400
1401     start_sequence ();
1402     temp = expand_builtin_apply_args_1 ();
1403     seq = get_insns ();
1404     end_sequence ();
1405
1406     apply_args_value = temp;
1407
1408     /* Put the insns after the NOTE that starts the function.
1409        If this is inside a start_sequence, make the outer-level insn
1410        chain current, so the code is placed at the start of the
1411        function.  */
1412     push_topmost_sequence ();
1413     emit_insn_before (seq, NEXT_INSN (entry_of_function ()));
1414     pop_topmost_sequence ();
1415     return temp;
1416   }
1417 }
1418
1419 /* Perform an untyped call and save the state required to perform an
1420    untyped return of whatever value was returned by the given function.  */
1421
1422 static rtx
1423 expand_builtin_apply (rtx function, rtx arguments, rtx argsize)
1424 {
1425   int size, align, regno;
1426   enum machine_mode mode;
1427   rtx incoming_args, result, reg, dest, src, call_insn;
1428   rtx old_stack_level = 0;
1429   rtx call_fusage = 0;
1430   rtx struct_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0);
1431
1432   arguments = convert_memory_address (Pmode, arguments);
1433
1434   /* Create a block where the return registers can be saved.  */
1435   result = assign_stack_local (BLKmode, apply_result_size (), -1);
1436
1437   /* Fetch the arg pointer from the ARGUMENTS block.  */
1438   incoming_args = gen_reg_rtx (Pmode);
1439   emit_move_insn (incoming_args, gen_rtx_MEM (Pmode, arguments));
1440 #ifndef STACK_GROWS_DOWNWARD
1441   incoming_args = expand_simple_binop (Pmode, MINUS, incoming_args, argsize,
1442                                        incoming_args, 0, OPTAB_LIB_WIDEN);
1443 #endif
1444
1445   /* Push a new argument block and copy the arguments.  Do not allow
1446      the (potential) memcpy call below to interfere with our stack
1447      manipulations.  */
1448   do_pending_stack_adjust ();
1449   NO_DEFER_POP;
1450
1451   /* Save the stack with nonlocal if available.  */
1452 #ifdef HAVE_save_stack_nonlocal
1453   if (HAVE_save_stack_nonlocal)
1454     emit_stack_save (SAVE_NONLOCAL, &old_stack_level, NULL_RTX);
1455   else
1456 #endif
1457     emit_stack_save (SAVE_BLOCK, &old_stack_level, NULL_RTX);
1458
1459   /* Allocate a block of memory onto the stack and copy the memory
1460      arguments to the outgoing arguments address.  */
1461   allocate_dynamic_stack_space (argsize, 0, BITS_PER_UNIT);
1462   dest = virtual_outgoing_args_rtx;
1463 #ifndef STACK_GROWS_DOWNWARD
1464   if (GET_CODE (argsize) == CONST_INT)
1465     dest = plus_constant (dest, -INTVAL (argsize));
1466   else
1467     dest = gen_rtx_PLUS (Pmode, dest, negate_rtx (Pmode, argsize));
1468 #endif
1469   dest = gen_rtx_MEM (BLKmode, dest);
1470   set_mem_align (dest, PARM_BOUNDARY);
1471   src = gen_rtx_MEM (BLKmode, incoming_args);
1472   set_mem_align (src, PARM_BOUNDARY);
1473   emit_block_move (dest, src, argsize, BLOCK_OP_NORMAL);
1474
1475   /* Refer to the argument block.  */
1476   apply_args_size ();
1477   arguments = gen_rtx_MEM (BLKmode, arguments);
1478   set_mem_align (arguments, PARM_BOUNDARY);
1479
1480   /* Walk past the arg-pointer and structure value address.  */
1481   size = GET_MODE_SIZE (Pmode);
1482   if (struct_value)
1483     size += GET_MODE_SIZE (Pmode);
1484
1485   /* Restore each of the registers previously saved.  Make USE insns
1486      for each of these registers for use in making the call.  */
1487   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1488     if ((mode = apply_args_mode[regno]) != VOIDmode)
1489       {
1490         align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1491         if (size % align != 0)
1492           size = CEIL (size, align) * align;
1493         reg = gen_rtx_REG (mode, regno);
1494         emit_move_insn (reg, adjust_address (arguments, mode, size));
1495         use_reg (&call_fusage, reg);
1496         size += GET_MODE_SIZE (mode);
1497       }
1498
1499   /* Restore the structure value address unless this is passed as an
1500      "invisible" first argument.  */
1501   size = GET_MODE_SIZE (Pmode);
1502   if (struct_value)
1503     {
1504       rtx value = gen_reg_rtx (Pmode);
1505       emit_move_insn (value, adjust_address (arguments, Pmode, size));
1506       emit_move_insn (struct_value, value);
1507       if (REG_P (struct_value))
1508         use_reg (&call_fusage, struct_value);
1509       size += GET_MODE_SIZE (Pmode);
1510     }
1511
1512   /* All arguments and registers used for the call are set up by now!  */
1513   function = prepare_call_address (function, NULL, &call_fusage, 0, 0);
1514
1515   /* Ensure address is valid.  SYMBOL_REF is already valid, so no need,
1516      and we don't want to load it into a register as an optimization,
1517      because prepare_call_address already did it if it should be done.  */
1518   if (GET_CODE (function) != SYMBOL_REF)
1519     function = memory_address (FUNCTION_MODE, function);
1520
1521   /* Generate the actual call instruction and save the return value.  */
1522 #ifdef HAVE_untyped_call
1523   if (HAVE_untyped_call)
1524     emit_call_insn (gen_untyped_call (gen_rtx_MEM (FUNCTION_MODE, function),
1525                                       result, result_vector (1, result)));
1526   else
1527 #endif
1528 #ifdef HAVE_call_value
1529   if (HAVE_call_value)
1530     {
1531       rtx valreg = 0;
1532
1533       /* Locate the unique return register.  It is not possible to
1534          express a call that sets more than one return register using
1535          call_value; use untyped_call for that.  In fact, untyped_call
1536          only needs to save the return registers in the given block.  */
1537       for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1538         if ((mode = apply_result_mode[regno]) != VOIDmode)
1539           {
1540             gcc_assert (!valreg); /* HAVE_untyped_call required.  */
1541
1542             valreg = gen_rtx_REG (mode, regno);
1543           }
1544
1545       emit_call_insn (GEN_CALL_VALUE (valreg,
1546                                       gen_rtx_MEM (FUNCTION_MODE, function),
1547                                       const0_rtx, NULL_RTX, const0_rtx));
1548
1549       emit_move_insn (adjust_address (result, GET_MODE (valreg), 0), valreg);
1550     }
1551   else
1552 #endif
1553     gcc_unreachable ();
1554
1555   /* Find the CALL insn we just emitted, and attach the register usage
1556      information.  */
1557   call_insn = last_call_insn ();
1558   add_function_usage_to (call_insn, call_fusage);
1559
1560   /* Restore the stack.  */
1561 #ifdef HAVE_save_stack_nonlocal
1562   if (HAVE_save_stack_nonlocal)
1563     emit_stack_restore (SAVE_NONLOCAL, old_stack_level, NULL_RTX);
1564   else
1565 #endif
1566     emit_stack_restore (SAVE_BLOCK, old_stack_level, NULL_RTX);
1567
1568   OK_DEFER_POP;
1569
1570   /* Return the address of the result block.  */
1571   result = copy_addr_to_reg (XEXP (result, 0));
1572   return convert_memory_address (ptr_mode, result);
1573 }
1574
1575 /* Perform an untyped return.  */
1576
1577 static void
1578 expand_builtin_return (rtx result)
1579 {
1580   int size, align, regno;
1581   enum machine_mode mode;
1582   rtx reg;
1583   rtx call_fusage = 0;
1584
1585   result = convert_memory_address (Pmode, result);
1586
1587   apply_result_size ();
1588   result = gen_rtx_MEM (BLKmode, result);
1589
1590 #ifdef HAVE_untyped_return
1591   if (HAVE_untyped_return)
1592     {
1593       emit_jump_insn (gen_untyped_return (result, result_vector (0, result)));
1594       emit_barrier ();
1595       return;
1596     }
1597 #endif
1598
1599   /* Restore the return value and note that each value is used.  */
1600   size = 0;
1601   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1602     if ((mode = apply_result_mode[regno]) != VOIDmode)
1603       {
1604         align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1605         if (size % align != 0)
1606           size = CEIL (size, align) * align;
1607         reg = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1608         emit_move_insn (reg, adjust_address (result, mode, size));
1609
1610         push_to_sequence (call_fusage);
1611         emit_insn (gen_rtx_USE (VOIDmode, reg));
1612         call_fusage = get_insns ();
1613         end_sequence ();
1614         size += GET_MODE_SIZE (mode);
1615       }
1616
1617   /* Put the USE insns before the return.  */
1618   emit_insn (call_fusage);
1619
1620   /* Return whatever values was restored by jumping directly to the end
1621      of the function.  */
1622   expand_naked_return ();
1623 }
1624
1625 /* Used by expand_builtin_classify_type and fold_builtin_classify_type.  */
1626
1627 static enum type_class
1628 type_to_class (tree type)
1629 {
1630   switch (TREE_CODE (type))
1631     {
1632     case VOID_TYPE:        return void_type_class;
1633     case INTEGER_TYPE:     return integer_type_class;
1634     case ENUMERAL_TYPE:    return enumeral_type_class;
1635     case BOOLEAN_TYPE:     return boolean_type_class;
1636     case POINTER_TYPE:     return pointer_type_class;
1637     case REFERENCE_TYPE:   return reference_type_class;
1638     case OFFSET_TYPE:      return offset_type_class;
1639     case REAL_TYPE:        return real_type_class;
1640     case COMPLEX_TYPE:     return complex_type_class;
1641     case FUNCTION_TYPE:    return function_type_class;
1642     case METHOD_TYPE:      return method_type_class;
1643     case RECORD_TYPE:      return record_type_class;
1644     case UNION_TYPE:
1645     case QUAL_UNION_TYPE:  return union_type_class;
1646     case ARRAY_TYPE:       return (TYPE_STRING_FLAG (type)
1647                                    ? string_type_class : array_type_class);
1648     case LANG_TYPE:        return lang_type_class;
1649     default:               return no_type_class;
1650     }
1651 }
1652
1653 /* Expand a call to __builtin_classify_type with arguments found in
1654    ARGLIST.  */
1655
1656 static rtx
1657 expand_builtin_classify_type (tree arglist)
1658 {
1659   if (arglist != 0)
1660     return GEN_INT (type_to_class (TREE_TYPE (TREE_VALUE (arglist))));
1661   return GEN_INT (no_type_class);
1662 }
1663
1664 /* This helper macro, meant to be used in mathfn_built_in below,
1665    determines which among a set of three builtin math functions is
1666    appropriate for a given type mode.  The `F' and `L' cases are
1667    automatically generated from the `double' case.  */
1668 #define CASE_MATHFN(BUILT_IN_MATHFN) \
1669   case BUILT_IN_MATHFN: case BUILT_IN_MATHFN##F: case BUILT_IN_MATHFN##L: \
1670   fcode = BUILT_IN_MATHFN; fcodef = BUILT_IN_MATHFN##F ; \
1671   fcodel = BUILT_IN_MATHFN##L ; break;
1672
1673 /* Return mathematic function equivalent to FN but operating directly
1674    on TYPE, if available.  If we can't do the conversion, return zero.  */
1675 tree
1676 mathfn_built_in (tree type, enum built_in_function fn)
1677 {
1678   enum built_in_function fcode, fcodef, fcodel;
1679
1680   switch (fn)
1681     {
1682       CASE_MATHFN (BUILT_IN_ACOS)
1683       CASE_MATHFN (BUILT_IN_ACOSH)
1684       CASE_MATHFN (BUILT_IN_ASIN)
1685       CASE_MATHFN (BUILT_IN_ASINH)
1686       CASE_MATHFN (BUILT_IN_ATAN)
1687       CASE_MATHFN (BUILT_IN_ATAN2)
1688       CASE_MATHFN (BUILT_IN_ATANH)
1689       CASE_MATHFN (BUILT_IN_CBRT)
1690       CASE_MATHFN (BUILT_IN_CEIL)
1691       CASE_MATHFN (BUILT_IN_COPYSIGN)
1692       CASE_MATHFN (BUILT_IN_COS)
1693       CASE_MATHFN (BUILT_IN_COSH)
1694       CASE_MATHFN (BUILT_IN_DREM)
1695       CASE_MATHFN (BUILT_IN_ERF)
1696       CASE_MATHFN (BUILT_IN_ERFC)
1697       CASE_MATHFN (BUILT_IN_EXP)
1698       CASE_MATHFN (BUILT_IN_EXP10)
1699       CASE_MATHFN (BUILT_IN_EXP2)
1700       CASE_MATHFN (BUILT_IN_EXPM1)
1701       CASE_MATHFN (BUILT_IN_FABS)
1702       CASE_MATHFN (BUILT_IN_FDIM)
1703       CASE_MATHFN (BUILT_IN_FLOOR)
1704       CASE_MATHFN (BUILT_IN_FMA)
1705       CASE_MATHFN (BUILT_IN_FMAX)
1706       CASE_MATHFN (BUILT_IN_FMIN)
1707       CASE_MATHFN (BUILT_IN_FMOD)
1708       CASE_MATHFN (BUILT_IN_FREXP)
1709       CASE_MATHFN (BUILT_IN_GAMMA)
1710       CASE_MATHFN (BUILT_IN_HUGE_VAL)
1711       CASE_MATHFN (BUILT_IN_HYPOT)
1712       CASE_MATHFN (BUILT_IN_ILOGB)
1713       CASE_MATHFN (BUILT_IN_INF)
1714       CASE_MATHFN (BUILT_IN_J0)
1715       CASE_MATHFN (BUILT_IN_J1)
1716       CASE_MATHFN (BUILT_IN_JN)
1717       CASE_MATHFN (BUILT_IN_LCEIL)
1718       CASE_MATHFN (BUILT_IN_LDEXP)
1719       CASE_MATHFN (BUILT_IN_LFLOOR)
1720       CASE_MATHFN (BUILT_IN_LGAMMA)
1721       CASE_MATHFN (BUILT_IN_LLCEIL)
1722       CASE_MATHFN (BUILT_IN_LLFLOOR)
1723       CASE_MATHFN (BUILT_IN_LLRINT)
1724       CASE_MATHFN (BUILT_IN_LLROUND)
1725       CASE_MATHFN (BUILT_IN_LOG)
1726       CASE_MATHFN (BUILT_IN_LOG10)
1727       CASE_MATHFN (BUILT_IN_LOG1P)
1728       CASE_MATHFN (BUILT_IN_LOG2)
1729       CASE_MATHFN (BUILT_IN_LOGB)
1730       CASE_MATHFN (BUILT_IN_LRINT)
1731       CASE_MATHFN (BUILT_IN_LROUND)
1732       CASE_MATHFN (BUILT_IN_MODF)
1733       CASE_MATHFN (BUILT_IN_NAN)
1734       CASE_MATHFN (BUILT_IN_NANS)
1735       CASE_MATHFN (BUILT_IN_NEARBYINT)
1736       CASE_MATHFN (BUILT_IN_NEXTAFTER)
1737       CASE_MATHFN (BUILT_IN_NEXTTOWARD)
1738       CASE_MATHFN (BUILT_IN_POW)
1739       CASE_MATHFN (BUILT_IN_POWI)
1740       CASE_MATHFN (BUILT_IN_POW10)
1741       CASE_MATHFN (BUILT_IN_REMAINDER)
1742       CASE_MATHFN (BUILT_IN_REMQUO)
1743       CASE_MATHFN (BUILT_IN_RINT)
1744       CASE_MATHFN (BUILT_IN_ROUND)
1745       CASE_MATHFN (BUILT_IN_SCALB)
1746       CASE_MATHFN (BUILT_IN_SCALBLN)
1747       CASE_MATHFN (BUILT_IN_SCALBN)
1748       CASE_MATHFN (BUILT_IN_SIGNIFICAND)
1749       CASE_MATHFN (BUILT_IN_SIN)
1750       CASE_MATHFN (BUILT_IN_SINCOS)
1751       CASE_MATHFN (BUILT_IN_SINH)
1752       CASE_MATHFN (BUILT_IN_SQRT)
1753       CASE_MATHFN (BUILT_IN_TAN)
1754       CASE_MATHFN (BUILT_IN_TANH)
1755       CASE_MATHFN (BUILT_IN_TGAMMA)
1756       CASE_MATHFN (BUILT_IN_TRUNC)
1757       CASE_MATHFN (BUILT_IN_Y0)
1758       CASE_MATHFN (BUILT_IN_Y1)
1759       CASE_MATHFN (BUILT_IN_YN)
1760
1761       default:
1762         return 0;
1763       }
1764
1765   if (TYPE_MAIN_VARIANT (type) == double_type_node)
1766     return implicit_built_in_decls[fcode];
1767   else if (TYPE_MAIN_VARIANT (type) == float_type_node)
1768     return implicit_built_in_decls[fcodef];
1769   else if (TYPE_MAIN_VARIANT (type) == long_double_type_node)
1770     return implicit_built_in_decls[fcodel];
1771   else
1772     return 0;
1773 }
1774
1775 /* If errno must be maintained, expand the RTL to check if the result,
1776    TARGET, of a built-in function call, EXP, is NaN, and if so set
1777    errno to EDOM.  */
1778
1779 static void
1780 expand_errno_check (tree exp, rtx target)
1781 {
1782   rtx lab = gen_label_rtx ();
1783
1784   /* Test the result; if it is NaN, set errno=EDOM because
1785      the argument was not in the domain.  */
1786   emit_cmp_and_jump_insns (target, target, EQ, 0, GET_MODE (target),
1787                            0, lab);
1788
1789 #ifdef TARGET_EDOM
1790   /* If this built-in doesn't throw an exception, set errno directly.  */
1791   if (TREE_NOTHROW (TREE_OPERAND (TREE_OPERAND (exp, 0), 0)))
1792     {
1793 #ifdef GEN_ERRNO_RTX
1794       rtx errno_rtx = GEN_ERRNO_RTX;
1795 #else
1796       rtx errno_rtx
1797           = gen_rtx_MEM (word_mode, gen_rtx_SYMBOL_REF (Pmode, "errno"));
1798 #endif
1799       emit_move_insn (errno_rtx, GEN_INT (TARGET_EDOM));
1800       emit_label (lab);
1801       return;
1802     }
1803 #endif
1804
1805   /* We can't set errno=EDOM directly; let the library call do it.
1806      Pop the arguments right away in case the call gets deleted.  */
1807   NO_DEFER_POP;
1808   expand_call (exp, target, 0);
1809   OK_DEFER_POP;
1810   emit_label (lab);
1811 }
1812
1813
1814 /* Expand a call to one of the builtin math functions (sqrt, exp, or log).
1815    Return 0 if a normal call should be emitted rather than expanding the
1816    function in-line.  EXP is the expression that is a call to the builtin
1817    function; if convenient, the result should be placed in TARGET.
1818    SUBTARGET may be used as the target for computing one of EXP's operands.  */
1819
1820 static rtx
1821 expand_builtin_mathfn (tree exp, rtx target, rtx subtarget)
1822 {
1823   optab builtin_optab;
1824   rtx op0, insns, before_call;
1825   tree fndecl = get_callee_fndecl (exp);
1826   tree arglist = TREE_OPERAND (exp, 1);
1827   enum machine_mode mode;
1828   bool errno_set = false;
1829   tree arg, narg;
1830
1831   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
1832     return 0;
1833
1834   arg = TREE_VALUE (arglist);
1835
1836   switch (DECL_FUNCTION_CODE (fndecl))
1837     {
1838     CASE_FLT_FN (BUILT_IN_SQRT):
1839       errno_set = ! tree_expr_nonnegative_p (arg);
1840       builtin_optab = sqrt_optab;
1841       break;
1842     CASE_FLT_FN (BUILT_IN_EXP):
1843       errno_set = true; builtin_optab = exp_optab; break;
1844     CASE_FLT_FN (BUILT_IN_EXP10):
1845     CASE_FLT_FN (BUILT_IN_POW10):
1846       errno_set = true; builtin_optab = exp10_optab; break;
1847     CASE_FLT_FN (BUILT_IN_EXP2):
1848       errno_set = true; builtin_optab = exp2_optab; break;
1849     CASE_FLT_FN (BUILT_IN_EXPM1):
1850       errno_set = true; builtin_optab = expm1_optab; break;
1851     CASE_FLT_FN (BUILT_IN_LOGB):
1852       errno_set = true; builtin_optab = logb_optab; break;
1853     CASE_FLT_FN (BUILT_IN_ILOGB):
1854       errno_set = true; builtin_optab = ilogb_optab; break;
1855     CASE_FLT_FN (BUILT_IN_LOG):
1856       errno_set = true; builtin_optab = log_optab; break;
1857     CASE_FLT_FN (BUILT_IN_LOG10):
1858       errno_set = true; builtin_optab = log10_optab; break;
1859     CASE_FLT_FN (BUILT_IN_LOG2):
1860       errno_set = true; builtin_optab = log2_optab; break;
1861     CASE_FLT_FN (BUILT_IN_LOG1P):
1862       errno_set = true; builtin_optab = log1p_optab; break;
1863     CASE_FLT_FN (BUILT_IN_ASIN):
1864       builtin_optab = asin_optab; break;
1865     CASE_FLT_FN (BUILT_IN_ACOS):
1866       builtin_optab = acos_optab; break;
1867     CASE_FLT_FN (BUILT_IN_TAN):
1868       builtin_optab = tan_optab; break;
1869     CASE_FLT_FN (BUILT_IN_ATAN):
1870       builtin_optab = atan_optab; break;
1871     CASE_FLT_FN (BUILT_IN_FLOOR):
1872       builtin_optab = floor_optab; break;
1873     CASE_FLT_FN (BUILT_IN_CEIL):
1874       builtin_optab = ceil_optab; break;
1875     CASE_FLT_FN (BUILT_IN_TRUNC):
1876       builtin_optab = btrunc_optab; break;
1877     CASE_FLT_FN (BUILT_IN_ROUND):
1878       builtin_optab = round_optab; break;
1879     CASE_FLT_FN (BUILT_IN_NEARBYINT):
1880       builtin_optab = nearbyint_optab; break;
1881     CASE_FLT_FN (BUILT_IN_RINT):
1882       builtin_optab = rint_optab; break;
1883     CASE_FLT_FN (BUILT_IN_LRINT):
1884     CASE_FLT_FN (BUILT_IN_LLRINT):
1885       builtin_optab = lrint_optab; break;
1886     default:
1887       gcc_unreachable ();
1888     }
1889
1890   /* Make a suitable register to place result in.  */
1891   mode = TYPE_MODE (TREE_TYPE (exp));
1892
1893   if (! flag_errno_math || ! HONOR_NANS (mode))
1894     errno_set = false;
1895
1896   /* Before working hard, check whether the instruction is available.  */
1897   if (builtin_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1898     {
1899       target = gen_reg_rtx (mode);
1900
1901       /* Wrap the computation of the argument in a SAVE_EXPR, as we may
1902          need to expand the argument again.  This way, we will not perform
1903          side-effects more the once.  */
1904       narg = builtin_save_expr (arg);
1905       if (narg != arg)
1906         {
1907           arg = narg;
1908           arglist = build_tree_list (NULL_TREE, arg);
1909           exp = build_function_call_expr (fndecl, arglist);
1910         }
1911
1912       op0 = expand_expr (arg, subtarget, VOIDmode, 0);
1913
1914       start_sequence ();
1915
1916       /* Compute into TARGET.
1917          Set TARGET to wherever the result comes back.  */
1918       target = expand_unop (mode, builtin_optab, op0, target, 0);
1919
1920       if (target != 0)
1921         {
1922           if (errno_set)
1923             expand_errno_check (exp, target);
1924
1925           /* Output the entire sequence.  */
1926           insns = get_insns ();
1927           end_sequence ();
1928           emit_insn (insns);
1929           return target;
1930         }
1931
1932       /* If we were unable to expand via the builtin, stop the sequence
1933          (without outputting the insns) and call to the library function
1934          with the stabilized argument list.  */
1935       end_sequence ();
1936     }
1937
1938   before_call = get_last_insn ();
1939
1940   target = expand_call (exp, target, target == const0_rtx);
1941
1942   /* If this is a sqrt operation and we don't care about errno, try to
1943      attach a REG_EQUAL note with a SQRT rtx to the emitted libcall.
1944      This allows the semantics of the libcall to be visible to the RTL
1945      optimizers.  */
1946   if (builtin_optab == sqrt_optab && !errno_set)
1947     {
1948       /* Search backwards through the insns emitted by expand_call looking
1949          for the instruction with the REG_RETVAL note.  */
1950       rtx last = get_last_insn ();
1951       while (last != before_call)
1952         {
1953           if (find_reg_note (last, REG_RETVAL, NULL))
1954             {
1955               rtx note = find_reg_note (last, REG_EQUAL, NULL);
1956               /* Check that the REQ_EQUAL note is an EXPR_LIST with
1957                  two elements, i.e. symbol_ref(sqrt) and the operand.  */
1958               if (note
1959                   && GET_CODE (note) == EXPR_LIST
1960                   && GET_CODE (XEXP (note, 0)) == EXPR_LIST
1961                   && XEXP (XEXP (note, 0), 1) != NULL_RTX
1962                   && XEXP (XEXP (XEXP (note, 0), 1), 1) == NULL_RTX)
1963                 {
1964                   rtx operand = XEXP (XEXP (XEXP (note, 0), 1), 0);
1965                   /* Check operand is a register with expected mode.  */
1966                   if (operand
1967                       && REG_P (operand)
1968                       && GET_MODE (operand) == mode)
1969                     {
1970                       /* Replace the REG_EQUAL note with a SQRT rtx.  */
1971                       rtx equiv = gen_rtx_SQRT (mode, operand);
1972                       set_unique_reg_note (last, REG_EQUAL, equiv);
1973                     }
1974                 }
1975               break;
1976             }
1977           last = PREV_INSN (last);
1978         }
1979     }
1980
1981   return target;
1982 }
1983
1984 /* Expand a call to the builtin binary math functions (pow and atan2).
1985    Return 0 if a normal call should be emitted rather than expanding the
1986    function in-line.  EXP is the expression that is a call to the builtin
1987    function; if convenient, the result should be placed in TARGET.
1988    SUBTARGET may be used as the target for computing one of EXP's
1989    operands.  */
1990
1991 static rtx
1992 expand_builtin_mathfn_2 (tree exp, rtx target, rtx subtarget)
1993 {
1994   optab builtin_optab;
1995   rtx op0, op1, insns;
1996   int op1_type = REAL_TYPE;
1997   tree fndecl = get_callee_fndecl (exp);
1998   tree arglist = TREE_OPERAND (exp, 1);
1999   tree arg0, arg1, temp, narg;
2000   enum machine_mode mode;
2001   bool errno_set = true;
2002   bool stable = true;
2003
2004   if ((DECL_FUNCTION_CODE (fndecl) == BUILT_IN_LDEXP)
2005       || (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_LDEXPF)
2006       || (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_LDEXPL))
2007     op1_type = INTEGER_TYPE;
2008
2009   if (!validate_arglist (arglist, REAL_TYPE, op1_type, VOID_TYPE))
2010     return 0;
2011
2012   arg0 = TREE_VALUE (arglist);
2013   arg1 = TREE_VALUE (TREE_CHAIN (arglist));
2014
2015   switch (DECL_FUNCTION_CODE (fndecl))
2016     {
2017     CASE_FLT_FN (BUILT_IN_POW):
2018       builtin_optab = pow_optab; break;
2019     CASE_FLT_FN (BUILT_IN_ATAN2):
2020       builtin_optab = atan2_optab; break;
2021     CASE_FLT_FN (BUILT_IN_LDEXP):
2022       builtin_optab = ldexp_optab; break;
2023     CASE_FLT_FN (BUILT_IN_FMOD):
2024       builtin_optab = fmod_optab; break;
2025     CASE_FLT_FN (BUILT_IN_DREM):
2026       builtin_optab = drem_optab; break;
2027     default:
2028       gcc_unreachable ();
2029     }
2030
2031   /* Make a suitable register to place result in.  */
2032   mode = TYPE_MODE (TREE_TYPE (exp));
2033
2034   /* Before working hard, check whether the instruction is available.  */
2035   if (builtin_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing)
2036     return 0;
2037
2038   target = gen_reg_rtx (mode);
2039
2040   if (! flag_errno_math || ! HONOR_NANS (mode))
2041     errno_set = false;
2042
2043   /* Always stabilize the argument list.  */
2044   narg = builtin_save_expr (arg1);
2045   if (narg != arg1)
2046     {
2047       arg1 = narg;
2048       temp = build_tree_list (NULL_TREE, narg);
2049       stable = false;
2050     }
2051   else
2052     temp = TREE_CHAIN (arglist);
2053
2054   narg = builtin_save_expr (arg0);
2055   if (narg != arg0)
2056     {
2057       arg0 = narg;
2058       arglist = tree_cons (NULL_TREE, narg, temp);
2059       stable = false;
2060     }
2061   else if (! stable)
2062     arglist = tree_cons (NULL_TREE, arg0, temp);
2063
2064   if (! stable)
2065     exp = build_function_call_expr (fndecl, arglist);
2066
2067   op0 = expand_expr (arg0, subtarget, VOIDmode, EXPAND_NORMAL);
2068   op1 = expand_normal (arg1);
2069
2070   start_sequence ();
2071
2072   /* Compute into TARGET.
2073      Set TARGET to wherever the result comes back.  */
2074   target = expand_binop (mode, builtin_optab, op0, op1,
2075                          target, 0, OPTAB_DIRECT);
2076
2077   /* If we were unable to expand via the builtin, stop the sequence
2078      (without outputting the insns) and call to the library function
2079      with the stabilized argument list.  */
2080   if (target == 0)
2081     {
2082       end_sequence ();
2083       return expand_call (exp, target, target == const0_rtx);
2084     }
2085
2086   if (errno_set)
2087     expand_errno_check (exp, target);
2088
2089   /* Output the entire sequence.  */
2090   insns = get_insns ();
2091   end_sequence ();
2092   emit_insn (insns);
2093
2094   return target;
2095 }
2096
2097 /* Expand a call to the builtin sin and cos math functions.
2098    Return 0 if a normal call should be emitted rather than expanding the
2099    function in-line.  EXP is the expression that is a call to the builtin
2100    function; if convenient, the result should be placed in TARGET.
2101    SUBTARGET may be used as the target for computing one of EXP's
2102    operands.  */
2103
2104 static rtx
2105 expand_builtin_mathfn_3 (tree exp, rtx target, rtx subtarget)
2106 {
2107   optab builtin_optab;
2108   rtx op0, insns;
2109   tree fndecl = get_callee_fndecl (exp);
2110   tree arglist = TREE_OPERAND (exp, 1);
2111   enum machine_mode mode;
2112   tree arg, narg;
2113
2114   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
2115     return 0;
2116
2117   arg = TREE_VALUE (arglist);
2118
2119   switch (DECL_FUNCTION_CODE (fndecl))
2120     {
2121     CASE_FLT_FN (BUILT_IN_SIN):
2122     CASE_FLT_FN (BUILT_IN_COS):
2123       builtin_optab = sincos_optab; break;
2124     default:
2125       gcc_unreachable ();
2126     }
2127
2128   /* Make a suitable register to place result in.  */
2129   mode = TYPE_MODE (TREE_TYPE (exp));
2130
2131   /* Check if sincos insn is available, otherwise fallback
2132      to sin or cos insn.  */
2133   if (builtin_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing) {
2134     switch (DECL_FUNCTION_CODE (fndecl))
2135       {
2136       CASE_FLT_FN (BUILT_IN_SIN):
2137         builtin_optab = sin_optab; break;
2138       CASE_FLT_FN (BUILT_IN_COS):
2139         builtin_optab = cos_optab; break;
2140       default:
2141         gcc_unreachable ();
2142       }
2143   }
2144
2145   /* Before working hard, check whether the instruction is available.  */
2146   if (builtin_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2147     {
2148       target = gen_reg_rtx (mode);
2149
2150       /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2151          need to expand the argument again.  This way, we will not perform
2152          side-effects more the once.  */
2153       narg = save_expr (arg);
2154       if (narg != arg)
2155         {
2156           arg = narg;
2157           arglist = build_tree_list (NULL_TREE, arg);
2158           exp = build_function_call_expr (fndecl, arglist);
2159         }
2160
2161       op0 = expand_expr (arg, subtarget, VOIDmode, 0);
2162
2163       start_sequence ();
2164
2165       /* Compute into TARGET.
2166          Set TARGET to wherever the result comes back.  */
2167       if (builtin_optab == sincos_optab)
2168         {
2169           int result;
2170
2171           switch (DECL_FUNCTION_CODE (fndecl))
2172             {
2173             CASE_FLT_FN (BUILT_IN_SIN):
2174               result = expand_twoval_unop (builtin_optab, op0, 0, target, 0);
2175               break;
2176             CASE_FLT_FN (BUILT_IN_COS):
2177               result = expand_twoval_unop (builtin_optab, op0, target, 0, 0);
2178               break;
2179             default:
2180               gcc_unreachable ();
2181             }
2182           gcc_assert (result);
2183         }
2184       else
2185         {
2186           target = expand_unop (mode, builtin_optab, op0, target, 0);
2187         }
2188
2189       if (target != 0)
2190         {
2191           /* Output the entire sequence.  */
2192           insns = get_insns ();
2193           end_sequence ();
2194           emit_insn (insns);
2195           return target;
2196         }
2197
2198       /* If we were unable to expand via the builtin, stop the sequence
2199          (without outputting the insns) and call to the library function
2200          with the stabilized argument list.  */
2201       end_sequence ();
2202     }
2203
2204   target = expand_call (exp, target, target == const0_rtx);
2205
2206   return target;
2207 }
2208
2209 /* Expand a call to the builtin sincos math function.
2210    Return 0 if a normal call should be emitted rather than expanding the
2211    function in-line.  EXP is the expression that is a call to the builtin
2212    function.  */
2213
2214 static rtx
2215 expand_builtin_sincos (tree exp)
2216 {
2217   rtx op0, op1, op2, target1, target2;
2218   tree arglist = TREE_OPERAND (exp, 1);
2219   enum machine_mode mode;
2220   tree arg, sinp, cosp;
2221   int result;
2222
2223   if (!validate_arglist (arglist, REAL_TYPE,
2224                          POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2225     return 0;
2226
2227   arg = TREE_VALUE (arglist);
2228   sinp = TREE_VALUE (TREE_CHAIN (arglist));
2229   cosp = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2230
2231   /* Make a suitable register to place result in.  */
2232   mode = TYPE_MODE (TREE_TYPE (arg));
2233
2234   /* Check if sincos insn is available, otherwise emit the call.  */
2235   if (sincos_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing)
2236     return NULL_RTX;
2237
2238   target1 = gen_reg_rtx (mode);
2239   target2 = gen_reg_rtx (mode);
2240
2241   op0 = expand_normal (arg);
2242   op1 = expand_normal (build_fold_indirect_ref (sinp));
2243   op2 = expand_normal (build_fold_indirect_ref (cosp));
2244
2245   /* Compute into target1 and target2.
2246      Set TARGET to wherever the result comes back.  */
2247   result = expand_twoval_unop (sincos_optab, op0, target2, target1, 0);
2248   gcc_assert (result);
2249
2250   /* Move target1 and target2 to the memory locations indicated
2251      by op1 and op2.  */
2252   emit_move_insn (op1, target1);
2253   emit_move_insn (op2, target2);
2254
2255   return const0_rtx;
2256 }
2257
2258 /* Expand a call to one of the builtin rounding functions (lfloor).
2259    If expanding via optab fails, lower expression to (int)(floor(x)).
2260    EXP is the expression that is a call to the builtin function;
2261    if convenient, the result should be placed in TARGET.  SUBTARGET may
2262    be used as the target for computing one of EXP's operands.  */
2263
2264 static rtx
2265 expand_builtin_int_roundingfn (tree exp, rtx target, rtx subtarget)
2266 {
2267   optab builtin_optab;
2268   rtx op0, insns, tmp;
2269   tree fndecl = get_callee_fndecl (exp);
2270   tree arglist = TREE_OPERAND (exp, 1);
2271   enum built_in_function fallback_fn;
2272   tree fallback_fndecl;
2273   enum machine_mode mode;
2274   tree arg, narg;
2275
2276   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
2277     gcc_unreachable ();
2278
2279   arg = TREE_VALUE (arglist);
2280
2281   switch (DECL_FUNCTION_CODE (fndecl))
2282     {
2283     CASE_FLT_FN (BUILT_IN_LCEIL):
2284     CASE_FLT_FN (BUILT_IN_LLCEIL):
2285       builtin_optab = lceil_optab;
2286       fallback_fn = BUILT_IN_CEIL;
2287       break;
2288
2289     CASE_FLT_FN (BUILT_IN_LFLOOR):
2290     CASE_FLT_FN (BUILT_IN_LLFLOOR):
2291       builtin_optab = lfloor_optab;
2292       fallback_fn = BUILT_IN_FLOOR;
2293       break;
2294
2295     default:
2296       gcc_unreachable ();
2297     }
2298
2299   /* Make a suitable register to place result in.  */
2300   mode = TYPE_MODE (TREE_TYPE (exp));
2301
2302   /* Before working hard, check whether the instruction is available.  */
2303   if (builtin_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2304     {
2305       target = gen_reg_rtx (mode);
2306
2307       /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2308          need to expand the argument again.  This way, we will not perform
2309          side-effects more the once.  */
2310       narg = builtin_save_expr (arg);
2311       if (narg != arg)
2312         {
2313           arg = narg;
2314           arglist = build_tree_list (NULL_TREE, arg);
2315           exp = build_function_call_expr (fndecl, arglist);
2316         }
2317
2318       op0 = expand_expr (arg, subtarget, VOIDmode, 0);
2319
2320       start_sequence ();
2321
2322       /* Compute into TARGET.
2323          Set TARGET to wherever the result comes back.  */
2324       target = expand_unop (mode, builtin_optab, op0, target, 0);
2325
2326       if (target != 0)
2327         {
2328           /* Output the entire sequence.  */
2329           insns = get_insns ();
2330           end_sequence ();
2331           emit_insn (insns);
2332           return target;
2333         }
2334
2335       /* If we were unable to expand via the builtin, stop the sequence
2336          (without outputting the insns).  */
2337       end_sequence ();
2338     }
2339
2340   /* Fall back to floating point rounding optab.  */
2341   fallback_fndecl = mathfn_built_in (TREE_TYPE (arg), fallback_fn);
2342   /* We shouldn't get here on targets without TARGET_C99_FUNCTIONS.
2343      ??? Perhaps convert (int)floorf(x) into (int)floor((double)x).  */
2344   gcc_assert (fallback_fndecl != NULL_TREE);
2345   exp = build_function_call_expr (fallback_fndecl, arglist);
2346
2347   tmp = expand_normal (exp);
2348
2349   /* Truncate the result of floating point optab to integer
2350      via expand_fix ().  */
2351   target = gen_reg_rtx (mode);
2352   expand_fix (target, tmp, 0);
2353
2354   return target;
2355 }
2356
2357 /* To evaluate powi(x,n), the floating point value x raised to the
2358    constant integer exponent n, we use a hybrid algorithm that
2359    combines the "window method" with look-up tables.  For an
2360    introduction to exponentiation algorithms and "addition chains",
2361    see section 4.6.3, "Evaluation of Powers" of Donald E. Knuth,
2362    "Seminumerical Algorithms", Vol. 2, "The Art of Computer Programming",
2363    3rd Edition, 1998, and Daniel M. Gordon, "A Survey of Fast Exponentiation
2364    Methods", Journal of Algorithms, Vol. 27, pp. 129-146, 1998.  */
2365
2366 /* Provide a default value for POWI_MAX_MULTS, the maximum number of
2367    multiplications to inline before calling the system library's pow
2368    function.  powi(x,n) requires at worst 2*bits(n)-2 multiplications,
2369    so this default never requires calling pow, powf or powl.  */
2370
2371 #ifndef POWI_MAX_MULTS
2372 #define POWI_MAX_MULTS  (2*HOST_BITS_PER_WIDE_INT-2)
2373 #endif
2374
2375 /* The size of the "optimal power tree" lookup table.  All
2376    exponents less than this value are simply looked up in the
2377    powi_table below.  This threshold is also used to size the
2378    cache of pseudo registers that hold intermediate results.  */
2379 #define POWI_TABLE_SIZE 256
2380
2381 /* The size, in bits of the window, used in the "window method"
2382    exponentiation algorithm.  This is equivalent to a radix of
2383    (1<<POWI_WINDOW_SIZE) in the corresponding "m-ary method".  */
2384 #define POWI_WINDOW_SIZE 3
2385
2386 /* The following table is an efficient representation of an
2387    "optimal power tree".  For each value, i, the corresponding
2388    value, j, in the table states than an optimal evaluation
2389    sequence for calculating pow(x,i) can be found by evaluating
2390    pow(x,j)*pow(x,i-j).  An optimal power tree for the first
2391    100 integers is given in Knuth's "Seminumerical algorithms".  */
2392
2393 static const unsigned char powi_table[POWI_TABLE_SIZE] =
2394   {
2395       0,   1,   1,   2,   2,   3,   3,   4,  /*   0 -   7 */
2396       4,   6,   5,   6,   6,  10,   7,   9,  /*   8 -  15 */
2397       8,  16,   9,  16,  10,  12,  11,  13,  /*  16 -  23 */
2398      12,  17,  13,  18,  14,  24,  15,  26,  /*  24 -  31 */
2399      16,  17,  17,  19,  18,  33,  19,  26,  /*  32 -  39 */
2400      20,  25,  21,  40,  22,  27,  23,  44,  /*  40 -  47 */
2401      24,  32,  25,  34,  26,  29,  27,  44,  /*  48 -  55 */
2402      28,  31,  29,  34,  30,  60,  31,  36,  /*  56 -  63 */
2403      32,  64,  33,  34,  34,  46,  35,  37,  /*  64 -  71 */
2404      36,  65,  37,  50,  38,  48,  39,  69,  /*  72 -  79 */
2405      40,  49,  41,  43,  42,  51,  43,  58,  /*  80 -  87 */
2406      44,  64,  45,  47,  46,  59,  47,  76,  /*  88 -  95 */
2407      48,  65,  49,  66,  50,  67,  51,  66,  /*  96 - 103 */
2408      52,  70,  53,  74,  54, 104,  55,  74,  /* 104 - 111 */
2409      56,  64,  57,  69,  58,  78,  59,  68,  /* 112 - 119 */
2410      60,  61,  61,  80,  62,  75,  63,  68,  /* 120 - 127 */
2411      64,  65,  65, 128,  66, 129,  67,  90,  /* 128 - 135 */
2412      68,  73,  69, 131,  70,  94,  71,  88,  /* 136 - 143 */
2413      72, 128,  73,  98,  74, 132,  75, 121,  /* 144 - 151 */
2414      76, 102,  77, 124,  78, 132,  79, 106,  /* 152 - 159 */
2415      80,  97,  81, 160,  82,  99,  83, 134,  /* 160 - 167 */
2416      84,  86,  85,  95,  86, 160,  87, 100,  /* 168 - 175 */
2417      88, 113,  89,  98,  90, 107,  91, 122,  /* 176 - 183 */
2418      92, 111,  93, 102,  94, 126,  95, 150,  /* 184 - 191 */
2419      96, 128,  97, 130,  98, 133,  99, 195,  /* 192 - 199 */
2420     100, 128, 101, 123, 102, 164, 103, 138,  /* 200 - 207 */
2421     104, 145, 105, 146, 106, 109, 107, 149,  /* 208 - 215 */
2422     108, 200, 109, 146, 110, 170, 111, 157,  /* 216 - 223 */
2423     112, 128, 113, 130, 114, 182, 115, 132,  /* 224 - 231 */
2424     116, 200, 117, 132, 118, 158, 119, 206,  /* 232 - 239 */
2425     120, 240, 121, 162, 122, 147, 123, 152,  /* 240 - 247 */
2426     124, 166, 125, 214, 126, 138, 127, 153,  /* 248 - 255 */
2427   };
2428
2429
2430 /* Return the number of multiplications required to calculate
2431    powi(x,n) where n is less than POWI_TABLE_SIZE.  This is a
2432    subroutine of powi_cost.  CACHE is an array indicating
2433    which exponents have already been calculated.  */
2434
2435 static int
2436 powi_lookup_cost (unsigned HOST_WIDE_INT n, bool *cache)
2437 {
2438   /* If we've already calculated this exponent, then this evaluation
2439      doesn't require any additional multiplications.  */
2440   if (cache[n])
2441     return 0;
2442
2443   cache[n] = true;
2444   return powi_lookup_cost (n - powi_table[n], cache)
2445          + powi_lookup_cost (powi_table[n], cache) + 1;
2446 }
2447
2448 /* Return the number of multiplications required to calculate
2449    powi(x,n) for an arbitrary x, given the exponent N.  This
2450    function needs to be kept in sync with expand_powi below.  */
2451
2452 static int
2453 powi_cost (HOST_WIDE_INT n)
2454 {
2455   bool cache[POWI_TABLE_SIZE];
2456   unsigned HOST_WIDE_INT digit;
2457   unsigned HOST_WIDE_INT val;
2458   int result;
2459
2460   if (n == 0)
2461     return 0;
2462
2463   /* Ignore the reciprocal when calculating the cost.  */
2464   val = (n < 0) ? -n : n;
2465
2466   /* Initialize the exponent cache.  */
2467   memset (cache, 0, POWI_TABLE_SIZE * sizeof (bool));
2468   cache[1] = true;
2469
2470   result = 0;
2471
2472   while (val >= POWI_TABLE_SIZE)
2473     {
2474       if (val & 1)
2475         {
2476           digit = val & ((1 << POWI_WINDOW_SIZE) - 1);
2477           result += powi_lookup_cost (digit, cache)
2478                     + POWI_WINDOW_SIZE + 1;
2479           val >>= POWI_WINDOW_SIZE;
2480         }
2481       else
2482         {
2483           val >>= 1;
2484           result++;
2485         }
2486     }
2487
2488   return result + powi_lookup_cost (val, cache);
2489 }
2490
2491 /* Recursive subroutine of expand_powi.  This function takes the array,
2492    CACHE, of already calculated exponents and an exponent N and returns
2493    an RTX that corresponds to CACHE[1]**N, as calculated in mode MODE.  */
2494
2495 static rtx
2496 expand_powi_1 (enum machine_mode mode, unsigned HOST_WIDE_INT n, rtx *cache)
2497 {
2498   unsigned HOST_WIDE_INT digit;
2499   rtx target, result;
2500   rtx op0, op1;
2501
2502   if (n < POWI_TABLE_SIZE)
2503     {
2504       if (cache[n])
2505         return cache[n];
2506
2507       target = gen_reg_rtx (mode);
2508       cache[n] = target;
2509
2510       op0 = expand_powi_1 (mode, n - powi_table[n], cache);
2511       op1 = expand_powi_1 (mode, powi_table[n], cache);
2512     }
2513   else if (n & 1)
2514     {
2515       target = gen_reg_rtx (mode);
2516       digit = n & ((1 << POWI_WINDOW_SIZE) - 1);
2517       op0 = expand_powi_1 (mode, n - digit, cache);
2518       op1 = expand_powi_1 (mode, digit, cache);
2519     }
2520   else
2521     {
2522       target = gen_reg_rtx (mode);
2523       op0 = expand_powi_1 (mode, n >> 1, cache);
2524       op1 = op0;
2525     }
2526
2527   result = expand_mult (mode, op0, op1, target, 0);
2528   if (result != target)
2529     emit_move_insn (target, result);
2530   return target;
2531 }
2532
2533 /* Expand the RTL to evaluate powi(x,n) in mode MODE.  X is the
2534    floating point operand in mode MODE, and N is the exponent.  This
2535    function needs to be kept in sync with powi_cost above.  */
2536
2537 static rtx
2538 expand_powi (rtx x, enum machine_mode mode, HOST_WIDE_INT n)
2539 {
2540   unsigned HOST_WIDE_INT val;
2541   rtx cache[POWI_TABLE_SIZE];
2542   rtx result;
2543
2544   if (n == 0)
2545     return CONST1_RTX (mode);
2546
2547   val = (n < 0) ? -n : n;
2548
2549   memset (cache, 0, sizeof (cache));
2550   cache[1] = x;
2551
2552   result = expand_powi_1 (mode, (n < 0) ? -n : n, cache);
2553
2554   /* If the original exponent was negative, reciprocate the result.  */
2555   if (n < 0)
2556     result = expand_binop (mode, sdiv_optab, CONST1_RTX (mode),
2557                            result, NULL_RTX, 0, OPTAB_LIB_WIDEN);
2558
2559   return result;
2560 }
2561
2562 /* Expand a call to the pow built-in mathematical function.  Return 0 if
2563    a normal call should be emitted rather than expanding the function
2564    in-line.  EXP is the expression that is a call to the builtin
2565    function; if convenient, the result should be placed in TARGET.  */
2566
2567 static rtx
2568 expand_builtin_pow (tree exp, rtx target, rtx subtarget)
2569 {
2570   tree arglist = TREE_OPERAND (exp, 1);
2571   tree arg0, arg1;
2572
2573   if (! validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
2574     return 0;
2575
2576   arg0 = TREE_VALUE (arglist);
2577   arg1 = TREE_VALUE (TREE_CHAIN (arglist));
2578
2579   if (TREE_CODE (arg1) == REAL_CST
2580       && ! TREE_CONSTANT_OVERFLOW (arg1))
2581     {
2582       REAL_VALUE_TYPE cint;
2583       REAL_VALUE_TYPE c;
2584       HOST_WIDE_INT n;
2585
2586       c = TREE_REAL_CST (arg1);
2587       n = real_to_integer (&c);
2588       real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
2589       if (real_identical (&c, &cint))
2590         {
2591           /* If the exponent is -1, 0, 1 or 2, then expand_powi is exact.
2592              Otherwise, check the number of multiplications required.
2593              Note that pow never sets errno for an integer exponent.  */
2594           if ((n >= -1 && n <= 2)
2595               || (flag_unsafe_math_optimizations
2596                   && ! optimize_size
2597                   && powi_cost (n) <= POWI_MAX_MULTS))
2598             {
2599               enum machine_mode mode = TYPE_MODE (TREE_TYPE (exp));
2600               rtx op = expand_expr (arg0, subtarget, VOIDmode, 0);
2601               op = force_reg (mode, op);
2602               return expand_powi (op, mode, n);
2603             }
2604         }
2605     }
2606
2607   if (! flag_unsafe_math_optimizations)
2608     return NULL_RTX;
2609   return expand_builtin_mathfn_2 (exp, target, subtarget);
2610 }
2611
2612 /* Expand a call to the powi built-in mathematical function.  Return 0 if
2613    a normal call should be emitted rather than expanding the function
2614    in-line.  EXP is the expression that is a call to the builtin
2615    function; if convenient, the result should be placed in TARGET.  */
2616
2617 static rtx
2618 expand_builtin_powi (tree exp, rtx target, rtx subtarget)
2619 {
2620   tree arglist = TREE_OPERAND (exp, 1);
2621   tree arg0, arg1;
2622   rtx op0, op1;
2623   enum machine_mode mode;
2624   enum machine_mode mode2;
2625
2626   if (! validate_arglist (arglist, REAL_TYPE, INTEGER_TYPE, VOID_TYPE))
2627     return 0;
2628
2629   arg0 = TREE_VALUE (arglist);
2630   arg1 = TREE_VALUE (TREE_CHAIN (arglist));
2631   mode = TYPE_MODE (TREE_TYPE (exp));
2632
2633   /* Handle constant power.  */
2634
2635   if (TREE_CODE (arg1) == INTEGER_CST
2636       && ! TREE_CONSTANT_OVERFLOW (arg1))
2637     {
2638       HOST_WIDE_INT n = TREE_INT_CST_LOW (arg1);
2639
2640       /* If the exponent is -1, 0, 1 or 2, then expand_powi is exact.
2641          Otherwise, check the number of multiplications required.  */
2642       if ((TREE_INT_CST_HIGH (arg1) == 0
2643            || TREE_INT_CST_HIGH (arg1) == -1)
2644           && ((n >= -1 && n <= 2)
2645               || (! optimize_size
2646                   && powi_cost (n) <= POWI_MAX_MULTS)))
2647         {
2648           op0 = expand_expr (arg0, subtarget, VOIDmode, 0);
2649           op0 = force_reg (mode, op0);
2650           return expand_powi (op0, mode, n);
2651         }
2652     }
2653
2654   /* Emit a libcall to libgcc.  */
2655
2656   /* Mode of the 2nd argument must match that of an int. */
2657   mode2 = mode_for_size (INT_TYPE_SIZE, MODE_INT, 0);
2658
2659   if (target == NULL_RTX)
2660     target = gen_reg_rtx (mode);
2661
2662   op0 = expand_expr (arg0, subtarget, mode, 0);
2663   if (GET_MODE (op0) != mode)
2664     op0 = convert_to_mode (mode, op0, 0);
2665   op1 = expand_expr (arg1, 0, mode2, 0);
2666   if (GET_MODE (op1) != mode2)
2667     op1 = convert_to_mode (mode2, op1, 0);
2668
2669   target = emit_library_call_value (powi_optab->handlers[(int) mode].libfunc,
2670                                     target, LCT_CONST_MAKE_BLOCK, mode, 2,
2671                                     op0, mode, op1, mode2);
2672
2673   return target;
2674 }
2675
2676 /* Expand expression EXP which is a call to the strlen builtin.  Return 0
2677    if we failed the caller should emit a normal call, otherwise
2678    try to get the result in TARGET, if convenient.  */
2679
2680 static rtx
2681 expand_builtin_strlen (tree arglist, rtx target,
2682                        enum machine_mode target_mode)
2683 {
2684   if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
2685     return 0;
2686   else
2687     {
2688       rtx pat;
2689       tree len, src = TREE_VALUE (arglist);
2690       rtx result, src_reg, char_rtx, before_strlen;
2691       enum machine_mode insn_mode = target_mode, char_mode;
2692       enum insn_code icode = CODE_FOR_nothing;
2693       int align;
2694
2695       /* If the length can be computed at compile-time, return it.  */
2696       len = c_strlen (src, 0);
2697       if (len)
2698         return expand_expr (len, target, target_mode, EXPAND_NORMAL);
2699
2700       /* If the length can be computed at compile-time and is constant
2701          integer, but there are side-effects in src, evaluate
2702          src for side-effects, then return len.
2703          E.g. x = strlen (i++ ? "xfoo" + 1 : "bar");
2704          can be optimized into: i++; x = 3;  */
2705       len = c_strlen (src, 1);
2706       if (len && TREE_CODE (len) == INTEGER_CST)
2707         {
2708           expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
2709           return expand_expr (len, target, target_mode, EXPAND_NORMAL);
2710         }
2711
2712       align = get_pointer_alignment (src, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
2713
2714       /* If SRC is not a pointer type, don't do this operation inline.  */
2715       if (align == 0)
2716         return 0;
2717
2718       /* Bail out if we can't compute strlen in the right mode.  */
2719       while (insn_mode != VOIDmode)
2720         {
2721           icode = strlen_optab->handlers[(int) insn_mode].insn_code;
2722           if (icode != CODE_FOR_nothing)
2723             break;
2724
2725           insn_mode = GET_MODE_WIDER_MODE (insn_mode);
2726         }
2727       if (insn_mode == VOIDmode)
2728         return 0;
2729
2730       /* Make a place to write the result of the instruction.  */
2731       result = target;
2732       if (! (result != 0
2733              && REG_P (result)
2734              && GET_MODE (result) == insn_mode
2735              && REGNO (result) >= FIRST_PSEUDO_REGISTER))
2736         result = gen_reg_rtx (insn_mode);
2737
2738       /* Make a place to hold the source address.  We will not expand
2739          the actual source until we are sure that the expansion will
2740          not fail -- there are trees that cannot be expanded twice.  */
2741       src_reg = gen_reg_rtx (Pmode);
2742
2743       /* Mark the beginning of the strlen sequence so we can emit the
2744          source operand later.  */
2745       before_strlen = get_last_insn ();
2746
2747       char_rtx = const0_rtx;
2748       char_mode = insn_data[(int) icode].operand[2].mode;
2749       if (! (*insn_data[(int) icode].operand[2].predicate) (char_rtx,
2750                                                             char_mode))
2751         char_rtx = copy_to_mode_reg (char_mode, char_rtx);
2752
2753       pat = GEN_FCN (icode) (result, gen_rtx_MEM (BLKmode, src_reg),
2754                              char_rtx, GEN_INT (align));
2755       if (! pat)
2756         return 0;
2757       emit_insn (pat);
2758
2759       /* Now that we are assured of success, expand the source.  */
2760       start_sequence ();
2761       pat = expand_expr (src, src_reg, ptr_mode, EXPAND_NORMAL);
2762       if (pat != src_reg)
2763         emit_move_insn (src_reg, pat);
2764       pat = get_insns ();
2765       end_sequence ();
2766
2767       if (before_strlen)
2768         emit_insn_after (pat, before_strlen);
2769       else
2770         emit_insn_before (pat, get_insns ());
2771
2772       /* Return the value in the proper mode for this function.  */
2773       if (GET_MODE (result) == target_mode)
2774         target = result;
2775       else if (target != 0)
2776         convert_move (target, result, 0);
2777       else
2778         target = convert_to_mode (target_mode, result, 0);
2779
2780       return target;
2781     }
2782 }
2783
2784 /* Expand a call to the strstr builtin.  Return 0 if we failed the
2785    caller should emit a normal call, otherwise try to get the result
2786    in TARGET, if convenient (and in mode MODE if that's convenient).  */
2787
2788 static rtx
2789 expand_builtin_strstr (tree arglist, tree type, rtx target, enum machine_mode mode)
2790 {
2791   if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2792     {
2793       tree result = fold_builtin_strstr (arglist, type);
2794       if (result)
2795         return expand_expr (result, target, mode, EXPAND_NORMAL);
2796     }
2797   return 0;
2798 }
2799
2800 /* Expand a call to the strchr builtin.  Return 0 if we failed the
2801    caller should emit a normal call, otherwise try to get the result
2802    in TARGET, if convenient (and in mode MODE if that's convenient).  */
2803
2804 static rtx
2805 expand_builtin_strchr (tree arglist, tree type, rtx target, enum machine_mode mode)
2806 {
2807   if (validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2808     {
2809       tree result = fold_builtin_strchr (arglist, type);
2810       if (result)
2811         return expand_expr (result, target, mode, EXPAND_NORMAL);
2812
2813       /* FIXME: Should use strchrM optab so that ports can optimize this.  */
2814     }
2815   return 0;
2816 }
2817
2818 /* Expand a call to the strrchr builtin.  Return 0 if we failed the
2819    caller should emit a normal call, otherwise try to get the result
2820    in TARGET, if convenient (and in mode MODE if that's convenient).  */
2821
2822 static rtx
2823 expand_builtin_strrchr (tree arglist, tree type, rtx target, enum machine_mode mode)
2824 {
2825   if (validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2826     {
2827       tree result = fold_builtin_strrchr (arglist, type);
2828       if (result)
2829         return expand_expr (result, target, mode, EXPAND_NORMAL);
2830     }
2831   return 0;
2832 }
2833
2834 /* Expand a call to the strpbrk builtin.  Return 0 if we failed the
2835    caller should emit a normal call, otherwise try to get the result
2836    in TARGET, if convenient (and in mode MODE if that's convenient).  */
2837
2838 static rtx
2839 expand_builtin_strpbrk (tree arglist, tree type, rtx target, enum machine_mode mode)
2840 {
2841   if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2842     {
2843       tree result = fold_builtin_strpbrk (arglist, type);
2844       if (result)
2845         return expand_expr (result, target, mode, EXPAND_NORMAL);
2846     }
2847   return 0;
2848 }
2849
2850 /* Callback routine for store_by_pieces.  Read GET_MODE_BITSIZE (MODE)
2851    bytes from constant string DATA + OFFSET and return it as target
2852    constant.  */
2853
2854 static rtx
2855 builtin_memcpy_read_str (void *data, HOST_WIDE_INT offset,
2856                          enum machine_mode mode)
2857 {
2858   const char *str = (const char *) data;
2859
2860   gcc_assert (offset >= 0
2861               && ((unsigned HOST_WIDE_INT) offset + GET_MODE_SIZE (mode)
2862                   <= strlen (str) + 1));
2863
2864   return c_readstr (str + offset, mode);
2865 }
2866
2867 /* Expand a call to the memcpy builtin, with arguments in ARGLIST.
2868    Return 0 if we failed, the caller should emit a normal call,
2869    otherwise try to get the result in TARGET, if convenient (and in
2870    mode MODE if that's convenient).  */
2871 static rtx
2872 expand_builtin_memcpy (tree exp, rtx target, enum machine_mode mode)
2873 {
2874   tree fndecl = get_callee_fndecl (exp);
2875   tree arglist = TREE_OPERAND (exp, 1);
2876   if (!validate_arglist (arglist,
2877                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2878     return 0;
2879   else
2880     {
2881       tree dest = TREE_VALUE (arglist);
2882       tree src = TREE_VALUE (TREE_CHAIN (arglist));
2883       tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2884       const char *src_str;
2885       unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
2886       unsigned int dest_align
2887         = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2888       rtx dest_mem, src_mem, dest_addr, len_rtx;
2889       tree result = fold_builtin_memory_op (arglist, TREE_TYPE (TREE_TYPE (fndecl)),
2890                                             false, /*endp=*/0);
2891
2892       if (result)
2893         {
2894           while (TREE_CODE (result) == COMPOUND_EXPR)
2895             {
2896               expand_expr (TREE_OPERAND (result, 0), const0_rtx, VOIDmode,
2897                            EXPAND_NORMAL);
2898               result = TREE_OPERAND (result, 1);
2899             }
2900           return expand_expr (result, target, mode, EXPAND_NORMAL);
2901         }
2902
2903       /* If DEST is not a pointer type, call the normal function.  */
2904       if (dest_align == 0)
2905         return 0;
2906
2907       /* If either SRC is not a pointer type, don't do this
2908          operation in-line.  */
2909       if (src_align == 0)
2910         return 0;
2911
2912       dest_mem = get_memory_rtx (dest, len);
2913       set_mem_align (dest_mem, dest_align);
2914       len_rtx = expand_normal (len);
2915       src_str = c_getstr (src);
2916
2917       /* If SRC is a string constant and block move would be done
2918          by pieces, we can avoid loading the string from memory
2919          and only stored the computed constants.  */
2920       if (src_str
2921           && GET_CODE (len_rtx) == CONST_INT
2922           && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
2923           && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
2924                                   (void *) src_str, dest_align))
2925         {
2926           dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
2927                                       builtin_memcpy_read_str,
2928                                       (void *) src_str, dest_align, 0);
2929           dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2930           dest_mem = convert_memory_address (ptr_mode, dest_mem);
2931           return dest_mem;
2932         }
2933
2934       src_mem = get_memory_rtx (src, len);
2935       set_mem_align (src_mem, src_align);
2936
2937       /* Copy word part most expediently.  */
2938       dest_addr = emit_block_move (dest_mem, src_mem, len_rtx,
2939                                    CALL_EXPR_TAILCALL (exp)
2940                                    ? BLOCK_OP_TAILCALL : BLOCK_OP_NORMAL);
2941
2942       if (dest_addr == 0)
2943         {
2944           dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2945           dest_addr = convert_memory_address (ptr_mode, dest_addr);
2946         }
2947       return dest_addr;
2948     }
2949 }
2950
2951 /* Expand a call to the mempcpy builtin, with arguments in ARGLIST.
2952    Return 0 if we failed; the caller should emit a normal call,
2953    otherwise try to get the result in TARGET, if convenient (and in
2954    mode MODE if that's convenient).  If ENDP is 0 return the
2955    destination pointer, if ENDP is 1 return the end pointer ala
2956    mempcpy, and if ENDP is 2 return the end pointer minus one ala
2957    stpcpy.  */
2958
2959 static rtx
2960 expand_builtin_mempcpy (tree arglist, tree type, rtx target, enum machine_mode mode,
2961                         int endp)
2962 {
2963   if (!validate_arglist (arglist,
2964                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2965     return 0;
2966   /* If return value is ignored, transform mempcpy into memcpy.  */
2967   else if (target == const0_rtx)
2968     {
2969       tree fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
2970
2971       if (!fn)
2972         return 0;
2973
2974       return expand_expr (build_function_call_expr (fn, arglist),
2975                           target, mode, EXPAND_NORMAL);
2976     }
2977   else
2978     {
2979       tree dest = TREE_VALUE (arglist);
2980       tree src = TREE_VALUE (TREE_CHAIN (arglist));
2981       tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2982       const char *src_str;
2983       unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
2984       unsigned int dest_align
2985         = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2986       rtx dest_mem, src_mem, len_rtx;
2987       tree result = fold_builtin_memory_op (arglist, type, false, endp);
2988
2989       if (result)
2990         {
2991           while (TREE_CODE (result) == COMPOUND_EXPR)
2992             {
2993               expand_expr (TREE_OPERAND (result, 0), const0_rtx, VOIDmode,
2994                            EXPAND_NORMAL);
2995               result = TREE_OPERAND (result, 1);
2996             }
2997           return expand_expr (result, target, mode, EXPAND_NORMAL);
2998         }
2999
3000       /* If either SRC or DEST is not a pointer type, don't do this
3001          operation in-line.  */
3002       if (dest_align == 0 || src_align == 0)
3003         return 0;
3004
3005       /* If LEN is not constant, call the normal function.  */
3006       if (! host_integerp (len, 1))
3007         return 0;
3008
3009       len_rtx = expand_normal (len);
3010       src_str = c_getstr (src);
3011
3012       /* If SRC is a string constant and block move would be done
3013          by pieces, we can avoid loading the string from memory
3014          and only stored the computed constants.  */
3015       if (src_str
3016           && GET_CODE (len_rtx) == CONST_INT
3017           && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
3018           && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
3019                                   (void *) src_str, dest_align))
3020         {
3021           dest_mem = get_memory_rtx (dest, len);
3022           set_mem_align (dest_mem, dest_align);
3023           dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
3024                                       builtin_memcpy_read_str,
3025                                       (void *) src_str, dest_align, endp);
3026           dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3027           dest_mem = convert_memory_address (ptr_mode, dest_mem);
3028           return dest_mem;
3029         }
3030
3031       if (GET_CODE (len_rtx) == CONST_INT
3032           && can_move_by_pieces (INTVAL (len_rtx),
3033                                  MIN (dest_align, src_align)))
3034         {
3035           dest_mem = get_memory_rtx (dest, len);
3036           set_mem_align (dest_mem, dest_align);
3037           src_mem = get_memory_rtx (src, len);
3038           set_mem_align (src_mem, src_align);
3039           dest_mem = move_by_pieces (dest_mem, src_mem, INTVAL (len_rtx),
3040                                      MIN (dest_align, src_align), endp);
3041           dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3042           dest_mem = convert_memory_address (ptr_mode, dest_mem);
3043           return dest_mem;
3044         }
3045
3046       return 0;
3047     }
3048 }
3049
3050 /* Expand expression EXP, which is a call to the memmove builtin.  Return 0
3051    if we failed; the caller should emit a normal call.  */
3052
3053 static rtx
3054 expand_builtin_memmove (tree arglist, tree type, rtx target,
3055                         enum machine_mode mode, tree orig_exp)
3056 {
3057   if (!validate_arglist (arglist,
3058                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3059     return 0;
3060   else
3061     {
3062       tree dest = TREE_VALUE (arglist);
3063       tree src = TREE_VALUE (TREE_CHAIN (arglist));
3064       tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3065
3066       unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
3067       unsigned int dest_align
3068         = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
3069       tree result = fold_builtin_memory_op (arglist, type, false, /*endp=*/3);
3070
3071       if (result)
3072         {
3073           while (TREE_CODE (result) == COMPOUND_EXPR)
3074             {
3075               expand_expr (TREE_OPERAND (result, 0), const0_rtx, VOIDmode,
3076                            EXPAND_NORMAL);
3077               result = TREE_OPERAND (result, 1);
3078             }
3079           return expand_expr (result, target, mode, EXPAND_NORMAL);
3080         }
3081
3082       /* If DEST is not a pointer type, call the normal function.  */
3083       if (dest_align == 0)
3084         return 0;
3085
3086       /* If either SRC is not a pointer type, don't do this
3087          operation in-line.  */
3088       if (src_align == 0)
3089         return 0;
3090
3091       /* If src is categorized for a readonly section we can use
3092          normal memcpy.  */
3093       if (readonly_data_expr (src))
3094         {
3095           tree fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
3096           if (!fn)
3097             return 0;
3098           fn = build_function_call_expr (fn, arglist);
3099           if (TREE_CODE (fn) == CALL_EXPR)
3100             CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (orig_exp);
3101           return expand_expr (fn, target, mode, EXPAND_NORMAL);
3102         }
3103
3104       /* If length is 1 and we can expand memcpy call inline,
3105          it is ok to use memcpy as well.  */
3106       if (integer_onep (len))
3107         {
3108           rtx ret = expand_builtin_mempcpy (arglist, type, target, mode,
3109                                             /*endp=*/0);
3110           if (ret)
3111             return ret;
3112         }
3113
3114       /* Otherwise, call the normal function.  */
3115       return 0;
3116    }
3117 }
3118
3119 /* Expand expression EXP, which is a call to the bcopy builtin.  Return 0
3120    if we failed the caller should emit a normal call.  */
3121
3122 static rtx
3123 expand_builtin_bcopy (tree exp)
3124 {
3125   tree arglist = TREE_OPERAND (exp, 1);
3126   tree type = TREE_TYPE (exp);
3127   tree src, dest, size, newarglist;
3128
3129   if (!validate_arglist (arglist,
3130                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3131     return NULL_RTX;
3132
3133   src = TREE_VALUE (arglist);
3134   dest = TREE_VALUE (TREE_CHAIN (arglist));
3135   size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3136
3137   /* New argument list transforming bcopy(ptr x, ptr y, int z) to
3138      memmove(ptr y, ptr x, size_t z).   This is done this way
3139      so that if it isn't expanded inline, we fallback to
3140      calling bcopy instead of memmove.  */
3141
3142   newarglist = build_tree_list (NULL_TREE, fold_convert (sizetype, size));
3143   newarglist = tree_cons (NULL_TREE, src, newarglist);
3144   newarglist = tree_cons (NULL_TREE, dest, newarglist);
3145
3146   return expand_builtin_memmove (newarglist, type, const0_rtx, VOIDmode, exp);
3147 }
3148
3149 #ifndef HAVE_movstr
3150 # define HAVE_movstr 0
3151 # define CODE_FOR_movstr CODE_FOR_nothing
3152 #endif
3153
3154 /* Expand into a movstr instruction, if one is available.  Return 0 if
3155    we failed, the caller should emit a normal call, otherwise try to
3156    get the result in TARGET, if convenient.  If ENDP is 0 return the
3157    destination pointer, if ENDP is 1 return the end pointer ala
3158    mempcpy, and if ENDP is 2 return the end pointer minus one ala
3159    stpcpy.  */
3160
3161 static rtx
3162 expand_movstr (tree dest, tree src, rtx target, int endp)
3163 {
3164   rtx end;
3165   rtx dest_mem;
3166   rtx src_mem;
3167   rtx insn;
3168   const struct insn_data * data;
3169
3170   if (!HAVE_movstr)
3171     return 0;
3172
3173   dest_mem = get_memory_rtx (dest, NULL);
3174   src_mem = get_memory_rtx (src, NULL);
3175   if (!endp)
3176     {
3177       target = force_reg (Pmode, XEXP (dest_mem, 0));
3178       dest_mem = replace_equiv_address (dest_mem, target);
3179       end = gen_reg_rtx (Pmode);
3180     }
3181   else
3182     {
3183       if (target == 0 || target == const0_rtx)
3184         {
3185           end = gen_reg_rtx (Pmode);
3186           if (target == 0)
3187             target = end;
3188         }
3189       else
3190         end = target;
3191     }
3192
3193   data = insn_data + CODE_FOR_movstr;
3194
3195   if (data->operand[0].mode != VOIDmode)
3196     end = gen_lowpart (data->operand[0].mode, end);
3197
3198   insn = data->genfun (end, dest_mem, src_mem);
3199
3200   gcc_assert (insn);
3201
3202   emit_insn (insn);
3203
3204   /* movstr is supposed to set end to the address of the NUL
3205      terminator.  If the caller requested a mempcpy-like return value,
3206      adjust it.  */
3207   if (endp == 1 && target != const0_rtx)
3208     {
3209       rtx tem = plus_constant (gen_lowpart (GET_MODE (target), end), 1);
3210       emit_move_insn (target, force_operand (tem, NULL_RTX));
3211     }
3212
3213   return target;
3214 }
3215
3216 /* Expand expression EXP, which is a call to the strcpy builtin.  Return 0
3217    if we failed the caller should emit a normal call, otherwise try to get
3218    the result in TARGET, if convenient (and in mode MODE if that's
3219    convenient).  */
3220
3221 static rtx
3222 expand_builtin_strcpy (tree fndecl, tree arglist, rtx target, enum machine_mode mode)
3223 {
3224   if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3225     {
3226       tree result = fold_builtin_strcpy (fndecl, arglist, 0);
3227       if (result)
3228         {
3229           while (TREE_CODE (result) == COMPOUND_EXPR)
3230             {
3231               expand_expr (TREE_OPERAND (result, 0), const0_rtx, VOIDmode,
3232                            EXPAND_NORMAL);
3233               result = TREE_OPERAND (result, 1);
3234             }
3235           return expand_expr (result, target, mode, EXPAND_NORMAL);
3236         }
3237
3238       return expand_movstr (TREE_VALUE (arglist),
3239                             TREE_VALUE (TREE_CHAIN (arglist)),
3240                             target, /*endp=*/0);
3241     }
3242   return 0;
3243 }
3244
3245 /* Expand a call to the stpcpy builtin, with arguments in ARGLIST.
3246    Return 0 if we failed the caller should emit a normal call,
3247    otherwise try to get the result in TARGET, if convenient (and in
3248    mode MODE if that's convenient).  */
3249
3250 static rtx
3251 expand_builtin_stpcpy (tree exp, rtx target, enum machine_mode mode)
3252 {
3253   tree arglist = TREE_OPERAND (exp, 1);
3254   /* If return value is ignored, transform stpcpy into strcpy.  */
3255   if (target == const0_rtx)
3256     {
3257       tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
3258       if (!fn)
3259         return 0;
3260
3261       return expand_expr (build_function_call_expr (fn, arglist),
3262                           target, mode, EXPAND_NORMAL);
3263     }
3264
3265   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3266     return 0;
3267   else
3268     {
3269       tree dst, src, len, lenp1;
3270       tree narglist;
3271       rtx ret;
3272
3273       /* Ensure we get an actual string whose length can be evaluated at
3274          compile-time, not an expression containing a string.  This is
3275          because the latter will potentially produce pessimized code
3276          when used to produce the return value.  */
3277       src = TREE_VALUE (TREE_CHAIN (arglist));
3278       if (! c_getstr (src) || ! (len = c_strlen (src, 0)))
3279         return expand_movstr (TREE_VALUE (arglist),
3280                               TREE_VALUE (TREE_CHAIN (arglist)),
3281                               target, /*endp=*/2);
3282
3283       dst = TREE_VALUE (arglist);
3284       lenp1 = size_binop (PLUS_EXPR, len, ssize_int (1));
3285       narglist = build_tree_list (NULL_TREE, lenp1);
3286       narglist = tree_cons (NULL_TREE, src, narglist);
3287       narglist = tree_cons (NULL_TREE, dst, narglist);
3288       ret = expand_builtin_mempcpy (narglist, TREE_TYPE (exp),
3289                                     target, mode, /*endp=*/2);
3290
3291       if (ret)
3292         return ret;
3293
3294       if (TREE_CODE (len) == INTEGER_CST)
3295         {
3296           rtx len_rtx = expand_normal (len);
3297
3298           if (GET_CODE (len_rtx) == CONST_INT)
3299             {
3300               ret = expand_builtin_strcpy (get_callee_fndecl (exp),
3301                                            arglist, target, mode);
3302
3303               if (ret)
3304                 {
3305                   if (! target)
3306                     {
3307                       if (mode != VOIDmode)
3308                         target = gen_reg_rtx (mode);
3309                       else
3310                         target = gen_reg_rtx (GET_MODE (ret));
3311                     }
3312                   if (GET_MODE (target) != GET_MODE (ret))
3313                     ret = gen_lowpart (GET_MODE (target), ret);
3314
3315                   ret = plus_constant (ret, INTVAL (len_rtx));
3316                   ret = emit_move_insn (target, force_operand (ret, NULL_RTX));
3317                   gcc_assert (ret);
3318
3319                   return target;
3320                 }
3321             }
3322         }
3323
3324       return expand_movstr (TREE_VALUE (arglist),
3325                             TREE_VALUE (TREE_CHAIN (arglist)),
3326                             target, /*endp=*/2);
3327     }
3328 }
3329
3330 /* Callback routine for store_by_pieces.  Read GET_MODE_BITSIZE (MODE)
3331    bytes from constant string DATA + OFFSET and return it as target
3332    constant.  */
3333
3334 static rtx
3335 builtin_strncpy_read_str (void *data, HOST_WIDE_INT offset,
3336                           enum machine_mode mode)
3337 {
3338   const char *str = (const char *) data;
3339
3340   if ((unsigned HOST_WIDE_INT) offset > strlen (str))
3341     return const0_rtx;
3342
3343   return c_readstr (str + offset, mode);
3344 }
3345
3346 /* Expand expression EXP, which is a call to the strncpy builtin.  Return 0
3347    if we failed the caller should emit a normal call.  */
3348
3349 static rtx
3350 expand_builtin_strncpy (tree exp, rtx target, enum machine_mode mode)
3351 {
3352   tree fndecl = get_callee_fndecl (exp);
3353   tree arglist = TREE_OPERAND (exp, 1);
3354   if (validate_arglist (arglist,
3355                         POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3356     {
3357       tree slen = c_strlen (TREE_VALUE (TREE_CHAIN (arglist)), 1);
3358       tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3359       tree result = fold_builtin_strncpy (fndecl, arglist, slen);
3360
3361       if (result)
3362         {
3363           while (TREE_CODE (result) == COMPOUND_EXPR)
3364             {
3365               expand_expr (TREE_OPERAND (result, 0), const0_rtx, VOIDmode,
3366                            EXPAND_NORMAL);
3367               result = TREE_OPERAND (result, 1);
3368             }
3369           return expand_expr (result, target, mode, EXPAND_NORMAL);
3370         }
3371
3372       /* We must be passed a constant len and src parameter.  */
3373       if (!host_integerp (len, 1) || !slen || !host_integerp (slen, 1))
3374         return 0;
3375
3376       slen = size_binop (PLUS_EXPR, slen, ssize_int (1));
3377
3378       /* We're required to pad with trailing zeros if the requested
3379          len is greater than strlen(s2)+1.  In that case try to
3380          use store_by_pieces, if it fails, punt.  */
3381       if (tree_int_cst_lt (slen, len))
3382         {
3383           tree dest = TREE_VALUE (arglist);
3384           unsigned int dest_align
3385             = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
3386           const char *p = c_getstr (TREE_VALUE (TREE_CHAIN (arglist)));
3387           rtx dest_mem;
3388
3389           if (!p || dest_align == 0 || !host_integerp (len, 1)
3390               || !can_store_by_pieces (tree_low_cst (len, 1),
3391                                        builtin_strncpy_read_str,
3392                                        (void *) p, dest_align))
3393             return 0;
3394
3395           dest_mem = get_memory_rtx (dest, len);
3396           store_by_pieces (dest_mem, tree_low_cst (len, 1),
3397                            builtin_strncpy_read_str,
3398                            (void *) p, dest_align, 0);
3399           dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3400           dest_mem = convert_memory_address (ptr_mode, dest_mem);
3401           return dest_mem;
3402         }
3403     }
3404   return 0;
3405 }
3406
3407 /* Callback routine for store_by_pieces.  Read GET_MODE_BITSIZE (MODE)
3408    bytes from constant string DATA + OFFSET and return it as target
3409    constant.  */
3410
3411 static rtx
3412 builtin_memset_read_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
3413                          enum machine_mode mode)
3414 {
3415   const char *c = (const char *) data;
3416   char *p = alloca (GET_MODE_SIZE (mode));
3417
3418   memset (p, *c, GET_MODE_SIZE (mode));
3419
3420   return c_readstr (p, mode);
3421 }
3422
3423 /* Callback routine for store_by_pieces.  Return the RTL of a register
3424    containing GET_MODE_SIZE (MODE) consecutive copies of the unsigned
3425    char value given in the RTL register data.  For example, if mode is
3426    4 bytes wide, return the RTL for 0x01010101*data.  */
3427
3428 static rtx
3429 builtin_memset_gen_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
3430                         enum machine_mode mode)
3431 {
3432   rtx target, coeff;
3433   size_t size;
3434   char *p;
3435
3436   size = GET_MODE_SIZE (mode);
3437   if (size == 1)
3438     return (rtx) data;
3439
3440   p = alloca (size);
3441   memset (p, 1, size);
3442   coeff = c_readstr (p, mode);
3443
3444   target = convert_to_mode (mode, (rtx) data, 1);
3445   target = expand_mult (mode, target, coeff, NULL_RTX, 1);
3446   return force_reg (mode, target);
3447 }
3448
3449 /* Expand expression EXP, which is a call to the memset builtin.  Return 0
3450    if we failed the caller should emit a normal call, otherwise try to get
3451    the result in TARGET, if convenient (and in mode MODE if that's
3452    convenient).  */
3453
3454 static rtx
3455 expand_builtin_memset (tree arglist, rtx target, enum machine_mode mode,
3456                        tree orig_exp)
3457 {
3458   if (!validate_arglist (arglist,
3459                          POINTER_TYPE, INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
3460     return 0;
3461   else
3462     {
3463       tree dest = TREE_VALUE (arglist);
3464       tree val = TREE_VALUE (TREE_CHAIN (arglist));
3465       tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3466       tree fndecl, fn;
3467       enum built_in_function fcode;
3468       char c;
3469       unsigned int dest_align;
3470       rtx dest_mem, dest_addr, len_rtx;
3471
3472       dest_align = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
3473
3474       /* If DEST is not a pointer type, don't do this
3475          operation in-line.  */
3476       if (dest_align == 0)
3477         return 0;
3478
3479       /* If the LEN parameter is zero, return DEST.  */
3480       if (integer_zerop (len))
3481         {
3482           /* Evaluate and ignore VAL in case it has side-effects.  */
3483           expand_expr (val, const0_rtx, VOIDmode, EXPAND_NORMAL);
3484           return expand_expr (dest, target, mode, EXPAND_NORMAL);
3485         }
3486
3487       /* Stabilize the arguments in case we fail.  */
3488       dest = builtin_save_expr (dest);
3489       val = builtin_save_expr (val);
3490       len = builtin_save_expr (len);
3491
3492       len_rtx = expand_normal (len);
3493       dest_mem = get_memory_rtx (dest, len);
3494
3495       if (TREE_CODE (val) != INTEGER_CST)
3496         {
3497           rtx val_rtx;
3498
3499           val_rtx = expand_normal (val);
3500           val_rtx = convert_to_mode (TYPE_MODE (unsigned_char_type_node),
3501                                      val_rtx, 0);
3502
3503           /* Assume that we can memset by pieces if we can store the
3504            * the coefficients by pieces (in the required modes).
3505            * We can't pass builtin_memset_gen_str as that emits RTL.  */
3506           c = 1;
3507           if (host_integerp (len, 1)
3508               && !(optimize_size && tree_low_cst (len, 1) > 1)
3509               && can_store_by_pieces (tree_low_cst (len, 1),
3510                                       builtin_memset_read_str, &c, dest_align))
3511             {
3512               val_rtx = force_reg (TYPE_MODE (unsigned_char_type_node),
3513                                    val_rtx);
3514               store_by_pieces (dest_mem, tree_low_cst (len, 1),
3515                                builtin_memset_gen_str, val_rtx, dest_align, 0);
3516             }
3517           else if (!set_storage_via_setmem (dest_mem, len_rtx, val_rtx,
3518                                             dest_align))
3519             goto do_libcall;
3520
3521           dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3522           dest_mem = convert_memory_address (ptr_mode, dest_mem);
3523           return dest_mem;
3524         }
3525
3526       if (target_char_cast (val, &c))
3527         goto do_libcall;
3528
3529       if (c)
3530         {
3531           if (host_integerp (len, 1)
3532               && !(optimize_size && tree_low_cst (len, 1) > 1)
3533               && can_store_by_pieces (tree_low_cst (len, 1),
3534                                       builtin_memset_read_str, &c, dest_align))
3535             store_by_pieces (dest_mem, tree_low_cst (len, 1),
3536                              builtin_memset_read_str, &c, dest_align, 0);
3537           else if (!set_storage_via_setmem (dest_mem, len_rtx, GEN_INT (c),
3538                                             dest_align))
3539             goto do_libcall;
3540
3541           dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3542           dest_mem = convert_memory_address (ptr_mode, dest_mem);
3543           return dest_mem;
3544         }
3545
3546       set_mem_align (dest_mem, dest_align);
3547       dest_addr = clear_storage (dest_mem, len_rtx,
3548                                  CALL_EXPR_TAILCALL (orig_exp)
3549                                  ? BLOCK_OP_TAILCALL : BLOCK_OP_NORMAL);
3550
3551       if (dest_addr == 0)
3552         {
3553           dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3554           dest_addr = convert_memory_address (ptr_mode, dest_addr);
3555         }
3556
3557       return dest_addr;
3558
3559     do_libcall:
3560       fndecl = get_callee_fndecl (orig_exp);
3561       fcode = DECL_FUNCTION_CODE (fndecl);
3562       gcc_assert (fcode == BUILT_IN_MEMSET || fcode == BUILT_IN_BZERO);
3563       arglist = build_tree_list (NULL_TREE, len);
3564       if (fcode == BUILT_IN_MEMSET)
3565         arglist = tree_cons (NULL_TREE, val, arglist);
3566       arglist = tree_cons (NULL_TREE, dest, arglist);
3567       fn = build_function_call_expr (fndecl, arglist);
3568       if (TREE_CODE (fn) == CALL_EXPR)
3569         CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (orig_exp);
3570       return expand_call (fn, target, target == const0_rtx);
3571     }
3572 }
3573
3574 /* Expand expression EXP, which is a call to the bzero builtin.  Return 0
3575    if we failed the caller should emit a normal call.  */
3576
3577 static rtx
3578 expand_builtin_bzero (tree exp)
3579 {
3580   tree arglist = TREE_OPERAND (exp, 1);
3581   tree dest, size, newarglist;
3582
3583   if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3584     return NULL_RTX;
3585
3586   dest = TREE_VALUE (arglist);
3587   size = TREE_VALUE (TREE_CHAIN (arglist));
3588
3589   /* New argument list transforming bzero(ptr x, int y) to
3590      memset(ptr x, int 0, size_t y).   This is done this way
3591      so that if it isn't expanded inline, we fallback to
3592      calling bzero instead of memset.  */
3593
3594   newarglist = build_tree_list (NULL_TREE, fold_convert (sizetype, size));
3595   newarglist = tree_cons (NULL_TREE, integer_zero_node, newarglist);
3596   newarglist = tree_cons (NULL_TREE, dest, newarglist);
3597
3598   return expand_builtin_memset (newarglist, const0_rtx, VOIDmode, exp);
3599 }
3600
3601 /* Expand expression EXP, which is a call to the memcmp built-in function.
3602    ARGLIST is the argument list for this call.  Return 0 if we failed and the
3603    caller should emit a normal call, otherwise try to get the result in
3604    TARGET, if convenient (and in mode MODE, if that's convenient).  */
3605
3606 static rtx
3607 expand_builtin_memcmp (tree exp ATTRIBUTE_UNUSED, tree arglist, rtx target,
3608                        enum machine_mode mode)
3609 {
3610   if (!validate_arglist (arglist,
3611                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3612     return 0;
3613   else
3614     {
3615       tree result = fold_builtin_memcmp (arglist);
3616       if (result)
3617         return expand_expr (result, target, mode, EXPAND_NORMAL);
3618     }
3619
3620 #if defined HAVE_cmpmemsi || defined HAVE_cmpstrnsi
3621   {
3622     tree arg1 = TREE_VALUE (arglist);
3623     tree arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3624     tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3625     rtx arg1_rtx, arg2_rtx, arg3_rtx;
3626     rtx result;
3627     rtx insn;
3628
3629     int arg1_align
3630       = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3631     int arg2_align
3632       = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3633     enum machine_mode insn_mode;
3634
3635 #ifdef HAVE_cmpmemsi
3636     if (HAVE_cmpmemsi)
3637       insn_mode = insn_data[(int) CODE_FOR_cmpmemsi].operand[0].mode;
3638     else
3639 #endif
3640 #ifdef HAVE_cmpstrnsi
3641     if (HAVE_cmpstrnsi)
3642       insn_mode = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode;
3643     else
3644 #endif
3645       return 0;
3646
3647     /* If we don't have POINTER_TYPE, call the function.  */
3648     if (arg1_align == 0 || arg2_align == 0)
3649       return 0;
3650
3651     /* Make a place to write the result of the instruction.  */
3652     result = target;
3653     if (! (result != 0
3654            && REG_P (result) && GET_MODE (result) == insn_mode
3655            && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3656       result = gen_reg_rtx (insn_mode);
3657
3658     arg1_rtx = get_memory_rtx (arg1, len);
3659     arg2_rtx = get_memory_rtx (arg2, len);
3660     arg3_rtx = expand_normal (len);
3661
3662     /* Set MEM_SIZE as appropriate.  */
3663     if (GET_CODE (arg3_rtx) == CONST_INT)
3664       {
3665         set_mem_size (arg1_rtx, arg3_rtx);
3666         set_mem_size (arg2_rtx, arg3_rtx);
3667       }
3668
3669 #ifdef HAVE_cmpmemsi
3670     if (HAVE_cmpmemsi)
3671       insn = gen_cmpmemsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3672                            GEN_INT (MIN (arg1_align, arg2_align)));
3673     else
3674 #endif
3675 #ifdef HAVE_cmpstrnsi
3676     if (HAVE_cmpstrnsi)
3677       insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3678                             GEN_INT (MIN (arg1_align, arg2_align)));
3679     else
3680 #endif
3681       gcc_unreachable ();
3682
3683     if (insn)
3684       emit_insn (insn);
3685     else
3686       emit_library_call_value (memcmp_libfunc, result, LCT_PURE_MAKE_BLOCK,
3687                                TYPE_MODE (integer_type_node), 3,
3688                                XEXP (arg1_rtx, 0), Pmode,
3689                                XEXP (arg2_rtx, 0), Pmode,
3690                                convert_to_mode (TYPE_MODE (sizetype), arg3_rtx,
3691                                                 TYPE_UNSIGNED (sizetype)),
3692                                TYPE_MODE (sizetype));
3693
3694     /* Return the value in the proper mode for this function.  */
3695     mode = TYPE_MODE (TREE_TYPE (exp));
3696     if (GET_MODE (result) == mode)
3697       return result;
3698     else if (target != 0)
3699       {
3700         convert_move (target, result, 0);
3701         return target;
3702       }
3703     else
3704       return convert_to_mode (mode, result, 0);
3705   }
3706 #endif
3707
3708   return 0;
3709 }
3710
3711 /* Expand expression EXP, which is a call to the strcmp builtin.  Return 0
3712    if we failed the caller should emit a normal call, otherwise try to get
3713    the result in TARGET, if convenient.  */
3714
3715 static rtx
3716 expand_builtin_strcmp (tree exp, rtx target, enum machine_mode mode)
3717 {
3718   tree arglist = TREE_OPERAND (exp, 1);
3719
3720   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3721     return 0;
3722   else
3723     {
3724       tree result = fold_builtin_strcmp (arglist);
3725       if (result)
3726         return expand_expr (result, target, mode, EXPAND_NORMAL);
3727     }
3728
3729 #if defined HAVE_cmpstrsi || defined HAVE_cmpstrnsi
3730   if (cmpstr_optab[SImode] != CODE_FOR_nothing
3731       || cmpstrn_optab[SImode] != CODE_FOR_nothing)
3732     {
3733       rtx arg1_rtx, arg2_rtx;
3734       rtx result, insn = NULL_RTX;
3735       tree fndecl, fn;
3736
3737       tree arg1 = TREE_VALUE (arglist);
3738       tree arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3739       int arg1_align
3740         = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3741       int arg2_align
3742         = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3743
3744       /* If we don't have POINTER_TYPE, call the function.  */
3745       if (arg1_align == 0 || arg2_align == 0)
3746         return 0;
3747
3748       /* Stabilize the arguments in case gen_cmpstr(n)si fail.  */
3749       arg1 = builtin_save_expr (arg1);
3750       arg2 = builtin_save_expr (arg2);
3751
3752       arg1_rtx = get_memory_rtx (arg1, NULL);
3753       arg2_rtx = get_memory_rtx (arg2, NULL);
3754
3755 #ifdef HAVE_cmpstrsi
3756       /* Try to call cmpstrsi.  */
3757       if (HAVE_cmpstrsi)
3758         {
3759           enum machine_mode insn_mode
3760             = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
3761
3762           /* Make a place to write the result of the instruction.  */
3763           result = target;
3764           if (! (result != 0
3765                  && REG_P (result) && GET_MODE (result) == insn_mode
3766                  && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3767             result = gen_reg_rtx (insn_mode);
3768
3769           insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx,
3770                                GEN_INT (MIN (arg1_align, arg2_align)));
3771         }
3772 #endif
3773 #ifdef HAVE_cmpstrnsi
3774       /* Try to determine at least one length and call cmpstrnsi.  */
3775       if (!insn && HAVE_cmpstrnsi)
3776         {
3777           tree len;
3778           rtx arg3_rtx;
3779
3780           enum machine_mode insn_mode
3781             = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode;
3782           tree len1 = c_strlen (arg1, 1);
3783           tree len2 = c_strlen (arg2, 1);
3784
3785           if (len1)
3786             len1 = size_binop (PLUS_EXPR, ssize_int (1), len1);
3787           if (len2)
3788             len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
3789
3790           /* If we don't have a constant length for the first, use the length
3791              of the second, if we know it.  We don't require a constant for
3792              this case; some cost analysis could be done if both are available
3793              but neither is constant.  For now, assume they're equally cheap,
3794              unless one has side effects.  If both strings have constant lengths,
3795              use the smaller.  */
3796
3797           if (!len1)
3798             len = len2;
3799           else if (!len2)
3800             len = len1;
3801           else if (TREE_SIDE_EFFECTS (len1))
3802             len = len2;
3803           else if (TREE_SIDE_EFFECTS (len2))
3804             len = len1;
3805           else if (TREE_CODE (len1) != INTEGER_CST)
3806             len = len2;
3807           else if (TREE_CODE (len2) != INTEGER_CST)
3808             len = len1;
3809           else if (tree_int_cst_lt (len1, len2))
3810             len = len1;
3811           else
3812             len = len2;
3813
3814           /* If both arguments have side effects, we cannot optimize.  */
3815           if (!len || TREE_SIDE_EFFECTS (len))
3816             goto do_libcall;
3817
3818           arg3_rtx = expand_normal (len);
3819
3820           /* Make a place to write the result of the instruction.  */
3821           result = target;
3822           if (! (result != 0
3823                  && REG_P (result) && GET_MODE (result) == insn_mode
3824                  && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3825             result = gen_reg_rtx (insn_mode);
3826
3827           insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3828                                 GEN_INT (MIN (arg1_align, arg2_align)));
3829         }
3830 #endif
3831
3832       if (insn)
3833         {
3834           emit_insn (insn);
3835
3836           /* Return the value in the proper mode for this function.  */
3837           mode = TYPE_MODE (TREE_TYPE (exp));
3838           if (GET_MODE (result) == mode)
3839             return result;
3840           if (target == 0)
3841             return convert_to_mode (mode, result, 0);
3842           convert_move (target, result, 0);
3843           return target;
3844         }
3845
3846       /* Expand the library call ourselves using a stabilized argument
3847          list to avoid re-evaluating the function's arguments twice.  */
3848 #ifdef HAVE_cmpstrnsi
3849     do_libcall:
3850 #endif
3851       arglist = build_tree_list (NULL_TREE, arg2);
3852       arglist = tree_cons (NULL_TREE, arg1, arglist);
3853       fndecl = get_callee_fndecl (exp);
3854       fn = build_function_call_expr (fndecl, arglist);
3855       if (TREE_CODE (fn) == CALL_EXPR)
3856         CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
3857       return expand_call (fn, target, target == const0_rtx);
3858     }
3859 #endif
3860   return 0;
3861 }
3862
3863 /* Expand expression EXP, which is a call to the strncmp builtin.  Return 0
3864    if we failed the caller should emit a normal call, otherwise try to get
3865    the result in TARGET, if convenient.  */
3866
3867 static rtx
3868 expand_builtin_strncmp (tree exp, rtx target, enum machine_mode mode)
3869 {
3870   tree arglist = TREE_OPERAND (exp, 1);
3871
3872   if (!validate_arglist (arglist,
3873                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3874     return 0;
3875   else
3876     {
3877       tree result = fold_builtin_strncmp (arglist);
3878       if (result)
3879         return expand_expr (result, target, mode, EXPAND_NORMAL);
3880     }
3881
3882   /* If c_strlen can determine an expression for one of the string
3883      lengths, and it doesn't have side effects, then emit cmpstrnsi
3884      using length MIN(strlen(string)+1, arg3).  */
3885 #ifdef HAVE_cmpstrnsi
3886   if (HAVE_cmpstrnsi)
3887   {
3888     tree arg1 = TREE_VALUE (arglist);
3889     tree arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3890     tree arg3 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3891     tree len, len1, len2;
3892     rtx arg1_rtx, arg2_rtx, arg3_rtx;
3893     rtx result, insn;
3894     tree fndecl, fn;
3895
3896     int arg1_align
3897       = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3898     int arg2_align
3899       = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3900     enum machine_mode insn_mode
3901       = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode;
3902
3903     len1 = c_strlen (arg1, 1);
3904     len2 = c_strlen (arg2, 1);
3905
3906     if (len1)
3907       len1 = size_binop (PLUS_EXPR, ssize_int (1), len1);
3908     if (len2)
3909       len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
3910
3911     /* If we don't have a constant length for the first, use the length
3912        of the second, if we know it.  We don't require a constant for
3913        this case; some cost analysis could be done if both are available
3914        but neither is constant.  For now, assume they're equally cheap,
3915        unless one has side effects.  If both strings have constant lengths,
3916        use the smaller.  */
3917
3918     if (!len1)
3919       len = len2;
3920     else if (!len2)
3921       len = len1;
3922     else if (TREE_SIDE_EFFECTS (len1))
3923       len = len2;
3924     else if (TREE_SIDE_EFFECTS (len2))
3925       len = len1;
3926     else if (TREE_CODE (len1) != INTEGER_CST)
3927       len = len2;
3928     else if (TREE_CODE (len2) != INTEGER_CST)
3929       len = len1;
3930     else if (tree_int_cst_lt (len1, len2))
3931       len = len1;
3932     else
3933       len = len2;
3934
3935     /* If both arguments have side effects, we cannot optimize.  */
3936     if (!len || TREE_SIDE_EFFECTS (len))
3937       return 0;
3938
3939     /* The actual new length parameter is MIN(len,arg3).  */
3940     len = fold_build2 (MIN_EXPR, TREE_TYPE (len), len,
3941                        fold_convert (TREE_TYPE (len), arg3));
3942
3943     /* If we don't have POINTER_TYPE, call the function.  */
3944     if (arg1_align == 0 || arg2_align == 0)
3945       return 0;
3946
3947     /* Make a place to write the result of the instruction.  */
3948     result = target;
3949     if (! (result != 0
3950            && REG_P (result) && GET_MODE (result) == insn_mode
3951            && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3952       result = gen_reg_rtx (insn_mode);
3953
3954     /* Stabilize the arguments in case gen_cmpstrnsi fails.  */
3955     arg1 = builtin_save_expr (arg1);
3956     arg2 = builtin_save_expr (arg2);
3957     len = builtin_save_expr (len);
3958
3959     arg1_rtx = get_memory_rtx (arg1, len);
3960     arg2_rtx = get_memory_rtx (arg2, len);
3961     arg3_rtx = expand_normal (len);
3962     insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3963                           GEN_INT (MIN (arg1_align, arg2_align)));
3964     if (insn)
3965       {
3966         emit_insn (insn);
3967
3968         /* Return the value in the proper mode for this function.  */
3969         mode = TYPE_MODE (TREE_TYPE (exp));
3970         if (GET_MODE (result) == mode)
3971           return result;
3972         if (target == 0)
3973           return convert_to_mode (mode, result, 0);
3974         convert_move (target, result, 0);
3975         return target;
3976       }
3977
3978     /* Expand the library call ourselves using a stabilized argument
3979        list to avoid re-evaluating the function's arguments twice.  */
3980     arglist = build_tree_list (NULL_TREE, len);
3981     arglist = tree_cons (NULL_TREE, arg2, arglist);
3982     arglist = tree_cons (NULL_TREE, arg1, arglist);
3983     fndecl = get_callee_fndecl (exp);
3984     fn = build_function_call_expr (fndecl, arglist);
3985     if (TREE_CODE (fn) == CALL_EXPR)
3986       CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
3987     return expand_call (fn, target, target == const0_rtx);
3988   }
3989 #endif
3990   return 0;
3991 }
3992
3993 /* Expand expression EXP, which is a call to the strcat builtin.
3994    Return 0 if we failed the caller should emit a normal call,
3995    otherwise try to get the result in TARGET, if convenient.  */
3996
3997 static rtx
3998 expand_builtin_strcat (tree fndecl, tree arglist, rtx target, enum machine_mode mode)
3999 {
4000   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4001     return 0;
4002   else
4003     {
4004       tree dst = TREE_VALUE (arglist),
4005       src = TREE_VALUE (TREE_CHAIN (arglist));
4006       const char *p = c_getstr (src);
4007
4008       /* If the string length is zero, return the dst parameter.  */
4009       if (p && *p == '\0')
4010         return expand_expr (dst, target, mode, EXPAND_NORMAL);
4011
4012       if (!optimize_size)
4013         {
4014           /* See if we can store by pieces into (dst + strlen(dst)).  */
4015           tree newsrc, newdst,
4016             strlen_fn = implicit_built_in_decls[BUILT_IN_STRLEN];
4017           rtx insns;
4018
4019           /* Stabilize the argument list.  */
4020           newsrc = builtin_save_expr (src);
4021           if (newsrc != src)
4022             arglist = build_tree_list (NULL_TREE, newsrc);
4023           else
4024             arglist = TREE_CHAIN (arglist); /* Reusing arglist if safe.  */
4025
4026           dst = builtin_save_expr (dst);
4027
4028           start_sequence ();
4029
4030           /* Create strlen (dst).  */
4031           newdst =
4032             build_function_call_expr (strlen_fn,
4033                                       build_tree_list (NULL_TREE, dst));
4034           /* Create (dst + (cast) strlen (dst)).  */
4035           newdst = fold_convert (TREE_TYPE (dst), newdst);
4036           newdst = fold_build2 (PLUS_EXPR, TREE_TYPE (dst), dst, newdst);
4037
4038           newdst = builtin_save_expr (newdst);
4039           arglist = tree_cons (NULL_TREE, newdst, arglist);
4040
4041           if (!expand_builtin_strcpy (fndecl, arglist, target, mode))
4042             {
4043               end_sequence (); /* Stop sequence.  */
4044               return 0;
4045             }
4046
4047           /* Output the entire sequence.  */
4048           insns = get_insns ();
4049           end_sequence ();
4050           emit_insn (insns);
4051
4052           return expand_expr (dst, target, mode, EXPAND_NORMAL);
4053         }
4054
4055       return 0;
4056     }
4057 }
4058
4059 /* Expand expression EXP, which is a call to the strncat builtin.
4060    Return 0 if we failed the caller should emit a normal call,
4061    otherwise try to get the result in TARGET, if convenient.  */
4062
4063 static rtx
4064 expand_builtin_strncat (tree arglist, rtx target, enum machine_mode mode)
4065 {
4066   if (validate_arglist (arglist,
4067                         POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
4068     {
4069       tree result = fold_builtin_strncat (arglist);
4070       if (result)
4071         return expand_expr (result, target, mode, EXPAND_NORMAL);
4072     }
4073   return 0;
4074 }
4075
4076 /* Expand expression EXP, which is a call to the strspn builtin.
4077    Return 0 if we failed the caller should emit a normal call,
4078    otherwise try to get the result in TARGET, if convenient.  */
4079
4080 static rtx
4081 expand_builtin_strspn (tree arglist, rtx target, enum machine_mode mode)
4082 {
4083   if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4084     {
4085       tree result = fold_builtin_strspn (arglist);
4086       if (result)
4087         return expand_expr (result, target, mode, EXPAND_NORMAL);
4088     }
4089   return 0;
4090 }
4091
4092 /* Expand expression EXP, which is a call to the strcspn builtin.
4093    Return 0 if we failed the caller should emit a normal call,
4094    otherwise try to get the result in TARGET, if convenient.  */
4095
4096 static rtx
4097 expand_builtin_strcspn (tree arglist, rtx target, enum machine_mode mode)
4098 {
4099   if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4100     {
4101       tree result = fold_builtin_strcspn (arglist);
4102       if (result)
4103         return expand_expr (result, target, mode, EXPAND_NORMAL);
4104     }
4105   return 0;
4106 }
4107
4108 /* Expand a call to __builtin_saveregs, generating the result in TARGET,
4109    if that's convenient.  */
4110
4111 rtx
4112 expand_builtin_saveregs (void)
4113 {
4114   rtx val, seq;
4115
4116   /* Don't do __builtin_saveregs more than once in a function.
4117      Save the result of the first call and reuse it.  */
4118   if (saveregs_value != 0)
4119     return saveregs_value;
4120
4121   /* When this function is called, it means that registers must be
4122      saved on entry to this function.  So we migrate the call to the
4123      first insn of this function.  */
4124
4125   start_sequence ();
4126
4127   /* Do whatever the machine needs done in this case.  */
4128   val = targetm.calls.expand_builtin_saveregs ();
4129
4130   seq = get_insns ();
4131   end_sequence ();
4132
4133   saveregs_value = val;
4134
4135   /* Put the insns after the NOTE that starts the function.  If this
4136      is inside a start_sequence, make the outer-level insn chain current, so
4137      the code is placed at the start of the function.  */
4138   push_topmost_sequence ();
4139   emit_insn_after (seq, entry_of_function ());
4140   pop_topmost_sequence ();
4141
4142   return val;
4143 }
4144
4145 /* __builtin_args_info (N) returns word N of the arg space info
4146    for the current function.  The number and meanings of words
4147    is controlled by the definition of CUMULATIVE_ARGS.  */
4148
4149 static rtx
4150 expand_builtin_args_info (tree arglist)
4151 {
4152   int nwords = sizeof (CUMULATIVE_ARGS) / sizeof (int);
4153   int *word_ptr = (int *) &current_function_args_info;
4154
4155   gcc_assert (sizeof (CUMULATIVE_ARGS) % sizeof (int) == 0);
4156
4157   if (arglist != 0)
4158     {
4159       if (!host_integerp (TREE_VALUE (arglist), 0))
4160         error ("argument of %<__builtin_args_info%> must be constant");
4161       else
4162         {
4163           HOST_WIDE_INT wordnum = tree_low_cst (TREE_VALUE (arglist), 0);
4164
4165           if (wordnum < 0 || wordnum >= nwords)
4166             error ("argument of %<__builtin_args_info%> out of range");
4167           else
4168             return GEN_INT (word_ptr[wordnum]);
4169         }