OSDN Git Service

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