OSDN Git Service

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