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