OSDN Git Service

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