OSDN Git Service

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