OSDN Git Service

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