OSDN Git Service

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