OSDN Git Service

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