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