OSDN Git Service

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