OSDN Git Service

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