OSDN Git Service

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