OSDN Git Service

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