OSDN Git Service

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