OSDN Git Service

* config/h8300/h8300.c: Remove an extern declaration of
[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_LOG10:
1666     case BUILT_IN_LOG10F:
1667     case BUILT_IN_LOG10L:
1668       errno_set = true; builtin_optab = log10_optab; break;
1669     case BUILT_IN_LOG2:
1670     case BUILT_IN_LOG2F:
1671     case BUILT_IN_LOG2L:
1672       errno_set = true; builtin_optab = log2_optab; break;
1673     case BUILT_IN_TAN:
1674     case BUILT_IN_TANF:
1675     case BUILT_IN_TANL:
1676       builtin_optab = tan_optab; break;
1677     case BUILT_IN_ATAN:
1678     case BUILT_IN_ATANF:
1679     case BUILT_IN_ATANL:
1680       builtin_optab = atan_optab; break;
1681     case BUILT_IN_FLOOR:
1682     case BUILT_IN_FLOORF:
1683     case BUILT_IN_FLOORL:
1684       builtin_optab = floor_optab; break;
1685     case BUILT_IN_CEIL:
1686     case BUILT_IN_CEILF:
1687     case BUILT_IN_CEILL:
1688       builtin_optab = ceil_optab; break;
1689     case BUILT_IN_TRUNC:
1690     case BUILT_IN_TRUNCF:
1691     case BUILT_IN_TRUNCL:
1692       builtin_optab = btrunc_optab; break;
1693     case BUILT_IN_ROUND:
1694     case BUILT_IN_ROUNDF:
1695     case BUILT_IN_ROUNDL:
1696       builtin_optab = round_optab; break;
1697     case BUILT_IN_NEARBYINT:
1698     case BUILT_IN_NEARBYINTF:
1699     case BUILT_IN_NEARBYINTL:
1700       builtin_optab = nearbyint_optab; break;
1701     default:
1702       abort ();
1703     }
1704
1705   /* Make a suitable register to place result in.  */
1706   mode = TYPE_MODE (TREE_TYPE (exp));
1707
1708   if (! flag_errno_math || ! HONOR_NANS (mode))
1709     errno_set = false;
1710
1711   /* Before working hard, check whether the instruction is available.  */
1712   if (builtin_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1713     {
1714       target = gen_reg_rtx (mode);
1715
1716       /* Wrap the computation of the argument in a SAVE_EXPR, as we may
1717          need to expand the argument again.  This way, we will not perform
1718          side-effects more the once.  */
1719       narg = save_expr (arg);
1720       if (narg != arg)
1721         {
1722           arglist = build_tree_list (NULL_TREE, arg);
1723           exp = build_function_call_expr (fndecl, arglist);
1724         }
1725
1726       op0 = expand_expr (arg, subtarget, VOIDmode, 0);
1727
1728       emit_queue ();
1729       start_sequence ();
1730
1731       /* Compute into TARGET.
1732          Set TARGET to wherever the result comes back.  */
1733       target = expand_unop (mode, builtin_optab, op0, target, 0);
1734
1735       if (target != 0)
1736         {
1737           if (errno_set)
1738             expand_errno_check (exp, target);
1739
1740           /* Output the entire sequence.  */
1741           insns = get_insns ();
1742           end_sequence ();
1743           emit_insn (insns);
1744           return target;
1745         }
1746
1747       /* If we were unable to expand via the builtin, stop the sequence
1748          (without outputting the insns) and call to the library function
1749          with the stabilized argument list.  */
1750       end_sequence ();
1751     }
1752
1753   before_call = get_last_insn ();
1754
1755   target = expand_call (exp, target, target == const0_rtx);
1756
1757   /* If this is a sqrt operation and we don't care about errno, try to
1758      attach a REG_EQUAL note with a SQRT rtx to the emitted libcall.
1759      This allows the semantics of the libcall to be visible to the RTL
1760      optimizers.  */
1761   if (builtin_optab == sqrt_optab && !errno_set)
1762     {
1763       /* Search backwards through the insns emitted by expand_call looking
1764          for the instruction with the REG_RETVAL note.  */
1765       rtx last = get_last_insn ();
1766       while (last != before_call)
1767         {
1768           if (find_reg_note (last, REG_RETVAL, NULL))
1769             {
1770               rtx note = find_reg_note (last, REG_EQUAL, NULL);
1771               /* Check that the REQ_EQUAL note is an EXPR_LIST with
1772                  two elements, i.e. symbol_ref(sqrt) and the operand.  */
1773               if (note
1774                   && GET_CODE (note) == EXPR_LIST
1775                   && GET_CODE (XEXP (note, 0)) == EXPR_LIST
1776                   && XEXP (XEXP (note, 0), 1) != NULL_RTX
1777                   && XEXP (XEXP (XEXP (note, 0), 1), 1) == NULL_RTX)
1778                 {
1779                   rtx operand = XEXP (XEXP (XEXP (note, 0), 1), 0);
1780                   /* Check operand is a register with expected mode.  */
1781                   if (operand
1782                       && GET_CODE (operand) == REG
1783                       && GET_MODE (operand) == mode)
1784                     {
1785                       /* Replace the REG_EQUAL note with a SQRT rtx.  */
1786                       rtx equiv = gen_rtx_SQRT (mode, operand);
1787                       set_unique_reg_note (last, REG_EQUAL, equiv);
1788                     }
1789                 }
1790               break;
1791             }
1792           last = PREV_INSN (last);
1793         }
1794     }
1795
1796   return target;
1797 }
1798
1799 /* Expand a call to the builtin binary math functions (pow and atan2).
1800    Return 0 if a normal call should be emitted rather than expanding the
1801    function in-line.  EXP is the expression that is a call to the builtin
1802    function; if convenient, the result should be placed in TARGET.
1803    SUBTARGET may be used as the target for computing one of EXP's
1804    operands.  */
1805
1806 static rtx
1807 expand_builtin_mathfn_2 (tree exp, rtx target, rtx subtarget)
1808 {
1809   optab builtin_optab;
1810   rtx op0, op1, insns;
1811   tree fndecl = get_callee_fndecl (exp);
1812   tree arglist = TREE_OPERAND (exp, 1);
1813   tree arg0, arg1, temp, narg;
1814   enum machine_mode mode;
1815   bool errno_set = true;
1816   bool stable = true;
1817
1818   if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
1819     return 0;
1820
1821   arg0 = TREE_VALUE (arglist);
1822   arg1 = TREE_VALUE (TREE_CHAIN (arglist));
1823
1824   switch (DECL_FUNCTION_CODE (fndecl))
1825     {
1826     case BUILT_IN_POW:
1827     case BUILT_IN_POWF:
1828     case BUILT_IN_POWL:
1829       builtin_optab = pow_optab; break;
1830     case BUILT_IN_ATAN2:
1831     case BUILT_IN_ATAN2F:
1832     case BUILT_IN_ATAN2L:
1833       builtin_optab = atan2_optab; break;
1834     default:
1835       abort ();
1836     }
1837
1838   /* Make a suitable register to place result in.  */
1839   mode = TYPE_MODE (TREE_TYPE (exp));
1840
1841   /* Before working hard, check whether the instruction is available.  */
1842   if (builtin_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing)
1843     return 0;
1844
1845   target = gen_reg_rtx (mode);
1846
1847   if (! flag_errno_math || ! HONOR_NANS (mode))
1848     errno_set = false;
1849
1850   /* Alway stabilize the argument list.  */
1851   narg = save_expr (arg1);
1852   if (narg != arg1)
1853     {
1854       temp = build_tree_list (NULL_TREE, narg);
1855       stable = false;
1856     }
1857   else
1858     temp = TREE_CHAIN (arglist);
1859
1860   narg = save_expr (arg0);
1861   if (narg != arg0)
1862     {
1863       arglist = tree_cons (NULL_TREE, narg, temp);
1864       stable = false;
1865     }
1866   else if (! stable)
1867     arglist = tree_cons (NULL_TREE, arg0, temp);
1868
1869   if (! stable)
1870     exp = build_function_call_expr (fndecl, arglist);
1871
1872   op0 = expand_expr (arg0, subtarget, VOIDmode, 0);
1873   op1 = expand_expr (arg1, 0, VOIDmode, 0);
1874
1875   emit_queue ();
1876   start_sequence ();
1877
1878   /* Compute into TARGET.
1879      Set TARGET to wherever the result comes back.  */
1880   target = expand_binop (mode, builtin_optab, op0, op1,
1881                          target, 0, OPTAB_DIRECT);
1882
1883   /* If we were unable to expand via the builtin, stop the sequence
1884      (without outputting the insns) and call to the library function
1885      with the stabilized argument list.  */
1886   if (target == 0)
1887     {
1888       end_sequence ();
1889       return expand_call (exp, target, target == const0_rtx);
1890     }
1891
1892   if (errno_set)
1893     expand_errno_check (exp, target);
1894
1895   /* Output the entire sequence.  */
1896   insns = get_insns ();
1897   end_sequence ();
1898   emit_insn (insns);
1899
1900   return target;
1901 }
1902
1903 /* To evaluate powi(x,n), the floating point value x raised to the
1904    constant integer exponent n, we use a hybrid algorithm that
1905    combines the "window method" with look-up tables.  For an
1906    introduction to exponentiation algorithms and "addition chains",
1907    see section 4.6.3, "Evaluation of Powers" of Donald E. Knuth,
1908    "Seminumerical Algorithms", Vol. 2, "The Art of Computer Programming",
1909    3rd Edition, 1998, and Daniel M. Gordon, "A Survey of Fast Exponentiation
1910    Methods", Journal of Algorithms, Vol. 27, pp. 129-146, 1998.  */
1911
1912 /* Provide a default value for POWI_MAX_MULTS, the maximum number of
1913    multiplications to inline before calling the system library's pow
1914    function.  powi(x,n) requires at worst 2*bits(n)-2 multiplications,
1915    so this default never requires calling pow, powf or powl.  */
1916  
1917 #ifndef POWI_MAX_MULTS
1918 #define POWI_MAX_MULTS  (2*HOST_BITS_PER_WIDE_INT-2)
1919 #endif
1920
1921 /* The size of the "optimal power tree" lookup table.  All
1922    exponents less than this value are simply looked up in the
1923    powi_table below.  This threshold is also used to size the
1924    cache of pseudo registers that hold intermediate results.  */
1925 #define POWI_TABLE_SIZE 256
1926
1927 /* The size, in bits of the window, used in the "window method"
1928    exponentiation algorithm.  This is equivalent to a radix of
1929    (1<<POWI_WINDOW_SIZE) in the corresponding "m-ary method".  */
1930 #define POWI_WINDOW_SIZE 3
1931
1932 /* The following table is an efficient representation of an
1933    "optimal power tree".  For each value, i, the corresponding
1934    value, j, in the table states than an optimal evaluation
1935    sequence for calculating pow(x,i) can be found by evaluating
1936    pow(x,j)*pow(x,i-j).  An optimal power tree for the first
1937    100 integers is given in Knuth's "Seminumerical algorithms".  */
1938
1939 static const unsigned char powi_table[POWI_TABLE_SIZE] =
1940   {
1941       0,   1,   1,   2,   2,   3,   3,   4,  /*   0 -   7 */
1942       4,   6,   5,   6,   6,  10,   7,   9,  /*   8 -  15 */
1943       8,  16,   9,  16,  10,  12,  11,  13,  /*  16 -  23 */
1944      12,  17,  13,  18,  14,  24,  15,  26,  /*  24 -  31 */
1945      16,  17,  17,  19,  18,  33,  19,  26,  /*  32 -  39 */
1946      20,  25,  21,  40,  22,  27,  23,  44,  /*  40 -  47 */
1947      24,  32,  25,  34,  26,  29,  27,  44,  /*  48 -  55 */
1948      28,  31,  29,  34,  30,  60,  31,  36,  /*  56 -  63 */
1949      32,  64,  33,  34,  34,  46,  35,  37,  /*  64 -  71 */
1950      36,  65,  37,  50,  38,  48,  39,  69,  /*  72 -  79 */
1951      40,  49,  41,  43,  42,  51,  43,  58,  /*  80 -  87 */
1952      44,  64,  45,  47,  46,  59,  47,  76,  /*  88 -  95 */
1953      48,  65,  49,  66,  50,  67,  51,  66,  /*  96 - 103 */
1954      52,  70,  53,  74,  54, 104,  55,  74,  /* 104 - 111 */
1955      56,  64,  57,  69,  58,  78,  59,  68,  /* 112 - 119 */
1956      60,  61,  61,  80,  62,  75,  63,  68,  /* 120 - 127 */
1957      64,  65,  65, 128,  66, 129,  67,  90,  /* 128 - 135 */
1958      68,  73,  69, 131,  70,  94,  71,  88,  /* 136 - 143 */
1959      72, 128,  73,  98,  74, 132,  75, 121,  /* 144 - 151 */
1960      76, 102,  77, 124,  78, 132,  79, 106,  /* 152 - 159 */
1961      80,  97,  81, 160,  82,  99,  83, 134,  /* 160 - 167 */
1962      84,  86,  85,  95,  86, 160,  87, 100,  /* 168 - 175 */
1963      88, 113,  89,  98,  90, 107,  91, 122,  /* 176 - 183 */
1964      92, 111,  93, 102,  94, 126,  95, 150,  /* 184 - 191 */
1965      96, 128,  97, 130,  98, 133,  99, 195,  /* 192 - 199 */
1966     100, 128, 101, 123, 102, 164, 103, 138,  /* 200 - 207 */
1967     104, 145, 105, 146, 106, 109, 107, 149,  /* 208 - 215 */
1968     108, 200, 109, 146, 110, 170, 111, 157,  /* 216 - 223 */
1969     112, 128, 113, 130, 114, 182, 115, 132,  /* 224 - 231 */
1970     116, 200, 117, 132, 118, 158, 119, 206,  /* 232 - 239 */
1971     120, 240, 121, 162, 122, 147, 123, 152,  /* 240 - 247 */
1972     124, 166, 125, 214, 126, 138, 127, 153,  /* 248 - 255 */
1973   };
1974
1975
1976 /* Return the number of multiplications required to calculate
1977    powi(x,n) where n is less than POWI_TABLE_SIZE.  This is a
1978    subroutine of powi_cost.  CACHE is an array indicating
1979    which exponents have already been calculated.  */
1980
1981 static int
1982 powi_lookup_cost (unsigned HOST_WIDE_INT n, bool *cache)
1983 {
1984   /* If we've already calculated this exponent, then this evaluation
1985      doesn't require any additional multiplications.  */
1986   if (cache[n])
1987     return 0;
1988
1989   cache[n] = true;
1990   return powi_lookup_cost (n - powi_table[n], cache)
1991          + powi_lookup_cost (powi_table[n], cache) + 1;
1992 }
1993
1994 /* Return the number of multiplications required to calculate
1995    powi(x,n) for an arbitrary x, given the exponent N.  This
1996    function needs to be kept in sync with expand_powi below.  */
1997
1998 static int
1999 powi_cost (HOST_WIDE_INT n)
2000 {
2001   bool cache[POWI_TABLE_SIZE];
2002   unsigned HOST_WIDE_INT digit;
2003   unsigned HOST_WIDE_INT val;
2004   int result;
2005
2006   if (n == 0)
2007     return 0;
2008
2009   /* Ignore the reciprocal when calculating the cost.  */
2010   val = (n < 0) ? -n : n;
2011
2012   /* Initialize the exponent cache.  */
2013   memset (cache, 0, POWI_TABLE_SIZE * sizeof (bool));
2014   cache[1] = true;
2015
2016   result = 0;
2017
2018   while (val >= POWI_TABLE_SIZE)
2019     {
2020       if (val & 1)
2021         {
2022           digit = val & ((1 << POWI_WINDOW_SIZE) - 1);
2023           result += powi_lookup_cost (digit, cache)
2024                     + POWI_WINDOW_SIZE + 1;
2025           val >>= POWI_WINDOW_SIZE;
2026         }
2027       else
2028         {
2029           val >>= 1;
2030           result++;
2031         }
2032     }
2033   
2034   return result + powi_lookup_cost (val, cache);
2035 }
2036
2037 /* Recursive subroutine of expand_powi.  This function takes the array,
2038    CACHE, of already calculated exponents and an exponent N and returns
2039    an RTX that corresponds to CACHE[1]**N, as calculated in mode MODE.  */
2040
2041 static rtx
2042 expand_powi_1 (enum machine_mode mode, unsigned HOST_WIDE_INT n, rtx *cache)
2043 {
2044   unsigned HOST_WIDE_INT digit;
2045   rtx target, result;
2046   rtx op0, op1;
2047
2048   if (n < POWI_TABLE_SIZE)
2049     {
2050       if (cache[n])
2051         return cache[n];
2052
2053       target = gen_reg_rtx (mode);
2054       cache[n] = target;
2055
2056       op0 = expand_powi_1 (mode, n - powi_table[n], cache);
2057       op1 = expand_powi_1 (mode, powi_table[n], cache);
2058     }
2059   else if (n & 1)
2060     {
2061       target = gen_reg_rtx (mode);
2062       digit = n & ((1 << POWI_WINDOW_SIZE) - 1);
2063       op0 = expand_powi_1 (mode, n - digit, cache);
2064       op1 = expand_powi_1 (mode, digit, cache);
2065     }
2066   else
2067     {
2068       target = gen_reg_rtx (mode);
2069       op0 = expand_powi_1 (mode, n >> 1, cache);
2070       op1 = op0;
2071     }
2072
2073   result = expand_mult (mode, op0, op1, target, 0);
2074   if (result != target)
2075     emit_move_insn (target, result);
2076   return target;
2077 }
2078
2079 /* Expand the RTL to evaluate powi(x,n) in mode MODE.  X is the
2080    floating point operand in mode MODE, and N is the exponent.  This
2081    function needs to be kept in sync with powi_cost above.  */
2082    
2083 static rtx
2084 expand_powi (rtx x, enum machine_mode mode, HOST_WIDE_INT n)
2085 {
2086   unsigned HOST_WIDE_INT val;
2087   rtx cache[POWI_TABLE_SIZE];
2088   rtx result;
2089
2090   if (n == 0)
2091     return CONST1_RTX (mode);
2092
2093   val = (n < 0) ? -n : n;
2094
2095   memset (cache, 0, sizeof (cache));
2096   cache[1] = x;
2097
2098   result = expand_powi_1 (mode, (n < 0) ? -n : n, cache);
2099
2100   /* If the original exponent was negative, reciprocate the result.  */
2101   if (n < 0)
2102     result = expand_binop (mode, sdiv_optab, CONST1_RTX (mode),
2103                            result, NULL_RTX, 0, OPTAB_LIB_WIDEN);
2104
2105   return result;
2106 }
2107
2108 /* Expand a call to the pow built-in mathematical function.  Return 0 if
2109    a normal call should be emitted rather than expanding the function
2110    in-line.  EXP is the expression that is a call to the builtin
2111    function; if convenient, the result should be placed in TARGET.  */
2112
2113 static rtx
2114 expand_builtin_pow (tree exp, rtx target, rtx subtarget)
2115 {
2116   tree arglist = TREE_OPERAND (exp, 1);
2117   tree arg0, arg1;
2118
2119   if (! validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
2120     return 0;
2121
2122   arg0 = TREE_VALUE (arglist);
2123   arg1 = TREE_VALUE (TREE_CHAIN (arglist));
2124
2125   if (TREE_CODE (arg1) == REAL_CST
2126       && ! TREE_CONSTANT_OVERFLOW (arg1))
2127     {
2128       REAL_VALUE_TYPE cint;
2129       REAL_VALUE_TYPE c;
2130       HOST_WIDE_INT n;
2131
2132       c = TREE_REAL_CST (arg1);
2133       n = real_to_integer (&c);
2134       real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
2135       if (real_identical (&c, &cint))
2136         {
2137           /* If the exponent is -1, 0, 1 or 2, then expand_powi is exact.
2138              Otherwise, check the number of multiplications required.
2139              Note that pow never sets errno for an integer exponent.  */
2140           if ((n >= -1 && n <= 2)
2141               || (flag_unsafe_math_optimizations
2142                   && ! optimize_size
2143                   && powi_cost (n) <= POWI_MAX_MULTS))
2144             {
2145               enum machine_mode mode = TYPE_MODE (TREE_TYPE (exp));
2146               rtx op = expand_expr (arg0, subtarget, VOIDmode, 0);
2147               op = force_reg (mode, op);
2148               return expand_powi (op, mode, n);
2149             }
2150         }
2151     }
2152
2153   if (! flag_unsafe_math_optimizations)
2154     return NULL_RTX;
2155   return expand_builtin_mathfn_2 (exp, target, subtarget);
2156 }
2157
2158 /* Expand expression EXP which is a call to the strlen builtin.  Return 0
2159    if we failed the caller should emit a normal call, otherwise
2160    try to get the result in TARGET, if convenient.  */
2161
2162 static rtx
2163 expand_builtin_strlen (tree arglist, rtx target,
2164                        enum machine_mode target_mode)
2165 {
2166   if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
2167     return 0;
2168   else
2169     {
2170       rtx pat;
2171       tree len, src = TREE_VALUE (arglist);
2172       rtx result, src_reg, char_rtx, before_strlen;
2173       enum machine_mode insn_mode = target_mode, char_mode;
2174       enum insn_code icode = CODE_FOR_nothing;
2175       int align;
2176
2177       /* If the length can be computed at compile-time, return it.  */
2178       len = c_strlen (src, 0);
2179       if (len)
2180         return expand_expr (len, target, target_mode, EXPAND_NORMAL);
2181
2182       /* If the length can be computed at compile-time and is constant
2183          integer, but there are side-effects in src, evaluate
2184          src for side-effects, then return len.
2185          E.g. x = strlen (i++ ? "xfoo" + 1 : "bar");
2186          can be optimized into: i++; x = 3;  */
2187       len = c_strlen (src, 1);
2188       if (len && TREE_CODE (len) == INTEGER_CST)
2189         {
2190           expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
2191           return expand_expr (len, target, target_mode, EXPAND_NORMAL);
2192         }
2193
2194       align = get_pointer_alignment (src, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
2195
2196       /* If SRC is not a pointer type, don't do this operation inline.  */
2197       if (align == 0)
2198         return 0;
2199
2200       /* Bail out if we can't compute strlen in the right mode.  */
2201       while (insn_mode != VOIDmode)
2202         {
2203           icode = strlen_optab->handlers[(int) insn_mode].insn_code;
2204           if (icode != CODE_FOR_nothing)
2205             break;
2206
2207           insn_mode = GET_MODE_WIDER_MODE (insn_mode);
2208         }
2209       if (insn_mode == VOIDmode)
2210         return 0;
2211
2212       /* Make a place to write the result of the instruction.  */
2213       result = target;
2214       if (! (result != 0
2215              && GET_CODE (result) == REG
2216              && GET_MODE (result) == insn_mode
2217              && REGNO (result) >= FIRST_PSEUDO_REGISTER))
2218         result = gen_reg_rtx (insn_mode);
2219
2220       /* Make a place to hold the source address.  We will not expand
2221          the actual source until we are sure that the expansion will
2222          not fail -- there are trees that cannot be expanded twice.  */
2223       src_reg = gen_reg_rtx (Pmode);
2224
2225       /* Mark the beginning of the strlen sequence so we can emit the
2226          source operand later.  */
2227       before_strlen = get_last_insn ();
2228
2229       char_rtx = const0_rtx;
2230       char_mode = insn_data[(int) icode].operand[2].mode;
2231       if (! (*insn_data[(int) icode].operand[2].predicate) (char_rtx,
2232                                                             char_mode))
2233         char_rtx = copy_to_mode_reg (char_mode, char_rtx);
2234
2235       pat = GEN_FCN (icode) (result, gen_rtx_MEM (BLKmode, src_reg),
2236                              char_rtx, GEN_INT (align));
2237       if (! pat)
2238         return 0;
2239       emit_insn (pat);
2240
2241       /* Now that we are assured of success, expand the source.  */
2242       start_sequence ();
2243       pat = memory_address (BLKmode,
2244                             expand_expr (src, src_reg, ptr_mode, EXPAND_SUM));
2245       if (pat != src_reg)
2246         emit_move_insn (src_reg, pat);
2247       pat = get_insns ();
2248       end_sequence ();
2249
2250       if (before_strlen)
2251         emit_insn_after (pat, before_strlen);
2252       else
2253         emit_insn_before (pat, get_insns ());
2254
2255       /* Return the value in the proper mode for this function.  */
2256       if (GET_MODE (result) == target_mode)
2257         target = result;
2258       else if (target != 0)
2259         convert_move (target, result, 0);
2260       else
2261         target = convert_to_mode (target_mode, result, 0);
2262
2263       return target;
2264     }
2265 }
2266
2267 /* Expand a call to the strstr builtin.  Return 0 if we failed the
2268    caller should emit a normal call, otherwise try to get the result
2269    in TARGET, if convenient (and in mode MODE if that's convenient).  */
2270
2271 static rtx
2272 expand_builtin_strstr (tree arglist, rtx target, enum machine_mode mode)
2273 {
2274   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2275     return 0;
2276   else
2277     {
2278       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
2279       tree fn;
2280       const char *p1, *p2;
2281
2282       p2 = c_getstr (s2);
2283       if (p2 == NULL)
2284         return 0;
2285
2286       p1 = c_getstr (s1);
2287       if (p1 != NULL)
2288         {
2289           const char *r = strstr (p1, p2);
2290
2291           if (r == NULL)
2292             return const0_rtx;
2293
2294           /* Return an offset into the constant string argument.  */
2295           return expand_expr (fold (build (PLUS_EXPR, TREE_TYPE (s1),
2296                                            s1, convert (TREE_TYPE (s1),
2297                                                         ssize_int (r - p1)))),
2298                               target, mode, EXPAND_NORMAL);
2299         }
2300
2301       if (p2[0] == '\0')
2302         return expand_expr (s1, target, mode, EXPAND_NORMAL);
2303
2304       if (p2[1] != '\0')
2305         return 0;
2306
2307       fn = implicit_built_in_decls[BUILT_IN_STRCHR];
2308       if (!fn)
2309         return 0;
2310
2311       /* New argument list transforming strstr(s1, s2) to
2312          strchr(s1, s2[0]).  */
2313       arglist =
2314         build_tree_list (NULL_TREE, build_int_2 (p2[0], 0));
2315       arglist = tree_cons (NULL_TREE, s1, arglist);
2316       return expand_expr (build_function_call_expr (fn, arglist),
2317                           target, mode, EXPAND_NORMAL);
2318     }
2319 }
2320
2321 /* Expand a call to the strchr builtin.  Return 0 if we failed the
2322    caller should emit a normal call, otherwise try to get the result
2323    in TARGET, if convenient (and in mode MODE if that's convenient).  */
2324
2325 static rtx
2326 expand_builtin_strchr (tree arglist, rtx target, enum machine_mode mode)
2327 {
2328   if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2329     return 0;
2330   else
2331     {
2332       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
2333       const char *p1;
2334
2335       if (TREE_CODE (s2) != INTEGER_CST)
2336         return 0;
2337
2338       p1 = c_getstr (s1);
2339       if (p1 != NULL)
2340         {
2341           char c;
2342           const char *r;
2343
2344           if (target_char_cast (s2, &c))
2345             return 0;
2346
2347           r = strchr (p1, c);
2348
2349           if (r == NULL)
2350             return const0_rtx;
2351
2352           /* Return an offset into the constant string argument.  */
2353           return expand_expr (fold (build (PLUS_EXPR, TREE_TYPE (s1),
2354                                            s1, convert (TREE_TYPE (s1),
2355                                                         ssize_int (r - p1)))),
2356                               target, mode, EXPAND_NORMAL);
2357         }
2358
2359       /* FIXME: Should use here strchrM optab so that ports can optimize
2360          this.  */
2361       return 0;
2362     }
2363 }
2364
2365 /* Expand a call to the strrchr builtin.  Return 0 if we failed the
2366    caller should emit a normal call, otherwise try to get the result
2367    in TARGET, if convenient (and in mode MODE if that's convenient).  */
2368
2369 static rtx
2370 expand_builtin_strrchr (tree arglist, rtx target, enum machine_mode mode)
2371 {
2372   if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2373     return 0;
2374   else
2375     {
2376       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
2377       tree fn;
2378       const char *p1;
2379
2380       if (TREE_CODE (s2) != INTEGER_CST)
2381         return 0;
2382
2383       p1 = c_getstr (s1);
2384       if (p1 != NULL)
2385         {
2386           char c;
2387           const char *r;
2388
2389           if (target_char_cast (s2, &c))
2390             return 0;
2391
2392           r = strrchr (p1, c);
2393
2394           if (r == NULL)
2395             return const0_rtx;
2396
2397           /* Return an offset into the constant string argument.  */
2398           return expand_expr (fold (build (PLUS_EXPR, TREE_TYPE (s1),
2399                                            s1, convert (TREE_TYPE (s1),
2400                                                         ssize_int (r - p1)))),
2401                               target, mode, EXPAND_NORMAL);
2402         }
2403
2404       if (! integer_zerop (s2))
2405         return 0;
2406
2407       fn = implicit_built_in_decls[BUILT_IN_STRCHR];
2408       if (!fn)
2409         return 0;
2410
2411       /* Transform strrchr(s1, '\0') to strchr(s1, '\0').  */
2412       return expand_expr (build_function_call_expr (fn, arglist),
2413                           target, mode, EXPAND_NORMAL);
2414     }
2415 }
2416
2417 /* Expand a call to the strpbrk builtin.  Return 0 if we failed the
2418    caller should emit a normal call, otherwise try to get the result
2419    in TARGET, if convenient (and in mode MODE if that's convenient).  */
2420
2421 static rtx
2422 expand_builtin_strpbrk (tree arglist, rtx target, enum machine_mode mode)
2423 {
2424   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2425     return 0;
2426   else
2427     {
2428       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
2429       tree fn;
2430       const char *p1, *p2;
2431
2432       p2 = c_getstr (s2);
2433       if (p2 == NULL)
2434         return 0;
2435
2436       p1 = c_getstr (s1);
2437       if (p1 != NULL)
2438         {
2439           const char *r = strpbrk (p1, p2);
2440
2441           if (r == NULL)
2442             return const0_rtx;
2443
2444           /* Return an offset into the constant string argument.  */
2445           return expand_expr (fold (build (PLUS_EXPR, TREE_TYPE (s1),
2446                                            s1, convert (TREE_TYPE (s1),
2447                                                         ssize_int (r - p1)))),
2448                               target, mode, EXPAND_NORMAL);
2449         }
2450
2451       if (p2[0] == '\0')
2452         {
2453           /* strpbrk(x, "") == NULL.
2454              Evaluate and ignore the arguments in case they had
2455              side-effects.  */
2456           expand_expr (s1, const0_rtx, VOIDmode, EXPAND_NORMAL);
2457           return const0_rtx;
2458         }
2459
2460       if (p2[1] != '\0')
2461         return 0;  /* Really call strpbrk.  */
2462
2463       fn = implicit_built_in_decls[BUILT_IN_STRCHR];
2464       if (!fn)
2465         return 0;
2466
2467       /* New argument list transforming strpbrk(s1, s2) to
2468          strchr(s1, s2[0]).  */
2469       arglist =
2470         build_tree_list (NULL_TREE, build_int_2 (p2[0], 0));
2471       arglist = tree_cons (NULL_TREE, s1, arglist);
2472       return expand_expr (build_function_call_expr (fn, arglist),
2473                           target, mode, EXPAND_NORMAL);
2474     }
2475 }
2476
2477 /* Callback routine for store_by_pieces.  Read GET_MODE_BITSIZE (MODE)
2478    bytes from constant string DATA + OFFSET and return it as target
2479    constant.  */
2480
2481 static rtx
2482 builtin_memcpy_read_str (void *data, HOST_WIDE_INT offset,
2483                          enum machine_mode mode)
2484 {
2485   const char *str = (const char *) data;
2486
2487   if (offset < 0
2488       || ((unsigned HOST_WIDE_INT) offset + GET_MODE_SIZE (mode)
2489           > strlen (str) + 1))
2490     abort ();  /* Attempt to read past the end of constant string.  */
2491
2492   return c_readstr (str + offset, mode);
2493 }
2494
2495 /* Expand a call to the memcpy builtin, with arguments in ARGLIST.
2496    Return 0 if we failed, the caller should emit a normal call,
2497    otherwise try to get the result in TARGET, if convenient (and in
2498    mode MODE if that's convenient).  */
2499 static rtx
2500 expand_builtin_memcpy (tree arglist, rtx target, enum machine_mode mode)
2501 {
2502   if (!validate_arglist (arglist,
2503                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2504     return 0;
2505   else
2506     {
2507       tree dest = TREE_VALUE (arglist);
2508       tree src = TREE_VALUE (TREE_CHAIN (arglist));
2509       tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2510       const char *src_str;
2511       unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
2512       unsigned int dest_align
2513         = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2514       rtx dest_mem, src_mem, dest_addr, len_rtx;
2515
2516       /* If DEST is not a pointer type, call the normal function.  */
2517       if (dest_align == 0)
2518         return 0;
2519
2520       /* If the LEN parameter is zero, return DEST.  */
2521       if (integer_zerop (len))
2522         {
2523           /* Evaluate and ignore SRC in case it has side-effects.  */
2524           expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
2525           return expand_expr (dest, target, mode, EXPAND_NORMAL);
2526         }
2527
2528       /* If SRC and DEST are the same (and not volatile), return DEST.  */
2529       if (operand_equal_p (src, dest, 0))
2530         {
2531           /* Evaluate and ignore LEN in case it has side-effects.  */
2532           expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
2533           return expand_expr (dest, target, mode, EXPAND_NORMAL);
2534         }
2535
2536       /* If either SRC is not a pointer type, don't do this
2537          operation in-line.  */
2538       if (src_align == 0)
2539         return 0;
2540
2541       dest_mem = get_memory_rtx (dest);
2542       set_mem_align (dest_mem, dest_align);
2543       len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
2544       src_str = c_getstr (src);
2545
2546       /* If SRC is a string constant and block move would be done
2547          by pieces, we can avoid loading the string from memory
2548          and only stored the computed constants.  */
2549       if (src_str
2550           && GET_CODE (len_rtx) == CONST_INT
2551           && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
2552           && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
2553                                   (void *) src_str, dest_align))
2554         {
2555           dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
2556                                       builtin_memcpy_read_str,
2557                                       (void *) src_str, dest_align, 0);
2558           dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2559           dest_mem = convert_memory_address (ptr_mode, dest_mem);
2560           return dest_mem;
2561         }
2562
2563       src_mem = get_memory_rtx (src);
2564       set_mem_align (src_mem, src_align);
2565
2566       /* Copy word part most expediently.  */
2567       dest_addr = emit_block_move (dest_mem, src_mem, len_rtx,
2568                                    BLOCK_OP_NORMAL);
2569
2570       if (dest_addr == 0)
2571         {
2572           dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2573           dest_addr = convert_memory_address (ptr_mode, dest_addr);
2574         }
2575       return dest_addr;
2576     }
2577 }
2578
2579 /* Expand a call to the mempcpy builtin, with arguments in ARGLIST.
2580    Return 0 if we failed the caller should emit a normal call,
2581    otherwise try to get the result in TARGET, if convenient (and in
2582    mode MODE if that's convenient).  If ENDP is 0 return the
2583    destination pointer, if ENDP is 1 return the end pointer ala
2584    mempcpy, and if ENDP is 2 return the end pointer minus one ala
2585    stpcpy.  */
2586
2587 static rtx
2588 expand_builtin_mempcpy (tree arglist, rtx target, enum machine_mode mode,
2589                         int endp)
2590 {
2591   if (!validate_arglist (arglist,
2592                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2593     return 0;
2594   /* If return value is ignored, transform mempcpy into memcpy.  */
2595   else if (target == const0_rtx)
2596     {
2597       tree fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
2598
2599       if (!fn)
2600         return 0;
2601
2602       return expand_expr (build_function_call_expr (fn, arglist),
2603                           target, mode, EXPAND_NORMAL);
2604     }
2605   else
2606     {
2607       tree dest = TREE_VALUE (arglist);
2608       tree src = TREE_VALUE (TREE_CHAIN (arglist));
2609       tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2610       const char *src_str;
2611       unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
2612       unsigned int dest_align
2613         = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2614       rtx dest_mem, src_mem, len_rtx;
2615
2616       /* If DEST is not a pointer type, call the normal function.  */
2617       if (dest_align == 0)
2618         return 0;
2619
2620       /* If SRC and DEST are the same (and not volatile), do nothing.  */
2621       if (operand_equal_p (src, dest, 0))
2622         {
2623           tree expr;
2624
2625           if (endp == 0)
2626             {
2627               /* Evaluate and ignore LEN in case it has side-effects.  */
2628               expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
2629               return expand_expr (dest, target, mode, EXPAND_NORMAL);
2630             }
2631
2632           if (endp == 2)
2633             len = fold (build (MINUS_EXPR, TREE_TYPE (len), dest,
2634                                integer_one_node));
2635           len = convert (TREE_TYPE (dest), len);
2636           expr = fold (build (PLUS_EXPR, TREE_TYPE (dest), dest, len));
2637           return expand_expr (expr, target, mode, EXPAND_NORMAL);
2638         }
2639
2640       /* If LEN is not constant, call the normal function.  */
2641       if (! host_integerp (len, 1))
2642         return 0;
2643   
2644       /* If the LEN parameter is zero, return DEST.  */
2645       if (tree_low_cst (len, 1) == 0)
2646         {
2647           /* Evaluate and ignore SRC in case it has side-effects.  */
2648           expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
2649           return expand_expr (dest, target, mode, EXPAND_NORMAL);
2650         }
2651
2652       /* If either SRC is not a pointer type, don't do this
2653          operation in-line.  */
2654       if (src_align == 0)
2655         return 0;
2656
2657       len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
2658       src_str = c_getstr (src);
2659
2660       /* If SRC is a string constant and block move would be done
2661          by pieces, we can avoid loading the string from memory
2662          and only stored the computed constants.  */
2663       if (src_str
2664           && GET_CODE (len_rtx) == CONST_INT
2665           && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
2666           && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
2667                                   (void *) src_str, dest_align))
2668         {
2669           dest_mem = get_memory_rtx (dest);
2670           set_mem_align (dest_mem, dest_align);
2671           dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
2672                                       builtin_memcpy_read_str,
2673                                       (void *) src_str, dest_align, endp);
2674           dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2675           dest_mem = convert_memory_address (ptr_mode, dest_mem);
2676           return dest_mem;
2677         }
2678
2679       if (GET_CODE (len_rtx) == CONST_INT
2680           && can_move_by_pieces (INTVAL (len_rtx),
2681                                  MIN (dest_align, src_align)))
2682         {
2683           dest_mem = get_memory_rtx (dest);
2684           set_mem_align (dest_mem, dest_align);
2685           src_mem = get_memory_rtx (src);
2686           set_mem_align (src_mem, src_align);
2687           dest_mem = move_by_pieces (dest_mem, src_mem, INTVAL (len_rtx),
2688                                      MIN (dest_align, src_align), endp);
2689           dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2690           dest_mem = convert_memory_address (ptr_mode, dest_mem);
2691           return dest_mem;
2692         }
2693
2694       return 0;
2695     }
2696 }
2697
2698 /* Expand expression EXP, which is a call to the memmove builtin.  Return 0
2699    if we failed the caller should emit a normal call.  */
2700
2701 static rtx
2702 expand_builtin_memmove (tree arglist, rtx target, enum machine_mode mode)
2703 {
2704   if (!validate_arglist (arglist,
2705                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2706     return 0;
2707   else
2708     {
2709       tree dest = TREE_VALUE (arglist);
2710       tree src = TREE_VALUE (TREE_CHAIN (arglist));
2711       tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2712
2713       unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
2714       unsigned int dest_align
2715         = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2716
2717       /* If DEST is not a pointer type, call the normal function.  */
2718       if (dest_align == 0)
2719         return 0;
2720
2721       /* If the LEN parameter is zero, return DEST.  */
2722       if (integer_zerop (len))
2723         {
2724           /* Evaluate and ignore SRC in case it has side-effects.  */
2725           expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
2726           return expand_expr (dest, target, mode, EXPAND_NORMAL);
2727         }
2728
2729       /* If SRC and DEST are the same (and not volatile), return DEST.  */
2730       if (operand_equal_p (src, dest, 0))
2731         {
2732           /* Evaluate and ignore LEN in case it has side-effects.  */
2733           expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
2734           return expand_expr (dest, target, mode, EXPAND_NORMAL);
2735         }
2736
2737       /* If either SRC is not a pointer type, don't do this
2738          operation in-line.  */
2739       if (src_align == 0)
2740         return 0;
2741
2742       /* If src is categorized for a readonly section we can use
2743          normal memcpy.  */
2744       if (readonly_data_expr (src))
2745         {
2746           tree const fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
2747           if (!fn)
2748             return 0;
2749           return expand_expr (build_function_call_expr (fn, arglist),
2750                               target, mode, EXPAND_NORMAL);
2751         }
2752
2753       /* Otherwise, call the normal function.  */
2754       return 0;
2755    }
2756 }
2757
2758 /* Expand expression EXP, which is a call to the bcopy builtin.  Return 0
2759    if we failed the caller should emit a normal call.  */
2760
2761 static rtx
2762 expand_builtin_bcopy (tree arglist)
2763 {
2764   tree src, dest, size, newarglist;
2765
2766   if (!validate_arglist (arglist,
2767                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2768     return NULL_RTX;
2769
2770   src = TREE_VALUE (arglist);
2771   dest = TREE_VALUE (TREE_CHAIN (arglist));
2772   size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2773
2774   /* New argument list transforming bcopy(ptr x, ptr y, int z) to
2775      memmove(ptr y, ptr x, size_t z).   This is done this way
2776      so that if it isn't expanded inline, we fallback to
2777      calling bcopy instead of memmove.  */
2778
2779   newarglist = build_tree_list (NULL_TREE, convert (sizetype, size));
2780   newarglist = tree_cons (NULL_TREE, src, newarglist);
2781   newarglist = tree_cons (NULL_TREE, dest, newarglist);
2782
2783   return expand_builtin_memmove (newarglist, const0_rtx, VOIDmode);
2784 }
2785
2786 /* Expand expression EXP, which is a call to the strcpy builtin.  Return 0
2787    if we failed the caller should emit a normal call, otherwise try to get
2788    the result in TARGET, if convenient (and in mode MODE if that's
2789    convenient).  */
2790
2791 static rtx
2792 expand_builtin_strcpy (tree arglist, rtx target, enum machine_mode mode)
2793 {
2794   tree fn, len, src, dst;
2795
2796   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2797     return 0;
2798
2799   src = TREE_VALUE (TREE_CHAIN (arglist));
2800   dst = TREE_VALUE (arglist);
2801
2802   /* If SRC and DST are equal (and not volatile), return DST.  */
2803   if (operand_equal_p (src, dst, 0))
2804     return expand_expr (dst, target, mode, EXPAND_NORMAL);
2805
2806   fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
2807   if (!fn)
2808     return 0;
2809
2810   len = c_strlen (src, 1);
2811   if (len == 0 || TREE_SIDE_EFFECTS (len))
2812     return 0;
2813
2814   len = size_binop (PLUS_EXPR, len, ssize_int (1));
2815   arglist = build_tree_list (NULL_TREE, len);
2816   arglist = tree_cons (NULL_TREE, src, arglist);
2817   arglist = tree_cons (NULL_TREE, dst, arglist);
2818   return expand_expr (build_function_call_expr (fn, arglist),
2819                       target, mode, EXPAND_NORMAL);
2820 }
2821
2822 /* Expand a call to the stpcpy builtin, with arguments in ARGLIST.
2823    Return 0 if we failed the caller should emit a normal call,
2824    otherwise try to get the result in TARGET, if convenient (and in
2825    mode MODE if that's convenient).  */
2826
2827 static rtx
2828 expand_builtin_stpcpy (tree arglist, rtx target, enum machine_mode mode)
2829 {
2830   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2831     return 0;
2832   else
2833     {
2834       tree dst, src, len;
2835
2836       /* If return value is ignored, transform stpcpy into strcpy.  */
2837       if (target == const0_rtx)
2838         {
2839           tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
2840           if (!fn)
2841             return 0;
2842
2843           return expand_expr (build_function_call_expr (fn, arglist),
2844                               target, mode, EXPAND_NORMAL);
2845         }
2846
2847       /* Ensure we get an actual string whose length can be evaluated at
2848          compile-time, not an expression containing a string.  This is
2849          because the latter will potentially produce pessimized code
2850          when used to produce the return value.  */
2851       src = TREE_VALUE (TREE_CHAIN (arglist));
2852       if (! c_getstr (src) || ! (len = c_strlen (src, 0)))
2853         return 0;
2854
2855       dst = TREE_VALUE (arglist);
2856       len = fold (size_binop (PLUS_EXPR, len, ssize_int (1)));
2857       arglist = build_tree_list (NULL_TREE, len);
2858       arglist = tree_cons (NULL_TREE, src, arglist);
2859       arglist = tree_cons (NULL_TREE, dst, arglist);
2860       return expand_builtin_mempcpy (arglist, target, mode, /*endp=*/2);
2861     }
2862 }
2863
2864 /* Callback routine for store_by_pieces.  Read GET_MODE_BITSIZE (MODE)
2865    bytes from constant string DATA + OFFSET and return it as target
2866    constant.  */
2867
2868 static rtx
2869 builtin_strncpy_read_str (void *data, HOST_WIDE_INT offset,
2870                           enum machine_mode mode)
2871 {
2872   const char *str = (const char *) data;
2873
2874   if ((unsigned HOST_WIDE_INT) offset > strlen (str))
2875     return const0_rtx;
2876
2877   return c_readstr (str + offset, mode);
2878 }
2879
2880 /* Expand expression EXP, which is a call to the strncpy builtin.  Return 0
2881    if we failed the caller should emit a normal call.  */
2882
2883 static rtx
2884 expand_builtin_strncpy (tree arglist, rtx target, enum machine_mode mode)
2885 {
2886   if (!validate_arglist (arglist,
2887                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2888     return 0;
2889   else
2890     {
2891       tree slen = c_strlen (TREE_VALUE (TREE_CHAIN (arglist)), 1);
2892       tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2893       tree fn;
2894
2895       /* We must be passed a constant len parameter.  */
2896       if (TREE_CODE (len) != INTEGER_CST)
2897         return 0;
2898
2899       /* If the len parameter is zero, return the dst parameter.  */
2900       if (integer_zerop (len))
2901         {
2902           /* Evaluate and ignore the src argument in case it has
2903              side-effects.  */
2904           expand_expr (TREE_VALUE (TREE_CHAIN (arglist)), const0_rtx,
2905                        VOIDmode, EXPAND_NORMAL);
2906           /* Return the dst parameter.  */
2907           return expand_expr (TREE_VALUE (arglist), target, mode,
2908                               EXPAND_NORMAL);
2909         }
2910
2911       /* Now, we must be passed a constant src ptr parameter.  */
2912       if (slen == 0 || TREE_CODE (slen) != INTEGER_CST)
2913         return 0;
2914
2915       slen = size_binop (PLUS_EXPR, slen, ssize_int (1));
2916
2917       /* We're required to pad with trailing zeros if the requested
2918          len is greater than strlen(s2)+1.  In that case try to
2919          use store_by_pieces, if it fails, punt.  */
2920       if (tree_int_cst_lt (slen, len))
2921         {
2922           tree dest = TREE_VALUE (arglist);
2923           unsigned int dest_align
2924             = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2925           const char *p = c_getstr (TREE_VALUE (TREE_CHAIN (arglist)));
2926           rtx dest_mem;
2927
2928           if (!p || dest_align == 0 || !host_integerp (len, 1)
2929               || !can_store_by_pieces (tree_low_cst (len, 1),
2930                                        builtin_strncpy_read_str,
2931                                        (void *) p, dest_align))
2932             return 0;
2933
2934           dest_mem = get_memory_rtx (dest);
2935           store_by_pieces (dest_mem, tree_low_cst (len, 1),
2936                            builtin_strncpy_read_str,
2937                            (void *) p, dest_align, 0);
2938           dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2939           dest_mem = convert_memory_address (ptr_mode, dest_mem);
2940           return dest_mem;
2941         }
2942
2943       /* OK transform into builtin memcpy.  */
2944       fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
2945       if (!fn)
2946         return 0;
2947       return expand_expr (build_function_call_expr (fn, arglist),
2948                           target, mode, EXPAND_NORMAL);
2949     }
2950 }
2951
2952 /* Callback routine for store_by_pieces.  Read GET_MODE_BITSIZE (MODE)
2953    bytes from constant string DATA + OFFSET and return it as target
2954    constant.  */
2955
2956 static rtx
2957 builtin_memset_read_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
2958                          enum machine_mode mode)
2959 {
2960   const char *c = (const char *) data;
2961   char *p = alloca (GET_MODE_SIZE (mode));
2962
2963   memset (p, *c, GET_MODE_SIZE (mode));
2964
2965   return c_readstr (p, mode);
2966 }
2967
2968 /* Callback routine for store_by_pieces.  Return the RTL of a register
2969    containing GET_MODE_SIZE (MODE) consecutive copies of the unsigned
2970    char value given in the RTL register data.  For example, if mode is
2971    4 bytes wide, return the RTL for 0x01010101*data.  */
2972
2973 static rtx
2974 builtin_memset_gen_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
2975                         enum machine_mode mode)
2976 {
2977   rtx target, coeff;
2978   size_t size;
2979   char *p;
2980
2981   size = GET_MODE_SIZE (mode);
2982   if (size == 1)
2983     return (rtx) data;
2984
2985   p = alloca (size);
2986   memset (p, 1, size);
2987   coeff = c_readstr (p, mode);
2988
2989   target = convert_to_mode (mode, (rtx) data, 1);
2990   target = expand_mult (mode, target, coeff, NULL_RTX, 1);
2991   return force_reg (mode, target);
2992 }
2993
2994 /* Expand expression EXP, which is a call to the memset builtin.  Return 0
2995    if we failed the caller should emit a normal call, otherwise try to get
2996    the result in TARGET, if convenient (and in mode MODE if that's
2997    convenient).  */
2998
2999 static rtx
3000 expand_builtin_memset (tree arglist, rtx target, enum machine_mode mode)
3001 {
3002   if (!validate_arglist (arglist,
3003                          POINTER_TYPE, INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
3004     return 0;
3005   else
3006     {
3007       tree dest = TREE_VALUE (arglist);
3008       tree val = TREE_VALUE (TREE_CHAIN (arglist));
3009       tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3010       char c;
3011
3012       unsigned int dest_align
3013         = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
3014       rtx dest_mem, dest_addr, len_rtx;
3015
3016       /* If DEST is not a pointer type, don't do this
3017          operation in-line.  */
3018       if (dest_align == 0)
3019         return 0;
3020
3021       /* If the LEN parameter is zero, return DEST.  */
3022       if (integer_zerop (len))
3023         {
3024           /* Evaluate and ignore VAL in case it has side-effects.  */
3025           expand_expr (val, const0_rtx, VOIDmode, EXPAND_NORMAL);
3026           return expand_expr (dest, target, mode, EXPAND_NORMAL);
3027         }
3028
3029       if (TREE_CODE (val) != INTEGER_CST)
3030         {
3031           rtx val_rtx;
3032
3033           if (!host_integerp (len, 1))
3034             return 0;
3035
3036           if (optimize_size && tree_low_cst (len, 1) > 1)
3037             return 0;
3038
3039           /* Assume that we can memset by pieces if we can store the
3040            * the coefficients by pieces (in the required modes).
3041            * We can't pass builtin_memset_gen_str as that emits RTL.  */
3042           c = 1;
3043           if (!can_store_by_pieces (tree_low_cst (len, 1),
3044                                     builtin_memset_read_str,
3045                                     &c, dest_align))
3046             return 0;
3047
3048           val = fold (build1 (CONVERT_EXPR, unsigned_char_type_node, val));
3049           val_rtx = expand_expr (val, NULL_RTX, VOIDmode, 0);
3050           val_rtx = force_reg (TYPE_MODE (unsigned_char_type_node),
3051                                val_rtx);
3052           dest_mem = get_memory_rtx (dest);
3053           store_by_pieces (dest_mem, tree_low_cst (len, 1),
3054                            builtin_memset_gen_str,
3055                            val_rtx, dest_align, 0);
3056           dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3057           dest_mem = convert_memory_address (ptr_mode, dest_mem);
3058           return dest_mem;
3059         }
3060
3061       if (target_char_cast (val, &c))
3062         return 0;
3063
3064       if (c)
3065         {
3066           if (!host_integerp (len, 1))
3067             return 0;
3068           if (!can_store_by_pieces (tree_low_cst (len, 1),
3069                                     builtin_memset_read_str, &c,
3070                                     dest_align))
3071             return 0;
3072
3073           dest_mem = get_memory_rtx (dest);
3074           store_by_pieces (dest_mem, tree_low_cst (len, 1),
3075                            builtin_memset_read_str,
3076                            &c, dest_align, 0);
3077           dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3078           dest_mem = convert_memory_address (ptr_mode, dest_mem);
3079           return dest_mem;
3080         }
3081
3082       len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
3083
3084       dest_mem = get_memory_rtx (dest);
3085       set_mem_align (dest_mem, dest_align);
3086       dest_addr = clear_storage (dest_mem, len_rtx);
3087
3088       if (dest_addr == 0)
3089         {
3090           dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3091           dest_addr = convert_memory_address (ptr_mode, dest_addr);
3092         }
3093
3094       return dest_addr;
3095     }
3096 }
3097
3098 /* Expand expression EXP, which is a call to the bzero builtin.  Return 0
3099    if we failed the caller should emit a normal call.  */
3100
3101 static rtx
3102 expand_builtin_bzero (tree arglist)
3103 {
3104   tree dest, size, newarglist;
3105
3106   if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3107     return NULL_RTX;
3108
3109   dest = TREE_VALUE (arglist);
3110   size = TREE_VALUE (TREE_CHAIN (arglist));
3111
3112   /* New argument list transforming bzero(ptr x, int y) to
3113      memset(ptr x, int 0, size_t y).   This is done this way
3114      so that if it isn't expanded inline, we fallback to
3115      calling bzero instead of memset.  */
3116
3117   newarglist = build_tree_list (NULL_TREE, convert (sizetype, size));
3118   newarglist = tree_cons (NULL_TREE, integer_zero_node, newarglist);
3119   newarglist = tree_cons (NULL_TREE, dest, newarglist);
3120
3121   return expand_builtin_memset (newarglist, const0_rtx, VOIDmode);
3122 }
3123
3124 /* Expand expression EXP, which is a call to the memcmp built-in function.
3125    ARGLIST is the argument list for this call.  Return 0 if we failed and the
3126    caller should emit a normal call, otherwise try to get the result in
3127    TARGET, if convenient (and in mode MODE, if that's convenient).  */
3128
3129 static rtx
3130 expand_builtin_memcmp (tree exp ATTRIBUTE_UNUSED, tree arglist, rtx target,
3131                        enum machine_mode mode)
3132 {
3133   tree arg1, arg2, len;
3134   const char *p1, *p2;
3135
3136   if (!validate_arglist (arglist,
3137                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3138     return 0;
3139
3140   arg1 = TREE_VALUE (arglist);
3141   arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3142   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3143
3144   /* If the len parameter is zero, return zero.  */
3145   if (integer_zerop (len))
3146     {
3147       /* Evaluate and ignore arg1 and arg2 in case they have
3148          side-effects.  */
3149       expand_expr (arg1, const0_rtx, VOIDmode, EXPAND_NORMAL);
3150       expand_expr (arg2, const0_rtx, VOIDmode, EXPAND_NORMAL);
3151       return const0_rtx;
3152     }
3153
3154   /* If both arguments are equal (and not volatile), return zero.  */
3155   if (operand_equal_p (arg1, arg2, 0))
3156     {
3157       /* Evaluate and ignore len in case it has side-effects.  */
3158       expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
3159       return const0_rtx;
3160     }
3161
3162   p1 = c_getstr (arg1);
3163   p2 = c_getstr (arg2);
3164
3165   /* If all arguments are constant, and the value of len is not greater
3166      than the lengths of arg1 and arg2, evaluate at compile-time.  */
3167   if (host_integerp (len, 1) && p1 && p2
3168       && compare_tree_int (len, strlen (p1) + 1) <= 0
3169       && compare_tree_int (len, strlen (p2) + 1) <= 0)
3170     {
3171       const int r = memcmp (p1, p2, tree_low_cst (len, 1));
3172
3173       return (r < 0 ? constm1_rtx : (r > 0 ? const1_rtx : const0_rtx));
3174     }
3175
3176   /* If len parameter is one, return an expression corresponding to
3177      (*(const unsigned char*)arg1 - (const unsigned char*)arg2).  */
3178   if (integer_onep (len))
3179     {
3180       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
3181       tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
3182       tree ind1 =
3183       fold (build1 (CONVERT_EXPR, integer_type_node,
3184                     build1 (INDIRECT_REF, cst_uchar_node,
3185                             build1 (NOP_EXPR, cst_uchar_ptr_node, arg1))));
3186       tree ind2 =
3187       fold (build1 (CONVERT_EXPR, integer_type_node,
3188                     build1 (INDIRECT_REF, cst_uchar_node,
3189                             build1 (NOP_EXPR, cst_uchar_ptr_node, arg2))));
3190       tree result = fold (build (MINUS_EXPR, integer_type_node, ind1, ind2));
3191       return expand_expr (result, target, mode, EXPAND_NORMAL);
3192     }
3193
3194 #if defined HAVE_cmpmemsi || defined HAVE_cmpstrsi
3195   {
3196     rtx arg1_rtx, arg2_rtx, arg3_rtx;
3197     rtx result;
3198     rtx insn;
3199
3200     int arg1_align
3201       = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3202     int arg2_align
3203       = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3204     enum machine_mode insn_mode;
3205
3206 #ifdef HAVE_cmpmemsi
3207     if (HAVE_cmpmemsi)
3208       insn_mode = insn_data[(int) CODE_FOR_cmpmemsi].operand[0].mode;
3209     else
3210 #endif
3211 #ifdef HAVE_cmpstrsi
3212     if (HAVE_cmpstrsi)
3213       insn_mode = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
3214     else
3215 #endif
3216       return 0;     
3217
3218     /* If we don't have POINTER_TYPE, call the function.  */
3219     if (arg1_align == 0 || arg2_align == 0)
3220       return 0;
3221
3222     /* Make a place to write the result of the instruction.  */
3223     result = target;
3224     if (! (result != 0
3225            && GET_CODE (result) == REG && GET_MODE (result) == insn_mode
3226            && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3227       result = gen_reg_rtx (insn_mode);
3228
3229     arg1_rtx = get_memory_rtx (arg1);
3230     arg2_rtx = get_memory_rtx (arg2);
3231     arg3_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
3232 #ifdef HAVE_cmpmemsi
3233     if (HAVE_cmpmemsi)
3234       insn = gen_cmpmemsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3235                            GEN_INT (MIN (arg1_align, arg2_align)));
3236     else
3237 #endif
3238 #ifdef HAVE_cmpstrsi
3239     if (HAVE_cmpstrsi)
3240       insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3241                            GEN_INT (MIN (arg1_align, arg2_align)));
3242     else
3243 #endif
3244       abort ();
3245
3246     if (insn)
3247       emit_insn (insn);
3248     else
3249       emit_library_call_value (memcmp_libfunc, result, LCT_PURE_MAKE_BLOCK,
3250                                TYPE_MODE (integer_type_node), 3,
3251                                XEXP (arg1_rtx, 0), Pmode,
3252                                XEXP (arg2_rtx, 0), Pmode,
3253                                convert_to_mode (TYPE_MODE (sizetype), arg3_rtx,
3254                                                 TREE_UNSIGNED (sizetype)),
3255                                TYPE_MODE (sizetype));
3256
3257     /* Return the value in the proper mode for this function.  */
3258     mode = TYPE_MODE (TREE_TYPE (exp));
3259     if (GET_MODE (result) == mode)
3260       return result;
3261     else if (target != 0)
3262       {
3263         convert_move (target, result, 0);
3264         return target;
3265       }
3266     else
3267       return convert_to_mode (mode, result, 0);
3268   }
3269 #endif
3270
3271   return 0;
3272 }
3273
3274 /* Expand expression EXP, which is a call to the strcmp builtin.  Return 0
3275    if we failed the caller should emit a normal call, otherwise try to get
3276    the result in TARGET, if convenient.  */
3277
3278 static rtx
3279 expand_builtin_strcmp (tree exp, rtx target, enum machine_mode mode)
3280 {
3281   tree arglist = TREE_OPERAND (exp, 1);
3282   tree arg1, arg2;
3283   const char *p1, *p2;
3284
3285   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3286     return 0;
3287
3288   arg1 = TREE_VALUE (arglist);
3289   arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3290
3291   /* If both arguments are equal (and not volatile), return zero.  */
3292   if (operand_equal_p (arg1, arg2, 0))
3293     return const0_rtx;
3294
3295   p1 = c_getstr (arg1);
3296   p2 = c_getstr (arg2);
3297
3298   if (p1 && p2)
3299     {
3300       const int i = strcmp (p1, p2);
3301       return (i < 0 ? constm1_rtx : (i > 0 ? const1_rtx : const0_rtx));
3302     }
3303
3304   /* If either arg is "", return an expression corresponding to
3305      (*(const unsigned char*)arg1 - (const unsigned char*)arg2).  */
3306   if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
3307     {
3308       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
3309       tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
3310       tree ind1 =
3311         fold (build1 (CONVERT_EXPR, integer_type_node,
3312                       build1 (INDIRECT_REF, cst_uchar_node,
3313                               build1 (NOP_EXPR, cst_uchar_ptr_node, arg1))));
3314       tree ind2 =
3315         fold (build1 (CONVERT_EXPR, integer_type_node,
3316                       build1 (INDIRECT_REF, cst_uchar_node,
3317                               build1 (NOP_EXPR, cst_uchar_ptr_node, arg2))));
3318       tree result = fold (build (MINUS_EXPR, integer_type_node, ind1, ind2));
3319       return expand_expr (result, target, mode, EXPAND_NORMAL);
3320     }
3321
3322 #ifdef HAVE_cmpstrsi
3323   if (HAVE_cmpstrsi)
3324   {
3325     tree len, len1, len2;
3326     rtx arg1_rtx, arg2_rtx, arg3_rtx;
3327     rtx result, insn;
3328     tree fndecl;
3329
3330     int arg1_align
3331       = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3332     int arg2_align
3333       = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3334     enum machine_mode insn_mode
3335       = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
3336
3337     len1 = c_strlen (arg1, 1);
3338     len2 = c_strlen (arg2, 1);
3339
3340     if (len1)
3341       len1 = size_binop (PLUS_EXPR, ssize_int (1), len1);
3342     if (len2)
3343       len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
3344
3345     /* If we don't have a constant length for the first, use the length
3346        of the second, if we know it.  We don't require a constant for
3347        this case; some cost analysis could be done if both are available
3348        but neither is constant.  For now, assume they're equally cheap,
3349        unless one has side effects.  If both strings have constant lengths,
3350        use the smaller.  */
3351
3352     if (!len1)
3353       len = len2;
3354     else if (!len2)
3355       len = len1;
3356     else if (TREE_SIDE_EFFECTS (len1))
3357       len = len2;
3358     else if (TREE_SIDE_EFFECTS (len2))
3359       len = len1;
3360     else if (TREE_CODE (len1) != INTEGER_CST)
3361       len = len2;
3362     else if (TREE_CODE (len2) != INTEGER_CST)
3363       len = len1;
3364     else if (tree_int_cst_lt (len1, len2))
3365       len = len1;
3366     else
3367       len = len2;
3368
3369     /* If both arguments have side effects, we cannot optimize.  */
3370     if (!len || TREE_SIDE_EFFECTS (len))
3371       return 0;
3372
3373     /* If we don't have POINTER_TYPE, call the function.  */
3374     if (arg1_align == 0 || arg2_align == 0)
3375       return 0;
3376
3377     /* Make a place to write the result of the instruction.  */
3378     result = target;
3379     if (! (result != 0
3380            && GET_CODE (result) == REG && GET_MODE (result) == insn_mode
3381            && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3382       result = gen_reg_rtx (insn_mode);
3383
3384     /* Stabilize the arguments in case gen_cmpstrsi fails.  */
3385     arg1 = save_expr (arg1);
3386     arg2 = save_expr (arg2);
3387
3388     arg1_rtx = get_memory_rtx (arg1);
3389     arg2_rtx = get_memory_rtx (arg2);
3390     arg3_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
3391     insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3392                          GEN_INT (MIN (arg1_align, arg2_align)));
3393     if (insn)
3394       {
3395         emit_insn (insn);
3396
3397         /* Return the value in the proper mode for this function.  */
3398         mode = TYPE_MODE (TREE_TYPE (exp));
3399         if (GET_MODE (result) == mode)
3400           return result;
3401         if (target == 0)
3402           return convert_to_mode (mode, result, 0);
3403         convert_move (target, result, 0);
3404         return target;
3405       }
3406
3407     /* Expand the library call ourselves using a stabilized argument
3408        list to avoid re-evaluating the function's arguments twice.  */
3409     arglist = build_tree_list (NULL_TREE, arg2);
3410     arglist = tree_cons (NULL_TREE, arg1, arglist);
3411     fndecl = get_callee_fndecl (exp);
3412     exp = build_function_call_expr (fndecl, arglist);
3413     return expand_call (exp, target, target == const0_rtx);
3414   }
3415 #endif
3416   return 0;
3417 }
3418
3419 /* Expand expression EXP, which is a call to the strncmp builtin.  Return 0
3420    if we failed the caller should emit a normal call, otherwise try to get
3421    the result in TARGET, if convenient.  */
3422
3423 static rtx
3424 expand_builtin_strncmp (tree exp, rtx target, enum machine_mode mode)
3425 {
3426   tree arglist = TREE_OPERAND (exp, 1);
3427   tree arg1, arg2, arg3;
3428   const char *p1, *p2;
3429
3430   if (!validate_arglist (arglist,
3431                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3432     return 0;
3433
3434   arg1 = TREE_VALUE (arglist);
3435   arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3436   arg3 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3437
3438   /* If the len parameter is zero, return zero.  */
3439   if (integer_zerop (arg3))
3440     {
3441       /* Evaluate and ignore arg1 and arg2 in case they have
3442          side-effects.  */
3443       expand_expr (arg1, const0_rtx, VOIDmode, EXPAND_NORMAL);
3444       expand_expr (arg2, const0_rtx, VOIDmode, EXPAND_NORMAL);
3445       return const0_rtx;
3446     }
3447
3448   /* If arg1 and arg2 are equal (and not volatile), return zero.  */
3449   if (operand_equal_p (arg1, arg2, 0))
3450     {
3451       /* Evaluate and ignore arg3 in case it has side-effects.  */
3452       expand_expr (arg3, const0_rtx, VOIDmode, EXPAND_NORMAL);
3453       return const0_rtx;
3454     }
3455
3456   p1 = c_getstr (arg1);
3457   p2 = c_getstr (arg2);
3458
3459   /* If all arguments are constant, evaluate at compile-time.  */
3460   if (host_integerp (arg3, 1) && p1 && p2)
3461     {
3462       const int r = strncmp (p1, p2, tree_low_cst (arg3, 1));
3463       return (r < 0 ? constm1_rtx : (r > 0 ? const1_rtx : const0_rtx));
3464     }
3465
3466   /* If len == 1 or (either string parameter is "" and (len >= 1)),
3467       return (*(const u_char*)arg1 - *(const u_char*)arg2).  */
3468   if (host_integerp (arg3, 1)
3469       && (tree_low_cst (arg3, 1) == 1
3470           || (tree_low_cst (arg3, 1) > 1
3471               && ((p1 && *p1 == '\0') || (p2 && *p2 == '\0')))))
3472     {
3473       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
3474       tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
3475       tree ind1 =
3476         fold (build1 (CONVERT_EXPR, integer_type_node,
3477                       build1 (INDIRECT_REF, cst_uchar_node,
3478                               build1 (NOP_EXPR, cst_uchar_ptr_node, arg1))));
3479       tree ind2 =
3480         fold (build1 (CONVERT_EXPR, integer_type_node,
3481                       build1 (INDIRECT_REF, cst_uchar_node,
3482                               build1 (NOP_EXPR, cst_uchar_ptr_node, arg2))));
3483       tree result = fold (build (MINUS_EXPR, integer_type_node, ind1, ind2));
3484       return expand_expr (result, target, mode, EXPAND_NORMAL);
3485     }
3486
3487   /* If c_strlen can determine an expression for one of the string
3488      lengths, and it doesn't have side effects, then emit cmpstrsi
3489      using length MIN(strlen(string)+1, arg3).  */
3490 #ifdef HAVE_cmpstrsi
3491   if (HAVE_cmpstrsi)
3492   {
3493     tree len, len1, len2;
3494     rtx arg1_rtx, arg2_rtx, arg3_rtx;
3495     rtx result, insn;
3496     tree fndecl;
3497
3498     int arg1_align
3499       = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3500     int arg2_align
3501       = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3502     enum machine_mode insn_mode
3503       = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
3504
3505     len1 = c_strlen (arg1, 1);
3506     len2 = c_strlen (arg2, 1);
3507
3508     if (len1)
3509       len1 = size_binop (PLUS_EXPR, ssize_int (1), len1);
3510     if (len2)
3511       len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
3512
3513     /* If we don't have a constant length for the first, use the length
3514        of the second, if we know it.  We don't require a constant for
3515        this case; some cost analysis could be done if both are available
3516        but neither is constant.  For now, assume they're equally cheap,
3517        unless one has side effects.  If both strings have constant lengths,
3518        use the smaller.  */
3519
3520     if (!len1)
3521       len = len2;
3522     else if (!len2)
3523       len = len1;
3524     else if (TREE_SIDE_EFFECTS (len1))
3525       len = len2;
3526     else if (TREE_SIDE_EFFECTS (len2))
3527       len = len1;
3528     else if (TREE_CODE (len1) != INTEGER_CST)
3529       len = len2;
3530     else if (TREE_CODE (len2) != INTEGER_CST)
3531       len = len1;
3532     else if (tree_int_cst_lt (len1, len2))
3533       len = len1;
3534     else
3535       len = len2;
3536
3537     /* If both arguments have side effects, we cannot optimize.  */
3538     if (!len || TREE_SIDE_EFFECTS (len))
3539       return 0;
3540
3541     /* The actual new length parameter is MIN(len,arg3).  */
3542     len = fold (build (MIN_EXPR, TREE_TYPE (len), len, arg3));
3543
3544     /* If we don't have POINTER_TYPE, call the function.  */
3545     if (arg1_align == 0 || arg2_align == 0)
3546       return 0;
3547
3548     /* Make a place to write the result of the instruction.  */
3549     result = target;
3550     if (! (result != 0
3551            && GET_CODE (result) == REG && GET_MODE (result) == insn_mode
3552            && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3553       result = gen_reg_rtx (insn_mode);
3554
3555     /* Stabilize the arguments in case gen_cmpstrsi fails.  */
3556     arg1 = save_expr (arg1);
3557     arg2 = save_expr (arg2);
3558     len = save_expr (len);
3559
3560     arg1_rtx = get_memory_rtx (arg1);
3561     arg2_rtx = get_memory_rtx (arg2);
3562     arg3_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
3563     insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3564                          GEN_INT (MIN (arg1_align, arg2_align)));
3565     if (insn)
3566       {
3567         emit_insn (insn);
3568
3569         /* Return the value in the proper mode for this function.  */
3570         mode = TYPE_MODE (TREE_TYPE (exp));
3571         if (GET_MODE (result) == mode)
3572           return result;
3573         if (target == 0)
3574           return convert_to_mode (mode, result, 0);
3575         convert_move (target, result, 0);
3576         return target;
3577       }
3578
3579     /* Expand the library call ourselves using a stabilized argument
3580        list to avoid re-evaluating the function's arguments twice.  */
3581     arglist = build_tree_list (NULL_TREE, len);
3582     arglist = tree_cons (NULL_TREE, arg2, arglist);
3583     arglist = tree_cons (NULL_TREE, arg1, arglist);
3584     fndecl = get_callee_fndecl (exp);
3585     exp = build_function_call_expr (fndecl, arglist);
3586     return expand_call (exp, target, target == const0_rtx);
3587   }
3588 #endif
3589   return 0;
3590 }
3591
3592 /* Expand expression EXP, which is a call to the strcat builtin.
3593    Return 0 if we failed the caller should emit a normal call,
3594    otherwise try to get the result in TARGET, if convenient.  */
3595
3596 static rtx
3597 expand_builtin_strcat (tree arglist, rtx target, enum machine_mode mode)
3598 {
3599   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3600     return 0;
3601   else
3602     {
3603       tree dst = TREE_VALUE (arglist),
3604         src = TREE_VALUE (TREE_CHAIN (arglist));
3605       const char *p = c_getstr (src);
3606
3607       if (p)
3608         {
3609           /* If the string length is zero, return the dst parameter.  */
3610           if (*p == '\0')
3611             return expand_expr (dst, target, mode, EXPAND_NORMAL);
3612           else if (!optimize_size)
3613             {
3614               /* Otherwise if !optimize_size, see if we can store by
3615                  pieces into (dst + strlen(dst)).  */
3616               tree newdst, arglist,
3617                 strlen_fn = implicit_built_in_decls[BUILT_IN_STRLEN];
3618               
3619               /* This is the length argument.  */
3620               arglist = build_tree_list (NULL_TREE,
3621                                          fold (size_binop (PLUS_EXPR,
3622                                                            c_strlen (src, 0),
3623                                                            ssize_int (1))));
3624               /* Prepend src argument.  */
3625               arglist = tree_cons (NULL_TREE, src, arglist);
3626               
3627               /* We're going to use dst more than once.  */
3628               dst = save_expr (dst);
3629
3630               /* Create strlen (dst).  */
3631               newdst =
3632                 fold (build_function_call_expr (strlen_fn,
3633                                                 build_tree_list (NULL_TREE,
3634                                                                  dst)));
3635               /* Create (dst + strlen (dst)).  */
3636               newdst = fold (build (PLUS_EXPR, TREE_TYPE (dst), dst, newdst));
3637
3638               /* Prepend the new dst argument.  */
3639               arglist = tree_cons (NULL_TREE, newdst, arglist);
3640               
3641               /* We don't want to get turned into a memcpy if the
3642                  target is const0_rtx, i.e. when the return value
3643                  isn't used.  That would produce pessimized code so
3644                  pass in a target of zero, it should never actually be
3645                  used.  If this was successful return the original
3646                  dst, not the result of mempcpy.  */
3647               if (expand_builtin_mempcpy (arglist, /*target=*/0, mode, /*endp=*/0))
3648                 return expand_expr (dst, target, mode, EXPAND_NORMAL);
3649               else
3650                 return 0;
3651             }
3652         }
3653
3654       return 0;
3655     }
3656 }
3657
3658 /* Expand expression EXP, which is a call to the strncat builtin.
3659    Return 0 if we failed the caller should emit a normal call,
3660    otherwise try to get the result in TARGET, if convenient.  */
3661
3662 static rtx
3663 expand_builtin_strncat (tree arglist, rtx target, enum machine_mode mode)
3664 {
3665   if (!validate_arglist (arglist,
3666                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3667     return 0;
3668   else
3669     {
3670       tree dst = TREE_VALUE (arglist),
3671         src = TREE_VALUE (TREE_CHAIN (arglist)),
3672         len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3673       const char *p = c_getstr (src);
3674
3675       /* If the requested length is zero, or the src parameter string
3676           length is zero, return the dst parameter.  */
3677       if (integer_zerop (len) || (p && *p == '\0'))
3678         {
3679           /* Evaluate and ignore the src and len parameters in case
3680              they have side-effects.  */
3681           expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
3682           expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
3683           return expand_expr (dst, target, mode, EXPAND_NORMAL);
3684         }
3685
3686       /* If the requested len is greater than or equal to the string
3687          length, call strcat.  */
3688       if (TREE_CODE (len) == INTEGER_CST && p
3689           && compare_tree_int (len, strlen (p)) >= 0)
3690         {
3691           tree newarglist
3692             = tree_cons (NULL_TREE, dst, build_tree_list (NULL_TREE, src));
3693           tree fn = implicit_built_in_decls[BUILT_IN_STRCAT];
3694
3695           /* If the replacement _DECL isn't initialized, don't do the
3696              transformation.  */
3697           if (!fn)
3698             return 0;
3699
3700           return expand_expr (build_function_call_expr (fn, newarglist),
3701                               target, mode, EXPAND_NORMAL);
3702         }
3703       return 0;
3704     }
3705 }
3706
3707 /* Expand expression EXP, which is a call to the strspn builtin.
3708    Return 0 if we failed the caller should emit a normal call,
3709    otherwise try to get the result in TARGET, if convenient.  */
3710
3711 static rtx
3712 expand_builtin_strspn (tree arglist, rtx target, enum machine_mode mode)
3713 {
3714   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3715     return 0;
3716   else
3717     {
3718       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
3719       const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
3720
3721       /* If both arguments are constants, evaluate at compile-time.  */
3722       if (p1 && p2)
3723         {
3724           const size_t r = strspn (p1, p2);
3725           return expand_expr (size_int (r), target, mode, EXPAND_NORMAL);
3726         }
3727
3728       /* If either argument is "", return 0.  */
3729       if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
3730         {
3731           /* Evaluate and ignore both arguments in case either one has
3732              side-effects.  */
3733           expand_expr (s1, const0_rtx, VOIDmode, EXPAND_NORMAL);
3734           expand_expr (s2, const0_rtx, VOIDmode, EXPAND_NORMAL);
3735           return const0_rtx;
3736         }
3737       return 0;
3738     }
3739 }
3740
3741 /* Expand expression EXP, which is a call to the strcspn builtin.
3742    Return 0 if we failed the caller should emit a normal call,
3743    otherwise try to get the result in TARGET, if convenient.  */
3744
3745 static rtx
3746 expand_builtin_strcspn (tree arglist, rtx target, enum machine_mode mode)
3747 {
3748   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3749     return 0;
3750   else
3751     {
3752       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
3753       const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
3754
3755       /* If both arguments are constants, evaluate at compile-time.  */
3756       if (p1 && p2)
3757         {
3758           const size_t r = strcspn (p1, p2);
3759           return expand_expr (size_int (r), target, mode, EXPAND_NORMAL);
3760         }
3761
3762       /* If the first argument is "", return 0.  */
3763       if (p1 && *p1 == '\0')
3764         {
3765           /* Evaluate and ignore argument s2 in case it has
3766              side-effects.  */
3767           expand_expr (s2, const0_rtx, VOIDmode, EXPAND_NORMAL);
3768           return const0_rtx;
3769         }
3770
3771       /* If the second argument is "", return __builtin_strlen(s1).  */
3772       if (p2 && *p2 == '\0')
3773         {
3774           tree newarglist = build_tree_list (NULL_TREE, s1),
3775             fn = implicit_built_in_decls[BUILT_IN_STRLEN];
3776
3777           /* If the replacement _DECL isn't initialized, don't do the
3778              transformation.  */
3779           if (!fn)
3780             return 0;
3781
3782           return expand_expr (build_function_call_expr (fn, newarglist),
3783                               target, mode, EXPAND_NORMAL);
3784         }
3785       return 0;
3786     }
3787 }
3788
3789 /* Expand a call to __builtin_saveregs, generating the result in TARGET,
3790    if that's convenient.  */
3791
3792 rtx
3793 expand_builtin_saveregs (void)
3794 {
3795   rtx val, seq;
3796
3797   /* Don't do __builtin_saveregs more than once in a function.
3798      Save the result of the first call and reuse it.  */
3799   if (saveregs_value != 0)
3800     return saveregs_value;
3801
3802   /* When this function is called, it means that registers must be
3803      saved on entry to this function.  So we migrate the call to the
3804      first insn of this function.  */
3805
3806   start_sequence ();
3807
3808   /* Do whatever the machine needs done in this case.  */
3809   val = targetm.calls.expand_builtin_saveregs ();
3810
3811   seq = get_insns ();
3812   end_sequence ();
3813
3814   saveregs_value = val;
3815
3816   /* Put the insns after the NOTE that starts the function.  If this
3817      is inside a start_sequence, make the outer-level insn chain current, so
3818      the code is placed at the start of the function.  */
3819   push_topmost_sequence ();
3820   emit_insn_after (seq, get_insns ());
3821   pop_topmost_sequence ();
3822
3823   return val;
3824 }
3825
3826 /* __builtin_args_info (N) returns word N of the arg space info
3827    for the current function.  The number and meanings of words
3828    is controlled by the definition of CUMULATIVE_ARGS.  */
3829
3830 static rtx
3831 expand_builtin_args_info (tree arglist)
3832 {
3833   int nwords = sizeof (CUMULATIVE_ARGS) / sizeof (int);
3834   int *word_ptr = (int *) &current_function_args_info;
3835
3836   if (sizeof (CUMULATIVE_ARGS) % sizeof (int) != 0)
3837     abort ();
3838
3839   if (arglist != 0)
3840     {
3841       if (!host_integerp (TREE_VALUE (arglist), 0))
3842         error ("argument of `__builtin_args_info' must be constant");
3843       else
3844         {
3845           HOST_WIDE_INT wordnum = tree_low_cst (TREE_VALUE (arglist), 0);
3846
3847           if (wordnum < 0 || wordnum >= nwords)
3848             error ("argument of `__builtin_args_info' out of range");
3849           else
3850             return GEN_INT (word_ptr[wordnum]);
3851         }
3852     }
3853   else
3854     error ("missing argument in `__builtin_args_info'");
3855
3856   return const0_rtx;
3857 }
3858
3859 /* Expand ARGLIST, from a call to __builtin_next_arg.  */
3860
3861 static rtx
3862 expand_builtin_next_arg (tree arglist)
3863 {
3864   tree fntype = TREE_TYPE (current_function_decl);
3865
3866   if (TYPE_ARG_TYPES (fntype) == 0
3867       || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
3868           == void_type_node))
3869     {
3870       error ("`va_start' used in function with fixed args");
3871       return const0_rtx;
3872     }
3873
3874   if (arglist)
3875     {
3876       tree last_parm = tree_last (DECL_ARGUMENTS (current_function_decl));
3877       tree arg = TREE_VALUE (arglist);
3878
3879       /* Strip off all nops for the sake of the comparison.  This
3880          is not quite the same as STRIP_NOPS.  It does more.
3881          We must also strip off INDIRECT_EXPR for C++ reference
3882          parameters.  */
3883       while (TREE_CODE (arg) == NOP_EXPR
3884              || TREE_CODE (arg) == CONVERT_EXPR
3885              || TREE_CODE (arg) == NON_LVALUE_EXPR
3886              || TREE_CODE (arg) == INDIRECT_REF)
3887         arg = TREE_OPERAND (arg, 0);
3888       if (arg != last_parm)
3889         warning ("second parameter of `va_start' not last named argument");
3890     }
3891   else
3892     /* Evidently an out of date version of <stdarg.h>; can't validate
3893        va_start's second argument, but can still work as intended.  */
3894     warning ("`__builtin_next_arg' called without an argument");
3895
3896   return expand_binop (Pmode, add_optab,
3897                        current_function_internal_arg_pointer,
3898                        current_function_arg_offset_rtx,
3899                        NULL_RTX, 0, OPTAB_LIB_WIDEN);
3900 }
3901
3902 /* Make it easier for the backends by protecting the valist argument
3903    from multiple evaluations.  */
3904
3905 static tree
3906 stabilize_va_list (tree valist, int needs_lvalue)
3907 {
3908   if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
3909     {
3910       if (TREE_SIDE_EFFECTS (valist))
3911         valist = save_expr (valist);
3912
3913       /* For this case, the backends will be expecting a pointer to
3914          TREE_TYPE (va_list_type_node), but it's possible we've
3915          actually been given an array (an actual va_list_type_node).
3916          So fix it.  */
3917       if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
3918         {
3919           tree p1 = build_pointer_type (TREE_TYPE (va_list_type_node));
3920           tree p2 = build_pointer_type (va_list_type_node);
3921
3922           valist = build1 (ADDR_EXPR, p2, valist);
3923           valist = fold (build1 (NOP_EXPR, p1, valist));
3924         }
3925     }
3926   else
3927     {
3928       tree pt;
3929
3930       if (! needs_lvalue)
3931         {
3932           if (! TREE_SIDE_EFFECTS (valist))
3933             return valist;
3934
3935           pt = build_pointer_type (va_list_type_node);
3936           valist = fold (build1 (ADDR_EXPR, pt, valist));
3937           TREE_SIDE_EFFECTS (valist) = 1;
3938         }
3939
3940       if (TREE_SIDE_EFFECTS (valist))
3941         valist = save_expr (valist);
3942       valist = fold (build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (valist)),
3943                              valist));
3944     }
3945
3946   return valist;
3947 }
3948
3949 /* The "standard" definition of va_list is void*.  */
3950
3951 tree
3952 std_build_builtin_va_list (void)
3953 {
3954   return ptr_type_node;
3955 }
3956
3957 /* The "standard" implementation of va_start: just assign `nextarg' to
3958    the variable.  */
3959
3960 void
3961 std_expand_builtin_va_start (tree valist, rtx nextarg)
3962 {
3963   tree t;
3964
3965   t = build (MODIFY_EXPR, TREE_TYPE (valist), valist,
3966              make_tree (ptr_type_node, nextarg));
3967   TREE_SIDE_EFFECTS (t) = 1;
3968
3969   expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
3970 }
3971
3972 /* Expand ARGLIST, from a call to __builtin_va_start.  */
3973
3974 static rtx
3975 expand_builtin_va_start (tree arglist)
3976 {
3977   rtx nextarg;
3978   tree chain, valist;
3979
3980   chain = TREE_CHAIN (arglist);
3981
3982   if (TREE_CHAIN (chain))
3983     error ("too many arguments to function `va_start'");
3984
3985   nextarg = expand_builtin_next_arg (chain);
3986   valist = stabilize_va_list (TREE_VALUE (arglist), 1);
3987
3988 #ifdef EXPAND_BUILTIN_VA_START
3989   EXPAND_BUILTIN_VA_START (valist, nextarg);
3990 #else
3991   std_expand_builtin_va_start (valist, nextarg);
3992 #endif
3993
3994   return const0_rtx;
3995 }
3996
3997 /* The "standard" implementation of va_arg: read the value from the
3998    current (padded) address and increment by the (padded) size.  */
3999
4000 rtx
4001 std_expand_builtin_va_arg (tree valist, tree type)
4002 {
4003   tree addr_tree, t, type_size = NULL;
4004   tree align, alignm1;
4005   tree rounded_size;
4006   rtx addr;
4007   HOST_WIDE_INT boundary;
4008
4009   /* Compute the rounded size of the type.  */
4010   align = size_int (PARM_BOUNDARY / BITS_PER_UNIT);
4011   alignm1 = size_int (PARM_BOUNDARY / BITS_PER_UNIT - 1);
4012   boundary = FUNCTION_ARG_BOUNDARY (TYPE_MODE (type), type);
4013
4014   /* va_list pointer is aligned to PARM_BOUNDARY.  If argument actually
4015      requires greater alignment, we must perform dynamic alignment.  */
4016
4017   if (boundary > PARM_BOUNDARY)
4018     {
4019       if (!PAD_VARARGS_DOWN)
4020         {
4021           t = build (MODIFY_EXPR, TREE_TYPE (valist), valist,
4022                      build (PLUS_EXPR, TREE_TYPE (valist), valist,
4023                             build_int_2 (boundary / BITS_PER_UNIT - 1, 0)));
4024           TREE_SIDE_EFFECTS (t) = 1;
4025           expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4026         }
4027       t = build (MODIFY_EXPR, TREE_TYPE (valist), valist,
4028                  build (BIT_AND_EXPR, TREE_TYPE (valist), valist,
4029                         build_int_2 (~(boundary / BITS_PER_UNIT - 1), -1)));
4030       TREE_SIDE_EFFECTS (t) = 1;
4031       expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4032     }
4033   if (type == error_mark_node
4034       || (type_size = TYPE_SIZE_UNIT (TYPE_MAIN_VARIANT (type))) == NULL
4035       || TREE_OVERFLOW (type_size))
4036     rounded_size = size_zero_node;
4037   else
4038     rounded_size = fold (build (MULT_EXPR, sizetype,
4039                                 fold (build (TRUNC_DIV_EXPR, sizetype,
4040                                              fold (build (PLUS_EXPR, sizetype,
4041                                                           type_size, alignm1)),
4042                                              align)),
4043                                 align));
4044
4045   /* Get AP.  */
4046   addr_tree = valist;
4047   if (PAD_VARARGS_DOWN && ! integer_zerop (rounded_size))
4048     {
4049       /* Small args are padded downward.  */
4050       addr_tree = fold (build (PLUS_EXPR, TREE_TYPE (addr_tree), addr_tree,
4051                                fold (build (COND_EXPR, sizetype,
4052                                             fold (build (GT_EXPR, sizetype,
4053                                                          rounded_size,
4054                                                          align)),
4055                                             size_zero_node,
4056                                             fold (build (MINUS_EXPR, sizetype,
4057                                                          rounded_size,
4058                                                          type_size))))));
4059     }
4060
4061   addr = expand_expr (addr_tree, NULL_RTX, Pmode, EXPAND_NORMAL);
4062   addr = copy_to_reg (addr);
4063
4064   /* Compute new value for AP.  */
4065   if (! integer_zerop (rounded_size))
4066     {
4067       t = build (MODIFY_EXPR, TREE_TYPE (valist), valist,
4068                  build (PLUS_EXPR, TREE_TYPE (valist), valist,
4069                         rounded_size));
4070       TREE_SIDE_EFFECTS (t) = 1;
4071       expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4072     }
4073
4074   return addr;
4075 }
4076
4077 /* Expand __builtin_va_arg, which is not really a builtin function, but
4078    a very special sort of operator.  */
4079
4080 rtx
4081 expand_builtin_va_arg (tree valist, tree type)
4082 {
4083   rtx addr, result;
4084   tree promoted_type, want_va_type, have_va_type;
4085
4086   /* Verify that valist is of the proper type.  */
4087
4088   want_va_type = va_list_type_node;
4089   have_va_type = TREE_TYPE (valist);
4090   if (TREE_CODE (want_va_type) == ARRAY_TYPE)
4091     {
4092       /* If va_list is an array type, the argument may have decayed
4093          to a pointer type, e.g. by being passed to another function.
4094          In that case, unwrap both types so that we can compare the
4095          underlying records.  */
4096       if (TREE_CODE (have_va_type) == ARRAY_TYPE
4097           || TREE_CODE (have_va_type) == POINTER_TYPE)
4098         {
4099           want_va_type = TREE_TYPE (want_va_type);
4100           have_va_type = TREE_TYPE (have_va_type);
4101         }
4102     }
4103   if (TYPE_MAIN_VARIANT (want_va_type) != TYPE_MAIN_VARIANT (have_va_type))
4104     {
4105       error ("first argument to `va_arg' not of type `va_list'");
4106       addr = const0_rtx;
4107     }
4108
4109   /* Generate a diagnostic for requesting data of a type that cannot
4110      be passed through `...' due to type promotion at the call site.  */
4111   else if ((promoted_type = (*lang_hooks.types.type_promotes_to) (type))
4112            != type)
4113     {
4114       const char *name = "<anonymous type>", *pname = 0;
4115       static bool gave_help;
4116
4117       if (TYPE_NAME (type))
4118         {
4119           if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE)
4120             name = IDENTIFIER_POINTER (TYPE_NAME (type));
4121           else if (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
4122                    && DECL_NAME (TYPE_NAME (type)))
4123             name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type)));
4124         }
4125       if (TYPE_NAME (promoted_type))
4126         {
4127           if (TREE_CODE (TYPE_NAME (promoted_type)) == IDENTIFIER_NODE)
4128             pname = IDENTIFIER_POINTER (TYPE_NAME (promoted_type));
4129           else if (TREE_CODE (TYPE_NAME (promoted_type)) == TYPE_DECL
4130                    && DECL_NAME (TYPE_NAME (promoted_type)))
4131             pname = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (promoted_type)));
4132         }
4133
4134       /* Unfortunately, this is merely undefined, rather than a constraint
4135          violation, so we cannot make this an error.  If this call is never
4136          executed, the program is still strictly conforming.  */
4137       warning ("`%s' is promoted to `%s' when passed through `...'",
4138                name, pname);
4139       if (! gave_help)
4140         {
4141           gave_help = true;
4142           warning ("(so you should pass `%s' not `%s' to `va_arg')",
4143                    pname, name);
4144         }
4145
4146       /* We can, however, treat "undefined" any way we please.
4147          Call abort to encourage the user to fix the program.  */
4148       expand_builtin_trap ();
4149
4150       /* This is dead code, but go ahead and finish so that the
4151          mode of the result comes out right.  */
4152       addr = const0_rtx;
4153     }
4154   else
4155     {
4156       /* Make it easier for the backends by protecting the valist argument
4157          from multiple evaluations.  */
4158       valist = stabilize_va_list (valist, 0);
4159
4160 #ifdef EXPAND_BUILTIN_VA_ARG
4161       addr = EXPAND_BUILTIN_VA_ARG (valist, type);
4162 #else
4163       addr = std_expand_builtin_va_arg (valist, type);
4164 #endif
4165     }
4166
4167   addr = convert_memory_address (Pmode, addr);
4168
4169   result = gen_rtx_MEM (TYPE_MODE (type), addr);
4170   set_mem_alias_set (result, get_varargs_alias_set ());
4171
4172   return result;
4173 }
4174
4175 /* Expand ARGLIST, from a call to __builtin_va_end.  */
4176
4177 static rtx
4178 expand_builtin_va_end (tree arglist)
4179 {
4180   tree valist = TREE_VALUE (arglist);
4181
4182   /* Evaluate for side effects, if needed.  I hate macros that don't
4183      do that.  */
4184   if (TREE_SIDE_EFFECTS (valist))
4185     expand_expr (valist, const0_rtx, VOIDmode, EXPAND_NORMAL);
4186
4187   return const0_rtx;
4188 }
4189
4190 /* Expand ARGLIST, from a call to __builtin_va_copy.  We do this as a
4191    builtin rather than just as an assignment in stdarg.h because of the
4192    nastiness of array-type va_list types.  */
4193
4194 static rtx
4195 expand_builtin_va_copy (tree arglist)
4196 {
4197   tree dst, src, t;
4198
4199   dst = TREE_VALUE (arglist);
4200   src = TREE_VALUE (TREE_CHAIN (arglist));
4201
4202   dst = stabilize_va_list (dst, 1);
4203   src = stabilize_va_list (src, 0);
4204
4205   if (TREE_CODE (va_list_type_node) != ARRAY_TYPE)
4206     {
4207       t = build (MODIFY_EXPR, va_list_type_node, dst, src);
4208       TREE_SIDE_EFFECTS (t) = 1;
4209       expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4210     }
4211   else
4212     {
4213       rtx dstb, srcb, size;
4214
4215       /* Evaluate to pointers.  */
4216       dstb = expand_expr (dst, NULL_RTX, Pmode, EXPAND_NORMAL);
4217       srcb = expand_expr (src, NULL_RTX, Pmode, EXPAND_NORMAL);
4218       size = expand_expr (TYPE_SIZE_UNIT (va_list_type_node), NULL_RTX,
4219                           VOIDmode, EXPAND_NORMAL);
4220
4221       dstb = convert_memory_address (Pmode, dstb);
4222       srcb = convert_memory_address (Pmode, srcb);
4223
4224       /* "Dereference" to BLKmode memories.  */
4225       dstb = gen_rtx_MEM (BLKmode, dstb);
4226       set_mem_alias_set (dstb, get_alias_set (TREE_TYPE (TREE_TYPE (dst))));
4227       set_mem_align (dstb, TYPE_ALIGN (va_list_type_node));
4228       srcb = gen_rtx_MEM (BLKmode, srcb);
4229       set_mem_alias_set (srcb, get_alias_set (TREE_TYPE (TREE_TYPE (src))));
4230       set_mem_align (srcb, TYPE_ALIGN (va_list_type_node));
4231
4232       /* Copy.  */
4233       emit_block_move (dstb, srcb, size, BLOCK_OP_NORMAL);
4234     }
4235
4236   return const0_rtx;
4237 }
4238
4239 /* Expand a call to one of the builtin functions __builtin_frame_address or
4240    __builtin_return_address.  */
4241
4242 static rtx
4243 expand_builtin_frame_address (tree fndecl, tree arglist)
4244 {
4245   /* The argument must be a nonnegative integer constant.
4246      It counts the number of frames to scan up the stack.
4247      The value is the return address saved in that frame.  */
4248   if (arglist == 0)
4249     /* Warning about missing arg was already issued.  */
4250     return const0_rtx;
4251   else if (! host_integerp (TREE_VALUE (arglist), 1))
4252     {
4253       if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4254         error ("invalid arg to `__builtin_frame_address'");
4255       else
4256         error ("invalid arg to `__builtin_return_address'");
4257       return const0_rtx;
4258     }
4259   else
4260     {
4261       rtx tem
4262         = expand_builtin_return_addr (DECL_FUNCTION_CODE (fndecl),
4263                                       tree_low_cst (TREE_VALUE (arglist), 1),
4264                                       hard_frame_pointer_rtx);
4265
4266       /* Some ports cannot access arbitrary stack frames.  */
4267       if (tem == NULL)
4268         {
4269           if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4270             warning ("unsupported arg to `__builtin_frame_address'");
4271           else
4272             warning ("unsupported arg to `__builtin_return_address'");
4273           return const0_rtx;
4274         }
4275
4276       /* For __builtin_frame_address, return what we've got.  */
4277       if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4278         return tem;
4279
4280       if (GET_CODE (tem) != REG
4281           && ! CONSTANT_P (tem))
4282         tem = copy_to_mode_reg (Pmode, tem);
4283       return tem;
4284     }
4285 }
4286
4287 /* Expand a call to the alloca builtin, with arguments ARGLIST.  Return 0 if
4288    we failed and the caller should emit a normal call, otherwise try to get
4289    the result in TARGET, if convenient.  */
4290
4291 static rtx
4292 expand_builtin_alloca (tree arglist, rtx target)
4293 {
4294   rtx op0;
4295   rtx result;
4296
4297   if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
4298     return 0;
4299
4300   /* Compute the argument.  */
4301   op0 = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
4302
4303   /* Allocate the desired space.  */
4304   result = allocate_dynamic_stack_space (op0, target, BITS_PER_UNIT);
4305   result = convert_memory_address (ptr_mode, result);
4306
4307   return result;
4308 }
4309
4310 /* Expand a call to a unary builtin.  The arguments are in ARGLIST.
4311    Return 0 if a normal call should be emitted rather than expanding the
4312    function in-line.  If convenient, the result should be placed in TARGET.
4313    SUBTARGET may be used as the target for computing one of EXP's operands.  */
4314
4315 static rtx
4316 expand_builtin_unop (enum machine_mode target_mode, tree arglist, rtx target,
4317                      rtx subtarget, optab op_optab)
4318 {
4319   rtx op0;
4320   if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
4321     return 0;
4322
4323   /* Compute the argument.  */
4324   op0 = expand_expr (TREE_VALUE (arglist), subtarget, VOIDmode, 0);
4325   /* Compute op, into TARGET if possible.
4326      Set TARGET to wherever the result comes back.  */
4327   target = expand_unop (TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist))),
4328                         op_optab, op0, target, 1);
4329   if (target == 0)
4330     abort ();
4331
4332   return convert_to_mode (target_mode, target, 0);
4333 }
4334
4335 /* If the string passed to fputs is a constant and is one character
4336    long, we attempt to transform this call into __builtin_fputc().  */
4337
4338 static rtx
4339 expand_builtin_fputs (tree arglist, rtx target, bool unlocked)
4340 {
4341   tree len, fn;
4342   tree fn_fputc = unlocked ? implicit_built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
4343     : implicit_built_in_decls[BUILT_IN_FPUTC];
4344   tree fn_fwrite = unlocked ? implicit_built_in_decls[BUILT_IN_FWRITE_UNLOCKED]
4345     : implicit_built_in_decls[BUILT_IN_FWRITE];
4346
4347   /* If the return value is used, or the replacement _DECL isn't
4348      initialized, don't do the transformation.  */
4349   if (target != const0_rtx || !fn_fputc || !fn_fwrite)
4350     return 0;
4351
4352   /* Verify the arguments in the original call.  */
4353   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4354     return 0;
4355
4356   /* Get the length of the string passed to fputs.  If the length
4357      can't be determined, punt.  */
4358   if (!(len = c_strlen (TREE_VALUE (arglist), 1))
4359       || TREE_CODE (len) != INTEGER_CST)
4360     return 0;
4361
4362   switch (compare_tree_int (len, 1))
4363     {
4364     case -1: /* length is 0, delete the call entirely .  */
4365       {
4366         /* Evaluate and ignore the argument in case it has
4367            side-effects.  */
4368         expand_expr (TREE_VALUE (TREE_CHAIN (arglist)), const0_rtx,
4369                      VOIDmode, EXPAND_NORMAL);
4370         return const0_rtx;
4371       }
4372     case 0: /* length is 1, call fputc.  */
4373       {
4374         const char *p = c_getstr (TREE_VALUE (arglist));
4375
4376         if (p != NULL)
4377           {
4378             /* New argument list transforming fputs(string, stream) to
4379                fputc(string[0], stream).  */
4380             arglist =
4381               build_tree_list (NULL_TREE, TREE_VALUE (TREE_CHAIN (arglist)));
4382             arglist =
4383               tree_cons (NULL_TREE, build_int_2 (p[0], 0), arglist);
4384             fn = fn_fputc;
4385             break;
4386           }
4387       }
4388       /* Fall through.  */
4389     case 1: /* length is greater than 1, call fwrite.  */
4390       {
4391         tree string_arg;
4392
4393         /* If optimizing for size keep fputs.  */
4394         if (optimize_size)
4395           return 0;
4396         string_arg = TREE_VALUE (arglist);
4397         /* New argument list transforming fputs(string, stream) to
4398            fwrite(string, 1, len, stream).  */
4399         arglist = build_tree_list (NULL_TREE, TREE_VALUE (TREE_CHAIN (arglist)));
4400         arglist = tree_cons (NULL_TREE, len, arglist);
4401         arglist = tree_cons (NULL_TREE, size_one_node, arglist);
4402         arglist = tree_cons (NULL_TREE, string_arg, arglist);
4403         fn = fn_fwrite;
4404         break;
4405       }
4406     default:
4407       abort ();
4408     }
4409
4410   return expand_expr (build_function_call_expr (fn, arglist),
4411                       const0_rtx, VOIDmode, EXPAND_NORMAL);
4412 }
4413
4414 /* Expand a call to __builtin_expect.  We return our argument and emit a
4415    NOTE_INSN_EXPECTED_VALUE note.  This is the expansion of __builtin_expect in
4416    a non-jump context.  */
4417
4418 static rtx
4419 expand_builtin_expect (tree arglist, rtx target)
4420 {
4421   tree exp, c;
4422   rtx note, rtx_c;
4423
4424   if (arglist == NULL_TREE
4425       || TREE_CHAIN (arglist) == NULL_TREE)
4426     return const0_rtx;
4427   exp = TREE_VALUE (arglist);
4428   c = TREE_VALUE (TREE_CHAIN (arglist));
4429
4430   if (TREE_CODE (c) != INTEGER_CST)
4431     {
4432       error ("second arg to `__builtin_expect' must be a constant");
4433       c = integer_zero_node;
4434     }
4435
4436   target = expand_expr (exp, target, VOIDmode, EXPAND_NORMAL);
4437
4438   /* Don't bother with expected value notes for integral constants.  */
4439   if (flag_guess_branch_prob && GET_CODE (target) != CONST_INT)
4440     {
4441       /* We do need to force this into a register so that we can be
4442          moderately sure to be able to correctly interpret the branch
4443          condition later.  */
4444       target = force_reg (GET_MODE (target), target);
4445
4446       rtx_c = expand_expr (c, NULL_RTX, GET_MODE (target), EXPAND_NORMAL);
4447
4448       note = emit_note (NOTE_INSN_EXPECTED_VALUE);
4449       NOTE_EXPECTED_VALUE (note) = gen_rtx_EQ (VOIDmode, target, rtx_c);
4450     }
4451
4452   return target;
4453 }
4454
4455 /* Like expand_builtin_expect, except do this in a jump context.  This is
4456    called from do_jump if the conditional is a __builtin_expect.  Return either
4457    a list of insns to emit the jump or NULL if we cannot optimize
4458    __builtin_expect.  We need to optimize this at jump time so that machines
4459    like the PowerPC don't turn the test into a SCC operation, and then jump
4460    based on the test being 0/1.  */
4461
4462 rtx
4463 expand_builtin_expect_jump (tree exp, rtx if_false_label, rtx if_true_label)
4464 {
4465   tree arglist = TREE_OPERAND (exp, 1);
4466   tree arg0 = TREE_VALUE (arglist);
4467   tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
4468   rtx ret = NULL_RTX;
4469
4470   /* Only handle __builtin_expect (test, 0) and
4471      __builtin_expect (test, 1).  */
4472   if (TREE_CODE (TREE_TYPE (arg1)) == INTEGER_TYPE
4473       && (integer_zerop (arg1) || integer_onep (arg1)))
4474     {
4475       rtx insn, drop_through_label, temp;
4476
4477       /* Expand the jump insns.  */
4478       start_sequence ();
4479       do_jump (arg0, if_false_label, if_true_label);
4480       ret = get_insns ();
4481
4482       drop_through_label = get_last_insn ();
4483       if (drop_through_label && GET_CODE (drop_through_label) == NOTE)
4484         drop_through_label = prev_nonnote_insn (drop_through_label);
4485       if (drop_through_label && GET_CODE (drop_through_label) != CODE_LABEL)
4486         drop_through_label = NULL_RTX;
4487       end_sequence ();
4488
4489       if (! if_true_label)
4490         if_true_label = drop_through_label;
4491       if (! if_false_label)
4492         if_false_label = drop_through_label;
4493
4494       /* Go through and add the expect's to each of the conditional jumps.  */
4495       insn = ret;
4496       while (insn != NULL_RTX)
4497         {
4498           rtx next = NEXT_INSN (insn);
4499
4500           if (GET_CODE (insn) == JUMP_INSN && any_condjump_p (insn))
4501             {
4502               rtx ifelse = SET_SRC (pc_set (insn));
4503               rtx then_dest = XEXP (ifelse, 1);
4504               rtx else_dest = XEXP (ifelse, 2);
4505               int taken = -1;
4506
4507               /* First check if we recognize any of the labels.  */
4508               if (GET_CODE (then_dest) == LABEL_REF
4509                   && XEXP (then_dest, 0) == if_true_label)
4510                 taken = 1;
4511               else if (GET_CODE (then_dest) == LABEL_REF
4512                        && XEXP (then_dest, 0) == if_false_label)
4513                 taken = 0;
4514               else if (GET_CODE (else_dest) == LABEL_REF
4515                        && XEXP (else_dest, 0) == if_false_label)
4516                 taken = 1;
4517               else if (GET_CODE (else_dest) == LABEL_REF
4518                        && XEXP (else_dest, 0) == if_true_label)
4519                 taken = 0;
4520               /* Otherwise check where we drop through.  */
4521               else if (else_dest == pc_rtx)
4522                 {
4523                   if (next && GET_CODE (next) == NOTE)
4524                     next = next_nonnote_insn (next);
4525
4526                   if (next && GET_CODE (next) == JUMP_INSN
4527                       && any_uncondjump_p (next))
4528                     temp = XEXP (SET_SRC (pc_set (next)), 0);
4529                   else
4530                     temp = next;
4531
4532                   /* TEMP is either a CODE_LABEL, NULL_RTX or something
4533                      else that can't possibly match either target label.  */
4534                   if (temp == if_false_label)
4535                     taken = 1;
4536                   else if (temp == if_true_label)
4537                     taken = 0;
4538                 }
4539               else if (then_dest == pc_rtx)
4540                 {
4541                   if (next && GET_CODE (next) == NOTE)
4542                     next = next_nonnote_insn (next);
4543
4544                   if (next && GET_CODE (next) == JUMP_INSN
4545                       && any_uncondjump_p (next))
4546                     temp = XEXP (SET_SRC (pc_set (next)), 0);
4547                   else
4548                     temp = next;
4549
4550                   if (temp == if_false_label)
4551                     taken = 0;
4552                   else if (temp == if_true_label)
4553                     taken = 1;
4554                 }
4555
4556               if (taken != -1)
4557                 {
4558                   /* If the test is expected to fail, reverse the
4559                      probabilities.  */
4560                   if (integer_zerop (arg1))
4561                     taken = 1 - taken;
4562                   predict_insn_def (insn, PRED_BUILTIN_EXPECT, taken);
4563                 }
4564             }
4565
4566           insn = next;
4567         }
4568     }
4569
4570   return ret;
4571 }
4572
4573 void
4574 expand_builtin_trap (void)
4575 {
4576 #ifdef HAVE_trap
4577   if (HAVE_trap)
4578     emit_insn (gen_trap ());
4579   else
4580 #endif
4581     emit_library_call (abort_libfunc, LCT_NORETURN, VOIDmode, 0);
4582   emit_barrier ();
4583 }
4584
4585 /* Expand a call to fabs, fabsf or fabsl with arguments ARGLIST.
4586    Return 0 if a normal call should be emitted rather than expanding
4587    the function inline.  If convenient, the result should be placed
4588    in TARGET.  SUBTARGET may be used as the target for computing
4589    the operand.  */
4590
4591 static rtx
4592 expand_builtin_fabs (tree arglist, rtx target, rtx subtarget)
4593 {
4594   enum machine_mode mode;
4595   tree arg;
4596   rtx op0;
4597
4598   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
4599     return 0;
4600
4601   arg = TREE_VALUE (arglist);
4602   mode = TYPE_MODE (TREE_TYPE (arg));
4603   op0 = expand_expr (arg, subtarget, VOIDmode, 0);
4604   return expand_abs (mode, op0, target, 0, safe_from_p (target, arg, 1));
4605 }
4606
4607 /* Expand a call to cabs, cabsf or cabsl with arguments ARGLIST.
4608    Return 0 if a normal call should be emitted rather than expanding
4609    the function inline.  If convenient, the result should be placed
4610    in target.  */
4611
4612 static rtx
4613 expand_builtin_cabs (tree arglist, rtx target)
4614 {
4615   enum machine_mode mode;
4616   tree arg;
4617   rtx op0;
4618
4619   if (arglist == 0 || TREE_CHAIN (arglist))
4620     return 0;
4621   arg = TREE_VALUE (arglist);
4622   if (TREE_CODE (TREE_TYPE (arg)) != COMPLEX_TYPE
4623       || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) != REAL_TYPE)
4624     return 0;
4625
4626   mode = TYPE_MODE (TREE_TYPE (arg));
4627   op0 = expand_expr (arg, NULL_RTX, VOIDmode, 0);
4628   return expand_complex_abs (mode, op0, target, 0);
4629 }
4630
4631 /* Create a new constant string literal and return a char* pointer to it.
4632    The STRING_CST value is the LEN characters at STR.  */
4633 static tree
4634 build_string_literal (int len, const char *str)
4635 {
4636   tree t, elem, index, type;
4637
4638   t = build_string (len, str);
4639   elem = build_type_variant (char_type_node, 1, 0);
4640   index = build_index_type (build_int_2 (len - 1, 0));
4641   type = build_array_type (elem, index);
4642   TREE_TYPE (t) = type;
4643   TREE_CONSTANT (t) = 1;
4644   TREE_READONLY (t) = 1;
4645   TREE_STATIC (t) = 1;
4646
4647   type = build_pointer_type (type);
4648   t = build1 (ADDR_EXPR, type, t);
4649
4650   type = build_pointer_type (elem);
4651   t = build1 (NOP_EXPR, type, t);
4652   return t;
4653 }
4654
4655 /* Expand a call to printf or printf_unlocked with argument list ARGLIST.
4656    Return 0 if a normal call should be emitted rather than transforming
4657    the function inline.  If convenient, the result should be placed in
4658    TARGET with mode MODE.  UNLOCKED indicates this is a printf_unlocked 
4659    call.  */
4660 static rtx
4661 expand_builtin_printf (tree arglist, rtx target, enum machine_mode mode,
4662                        bool unlocked)
4663 {
4664   tree fn_putchar = unlocked
4665                     ? implicit_built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED]
4666                     : implicit_built_in_decls[BUILT_IN_PUTCHAR];
4667   tree fn_puts = unlocked ? implicit_built_in_decls[BUILT_IN_PUTS_UNLOCKED]
4668                           : implicit_built_in_decls[BUILT_IN_PUTS];
4669   const char *fmt_str;
4670   tree fn, fmt, arg;
4671
4672   /* If the return value is used, don't do the transformation.  */
4673   if (target != const0_rtx)
4674     return 0;
4675
4676   /* Verify the required arguments in the original call.  */
4677   if (! arglist)
4678     return 0;
4679   fmt = TREE_VALUE (arglist);
4680   if (TREE_CODE (TREE_TYPE (fmt)) != POINTER_TYPE)
4681     return 0;
4682   arglist = TREE_CHAIN (arglist);
4683
4684   /* Check whether the format is a literal string constant.  */
4685   fmt_str = c_getstr (fmt);
4686   if (fmt_str == NULL)
4687     return 0;
4688
4689   /* If the format specifier was "%s\n", call __builtin_puts(arg).  */
4690   if (strcmp (fmt_str, "%s\n") == 0)
4691     {
4692       if (! arglist
4693           || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE
4694           || TREE_CHAIN (arglist))
4695         return 0;
4696       fn = fn_puts;
4697     }
4698   /* If the format specifier was "%c", call __builtin_putchar(arg).  */
4699   else if (strcmp (fmt_str, "%c") == 0)
4700     {
4701       if (! arglist
4702           || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
4703           || TREE_CHAIN (arglist))
4704         return 0;
4705       fn = fn_putchar;
4706     }
4707   else
4708     {
4709       /* We can't handle anything else with % args or %% ... yet.  */
4710       if (strchr (fmt_str, '%'))
4711         return 0;
4712
4713       if (arglist)
4714         return 0;
4715
4716       /* If the format specifier was "", printf does nothing.  */
4717       if (fmt_str[0] == '\0')
4718         return const0_rtx;
4719       /* If the format specifier has length of 1, call putchar.  */
4720       if (fmt_str[1] == '\0')
4721         {
4722           /* Given printf("c"), (where c is any one character,)
4723              convert "c"[0] to an int and pass that to the replacement
4724              function.  */
4725           arg = build_int_2 (fmt_str[0], 0);
4726           arglist = build_tree_list (NULL_TREE, arg);
4727           fn = fn_putchar;
4728         }
4729       else
4730         {
4731           /* If the format specifier was "string\n", call puts("string").  */
4732           size_t len = strlen (fmt_str);
4733           if (fmt_str[len - 1] == '\n')
4734             {
4735               /* Create a NUL-terminated string that's one char shorter
4736                  than the original, stripping off the trailing '\n'.  */
4737               char *newstr = (char *) alloca (len);
4738               memcpy (newstr, fmt_str, len - 1);
4739               newstr[len - 1] = 0;
4740
4741               arg = build_string_literal (len, newstr);
4742               arglist = build_tree_list (NULL_TREE, arg);
4743               fn = fn_puts;
4744             }
4745           else
4746             /* We'd like to arrange to call fputs(string,stdout) here,
4747                but we need stdout and don't have a way to get it yet.  */
4748             return 0;
4749         }
4750     }
4751
4752   if (!fn)
4753     return 0;
4754   return expand_expr (build_function_call_expr (fn, arglist),
4755                       target, mode, EXPAND_NORMAL);
4756 }
4757
4758 /* Expand a call to fprintf or fprintf_unlocked with argument list ARGLIST.
4759    Return 0 if a normal call should be emitted rather than transforming
4760    the function inline.  If convenient, the result should be placed in
4761    TARGET with mode MODE.  UNLOCKED indicates this is a fprintf_unlocked 
4762    call.  */
4763 static rtx
4764 expand_builtin_fprintf (tree arglist, rtx target, enum machine_mode mode,
4765                         bool unlocked)
4766 {
4767   tree fn_fputc = unlocked ? implicit_built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
4768                            : implicit_built_in_decls[BUILT_IN_FPUTC];
4769   tree fn_fputs = unlocked ? implicit_built_in_decls[BUILT_IN_FPUTS_UNLOCKED]
4770                            : implicit_built_in_decls[BUILT_IN_FPUTS];
4771   const char *fmt_str;
4772   tree fn, fmt, fp, arg;
4773
4774   /* If the return value is used, don't do the transformation.  */
4775   if (target != const0_rtx)
4776     return 0;
4777
4778   /* Verify the required arguments in the original call.  */
4779   if (! arglist)
4780     return 0;
4781   fp = TREE_VALUE (arglist);
4782   if (TREE_CODE (TREE_TYPE (fp)) != POINTER_TYPE)
4783     return 0;
4784   arglist = TREE_CHAIN (arglist);
4785   if (! arglist)
4786     return 0;
4787   fmt = TREE_VALUE (arglist);
4788   if (TREE_CODE (TREE_TYPE (fmt)) != POINTER_TYPE)
4789     return 0;
4790   arglist = TREE_CHAIN (arglist);
4791
4792   /* Check whether the format is a literal string constant.  */
4793   fmt_str = c_getstr (fmt);
4794   if (fmt_str == NULL)
4795     return 0;
4796
4797   /* If the format specifier was "%s", call __builtin_fputs(arg,fp).  */
4798   if (strcmp (fmt_str, "%s") == 0)
4799     {
4800       if (! arglist
4801           || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE
4802           || TREE_CHAIN (arglist))
4803         return 0;
4804       arg = TREE_VALUE (arglist);
4805       arglist = build_tree_list (NULL_TREE, fp);
4806       arglist = tree_cons (NULL_TREE, arg, arglist);
4807       fn = fn_fputs;
4808     }
4809   /* If the format specifier was "%c", call __builtin_fputc(arg,fp).  */
4810   else if (strcmp (fmt_str, "%c") == 0)
4811     {
4812       if (! arglist
4813           || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
4814           || TREE_CHAIN (arglist))
4815         return 0;
4816       arg = TREE_VALUE (arglist);
4817       arglist = build_tree_list (NULL_TREE, fp);
4818       arglist = tree_cons (NULL_TREE, arg, arglist);
4819       fn = fn_fputc;
4820     }
4821   else
4822     {
4823       /* We can't handle anything else with % args or %% ... yet.  */
4824       if (strchr (fmt_str, '%'))
4825         return 0;
4826
4827       if (arglist)
4828         return 0;
4829
4830       /* If the format specifier was "", fprintf does nothing.  */
4831       if (fmt_str[0] == '\0')
4832         {
4833           /* Evaluate and ignore FILE* argument for side-effects.  */
4834           expand_expr (fp, const0_rtx, VOIDmode, EXPAND_NORMAL);
4835           return const0_rtx;
4836         }
4837
4838       /* When "string" doesn't contain %, replace all cases of
4839          fprintf(stream,string) with fputs(string,stream).  The fputs
4840          builtin will take care of special cases like length == 1.  */
4841       arglist = build_tree_list (NULL_TREE, fp);
4842       arglist = tree_cons (NULL_TREE, fmt, arglist);
4843       fn = fn_fputs;
4844     }
4845
4846   if (!fn)
4847     return 0;
4848   return expand_expr (build_function_call_expr (fn, arglist),
4849                       target, mode, EXPAND_NORMAL);
4850 }
4851
4852 /* Expand a call to sprintf with argument list ARGLIST.  Return 0 if
4853    a normal call should be emitted rather than expanding the function
4854    inline.  If convenient, the result should be placed in TARGET with
4855    mode MODE.  */
4856
4857 static rtx
4858 expand_builtin_sprintf (tree arglist, rtx target, enum machine_mode mode)
4859 {
4860   tree orig_arglist, dest, fmt;
4861   const char *fmt_str;
4862
4863   orig_arglist = arglist;
4864
4865   /* Verify the required arguments in the original call.  */
4866   if (! arglist)
4867     return 0;
4868   dest = TREE_VALUE (arglist);
4869   if (TREE_CODE (TREE_TYPE (dest)) != POINTER_TYPE)
4870     return 0;
4871   arglist = TREE_CHAIN (arglist);
4872   if (! arglist)
4873     return 0;
4874   fmt = TREE_VALUE (arglist);
4875   if (TREE_CODE (TREE_TYPE (fmt)) != POINTER_TYPE)
4876     return 0;
4877   arglist = TREE_CHAIN (arglist);
4878
4879   /* Check whether the format is a literal string constant.  */
4880   fmt_str = c_getstr (fmt);
4881   if (fmt_str == NULL)
4882     return 0;
4883
4884   /* If the format doesn't contain % args or %%, use strcpy.  */
4885   if (strchr (fmt_str, '%') == 0)
4886     {
4887       tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
4888       tree exp;
4889
4890       if (arglist || ! fn)
4891         return 0;
4892       expand_expr (build_function_call_expr (fn, orig_arglist),
4893                    const0_rtx, VOIDmode, EXPAND_NORMAL);
4894       if (target == const0_rtx)
4895         return const0_rtx;
4896       exp = build_int_2 (strlen (fmt_str), 0);
4897       exp = fold (build1 (NOP_EXPR, integer_type_node, exp));
4898       return expand_expr (exp, target, mode, EXPAND_NORMAL);
4899     }
4900   /* If the format is "%s", use strcpy if the result isn't used.  */
4901   else if (strcmp (fmt_str, "%s") == 0)
4902     {
4903       tree fn, arg, len;
4904       fn = implicit_built_in_decls[BUILT_IN_STRCPY];
4905
4906       if (! fn)
4907         return 0;
4908
4909       if (! arglist || TREE_CHAIN (arglist))
4910         return 0;
4911       arg = TREE_VALUE (arglist);
4912       if (TREE_CODE (TREE_TYPE (arg)) != POINTER_TYPE)
4913         return 0;
4914
4915       if (target != const0_rtx)
4916         {
4917           len = c_strlen (arg, 1);
4918           if (! len || TREE_CODE (len) != INTEGER_CST)
4919             return 0;
4920         }
4921       else
4922         len = NULL_TREE;
4923
4924       arglist = build_tree_list (NULL_TREE, arg);
4925       arglist = tree_cons (NULL_TREE, dest, arglist);
4926       expand_expr (build_function_call_expr (fn, arglist),
4927                    const0_rtx, VOIDmode, EXPAND_NORMAL);
4928
4929       if (target == const0_rtx)
4930         return const0_rtx;
4931       return expand_expr (len, target, mode, EXPAND_NORMAL);
4932     }
4933
4934   return 0;
4935 }
4936
4937 /* Expand a call to the built-in signbit, signbitf or signbitl function.
4938    Return NULL_RTX if a normal call should be emitted rather than expanding
4939    the function in-line.  EXP is the expression that is a call to the builtin
4940    function; if convenient, the result should be placed in TARGET.  */
4941
4942 static rtx
4943 expand_builtin_signbit (tree exp, rtx target)
4944 {
4945   const struct real_format *fmt;
4946   enum machine_mode fmode, imode, rmode;
4947   HOST_WIDE_INT hi, lo;
4948   tree arg, arglist;
4949   int bitpos;
4950   rtx temp;
4951
4952   arglist = TREE_OPERAND (exp, 1);
4953   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
4954     return 0;
4955
4956   arg = TREE_VALUE (arglist);
4957   fmode = TYPE_MODE (TREE_TYPE (arg));
4958   rmode = TYPE_MODE (TREE_TYPE (exp));
4959   fmt = REAL_MODE_FORMAT (fmode);
4960
4961   /* For floating point formats without a sign bit, implement signbit
4962      as "ARG < 0.0".  */
4963   if (fmt->signbit < 0)
4964   {
4965     /* But we can't do this if the format supports signed zero.  */
4966     if (fmt->has_signed_zero && HONOR_SIGNED_ZEROS (fmode))
4967       return 0;
4968
4969     arg = fold (build (LT_EXPR, TREE_TYPE (exp), arg,
4970                 build_real (TREE_TYPE (arg), dconst0)));
4971     return expand_expr (arg, target, VOIDmode, EXPAND_NORMAL);
4972   }
4973
4974   imode = int_mode_for_mode (fmode);
4975   if (imode == BLKmode)
4976     return 0;
4977
4978   bitpos = fmt->signbit;
4979   /* Handle targets with different FP word orders.  */
4980   if (FLOAT_WORDS_BIG_ENDIAN != WORDS_BIG_ENDIAN)
4981     {
4982       int nwords = GET_MODE_BITSIZE (fmode) / BITS_PER_WORD;
4983       int word = nwords - (bitpos / BITS_PER_WORD) - 1;
4984       bitpos = word * BITS_PER_WORD + bitpos % BITS_PER_WORD;
4985     }
4986
4987   /* If the sign bit is not in the lowpart and the floating point format
4988      is wider than an integer, check that is twice the size of an integer
4989      so that we can use gen_highpart below.  */
4990   if (bitpos >= GET_MODE_BITSIZE (rmode)
4991       && GET_MODE_BITSIZE (imode) != 2 * GET_MODE_BITSIZE (rmode))
4992     return 0;
4993
4994   temp = expand_expr (arg, NULL_RTX, VOIDmode, 0);
4995   temp = gen_lowpart (imode, temp);
4996
4997   if (GET_MODE_BITSIZE (imode) > GET_MODE_BITSIZE (rmode))
4998     {
4999       if (BITS_BIG_ENDIAN)
5000         bitpos = GET_MODE_BITSIZE (imode) - 1 - bitpos;
5001       temp = copy_to_mode_reg (imode, temp);
5002       temp = extract_bit_field (temp, 1, bitpos, 1,
5003                                 NULL_RTX, rmode, rmode,
5004                                 GET_MODE_SIZE (imode));
5005     }
5006   else
5007     {
5008       if (GET_MODE_BITSIZE (imode) < GET_MODE_BITSIZE (rmode))
5009         temp = gen_lowpart (rmode, temp);
5010       if (bitpos < HOST_BITS_PER_WIDE_INT)
5011         {
5012           hi = 0;
5013           lo = (HOST_WIDE_INT) 1 << bitpos;
5014         }
5015       else
5016         {
5017           hi = (HOST_WIDE_INT) 1 << (bitpos - HOST_BITS_PER_WIDE_INT);
5018           lo = 0;
5019         }
5020
5021       temp = force_reg (rmode, temp);
5022       temp = expand_binop (rmode, and_optab, temp,
5023                            immed_double_const (lo, hi, rmode),
5024                            target, 1, OPTAB_LIB_WIDEN);
5025     }
5026   return temp;
5027 }
5028 \f
5029 /* Expand an expression EXP that calls a built-in function,
5030    with result going to TARGET if that's convenient
5031    (and in mode MODE if that's convenient).
5032    SUBTARGET may be used as the target for computing one of EXP's operands.
5033    IGNORE is nonzero if the value is to be ignored.  */
5034
5035 rtx
5036 expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
5037                 int ignore)
5038 {
5039   tree fndecl = get_callee_fndecl (exp);
5040   tree arglist = TREE_OPERAND (exp, 1);
5041   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
5042   enum machine_mode target_mode = TYPE_MODE (TREE_TYPE (exp));
5043
5044   /* Perform postincrements before expanding builtin functions.  */
5045   emit_queue ();
5046
5047   if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
5048     return (*targetm.expand_builtin) (exp, target, subtarget, mode, ignore);
5049
5050   /* When not optimizing, generate calls to library functions for a certain
5051      set of builtins.  */
5052   if (!optimize
5053       && !CALLED_AS_BUILT_IN (fndecl)
5054       && DECL_ASSEMBLER_NAME_SET_P (fndecl)
5055       && fcode != BUILT_IN_ALLOCA)
5056     return expand_call (exp, target, ignore);
5057
5058   /* The built-in function expanders test for target == const0_rtx
5059      to determine whether the function's result will be ignored.  */
5060   if (ignore)
5061     target = const0_rtx;
5062
5063   /* If the result of a pure or const built-in function is ignored, and
5064      none of its arguments are volatile, we can avoid expanding the
5065      built-in call and just evaluate the arguments for side-effects.  */
5066   if (target == const0_rtx
5067       && (DECL_IS_PURE (fndecl) || TREE_READONLY (fndecl)))
5068     {
5069       bool volatilep = false;
5070       tree arg;
5071
5072       for (arg = arglist; arg; arg = TREE_CHAIN (arg))
5073         if (TREE_THIS_VOLATILE (TREE_VALUE (arg)))
5074           {
5075             volatilep = true;
5076             break;
5077           }
5078
5079       if (! volatilep)
5080         {
5081           for (arg = arglist; arg; arg = TREE_CHAIN (arg))
5082             expand_expr (TREE_VALUE (arg), const0_rtx,
5083                          VOIDmode, EXPAND_NORMAL);
5084           return const0_rtx;
5085         }
5086     }
5087
5088   switch (fcode)
5089     {
5090     case BUILT_IN_ABS:
5091     case BUILT_IN_LABS:
5092     case BUILT_IN_LLABS:
5093     case BUILT_IN_IMAXABS:
5094       /* build_function_call changes these into ABS_EXPR.  */
5095       abort ();
5096
5097     case BUILT_IN_FABS:
5098     case BUILT_IN_FABSF:
5099     case BUILT_IN_FABSL:
5100       target = expand_builtin_fabs (arglist, target, subtarget);
5101       if (target)
5102         return target;
5103       break;
5104
5105     case BUILT_IN_CABS:
5106     case BUILT_IN_CABSF:
5107     case BUILT_IN_CABSL:
5108       if (flag_unsafe_math_optimizations)
5109         {
5110           target = expand_builtin_cabs (arglist, target);
5111           if (target)
5112             return target;
5113         }
5114       break;
5115
5116     case BUILT_IN_CONJ:
5117     case BUILT_IN_CONJF:
5118     case BUILT_IN_CONJL:
5119     case BUILT_IN_CREAL:
5120     case BUILT_IN_CREALF:
5121     case BUILT_IN_CREALL:
5122     case BUILT_IN_CIMAG:
5123     case BUILT_IN_CIMAGF:
5124     case BUILT_IN_CIMAGL:
5125       /* expand_tree_builtin changes these into CONJ_EXPR, REALPART_EXPR
5126          and IMAGPART_EXPR.  */
5127       abort ();
5128
5129     case BUILT_IN_SIN:
5130     case BUILT_IN_SINF:
5131     case BUILT_IN_SINL:
5132     case BUILT_IN_COS:
5133     case BUILT_IN_COSF:
5134     case BUILT_IN_COSL:
5135     case BUILT_IN_EXP:
5136     case BUILT_IN_EXPF:
5137     case BUILT_IN_EXPL:
5138     case BUILT_IN_LOG:
5139     case BUILT_IN_LOGF:
5140     case BUILT_IN_LOGL:
5141     case BUILT_IN_LOG10:
5142     case BUILT_IN_LOG10F:
5143     case BUILT_IN_LOG10L:
5144     case BUILT_IN_LOG2:
5145     case BUILT_IN_LOG2F:
5146     case BUILT_IN_LOG2L:
5147     case BUILT_IN_TAN:
5148     case BUILT_IN_TANF:
5149     case BUILT_IN_TANL:
5150     case BUILT_IN_ATAN:
5151     case BUILT_IN_ATANF:
5152     case BUILT_IN_ATANL:
5153       /* Treat these like sqrt only if unsafe math optimizations are allowed,
5154          because of possible accuracy problems.  */
5155       if (! flag_unsafe_math_optimizations)
5156         break;
5157     case BUILT_IN_SQRT:
5158     case BUILT_IN_SQRTF:
5159     case BUILT_IN_SQRTL:
5160     case BUILT_IN_FLOOR:
5161     case BUILT_IN_FLOORF:
5162     case BUILT_IN_FLOORL:
5163     case BUILT_IN_CEIL:
5164     case BUILT_IN_CEILF:
5165     case BUILT_IN_CEILL:
5166     case BUILT_IN_TRUNC:
5167     case BUILT_IN_TRUNCF:
5168     case BUILT_IN_TRUNCL:
5169     case BUILT_IN_ROUND:
5170     case BUILT_IN_ROUNDF:
5171     case BUILT_IN_ROUNDL:
5172     case BUILT_IN_NEARBYINT:
5173     case BUILT_IN_NEARBYINTF:
5174     case BUILT_IN_NEARBYINTL:
5175       target = expand_builtin_mathfn (exp, target, subtarget);
5176       if (target)
5177         return target;
5178       break;
5179
5180     case BUILT_IN_POW:
5181     case BUILT_IN_POWF:
5182     case BUILT_IN_POWL:
5183       target = expand_builtin_pow (exp, target, subtarget);
5184       if (target)
5185         return target;
5186       break;
5187
5188     case BUILT_IN_ATAN2:
5189     case BUILT_IN_ATAN2F:
5190     case BUILT_IN_ATAN2L:
5191       if (! flag_unsafe_math_optimizations)
5192         break;
5193       target = expand_builtin_mathfn_2 (exp, target, subtarget);
5194       if (target)
5195         return target;
5196       break;
5197
5198     case BUILT_IN_APPLY_ARGS:
5199       return expand_builtin_apply_args ();
5200
5201       /* __builtin_apply (FUNCTION, ARGUMENTS, ARGSIZE) invokes
5202          FUNCTION with a copy of the parameters described by
5203          ARGUMENTS, and ARGSIZE.  It returns a block of memory
5204          allocated on the stack into which is stored all the registers
5205          that might possibly be used for returning the result of a
5206          function.  ARGUMENTS is the value returned by
5207          __builtin_apply_args.  ARGSIZE is the number of bytes of
5208          arguments that must be copied.  ??? How should this value be
5209          computed?  We'll also need a safe worst case value for varargs
5210          functions.  */
5211     case BUILT_IN_APPLY:
5212       if (!validate_arglist (arglist, POINTER_TYPE,
5213                              POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)
5214           && !validate_arglist (arglist, REFERENCE_TYPE,
5215                                 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
5216         return const0_rtx;
5217       else
5218         {
5219           int i;
5220           tree t;
5221           rtx ops[3];
5222
5223           for (t = arglist, i = 0; t; t = TREE_CHAIN (t), i++)
5224             ops[i] = expand_expr (TREE_VALUE (t), NULL_RTX, VOIDmode, 0);
5225
5226           return expand_builtin_apply (ops[0], ops[1], ops[2]);
5227         }
5228
5229       /* __builtin_return (RESULT) causes the function to return the
5230          value described by RESULT.  RESULT is address of the block of
5231          memory returned by __builtin_apply.  */
5232     case BUILT_IN_RETURN:
5233       if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5234         expand_builtin_return (expand_expr (TREE_VALUE (arglist),
5235                                             NULL_RTX, VOIDmode, 0));
5236       return const0_rtx;
5237
5238     case BUILT_IN_SAVEREGS:
5239       return expand_builtin_saveregs ();
5240
5241     case BUILT_IN_ARGS_INFO:
5242       return expand_builtin_args_info (arglist);
5243
5244       /* Return the address of the first anonymous stack arg.  */
5245     case BUILT_IN_NEXT_ARG:
5246       return expand_builtin_next_arg (arglist);
5247
5248     case BUILT_IN_CLASSIFY_TYPE:
5249       return expand_builtin_classify_type (arglist);
5250
5251     case BUILT_IN_CONSTANT_P:
5252       return expand_builtin_constant_p (arglist, target_mode);
5253
5254     case BUILT_IN_FRAME_ADDRESS:
5255     case BUILT_IN_RETURN_ADDRESS:
5256       return expand_builtin_frame_address (fndecl, arglist);
5257
5258     /* Returns the address of the area where the structure is returned.
5259        0 otherwise.  */
5260     case BUILT_IN_AGGREGATE_INCOMING_ADDRESS:
5261       if (arglist != 0
5262           || ! AGGREGATE_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl)))
5263           || GET_CODE (DECL_RTL (DECL_RESULT (current_function_decl))) != MEM)
5264         return const0_rtx;
5265       else
5266         return XEXP (DECL_RTL (DECL_RESULT (current_function_decl)), 0);
5267
5268     case BUILT_IN_ALLOCA:
5269       target = expand_builtin_alloca (arglist, target);
5270       if (target)
5271         return target;
5272       break;
5273
5274     case BUILT_IN_FFS:
5275     case BUILT_IN_FFSL:
5276     case BUILT_IN_FFSLL:
5277       target = expand_builtin_unop (target_mode, arglist, target,
5278                                     subtarget, ffs_optab);
5279       if (target)
5280         return target;
5281       break;
5282
5283     case BUILT_IN_CLZ:
5284     case BUILT_IN_CLZL:
5285     case BUILT_IN_CLZLL:
5286       target = expand_builtin_unop (target_mode, arglist, target,
5287                                     subtarget, clz_optab);
5288       if (target)
5289         return target;
5290       break;
5291
5292     case BUILT_IN_CTZ:
5293     case BUILT_IN_CTZL:
5294     case BUILT_IN_CTZLL:
5295       target = expand_builtin_unop (target_mode, arglist, target,
5296                                     subtarget, ctz_optab);
5297       if (target)
5298         return target;
5299       break;
5300
5301     case BUILT_IN_POPCOUNT:
5302     case BUILT_IN_POPCOUNTL:
5303     case BUILT_IN_POPCOUNTLL:
5304       target = expand_builtin_unop (target_mode, arglist, target,
5305                                     subtarget, popcount_optab);
5306       if (target)
5307         return target;
5308       break;
5309
5310     case BUILT_IN_PARITY:
5311     case BUILT_IN_PARITYL:
5312     case BUILT_IN_PARITYLL:
5313       target = expand_builtin_unop (target_mode, arglist, target,
5314                                     subtarget, parity_optab);
5315       if (target)
5316         return target;
5317       break;
5318
5319     case BUILT_IN_STRLEN:
5320       target = expand_builtin_strlen (arglist, target, target_mode);
5321       if (target)
5322         return target;
5323       break;
5324
5325     case BUILT_IN_STRCPY:
5326       target = expand_builtin_strcpy (arglist, target, mode);
5327       if (target)
5328         return target;
5329       break;
5330
5331     case BUILT_IN_STRNCPY:
5332       target = expand_builtin_strncpy (arglist, target, mode);
5333       if (target)
5334         return target;
5335       break;
5336
5337     case BUILT_IN_STPCPY:
5338       target = expand_builtin_stpcpy (arglist, target, mode);
5339       if (target)
5340         return target;
5341       break;
5342
5343     case BUILT_IN_STRCAT:
5344       target = expand_builtin_strcat (arglist, target, mode);
5345       if (target)
5346         return target;
5347       break;
5348
5349     case BUILT_IN_STRNCAT:
5350       target = expand_builtin_strncat (arglist, target, mode);
5351       if (target)
5352         return target;
5353       break;
5354
5355     case BUILT_IN_STRSPN:
5356       target = expand_builtin_strspn (arglist, target, mode);
5357       if (target)
5358         return target;
5359       break;
5360
5361     case BUILT_IN_STRCSPN:
5362       target = expand_builtin_strcspn (arglist, target, mode);
5363       if (target)
5364         return target;
5365       break;
5366
5367     case BUILT_IN_STRSTR:
5368       target = expand_builtin_strstr (arglist, target, mode);
5369       if (target)
5370         return target;
5371       break;
5372
5373     case BUILT_IN_STRPBRK:
5374       target = expand_builtin_strpbrk (arglist, target, mode);
5375       if (target)
5376         return target;
5377       break;
5378
5379     case BUILT_IN_INDEX:
5380     case BUILT_IN_STRCHR:
5381       target = expand_builtin_strchr (arglist, target, mode);
5382       if (target)
5383         return target;
5384       break;
5385
5386     case BUILT_IN_RINDEX:
5387     case BUILT_IN_STRRCHR:
5388       target = expand_builtin_strrchr (arglist, target, mode);
5389       if (target)
5390         return target;
5391       break;
5392
5393     case BUILT_IN_MEMCPY:
5394       target = expand_builtin_memcpy (arglist, target, mode);
5395       if (target)
5396         return target;
5397       break;
5398
5399     case BUILT_IN_MEMPCPY:
5400       target = expand_builtin_mempcpy (arglist, target, mode, /*endp=*/ 1);
5401       if (target)
5402         return target;
5403       break;
5404
5405     case BUILT_IN_MEMMOVE:
5406       target = expand_builtin_memmove (arglist, target, mode);
5407       if (target)
5408         return target;
5409       break;
5410
5411     case BUILT_IN_BCOPY:
5412       target = expand_builtin_bcopy (arglist);
5413       if (target)
5414         return target;
5415       break;
5416
5417     case BUILT_IN_MEMSET:
5418       target = expand_builtin_memset (arglist, target, mode);
5419       if (target)
5420         return target;
5421       break;
5422
5423     case BUILT_IN_BZERO:
5424       target = expand_builtin_bzero (arglist);
5425       if (target)
5426         return target;
5427       break;
5428
5429     case BUILT_IN_STRCMP:
5430       target = expand_builtin_strcmp (exp, target, mode);
5431       if (target)
5432         return target;
5433       break;
5434
5435     case BUILT_IN_STRNCMP:
5436       target = expand_builtin_strncmp (exp, target, mode);
5437       if (target)
5438         return target;
5439       break;
5440
5441     case BUILT_IN_BCMP:
5442     case BUILT_IN_MEMCMP:
5443       target = expand_builtin_memcmp (exp, arglist, target, mode);
5444       if (target)
5445         return target;
5446       break;
5447
5448     case BUILT_IN_SETJMP:
5449       target = expand_builtin_setjmp (arglist, target);
5450       if (target)
5451         return target;
5452       break;
5453
5454       /* __builtin_longjmp is passed a pointer to an array of five words.
5455          It's similar to the C library longjmp function but works with
5456          __builtin_setjmp above.  */
5457     case BUILT_IN_LONGJMP:
5458       if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
5459         break;
5460       else
5461         {
5462           rtx buf_addr = expand_expr (TREE_VALUE (arglist), subtarget,
5463                                       VOIDmode, 0);
5464           rtx value = expand_expr (TREE_VALUE (TREE_CHAIN (arglist)),
5465                                    NULL_RTX, VOIDmode, 0);
5466
5467           if (value != const1_rtx)
5468             {
5469               error ("__builtin_longjmp second argument must be 1");
5470               return const0_rtx;
5471             }
5472
5473           expand_builtin_longjmp (buf_addr, value);
5474           return const0_rtx;
5475         }
5476
5477     case BUILT_IN_TRAP:
5478       expand_builtin_trap ();
5479       return const0_rtx;
5480
5481     case BUILT_IN_PRINTF:
5482       target = expand_builtin_printf (arglist, target, mode, false);
5483       if (target)
5484         return target;
5485       break;
5486
5487     case BUILT_IN_PRINTF_UNLOCKED:
5488       target = expand_builtin_printf (arglist, target, mode, true);
5489       if (target)
5490         return target;
5491       break;
5492
5493     case BUILT_IN_FPUTS:
5494       target = expand_builtin_fputs (arglist, target, false);
5495       if (target)
5496         return target;
5497       break;
5498
5499     case BUILT_IN_FPUTS_UNLOCKED:
5500       target = expand_builtin_fputs (arglist, target, true);
5501       if (target)
5502         return target;
5503       break;
5504
5505     case BUILT_IN_FPRINTF:
5506       target = expand_builtin_fprintf (arglist, target, mode, false);
5507       if (target)
5508         return target;
5509       break;
5510
5511     case BUILT_IN_FPRINTF_UNLOCKED:
5512       target = expand_builtin_fprintf (arglist, target, mode, true);
5513       if (target)
5514         return target;
5515       break;
5516
5517     case BUILT_IN_SPRINTF:
5518       target = expand_builtin_sprintf (arglist, target, mode);
5519       if (target)
5520         return target;
5521       break;
5522
5523     case BUILT_IN_SIGNBIT:
5524     case BUILT_IN_SIGNBITF:
5525     case BUILT_IN_SIGNBITL:
5526       target = expand_builtin_signbit (exp, target);
5527       if (target)
5528         return target;
5529       break;
5530
5531       /* Various hooks for the DWARF 2 __throw routine.  */
5532     case BUILT_IN_UNWIND_INIT:
5533       expand_builtin_unwind_init ();
5534       return const0_rtx;
5535     case BUILT_IN_DWARF_CFA:
5536       return virtual_cfa_rtx;
5537 #ifdef DWARF2_UNWIND_INFO
5538     case BUILT_IN_DWARF_SP_COLUMN:
5539       return expand_builtin_dwarf_sp_column ();
5540     case BUILT_IN_INIT_DWARF_REG_SIZES:
5541       expand_builtin_init_dwarf_reg_sizes (TREE_VALUE (arglist));
5542       return const0_rtx;
5543 #endif
5544     case BUILT_IN_FROB_RETURN_ADDR:
5545       return expand_builtin_frob_return_addr (TREE_VALUE (arglist));
5546     case BUILT_IN_EXTRACT_RETURN_ADDR:
5547       return expand_builtin_extract_return_addr (TREE_VALUE (arglist));
5548     case BUILT_IN_EH_RETURN:
5549       expand_builtin_eh_return (TREE_VALUE (arglist),
5550                                 TREE_VALUE (TREE_CHAIN (arglist)));
5551       return const0_rtx;
5552 #ifdef EH_RETURN_DATA_REGNO
5553     case BUILT_IN_EH_RETURN_DATA_REGNO:
5554       return expand_builtin_eh_return_data_regno (arglist);
5555 #endif
5556     case BUILT_IN_EXTEND_POINTER:
5557       return expand_builtin_extend_pointer (TREE_VALUE (arglist));
5558
5559     case BUILT_IN_VA_START:
5560     case BUILT_IN_STDARG_START:
5561       return expand_builtin_va_start (arglist);
5562     case BUILT_IN_VA_END:
5563       return expand_builtin_va_end (arglist);
5564     case BUILT_IN_VA_COPY:
5565       return expand_builtin_va_copy (arglist);
5566     case BUILT_IN_EXPECT:
5567       return expand_builtin_expect (arglist, target);
5568     case BUILT_IN_PREFETCH:
5569       expand_builtin_prefetch (arglist);
5570       return const0_rtx;
5571
5572
5573     default:    /* just do library call, if unknown builtin */
5574       if (!DECL_ASSEMBLER_NAME_SET_P (fndecl))
5575         error ("built-in function `%s' not currently supported",
5576                IDENTIFIER_POINTER (DECL_NAME (fndecl)));
5577     }
5578
5579   /* The switch statement above can drop through to cause the function
5580      to be called normally.  */
5581   return expand_call (exp, target, ignore);
5582 }
5583
5584 /* Determine whether a tree node represents a call to a built-in
5585    function.  If the tree T is a call to a built-in function with
5586    the right number of arguments of the appropriate types, return
5587    the DECL_FUNCTION_CODE of the call, e.g. BUILT_IN_SQRT.
5588    Otherwise the return value is END_BUILTINS.  */
5589
5590 enum built_in_function
5591 builtin_mathfn_code (tree t)
5592 {
5593   tree fndecl, arglist, parmlist;
5594   tree argtype, parmtype;
5595
5596   if (TREE_CODE (t) != CALL_EXPR
5597       || TREE_CODE (TREE_OPERAND (t, 0)) != ADDR_EXPR)
5598     return END_BUILTINS;
5599
5600   fndecl = get_callee_fndecl (t);
5601   if (fndecl == NULL_TREE
5602       || TREE_CODE (fndecl) != FUNCTION_DECL
5603       || ! DECL_BUILT_IN (fndecl)
5604       || DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
5605     return END_BUILTINS;
5606
5607   arglist = TREE_OPERAND (t, 1);
5608   parmlist = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
5609   for (; parmlist; parmlist = TREE_CHAIN (parmlist))
5610     {
5611       /* If a function doesn't take a variable number of arguments,
5612          the last element in the list will have type `void'.  */
5613       parmtype = TREE_VALUE (parmlist);
5614       if (VOID_TYPE_P (parmtype))
5615         {
5616           if (arglist)
5617             return END_BUILTINS;
5618           return DECL_FUNCTION_CODE (fndecl);
5619         }
5620
5621       if (! arglist)
5622         return END_BUILTINS;
5623
5624       argtype = TREE_TYPE (TREE_VALUE (arglist));
5625
5626       if (SCALAR_FLOAT_TYPE_P (parmtype))
5627         {
5628           if (! SCALAR_FLOAT_TYPE_P (argtype))
5629             return END_BUILTINS;
5630         }
5631       else if (COMPLEX_FLOAT_TYPE_P (parmtype))
5632         {
5633           if (! COMPLEX_FLOAT_TYPE_P (argtype))
5634             return END_BUILTINS;
5635         }
5636       else if (POINTER_TYPE_P (parmtype))
5637         {
5638           if (! POINTER_TYPE_P (argtype))
5639             return END_BUILTINS;
5640         }
5641       else if (INTEGRAL_TYPE_P (parmtype))
5642         {
5643           if (! INTEGRAL_TYPE_P (argtype))
5644             return END_BUILTINS;
5645         }
5646       else
5647         return END_BUILTINS;
5648
5649       arglist = TREE_CHAIN (arglist);
5650     }
5651
5652   /* Variable-length argument list.  */
5653   return DECL_FUNCTION_CODE (fndecl);
5654 }
5655
5656 /* Fold a call to __builtin_constant_p, if we know it will evaluate to a
5657    constant.  ARGLIST is the argument list of the call.  */
5658
5659 static tree
5660 fold_builtin_constant_p (tree arglist)
5661 {
5662   if (arglist == 0)
5663     return 0;
5664
5665   arglist = TREE_VALUE (arglist);
5666
5667   /* We return 1 for a numeric type that's known to be a constant
5668      value at compile-time or for an aggregate type that's a
5669      literal constant.  */
5670   STRIP_NOPS (arglist);
5671
5672   /* If we know this is a constant, emit the constant of one.  */
5673   if (TREE_CODE_CLASS (TREE_CODE (arglist)) == 'c'
5674       || (TREE_CODE (arglist) == CONSTRUCTOR
5675           && TREE_CONSTANT (arglist))
5676       || (TREE_CODE (arglist) == ADDR_EXPR
5677           && TREE_CODE (TREE_OPERAND (arglist, 0)) == STRING_CST))
5678     return integer_one_node;
5679
5680   /* If this expression has side effects, show we don't know it to be a
5681      constant.  Likewise if it's a pointer or aggregate type since in
5682      those case we only want literals, since those are only optimized
5683      when generating RTL, not later.
5684      And finally, if we are compiling an initializer, not code, we
5685      need to return a definite result now; there's not going to be any
5686      more optimization done.  */
5687   if (TREE_SIDE_EFFECTS (arglist)
5688       || AGGREGATE_TYPE_P (TREE_TYPE (arglist))
5689       || POINTER_TYPE_P (TREE_TYPE (arglist))
5690       || cfun == 0)
5691     return integer_zero_node;
5692
5693   return 0;
5694 }
5695
5696 /* Fold a call to __builtin_classify_type.  */
5697
5698 static tree
5699 fold_builtin_classify_type (tree arglist)
5700 {
5701   if (arglist == 0)
5702     return build_int_2 (no_type_class, 0);
5703
5704   return build_int_2 (type_to_class (TREE_TYPE (TREE_VALUE (arglist))), 0);
5705 }
5706
5707 /* Fold a call to __builtin_inf or __builtin_huge_val.  */
5708
5709 static tree
5710 fold_builtin_inf (tree type, int warn)
5711 {
5712   REAL_VALUE_TYPE real;
5713
5714   if (!MODE_HAS_INFINITIES (TYPE_MODE (type)) && warn)
5715     warning ("target format does not support infinity");
5716
5717   real_inf (&real);
5718   return build_real (type, real);
5719 }
5720
5721 /* Fold a call to __builtin_nan or __builtin_nans.  */
5722
5723 static tree
5724 fold_builtin_nan (tree arglist, tree type, int quiet)
5725 {
5726   REAL_VALUE_TYPE real;
5727   const char *str;
5728
5729   if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5730     return 0;
5731   str = c_getstr (TREE_VALUE (arglist));
5732   if (!str)
5733     return 0;
5734
5735   if (!real_nan (&real, str, quiet, TYPE_MODE (type)))
5736     return 0;
5737
5738   return build_real (type, real);
5739 }
5740
5741 /* Return true if the floating point expression T has an integer value.
5742    We also allow +Inf, -Inf and NaN to be considered integer values.  */
5743
5744 static bool
5745 integer_valued_real_p (tree t)
5746 {
5747   switch (TREE_CODE (t))
5748     {
5749     case FLOAT_EXPR:
5750       return true;
5751
5752     case ABS_EXPR:
5753     case SAVE_EXPR:
5754     case NON_LVALUE_EXPR:
5755       return integer_valued_real_p (TREE_OPERAND (t, 0));
5756
5757     case COMPOUND_EXPR:
5758     case MODIFY_EXPR:
5759     case BIND_EXPR:
5760       return integer_valued_real_p (TREE_OPERAND (t, 1));
5761
5762     case PLUS_EXPR:
5763     case MINUS_EXPR:
5764     case MULT_EXPR:
5765     case MIN_EXPR:
5766     case MAX_EXPR:
5767       return integer_valued_real_p (TREE_OPERAND (t, 0))
5768              && integer_valued_real_p (TREE_OPERAND (t, 1));
5769
5770     case COND_EXPR:
5771       return integer_valued_real_p (TREE_OPERAND (t, 1))
5772              && integer_valued_real_p (TREE_OPERAND (t, 2));
5773
5774     case REAL_CST:
5775       if (! TREE_CONSTANT_OVERFLOW (t))
5776       {
5777         REAL_VALUE_TYPE c, cint;
5778
5779         c = TREE_REAL_CST (t);
5780         real_trunc (&cint, TYPE_MODE (TREE_TYPE (t)), &c);
5781         return real_identical (&c, &cint);
5782       }
5783
5784     case NOP_EXPR:
5785       {
5786         tree type = TREE_TYPE (TREE_OPERAND (t, 0));
5787         if (TREE_CODE (type) == INTEGER_TYPE)
5788           return true;
5789         if (TREE_CODE (type) == REAL_TYPE)
5790           return integer_valued_real_p (TREE_OPERAND (t, 0));
5791         break;
5792       }
5793
5794     case CALL_EXPR:
5795       switch (builtin_mathfn_code (t))
5796         {
5797         case BUILT_IN_CEIL:
5798         case BUILT_IN_CEILF:
5799         case BUILT_IN_CEILL:
5800         case BUILT_IN_FLOOR:
5801         case BUILT_IN_FLOORF:
5802         case BUILT_IN_FLOORL:
5803         case BUILT_IN_NEARBYINT:
5804         case BUILT_IN_NEARBYINTF:
5805         case BUILT_IN_NEARBYINTL:
5806         case BUILT_IN_ROUND:
5807         case BUILT_IN_ROUNDF:
5808         case BUILT_IN_ROUNDL:
5809         case BUILT_IN_TRUNC:
5810         case BUILT_IN_TRUNCF:
5811         case BUILT_IN_TRUNCL:
5812           return true;
5813
5814         default:
5815           break;
5816         }
5817       break;
5818
5819     default:
5820       break;
5821     }
5822   return false;
5823 }
5824
5825 /* EXP is assumed to be builtin call where truncation can be propagated
5826    across (for instance floor((double)f) == (double)floorf (f).
5827    Do the transformation.  */
5828
5829 static tree
5830 fold_trunc_transparent_mathfn (tree exp)
5831 {
5832   tree fndecl = get_callee_fndecl (exp);
5833   tree arglist = TREE_OPERAND (exp, 1);
5834   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
5835   tree arg;
5836
5837   if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
5838     return 0;
5839
5840   arg = TREE_VALUE (arglist);
5841   /* Integer rounding functions are idempotent.  */
5842   if (fcode == builtin_mathfn_code (arg))
5843     return arg;
5844
5845   /* If argument is already integer valued, and we don't need to worry
5846      about setting errno, there's no need to perform rounding.  */
5847   if (! flag_errno_math && integer_valued_real_p (arg))
5848     return arg;
5849
5850   if (optimize)
5851     {
5852       tree arg0 = strip_float_extensions (arg);
5853       tree ftype = TREE_TYPE (exp);
5854       tree newtype = TREE_TYPE (arg0);
5855       tree decl;
5856
5857       if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
5858           && (decl = mathfn_built_in (newtype, fcode)))
5859         {
5860           arglist =
5861             build_tree_list (NULL_TREE, fold (convert (newtype, arg0)));
5862           return convert (ftype,
5863                           build_function_call_expr (decl, arglist));
5864         }
5865     }
5866   return 0;
5867 }
5868
5869 /* Fold function call to builtin cabs, cabsf or cabsl.  FNDECL is the
5870    function's DECL, ARGLIST is the argument list and TYPE is the return
5871    type.  Return NULL_TREE if no simplification can be made.  */
5872
5873 static tree
5874 fold_builtin_cabs (tree fndecl, tree arglist, tree type)
5875 {
5876   tree arg;
5877
5878   if (!arglist || TREE_CHAIN (arglist))
5879     return NULL_TREE;
5880
5881   arg = TREE_VALUE (arglist);
5882   if (TREE_CODE (TREE_TYPE (arg)) != COMPLEX_TYPE
5883       || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) != REAL_TYPE)
5884     return NULL_TREE;
5885
5886   /* Evaluate cabs of a constant at compile-time.  */
5887   if (flag_unsafe_math_optimizations
5888       && TREE_CODE (arg) == COMPLEX_CST
5889       && TREE_CODE (TREE_REALPART (arg)) == REAL_CST
5890       && TREE_CODE (TREE_IMAGPART (arg)) == REAL_CST
5891       && ! TREE_CONSTANT_OVERFLOW (TREE_REALPART (arg))
5892       && ! TREE_CONSTANT_OVERFLOW (TREE_IMAGPART (arg)))
5893     {
5894       REAL_VALUE_TYPE r, i;
5895
5896       r = TREE_REAL_CST (TREE_REALPART (arg));
5897       i = TREE_REAL_CST (TREE_IMAGPART (arg));
5898
5899       real_arithmetic (&r, MULT_EXPR, &r, &r);
5900       real_arithmetic (&i, MULT_EXPR, &i, &i);
5901       real_arithmetic (&r, PLUS_EXPR, &r, &i);
5902       if (real_sqrt (&r, TYPE_MODE (type), &r)
5903           || ! flag_trapping_math)
5904         return build_real (type, r);
5905     }
5906
5907   /* If either part is zero, cabs is fabs of the other.  */
5908   if (TREE_CODE (arg) == COMPLEX_EXPR
5909       && real_zerop (TREE_OPERAND (arg, 0)))
5910     return fold (build1 (ABS_EXPR, type, TREE_OPERAND (arg, 1)));
5911   if (TREE_CODE (arg) == COMPLEX_EXPR
5912       && real_zerop (TREE_OPERAND (arg, 1)))
5913     return fold (build1 (ABS_EXPR, type, TREE_OPERAND (arg, 0)));
5914
5915   if (flag_unsafe_math_optimizations)
5916     {
5917       enum built_in_function fcode;
5918       tree sqrtfn;
5919
5920       fcode = DECL_FUNCTION_CODE (fndecl);
5921       if (fcode == BUILT_IN_CABS)
5922         sqrtfn = implicit_built_in_decls[BUILT_IN_SQRT];
5923       else if (fcode == BUILT_IN_CABSF)
5924         sqrtfn = implicit_built_in_decls[BUILT_IN_SQRTF];
5925       else if (fcode == BUILT_IN_CABSL)
5926         sqrtfn = implicit_built_in_decls[BUILT_IN_SQRTL];
5927       else
5928         sqrtfn = NULL_TREE;
5929
5930       if (sqrtfn != NULL_TREE)
5931         {
5932           tree rpart, ipart, result, arglist;
5933
5934           arg = save_expr (arg);
5935
5936           rpart = fold (build1 (REALPART_EXPR, type, arg));
5937           ipart = fold (build1 (IMAGPART_EXPR, type, arg));
5938
5939           rpart = save_expr (rpart);
5940           ipart = save_expr (ipart);
5941
5942           result = fold (build (PLUS_EXPR, type,
5943                                 fold (build (MULT_EXPR, type,
5944                                              rpart, rpart)),
5945                                 fold (build (MULT_EXPR, type,
5946                                              ipart, ipart))));
5947
5948           arglist = build_tree_list (NULL_TREE, result);
5949           return build_function_call_expr (sqrtfn, arglist);
5950         }
5951     }
5952
5953   return NULL_TREE;
5954 }
5955
5956 /* Fold function call to builtin trunc, truncf or truncl.  Return
5957    NULL_TREE if no simplification can be made.  */
5958
5959 static tree
5960 fold_builtin_trunc (tree exp)
5961 {
5962   tree arglist = TREE_OPERAND (exp, 1);
5963   tree arg;
5964
5965   if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
5966     return 0;
5967
5968   /* Optimize trunc of constant value.  */
5969   arg = TREE_VALUE (arglist);
5970   if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
5971     {
5972       REAL_VALUE_TYPE r, x;
5973       tree type = TREE_TYPE (exp);
5974
5975       x = TREE_REAL_CST (arg);
5976       real_trunc (&r, TYPE_MODE (type), &x);
5977       return build_real (type, r);
5978     }
5979
5980   return fold_trunc_transparent_mathfn (exp);
5981 }
5982
5983 /* Fold function call to builtin floor, floorf or floorl.  Return
5984    NULL_TREE if no simplification can be made.  */
5985
5986 static tree
5987 fold_builtin_floor (tree exp)
5988 {
5989   tree arglist = TREE_OPERAND (exp, 1);
5990   tree arg;
5991
5992   if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
5993     return 0;
5994
5995   /* Optimize floor of constant value.  */
5996   arg = TREE_VALUE (arglist);
5997   if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
5998     {
5999       REAL_VALUE_TYPE x;
6000
6001       x = TREE_REAL_CST (arg);
6002       if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
6003         {
6004           tree type = TREE_TYPE (exp);
6005           REAL_VALUE_TYPE r;
6006
6007           real_floor (&r, TYPE_MODE (type), &x);
6008           return build_real (type, r);
6009         }
6010     }
6011
6012   return fold_trunc_transparent_mathfn (exp);
6013 }
6014
6015 /* Fold function call to builtin ceil, ceilf or ceill.  Return
6016    NULL_TREE if no simplification can be made.  */
6017
6018 static tree
6019 fold_builtin_ceil (tree exp)
6020 {
6021   tree arglist = TREE_OPERAND (exp, 1);
6022   tree arg;
6023
6024   if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6025     return 0;
6026
6027   /* Optimize ceil of constant value.  */
6028   arg = TREE_VALUE (arglist);
6029   if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
6030     {
6031       REAL_VALUE_TYPE x;
6032
6033       x = TREE_REAL_CST (arg);
6034       if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
6035         {
6036           tree type = TREE_TYPE (exp);
6037           REAL_VALUE_TYPE r;
6038
6039           real_ceil (&r, TYPE_MODE (type), &x);
6040           return build_real (type, r);
6041         }
6042     }
6043
6044   return fold_trunc_transparent_mathfn (exp);
6045 }
6046
6047 /* Fold function call to builtin round, roundf or roundl.  Return
6048    NULL_TREE if no simplification can be made.  */
6049
6050 static tree
6051 fold_builtin_round (tree exp)
6052 {
6053   tree arglist = TREE_OPERAND (exp, 1);
6054   tree arg;
6055
6056   if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6057     return 0;
6058
6059   /* Optimize ceil of constant value.  */
6060   arg = TREE_VALUE (arglist);
6061   if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
6062     {
6063       REAL_VALUE_TYPE x;
6064
6065       x = TREE_REAL_CST (arg);
6066       if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
6067         {
6068           tree type = TREE_TYPE (exp);
6069           REAL_VALUE_TYPE r;
6070
6071           real_round (&r, TYPE_MODE (type), &x);
6072           return build_real (type, r);
6073         }
6074     }
6075
6076   return fold_trunc_transparent_mathfn (exp);
6077 }
6078
6079 /* Fold function call to builtin ffs, clz, ctz, popcount and parity
6080    and their long and long long variants (i.e. ffsl and ffsll).
6081    Return NULL_TREE if no simplification can be made.  */
6082
6083 static tree
6084 fold_builtin_bitop (tree exp)
6085 {
6086   tree fndecl = get_callee_fndecl (exp);
6087   tree arglist = TREE_OPERAND (exp, 1);
6088   tree arg;
6089
6090   if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
6091     return NULL_TREE;
6092
6093   /* Optimize for constant argument.  */
6094   arg = TREE_VALUE (arglist);
6095   if (TREE_CODE (arg) == INTEGER_CST && ! TREE_CONSTANT_OVERFLOW (arg))
6096     {
6097       HOST_WIDE_INT hi, width, result;
6098       unsigned HOST_WIDE_INT lo;
6099       tree type, t;
6100
6101       type = TREE_TYPE (arg);
6102       width = TYPE_PRECISION (type);
6103       lo = TREE_INT_CST_LOW (arg);
6104
6105       /* Clear all the bits that are beyond the type's precision.  */
6106       if (width > HOST_BITS_PER_WIDE_INT)
6107         {
6108           hi = TREE_INT_CST_HIGH (arg);
6109           if (width < 2 * HOST_BITS_PER_WIDE_INT)
6110             hi &= ~((HOST_WIDE_INT) (-1) >> (width - HOST_BITS_PER_WIDE_INT));
6111         }
6112       else
6113         {
6114           hi = 0;
6115           if (width < HOST_BITS_PER_WIDE_INT)
6116             lo &= ~((unsigned HOST_WIDE_INT) (-1) << width);
6117         }
6118
6119       switch (DECL_FUNCTION_CODE (fndecl))
6120         {
6121         case BUILT_IN_FFS:
6122         case BUILT_IN_FFSL:
6123         case BUILT_IN_FFSLL:
6124           if (lo != 0)
6125             result = exact_log2 (lo & -lo) + 1;
6126           else if (hi != 0)
6127             result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi) + 1;
6128           else
6129             result = 0;
6130           break;
6131
6132         case BUILT_IN_CLZ:
6133         case BUILT_IN_CLZL:
6134         case BUILT_IN_CLZLL:
6135           if (hi != 0)
6136             result = width - floor_log2 (hi) - 1 - HOST_BITS_PER_WIDE_INT;
6137           else if (lo != 0)
6138             result = width - floor_log2 (lo) - 1;
6139           else if (! CLZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
6140             result = width;
6141           break;
6142
6143         case BUILT_IN_CTZ:
6144         case BUILT_IN_CTZL:
6145         case BUILT_IN_CTZLL:
6146           if (lo != 0)
6147             result = exact_log2 (lo & -lo);
6148           else if (hi != 0)
6149             result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi);
6150           else if (! CTZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
6151             result = width;
6152           break;
6153
6154         case BUILT_IN_POPCOUNT:
6155         case BUILT_IN_POPCOUNTL:
6156         case BUILT_IN_POPCOUNTLL:
6157           result = 0;
6158           while (lo)
6159             result++, lo &= lo - 1;
6160           while (hi)
6161             result++, hi &= hi - 1;
6162           break;
6163
6164         case BUILT_IN_PARITY:
6165         case BUILT_IN_PARITYL:
6166         case BUILT_IN_PARITYLL:
6167           result = 0;
6168           while (lo)
6169             result++, lo &= lo - 1;
6170           while (hi)
6171             result++, hi &= hi - 1;
6172           result &= 1;
6173           break;
6174
6175         default:
6176           abort();
6177         }
6178
6179       t = build_int_2 (result, 0);
6180       TREE_TYPE (t) = TREE_TYPE (exp);
6181       return t;
6182     }
6183
6184   return NULL_TREE;
6185 }
6186
6187 /* Return true if EXPR is the real constant contained in VALUE.  */
6188
6189 static bool
6190 real_dconstp (tree expr, const REAL_VALUE_TYPE *value)
6191 {
6192   STRIP_NOPS (expr);
6193
6194   return ((TREE_CODE (expr) == REAL_CST
6195            && ! TREE_CONSTANT_OVERFLOW (expr)
6196            && REAL_VALUES_EQUAL (TREE_REAL_CST (expr), *value))
6197           || (TREE_CODE (expr) == COMPLEX_CST
6198               && real_dconstp (TREE_REALPART (expr), value)
6199               && real_zerop (TREE_IMAGPART (expr))));
6200 }
6201
6202 /* A subroutine of fold_builtin to fold the various logarithmic
6203    functions.  EXP is the CALL_EXPR of a call to a builtin log*
6204    function.  VALUE is the base of the log* function.  */
6205
6206 static tree
6207 fold_builtin_logarithm (tree exp, const REAL_VALUE_TYPE *value)
6208 {
6209   tree arglist = TREE_OPERAND (exp, 1);
6210
6211   if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6212     {
6213       tree fndecl = get_callee_fndecl (exp);
6214       tree type = TREE_TYPE (TREE_TYPE (fndecl));
6215       tree arg = TREE_VALUE (arglist);
6216       const enum built_in_function fcode = builtin_mathfn_code (arg);
6217         
6218       /* Optimize log*(1.0) = 0.0.  */
6219       if (real_onep (arg))
6220         return build_real (type, dconst0);
6221
6222       /* Optimize logN(N) = 1.0.  If N can't be truncated to MODE
6223          exactly, then only do this if flag_unsafe_math_optimizations.  */
6224       if (exact_real_truncate (TYPE_MODE (type), value)
6225           || flag_unsafe_math_optimizations)
6226         {
6227           const REAL_VALUE_TYPE value_truncate =
6228             real_value_truncate (TYPE_MODE (type), *value);
6229           if (real_dconstp (arg, &value_truncate))
6230             return build_real (type, dconst1);
6231         }
6232       
6233       /* Special case, optimize logN(expN(x)) = x.  */
6234       if (flag_unsafe_math_optimizations
6235           && ((value == &dconste
6236                && (fcode == BUILT_IN_EXP
6237                    || fcode == BUILT_IN_EXPF
6238                    || fcode == BUILT_IN_EXPL))
6239               || (value == &dconst2
6240                   && (fcode == BUILT_IN_EXP2
6241                       || fcode == BUILT_IN_EXP2F
6242                       || fcode == BUILT_IN_EXP2L))
6243               || (value == &dconst10
6244                   && (fcode == BUILT_IN_EXP10
6245                       || fcode == BUILT_IN_EXP10F
6246                       || fcode == BUILT_IN_EXP10L))))
6247         return convert (type, TREE_VALUE (TREE_OPERAND (arg, 1)));
6248
6249       /* Optimize log*(func()) for various exponential functions.  We
6250          want to determine the value "x" and the power "exponent" in
6251          order to transform logN(x**exponent) into exponent*logN(x).  */
6252       if (flag_unsafe_math_optimizations)
6253         {
6254           tree exponent = 0, x = 0;
6255           
6256           switch (fcode)
6257           {
6258           case BUILT_IN_EXP:
6259           case BUILT_IN_EXPF:
6260           case BUILT_IN_EXPL:
6261             /* Prepare to do logN(exp(exponent) -> exponent*logN(e).  */
6262             x = build_real (type,
6263                             real_value_truncate (TYPE_MODE (type), dconste));
6264             exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
6265             break;
6266           case BUILT_IN_EXP2:
6267           case BUILT_IN_EXP2F:
6268           case BUILT_IN_EXP2L:
6269             /* Prepare to do logN(exp2(exponent) -> exponent*logN(2).  */
6270             x = build_real (type, dconst2);
6271             exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
6272             break;
6273           case BUILT_IN_EXP10:
6274           case BUILT_IN_EXP10F:
6275           case BUILT_IN_EXP10L:
6276           case BUILT_IN_POW10:
6277           case BUILT_IN_POW10F:
6278           case BUILT_IN_POW10L:
6279             /* Prepare to do logN(exp10(exponent) -> exponent*logN(10).  */
6280             x = build_real (type, dconst10);
6281             exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
6282             break;
6283           case BUILT_IN_SQRT:
6284           case BUILT_IN_SQRTF:
6285           case BUILT_IN_SQRTL:
6286             /* Prepare to do logN(sqrt(x) -> 0.5*logN(x).  */
6287             x = TREE_VALUE (TREE_OPERAND (arg, 1));
6288             exponent = build_real (type, dconsthalf);
6289             break;
6290           case BUILT_IN_CBRT:
6291           case BUILT_IN_CBRTF:
6292           case BUILT_IN_CBRTL:
6293             /* Prepare to do logN(cbrt(x) -> (1/3)*logN(x).  */
6294             x = TREE_VALUE (TREE_OPERAND (arg, 1));
6295             exponent = build_real (type, real_value_truncate (TYPE_MODE (type),
6296                                                               dconstthird));
6297             break;
6298           case BUILT_IN_POW:
6299           case BUILT_IN_POWF:
6300           case BUILT_IN_POWL:
6301             /* Prepare to do logN(pow(x,exponent) -> exponent*logN(x).  */
6302             x = TREE_VALUE (TREE_OPERAND (arg, 1));
6303             exponent = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
6304             break;
6305           default:
6306             break;
6307           }
6308
6309           /* Now perform the optimization.  */
6310           if (x && exponent)
6311             {
6312               tree logfn;
6313               arglist = build_tree_list (NULL_TREE, x);
6314               logfn = build_function_call_expr (fndecl, arglist);
6315               return fold (build (MULT_EXPR, type, exponent, logfn));
6316             }
6317         }
6318     }
6319
6320   return 0;
6321 }
6322           
6323 /* A subroutine of fold_builtin to fold the various exponent
6324    functions.  EXP is the CALL_EXPR of a call to a builtin function.
6325    VALUE is the value which will be raised to a power.  */
6326
6327 static tree
6328 fold_builtin_exponent (tree exp, const REAL_VALUE_TYPE *value)
6329 {
6330   tree arglist = TREE_OPERAND (exp, 1);
6331
6332   if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6333     {
6334       tree fndecl = get_callee_fndecl (exp);
6335       tree type = TREE_TYPE (TREE_TYPE (fndecl));
6336       tree arg = TREE_VALUE (arglist);
6337
6338       /* Optimize exp*(0.0) = 1.0.  */
6339       if (real_zerop (arg))
6340         return build_real (type, dconst1);
6341
6342       /* Optimize expN(1.0) = N.  */
6343       if (real_onep (arg))
6344         {
6345           REAL_VALUE_TYPE cst;
6346
6347           real_convert (&cst, TYPE_MODE (type), value);
6348           return build_real (type, cst);
6349         }
6350
6351       /* Attempt to evaluate expN(integer) at compile-time.  */
6352       if (flag_unsafe_math_optimizations
6353           && TREE_CODE (arg) == REAL_CST
6354           && ! TREE_CONSTANT_OVERFLOW (arg))
6355         {
6356           REAL_VALUE_TYPE cint;
6357           REAL_VALUE_TYPE c;
6358           HOST_WIDE_INT n;
6359
6360           c = TREE_REAL_CST (arg);
6361           n = real_to_integer (&c);
6362           real_from_integer (&cint, VOIDmode, n,
6363                              n < 0 ? -1 : 0, 0);
6364           if (real_identical (&c, &cint))
6365             {
6366               REAL_VALUE_TYPE x;
6367
6368               real_powi (&x, TYPE_MODE (type), value, n);
6369               return build_real (type, x);
6370             }
6371         }
6372
6373       /* Optimize expN(logN(x)) = x.  */
6374       if (flag_unsafe_math_optimizations)
6375         {
6376           const enum built_in_function fcode = builtin_mathfn_code (arg);
6377
6378           if ((value == &dconste
6379                && (fcode == BUILT_IN_LOG
6380                    || fcode == BUILT_IN_LOGF
6381                    || fcode == BUILT_IN_LOGL))
6382               || (value == &dconst2
6383                   && (fcode == BUILT_IN_LOG2
6384                       || fcode == BUILT_IN_LOG2F
6385                       || fcode == BUILT_IN_LOG2L))
6386               || (value == &dconst10
6387                   && (fcode == BUILT_IN_LOG10
6388                       || fcode == BUILT_IN_LOG10F
6389                       || fcode == BUILT_IN_LOG10L)))
6390             return convert (type, TREE_VALUE (TREE_OPERAND (arg, 1)));
6391         }
6392     }
6393
6394   return 0;
6395 }
6396
6397 /* Fold function call to builtin memcpy.  Return
6398    NULL_TREE if no simplification can be made.  */
6399
6400 static tree
6401 fold_builtin_memcpy (tree exp)
6402 {
6403   tree arglist = TREE_OPERAND (exp, 1);
6404   tree dest, src, len;
6405
6406   if (!validate_arglist (arglist,
6407                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
6408     return 0;
6409
6410   dest = TREE_VALUE (arglist);
6411   src = TREE_VALUE (TREE_CHAIN (arglist));
6412   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
6413
6414   /* If the LEN parameter is zero, return DEST.  */
6415   if (integer_zerop (len))
6416     return omit_one_operand (TREE_TYPE (exp), dest, src);
6417
6418   /* If SRC and DEST are the same (and not volatile), return DEST.  */
6419   if (operand_equal_p (src, dest, 0))
6420     return omit_one_operand (TREE_TYPE (exp), dest, len);
6421
6422   return 0;
6423 }
6424
6425 /* Fold function call to builtin mempcpy.  Return
6426    NULL_TREE if no simplification can be made.  */
6427
6428 static tree
6429 fold_builtin_mempcpy (tree exp)
6430 {
6431   tree arglist = TREE_OPERAND (exp, 1);
6432   tree dest, src, len;
6433
6434   if (!validate_arglist (arglist,
6435                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
6436     return 0;
6437
6438   dest = TREE_VALUE (arglist);
6439   src = TREE_VALUE (TREE_CHAIN (arglist));
6440   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
6441
6442   /* If the LEN parameter is zero, return DEST.  */
6443   if (integer_zerop (len))
6444     return omit_one_operand (TREE_TYPE (exp), dest, src);
6445
6446   /* If SRC and DEST are the same (and not volatile), return DEST+LEN.  */
6447   if (operand_equal_p (src, dest, 0))
6448     {
6449       tree temp = convert (TREE_TYPE (dest), len);
6450       temp = fold (build (PLUS_EXPR, TREE_TYPE (dest), dest, len));
6451       return convert (TREE_TYPE (exp), temp);
6452     }
6453
6454   return 0;
6455 }
6456
6457 /* Fold function call to builtin memmove.  Return
6458    NULL_TREE if no simplification can be made.  */
6459
6460 static tree
6461 fold_builtin_memmove (tree exp)
6462 {
6463   tree arglist = TREE_OPERAND (exp, 1);
6464   tree dest, src, len;
6465
6466   if (!validate_arglist (arglist,
6467                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
6468     return 0;
6469
6470   dest = TREE_VALUE (arglist);
6471   src = TREE_VALUE (TREE_CHAIN (arglist));
6472   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
6473
6474   /* If the LEN parameter is zero, return DEST.  */
6475   if (integer_zerop (len))
6476     return omit_one_operand (TREE_TYPE (exp), dest, src);
6477
6478   /* If SRC and DEST are the same (and not volatile), return DEST.  */
6479   if (operand_equal_p (src, dest, 0))
6480     return omit_one_operand (TREE_TYPE (exp), dest, len);
6481
6482   return 0;
6483 }
6484
6485 /* Fold function call to builtin strcpy.  Return
6486    NULL_TREE if no simplification can be made.  */
6487
6488 static tree
6489 fold_builtin_strcpy (tree exp)
6490 {
6491   tree arglist = TREE_OPERAND (exp, 1);
6492   tree dest, src;
6493
6494   if (!validate_arglist (arglist,
6495                          POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
6496     return 0;
6497
6498   dest = TREE_VALUE (arglist);
6499   src = TREE_VALUE (TREE_CHAIN (arglist));
6500
6501   /* If SRC and DEST are the same (and not volatile), return DEST.  */
6502   if (operand_equal_p (src, dest, 0))
6503     return convert (TREE_TYPE (exp), dest);
6504
6505   return 0;
6506 }
6507
6508 /* Fold function call to builtin strncpy.  Return
6509    NULL_TREE if no simplification can be made.  */
6510
6511 static tree
6512 fold_builtin_strncpy (tree exp)
6513 {
6514   tree arglist = TREE_OPERAND (exp, 1);
6515   tree dest, src, len;
6516
6517   if (!validate_arglist (arglist,
6518                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
6519     return 0;
6520
6521   dest = TREE_VALUE (arglist);
6522   src = TREE_VALUE (TREE_CHAIN (arglist));
6523   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
6524
6525   /* If the LEN parameter is zero, return DEST.  */
6526   if (integer_zerop (len))
6527     return omit_one_operand (TREE_TYPE (exp), dest, src);
6528
6529   return 0;
6530 }
6531
6532 /* Fold function call to builtin memcmp.  Return
6533    NULL_TREE if no simplification can be made.  */
6534
6535 static tree
6536 fold_builtin_memcmp (tree exp)
6537 {
6538   tree arglist = TREE_OPERAND (exp, 1);
6539   tree arg1, arg2, len;
6540
6541   if (!validate_arglist (arglist,
6542                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
6543     return 0;
6544
6545   arg1 = TREE_VALUE (arglist);
6546   arg2 = TREE_VALUE (TREE_CHAIN (arglist));
6547   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
6548
6549   /* If the LEN parameter is zero, return zero.  */
6550   if (integer_zerop (len))
6551     {
6552       tree temp = omit_one_operand (TREE_TYPE (exp), integer_zero_node, arg2);
6553       return omit_one_operand (TREE_TYPE (exp), temp, arg1);
6554     }
6555
6556   /* If ARG1 and ARG2 are the same (and not volatile), return zero.  */
6557   if (operand_equal_p (arg1, arg2, 0))
6558     return omit_one_operand (TREE_TYPE (exp), integer_zero_node, len);
6559
6560   return 0;
6561 }
6562
6563 /* Fold function call to builtin strcmp.  Return
6564    NULL_TREE if no simplification can be made.  */
6565
6566 static tree
6567 fold_builtin_strcmp (tree exp)
6568 {
6569   tree arglist = TREE_OPERAND (exp, 1);
6570   tree arg1, arg2;
6571   const char *p1, *p2;
6572
6573   if (!validate_arglist (arglist,
6574                          POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
6575     return 0;
6576
6577   arg1 = TREE_VALUE (arglist);
6578   arg2 = TREE_VALUE (TREE_CHAIN (arglist));
6579
6580   /* If ARG1 and ARG2 are the same (and not volatile), return zero.  */
6581   if (operand_equal_p (arg1, arg2, 0))
6582     return convert (TREE_TYPE (exp), integer_zero_node);
6583
6584   p1 = c_getstr (arg1);
6585   p2 = c_getstr (arg2);
6586
6587   if (p1 && p2)
6588     {
6589       tree temp;
6590       const int i = strcmp (p1, p2);
6591       if (i < 0)
6592         temp = integer_minus_one_node;
6593       else if (i > 0)
6594         temp = integer_one_node;
6595       else
6596         temp = integer_zero_node;
6597       return convert (TREE_TYPE (exp), temp);
6598     }
6599
6600   return 0;
6601 }
6602
6603 /* Fold function call to builtin strncmp.  Return
6604    NULL_TREE if no simplification can be made.  */
6605
6606 static tree
6607 fold_builtin_strncmp (tree exp)
6608 {
6609   tree arglist = TREE_OPERAND (exp, 1);
6610   tree arg1, arg2, len;
6611   const char *p1, *p2;
6612
6613   if (!validate_arglist (arglist,
6614                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
6615     return 0;
6616
6617   arg1 = TREE_VALUE (arglist);
6618   arg2 = TREE_VALUE (TREE_CHAIN (arglist));
6619   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
6620
6621   /* If the LEN parameter is zero, return zero.  */
6622   if (integer_zerop (len))
6623     {
6624       tree temp = omit_one_operand (TREE_TYPE (exp), integer_zero_node, arg2);
6625       return omit_one_operand (TREE_TYPE (exp), temp, arg1);
6626     }
6627
6628   /* If ARG1 and ARG2 are the same (and not volatile), return zero.  */
6629   if (operand_equal_p (arg1, arg2, 0))
6630     return omit_one_operand (TREE_TYPE (exp), integer_zero_node, len);
6631
6632   p1 = c_getstr (arg1);
6633   p2 = c_getstr (arg2);
6634
6635   if (host_integerp (len, 1) && p1 && p2)
6636     {
6637       tree temp;
6638       const int i = strncmp (p1, p2, tree_low_cst (len, 1));
6639       if (i < 0)
6640         temp = integer_minus_one_node;
6641       else if (i > 0)
6642         temp = integer_one_node;
6643       else
6644         temp = integer_zero_node;
6645       return convert (TREE_TYPE (exp), temp);
6646     }
6647
6648   return 0;
6649 }
6650
6651 /* Fold function call to builtin signbit, signbitf or signbitl.  Return
6652    NULL_TREE if no simplification can be made.  */
6653
6654 static tree
6655 fold_builtin_signbit (tree exp)
6656 {
6657   tree arglist = TREE_OPERAND (exp, 1);
6658   tree arg, temp;
6659
6660   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6661     return NULL_TREE;
6662
6663   arg = TREE_VALUE (arglist);
6664
6665   /* If ARG is a compile-time constant, determine the result.  */
6666   if (TREE_CODE (arg) == REAL_CST
6667       && !TREE_CONSTANT_OVERFLOW (arg))
6668     {
6669       REAL_VALUE_TYPE c;
6670
6671       c = TREE_REAL_CST (arg);
6672       temp = REAL_VALUE_NEGATIVE (c) ? integer_one_node : integer_zero_node;
6673       return convert (TREE_TYPE (exp), temp);
6674     }
6675
6676   /* If ARG is non-negative, the result is always zero.  */
6677   if (tree_expr_nonnegative_p (arg))
6678     return omit_one_operand (TREE_TYPE (exp), integer_zero_node, arg);
6679
6680   /* If ARG's format doesn't have signed zeros, return "arg < 0.0".  */
6681   if (!HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg))))
6682     return fold (build (LT_EXPR, TREE_TYPE (exp), arg,
6683                         build_real (TREE_TYPE (arg), dconst0)));
6684
6685   return NULL_TREE;
6686 }
6687
6688
6689 /* Used by constant folding to eliminate some builtin calls early.  EXP is
6690    the CALL_EXPR of a call to a builtin function.  */
6691
6692 tree
6693 fold_builtin (tree exp)
6694 {
6695   tree fndecl = get_callee_fndecl (exp);
6696   tree arglist = TREE_OPERAND (exp, 1);
6697   tree type = TREE_TYPE (TREE_TYPE (fndecl));
6698
6699   if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
6700     return 0;
6701
6702   switch (DECL_FUNCTION_CODE (fndecl))
6703     {
6704     case BUILT_IN_CONSTANT_P:
6705       return fold_builtin_constant_p (arglist);
6706
6707     case BUILT_IN_CLASSIFY_TYPE:
6708       return fold_builtin_classify_type (arglist);
6709
6710     case BUILT_IN_STRLEN:
6711       if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6712         {
6713           tree len = c_strlen (TREE_VALUE (arglist), 0);
6714           if (len)
6715             {
6716               /* Convert from the internal "sizetype" type to "size_t".  */
6717               if (size_type_node)
6718                 len = convert (size_type_node, len);
6719               return len;
6720             }
6721         }
6722       break;
6723
6724     case BUILT_IN_FABS:
6725     case BUILT_IN_FABSF:
6726     case BUILT_IN_FABSL:
6727       if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6728         return fold (build1 (ABS_EXPR, type, TREE_VALUE (arglist)));
6729       break;
6730
6731     case BUILT_IN_CABS:
6732     case BUILT_IN_CABSF:
6733     case BUILT_IN_CABSL:
6734       return fold_builtin_cabs (fndecl, arglist, type);
6735
6736     case BUILT_IN_SQRT:
6737     case BUILT_IN_SQRTF:
6738     case BUILT_IN_SQRTL:
6739       if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6740         {
6741           enum built_in_function fcode;
6742           tree arg = TREE_VALUE (arglist);
6743
6744           /* Optimize sqrt of constant value.  */
6745           if (TREE_CODE (arg) == REAL_CST
6746               && ! TREE_CONSTANT_OVERFLOW (arg))
6747             {
6748               REAL_VALUE_TYPE r, x;
6749
6750               x = TREE_REAL_CST (arg);
6751               if (real_sqrt (&r, TYPE_MODE (type), &x)
6752                   || (!flag_trapping_math && !flag_errno_math))
6753                 return build_real (type, r);
6754             }
6755
6756           /* Optimize sqrt(exp(x)) = exp(x*0.5).  */
6757           fcode = builtin_mathfn_code (arg);
6758           if (flag_unsafe_math_optimizations
6759               && (fcode == BUILT_IN_EXP
6760                   || fcode == BUILT_IN_EXPF
6761                   || fcode == BUILT_IN_EXPL))
6762             {
6763               tree expfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
6764               arg = fold (build (MULT_EXPR, type,
6765                                  TREE_VALUE (TREE_OPERAND (arg, 1)),
6766                                  build_real (type, dconsthalf)));
6767               arglist = build_tree_list (NULL_TREE, arg);
6768               return build_function_call_expr (expfn, arglist);
6769             }
6770
6771           /* Optimize sqrt(pow(x,y)) = pow(x,y*0.5).  */
6772           if (flag_unsafe_math_optimizations
6773               && (fcode == BUILT_IN_POW
6774                   || fcode == BUILT_IN_POWF
6775                   || fcode == BUILT_IN_POWL))
6776             {
6777               tree powfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
6778               tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
6779               tree arg1 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
6780               tree narg1 = fold (build (MULT_EXPR, type, arg1,
6781                                         build_real (type, dconsthalf)));
6782               arglist = tree_cons (NULL_TREE, arg0,
6783                                    build_tree_list (NULL_TREE, narg1));
6784               return build_function_call_expr (powfn, arglist);
6785             }
6786         }
6787       break;
6788
6789     case BUILT_IN_SIN:
6790     case BUILT_IN_SINF:
6791     case BUILT_IN_SINL:
6792       if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6793         {
6794           tree arg = TREE_VALUE (arglist);
6795
6796           /* Optimize sin(0.0) = 0.0.  */
6797           if (real_zerop (arg))
6798             return arg;
6799         }
6800       break;
6801
6802     case BUILT_IN_COS:
6803     case BUILT_IN_COSF:
6804     case BUILT_IN_COSL:
6805       if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6806         {
6807           tree arg = TREE_VALUE (arglist);
6808
6809           /* Optimize cos(0.0) = 1.0.  */
6810           if (real_zerop (arg))
6811             return build_real (type, dconst1);
6812
6813           /* Optimize cos(-x) into cos(x).  */
6814           if (TREE_CODE (arg) == NEGATE_EXPR)
6815             {
6816               tree arglist = build_tree_list (NULL_TREE,
6817                                               TREE_OPERAND (arg, 0));
6818               return build_function_call_expr (fndecl, arglist);
6819             }
6820         }
6821       break;
6822
6823     case BUILT_IN_EXP:
6824     case BUILT_IN_EXPF:
6825     case BUILT_IN_EXPL:
6826       return fold_builtin_exponent (exp, &dconste);
6827     case BUILT_IN_EXP2:
6828     case BUILT_IN_EXP2F:
6829     case BUILT_IN_EXP2L:
6830       return fold_builtin_exponent (exp, &dconst2);
6831     case BUILT_IN_EXP10:
6832     case BUILT_IN_EXP10F:
6833     case BUILT_IN_EXP10L:
6834     case BUILT_IN_POW10:
6835     case BUILT_IN_POW10F:
6836     case BUILT_IN_POW10L:
6837       return fold_builtin_exponent (exp, &dconst10);
6838     case BUILT_IN_LOG:
6839     case BUILT_IN_LOGF:
6840     case BUILT_IN_LOGL:
6841       return fold_builtin_logarithm (exp, &dconste);
6842       break;
6843     case BUILT_IN_LOG2:
6844     case BUILT_IN_LOG2F:
6845     case BUILT_IN_LOG2L:
6846       return fold_builtin_logarithm (exp, &dconst2);
6847       break;
6848     case BUILT_IN_LOG10:
6849     case BUILT_IN_LOG10F:
6850     case BUILT_IN_LOG10L:
6851       return fold_builtin_logarithm (exp, &dconst10);
6852       break;
6853
6854     case BUILT_IN_TAN:
6855     case BUILT_IN_TANF:
6856     case BUILT_IN_TANL:
6857       if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6858         {
6859           enum built_in_function fcode;
6860           tree arg = TREE_VALUE (arglist);
6861
6862           /* Optimize tan(0.0) = 0.0.  */
6863           if (real_zerop (arg))
6864             return arg;
6865
6866           /* Optimize tan(atan(x)) = x.  */
6867           fcode = builtin_mathfn_code (arg);
6868           if (flag_unsafe_math_optimizations
6869               && (fcode == BUILT_IN_ATAN
6870                   || fcode == BUILT_IN_ATANF
6871                   || fcode == BUILT_IN_ATANL))
6872             return TREE_VALUE (TREE_OPERAND (arg, 1));
6873         }
6874       break;
6875
6876     case BUILT_IN_ATAN:
6877     case BUILT_IN_ATANF:
6878     case BUILT_IN_ATANL:
6879       if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6880         {
6881           tree arg = TREE_VALUE (arglist);
6882
6883           /* Optimize atan(0.0) = 0.0.  */
6884           if (real_zerop (arg))
6885             return arg;
6886
6887           /* Optimize atan(1.0) = pi/4.  */
6888           if (real_onep (arg))
6889             {
6890               REAL_VALUE_TYPE cst;
6891
6892               real_convert (&cst, TYPE_MODE (type), &dconstpi);
6893               cst.exp -= 2;
6894               return build_real (type, cst);
6895             }
6896         }
6897       break;
6898
6899     case BUILT_IN_POW:
6900     case BUILT_IN_POWF:
6901     case BUILT_IN_POWL:
6902       if (validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
6903         {
6904           enum built_in_function fcode;
6905           tree arg0 = TREE_VALUE (arglist);
6906           tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
6907
6908           /* Optimize pow(1.0,y) = 1.0.  */
6909           if (real_onep (arg0))
6910             return omit_one_operand (type, build_real (type, dconst1), arg1);
6911
6912           if (TREE_CODE (arg1) == REAL_CST
6913               && ! TREE_CONSTANT_OVERFLOW (arg1))
6914             {
6915               REAL_VALUE_TYPE c;
6916               c = TREE_REAL_CST (arg1);
6917
6918               /* Optimize pow(x,0.0) = 1.0.  */
6919               if (REAL_VALUES_EQUAL (c, dconst0))
6920                 return omit_one_operand (type, build_real (type, dconst1),
6921                                          arg0);
6922
6923               /* Optimize pow(x,1.0) = x.  */
6924               if (REAL_VALUES_EQUAL (c, dconst1))
6925                 return arg0;
6926
6927               /* Optimize pow(x,-1.0) = 1.0/x.  */
6928               if (REAL_VALUES_EQUAL (c, dconstm1))
6929                 return fold (build (RDIV_EXPR, type,
6930                                     build_real (type, dconst1),
6931                                     arg0));
6932
6933               /* Optimize pow(x,0.5) = sqrt(x).  */
6934               if (flag_unsafe_math_optimizations
6935                   && REAL_VALUES_EQUAL (c, dconsthalf))
6936                 {
6937                   tree sqrtfn;
6938
6939                   fcode = DECL_FUNCTION_CODE (fndecl);
6940                   if (fcode == BUILT_IN_POW)
6941                     sqrtfn = implicit_built_in_decls[BUILT_IN_SQRT];
6942                   else if (fcode == BUILT_IN_POWF)
6943                     sqrtfn = implicit_built_in_decls[BUILT_IN_SQRTF];
6944                   else if (fcode == BUILT_IN_POWL)
6945                     sqrtfn = implicit_built_in_decls[BUILT_IN_SQRTL];
6946                   else
6947                     sqrtfn = NULL_TREE;
6948
6949                   if (sqrtfn != NULL_TREE)
6950                     {
6951                       tree arglist = build_tree_list (NULL_TREE, arg0);
6952                       return build_function_call_expr (sqrtfn, arglist);
6953                     }
6954                 }
6955
6956               /* Attempt to evaluate pow at compile-time.  */
6957               if (TREE_CODE (arg0) == REAL_CST
6958                   && ! TREE_CONSTANT_OVERFLOW (arg0))
6959                 {
6960                   REAL_VALUE_TYPE cint;
6961                   HOST_WIDE_INT n;
6962
6963                   n = real_to_integer (&c);
6964                   real_from_integer (&cint, VOIDmode, n,
6965                                      n < 0 ? -1 : 0, 0);
6966                   if (real_identical (&c, &cint))
6967                     {
6968                       REAL_VALUE_TYPE x;
6969                       bool inexact;
6970
6971                       x = TREE_REAL_CST (arg0);
6972                       inexact = real_powi (&x, TYPE_MODE (type), &x, n);
6973                       if (flag_unsafe_math_optimizations || !inexact)
6974                         return build_real (type, x);
6975                     }
6976                 }
6977             }
6978
6979           /* Optimize pow(exp(x),y) = exp(x*y).  */
6980           fcode = builtin_mathfn_code (arg0);
6981           if (flag_unsafe_math_optimizations
6982               && (fcode == BUILT_IN_EXP
6983                   || fcode == BUILT_IN_EXPF
6984                   || fcode == BUILT_IN_EXPL))
6985             {
6986               tree expfn = TREE_OPERAND (TREE_OPERAND (arg0, 0), 0);
6987               tree arg = TREE_VALUE (TREE_OPERAND (arg0, 1));
6988               arg = fold (build (MULT_EXPR, type, arg, arg1));
6989               arglist = build_tree_list (NULL_TREE, arg);
6990               return build_function_call_expr (expfn, arglist);
6991             }
6992
6993           /* Optimize pow(sqrt(x),y) = pow(x,y*0.5).  */
6994           if (flag_unsafe_math_optimizations
6995               && (fcode == BUILT_IN_SQRT
6996                   || fcode == BUILT_IN_SQRTF
6997                   || fcode == BUILT_IN_SQRTL))
6998             {
6999               tree narg0 = TREE_VALUE (TREE_OPERAND (arg0, 1));
7000               tree narg1 = fold (build (MULT_EXPR, type, arg1,
7001                                         build_real (type, dconsthalf)));
7002
7003               arglist = tree_cons (NULL_TREE, narg0,
7004                                    build_tree_list (NULL_TREE, narg1));
7005               return build_function_call_expr (fndecl, arglist);
7006             }
7007
7008           /* Optimize pow(pow(x,y),z) = pow(x,y*z).  */
7009           if (flag_unsafe_math_optimizations
7010               && (fcode == BUILT_IN_POW
7011                   || fcode == BUILT_IN_POWF
7012                   || fcode == BUILT_IN_POWL))
7013             {
7014               tree arg00 = TREE_VALUE (TREE_OPERAND (arg0, 1));
7015               tree arg01 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg0, 1)));
7016               tree narg1 = fold (build (MULT_EXPR, type, arg01, arg1));
7017               arglist = tree_cons (NULL_TREE, arg00,
7018                                    build_tree_list (NULL_TREE, narg1));
7019               return build_function_call_expr (fndecl, arglist);
7020             }
7021         }
7022       break;
7023
7024     case BUILT_IN_INF:
7025     case BUILT_IN_INFF:
7026     case BUILT_IN_INFL:
7027       return fold_builtin_inf (type, true);
7028
7029     case BUILT_IN_HUGE_VAL:
7030     case BUILT_IN_HUGE_VALF:
7031     case BUILT_IN_HUGE_VALL:
7032       return fold_builtin_inf (type, false);
7033
7034     case BUILT_IN_NAN:
7035     case BUILT_IN_NANF:
7036     case BUILT_IN_NANL:
7037       return fold_builtin_nan (arglist, type, true);
7038
7039     case BUILT_IN_NANS:
7040     case BUILT_IN_NANSF:
7041     case BUILT_IN_NANSL:
7042       return fold_builtin_nan (arglist, type, false);
7043
7044     case BUILT_IN_FLOOR:
7045     case BUILT_IN_FLOORF:
7046     case BUILT_IN_FLOORL:
7047       return fold_builtin_floor (exp);
7048
7049     case BUILT_IN_CEIL:
7050     case BUILT_IN_CEILF:
7051     case BUILT_IN_CEILL:
7052       return fold_builtin_ceil (exp);
7053
7054     case BUILT_IN_TRUNC:
7055     case BUILT_IN_TRUNCF:
7056     case BUILT_IN_TRUNCL:
7057       return fold_builtin_trunc (exp);
7058
7059     case BUILT_IN_ROUND:
7060     case BUILT_IN_ROUNDF:
7061     case BUILT_IN_ROUNDL:
7062       return fold_builtin_round (exp);
7063
7064     case BUILT_IN_NEARBYINT:
7065     case BUILT_IN_NEARBYINTF:
7066     case BUILT_IN_NEARBYINTL:
7067       return fold_trunc_transparent_mathfn (exp);
7068
7069     case BUILT_IN_FFS:
7070     case BUILT_IN_FFSL:
7071     case BUILT_IN_FFSLL:
7072     case BUILT_IN_CLZ:
7073     case BUILT_IN_CLZL:
7074     case BUILT_IN_CLZLL:
7075     case BUILT_IN_CTZ:
7076     case BUILT_IN_CTZL:
7077     case BUILT_IN_CTZLL:
7078     case BUILT_IN_POPCOUNT:
7079     case BUILT_IN_POPCOUNTL:
7080     case BUILT_IN_POPCOUNTLL:
7081     case BUILT_IN_PARITY:
7082     case BUILT_IN_PARITYL:
7083     case BUILT_IN_PARITYLL:
7084       return fold_builtin_bitop (exp);
7085
7086     case BUILT_IN_MEMCPY:
7087       return fold_builtin_memcpy (exp);
7088
7089     case BUILT_IN_MEMPCPY:
7090       return fold_builtin_mempcpy (exp);
7091
7092     case BUILT_IN_MEMMOVE:
7093       return fold_builtin_memmove (exp);
7094
7095     case BUILT_IN_STRCPY:
7096       return fold_builtin_strcpy (exp);
7097
7098     case BUILT_IN_STRNCPY:
7099       return fold_builtin_strncpy (exp);
7100
7101     case BUILT_IN_MEMCMP:
7102       return fold_builtin_memcmp (exp);
7103
7104     case BUILT_IN_STRCMP:
7105       return fold_builtin_strcmp (exp);
7106
7107     case BUILT_IN_STRNCMP:
7108       return fold_builtin_strncmp (exp);
7109
7110     case BUILT_IN_SIGNBIT:
7111     case BUILT_IN_SIGNBITF:
7112     case BUILT_IN_SIGNBITL:
7113       return fold_builtin_signbit (exp);
7114
7115     default:
7116       break;
7117     }
7118
7119   return 0;
7120 }
7121
7122 /* Conveniently construct a function call expression.  */
7123
7124 tree
7125 build_function_call_expr (tree fn, tree arglist)
7126 {
7127   tree call_expr;
7128
7129   call_expr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
7130   call_expr = build (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)),
7131                      call_expr, arglist);
7132   return fold (call_expr);
7133 }
7134
7135 /* This function validates the types of a function call argument list
7136    represented as a tree chain of parameters against a specified list
7137    of tree_codes.  If the last specifier is a 0, that represents an
7138    ellipses, otherwise the last specifier must be a VOID_TYPE.  */
7139
7140 static int
7141 validate_arglist (tree arglist, ...)
7142 {
7143   enum tree_code code;
7144   int res = 0;
7145   va_list ap;
7146
7147   va_start (ap, arglist);
7148
7149   do
7150     {
7151       code = va_arg (ap, enum tree_code);
7152       switch (code)
7153         {
7154         case 0:
7155           /* This signifies an ellipses, any further arguments are all ok.  */
7156           res = 1;
7157           goto end;
7158         case VOID_TYPE:
7159           /* This signifies an endlink, if no arguments remain, return
7160              true, otherwise return false.  */
7161           res = arglist == 0;
7162           goto end;
7163         default:
7164           /* If no parameters remain or the parameter's code does not
7165              match the specified code, return false.  Otherwise continue
7166              checking any remaining arguments.  */
7167           if (arglist == 0
7168               || code != TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))))
7169             goto end;
7170           break;
7171         }
7172       arglist = TREE_CHAIN (arglist);
7173     }
7174   while (1);
7175
7176   /* We need gotos here since we can only have one VA_CLOSE in a
7177      function.  */
7178  end: ;
7179   va_end (ap);
7180
7181   return res;
7182 }
7183
7184 /* Default target-specific builtin expander that does nothing.  */
7185
7186 rtx
7187 default_expand_builtin (tree exp ATTRIBUTE_UNUSED,
7188                         rtx target ATTRIBUTE_UNUSED,
7189                         rtx subtarget ATTRIBUTE_UNUSED,
7190                         enum machine_mode mode ATTRIBUTE_UNUSED,
7191                         int ignore ATTRIBUTE_UNUSED)
7192 {
7193   return NULL_RTX;
7194 }
7195
7196 /* Instantiate all remaining CONSTANT_P_RTX nodes.  */
7197
7198 void
7199 purge_builtin_constant_p (void)
7200 {
7201   rtx insn, set, arg, new, note;
7202
7203   for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
7204     if (INSN_P (insn)
7205         && (set = single_set (insn)) != NULL_RTX
7206         && (GET_CODE (arg = SET_SRC (set)) == CONSTANT_P_RTX
7207             || (GET_CODE (arg) == SUBREG
7208                 && (GET_CODE (arg = SUBREG_REG (arg))
7209                     == CONSTANT_P_RTX))))
7210       {
7211         arg = XEXP (arg, 0);
7212         new = CONSTANT_P (arg) ? const1_rtx : const0_rtx;
7213         validate_change (insn, &SET_SRC (set), new, 0);
7214
7215         /* Remove the REG_EQUAL note from the insn.  */
7216         if ((note = find_reg_note (insn, REG_EQUAL, NULL_RTX)) != 0)
7217           remove_note (insn, note);
7218       }
7219 }
7220
7221 /* Returns true is EXP represents data that would potentially reside
7222    in a readonly section.  */
7223
7224 static bool
7225 readonly_data_expr (tree exp)
7226 {
7227   STRIP_NOPS (exp);
7228
7229   if (TREE_CODE (exp) == ADDR_EXPR)
7230     return decl_readonly_section (TREE_OPERAND (exp, 0), 0);
7231   else
7232     return false;
7233 }