OSDN Git Service

* builtins.c (fold_trunc_transparent_mathfn): Undo accidental commit.
[pf3gnuchains/gcc-fork.git] / gcc / builtins.c
1 /* Expand builtin functions.
2    Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3    2000, 2001, 2002, 2003 Free Software Foundation, Inc.
4
5 This file is part of GCC.
6
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
10 version.
11
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15 for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING.  If not, write to the Free
19 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
20 02111-1307, USA.  */
21
22 #include "config.h"
23 #include "system.h"
24 #include "coretypes.h"
25 #include "tm.h"
26 #include "machmode.h"
27 #include "real.h"
28 #include "rtl.h"
29 #include "tree.h"
30 #include "flags.h"
31 #include "regs.h"
32 #include "hard-reg-set.h"
33 #include "except.h"
34 #include "function.h"
35 #include "insn-config.h"
36 #include "expr.h"
37 #include "optabs.h"
38 #include "libfuncs.h"
39 #include "recog.h"
40 #include "output.h"
41 #include "typeclass.h"
42 #include "toplev.h"
43 #include "predict.h"
44 #include "tm_p.h"
45 #include "target.h"
46 #include "langhooks.h"
47
48 #define CALLED_AS_BUILT_IN(NODE) \
49    (!strncmp (IDENTIFIER_POINTER (DECL_NAME (NODE)), "__builtin_", 10))
50
51 /* Register mappings for target machines without register windows.  */
52 #ifndef INCOMING_REGNO
53 #define INCOMING_REGNO(OUT) (OUT)
54 #endif
55 #ifndef OUTGOING_REGNO
56 #define OUTGOING_REGNO(IN) (IN)
57 #endif
58
59 #ifndef PAD_VARARGS_DOWN
60 #define PAD_VARARGS_DOWN BYTES_BIG_ENDIAN
61 #endif
62
63 /* Define the names of the builtin function types and codes.  */
64 const char *const built_in_class_names[4]
65   = {"NOT_BUILT_IN", "BUILT_IN_FRONTEND", "BUILT_IN_MD", "BUILT_IN_NORMAL"};
66
67 #define DEF_BUILTIN(X, N, C, T, LT, B, F, NA, AT, IM) STRINGX(X),
68 const char *const built_in_names[(int) END_BUILTINS] =
69 {
70 #include "builtins.def"
71 };
72 #undef DEF_BUILTIN
73
74 /* Setup an array of _DECL trees, make sure each element is
75    initialized to NULL_TREE.  */
76 tree built_in_decls[(int) END_BUILTINS];
77 /* Declarations used when constructing the builtin implicitly in the compiler.
78    It may be NULL_TREE when this is invalid (for instance runtime is not
79    required to implement the function call in all cases.  */
80 tree implicit_built_in_decls[(int) END_BUILTINS];
81
82 static int get_pointer_alignment        PARAMS ((tree, unsigned int));
83 static tree c_strlen                    PARAMS ((tree));
84 static const char *c_getstr             PARAMS ((tree));
85 static rtx c_readstr                    PARAMS ((const char *,
86                                                  enum machine_mode));
87 static int target_char_cast             PARAMS ((tree, char *));
88 static rtx get_memory_rtx               PARAMS ((tree));
89 static int apply_args_size              PARAMS ((void));
90 static int apply_result_size            PARAMS ((void));
91 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
92 static rtx result_vector                PARAMS ((int, rtx));
93 #endif
94 static rtx expand_builtin_setjmp        PARAMS ((tree, rtx));
95 static void expand_builtin_prefetch     PARAMS ((tree));
96 static rtx expand_builtin_apply_args    PARAMS ((void));
97 static rtx expand_builtin_apply_args_1  PARAMS ((void));
98 static rtx expand_builtin_apply         PARAMS ((rtx, rtx, rtx));
99 static void expand_builtin_return       PARAMS ((rtx));
100 static enum type_class type_to_class    PARAMS ((tree));
101 static rtx expand_builtin_classify_type PARAMS ((tree));
102 static rtx expand_builtin_mathfn        PARAMS ((tree, rtx, rtx));
103 static rtx expand_builtin_constant_p    PARAMS ((tree));
104 static rtx expand_builtin_args_info     PARAMS ((tree));
105 static rtx expand_builtin_next_arg      PARAMS ((tree));
106 static rtx expand_builtin_va_start      PARAMS ((tree));
107 static rtx expand_builtin_va_end        PARAMS ((tree));
108 static rtx expand_builtin_va_copy       PARAMS ((tree));
109 static rtx expand_builtin_memcmp        PARAMS ((tree, tree, rtx,
110                                                  enum machine_mode));
111 static rtx expand_builtin_strcmp        PARAMS ((tree, rtx,
112                                                  enum machine_mode));
113 static rtx expand_builtin_strncmp       PARAMS ((tree, rtx,
114                                                  enum machine_mode));
115 static rtx builtin_memcpy_read_str      PARAMS ((PTR, HOST_WIDE_INT,
116                                                  enum machine_mode));
117 static rtx expand_builtin_strcat        PARAMS ((tree, rtx,
118                                                  enum machine_mode));
119 static rtx expand_builtin_strncat       PARAMS ((tree, rtx,
120                                                  enum machine_mode));
121 static rtx expand_builtin_strspn        PARAMS ((tree, rtx,
122                                                  enum machine_mode));
123 static rtx expand_builtin_strcspn       PARAMS ((tree, rtx,
124                                                  enum machine_mode));
125 static rtx expand_builtin_memcpy        PARAMS ((tree, rtx,
126                                                  enum machine_mode));
127 static rtx expand_builtin_strcpy        PARAMS ((tree, rtx,
128                                                  enum machine_mode));
129 static rtx builtin_strncpy_read_str     PARAMS ((PTR, HOST_WIDE_INT,
130                                                  enum machine_mode));
131 static rtx expand_builtin_strncpy       PARAMS ((tree, rtx,
132                                                  enum machine_mode));
133 static rtx builtin_memset_read_str      PARAMS ((PTR, HOST_WIDE_INT,
134                                                  enum machine_mode));
135 static rtx builtin_memset_gen_str       PARAMS ((PTR, HOST_WIDE_INT,
136                                                  enum machine_mode));
137 static rtx expand_builtin_memset        PARAMS ((tree, rtx,
138                                                  enum machine_mode));
139 static rtx expand_builtin_bzero         PARAMS ((tree));
140 static rtx expand_builtin_strlen        PARAMS ((tree, rtx));
141 static rtx expand_builtin_strstr        PARAMS ((tree, rtx,
142                                                  enum machine_mode));
143 static rtx expand_builtin_strpbrk       PARAMS ((tree, rtx,
144                                                  enum machine_mode));
145 static rtx expand_builtin_strchr        PARAMS ((tree, rtx,
146                                                  enum machine_mode));
147 static rtx expand_builtin_strrchr       PARAMS ((tree, rtx,
148                                                  enum machine_mode));
149 static rtx expand_builtin_alloca        PARAMS ((tree, rtx));
150 static rtx expand_builtin_ffs           PARAMS ((tree, rtx, rtx));
151 static rtx expand_builtin_frame_address PARAMS ((tree));
152 static rtx expand_builtin_fputs         PARAMS ((tree, int, int));
153 static tree stabilize_va_list           PARAMS ((tree, int));
154 static rtx expand_builtin_expect        PARAMS ((tree, rtx));
155 static tree fold_builtin_constant_p     PARAMS ((tree));
156 static tree fold_builtin_classify_type  PARAMS ((tree));
157 static tree fold_builtin_inf            PARAMS ((tree, int));
158 static tree fold_builtin_nan            PARAMS ((tree, tree, int));
159 static int validate_arglist             PARAMS ((tree, ...));
160
161 /* Return the alignment in bits of EXP, a pointer valued expression.
162    But don't return more than MAX_ALIGN no matter what.
163    The alignment returned is, by default, the alignment of the thing that
164    EXP points to.  If it is not a POINTER_TYPE, 0 is returned.
165
166    Otherwise, look at the expression to see if we can do better, i.e., if the
167    expression is actually pointing at an object whose alignment is tighter.  */
168
169 static int
170 get_pointer_alignment (exp, max_align)
171      tree exp;
172      unsigned int max_align;
173 {
174   unsigned int align, inner;
175
176   if (TREE_CODE (TREE_TYPE (exp)) != POINTER_TYPE)
177     return 0;
178
179   align = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
180   align = MIN (align, max_align);
181
182   while (1)
183     {
184       switch (TREE_CODE (exp))
185         {
186         case NOP_EXPR:
187         case CONVERT_EXPR:
188         case NON_LVALUE_EXPR:
189           exp = TREE_OPERAND (exp, 0);
190           if (TREE_CODE (TREE_TYPE (exp)) != POINTER_TYPE)
191             return align;
192
193           inner = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
194           align = MIN (inner, max_align);
195           break;
196
197         case PLUS_EXPR:
198           /* If sum of pointer + int, restrict our maximum alignment to that
199              imposed by the integer.  If not, we can't do any better than
200              ALIGN.  */
201           if (! host_integerp (TREE_OPERAND (exp, 1), 1))
202             return align;
203
204           while (((tree_low_cst (TREE_OPERAND (exp, 1), 1))
205                   & (max_align / BITS_PER_UNIT - 1))
206                  != 0)
207             max_align >>= 1;
208
209           exp = TREE_OPERAND (exp, 0);
210           break;
211
212         case ADDR_EXPR:
213           /* See what we are pointing at and look at its alignment.  */
214           exp = TREE_OPERAND (exp, 0);
215           if (TREE_CODE (exp) == FUNCTION_DECL)
216             align = FUNCTION_BOUNDARY;
217           else if (DECL_P (exp))
218             align = DECL_ALIGN (exp);
219 #ifdef CONSTANT_ALIGNMENT
220           else if (TREE_CODE_CLASS (TREE_CODE (exp)) == 'c')
221             align = CONSTANT_ALIGNMENT (exp, align);
222 #endif
223           return MIN (align, max_align);
224
225         default:
226           return align;
227         }
228     }
229 }
230
231 /* Compute the length of a C string.  TREE_STRING_LENGTH is not the right
232    way, because it could contain a zero byte in the middle.
233    TREE_STRING_LENGTH is the size of the character array, not the string.
234
235    The value returned is of type `ssizetype'.
236
237    Unfortunately, string_constant can't access the values of const char
238    arrays with initializers, so neither can we do so here.  */
239
240 static tree
241 c_strlen (src)
242      tree src;
243 {
244   tree offset_node;
245   HOST_WIDE_INT offset;
246   int max;
247   const char *ptr;
248
249   src = string_constant (src, &offset_node);
250   if (src == 0)
251     return 0;
252
253   max = TREE_STRING_LENGTH (src) - 1;
254   ptr = TREE_STRING_POINTER (src);
255
256   if (offset_node && TREE_CODE (offset_node) != INTEGER_CST)
257     {
258       /* If the string has an internal zero byte (e.g., "foo\0bar"), we can't
259          compute the offset to the following null if we don't know where to
260          start searching for it.  */
261       int i;
262
263       for (i = 0; i < max; i++)
264         if (ptr[i] == 0)
265           return 0;
266
267       /* We don't know the starting offset, but we do know that the string
268          has no internal zero bytes.  We can assume that the offset falls
269          within the bounds of the string; otherwise, the programmer deserves
270          what he gets.  Subtract the offset from the length of the string,
271          and return that.  This would perhaps not be valid if we were dealing
272          with named arrays in addition to literal string constants.  */
273
274       return size_diffop (size_int (max), offset_node);
275     }
276
277   /* We have a known offset into the string.  Start searching there for
278      a null character if we can represent it as a single HOST_WIDE_INT.  */
279   if (offset_node == 0)
280     offset = 0;
281   else if (! host_integerp (offset_node, 0))
282     offset = -1;
283   else
284     offset = tree_low_cst (offset_node, 0);
285
286   /* If the offset is known to be out of bounds, warn, and call strlen at
287      runtime.  */
288   if (offset < 0 || offset > max)
289     {
290       warning ("offset outside bounds of constant string");
291       return 0;
292     }
293
294   /* Use strlen to search for the first zero byte.  Since any strings
295      constructed with build_string will have nulls appended, we win even
296      if we get handed something like (char[4])"abcd".
297
298      Since OFFSET is our starting index into the string, no further
299      calculation is needed.  */
300   return ssize_int (strlen (ptr + offset));
301 }
302
303 /* Return a char pointer for a C string if it is a string constant
304    or sum of string constant and integer constant.  */
305
306 static const char *
307 c_getstr (src)
308      tree src;
309 {
310   tree offset_node;
311
312   src = string_constant (src, &offset_node);
313   if (src == 0)
314     return 0;
315
316   if (offset_node == 0)
317     return TREE_STRING_POINTER (src);
318   else if (!host_integerp (offset_node, 1)
319            || compare_tree_int (offset_node, TREE_STRING_LENGTH (src) - 1) > 0)
320     return 0;
321
322   return TREE_STRING_POINTER (src) + tree_low_cst (offset_node, 1);
323 }
324
325 /* Return a CONST_INT or CONST_DOUBLE corresponding to target reading
326    GET_MODE_BITSIZE (MODE) bits from string constant STR.  */
327
328 static rtx
329 c_readstr (str, mode)
330      const char *str;
331      enum machine_mode mode;
332 {
333   HOST_WIDE_INT c[2];
334   HOST_WIDE_INT ch;
335   unsigned int i, j;
336
337   if (GET_MODE_CLASS (mode) != MODE_INT)
338     abort ();
339   c[0] = 0;
340   c[1] = 0;
341   ch = 1;
342   for (i = 0; i < GET_MODE_SIZE (mode); i++)
343     {
344       j = i;
345       if (WORDS_BIG_ENDIAN)
346         j = GET_MODE_SIZE (mode) - i - 1;
347       if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN
348           && GET_MODE_SIZE (mode) > UNITS_PER_WORD)
349         j = j + UNITS_PER_WORD - 2 * (j % UNITS_PER_WORD) - 1;
350       j *= BITS_PER_UNIT;
351       if (j > 2 * HOST_BITS_PER_WIDE_INT)
352         abort ();
353       if (ch)
354         ch = (unsigned char) str[i];
355       c[j / HOST_BITS_PER_WIDE_INT] |= ch << (j % HOST_BITS_PER_WIDE_INT);
356     }
357   return immed_double_const (c[0], c[1], mode);
358 }
359
360 /* Cast a target constant CST to target CHAR and if that value fits into
361    host char type, return zero and put that value into variable pointed by
362    P.  */
363
364 static int
365 target_char_cast (cst, p)
366      tree cst;
367      char *p;
368 {
369   unsigned HOST_WIDE_INT val, hostval;
370
371   if (!host_integerp (cst, 1)
372       || CHAR_TYPE_SIZE > HOST_BITS_PER_WIDE_INT)
373     return 1;
374
375   val = tree_low_cst (cst, 1);
376   if (CHAR_TYPE_SIZE < HOST_BITS_PER_WIDE_INT)
377     val &= (((unsigned HOST_WIDE_INT) 1) << CHAR_TYPE_SIZE) - 1;
378
379   hostval = val;
380   if (HOST_BITS_PER_CHAR < HOST_BITS_PER_WIDE_INT)
381     hostval &= (((unsigned HOST_WIDE_INT) 1) << HOST_BITS_PER_CHAR) - 1;
382
383   if (val != hostval)
384     return 1;
385
386   *p = hostval;
387   return 0;
388 }
389
390 /* Given TEM, a pointer to a stack frame, follow the dynamic chain COUNT
391    times to get the address of either a higher stack frame, or a return
392    address located within it (depending on FNDECL_CODE).  */
393
394 rtx
395 expand_builtin_return_addr (fndecl_code, count, tem)
396      enum built_in_function fndecl_code;
397      int count;
398      rtx tem;
399 {
400   int i;
401
402   /* Some machines need special handling before we can access
403      arbitrary frames.  For example, on the sparc, we must first flush
404      all register windows to the stack.  */
405 #ifdef SETUP_FRAME_ADDRESSES
406   if (count > 0)
407     SETUP_FRAME_ADDRESSES ();
408 #endif
409
410   /* On the sparc, the return address is not in the frame, it is in a
411      register.  There is no way to access it off of the current frame
412      pointer, but it can be accessed off the previous frame pointer by
413      reading the value from the register window save area.  */
414 #ifdef RETURN_ADDR_IN_PREVIOUS_FRAME
415   if (fndecl_code == BUILT_IN_RETURN_ADDRESS)
416     count--;
417 #endif
418
419   /* Scan back COUNT frames to the specified frame.  */
420   for (i = 0; i < count; i++)
421     {
422       /* Assume the dynamic chain pointer is in the word that the
423          frame address points to, unless otherwise specified.  */
424 #ifdef DYNAMIC_CHAIN_ADDRESS
425       tem = DYNAMIC_CHAIN_ADDRESS (tem);
426 #endif
427       tem = memory_address (Pmode, tem);
428       tem = gen_rtx_MEM (Pmode, tem);
429       set_mem_alias_set (tem, get_frame_alias_set ());
430       tem = copy_to_reg (tem);
431     }
432
433   /* For __builtin_frame_address, return what we've got.  */
434   if (fndecl_code == BUILT_IN_FRAME_ADDRESS)
435     return tem;
436
437   /* For __builtin_return_address, Get the return address from that
438      frame.  */
439 #ifdef RETURN_ADDR_RTX
440   tem = RETURN_ADDR_RTX (count, tem);
441 #else
442   tem = memory_address (Pmode,
443                         plus_constant (tem, GET_MODE_SIZE (Pmode)));
444   tem = gen_rtx_MEM (Pmode, tem);
445   set_mem_alias_set (tem, get_frame_alias_set ());
446 #endif
447   return tem;
448 }
449
450 /* Alias set used for setjmp buffer.  */
451 static HOST_WIDE_INT setjmp_alias_set = -1;
452
453 /* Construct the leading half of a __builtin_setjmp call.  Control will
454    return to RECEIVER_LABEL.  This is used directly by sjlj exception
455    handling code.  */
456
457 void
458 expand_builtin_setjmp_setup (buf_addr, receiver_label)
459      rtx buf_addr;
460      rtx receiver_label;
461 {
462   enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
463   rtx stack_save;
464   rtx mem;
465
466   if (setjmp_alias_set == -1)
467     setjmp_alias_set = new_alias_set ();
468
469 #ifdef POINTERS_EXTEND_UNSIGNED
470   if (GET_MODE (buf_addr) != Pmode)
471     buf_addr = convert_memory_address (Pmode, buf_addr);
472 #endif
473
474   buf_addr = force_reg (Pmode, force_operand (buf_addr, NULL_RTX));
475
476   emit_queue ();
477
478   /* We store the frame pointer and the address of receiver_label in
479      the buffer and use the rest of it for the stack save area, which
480      is machine-dependent.  */
481
482 #ifndef BUILTIN_SETJMP_FRAME_VALUE
483 #define BUILTIN_SETJMP_FRAME_VALUE virtual_stack_vars_rtx
484 #endif
485
486   mem = gen_rtx_MEM (Pmode, buf_addr);
487   set_mem_alias_set (mem, setjmp_alias_set);
488   emit_move_insn (mem, BUILTIN_SETJMP_FRAME_VALUE);
489
490   mem = gen_rtx_MEM (Pmode, plus_constant (buf_addr, GET_MODE_SIZE (Pmode))),
491   set_mem_alias_set (mem, setjmp_alias_set);
492
493   emit_move_insn (validize_mem (mem),
494                   force_reg (Pmode, gen_rtx_LABEL_REF (Pmode, receiver_label)));
495
496   stack_save = gen_rtx_MEM (sa_mode,
497                             plus_constant (buf_addr,
498                                            2 * GET_MODE_SIZE (Pmode)));
499   set_mem_alias_set (stack_save, setjmp_alias_set);
500   emit_stack_save (SAVE_NONLOCAL, &stack_save, NULL_RTX);
501
502   /* If there is further processing to do, do it.  */
503 #ifdef HAVE_builtin_setjmp_setup
504   if (HAVE_builtin_setjmp_setup)
505     emit_insn (gen_builtin_setjmp_setup (buf_addr));
506 #endif
507
508   /* Tell optimize_save_area_alloca that extra work is going to
509      need to go on during alloca.  */
510   current_function_calls_setjmp = 1;
511
512   /* Set this so all the registers get saved in our frame; we need to be
513      able to copy the saved values for any registers from frames we unwind.  */
514   current_function_has_nonlocal_label = 1;
515 }
516
517 /* Construct the trailing part of a __builtin_setjmp call.
518    This is used directly by sjlj exception handling code.  */
519
520 void
521 expand_builtin_setjmp_receiver (receiver_label)
522      rtx receiver_label ATTRIBUTE_UNUSED;
523 {
524   /* Clobber the FP when we get here, so we have to make sure it's
525      marked as used by this function.  */
526   emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
527
528   /* Mark the static chain as clobbered here so life information
529      doesn't get messed up for it.  */
530   emit_insn (gen_rtx_CLOBBER (VOIDmode, static_chain_rtx));
531
532   /* Now put in the code to restore the frame pointer, and argument
533      pointer, if needed.  The code below is from expand_end_bindings
534      in stmt.c; see detailed documentation there.  */
535 #ifdef HAVE_nonlocal_goto
536   if (! HAVE_nonlocal_goto)
537 #endif
538     emit_move_insn (virtual_stack_vars_rtx, hard_frame_pointer_rtx);
539
540 #if ARG_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
541   if (fixed_regs[ARG_POINTER_REGNUM])
542     {
543 #ifdef ELIMINABLE_REGS
544       size_t i;
545       static const struct elims {const int from, to;} elim_regs[] = ELIMINABLE_REGS;
546
547       for (i = 0; i < ARRAY_SIZE (elim_regs); i++)
548         if (elim_regs[i].from == ARG_POINTER_REGNUM
549             && elim_regs[i].to == HARD_FRAME_POINTER_REGNUM)
550           break;
551
552       if (i == ARRAY_SIZE (elim_regs))
553 #endif
554         {
555           /* Now restore our arg pointer from the address at which it
556              was saved in our stack frame.  */
557           emit_move_insn (virtual_incoming_args_rtx,
558                           copy_to_reg (get_arg_pointer_save_area (cfun)));
559         }
560     }
561 #endif
562
563 #ifdef HAVE_builtin_setjmp_receiver
564   if (HAVE_builtin_setjmp_receiver)
565     emit_insn (gen_builtin_setjmp_receiver (receiver_label));
566   else
567 #endif
568 #ifdef HAVE_nonlocal_goto_receiver
569     if (HAVE_nonlocal_goto_receiver)
570       emit_insn (gen_nonlocal_goto_receiver ());
571     else
572 #endif
573       { /* Nothing */ }
574
575   /* @@@ This is a kludge.  Not all machine descriptions define a blockage
576      insn, but we must not allow the code we just generated to be reordered
577      by scheduling.  Specifically, the update of the frame pointer must
578      happen immediately, not later.  So emit an ASM_INPUT to act as blockage
579      insn.  */
580   emit_insn (gen_rtx_ASM_INPUT (VOIDmode, ""));
581 }
582
583 /* __builtin_setjmp is passed a pointer to an array of five words (not
584    all will be used on all machines).  It operates similarly to the C
585    library function of the same name, but is more efficient.  Much of
586    the code below (and for longjmp) is copied from the handling of
587    non-local gotos.
588
589    NOTE: This is intended for use by GNAT and the exception handling
590    scheme in the compiler and will only work in the method used by
591    them.  */
592
593 static rtx
594 expand_builtin_setjmp (arglist, target)
595      tree arglist;
596      rtx target;
597 {
598   rtx buf_addr, next_lab, cont_lab;
599
600   if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
601     return NULL_RTX;
602
603   if (target == 0 || GET_CODE (target) != REG
604       || REGNO (target) < FIRST_PSEUDO_REGISTER)
605     target = gen_reg_rtx (TYPE_MODE (integer_type_node));
606
607   buf_addr = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
608
609   next_lab = gen_label_rtx ();
610   cont_lab = gen_label_rtx ();
611
612   expand_builtin_setjmp_setup (buf_addr, next_lab);
613
614   /* Set TARGET to zero and branch to the continue label.  */
615   emit_move_insn (target, const0_rtx);
616   emit_jump_insn (gen_jump (cont_lab));
617   emit_barrier ();
618   emit_label (next_lab);
619
620   expand_builtin_setjmp_receiver (next_lab);
621
622   /* Set TARGET to one.  */
623   emit_move_insn (target, const1_rtx);
624   emit_label (cont_lab);
625
626   /* Tell flow about the strange goings on.  Putting `next_lab' on
627      `nonlocal_goto_handler_labels' to indicates that function
628      calls may traverse the arc back to this label.  */
629
630   current_function_has_nonlocal_label = 1;
631   nonlocal_goto_handler_labels
632     = gen_rtx_EXPR_LIST (VOIDmode, next_lab, nonlocal_goto_handler_labels);
633
634   return target;
635 }
636
637 /* __builtin_longjmp is passed a pointer to an array of five words (not
638    all will be used on all machines).  It operates similarly to the C
639    library function of the same name, but is more efficient.  Much of
640    the code below is copied from the handling of non-local gotos.
641
642    NOTE: This is intended for use by GNAT and the exception handling
643    scheme in the compiler and will only work in the method used by
644    them.  */
645
646 void
647 expand_builtin_longjmp (buf_addr, value)
648      rtx buf_addr, value;
649 {
650   rtx fp, lab, stack, insn, last;
651   enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
652
653   if (setjmp_alias_set == -1)
654     setjmp_alias_set = new_alias_set ();
655
656 #ifdef POINTERS_EXTEND_UNSIGNED
657   if (GET_MODE (buf_addr) != Pmode)
658     buf_addr = convert_memory_address (Pmode, buf_addr);
659 #endif
660
661   buf_addr = force_reg (Pmode, buf_addr);
662
663   /* We used to store value in static_chain_rtx, but that fails if pointers
664      are smaller than integers.  We instead require that the user must pass
665      a second argument of 1, because that is what builtin_setjmp will
666      return.  This also makes EH slightly more efficient, since we are no
667      longer copying around a value that we don't care about.  */
668   if (value != const1_rtx)
669     abort ();
670
671   current_function_calls_longjmp = 1;
672
673   last = get_last_insn ();
674 #ifdef HAVE_builtin_longjmp
675   if (HAVE_builtin_longjmp)
676     emit_insn (gen_builtin_longjmp (buf_addr));
677   else
678 #endif
679     {
680       fp = gen_rtx_MEM (Pmode, buf_addr);
681       lab = gen_rtx_MEM (Pmode, plus_constant (buf_addr,
682                                                GET_MODE_SIZE (Pmode)));
683
684       stack = gen_rtx_MEM (sa_mode, plus_constant (buf_addr,
685                                                    2 * GET_MODE_SIZE (Pmode)));
686       set_mem_alias_set (fp, setjmp_alias_set);
687       set_mem_alias_set (lab, setjmp_alias_set);
688       set_mem_alias_set (stack, setjmp_alias_set);
689
690       /* Pick up FP, label, and SP from the block and jump.  This code is
691          from expand_goto in stmt.c; see there for detailed comments.  */
692 #if HAVE_nonlocal_goto
693       if (HAVE_nonlocal_goto)
694         /* We have to pass a value to the nonlocal_goto pattern that will
695            get copied into the static_chain pointer, but it does not matter
696            what that value is, because builtin_setjmp does not use it.  */
697         emit_insn (gen_nonlocal_goto (value, lab, stack, fp));
698       else
699 #endif
700         {
701           lab = copy_to_reg (lab);
702
703           emit_move_insn (hard_frame_pointer_rtx, fp);
704           emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
705
706           emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
707           emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
708           emit_indirect_jump (lab);
709         }
710     }
711
712   /* Search backwards and mark the jump insn as a non-local goto.
713      Note that this precludes the use of __builtin_longjmp to a
714      __builtin_setjmp target in the same function.  However, we've
715      already cautioned the user that these functions are for
716      internal exception handling use only.  */
717   for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
718     {
719       if (insn == last)
720         abort ();
721       if (GET_CODE (insn) == JUMP_INSN)
722         {
723           REG_NOTES (insn) = alloc_EXPR_LIST (REG_NON_LOCAL_GOTO, const0_rtx,
724                                               REG_NOTES (insn));
725           break;
726         }
727       else if (GET_CODE (insn) == CALL_INSN)
728         break;
729     }
730 }
731
732 /* Expand a call to __builtin_prefetch.  For a target that does not support
733    data prefetch, evaluate the memory address argument in case it has side
734    effects.  */
735
736 static void
737 expand_builtin_prefetch (arglist)
738      tree arglist;
739 {
740   tree arg0, arg1, arg2;
741   rtx op0, op1, op2;
742
743   if (!validate_arglist (arglist, POINTER_TYPE, 0))
744     return;
745
746   arg0 = TREE_VALUE (arglist);
747   /* Arguments 1 and 2 are optional; argument 1 (read/write) defaults to
748      zero (read) and argument 2 (locality) defaults to 3 (high degree of
749      locality).  */
750   if (TREE_CHAIN (arglist))
751     {
752       arg1 = TREE_VALUE (TREE_CHAIN (arglist));
753       if (TREE_CHAIN (TREE_CHAIN (arglist)))
754         arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
755       else
756         arg2 = build_int_2 (3, 0);
757     }
758   else
759     {
760       arg1 = integer_zero_node;
761       arg2 = build_int_2 (3, 0);
762     }
763
764   /* Argument 0 is an address.  */
765   op0 = expand_expr (arg0, NULL_RTX, Pmode, EXPAND_NORMAL);
766
767   /* Argument 1 (read/write flag) must be a compile-time constant int.  */
768   if (TREE_CODE (arg1) != INTEGER_CST)
769     {
770       error ("second arg to `__builtin_prefetch' must be a constant");
771       arg1 = integer_zero_node;
772     }
773   op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
774   /* Argument 1 must be either zero or one.  */
775   if (INTVAL (op1) != 0 && INTVAL (op1) != 1)
776     {
777       warning ("invalid second arg to __builtin_prefetch; using zero");
778       op1 = const0_rtx;
779     }
780
781   /* Argument 2 (locality) must be a compile-time constant int.  */
782   if (TREE_CODE (arg2) != INTEGER_CST)
783     {
784       error ("third arg to `__builtin_prefetch' must be a constant");
785       arg2 = integer_zero_node;
786     }
787   op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0);
788   /* Argument 2 must be 0, 1, 2, or 3.  */
789   if (INTVAL (op2) < 0 || INTVAL (op2) > 3)
790     {
791       warning ("invalid third arg to __builtin_prefetch; using zero");
792       op2 = const0_rtx;
793     }
794
795 #ifdef HAVE_prefetch
796   if (HAVE_prefetch)
797     {
798       if ((! (*insn_data[(int) CODE_FOR_prefetch].operand[0].predicate)
799              (op0,
800               insn_data[(int) CODE_FOR_prefetch].operand[0].mode))
801           || (GET_MODE(op0) != Pmode))
802         {
803 #ifdef POINTERS_EXTEND_UNSIGNED
804           if (GET_MODE(op0) != Pmode)
805             op0 = convert_memory_address (Pmode, op0);
806 #endif
807           op0 = force_reg (Pmode, op0);
808         }
809       emit_insn (gen_prefetch (op0, op1, op2));
810     }
811   else
812 #endif
813     op0 = protect_from_queue (op0, 0);
814   /* Don't do anything with direct references to volatile memory, but
815      generate code to handle other side effects.  */
816   if (GET_CODE (op0) != MEM && side_effects_p (op0))
817     emit_insn (op0);
818 }
819
820 /* Get a MEM rtx for expression EXP which is the address of an operand
821    to be used to be used in a string instruction (cmpstrsi, movstrsi, ..).  */
822
823 static rtx
824 get_memory_rtx (exp)
825      tree exp;
826 {
827   rtx addr = expand_expr (exp, NULL_RTX, ptr_mode, EXPAND_SUM);
828   rtx mem;
829
830 #ifdef POINTERS_EXTEND_UNSIGNED
831   if (GET_MODE (addr) != Pmode)
832     addr = convert_memory_address (Pmode, addr);
833 #endif
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 offset of register REGNO into the block returned by
883    __builtin_apply_args.  This is not declared static, since it is
884    needed in objc-act.c.  */
885
886 int
887 apply_args_register_offset (regno)
888      int regno;
889 {
890   apply_args_size ();
891
892   /* Arguments are always put in outgoing registers (in the argument
893      block) if such make sense.  */
894 #ifdef OUTGOING_REGNO
895   regno = OUTGOING_REGNO (regno);
896 #endif
897   return apply_args_reg_offset[regno];
898 }
899
900 /* Return the size required for the block returned by __builtin_apply_args,
901    and initialize apply_args_mode.  */
902
903 static int
904 apply_args_size ()
905 {
906   static int size = -1;
907   int align;
908   unsigned int regno;
909   enum machine_mode mode;
910
911   /* The values computed by this function never change.  */
912   if (size < 0)
913     {
914       /* The first value is the incoming arg-pointer.  */
915       size = GET_MODE_SIZE (Pmode);
916
917       /* The second value is the structure value address unless this is
918          passed as an "invisible" first argument.  */
919       if (struct_value_rtx)
920         size += GET_MODE_SIZE (Pmode);
921
922       for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
923         if (FUNCTION_ARG_REGNO_P (regno))
924           {
925             /* Search for the proper mode for copying this register's
926                value.  I'm not sure this is right, but it works so far.  */
927             enum machine_mode best_mode = VOIDmode;
928
929             for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT);
930                  mode != VOIDmode;
931                  mode = GET_MODE_WIDER_MODE (mode))
932               if (HARD_REGNO_MODE_OK (regno, mode)
933                   && HARD_REGNO_NREGS (regno, mode) == 1)
934                 best_mode = mode;
935
936             if (best_mode == VOIDmode)
937               for (mode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT);
938                    mode != VOIDmode;
939                    mode = GET_MODE_WIDER_MODE (mode))
940                 if (HARD_REGNO_MODE_OK (regno, mode)
941                     && have_insn_for (SET, mode))
942                   best_mode = mode;
943
944             if (best_mode == VOIDmode)
945               for (mode = GET_CLASS_NARROWEST_MODE (MODE_VECTOR_FLOAT);
946                    mode != VOIDmode;
947                    mode = GET_MODE_WIDER_MODE (mode))
948                 if (HARD_REGNO_MODE_OK (regno, mode)
949                     && have_insn_for (SET, mode))
950                   best_mode = mode;
951
952             if (best_mode == VOIDmode)
953               for (mode = GET_CLASS_NARROWEST_MODE (MODE_VECTOR_INT);
954                    mode != VOIDmode;
955                    mode = GET_MODE_WIDER_MODE (mode))
956                 if (HARD_REGNO_MODE_OK (regno, mode)
957                     && have_insn_for (SET, mode))
958                   best_mode = mode;
959
960             mode = best_mode;
961             if (mode == VOIDmode)
962               abort ();
963
964             align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
965             if (size % align != 0)
966               size = CEIL (size, align) * align;
967             apply_args_reg_offset[regno] = size;
968             size += GET_MODE_SIZE (mode);
969             apply_args_mode[regno] = mode;
970           }
971         else
972           {
973             apply_args_mode[regno] = VOIDmode;
974             apply_args_reg_offset[regno] = 0;
975           }
976     }
977   return size;
978 }
979
980 /* Return the size required for the block returned by __builtin_apply,
981    and initialize apply_result_mode.  */
982
983 static int
984 apply_result_size ()
985 {
986   static int size = -1;
987   int align, regno;
988   enum machine_mode mode;
989
990   /* The values computed by this function never change.  */
991   if (size < 0)
992     {
993       size = 0;
994
995       for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
996         if (FUNCTION_VALUE_REGNO_P (regno))
997           {
998             /* Search for the proper mode for copying this register's
999                value.  I'm not sure this is right, but it works so far.  */
1000             enum machine_mode best_mode = VOIDmode;
1001
1002             for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT);
1003                  mode != TImode;
1004                  mode = GET_MODE_WIDER_MODE (mode))
1005               if (HARD_REGNO_MODE_OK (regno, mode))
1006                 best_mode = mode;
1007
1008             if (best_mode == VOIDmode)
1009               for (mode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT);
1010                    mode != VOIDmode;
1011                    mode = GET_MODE_WIDER_MODE (mode))
1012                 if (HARD_REGNO_MODE_OK (regno, mode)
1013                     && have_insn_for (SET, mode))
1014                   best_mode = mode;
1015
1016             if (best_mode == VOIDmode)
1017               for (mode = GET_CLASS_NARROWEST_MODE (MODE_VECTOR_FLOAT);
1018                    mode != VOIDmode;
1019                    mode = GET_MODE_WIDER_MODE (mode))
1020                 if (HARD_REGNO_MODE_OK (regno, mode)
1021                     && have_insn_for (SET, mode))
1022                   best_mode = mode;
1023
1024             if (best_mode == VOIDmode)
1025               for (mode = GET_CLASS_NARROWEST_MODE (MODE_VECTOR_INT);
1026                    mode != VOIDmode;
1027                    mode = GET_MODE_WIDER_MODE (mode))
1028                 if (HARD_REGNO_MODE_OK (regno, mode)
1029                     && have_insn_for (SET, mode))
1030                   best_mode = mode;
1031
1032             mode = best_mode;
1033             if (mode == VOIDmode)
1034               abort ();
1035
1036             align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1037             if (size % align != 0)
1038               size = CEIL (size, align) * align;
1039             size += GET_MODE_SIZE (mode);
1040             apply_result_mode[regno] = mode;
1041           }
1042         else
1043           apply_result_mode[regno] = VOIDmode;
1044
1045       /* Allow targets that use untyped_call and untyped_return to override
1046          the size so that machine-specific information can be stored here.  */
1047 #ifdef APPLY_RESULT_SIZE
1048       size = APPLY_RESULT_SIZE;
1049 #endif
1050     }
1051   return size;
1052 }
1053
1054 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
1055 /* Create a vector describing the result block RESULT.  If SAVEP is true,
1056    the result block is used to save the values; otherwise it is used to
1057    restore the values.  */
1058
1059 static rtx
1060 result_vector (savep, result)
1061      int savep;
1062      rtx result;
1063 {
1064   int regno, size, align, nelts;
1065   enum machine_mode mode;
1066   rtx reg, mem;
1067   rtx *savevec = (rtx *) alloca (FIRST_PSEUDO_REGISTER * sizeof (rtx));
1068
1069   size = nelts = 0;
1070   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1071     if ((mode = apply_result_mode[regno]) != VOIDmode)
1072       {
1073         align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1074         if (size % align != 0)
1075           size = CEIL (size, align) * align;
1076         reg = gen_rtx_REG (mode, savep ? regno : INCOMING_REGNO (regno));
1077         mem = adjust_address (result, mode, size);
1078         savevec[nelts++] = (savep
1079                             ? gen_rtx_SET (VOIDmode, mem, reg)
1080                             : gen_rtx_SET (VOIDmode, reg, mem));
1081         size += GET_MODE_SIZE (mode);
1082       }
1083   return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (nelts, savevec));
1084 }
1085 #endif /* HAVE_untyped_call or HAVE_untyped_return */
1086
1087 /* Save the state required to perform an untyped call with the same
1088    arguments as were passed to the current function.  */
1089
1090 static rtx
1091 expand_builtin_apply_args_1 ()
1092 {
1093   rtx registers;
1094   int size, align, regno;
1095   enum machine_mode mode;
1096
1097   /* Create a block where the arg-pointer, structure value address,
1098      and argument registers can be saved.  */
1099   registers = assign_stack_local (BLKmode, apply_args_size (), -1);
1100
1101   /* Walk past the arg-pointer and structure value address.  */
1102   size = GET_MODE_SIZE (Pmode);
1103   if (struct_value_rtx)
1104     size += GET_MODE_SIZE (Pmode);
1105
1106   /* Save each register used in calling a function to the block.  */
1107   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1108     if ((mode = apply_args_mode[regno]) != VOIDmode)
1109       {
1110         rtx tem;
1111
1112         align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1113         if (size % align != 0)
1114           size = CEIL (size, align) * align;
1115
1116         tem = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1117
1118         emit_move_insn (adjust_address (registers, mode, size), tem);
1119         size += GET_MODE_SIZE (mode);
1120       }
1121
1122   /* Save the arg pointer to the block.  */
1123   emit_move_insn (adjust_address (registers, Pmode, 0),
1124                   copy_to_reg (virtual_incoming_args_rtx));
1125   size = GET_MODE_SIZE (Pmode);
1126
1127   /* Save the structure value address unless this is passed as an
1128      "invisible" first argument.  */
1129   if (struct_value_incoming_rtx)
1130     {
1131       emit_move_insn (adjust_address (registers, Pmode, size),
1132                       copy_to_reg (struct_value_incoming_rtx));
1133       size += GET_MODE_SIZE (Pmode);
1134     }
1135
1136   /* Return the address of the block.  */
1137   return copy_addr_to_reg (XEXP (registers, 0));
1138 }
1139
1140 /* __builtin_apply_args returns block of memory allocated on
1141    the stack into which is stored the arg pointer, structure
1142    value address, static chain, and all the registers that might
1143    possibly be used in performing a function call.  The code is
1144    moved to the start of the function so the incoming values are
1145    saved.  */
1146
1147 static rtx
1148 expand_builtin_apply_args ()
1149 {
1150   /* Don't do __builtin_apply_args more than once in a function.
1151      Save the result of the first call and reuse it.  */
1152   if (apply_args_value != 0)
1153     return apply_args_value;
1154   {
1155     /* When this function is called, it means that registers must be
1156        saved on entry to this function.  So we migrate the
1157        call to the first insn of this function.  */
1158     rtx temp;
1159     rtx seq;
1160
1161     start_sequence ();
1162     temp = expand_builtin_apply_args_1 ();
1163     seq = get_insns ();
1164     end_sequence ();
1165
1166     apply_args_value = temp;
1167
1168     /* Put the insns after the NOTE that starts the function.
1169        If this is inside a start_sequence, make the outer-level insn
1170        chain current, so the code is placed at the start of the
1171        function.  */
1172     push_topmost_sequence ();
1173     emit_insn_before (seq, NEXT_INSN (get_insns ()));
1174     pop_topmost_sequence ();
1175     return temp;
1176   }
1177 }
1178
1179 /* Perform an untyped call and save the state required to perform an
1180    untyped return of whatever value was returned by the given function.  */
1181
1182 static rtx
1183 expand_builtin_apply (function, arguments, argsize)
1184      rtx function, arguments, argsize;
1185 {
1186   int size, align, regno;
1187   enum machine_mode mode;
1188   rtx incoming_args, result, reg, dest, src, call_insn;
1189   rtx old_stack_level = 0;
1190   rtx call_fusage = 0;
1191
1192 #ifdef POINTERS_EXTEND_UNSIGNED
1193   if (GET_MODE (arguments) != Pmode)
1194     arguments = convert_memory_address (Pmode, arguments);
1195 #endif
1196
1197   /* Create a block where the return registers can be saved.  */
1198   result = assign_stack_local (BLKmode, apply_result_size (), -1);
1199
1200   /* Fetch the arg pointer from the ARGUMENTS block.  */
1201   incoming_args = gen_reg_rtx (Pmode);
1202   emit_move_insn (incoming_args, gen_rtx_MEM (Pmode, arguments));
1203 #ifndef STACK_GROWS_DOWNWARD
1204   incoming_args = expand_simple_binop (Pmode, MINUS, incoming_args, argsize,
1205                                        incoming_args, 0, OPTAB_LIB_WIDEN);
1206 #endif
1207
1208   /* Perform postincrements before actually calling the function.  */
1209   emit_queue ();
1210
1211   /* Push a new argument block and copy the arguments.  Do not allow
1212      the (potential) memcpy call below to interfere with our stack
1213      manipulations.  */
1214   do_pending_stack_adjust ();
1215   NO_DEFER_POP;
1216
1217   /* Save the stack with nonlocal if available */
1218 #ifdef HAVE_save_stack_nonlocal
1219   if (HAVE_save_stack_nonlocal)
1220     emit_stack_save (SAVE_NONLOCAL, &old_stack_level, NULL_RTX);
1221   else
1222 #endif
1223     emit_stack_save (SAVE_BLOCK, &old_stack_level, NULL_RTX);
1224
1225   /* Push a block of memory onto the stack to store the memory arguments.
1226      Save the address in a register, and copy the memory arguments.  ??? I
1227      haven't figured out how the calling convention macros effect this,
1228      but it's likely that the source and/or destination addresses in
1229      the block copy will need updating in machine specific ways.  */
1230   dest = allocate_dynamic_stack_space (argsize, 0, BITS_PER_UNIT);
1231   dest = gen_rtx_MEM (BLKmode, dest);
1232   set_mem_align (dest, PARM_BOUNDARY);
1233   src = gen_rtx_MEM (BLKmode, incoming_args);
1234   set_mem_align (src, PARM_BOUNDARY);
1235   emit_block_move (dest, src, argsize, BLOCK_OP_NORMAL);
1236
1237   /* Refer to the argument block.  */
1238   apply_args_size ();
1239   arguments = gen_rtx_MEM (BLKmode, arguments);
1240   set_mem_align (arguments, PARM_BOUNDARY);
1241
1242   /* Walk past the arg-pointer and structure value address.  */
1243   size = GET_MODE_SIZE (Pmode);
1244   if (struct_value_rtx)
1245     size += GET_MODE_SIZE (Pmode);
1246
1247   /* Restore each of the registers previously saved.  Make USE insns
1248      for each of these registers for use in making the call.  */
1249   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1250     if ((mode = apply_args_mode[regno]) != VOIDmode)
1251       {
1252         align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1253         if (size % align != 0)
1254           size = CEIL (size, align) * align;
1255         reg = gen_rtx_REG (mode, regno);
1256         emit_move_insn (reg, adjust_address (arguments, mode, size));
1257         use_reg (&call_fusage, reg);
1258         size += GET_MODE_SIZE (mode);
1259       }
1260
1261   /* Restore the structure value address unless this is passed as an
1262      "invisible" first argument.  */
1263   size = GET_MODE_SIZE (Pmode);
1264   if (struct_value_rtx)
1265     {
1266       rtx value = gen_reg_rtx (Pmode);
1267       emit_move_insn (value, adjust_address (arguments, Pmode, size));
1268       emit_move_insn (struct_value_rtx, value);
1269       if (GET_CODE (struct_value_rtx) == REG)
1270         use_reg (&call_fusage, struct_value_rtx);
1271       size += GET_MODE_SIZE (Pmode);
1272     }
1273
1274   /* All arguments and registers used for the call are set up by now!  */
1275   function = prepare_call_address (function, NULL_TREE, &call_fusage, 0, 0);
1276
1277   /* Ensure address is valid.  SYMBOL_REF is already valid, so no need,
1278      and we don't want to load it into a register as an optimization,
1279      because prepare_call_address already did it if it should be done.  */
1280   if (GET_CODE (function) != SYMBOL_REF)
1281     function = memory_address (FUNCTION_MODE, function);
1282
1283   /* Generate the actual call instruction and save the return value.  */
1284 #ifdef HAVE_untyped_call
1285   if (HAVE_untyped_call)
1286     emit_call_insn (gen_untyped_call (gen_rtx_MEM (FUNCTION_MODE, function),
1287                                       result, result_vector (1, result)));
1288   else
1289 #endif
1290 #ifdef HAVE_call_value
1291   if (HAVE_call_value)
1292     {
1293       rtx valreg = 0;
1294
1295       /* Locate the unique return register.  It is not possible to
1296          express a call that sets more than one return register using
1297          call_value; use untyped_call for that.  In fact, untyped_call
1298          only needs to save the return registers in the given block.  */
1299       for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1300         if ((mode = apply_result_mode[regno]) != VOIDmode)
1301           {
1302             if (valreg)
1303               abort (); /* HAVE_untyped_call required.  */
1304             valreg = gen_rtx_REG (mode, regno);
1305           }
1306
1307       emit_call_insn (GEN_CALL_VALUE (valreg,
1308                                       gen_rtx_MEM (FUNCTION_MODE, function),
1309                                       const0_rtx, NULL_RTX, const0_rtx));
1310
1311       emit_move_insn (adjust_address (result, GET_MODE (valreg), 0), valreg);
1312     }
1313   else
1314 #endif
1315     abort ();
1316
1317   /* Find the CALL insn we just emitted.  */
1318   for (call_insn = get_last_insn ();
1319        call_insn && GET_CODE (call_insn) != CALL_INSN;
1320        call_insn = PREV_INSN (call_insn))
1321     ;
1322
1323   if (! call_insn)
1324     abort ();
1325
1326   /* Put the register usage information on the CALL.  If there is already
1327      some usage information, put ours at the end.  */
1328   if (CALL_INSN_FUNCTION_USAGE (call_insn))
1329     {
1330       rtx link;
1331
1332       for (link = CALL_INSN_FUNCTION_USAGE (call_insn); XEXP (link, 1) != 0;
1333            link = XEXP (link, 1))
1334         ;
1335
1336       XEXP (link, 1) = call_fusage;
1337     }
1338   else
1339     CALL_INSN_FUNCTION_USAGE (call_insn) = call_fusage;
1340
1341   /* Restore the stack.  */
1342 #ifdef HAVE_save_stack_nonlocal
1343   if (HAVE_save_stack_nonlocal)
1344     emit_stack_restore (SAVE_NONLOCAL, old_stack_level, NULL_RTX);
1345   else
1346 #endif
1347     emit_stack_restore (SAVE_BLOCK, old_stack_level, NULL_RTX);
1348
1349   OK_DEFER_POP;
1350
1351   /* Return the address of the result block.  */
1352   return copy_addr_to_reg (XEXP (result, 0));
1353 }
1354
1355 /* Perform an untyped return.  */
1356
1357 static void
1358 expand_builtin_return (result)
1359      rtx result;
1360 {
1361   int size, align, regno;
1362   enum machine_mode mode;
1363   rtx reg;
1364   rtx call_fusage = 0;
1365
1366 #ifdef POINTERS_EXTEND_UNSIGNED
1367   if (GET_MODE (result) != Pmode)
1368     result = convert_memory_address (Pmode, result);
1369 #endif
1370
1371   apply_result_size ();
1372   result = gen_rtx_MEM (BLKmode, result);
1373
1374 #ifdef HAVE_untyped_return
1375   if (HAVE_untyped_return)
1376     {
1377       emit_jump_insn (gen_untyped_return (result, result_vector (0, result)));
1378       emit_barrier ();
1379       return;
1380     }
1381 #endif
1382
1383   /* Restore the return value and note that each value is used.  */
1384   size = 0;
1385   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1386     if ((mode = apply_result_mode[regno]) != VOIDmode)
1387       {
1388         align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1389         if (size % align != 0)
1390           size = CEIL (size, align) * align;
1391         reg = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1392         emit_move_insn (reg, adjust_address (result, mode, size));
1393
1394         push_to_sequence (call_fusage);
1395         emit_insn (gen_rtx_USE (VOIDmode, reg));
1396         call_fusage = get_insns ();
1397         end_sequence ();
1398         size += GET_MODE_SIZE (mode);
1399       }
1400
1401   /* Put the USE insns before the return.  */
1402   emit_insn (call_fusage);
1403
1404   /* Return whatever values was restored by jumping directly to the end
1405      of the function.  */
1406   expand_null_return ();
1407 }
1408
1409 /* Used by expand_builtin_classify_type and fold_builtin_classify_type.  */
1410
1411 static enum type_class
1412 type_to_class (type)
1413      tree type;
1414 {
1415   switch (TREE_CODE (type))
1416     {
1417     case VOID_TYPE:        return void_type_class;
1418     case INTEGER_TYPE:     return integer_type_class;
1419     case CHAR_TYPE:        return char_type_class;
1420     case ENUMERAL_TYPE:    return enumeral_type_class;
1421     case BOOLEAN_TYPE:     return boolean_type_class;
1422     case POINTER_TYPE:     return pointer_type_class;
1423     case REFERENCE_TYPE:   return reference_type_class;
1424     case OFFSET_TYPE:      return offset_type_class;
1425     case REAL_TYPE:        return real_type_class;
1426     case COMPLEX_TYPE:     return complex_type_class;
1427     case FUNCTION_TYPE:    return function_type_class;
1428     case METHOD_TYPE:      return method_type_class;
1429     case RECORD_TYPE:      return record_type_class;
1430     case UNION_TYPE:
1431     case QUAL_UNION_TYPE:  return union_type_class;
1432     case ARRAY_TYPE:       return (TYPE_STRING_FLAG (type)
1433                                    ? string_type_class : array_type_class);
1434     case SET_TYPE:         return set_type_class;
1435     case FILE_TYPE:        return file_type_class;
1436     case LANG_TYPE:        return lang_type_class;
1437     default:               return no_type_class;
1438     }
1439 }
1440
1441 /* Expand a call to __builtin_classify_type with arguments found in
1442    ARGLIST.  */
1443
1444 static rtx
1445 expand_builtin_classify_type (arglist)
1446      tree arglist;
1447 {
1448   if (arglist != 0)
1449     return GEN_INT (type_to_class (TREE_TYPE (TREE_VALUE (arglist))));
1450   return GEN_INT (no_type_class);
1451 }
1452
1453 /* Expand expression EXP, which is a call to __builtin_constant_p.  */
1454
1455 static rtx
1456 expand_builtin_constant_p (exp)
1457      tree exp;
1458 {
1459   tree arglist = TREE_OPERAND (exp, 1);
1460   enum machine_mode value_mode = TYPE_MODE (TREE_TYPE (exp));
1461   rtx tmp;
1462
1463   if (arglist == 0)
1464     return const0_rtx;
1465   arglist = TREE_VALUE (arglist);
1466
1467   /* We have taken care of the easy cases during constant folding.  This
1468      case is not obvious, so emit (constant_p_rtx (ARGLIST)) and let CSE
1469      get a chance to see if it can deduce whether ARGLIST is constant.  */
1470
1471   tmp = expand_expr (arglist, NULL_RTX, VOIDmode, 0);
1472   tmp = gen_rtx_CONSTANT_P_RTX (value_mode, tmp);
1473   return tmp;
1474 }
1475
1476 /* Return mathematic function equivalent to FN but operating directly on TYPE,
1477    if available.  */
1478 tree
1479 mathfn_built_in (type, fn)
1480      tree type;
1481      enum built_in_function fn;
1482 {
1483   enum built_in_function fcode = NOT_BUILT_IN;
1484   if (TYPE_MODE (type) == TYPE_MODE (double_type_node))
1485     switch (fn)
1486       {
1487       case BUILT_IN_SQRT:
1488       case BUILT_IN_SQRTF:
1489       case BUILT_IN_SQRTL:
1490         fcode = BUILT_IN_SQRT;
1491         break;
1492       case BUILT_IN_SIN:
1493       case BUILT_IN_SINF:
1494       case BUILT_IN_SINL:
1495         fcode = BUILT_IN_SIN;
1496         break;
1497       case BUILT_IN_COS:
1498       case BUILT_IN_COSF:
1499       case BUILT_IN_COSL:
1500         fcode = BUILT_IN_COS;
1501         break;
1502       case BUILT_IN_EXP:
1503       case BUILT_IN_EXPF:
1504       case BUILT_IN_EXPL:
1505         fcode = BUILT_IN_EXP;
1506         break;
1507       case BUILT_IN_FLOOR:
1508       case BUILT_IN_FLOORF:
1509       case BUILT_IN_FLOORL:
1510         fcode = BUILT_IN_FLOOR;
1511         break;
1512       case BUILT_IN_CEIL:
1513       case BUILT_IN_CEILF:
1514       case BUILT_IN_CEILL:
1515         fcode = BUILT_IN_CEIL;
1516         break;
1517       case BUILT_IN_TRUNC:
1518       case BUILT_IN_TRUNCF:
1519       case BUILT_IN_TRUNCL:
1520         fcode = BUILT_IN_TRUNC;
1521         break;
1522       case BUILT_IN_ROUND:
1523       case BUILT_IN_ROUNDF:
1524       case BUILT_IN_ROUNDL:
1525         fcode = BUILT_IN_ROUND;
1526         break;
1527       case BUILT_IN_NEARBYINT:
1528       case BUILT_IN_NEARBYINTF:
1529       case BUILT_IN_NEARBYINTL:
1530         fcode = BUILT_IN_NEARBYINT;
1531         break;
1532       default:
1533         abort ();
1534       }
1535   else if (TYPE_MODE (type) == TYPE_MODE (float_type_node))
1536     switch (fn)
1537       {
1538       case BUILT_IN_SQRT:
1539       case BUILT_IN_SQRTF:
1540       case BUILT_IN_SQRTL:
1541         fcode = BUILT_IN_SQRTF;
1542         break;
1543       case BUILT_IN_SIN:
1544       case BUILT_IN_SINF:
1545       case BUILT_IN_SINL:
1546         fcode = BUILT_IN_SINF;
1547         break;
1548       case BUILT_IN_COS:
1549       case BUILT_IN_COSF:
1550       case BUILT_IN_COSL:
1551         fcode = BUILT_IN_COSF;
1552         break;
1553       case BUILT_IN_EXP:
1554       case BUILT_IN_EXPF:
1555       case BUILT_IN_EXPL:
1556         fcode = BUILT_IN_EXPF;
1557         break;
1558       case BUILT_IN_FLOOR:
1559       case BUILT_IN_FLOORF:
1560       case BUILT_IN_FLOORL:
1561         fcode = BUILT_IN_FLOORF;
1562         break;
1563       case BUILT_IN_CEIL:
1564       case BUILT_IN_CEILF:
1565       case BUILT_IN_CEILL:
1566         fcode = BUILT_IN_CEILF;
1567         break;
1568       case BUILT_IN_TRUNC:
1569       case BUILT_IN_TRUNCF:
1570       case BUILT_IN_TRUNCL:
1571         fcode = BUILT_IN_TRUNCF;
1572         break;
1573       case BUILT_IN_ROUND:
1574       case BUILT_IN_ROUNDF:
1575       case BUILT_IN_ROUNDL:
1576         fcode = BUILT_IN_ROUNDF;
1577         break;
1578       case BUILT_IN_NEARBYINT:
1579       case BUILT_IN_NEARBYINTF:
1580       case BUILT_IN_NEARBYINTL:
1581         fcode = BUILT_IN_NEARBYINTF;
1582         break;
1583       default:
1584         abort ();
1585       }
1586   else if (TYPE_MODE (type) == TYPE_MODE (long_double_type_node))
1587     switch (fn)
1588       {
1589       case BUILT_IN_SQRT:
1590       case BUILT_IN_SQRTF:
1591       case BUILT_IN_SQRTL:
1592         fcode = BUILT_IN_SQRTL;
1593         break;
1594       case BUILT_IN_SIN:
1595       case BUILT_IN_SINF:
1596       case BUILT_IN_SINL:
1597         fcode = BUILT_IN_SINL;
1598         break;
1599       case BUILT_IN_COS:
1600       case BUILT_IN_COSF:
1601       case BUILT_IN_COSL:
1602         fcode = BUILT_IN_COSL;
1603         break;
1604       case BUILT_IN_EXP:
1605       case BUILT_IN_EXPF:
1606       case BUILT_IN_EXPL:
1607         fcode = BUILT_IN_EXPL;
1608         break;
1609       case BUILT_IN_FLOOR:
1610       case BUILT_IN_FLOORF:
1611       case BUILT_IN_FLOORL:
1612         fcode = BUILT_IN_FLOORL;
1613         break;
1614       case BUILT_IN_CEIL:
1615       case BUILT_IN_CEILF:
1616       case BUILT_IN_CEILL:
1617         fcode = BUILT_IN_CEILL;
1618         break;
1619       case BUILT_IN_TRUNC:
1620       case BUILT_IN_TRUNCF:
1621       case BUILT_IN_TRUNCL:
1622         fcode = BUILT_IN_TRUNCL;
1623         break;
1624       case BUILT_IN_ROUND:
1625       case BUILT_IN_ROUNDF:
1626       case BUILT_IN_ROUNDL:
1627         fcode = BUILT_IN_ROUNDL;
1628         break;
1629       case BUILT_IN_NEARBYINT:
1630       case BUILT_IN_NEARBYINTF:
1631       case BUILT_IN_NEARBYINTL:
1632         fcode = BUILT_IN_NEARBYINTL;
1633         break;
1634       default:
1635         abort ();
1636       }
1637   return implicit_built_in_decls[fcode];
1638 }
1639
1640 /* Expand a call to one of the builtin math functions (sin, cos, or sqrt).
1641    Return 0 if a normal call should be emitted rather than expanding the
1642    function in-line.  EXP is the expression that is a call to the builtin
1643    function; if convenient, the result should be placed in TARGET.
1644    SUBTARGET may be used as the target for computing one of EXP's operands.  */
1645
1646 static rtx
1647 expand_builtin_mathfn (exp, target, subtarget)
1648      tree exp;
1649      rtx target, subtarget;
1650 {
1651   optab builtin_optab;
1652   rtx op0, insns;
1653   tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
1654   tree arglist = TREE_OPERAND (exp, 1);
1655   enum machine_mode argmode;
1656   bool errno_set = true;
1657
1658   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
1659     return 0;
1660
1661   /* Stabilize and compute the argument.  */
1662   if (TREE_CODE (TREE_VALUE (arglist)) != VAR_DECL
1663       && TREE_CODE (TREE_VALUE (arglist)) != PARM_DECL)
1664     {
1665       exp = copy_node (exp);
1666       TREE_OPERAND (exp, 1) = arglist;
1667       /* Wrap the computation of the argument in a SAVE_EXPR.  That
1668          way, if we need to expand the argument again (as in the
1669          flag_errno_math case below where we cannot directly set
1670          errno), we will not perform side-effects more than once.
1671          Note that here we're mutating the original EXP as well as the
1672          copy; that's the right thing to do in case the original EXP
1673          is expanded later.  */
1674       TREE_VALUE (arglist) = save_expr (TREE_VALUE (arglist));
1675       arglist = copy_node (arglist);
1676     }
1677   op0 = expand_expr (TREE_VALUE (arglist), subtarget, VOIDmode, 0);
1678
1679   /* Make a suitable register to place result in.  */
1680   target = gen_reg_rtx (TYPE_MODE (TREE_TYPE (exp)));
1681
1682   emit_queue ();
1683   start_sequence ();
1684
1685   switch (DECL_FUNCTION_CODE (fndecl))
1686     {
1687     case BUILT_IN_SIN:
1688     case BUILT_IN_SINF:
1689     case BUILT_IN_SINL:
1690       builtin_optab = sin_optab; break;
1691     case BUILT_IN_COS:
1692     case BUILT_IN_COSF:
1693     case BUILT_IN_COSL:
1694       builtin_optab = cos_optab; break;
1695     case BUILT_IN_SQRT:
1696     case BUILT_IN_SQRTF:
1697     case BUILT_IN_SQRTL:
1698       builtin_optab = sqrt_optab; break;
1699     case BUILT_IN_EXP:
1700     case BUILT_IN_EXPF:
1701     case BUILT_IN_EXPL:
1702       builtin_optab = exp_optab; break;
1703     case BUILT_IN_LOG:
1704     case BUILT_IN_LOGF:
1705     case BUILT_IN_LOGL:
1706       builtin_optab = log_optab; break;
1707     case BUILT_IN_FLOOR:
1708     case BUILT_IN_FLOORF:
1709     case BUILT_IN_FLOORL:
1710       errno_set = false ; builtin_optab = floor_optab; break;
1711     case BUILT_IN_CEIL:
1712     case BUILT_IN_CEILF:
1713     case BUILT_IN_CEILL:
1714       errno_set = false ; builtin_optab = ceil_optab; break;
1715     case BUILT_IN_TRUNC:
1716     case BUILT_IN_TRUNCF:
1717     case BUILT_IN_TRUNCL:
1718       errno_set = false ; builtin_optab = trunc_optab; break;
1719     case BUILT_IN_ROUND:
1720     case BUILT_IN_ROUNDF:
1721     case BUILT_IN_ROUNDL:
1722       errno_set = false ; builtin_optab = round_optab; break;
1723     case BUILT_IN_NEARBYINT:
1724     case BUILT_IN_NEARBYINTF:
1725     case BUILT_IN_NEARBYINTL:
1726       errno_set = false ; builtin_optab = nearbyint_optab; break;
1727     default:
1728       abort ();
1729     }
1730
1731   /* Compute into TARGET.
1732      Set TARGET to wherever the result comes back.  */
1733   argmode = TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist)));
1734   target = expand_unop (argmode, builtin_optab, op0, target, 0);
1735
1736   /* If we were unable to expand via the builtin, stop the
1737      sequence (without outputting the insns) and return 0, causing
1738      a call to the library function.  */
1739   if (target == 0)
1740     {
1741       end_sequence ();
1742       return 0;
1743     }
1744
1745   /* If errno must be maintained, we must set it to EDOM for NaN results.  */
1746
1747   if (flag_errno_math && errno_set && HONOR_NANS (argmode))
1748     {
1749       rtx lab1;
1750
1751       lab1 = gen_label_rtx ();
1752
1753       /* Test the result; if it is NaN, set errno=EDOM because
1754          the argument was not in the domain.  */
1755       emit_cmp_and_jump_insns (target, target, EQ, 0, GET_MODE (target),
1756                                0, lab1);
1757
1758 #ifdef TARGET_EDOM
1759       {
1760 #ifdef GEN_ERRNO_RTX
1761         rtx errno_rtx = GEN_ERRNO_RTX;
1762 #else
1763         rtx errno_rtx
1764           = gen_rtx_MEM (word_mode, gen_rtx_SYMBOL_REF (Pmode, "errno"));
1765 #endif
1766
1767         emit_move_insn (errno_rtx, GEN_INT (TARGET_EDOM));
1768       }
1769 #else
1770       /* We can't set errno=EDOM directly; let the library call do it.
1771          Pop the arguments right away in case the call gets deleted.  */
1772       NO_DEFER_POP;
1773       expand_call (exp, target, 0);
1774       OK_DEFER_POP;
1775 #endif
1776
1777       emit_label (lab1);
1778     }
1779
1780   /* Output the entire sequence.  */
1781   insns = get_insns ();
1782   end_sequence ();
1783   emit_insn (insns);
1784
1785   return target;
1786 }
1787
1788 /* Expand expression EXP which is a call to the strlen builtin.  Return 0
1789    if we failed the caller should emit a normal call, otherwise
1790    try to get the result in TARGET, if convenient.  */
1791
1792 static rtx
1793 expand_builtin_strlen (exp, target)
1794      tree exp;
1795      rtx target;
1796 {
1797   tree arglist = TREE_OPERAND (exp, 1);
1798   enum machine_mode value_mode = TYPE_MODE (TREE_TYPE (exp));
1799
1800   if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
1801     return 0;
1802   else
1803     {
1804       rtx pat;
1805       tree src = TREE_VALUE (arglist);
1806
1807       int align
1808         = get_pointer_alignment (src, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
1809
1810       rtx result, src_reg, char_rtx, before_strlen;
1811       enum machine_mode insn_mode = value_mode, char_mode;
1812       enum insn_code icode = CODE_FOR_nothing;
1813
1814       /* If SRC is not a pointer type, don't do this operation inline.  */
1815       if (align == 0)
1816         return 0;
1817
1818       /* Bail out if we can't compute strlen in the right mode.  */
1819       while (insn_mode != VOIDmode)
1820         {
1821           icode = strlen_optab->handlers[(int) insn_mode].insn_code;
1822           if (icode != CODE_FOR_nothing)
1823             break;
1824
1825           insn_mode = GET_MODE_WIDER_MODE (insn_mode);
1826         }
1827       if (insn_mode == VOIDmode)
1828         return 0;
1829
1830       /* Make a place to write the result of the instruction.  */
1831       result = target;
1832       if (! (result != 0
1833              && GET_CODE (result) == REG
1834              && GET_MODE (result) == insn_mode
1835              && REGNO (result) >= FIRST_PSEUDO_REGISTER))
1836         result = gen_reg_rtx (insn_mode);
1837
1838       /* Make a place to hold the source address.  We will not expand
1839          the actual source until we are sure that the expansion will
1840          not fail -- there are trees that cannot be expanded twice.  */
1841       src_reg = gen_reg_rtx (Pmode);
1842
1843       /* Mark the beginning of the strlen sequence so we can emit the
1844          source operand later.  */
1845       before_strlen = get_last_insn ();
1846
1847       char_rtx = const0_rtx;
1848       char_mode = insn_data[(int) icode].operand[2].mode;
1849       if (! (*insn_data[(int) icode].operand[2].predicate) (char_rtx,
1850                                                             char_mode))
1851         char_rtx = copy_to_mode_reg (char_mode, char_rtx);
1852
1853       pat = GEN_FCN (icode) (result, gen_rtx_MEM (BLKmode, src_reg),
1854                              char_rtx, GEN_INT (align));
1855       if (! pat)
1856         return 0;
1857       emit_insn (pat);
1858
1859       /* Now that we are assured of success, expand the source.  */
1860       start_sequence ();
1861       pat = memory_address (BLKmode,
1862                             expand_expr (src, src_reg, ptr_mode, EXPAND_SUM));
1863       if (pat != src_reg)
1864         emit_move_insn (src_reg, pat);
1865       pat = get_insns ();
1866       end_sequence ();
1867
1868       if (before_strlen)
1869         emit_insn_after (pat, before_strlen);
1870       else
1871         emit_insn_before (pat, get_insns ());
1872
1873       /* Return the value in the proper mode for this function.  */
1874       if (GET_MODE (result) == value_mode)
1875         target = result;
1876       else if (target != 0)
1877         convert_move (target, result, 0);
1878       else
1879         target = convert_to_mode (value_mode, result, 0);
1880
1881       return target;
1882     }
1883 }
1884
1885 /* Expand a call to the strstr builtin.  Return 0 if we failed the
1886    caller should emit a normal call, otherwise try to get the result
1887    in TARGET, if convenient (and in mode MODE if that's convenient).  */
1888
1889 static rtx
1890 expand_builtin_strstr (arglist, target, mode)
1891      tree arglist;
1892      rtx target;
1893      enum machine_mode mode;
1894 {
1895   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
1896     return 0;
1897   else
1898     {
1899       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
1900       tree fn;
1901       const char *p1, *p2;
1902
1903       p2 = c_getstr (s2);
1904       if (p2 == NULL)
1905         return 0;
1906
1907       p1 = c_getstr (s1);
1908       if (p1 != NULL)
1909         {
1910           const char *r = strstr (p1, p2);
1911
1912           if (r == NULL)
1913             return const0_rtx;
1914
1915           /* Return an offset into the constant string argument.  */
1916           return expand_expr (fold (build (PLUS_EXPR, TREE_TYPE (s1),
1917                                            s1, ssize_int (r - p1))),
1918                               target, mode, EXPAND_NORMAL);
1919         }
1920
1921       if (p2[0] == '\0')
1922         return expand_expr (s1, target, mode, EXPAND_NORMAL);
1923
1924       if (p2[1] != '\0')
1925         return 0;
1926
1927       fn = implicit_built_in_decls[BUILT_IN_STRCHR];
1928       if (!fn)
1929         return 0;
1930
1931       /* New argument list transforming strstr(s1, s2) to
1932          strchr(s1, s2[0]).  */
1933       arglist =
1934         build_tree_list (NULL_TREE, build_int_2 (p2[0], 0));
1935       arglist = tree_cons (NULL_TREE, s1, arglist);
1936       return expand_expr (build_function_call_expr (fn, arglist),
1937                           target, mode, EXPAND_NORMAL);
1938     }
1939 }
1940
1941 /* Expand a call to the strchr builtin.  Return 0 if we failed the
1942    caller should emit a normal call, otherwise try to get the result
1943    in TARGET, if convenient (and in mode MODE if that's convenient).  */
1944
1945 static rtx
1946 expand_builtin_strchr (arglist, target, mode)
1947      tree arglist;
1948      rtx target;
1949      enum machine_mode mode;
1950 {
1951   if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
1952     return 0;
1953   else
1954     {
1955       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
1956       const char *p1;
1957
1958       if (TREE_CODE (s2) != INTEGER_CST)
1959         return 0;
1960
1961       p1 = c_getstr (s1);
1962       if (p1 != NULL)
1963         {
1964           char c;
1965           const char *r;
1966
1967           if (target_char_cast (s2, &c))
1968             return 0;
1969
1970           r = strchr (p1, c);
1971
1972           if (r == NULL)
1973             return const0_rtx;
1974
1975           /* Return an offset into the constant string argument.  */
1976           return expand_expr (fold (build (PLUS_EXPR, TREE_TYPE (s1),
1977                                            s1, ssize_int (r - p1))),
1978                               target, mode, EXPAND_NORMAL);
1979         }
1980
1981       /* FIXME: Should use here strchrM optab so that ports can optimize
1982          this.  */
1983       return 0;
1984     }
1985 }
1986
1987 /* Expand a call to the strrchr builtin.  Return 0 if we failed the
1988    caller should emit a normal call, otherwise try to get the result
1989    in TARGET, if convenient (and in mode MODE if that's convenient).  */
1990
1991 static rtx
1992 expand_builtin_strrchr (arglist, target, mode)
1993      tree arglist;
1994      rtx target;
1995      enum machine_mode mode;
1996 {
1997   if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
1998     return 0;
1999   else
2000     {
2001       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
2002       tree fn;
2003       const char *p1;
2004
2005       if (TREE_CODE (s2) != INTEGER_CST)
2006         return 0;
2007
2008       p1 = c_getstr (s1);
2009       if (p1 != NULL)
2010         {
2011           char c;
2012           const char *r;
2013
2014           if (target_char_cast (s2, &c))
2015             return 0;
2016
2017           r = strrchr (p1, c);
2018
2019           if (r == NULL)
2020             return const0_rtx;
2021
2022           /* Return an offset into the constant string argument.  */
2023           return expand_expr (fold (build (PLUS_EXPR, TREE_TYPE (s1),
2024                                            s1, ssize_int (r - p1))),
2025                               target, mode, EXPAND_NORMAL);
2026         }
2027
2028       if (! integer_zerop (s2))
2029         return 0;
2030
2031       fn = implicit_built_in_decls[BUILT_IN_STRCHR];
2032       if (!fn)
2033         return 0;
2034
2035       /* Transform strrchr(s1, '\0') to strchr(s1, '\0').  */
2036       return expand_expr (build_function_call_expr (fn, arglist),
2037                           target, mode, EXPAND_NORMAL);
2038     }
2039 }
2040
2041 /* Expand a call to the strpbrk builtin.  Return 0 if we failed the
2042    caller should emit a normal call, otherwise try to get the result
2043    in TARGET, if convenient (and in mode MODE if that's convenient).  */
2044
2045 static rtx
2046 expand_builtin_strpbrk (arglist, target, mode)
2047      tree arglist;
2048      rtx target;
2049      enum machine_mode mode;
2050 {
2051   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2052     return 0;
2053   else
2054     {
2055       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
2056       tree fn;
2057       const char *p1, *p2;
2058
2059       p2 = c_getstr (s2);
2060       if (p2 == NULL)
2061         return 0;
2062
2063       p1 = c_getstr (s1);
2064       if (p1 != NULL)
2065         {
2066           const char *r = strpbrk (p1, p2);
2067
2068           if (r == NULL)
2069             return const0_rtx;
2070
2071           /* Return an offset into the constant string argument.  */
2072           return expand_expr (fold (build (PLUS_EXPR, TREE_TYPE (s1),
2073                                            s1, ssize_int (r - p1))),
2074                               target, mode, EXPAND_NORMAL);
2075         }
2076
2077       if (p2[0] == '\0')
2078         {
2079           /* strpbrk(x, "") == NULL.
2080              Evaluate and ignore the arguments in case they had
2081              side-effects.  */
2082           expand_expr (s1, const0_rtx, VOIDmode, EXPAND_NORMAL);
2083           return const0_rtx;
2084         }
2085
2086       if (p2[1] != '\0')
2087         return 0;  /* Really call strpbrk.  */
2088
2089       fn = implicit_built_in_decls[BUILT_IN_STRCHR];
2090       if (!fn)
2091         return 0;
2092
2093       /* New argument list transforming strpbrk(s1, s2) to
2094          strchr(s1, s2[0]).  */
2095       arglist =
2096         build_tree_list (NULL_TREE, build_int_2 (p2[0], 0));
2097       arglist = tree_cons (NULL_TREE, s1, arglist);
2098       return expand_expr (build_function_call_expr (fn, arglist),
2099                           target, mode, EXPAND_NORMAL);
2100     }
2101 }
2102
2103 /* Callback routine for store_by_pieces.  Read GET_MODE_BITSIZE (MODE)
2104    bytes from constant string DATA + OFFSET and return it as target
2105    constant.  */
2106
2107 static rtx
2108 builtin_memcpy_read_str (data, offset, mode)
2109      PTR data;
2110      HOST_WIDE_INT offset;
2111      enum machine_mode mode;
2112 {
2113   const char *str = (const char *) data;
2114
2115   if (offset < 0
2116       || ((unsigned HOST_WIDE_INT) offset + GET_MODE_SIZE (mode)
2117           > strlen (str) + 1))
2118     abort ();  /* Attempt to read past the end of constant string.  */
2119
2120   return c_readstr (str + offset, mode);
2121 }
2122
2123 /* Expand a call to the memcpy builtin, with arguments in ARGLIST.
2124    Return 0 if we failed, the caller should emit a normal call, otherwise
2125    try to get the result in TARGET, if convenient (and in mode MODE if
2126    that's convenient).  */
2127
2128 static rtx
2129 expand_builtin_memcpy (arglist, target, mode)
2130      tree arglist;
2131      rtx target;
2132      enum machine_mode mode;
2133 {
2134   if (!validate_arglist (arglist,
2135                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2136     return 0;
2137   else
2138     {
2139       tree dest = TREE_VALUE (arglist);
2140       tree src = TREE_VALUE (TREE_CHAIN (arglist));
2141       tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2142       const char *src_str;
2143
2144       unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
2145       unsigned int dest_align
2146         = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2147       rtx dest_mem, src_mem, dest_addr, len_rtx;
2148
2149       /* If DEST is not a pointer type, call the normal function.  */
2150       if (dest_align == 0)
2151         return 0;
2152
2153       /* If the LEN parameter is zero, return DEST.  */
2154       if (host_integerp (len, 1) && tree_low_cst (len, 1) == 0)
2155         {
2156           /* Evaluate and ignore SRC in case it has side-effects.  */
2157           expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
2158           return expand_expr (dest, target, mode, EXPAND_NORMAL);
2159         }
2160
2161       /* If either SRC is not a pointer type, don't do this
2162          operation in-line.  */
2163       if (src_align == 0)
2164         return 0;
2165
2166       dest_mem = get_memory_rtx (dest);
2167       set_mem_align (dest_mem, dest_align);
2168       len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
2169       src_str = c_getstr (src);
2170
2171       /* If SRC is a string constant and block move would be done
2172          by pieces, we can avoid loading the string from memory
2173          and only stored the computed constants.  */
2174       if (src_str
2175           && GET_CODE (len_rtx) == CONST_INT
2176           && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
2177           && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
2178                                   (PTR) src_str, dest_align))
2179         {
2180           store_by_pieces (dest_mem, INTVAL (len_rtx),
2181                            builtin_memcpy_read_str,
2182                            (PTR) src_str, dest_align);
2183           dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2184 #ifdef POINTERS_EXTEND_UNSIGNED
2185           if (GET_MODE (dest_mem) != ptr_mode)
2186             dest_mem = convert_memory_address (ptr_mode, dest_mem);
2187 #endif
2188           return dest_mem;
2189         }
2190
2191       src_mem = get_memory_rtx (src);
2192       set_mem_align (src_mem, src_align);
2193
2194       /* Copy word part most expediently.  */
2195       dest_addr = emit_block_move (dest_mem, src_mem, len_rtx,
2196                                    BLOCK_OP_NORMAL);
2197
2198       if (dest_addr == 0)
2199         {
2200           dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2201 #ifdef POINTERS_EXTEND_UNSIGNED
2202           if (GET_MODE (dest_addr) != ptr_mode)
2203             dest_addr = convert_memory_address (ptr_mode, dest_addr);
2204 #endif
2205         }
2206
2207       return dest_addr;
2208     }
2209 }
2210
2211 /* Expand expression EXP, which is a call to the strcpy builtin.  Return 0
2212    if we failed the caller should emit a normal call, otherwise try to get
2213    the result in TARGET, if convenient (and in mode MODE if that's
2214    convenient).  */
2215
2216 static rtx
2217 expand_builtin_strcpy (exp, target, mode)
2218      tree exp;
2219      rtx target;
2220      enum machine_mode mode;
2221 {
2222   tree arglist = TREE_OPERAND (exp, 1);
2223   tree fn, len;
2224
2225   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2226     return 0;
2227
2228   fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
2229   if (!fn)
2230     return 0;
2231
2232   len = c_strlen (TREE_VALUE (TREE_CHAIN (arglist)));
2233   if (len == 0)
2234     return 0;
2235
2236   len = size_binop (PLUS_EXPR, len, ssize_int (1));
2237   chainon (arglist, build_tree_list (NULL_TREE, len));
2238   return expand_expr (build_function_call_expr (fn, arglist),
2239                       target, mode, EXPAND_NORMAL);
2240 }
2241
2242 /* Callback routine for store_by_pieces.  Read GET_MODE_BITSIZE (MODE)
2243    bytes from constant string DATA + OFFSET and return it as target
2244    constant.  */
2245
2246 static rtx
2247 builtin_strncpy_read_str (data, offset, mode)
2248      PTR data;
2249      HOST_WIDE_INT offset;
2250      enum machine_mode mode;
2251 {
2252   const char *str = (const char *) data;
2253
2254   if ((unsigned HOST_WIDE_INT) offset > strlen (str))
2255     return const0_rtx;
2256
2257   return c_readstr (str + offset, mode);
2258 }
2259
2260 /* Expand expression EXP, which is a call to the strncpy builtin.  Return 0
2261    if we failed the caller should emit a normal call.  */
2262
2263 static rtx
2264 expand_builtin_strncpy (arglist, target, mode)
2265      tree arglist;
2266      rtx target;
2267      enum machine_mode mode;
2268 {
2269   if (!validate_arglist (arglist,
2270                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2271     return 0;
2272   else
2273     {
2274       tree slen = c_strlen (TREE_VALUE (TREE_CHAIN (arglist)));
2275       tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2276       tree fn;
2277
2278       /* We must be passed a constant len parameter.  */
2279       if (TREE_CODE (len) != INTEGER_CST)
2280         return 0;
2281
2282       /* If the len parameter is zero, return the dst parameter.  */
2283       if (integer_zerop (len))
2284         {
2285           /* Evaluate and ignore the src argument in case it has
2286              side-effects.  */
2287           expand_expr (TREE_VALUE (TREE_CHAIN (arglist)), const0_rtx,
2288                        VOIDmode, EXPAND_NORMAL);
2289           /* Return the dst parameter.  */
2290           return expand_expr (TREE_VALUE (arglist), target, mode,
2291                               EXPAND_NORMAL);
2292         }
2293
2294       /* Now, we must be passed a constant src ptr parameter.  */
2295       if (slen == 0 || TREE_CODE (slen) != INTEGER_CST)
2296         return 0;
2297
2298       slen = size_binop (PLUS_EXPR, slen, ssize_int (1));
2299
2300       /* We're required to pad with trailing zeros if the requested
2301          len is greater than strlen(s2)+1.  In that case try to
2302          use store_by_pieces, if it fails, punt.  */
2303       if (tree_int_cst_lt (slen, len))
2304         {
2305           tree dest = TREE_VALUE (arglist);
2306           unsigned int dest_align
2307             = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2308           const char *p = c_getstr (TREE_VALUE (TREE_CHAIN (arglist)));
2309           rtx dest_mem;
2310
2311           if (!p || dest_align == 0 || !host_integerp (len, 1)
2312               || !can_store_by_pieces (tree_low_cst (len, 1),
2313                                        builtin_strncpy_read_str,
2314                                        (PTR) p, dest_align))
2315             return 0;
2316
2317           dest_mem = get_memory_rtx (dest);
2318           store_by_pieces (dest_mem, tree_low_cst (len, 1),
2319                            builtin_strncpy_read_str,
2320                            (PTR) p, dest_align);
2321           dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2322 #ifdef POINTERS_EXTEND_UNSIGNED
2323           if (GET_MODE (dest_mem) != ptr_mode)
2324             dest_mem = convert_memory_address (ptr_mode, dest_mem);
2325 #endif
2326           return dest_mem;
2327         }
2328
2329       /* OK transform into builtin memcpy.  */
2330       fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
2331       if (!fn)
2332         return 0;
2333       return expand_expr (build_function_call_expr (fn, arglist),
2334                           target, mode, EXPAND_NORMAL);
2335     }
2336 }
2337
2338 /* Callback routine for store_by_pieces.  Read GET_MODE_BITSIZE (MODE)
2339    bytes from constant string DATA + OFFSET and return it as target
2340    constant.  */
2341
2342 static rtx
2343 builtin_memset_read_str (data, offset, mode)
2344      PTR data;
2345      HOST_WIDE_INT offset ATTRIBUTE_UNUSED;
2346      enum machine_mode mode;
2347 {
2348   const char *c = (const char *) data;
2349   char *p = alloca (GET_MODE_SIZE (mode));
2350
2351   memset (p, *c, GET_MODE_SIZE (mode));
2352
2353   return c_readstr (p, mode);
2354 }
2355
2356 /* Callback routine for store_by_pieces.  Return the RTL of a register
2357    containing GET_MODE_SIZE (MODE) consecutive copies of the unsigned
2358    char value given in the RTL register data.  For example, if mode is
2359    4 bytes wide, return the RTL for 0x01010101*data.  */
2360
2361 static rtx
2362 builtin_memset_gen_str (data, offset, mode)
2363      PTR data;
2364      HOST_WIDE_INT offset ATTRIBUTE_UNUSED;
2365      enum machine_mode mode;
2366 {
2367   rtx target, coeff;
2368   size_t size;
2369   char *p;
2370
2371   size = GET_MODE_SIZE (mode);
2372   if (size == 1)
2373     return (rtx) data;
2374
2375   p = alloca (size);
2376   memset (p, 1, size);
2377   coeff = c_readstr (p, mode);
2378
2379   target = convert_to_mode (mode, (rtx) data, 1);
2380   target = expand_mult (mode, target, coeff, NULL_RTX, 1);
2381   return force_reg (mode, target);
2382 }
2383
2384 /* Expand expression EXP, which is a call to the memset builtin.  Return 0
2385    if we failed the caller should emit a normal call, otherwise try to get
2386    the result in TARGET, if convenient (and in mode MODE if that's
2387    convenient).  */
2388
2389 static rtx
2390 expand_builtin_memset (exp, target, mode)
2391      tree exp;
2392      rtx target;
2393      enum machine_mode mode;
2394 {
2395   tree arglist = TREE_OPERAND (exp, 1);
2396
2397   if (!validate_arglist (arglist,
2398                          POINTER_TYPE, INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
2399     return 0;
2400   else
2401     {
2402       tree dest = TREE_VALUE (arglist);
2403       tree val = TREE_VALUE (TREE_CHAIN (arglist));
2404       tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2405       char c;
2406
2407       unsigned int dest_align
2408         = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2409       rtx dest_mem, dest_addr, len_rtx;
2410
2411       /* If DEST is not a pointer type, don't do this
2412          operation in-line.  */
2413       if (dest_align == 0)
2414         return 0;
2415
2416       /* If the LEN parameter is zero, return DEST.  */
2417       if (host_integerp (len, 1) && tree_low_cst (len, 1) == 0)
2418         {
2419           /* Evaluate and ignore VAL in case it has side-effects.  */
2420           expand_expr (val, const0_rtx, VOIDmode, EXPAND_NORMAL);
2421           return expand_expr (dest, target, mode, EXPAND_NORMAL);
2422         }
2423
2424       if (TREE_CODE (val) != INTEGER_CST)
2425         {
2426           rtx val_rtx;
2427
2428           if (!host_integerp (len, 1))
2429             return 0;
2430
2431           if (optimize_size && tree_low_cst (len, 1) > 1)
2432             return 0;
2433
2434           /* Assume that we can memset by pieces if we can store the
2435            * the coefficients by pieces (in the required modes).
2436            * We can't pass builtin_memset_gen_str as that emits RTL.  */
2437           c = 1;
2438           if (!can_store_by_pieces (tree_low_cst (len, 1),
2439                                     builtin_memset_read_str,
2440                                     (PTR) &c, dest_align))
2441             return 0;
2442
2443           val = fold (build1 (CONVERT_EXPR, unsigned_char_type_node, val));
2444           val_rtx = expand_expr (val, NULL_RTX, VOIDmode, 0);
2445           val_rtx = force_reg (TYPE_MODE (unsigned_char_type_node),
2446                                val_rtx);
2447           dest_mem = get_memory_rtx (dest);
2448           store_by_pieces (dest_mem, tree_low_cst (len, 1),
2449                            builtin_memset_gen_str,
2450                            (PTR) val_rtx, dest_align);
2451           dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2452 #ifdef POINTERS_EXTEND_UNSIGNED
2453           if (GET_MODE (dest_mem) != ptr_mode)
2454             dest_mem = convert_memory_address (ptr_mode, dest_mem);
2455 #endif
2456           return dest_mem;
2457         }
2458
2459       if (target_char_cast (val, &c))
2460         return 0;
2461
2462       if (c)
2463         {
2464           if (!host_integerp (len, 1))
2465             return 0;
2466           if (!can_store_by_pieces (tree_low_cst (len, 1),
2467                                     builtin_memset_read_str, (PTR) &c,
2468                                     dest_align))
2469             return 0;
2470
2471           dest_mem = get_memory_rtx (dest);
2472           store_by_pieces (dest_mem, tree_low_cst (len, 1),
2473                            builtin_memset_read_str,
2474                            (PTR) &c, dest_align);
2475           dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2476 #ifdef POINTERS_EXTEND_UNSIGNED
2477           if (GET_MODE (dest_mem) != ptr_mode)
2478             dest_mem = convert_memory_address (ptr_mode, dest_mem);
2479 #endif
2480           return dest_mem;
2481         }
2482
2483       len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
2484
2485       dest_mem = get_memory_rtx (dest);
2486       set_mem_align (dest_mem, dest_align);
2487       dest_addr = clear_storage (dest_mem, len_rtx);
2488
2489       if (dest_addr == 0)
2490         {
2491           dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2492 #ifdef POINTERS_EXTEND_UNSIGNED
2493           if (GET_MODE (dest_addr) != ptr_mode)
2494             dest_addr = convert_memory_address (ptr_mode, dest_addr);
2495 #endif
2496         }
2497
2498       return dest_addr;
2499     }
2500 }
2501
2502 /* Expand expression EXP, which is a call to the bzero builtin.  Return 0
2503    if we failed the caller should emit a normal call.  */
2504
2505 static rtx
2506 expand_builtin_bzero (exp)
2507      tree exp;
2508 {
2509   tree arglist = TREE_OPERAND (exp, 1);
2510   tree dest, size, newarglist;
2511   rtx result;
2512
2513   if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2514     return NULL_RTX;
2515
2516   dest = TREE_VALUE (arglist);
2517   size = TREE_VALUE (TREE_CHAIN (arglist));
2518
2519   /* New argument list transforming bzero(ptr x, int y) to
2520      memset(ptr x, int 0, size_t y).   This is done this way
2521      so that if it isn't expanded inline, we fallback to
2522      calling bzero instead of memset.  */
2523
2524   newarglist = build_tree_list (NULL_TREE, convert (sizetype, size));
2525   newarglist = tree_cons (NULL_TREE, integer_zero_node, newarglist);
2526   newarglist = tree_cons (NULL_TREE, dest, newarglist);
2527
2528   TREE_OPERAND (exp, 1) = newarglist;
2529   result = expand_builtin_memset (exp, const0_rtx, VOIDmode);
2530
2531   /* Always restore the original arguments.  */
2532   TREE_OPERAND (exp, 1) = arglist;
2533
2534   return result;
2535 }
2536
2537 /* Expand expression EXP, which is a call to the memcmp or the strcmp builtin.
2538    ARGLIST is the argument list for this call.  Return 0 if we failed and the
2539    caller should emit a normal call, otherwise try to get the result in
2540    TARGET, if convenient (and in mode MODE, if that's convenient).  */
2541
2542 static rtx
2543 expand_builtin_memcmp (exp, arglist, target, mode)
2544      tree exp ATTRIBUTE_UNUSED;
2545      tree arglist;
2546      rtx target;
2547      enum machine_mode mode;
2548 {
2549   tree arg1, arg2, len;
2550   const char *p1, *p2;
2551
2552   if (!validate_arglist (arglist,
2553                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2554     return 0;
2555
2556   arg1 = TREE_VALUE (arglist);
2557   arg2 = TREE_VALUE (TREE_CHAIN (arglist));
2558   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2559
2560   /* If the len parameter is zero, return zero.  */
2561   if (host_integerp (len, 1) && tree_low_cst (len, 1) == 0)
2562     {
2563       /* Evaluate and ignore arg1 and arg2 in case they have
2564          side-effects.  */
2565       expand_expr (arg1, const0_rtx, VOIDmode, EXPAND_NORMAL);
2566       expand_expr (arg2, const0_rtx, VOIDmode, EXPAND_NORMAL);
2567       return const0_rtx;
2568     }
2569
2570   p1 = c_getstr (arg1);
2571   p2 = c_getstr (arg2);
2572
2573   /* If all arguments are constant, and the value of len is not greater
2574      than the lengths of arg1 and arg2, evaluate at compile-time.  */
2575   if (host_integerp (len, 1) && p1 && p2
2576       && compare_tree_int (len, strlen (p1) + 1) <= 0
2577       && compare_tree_int (len, strlen (p2) + 1) <= 0)
2578     {
2579       const int r = memcmp (p1, p2, tree_low_cst (len, 1));
2580
2581       return (r < 0 ? constm1_rtx : (r > 0 ? const1_rtx : const0_rtx));
2582     }
2583
2584   /* If len parameter is one, return an expression corresponding to
2585      (*(const unsigned char*)arg1 - (const unsigned char*)arg2).  */
2586   if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
2587     {
2588       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
2589       tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
2590       tree ind1 =
2591       fold (build1 (CONVERT_EXPR, integer_type_node,
2592                     build1 (INDIRECT_REF, cst_uchar_node,
2593                             build1 (NOP_EXPR, cst_uchar_ptr_node, arg1))));
2594       tree ind2 =
2595       fold (build1 (CONVERT_EXPR, integer_type_node,
2596                     build1 (INDIRECT_REF, cst_uchar_node,
2597                             build1 (NOP_EXPR, cst_uchar_ptr_node, arg2))));
2598       tree result = fold (build (MINUS_EXPR, integer_type_node, ind1, ind2));
2599       return expand_expr (result, target, mode, EXPAND_NORMAL);
2600     }
2601
2602 #ifdef HAVE_cmpstrsi
2603   {
2604     rtx arg1_rtx, arg2_rtx, arg3_rtx;
2605     rtx result;
2606     rtx insn;
2607
2608     int arg1_align
2609       = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
2610     int arg2_align
2611       = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
2612     enum machine_mode insn_mode
2613       = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
2614
2615     /* If we don't have POINTER_TYPE, call the function.  */
2616     if (arg1_align == 0 || arg2_align == 0)
2617       return 0;
2618
2619     /* Make a place to write the result of the instruction.  */
2620     result = target;
2621     if (! (result != 0
2622            && GET_CODE (result) == REG && GET_MODE (result) == insn_mode
2623            && REGNO (result) >= FIRST_PSEUDO_REGISTER))
2624       result = gen_reg_rtx (insn_mode);
2625
2626     arg1_rtx = get_memory_rtx (arg1);
2627     arg2_rtx = get_memory_rtx (arg2);
2628     arg3_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
2629     if (!HAVE_cmpstrsi)
2630       insn = NULL_RTX;
2631     else
2632       insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
2633                            GEN_INT (MIN (arg1_align, arg2_align)));
2634
2635     if (insn)
2636       emit_insn (insn);
2637     else
2638       emit_library_call_value (memcmp_libfunc, result, LCT_PURE_MAKE_BLOCK,
2639                                TYPE_MODE (integer_type_node), 3,
2640                                XEXP (arg1_rtx, 0), Pmode,
2641                                XEXP (arg2_rtx, 0), Pmode,
2642                                convert_to_mode (TYPE_MODE (sizetype), arg3_rtx,
2643                                                 TREE_UNSIGNED (sizetype)),
2644                                TYPE_MODE (sizetype));
2645
2646     /* Return the value in the proper mode for this function.  */
2647     mode = TYPE_MODE (TREE_TYPE (exp));
2648     if (GET_MODE (result) == mode)
2649       return result;
2650     else if (target != 0)
2651       {
2652         convert_move (target, result, 0);
2653         return target;
2654       }
2655     else
2656       return convert_to_mode (mode, result, 0);
2657   }
2658 #endif
2659
2660   return 0;
2661 }
2662
2663 /* Expand expression EXP, which is a call to the strcmp builtin.  Return 0
2664    if we failed the caller should emit a normal call, otherwise try to get
2665    the result in TARGET, if convenient.  */
2666
2667 static rtx
2668 expand_builtin_strcmp (exp, target, mode)
2669      tree exp;
2670      rtx target;
2671      enum machine_mode mode;
2672 {
2673   tree arglist = TREE_OPERAND (exp, 1);
2674   tree arg1, arg2, len, len2, fn;
2675   const char *p1, *p2;
2676
2677   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2678     return 0;
2679
2680   arg1 = TREE_VALUE (arglist);
2681   arg2 = TREE_VALUE (TREE_CHAIN (arglist));
2682
2683   p1 = c_getstr (arg1);
2684   p2 = c_getstr (arg2);
2685
2686   if (p1 && p2)
2687     {
2688       const int i = strcmp (p1, p2);
2689       return (i < 0 ? constm1_rtx : (i > 0 ? const1_rtx : const0_rtx));
2690     }
2691
2692   /* If either arg is "", return an expression corresponding to
2693      (*(const unsigned char*)arg1 - (const unsigned char*)arg2).  */
2694   if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
2695     {
2696       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
2697       tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
2698       tree ind1 =
2699         fold (build1 (CONVERT_EXPR, integer_type_node,
2700                       build1 (INDIRECT_REF, cst_uchar_node,
2701                               build1 (NOP_EXPR, cst_uchar_ptr_node, arg1))));
2702       tree ind2 =
2703         fold (build1 (CONVERT_EXPR, integer_type_node,
2704                       build1 (INDIRECT_REF, cst_uchar_node,
2705                               build1 (NOP_EXPR, cst_uchar_ptr_node, arg2))));
2706       tree result = fold (build (MINUS_EXPR, integer_type_node, ind1, ind2));
2707       return expand_expr (result, target, mode, EXPAND_NORMAL);
2708     }
2709
2710   len = c_strlen (arg1);
2711   len2 = c_strlen (arg2);
2712
2713   if (len)
2714     len = size_binop (PLUS_EXPR, ssize_int (1), len);
2715
2716   if (len2)
2717     len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
2718
2719   /* If we don't have a constant length for the first, use the length
2720      of the second, if we know it.  We don't require a constant for
2721      this case; some cost analysis could be done if both are available
2722      but neither is constant.  For now, assume they're equally cheap
2723      unless one has side effects.
2724
2725      If both strings have constant lengths, use the smaller.  This
2726      could arise if optimization results in strcpy being called with
2727      two fixed strings, or if the code was machine-generated.  We should
2728      add some code to the `memcmp' handler below to deal with such
2729      situations, someday.  */
2730
2731   if (!len || TREE_CODE (len) != INTEGER_CST)
2732     {
2733       if (len2 && !TREE_SIDE_EFFECTS (len2))
2734         len = len2;
2735       else if (len == 0)
2736         return 0;
2737     }
2738   else if (len2 && TREE_CODE (len2) == INTEGER_CST
2739            && tree_int_cst_lt (len2, len))
2740     len = len2;
2741
2742   /* If both arguments have side effects, we cannot optimize.  */
2743   if (TREE_SIDE_EFFECTS (len))
2744     return 0;
2745
2746   fn = implicit_built_in_decls[BUILT_IN_MEMCMP];
2747   if (!fn)
2748     return 0;
2749
2750   chainon (arglist, build_tree_list (NULL_TREE, len));
2751   return expand_expr (build_function_call_expr (fn, arglist),
2752                       target, mode, EXPAND_NORMAL);
2753 }
2754
2755 /* Expand expression EXP, which is a call to the strncmp builtin.  Return 0
2756    if we failed the caller should emit a normal call, otherwise try to get
2757    the result in TARGET, if convenient.  */
2758
2759 static rtx
2760 expand_builtin_strncmp (exp, target, mode)
2761      tree exp;
2762      rtx target;
2763      enum machine_mode mode;
2764 {
2765   tree arglist = TREE_OPERAND (exp, 1);
2766   tree fn, newarglist, len = 0;
2767   tree arg1, arg2, arg3;
2768   const char *p1, *p2;
2769
2770   if (!validate_arglist (arglist,
2771                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2772     return 0;
2773
2774   arg1 = TREE_VALUE (arglist);
2775   arg2 = TREE_VALUE (TREE_CHAIN (arglist));
2776   arg3 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2777
2778   /* If the len parameter is zero, return zero.  */
2779   if (host_integerp (arg3, 1) && tree_low_cst (arg3, 1) == 0)
2780     {
2781       /* Evaluate and ignore arg1 and arg2 in case they have
2782          side-effects.  */
2783       expand_expr (arg1, const0_rtx, VOIDmode, EXPAND_NORMAL);
2784       expand_expr (arg2, const0_rtx, VOIDmode, EXPAND_NORMAL);
2785       return const0_rtx;
2786     }
2787
2788   p1 = c_getstr (arg1);
2789   p2 = c_getstr (arg2);
2790
2791   /* If all arguments are constant, evaluate at compile-time.  */
2792   if (host_integerp (arg3, 1) && p1 && p2)
2793     {
2794       const int r = strncmp (p1, p2, tree_low_cst (arg3, 1));
2795       return (r < 0 ? constm1_rtx : (r > 0 ? const1_rtx : const0_rtx));
2796     }
2797
2798   /* If len == 1 or (either string parameter is "" and (len >= 1)),
2799       return (*(const u_char*)arg1 - *(const u_char*)arg2).  */
2800   if (host_integerp (arg3, 1)
2801       && (tree_low_cst (arg3, 1) == 1
2802           || (tree_low_cst (arg3, 1) > 1
2803               && ((p1 && *p1 == '\0') || (p2 && *p2 == '\0')))))
2804     {
2805       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
2806       tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
2807       tree ind1 =
2808         fold (build1 (CONVERT_EXPR, integer_type_node,
2809                       build1 (INDIRECT_REF, cst_uchar_node,
2810                               build1 (NOP_EXPR, cst_uchar_ptr_node, arg1))));
2811       tree ind2 =
2812         fold (build1 (CONVERT_EXPR, integer_type_node,
2813                       build1 (INDIRECT_REF, cst_uchar_node,
2814                               build1 (NOP_EXPR, cst_uchar_ptr_node, arg2))));
2815       tree result = fold (build (MINUS_EXPR, integer_type_node, ind1, ind2));
2816       return expand_expr (result, target, mode, EXPAND_NORMAL);
2817     }
2818
2819   /* If c_strlen can determine an expression for one of the string
2820      lengths, and it doesn't have side effects, then call
2821      expand_builtin_memcmp() using length MIN(strlen(string)+1, arg3).  */
2822
2823   /* Perhaps one of the strings is really constant, if so prefer
2824      that constant length over the other string's length.  */
2825   if (p1)
2826     len = c_strlen (arg1);
2827   else if (p2)
2828     len = c_strlen (arg2);
2829
2830   /* If we still don't have a len, try either string arg as long
2831      as they don't have side effects.  */
2832   if (!len && !TREE_SIDE_EFFECTS (arg1))
2833     len = c_strlen (arg1);
2834   if (!len && !TREE_SIDE_EFFECTS (arg2))
2835     len = c_strlen (arg2);
2836   /* If we still don't have a length, punt.  */
2837   if (!len)
2838     return 0;
2839
2840   fn = implicit_built_in_decls[BUILT_IN_MEMCMP];
2841   if (!fn)
2842     return 0;
2843
2844   /* Add one to the string length.  */
2845   len = fold (size_binop (PLUS_EXPR, len, ssize_int (1)));
2846
2847   /* The actual new length parameter is MIN(len,arg3).  */
2848   len = fold (build (MIN_EXPR, TREE_TYPE (len), len, arg3));
2849
2850   newarglist = build_tree_list (NULL_TREE, len);
2851   newarglist = tree_cons (NULL_TREE, arg2, newarglist);
2852   newarglist = tree_cons (NULL_TREE, arg1, newarglist);
2853   return expand_expr (build_function_call_expr (fn, newarglist),
2854                       target, mode, EXPAND_NORMAL);
2855 }
2856
2857 /* Expand expression EXP, which is a call to the strcat builtin.
2858    Return 0 if we failed the caller should emit a normal call,
2859    otherwise try to get the result in TARGET, if convenient.  */
2860
2861 static rtx
2862 expand_builtin_strcat (arglist, target, mode)
2863      tree arglist;
2864      rtx target;
2865      enum machine_mode mode;
2866 {
2867   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2868     return 0;
2869   else
2870     {
2871       tree dst = TREE_VALUE (arglist),
2872         src = TREE_VALUE (TREE_CHAIN (arglist));
2873       const char *p = c_getstr (src);
2874
2875       /* If the string length is zero, return the dst parameter.  */
2876       if (p && *p == '\0')
2877         return expand_expr (dst, target, mode, EXPAND_NORMAL);
2878
2879       return 0;
2880     }
2881 }
2882
2883 /* Expand expression EXP, which is a call to the strncat builtin.
2884    Return 0 if we failed the caller should emit a normal call,
2885    otherwise try to get the result in TARGET, if convenient.  */
2886
2887 static rtx
2888 expand_builtin_strncat (arglist, target, mode)
2889      tree arglist;
2890      rtx target;
2891      enum machine_mode mode;
2892 {
2893   if (!validate_arglist (arglist,
2894                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2895     return 0;
2896   else
2897     {
2898       tree dst = TREE_VALUE (arglist),
2899         src = TREE_VALUE (TREE_CHAIN (arglist)),
2900         len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2901       const char *p = c_getstr (src);
2902
2903       /* If the requested length is zero, or the src parameter string
2904           length is zero, return the dst parameter.  */
2905       if (integer_zerop (len) || (p && *p == '\0'))
2906         {
2907           /* Evaluate and ignore the src and len parameters in case
2908              they have side-effects.  */
2909           expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
2910           expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
2911           return expand_expr (dst, target, mode, EXPAND_NORMAL);
2912         }
2913
2914       /* If the requested len is greater than or equal to the string
2915          length, call strcat.  */
2916       if (TREE_CODE (len) == INTEGER_CST && p
2917           && compare_tree_int (len, strlen (p)) >= 0)
2918         {
2919           tree newarglist
2920             = tree_cons (NULL_TREE, dst, build_tree_list (NULL_TREE, src));
2921           tree fn = implicit_built_in_decls[BUILT_IN_STRCAT];
2922
2923           /* If the replacement _DECL isn't initialized, don't do the
2924              transformation.  */
2925           if (!fn)
2926             return 0;
2927
2928           return expand_expr (build_function_call_expr (fn, newarglist),
2929                               target, mode, EXPAND_NORMAL);
2930         }
2931       return 0;
2932     }
2933 }
2934
2935 /* Expand expression EXP, which is a call to the strspn builtin.
2936    Return 0 if we failed the caller should emit a normal call,
2937    otherwise try to get the result in TARGET, if convenient.  */
2938
2939 static rtx
2940 expand_builtin_strspn (arglist, target, mode)
2941      tree arglist;
2942      rtx target;
2943      enum machine_mode mode;
2944 {
2945   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2946     return 0;
2947   else
2948     {
2949       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
2950       const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
2951
2952       /* If both arguments are constants, evaluate at compile-time.  */
2953       if (p1 && p2)
2954         {
2955           const size_t r = strspn (p1, p2);
2956           return expand_expr (size_int (r), target, mode, EXPAND_NORMAL);
2957         }
2958
2959       /* If either argument is "", return 0.  */
2960       if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
2961         {
2962           /* Evaluate and ignore both arguments in case either one has
2963              side-effects.  */
2964           expand_expr (s1, const0_rtx, VOIDmode, EXPAND_NORMAL);
2965           expand_expr (s2, const0_rtx, VOIDmode, EXPAND_NORMAL);
2966           return const0_rtx;
2967         }
2968       return 0;
2969     }
2970 }
2971
2972 /* Expand expression EXP, which is a call to the strcspn builtin.
2973    Return 0 if we failed the caller should emit a normal call,
2974    otherwise try to get the result in TARGET, if convenient.  */
2975
2976 static rtx
2977 expand_builtin_strcspn (arglist, target, mode)
2978      tree arglist;
2979      rtx target;
2980      enum machine_mode mode;
2981 {
2982   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2983     return 0;
2984   else
2985     {
2986       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
2987       const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
2988
2989       /* If both arguments are constants, evaluate at compile-time.  */
2990       if (p1 && p2)
2991         {
2992           const size_t r = strcspn (p1, p2);
2993           return expand_expr (size_int (r), target, mode, EXPAND_NORMAL);
2994         }
2995
2996       /* If the first argument is "", return 0.  */
2997       if (p1 && *p1 == '\0')
2998         {
2999           /* Evaluate and ignore argument s2 in case it has
3000              side-effects.  */
3001           expand_expr (s2, const0_rtx, VOIDmode, EXPAND_NORMAL);
3002           return const0_rtx;
3003         }
3004
3005       /* If the second argument is "", return __builtin_strlen(s1).  */
3006       if (p2 && *p2 == '\0')
3007         {
3008           tree newarglist = build_tree_list (NULL_TREE, s1),
3009             fn = implicit_built_in_decls[BUILT_IN_STRLEN];
3010
3011           /* If the replacement _DECL isn't initialized, don't do the
3012              transformation.  */
3013           if (!fn)
3014             return 0;
3015
3016           return expand_expr (build_function_call_expr (fn, newarglist),
3017                               target, mode, EXPAND_NORMAL);
3018         }
3019       return 0;
3020     }
3021 }
3022
3023 /* Expand a call to __builtin_saveregs, generating the result in TARGET,
3024    if that's convenient.  */
3025
3026 rtx
3027 expand_builtin_saveregs ()
3028 {
3029   rtx val, seq;
3030
3031   /* Don't do __builtin_saveregs more than once in a function.
3032      Save the result of the first call and reuse it.  */
3033   if (saveregs_value != 0)
3034     return saveregs_value;
3035
3036   /* When this function is called, it means that registers must be
3037      saved on entry to this function.  So we migrate the call to the
3038      first insn of this function.  */
3039
3040   start_sequence ();
3041
3042 #ifdef EXPAND_BUILTIN_SAVEREGS
3043   /* Do whatever the machine needs done in this case.  */
3044   val = EXPAND_BUILTIN_SAVEREGS ();
3045 #else
3046   /* ??? We used to try and build up a call to the out of line function,
3047      guessing about what registers needed saving etc.  This became much
3048      harder with __builtin_va_start, since we don't have a tree for a
3049      call to __builtin_saveregs to fall back on.  There was exactly one
3050      port (i860) that used this code, and I'm unconvinced it could actually
3051      handle the general case.  So we no longer try to handle anything
3052      weird and make the backend absorb the evil.  */
3053
3054   error ("__builtin_saveregs not supported by this target");
3055   val = const0_rtx;
3056 #endif
3057
3058   seq = get_insns ();
3059   end_sequence ();
3060
3061   saveregs_value = val;
3062
3063   /* Put the insns after the NOTE that starts the function.  If this
3064      is inside a start_sequence, make the outer-level insn chain current, so
3065      the code is placed at the start of the function.  */
3066   push_topmost_sequence ();
3067   emit_insn_after (seq, get_insns ());
3068   pop_topmost_sequence ();
3069
3070   return val;
3071 }
3072
3073 /* __builtin_args_info (N) returns word N of the arg space info
3074    for the current function.  The number and meanings of words
3075    is controlled by the definition of CUMULATIVE_ARGS.  */
3076
3077 static rtx
3078 expand_builtin_args_info (exp)
3079      tree exp;
3080 {
3081   tree arglist = TREE_OPERAND (exp, 1);
3082   int nwords = sizeof (CUMULATIVE_ARGS) / sizeof (int);
3083   int *word_ptr = (int *) &current_function_args_info;
3084 #if 0
3085   /* These are used by the code below that is if 0'ed away */
3086   int i;
3087   tree type, elts, result;
3088 #endif
3089
3090   if (sizeof (CUMULATIVE_ARGS) % sizeof (int) != 0)
3091     abort ();
3092
3093   if (arglist != 0)
3094     {
3095       if (!host_integerp (TREE_VALUE (arglist), 0))
3096         error ("argument of `__builtin_args_info' must be constant");
3097       else
3098         {
3099           HOST_WIDE_INT wordnum = tree_low_cst (TREE_VALUE (arglist), 0);
3100
3101           if (wordnum < 0 || wordnum >= nwords)
3102             error ("argument of `__builtin_args_info' out of range");
3103           else
3104             return GEN_INT (word_ptr[wordnum]);
3105         }
3106     }
3107   else
3108     error ("missing argument in `__builtin_args_info'");
3109
3110   return const0_rtx;
3111
3112 #if 0
3113   for (i = 0; i < nwords; i++)
3114     elts = tree_cons (NULL_TREE, build_int_2 (word_ptr[i], 0));
3115
3116   type = build_array_type (integer_type_node,
3117                            build_index_type (build_int_2 (nwords, 0)));
3118   result = build (CONSTRUCTOR, type, NULL_TREE, nreverse (elts));
3119   TREE_CONSTANT (result) = 1;
3120   TREE_STATIC (result) = 1;
3121   result = build1 (INDIRECT_REF, build_pointer_type (type), result);
3122   TREE_CONSTANT (result) = 1;
3123   return expand_expr (result, NULL_RTX, VOIDmode, 0);
3124 #endif
3125 }
3126
3127 /* Expand ARGLIST, from a call to __builtin_next_arg.  */
3128
3129 static rtx
3130 expand_builtin_next_arg (arglist)
3131      tree arglist;
3132 {
3133   tree fntype = TREE_TYPE (current_function_decl);
3134
3135   if (TYPE_ARG_TYPES (fntype) == 0
3136       || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
3137           == void_type_node))
3138     {
3139       error ("`va_start' used in function with fixed args");
3140       return const0_rtx;
3141     }
3142
3143   if (arglist)
3144     {
3145       tree last_parm = tree_last (DECL_ARGUMENTS (current_function_decl));
3146       tree arg = TREE_VALUE (arglist);
3147
3148       /* Strip off all nops for the sake of the comparison.  This
3149          is not quite the same as STRIP_NOPS.  It does more.
3150          We must also strip off INDIRECT_EXPR for C++ reference
3151          parameters.  */
3152       while (TREE_CODE (arg) == NOP_EXPR
3153              || TREE_CODE (arg) == CONVERT_EXPR
3154              || TREE_CODE (arg) == NON_LVALUE_EXPR
3155              || TREE_CODE (arg) == INDIRECT_REF)
3156         arg = TREE_OPERAND (arg, 0);
3157       if (arg != last_parm)
3158         warning ("second parameter of `va_start' not last named argument");
3159     }
3160   else
3161     /* Evidently an out of date version of <stdarg.h>; can't validate
3162        va_start's second argument, but can still work as intended.  */
3163     warning ("`__builtin_next_arg' called without an argument");
3164
3165   return expand_binop (Pmode, add_optab,
3166                        current_function_internal_arg_pointer,
3167                        current_function_arg_offset_rtx,
3168                        NULL_RTX, 0, OPTAB_LIB_WIDEN);
3169 }
3170
3171 /* Make it easier for the backends by protecting the valist argument
3172    from multiple evaluations.  */
3173
3174 static tree
3175 stabilize_va_list (valist, needs_lvalue)
3176      tree valist;
3177      int needs_lvalue;
3178 {
3179   if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
3180     {
3181       if (TREE_SIDE_EFFECTS (valist))
3182         valist = save_expr (valist);
3183
3184       /* For this case, the backends will be expecting a pointer to
3185          TREE_TYPE (va_list_type_node), but it's possible we've
3186          actually been given an array (an actual va_list_type_node).
3187          So fix it.  */
3188       if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
3189         {
3190           tree p1 = build_pointer_type (TREE_TYPE (va_list_type_node));
3191           tree p2 = build_pointer_type (va_list_type_node);
3192
3193           valist = build1 (ADDR_EXPR, p2, valist);
3194           valist = fold (build1 (NOP_EXPR, p1, valist));
3195         }
3196     }
3197   else
3198     {
3199       tree pt;
3200
3201       if (! needs_lvalue)
3202         {
3203           if (! TREE_SIDE_EFFECTS (valist))
3204             return valist;
3205
3206           pt = build_pointer_type (va_list_type_node);
3207           valist = fold (build1 (ADDR_EXPR, pt, valist));
3208           TREE_SIDE_EFFECTS (valist) = 1;
3209         }
3210
3211       if (TREE_SIDE_EFFECTS (valist))
3212         valist = save_expr (valist);
3213       valist = fold (build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (valist)),
3214                              valist));
3215     }
3216
3217   return valist;
3218 }
3219
3220 /* The "standard" implementation of va_start: just assign `nextarg' to
3221    the variable.  */
3222
3223 void
3224 std_expand_builtin_va_start (valist, nextarg)
3225      tree valist;
3226      rtx nextarg;
3227 {
3228   tree t;
3229
3230   t = build (MODIFY_EXPR, TREE_TYPE (valist), valist,
3231              make_tree (ptr_type_node, nextarg));
3232   TREE_SIDE_EFFECTS (t) = 1;
3233
3234   expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
3235 }
3236
3237 /* Expand ARGLIST, from a call to __builtin_va_start.  */
3238
3239 static rtx
3240 expand_builtin_va_start (arglist)
3241      tree arglist;
3242 {
3243   rtx nextarg;
3244   tree chain, valist;
3245
3246   chain = TREE_CHAIN (arglist);
3247
3248   if (TREE_CHAIN (chain))
3249     error ("too many arguments to function `va_start'");
3250
3251   nextarg = expand_builtin_next_arg (chain);
3252   valist = stabilize_va_list (TREE_VALUE (arglist), 1);
3253
3254 #ifdef EXPAND_BUILTIN_VA_START
3255   EXPAND_BUILTIN_VA_START (valist, nextarg);
3256 #else
3257   std_expand_builtin_va_start (valist, nextarg);
3258 #endif
3259
3260   return const0_rtx;
3261 }
3262
3263 /* The "standard" implementation of va_arg: read the value from the
3264    current (padded) address and increment by the (padded) size.  */
3265
3266 rtx
3267 std_expand_builtin_va_arg (valist, type)
3268      tree valist, type;
3269 {
3270   tree addr_tree, t, type_size = NULL;
3271   tree align, alignm1;
3272   tree rounded_size;
3273   rtx addr;
3274
3275   /* Compute the rounded size of the type.  */
3276   align = size_int (PARM_BOUNDARY / BITS_PER_UNIT);
3277   alignm1 = size_int (PARM_BOUNDARY / BITS_PER_UNIT - 1);
3278   if (type == error_mark_node
3279       || (type_size = TYPE_SIZE_UNIT (TYPE_MAIN_VARIANT (type))) == NULL
3280       || TREE_OVERFLOW (type_size))
3281     rounded_size = size_zero_node;
3282   else
3283     rounded_size = fold (build (MULT_EXPR, sizetype,
3284                                 fold (build (TRUNC_DIV_EXPR, sizetype,
3285                                              fold (build (PLUS_EXPR, sizetype,
3286                                                           type_size, alignm1)),
3287                                              align)),
3288                                 align));
3289
3290   /* Get AP.  */
3291   addr_tree = valist;
3292   if (PAD_VARARGS_DOWN && ! integer_zerop (rounded_size))
3293     {
3294       /* Small args are padded downward.  */
3295       addr_tree = fold (build (PLUS_EXPR, TREE_TYPE (addr_tree), addr_tree,
3296                                fold (build (COND_EXPR, sizetype,
3297                                             fold (build (GT_EXPR, sizetype,
3298                                                          rounded_size,
3299                                                          align)),
3300                                             size_zero_node,
3301                                             fold (build (MINUS_EXPR, sizetype,
3302                                                          rounded_size,
3303                                                          type_size))))));
3304     }
3305
3306   addr = expand_expr (addr_tree, NULL_RTX, Pmode, EXPAND_NORMAL);
3307   addr = copy_to_reg (addr);
3308
3309   /* Compute new value for AP.  */
3310   if (! integer_zerop (rounded_size))
3311     {
3312       t = build (MODIFY_EXPR, TREE_TYPE (valist), valist,
3313                  build (PLUS_EXPR, TREE_TYPE (valist), valist,
3314                         rounded_size));
3315       TREE_SIDE_EFFECTS (t) = 1;
3316       expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
3317     }
3318
3319   return addr;
3320 }
3321
3322 /* Expand __builtin_va_arg, which is not really a builtin function, but
3323    a very special sort of operator.  */
3324
3325 rtx
3326 expand_builtin_va_arg (valist, type)
3327      tree valist, type;
3328 {
3329   rtx addr, result;
3330   tree promoted_type, want_va_type, have_va_type;
3331
3332   /* Verify that valist is of the proper type.  */
3333
3334   want_va_type = va_list_type_node;
3335   have_va_type = TREE_TYPE (valist);
3336   if (TREE_CODE (want_va_type) == ARRAY_TYPE)
3337     {
3338       /* If va_list is an array type, the argument may have decayed
3339          to a pointer type, e.g. by being passed to another function.
3340          In that case, unwrap both types so that we can compare the
3341          underlying records.  */
3342       if (TREE_CODE (have_va_type) == ARRAY_TYPE
3343           || TREE_CODE (have_va_type) == POINTER_TYPE)
3344         {
3345           want_va_type = TREE_TYPE (want_va_type);
3346           have_va_type = TREE_TYPE (have_va_type);
3347         }
3348     }
3349   if (TYPE_MAIN_VARIANT (want_va_type) != TYPE_MAIN_VARIANT (have_va_type))
3350     {
3351       error ("first argument to `va_arg' not of type `va_list'");
3352       addr = const0_rtx;
3353     }
3354
3355   /* Generate a diagnostic for requesting data of a type that cannot
3356      be passed through `...' due to type promotion at the call site.  */
3357   else if ((promoted_type = (*lang_hooks.types.type_promotes_to) (type))
3358            != type)
3359     {
3360       const char *name = "<anonymous type>", *pname = 0;
3361       static bool gave_help;
3362
3363       if (TYPE_NAME (type))
3364         {
3365           if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE)
3366             name = IDENTIFIER_POINTER (TYPE_NAME (type));
3367           else if (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
3368                    && DECL_NAME (TYPE_NAME (type)))
3369             name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type)));
3370         }
3371       if (TYPE_NAME (promoted_type))
3372         {
3373           if (TREE_CODE (TYPE_NAME (promoted_type)) == IDENTIFIER_NODE)
3374             pname = IDENTIFIER_POINTER (TYPE_NAME (promoted_type));
3375           else if (TREE_CODE (TYPE_NAME (promoted_type)) == TYPE_DECL
3376                    && DECL_NAME (TYPE_NAME (promoted_type)))
3377             pname = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (promoted_type)));
3378         }
3379
3380       /* Unfortunately, this is merely undefined, rather than a constraint
3381          violation, so we cannot make this an error.  If this call is never
3382          executed, the program is still strictly conforming.  */
3383       warning ("`%s' is promoted to `%s' when passed through `...'",
3384                name, pname);
3385       if (! gave_help)
3386         {
3387           gave_help = true;
3388           warning ("(so you should pass `%s' not `%s' to `va_arg')",
3389                    pname, name);
3390         }
3391
3392       /* We can, however, treat "undefined" any way we please.
3393          Call abort to encourage the user to fix the program.  */
3394       expand_builtin_trap ();
3395
3396       /* This is dead code, but go ahead and finish so that the
3397          mode of the result comes out right.  */
3398       addr = const0_rtx;
3399     }
3400   else
3401     {
3402       /* Make it easier for the backends by protecting the valist argument
3403          from multiple evaluations.  */
3404       valist = stabilize_va_list (valist, 0);
3405
3406 #ifdef EXPAND_BUILTIN_VA_ARG
3407       addr = EXPAND_BUILTIN_VA_ARG (valist, type);
3408 #else
3409       addr = std_expand_builtin_va_arg (valist, type);
3410 #endif
3411     }
3412
3413 #ifdef POINTERS_EXTEND_UNSIGNED
3414   if (GET_MODE (addr) != Pmode)
3415     addr = convert_memory_address (Pmode, addr);
3416 #endif
3417
3418   result = gen_rtx_MEM (TYPE_MODE (type), addr);
3419   set_mem_alias_set (result, get_varargs_alias_set ());
3420
3421   return result;
3422 }
3423
3424 /* Expand ARGLIST, from a call to __builtin_va_end.  */
3425
3426 static rtx
3427 expand_builtin_va_end (arglist)
3428      tree arglist;
3429 {
3430   tree valist = TREE_VALUE (arglist);
3431
3432 #ifdef EXPAND_BUILTIN_VA_END
3433   valist = stabilize_va_list (valist, 0);
3434   EXPAND_BUILTIN_VA_END (arglist);
3435 #else
3436   /* Evaluate for side effects, if needed.  I hate macros that don't
3437      do that.  */
3438   if (TREE_SIDE_EFFECTS (valist))
3439     expand_expr (valist, const0_rtx, VOIDmode, EXPAND_NORMAL);
3440 #endif
3441
3442   return const0_rtx;
3443 }
3444
3445 /* Expand ARGLIST, from a call to __builtin_va_copy.  We do this as a
3446    builtin rather than just as an assignment in stdarg.h because of the
3447    nastiness of array-type va_list types.  */
3448
3449 static rtx
3450 expand_builtin_va_copy (arglist)
3451      tree arglist;
3452 {
3453   tree dst, src, t;
3454
3455   dst = TREE_VALUE (arglist);
3456   src = TREE_VALUE (TREE_CHAIN (arglist));
3457
3458   dst = stabilize_va_list (dst, 1);
3459   src = stabilize_va_list (src, 0);
3460
3461   if (TREE_CODE (va_list_type_node) != ARRAY_TYPE)
3462     {
3463       t = build (MODIFY_EXPR, va_list_type_node, dst, src);
3464       TREE_SIDE_EFFECTS (t) = 1;
3465       expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
3466     }
3467   else
3468     {
3469       rtx dstb, srcb, size;
3470
3471       /* Evaluate to pointers.  */
3472       dstb = expand_expr (dst, NULL_RTX, Pmode, EXPAND_NORMAL);
3473       srcb = expand_expr (src, NULL_RTX, Pmode, EXPAND_NORMAL);
3474       size = expand_expr (TYPE_SIZE_UNIT (va_list_type_node), NULL_RTX,
3475                           VOIDmode, EXPAND_NORMAL);
3476
3477 #ifdef POINTERS_EXTEND_UNSIGNED
3478       if (GET_MODE (dstb) != Pmode)
3479         dstb = convert_memory_address (Pmode, dstb);
3480
3481       if (GET_MODE (srcb) != Pmode)
3482         srcb = convert_memory_address (Pmode, srcb);
3483 #endif
3484
3485       /* "Dereference" to BLKmode memories.  */
3486       dstb = gen_rtx_MEM (BLKmode, dstb);
3487       set_mem_alias_set (dstb, get_alias_set (TREE_TYPE (TREE_TYPE (dst))));
3488       set_mem_align (dstb, TYPE_ALIGN (va_list_type_node));
3489       srcb = gen_rtx_MEM (BLKmode, srcb);
3490       set_mem_alias_set (srcb, get_alias_set (TREE_TYPE (TREE_TYPE (src))));
3491       set_mem_align (srcb, TYPE_ALIGN (va_list_type_node));
3492
3493       /* Copy.  */
3494       emit_block_move (dstb, srcb, size, BLOCK_OP_NORMAL);
3495     }
3496
3497   return const0_rtx;
3498 }
3499
3500 /* Expand a call to one of the builtin functions __builtin_frame_address or
3501    __builtin_return_address.  */
3502
3503 static rtx
3504 expand_builtin_frame_address (exp)
3505      tree exp;
3506 {
3507   tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
3508   tree arglist = TREE_OPERAND (exp, 1);
3509
3510   /* The argument must be a nonnegative integer constant.
3511      It counts the number of frames to scan up the stack.
3512      The value is the return address saved in that frame.  */
3513   if (arglist == 0)
3514     /* Warning about missing arg was already issued.  */
3515     return const0_rtx;
3516   else if (! host_integerp (TREE_VALUE (arglist), 1))
3517     {
3518       if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
3519         error ("invalid arg to `__builtin_frame_address'");
3520       else
3521         error ("invalid arg to `__builtin_return_address'");
3522       return const0_rtx;
3523     }
3524   else
3525     {
3526       rtx tem
3527         = expand_builtin_return_addr (DECL_FUNCTION_CODE (fndecl),
3528                                       tree_low_cst (TREE_VALUE (arglist), 1),
3529                                       hard_frame_pointer_rtx);
3530
3531       /* Some ports cannot access arbitrary stack frames.  */
3532       if (tem == NULL)
3533         {
3534           if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
3535             warning ("unsupported arg to `__builtin_frame_address'");
3536           else
3537             warning ("unsupported arg to `__builtin_return_address'");
3538           return const0_rtx;
3539         }
3540
3541       /* For __builtin_frame_address, return what we've got.  */
3542       if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
3543         return tem;
3544
3545       if (GET_CODE (tem) != REG
3546           && ! CONSTANT_P (tem))
3547         tem = copy_to_mode_reg (Pmode, tem);
3548       return tem;
3549     }
3550 }
3551
3552 /* Expand a call to the alloca builtin, with arguments ARGLIST.  Return 0 if
3553    we failed and the caller should emit a normal call, otherwise try to get
3554    the result in TARGET, if convenient.  */
3555
3556 static rtx
3557 expand_builtin_alloca (arglist, target)
3558      tree arglist;
3559      rtx target;
3560 {
3561   rtx op0;
3562   rtx result;
3563
3564   if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
3565     return 0;
3566
3567   /* Compute the argument.  */
3568   op0 = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
3569
3570   /* Allocate the desired space.  */
3571   result = allocate_dynamic_stack_space (op0, target, BITS_PER_UNIT);
3572
3573 #ifdef POINTERS_EXTEND_UNSIGNED
3574   if (GET_MODE (result) != ptr_mode)
3575     result = convert_memory_address (ptr_mode, result);
3576 #endif
3577
3578   return result;
3579 }
3580
3581 /* Expand a call to the ffs builtin.  The arguments are in ARGLIST.
3582    Return 0 if a normal call should be emitted rather than expanding the
3583    function in-line.  If convenient, the result should be placed in TARGET.
3584    SUBTARGET may be used as the target for computing one of EXP's operands.  */
3585
3586 static rtx
3587 expand_builtin_ffs (arglist, target, subtarget)
3588      tree arglist;
3589      rtx target, subtarget;
3590 {
3591   rtx op0;
3592   if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
3593     return 0;
3594
3595   /* Compute the argument.  */
3596   op0 = expand_expr (TREE_VALUE (arglist), subtarget, VOIDmode, 0);
3597   /* Compute ffs, into TARGET if possible.
3598      Set TARGET to wherever the result comes back.  */
3599   target = expand_unop (TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist))),
3600                         ffs_optab, op0, target, 1);
3601   if (target == 0)
3602     abort ();
3603   return target;
3604 }
3605
3606 /* If the string passed to fputs is a constant and is one character
3607    long, we attempt to transform this call into __builtin_fputc().  */
3608
3609 static rtx
3610 expand_builtin_fputs (arglist, ignore, unlocked)
3611      tree arglist;
3612      int ignore;
3613      int unlocked;
3614 {
3615   tree len, fn;
3616   tree fn_fputc = unlocked ? implicit_built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
3617     : implicit_built_in_decls[BUILT_IN_FPUTC];
3618   tree fn_fwrite = unlocked ? implicit_built_in_decls[BUILT_IN_FWRITE_UNLOCKED]
3619     : implicit_built_in_decls[BUILT_IN_FWRITE];
3620
3621   /* If the return value is used, or the replacement _DECL isn't
3622      initialized, don't do the transformation.  */
3623   if (!ignore || !fn_fputc || !fn_fwrite)
3624     return 0;
3625
3626   /* Verify the arguments in the original call.  */
3627   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3628     return 0;
3629
3630   /* Get the length of the string passed to fputs.  If the length
3631      can't be determined, punt.  */
3632   if (!(len = c_strlen (TREE_VALUE (arglist)))
3633       || TREE_CODE (len) != INTEGER_CST)
3634     return 0;
3635
3636   switch (compare_tree_int (len, 1))
3637     {
3638     case -1: /* length is 0, delete the call entirely .  */
3639       {
3640         /* Evaluate and ignore the argument in case it has
3641            side-effects.  */
3642         expand_expr (TREE_VALUE (TREE_CHAIN (arglist)), const0_rtx,
3643                      VOIDmode, EXPAND_NORMAL);
3644         return const0_rtx;
3645       }
3646     case 0: /* length is 1, call fputc.  */
3647       {
3648         const char *p = c_getstr (TREE_VALUE (arglist));
3649
3650         if (p != NULL)
3651           {
3652             /* New argument list transforming fputs(string, stream) to
3653                fputc(string[0], stream).  */
3654             arglist =
3655               build_tree_list (NULL_TREE, TREE_VALUE (TREE_CHAIN (arglist)));
3656             arglist =
3657               tree_cons (NULL_TREE, build_int_2 (p[0], 0), arglist);
3658             fn = fn_fputc;
3659             break;
3660           }
3661       }
3662       /* FALLTHROUGH */
3663     case 1: /* length is greater than 1, call fwrite.  */
3664       {
3665         tree string_arg = TREE_VALUE (arglist);
3666
3667         /* New argument list transforming fputs(string, stream) to
3668            fwrite(string, 1, len, stream).  */
3669         arglist = build_tree_list (NULL_TREE, TREE_VALUE (TREE_CHAIN (arglist)));
3670         arglist = tree_cons (NULL_TREE, len, arglist);
3671         arglist = tree_cons (NULL_TREE, size_one_node, arglist);
3672         arglist = tree_cons (NULL_TREE, string_arg, arglist);
3673         fn = fn_fwrite;
3674         break;
3675       }
3676     default:
3677       abort ();
3678     }
3679
3680   return expand_expr (build_function_call_expr (fn, arglist),
3681                       (ignore ? const0_rtx : NULL_RTX),
3682                       VOIDmode, EXPAND_NORMAL);
3683 }
3684
3685 /* Expand a call to __builtin_expect.  We return our argument and emit a
3686    NOTE_INSN_EXPECTED_VALUE note.  This is the expansion of __builtin_expect in
3687    a non-jump context.  */
3688
3689 static rtx
3690 expand_builtin_expect (arglist, target)
3691      tree arglist;
3692      rtx target;
3693 {
3694   tree exp, c;
3695   rtx note, rtx_c;
3696
3697   if (arglist == NULL_TREE
3698       || TREE_CHAIN (arglist) == NULL_TREE)
3699     return const0_rtx;
3700   exp = TREE_VALUE (arglist);
3701   c = TREE_VALUE (TREE_CHAIN (arglist));
3702
3703   if (TREE_CODE (c) != INTEGER_CST)
3704     {
3705       error ("second arg to `__builtin_expect' must be a constant");
3706       c = integer_zero_node;
3707     }
3708
3709   target = expand_expr (exp, target, VOIDmode, EXPAND_NORMAL);
3710
3711   /* Don't bother with expected value notes for integral constants.  */
3712   if (GET_CODE (target) != CONST_INT)
3713     {
3714       /* We do need to force this into a register so that we can be
3715          moderately sure to be able to correctly interpret the branch
3716          condition later.  */
3717       target = force_reg (GET_MODE (target), target);
3718
3719       rtx_c = expand_expr (c, NULL_RTX, GET_MODE (target), EXPAND_NORMAL);
3720
3721       note = emit_note (NULL, NOTE_INSN_EXPECTED_VALUE);
3722       NOTE_EXPECTED_VALUE (note) = gen_rtx_EQ (VOIDmode, target, rtx_c);
3723     }
3724
3725   return target;
3726 }
3727
3728 /* Like expand_builtin_expect, except do this in a jump context.  This is
3729    called from do_jump if the conditional is a __builtin_expect.  Return either
3730    a list of insns to emit the jump or NULL if we cannot optimize
3731    __builtin_expect.  We need to optimize this at jump time so that machines
3732    like the PowerPC don't turn the test into a SCC operation, and then jump
3733    based on the test being 0/1.  */
3734
3735 rtx
3736 expand_builtin_expect_jump (exp, if_false_label, if_true_label)
3737      tree exp;
3738      rtx if_false_label;
3739      rtx if_true_label;
3740 {
3741   tree arglist = TREE_OPERAND (exp, 1);
3742   tree arg0 = TREE_VALUE (arglist);
3743   tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
3744   rtx ret = NULL_RTX;
3745
3746   /* Only handle __builtin_expect (test, 0) and
3747      __builtin_expect (test, 1).  */
3748   if (TREE_CODE (TREE_TYPE (arg1)) == INTEGER_TYPE
3749       && (integer_zerop (arg1) || integer_onep (arg1)))
3750     {
3751       int num_jumps = 0;
3752       rtx insn;
3753
3754       /* If we fail to locate an appropriate conditional jump, we'll
3755          fall back to normal evaluation.  Ensure that the expression
3756          can be re-evaluated.  */
3757       switch (unsafe_for_reeval (arg0))
3758         {
3759         case 0: /* Safe.  */
3760           break;
3761
3762         case 1: /* Mildly unsafe.  */
3763           arg0 = unsave_expr (arg0);
3764           break;
3765
3766         case 2: /* Wildly unsafe.  */
3767           return NULL_RTX;
3768         }
3769
3770       /* Expand the jump insns.  */
3771       start_sequence ();
3772       do_jump (arg0, if_false_label, if_true_label);
3773       ret = get_insns ();
3774       end_sequence ();
3775
3776       /* Now that the __builtin_expect has been validated, go through and add
3777          the expect's to each of the conditional jumps.  If we run into an
3778          error, just give up and generate the 'safe' code of doing a SCC
3779          operation and then doing a branch on that.  */
3780       insn = ret;
3781       while (insn != NULL_RTX)
3782         {
3783           rtx next = NEXT_INSN (insn);
3784           rtx pattern;
3785
3786           if (GET_CODE (insn) == JUMP_INSN && any_condjump_p (insn)
3787               && (pattern = pc_set (insn)) != NULL_RTX)
3788             {
3789               rtx ifelse = SET_SRC (pattern);
3790               rtx label;
3791               int taken;
3792
3793               if (GET_CODE (ifelse) != IF_THEN_ELSE)
3794                 goto do_next_insn;
3795
3796               if (GET_CODE (XEXP (ifelse, 1)) == LABEL_REF)
3797                 {
3798                   taken = 1;
3799                   label = XEXP (XEXP (ifelse, 1), 0);
3800                 }
3801               /* An inverted jump reverses the probabilities.  */
3802               else if (GET_CODE (XEXP (ifelse, 2)) == LABEL_REF)
3803                 {
3804                   taken = 0;
3805                   label = XEXP (XEXP (ifelse, 2), 0);
3806                 }
3807               /* We shouldn't have to worry about conditional returns during
3808                  the expansion stage, but handle it gracefully anyway.  */
3809               else if (GET_CODE (XEXP (ifelse, 1)) == RETURN)
3810                 {
3811                   taken = 1;
3812                   label = NULL_RTX;
3813                 }
3814               /* An inverted return reverses the probabilities.  */
3815               else if (GET_CODE (XEXP (ifelse, 2)) == RETURN)
3816                 {
3817                   taken = 0;
3818                   label = NULL_RTX;
3819                 }
3820               else
3821                 goto do_next_insn;
3822
3823               /* If the test is expected to fail, reverse the
3824                  probabilities.  */
3825               if (integer_zerop (arg1))
3826                 taken = 1 - taken;
3827
3828               /* If we are jumping to the false label, reverse the
3829                  probabilities.  */
3830               if (label == NULL_RTX)
3831                 ;               /* conditional return */
3832               else if (label == if_false_label)
3833                 taken = 1 - taken;
3834               else if (label != if_true_label)
3835                 goto do_next_insn;
3836
3837               num_jumps++;
3838               predict_insn_def (insn, PRED_BUILTIN_EXPECT, taken);
3839             }
3840
3841         do_next_insn:
3842           insn = next;
3843         }
3844
3845       /* If no jumps were modified, fail and do __builtin_expect the normal
3846          way.  */
3847       if (num_jumps == 0)
3848         ret = NULL_RTX;
3849     }
3850
3851   return ret;
3852 }
3853
3854 void
3855 expand_builtin_trap ()
3856 {
3857 #ifdef HAVE_trap
3858   if (HAVE_trap)
3859     emit_insn (gen_trap ());
3860   else
3861 #endif
3862     emit_library_call (abort_libfunc, LCT_NORETURN, VOIDmode, 0);
3863   emit_barrier ();
3864 }
3865 \f
3866 /* Expand an expression EXP that calls a built-in function,
3867    with result going to TARGET if that's convenient
3868    (and in mode MODE if that's convenient).
3869    SUBTARGET may be used as the target for computing one of EXP's operands.
3870    IGNORE is nonzero if the value is to be ignored.  */
3871
3872 rtx
3873 expand_builtin (exp, target, subtarget, mode, ignore)
3874      tree exp;
3875      rtx target;
3876      rtx subtarget;
3877      enum machine_mode mode;
3878      int ignore;
3879 {
3880   tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
3881   tree arglist = TREE_OPERAND (exp, 1);
3882   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
3883
3884   if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
3885     return (*targetm.expand_builtin) (exp, target, subtarget, mode, ignore);
3886
3887   /* When not optimizing, generate calls to library functions for a certain
3888      set of builtins.  */
3889   if (!optimize && !CALLED_AS_BUILT_IN (fndecl))
3890     switch (fcode)
3891       {
3892       case BUILT_IN_SQRT:
3893       case BUILT_IN_SQRTF:
3894       case BUILT_IN_SQRTL:
3895       case BUILT_IN_SIN:
3896       case BUILT_IN_SINF:
3897       case BUILT_IN_SINL:
3898       case BUILT_IN_COS:
3899       case BUILT_IN_COSF:
3900       case BUILT_IN_COSL:
3901       case BUILT_IN_EXP:
3902       case BUILT_IN_EXPF:
3903       case BUILT_IN_EXPL:
3904       case BUILT_IN_MEMSET:
3905       case BUILT_IN_MEMCPY:
3906       case BUILT_IN_MEMCMP:
3907       case BUILT_IN_BCMP:
3908       case BUILT_IN_BZERO:
3909       case BUILT_IN_INDEX:
3910       case BUILT_IN_RINDEX:
3911       case BUILT_IN_STRCHR:
3912       case BUILT_IN_STRRCHR:
3913       case BUILT_IN_STRLEN:
3914       case BUILT_IN_STRCPY:
3915       case BUILT_IN_STRNCPY:
3916       case BUILT_IN_STRNCMP:
3917       case BUILT_IN_STRSTR:
3918       case BUILT_IN_STRPBRK:
3919       case BUILT_IN_STRCAT:
3920       case BUILT_IN_STRNCAT:
3921       case BUILT_IN_STRSPN:
3922       case BUILT_IN_STRCSPN:
3923       case BUILT_IN_STRCMP:
3924       case BUILT_IN_FFS:
3925       case BUILT_IN_PUTCHAR:
3926       case BUILT_IN_PUTS:
3927       case BUILT_IN_PRINTF:
3928       case BUILT_IN_FPUTC:
3929       case BUILT_IN_FPUTS:
3930       case BUILT_IN_FWRITE:
3931       case BUILT_IN_PUTCHAR_UNLOCKED:
3932       case BUILT_IN_PUTS_UNLOCKED:
3933       case BUILT_IN_PRINTF_UNLOCKED:
3934       case BUILT_IN_FPUTC_UNLOCKED:
3935       case BUILT_IN_FPUTS_UNLOCKED:
3936       case BUILT_IN_FWRITE_UNLOCKED:
3937       case BUILT_IN_FLOOR:
3938       case BUILT_IN_FLOORF:
3939       case BUILT_IN_FLOORL:
3940       case BUILT_IN_CEIL:
3941       case BUILT_IN_CEILF:
3942       case BUILT_IN_CEILL:
3943       case BUILT_IN_TRUNC:
3944       case BUILT_IN_TRUNCF:
3945       case BUILT_IN_TRUNCL:
3946       case BUILT_IN_ROUND:
3947       case BUILT_IN_ROUNDF:
3948       case BUILT_IN_ROUNDL:
3949       case BUILT_IN_NEARBYINT:
3950       case BUILT_IN_NEARBYINTF:
3951       case BUILT_IN_NEARBYINTL:
3952         return expand_call (exp, target, ignore);
3953
3954       default:
3955         break;
3956       }
3957
3958   switch (fcode)
3959     {
3960     case BUILT_IN_ABS:
3961     case BUILT_IN_LABS:
3962     case BUILT_IN_LLABS:
3963     case BUILT_IN_IMAXABS:
3964     case BUILT_IN_FABS:
3965     case BUILT_IN_FABSF:
3966     case BUILT_IN_FABSL:
3967       /* build_function_call changes these into ABS_EXPR.  */
3968       abort ();
3969
3970     case BUILT_IN_CONJ:
3971     case BUILT_IN_CONJF:
3972     case BUILT_IN_CONJL:
3973     case BUILT_IN_CREAL:
3974     case BUILT_IN_CREALF:
3975     case BUILT_IN_CREALL:
3976     case BUILT_IN_CIMAG:
3977     case BUILT_IN_CIMAGF:
3978     case BUILT_IN_CIMAGL:
3979       /* expand_tree_builtin changes these into CONJ_EXPR, REALPART_EXPR
3980          and IMAGPART_EXPR.  */
3981       abort ();
3982
3983     case BUILT_IN_SIN:
3984     case BUILT_IN_SINF:
3985     case BUILT_IN_SINL:
3986     case BUILT_IN_COS:
3987     case BUILT_IN_COSF:
3988     case BUILT_IN_COSL:
3989     case BUILT_IN_EXP:
3990     case BUILT_IN_EXPF:
3991     case BUILT_IN_EXPL:
3992     case BUILT_IN_LOG:
3993     case BUILT_IN_LOGF:
3994     case BUILT_IN_LOGL:
3995       /* Treat these like sqrt only if unsafe math optimizations are allowed,
3996          because of possible accuracy problems.  */
3997       if (! flag_unsafe_math_optimizations)
3998         break;
3999     case BUILT_IN_SQRT:
4000     case BUILT_IN_SQRTF:
4001     case BUILT_IN_SQRTL:
4002     case BUILT_IN_FLOOR:
4003     case BUILT_IN_FLOORF:
4004     case BUILT_IN_FLOORL:
4005     case BUILT_IN_CEIL:
4006     case BUILT_IN_CEILF:
4007     case BUILT_IN_CEILL:
4008     case BUILT_IN_TRUNC:
4009     case BUILT_IN_TRUNCF:
4010     case BUILT_IN_TRUNCL:
4011     case BUILT_IN_ROUND:
4012     case BUILT_IN_ROUNDF:
4013     case BUILT_IN_ROUNDL:
4014     case BUILT_IN_NEARBYINT:
4015     case BUILT_IN_NEARBYINTF:
4016     case BUILT_IN_NEARBYINTL:
4017       target = expand_builtin_mathfn (exp, target, subtarget);
4018       if (target)
4019         return target;
4020       break;
4021
4022     case BUILT_IN_APPLY_ARGS:
4023       return expand_builtin_apply_args ();
4024
4025       /* __builtin_apply (FUNCTION, ARGUMENTS, ARGSIZE) invokes
4026          FUNCTION with a copy of the parameters described by
4027          ARGUMENTS, and ARGSIZE.  It returns a block of memory
4028          allocated on the stack into which is stored all the registers
4029          that might possibly be used for returning the result of a
4030          function.  ARGUMENTS is the value returned by
4031          __builtin_apply_args.  ARGSIZE is the number of bytes of
4032          arguments that must be copied.  ??? How should this value be
4033          computed?  We'll also need a safe worst case value for varargs
4034          functions.  */
4035     case BUILT_IN_APPLY:
4036       if (!validate_arglist (arglist, POINTER_TYPE,
4037                              POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)
4038           && !validate_arglist (arglist, REFERENCE_TYPE,
4039                                 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
4040         return const0_rtx;
4041       else
4042         {
4043           int i;
4044           tree t;
4045           rtx ops[3];
4046
4047           for (t = arglist, i = 0; t; t = TREE_CHAIN (t), i++)
4048             ops[i] = expand_expr (TREE_VALUE (t), NULL_RTX, VOIDmode, 0);
4049
4050           return expand_builtin_apply (ops[0], ops[1], ops[2]);
4051         }
4052
4053       /* __builtin_return (RESULT) causes the function to return the
4054          value described by RESULT.  RESULT is address of the block of
4055          memory returned by __builtin_apply.  */
4056     case BUILT_IN_RETURN:
4057       if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
4058         expand_builtin_return (expand_expr (TREE_VALUE (arglist),
4059                                             NULL_RTX, VOIDmode, 0));
4060       return const0_rtx;
4061
4062     case BUILT_IN_SAVEREGS:
4063       return expand_builtin_saveregs ();
4064
4065     case BUILT_IN_ARGS_INFO:
4066       return expand_builtin_args_info (exp);
4067
4068       /* Return the address of the first anonymous stack arg.  */
4069     case BUILT_IN_NEXT_ARG:
4070       return expand_builtin_next_arg (arglist);
4071
4072     case BUILT_IN_CLASSIFY_TYPE:
4073       return expand_builtin_classify_type (arglist);
4074
4075     case BUILT_IN_CONSTANT_P:
4076       return expand_builtin_constant_p (exp);
4077
4078     case BUILT_IN_FRAME_ADDRESS:
4079     case BUILT_IN_RETURN_ADDRESS:
4080       return expand_builtin_frame_address (exp);
4081
4082     /* Returns the address of the area where the structure is returned.
4083        0 otherwise.  */
4084     case BUILT_IN_AGGREGATE_INCOMING_ADDRESS:
4085       if (arglist != 0
4086           || ! AGGREGATE_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl)))
4087           || GET_CODE (DECL_RTL (DECL_RESULT (current_function_decl))) != MEM)
4088         return const0_rtx;
4089       else
4090         return XEXP (DECL_RTL (DECL_RESULT (current_function_decl)), 0);
4091
4092     case BUILT_IN_ALLOCA:
4093       target = expand_builtin_alloca (arglist, target);
4094       if (target)
4095         return target;
4096       break;
4097
4098     case BUILT_IN_FFS:
4099       target = expand_builtin_ffs (arglist, target, subtarget);
4100       if (target)
4101         return target;
4102       break;
4103
4104     case BUILT_IN_STRLEN:
4105       target = expand_builtin_strlen (exp, target);
4106       if (target)
4107         return target;
4108       break;
4109
4110     case BUILT_IN_STRCPY:
4111       target = expand_builtin_strcpy (exp, target, mode);
4112       if (target)
4113         return target;
4114       break;
4115
4116     case BUILT_IN_STRNCPY:
4117       target = expand_builtin_strncpy (arglist, target, mode);
4118       if (target)
4119         return target;
4120       break;
4121
4122     case BUILT_IN_STRCAT:
4123       target = expand_builtin_strcat (arglist, target, mode);
4124       if (target)
4125         return target;
4126       break;
4127
4128     case BUILT_IN_STRNCAT:
4129       target = expand_builtin_strncat (arglist, target, mode);
4130       if (target)
4131         return target;
4132       break;
4133
4134     case BUILT_IN_STRSPN:
4135       target = expand_builtin_strspn (arglist, target, mode);
4136       if (target)
4137         return target;
4138       break;
4139
4140     case BUILT_IN_STRCSPN:
4141       target = expand_builtin_strcspn (arglist, target, mode);
4142       if (target)
4143         return target;
4144       break;
4145
4146     case BUILT_IN_STRSTR:
4147       target = expand_builtin_strstr (arglist, target, mode);
4148       if (target)
4149         return target;
4150       break;
4151
4152     case BUILT_IN_STRPBRK:
4153       target = expand_builtin_strpbrk (arglist, target, mode);
4154       if (target)
4155         return target;
4156       break;
4157
4158     case BUILT_IN_INDEX:
4159     case BUILT_IN_STRCHR:
4160       target = expand_builtin_strchr (arglist, target, mode);
4161       if (target)
4162         return target;
4163       break;
4164
4165     case BUILT_IN_RINDEX:
4166     case BUILT_IN_STRRCHR:
4167       target = expand_builtin_strrchr (arglist, target, mode);
4168       if (target)
4169         return target;
4170       break;
4171
4172     case BUILT_IN_MEMCPY:
4173       target = expand_builtin_memcpy (arglist, target, mode);
4174       if (target)
4175         return target;
4176       break;
4177
4178     case BUILT_IN_MEMSET:
4179       target = expand_builtin_memset (exp, target, mode);
4180       if (target)
4181         return target;
4182       break;
4183
4184     case BUILT_IN_BZERO:
4185       target = expand_builtin_bzero (exp);
4186       if (target)
4187         return target;
4188       break;
4189
4190     case BUILT_IN_STRCMP:
4191       target = expand_builtin_strcmp (exp, target, mode);
4192       if (target)
4193         return target;
4194       break;
4195
4196     case BUILT_IN_STRNCMP:
4197       target = expand_builtin_strncmp (exp, target, mode);
4198       if (target)
4199         return target;
4200       break;
4201
4202     case BUILT_IN_BCMP:
4203     case BUILT_IN_MEMCMP:
4204       target = expand_builtin_memcmp (exp, arglist, target, mode);
4205       if (target)
4206         return target;
4207       break;
4208
4209     case BUILT_IN_SETJMP:
4210       target = expand_builtin_setjmp (arglist, target);
4211       if (target)
4212         return target;
4213       break;
4214
4215       /* __builtin_longjmp is passed a pointer to an array of five words.
4216          It's similar to the C library longjmp function but works with
4217          __builtin_setjmp above.  */
4218     case BUILT_IN_LONGJMP:
4219       if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
4220         break;
4221       else
4222         {
4223           rtx buf_addr = expand_expr (TREE_VALUE (arglist), subtarget,
4224                                       VOIDmode, 0);
4225           rtx value = expand_expr (TREE_VALUE (TREE_CHAIN (arglist)),
4226                                    NULL_RTX, VOIDmode, 0);
4227
4228           if (value != const1_rtx)
4229             {
4230               error ("__builtin_longjmp second argument must be 1");
4231               return const0_rtx;
4232             }
4233
4234           expand_builtin_longjmp (buf_addr, value);
4235           return const0_rtx;
4236         }
4237
4238     case BUILT_IN_TRAP:
4239       expand_builtin_trap ();
4240       return const0_rtx;
4241
4242     case BUILT_IN_FPUTS:
4243       target = expand_builtin_fputs (arglist, ignore,/*unlocked=*/ 0);
4244       if (target)
4245         return target;
4246       break;
4247     case BUILT_IN_FPUTS_UNLOCKED:
4248       target = expand_builtin_fputs (arglist, ignore,/*unlocked=*/ 1);
4249       if (target)
4250         return target;
4251       break;
4252
4253       /* Various hooks for the DWARF 2 __throw routine.  */
4254     case BUILT_IN_UNWIND_INIT:
4255       expand_builtin_unwind_init ();
4256       return const0_rtx;
4257     case BUILT_IN_DWARF_CFA:
4258       return virtual_cfa_rtx;
4259 #ifdef DWARF2_UNWIND_INFO
4260     case BUILT_IN_DWARF_FP_REGNUM:
4261       return expand_builtin_dwarf_fp_regnum ();
4262     case BUILT_IN_INIT_DWARF_REG_SIZES:
4263       expand_builtin_init_dwarf_reg_sizes (TREE_VALUE (arglist));
4264       return const0_rtx;
4265 #endif
4266     case BUILT_IN_FROB_RETURN_ADDR:
4267       return expand_builtin_frob_return_addr (TREE_VALUE (arglist));
4268     case BUILT_IN_EXTRACT_RETURN_ADDR:
4269       return expand_builtin_extract_return_addr (TREE_VALUE (arglist));
4270     case BUILT_IN_EH_RETURN:
4271       expand_builtin_eh_return (TREE_VALUE (arglist),
4272                                 TREE_VALUE (TREE_CHAIN (arglist)));
4273       return const0_rtx;
4274 #ifdef EH_RETURN_DATA_REGNO
4275     case BUILT_IN_EH_RETURN_DATA_REGNO:
4276       return expand_builtin_eh_return_data_regno (arglist);
4277 #endif
4278     case BUILT_IN_VA_START:
4279     case BUILT_IN_STDARG_START:
4280       return expand_builtin_va_start (arglist);
4281     case BUILT_IN_VA_END:
4282       return expand_builtin_va_end (arglist);
4283     case BUILT_IN_VA_COPY:
4284       return expand_builtin_va_copy (arglist);
4285     case BUILT_IN_EXPECT:
4286       return expand_builtin_expect (arglist, target);
4287     case BUILT_IN_PREFETCH:
4288       expand_builtin_prefetch (arglist);
4289       return const0_rtx;
4290
4291
4292     default:    /* just do library call, if unknown builtin */
4293       if (!DECL_ASSEMBLER_NAME_SET_P (fndecl))
4294         error ("built-in function `%s' not currently supported",
4295                IDENTIFIER_POINTER (DECL_NAME (fndecl)));
4296     }
4297
4298   /* The switch statement above can drop through to cause the function
4299      to be called normally.  */
4300   return expand_call (exp, target, ignore);
4301 }
4302
4303 /* Determine whether a tree node represents a call to a built-in
4304    math function.  If the tree T is a call to a built-in function
4305    taking a single real argument, then the return value is the
4306    DECL_FUNCTION_CODE of the call, e.g. BUILT_IN_SQRT.  Otherwise
4307    the return value is END_BUILTINS.  */
4308    
4309 enum built_in_function
4310 builtin_mathfn_code (t)
4311      tree t;
4312 {
4313   tree fndecl, arglist;
4314
4315   if (TREE_CODE (t) != CALL_EXPR
4316       || TREE_CODE (TREE_OPERAND (t, 0)) != ADDR_EXPR)
4317     return END_BUILTINS;
4318
4319   fndecl = TREE_OPERAND (TREE_OPERAND (t, 0), 0);
4320   if (TREE_CODE (fndecl) != FUNCTION_DECL
4321       || ! DECL_BUILT_IN (fndecl)
4322       || DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
4323     return END_BUILTINS;
4324
4325   arglist = TREE_OPERAND (t, 1);
4326   if (! arglist
4327       || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != REAL_TYPE
4328       || TREE_CHAIN (arglist))
4329     return END_BUILTINS;
4330
4331   return DECL_FUNCTION_CODE (fndecl);
4332 }
4333
4334 /* Fold a call to __builtin_constant_p, if we know it will evaluate to a
4335    constant.  ARGLIST is the argument list of the call.  */
4336
4337 static tree
4338 fold_builtin_constant_p (arglist)
4339      tree arglist;
4340 {
4341   if (arglist == 0)
4342     return 0;
4343
4344   arglist = TREE_VALUE (arglist);
4345
4346   /* We return 1 for a numeric type that's known to be a constant
4347      value at compile-time or for an aggregate type that's a
4348      literal constant.  */
4349   STRIP_NOPS (arglist);
4350
4351   /* If we know this is a constant, emit the constant of one.  */
4352   if (TREE_CODE_CLASS (TREE_CODE (arglist)) == 'c'
4353       || (TREE_CODE (arglist) == CONSTRUCTOR
4354           && TREE_CONSTANT (arglist))
4355       || (TREE_CODE (arglist) == ADDR_EXPR
4356           && TREE_CODE (TREE_OPERAND (arglist, 0)) == STRING_CST))
4357     return integer_one_node;
4358
4359   /* If we aren't going to be running CSE or this expression
4360      has side effects, show we don't know it to be a constant.
4361      Likewise if it's a pointer or aggregate type since in those
4362      case we only want literals, since those are only optimized
4363      when generating RTL, not later.
4364      And finally, if we are compiling an initializer, not code, we
4365      need to return a definite result now; there's not going to be any
4366      more optimization done.  */
4367   if (TREE_SIDE_EFFECTS (arglist) || cse_not_expected
4368       || AGGREGATE_TYPE_P (TREE_TYPE (arglist))
4369       || POINTER_TYPE_P (TREE_TYPE (arglist))
4370       || cfun == 0)
4371     return integer_zero_node;
4372
4373   return 0;
4374 }
4375
4376 /* Fold a call to __builtin_classify_type.  */
4377
4378 static tree
4379 fold_builtin_classify_type (arglist)
4380      tree arglist;
4381 {
4382   if (arglist == 0)
4383     return build_int_2 (no_type_class, 0);
4384
4385   return build_int_2 (type_to_class (TREE_TYPE (TREE_VALUE (arglist))), 0);
4386 }
4387
4388 /* Fold a call to __builtin_inf or __builtin_huge_val.  */
4389
4390 static tree
4391 fold_builtin_inf (type, warn)
4392      tree type;
4393      int warn;
4394 {
4395   REAL_VALUE_TYPE real;
4396
4397   if (!MODE_HAS_INFINITIES (TYPE_MODE (type)) && warn)
4398     warning ("target format does not support infinity");
4399
4400   real_inf (&real);
4401   return build_real (type, real);
4402 }
4403
4404 /* Fold a call to __builtin_nan or __builtin_nans.  */
4405
4406 static tree
4407 fold_builtin_nan (arglist, type, quiet)
4408      tree arglist, type;
4409      int quiet;
4410 {
4411   REAL_VALUE_TYPE real;
4412   const char *str;
4413
4414   if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
4415     return 0;
4416   str = c_getstr (TREE_VALUE (arglist));
4417   if (!str)
4418     return 0;
4419
4420   if (!real_nan (&real, str, quiet, TYPE_MODE (type)))
4421     return 0;
4422
4423   return build_real (type, real);
4424 }
4425
4426 /* Used by constant folding to eliminate some builtin calls early.  EXP is
4427    the CALL_EXPR of a call to a builtin function.  */
4428
4429 tree
4430 fold_builtin (exp)
4431      tree exp;
4432 {
4433   tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
4434   tree arglist = TREE_OPERAND (exp, 1);
4435   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
4436
4437   if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
4438     return 0;
4439
4440   switch (fcode)
4441     {
4442     case BUILT_IN_CONSTANT_P:
4443       return fold_builtin_constant_p (arglist);
4444
4445     case BUILT_IN_CLASSIFY_TYPE:
4446       return fold_builtin_classify_type (arglist);
4447
4448     case BUILT_IN_STRLEN:
4449       if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
4450         {
4451           tree len = c_strlen (TREE_VALUE (arglist));
4452           if (len)
4453             {
4454               /* Convert from the internal "sizetype" type to "size_t".  */
4455               if (size_type_node)
4456                 len = convert (size_type_node, len);
4457               return len;
4458             }
4459         }
4460       break;
4461
4462     case BUILT_IN_SQRT:
4463     case BUILT_IN_SQRTF:
4464     case BUILT_IN_SQRTL:
4465       if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
4466         {
4467           enum built_in_function fcode;
4468           tree arg = TREE_VALUE (arglist);
4469
4470           /* Optimize sqrt of constant value.  */
4471           if (TREE_CODE (arg) == REAL_CST
4472               && ! TREE_CONSTANT_OVERFLOW (arg))
4473             {
4474               enum machine_mode mode;
4475               REAL_VALUE_TYPE r, x;
4476
4477               x = TREE_REAL_CST (arg);
4478               mode = TYPE_MODE (TREE_TYPE (arg));
4479               if (real_sqrt (&r, mode, &x)
4480                   || (!flag_trapping_math && !flag_errno_math))
4481                 return build_real (TREE_TYPE (arg), r);
4482             }
4483
4484           /* Optimize sqrt(exp(x)) = exp(x/2.0).  */
4485           fcode = builtin_mathfn_code (arg);
4486           if (flag_unsafe_math_optimizations
4487               && (fcode == BUILT_IN_EXP
4488                   || fcode == BUILT_IN_EXPF
4489                   || fcode == BUILT_IN_EXPL))
4490             {
4491               tree expfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
4492               arg = build (RDIV_EXPR, TREE_TYPE (arg),
4493                            TREE_VALUE (TREE_OPERAND (arg, 1)),
4494                            build_real (TREE_TYPE (arg), dconst2));
4495               arglist = build_tree_list (NULL_TREE, arg);
4496               return build_function_call_expr (expfn, arglist);
4497             }
4498         }
4499       break;
4500
4501     case BUILT_IN_EXP:
4502     case BUILT_IN_EXPF:
4503     case BUILT_IN_EXPL:
4504       if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
4505         {
4506           enum built_in_function fcode;
4507           tree arg = TREE_VALUE (arglist);
4508
4509           /* Optimize exp(0.0) = 1.0.  */
4510           if (real_zerop (arg))
4511             return build_real (TREE_TYPE (arg), dconst1);
4512
4513           /* Optimize exp(log(x)) = x.  */
4514           fcode = builtin_mathfn_code (arg);
4515           if (flag_unsafe_math_optimizations
4516               && (fcode == BUILT_IN_LOG
4517                   || fcode == BUILT_IN_LOGF
4518                   || fcode == BUILT_IN_LOGL))
4519             return TREE_VALUE (TREE_OPERAND (arg, 1));
4520         }
4521       break;
4522
4523     case BUILT_IN_LOG:
4524     case BUILT_IN_LOGF:
4525     case BUILT_IN_LOGL:
4526       if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
4527         {
4528           enum built_in_function fcode;
4529           tree arg = TREE_VALUE (arglist);
4530
4531           /* Optimize log(1.0) = 0.0.  */
4532           if (real_onep (arg))
4533             return build_real (TREE_TYPE (arg), dconst0);
4534
4535           /* Optimize log(exp(x)) = x.  */
4536           fcode = builtin_mathfn_code (arg);
4537           if (flag_unsafe_math_optimizations
4538               && (fcode == BUILT_IN_EXP
4539                   || fcode == BUILT_IN_EXPF
4540                   || fcode == BUILT_IN_EXPL))
4541             return TREE_VALUE (TREE_OPERAND (arg, 1));
4542
4543           /* Optimize log(sqrt(x)) = log(x)/2.0.  */
4544           if (flag_unsafe_math_optimizations
4545               && (fcode == BUILT_IN_SQRT
4546                   || fcode == BUILT_IN_SQRTF
4547                   || fcode == BUILT_IN_SQRTL))
4548             {
4549               tree logfn = build_function_call_expr (fndecl,
4550                                                      TREE_OPERAND (arg, 1));
4551               return fold (build (RDIV_EXPR, TREE_TYPE (arg), logfn,
4552                                   build_real (TREE_TYPE (arg), dconst2)));
4553             }
4554         }
4555       break;
4556
4557     case BUILT_IN_INF:
4558     case BUILT_IN_INFF:
4559     case BUILT_IN_INFL:
4560       return fold_builtin_inf (TREE_TYPE (TREE_TYPE (fndecl)), true);
4561
4562     case BUILT_IN_HUGE_VAL:
4563     case BUILT_IN_HUGE_VALF:
4564     case BUILT_IN_HUGE_VALL:
4565       return fold_builtin_inf (TREE_TYPE (TREE_TYPE (fndecl)), false);
4566
4567     case BUILT_IN_NAN:
4568     case BUILT_IN_NANF:
4569     case BUILT_IN_NANL:
4570       return fold_builtin_nan (arglist, TREE_TYPE (TREE_TYPE (fndecl)), true);
4571
4572     case BUILT_IN_NANS:
4573     case BUILT_IN_NANSF:
4574     case BUILT_IN_NANSL:
4575       return fold_builtin_nan (arglist, TREE_TYPE (TREE_TYPE (fndecl)), false);
4576
4577     default:
4578       break;
4579     }
4580
4581   return 0;
4582 }
4583
4584 /* Conveniently construct a function call expression.  */
4585
4586 tree
4587 build_function_call_expr (fn, arglist)
4588      tree fn, arglist;
4589 {
4590   tree call_expr;
4591
4592   call_expr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
4593   call_expr = build (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)),
4594                      call_expr, arglist);
4595   TREE_SIDE_EFFECTS (call_expr) = 1;
4596   return fold (call_expr);
4597 }
4598
4599 /* This function validates the types of a function call argument list
4600    represented as a tree chain of parameters against a specified list
4601    of tree_codes.  If the last specifier is a 0, that represents an
4602    ellipses, otherwise the last specifier must be a VOID_TYPE.  */
4603
4604 static int
4605 validate_arglist VPARAMS ((tree arglist, ...))
4606 {
4607   enum tree_code code;
4608   int res = 0;
4609
4610   VA_OPEN (ap, arglist);
4611   VA_FIXEDARG (ap, tree, arglist);
4612
4613   do
4614     {
4615       code = va_arg (ap, enum tree_code);
4616       switch (code)
4617         {
4618         case 0:
4619           /* This signifies an ellipses, any further arguments are all ok.  */
4620           res = 1;
4621           goto end;
4622         case VOID_TYPE:
4623           /* This signifies an endlink, if no arguments remain, return
4624              true, otherwise return false.  */
4625           res = arglist == 0;
4626           goto end;
4627         default:
4628           /* If no parameters remain or the parameter's code does not
4629              match the specified code, return false.  Otherwise continue
4630              checking any remaining arguments.  */
4631           if (arglist == 0
4632               || code != TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))))
4633             goto end;
4634           break;
4635         }
4636       arglist = TREE_CHAIN (arglist);
4637     }
4638   while (1);
4639
4640   /* We need gotos here since we can only have one VA_CLOSE in a
4641      function.  */
4642  end: ;
4643   VA_CLOSE (ap);
4644
4645   return res;
4646 }
4647
4648 /* Default version of target-specific builtin setup that does nothing.  */
4649
4650 void
4651 default_init_builtins ()
4652 {
4653 }
4654
4655 /* Default target-specific builtin expander that does nothing.  */
4656
4657 rtx
4658 default_expand_builtin (exp, target, subtarget, mode, ignore)
4659      tree exp ATTRIBUTE_UNUSED;
4660      rtx target ATTRIBUTE_UNUSED;
4661      rtx subtarget ATTRIBUTE_UNUSED;
4662      enum machine_mode mode ATTRIBUTE_UNUSED;
4663      int ignore ATTRIBUTE_UNUSED;
4664 {
4665   return NULL_RTX;
4666 }
4667
4668 /* Instantiate all remaining CONSTANT_P_RTX nodes.  */
4669
4670 void
4671 purge_builtin_constant_p ()
4672 {
4673   rtx insn, done, set;
4674   rtx arg, new, note;
4675   basic_block bb;
4676
4677   FOR_EACH_BB (bb)
4678     {
4679       done = NEXT_INSN (bb->end);
4680       for (insn = bb->head; insn != done; insn = NEXT_INSN (insn))
4681         if (INSN_P (insn)
4682             && (set = single_set (insn)) != NULL_RTX
4683             && GET_CODE (SET_SRC (set)) == CONSTANT_P_RTX)
4684           {
4685             arg = XEXP (SET_SRC (set), 0);
4686             new = CONSTANT_P (arg) ? const1_rtx : const0_rtx;
4687             validate_change (insn, &SET_SRC (set), new, 0);
4688
4689             /* Remove the REG_EQUAL note from the insn.  */
4690             if ((note = find_reg_note (insn, REG_EQUAL, NULL_RTX)) != 0)
4691               remove_note (insn, note);
4692           }
4693     }
4694 }
4695