OSDN Git Service

gcc:
[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) STRINGX(X),
68 const char *const built_in_names[(int) END_BUILTINS] =
69 {
70 #include "builtins.def"
71 };
72 #undef DEF_BUILTIN
73
74 /* Setup an array of _DECL trees, make sure each element is
75    initialized to NULL_TREE.  */
76 tree built_in_decls[(int) END_BUILTINS];
77 /* Declarations used when constructing the builtin implicitly in the compiler.
78    It may be NULL_TREE when this is invalid (for instance runtime is not
79    required to implement the function call in all cases.  */
80 tree implicit_built_in_decls[(int) END_BUILTINS];
81
82 static int get_pointer_alignment        PARAMS ((tree, unsigned int));
83 static tree c_strlen                    PARAMS ((tree));
84 static const char *c_getstr             PARAMS ((tree));
85 static rtx c_readstr                    PARAMS ((const char *,
86                                                  enum machine_mode));
87 static int target_char_cast             PARAMS ((tree, char *));
88 static rtx get_memory_rtx               PARAMS ((tree));
89 static int apply_args_size              PARAMS ((void));
90 static int apply_result_size            PARAMS ((void));
91 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
92 static rtx result_vector                PARAMS ((int, rtx));
93 #endif
94 static rtx expand_builtin_setjmp        PARAMS ((tree, rtx));
95 static void expand_builtin_prefetch     PARAMS ((tree));
96 static rtx expand_builtin_apply_args    PARAMS ((void));
97 static rtx expand_builtin_apply_args_1  PARAMS ((void));
98 static rtx expand_builtin_apply         PARAMS ((rtx, rtx, rtx));
99 static void expand_builtin_return       PARAMS ((rtx));
100 static enum type_class type_to_class    PARAMS ((tree));
101 static rtx expand_builtin_classify_type PARAMS ((tree));
102 static void expand_errno_check          PARAMS ((tree, rtx));
103 static rtx expand_builtin_mathfn        PARAMS ((tree, rtx, rtx));
104 static rtx expand_builtin_mathfn_2      PARAMS ((tree, rtx, rtx));
105 static rtx expand_builtin_constant_p    PARAMS ((tree));
106 static rtx expand_builtin_args_info     PARAMS ((tree));
107 static rtx expand_builtin_next_arg      PARAMS ((tree));
108 static rtx expand_builtin_va_start      PARAMS ((tree));
109 static rtx expand_builtin_va_end        PARAMS ((tree));
110 static rtx expand_builtin_va_copy       PARAMS ((tree));
111 static rtx expand_builtin_memcmp        PARAMS ((tree, tree, rtx,
112                                                  enum machine_mode));
113 static rtx expand_builtin_strcmp        PARAMS ((tree, rtx,
114                                                  enum machine_mode));
115 static rtx expand_builtin_strncmp       PARAMS ((tree, rtx,
116                                                  enum machine_mode));
117 static rtx builtin_memcpy_read_str      PARAMS ((PTR, HOST_WIDE_INT,
118                                                  enum machine_mode));
119 static rtx expand_builtin_strcat        PARAMS ((tree, rtx,
120                                                  enum machine_mode));
121 static rtx expand_builtin_strncat       PARAMS ((tree, rtx,
122                                                  enum machine_mode));
123 static rtx expand_builtin_strspn        PARAMS ((tree, rtx,
124                                                  enum machine_mode));
125 static rtx expand_builtin_strcspn       PARAMS ((tree, rtx,
126                                                  enum machine_mode));
127 static rtx expand_builtin_memcpy        PARAMS ((tree, rtx,
128                                                  enum machine_mode));
129 static rtx expand_builtin_strcpy        PARAMS ((tree, rtx,
130                                                  enum machine_mode));
131 static rtx builtin_strncpy_read_str     PARAMS ((PTR, HOST_WIDE_INT,
132                                                  enum machine_mode));
133 static rtx expand_builtin_strncpy       PARAMS ((tree, rtx,
134                                                  enum machine_mode));
135 static rtx builtin_memset_read_str      PARAMS ((PTR, HOST_WIDE_INT,
136                                                  enum machine_mode));
137 static rtx builtin_memset_gen_str       PARAMS ((PTR, HOST_WIDE_INT,
138                                                  enum machine_mode));
139 static rtx expand_builtin_memset        PARAMS ((tree, rtx,
140                                                  enum machine_mode));
141 static rtx expand_builtin_bzero         PARAMS ((tree));
142 static rtx expand_builtin_strlen        PARAMS ((tree, rtx));
143 static rtx expand_builtin_strstr        PARAMS ((tree, rtx,
144                                                  enum machine_mode));
145 static rtx expand_builtin_strpbrk       PARAMS ((tree, rtx,
146                                                  enum machine_mode));
147 static rtx expand_builtin_strchr        PARAMS ((tree, rtx,
148                                                  enum machine_mode));
149 static rtx expand_builtin_strrchr       PARAMS ((tree, rtx,
150                                                  enum machine_mode));
151 static rtx expand_builtin_alloca        PARAMS ((tree, rtx));
152 static rtx expand_builtin_unop          PARAMS ((enum machine_mode,
153                                                  tree, rtx, rtx, optab));
154 static rtx expand_builtin_frame_address PARAMS ((tree));
155 static rtx expand_builtin_fputs         PARAMS ((tree, int, int));
156 static tree stabilize_va_list           PARAMS ((tree, int));
157 static rtx expand_builtin_expect        PARAMS ((tree, rtx));
158 static tree fold_builtin_constant_p     PARAMS ((tree));
159 static tree fold_builtin_classify_type  PARAMS ((tree));
160 static tree fold_builtin_inf            PARAMS ((tree, int));
161 static tree fold_builtin_nan            PARAMS ((tree, tree, int));
162 static int validate_arglist             PARAMS ((tree, ...));
163 static tree fold_trunc_transparent_mathfn PARAMS ((tree));
164
165 /* Return the alignment in bits of EXP, a pointer valued expression.
166    But don't return more than MAX_ALIGN no matter what.
167    The alignment returned is, by default, the alignment of the thing that
168    EXP points to.  If it is not a POINTER_TYPE, 0 is returned.
169
170    Otherwise, look at the expression to see if we can do better, i.e., if the
171    expression is actually pointing at an object whose alignment is tighter.  */
172
173 static int
174 get_pointer_alignment (exp, max_align)
175      tree exp;
176      unsigned int max_align;
177 {
178   unsigned int align, inner;
179
180   if (TREE_CODE (TREE_TYPE (exp)) != POINTER_TYPE)
181     return 0;
182
183   align = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
184   align = MIN (align, max_align);
185
186   while (1)
187     {
188       switch (TREE_CODE (exp))
189         {
190         case NOP_EXPR:
191         case CONVERT_EXPR:
192         case NON_LVALUE_EXPR:
193           exp = TREE_OPERAND (exp, 0);
194           if (TREE_CODE (TREE_TYPE (exp)) != POINTER_TYPE)
195             return align;
196
197           inner = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
198           align = MIN (inner, max_align);
199           break;
200
201         case PLUS_EXPR:
202           /* If sum of pointer + int, restrict our maximum alignment to that
203              imposed by the integer.  If not, we can't do any better than
204              ALIGN.  */
205           if (! host_integerp (TREE_OPERAND (exp, 1), 1))
206             return align;
207
208           while (((tree_low_cst (TREE_OPERAND (exp, 1), 1))
209                   & (max_align / BITS_PER_UNIT - 1))
210                  != 0)
211             max_align >>= 1;
212
213           exp = TREE_OPERAND (exp, 0);
214           break;
215
216         case ADDR_EXPR:
217           /* See what we are pointing at and look at its alignment.  */
218           exp = TREE_OPERAND (exp, 0);
219           if (TREE_CODE (exp) == FUNCTION_DECL)
220             align = FUNCTION_BOUNDARY;
221           else if (DECL_P (exp))
222             align = DECL_ALIGN (exp);
223 #ifdef CONSTANT_ALIGNMENT
224           else if (TREE_CODE_CLASS (TREE_CODE (exp)) == 'c')
225             align = CONSTANT_ALIGNMENT (exp, align);
226 #endif
227           return MIN (align, max_align);
228
229         default:
230           return align;
231         }
232     }
233 }
234
235 /* Compute the length of a C string.  TREE_STRING_LENGTH is not the right
236    way, because it could contain a zero byte in the middle.
237    TREE_STRING_LENGTH is the size of the character array, not the string.
238
239    The value returned is of type `ssizetype'.
240
241    Unfortunately, string_constant can't access the values of const char
242    arrays with initializers, so neither can we do so here.  */
243
244 static tree
245 c_strlen (src)
246      tree src;
247 {
248   tree offset_node;
249   HOST_WIDE_INT offset;
250   int max;
251   const char *ptr;
252
253   src = string_constant (src, &offset_node);
254   if (src == 0)
255     return 0;
256
257   max = TREE_STRING_LENGTH (src) - 1;
258   ptr = TREE_STRING_POINTER (src);
259
260   if (offset_node && TREE_CODE (offset_node) != INTEGER_CST)
261     {
262       /* If the string has an internal zero byte (e.g., "foo\0bar"), we can't
263          compute the offset to the following null if we don't know where to
264          start searching for it.  */
265       int i;
266
267       for (i = 0; i < max; i++)
268         if (ptr[i] == 0)
269           return 0;
270
271       /* We don't know the starting offset, but we do know that the string
272          has no internal zero bytes.  We can assume that the offset falls
273          within the bounds of the string; otherwise, the programmer deserves
274          what he gets.  Subtract the offset from the length of the string,
275          and return that.  This would perhaps not be valid if we were dealing
276          with named arrays in addition to literal string constants.  */
277
278       return size_diffop (size_int (max), offset_node);
279     }
280
281   /* We have a known offset into the string.  Start searching there for
282      a null character if we can represent it as a single HOST_WIDE_INT.  */
283   if (offset_node == 0)
284     offset = 0;
285   else if (! host_integerp (offset_node, 0))
286     offset = -1;
287   else
288     offset = tree_low_cst (offset_node, 0);
289
290   /* If the offset is known to be out of bounds, warn, and call strlen at
291      runtime.  */
292   if (offset < 0 || offset > max)
293     {
294       warning ("offset outside bounds of constant string");
295       return 0;
296     }
297
298   /* Use strlen to search for the first zero byte.  Since any strings
299      constructed with build_string will have nulls appended, we win even
300      if we get handed something like (char[4])"abcd".
301
302      Since OFFSET is our starting index into the string, no further
303      calculation is needed.  */
304   return ssize_int (strlen (ptr + offset));
305 }
306
307 /* Return a char pointer for a C string if it is a string constant
308    or sum of string constant and integer constant.  */
309
310 static const char *
311 c_getstr (src)
312      tree src;
313 {
314   tree offset_node;
315
316   src = string_constant (src, &offset_node);
317   if (src == 0)
318     return 0;
319
320   if (offset_node == 0)
321     return TREE_STRING_POINTER (src);
322   else if (!host_integerp (offset_node, 1)
323            || compare_tree_int (offset_node, TREE_STRING_LENGTH (src) - 1) > 0)
324     return 0;
325
326   return TREE_STRING_POINTER (src) + tree_low_cst (offset_node, 1);
327 }
328
329 /* Return a CONST_INT or CONST_DOUBLE corresponding to target reading
330    GET_MODE_BITSIZE (MODE) bits from string constant STR.  */
331
332 static rtx
333 c_readstr (str, mode)
334      const char *str;
335      enum machine_mode mode;
336 {
337   HOST_WIDE_INT c[2];
338   HOST_WIDE_INT ch;
339   unsigned int i, j;
340
341   if (GET_MODE_CLASS (mode) != MODE_INT)
342     abort ();
343   c[0] = 0;
344   c[1] = 0;
345   ch = 1;
346   for (i = 0; i < GET_MODE_SIZE (mode); i++)
347     {
348       j = i;
349       if (WORDS_BIG_ENDIAN)
350         j = GET_MODE_SIZE (mode) - i - 1;
351       if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN
352           && GET_MODE_SIZE (mode) > UNITS_PER_WORD)
353         j = j + UNITS_PER_WORD - 2 * (j % UNITS_PER_WORD) - 1;
354       j *= BITS_PER_UNIT;
355       if (j > 2 * HOST_BITS_PER_WIDE_INT)
356         abort ();
357       if (ch)
358         ch = (unsigned char) str[i];
359       c[j / HOST_BITS_PER_WIDE_INT] |= ch << (j % HOST_BITS_PER_WIDE_INT);
360     }
361   return immed_double_const (c[0], c[1], mode);
362 }
363
364 /* Cast a target constant CST to target CHAR and if that value fits into
365    host char type, return zero and put that value into variable pointed by
366    P.  */
367
368 static int
369 target_char_cast (cst, p)
370      tree cst;
371      char *p;
372 {
373   unsigned HOST_WIDE_INT val, hostval;
374
375   if (!host_integerp (cst, 1)
376       || CHAR_TYPE_SIZE > HOST_BITS_PER_WIDE_INT)
377     return 1;
378
379   val = tree_low_cst (cst, 1);
380   if (CHAR_TYPE_SIZE < HOST_BITS_PER_WIDE_INT)
381     val &= (((unsigned HOST_WIDE_INT) 1) << CHAR_TYPE_SIZE) - 1;
382
383   hostval = val;
384   if (HOST_BITS_PER_CHAR < HOST_BITS_PER_WIDE_INT)
385     hostval &= (((unsigned HOST_WIDE_INT) 1) << HOST_BITS_PER_CHAR) - 1;
386
387   if (val != hostval)
388     return 1;
389
390   *p = hostval;
391   return 0;
392 }
393
394 /* Given TEM, a pointer to a stack frame, follow the dynamic chain COUNT
395    times to get the address of either a higher stack frame, or a return
396    address located within it (depending on FNDECL_CODE).  */
397
398 rtx
399 expand_builtin_return_addr (fndecl_code, count, tem)
400      enum built_in_function fndecl_code;
401      int count;
402      rtx tem;
403 {
404   int i;
405
406   /* Some machines need special handling before we can access
407      arbitrary frames.  For example, on the sparc, we must first flush
408      all register windows to the stack.  */
409 #ifdef SETUP_FRAME_ADDRESSES
410   if (count > 0)
411     SETUP_FRAME_ADDRESSES ();
412 #endif
413
414   /* On the sparc, the return address is not in the frame, it is in a
415      register.  There is no way to access it off of the current frame
416      pointer, but it can be accessed off the previous frame pointer by
417      reading the value from the register window save area.  */
418 #ifdef RETURN_ADDR_IN_PREVIOUS_FRAME
419   if (fndecl_code == BUILT_IN_RETURN_ADDRESS)
420     count--;
421 #endif
422
423   /* Scan back COUNT frames to the specified frame.  */
424   for (i = 0; i < count; i++)
425     {
426       /* Assume the dynamic chain pointer is in the word that the
427          frame address points to, unless otherwise specified.  */
428 #ifdef DYNAMIC_CHAIN_ADDRESS
429       tem = DYNAMIC_CHAIN_ADDRESS (tem);
430 #endif
431       tem = memory_address (Pmode, tem);
432       tem = gen_rtx_MEM (Pmode, tem);
433       set_mem_alias_set (tem, get_frame_alias_set ());
434       tem = copy_to_reg (tem);
435     }
436
437   /* For __builtin_frame_address, return what we've got.  */
438   if (fndecl_code == BUILT_IN_FRAME_ADDRESS)
439     return tem;
440
441   /* For __builtin_return_address, Get the return address from that
442      frame.  */
443 #ifdef RETURN_ADDR_RTX
444   tem = RETURN_ADDR_RTX (count, tem);
445 #else
446   tem = memory_address (Pmode,
447                         plus_constant (tem, GET_MODE_SIZE (Pmode)));
448   tem = gen_rtx_MEM (Pmode, tem);
449   set_mem_alias_set (tem, get_frame_alias_set ());
450 #endif
451   return tem;
452 }
453
454 /* Alias set used for setjmp buffer.  */
455 static HOST_WIDE_INT setjmp_alias_set = -1;
456
457 /* Construct the leading half of a __builtin_setjmp call.  Control will
458    return to RECEIVER_LABEL.  This is used directly by sjlj exception
459    handling code.  */
460
461 void
462 expand_builtin_setjmp_setup (buf_addr, receiver_label)
463      rtx buf_addr;
464      rtx receiver_label;
465 {
466   enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
467   rtx stack_save;
468   rtx mem;
469
470   if (setjmp_alias_set == -1)
471     setjmp_alias_set = new_alias_set ();
472
473 #ifdef POINTERS_EXTEND_UNSIGNED
474   if (GET_MODE (buf_addr) != Pmode)
475     buf_addr = convert_memory_address (Pmode, buf_addr);
476 #endif
477
478   buf_addr = force_reg (Pmode, force_operand (buf_addr, NULL_RTX));
479
480   emit_queue ();
481
482   /* We store the frame pointer and the address of receiver_label in
483      the buffer and use the rest of it for the stack save area, which
484      is machine-dependent.  */
485
486 #ifndef BUILTIN_SETJMP_FRAME_VALUE
487 #define BUILTIN_SETJMP_FRAME_VALUE virtual_stack_vars_rtx
488 #endif
489
490   mem = gen_rtx_MEM (Pmode, buf_addr);
491   set_mem_alias_set (mem, setjmp_alias_set);
492   emit_move_insn (mem, BUILTIN_SETJMP_FRAME_VALUE);
493
494   mem = gen_rtx_MEM (Pmode, plus_constant (buf_addr, GET_MODE_SIZE (Pmode))),
495   set_mem_alias_set (mem, setjmp_alias_set);
496
497   emit_move_insn (validize_mem (mem),
498                   force_reg (Pmode, gen_rtx_LABEL_REF (Pmode, receiver_label)));
499
500   stack_save = gen_rtx_MEM (sa_mode,
501                             plus_constant (buf_addr,
502                                            2 * GET_MODE_SIZE (Pmode)));
503   set_mem_alias_set (stack_save, setjmp_alias_set);
504   emit_stack_save (SAVE_NONLOCAL, &stack_save, NULL_RTX);
505
506   /* If there is further processing to do, do it.  */
507 #ifdef HAVE_builtin_setjmp_setup
508   if (HAVE_builtin_setjmp_setup)
509     emit_insn (gen_builtin_setjmp_setup (buf_addr));
510 #endif
511
512   /* Tell optimize_save_area_alloca that extra work is going to
513      need to go on during alloca.  */
514   current_function_calls_setjmp = 1;
515
516   /* Set this so all the registers get saved in our frame; we need to be
517      able to copy the saved values for any registers from frames we unwind.  */
518   current_function_has_nonlocal_label = 1;
519 }
520
521 /* Construct the trailing part of a __builtin_setjmp call.
522    This is used directly by sjlj exception handling code.  */
523
524 void
525 expand_builtin_setjmp_receiver (receiver_label)
526      rtx receiver_label ATTRIBUTE_UNUSED;
527 {
528   /* Clobber the FP when we get here, so we have to make sure it's
529      marked as used by this function.  */
530   emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
531
532   /* Mark the static chain as clobbered here so life information
533      doesn't get messed up for it.  */
534   emit_insn (gen_rtx_CLOBBER (VOIDmode, static_chain_rtx));
535
536   /* Now put in the code to restore the frame pointer, and argument
537      pointer, if needed.  The code below is from expand_end_bindings
538      in stmt.c; see detailed documentation there.  */
539 #ifdef HAVE_nonlocal_goto
540   if (! HAVE_nonlocal_goto)
541 #endif
542     emit_move_insn (virtual_stack_vars_rtx, hard_frame_pointer_rtx);
543
544 #if ARG_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
545   if (fixed_regs[ARG_POINTER_REGNUM])
546     {
547 #ifdef ELIMINABLE_REGS
548       size_t i;
549       static const struct elims {const int from, to;} elim_regs[] = ELIMINABLE_REGS;
550
551       for (i = 0; i < ARRAY_SIZE (elim_regs); i++)
552         if (elim_regs[i].from == ARG_POINTER_REGNUM
553             && elim_regs[i].to == HARD_FRAME_POINTER_REGNUM)
554           break;
555
556       if (i == ARRAY_SIZE (elim_regs))
557 #endif
558         {
559           /* Now restore our arg pointer from the address at which it
560              was saved in our stack frame.  */
561           emit_move_insn (virtual_incoming_args_rtx,
562                           copy_to_reg (get_arg_pointer_save_area (cfun)));
563         }
564     }
565 #endif
566
567 #ifdef HAVE_builtin_setjmp_receiver
568   if (HAVE_builtin_setjmp_receiver)
569     emit_insn (gen_builtin_setjmp_receiver (receiver_label));
570   else
571 #endif
572 #ifdef HAVE_nonlocal_goto_receiver
573     if (HAVE_nonlocal_goto_receiver)
574       emit_insn (gen_nonlocal_goto_receiver ());
575     else
576 #endif
577       { /* Nothing */ }
578
579   /* @@@ This is a kludge.  Not all machine descriptions define a blockage
580      insn, but we must not allow the code we just generated to be reordered
581      by scheduling.  Specifically, the update of the frame pointer must
582      happen immediately, not later.  So emit an ASM_INPUT to act as blockage
583      insn.  */
584   emit_insn (gen_rtx_ASM_INPUT (VOIDmode, ""));
585 }
586
587 /* __builtin_setjmp is passed a pointer to an array of five words (not
588    all will be used on all machines).  It operates similarly to the C
589    library function of the same name, but is more efficient.  Much of
590    the code below (and for longjmp) is copied from the handling of
591    non-local gotos.
592
593    NOTE: This is intended for use by GNAT and the exception handling
594    scheme in the compiler and will only work in the method used by
595    them.  */
596
597 static rtx
598 expand_builtin_setjmp (arglist, target)
599      tree arglist;
600      rtx target;
601 {
602   rtx buf_addr, next_lab, cont_lab;
603
604   if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
605     return NULL_RTX;
606
607   if (target == 0 || GET_CODE (target) != REG
608       || REGNO (target) < FIRST_PSEUDO_REGISTER)
609     target = gen_reg_rtx (TYPE_MODE (integer_type_node));
610
611   buf_addr = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
612
613   next_lab = gen_label_rtx ();
614   cont_lab = gen_label_rtx ();
615
616   expand_builtin_setjmp_setup (buf_addr, next_lab);
617
618   /* Set TARGET to zero and branch to the continue label.  */
619   emit_move_insn (target, const0_rtx);
620   emit_jump_insn (gen_jump (cont_lab));
621   emit_barrier ();
622   emit_label (next_lab);
623
624   expand_builtin_setjmp_receiver (next_lab);
625
626   /* Set TARGET to one.  */
627   emit_move_insn (target, const1_rtx);
628   emit_label (cont_lab);
629
630   /* Tell flow about the strange goings on.  Putting `next_lab' on
631      `nonlocal_goto_handler_labels' to indicates that function
632      calls may traverse the arc back to this label.  */
633
634   current_function_has_nonlocal_label = 1;
635   nonlocal_goto_handler_labels
636     = gen_rtx_EXPR_LIST (VOIDmode, next_lab, nonlocal_goto_handler_labels);
637
638   return target;
639 }
640
641 /* __builtin_longjmp is passed a pointer to an array of five words (not
642    all will be used on all machines).  It operates similarly to the C
643    library function of the same name, but is more efficient.  Much of
644    the code below is copied from the handling of non-local gotos.
645
646    NOTE: This is intended for use by GNAT and the exception handling
647    scheme in the compiler and will only work in the method used by
648    them.  */
649
650 void
651 expand_builtin_longjmp (buf_addr, value)
652      rtx buf_addr, value;
653 {
654   rtx fp, lab, stack, insn, last;
655   enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
656
657   if (setjmp_alias_set == -1)
658     setjmp_alias_set = new_alias_set ();
659
660 #ifdef POINTERS_EXTEND_UNSIGNED
661   if (GET_MODE (buf_addr) != Pmode)
662     buf_addr = convert_memory_address (Pmode, buf_addr);
663 #endif
664
665   buf_addr = force_reg (Pmode, buf_addr);
666
667   /* We used to store value in static_chain_rtx, but that fails if pointers
668      are smaller than integers.  We instead require that the user must pass
669      a second argument of 1, because that is what builtin_setjmp will
670      return.  This also makes EH slightly more efficient, since we are no
671      longer copying around a value that we don't care about.  */
672   if (value != const1_rtx)
673     abort ();
674
675   current_function_calls_longjmp = 1;
676
677   last = get_last_insn ();
678 #ifdef HAVE_builtin_longjmp
679   if (HAVE_builtin_longjmp)
680     emit_insn (gen_builtin_longjmp (buf_addr));
681   else
682 #endif
683     {
684       fp = gen_rtx_MEM (Pmode, buf_addr);
685       lab = gen_rtx_MEM (Pmode, plus_constant (buf_addr,
686                                                GET_MODE_SIZE (Pmode)));
687
688       stack = gen_rtx_MEM (sa_mode, plus_constant (buf_addr,
689                                                    2 * GET_MODE_SIZE (Pmode)));
690       set_mem_alias_set (fp, setjmp_alias_set);
691       set_mem_alias_set (lab, setjmp_alias_set);
692       set_mem_alias_set (stack, setjmp_alias_set);
693
694       /* Pick up FP, label, and SP from the block and jump.  This code is
695          from expand_goto in stmt.c; see there for detailed comments.  */
696 #if HAVE_nonlocal_goto
697       if (HAVE_nonlocal_goto)
698         /* We have to pass a value to the nonlocal_goto pattern that will
699            get copied into the static_chain pointer, but it does not matter
700            what that value is, because builtin_setjmp does not use it.  */
701         emit_insn (gen_nonlocal_goto (value, lab, stack, fp));
702       else
703 #endif
704         {
705           lab = copy_to_reg (lab);
706
707           emit_move_insn (hard_frame_pointer_rtx, fp);
708           emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
709
710           emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
711           emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
712           emit_indirect_jump (lab);
713         }
714     }
715
716   /* Search backwards and mark the jump insn as a non-local goto.
717      Note that this precludes the use of __builtin_longjmp to a
718      __builtin_setjmp target in the same function.  However, we've
719      already cautioned the user that these functions are for
720      internal exception handling use only.  */
721   for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
722     {
723       if (insn == last)
724         abort ();
725       if (GET_CODE (insn) == JUMP_INSN)
726         {
727           REG_NOTES (insn) = alloc_EXPR_LIST (REG_NON_LOCAL_GOTO, const0_rtx,
728                                               REG_NOTES (insn));
729           break;
730         }
731       else if (GET_CODE (insn) == CALL_INSN)
732         break;
733     }
734 }
735
736 /* Expand a call to __builtin_prefetch.  For a target that does not support
737    data prefetch, evaluate the memory address argument in case it has side
738    effects.  */
739
740 static void
741 expand_builtin_prefetch (arglist)
742      tree arglist;
743 {
744   tree arg0, arg1, arg2;
745   rtx op0, op1, op2;
746
747   if (!validate_arglist (arglist, POINTER_TYPE, 0))
748     return;
749
750   arg0 = TREE_VALUE (arglist);
751   /* Arguments 1 and 2 are optional; argument 1 (read/write) defaults to
752      zero (read) and argument 2 (locality) defaults to 3 (high degree of
753      locality).  */
754   if (TREE_CHAIN (arglist))
755     {
756       arg1 = TREE_VALUE (TREE_CHAIN (arglist));
757       if (TREE_CHAIN (TREE_CHAIN (arglist)))
758         arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
759       else
760         arg2 = build_int_2 (3, 0);
761     }
762   else
763     {
764       arg1 = integer_zero_node;
765       arg2 = build_int_2 (3, 0);
766     }
767
768   /* Argument 0 is an address.  */
769   op0 = expand_expr (arg0, NULL_RTX, Pmode, EXPAND_NORMAL);
770
771   /* Argument 1 (read/write flag) must be a compile-time constant int.  */
772   if (TREE_CODE (arg1) != INTEGER_CST)
773     {
774       error ("second arg to `__builtin_prefetch' must be a constant");
775       arg1 = integer_zero_node;
776     }
777   op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
778   /* Argument 1 must be either zero or one.  */
779   if (INTVAL (op1) != 0 && INTVAL (op1) != 1)
780     {
781       warning ("invalid second arg to __builtin_prefetch; using zero");
782       op1 = const0_rtx;
783     }
784
785   /* Argument 2 (locality) must be a compile-time constant int.  */
786   if (TREE_CODE (arg2) != INTEGER_CST)
787     {
788       error ("third arg to `__builtin_prefetch' must be a constant");
789       arg2 = integer_zero_node;
790     }
791   op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0);
792   /* Argument 2 must be 0, 1, 2, or 3.  */
793   if (INTVAL (op2) < 0 || INTVAL (op2) > 3)
794     {
795       warning ("invalid third arg to __builtin_prefetch; using zero");
796       op2 = const0_rtx;
797     }
798
799 #ifdef HAVE_prefetch
800   if (HAVE_prefetch)
801     {
802       if ((! (*insn_data[(int) CODE_FOR_prefetch].operand[0].predicate)
803              (op0,
804               insn_data[(int) CODE_FOR_prefetch].operand[0].mode))
805           || (GET_MODE(op0) != Pmode))
806         {
807 #ifdef POINTERS_EXTEND_UNSIGNED
808           if (GET_MODE(op0) != Pmode)
809             op0 = convert_memory_address (Pmode, op0);
810 #endif
811           op0 = force_reg (Pmode, op0);
812         }
813       emit_insn (gen_prefetch (op0, op1, op2));
814     }
815   else
816 #endif
817     op0 = protect_from_queue (op0, 0);
818   /* Don't do anything with direct references to volatile memory, but
819      generate code to handle other side effects.  */
820   if (GET_CODE (op0) != MEM && side_effects_p (op0))
821     emit_insn (op0);
822 }
823
824 /* Get a MEM rtx for expression EXP which is the address of an operand
825    to be used to be used in a string instruction (cmpstrsi, movstrsi, ..).  */
826
827 static rtx
828 get_memory_rtx (exp)
829      tree exp;
830 {
831   rtx addr = expand_expr (exp, NULL_RTX, ptr_mode, EXPAND_SUM);
832   rtx mem;
833
834 #ifdef POINTERS_EXTEND_UNSIGNED
835   if (GET_MODE (addr) != Pmode)
836     addr = convert_memory_address (Pmode, addr);
837 #endif
838
839   mem = gen_rtx_MEM (BLKmode, memory_address (BLKmode, addr));
840
841   /* Get an expression we can use to find the attributes to assign to MEM.
842      If it is an ADDR_EXPR, use the operand.  Otherwise, dereference it if
843      we can.  First remove any nops.  */
844   while ((TREE_CODE (exp) == NOP_EXPR || TREE_CODE (exp) == CONVERT_EXPR
845           || TREE_CODE (exp) == NON_LVALUE_EXPR)
846          && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (exp, 0))))
847     exp = TREE_OPERAND (exp, 0);
848
849   if (TREE_CODE (exp) == ADDR_EXPR)
850     {
851       exp = TREE_OPERAND (exp, 0);
852       set_mem_attributes (mem, exp, 0);
853     }
854   else if (POINTER_TYPE_P (TREE_TYPE (exp)))
855     {
856       exp = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (exp)), exp);
857       /* memcpy, memset and other builtin stringops can alias with anything.  */
858       set_mem_alias_set (mem, 0);
859     }
860
861   return mem;
862 }
863 \f
864 /* Built-in functions to perform an untyped call and return.  */
865
866 /* For each register that may be used for calling a function, this
867    gives a mode used to copy the register's value.  VOIDmode indicates
868    the register is not used for calling a function.  If the machine
869    has register windows, this gives only the outbound registers.
870    INCOMING_REGNO gives the corresponding inbound register.  */
871 static enum machine_mode apply_args_mode[FIRST_PSEUDO_REGISTER];
872
873 /* For each register that may be used for returning values, this gives
874    a mode used to copy the register's value.  VOIDmode indicates the
875    register is not used for returning values.  If the machine has
876    register windows, this gives only the outbound registers.
877    INCOMING_REGNO gives the corresponding inbound register.  */
878 static enum machine_mode apply_result_mode[FIRST_PSEUDO_REGISTER];
879
880 /* For each register that may be used for calling a function, this
881    gives the offset of that register into the block returned by
882    __builtin_apply_args.  0 indicates that the register is not
883    used for calling a function.  */
884 static int apply_args_reg_offset[FIRST_PSEUDO_REGISTER];
885
886 /* Return the offset of register REGNO into the block returned by
887    __builtin_apply_args.  This is not declared static, since it is
888    needed in objc-act.c.  */
889
890 int
891 apply_args_register_offset (regno)
892      int regno;
893 {
894   apply_args_size ();
895
896   /* Arguments are always put in outgoing registers (in the argument
897      block) if such make sense.  */
898 #ifdef OUTGOING_REGNO
899   regno = OUTGOING_REGNO (regno);
900 #endif
901   return apply_args_reg_offset[regno];
902 }
903
904 /* Return the size required for the block returned by __builtin_apply_args,
905    and initialize apply_args_mode.  */
906
907 static int
908 apply_args_size ()
909 {
910   static int size = -1;
911   int align;
912   unsigned int regno;
913   enum machine_mode mode;
914
915   /* The values computed by this function never change.  */
916   if (size < 0)
917     {
918       /* The first value is the incoming arg-pointer.  */
919       size = GET_MODE_SIZE (Pmode);
920
921       /* The second value is the structure value address unless this is
922          passed as an "invisible" first argument.  */
923       if (struct_value_rtx)
924         size += GET_MODE_SIZE (Pmode);
925
926       for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
927         if (FUNCTION_ARG_REGNO_P (regno))
928           {
929             /* Search for the proper mode for copying this register's
930                value.  I'm not sure this is right, but it works so far.  */
931             enum machine_mode best_mode = VOIDmode;
932
933             for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT);
934                  mode != VOIDmode;
935                  mode = GET_MODE_WIDER_MODE (mode))
936               if (HARD_REGNO_MODE_OK (regno, mode)
937                   && HARD_REGNO_NREGS (regno, mode) == 1)
938                 best_mode = mode;
939
940             if (best_mode == VOIDmode)
941               for (mode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT);
942                    mode != VOIDmode;
943                    mode = GET_MODE_WIDER_MODE (mode))
944                 if (HARD_REGNO_MODE_OK (regno, mode)
945                     && have_insn_for (SET, mode))
946                   best_mode = mode;
947
948             if (best_mode == VOIDmode)
949               for (mode = GET_CLASS_NARROWEST_MODE (MODE_VECTOR_FLOAT);
950                    mode != VOIDmode;
951                    mode = GET_MODE_WIDER_MODE (mode))
952                 if (HARD_REGNO_MODE_OK (regno, mode)
953                     && have_insn_for (SET, mode))
954                   best_mode = mode;
955
956             if (best_mode == VOIDmode)
957               for (mode = GET_CLASS_NARROWEST_MODE (MODE_VECTOR_INT);
958                    mode != VOIDmode;
959                    mode = GET_MODE_WIDER_MODE (mode))
960                 if (HARD_REGNO_MODE_OK (regno, mode)
961                     && have_insn_for (SET, mode))
962                   best_mode = mode;
963
964             mode = best_mode;
965             if (mode == VOIDmode)
966               abort ();
967
968             align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
969             if (size % align != 0)
970               size = CEIL (size, align) * align;
971             apply_args_reg_offset[regno] = size;
972             size += GET_MODE_SIZE (mode);
973             apply_args_mode[regno] = mode;
974           }
975         else
976           {
977             apply_args_mode[regno] = VOIDmode;
978             apply_args_reg_offset[regno] = 0;
979           }
980     }
981   return size;
982 }
983
984 /* Return the size required for the block returned by __builtin_apply,
985    and initialize apply_result_mode.  */
986
987 static int
988 apply_result_size ()
989 {
990   static int size = -1;
991   int align, regno;
992   enum machine_mode mode;
993
994   /* The values computed by this function never change.  */
995   if (size < 0)
996     {
997       size = 0;
998
999       for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1000         if (FUNCTION_VALUE_REGNO_P (regno))
1001           {
1002             /* Search for the proper mode for copying this register's
1003                value.  I'm not sure this is right, but it works so far.  */
1004             enum machine_mode best_mode = VOIDmode;
1005
1006             for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT);
1007                  mode != TImode;
1008                  mode = GET_MODE_WIDER_MODE (mode))
1009               if (HARD_REGNO_MODE_OK (regno, mode))
1010                 best_mode = mode;
1011
1012             if (best_mode == VOIDmode)
1013               for (mode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT);
1014                    mode != VOIDmode;
1015                    mode = GET_MODE_WIDER_MODE (mode))
1016                 if (HARD_REGNO_MODE_OK (regno, mode)
1017                     && have_insn_for (SET, mode))
1018                   best_mode = mode;
1019
1020             if (best_mode == VOIDmode)
1021               for (mode = GET_CLASS_NARROWEST_MODE (MODE_VECTOR_FLOAT);
1022                    mode != VOIDmode;
1023                    mode = GET_MODE_WIDER_MODE (mode))
1024                 if (HARD_REGNO_MODE_OK (regno, mode)
1025                     && have_insn_for (SET, mode))
1026                   best_mode = mode;
1027
1028             if (best_mode == VOIDmode)
1029               for (mode = GET_CLASS_NARROWEST_MODE (MODE_VECTOR_INT);
1030                    mode != VOIDmode;
1031                    mode = GET_MODE_WIDER_MODE (mode))
1032                 if (HARD_REGNO_MODE_OK (regno, mode)
1033                     && have_insn_for (SET, mode))
1034                   best_mode = mode;
1035
1036             mode = best_mode;
1037             if (mode == VOIDmode)
1038               abort ();
1039
1040             align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1041             if (size % align != 0)
1042               size = CEIL (size, align) * align;
1043             size += GET_MODE_SIZE (mode);
1044             apply_result_mode[regno] = mode;
1045           }
1046         else
1047           apply_result_mode[regno] = VOIDmode;
1048
1049       /* Allow targets that use untyped_call and untyped_return to override
1050          the size so that machine-specific information can be stored here.  */
1051 #ifdef APPLY_RESULT_SIZE
1052       size = APPLY_RESULT_SIZE;
1053 #endif
1054     }
1055   return size;
1056 }
1057
1058 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
1059 /* Create a vector describing the result block RESULT.  If SAVEP is true,
1060    the result block is used to save the values; otherwise it is used to
1061    restore the values.  */
1062
1063 static rtx
1064 result_vector (savep, result)
1065      int savep;
1066      rtx result;
1067 {
1068   int regno, size, align, nelts;
1069   enum machine_mode mode;
1070   rtx reg, mem;
1071   rtx *savevec = (rtx *) alloca (FIRST_PSEUDO_REGISTER * sizeof (rtx));
1072
1073   size = nelts = 0;
1074   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1075     if ((mode = apply_result_mode[regno]) != VOIDmode)
1076       {
1077         align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1078         if (size % align != 0)
1079           size = CEIL (size, align) * align;
1080         reg = gen_rtx_REG (mode, savep ? regno : INCOMING_REGNO (regno));
1081         mem = adjust_address (result, mode, size);
1082         savevec[nelts++] = (savep
1083                             ? gen_rtx_SET (VOIDmode, mem, reg)
1084                             : gen_rtx_SET (VOIDmode, reg, mem));
1085         size += GET_MODE_SIZE (mode);
1086       }
1087   return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (nelts, savevec));
1088 }
1089 #endif /* HAVE_untyped_call or HAVE_untyped_return */
1090
1091 /* Save the state required to perform an untyped call with the same
1092    arguments as were passed to the current function.  */
1093
1094 static rtx
1095 expand_builtin_apply_args_1 ()
1096 {
1097   rtx registers;
1098   int size, align, regno;
1099   enum machine_mode mode;
1100
1101   /* Create a block where the arg-pointer, structure value address,
1102      and argument registers can be saved.  */
1103   registers = assign_stack_local (BLKmode, apply_args_size (), -1);
1104
1105   /* Walk past the arg-pointer and structure value address.  */
1106   size = GET_MODE_SIZE (Pmode);
1107   if (struct_value_rtx)
1108     size += GET_MODE_SIZE (Pmode);
1109
1110   /* Save each register used in calling a function to the block.  */
1111   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1112     if ((mode = apply_args_mode[regno]) != VOIDmode)
1113       {
1114         rtx tem;
1115
1116         align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1117         if (size % align != 0)
1118           size = CEIL (size, align) * align;
1119
1120         tem = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1121
1122         emit_move_insn (adjust_address (registers, mode, size), tem);
1123         size += GET_MODE_SIZE (mode);
1124       }
1125
1126   /* Save the arg pointer to the block.  */
1127   emit_move_insn (adjust_address (registers, Pmode, 0),
1128                   copy_to_reg (virtual_incoming_args_rtx));
1129   size = GET_MODE_SIZE (Pmode);
1130
1131   /* Save the structure value address unless this is passed as an
1132      "invisible" first argument.  */
1133   if (struct_value_incoming_rtx)
1134     {
1135       emit_move_insn (adjust_address (registers, Pmode, size),
1136                       copy_to_reg (struct_value_incoming_rtx));
1137       size += GET_MODE_SIZE (Pmode);
1138     }
1139
1140   /* Return the address of the block.  */
1141   return copy_addr_to_reg (XEXP (registers, 0));
1142 }
1143
1144 /* __builtin_apply_args returns block of memory allocated on
1145    the stack into which is stored the arg pointer, structure
1146    value address, static chain, and all the registers that might
1147    possibly be used in performing a function call.  The code is
1148    moved to the start of the function so the incoming values are
1149    saved.  */
1150
1151 static rtx
1152 expand_builtin_apply_args ()
1153 {
1154   /* Don't do __builtin_apply_args more than once in a function.
1155      Save the result of the first call and reuse it.  */
1156   if (apply_args_value != 0)
1157     return apply_args_value;
1158   {
1159     /* When this function is called, it means that registers must be
1160        saved on entry to this function.  So we migrate the
1161        call to the first insn of this function.  */
1162     rtx temp;
1163     rtx seq;
1164
1165     start_sequence ();
1166     temp = expand_builtin_apply_args_1 ();
1167     seq = get_insns ();
1168     end_sequence ();
1169
1170     apply_args_value = temp;
1171
1172     /* Put the insns after the NOTE that starts the function.
1173        If this is inside a start_sequence, make the outer-level insn
1174        chain current, so the code is placed at the start of the
1175        function.  */
1176     push_topmost_sequence ();
1177     emit_insn_before (seq, NEXT_INSN (get_insns ()));
1178     pop_topmost_sequence ();
1179     return temp;
1180   }
1181 }
1182
1183 /* Perform an untyped call and save the state required to perform an
1184    untyped return of whatever value was returned by the given function.  */
1185
1186 static rtx
1187 expand_builtin_apply (function, arguments, argsize)
1188      rtx function, arguments, argsize;
1189 {
1190   int size, align, regno;
1191   enum machine_mode mode;
1192   rtx incoming_args, result, reg, dest, src, call_insn;
1193   rtx old_stack_level = 0;
1194   rtx call_fusage = 0;
1195
1196 #ifdef POINTERS_EXTEND_UNSIGNED
1197   if (GET_MODE (arguments) != Pmode)
1198     arguments = convert_memory_address (Pmode, arguments);
1199 #endif
1200
1201   /* Create a block where the return registers can be saved.  */
1202   result = assign_stack_local (BLKmode, apply_result_size (), -1);
1203
1204   /* Fetch the arg pointer from the ARGUMENTS block.  */
1205   incoming_args = gen_reg_rtx (Pmode);
1206   emit_move_insn (incoming_args, gen_rtx_MEM (Pmode, arguments));
1207 #ifndef STACK_GROWS_DOWNWARD
1208   incoming_args = expand_simple_binop (Pmode, MINUS, incoming_args, argsize,
1209                                        incoming_args, 0, OPTAB_LIB_WIDEN);
1210 #endif
1211
1212   /* Perform postincrements before actually calling the function.  */
1213   emit_queue ();
1214
1215   /* Push a new argument block and copy the arguments.  Do not allow
1216      the (potential) memcpy call below to interfere with our stack
1217      manipulations.  */
1218   do_pending_stack_adjust ();
1219   NO_DEFER_POP;
1220
1221   /* Save the stack with nonlocal if available */
1222 #ifdef HAVE_save_stack_nonlocal
1223   if (HAVE_save_stack_nonlocal)
1224     emit_stack_save (SAVE_NONLOCAL, &old_stack_level, NULL_RTX);
1225   else
1226 #endif
1227     emit_stack_save (SAVE_BLOCK, &old_stack_level, NULL_RTX);
1228
1229   /* Push a block of memory onto the stack to store the memory arguments.
1230      Save the address in a register, and copy the memory arguments.  ??? I
1231      haven't figured out how the calling convention macros effect this,
1232      but it's likely that the source and/or destination addresses in
1233      the block copy will need updating in machine specific ways.  */
1234   dest = allocate_dynamic_stack_space (argsize, 0, BITS_PER_UNIT);
1235   dest = gen_rtx_MEM (BLKmode, dest);
1236   set_mem_align (dest, PARM_BOUNDARY);
1237   src = gen_rtx_MEM (BLKmode, incoming_args);
1238   set_mem_align (src, PARM_BOUNDARY);
1239   emit_block_move (dest, src, argsize, BLOCK_OP_NORMAL);
1240
1241   /* Refer to the argument block.  */
1242   apply_args_size ();
1243   arguments = gen_rtx_MEM (BLKmode, arguments);
1244   set_mem_align (arguments, PARM_BOUNDARY);
1245
1246   /* Walk past the arg-pointer and structure value address.  */
1247   size = GET_MODE_SIZE (Pmode);
1248   if (struct_value_rtx)
1249     size += GET_MODE_SIZE (Pmode);
1250
1251   /* Restore each of the registers previously saved.  Make USE insns
1252      for each of these registers for use in making the call.  */
1253   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1254     if ((mode = apply_args_mode[regno]) != VOIDmode)
1255       {
1256         align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1257         if (size % align != 0)
1258           size = CEIL (size, align) * align;
1259         reg = gen_rtx_REG (mode, regno);
1260         emit_move_insn (reg, adjust_address (arguments, mode, size));
1261         use_reg (&call_fusage, reg);
1262         size += GET_MODE_SIZE (mode);
1263       }
1264
1265   /* Restore the structure value address unless this is passed as an
1266      "invisible" first argument.  */
1267   size = GET_MODE_SIZE (Pmode);
1268   if (struct_value_rtx)
1269     {
1270       rtx value = gen_reg_rtx (Pmode);
1271       emit_move_insn (value, adjust_address (arguments, Pmode, size));
1272       emit_move_insn (struct_value_rtx, value);
1273       if (GET_CODE (struct_value_rtx) == REG)
1274         use_reg (&call_fusage, struct_value_rtx);
1275       size += GET_MODE_SIZE (Pmode);
1276     }
1277
1278   /* All arguments and registers used for the call are set up by now!  */
1279   function = prepare_call_address (function, NULL_TREE, &call_fusage, 0, 0);
1280
1281   /* Ensure address is valid.  SYMBOL_REF is already valid, so no need,
1282      and we don't want to load it into a register as an optimization,
1283      because prepare_call_address already did it if it should be done.  */
1284   if (GET_CODE (function) != SYMBOL_REF)
1285     function = memory_address (FUNCTION_MODE, function);
1286
1287   /* Generate the actual call instruction and save the return value.  */
1288 #ifdef HAVE_untyped_call
1289   if (HAVE_untyped_call)
1290     emit_call_insn (gen_untyped_call (gen_rtx_MEM (FUNCTION_MODE, function),
1291                                       result, result_vector (1, result)));
1292   else
1293 #endif
1294 #ifdef HAVE_call_value
1295   if (HAVE_call_value)
1296     {
1297       rtx valreg = 0;
1298
1299       /* Locate the unique return register.  It is not possible to
1300          express a call that sets more than one return register using
1301          call_value; use untyped_call for that.  In fact, untyped_call
1302          only needs to save the return registers in the given block.  */
1303       for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1304         if ((mode = apply_result_mode[regno]) != VOIDmode)
1305           {
1306             if (valreg)
1307               abort (); /* HAVE_untyped_call required.  */
1308             valreg = gen_rtx_REG (mode, regno);
1309           }
1310
1311       emit_call_insn (GEN_CALL_VALUE (valreg,
1312                                       gen_rtx_MEM (FUNCTION_MODE, function),
1313                                       const0_rtx, NULL_RTX, const0_rtx));
1314
1315       emit_move_insn (adjust_address (result, GET_MODE (valreg), 0), valreg);
1316     }
1317   else
1318 #endif
1319     abort ();
1320
1321   /* Find the CALL insn we just emitted.  */
1322   for (call_insn = get_last_insn ();
1323        call_insn && GET_CODE (call_insn) != CALL_INSN;
1324        call_insn = PREV_INSN (call_insn))
1325     ;
1326
1327   if (! call_insn)
1328     abort ();
1329
1330   /* Put the register usage information on the CALL.  If there is already
1331      some usage information, put ours at the end.  */
1332   if (CALL_INSN_FUNCTION_USAGE (call_insn))
1333     {
1334       rtx link;
1335
1336       for (link = CALL_INSN_FUNCTION_USAGE (call_insn); XEXP (link, 1) != 0;
1337            link = XEXP (link, 1))
1338         ;
1339
1340       XEXP (link, 1) = call_fusage;
1341     }
1342   else
1343     CALL_INSN_FUNCTION_USAGE (call_insn) = call_fusage;
1344
1345   /* Restore the stack.  */
1346 #ifdef HAVE_save_stack_nonlocal
1347   if (HAVE_save_stack_nonlocal)
1348     emit_stack_restore (SAVE_NONLOCAL, old_stack_level, NULL_RTX);
1349   else
1350 #endif
1351     emit_stack_restore (SAVE_BLOCK, old_stack_level, NULL_RTX);
1352
1353   OK_DEFER_POP;
1354
1355   /* Return the address of the result block.  */
1356   return copy_addr_to_reg (XEXP (result, 0));
1357 }
1358
1359 /* Perform an untyped return.  */
1360
1361 static void
1362 expand_builtin_return (result)
1363      rtx result;
1364 {
1365   int size, align, regno;
1366   enum machine_mode mode;
1367   rtx reg;
1368   rtx call_fusage = 0;
1369
1370 #ifdef POINTERS_EXTEND_UNSIGNED
1371   if (GET_MODE (result) != Pmode)
1372     result = convert_memory_address (Pmode, result);
1373 #endif
1374
1375   apply_result_size ();
1376   result = gen_rtx_MEM (BLKmode, result);
1377
1378 #ifdef HAVE_untyped_return
1379   if (HAVE_untyped_return)
1380     {
1381       emit_jump_insn (gen_untyped_return (result, result_vector (0, result)));
1382       emit_barrier ();
1383       return;
1384     }
1385 #endif
1386
1387   /* Restore the return value and note that each value is used.  */
1388   size = 0;
1389   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1390     if ((mode = apply_result_mode[regno]) != VOIDmode)
1391       {
1392         align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1393         if (size % align != 0)
1394           size = CEIL (size, align) * align;
1395         reg = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1396         emit_move_insn (reg, adjust_address (result, mode, size));
1397
1398         push_to_sequence (call_fusage);
1399         emit_insn (gen_rtx_USE (VOIDmode, reg));
1400         call_fusage = get_insns ();
1401         end_sequence ();
1402         size += GET_MODE_SIZE (mode);
1403       }
1404
1405   /* Put the USE insns before the return.  */
1406   emit_insn (call_fusage);
1407
1408   /* Return whatever values was restored by jumping directly to the end
1409      of the function.  */
1410   expand_null_return ();
1411 }
1412
1413 /* Used by expand_builtin_classify_type and fold_builtin_classify_type.  */
1414
1415 static enum type_class
1416 type_to_class (type)
1417      tree type;
1418 {
1419   switch (TREE_CODE (type))
1420     {
1421     case VOID_TYPE:        return void_type_class;
1422     case INTEGER_TYPE:     return integer_type_class;
1423     case CHAR_TYPE:        return char_type_class;
1424     case ENUMERAL_TYPE:    return enumeral_type_class;
1425     case BOOLEAN_TYPE:     return boolean_type_class;
1426     case POINTER_TYPE:     return pointer_type_class;
1427     case REFERENCE_TYPE:   return reference_type_class;
1428     case OFFSET_TYPE:      return offset_type_class;
1429     case REAL_TYPE:        return real_type_class;
1430     case COMPLEX_TYPE:     return complex_type_class;
1431     case FUNCTION_TYPE:    return function_type_class;
1432     case METHOD_TYPE:      return method_type_class;
1433     case RECORD_TYPE:      return record_type_class;
1434     case UNION_TYPE:
1435     case QUAL_UNION_TYPE:  return union_type_class;
1436     case ARRAY_TYPE:       return (TYPE_STRING_FLAG (type)
1437                                    ? string_type_class : array_type_class);
1438     case SET_TYPE:         return set_type_class;
1439     case FILE_TYPE:        return file_type_class;
1440     case LANG_TYPE:        return lang_type_class;
1441     default:               return no_type_class;
1442     }
1443 }
1444
1445 /* Expand a call to __builtin_classify_type with arguments found in
1446    ARGLIST.  */
1447
1448 static rtx
1449 expand_builtin_classify_type (arglist)
1450      tree arglist;
1451 {
1452   if (arglist != 0)
1453     return GEN_INT (type_to_class (TREE_TYPE (TREE_VALUE (arglist))));
1454   return GEN_INT (no_type_class);
1455 }
1456
1457 /* Expand expression EXP, which is a call to __builtin_constant_p.  */
1458
1459 static rtx
1460 expand_builtin_constant_p (exp)
1461      tree exp;
1462 {
1463   tree arglist = TREE_OPERAND (exp, 1);
1464   enum machine_mode value_mode = TYPE_MODE (TREE_TYPE (exp));
1465   rtx tmp;
1466
1467   if (arglist == 0)
1468     return const0_rtx;
1469   arglist = TREE_VALUE (arglist);
1470
1471   /* We have taken care of the easy cases during constant folding.  This
1472      case is not obvious, so emit (constant_p_rtx (ARGLIST)) and let CSE
1473      get a chance to see if it can deduce whether ARGLIST is constant.  */
1474
1475   current_function_calls_constant_p = 1;
1476
1477   tmp = expand_expr (arglist, NULL_RTX, VOIDmode, 0);
1478   tmp = gen_rtx_CONSTANT_P_RTX (value_mode, tmp);
1479   return tmp;
1480 }
1481
1482 /* Return mathematic function equivalent to FN but operating directly on TYPE,
1483    if available.  */
1484 tree
1485 mathfn_built_in (type, fn)
1486      tree type;
1487      enum built_in_function fn;
1488 {
1489   enum built_in_function fcode = NOT_BUILT_IN;
1490   if (TYPE_MODE (type) == TYPE_MODE (double_type_node))
1491     switch (fn)
1492       {
1493       case BUILT_IN_SQRT:
1494       case BUILT_IN_SQRTF:
1495       case BUILT_IN_SQRTL:
1496         fcode = BUILT_IN_SQRT;
1497         break;
1498       case BUILT_IN_SIN:
1499       case BUILT_IN_SINF:
1500       case BUILT_IN_SINL:
1501         fcode = BUILT_IN_SIN;
1502         break;
1503       case BUILT_IN_COS:
1504       case BUILT_IN_COSF:
1505       case BUILT_IN_COSL:
1506         fcode = BUILT_IN_COS;
1507         break;
1508       case BUILT_IN_EXP:
1509       case BUILT_IN_EXPF:
1510       case BUILT_IN_EXPL:
1511         fcode = BUILT_IN_EXP;
1512         break;
1513       case BUILT_IN_LOG:
1514       case BUILT_IN_LOGF:
1515       case BUILT_IN_LOGL:
1516         fcode = BUILT_IN_LOG;
1517         break;
1518       case BUILT_IN_FLOOR:
1519       case BUILT_IN_FLOORF:
1520       case BUILT_IN_FLOORL:
1521         fcode = BUILT_IN_FLOOR;
1522         break;
1523       case BUILT_IN_CEIL:
1524       case BUILT_IN_CEILF:
1525       case BUILT_IN_CEILL:
1526         fcode = BUILT_IN_CEIL;
1527         break;
1528       case BUILT_IN_TRUNC:
1529       case BUILT_IN_TRUNCF:
1530       case BUILT_IN_TRUNCL:
1531         fcode = BUILT_IN_TRUNC;
1532         break;
1533       case BUILT_IN_ROUND:
1534       case BUILT_IN_ROUNDF:
1535       case BUILT_IN_ROUNDL:
1536         fcode = BUILT_IN_ROUND;
1537         break;
1538       case BUILT_IN_NEARBYINT:
1539       case BUILT_IN_NEARBYINTF:
1540       case BUILT_IN_NEARBYINTL:
1541         fcode = BUILT_IN_NEARBYINT;
1542         break;
1543       default:
1544         abort ();
1545       }
1546   else if (TYPE_MODE (type) == TYPE_MODE (float_type_node))
1547     switch (fn)
1548       {
1549       case BUILT_IN_SQRT:
1550       case BUILT_IN_SQRTF:
1551       case BUILT_IN_SQRTL:
1552         fcode = BUILT_IN_SQRTF;
1553         break;
1554       case BUILT_IN_SIN:
1555       case BUILT_IN_SINF:
1556       case BUILT_IN_SINL:
1557         fcode = BUILT_IN_SINF;
1558         break;
1559       case BUILT_IN_COS:
1560       case BUILT_IN_COSF:
1561       case BUILT_IN_COSL:
1562         fcode = BUILT_IN_COSF;
1563         break;
1564       case BUILT_IN_EXP:
1565       case BUILT_IN_EXPF:
1566       case BUILT_IN_EXPL:
1567         fcode = BUILT_IN_EXPF;
1568         break;
1569       case BUILT_IN_LOG:
1570       case BUILT_IN_LOGF:
1571       case BUILT_IN_LOGL:
1572         fcode = BUILT_IN_LOGF;
1573         break;
1574       case BUILT_IN_FLOOR:
1575       case BUILT_IN_FLOORF:
1576       case BUILT_IN_FLOORL:
1577         fcode = BUILT_IN_FLOORF;
1578         break;
1579       case BUILT_IN_CEIL:
1580       case BUILT_IN_CEILF:
1581       case BUILT_IN_CEILL:
1582         fcode = BUILT_IN_CEILF;
1583         break;
1584       case BUILT_IN_TRUNC:
1585       case BUILT_IN_TRUNCF:
1586       case BUILT_IN_TRUNCL:
1587         fcode = BUILT_IN_TRUNCF;
1588         break;
1589       case BUILT_IN_ROUND:
1590       case BUILT_IN_ROUNDF:
1591       case BUILT_IN_ROUNDL:
1592         fcode = BUILT_IN_ROUNDF;
1593         break;
1594       case BUILT_IN_NEARBYINT:
1595       case BUILT_IN_NEARBYINTF:
1596       case BUILT_IN_NEARBYINTL:
1597         fcode = BUILT_IN_NEARBYINTF;
1598         break;
1599       default:
1600         abort ();
1601       }
1602   else if (TYPE_MODE (type) == TYPE_MODE (long_double_type_node))
1603     switch (fn)
1604       {
1605       case BUILT_IN_SQRT:
1606       case BUILT_IN_SQRTF:
1607       case BUILT_IN_SQRTL:
1608         fcode = BUILT_IN_SQRTL;
1609         break;
1610       case BUILT_IN_SIN:
1611       case BUILT_IN_SINF:
1612       case BUILT_IN_SINL:
1613         fcode = BUILT_IN_SINL;
1614         break;
1615       case BUILT_IN_COS:
1616       case BUILT_IN_COSF:
1617       case BUILT_IN_COSL:
1618         fcode = BUILT_IN_COSL;
1619         break;
1620       case BUILT_IN_EXP:
1621       case BUILT_IN_EXPF:
1622       case BUILT_IN_EXPL:
1623         fcode = BUILT_IN_EXPL;
1624         break;
1625       case BUILT_IN_LOG:
1626       case BUILT_IN_LOGF:
1627       case BUILT_IN_LOGL:
1628         fcode = BUILT_IN_LOGL;
1629         break;
1630       case BUILT_IN_FLOOR:
1631       case BUILT_IN_FLOORF:
1632       case BUILT_IN_FLOORL:
1633         fcode = BUILT_IN_FLOORL;
1634         break;
1635       case BUILT_IN_CEIL:
1636       case BUILT_IN_CEILF:
1637       case BUILT_IN_CEILL:
1638         fcode = BUILT_IN_CEILL;
1639         break;
1640       case BUILT_IN_TRUNC:
1641       case BUILT_IN_TRUNCF:
1642       case BUILT_IN_TRUNCL:
1643         fcode = BUILT_IN_TRUNCL;
1644         break;
1645       case BUILT_IN_ROUND:
1646       case BUILT_IN_ROUNDF:
1647       case BUILT_IN_ROUNDL:
1648         fcode = BUILT_IN_ROUNDL;
1649         break;
1650       case BUILT_IN_NEARBYINT:
1651       case BUILT_IN_NEARBYINTF:
1652       case BUILT_IN_NEARBYINTL:
1653         fcode = BUILT_IN_NEARBYINTL;
1654         break;
1655       default:
1656         abort ();
1657       }
1658   return implicit_built_in_decls[fcode];
1659 }
1660
1661 /* If errno must be maintained, expand the RTL to check if the result,
1662    TARGET, of a built-in function call, EXP, is NaN, and if so set
1663    errno to EDOM.  */
1664
1665 static void
1666 expand_errno_check (exp, target)
1667      tree exp;
1668      rtx target;
1669 {
1670   rtx lab;
1671
1672   if (flag_errno_math && HONOR_NANS (GET_MODE (target)))
1673     {
1674       lab = gen_label_rtx ();
1675
1676       /* Test the result; if it is NaN, set errno=EDOM because
1677          the argument was not in the domain.  */
1678       emit_cmp_and_jump_insns (target, target, EQ, 0, GET_MODE (target),
1679                                0, lab);
1680
1681 #ifdef TARGET_EDOM
1682       {
1683 #ifdef GEN_ERRNO_RTX
1684         rtx errno_rtx = GEN_ERRNO_RTX;
1685 #else
1686         rtx errno_rtx
1687           = gen_rtx_MEM (word_mode, gen_rtx_SYMBOL_REF (Pmode, "errno"));
1688 #endif
1689
1690         emit_move_insn (errno_rtx, GEN_INT (TARGET_EDOM));
1691       }
1692 #else
1693       /* We can't set errno=EDOM directly; let the library call do it.
1694          Pop the arguments right away in case the call gets deleted.  */
1695       NO_DEFER_POP;
1696       expand_call (exp, target, 0);
1697       OK_DEFER_POP;
1698 #endif
1699
1700       emit_label (lab);
1701     }
1702 }
1703
1704
1705 /* Expand a call to one of the builtin math functions (sin, cos, or sqrt).
1706    Return 0 if a normal call should be emitted rather than expanding the
1707    function in-line.  EXP is the expression that is a call to the builtin
1708    function; if convenient, the result should be placed in TARGET.
1709    SUBTARGET may be used as the target for computing one of EXP's operands.  */
1710
1711 static rtx
1712 expand_builtin_mathfn (exp, target, subtarget)
1713      tree exp;
1714      rtx target, subtarget;
1715 {
1716   optab builtin_optab;
1717   rtx op0, insns;
1718   tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
1719   tree arglist = TREE_OPERAND (exp, 1);
1720   enum machine_mode argmode;
1721   bool errno_set = true;
1722
1723   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
1724     return 0;
1725
1726   /* Stabilize and compute the argument.  */
1727   if (TREE_CODE (TREE_VALUE (arglist)) != VAR_DECL
1728       && TREE_CODE (TREE_VALUE (arglist)) != PARM_DECL)
1729     {
1730       exp = copy_node (exp);
1731       TREE_OPERAND (exp, 1) = arglist;
1732       /* Wrap the computation of the argument in a SAVE_EXPR.  That
1733          way, if we need to expand the argument again (as in the
1734          flag_errno_math case below where we cannot directly set
1735          errno), we will not perform side-effects more than once.
1736          Note that here we're mutating the original EXP as well as the
1737          copy; that's the right thing to do in case the original EXP
1738          is expanded later.  */
1739       TREE_VALUE (arglist) = save_expr (TREE_VALUE (arglist));
1740       arglist = copy_node (arglist);
1741     }
1742   op0 = expand_expr (TREE_VALUE (arglist), subtarget, VOIDmode, 0);
1743
1744   /* Make a suitable register to place result in.  */
1745   target = gen_reg_rtx (TYPE_MODE (TREE_TYPE (exp)));
1746
1747   emit_queue ();
1748   start_sequence ();
1749
1750   switch (DECL_FUNCTION_CODE (fndecl))
1751     {
1752     case BUILT_IN_SIN:
1753     case BUILT_IN_SINF:
1754     case BUILT_IN_SINL:
1755       builtin_optab = sin_optab; break;
1756     case BUILT_IN_COS:
1757     case BUILT_IN_COSF:
1758     case BUILT_IN_COSL:
1759       builtin_optab = cos_optab; break;
1760     case BUILT_IN_SQRT:
1761     case BUILT_IN_SQRTF:
1762     case BUILT_IN_SQRTL:
1763       builtin_optab = sqrt_optab; break;
1764     case BUILT_IN_EXP:
1765     case BUILT_IN_EXPF:
1766     case BUILT_IN_EXPL:
1767       builtin_optab = exp_optab; break;
1768     case BUILT_IN_LOG:
1769     case BUILT_IN_LOGF:
1770     case BUILT_IN_LOGL:
1771       builtin_optab = log_optab; break;
1772     case BUILT_IN_FLOOR:
1773     case BUILT_IN_FLOORF:
1774     case BUILT_IN_FLOORL:
1775       errno_set = false ; builtin_optab = floor_optab; break;
1776     case BUILT_IN_CEIL:
1777     case BUILT_IN_CEILF:
1778     case BUILT_IN_CEILL:
1779       errno_set = false ; builtin_optab = ceil_optab; break;
1780     case BUILT_IN_TRUNC:
1781     case BUILT_IN_TRUNCF:
1782     case BUILT_IN_TRUNCL:
1783       errno_set = false ; builtin_optab = trunc_optab; break;
1784     case BUILT_IN_ROUND:
1785     case BUILT_IN_ROUNDF:
1786     case BUILT_IN_ROUNDL:
1787       errno_set = false ; builtin_optab = round_optab; break;
1788     case BUILT_IN_NEARBYINT:
1789     case BUILT_IN_NEARBYINTF:
1790     case BUILT_IN_NEARBYINTL:
1791       errno_set = false ; builtin_optab = nearbyint_optab; break;
1792     default:
1793       abort ();
1794     }
1795
1796   /* Compute into TARGET.
1797      Set TARGET to wherever the result comes back.  */
1798   argmode = TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist)));
1799   target = expand_unop (argmode, builtin_optab, op0, target, 0);
1800
1801   /* If we were unable to expand via the builtin, stop the
1802      sequence (without outputting the insns) and return 0, causing
1803      a call to the library function.  */
1804   if (target == 0)
1805     {
1806       end_sequence ();
1807       return 0;
1808     }
1809
1810   if (errno_set)
1811     expand_errno_check (exp, target);
1812
1813   /* Output the entire sequence.  */
1814   insns = get_insns ();
1815   end_sequence ();
1816   emit_insn (insns);
1817
1818   return target;
1819 }
1820
1821 /* Expand a call to the builtin binary math functions (pow and atan2).
1822    Return 0 if a normal call should be emitted rather than expanding the
1823    function in-line.  EXP is the expression that is a call to the builtin
1824    function; if convenient, the result should be placed in TARGET.
1825    SUBTARGET may be used as the target for computing one of EXP's
1826    operands.  */
1827
1828 static rtx
1829 expand_builtin_mathfn_2 (exp, target, subtarget)
1830      tree exp;
1831      rtx target, subtarget;
1832 {
1833   optab builtin_optab;
1834   rtx op0, op1, insns;
1835   tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
1836   tree arglist = TREE_OPERAND (exp, 1);
1837   tree arg0, arg1;
1838   enum machine_mode argmode;
1839   bool errno_set = true;
1840   bool stable = true;
1841
1842   if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
1843     return 0;
1844
1845   arg0 = TREE_VALUE (arglist);
1846   arg1 = TREE_VALUE (TREE_CHAIN (arglist));
1847
1848   /* Stabilize the arguments.  */
1849   if (TREE_CODE (arg0) != VAR_DECL && TREE_CODE (arg0) != PARM_DECL)
1850     {
1851       arg0 = save_expr (arg0);
1852       TREE_VALUE (arglist) = arg0;
1853       stable = false;
1854     }
1855   if (TREE_CODE (arg1) != VAR_DECL && TREE_CODE (arg1) != PARM_DECL)
1856     {
1857       arg1 = save_expr (arg1);
1858       TREE_VALUE (TREE_CHAIN (arglist)) = arg1;
1859       stable = false;
1860     }
1861
1862   if (! stable)
1863     {
1864       exp = copy_node (exp);
1865       arglist = tree_cons (NULL_TREE, arg0,
1866                            build_tree_list (NULL_TREE, arg1));
1867       TREE_OPERAND (exp, 1) = arglist;
1868     }
1869
1870   op0 = expand_expr (arg0, subtarget, VOIDmode, 0);
1871   op1 = expand_expr (arg1, 0, VOIDmode, 0);
1872
1873   /* Make a suitable register to place result in.  */
1874   target = gen_reg_rtx (TYPE_MODE (TREE_TYPE (exp)));
1875
1876   emit_queue ();
1877   start_sequence ();
1878
1879   switch (DECL_FUNCTION_CODE (fndecl))
1880     {
1881     case BUILT_IN_POW:
1882     case BUILT_IN_POWF:
1883     case BUILT_IN_POWL:
1884       builtin_optab = pow_optab; break;
1885     case BUILT_IN_ATAN2:
1886     case BUILT_IN_ATAN2F:
1887     case BUILT_IN_ATAN2L:
1888       builtin_optab = atan2_optab; break;
1889     default:
1890       abort ();
1891     }
1892
1893   /* Compute into TARGET.
1894      Set TARGET to wherever the result comes back.  */
1895   argmode = TYPE_MODE (TREE_TYPE (arg0));
1896   target = expand_binop (argmode, builtin_optab, op0, op1,
1897                          target, 0, OPTAB_DIRECT);
1898
1899   /* If we were unable to expand via the builtin, stop the
1900      sequence (without outputting the insns) and return 0, causing
1901      a call to the library function.  */
1902   if (target == 0)
1903     {
1904       end_sequence ();
1905       return 0;
1906     }
1907
1908   if (errno_set)
1909     expand_errno_check (exp, target);
1910
1911   /* Output the entire sequence.  */
1912   insns = get_insns ();
1913   end_sequence ();
1914   emit_insn (insns);
1915
1916   return target;
1917 }
1918
1919 /* Expand expression EXP which is a call to the strlen builtin.  Return 0
1920    if we failed the caller should emit a normal call, otherwise
1921    try to get the result in TARGET, if convenient.  */
1922
1923 static rtx
1924 expand_builtin_strlen (exp, target)
1925      tree exp;
1926      rtx target;
1927 {
1928   tree arglist = TREE_OPERAND (exp, 1);
1929   enum machine_mode value_mode = TYPE_MODE (TREE_TYPE (exp));
1930
1931   if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
1932     return 0;
1933   else
1934     {
1935       rtx pat;
1936       tree src = TREE_VALUE (arglist);
1937
1938       int align
1939         = get_pointer_alignment (src, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
1940
1941       rtx result, src_reg, char_rtx, before_strlen;
1942       enum machine_mode insn_mode = value_mode, char_mode;
1943       enum insn_code icode = CODE_FOR_nothing;
1944
1945       /* If SRC is not a pointer type, don't do this operation inline.  */
1946       if (align == 0)
1947         return 0;
1948
1949       /* Bail out if we can't compute strlen in the right mode.  */
1950       while (insn_mode != VOIDmode)
1951         {
1952           icode = strlen_optab->handlers[(int) insn_mode].insn_code;
1953           if (icode != CODE_FOR_nothing)
1954             break;
1955
1956           insn_mode = GET_MODE_WIDER_MODE (insn_mode);
1957         }
1958       if (insn_mode == VOIDmode)
1959         return 0;
1960
1961       /* Make a place to write the result of the instruction.  */
1962       result = target;
1963       if (! (result != 0
1964              && GET_CODE (result) == REG
1965              && GET_MODE (result) == insn_mode
1966              && REGNO (result) >= FIRST_PSEUDO_REGISTER))
1967         result = gen_reg_rtx (insn_mode);
1968
1969       /* Make a place to hold the source address.  We will not expand
1970          the actual source until we are sure that the expansion will
1971          not fail -- there are trees that cannot be expanded twice.  */
1972       src_reg = gen_reg_rtx (Pmode);
1973
1974       /* Mark the beginning of the strlen sequence so we can emit the
1975          source operand later.  */
1976       before_strlen = get_last_insn ();
1977
1978       char_rtx = const0_rtx;
1979       char_mode = insn_data[(int) icode].operand[2].mode;
1980       if (! (*insn_data[(int) icode].operand[2].predicate) (char_rtx,
1981                                                             char_mode))
1982         char_rtx = copy_to_mode_reg (char_mode, char_rtx);
1983
1984       pat = GEN_FCN (icode) (result, gen_rtx_MEM (BLKmode, src_reg),
1985                              char_rtx, GEN_INT (align));
1986       if (! pat)
1987         return 0;
1988       emit_insn (pat);
1989
1990       /* Now that we are assured of success, expand the source.  */
1991       start_sequence ();
1992       pat = memory_address (BLKmode,
1993                             expand_expr (src, src_reg, ptr_mode, EXPAND_SUM));
1994       if (pat != src_reg)
1995         emit_move_insn (src_reg, pat);
1996       pat = get_insns ();
1997       end_sequence ();
1998
1999       if (before_strlen)
2000         emit_insn_after (pat, before_strlen);
2001       else
2002         emit_insn_before (pat, get_insns ());
2003
2004       /* Return the value in the proper mode for this function.  */
2005       if (GET_MODE (result) == value_mode)
2006         target = result;
2007       else if (target != 0)
2008         convert_move (target, result, 0);
2009       else
2010         target = convert_to_mode (value_mode, result, 0);
2011
2012       return target;
2013     }
2014 }
2015
2016 /* Expand a call to the strstr builtin.  Return 0 if we failed the
2017    caller should emit a normal call, otherwise try to get the result
2018    in TARGET, if convenient (and in mode MODE if that's convenient).  */
2019
2020 static rtx
2021 expand_builtin_strstr (arglist, target, mode)
2022      tree arglist;
2023      rtx target;
2024      enum machine_mode mode;
2025 {
2026   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2027     return 0;
2028   else
2029     {
2030       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
2031       tree fn;
2032       const char *p1, *p2;
2033
2034       p2 = c_getstr (s2);
2035       if (p2 == NULL)
2036         return 0;
2037
2038       p1 = c_getstr (s1);
2039       if (p1 != NULL)
2040         {
2041           const char *r = strstr (p1, p2);
2042
2043           if (r == NULL)
2044             return const0_rtx;
2045
2046           /* Return an offset into the constant string argument.  */
2047           return expand_expr (fold (build (PLUS_EXPR, TREE_TYPE (s1),
2048                                            s1, ssize_int (r - p1))),
2049                               target, mode, EXPAND_NORMAL);
2050         }
2051
2052       if (p2[0] == '\0')
2053         return expand_expr (s1, target, mode, EXPAND_NORMAL);
2054
2055       if (p2[1] != '\0')
2056         return 0;
2057
2058       fn = implicit_built_in_decls[BUILT_IN_STRCHR];
2059       if (!fn)
2060         return 0;
2061
2062       /* New argument list transforming strstr(s1, s2) to
2063          strchr(s1, s2[0]).  */
2064       arglist =
2065         build_tree_list (NULL_TREE, build_int_2 (p2[0], 0));
2066       arglist = tree_cons (NULL_TREE, s1, arglist);
2067       return expand_expr (build_function_call_expr (fn, arglist),
2068                           target, mode, EXPAND_NORMAL);
2069     }
2070 }
2071
2072 /* Expand a call to the strchr builtin.  Return 0 if we failed the
2073    caller should emit a normal call, otherwise try to get the result
2074    in TARGET, if convenient (and in mode MODE if that's convenient).  */
2075
2076 static rtx
2077 expand_builtin_strchr (arglist, target, mode)
2078      tree arglist;
2079      rtx target;
2080      enum machine_mode mode;
2081 {
2082   if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2083     return 0;
2084   else
2085     {
2086       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
2087       const char *p1;
2088
2089       if (TREE_CODE (s2) != INTEGER_CST)
2090         return 0;
2091
2092       p1 = c_getstr (s1);
2093       if (p1 != NULL)
2094         {
2095           char c;
2096           const char *r;
2097
2098           if (target_char_cast (s2, &c))
2099             return 0;
2100
2101           r = strchr (p1, c);
2102
2103           if (r == NULL)
2104             return const0_rtx;
2105
2106           /* Return an offset into the constant string argument.  */
2107           return expand_expr (fold (build (PLUS_EXPR, TREE_TYPE (s1),
2108                                            s1, ssize_int (r - p1))),
2109                               target, mode, EXPAND_NORMAL);
2110         }
2111
2112       /* FIXME: Should use here strchrM optab so that ports can optimize
2113          this.  */
2114       return 0;
2115     }
2116 }
2117
2118 /* Expand a call to the strrchr builtin.  Return 0 if we failed the
2119    caller should emit a normal call, otherwise try to get the result
2120    in TARGET, if convenient (and in mode MODE if that's convenient).  */
2121
2122 static rtx
2123 expand_builtin_strrchr (arglist, target, mode)
2124      tree arglist;
2125      rtx target;
2126      enum machine_mode mode;
2127 {
2128   if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2129     return 0;
2130   else
2131     {
2132       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
2133       tree fn;
2134       const char *p1;
2135
2136       if (TREE_CODE (s2) != INTEGER_CST)
2137         return 0;
2138
2139       p1 = c_getstr (s1);
2140       if (p1 != NULL)
2141         {
2142           char c;
2143           const char *r;
2144
2145           if (target_char_cast (s2, &c))
2146             return 0;
2147
2148           r = strrchr (p1, c);
2149
2150           if (r == NULL)
2151             return const0_rtx;
2152
2153           /* Return an offset into the constant string argument.  */
2154           return expand_expr (fold (build (PLUS_EXPR, TREE_TYPE (s1),
2155                                            s1, ssize_int (r - p1))),
2156                               target, mode, EXPAND_NORMAL);
2157         }
2158
2159       if (! integer_zerop (s2))
2160         return 0;
2161
2162       fn = implicit_built_in_decls[BUILT_IN_STRCHR];
2163       if (!fn)
2164         return 0;
2165
2166       /* Transform strrchr(s1, '\0') to strchr(s1, '\0').  */
2167       return expand_expr (build_function_call_expr (fn, arglist),
2168                           target, mode, EXPAND_NORMAL);
2169     }
2170 }
2171
2172 /* Expand a call to the strpbrk builtin.  Return 0 if we failed the
2173    caller should emit a normal call, otherwise try to get the result
2174    in TARGET, if convenient (and in mode MODE if that's convenient).  */
2175
2176 static rtx
2177 expand_builtin_strpbrk (arglist, target, mode)
2178      tree arglist;
2179      rtx target;
2180      enum machine_mode mode;
2181 {
2182   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2183     return 0;
2184   else
2185     {
2186       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
2187       tree fn;
2188       const char *p1, *p2;
2189
2190       p2 = c_getstr (s2);
2191       if (p2 == NULL)
2192         return 0;
2193
2194       p1 = c_getstr (s1);
2195       if (p1 != NULL)
2196         {
2197           const char *r = strpbrk (p1, p2);
2198
2199           if (r == NULL)
2200             return const0_rtx;
2201
2202           /* Return an offset into the constant string argument.  */
2203           return expand_expr (fold (build (PLUS_EXPR, TREE_TYPE (s1),
2204                                            s1, ssize_int (r - p1))),
2205                               target, mode, EXPAND_NORMAL);
2206         }
2207
2208       if (p2[0] == '\0')
2209         {
2210           /* strpbrk(x, "") == NULL.
2211              Evaluate and ignore the arguments in case they had
2212              side-effects.  */
2213           expand_expr (s1, const0_rtx, VOIDmode, EXPAND_NORMAL);
2214           return const0_rtx;
2215         }
2216
2217       if (p2[1] != '\0')
2218         return 0;  /* Really call strpbrk.  */
2219
2220       fn = implicit_built_in_decls[BUILT_IN_STRCHR];
2221       if (!fn)
2222         return 0;
2223
2224       /* New argument list transforming strpbrk(s1, s2) to
2225          strchr(s1, s2[0]).  */
2226       arglist =
2227         build_tree_list (NULL_TREE, build_int_2 (p2[0], 0));
2228       arglist = tree_cons (NULL_TREE, s1, arglist);
2229       return expand_expr (build_function_call_expr (fn, arglist),
2230                           target, mode, EXPAND_NORMAL);
2231     }
2232 }
2233
2234 /* Callback routine for store_by_pieces.  Read GET_MODE_BITSIZE (MODE)
2235    bytes from constant string DATA + OFFSET and return it as target
2236    constant.  */
2237
2238 static rtx
2239 builtin_memcpy_read_str (data, offset, mode)
2240      PTR data;
2241      HOST_WIDE_INT offset;
2242      enum machine_mode mode;
2243 {
2244   const char *str = (const char *) data;
2245
2246   if (offset < 0
2247       || ((unsigned HOST_WIDE_INT) offset + GET_MODE_SIZE (mode)
2248           > strlen (str) + 1))
2249     abort ();  /* Attempt to read past the end of constant string.  */
2250
2251   return c_readstr (str + offset, mode);
2252 }
2253
2254 /* Expand a call to the memcpy builtin, with arguments in ARGLIST.
2255    Return 0 if we failed, the caller should emit a normal call, otherwise
2256    try to get the result in TARGET, if convenient (and in mode MODE if
2257    that's convenient).  */
2258
2259 static rtx
2260 expand_builtin_memcpy (arglist, target, mode)
2261      tree arglist;
2262      rtx target;
2263      enum machine_mode mode;
2264 {
2265   if (!validate_arglist (arglist,
2266                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2267     return 0;
2268   else
2269     {
2270       tree dest = TREE_VALUE (arglist);
2271       tree src = TREE_VALUE (TREE_CHAIN (arglist));
2272       tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2273       const char *src_str;
2274
2275       unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
2276       unsigned int dest_align
2277         = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2278       rtx dest_mem, src_mem, dest_addr, len_rtx;
2279
2280       /* If DEST is not a pointer type, call the normal function.  */
2281       if (dest_align == 0)
2282         return 0;
2283
2284       /* If the LEN parameter is zero, return DEST.  */
2285       if (host_integerp (len, 1) && tree_low_cst (len, 1) == 0)
2286         {
2287           /* Evaluate and ignore SRC in case it has side-effects.  */
2288           expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
2289           return expand_expr (dest, target, mode, EXPAND_NORMAL);
2290         }
2291
2292       /* If either SRC is not a pointer type, don't do this
2293          operation in-line.  */
2294       if (src_align == 0)
2295         return 0;
2296
2297       dest_mem = get_memory_rtx (dest);
2298       set_mem_align (dest_mem, dest_align);
2299       len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
2300       src_str = c_getstr (src);
2301
2302       /* If SRC is a string constant and block move would be done
2303          by pieces, we can avoid loading the string from memory
2304          and only stored the computed constants.  */
2305       if (src_str
2306           && GET_CODE (len_rtx) == CONST_INT
2307           && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
2308           && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
2309                                   (PTR) src_str, dest_align))
2310         {
2311           store_by_pieces (dest_mem, INTVAL (len_rtx),
2312                            builtin_memcpy_read_str,
2313                            (PTR) src_str, dest_align);
2314           dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2315 #ifdef POINTERS_EXTEND_UNSIGNED
2316           if (GET_MODE (dest_mem) != ptr_mode)
2317             dest_mem = convert_memory_address (ptr_mode, dest_mem);
2318 #endif
2319           return dest_mem;
2320         }
2321
2322       src_mem = get_memory_rtx (src);
2323       set_mem_align (src_mem, src_align);
2324
2325       /* Copy word part most expediently.  */
2326       dest_addr = emit_block_move (dest_mem, src_mem, len_rtx,
2327                                    BLOCK_OP_NORMAL);
2328
2329       if (dest_addr == 0)
2330         {
2331           dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2332 #ifdef POINTERS_EXTEND_UNSIGNED
2333           if (GET_MODE (dest_addr) != ptr_mode)
2334             dest_addr = convert_memory_address (ptr_mode, dest_addr);
2335 #endif
2336         }
2337
2338       return dest_addr;
2339     }
2340 }
2341
2342 /* Expand expression EXP, which is a call to the strcpy builtin.  Return 0
2343    if we failed the caller should emit a normal call, otherwise try to get
2344    the result in TARGET, if convenient (and in mode MODE if that's
2345    convenient).  */
2346
2347 static rtx
2348 expand_builtin_strcpy (exp, target, mode)
2349      tree exp;
2350      rtx target;
2351      enum machine_mode mode;
2352 {
2353   tree arglist = TREE_OPERAND (exp, 1);
2354   tree fn, len;
2355
2356   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2357     return 0;
2358
2359   fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
2360   if (!fn)
2361     return 0;
2362
2363   len = c_strlen (TREE_VALUE (TREE_CHAIN (arglist)));
2364   if (len == 0)
2365     return 0;
2366
2367   len = size_binop (PLUS_EXPR, len, ssize_int (1));
2368   chainon (arglist, build_tree_list (NULL_TREE, len));
2369   return expand_expr (build_function_call_expr (fn, arglist),
2370                       target, mode, EXPAND_NORMAL);
2371 }
2372
2373 /* Callback routine for store_by_pieces.  Read GET_MODE_BITSIZE (MODE)
2374    bytes from constant string DATA + OFFSET and return it as target
2375    constant.  */
2376
2377 static rtx
2378 builtin_strncpy_read_str (data, offset, mode)
2379      PTR data;
2380      HOST_WIDE_INT offset;
2381      enum machine_mode mode;
2382 {
2383   const char *str = (const char *) data;
2384
2385   if ((unsigned HOST_WIDE_INT) offset > strlen (str))
2386     return const0_rtx;
2387
2388   return c_readstr (str + offset, mode);
2389 }
2390
2391 /* Expand expression EXP, which is a call to the strncpy builtin.  Return 0
2392    if we failed the caller should emit a normal call.  */
2393
2394 static rtx
2395 expand_builtin_strncpy (arglist, target, mode)
2396      tree arglist;
2397      rtx target;
2398      enum machine_mode mode;
2399 {
2400   if (!validate_arglist (arglist,
2401                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2402     return 0;
2403   else
2404     {
2405       tree slen = c_strlen (TREE_VALUE (TREE_CHAIN (arglist)));
2406       tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2407       tree fn;
2408
2409       /* We must be passed a constant len parameter.  */
2410       if (TREE_CODE (len) != INTEGER_CST)
2411         return 0;
2412
2413       /* If the len parameter is zero, return the dst parameter.  */
2414       if (integer_zerop (len))
2415         {
2416           /* Evaluate and ignore the src argument in case it has
2417              side-effects.  */
2418           expand_expr (TREE_VALUE (TREE_CHAIN (arglist)), const0_rtx,
2419                        VOIDmode, EXPAND_NORMAL);
2420           /* Return the dst parameter.  */
2421           return expand_expr (TREE_VALUE (arglist), target, mode,
2422                               EXPAND_NORMAL);
2423         }
2424
2425       /* Now, we must be passed a constant src ptr parameter.  */
2426       if (slen == 0 || TREE_CODE (slen) != INTEGER_CST)
2427         return 0;
2428
2429       slen = size_binop (PLUS_EXPR, slen, ssize_int (1));
2430
2431       /* We're required to pad with trailing zeros if the requested
2432          len is greater than strlen(s2)+1.  In that case try to
2433          use store_by_pieces, if it fails, punt.  */
2434       if (tree_int_cst_lt (slen, len))
2435         {
2436           tree dest = TREE_VALUE (arglist);
2437           unsigned int dest_align
2438             = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2439           const char *p = c_getstr (TREE_VALUE (TREE_CHAIN (arglist)));
2440           rtx dest_mem;
2441
2442           if (!p || dest_align == 0 || !host_integerp (len, 1)
2443               || !can_store_by_pieces (tree_low_cst (len, 1),
2444                                        builtin_strncpy_read_str,
2445                                        (PTR) p, dest_align))
2446             return 0;
2447
2448           dest_mem = get_memory_rtx (dest);
2449           store_by_pieces (dest_mem, tree_low_cst (len, 1),
2450                            builtin_strncpy_read_str,
2451                            (PTR) p, dest_align);
2452           dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2453 #ifdef POINTERS_EXTEND_UNSIGNED
2454           if (GET_MODE (dest_mem) != ptr_mode)
2455             dest_mem = convert_memory_address (ptr_mode, dest_mem);
2456 #endif
2457           return dest_mem;
2458         }
2459
2460       /* OK transform into builtin memcpy.  */
2461       fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
2462       if (!fn)
2463         return 0;
2464       return expand_expr (build_function_call_expr (fn, arglist),
2465                           target, mode, EXPAND_NORMAL);
2466     }
2467 }
2468
2469 /* Callback routine for store_by_pieces.  Read GET_MODE_BITSIZE (MODE)
2470    bytes from constant string DATA + OFFSET and return it as target
2471    constant.  */
2472
2473 static rtx
2474 builtin_memset_read_str (data, offset, mode)
2475      PTR data;
2476      HOST_WIDE_INT offset ATTRIBUTE_UNUSED;
2477      enum machine_mode mode;
2478 {
2479   const char *c = (const char *) data;
2480   char *p = alloca (GET_MODE_SIZE (mode));
2481
2482   memset (p, *c, GET_MODE_SIZE (mode));
2483
2484   return c_readstr (p, mode);
2485 }
2486
2487 /* Callback routine for store_by_pieces.  Return the RTL of a register
2488    containing GET_MODE_SIZE (MODE) consecutive copies of the unsigned
2489    char value given in the RTL register data.  For example, if mode is
2490    4 bytes wide, return the RTL for 0x01010101*data.  */
2491
2492 static rtx
2493 builtin_memset_gen_str (data, offset, mode)
2494      PTR data;
2495      HOST_WIDE_INT offset ATTRIBUTE_UNUSED;
2496      enum machine_mode mode;
2497 {
2498   rtx target, coeff;
2499   size_t size;
2500   char *p;
2501
2502   size = GET_MODE_SIZE (mode);
2503   if (size == 1)
2504     return (rtx) data;
2505
2506   p = alloca (size);
2507   memset (p, 1, size);
2508   coeff = c_readstr (p, mode);
2509
2510   target = convert_to_mode (mode, (rtx) data, 1);
2511   target = expand_mult (mode, target, coeff, NULL_RTX, 1);
2512   return force_reg (mode, target);
2513 }
2514
2515 /* Expand expression EXP, which is a call to the memset builtin.  Return 0
2516    if we failed the caller should emit a normal call, otherwise try to get
2517    the result in TARGET, if convenient (and in mode MODE if that's
2518    convenient).  */
2519
2520 static rtx
2521 expand_builtin_memset (exp, target, mode)
2522      tree exp;
2523      rtx target;
2524      enum machine_mode mode;
2525 {
2526   tree arglist = TREE_OPERAND (exp, 1);
2527
2528   if (!validate_arglist (arglist,
2529                          POINTER_TYPE, INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
2530     return 0;
2531   else
2532     {
2533       tree dest = TREE_VALUE (arglist);
2534       tree val = TREE_VALUE (TREE_CHAIN (arglist));
2535       tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2536       char c;
2537
2538       unsigned int dest_align
2539         = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2540       rtx dest_mem, dest_addr, len_rtx;
2541
2542       /* If DEST is not a pointer type, don't do this
2543          operation in-line.  */
2544       if (dest_align == 0)
2545         return 0;
2546
2547       /* If the LEN parameter is zero, return DEST.  */
2548       if (host_integerp (len, 1) && tree_low_cst (len, 1) == 0)
2549         {
2550           /* Evaluate and ignore VAL in case it has side-effects.  */
2551           expand_expr (val, const0_rtx, VOIDmode, EXPAND_NORMAL);
2552           return expand_expr (dest, target, mode, EXPAND_NORMAL);
2553         }
2554
2555       if (TREE_CODE (val) != INTEGER_CST)
2556         {
2557           rtx val_rtx;
2558
2559           if (!host_integerp (len, 1))
2560             return 0;
2561
2562           if (optimize_size && tree_low_cst (len, 1) > 1)
2563             return 0;
2564
2565           /* Assume that we can memset by pieces if we can store the
2566            * the coefficients by pieces (in the required modes).
2567            * We can't pass builtin_memset_gen_str as that emits RTL.  */
2568           c = 1;
2569           if (!can_store_by_pieces (tree_low_cst (len, 1),
2570                                     builtin_memset_read_str,
2571                                     (PTR) &c, dest_align))
2572             return 0;
2573
2574           val = fold (build1 (CONVERT_EXPR, unsigned_char_type_node, val));
2575           val_rtx = expand_expr (val, NULL_RTX, VOIDmode, 0);
2576           val_rtx = force_reg (TYPE_MODE (unsigned_char_type_node),
2577                                val_rtx);
2578           dest_mem = get_memory_rtx (dest);
2579           store_by_pieces (dest_mem, tree_low_cst (len, 1),
2580                            builtin_memset_gen_str,
2581                            (PTR) val_rtx, dest_align);
2582           dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2583 #ifdef POINTERS_EXTEND_UNSIGNED
2584           if (GET_MODE (dest_mem) != ptr_mode)
2585             dest_mem = convert_memory_address (ptr_mode, dest_mem);
2586 #endif
2587           return dest_mem;
2588         }
2589
2590       if (target_char_cast (val, &c))
2591         return 0;
2592
2593       if (c)
2594         {
2595           if (!host_integerp (len, 1))
2596             return 0;
2597           if (!can_store_by_pieces (tree_low_cst (len, 1),
2598                                     builtin_memset_read_str, (PTR) &c,
2599                                     dest_align))
2600             return 0;
2601
2602           dest_mem = get_memory_rtx (dest);
2603           store_by_pieces (dest_mem, tree_low_cst (len, 1),
2604                            builtin_memset_read_str,
2605                            (PTR) &c, dest_align);
2606           dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2607 #ifdef POINTERS_EXTEND_UNSIGNED
2608           if (GET_MODE (dest_mem) != ptr_mode)
2609             dest_mem = convert_memory_address (ptr_mode, dest_mem);
2610 #endif
2611           return dest_mem;
2612         }
2613
2614       len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
2615
2616       dest_mem = get_memory_rtx (dest);
2617       set_mem_align (dest_mem, dest_align);
2618       dest_addr = clear_storage (dest_mem, len_rtx);
2619
2620       if (dest_addr == 0)
2621         {
2622           dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2623 #ifdef POINTERS_EXTEND_UNSIGNED
2624           if (GET_MODE (dest_addr) != ptr_mode)
2625             dest_addr = convert_memory_address (ptr_mode, dest_addr);
2626 #endif
2627         }
2628
2629       return dest_addr;
2630     }
2631 }
2632
2633 /* Expand expression EXP, which is a call to the bzero builtin.  Return 0
2634    if we failed the caller should emit a normal call.  */
2635
2636 static rtx
2637 expand_builtin_bzero (exp)
2638      tree exp;
2639 {
2640   tree arglist = TREE_OPERAND (exp, 1);
2641   tree dest, size, newarglist;
2642   rtx result;
2643
2644   if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2645     return NULL_RTX;
2646
2647   dest = TREE_VALUE (arglist);
2648   size = TREE_VALUE (TREE_CHAIN (arglist));
2649
2650   /* New argument list transforming bzero(ptr x, int y) to
2651      memset(ptr x, int 0, size_t y).   This is done this way
2652      so that if it isn't expanded inline, we fallback to
2653      calling bzero instead of memset.  */
2654
2655   newarglist = build_tree_list (NULL_TREE, convert (sizetype, size));
2656   newarglist = tree_cons (NULL_TREE, integer_zero_node, newarglist);
2657   newarglist = tree_cons (NULL_TREE, dest, newarglist);
2658
2659   TREE_OPERAND (exp, 1) = newarglist;
2660   result = expand_builtin_memset (exp, const0_rtx, VOIDmode);
2661
2662   /* Always restore the original arguments.  */
2663   TREE_OPERAND (exp, 1) = arglist;
2664
2665   return result;
2666 }
2667
2668 /* Expand expression EXP, which is a call to the memcmp or the strcmp builtin.
2669    ARGLIST is the argument list for this call.  Return 0 if we failed and the
2670    caller should emit a normal call, otherwise try to get the result in
2671    TARGET, if convenient (and in mode MODE, if that's convenient).  */
2672
2673 static rtx
2674 expand_builtin_memcmp (exp, arglist, target, mode)
2675      tree exp ATTRIBUTE_UNUSED;
2676      tree arglist;
2677      rtx target;
2678      enum machine_mode mode;
2679 {
2680   tree arg1, arg2, len;
2681   const char *p1, *p2;
2682
2683   if (!validate_arglist (arglist,
2684                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2685     return 0;
2686
2687   arg1 = TREE_VALUE (arglist);
2688   arg2 = TREE_VALUE (TREE_CHAIN (arglist));
2689   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2690
2691   /* If the len parameter is zero, return zero.  */
2692   if (host_integerp (len, 1) && tree_low_cst (len, 1) == 0)
2693     {
2694       /* Evaluate and ignore arg1 and arg2 in case they have
2695          side-effects.  */
2696       expand_expr (arg1, const0_rtx, VOIDmode, EXPAND_NORMAL);
2697       expand_expr (arg2, const0_rtx, VOIDmode, EXPAND_NORMAL);
2698       return const0_rtx;
2699     }
2700
2701   p1 = c_getstr (arg1);
2702   p2 = c_getstr (arg2);
2703
2704   /* If all arguments are constant, and the value of len is not greater
2705      than the lengths of arg1 and arg2, evaluate at compile-time.  */
2706   if (host_integerp (len, 1) && p1 && p2
2707       && compare_tree_int (len, strlen (p1) + 1) <= 0
2708       && compare_tree_int (len, strlen (p2) + 1) <= 0)
2709     {
2710       const int r = memcmp (p1, p2, tree_low_cst (len, 1));
2711
2712       return (r < 0 ? constm1_rtx : (r > 0 ? const1_rtx : const0_rtx));
2713     }
2714
2715   /* If len parameter is one, return an expression corresponding to
2716      (*(const unsigned char*)arg1 - (const unsigned char*)arg2).  */
2717   if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
2718     {
2719       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
2720       tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
2721       tree ind1 =
2722       fold (build1 (CONVERT_EXPR, integer_type_node,
2723                     build1 (INDIRECT_REF, cst_uchar_node,
2724                             build1 (NOP_EXPR, cst_uchar_ptr_node, arg1))));
2725       tree ind2 =
2726       fold (build1 (CONVERT_EXPR, integer_type_node,
2727                     build1 (INDIRECT_REF, cst_uchar_node,
2728                             build1 (NOP_EXPR, cst_uchar_ptr_node, arg2))));
2729       tree result = fold (build (MINUS_EXPR, integer_type_node, ind1, ind2));
2730       return expand_expr (result, target, mode, EXPAND_NORMAL);
2731     }
2732
2733 #ifdef HAVE_cmpstrsi
2734   {
2735     rtx arg1_rtx, arg2_rtx, arg3_rtx;
2736     rtx result;
2737     rtx insn;
2738
2739     int arg1_align
2740       = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
2741     int arg2_align
2742       = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
2743     enum machine_mode insn_mode
2744       = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
2745
2746     /* If we don't have POINTER_TYPE, call the function.  */
2747     if (arg1_align == 0 || arg2_align == 0)
2748       return 0;
2749
2750     /* Make a place to write the result of the instruction.  */
2751     result = target;
2752     if (! (result != 0
2753            && GET_CODE (result) == REG && GET_MODE (result) == insn_mode
2754            && REGNO (result) >= FIRST_PSEUDO_REGISTER))
2755       result = gen_reg_rtx (insn_mode);
2756
2757     arg1_rtx = get_memory_rtx (arg1);
2758     arg2_rtx = get_memory_rtx (arg2);
2759     arg3_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
2760     if (!HAVE_cmpstrsi)
2761       insn = NULL_RTX;
2762     else
2763       insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
2764                            GEN_INT (MIN (arg1_align, arg2_align)));
2765
2766     if (insn)
2767       emit_insn (insn);
2768     else
2769       emit_library_call_value (memcmp_libfunc, result, LCT_PURE_MAKE_BLOCK,
2770                                TYPE_MODE (integer_type_node), 3,
2771                                XEXP (arg1_rtx, 0), Pmode,
2772                                XEXP (arg2_rtx, 0), Pmode,
2773                                convert_to_mode (TYPE_MODE (sizetype), arg3_rtx,
2774                                                 TREE_UNSIGNED (sizetype)),
2775                                TYPE_MODE (sizetype));
2776
2777     /* Return the value in the proper mode for this function.  */
2778     mode = TYPE_MODE (TREE_TYPE (exp));
2779     if (GET_MODE (result) == mode)
2780       return result;
2781     else if (target != 0)
2782       {
2783         convert_move (target, result, 0);
2784         return target;
2785       }
2786     else
2787       return convert_to_mode (mode, result, 0);
2788   }
2789 #endif
2790
2791   return 0;
2792 }
2793
2794 /* Expand expression EXP, which is a call to the strcmp builtin.  Return 0
2795    if we failed the caller should emit a normal call, otherwise try to get
2796    the result in TARGET, if convenient.  */
2797
2798 static rtx
2799 expand_builtin_strcmp (exp, target, mode)
2800      tree exp;
2801      rtx target;
2802      enum machine_mode mode;
2803 {
2804   tree arglist = TREE_OPERAND (exp, 1);
2805   tree arg1, arg2, len, len2, fn;
2806   const char *p1, *p2;
2807
2808   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2809     return 0;
2810
2811   arg1 = TREE_VALUE (arglist);
2812   arg2 = TREE_VALUE (TREE_CHAIN (arglist));
2813
2814   p1 = c_getstr (arg1);
2815   p2 = c_getstr (arg2);
2816
2817   if (p1 && p2)
2818     {
2819       const int i = strcmp (p1, p2);
2820       return (i < 0 ? constm1_rtx : (i > 0 ? const1_rtx : const0_rtx));
2821     }
2822
2823   /* If either arg is "", return an expression corresponding to
2824      (*(const unsigned char*)arg1 - (const unsigned char*)arg2).  */
2825   if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
2826     {
2827       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
2828       tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
2829       tree ind1 =
2830         fold (build1 (CONVERT_EXPR, integer_type_node,
2831                       build1 (INDIRECT_REF, cst_uchar_node,
2832                               build1 (NOP_EXPR, cst_uchar_ptr_node, arg1))));
2833       tree ind2 =
2834         fold (build1 (CONVERT_EXPR, integer_type_node,
2835                       build1 (INDIRECT_REF, cst_uchar_node,
2836                               build1 (NOP_EXPR, cst_uchar_ptr_node, arg2))));
2837       tree result = fold (build (MINUS_EXPR, integer_type_node, ind1, ind2));
2838       return expand_expr (result, target, mode, EXPAND_NORMAL);
2839     }
2840
2841   len = c_strlen (arg1);
2842   len2 = c_strlen (arg2);
2843
2844   if (len)
2845     len = size_binop (PLUS_EXPR, ssize_int (1), len);
2846
2847   if (len2)
2848     len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
2849
2850   /* If we don't have a constant length for the first, use the length
2851      of the second, if we know it.  We don't require a constant for
2852      this case; some cost analysis could be done if both are available
2853      but neither is constant.  For now, assume they're equally cheap
2854      unless one has side effects.
2855
2856      If both strings have constant lengths, use the smaller.  This
2857      could arise if optimization results in strcpy being called with
2858      two fixed strings, or if the code was machine-generated.  We should
2859      add some code to the `memcmp' handler below to deal with such
2860      situations, someday.  */
2861
2862   if (!len || TREE_CODE (len) != INTEGER_CST)
2863     {
2864       if (len2 && !TREE_SIDE_EFFECTS (len2))
2865         len = len2;
2866       else if (len == 0)
2867         return 0;
2868     }
2869   else if (len2 && TREE_CODE (len2) == INTEGER_CST
2870            && tree_int_cst_lt (len2, len))
2871     len = len2;
2872
2873   /* If both arguments have side effects, we cannot optimize.  */
2874   if (TREE_SIDE_EFFECTS (len))
2875     return 0;
2876
2877   fn = implicit_built_in_decls[BUILT_IN_MEMCMP];
2878   if (!fn)
2879     return 0;
2880
2881   chainon (arglist, build_tree_list (NULL_TREE, len));
2882   return expand_expr (build_function_call_expr (fn, arglist),
2883                       target, mode, EXPAND_NORMAL);
2884 }
2885
2886 /* Expand expression EXP, which is a call to the strncmp builtin.  Return 0
2887    if we failed the caller should emit a normal call, otherwise try to get
2888    the result in TARGET, if convenient.  */
2889
2890 static rtx
2891 expand_builtin_strncmp (exp, target, mode)
2892      tree exp;
2893      rtx target;
2894      enum machine_mode mode;
2895 {
2896   tree arglist = TREE_OPERAND (exp, 1);
2897   tree fn, newarglist, len = 0;
2898   tree arg1, arg2, arg3;
2899   const char *p1, *p2;
2900
2901   if (!validate_arglist (arglist,
2902                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2903     return 0;
2904
2905   arg1 = TREE_VALUE (arglist);
2906   arg2 = TREE_VALUE (TREE_CHAIN (arglist));
2907   arg3 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2908
2909   /* If the len parameter is zero, return zero.  */
2910   if (host_integerp (arg3, 1) && tree_low_cst (arg3, 1) == 0)
2911     {
2912       /* Evaluate and ignore arg1 and arg2 in case they have
2913          side-effects.  */
2914       expand_expr (arg1, const0_rtx, VOIDmode, EXPAND_NORMAL);
2915       expand_expr (arg2, const0_rtx, VOIDmode, EXPAND_NORMAL);
2916       return const0_rtx;
2917     }
2918
2919   p1 = c_getstr (arg1);
2920   p2 = c_getstr (arg2);
2921
2922   /* If all arguments are constant, evaluate at compile-time.  */
2923   if (host_integerp (arg3, 1) && p1 && p2)
2924     {
2925       const int r = strncmp (p1, p2, tree_low_cst (arg3, 1));
2926       return (r < 0 ? constm1_rtx : (r > 0 ? const1_rtx : const0_rtx));
2927     }
2928
2929   /* If len == 1 or (either string parameter is "" and (len >= 1)),
2930       return (*(const u_char*)arg1 - *(const u_char*)arg2).  */
2931   if (host_integerp (arg3, 1)
2932       && (tree_low_cst (arg3, 1) == 1
2933           || (tree_low_cst (arg3, 1) > 1
2934               && ((p1 && *p1 == '\0') || (p2 && *p2 == '\0')))))
2935     {
2936       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
2937       tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
2938       tree ind1 =
2939         fold (build1 (CONVERT_EXPR, integer_type_node,
2940                       build1 (INDIRECT_REF, cst_uchar_node,
2941                               build1 (NOP_EXPR, cst_uchar_ptr_node, arg1))));
2942       tree ind2 =
2943         fold (build1 (CONVERT_EXPR, integer_type_node,
2944                       build1 (INDIRECT_REF, cst_uchar_node,
2945                               build1 (NOP_EXPR, cst_uchar_ptr_node, arg2))));
2946       tree result = fold (build (MINUS_EXPR, integer_type_node, ind1, ind2));
2947       return expand_expr (result, target, mode, EXPAND_NORMAL);
2948     }
2949
2950   /* If c_strlen can determine an expression for one of the string
2951      lengths, and it doesn't have side effects, then call
2952      expand_builtin_memcmp() using length MIN(strlen(string)+1, arg3).  */
2953
2954   /* Perhaps one of the strings is really constant, if so prefer
2955      that constant length over the other string's length.  */
2956   if (p1)
2957     len = c_strlen (arg1);
2958   else if (p2)
2959     len = c_strlen (arg2);
2960
2961   /* If we still don't have a len, try either string arg as long
2962      as they don't have side effects.  */
2963   if (!len && !TREE_SIDE_EFFECTS (arg1))
2964     len = c_strlen (arg1);
2965   if (!len && !TREE_SIDE_EFFECTS (arg2))
2966     len = c_strlen (arg2);
2967   /* If we still don't have a length, punt.  */
2968   if (!len)
2969     return 0;
2970
2971   fn = implicit_built_in_decls[BUILT_IN_MEMCMP];
2972   if (!fn)
2973     return 0;
2974
2975   /* Add one to the string length.  */
2976   len = fold (size_binop (PLUS_EXPR, len, ssize_int (1)));
2977
2978   /* The actual new length parameter is MIN(len,arg3).  */
2979   len = fold (build (MIN_EXPR, TREE_TYPE (len), len, arg3));
2980
2981   newarglist = build_tree_list (NULL_TREE, len);
2982   newarglist = tree_cons (NULL_TREE, arg2, newarglist);
2983   newarglist = tree_cons (NULL_TREE, arg1, newarglist);
2984   return expand_expr (build_function_call_expr (fn, newarglist),
2985                       target, mode, EXPAND_NORMAL);
2986 }
2987
2988 /* Expand expression EXP, which is a call to the strcat builtin.
2989    Return 0 if we failed the caller should emit a normal call,
2990    otherwise try to get the result in TARGET, if convenient.  */
2991
2992 static rtx
2993 expand_builtin_strcat (arglist, target, mode)
2994      tree arglist;
2995      rtx target;
2996      enum machine_mode mode;
2997 {
2998   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2999     return 0;
3000   else
3001     {
3002       tree dst = TREE_VALUE (arglist),
3003         src = TREE_VALUE (TREE_CHAIN (arglist));
3004       const char *p = c_getstr (src);
3005
3006       /* If the string length is zero, return the dst parameter.  */
3007       if (p && *p == '\0')
3008         return expand_expr (dst, target, mode, EXPAND_NORMAL);
3009
3010       return 0;
3011     }
3012 }
3013
3014 /* Expand expression EXP, which is a call to the strncat builtin.
3015    Return 0 if we failed the caller should emit a normal call,
3016    otherwise try to get the result in TARGET, if convenient.  */
3017
3018 static rtx
3019 expand_builtin_strncat (arglist, target, mode)
3020      tree arglist;
3021      rtx target;
3022      enum machine_mode mode;
3023 {
3024   if (!validate_arglist (arglist,
3025                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3026     return 0;
3027   else
3028     {
3029       tree dst = TREE_VALUE (arglist),
3030         src = TREE_VALUE (TREE_CHAIN (arglist)),
3031         len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3032       const char *p = c_getstr (src);
3033
3034       /* If the requested length is zero, or the src parameter string
3035           length is zero, return the dst parameter.  */
3036       if (integer_zerop (len) || (p && *p == '\0'))
3037         {
3038           /* Evaluate and ignore the src and len parameters in case
3039              they have side-effects.  */
3040           expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
3041           expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
3042           return expand_expr (dst, target, mode, EXPAND_NORMAL);
3043         }
3044
3045       /* If the requested len is greater than or equal to the string
3046          length, call strcat.  */
3047       if (TREE_CODE (len) == INTEGER_CST && p
3048           && compare_tree_int (len, strlen (p)) >= 0)
3049         {
3050           tree newarglist
3051             = tree_cons (NULL_TREE, dst, build_tree_list (NULL_TREE, src));
3052           tree fn = implicit_built_in_decls[BUILT_IN_STRCAT];
3053
3054           /* If the replacement _DECL isn't initialized, don't do the
3055              transformation.  */
3056           if (!fn)
3057             return 0;
3058
3059           return expand_expr (build_function_call_expr (fn, newarglist),
3060                               target, mode, EXPAND_NORMAL);
3061         }
3062       return 0;
3063     }
3064 }
3065
3066 /* Expand expression EXP, which is a call to the strspn builtin.
3067    Return 0 if we failed the caller should emit a normal call,
3068    otherwise try to get the result in TARGET, if convenient.  */
3069
3070 static rtx
3071 expand_builtin_strspn (arglist, target, mode)
3072      tree arglist;
3073      rtx target;
3074      enum machine_mode mode;
3075 {
3076   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3077     return 0;
3078   else
3079     {
3080       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
3081       const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
3082
3083       /* If both arguments are constants, evaluate at compile-time.  */
3084       if (p1 && p2)
3085         {
3086           const size_t r = strspn (p1, p2);
3087           return expand_expr (size_int (r), target, mode, EXPAND_NORMAL);
3088         }
3089
3090       /* If either argument is "", return 0.  */
3091       if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
3092         {
3093           /* Evaluate and ignore both arguments in case either one has
3094              side-effects.  */
3095           expand_expr (s1, const0_rtx, VOIDmode, EXPAND_NORMAL);
3096           expand_expr (s2, const0_rtx, VOIDmode, EXPAND_NORMAL);
3097           return const0_rtx;
3098         }
3099       return 0;
3100     }
3101 }
3102
3103 /* Expand expression EXP, which is a call to the strcspn builtin.
3104    Return 0 if we failed the caller should emit a normal call,
3105    otherwise try to get the result in TARGET, if convenient.  */
3106
3107 static rtx
3108 expand_builtin_strcspn (arglist, target, mode)
3109      tree arglist;
3110      rtx target;
3111      enum machine_mode mode;
3112 {
3113   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3114     return 0;
3115   else
3116     {
3117       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
3118       const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
3119
3120       /* If both arguments are constants, evaluate at compile-time.  */
3121       if (p1 && p2)
3122         {
3123           const size_t r = strcspn (p1, p2);
3124           return expand_expr (size_int (r), target, mode, EXPAND_NORMAL);
3125         }
3126
3127       /* If the first argument is "", return 0.  */
3128       if (p1 && *p1 == '\0')
3129         {
3130           /* Evaluate and ignore argument s2 in case it has
3131              side-effects.  */
3132           expand_expr (s2, const0_rtx, VOIDmode, EXPAND_NORMAL);
3133           return const0_rtx;
3134         }
3135
3136       /* If the second argument is "", return __builtin_strlen(s1).  */
3137       if (p2 && *p2 == '\0')
3138         {
3139           tree newarglist = build_tree_list (NULL_TREE, s1),
3140             fn = implicit_built_in_decls[BUILT_IN_STRLEN];
3141
3142           /* If the replacement _DECL isn't initialized, don't do the
3143              transformation.  */
3144           if (!fn)
3145             return 0;
3146
3147           return expand_expr (build_function_call_expr (fn, newarglist),
3148                               target, mode, EXPAND_NORMAL);
3149         }
3150       return 0;
3151     }
3152 }
3153
3154 /* Expand a call to __builtin_saveregs, generating the result in TARGET,
3155    if that's convenient.  */
3156
3157 rtx
3158 expand_builtin_saveregs ()
3159 {
3160   rtx val, seq;
3161
3162   /* Don't do __builtin_saveregs more than once in a function.
3163      Save the result of the first call and reuse it.  */
3164   if (saveregs_value != 0)
3165     return saveregs_value;
3166
3167   /* When this function is called, it means that registers must be
3168      saved on entry to this function.  So we migrate the call to the
3169      first insn of this function.  */
3170
3171   start_sequence ();
3172
3173 #ifdef EXPAND_BUILTIN_SAVEREGS
3174   /* Do whatever the machine needs done in this case.  */
3175   val = EXPAND_BUILTIN_SAVEREGS ();
3176 #else
3177   /* ??? We used to try and build up a call to the out of line function,
3178      guessing about what registers needed saving etc.  This became much
3179      harder with __builtin_va_start, since we don't have a tree for a
3180      call to __builtin_saveregs to fall back on.  There was exactly one
3181      port (i860) that used this code, and I'm unconvinced it could actually
3182      handle the general case.  So we no longer try to handle anything
3183      weird and make the backend absorb the evil.  */
3184
3185   error ("__builtin_saveregs not supported by this target");
3186   val = const0_rtx;
3187 #endif
3188
3189   seq = get_insns ();
3190   end_sequence ();
3191
3192   saveregs_value = val;
3193
3194   /* Put the insns after the NOTE that starts the function.  If this
3195      is inside a start_sequence, make the outer-level insn chain current, so
3196      the code is placed at the start of the function.  */
3197   push_topmost_sequence ();
3198   emit_insn_after (seq, get_insns ());
3199   pop_topmost_sequence ();
3200
3201   return val;
3202 }
3203
3204 /* __builtin_args_info (N) returns word N of the arg space info
3205    for the current function.  The number and meanings of words
3206    is controlled by the definition of CUMULATIVE_ARGS.  */
3207
3208 static rtx
3209 expand_builtin_args_info (exp)
3210      tree exp;
3211 {
3212   tree arglist = TREE_OPERAND (exp, 1);
3213   int nwords = sizeof (CUMULATIVE_ARGS) / sizeof (int);
3214   int *word_ptr = (int *) &current_function_args_info;
3215 #if 0
3216   /* These are used by the code below that is if 0'ed away */
3217   int i;
3218   tree type, elts, result;
3219 #endif
3220
3221   if (sizeof (CUMULATIVE_ARGS) % sizeof (int) != 0)
3222     abort ();
3223
3224   if (arglist != 0)
3225     {
3226       if (!host_integerp (TREE_VALUE (arglist), 0))
3227         error ("argument of `__builtin_args_info' must be constant");
3228       else
3229         {
3230           HOST_WIDE_INT wordnum = tree_low_cst (TREE_VALUE (arglist), 0);
3231
3232           if (wordnum < 0 || wordnum >= nwords)
3233             error ("argument of `__builtin_args_info' out of range");
3234           else
3235             return GEN_INT (word_ptr[wordnum]);
3236         }
3237     }
3238   else
3239     error ("missing argument in `__builtin_args_info'");
3240
3241   return const0_rtx;
3242
3243 #if 0
3244   for (i = 0; i < nwords; i++)
3245     elts = tree_cons (NULL_TREE, build_int_2 (word_ptr[i], 0));
3246
3247   type = build_array_type (integer_type_node,
3248                            build_index_type (build_int_2 (nwords, 0)));
3249   result = build (CONSTRUCTOR, type, NULL_TREE, nreverse (elts));
3250   TREE_CONSTANT (result) = 1;
3251   TREE_STATIC (result) = 1;
3252   result = build1 (INDIRECT_REF, build_pointer_type (type), result);
3253   TREE_CONSTANT (result) = 1;
3254   return expand_expr (result, NULL_RTX, VOIDmode, 0);
3255 #endif
3256 }
3257
3258 /* Expand ARGLIST, from a call to __builtin_next_arg.  */
3259
3260 static rtx
3261 expand_builtin_next_arg (arglist)
3262      tree arglist;
3263 {
3264   tree fntype = TREE_TYPE (current_function_decl);
3265
3266   if (TYPE_ARG_TYPES (fntype) == 0
3267       || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
3268           == void_type_node))
3269     {
3270       error ("`va_start' used in function with fixed args");
3271       return const0_rtx;
3272     }
3273
3274   if (arglist)
3275     {
3276       tree last_parm = tree_last (DECL_ARGUMENTS (current_function_decl));
3277       tree arg = TREE_VALUE (arglist);
3278
3279       /* Strip off all nops for the sake of the comparison.  This
3280          is not quite the same as STRIP_NOPS.  It does more.
3281          We must also strip off INDIRECT_EXPR for C++ reference
3282          parameters.  */
3283       while (TREE_CODE (arg) == NOP_EXPR
3284              || TREE_CODE (arg) == CONVERT_EXPR
3285              || TREE_CODE (arg) == NON_LVALUE_EXPR
3286              || TREE_CODE (arg) == INDIRECT_REF)
3287         arg = TREE_OPERAND (arg, 0);
3288       if (arg != last_parm)
3289         warning ("second parameter of `va_start' not last named argument");
3290     }
3291   else
3292     /* Evidently an out of date version of <stdarg.h>; can't validate
3293        va_start's second argument, but can still work as intended.  */
3294     warning ("`__builtin_next_arg' called without an argument");
3295
3296   return expand_binop (Pmode, add_optab,
3297                        current_function_internal_arg_pointer,
3298                        current_function_arg_offset_rtx,
3299                        NULL_RTX, 0, OPTAB_LIB_WIDEN);
3300 }
3301
3302 /* Make it easier for the backends by protecting the valist argument
3303    from multiple evaluations.  */
3304
3305 static tree
3306 stabilize_va_list (valist, needs_lvalue)
3307      tree valist;
3308      int needs_lvalue;
3309 {
3310   if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
3311     {
3312       if (TREE_SIDE_EFFECTS (valist))
3313         valist = save_expr (valist);
3314
3315       /* For this case, the backends will be expecting a pointer to
3316          TREE_TYPE (va_list_type_node), but it's possible we've
3317          actually been given an array (an actual va_list_type_node).
3318          So fix it.  */
3319       if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
3320         {
3321           tree p1 = build_pointer_type (TREE_TYPE (va_list_type_node));
3322           tree p2 = build_pointer_type (va_list_type_node);
3323
3324           valist = build1 (ADDR_EXPR, p2, valist);
3325           valist = fold (build1 (NOP_EXPR, p1, valist));
3326         }
3327     }
3328   else
3329     {
3330       tree pt;
3331
3332       if (! needs_lvalue)
3333         {
3334           if (! TREE_SIDE_EFFECTS (valist))
3335             return valist;
3336
3337           pt = build_pointer_type (va_list_type_node);
3338           valist = fold (build1 (ADDR_EXPR, pt, valist));
3339           TREE_SIDE_EFFECTS (valist) = 1;
3340         }
3341
3342       if (TREE_SIDE_EFFECTS (valist))
3343         valist = save_expr (valist);
3344       valist = fold (build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (valist)),
3345                              valist));
3346     }
3347
3348   return valist;
3349 }
3350
3351 /* The "standard" implementation of va_start: just assign `nextarg' to
3352    the variable.  */
3353
3354 void
3355 std_expand_builtin_va_start (valist, nextarg)
3356      tree valist;
3357      rtx nextarg;
3358 {
3359   tree t;
3360
3361   t = build (MODIFY_EXPR, TREE_TYPE (valist), valist,
3362              make_tree (ptr_type_node, nextarg));
3363   TREE_SIDE_EFFECTS (t) = 1;
3364
3365   expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
3366 }
3367
3368 /* Expand ARGLIST, from a call to __builtin_va_start.  */
3369
3370 static rtx
3371 expand_builtin_va_start (arglist)
3372      tree arglist;
3373 {
3374   rtx nextarg;
3375   tree chain, valist;
3376
3377   chain = TREE_CHAIN (arglist);
3378
3379   if (TREE_CHAIN (chain))
3380     error ("too many arguments to function `va_start'");
3381
3382   nextarg = expand_builtin_next_arg (chain);
3383   valist = stabilize_va_list (TREE_VALUE (arglist), 1);
3384
3385 #ifdef EXPAND_BUILTIN_VA_START
3386   EXPAND_BUILTIN_VA_START (valist, nextarg);
3387 #else
3388   std_expand_builtin_va_start (valist, nextarg);
3389 #endif
3390
3391   return const0_rtx;
3392 }
3393
3394 /* The "standard" implementation of va_arg: read the value from the
3395    current (padded) address and increment by the (padded) size.  */
3396
3397 rtx
3398 std_expand_builtin_va_arg (valist, type)
3399      tree valist, type;
3400 {
3401   tree addr_tree, t, type_size = NULL;
3402   tree align, alignm1;
3403   tree rounded_size;
3404   rtx addr;
3405
3406   /* Compute the rounded size of the type.  */
3407   align = size_int (PARM_BOUNDARY / BITS_PER_UNIT);
3408   alignm1 = size_int (PARM_BOUNDARY / BITS_PER_UNIT - 1);
3409   if (type == error_mark_node
3410       || (type_size = TYPE_SIZE_UNIT (TYPE_MAIN_VARIANT (type))) == NULL
3411       || TREE_OVERFLOW (type_size))
3412     rounded_size = size_zero_node;
3413   else
3414     rounded_size = fold (build (MULT_EXPR, sizetype,
3415                                 fold (build (TRUNC_DIV_EXPR, sizetype,
3416                                              fold (build (PLUS_EXPR, sizetype,
3417                                                           type_size, alignm1)),
3418                                              align)),
3419                                 align));
3420
3421   /* Get AP.  */
3422   addr_tree = valist;
3423   if (PAD_VARARGS_DOWN && ! integer_zerop (rounded_size))
3424     {
3425       /* Small args are padded downward.  */
3426       addr_tree = fold (build (PLUS_EXPR, TREE_TYPE (addr_tree), addr_tree,
3427                                fold (build (COND_EXPR, sizetype,
3428                                             fold (build (GT_EXPR, sizetype,
3429                                                          rounded_size,
3430                                                          align)),
3431                                             size_zero_node,
3432                                             fold (build (MINUS_EXPR, sizetype,
3433                                                          rounded_size,
3434                                                          type_size))))));
3435     }
3436
3437   addr = expand_expr (addr_tree, NULL_RTX, Pmode, EXPAND_NORMAL);
3438   addr = copy_to_reg (addr);
3439
3440   /* Compute new value for AP.  */
3441   if (! integer_zerop (rounded_size))
3442     {
3443       t = build (MODIFY_EXPR, TREE_TYPE (valist), valist,
3444                  build (PLUS_EXPR, TREE_TYPE (valist), valist,
3445                         rounded_size));
3446       TREE_SIDE_EFFECTS (t) = 1;
3447       expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
3448     }
3449
3450   return addr;
3451 }
3452
3453 /* Expand __builtin_va_arg, which is not really a builtin function, but
3454    a very special sort of operator.  */
3455
3456 rtx
3457 expand_builtin_va_arg (valist, type)
3458      tree valist, type;
3459 {
3460   rtx addr, result;
3461   tree promoted_type, want_va_type, have_va_type;
3462
3463   /* Verify that valist is of the proper type.  */
3464
3465   want_va_type = va_list_type_node;
3466   have_va_type = TREE_TYPE (valist);
3467   if (TREE_CODE (want_va_type) == ARRAY_TYPE)
3468     {
3469       /* If va_list is an array type, the argument may have decayed
3470          to a pointer type, e.g. by being passed to another function.
3471          In that case, unwrap both types so that we can compare the
3472          underlying records.  */
3473       if (TREE_CODE (have_va_type) == ARRAY_TYPE
3474           || TREE_CODE (have_va_type) == POINTER_TYPE)
3475         {
3476           want_va_type = TREE_TYPE (want_va_type);
3477           have_va_type = TREE_TYPE (have_va_type);
3478         }
3479     }
3480   if (TYPE_MAIN_VARIANT (want_va_type) != TYPE_MAIN_VARIANT (have_va_type))
3481     {
3482       error ("first argument to `va_arg' not of type `va_list'");
3483       addr = const0_rtx;
3484     }
3485
3486   /* Generate a diagnostic for requesting data of a type that cannot
3487      be passed through `...' due to type promotion at the call site.  */
3488   else if ((promoted_type = (*lang_hooks.types.type_promotes_to) (type))
3489            != type)
3490     {
3491       const char *name = "<anonymous type>", *pname = 0;
3492       static bool gave_help;
3493
3494       if (TYPE_NAME (type))
3495         {
3496           if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE)
3497             name = IDENTIFIER_POINTER (TYPE_NAME (type));
3498           else if (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
3499                    && DECL_NAME (TYPE_NAME (type)))
3500             name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type)));
3501         }
3502       if (TYPE_NAME (promoted_type))
3503         {
3504           if (TREE_CODE (TYPE_NAME (promoted_type)) == IDENTIFIER_NODE)
3505             pname = IDENTIFIER_POINTER (TYPE_NAME (promoted_type));
3506           else if (TREE_CODE (TYPE_NAME (promoted_type)) == TYPE_DECL
3507                    && DECL_NAME (TYPE_NAME (promoted_type)))
3508             pname = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (promoted_type)));
3509         }
3510
3511       /* Unfortunately, this is merely undefined, rather than a constraint
3512          violation, so we cannot make this an error.  If this call is never
3513          executed, the program is still strictly conforming.  */
3514       warning ("`%s' is promoted to `%s' when passed through `...'",
3515                name, pname);
3516       if (! gave_help)
3517         {
3518           gave_help = true;
3519           warning ("(so you should pass `%s' not `%s' to `va_arg')",
3520                    pname, name);
3521         }
3522
3523       /* We can, however, treat "undefined" any way we please.
3524          Call abort to encourage the user to fix the program.  */
3525       expand_builtin_trap ();
3526
3527       /* This is dead code, but go ahead and finish so that the
3528          mode of the result comes out right.  */
3529       addr = const0_rtx;
3530     }
3531   else
3532     {
3533       /* Make it easier for the backends by protecting the valist argument
3534          from multiple evaluations.  */
3535       valist = stabilize_va_list (valist, 0);
3536
3537 #ifdef EXPAND_BUILTIN_VA_ARG
3538       addr = EXPAND_BUILTIN_VA_ARG (valist, type);
3539 #else
3540       addr = std_expand_builtin_va_arg (valist, type);
3541 #endif
3542     }
3543
3544 #ifdef POINTERS_EXTEND_UNSIGNED
3545   if (GET_MODE (addr) != Pmode)
3546     addr = convert_memory_address (Pmode, addr);
3547 #endif
3548
3549   result = gen_rtx_MEM (TYPE_MODE (type), addr);
3550   set_mem_alias_set (result, get_varargs_alias_set ());
3551
3552   return result;
3553 }
3554
3555 /* Expand ARGLIST, from a call to __builtin_va_end.  */
3556
3557 static rtx
3558 expand_builtin_va_end (arglist)
3559      tree arglist;
3560 {
3561   tree valist = TREE_VALUE (arglist);
3562
3563 #ifdef EXPAND_BUILTIN_VA_END
3564   valist = stabilize_va_list (valist, 0);
3565   EXPAND_BUILTIN_VA_END (arglist);
3566 #else
3567   /* Evaluate for side effects, if needed.  I hate macros that don't
3568      do that.  */
3569   if (TREE_SIDE_EFFECTS (valist))
3570     expand_expr (valist, const0_rtx, VOIDmode, EXPAND_NORMAL);
3571 #endif
3572
3573   return const0_rtx;
3574 }
3575
3576 /* Expand ARGLIST, from a call to __builtin_va_copy.  We do this as a
3577    builtin rather than just as an assignment in stdarg.h because of the
3578    nastiness of array-type va_list types.  */
3579
3580 static rtx
3581 expand_builtin_va_copy (arglist)
3582      tree arglist;
3583 {
3584   tree dst, src, t;
3585
3586   dst = TREE_VALUE (arglist);
3587   src = TREE_VALUE (TREE_CHAIN (arglist));
3588
3589   dst = stabilize_va_list (dst, 1);
3590   src = stabilize_va_list (src, 0);
3591
3592   if (TREE_CODE (va_list_type_node) != ARRAY_TYPE)
3593     {
3594       t = build (MODIFY_EXPR, va_list_type_node, dst, src);
3595       TREE_SIDE_EFFECTS (t) = 1;
3596       expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
3597     }
3598   else
3599     {
3600       rtx dstb, srcb, size;
3601
3602       /* Evaluate to pointers.  */
3603       dstb = expand_expr (dst, NULL_RTX, Pmode, EXPAND_NORMAL);
3604       srcb = expand_expr (src, NULL_RTX, Pmode, EXPAND_NORMAL);
3605       size = expand_expr (TYPE_SIZE_UNIT (va_list_type_node), NULL_RTX,
3606                           VOIDmode, EXPAND_NORMAL);
3607
3608 #ifdef POINTERS_EXTEND_UNSIGNED
3609       if (GET_MODE (dstb) != Pmode)
3610         dstb = convert_memory_address (Pmode, dstb);
3611
3612       if (GET_MODE (srcb) != Pmode)
3613         srcb = convert_memory_address (Pmode, srcb);
3614 #endif
3615
3616       /* "Dereference" to BLKmode memories.  */
3617       dstb = gen_rtx_MEM (BLKmode, dstb);
3618       set_mem_alias_set (dstb, get_alias_set (TREE_TYPE (TREE_TYPE (dst))));
3619       set_mem_align (dstb, TYPE_ALIGN (va_list_type_node));
3620       srcb = gen_rtx_MEM (BLKmode, srcb);
3621       set_mem_alias_set (srcb, get_alias_set (TREE_TYPE (TREE_TYPE (src))));
3622       set_mem_align (srcb, TYPE_ALIGN (va_list_type_node));
3623
3624       /* Copy.  */
3625       emit_block_move (dstb, srcb, size, BLOCK_OP_NORMAL);
3626     }
3627
3628   return const0_rtx;
3629 }
3630
3631 /* Expand a call to one of the builtin functions __builtin_frame_address or
3632    __builtin_return_address.  */
3633
3634 static rtx
3635 expand_builtin_frame_address (exp)
3636      tree exp;
3637 {
3638   tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
3639   tree arglist = TREE_OPERAND (exp, 1);
3640
3641   /* The argument must be a nonnegative integer constant.
3642      It counts the number of frames to scan up the stack.
3643      The value is the return address saved in that frame.  */
3644   if (arglist == 0)
3645     /* Warning about missing arg was already issued.  */
3646     return const0_rtx;
3647   else if (! host_integerp (TREE_VALUE (arglist), 1))
3648     {
3649       if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
3650         error ("invalid arg to `__builtin_frame_address'");
3651       else
3652         error ("invalid arg to `__builtin_return_address'");
3653       return const0_rtx;
3654     }
3655   else
3656     {
3657       rtx tem
3658         = expand_builtin_return_addr (DECL_FUNCTION_CODE (fndecl),
3659                                       tree_low_cst (TREE_VALUE (arglist), 1),
3660                                       hard_frame_pointer_rtx);
3661
3662       /* Some ports cannot access arbitrary stack frames.  */
3663       if (tem == NULL)
3664         {
3665           if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
3666             warning ("unsupported arg to `__builtin_frame_address'");
3667           else
3668             warning ("unsupported arg to `__builtin_return_address'");
3669           return const0_rtx;
3670         }
3671
3672       /* For __builtin_frame_address, return what we've got.  */
3673       if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
3674         return tem;
3675
3676       if (GET_CODE (tem) != REG
3677           && ! CONSTANT_P (tem))
3678         tem = copy_to_mode_reg (Pmode, tem);
3679       return tem;
3680     }
3681 }
3682
3683 /* Expand a call to the alloca builtin, with arguments ARGLIST.  Return 0 if
3684    we failed and the caller should emit a normal call, otherwise try to get
3685    the result in TARGET, if convenient.  */
3686
3687 static rtx
3688 expand_builtin_alloca (arglist, target)
3689      tree arglist;
3690      rtx target;
3691 {
3692   rtx op0;
3693   rtx result;
3694
3695   if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
3696     return 0;
3697
3698   /* Compute the argument.  */
3699   op0 = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
3700
3701   /* Allocate the desired space.  */
3702   result = allocate_dynamic_stack_space (op0, target, BITS_PER_UNIT);
3703
3704 #ifdef POINTERS_EXTEND_UNSIGNED
3705   if (GET_MODE (result) != ptr_mode)
3706     result = convert_memory_address (ptr_mode, result);
3707 #endif
3708
3709   return result;
3710 }
3711
3712 /* Expand a call to a unary builtin.  The arguments are in ARGLIST.
3713    Return 0 if a normal call should be emitted rather than expanding the
3714    function in-line.  If convenient, the result should be placed in TARGET.
3715    SUBTARGET may be used as the target for computing one of EXP's operands.  */
3716
3717 static rtx
3718 expand_builtin_unop (target_mode, arglist, target, subtarget, op_optab)
3719      enum machine_mode target_mode;
3720      tree arglist;
3721      rtx target, subtarget;
3722      optab op_optab;
3723 {
3724   rtx op0;
3725   if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
3726     return 0;
3727
3728   /* Compute the argument.  */
3729   op0 = expand_expr (TREE_VALUE (arglist), subtarget, VOIDmode, 0);
3730   /* Compute op, into TARGET if possible.
3731      Set TARGET to wherever the result comes back.  */
3732   target = expand_unop (TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist))),
3733                         op_optab, op0, target, 1);
3734   if (target == 0)
3735     abort ();
3736
3737   return convert_to_mode (target_mode, target, 0);
3738 }
3739
3740 /* If the string passed to fputs is a constant and is one character
3741    long, we attempt to transform this call into __builtin_fputc().  */
3742
3743 static rtx
3744 expand_builtin_fputs (arglist, ignore, unlocked)
3745      tree arglist;
3746      int ignore;
3747      int unlocked;
3748 {
3749   tree len, fn;
3750   tree fn_fputc = unlocked ? implicit_built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
3751     : implicit_built_in_decls[BUILT_IN_FPUTC];
3752   tree fn_fwrite = unlocked ? implicit_built_in_decls[BUILT_IN_FWRITE_UNLOCKED]
3753     : implicit_built_in_decls[BUILT_IN_FWRITE];
3754
3755   /* If the return value is used, or the replacement _DECL isn't
3756      initialized, don't do the transformation.  */
3757   if (!ignore || !fn_fputc || !fn_fwrite)
3758     return 0;
3759
3760   /* Verify the arguments in the original call.  */
3761   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3762     return 0;
3763
3764   /* Get the length of the string passed to fputs.  If the length
3765      can't be determined, punt.  */
3766   if (!(len = c_strlen (TREE_VALUE (arglist)))
3767       || TREE_CODE (len) != INTEGER_CST)
3768     return 0;
3769
3770   switch (compare_tree_int (len, 1))
3771     {
3772     case -1: /* length is 0, delete the call entirely .  */
3773       {
3774         /* Evaluate and ignore the argument in case it has
3775            side-effects.  */
3776         expand_expr (TREE_VALUE (TREE_CHAIN (arglist)), const0_rtx,
3777                      VOIDmode, EXPAND_NORMAL);
3778         return const0_rtx;
3779       }
3780     case 0: /* length is 1, call fputc.  */
3781       {
3782         const char *p = c_getstr (TREE_VALUE (arglist));
3783
3784         if (p != NULL)
3785           {
3786             /* New argument list transforming fputs(string, stream) to
3787                fputc(string[0], stream).  */
3788             arglist =
3789               build_tree_list (NULL_TREE, TREE_VALUE (TREE_CHAIN (arglist)));
3790             arglist =
3791               tree_cons (NULL_TREE, build_int_2 (p[0], 0), arglist);
3792             fn = fn_fputc;
3793             break;
3794           }
3795       }
3796       /* FALLTHROUGH */
3797     case 1: /* length is greater than 1, call fwrite.  */
3798       {
3799         tree string_arg;
3800
3801         /* If optimizing for size keep fputs. */
3802         if (optimize_size)
3803           return 0;
3804         string_arg = TREE_VALUE (arglist);
3805         /* New argument list transforming fputs(string, stream) to
3806            fwrite(string, 1, len, stream).  */
3807         arglist = build_tree_list (NULL_TREE, TREE_VALUE (TREE_CHAIN (arglist)));
3808         arglist = tree_cons (NULL_TREE, len, arglist);
3809         arglist = tree_cons (NULL_TREE, size_one_node, arglist);
3810         arglist = tree_cons (NULL_TREE, string_arg, arglist);
3811         fn = fn_fwrite;
3812         break;
3813       }
3814     default:
3815       abort ();
3816     }
3817
3818   return expand_expr (build_function_call_expr (fn, arglist),
3819                       (ignore ? const0_rtx : NULL_RTX),
3820                       VOIDmode, EXPAND_NORMAL);
3821 }
3822
3823 /* Expand a call to __builtin_expect.  We return our argument and emit a
3824    NOTE_INSN_EXPECTED_VALUE note.  This is the expansion of __builtin_expect in
3825    a non-jump context.  */
3826
3827 static rtx
3828 expand_builtin_expect (arglist, target)
3829      tree arglist;
3830      rtx target;
3831 {
3832   tree exp, c;
3833   rtx note, rtx_c;
3834
3835   if (arglist == NULL_TREE
3836       || TREE_CHAIN (arglist) == NULL_TREE)
3837     return const0_rtx;
3838   exp = TREE_VALUE (arglist);
3839   c = TREE_VALUE (TREE_CHAIN (arglist));
3840
3841   if (TREE_CODE (c) != INTEGER_CST)
3842     {
3843       error ("second arg to `__builtin_expect' must be a constant");
3844       c = integer_zero_node;
3845     }
3846
3847   target = expand_expr (exp, target, VOIDmode, EXPAND_NORMAL);
3848
3849   /* Don't bother with expected value notes for integral constants.  */
3850   if (flag_guess_branch_prob && GET_CODE (target) != CONST_INT)
3851     {
3852       /* We do need to force this into a register so that we can be
3853          moderately sure to be able to correctly interpret the branch
3854          condition later.  */
3855       target = force_reg (GET_MODE (target), target);
3856
3857       rtx_c = expand_expr (c, NULL_RTX, GET_MODE (target), EXPAND_NORMAL);
3858
3859       note = emit_note (NULL, NOTE_INSN_EXPECTED_VALUE);
3860       NOTE_EXPECTED_VALUE (note) = gen_rtx_EQ (VOIDmode, target, rtx_c);
3861     }
3862
3863   return target;
3864 }
3865
3866 /* Like expand_builtin_expect, except do this in a jump context.  This is
3867    called from do_jump if the conditional is a __builtin_expect.  Return either
3868    a list of insns to emit the jump or NULL if we cannot optimize
3869    __builtin_expect.  We need to optimize this at jump time so that machines
3870    like the PowerPC don't turn the test into a SCC operation, and then jump
3871    based on the test being 0/1.  */
3872
3873 rtx
3874 expand_builtin_expect_jump (exp, if_false_label, if_true_label)
3875      tree exp;
3876      rtx if_false_label;
3877      rtx if_true_label;
3878 {
3879   tree arglist = TREE_OPERAND (exp, 1);
3880   tree arg0 = TREE_VALUE (arglist);
3881   tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
3882   rtx ret = NULL_RTX;
3883
3884   /* Only handle __builtin_expect (test, 0) and
3885      __builtin_expect (test, 1).  */
3886   if (TREE_CODE (TREE_TYPE (arg1)) == INTEGER_TYPE
3887       && (integer_zerop (arg1) || integer_onep (arg1)))
3888     {
3889       int num_jumps = 0;
3890       rtx insn;
3891
3892       /* If we fail to locate an appropriate conditional jump, we'll
3893          fall back to normal evaluation.  Ensure that the expression
3894          can be re-evaluated.  */
3895       switch (unsafe_for_reeval (arg0))
3896         {
3897         case 0: /* Safe.  */
3898           break;
3899
3900         case 1: /* Mildly unsafe.  */
3901           arg0 = unsave_expr (arg0);
3902           break;
3903
3904         case 2: /* Wildly unsafe.  */
3905           return NULL_RTX;
3906         }
3907
3908       /* Expand the jump insns.  */
3909       start_sequence ();
3910       do_jump (arg0, if_false_label, if_true_label);
3911       ret = get_insns ();
3912       end_sequence ();
3913
3914       /* Now that the __builtin_expect has been validated, go through and add
3915          the expect's to each of the conditional jumps.  If we run into an
3916          error, just give up and generate the 'safe' code of doing a SCC
3917          operation and then doing a branch on that.  */
3918       insn = ret;
3919       while (insn != NULL_RTX)
3920         {
3921           rtx next = NEXT_INSN (insn);
3922           rtx pattern;
3923
3924           if (GET_CODE (insn) == JUMP_INSN && any_condjump_p (insn)
3925               && (pattern = pc_set (insn)) != NULL_RTX)
3926             {
3927               rtx ifelse = SET_SRC (pattern);
3928               rtx label;
3929               int taken;
3930
3931               if (GET_CODE (ifelse) != IF_THEN_ELSE)
3932                 goto do_next_insn;
3933
3934               if (GET_CODE (XEXP (ifelse, 1)) == LABEL_REF)
3935                 {
3936                   taken = 1;
3937                   label = XEXP (XEXP (ifelse, 1), 0);
3938                 }
3939               /* An inverted jump reverses the probabilities.  */
3940               else if (GET_CODE (XEXP (ifelse, 2)) == LABEL_REF)
3941                 {
3942                   taken = 0;
3943                   label = XEXP (XEXP (ifelse, 2), 0);
3944                 }
3945               /* We shouldn't have to worry about conditional returns during
3946                  the expansion stage, but handle it gracefully anyway.  */
3947               else if (GET_CODE (XEXP (ifelse, 1)) == RETURN)
3948                 {
3949                   taken = 1;
3950                   label = NULL_RTX;
3951                 }
3952               /* An inverted return reverses the probabilities.  */
3953               else if (GET_CODE (XEXP (ifelse, 2)) == RETURN)
3954                 {
3955                   taken = 0;
3956                   label = NULL_RTX;
3957                 }
3958               else
3959                 goto do_next_insn;
3960
3961               /* If the test is expected to fail, reverse the
3962                  probabilities.  */
3963               if (integer_zerop (arg1))
3964                 taken = 1 - taken;
3965
3966               /* If we are jumping to the false label, reverse the
3967                  probabilities.  */
3968               if (label == NULL_RTX)
3969                 ;               /* conditional return */
3970               else if (label == if_false_label)
3971                 taken = 1 - taken;
3972               else if (label != if_true_label)
3973                 goto do_next_insn;
3974
3975               num_jumps++;
3976               predict_insn_def (insn, PRED_BUILTIN_EXPECT, taken);
3977             }
3978
3979         do_next_insn:
3980           insn = next;
3981         }
3982
3983       /* If no jumps were modified, fail and do __builtin_expect the normal
3984          way.  */
3985       if (num_jumps == 0)
3986         ret = NULL_RTX;
3987     }
3988
3989   return ret;
3990 }
3991
3992 void
3993 expand_builtin_trap ()
3994 {
3995 #ifdef HAVE_trap
3996   if (HAVE_trap)
3997     emit_insn (gen_trap ());
3998   else
3999 #endif
4000     emit_library_call (abort_libfunc, LCT_NORETURN, VOIDmode, 0);
4001   emit_barrier ();
4002 }
4003 \f
4004 /* Expand an expression EXP that calls a built-in function,
4005    with result going to TARGET if that's convenient
4006    (and in mode MODE if that's convenient).
4007    SUBTARGET may be used as the target for computing one of EXP's operands.
4008    IGNORE is nonzero if the value is to be ignored.  */
4009
4010 rtx
4011 expand_builtin (exp, target, subtarget, mode, ignore)
4012      tree exp;
4013      rtx target;
4014      rtx subtarget;
4015      enum machine_mode mode;
4016      int ignore;
4017 {
4018   tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
4019   tree arglist = TREE_OPERAND (exp, 1);
4020   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
4021   enum machine_mode target_mode = TYPE_MODE (TREE_TYPE (exp));
4022
4023   /* Perform postincrements before expanding builtin functions. Â */
4024   emit_queue ();
4025
4026   if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
4027     return (*targetm.expand_builtin) (exp, target, subtarget, mode, ignore);
4028
4029   /* When not optimizing, generate calls to library functions for a certain
4030      set of builtins.  */
4031   if (!optimize && !CALLED_AS_BUILT_IN (fndecl))
4032     switch (fcode)
4033       {
4034       case BUILT_IN_SQRT:
4035       case BUILT_IN_SQRTF:
4036       case BUILT_IN_SQRTL:
4037       case BUILT_IN_SIN:
4038       case BUILT_IN_SINF:
4039       case BUILT_IN_SINL:
4040       case BUILT_IN_COS:
4041       case BUILT_IN_COSF:
4042       case BUILT_IN_COSL:
4043       case BUILT_IN_EXP:
4044       case BUILT_IN_EXPF:
4045       case BUILT_IN_EXPL:
4046       case BUILT_IN_LOG:
4047       case BUILT_IN_LOGF:
4048       case BUILT_IN_LOGL:
4049       case BUILT_IN_POW:
4050       case BUILT_IN_POWF:
4051       case BUILT_IN_POWL:
4052       case BUILT_IN_ATAN2:
4053       case BUILT_IN_ATAN2F:
4054       case BUILT_IN_ATAN2L:
4055       case BUILT_IN_MEMSET:
4056       case BUILT_IN_MEMCPY:
4057       case BUILT_IN_MEMCMP:
4058       case BUILT_IN_BCMP:
4059       case BUILT_IN_BZERO:
4060       case BUILT_IN_INDEX:
4061       case BUILT_IN_RINDEX:
4062       case BUILT_IN_STRCHR:
4063       case BUILT_IN_STRRCHR:
4064       case BUILT_IN_STRLEN:
4065       case BUILT_IN_STRCPY:
4066       case BUILT_IN_STRNCPY:
4067       case BUILT_IN_STRNCMP:
4068       case BUILT_IN_STRSTR:
4069       case BUILT_IN_STRPBRK:
4070       case BUILT_IN_STRCAT:
4071       case BUILT_IN_STRNCAT:
4072       case BUILT_IN_STRSPN:
4073       case BUILT_IN_STRCSPN:
4074       case BUILT_IN_STRCMP:
4075       case BUILT_IN_FFS:
4076       case BUILT_IN_PUTCHAR:
4077       case BUILT_IN_PUTS:
4078       case BUILT_IN_PRINTF:
4079       case BUILT_IN_FPUTC:
4080       case BUILT_IN_FPUTS:
4081       case BUILT_IN_FWRITE:
4082       case BUILT_IN_PUTCHAR_UNLOCKED:
4083       case BUILT_IN_PUTS_UNLOCKED:
4084       case BUILT_IN_PRINTF_UNLOCKED:
4085       case BUILT_IN_FPUTC_UNLOCKED:
4086       case BUILT_IN_FPUTS_UNLOCKED:
4087       case BUILT_IN_FWRITE_UNLOCKED:
4088       case BUILT_IN_FLOOR:
4089       case BUILT_IN_FLOORF:
4090       case BUILT_IN_FLOORL:
4091       case BUILT_IN_CEIL:
4092       case BUILT_IN_CEILF:
4093       case BUILT_IN_CEILL:
4094       case BUILT_IN_TRUNC:
4095       case BUILT_IN_TRUNCF:
4096       case BUILT_IN_TRUNCL:
4097       case BUILT_IN_ROUND:
4098       case BUILT_IN_ROUNDF:
4099       case BUILT_IN_ROUNDL:
4100       case BUILT_IN_NEARBYINT:
4101       case BUILT_IN_NEARBYINTF:
4102       case BUILT_IN_NEARBYINTL:
4103         return expand_call (exp, target, ignore);
4104
4105       default:
4106         break;
4107       }
4108
4109   switch (fcode)
4110     {
4111     case BUILT_IN_ABS:
4112     case BUILT_IN_LABS:
4113     case BUILT_IN_LLABS:
4114     case BUILT_IN_IMAXABS:
4115     case BUILT_IN_FABS:
4116     case BUILT_IN_FABSF:
4117     case BUILT_IN_FABSL:
4118       /* build_function_call changes these into ABS_EXPR.  */
4119       abort ();
4120
4121     case BUILT_IN_CONJ:
4122     case BUILT_IN_CONJF:
4123     case BUILT_IN_CONJL:
4124     case BUILT_IN_CREAL:
4125     case BUILT_IN_CREALF:
4126     case BUILT_IN_CREALL:
4127     case BUILT_IN_CIMAG:
4128     case BUILT_IN_CIMAGF:
4129     case BUILT_IN_CIMAGL:
4130       /* expand_tree_builtin changes these into CONJ_EXPR, REALPART_EXPR
4131          and IMAGPART_EXPR.  */
4132       abort ();
4133
4134     case BUILT_IN_SIN:
4135     case BUILT_IN_SINF:
4136     case BUILT_IN_SINL:
4137     case BUILT_IN_COS:
4138     case BUILT_IN_COSF:
4139     case BUILT_IN_COSL:
4140     case BUILT_IN_EXP:
4141     case BUILT_IN_EXPF:
4142     case BUILT_IN_EXPL:
4143     case BUILT_IN_LOG:
4144     case BUILT_IN_LOGF:
4145     case BUILT_IN_LOGL:
4146       /* Treat these like sqrt only if unsafe math optimizations are allowed,
4147          because of possible accuracy problems.  */
4148       if (! flag_unsafe_math_optimizations)
4149         break;
4150     case BUILT_IN_SQRT:
4151     case BUILT_IN_SQRTF:
4152     case BUILT_IN_SQRTL:
4153     case BUILT_IN_FLOOR:
4154     case BUILT_IN_FLOORF:
4155     case BUILT_IN_FLOORL:
4156     case BUILT_IN_CEIL:
4157     case BUILT_IN_CEILF:
4158     case BUILT_IN_CEILL:
4159     case BUILT_IN_TRUNC:
4160     case BUILT_IN_TRUNCF:
4161     case BUILT_IN_TRUNCL:
4162     case BUILT_IN_ROUND:
4163     case BUILT_IN_ROUNDF:
4164     case BUILT_IN_ROUNDL:
4165     case BUILT_IN_NEARBYINT:
4166     case BUILT_IN_NEARBYINTF:
4167     case BUILT_IN_NEARBYINTL:
4168       target = expand_builtin_mathfn (exp, target, subtarget);
4169       if (target)
4170         return target;
4171       break;
4172
4173     case BUILT_IN_POW:
4174     case BUILT_IN_POWF:
4175     case BUILT_IN_POWL:
4176     case BUILT_IN_ATAN2:
4177     case BUILT_IN_ATAN2F:
4178     case BUILT_IN_ATAN2L:
4179       if (! flag_unsafe_math_optimizations)
4180         break;
4181       target = expand_builtin_mathfn_2 (exp, target, subtarget);
4182       if (target)
4183         return target;
4184       break;
4185
4186     case BUILT_IN_APPLY_ARGS:
4187       return expand_builtin_apply_args ();
4188
4189       /* __builtin_apply (FUNCTION, ARGUMENTS, ARGSIZE) invokes
4190          FUNCTION with a copy of the parameters described by
4191          ARGUMENTS, and ARGSIZE.  It returns a block of memory
4192          allocated on the stack into which is stored all the registers
4193          that might possibly be used for returning the result of a
4194          function.  ARGUMENTS is the value returned by
4195          __builtin_apply_args.  ARGSIZE is the number of bytes of
4196          arguments that must be copied.  ??? How should this value be
4197          computed?  We'll also need a safe worst case value for varargs
4198          functions.  */
4199     case BUILT_IN_APPLY:
4200       if (!validate_arglist (arglist, POINTER_TYPE,
4201                              POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)
4202           && !validate_arglist (arglist, REFERENCE_TYPE,
4203                                 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
4204         return const0_rtx;
4205       else
4206         {
4207           int i;
4208           tree t;
4209           rtx ops[3];
4210
4211           for (t = arglist, i = 0; t; t = TREE_CHAIN (t), i++)
4212             ops[i] = expand_expr (TREE_VALUE (t), NULL_RTX, VOIDmode, 0);
4213
4214           return expand_builtin_apply (ops[0], ops[1], ops[2]);
4215         }
4216
4217       /* __builtin_return (RESULT) causes the function to return the
4218          value described by RESULT.  RESULT is address of the block of
4219          memory returned by __builtin_apply.  */
4220     case BUILT_IN_RETURN:
4221       if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
4222         expand_builtin_return (expand_expr (TREE_VALUE (arglist),
4223                                             NULL_RTX, VOIDmode, 0));
4224       return const0_rtx;
4225
4226     case BUILT_IN_SAVEREGS:
4227       return expand_builtin_saveregs ();
4228
4229     case BUILT_IN_ARGS_INFO:
4230       return expand_builtin_args_info (exp);
4231
4232       /* Return the address of the first anonymous stack arg.  */
4233     case BUILT_IN_NEXT_ARG:
4234       return expand_builtin_next_arg (arglist);
4235
4236     case BUILT_IN_CLASSIFY_TYPE:
4237       return expand_builtin_classify_type (arglist);
4238
4239     case BUILT_IN_CONSTANT_P:
4240       return expand_builtin_constant_p (exp);
4241
4242     case BUILT_IN_FRAME_ADDRESS:
4243     case BUILT_IN_RETURN_ADDRESS:
4244       return expand_builtin_frame_address (exp);
4245
4246     /* Returns the address of the area where the structure is returned.
4247        0 otherwise.  */
4248     case BUILT_IN_AGGREGATE_INCOMING_ADDRESS:
4249       if (arglist != 0
4250           || ! AGGREGATE_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl)))
4251           || GET_CODE (DECL_RTL (DECL_RESULT (current_function_decl))) != MEM)
4252         return const0_rtx;
4253       else
4254         return XEXP (DECL_RTL (DECL_RESULT (current_function_decl)), 0);
4255
4256     case BUILT_IN_ALLOCA:
4257       target = expand_builtin_alloca (arglist, target);
4258       if (target)
4259         return target;
4260       break;
4261
4262     case BUILT_IN_FFS:
4263     case BUILT_IN_FFSL:
4264     case BUILT_IN_FFSLL:
4265       target = expand_builtin_unop (target_mode, arglist, target,
4266                                     subtarget, ffs_optab);
4267       if (target)
4268         return target;
4269       break;
4270
4271     case BUILT_IN_CLZ:
4272     case BUILT_IN_CLZL:
4273     case BUILT_IN_CLZLL:
4274       target = expand_builtin_unop (target_mode, arglist, target,
4275                                     subtarget, clz_optab);
4276       if (target)
4277         return target;
4278       break;
4279
4280     case BUILT_IN_CTZ:
4281     case BUILT_IN_CTZL:
4282     case BUILT_IN_CTZLL:
4283       target = expand_builtin_unop (target_mode, arglist, target,
4284                                     subtarget, ctz_optab);
4285       if (target)
4286         return target;
4287       break;
4288
4289     case BUILT_IN_POPCOUNT:
4290     case BUILT_IN_POPCOUNTL:
4291     case BUILT_IN_POPCOUNTLL:
4292       target = expand_builtin_unop (target_mode, arglist, target,
4293                                     subtarget, popcount_optab);
4294       if (target)
4295         return target;
4296       break;
4297
4298     case BUILT_IN_PARITY:
4299     case BUILT_IN_PARITYL:
4300     case BUILT_IN_PARITYLL:
4301       target = expand_builtin_unop (target_mode, arglist, target,
4302                                     subtarget, parity_optab);
4303       if (target)
4304         return target;
4305       break;
4306
4307     case BUILT_IN_STRLEN:
4308       target = expand_builtin_strlen (exp, target);
4309       if (target)
4310         return target;
4311       break;
4312
4313     case BUILT_IN_STRCPY:
4314       target = expand_builtin_strcpy (exp, target, mode);
4315       if (target)
4316         return target;
4317       break;
4318
4319     case BUILT_IN_STRNCPY:
4320       target = expand_builtin_strncpy (arglist, target, mode);
4321       if (target)
4322         return target;
4323       break;
4324
4325     case BUILT_IN_STRCAT:
4326       target = expand_builtin_strcat (arglist, target, mode);
4327       if (target)
4328         return target;
4329       break;
4330
4331     case BUILT_IN_STRNCAT:
4332       target = expand_builtin_strncat (arglist, target, mode);
4333       if (target)
4334         return target;
4335       break;
4336
4337     case BUILT_IN_STRSPN:
4338       target = expand_builtin_strspn (arglist, target, mode);
4339       if (target)
4340         return target;
4341       break;
4342
4343     case BUILT_IN_STRCSPN:
4344       target = expand_builtin_strcspn (arglist, target, mode);
4345       if (target)
4346         return target;
4347       break;
4348
4349     case BUILT_IN_STRSTR:
4350       target = expand_builtin_strstr (arglist, target, mode);
4351       if (target)
4352         return target;
4353       break;
4354
4355     case BUILT_IN_STRPBRK:
4356       target = expand_builtin_strpbrk (arglist, target, mode);
4357       if (target)
4358         return target;
4359       break;
4360
4361     case BUILT_IN_INDEX:
4362     case BUILT_IN_STRCHR:
4363       target = expand_builtin_strchr (arglist, target, mode);
4364       if (target)
4365         return target;
4366       break;
4367
4368     case BUILT_IN_RINDEX:
4369     case BUILT_IN_STRRCHR:
4370       target = expand_builtin_strrchr (arglist, target, mode);
4371       if (target)
4372         return target;
4373       break;
4374
4375     case BUILT_IN_MEMCPY:
4376       target = expand_builtin_memcpy (arglist, target, mode);
4377       if (target)
4378         return target;
4379       break;
4380
4381     case BUILT_IN_MEMSET:
4382       target = expand_builtin_memset (exp, target, mode);
4383       if (target)
4384         return target;
4385       break;
4386
4387     case BUILT_IN_BZERO:
4388       target = expand_builtin_bzero (exp);
4389       if (target)
4390         return target;
4391       break;
4392
4393     case BUILT_IN_STRCMP:
4394       target = expand_builtin_strcmp (exp, target, mode);
4395       if (target)
4396         return target;
4397       break;
4398
4399     case BUILT_IN_STRNCMP:
4400       target = expand_builtin_strncmp (exp, target, mode);
4401       if (target)
4402         return target;
4403       break;
4404
4405     case BUILT_IN_BCMP:
4406     case BUILT_IN_MEMCMP:
4407       target = expand_builtin_memcmp (exp, arglist, target, mode);
4408       if (target)
4409         return target;
4410       break;
4411
4412     case BUILT_IN_SETJMP:
4413       target = expand_builtin_setjmp (arglist, target);
4414       if (target)
4415         return target;
4416       break;
4417
4418       /* __builtin_longjmp is passed a pointer to an array of five words.
4419          It's similar to the C library longjmp function but works with
4420          __builtin_setjmp above.  */
4421     case BUILT_IN_LONGJMP:
4422       if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
4423         break;
4424       else
4425         {
4426           rtx buf_addr = expand_expr (TREE_VALUE (arglist), subtarget,
4427                                       VOIDmode, 0);
4428           rtx value = expand_expr (TREE_VALUE (TREE_CHAIN (arglist)),
4429                                    NULL_RTX, VOIDmode, 0);
4430
4431           if (value != const1_rtx)
4432             {
4433               error ("__builtin_longjmp second argument must be 1");
4434               return const0_rtx;
4435             }
4436
4437           expand_builtin_longjmp (buf_addr, value);
4438           return const0_rtx;
4439         }
4440
4441     case BUILT_IN_TRAP:
4442       expand_builtin_trap ();
4443       return const0_rtx;
4444
4445     case BUILT_IN_FPUTS:
4446       target = expand_builtin_fputs (arglist, ignore,/*unlocked=*/ 0);
4447       if (target)
4448         return target;
4449       break;
4450     case BUILT_IN_FPUTS_UNLOCKED:
4451       target = expand_builtin_fputs (arglist, ignore,/*unlocked=*/ 1);
4452       if (target)
4453         return target;
4454       break;
4455
4456       /* Various hooks for the DWARF 2 __throw routine.  */
4457     case BUILT_IN_UNWIND_INIT:
4458       expand_builtin_unwind_init ();
4459       return const0_rtx;
4460     case BUILT_IN_DWARF_CFA:
4461       return virtual_cfa_rtx;
4462 #ifdef DWARF2_UNWIND_INFO
4463     case BUILT_IN_DWARF_FP_REGNUM:
4464       return expand_builtin_dwarf_fp_regnum ();
4465     case BUILT_IN_INIT_DWARF_REG_SIZES:
4466       expand_builtin_init_dwarf_reg_sizes (TREE_VALUE (arglist));
4467       return const0_rtx;
4468 #endif
4469     case BUILT_IN_FROB_RETURN_ADDR:
4470       return expand_builtin_frob_return_addr (TREE_VALUE (arglist));
4471     case BUILT_IN_EXTRACT_RETURN_ADDR:
4472       return expand_builtin_extract_return_addr (TREE_VALUE (arglist));
4473     case BUILT_IN_EH_RETURN:
4474       expand_builtin_eh_return (TREE_VALUE (arglist),
4475                                 TREE_VALUE (TREE_CHAIN (arglist)));
4476       return const0_rtx;
4477 #ifdef EH_RETURN_DATA_REGNO
4478     case BUILT_IN_EH_RETURN_DATA_REGNO:
4479       return expand_builtin_eh_return_data_regno (arglist);
4480 #endif
4481     case BUILT_IN_VA_START:
4482     case BUILT_IN_STDARG_START:
4483       return expand_builtin_va_start (arglist);
4484     case BUILT_IN_VA_END:
4485       return expand_builtin_va_end (arglist);
4486     case BUILT_IN_VA_COPY:
4487       return expand_builtin_va_copy (arglist);
4488     case BUILT_IN_EXPECT:
4489       return expand_builtin_expect (arglist, target);
4490     case BUILT_IN_PREFETCH:
4491       expand_builtin_prefetch (arglist);
4492       return const0_rtx;
4493
4494
4495     default:    /* just do library call, if unknown builtin */
4496       if (!DECL_ASSEMBLER_NAME_SET_P (fndecl))
4497         error ("built-in function `%s' not currently supported",
4498                IDENTIFIER_POINTER (DECL_NAME (fndecl)));
4499     }
4500
4501   /* The switch statement above can drop through to cause the function
4502      to be called normally.  */
4503   return expand_call (exp, target, ignore);
4504 }
4505
4506 /* Determine whether a tree node represents a call to a built-in
4507    math function.  If the tree T is a call to a built-in function
4508    taking a single real argument, then the return value is the
4509    DECL_FUNCTION_CODE of the call, e.g. BUILT_IN_SQRT.  Otherwise
4510    the return value is END_BUILTINS.  */
4511    
4512 enum built_in_function
4513 builtin_mathfn_code (t)
4514      tree t;
4515 {
4516   tree fndecl, arglist;
4517
4518   if (TREE_CODE (t) != CALL_EXPR
4519       || TREE_CODE (TREE_OPERAND (t, 0)) != ADDR_EXPR)
4520     return END_BUILTINS;
4521
4522   fndecl = TREE_OPERAND (TREE_OPERAND (t, 0), 0);
4523   if (TREE_CODE (fndecl) != FUNCTION_DECL
4524       || ! DECL_BUILT_IN (fndecl)
4525       || DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
4526     return END_BUILTINS;
4527
4528   arglist = TREE_OPERAND (t, 1);
4529   if (! arglist
4530       || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != REAL_TYPE)
4531     return END_BUILTINS;
4532
4533   arglist = TREE_CHAIN (arglist);
4534   switch (DECL_FUNCTION_CODE (fndecl))
4535     {
4536     case BUILT_IN_POW:
4537     case BUILT_IN_POWF:
4538     case BUILT_IN_POWL:
4539     case BUILT_IN_ATAN2:
4540     case BUILT_IN_ATAN2F:
4541     case BUILT_IN_ATAN2L:
4542       if (! arglist
4543           || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != REAL_TYPE
4544           || TREE_CHAIN (arglist))
4545         return END_BUILTINS;
4546       break;
4547
4548     default:
4549       if (arglist)
4550         return END_BUILTINS;
4551       break;
4552     }
4553
4554   return DECL_FUNCTION_CODE (fndecl);
4555 }
4556
4557 /* Fold a call to __builtin_constant_p, if we know it will evaluate to a
4558    constant.  ARGLIST is the argument list of the call.  */
4559
4560 static tree
4561 fold_builtin_constant_p (arglist)
4562      tree arglist;
4563 {
4564   if (arglist == 0)
4565     return 0;
4566
4567   arglist = TREE_VALUE (arglist);
4568
4569   /* We return 1 for a numeric type that's known to be a constant
4570      value at compile-time or for an aggregate type that's a
4571      literal constant.  */
4572   STRIP_NOPS (arglist);
4573
4574   /* If we know this is a constant, emit the constant of one.  */
4575   if (TREE_CODE_CLASS (TREE_CODE (arglist)) == 'c'
4576       || (TREE_CODE (arglist) == CONSTRUCTOR
4577           && TREE_CONSTANT (arglist))
4578       || (TREE_CODE (arglist) == ADDR_EXPR
4579           && TREE_CODE (TREE_OPERAND (arglist, 0)) == STRING_CST))
4580     return integer_one_node;
4581
4582   /* If we aren't going to be running CSE or this expression
4583      has side effects, show we don't know it to be a constant.
4584      Likewise if it's a pointer or aggregate type since in those
4585      case we only want literals, since those are only optimized
4586      when generating RTL, not later.
4587      And finally, if we are compiling an initializer, not code, we
4588      need to return a definite result now; there's not going to be any
4589      more optimization done.  */
4590   if (TREE_SIDE_EFFECTS (arglist) || cse_not_expected
4591       || AGGREGATE_TYPE_P (TREE_TYPE (arglist))
4592       || POINTER_TYPE_P (TREE_TYPE (arglist))
4593       || cfun == 0)
4594     return integer_zero_node;
4595
4596   return 0;
4597 }
4598
4599 /* Fold a call to __builtin_classify_type.  */
4600
4601 static tree
4602 fold_builtin_classify_type (arglist)
4603      tree arglist;
4604 {
4605   if (arglist == 0)
4606     return build_int_2 (no_type_class, 0);
4607
4608   return build_int_2 (type_to_class (TREE_TYPE (TREE_VALUE (arglist))), 0);
4609 }
4610
4611 /* Fold a call to __builtin_inf or __builtin_huge_val.  */
4612
4613 static tree
4614 fold_builtin_inf (type, warn)
4615      tree type;
4616      int warn;
4617 {
4618   REAL_VALUE_TYPE real;
4619
4620   if (!MODE_HAS_INFINITIES (TYPE_MODE (type)) && warn)
4621     warning ("target format does not support infinity");
4622
4623   real_inf (&real);
4624   return build_real (type, real);
4625 }
4626
4627 /* Fold a call to __builtin_nan or __builtin_nans.  */
4628
4629 static tree
4630 fold_builtin_nan (arglist, type, quiet)
4631      tree arglist, type;
4632      int quiet;
4633 {
4634   REAL_VALUE_TYPE real;
4635   const char *str;
4636
4637   if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
4638     return 0;
4639   str = c_getstr (TREE_VALUE (arglist));
4640   if (!str)
4641     return 0;
4642
4643   if (!real_nan (&real, str, quiet, TYPE_MODE (type)))
4644     return 0;
4645
4646   return build_real (type, real);
4647 }
4648
4649 /* EXP is assumed to me builtin call where truncation can be propagated
4650    across (for instance floor((double)f) == (double)floorf (f).
4651    Do the transformation.  */
4652 static tree
4653 fold_trunc_transparent_mathfn (exp)
4654      tree exp;
4655 {
4656   tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
4657   tree arglist = TREE_OPERAND (exp, 1);
4658   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
4659
4660   if (optimize && validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
4661     {
4662       tree arg0 = strip_float_extensions (TREE_VALUE (arglist));
4663       tree ftype = TREE_TYPE (exp);
4664       tree newtype = TREE_TYPE (arg0);
4665       tree decl;
4666
4667       if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
4668           && (decl = mathfn_built_in (newtype, fcode)))
4669         {
4670           arglist =
4671             build_tree_list (NULL_TREE, fold (convert (newtype, arg0)));
4672           return convert (ftype,
4673                           build_function_call_expr (decl, arglist));
4674         }
4675     }
4676   return 0;
4677 }
4678
4679 /* Used by constant folding to eliminate some builtin calls early.  EXP is
4680    the CALL_EXPR of a call to a builtin function.  */
4681
4682 tree
4683 fold_builtin (exp)
4684      tree exp;
4685 {
4686   tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
4687   tree arglist = TREE_OPERAND (exp, 1);
4688   tree type = TREE_TYPE (TREE_TYPE (fndecl));
4689   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
4690
4691   if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
4692     return 0;
4693
4694   switch (fcode)
4695     {
4696     case BUILT_IN_CONSTANT_P:
4697       return fold_builtin_constant_p (arglist);
4698
4699     case BUILT_IN_CLASSIFY_TYPE:
4700       return fold_builtin_classify_type (arglist);
4701
4702     case BUILT_IN_STRLEN:
4703       if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
4704         {
4705           tree len = c_strlen (TREE_VALUE (arglist));
4706           if (len)
4707             {
4708               /* Convert from the internal "sizetype" type to "size_t".  */
4709               if (size_type_node)
4710                 len = convert (size_type_node, len);
4711               return len;
4712             }
4713         }
4714       break;
4715
4716     case BUILT_IN_SQRT:
4717     case BUILT_IN_SQRTF:
4718     case BUILT_IN_SQRTL:
4719       if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
4720         {
4721           enum built_in_function fcode;
4722           tree arg = TREE_VALUE (arglist);
4723
4724           /* Optimize sqrt of constant value.  */
4725           if (TREE_CODE (arg) == REAL_CST
4726               && ! TREE_CONSTANT_OVERFLOW (arg))
4727             {
4728               enum machine_mode mode;
4729               REAL_VALUE_TYPE r, x;
4730
4731               x = TREE_REAL_CST (arg);
4732               mode = TYPE_MODE (type);
4733               if (real_sqrt (&r, mode, &x)
4734                   || (!flag_trapping_math && !flag_errno_math))
4735                 return build_real (type, r);
4736             }
4737
4738           /* Optimize sqrt(exp(x)) = exp(x/2.0).  */
4739           fcode = builtin_mathfn_code (arg);
4740           if (flag_unsafe_math_optimizations
4741               && (fcode == BUILT_IN_EXP
4742                   || fcode == BUILT_IN_EXPF
4743                   || fcode == BUILT_IN_EXPL))
4744             {
4745               tree expfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
4746               arg = build (RDIV_EXPR, type,
4747                            TREE_VALUE (TREE_OPERAND (arg, 1)),
4748                            build_real (type, dconst2));
4749               arglist = build_tree_list (NULL_TREE, arg);
4750               return build_function_call_expr (expfn, arglist);
4751             }
4752         }
4753       break;
4754
4755     case BUILT_IN_EXP:
4756     case BUILT_IN_EXPF:
4757     case BUILT_IN_EXPL:
4758       if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
4759         {
4760           enum built_in_function fcode;
4761           tree arg = TREE_VALUE (arglist);
4762
4763           /* Optimize exp(0.0) = 1.0.  */
4764           if (real_zerop (arg))
4765             return build_real (type, dconst1);
4766
4767           /* Optimize exp(log(x)) = x.  */
4768           fcode = builtin_mathfn_code (arg);
4769           if (flag_unsafe_math_optimizations
4770               && (fcode == BUILT_IN_LOG
4771                   || fcode == BUILT_IN_LOGF
4772                   || fcode == BUILT_IN_LOGL))
4773             return TREE_VALUE (TREE_OPERAND (arg, 1));
4774         }
4775       break;
4776
4777     case BUILT_IN_LOG:
4778     case BUILT_IN_LOGF:
4779     case BUILT_IN_LOGL:
4780       if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
4781         {
4782           enum built_in_function fcode;
4783           tree arg = TREE_VALUE (arglist);
4784
4785           /* Optimize log(1.0) = 0.0.  */
4786           if (real_onep (arg))
4787             return build_real (type, dconst0);
4788
4789           /* Optimize log(exp(x)) = x.  */
4790           fcode = builtin_mathfn_code (arg);
4791           if (flag_unsafe_math_optimizations
4792               && (fcode == BUILT_IN_EXP
4793                   || fcode == BUILT_IN_EXPF
4794                   || fcode == BUILT_IN_EXPL))
4795             return TREE_VALUE (TREE_OPERAND (arg, 1));
4796
4797           /* Optimize log(sqrt(x)) = log(x)/2.0.  */
4798           if (flag_unsafe_math_optimizations
4799               && (fcode == BUILT_IN_SQRT
4800                   || fcode == BUILT_IN_SQRTF
4801                   || fcode == BUILT_IN_SQRTL))
4802             {
4803               tree logfn = build_function_call_expr (fndecl,
4804                                                      TREE_OPERAND (arg, 1));
4805               return fold (build (RDIV_EXPR, type, logfn,
4806                                   build_real (type, dconst2)));
4807             }
4808         }
4809       break;
4810
4811     case BUILT_IN_POW:
4812     case BUILT_IN_POWF:
4813     case BUILT_IN_POWL:
4814       if (validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
4815         {
4816           tree arg0 = TREE_VALUE (arglist);
4817           tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
4818
4819           /* Optimize pow(x,0.0) = 1.0.  */
4820           if (real_zerop (arg1))
4821             return omit_one_operand (type, build_real (type, dconst1), arg0);
4822
4823           /* Optimize pow(1.0,y) = 1.0.  */
4824           if (real_onep (arg0))
4825             return omit_one_operand (type, build_real (type, dconst1), arg1);
4826         }
4827       break;
4828
4829     case BUILT_IN_INF:
4830     case BUILT_IN_INFF:
4831     case BUILT_IN_INFL:
4832       return fold_builtin_inf (type, true);
4833
4834     case BUILT_IN_HUGE_VAL:
4835     case BUILT_IN_HUGE_VALF:
4836     case BUILT_IN_HUGE_VALL:
4837       return fold_builtin_inf (type, false);
4838
4839     case BUILT_IN_NAN:
4840     case BUILT_IN_NANF:
4841     case BUILT_IN_NANL:
4842       return fold_builtin_nan (arglist, type, true);
4843
4844     case BUILT_IN_NANS:
4845     case BUILT_IN_NANSF:
4846     case BUILT_IN_NANSL:
4847       return fold_builtin_nan (arglist, type, false);
4848
4849     case BUILT_IN_FLOOR:
4850     case BUILT_IN_FLOORF:
4851     case BUILT_IN_FLOORL:
4852     case BUILT_IN_CEIL:
4853     case BUILT_IN_CEILF:
4854     case BUILT_IN_CEILL:
4855     case BUILT_IN_TRUNC:
4856     case BUILT_IN_TRUNCF:
4857     case BUILT_IN_TRUNCL:
4858     case BUILT_IN_ROUND:
4859     case BUILT_IN_ROUNDF:
4860     case BUILT_IN_ROUNDL:
4861     case BUILT_IN_NEARBYINT:
4862     case BUILT_IN_NEARBYINTF:
4863     case BUILT_IN_NEARBYINTL:
4864       return fold_trunc_transparent_mathfn (exp);
4865
4866     default:
4867       break;
4868     }
4869
4870   return 0;
4871 }
4872
4873 /* Conveniently construct a function call expression.  */
4874
4875 tree
4876 build_function_call_expr (fn, arglist)
4877      tree fn, arglist;
4878 {
4879   tree call_expr;
4880
4881   call_expr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
4882   call_expr = build (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)),
4883                      call_expr, arglist);
4884   TREE_SIDE_EFFECTS (call_expr) = 1;
4885   return fold (call_expr);
4886 }
4887
4888 /* This function validates the types of a function call argument list
4889    represented as a tree chain of parameters against a specified list
4890    of tree_codes.  If the last specifier is a 0, that represents an
4891    ellipses, otherwise the last specifier must be a VOID_TYPE.  */
4892
4893 static int
4894 validate_arglist VPARAMS ((tree arglist, ...))
4895 {
4896   enum tree_code code;
4897   int res = 0;
4898
4899   VA_OPEN (ap, arglist);
4900   VA_FIXEDARG (ap, tree, arglist);
4901
4902   do
4903     {
4904       code = va_arg (ap, enum tree_code);
4905       switch (code)
4906         {
4907         case 0:
4908           /* This signifies an ellipses, any further arguments are all ok.  */
4909           res = 1;
4910           goto end;
4911         case VOID_TYPE:
4912           /* This signifies an endlink, if no arguments remain, return
4913              true, otherwise return false.  */
4914           res = arglist == 0;
4915           goto end;
4916         default:
4917           /* If no parameters remain or the parameter's code does not
4918              match the specified code, return false.  Otherwise continue
4919              checking any remaining arguments.  */
4920           if (arglist == 0
4921               || code != TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))))
4922             goto end;
4923           break;
4924         }
4925       arglist = TREE_CHAIN (arglist);
4926     }
4927   while (1);
4928
4929   /* We need gotos here since we can only have one VA_CLOSE in a
4930      function.  */
4931  end: ;
4932   VA_CLOSE (ap);
4933
4934   return res;
4935 }
4936
4937 /* Default version of target-specific builtin setup that does nothing.  */
4938
4939 void
4940 default_init_builtins ()
4941 {
4942 }
4943
4944 /* Default target-specific builtin expander that does nothing.  */
4945
4946 rtx
4947 default_expand_builtin (exp, target, subtarget, mode, ignore)
4948      tree exp ATTRIBUTE_UNUSED;
4949      rtx target ATTRIBUTE_UNUSED;
4950      rtx subtarget ATTRIBUTE_UNUSED;
4951      enum machine_mode mode ATTRIBUTE_UNUSED;
4952      int ignore ATTRIBUTE_UNUSED;
4953 {
4954   return NULL_RTX;
4955 }
4956
4957 /* Instantiate all remaining CONSTANT_P_RTX nodes.  */
4958
4959 void
4960 purge_builtin_constant_p ()
4961 {
4962   rtx insn, set, arg, new, note;
4963
4964   for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
4965     if (INSN_P (insn)
4966         && (set = single_set (insn)) != NULL_RTX
4967         && (GET_CODE (arg = SET_SRC (set)) == CONSTANT_P_RTX
4968             || (GET_CODE (arg) == SUBREG
4969                 && (GET_CODE (arg = SUBREG_REG (arg))
4970                     == CONSTANT_P_RTX))))
4971       {
4972         arg = XEXP (arg, 0);
4973         new = CONSTANT_P (arg) ? const1_rtx : const0_rtx;
4974         validate_change (insn, &SET_SRC (set), new, 0);
4975
4976         /* Remove the REG_EQUAL note from the insn.  */
4977         if ((note = find_reg_note (insn, REG_EQUAL, NULL_RTX)) != 0)
4978           remove_note (insn, note);
4979       }
4980 }
4981