OSDN Git Service

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