OSDN Git Service

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