OSDN Git Service

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