OSDN Git Service

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