OSDN Git Service

* builtins.c (expand_builtin_strncpy): Use integer_zerop instead
[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 ((TREE_CODE (len) == INTEGER_CST && integer_zerop (len))
2612           || (p && *p == '\0'))
2613         {
2614           /* Evaluate and ignore the src and len parameters in case
2615              they have side-effects.  */
2616           expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
2617           expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
2618           return expand_expr (dst, target, mode, EXPAND_NORMAL);
2619         }
2620
2621       /* If the requested len is greater than or equal to the string
2622          length, call strcat.  */
2623       if (TREE_CODE (len) == INTEGER_CST && p
2624           && compare_tree_int (len, strlen (p)) >= 0)
2625         {
2626           tree newarglist
2627             = tree_cons (NULL_TREE, dst, build_tree_list (NULL_TREE, src));
2628           tree fn = built_in_decls[BUILT_IN_STRCAT];
2629
2630           /* If the replacement _DECL isn't initialized, don't do the
2631              transformation.  */
2632           if (!fn)
2633             return 0;
2634
2635           return expand_expr (build_function_call_expr (fn, newarglist),
2636                               target, mode, EXPAND_NORMAL);
2637         }
2638       return 0;
2639     }
2640 }
2641
2642 /* Expand expression EXP, which is a call to the strspn builtin.
2643    Return 0 if we failed the caller should emit a normal call,
2644    otherwise try to get the result in TARGET, if convenient.  */
2645
2646 static rtx
2647 expand_builtin_strspn (arglist, target, mode)
2648      tree arglist;
2649      rtx target;
2650      enum machine_mode mode;
2651 {
2652   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2653     return 0;
2654   else
2655     {
2656       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
2657       const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
2658
2659       /* If both arguments are constants, evaluate at compile-time.  */
2660       if (p1 && p2)
2661         {
2662           const size_t r = strspn (p1, p2);
2663           return expand_expr (size_int (r), target, mode, EXPAND_NORMAL);
2664         }
2665
2666       /* If either argument is "", return 0.  */
2667       if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
2668         {
2669           /* Evaluate and ignore both arguments in case either one has
2670              side-effects.  */
2671           expand_expr (s1, const0_rtx, VOIDmode, EXPAND_NORMAL);
2672           expand_expr (s2, const0_rtx, VOIDmode, EXPAND_NORMAL);
2673           return const0_rtx;
2674         }
2675       return 0;
2676     }
2677 }
2678
2679 /* Expand expression EXP, which is a call to the strcspn builtin.
2680    Return 0 if we failed the caller should emit a normal call,
2681    otherwise try to get the result in TARGET, if convenient.  */
2682
2683 static rtx
2684 expand_builtin_strcspn (arglist, target, mode)
2685      tree arglist;
2686      rtx target;
2687      enum machine_mode mode;
2688 {
2689   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2690     return 0;
2691   else
2692     {
2693       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
2694       const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
2695
2696       /* If both arguments are constants, evaluate at compile-time.  */
2697       if (p1 && p2)
2698         {
2699           const size_t r = strcspn (p1, p2);
2700           return expand_expr (size_int (r), target, mode, EXPAND_NORMAL);
2701         }
2702
2703       /* If the first argument is "", return 0.  */
2704       if (p1 && *p1 == '\0')
2705         {
2706           /* Evaluate and ignore argument s2 in case it has
2707              side-effects.  */
2708           expand_expr (s2, const0_rtx, VOIDmode, EXPAND_NORMAL);
2709           return const0_rtx;
2710         }
2711
2712       /* If the second argument is "", return __builtin_strlen(s1).  */
2713       if (p2 && *p2 == '\0')
2714         {
2715           tree newarglist = build_tree_list (NULL_TREE, s1),
2716             fn = built_in_decls[BUILT_IN_STRLEN];
2717
2718           /* If the replacement _DECL isn't initialized, don't do the
2719              transformation.  */
2720           if (!fn)
2721             return 0;
2722
2723           return expand_expr (build_function_call_expr (fn, newarglist),
2724                               target, mode, EXPAND_NORMAL);
2725         }
2726       return 0;
2727     }
2728 }
2729
2730 /* Expand a call to __builtin_saveregs, generating the result in TARGET,
2731    if that's convenient.  */
2732
2733 rtx
2734 expand_builtin_saveregs ()
2735 {
2736   rtx val, seq;
2737
2738   /* Don't do __builtin_saveregs more than once in a function.
2739      Save the result of the first call and reuse it.  */
2740   if (saveregs_value != 0)
2741     return saveregs_value;
2742
2743   /* When this function is called, it means that registers must be
2744      saved on entry to this function.  So we migrate the call to the
2745      first insn of this function.  */
2746
2747   start_sequence ();
2748
2749 #ifdef EXPAND_BUILTIN_SAVEREGS
2750   /* Do whatever the machine needs done in this case.  */
2751   val = EXPAND_BUILTIN_SAVEREGS ();
2752 #else
2753   /* ??? We used to try and build up a call to the out of line function,
2754      guessing about what registers needed saving etc.  This became much
2755      harder with __builtin_va_start, since we don't have a tree for a
2756      call to __builtin_saveregs to fall back on.  There was exactly one
2757      port (i860) that used this code, and I'm unconvinced it could actually
2758      handle the general case.  So we no longer try to handle anything
2759      weird and make the backend absorb the evil.  */
2760
2761   error ("__builtin_saveregs not supported by this target");
2762   val = const0_rtx;
2763 #endif
2764
2765   seq = get_insns ();
2766   end_sequence ();
2767
2768   saveregs_value = val;
2769
2770   /* Put the sequence after the NOTE that starts the function.  If this
2771      is inside a SEQUENCE, make the outer-level insn chain current, so
2772      the code is placed at the start of the function.  */
2773   push_topmost_sequence ();
2774   emit_insns_after (seq, get_insns ());
2775   pop_topmost_sequence ();
2776
2777   return val;
2778 }
2779
2780 /* __builtin_args_info (N) returns word N of the arg space info
2781    for the current function.  The number and meanings of words
2782    is controlled by the definition of CUMULATIVE_ARGS.  */
2783
2784 static rtx
2785 expand_builtin_args_info (exp)
2786      tree exp;
2787 {
2788   tree arglist = TREE_OPERAND (exp, 1);
2789   int nwords = sizeof (CUMULATIVE_ARGS) / sizeof (int);
2790   int *word_ptr = (int *) &current_function_args_info;
2791 #if 0
2792   /* These are used by the code below that is if 0'ed away */
2793   int i;
2794   tree type, elts, result;
2795 #endif
2796
2797   if (sizeof (CUMULATIVE_ARGS) % sizeof (int) != 0)
2798     abort ();
2799
2800   if (arglist != 0)
2801     {
2802       if (!host_integerp (TREE_VALUE (arglist), 0))
2803         error ("argument of `__builtin_args_info' must be constant");
2804       else
2805         {
2806           HOST_WIDE_INT wordnum = tree_low_cst (TREE_VALUE (arglist), 0);
2807
2808           if (wordnum < 0 || wordnum >= nwords)
2809             error ("argument of `__builtin_args_info' out of range");
2810           else
2811             return GEN_INT (word_ptr[wordnum]);
2812         }
2813     }
2814   else
2815     error ("missing argument in `__builtin_args_info'");
2816
2817   return const0_rtx;
2818
2819 #if 0
2820   for (i = 0; i < nwords; i++)
2821     elts = tree_cons (NULL_TREE, build_int_2 (word_ptr[i], 0));
2822
2823   type = build_array_type (integer_type_node,
2824                            build_index_type (build_int_2 (nwords, 0)));
2825   result = build (CONSTRUCTOR, type, NULL_TREE, nreverse (elts));
2826   TREE_CONSTANT (result) = 1;
2827   TREE_STATIC (result) = 1;
2828   result = build1 (INDIRECT_REF, build_pointer_type (type), result);
2829   TREE_CONSTANT (result) = 1;
2830   return expand_expr (result, NULL_RTX, VOIDmode, 0);
2831 #endif
2832 }
2833
2834 /* Expand ARGLIST, from a call to __builtin_next_arg.  */
2835
2836 static rtx
2837 expand_builtin_next_arg (arglist)
2838      tree arglist;
2839 {
2840   tree fntype = TREE_TYPE (current_function_decl);
2841
2842   if ((TYPE_ARG_TYPES (fntype) == 0
2843        || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
2844            == void_type_node))
2845       && ! current_function_varargs)
2846     {
2847       error ("`va_start' used in function with fixed args");
2848       return const0_rtx;
2849     }
2850
2851   if (arglist)
2852     {
2853       tree last_parm = tree_last (DECL_ARGUMENTS (current_function_decl));
2854       tree arg = TREE_VALUE (arglist);
2855
2856       /* Strip off all nops for the sake of the comparison.  This
2857          is not quite the same as STRIP_NOPS.  It does more.
2858          We must also strip off INDIRECT_EXPR for C++ reference
2859          parameters.  */
2860       while (TREE_CODE (arg) == NOP_EXPR
2861              || TREE_CODE (arg) == CONVERT_EXPR
2862              || TREE_CODE (arg) == NON_LVALUE_EXPR
2863              || TREE_CODE (arg) == INDIRECT_REF)
2864         arg = TREE_OPERAND (arg, 0);
2865       if (arg != last_parm)
2866         warning ("second parameter of `va_start' not last named argument");
2867     }
2868   else if (! current_function_varargs)
2869     /* Evidently an out of date version of <stdarg.h>; can't validate
2870        va_start's second argument, but can still work as intended.  */
2871     warning ("`__builtin_next_arg' called without an argument");
2872
2873   return expand_binop (Pmode, add_optab,
2874                        current_function_internal_arg_pointer,
2875                        current_function_arg_offset_rtx,
2876                        NULL_RTX, 0, OPTAB_LIB_WIDEN);
2877 }
2878
2879 /* Make it easier for the backends by protecting the valist argument
2880    from multiple evaluations.  */
2881
2882 static tree
2883 stabilize_va_list (valist, needs_lvalue)
2884      tree valist;
2885      int needs_lvalue;
2886 {
2887   if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
2888     {
2889       if (TREE_SIDE_EFFECTS (valist))
2890         valist = save_expr (valist);
2891
2892       /* For this case, the backends will be expecting a pointer to
2893          TREE_TYPE (va_list_type_node), but it's possible we've
2894          actually been given an array (an actual va_list_type_node).
2895          So fix it.  */
2896       if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
2897         {
2898           tree p1 = build_pointer_type (TREE_TYPE (va_list_type_node));
2899           tree p2 = build_pointer_type (va_list_type_node);
2900
2901           valist = build1 (ADDR_EXPR, p2, valist);
2902           valist = fold (build1 (NOP_EXPR, p1, valist));
2903         }
2904     }
2905   else
2906     {
2907       tree pt;
2908
2909       if (! needs_lvalue)
2910         {
2911           if (! TREE_SIDE_EFFECTS (valist))
2912             return valist;
2913
2914           pt = build_pointer_type (va_list_type_node);
2915           valist = fold (build1 (ADDR_EXPR, pt, valist));
2916           TREE_SIDE_EFFECTS (valist) = 1;
2917         }
2918
2919       if (TREE_SIDE_EFFECTS (valist))
2920         valist = save_expr (valist);
2921       valist = fold (build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (valist)),
2922                              valist));
2923     }
2924
2925   return valist;
2926 }
2927
2928 /* The "standard" implementation of va_start: just assign `nextarg' to
2929    the variable.  */
2930
2931 void
2932 std_expand_builtin_va_start (stdarg_p, valist, nextarg)
2933      int stdarg_p;
2934      tree valist;
2935      rtx nextarg;
2936 {
2937   tree t;
2938
2939   if (! stdarg_p)
2940     {
2941       /* The dummy named parameter is declared as a 'word' sized
2942          object, but if a 'word' is smaller than an 'int', it would
2943          have been promoted to int when it was added to the arglist.  */
2944       int align = PARM_BOUNDARY / BITS_PER_UNIT;
2945       int size = MAX (UNITS_PER_WORD,
2946                       GET_MODE_SIZE (TYPE_MODE (integer_type_node)));
2947       int offset = ((size + align - 1) / align) * align;
2948       nextarg = plus_constant (nextarg, -offset);
2949     }
2950
2951   t = build (MODIFY_EXPR, TREE_TYPE (valist), valist,
2952              make_tree (ptr_type_node, nextarg));
2953   TREE_SIDE_EFFECTS (t) = 1;
2954
2955   expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
2956 }
2957
2958 /* Expand ARGLIST, which from a call to __builtin_stdarg_va_start or
2959    __builtin_varargs_va_start, depending on STDARG_P.  */
2960
2961 static rtx
2962 expand_builtin_va_start (stdarg_p, arglist)
2963      int stdarg_p;
2964      tree arglist;
2965 {
2966   rtx nextarg;
2967   tree chain = arglist, valist;
2968
2969   if (stdarg_p)
2970     nextarg = expand_builtin_next_arg (chain = TREE_CHAIN (arglist));
2971   else
2972     nextarg = expand_builtin_next_arg (NULL_TREE);
2973
2974   if (TREE_CHAIN (chain))
2975     error ("too many arguments to function `va_start'");
2976
2977   valist = stabilize_va_list (TREE_VALUE (arglist), 1);
2978
2979 #ifdef EXPAND_BUILTIN_VA_START
2980   EXPAND_BUILTIN_VA_START (stdarg_p, valist, nextarg);
2981 #else
2982   std_expand_builtin_va_start (stdarg_p, valist, nextarg);
2983 #endif
2984
2985   return const0_rtx;
2986 }
2987
2988 /* The "standard" implementation of va_arg: read the value from the
2989    current (padded) address and increment by the (padded) size.  */
2990
2991 rtx
2992 std_expand_builtin_va_arg (valist, type)
2993      tree valist, type;
2994 {
2995   tree addr_tree, t;
2996   HOST_WIDE_INT align;
2997   HOST_WIDE_INT rounded_size;
2998   rtx addr;
2999
3000   /* Compute the rounded size of the type.  */
3001   align = PARM_BOUNDARY / BITS_PER_UNIT;
3002   rounded_size = (((int_size_in_bytes (type) + align - 1) / align) * align);
3003
3004   /* Get AP.  */
3005   addr_tree = valist;
3006   if (PAD_VARARGS_DOWN)
3007     {
3008       /* Small args are padded downward.  */
3009
3010       HOST_WIDE_INT adj
3011         = rounded_size > align ? rounded_size : int_size_in_bytes (type);
3012
3013       addr_tree = build (PLUS_EXPR, TREE_TYPE (addr_tree), addr_tree,
3014                          build_int_2 (rounded_size - adj, 0));
3015     }
3016
3017   addr = expand_expr (addr_tree, NULL_RTX, Pmode, EXPAND_NORMAL);
3018   addr = copy_to_reg (addr);
3019
3020   /* Compute new value for AP.  */
3021   t = build (MODIFY_EXPR, TREE_TYPE (valist), valist,
3022              build (PLUS_EXPR, TREE_TYPE (valist), valist,
3023                     build_int_2 (rounded_size, 0)));
3024   TREE_SIDE_EFFECTS (t) = 1;
3025   expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
3026
3027   return addr;
3028 }
3029
3030 /* Expand __builtin_va_arg, which is not really a builtin function, but
3031    a very special sort of operator.  */
3032
3033 rtx
3034 expand_builtin_va_arg (valist, type)
3035      tree valist, type;
3036 {
3037   rtx addr, result;
3038   tree promoted_type, want_va_type, have_va_type;
3039
3040   /* Verify that valist is of the proper type.  */
3041
3042   want_va_type = va_list_type_node;
3043   have_va_type = TREE_TYPE (valist);
3044   if (TREE_CODE (want_va_type) == ARRAY_TYPE)
3045     {
3046       /* If va_list is an array type, the argument may have decayed
3047          to a pointer type, e.g. by being passed to another function.
3048          In that case, unwrap both types so that we can compare the
3049          underlying records.  */
3050       if (TREE_CODE (have_va_type) == ARRAY_TYPE
3051           || TREE_CODE (have_va_type) == POINTER_TYPE)
3052         {
3053           want_va_type = TREE_TYPE (want_va_type);
3054           have_va_type = TREE_TYPE (have_va_type);
3055         }
3056     }
3057   if (TYPE_MAIN_VARIANT (want_va_type) != TYPE_MAIN_VARIANT (have_va_type))
3058     {
3059       error ("first argument to `va_arg' not of type `va_list'");
3060       addr = const0_rtx;
3061     }
3062
3063   /* Generate a diagnostic for requesting data of a type that cannot
3064      be passed through `...' due to type promotion at the call site.  */
3065   else if ((promoted_type = (*lang_type_promotes_to) (type)) != NULL_TREE)
3066     {
3067       const char *name = "<anonymous type>", *pname = 0;
3068       static int gave_help;
3069
3070       if (TYPE_NAME (type))
3071         {
3072           if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE)
3073             name = IDENTIFIER_POINTER (TYPE_NAME (type));
3074           else if (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
3075                    && DECL_NAME (TYPE_NAME (type)))
3076             name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type)));
3077         }
3078       if (TYPE_NAME (promoted_type))
3079         {
3080           if (TREE_CODE (TYPE_NAME (promoted_type)) == IDENTIFIER_NODE)
3081             pname = IDENTIFIER_POINTER (TYPE_NAME (promoted_type));
3082           else if (TREE_CODE (TYPE_NAME (promoted_type)) == TYPE_DECL
3083                    && DECL_NAME (TYPE_NAME (promoted_type)))
3084             pname = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (promoted_type)));
3085         }
3086
3087       error ("`%s' is promoted to `%s' when passed through `...'", name, pname);
3088       if (! gave_help)
3089         {
3090           gave_help = 1;
3091           error ("(so you should pass `%s' not `%s' to `va_arg')", pname, name);
3092         }
3093
3094       addr = const0_rtx;
3095     }
3096   else
3097     {
3098       /* Make it easier for the backends by protecting the valist argument
3099          from multiple evaluations.  */
3100       valist = stabilize_va_list (valist, 0);
3101
3102 #ifdef EXPAND_BUILTIN_VA_ARG
3103       addr = EXPAND_BUILTIN_VA_ARG (valist, type);
3104 #else
3105       addr = std_expand_builtin_va_arg (valist, type);
3106 #endif
3107     }
3108
3109 #ifdef POINTERS_EXTEND_UNSIGNED
3110   if (GET_MODE (addr) != Pmode)
3111     addr = convert_memory_address (Pmode, addr);
3112 #endif
3113
3114   result = gen_rtx_MEM (TYPE_MODE (type), addr);
3115   set_mem_alias_set (result, get_varargs_alias_set ());
3116
3117   return result;
3118 }
3119
3120 /* Expand ARGLIST, from a call to __builtin_va_end.  */
3121
3122 static rtx
3123 expand_builtin_va_end (arglist)
3124      tree arglist;
3125 {
3126   tree valist = TREE_VALUE (arglist);
3127
3128 #ifdef EXPAND_BUILTIN_VA_END
3129   valist = stabilize_va_list (valist, 0);
3130   EXPAND_BUILTIN_VA_END(arglist);
3131 #else
3132   /* Evaluate for side effects, if needed.  I hate macros that don't
3133      do that.  */
3134   if (TREE_SIDE_EFFECTS (valist))
3135     expand_expr (valist, const0_rtx, VOIDmode, EXPAND_NORMAL);
3136 #endif
3137
3138   return const0_rtx;
3139 }
3140
3141 /* Expand ARGLIST, from a call to __builtin_va_copy.  We do this as a
3142    builtin rather than just as an assignment in stdarg.h because of the
3143    nastiness of array-type va_list types.  */
3144
3145 static rtx
3146 expand_builtin_va_copy (arglist)
3147      tree arglist;
3148 {
3149   tree dst, src, t;
3150
3151   dst = TREE_VALUE (arglist);
3152   src = TREE_VALUE (TREE_CHAIN (arglist));
3153
3154   dst = stabilize_va_list (dst, 1);
3155   src = stabilize_va_list (src, 0);
3156
3157   if (TREE_CODE (va_list_type_node) != ARRAY_TYPE)
3158     {
3159       t = build (MODIFY_EXPR, va_list_type_node, dst, src);
3160       TREE_SIDE_EFFECTS (t) = 1;
3161       expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
3162     }
3163   else
3164     {
3165       rtx dstb, srcb, size;
3166
3167       /* Evaluate to pointers.  */
3168       dstb = expand_expr (dst, NULL_RTX, Pmode, EXPAND_NORMAL);
3169       srcb = expand_expr (src, NULL_RTX, Pmode, EXPAND_NORMAL);
3170       size = expand_expr (TYPE_SIZE_UNIT (va_list_type_node), NULL_RTX,
3171                           VOIDmode, EXPAND_NORMAL);
3172
3173 #ifdef POINTERS_EXTEND_UNSIGNED
3174       if (GET_MODE (dstb) != Pmode)
3175         dstb = convert_memory_address (Pmode, dstb);
3176
3177       if (GET_MODE (srcb) != Pmode)
3178         srcb = convert_memory_address (Pmode, srcb);
3179 #endif
3180
3181       /* "Dereference" to BLKmode memories.  */
3182       dstb = gen_rtx_MEM (BLKmode, dstb);
3183       set_mem_alias_set (dstb, get_alias_set (TREE_TYPE (TREE_TYPE (dst))));
3184       set_mem_align (dstb, TYPE_ALIGN (va_list_type_node));
3185       srcb = gen_rtx_MEM (BLKmode, srcb);
3186       set_mem_alias_set (srcb, get_alias_set (TREE_TYPE (TREE_TYPE (src))));
3187       set_mem_align (srcb, TYPE_ALIGN (va_list_type_node));
3188
3189       /* Copy.  */
3190       emit_block_move (dstb, srcb, size);
3191     }
3192
3193   return const0_rtx;
3194 }
3195
3196 /* Expand a call to one of the builtin functions __builtin_frame_address or
3197    __builtin_return_address.  */
3198
3199 static rtx
3200 expand_builtin_frame_address (exp)
3201      tree exp;
3202 {
3203   tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
3204   tree arglist = TREE_OPERAND (exp, 1);
3205
3206   /* The argument must be a nonnegative integer constant.
3207      It counts the number of frames to scan up the stack.
3208      The value is the return address saved in that frame.  */
3209   if (arglist == 0)
3210     /* Warning about missing arg was already issued.  */
3211     return const0_rtx;
3212   else if (! host_integerp (TREE_VALUE (arglist), 1))
3213     {
3214       if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
3215         error ("invalid arg to `__builtin_frame_address'");
3216       else
3217         error ("invalid arg to `__builtin_return_address'");
3218       return const0_rtx;
3219     }
3220   else
3221     {
3222       rtx tem
3223         = expand_builtin_return_addr (DECL_FUNCTION_CODE (fndecl),
3224                                       tree_low_cst (TREE_VALUE (arglist), 1),
3225                                       hard_frame_pointer_rtx);
3226
3227       /* Some ports cannot access arbitrary stack frames.  */
3228       if (tem == NULL)
3229         {
3230           if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
3231             warning ("unsupported arg to `__builtin_frame_address'");
3232           else
3233             warning ("unsupported arg to `__builtin_return_address'");
3234           return const0_rtx;
3235         }
3236
3237       /* For __builtin_frame_address, return what we've got.  */
3238       if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
3239         return tem;
3240
3241       if (GET_CODE (tem) != REG
3242           && ! CONSTANT_P (tem))
3243         tem = copy_to_mode_reg (Pmode, tem);
3244       return tem;
3245     }
3246 }
3247
3248 /* Expand a call to the alloca builtin, with arguments ARGLIST.  Return 0 if
3249    we failed and the caller should emit a normal call, otherwise try to get
3250    the result in TARGET, if convenient.  */
3251
3252 static rtx
3253 expand_builtin_alloca (arglist, target)
3254      tree arglist;
3255      rtx target;
3256 {
3257   rtx op0;
3258   rtx result;
3259
3260   if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
3261     return 0;
3262
3263   /* Compute the argument.  */
3264   op0 = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
3265
3266   /* Allocate the desired space.  */
3267   result = allocate_dynamic_stack_space (op0, target, BITS_PER_UNIT);
3268
3269 #ifdef POINTERS_EXTEND_UNSIGNED
3270   if (GET_MODE (result) != ptr_mode)
3271     result = convert_memory_address (ptr_mode, result);
3272 #endif
3273
3274   return result;
3275 }
3276
3277 /* Expand a call to the ffs builtin.  The arguments are in ARGLIST.
3278    Return 0 if a normal call should be emitted rather than expanding the
3279    function in-line.  If convenient, the result should be placed in TARGET.
3280    SUBTARGET may be used as the target for computing one of EXP's operands.  */
3281
3282 static rtx
3283 expand_builtin_ffs (arglist, target, subtarget)
3284      tree arglist;
3285      rtx target, subtarget;
3286 {
3287   rtx op0;
3288   if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
3289     return 0;
3290
3291   /* Compute the argument.  */
3292   op0 = expand_expr (TREE_VALUE (arglist), subtarget, VOIDmode, 0);
3293   /* Compute ffs, into TARGET if possible.
3294      Set TARGET to wherever the result comes back.  */
3295   target = expand_unop (TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist))),
3296                         ffs_optab, op0, target, 1);
3297   if (target == 0)
3298     abort ();
3299   return target;
3300 }
3301
3302 /* If the string passed to fputs is a constant and is one character
3303    long, we attempt to transform this call into __builtin_fputc().  */
3304
3305 static rtx
3306 expand_builtin_fputs (arglist, ignore, unlocked)
3307      tree arglist;
3308      int ignore;
3309      int unlocked;
3310 {
3311   tree len, fn;
3312   tree fn_fputc = unlocked ? built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
3313     : built_in_decls[BUILT_IN_FPUTC];
3314   tree fn_fwrite = unlocked ? built_in_decls[BUILT_IN_FWRITE_UNLOCKED]
3315     : built_in_decls[BUILT_IN_FWRITE];
3316
3317   /* If the return value is used, or the replacement _DECL isn't
3318      initialized, don't do the transformation.  */
3319   if (!ignore || !fn_fputc || !fn_fwrite)
3320     return 0;
3321
3322   /* Verify the arguments in the original call.  */
3323   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3324     return 0;
3325
3326   /* Get the length of the string passed to fputs.  If the length
3327      can't be determined, punt.  */
3328   if (!(len = c_strlen (TREE_VALUE (arglist)))
3329       || TREE_CODE (len) != INTEGER_CST)
3330     return 0;
3331
3332   switch (compare_tree_int (len, 1))
3333     {
3334     case -1: /* length is 0, delete the call entirely .  */
3335       {
3336         /* Evaluate and ignore the argument in case it has
3337            side-effects.  */
3338         expand_expr (TREE_VALUE (TREE_CHAIN (arglist)), const0_rtx,
3339                      VOIDmode, EXPAND_NORMAL);
3340         return const0_rtx;
3341       }
3342     case 0: /* length is 1, call fputc.  */
3343       {
3344         const char *p = c_getstr (TREE_VALUE (arglist));
3345
3346         if (p != NULL)
3347           {
3348             /* New argument list transforming fputs(string, stream) to
3349                fputc(string[0], stream).  */
3350             arglist =
3351               build_tree_list (NULL_TREE, TREE_VALUE (TREE_CHAIN (arglist)));
3352             arglist =
3353               tree_cons (NULL_TREE, build_int_2 (p[0], 0), arglist);
3354             fn = fn_fputc;
3355             break;
3356           }
3357       }
3358       /* FALLTHROUGH */
3359     case 1: /* length is greater than 1, call fwrite.  */
3360       {
3361         tree string_arg = TREE_VALUE (arglist);
3362
3363         /* New argument list transforming fputs(string, stream) to
3364            fwrite(string, 1, len, stream).  */
3365         arglist = build_tree_list (NULL_TREE, TREE_VALUE (TREE_CHAIN (arglist)));
3366         arglist = tree_cons (NULL_TREE, len, arglist);
3367         arglist = tree_cons (NULL_TREE, size_one_node, arglist);
3368         arglist = tree_cons (NULL_TREE, string_arg, arglist);
3369         fn = fn_fwrite;
3370         break;
3371       }
3372     default:
3373       abort ();
3374     }
3375
3376   return expand_expr (build_function_call_expr (fn, arglist),
3377                       (ignore ? const0_rtx : NULL_RTX),
3378                       VOIDmode, EXPAND_NORMAL);
3379 }
3380
3381 /* Expand a call to __builtin_expect.  We return our argument and emit a
3382    NOTE_INSN_EXPECTED_VALUE note.  This is the expansion of __builtin_expect in
3383    a non-jump context.  */
3384
3385 static rtx
3386 expand_builtin_expect (arglist, target)
3387      tree arglist;
3388      rtx target;
3389 {
3390   tree exp, c;
3391   rtx note, rtx_c;
3392
3393   if (arglist == NULL_TREE
3394       || TREE_CHAIN (arglist) == NULL_TREE)
3395     return const0_rtx;
3396   exp = TREE_VALUE (arglist);
3397   c = TREE_VALUE (TREE_CHAIN (arglist));
3398
3399   if (TREE_CODE (c) != INTEGER_CST)
3400     {
3401       error ("second arg to `__builtin_expect' must be a constant");
3402       c = integer_zero_node;
3403     }
3404
3405   target = expand_expr (exp, target, VOIDmode, EXPAND_NORMAL);
3406
3407   /* Don't bother with expected value notes for integral constants.  */
3408   if (GET_CODE (target) != CONST_INT)
3409     {
3410       /* We do need to force this into a register so that we can be
3411          moderately sure to be able to correctly interpret the branch
3412          condition later.  */
3413       target = force_reg (GET_MODE (target), target);
3414
3415       rtx_c = expand_expr (c, NULL_RTX, GET_MODE (target), EXPAND_NORMAL);
3416
3417       note = emit_note (NULL, NOTE_INSN_EXPECTED_VALUE);
3418       NOTE_EXPECTED_VALUE (note) = gen_rtx_EQ (VOIDmode, target, rtx_c);
3419     }
3420
3421   return target;
3422 }
3423
3424 /* Like expand_builtin_expect, except do this in a jump context.  This is
3425    called from do_jump if the conditional is a __builtin_expect.  Return either
3426    a SEQUENCE of insns to emit the jump or NULL if we cannot optimize
3427    __builtin_expect.  We need to optimize this at jump time so that machines
3428    like the PowerPC don't turn the test into a SCC operation, and then jump
3429    based on the test being 0/1.  */
3430
3431 rtx
3432 expand_builtin_expect_jump (exp, if_false_label, if_true_label)
3433      tree exp;
3434      rtx if_false_label;
3435      rtx if_true_label;
3436 {
3437   tree arglist = TREE_OPERAND (exp, 1);
3438   tree arg0 = TREE_VALUE (arglist);
3439   tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
3440   rtx ret = NULL_RTX;
3441
3442   /* Only handle __builtin_expect (test, 0) and
3443      __builtin_expect (test, 1).  */
3444   if (TREE_CODE (TREE_TYPE (arg1)) == INTEGER_TYPE
3445       && (integer_zerop (arg1) || integer_onep (arg1)))
3446     {
3447       int j;
3448       int num_jumps = 0;
3449
3450       /* If we fail to locate an appropriate conditional jump, we'll
3451          fall back to normal evaluation.  Ensure that the expression
3452          can be re-evaluated.  */
3453       switch (unsafe_for_reeval (arg0))
3454         {
3455         case 0: /* Safe.  */
3456           break;
3457
3458         case 1: /* Mildly unsafe.  */
3459           arg0 = unsave_expr (arg0);
3460           break;
3461
3462         case 2: /* Wildly unsafe.  */
3463           return NULL_RTX;
3464         }
3465
3466       /* Expand the jump insns.  */
3467       start_sequence ();
3468       do_jump (arg0, if_false_label, if_true_label);
3469       ret = gen_sequence ();
3470       end_sequence ();
3471
3472       /* Now that the __builtin_expect has been validated, go through and add
3473          the expect's to each of the conditional jumps.  If we run into an
3474          error, just give up and generate the 'safe' code of doing a SCC
3475          operation and then doing a branch on that.  */
3476       for (j = 0; j < XVECLEN (ret, 0); j++)
3477         {
3478           rtx insn = XVECEXP (ret, 0, j);
3479           rtx pattern;
3480
3481           if (GET_CODE (insn) == JUMP_INSN && any_condjump_p (insn)
3482               && (pattern = pc_set (insn)) != NULL_RTX)
3483             {
3484               rtx ifelse = SET_SRC (pattern);
3485               rtx label;
3486               int taken;
3487
3488               if (GET_CODE (ifelse) != IF_THEN_ELSE)
3489                 continue;
3490
3491               if (GET_CODE (XEXP (ifelse, 1)) == LABEL_REF)
3492                 {
3493                   taken = 1;
3494                   label = XEXP (XEXP (ifelse, 1), 0);
3495                 }
3496               /* An inverted jump reverses the probabilities.  */
3497               else if (GET_CODE (XEXP (ifelse, 2)) == LABEL_REF)
3498                 {
3499                   taken = 0;
3500                   label = XEXP (XEXP (ifelse, 2), 0);
3501                 }
3502               /* We shouldn't have to worry about conditional returns during
3503                  the expansion stage, but handle it gracefully anyway.  */
3504               else if (GET_CODE (XEXP (ifelse, 1)) == RETURN)
3505                 {
3506                   taken = 1;
3507                   label = NULL_RTX;
3508                 }
3509               /* An inverted return reverses the probabilities.  */
3510               else if (GET_CODE (XEXP (ifelse, 2)) == RETURN)
3511                 {
3512                   taken = 0;
3513                   label = NULL_RTX;
3514                 }
3515               else
3516                 continue;
3517
3518               /* If the test is expected to fail, reverse the
3519                  probabilities.  */
3520               if (integer_zerop (arg1))
3521                 taken = 1 - taken;
3522
3523               /* If we are jumping to the false label, reverse the
3524                  probabilities.  */
3525               if (label == NULL_RTX)
3526                 ;               /* conditional return */
3527               else if (label == if_false_label)
3528                 taken = 1 - taken;
3529               else if (label != if_true_label)
3530                 continue;
3531
3532               num_jumps++;
3533               predict_insn_def (insn, PRED_BUILTIN_EXPECT, taken);
3534             }
3535         }
3536
3537       /* If no jumps were modified, fail and do __builtin_expect the normal
3538          way.  */
3539       if (num_jumps == 0)
3540         ret = NULL_RTX;
3541     }
3542
3543   return ret;
3544 }
3545 \f
3546 /* Expand an expression EXP that calls a built-in function,
3547    with result going to TARGET if that's convenient
3548    (and in mode MODE if that's convenient).
3549    SUBTARGET may be used as the target for computing one of EXP's operands.
3550    IGNORE is nonzero if the value is to be ignored.  */
3551
3552 rtx
3553 expand_builtin (exp, target, subtarget, mode, ignore)
3554      tree exp;
3555      rtx target;
3556      rtx subtarget;
3557      enum machine_mode mode;
3558      int ignore;
3559 {
3560   tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
3561   tree arglist = TREE_OPERAND (exp, 1);
3562   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
3563
3564   if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
3565     return (*targetm.expand_builtin) (exp, target, subtarget, mode, ignore);
3566
3567   /* When not optimizing, generate calls to library functions for a certain
3568      set of builtins.  */
3569   if (!optimize && !CALLED_AS_BUILT_IN (fndecl))
3570     switch (fcode)
3571       {
3572       case BUILT_IN_SIN:
3573       case BUILT_IN_COS:
3574       case BUILT_IN_SQRT:
3575       case BUILT_IN_SQRTF:
3576       case BUILT_IN_SQRTL:
3577       case BUILT_IN_MEMSET:
3578       case BUILT_IN_MEMCPY:
3579       case BUILT_IN_MEMCMP:
3580       case BUILT_IN_BCMP:
3581       case BUILT_IN_BZERO:
3582       case BUILT_IN_INDEX:
3583       case BUILT_IN_RINDEX:
3584       case BUILT_IN_STRCHR:
3585       case BUILT_IN_STRRCHR:
3586       case BUILT_IN_STRLEN:
3587       case BUILT_IN_STRCPY:
3588       case BUILT_IN_STRNCPY:
3589       case BUILT_IN_STRNCMP:
3590       case BUILT_IN_STRSTR:
3591       case BUILT_IN_STRPBRK:
3592       case BUILT_IN_STRCAT:
3593       case BUILT_IN_STRNCAT:
3594       case BUILT_IN_STRSPN:
3595       case BUILT_IN_STRCSPN:
3596       case BUILT_IN_STRCMP:
3597       case BUILT_IN_FFS:
3598       case BUILT_IN_PUTCHAR:
3599       case BUILT_IN_PUTS:
3600       case BUILT_IN_PRINTF:
3601       case BUILT_IN_FPUTC:
3602       case BUILT_IN_FPUTS:
3603       case BUILT_IN_FWRITE:
3604       case BUILT_IN_PUTCHAR_UNLOCKED:
3605       case BUILT_IN_PUTS_UNLOCKED:
3606       case BUILT_IN_PRINTF_UNLOCKED:
3607       case BUILT_IN_FPUTC_UNLOCKED:
3608       case BUILT_IN_FPUTS_UNLOCKED:
3609       case BUILT_IN_FWRITE_UNLOCKED:
3610         return expand_call (exp, target, ignore);
3611
3612       default:
3613         break;
3614     }
3615
3616   switch (fcode)
3617     {
3618     case BUILT_IN_ABS:
3619     case BUILT_IN_LABS:
3620     case BUILT_IN_LLABS:
3621     case BUILT_IN_IMAXABS:
3622     case BUILT_IN_FABS:
3623     case BUILT_IN_FABSF:
3624     case BUILT_IN_FABSL:
3625       /* build_function_call changes these into ABS_EXPR.  */
3626       abort ();
3627
3628     case BUILT_IN_CONJ:
3629     case BUILT_IN_CONJF:
3630     case BUILT_IN_CONJL:
3631     case BUILT_IN_CREAL:
3632     case BUILT_IN_CREALF:
3633     case BUILT_IN_CREALL:
3634     case BUILT_IN_CIMAG:
3635     case BUILT_IN_CIMAGF:
3636     case BUILT_IN_CIMAGL:
3637       /* expand_tree_builtin changes these into CONJ_EXPR, REALPART_EXPR
3638          and IMAGPART_EXPR.  */
3639       abort ();
3640
3641     case BUILT_IN_SIN:
3642     case BUILT_IN_SINF:
3643     case BUILT_IN_SINL:
3644     case BUILT_IN_COS:
3645     case BUILT_IN_COSF:
3646     case BUILT_IN_COSL:
3647       /* Treat these like sqrt only if unsafe math optimizations are allowed,
3648          because of possible accuracy problems.  */
3649       if (! flag_unsafe_math_optimizations)
3650         break;
3651     case BUILT_IN_SQRT:
3652     case BUILT_IN_SQRTF:
3653     case BUILT_IN_SQRTL:
3654       target = expand_builtin_mathfn (exp, target, subtarget);
3655       if (target)
3656         return target;
3657       break;
3658
3659     case BUILT_IN_FMOD:
3660       break;
3661
3662     case BUILT_IN_APPLY_ARGS:
3663       return expand_builtin_apply_args ();
3664
3665       /* __builtin_apply (FUNCTION, ARGUMENTS, ARGSIZE) invokes
3666          FUNCTION with a copy of the parameters described by
3667          ARGUMENTS, and ARGSIZE.  It returns a block of memory
3668          allocated on the stack into which is stored all the registers
3669          that might possibly be used for returning the result of a
3670          function.  ARGUMENTS is the value returned by
3671          __builtin_apply_args.  ARGSIZE is the number of bytes of
3672          arguments that must be copied.  ??? How should this value be
3673          computed?  We'll also need a safe worst case value for varargs
3674          functions.  */
3675     case BUILT_IN_APPLY:
3676       if (!validate_arglist (arglist, POINTER_TYPE,
3677                              POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)
3678           && !validate_arglist (arglist, REFERENCE_TYPE,
3679                                 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3680         return const0_rtx;
3681       else
3682         {
3683           int i;
3684           tree t;
3685           rtx ops[3];
3686
3687           for (t = arglist, i = 0; t; t = TREE_CHAIN (t), i++)
3688             ops[i] = expand_expr (TREE_VALUE (t), NULL_RTX, VOIDmode, 0);
3689
3690           return expand_builtin_apply (ops[0], ops[1], ops[2]);
3691         }
3692
3693       /* __builtin_return (RESULT) causes the function to return the
3694          value described by RESULT.  RESULT is address of the block of
3695          memory returned by __builtin_apply.  */
3696     case BUILT_IN_RETURN:
3697       if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
3698         expand_builtin_return (expand_expr (TREE_VALUE (arglist),
3699                                             NULL_RTX, VOIDmode, 0));
3700       return const0_rtx;
3701
3702     case BUILT_IN_SAVEREGS:
3703       return expand_builtin_saveregs ();
3704
3705     case BUILT_IN_ARGS_INFO:
3706       return expand_builtin_args_info (exp);
3707
3708       /* Return the address of the first anonymous stack arg.  */
3709     case BUILT_IN_NEXT_ARG:
3710       return expand_builtin_next_arg (arglist);
3711
3712     case BUILT_IN_CLASSIFY_TYPE:
3713       return expand_builtin_classify_type (arglist);
3714
3715     case BUILT_IN_CONSTANT_P:
3716       return expand_builtin_constant_p (exp);
3717
3718     case BUILT_IN_FRAME_ADDRESS:
3719     case BUILT_IN_RETURN_ADDRESS:
3720       return expand_builtin_frame_address (exp);
3721
3722     /* Returns the address of the area where the structure is returned.
3723        0 otherwise.  */
3724     case BUILT_IN_AGGREGATE_INCOMING_ADDRESS:
3725       if (arglist != 0
3726           || ! AGGREGATE_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl)))
3727           || GET_CODE (DECL_RTL (DECL_RESULT (current_function_decl))) != MEM)
3728         return const0_rtx;
3729       else
3730         return XEXP (DECL_RTL (DECL_RESULT (current_function_decl)), 0);
3731
3732     case BUILT_IN_ALLOCA:
3733       target = expand_builtin_alloca (arglist, target);
3734       if (target)
3735         return target;
3736       break;
3737
3738     case BUILT_IN_FFS:
3739       target = expand_builtin_ffs (arglist, target, subtarget);
3740       if (target)
3741         return target;
3742       break;
3743
3744     case BUILT_IN_STRLEN:
3745       target = expand_builtin_strlen (exp, target);
3746       if (target)
3747         return target;
3748       break;
3749
3750     case BUILT_IN_STRCPY:
3751       target = expand_builtin_strcpy (exp, target, mode);
3752       if (target)
3753         return target;
3754       break;
3755
3756     case BUILT_IN_STRNCPY:
3757       target = expand_builtin_strncpy (arglist, target, mode);
3758       if (target)
3759         return target;
3760       break;
3761
3762     case BUILT_IN_STRCAT:
3763       target = expand_builtin_strcat (arglist, target, mode);
3764       if (target)
3765         return target;
3766       break;
3767
3768     case BUILT_IN_STRNCAT:
3769       target = expand_builtin_strncat (arglist, target, mode);
3770       if (target)
3771         return target;
3772       break;
3773
3774     case BUILT_IN_STRSPN:
3775       target = expand_builtin_strspn (arglist, target, mode);
3776       if (target)
3777         return target;
3778       break;
3779
3780     case BUILT_IN_STRCSPN:
3781       target = expand_builtin_strcspn (arglist, target, mode);
3782       if (target)
3783         return target;
3784       break;
3785
3786     case BUILT_IN_STRSTR:
3787       target = expand_builtin_strstr (arglist, target, mode);
3788       if (target)
3789         return target;
3790       break;
3791
3792     case BUILT_IN_STRPBRK:
3793       target = expand_builtin_strpbrk (arglist, target, mode);
3794       if (target)
3795         return target;
3796       break;
3797
3798     case BUILT_IN_INDEX:
3799     case BUILT_IN_STRCHR:
3800       target = expand_builtin_strchr (arglist, target, mode);
3801       if (target)
3802         return target;
3803       break;
3804
3805     case BUILT_IN_RINDEX:
3806     case BUILT_IN_STRRCHR:
3807       target = expand_builtin_strrchr (arglist, target, mode);
3808       if (target)
3809         return target;
3810       break;
3811
3812     case BUILT_IN_MEMCPY:
3813       target = expand_builtin_memcpy (arglist, target, mode);
3814       if (target)
3815         return target;
3816       break;
3817
3818     case BUILT_IN_MEMSET:
3819       target = expand_builtin_memset (exp, target, mode);
3820       if (target)
3821         return target;
3822       break;
3823
3824     case BUILT_IN_BZERO:
3825       target = expand_builtin_bzero (exp);
3826       if (target)
3827         return target;
3828       break;
3829
3830     case BUILT_IN_STRCMP:
3831       target = expand_builtin_strcmp (exp, target, mode);
3832       if (target)
3833         return target;
3834       break;
3835
3836     case BUILT_IN_STRNCMP:
3837       target = expand_builtin_strncmp (exp, target, mode);
3838       if (target)
3839         return target;
3840       break;
3841
3842     case BUILT_IN_BCMP:
3843     case BUILT_IN_MEMCMP:
3844       target = expand_builtin_memcmp (exp, arglist, target, mode);
3845       if (target)
3846         return target;
3847       break;
3848
3849     case BUILT_IN_SETJMP:
3850       target = expand_builtin_setjmp (arglist, target);
3851       if (target)
3852         return target;
3853       break;
3854
3855       /* __builtin_longjmp is passed a pointer to an array of five words.
3856          It's similar to the C library longjmp function but works with
3857          __builtin_setjmp above.  */
3858     case BUILT_IN_LONGJMP:
3859       if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3860         break;
3861       else
3862         {
3863           rtx buf_addr = expand_expr (TREE_VALUE (arglist), subtarget,
3864                                       VOIDmode, 0);
3865           rtx value = expand_expr (TREE_VALUE (TREE_CHAIN (arglist)),
3866                                    NULL_RTX, VOIDmode, 0);
3867
3868           if (value != const1_rtx)
3869             {
3870               error ("__builtin_longjmp second argument must be 1");
3871               return const0_rtx;
3872             }
3873
3874           expand_builtin_longjmp (buf_addr, value);
3875           return const0_rtx;
3876         }
3877
3878     case BUILT_IN_TRAP:
3879 #ifdef HAVE_trap
3880       if (HAVE_trap)
3881         emit_insn (gen_trap ());
3882       else
3883 #endif
3884         error ("__builtin_trap not supported by this target");
3885       emit_barrier ();
3886       return const0_rtx;
3887
3888     case BUILT_IN_PUTCHAR:
3889     case BUILT_IN_PUTS:
3890     case BUILT_IN_FPUTC:
3891     case BUILT_IN_FWRITE:
3892     case BUILT_IN_PUTCHAR_UNLOCKED:
3893     case BUILT_IN_PUTS_UNLOCKED:
3894     case BUILT_IN_FPUTC_UNLOCKED:
3895     case BUILT_IN_FWRITE_UNLOCKED:
3896       break;
3897     case BUILT_IN_FPUTS:
3898       target = expand_builtin_fputs (arglist, ignore,/*unlocked=*/ 0);
3899       if (target)
3900         return target;
3901       break;
3902     case BUILT_IN_FPUTS_UNLOCKED:
3903       target = expand_builtin_fputs (arglist, ignore,/*unlocked=*/ 1);
3904       if (target)
3905         return target;
3906       break;
3907
3908       /* Various hooks for the DWARF 2 __throw routine.  */
3909     case BUILT_IN_UNWIND_INIT:
3910       expand_builtin_unwind_init ();
3911       return const0_rtx;
3912     case BUILT_IN_DWARF_CFA:
3913       return virtual_cfa_rtx;
3914 #ifdef DWARF2_UNWIND_INFO
3915     case BUILT_IN_DWARF_FP_REGNUM:
3916       return expand_builtin_dwarf_fp_regnum ();
3917     case BUILT_IN_INIT_DWARF_REG_SIZES:
3918       expand_builtin_init_dwarf_reg_sizes (TREE_VALUE (arglist));
3919       return const0_rtx;
3920 #endif
3921     case BUILT_IN_FROB_RETURN_ADDR:
3922       return expand_builtin_frob_return_addr (TREE_VALUE (arglist));
3923     case BUILT_IN_EXTRACT_RETURN_ADDR:
3924       return expand_builtin_extract_return_addr (TREE_VALUE (arglist));
3925     case BUILT_IN_EH_RETURN:
3926       expand_builtin_eh_return (TREE_VALUE (arglist),
3927                                 TREE_VALUE (TREE_CHAIN (arglist)));
3928       return const0_rtx;
3929 #ifdef EH_RETURN_DATA_REGNO
3930     case BUILT_IN_EH_RETURN_DATA_REGNO:
3931       return expand_builtin_eh_return_data_regno (arglist);
3932 #endif
3933     case BUILT_IN_VARARGS_START:
3934       return expand_builtin_va_start (0, arglist);
3935     case BUILT_IN_STDARG_START:
3936       return expand_builtin_va_start (1, arglist);
3937     case BUILT_IN_VA_END:
3938       return expand_builtin_va_end (arglist);
3939     case BUILT_IN_VA_COPY:
3940       return expand_builtin_va_copy (arglist);
3941     case BUILT_IN_EXPECT:
3942       return expand_builtin_expect (arglist, target);
3943     case BUILT_IN_PREFETCH:
3944       expand_builtin_prefetch (arglist);
3945       return const0_rtx;
3946
3947
3948     default:                    /* just do library call, if unknown builtin */
3949       error ("built-in function `%s' not currently supported",
3950              IDENTIFIER_POINTER (DECL_NAME (fndecl)));
3951     }
3952
3953   /* The switch statement above can drop through to cause the function
3954      to be called normally.  */
3955   return expand_call (exp, target, ignore);
3956 }
3957
3958 /* Fold a call to __builtin_constant_p, if we know it will evaluate to a
3959    constant.  ARGLIST is the argument list of the call.  */
3960
3961 static tree
3962 fold_builtin_constant_p (arglist)
3963      tree arglist;
3964 {
3965   if (arglist == 0)
3966     return 0;
3967
3968   arglist = TREE_VALUE (arglist);
3969
3970   /* We return 1 for a numeric type that's known to be a constant
3971      value at compile-time or for an aggregate type that's a
3972      literal constant.  */
3973   STRIP_NOPS (arglist);
3974
3975   /* If we know this is a constant, emit the constant of one.  */
3976   if (TREE_CODE_CLASS (TREE_CODE (arglist)) == 'c'
3977       || (TREE_CODE (arglist) == CONSTRUCTOR
3978           && TREE_CONSTANT (arglist))
3979       || (TREE_CODE (arglist) == ADDR_EXPR
3980           && TREE_CODE (TREE_OPERAND (arglist, 0)) == STRING_CST))
3981     return integer_one_node;
3982
3983   /* If we aren't going to be running CSE or this expression
3984      has side effects, show we don't know it to be a constant.
3985      Likewise if it's a pointer or aggregate type since in those
3986      case we only want literals, since those are only optimized
3987      when generating RTL, not later.
3988      And finally, if we are compiling an initializer, not code, we
3989      need to return a definite result now; there's not going to be any
3990      more optimization done.  */
3991   if (TREE_SIDE_EFFECTS (arglist) || cse_not_expected
3992       || AGGREGATE_TYPE_P (TREE_TYPE (arglist))
3993       || POINTER_TYPE_P (TREE_TYPE (arglist))
3994       || cfun == 0)
3995     return integer_zero_node;
3996
3997   return 0;
3998 }
3999
4000 /* Fold a call to __builtin_classify_type.  */
4001
4002 static tree
4003 fold_builtin_classify_type (arglist)
4004      tree arglist;
4005 {
4006   if (arglist == 0)
4007     return build_int_2 (no_type_class, 0);
4008
4009   return build_int_2 (type_to_class (TREE_TYPE (TREE_VALUE (arglist))), 0);
4010 }
4011
4012 /* Used by constant folding to eliminate some builtin calls early.  EXP is
4013    the CALL_EXPR of a call to a builtin function.  */
4014
4015 tree
4016 fold_builtin (exp)
4017      tree exp;
4018 {
4019   tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
4020   tree arglist = TREE_OPERAND (exp, 1);
4021   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
4022
4023   if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
4024     return 0;
4025
4026   switch (fcode)
4027     {
4028     case BUILT_IN_CONSTANT_P:
4029       return fold_builtin_constant_p (arglist);
4030
4031     case BUILT_IN_CLASSIFY_TYPE:
4032       return fold_builtin_classify_type (arglist);
4033
4034     case BUILT_IN_STRLEN:
4035       if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
4036         {
4037           tree len = c_strlen (TREE_VALUE (arglist));
4038           if (len != 0)
4039             return len;
4040         }
4041       break;
4042
4043     default:
4044       break;
4045     }
4046
4047   return 0;
4048 }
4049
4050 static tree
4051 build_function_call_expr (fn, arglist)
4052      tree fn, arglist;
4053 {
4054   tree call_expr;
4055
4056   call_expr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
4057   call_expr = build (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)),
4058                      call_expr, arglist);
4059   TREE_SIDE_EFFECTS (call_expr) = 1;
4060   return fold (call_expr);
4061 }
4062
4063 /* This function validates the types of a function call argument list
4064    represented as a tree chain of parameters against a specified list
4065    of tree_codes.  If the last specifier is a 0, that represents an
4066    ellipses, otherwise the last specifier must be a VOID_TYPE.  */
4067
4068 static int
4069 validate_arglist VPARAMS ((tree arglist, ...))
4070 {
4071   enum tree_code code;
4072   int res = 0;
4073
4074   VA_OPEN (ap, arglist);
4075   VA_FIXEDARG (ap, tree, arglist);
4076
4077   do {
4078     code = va_arg (ap, enum tree_code);
4079     switch (code)
4080     {
4081     case 0:
4082       /* This signifies an ellipses, any further arguments are all ok.  */
4083       res = 1;
4084       goto end;
4085     case VOID_TYPE:
4086       /* This signifies an endlink, if no arguments remain, return
4087          true, otherwise return false.  */
4088       res = arglist == 0;
4089       goto end;
4090     default:
4091       /* If no parameters remain or the parameter's code does not
4092          match the specified code, return false.  Otherwise continue
4093          checking any remaining arguments.  */
4094       if (arglist == 0 || code != TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))))
4095         goto end;
4096       break;
4097     }
4098     arglist = TREE_CHAIN (arglist);
4099   } while (1);
4100
4101   /* We need gotos here since we can only have one VA_CLOSE in a
4102      function.  */
4103  end: ;
4104   VA_CLOSE (ap);
4105
4106   return res;
4107 }
4108
4109 /* Default version of target-specific builtin setup that does nothing.  */
4110
4111 void
4112 default_init_builtins ()
4113 {
4114 }
4115
4116 /* Default target-specific builtin expander that does nothing.  */
4117
4118 rtx
4119 default_expand_builtin (exp, target, subtarget, mode, ignore)
4120      tree exp ATTRIBUTE_UNUSED;
4121      rtx target ATTRIBUTE_UNUSED;
4122      rtx subtarget ATTRIBUTE_UNUSED;
4123      enum machine_mode mode ATTRIBUTE_UNUSED;
4124      int ignore ATTRIBUTE_UNUSED;
4125 {
4126   return NULL_RTX;
4127 }