1 /* Expand builtin functions.
2 Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3 1999, 2000, 2001 Free Software Foundation, Inc.
5 This file is part of GCC.
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
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
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
30 #include "hard-reg-set.h"
33 #include "insn-config.h"
39 #include "typeclass.h"
45 #define CALLED_AS_BUILT_IN(NODE) \
46 (!strncmp (IDENTIFIER_POINTER (DECL_NAME (NODE)), "__builtin_", 10))
48 /* Register mappings for target machines without register windows. */
49 #ifndef INCOMING_REGNO
50 #define INCOMING_REGNO(OUT) (OUT)
52 #ifndef OUTGOING_REGNO
53 #define OUTGOING_REGNO(IN) (IN)
56 #ifndef PAD_VARARGS_DOWN
57 #define PAD_VARARGS_DOWN BYTES_BIG_ENDIAN
60 /* Define the names of the builtin function types and codes. */
61 const char *const built_in_class_names[4]
62 = {"NOT_BUILT_IN", "BUILT_IN_FRONTEND", "BUILT_IN_MD", "BUILT_IN_NORMAL"};
64 #define DEF_BUILTIN(X, N, C, T, LT, B, F, NA) STRINGX(X),
65 const char *const built_in_names[(int) END_BUILTINS] =
67 #include "builtins.def"
71 /* Setup an array of _DECL trees, make sure each element is
72 initialized to NULL_TREE. */
73 tree built_in_decls[(int) END_BUILTINS];
75 tree (*lang_type_promotes_to) PARAMS ((tree));
77 static int get_pointer_alignment PARAMS ((tree, unsigned int));
78 static tree c_strlen PARAMS ((tree));
79 static const char *c_getstr PARAMS ((tree));
80 static rtx c_readstr PARAMS ((const char *,
82 static int target_char_cast PARAMS ((tree, char *));
83 static rtx get_memory_rtx PARAMS ((tree));
84 static int apply_args_size PARAMS ((void));
85 static int apply_result_size PARAMS ((void));
86 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
87 static rtx result_vector PARAMS ((int, rtx));
89 static rtx expand_builtin_setjmp PARAMS ((tree, rtx));
90 static rtx expand_builtin_apply_args PARAMS ((void));
91 static rtx expand_builtin_apply_args_1 PARAMS ((void));
92 static rtx expand_builtin_apply PARAMS ((rtx, rtx, rtx));
93 static void expand_builtin_return PARAMS ((rtx));
94 static enum type_class type_to_class PARAMS ((tree));
95 static rtx expand_builtin_classify_type PARAMS ((tree));
96 static rtx expand_builtin_mathfn PARAMS ((tree, rtx, rtx));
97 static rtx expand_builtin_constant_p PARAMS ((tree));
98 static rtx expand_builtin_args_info PARAMS ((tree));
99 static rtx expand_builtin_next_arg PARAMS ((tree));
100 static rtx expand_builtin_va_start PARAMS ((int, tree));
101 static rtx expand_builtin_va_end PARAMS ((tree));
102 static rtx expand_builtin_va_copy PARAMS ((tree));
104 static rtx expand_builtin_memcmp PARAMS ((tree, tree, rtx));
106 static rtx expand_builtin_strcmp PARAMS ((tree, rtx,
108 static rtx expand_builtin_strncmp PARAMS ((tree, rtx,
110 static rtx builtin_memcpy_read_str PARAMS ((PTR, HOST_WIDE_INT,
112 static rtx expand_builtin_strcat PARAMS ((tree, rtx,
114 static rtx expand_builtin_strncat PARAMS ((tree, rtx,
116 static rtx expand_builtin_strspn PARAMS ((tree, rtx,
118 static rtx expand_builtin_strcspn PARAMS ((tree, rtx,
120 static rtx expand_builtin_memcpy PARAMS ((tree));
121 static rtx expand_builtin_strcpy PARAMS ((tree));
122 static rtx builtin_strncpy_read_str PARAMS ((PTR, HOST_WIDE_INT,
124 static rtx expand_builtin_strncpy PARAMS ((tree, rtx,
126 static rtx builtin_memset_read_str PARAMS ((PTR, HOST_WIDE_INT,
128 static rtx expand_builtin_memset PARAMS ((tree));
129 static rtx expand_builtin_bzero PARAMS ((tree));
130 static rtx expand_builtin_strlen PARAMS ((tree, rtx));
131 static rtx expand_builtin_strstr PARAMS ((tree, rtx,
133 static rtx expand_builtin_strpbrk PARAMS ((tree, rtx,
135 static rtx expand_builtin_strchr PARAMS ((tree, rtx,
137 static rtx expand_builtin_strrchr PARAMS ((tree, rtx,
139 static rtx expand_builtin_alloca PARAMS ((tree, rtx));
140 static rtx expand_builtin_ffs PARAMS ((tree, rtx, rtx));
141 static rtx expand_builtin_frame_address PARAMS ((tree));
142 static rtx expand_builtin_fputs PARAMS ((tree, int));
143 static tree stabilize_va_list PARAMS ((tree, int));
144 static rtx expand_builtin_expect PARAMS ((tree, rtx));
145 static tree fold_builtin_constant_p PARAMS ((tree));
146 static tree fold_builtin_classify_type PARAMS ((tree));
147 static tree build_function_call_expr PARAMS ((tree, tree));
148 static int validate_arglist PARAMS ((tree, ...));
150 /* Return the alignment in bits of EXP, a pointer valued expression.
151 But don't return more than MAX_ALIGN no matter what.
152 The alignment returned is, by default, the alignment of the thing that
153 EXP points to. If it is not a POINTER_TYPE, 0 is returned.
155 Otherwise, look at the expression to see if we can do better, i.e., if the
156 expression is actually pointing at an object whose alignment is tighter. */
159 get_pointer_alignment (exp, max_align)
161 unsigned int max_align;
163 unsigned int align, inner;
165 if (TREE_CODE (TREE_TYPE (exp)) != POINTER_TYPE)
168 align = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
169 align = MIN (align, max_align);
173 switch (TREE_CODE (exp))
177 case NON_LVALUE_EXPR:
178 exp = TREE_OPERAND (exp, 0);
179 if (TREE_CODE (TREE_TYPE (exp)) != POINTER_TYPE)
182 inner = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
183 align = MIN (inner, max_align);
187 /* If sum of pointer + int, restrict our maximum alignment to that
188 imposed by the integer. If not, we can't do any better than
190 if (! host_integerp (TREE_OPERAND (exp, 1), 1))
193 while (((tree_low_cst (TREE_OPERAND (exp, 1), 1))
194 & (max_align / BITS_PER_UNIT - 1))
198 exp = TREE_OPERAND (exp, 0);
202 /* See what we are pointing at and look at its alignment. */
203 exp = TREE_OPERAND (exp, 0);
204 if (TREE_CODE (exp) == FUNCTION_DECL)
205 align = FUNCTION_BOUNDARY;
206 else if (DECL_P (exp))
207 align = DECL_ALIGN (exp);
208 #ifdef CONSTANT_ALIGNMENT
209 else if (TREE_CODE_CLASS (TREE_CODE (exp)) == 'c')
210 align = CONSTANT_ALIGNMENT (exp, align);
212 return MIN (align, max_align);
220 /* Compute the length of a C string. TREE_STRING_LENGTH is not the right
221 way, because it could contain a zero byte in the middle.
222 TREE_STRING_LENGTH is the size of the character array, not the string.
224 The value returned is of type `ssizetype'.
226 Unfortunately, string_constant can't access the values of const char
227 arrays with initializers, so neither can we do so here. */
234 HOST_WIDE_INT offset;
238 src = string_constant (src, &offset_node);
242 max = TREE_STRING_LENGTH (src) - 1;
243 ptr = TREE_STRING_POINTER (src);
245 if (offset_node && TREE_CODE (offset_node) != INTEGER_CST)
247 /* If the string has an internal zero byte (e.g., "foo\0bar"), we can't
248 compute the offset to the following null if we don't know where to
249 start searching for it. */
252 for (i = 0; i < max; i++)
256 /* We don't know the starting offset, but we do know that the string
257 has no internal zero bytes. We can assume that the offset falls
258 within the bounds of the string; otherwise, the programmer deserves
259 what he gets. Subtract the offset from the length of the string,
260 and return that. This would perhaps not be valid if we were dealing
261 with named arrays in addition to literal string constants. */
263 return size_diffop (size_int (max), offset_node);
266 /* We have a known offset into the string. Start searching there for
267 a null character if we can represent it as a single HOST_WIDE_INT. */
268 if (offset_node == 0 || ! host_integerp (offset_node, 0))
271 offset = tree_low_cst (offset_node, 0);
273 /* If the offset is known to be out of bounds, warn, and call strlen at
275 if (offset < 0 || offset > max)
277 warning ("offset outside bounds of constant string");
281 /* Use strlen to search for the first zero byte. Since any strings
282 constructed with build_string will have nulls appended, we win even
283 if we get handed something like (char[4])"abcd".
285 Since OFFSET is our starting index into the string, no further
286 calculation is needed. */
287 return ssize_int (strlen (ptr + offset));
290 /* Return a char pointer for a C string if it is a string constant
291 or sum of string constant and integer constant. */
298 HOST_WIDE_INT offset;
302 src = string_constant (src, &offset_node);
306 max = TREE_STRING_LENGTH (src) - 1;
307 ptr = TREE_STRING_POINTER (src);
309 if (offset_node == 0 || !host_integerp (offset_node, 0))
312 offset = tree_low_cst (offset_node, 0);
313 if (offset < 0 || offset > max)
319 /* Return a CONST_INT or CONST_DOUBLE corresponding to target
320 reading GET_MODE_BITSIZE (MODE) bits from string constant
324 c_readstr (str, mode)
326 enum machine_mode mode;
332 if (GET_MODE_CLASS (mode) != MODE_INT)
337 for (i = 0; i < GET_MODE_SIZE (mode); i++)
340 if (WORDS_BIG_ENDIAN)
341 j = GET_MODE_SIZE (mode) - i - 1;
342 if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN
343 && GET_MODE_SIZE (mode) > UNITS_PER_WORD)
344 j = j + UNITS_PER_WORD - 2 * (j % UNITS_PER_WORD) - 1;
346 if (j > 2 * HOST_BITS_PER_WIDE_INT)
349 ch = (unsigned char) str[i];
350 c[j / HOST_BITS_PER_WIDE_INT] |= ch << (j % HOST_BITS_PER_WIDE_INT);
352 return immed_double_const (c[0], c[1], mode);
355 /* Cast a target constant CST to target CHAR and if that value fits into
356 host char type, return zero and put that value into variable pointed by
360 target_char_cast (cst, p)
364 unsigned HOST_WIDE_INT val, hostval;
366 if (!host_integerp (cst, 1)
367 || CHAR_TYPE_SIZE > HOST_BITS_PER_WIDE_INT)
370 val = tree_low_cst (cst, 1);
371 if (CHAR_TYPE_SIZE < HOST_BITS_PER_WIDE_INT)
372 val &= (((unsigned HOST_WIDE_INT) 1) << CHAR_TYPE_SIZE) - 1;
375 if (HOST_BITS_PER_CHAR < HOST_BITS_PER_WIDE_INT)
376 hostval &= (((unsigned HOST_WIDE_INT) 1) << HOST_BITS_PER_CHAR) - 1;
385 /* Given TEM, a pointer to a stack frame, follow the dynamic chain COUNT
386 times to get the address of either a higher stack frame, or a return
387 address located within it (depending on FNDECL_CODE). */
390 expand_builtin_return_addr (fndecl_code, count, tem)
391 enum built_in_function fndecl_code;
397 /* Some machines need special handling before we can access
398 arbitrary frames. For example, on the sparc, we must first flush
399 all register windows to the stack. */
400 #ifdef SETUP_FRAME_ADDRESSES
402 SETUP_FRAME_ADDRESSES ();
405 /* On the sparc, the return address is not in the frame, it is in a
406 register. There is no way to access it off of the current frame
407 pointer, but it can be accessed off the previous frame pointer by
408 reading the value from the register window save area. */
409 #ifdef RETURN_ADDR_IN_PREVIOUS_FRAME
410 if (fndecl_code == BUILT_IN_RETURN_ADDRESS)
414 /* Scan back COUNT frames to the specified frame. */
415 for (i = 0; i < count; i++)
417 /* Assume the dynamic chain pointer is in the word that the
418 frame address points to, unless otherwise specified. */
419 #ifdef DYNAMIC_CHAIN_ADDRESS
420 tem = DYNAMIC_CHAIN_ADDRESS (tem);
422 tem = memory_address (Pmode, tem);
423 tem = gen_rtx_MEM (Pmode, tem);
424 set_mem_alias_set (tem, get_frame_alias_set ());
425 tem = copy_to_reg (tem);
428 /* For __builtin_frame_address, return what we've got. */
429 if (fndecl_code == BUILT_IN_FRAME_ADDRESS)
432 /* For __builtin_return_address, Get the return address from that
434 #ifdef RETURN_ADDR_RTX
435 tem = RETURN_ADDR_RTX (count, tem);
437 tem = memory_address (Pmode,
438 plus_constant (tem, GET_MODE_SIZE (Pmode)));
439 tem = gen_rtx_MEM (Pmode, tem);
440 set_mem_alias_set (tem, get_frame_alias_set ());
445 /* Alias set used for setjmp buffer. */
446 static HOST_WIDE_INT setjmp_alias_set = -1;
448 /* Construct the leading half of a __builtin_setjmp call. Control will
449 return to RECEIVER_LABEL. This is used directly by sjlj exception
453 expand_builtin_setjmp_setup (buf_addr, receiver_label)
457 enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
461 if (setjmp_alias_set == -1)
462 setjmp_alias_set = new_alias_set ();
464 #ifdef POINTERS_EXTEND_UNSIGNED
465 buf_addr = convert_memory_address (Pmode, buf_addr);
468 buf_addr = force_reg (Pmode, force_operand (buf_addr, NULL_RTX));
472 /* We store the frame pointer and the address of receiver_label in
473 the buffer and use the rest of it for the stack save area, which
474 is machine-dependent. */
476 #ifndef BUILTIN_SETJMP_FRAME_VALUE
477 #define BUILTIN_SETJMP_FRAME_VALUE virtual_stack_vars_rtx
480 mem = gen_rtx_MEM (Pmode, buf_addr);
481 set_mem_alias_set (mem, setjmp_alias_set);
482 emit_move_insn (mem, BUILTIN_SETJMP_FRAME_VALUE);
484 mem = gen_rtx_MEM (Pmode, plus_constant (buf_addr, GET_MODE_SIZE (Pmode))),
485 set_mem_alias_set (mem, setjmp_alias_set);
487 emit_move_insn (validize_mem (mem),
488 force_reg (Pmode, gen_rtx_LABEL_REF (Pmode, receiver_label)));
490 stack_save = gen_rtx_MEM (sa_mode,
491 plus_constant (buf_addr,
492 2 * GET_MODE_SIZE (Pmode)));
493 set_mem_alias_set (stack_save, setjmp_alias_set);
494 emit_stack_save (SAVE_NONLOCAL, &stack_save, NULL_RTX);
496 /* If there is further processing to do, do it. */
497 #ifdef HAVE_builtin_setjmp_setup
498 if (HAVE_builtin_setjmp_setup)
499 emit_insn (gen_builtin_setjmp_setup (buf_addr));
502 /* Tell optimize_save_area_alloca that extra work is going to
503 need to go on during alloca. */
504 current_function_calls_setjmp = 1;
506 /* Set this so all the registers get saved in our frame; we need to be
507 able to copy the saved values for any registers from frames we unwind. */
508 current_function_has_nonlocal_label = 1;
511 /* Construct the trailing part of a __builtin_setjmp call.
512 This is used directly by sjlj exception handling code. */
515 expand_builtin_setjmp_receiver (receiver_label)
516 rtx receiver_label ATTRIBUTE_UNUSED;
518 /* Clobber the FP when we get here, so we have to make sure it's
519 marked as used by this function. */
520 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
522 /* Mark the static chain as clobbered here so life information
523 doesn't get messed up for it. */
524 emit_insn (gen_rtx_CLOBBER (VOIDmode, static_chain_rtx));
526 /* Now put in the code to restore the frame pointer, and argument
527 pointer, if needed. The code below is from expand_end_bindings
528 in stmt.c; see detailed documentation there. */
529 #ifdef HAVE_nonlocal_goto
530 if (! HAVE_nonlocal_goto)
532 emit_move_insn (virtual_stack_vars_rtx, hard_frame_pointer_rtx);
534 #if ARG_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
535 if (fixed_regs[ARG_POINTER_REGNUM])
537 #ifdef ELIMINABLE_REGS
539 static struct elims {int from, to;} elim_regs[] = ELIMINABLE_REGS;
541 for (i = 0; i < ARRAY_SIZE (elim_regs); i++)
542 if (elim_regs[i].from == ARG_POINTER_REGNUM
543 && elim_regs[i].to == HARD_FRAME_POINTER_REGNUM)
546 if (i == ARRAY_SIZE (elim_regs))
549 /* Now restore our arg pointer from the address at which it
550 was saved in our stack frame. */
551 emit_move_insn (virtual_incoming_args_rtx,
552 copy_to_reg (get_arg_pointer_save_area (cfun)));
557 #ifdef HAVE_builtin_setjmp_receiver
558 if (HAVE_builtin_setjmp_receiver)
559 emit_insn (gen_builtin_setjmp_receiver (receiver_label));
562 #ifdef HAVE_nonlocal_goto_receiver
563 if (HAVE_nonlocal_goto_receiver)
564 emit_insn (gen_nonlocal_goto_receiver ());
569 /* @@@ This is a kludge. Not all machine descriptions define a blockage
570 insn, but we must not allow the code we just generated to be reordered
571 by scheduling. Specifically, the update of the frame pointer must
572 happen immediately, not later. So emit an ASM_INPUT to act as blockage
574 emit_insn (gen_rtx_ASM_INPUT (VOIDmode, ""));
577 /* __builtin_setjmp is passed a pointer to an array of five words (not
578 all will be used on all machines). It operates similarly to the C
579 library function of the same name, but is more efficient. Much of
580 the code below (and for longjmp) is copied from the handling of
583 NOTE: This is intended for use by GNAT and the exception handling
584 scheme in the compiler and will only work in the method used by
588 expand_builtin_setjmp (arglist, target)
592 rtx buf_addr, next_lab, cont_lab;
594 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
597 if (target == 0 || GET_CODE (target) != REG
598 || REGNO (target) < FIRST_PSEUDO_REGISTER)
599 target = gen_reg_rtx (TYPE_MODE (integer_type_node));
601 buf_addr = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
603 next_lab = gen_label_rtx ();
604 cont_lab = gen_label_rtx ();
606 expand_builtin_setjmp_setup (buf_addr, next_lab);
608 /* Set TARGET to zero and branch to the continue label. */
609 emit_move_insn (target, const0_rtx);
610 emit_jump_insn (gen_jump (cont_lab));
612 emit_label (next_lab);
614 expand_builtin_setjmp_receiver (next_lab);
616 /* Set TARGET to one. */
617 emit_move_insn (target, const1_rtx);
618 emit_label (cont_lab);
620 /* Tell flow about the strange goings on. Putting `next_lab' on
621 `nonlocal_goto_handler_labels' to indicates that function
622 calls may traverse the arc back to this label. */
624 current_function_has_nonlocal_label = 1;
625 nonlocal_goto_handler_labels
626 = gen_rtx_EXPR_LIST (VOIDmode, next_lab, nonlocal_goto_handler_labels);
631 /* __builtin_longjmp is passed a pointer to an array of five words (not
632 all will be used on all machines). It operates similarly to the C
633 library function of the same name, but is more efficient. Much of
634 the code below is copied from the handling of non-local gotos.
636 NOTE: This is intended for use by GNAT and the exception handling
637 scheme in the compiler and will only work in the method used by
641 expand_builtin_longjmp (buf_addr, value)
644 rtx fp, lab, stack, insn;
645 enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
647 if (setjmp_alias_set == -1)
648 setjmp_alias_set = new_alias_set ();
650 #ifdef POINTERS_EXTEND_UNSIGNED
651 buf_addr = convert_memory_address (Pmode, buf_addr);
653 buf_addr = force_reg (Pmode, buf_addr);
655 /* We used to store value in static_chain_rtx, but that fails if pointers
656 are smaller than integers. We instead require that the user must pass
657 a second argument of 1, because that is what builtin_setjmp will
658 return. This also makes EH slightly more efficient, since we are no
659 longer copying around a value that we don't care about. */
660 if (value != const1_rtx)
663 current_function_calls_longjmp = 1;
665 #ifdef HAVE_builtin_longjmp
666 if (HAVE_builtin_longjmp)
667 emit_insn (gen_builtin_longjmp (buf_addr));
671 fp = gen_rtx_MEM (Pmode, buf_addr);
672 lab = gen_rtx_MEM (Pmode, plus_constant (buf_addr,
673 GET_MODE_SIZE (Pmode)));
675 stack = gen_rtx_MEM (sa_mode, plus_constant (buf_addr,
676 2 * GET_MODE_SIZE (Pmode)));
677 set_mem_alias_set (fp, setjmp_alias_set);
678 set_mem_alias_set (lab, setjmp_alias_set);
679 set_mem_alias_set (stack, setjmp_alias_set);
681 /* Pick up FP, label, and SP from the block and jump. This code is
682 from expand_goto in stmt.c; see there for detailed comments. */
683 #if HAVE_nonlocal_goto
684 if (HAVE_nonlocal_goto)
685 /* We have to pass a value to the nonlocal_goto pattern that will
686 get copied into the static_chain pointer, but it does not matter
687 what that value is, because builtin_setjmp does not use it. */
688 emit_insn (gen_nonlocal_goto (value, lab, stack, fp));
692 lab = copy_to_reg (lab);
694 emit_move_insn (hard_frame_pointer_rtx, fp);
695 emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
697 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
698 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
699 emit_indirect_jump (lab);
703 /* Search backwards and mark the jump insn as a non-local goto.
704 Note that this precludes the use of __builtin_longjmp to a
705 __builtin_setjmp target in the same function. However, we've
706 already cautioned the user that these functions are for
707 internal exception handling use only. */
708 for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
710 if (GET_CODE (insn) == JUMP_INSN)
712 REG_NOTES (insn) = alloc_EXPR_LIST (REG_NON_LOCAL_GOTO, const0_rtx,
716 else if (GET_CODE (insn) == CALL_INSN)
721 /* Get a MEM rtx for expression EXP which is the address of an operand
722 to be used to be used in a string instruction (cmpstrsi, movstrsi, ..). */
728 rtx mem = gen_rtx_MEM (BLKmode,
729 memory_address (BLKmode,
730 expand_expr (exp, NULL_RTX,
731 ptr_mode, EXPAND_SUM)));
733 /* Get an expression we can use to find the attributes to assign to MEM.
734 If it is an ADDR_EXPR, use the operand. Otherwise, dereference it if
735 we can. First remove any nops. */
736 while ((TREE_CODE (exp) == NOP_EXPR || TREE_CODE (exp) == CONVERT_EXPR
737 || TREE_CODE (exp) == NON_LVALUE_EXPR)
738 && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (exp, 0))))
739 exp = TREE_OPERAND (exp, 0);
741 if (TREE_CODE (exp) == ADDR_EXPR)
742 exp = TREE_OPERAND (exp, 0);
743 else if (POINTER_TYPE_P (TREE_TYPE (exp)))
744 exp = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (exp)), exp);
748 set_mem_attributes (mem, exp, 0);
749 /* memcpy, memset and other builtin stringops can alias with anything. */
750 set_mem_alias_set (mem, 0);
754 /* Built-in functions to perform an untyped call and return. */
756 /* For each register that may be used for calling a function, this
757 gives a mode used to copy the register's value. VOIDmode indicates
758 the register is not used for calling a function. If the machine
759 has register windows, this gives only the outbound registers.
760 INCOMING_REGNO gives the corresponding inbound register. */
761 static enum machine_mode apply_args_mode[FIRST_PSEUDO_REGISTER];
763 /* For each register that may be used for returning values, this gives
764 a mode used to copy the register's value. VOIDmode indicates the
765 register is not used for returning values. If the machine has
766 register windows, this gives only the outbound registers.
767 INCOMING_REGNO gives the corresponding inbound register. */
768 static enum machine_mode apply_result_mode[FIRST_PSEUDO_REGISTER];
770 /* For each register that may be used for calling a function, this
771 gives the offset of that register into the block returned by
772 __builtin_apply_args. 0 indicates that the register is not
773 used for calling a function. */
774 static int apply_args_reg_offset[FIRST_PSEUDO_REGISTER];
776 /* Return the offset of register REGNO into the block returned by
777 __builtin_apply_args. This is not declared static, since it is
778 needed in objc-act.c. */
781 apply_args_register_offset (regno)
786 /* Arguments are always put in outgoing registers (in the argument
787 block) if such make sense. */
788 #ifdef OUTGOING_REGNO
789 regno = OUTGOING_REGNO(regno);
791 return apply_args_reg_offset[regno];
794 /* Return the size required for the block returned by __builtin_apply_args,
795 and initialize apply_args_mode. */
800 static int size = -1;
802 enum machine_mode mode;
804 /* The values computed by this function never change. */
807 /* The first value is the incoming arg-pointer. */
808 size = GET_MODE_SIZE (Pmode);
810 /* The second value is the structure value address unless this is
811 passed as an "invisible" first argument. */
812 if (struct_value_rtx)
813 size += GET_MODE_SIZE (Pmode);
815 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
816 if (FUNCTION_ARG_REGNO_P (regno))
818 /* Search for the proper mode for copying this register's
819 value. I'm not sure this is right, but it works so far. */
820 enum machine_mode best_mode = VOIDmode;
822 for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT);
824 mode = GET_MODE_WIDER_MODE (mode))
825 if (HARD_REGNO_MODE_OK (regno, mode)
826 && HARD_REGNO_NREGS (regno, mode) == 1)
829 if (best_mode == VOIDmode)
830 for (mode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT);
832 mode = GET_MODE_WIDER_MODE (mode))
833 if (HARD_REGNO_MODE_OK (regno, mode)
834 && have_insn_for (SET, mode))
838 if (mode == VOIDmode)
841 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
842 if (size % align != 0)
843 size = CEIL (size, align) * align;
844 apply_args_reg_offset[regno] = size;
845 size += GET_MODE_SIZE (mode);
846 apply_args_mode[regno] = mode;
850 apply_args_mode[regno] = VOIDmode;
851 apply_args_reg_offset[regno] = 0;
857 /* Return the size required for the block returned by __builtin_apply,
858 and initialize apply_result_mode. */
863 static int size = -1;
865 enum machine_mode mode;
867 /* The values computed by this function never change. */
872 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
873 if (FUNCTION_VALUE_REGNO_P (regno))
875 /* Search for the proper mode for copying this register's
876 value. I'm not sure this is right, but it works so far. */
877 enum machine_mode best_mode = VOIDmode;
879 for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT);
881 mode = GET_MODE_WIDER_MODE (mode))
882 if (HARD_REGNO_MODE_OK (regno, mode))
885 if (best_mode == VOIDmode)
886 for (mode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT);
888 mode = GET_MODE_WIDER_MODE (mode))
889 if (HARD_REGNO_MODE_OK (regno, mode)
890 && have_insn_for (SET, mode))
894 if (mode == VOIDmode)
897 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
898 if (size % align != 0)
899 size = CEIL (size, align) * align;
900 size += GET_MODE_SIZE (mode);
901 apply_result_mode[regno] = mode;
904 apply_result_mode[regno] = VOIDmode;
906 /* Allow targets that use untyped_call and untyped_return to override
907 the size so that machine-specific information can be stored here. */
908 #ifdef APPLY_RESULT_SIZE
909 size = APPLY_RESULT_SIZE;
915 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
916 /* Create a vector describing the result block RESULT. If SAVEP is true,
917 the result block is used to save the values; otherwise it is used to
918 restore the values. */
921 result_vector (savep, result)
925 int regno, size, align, nelts;
926 enum machine_mode mode;
928 rtx *savevec = (rtx *) alloca (FIRST_PSEUDO_REGISTER * sizeof (rtx));
931 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
932 if ((mode = apply_result_mode[regno]) != VOIDmode)
934 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
935 if (size % align != 0)
936 size = CEIL (size, align) * align;
937 reg = gen_rtx_REG (mode, savep ? regno : INCOMING_REGNO (regno));
938 mem = adjust_address (result, mode, size);
939 savevec[nelts++] = (savep
940 ? gen_rtx_SET (VOIDmode, mem, reg)
941 : gen_rtx_SET (VOIDmode, reg, mem));
942 size += GET_MODE_SIZE (mode);
944 return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (nelts, savevec));
946 #endif /* HAVE_untyped_call or HAVE_untyped_return */
948 /* Save the state required to perform an untyped call with the same
949 arguments as were passed to the current function. */
952 expand_builtin_apply_args_1 ()
955 int size, align, regno;
956 enum machine_mode mode;
958 /* Create a block where the arg-pointer, structure value address,
959 and argument registers can be saved. */
960 registers = assign_stack_local (BLKmode, apply_args_size (), -1);
962 /* Walk past the arg-pointer and structure value address. */
963 size = GET_MODE_SIZE (Pmode);
964 if (struct_value_rtx)
965 size += GET_MODE_SIZE (Pmode);
967 /* Save each register used in calling a function to the block. */
968 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
969 if ((mode = apply_args_mode[regno]) != VOIDmode)
973 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
974 if (size % align != 0)
975 size = CEIL (size, align) * align;
977 tem = gen_rtx_REG (mode, INCOMING_REGNO (regno));
979 emit_move_insn (adjust_address (registers, mode, size), tem);
980 size += GET_MODE_SIZE (mode);
983 /* Save the arg pointer to the block. */
984 emit_move_insn (adjust_address (registers, Pmode, 0),
985 copy_to_reg (virtual_incoming_args_rtx));
986 size = GET_MODE_SIZE (Pmode);
988 /* Save the structure value address unless this is passed as an
989 "invisible" first argument. */
990 if (struct_value_incoming_rtx)
992 emit_move_insn (adjust_address (registers, Pmode, size),
993 copy_to_reg (struct_value_incoming_rtx));
994 size += GET_MODE_SIZE (Pmode);
997 /* Return the address of the block. */
998 return copy_addr_to_reg (XEXP (registers, 0));
1001 /* __builtin_apply_args returns block of memory allocated on
1002 the stack into which is stored the arg pointer, structure
1003 value address, static chain, and all the registers that might
1004 possibly be used in performing a function call. The code is
1005 moved to the start of the function so the incoming values are
1009 expand_builtin_apply_args ()
1011 /* Don't do __builtin_apply_args more than once in a function.
1012 Save the result of the first call and reuse it. */
1013 if (apply_args_value != 0)
1014 return apply_args_value;
1016 /* When this function is called, it means that registers must be
1017 saved on entry to this function. So we migrate the
1018 call to the first insn of this function. */
1023 temp = expand_builtin_apply_args_1 ();
1027 apply_args_value = temp;
1029 /* Put the sequence after the NOTE that starts the function.
1030 If this is inside a SEQUENCE, make the outer-level insn
1031 chain current, so the code is placed at the start of the
1033 push_topmost_sequence ();
1034 emit_insns_before (seq, NEXT_INSN (get_insns ()));
1035 pop_topmost_sequence ();
1040 /* Perform an untyped call and save the state required to perform an
1041 untyped return of whatever value was returned by the given function. */
1044 expand_builtin_apply (function, arguments, argsize)
1045 rtx function, arguments, argsize;
1047 int size, align, regno;
1048 enum machine_mode mode;
1049 rtx incoming_args, result, reg, dest, call_insn;
1050 rtx old_stack_level = 0;
1051 rtx call_fusage = 0;
1053 /* Create a block where the return registers can be saved. */
1054 result = assign_stack_local (BLKmode, apply_result_size (), -1);
1056 /* Fetch the arg pointer from the ARGUMENTS block. */
1057 incoming_args = gen_reg_rtx (Pmode);
1058 emit_move_insn (incoming_args,
1059 gen_rtx_MEM (Pmode, arguments));
1060 #ifndef STACK_GROWS_DOWNWARD
1061 incoming_args = expand_simple_binop (Pmode, MINUS, incoming_args, argsize,
1062 incoming_args, 0, OPTAB_LIB_WIDEN);
1065 /* Perform postincrements before actually calling the function. */
1068 /* Push a new argument block and copy the arguments. Do not allow
1069 the (potential) memcpy call below to interfere with our stack
1071 do_pending_stack_adjust ();
1074 /* Save the stack with nonlocal if available */
1075 #ifdef HAVE_save_stack_nonlocal
1076 if (HAVE_save_stack_nonlocal)
1077 emit_stack_save (SAVE_NONLOCAL, &old_stack_level, NULL_RTX);
1080 emit_stack_save (SAVE_BLOCK, &old_stack_level, NULL_RTX);
1082 /* Push a block of memory onto the stack to store the memory arguments.
1083 Save the address in a register, and copy the memory arguments. ??? I
1084 haven't figured out how the calling convention macros effect this,
1085 but it's likely that the source and/or destination addresses in
1086 the block copy will need updating in machine specific ways. */
1087 dest = allocate_dynamic_stack_space (argsize, 0, BITS_PER_UNIT);
1088 emit_block_move (gen_rtx_MEM (BLKmode, dest),
1089 gen_rtx_MEM (BLKmode, incoming_args),
1090 argsize, PARM_BOUNDARY);
1092 /* Refer to the argument block. */
1094 arguments = gen_rtx_MEM (BLKmode, arguments);
1096 /* Walk past the arg-pointer and structure value address. */
1097 size = GET_MODE_SIZE (Pmode);
1098 if (struct_value_rtx)
1099 size += GET_MODE_SIZE (Pmode);
1101 /* Restore each of the registers previously saved. Make USE insns
1102 for each of these registers for use in making the call. */
1103 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1104 if ((mode = apply_args_mode[regno]) != VOIDmode)
1106 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1107 if (size % align != 0)
1108 size = CEIL (size, align) * align;
1109 reg = gen_rtx_REG (mode, regno);
1110 emit_move_insn (reg, adjust_address (arguments, mode, size));
1111 use_reg (&call_fusage, reg);
1112 size += GET_MODE_SIZE (mode);
1115 /* Restore the structure value address unless this is passed as an
1116 "invisible" first argument. */
1117 size = GET_MODE_SIZE (Pmode);
1118 if (struct_value_rtx)
1120 rtx value = gen_reg_rtx (Pmode);
1121 emit_move_insn (value, adjust_address (arguments, Pmode, size));
1122 emit_move_insn (struct_value_rtx, value);
1123 if (GET_CODE (struct_value_rtx) == REG)
1124 use_reg (&call_fusage, struct_value_rtx);
1125 size += GET_MODE_SIZE (Pmode);
1128 /* All arguments and registers used for the call are set up by now! */
1129 function = prepare_call_address (function, NULL_TREE, &call_fusage, 0, 0);
1131 /* Ensure address is valid. SYMBOL_REF is already valid, so no need,
1132 and we don't want to load it into a register as an optimization,
1133 because prepare_call_address already did it if it should be done. */
1134 if (GET_CODE (function) != SYMBOL_REF)
1135 function = memory_address (FUNCTION_MODE, function);
1137 /* Generate the actual call instruction and save the return value. */
1138 #ifdef HAVE_untyped_call
1139 if (HAVE_untyped_call)
1140 emit_call_insn (gen_untyped_call (gen_rtx_MEM (FUNCTION_MODE, function),
1141 result, result_vector (1, result)));
1144 #ifdef HAVE_call_value
1145 if (HAVE_call_value)
1149 /* Locate the unique return register. It is not possible to
1150 express a call that sets more than one return register using
1151 call_value; use untyped_call for that. In fact, untyped_call
1152 only needs to save the return registers in the given block. */
1153 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1154 if ((mode = apply_result_mode[regno]) != VOIDmode)
1157 abort (); /* HAVE_untyped_call required. */
1158 valreg = gen_rtx_REG (mode, regno);
1161 emit_call_insn (GEN_CALL_VALUE (valreg,
1162 gen_rtx_MEM (FUNCTION_MODE, function),
1163 const0_rtx, NULL_RTX, const0_rtx));
1165 emit_move_insn (adjust_address (result, GET_MODE (valreg), 0), valreg);
1171 /* Find the CALL insn we just emitted. */
1172 for (call_insn = get_last_insn ();
1173 call_insn && GET_CODE (call_insn) != CALL_INSN;
1174 call_insn = PREV_INSN (call_insn))
1180 /* Put the register usage information on the CALL. If there is already
1181 some usage information, put ours at the end. */
1182 if (CALL_INSN_FUNCTION_USAGE (call_insn))
1186 for (link = CALL_INSN_FUNCTION_USAGE (call_insn); XEXP (link, 1) != 0;
1187 link = XEXP (link, 1))
1190 XEXP (link, 1) = call_fusage;
1193 CALL_INSN_FUNCTION_USAGE (call_insn) = call_fusage;
1195 /* Restore the stack. */
1196 #ifdef HAVE_save_stack_nonlocal
1197 if (HAVE_save_stack_nonlocal)
1198 emit_stack_restore (SAVE_NONLOCAL, old_stack_level, NULL_RTX);
1201 emit_stack_restore (SAVE_BLOCK, old_stack_level, NULL_RTX);
1205 /* Return the address of the result block. */
1206 return copy_addr_to_reg (XEXP (result, 0));
1209 /* Perform an untyped return. */
1212 expand_builtin_return (result)
1215 int size, align, regno;
1216 enum machine_mode mode;
1218 rtx call_fusage = 0;
1220 apply_result_size ();
1221 result = gen_rtx_MEM (BLKmode, result);
1223 #ifdef HAVE_untyped_return
1224 if (HAVE_untyped_return)
1226 emit_jump_insn (gen_untyped_return (result, result_vector (0, result)));
1232 /* Restore the return value and note that each value is used. */
1234 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1235 if ((mode = apply_result_mode[regno]) != VOIDmode)
1237 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1238 if (size % align != 0)
1239 size = CEIL (size, align) * align;
1240 reg = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1241 emit_move_insn (reg, adjust_address (result, mode, size));
1243 push_to_sequence (call_fusage);
1244 emit_insn (gen_rtx_USE (VOIDmode, reg));
1245 call_fusage = get_insns ();
1247 size += GET_MODE_SIZE (mode);
1250 /* Put the USE insns before the return. */
1251 emit_insns (call_fusage);
1253 /* Return whatever values was restored by jumping directly to the end
1255 expand_null_return ();
1258 /* Used by expand_builtin_classify_type and fold_builtin_classify_type. */
1260 static enum type_class
1261 type_to_class (type)
1264 switch (TREE_CODE (type))
1266 case VOID_TYPE: return void_type_class;
1267 case INTEGER_TYPE: return integer_type_class;
1268 case CHAR_TYPE: return char_type_class;
1269 case ENUMERAL_TYPE: return enumeral_type_class;
1270 case BOOLEAN_TYPE: return boolean_type_class;
1271 case POINTER_TYPE: return pointer_type_class;
1272 case REFERENCE_TYPE: return reference_type_class;
1273 case OFFSET_TYPE: return offset_type_class;
1274 case REAL_TYPE: return real_type_class;
1275 case COMPLEX_TYPE: return complex_type_class;
1276 case FUNCTION_TYPE: return function_type_class;
1277 case METHOD_TYPE: return method_type_class;
1278 case RECORD_TYPE: return record_type_class;
1280 case QUAL_UNION_TYPE: return union_type_class;
1281 case ARRAY_TYPE: return (TYPE_STRING_FLAG (type)
1282 ? string_type_class : array_type_class);
1283 case SET_TYPE: return set_type_class;
1284 case FILE_TYPE: return file_type_class;
1285 case LANG_TYPE: return lang_type_class;
1286 default: return no_type_class;
1290 /* Expand a call to __builtin_classify_type with arguments found in
1294 expand_builtin_classify_type (arglist)
1298 return GEN_INT (type_to_class (TREE_TYPE (TREE_VALUE (arglist))));
1299 return GEN_INT (no_type_class);
1302 /* Expand expression EXP, which is a call to __builtin_constant_p. */
1305 expand_builtin_constant_p (exp)
1308 tree arglist = TREE_OPERAND (exp, 1);
1309 enum machine_mode value_mode = TYPE_MODE (TREE_TYPE (exp));
1314 arglist = TREE_VALUE (arglist);
1316 /* We have taken care of the easy cases during constant folding. This
1317 case is not obvious, so emit (constant_p_rtx (ARGLIST)) and let CSE get a
1318 chance to see if it can deduce whether ARGLIST is constant. */
1320 tmp = expand_expr (arglist, NULL_RTX, VOIDmode, 0);
1321 tmp = gen_rtx_CONSTANT_P_RTX (value_mode, tmp);
1325 /* Expand a call to one of the builtin math functions (sin, cos, or sqrt).
1326 Return 0 if a normal call should be emitted rather than expanding the
1327 function in-line. EXP is the expression that is a call to the builtin
1328 function; if convenient, the result should be placed in TARGET.
1329 SUBTARGET may be used as the target for computing one of EXP's operands. */
1332 expand_builtin_mathfn (exp, target, subtarget)
1334 rtx target, subtarget;
1336 optab builtin_optab;
1338 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
1339 tree arglist = TREE_OPERAND (exp, 1);
1341 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
1344 /* Stabilize and compute the argument. */
1345 if (TREE_CODE (TREE_VALUE (arglist)) != VAR_DECL
1346 && TREE_CODE (TREE_VALUE (arglist)) != PARM_DECL)
1348 exp = copy_node (exp);
1349 TREE_OPERAND (exp, 1) = arglist;
1350 /* Wrap the computation of the argument in a SAVE_EXPR. That
1351 way, if we need to expand the argument again (as in the
1352 flag_errno_math case below where we cannot directly set
1353 errno), we will not perform side-effects more than once.
1354 Note that here we're mutating the original EXP as well as the
1355 copy; that's the right thing to do in case the original EXP
1356 is expanded later. */
1357 TREE_VALUE (arglist) = save_expr (TREE_VALUE (arglist));
1358 arglist = copy_node (arglist);
1360 op0 = expand_expr (TREE_VALUE (arglist), subtarget, VOIDmode, 0);
1362 /* Make a suitable register to place result in. */
1363 target = gen_reg_rtx (TYPE_MODE (TREE_TYPE (exp)));
1368 switch (DECL_FUNCTION_CODE (fndecl))
1373 builtin_optab = sin_optab; break;
1377 builtin_optab = cos_optab; break;
1378 case BUILT_IN_FSQRT:
1379 case BUILT_IN_SQRTF:
1380 case BUILT_IN_SQRTL:
1381 builtin_optab = sqrt_optab; break;
1386 /* Compute into TARGET.
1387 Set TARGET to wherever the result comes back. */
1388 target = expand_unop (TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist))),
1389 builtin_optab, op0, target, 0);
1391 /* If we were unable to expand via the builtin, stop the
1392 sequence (without outputting the insns) and return 0, causing
1393 a call to the library function. */
1400 /* If errno must be maintained and if we are not allowing unsafe
1401 math optimizations, check the result. */
1403 if (flag_errno_math && ! flag_unsafe_math_optimizations)
1407 /* Don't define the builtin FP instructions
1408 if your machine is not IEEE. */
1409 if (TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT)
1412 lab1 = gen_label_rtx ();
1414 /* Test the result; if it is NaN, set errno=EDOM because
1415 the argument was not in the domain. */
1416 emit_cmp_and_jump_insns (target, target, EQ, 0, GET_MODE (target),
1421 #ifdef GEN_ERRNO_RTX
1422 rtx errno_rtx = GEN_ERRNO_RTX;
1425 = gen_rtx_MEM (word_mode, gen_rtx_SYMBOL_REF (Pmode, "errno"));
1428 emit_move_insn (errno_rtx, GEN_INT (TARGET_EDOM));
1431 /* We can't set errno=EDOM directly; let the library call do it.
1432 Pop the arguments right away in case the call gets deleted. */
1434 expand_call (exp, target, 0);
1441 /* Output the entire sequence. */
1442 insns = get_insns ();
1449 /* Expand expression EXP which is a call to the strlen builtin. Return 0
1450 if we failed the caller should emit a normal call, otherwise
1451 try to get the result in TARGET, if convenient. */
1454 expand_builtin_strlen (exp, target)
1458 tree arglist = TREE_OPERAND (exp, 1);
1459 enum machine_mode value_mode = TYPE_MODE (TREE_TYPE (exp));
1461 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
1466 tree src = TREE_VALUE (arglist);
1469 = get_pointer_alignment (src, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
1471 rtx result, src_reg, char_rtx, before_strlen;
1472 enum machine_mode insn_mode = value_mode, char_mode;
1473 enum insn_code icode = CODE_FOR_nothing;
1475 /* If SRC is not a pointer type, don't do this operation inline. */
1479 /* Bail out if we can't compute strlen in the right mode. */
1480 while (insn_mode != VOIDmode)
1482 icode = strlen_optab->handlers[(int) insn_mode].insn_code;
1483 if (icode != CODE_FOR_nothing)
1486 insn_mode = GET_MODE_WIDER_MODE (insn_mode);
1488 if (insn_mode == VOIDmode)
1491 /* Make a place to write the result of the instruction. */
1494 && GET_CODE (result) == REG
1495 && GET_MODE (result) == insn_mode
1496 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
1497 result = gen_reg_rtx (insn_mode);
1499 /* Make a place to hold the source address. We will not expand
1500 the actual source until we are sure that the expansion will
1501 not fail -- there are trees that cannot be expanded twice. */
1502 src_reg = gen_reg_rtx (Pmode);
1504 /* Mark the beginning of the strlen sequence so we can emit the
1505 source operand later. */
1506 before_strlen = get_last_insn();
1508 /* Check the string is readable and has an end. */
1509 if (current_function_check_memory_usage)
1510 emit_library_call (chkr_check_str_libfunc, LCT_CONST_MAKE_BLOCK,
1511 VOIDmode, 2, src_reg, Pmode,
1512 GEN_INT (MEMORY_USE_RO),
1513 TYPE_MODE (integer_type_node));
1515 char_rtx = const0_rtx;
1516 char_mode = insn_data[(int) icode].operand[2].mode;
1517 if (! (*insn_data[(int) icode].operand[2].predicate) (char_rtx,
1519 char_rtx = copy_to_mode_reg (char_mode, char_rtx);
1521 pat = GEN_FCN (icode) (result, gen_rtx_MEM (BLKmode, src_reg),
1522 char_rtx, GEN_INT (align));
1527 /* Now that we are assured of success, expand the source. */
1529 pat = memory_address (BLKmode,
1530 expand_expr (src, src_reg, ptr_mode, EXPAND_SUM));
1532 emit_move_insn (src_reg, pat);
1533 pat = gen_sequence ();
1537 emit_insn_after (pat, before_strlen);
1539 emit_insn_before (pat, get_insns ());
1541 /* Return the value in the proper mode for this function. */
1542 if (GET_MODE (result) == value_mode)
1544 else if (target != 0)
1545 convert_move (target, result, 0);
1547 target = convert_to_mode (value_mode, result, 0);
1553 /* Expand a call to the strstr builtin. Return 0 if we failed the
1554 caller should emit a normal call, otherwise try to get the result
1555 in TARGET, if convenient (and in mode MODE if that's convenient). */
1558 expand_builtin_strstr (arglist, target, mode)
1561 enum machine_mode mode;
1563 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)
1564 || current_function_check_memory_usage)
1568 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
1570 const char *p1, *p2;
1579 const char *r = strstr (p1, p2);
1584 /* Return an offset into the constant string argument. */
1585 return expand_expr (fold (build (PLUS_EXPR, TREE_TYPE (s1),
1586 s1, ssize_int (r - p1))),
1587 target, mode, EXPAND_NORMAL);
1591 return expand_expr (s1, target, mode, EXPAND_NORMAL);
1596 fn = built_in_decls[BUILT_IN_STRCHR];
1600 /* New argument list transforming strstr(s1, s2) to
1601 strchr(s1, s2[0]). */
1603 build_tree_list (NULL_TREE, build_int_2 (p2[0], 0));
1604 arglist = tree_cons (NULL_TREE, s1, arglist);
1605 return expand_expr (build_function_call_expr (fn, arglist),
1606 target, mode, EXPAND_NORMAL);
1610 /* Expand a call to the strchr builtin. Return 0 if we failed the
1611 caller should emit a normal call, otherwise try to get the result
1612 in TARGET, if convenient (and in mode MODE if that's convenient). */
1615 expand_builtin_strchr (arglist, target, mode)
1618 enum machine_mode mode;
1620 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)
1621 || current_function_check_memory_usage)
1625 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
1628 if (TREE_CODE (s2) != INTEGER_CST)
1637 if (target_char_cast (s2, &c))
1645 /* Return an offset into the constant string argument. */
1646 return expand_expr (fold (build (PLUS_EXPR, TREE_TYPE (s1),
1647 s1, ssize_int (r - p1))),
1648 target, mode, EXPAND_NORMAL);
1651 /* FIXME: Should use here strchrM optab so that ports can optimize
1657 /* Expand a call to the strrchr builtin. Return 0 if we failed the
1658 caller should emit a normal call, otherwise try to get the result
1659 in TARGET, if convenient (and in mode MODE if that's convenient). */
1662 expand_builtin_strrchr (arglist, target, mode)
1665 enum machine_mode mode;
1667 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)
1668 || current_function_check_memory_usage)
1672 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
1676 if (TREE_CODE (s2) != INTEGER_CST)
1685 if (target_char_cast (s2, &c))
1688 r = strrchr (p1, c);
1693 /* Return an offset into the constant string argument. */
1694 return expand_expr (fold (build (PLUS_EXPR, TREE_TYPE (s1),
1695 s1, ssize_int (r - p1))),
1696 target, mode, EXPAND_NORMAL);
1699 if (! integer_zerop (s2))
1702 fn = built_in_decls[BUILT_IN_STRCHR];
1706 /* Transform strrchr(s1, '\0') to strchr(s1, '\0'). */
1707 return expand_expr (build_function_call_expr (fn, arglist),
1708 target, mode, EXPAND_NORMAL);
1712 /* Expand a call to the strpbrk builtin. Return 0 if we failed the
1713 caller should emit a normal call, otherwise try to get the result
1714 in TARGET, if convenient (and in mode MODE if that's convenient). */
1717 expand_builtin_strpbrk (arglist, target, mode)
1720 enum machine_mode mode;
1722 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)
1723 || current_function_check_memory_usage)
1727 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
1729 const char *p1, *p2;
1738 const char *r = strpbrk (p1, p2);
1743 /* Return an offset into the constant string argument. */
1744 return expand_expr (fold (build (PLUS_EXPR, TREE_TYPE (s1),
1745 s1, ssize_int (r - p1))),
1746 target, mode, EXPAND_NORMAL);
1751 /* strpbrk(x, "") == NULL.
1752 Evaluate and ignore the arguments in case they had
1754 expand_expr (s1, const0_rtx, VOIDmode, EXPAND_NORMAL);
1759 return 0; /* Really call strpbrk. */
1761 fn = built_in_decls[BUILT_IN_STRCHR];
1765 /* New argument list transforming strpbrk(s1, s2) to
1766 strchr(s1, s2[0]). */
1768 build_tree_list (NULL_TREE, build_int_2 (p2[0], 0));
1769 arglist = tree_cons (NULL_TREE, s1, arglist);
1770 return expand_expr (build_function_call_expr (fn, arglist),
1771 target, mode, EXPAND_NORMAL);
1775 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
1776 bytes from constant string DATA + OFFSET and return it as target
1780 builtin_memcpy_read_str (data, offset, mode)
1782 HOST_WIDE_INT offset;
1783 enum machine_mode mode;
1785 const char *str = (const char *) data;
1788 || ((unsigned HOST_WIDE_INT) offset + GET_MODE_SIZE (mode)
1789 > strlen (str) + 1))
1790 abort (); /* Attempt to read past the end of constant string. */
1792 return c_readstr (str + offset, mode);
1795 /* Expand a call to the memcpy builtin, with arguments in ARGLIST. */
1798 expand_builtin_memcpy (arglist)
1801 if (!validate_arglist (arglist,
1802 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
1806 tree dest = TREE_VALUE (arglist);
1807 tree src = TREE_VALUE (TREE_CHAIN (arglist));
1808 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
1809 const char *src_str;
1811 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
1812 unsigned int dest_align
1813 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
1814 rtx dest_mem, src_mem, dest_addr, len_rtx;
1816 /* If either SRC or DEST is not a pointer type, don't do
1817 this operation in-line. */
1818 if (src_align == 0 || dest_align == 0)
1821 dest_mem = get_memory_rtx (dest);
1822 len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
1823 src_str = c_getstr (src);
1825 /* If SRC is a string constant and block move would be done
1826 by pieces, we can avoid loading the string from memory
1827 and only stored the computed constants. */
1829 && !current_function_check_memory_usage
1830 && GET_CODE (len_rtx) == CONST_INT
1831 && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
1832 && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
1833 (PTR) src_str, dest_align))
1835 store_by_pieces (dest_mem, INTVAL (len_rtx),
1836 builtin_memcpy_read_str,
1837 (PTR) src_str, dest_align);
1838 return force_operand (XEXP (dest_mem, 0), NULL_RTX);
1841 src_mem = get_memory_rtx (src);
1843 /* Just copy the rights of SRC to the rights of DEST. */
1844 if (current_function_check_memory_usage)
1845 emit_library_call (chkr_copy_bitmap_libfunc, LCT_CONST_MAKE_BLOCK,
1846 VOIDmode, 3, XEXP (dest_mem, 0), Pmode,
1847 XEXP (src_mem, 0), Pmode,
1848 len_rtx, TYPE_MODE (sizetype));
1850 /* Copy word part most expediently. */
1852 = emit_block_move (dest_mem, src_mem, len_rtx,
1853 MIN (src_align, dest_align));
1856 dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
1862 /* Expand expression EXP, which is a call to the strcpy builtin. Return 0
1863 if we failed the caller should emit a normal call. */
1866 expand_builtin_strcpy (exp)
1869 tree arglist = TREE_OPERAND (exp, 1);
1872 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
1876 tree len = c_strlen (TREE_VALUE (TREE_CHAIN (arglist)));
1881 len = size_binop (PLUS_EXPR, len, ssize_int (1));
1882 chainon (arglist, build_tree_list (NULL_TREE, len));
1885 result = expand_builtin_memcpy (arglist);
1888 TREE_CHAIN (TREE_CHAIN (arglist)) = 0;
1892 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
1893 bytes from constant string DATA + OFFSET and return it as target
1897 builtin_strncpy_read_str (data, offset, mode)
1899 HOST_WIDE_INT offset;
1900 enum machine_mode mode;
1902 const char *str = (const char *) data;
1904 if ((unsigned HOST_WIDE_INT) offset > strlen (str))
1907 return c_readstr (str + offset, mode);
1910 /* Expand expression EXP, which is a call to the strncpy builtin. Return 0
1911 if we failed the caller should emit a normal call. */
1914 expand_builtin_strncpy (arglist, target, mode)
1917 enum machine_mode mode;
1919 if (!validate_arglist (arglist,
1920 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
1924 tree slen = c_strlen (TREE_VALUE (TREE_CHAIN (arglist)));
1925 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
1927 /* We must be passed a constant len parameter. */
1928 if (TREE_CODE (len) != INTEGER_CST)
1931 /* If the len parameter is zero, return the dst parameter. */
1932 if (compare_tree_int (len, 0) == 0)
1934 /* Evaluate and ignore the src argument in case it has
1936 expand_expr (TREE_VALUE (TREE_CHAIN (arglist)), const0_rtx,
1937 VOIDmode, EXPAND_NORMAL);
1938 /* Return the dst parameter. */
1939 return expand_expr (TREE_VALUE (arglist), target, mode,
1943 /* Now, we must be passed a constant src ptr parameter. */
1944 if (slen == 0 || TREE_CODE (slen) != INTEGER_CST)
1947 slen = size_binop (PLUS_EXPR, slen, ssize_int (1));
1949 /* We're required to pad with trailing zeros if the requested
1950 len is greater than strlen(s2)+1. In that case try to
1951 use store_by_pieces, if it fails, punt. */
1952 if (tree_int_cst_lt (slen, len))
1954 tree dest = TREE_VALUE (arglist);
1955 unsigned int dest_align
1956 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
1957 const char *p = c_getstr (TREE_VALUE (TREE_CHAIN (arglist)));
1960 if (!p || dest_align == 0 || !host_integerp (len, 1)
1961 || !can_store_by_pieces (tree_low_cst (len, 1),
1962 builtin_strncpy_read_str,
1963 (PTR) p, dest_align))
1966 dest_mem = get_memory_rtx (dest);
1967 store_by_pieces (dest_mem, tree_low_cst (len, 1),
1968 builtin_strncpy_read_str,
1969 (PTR) p, dest_align);
1970 return force_operand (XEXP (dest_mem, 0), NULL_RTX);
1973 /* OK transform into builtin memcpy. */
1974 return expand_builtin_memcpy (arglist);
1978 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
1979 bytes from constant string DATA + OFFSET and return it as target
1983 builtin_memset_read_str (data, offset, mode)
1985 HOST_WIDE_INT offset ATTRIBUTE_UNUSED;
1986 enum machine_mode mode;
1988 const char *c = (const char *) data;
1989 char *p = alloca (GET_MODE_SIZE (mode));
1991 memset (p, *c, GET_MODE_SIZE (mode));
1993 return c_readstr (p, mode);
1996 /* Expand expression EXP, which is a call to the memset builtin. Return 0
1997 if we failed the caller should emit a normal call. */
2000 expand_builtin_memset (exp)
2003 tree arglist = TREE_OPERAND (exp, 1);
2005 if (!validate_arglist (arglist,
2006 POINTER_TYPE, INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
2010 tree dest = TREE_VALUE (arglist);
2011 tree val = TREE_VALUE (TREE_CHAIN (arglist));
2012 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2015 unsigned int dest_align
2016 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2017 rtx dest_mem, dest_addr, len_rtx;
2019 /* If DEST is not a pointer type, don't do this
2020 operation in-line. */
2021 if (dest_align == 0)
2024 if (TREE_CODE (val) != INTEGER_CST)
2027 if (target_char_cast (val, &c))
2032 if (!host_integerp (len, 1))
2034 if (current_function_check_memory_usage
2035 || !can_store_by_pieces (tree_low_cst (len, 1),
2036 builtin_memset_read_str,
2037 (PTR) &c, dest_align))
2040 dest_mem = get_memory_rtx (dest);
2041 store_by_pieces (dest_mem, tree_low_cst (len, 1),
2042 builtin_memset_read_str,
2043 (PTR) &c, dest_align);
2044 return force_operand (XEXP (dest_mem, 0), NULL_RTX);
2047 len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
2049 dest_mem = get_memory_rtx (dest);
2051 /* Just check DST is writable and mark it as readable. */
2052 if (current_function_check_memory_usage)
2053 emit_library_call (chkr_check_addr_libfunc, LCT_CONST_MAKE_BLOCK,
2054 VOIDmode, 3, XEXP (dest_mem, 0), Pmode,
2055 len_rtx, TYPE_MODE (sizetype),
2056 GEN_INT (MEMORY_USE_WO),
2057 TYPE_MODE (integer_type_node));
2060 dest_addr = clear_storage (dest_mem, len_rtx, dest_align);
2063 dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2069 /* Expand expression EXP, which is a call to the bzero builtin. Return 0
2070 if we failed the caller should emit a normal call. */
2073 expand_builtin_bzero (exp)
2076 tree arglist = TREE_OPERAND (exp, 1);
2077 tree dest, size, newarglist;
2080 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2083 dest = TREE_VALUE (arglist);
2084 size = TREE_VALUE (TREE_CHAIN (arglist));
2086 /* New argument list transforming bzero(ptr x, int y) to
2087 memset(ptr x, int 0, size_t y). */
2089 newarglist = build_tree_list (NULL_TREE, convert (sizetype, size));
2090 newarglist = tree_cons (NULL_TREE, integer_zero_node, newarglist);
2091 newarglist = tree_cons (NULL_TREE, dest, newarglist);
2093 TREE_OPERAND (exp, 1) = newarglist;
2094 result = expand_builtin_memset(exp);
2096 /* Always restore the original arguments. */
2097 TREE_OPERAND (exp, 1) = arglist;
2102 #ifdef HAVE_cmpstrsi
2104 /* Expand expression EXP, which is a call to the memcmp or the strcmp builtin.
2105 ARGLIST is the argument list for this call. Return 0 if we failed and the
2106 caller should emit a normal call, otherwise try to get the result in
2107 TARGET, if convenient. */
2110 expand_builtin_memcmp (exp, arglist, target)
2115 /* If we need to check memory accesses, call the library function. */
2116 if (current_function_check_memory_usage)
2119 if (!validate_arglist (arglist,
2120 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2124 enum machine_mode mode;
2125 tree arg1 = TREE_VALUE (arglist);
2126 tree arg2 = TREE_VALUE (TREE_CHAIN (arglist));
2127 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2128 rtx arg1_rtx, arg2_rtx, arg3_rtx;
2133 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
2135 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
2136 enum machine_mode insn_mode
2137 = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
2139 /* If we don't have POINTER_TYPE, call the function. */
2140 if (arg1_align == 0 || arg2_align == 0)
2143 /* Make a place to write the result of the instruction. */
2146 && GET_CODE (result) == REG && GET_MODE (result) == insn_mode
2147 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
2148 result = gen_reg_rtx (insn_mode);
2150 arg1_rtx = get_memory_rtx (arg1);
2151 arg2_rtx = get_memory_rtx (arg2);
2152 arg3_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
2156 insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
2157 GEN_INT (MIN (arg1_align, arg2_align)));
2162 emit_library_call_value (memcmp_libfunc, result, LCT_PURE_MAKE_BLOCK,
2163 TYPE_MODE (integer_type_node), 3,
2164 XEXP (arg1_rtx, 0), Pmode,
2165 XEXP (arg2_rtx, 0), Pmode,
2166 convert_to_mode (TYPE_MODE (sizetype), arg3_rtx,
2167 TREE_UNSIGNED (sizetype)),
2168 TYPE_MODE (sizetype));
2170 /* Return the value in the proper mode for this function. */
2171 mode = TYPE_MODE (TREE_TYPE (exp));
2172 if (GET_MODE (result) == mode)
2174 else if (target != 0)
2176 convert_move (target, result, 0);
2180 return convert_to_mode (mode, result, 0);
2185 /* Expand expression EXP, which is a call to the strcmp builtin. Return 0
2186 if we failed the caller should emit a normal call, otherwise try to get
2187 the result in TARGET, if convenient. */
2190 expand_builtin_strcmp (exp, target, mode)
2193 enum machine_mode mode;
2195 tree arglist = TREE_OPERAND (exp, 1);
2197 const char *p1, *p2;
2199 /* If we need to check memory accesses, call the library function. */
2200 if (current_function_check_memory_usage)
2203 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2206 arg1 = TREE_VALUE (arglist);
2207 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
2209 p1 = c_getstr (arg1);
2210 p2 = c_getstr (arg2);
2214 const int i = strcmp (p1, p2);
2215 return (i < 0 ? constm1_rtx : (i > 0 ? const1_rtx : const0_rtx));
2218 /* If either arg is "", return an expression corresponding to
2219 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
2220 if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
2222 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
2223 tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
2225 fold (build1 (CONVERT_EXPR, integer_type_node,
2226 build1 (INDIRECT_REF, cst_uchar_node,
2227 build1 (NOP_EXPR, cst_uchar_ptr_node, arg1))));
2229 fold (build1 (CONVERT_EXPR, integer_type_node,
2230 build1 (INDIRECT_REF, cst_uchar_node,
2231 build1 (NOP_EXPR, cst_uchar_ptr_node, arg2))));
2232 tree result = fold (build (MINUS_EXPR, integer_type_node, ind1, ind2));
2233 return expand_expr (result, target, mode, EXPAND_NORMAL);
2236 #ifdef HAVE_cmpstrsi
2237 if (! HAVE_cmpstrsi)
2241 tree len = c_strlen (arg1);
2242 tree len2 = c_strlen (arg2);
2246 len = size_binop (PLUS_EXPR, ssize_int (1), len);
2249 len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
2251 /* If we don't have a constant length for the first, use the length
2252 of the second, if we know it. We don't require a constant for
2253 this case; some cost analysis could be done if both are available
2254 but neither is constant. For now, assume they're equally cheap
2255 unless one has side effects.
2257 If both strings have constant lengths, use the smaller. This
2258 could arise if optimization results in strcpy being called with
2259 two fixed strings, or if the code was machine-generated. We should
2260 add some code to the `memcmp' handler below to deal with such
2261 situations, someday. */
2263 if (!len || TREE_CODE (len) != INTEGER_CST)
2265 if (len2 && !TREE_SIDE_EFFECTS (len2))
2270 else if (len2 && TREE_CODE (len2) == INTEGER_CST
2271 && tree_int_cst_lt (len2, len))
2274 /* If both arguments have side effects, we cannot optimize. */
2275 if (TREE_SIDE_EFFECTS (len))
2278 chainon (arglist, build_tree_list (NULL_TREE, len));
2279 result = expand_builtin_memcmp (exp, arglist, target);
2281 TREE_CHAIN (TREE_CHAIN (arglist)) = 0;
2290 /* Expand expression EXP, which is a call to the strncmp builtin. Return 0
2291 if we failed the caller should emit a normal call, otherwise try to get
2292 the result in TARGET, if convenient. */
2295 expand_builtin_strncmp (exp, target, mode)
2298 enum machine_mode mode;
2300 tree arglist = TREE_OPERAND (exp, 1);
2301 tree arg1, arg2, arg3;
2302 const char *p1, *p2;
2304 /* If we need to check memory accesses, call the library function. */
2305 if (current_function_check_memory_usage)
2308 if (!validate_arglist (arglist,
2309 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2312 arg1 = TREE_VALUE (arglist);
2313 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
2314 arg3 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2316 /* If the len parameter is zero, return zero. */
2317 if (host_integerp (arg3, 1) && tree_low_cst (arg3, 1) == 0)
2319 /* Evaluate and ignore arg1 and arg2 in case they have
2321 expand_expr (arg1, const0_rtx, VOIDmode, EXPAND_NORMAL);
2322 expand_expr (arg2, const0_rtx, VOIDmode, EXPAND_NORMAL);
2326 p1 = c_getstr (arg1);
2327 p2 = c_getstr (arg2);
2329 /* If all arguments are constant, evaluate at compile-time. */
2330 if (host_integerp (arg3, 1) && p1 && p2)
2332 const int r = strncmp (p1, p2, tree_low_cst (arg3, 1));
2333 return (r < 0 ? constm1_rtx : (r > 0 ? const1_rtx : const0_rtx));
2336 /* If len == 1 or (either string parameter is "" and (len >= 1)),
2337 return (*(const u_char*)arg1 - *(const u_char*)arg2). */
2338 if (host_integerp (arg3, 1)
2339 && (tree_low_cst (arg3, 1) == 1
2340 || (tree_low_cst (arg3, 1) > 1
2341 && ((p1 && *p1 == '\0') || (p2 && *p2 == '\0')))))
2343 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
2344 tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
2346 fold (build1 (CONVERT_EXPR, integer_type_node,
2347 build1 (INDIRECT_REF, cst_uchar_node,
2348 build1 (NOP_EXPR, cst_uchar_ptr_node, arg1))));
2350 fold (build1 (CONVERT_EXPR, integer_type_node,
2351 build1 (INDIRECT_REF, cst_uchar_node,
2352 build1 (NOP_EXPR, cst_uchar_ptr_node, arg2))));
2353 tree result = fold (build (MINUS_EXPR, integer_type_node, ind1, ind2));
2354 return expand_expr (result, target, mode, EXPAND_NORMAL);
2357 #ifdef HAVE_cmpstrsi
2358 /* If c_strlen can determine an expression for one of the string
2359 lengths, and it doesn't have side effects, then call
2360 expand_builtin_memcmp() using length MIN(strlen(string)+1, arg3). */
2363 tree newarglist, len = 0;
2365 /* Perhaps one of the strings is really constant, if so prefer
2366 that constant length over the other string's length. */
2368 len = c_strlen (arg1);
2370 len = c_strlen (arg2);
2372 /* If we still don't have a len, try either string arg as long
2373 as they don't have side effects. */
2374 if (!len && !TREE_SIDE_EFFECTS (arg1))
2375 len = c_strlen (arg1);
2376 if (!len && !TREE_SIDE_EFFECTS (arg2))
2377 len = c_strlen (arg2);
2378 /* If we still don't have a length, punt. */
2382 /* Add one to the string length. */
2383 len = fold (size_binop (PLUS_EXPR, len, ssize_int (1)));
2385 /* The actual new length parameter is MIN(len,arg3). */
2386 len = fold (build (MIN_EXPR, TREE_TYPE (len), len, arg3));
2388 newarglist = build_tree_list (NULL_TREE, len);
2389 newarglist = tree_cons (NULL_TREE, arg2, newarglist);
2390 newarglist = tree_cons (NULL_TREE, arg1, newarglist);
2391 return expand_builtin_memcmp (exp, newarglist, target);
2398 /* Expand expression EXP, which is a call to the strcat builtin.
2399 Return 0 if we failed the caller should emit a normal call,
2400 otherwise try to get the result in TARGET, if convenient. */
2403 expand_builtin_strcat (arglist, target, mode)
2406 enum machine_mode mode;
2408 /* If we need to check memory accesses, call the library function. */
2409 if (current_function_check_memory_usage)
2412 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2416 tree dst = TREE_VALUE (arglist),
2417 src = TREE_VALUE (TREE_CHAIN (arglist));
2418 const char *p = c_getstr (src);
2420 /* If the string length is zero, return the dst parameter. */
2421 if (p && *p == '\0')
2422 return expand_expr (dst, target, mode, EXPAND_NORMAL);
2428 /* Expand expression EXP, which is a call to the strncat builtin.
2429 Return 0 if we failed the caller should emit a normal call,
2430 otherwise try to get the result in TARGET, if convenient. */
2433 expand_builtin_strncat (arglist, target, mode)
2436 enum machine_mode mode;
2438 /* If we need to check memory accesses, call the library function. */
2439 if (current_function_check_memory_usage)
2442 if (!validate_arglist (arglist,
2443 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2447 tree dst = TREE_VALUE (arglist),
2448 src = TREE_VALUE (TREE_CHAIN (arglist)),
2449 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2450 const char *p = c_getstr (src);
2452 /* If the requested length is zero, or the src parameter string
2453 length is zero, return the dst parameter. */
2454 if ((TREE_CODE (len) == INTEGER_CST && compare_tree_int (len, 0) == 0)
2455 || (p && *p == '\0'))
2457 /* Evaluate and ignore the src and len parameters in case
2458 they have side-effects. */
2459 expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
2460 expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
2461 return expand_expr (dst, target, mode, EXPAND_NORMAL);
2464 /* If the requested len is greater than or equal to the string
2465 length, call strcat. */
2466 if (TREE_CODE (len) == INTEGER_CST && p
2467 && compare_tree_int (len, strlen (p)) >= 0)
2470 tree_cons (NULL_TREE, dst, build_tree_list (NULL_TREE, src)),
2471 fn = built_in_decls[BUILT_IN_STRCAT];
2473 /* If the replacement _DECL isn't initialized, don't do the
2478 return expand_expr (build_function_call_expr (fn, newarglist),
2479 target, mode, EXPAND_NORMAL);
2485 /* Expand expression EXP, which is a call to the strspn builtin.
2486 Return 0 if we failed the caller should emit a normal call,
2487 otherwise try to get the result in TARGET, if convenient. */
2490 expand_builtin_strspn (arglist, target, mode)
2493 enum machine_mode mode;
2495 /* If we need to check memory accesses, call the library function. */
2496 if (current_function_check_memory_usage)
2499 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2503 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
2504 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
2506 /* If both arguments are constants, evaluate at compile-time. */
2509 const size_t r = strspn (p1, p2);
2510 return expand_expr (size_int (r), target, mode, EXPAND_NORMAL);
2513 /* If either argument is "", return 0. */
2514 if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
2516 /* Evaluate and ignore both arguments in case either one has
2518 expand_expr (s1, const0_rtx, VOIDmode, EXPAND_NORMAL);
2519 expand_expr (s2, const0_rtx, VOIDmode, EXPAND_NORMAL);
2526 /* Expand expression EXP, which is a call to the strcspn builtin.
2527 Return 0 if we failed the caller should emit a normal call,
2528 otherwise try to get the result in TARGET, if convenient. */
2531 expand_builtin_strcspn (arglist, target, mode)
2534 enum machine_mode mode;
2536 /* If we need to check memory accesses, call the library function. */
2537 if (current_function_check_memory_usage)
2540 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2544 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
2545 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
2547 /* If both arguments are constants, evaluate at compile-time. */
2550 const size_t r = strcspn (p1, p2);
2551 return expand_expr (size_int (r), target, mode, EXPAND_NORMAL);
2554 /* If the first argument is "", return 0. */
2555 if (p1 && *p1 == '\0')
2557 /* Evaluate and ignore argument s2 in case it has
2559 expand_expr (s2, const0_rtx, VOIDmode, EXPAND_NORMAL);
2563 /* If the second argument is "", return __builtin_strlen(s1). */
2564 if (p2 && *p2 == '\0')
2566 tree newarglist = build_tree_list (NULL_TREE, s1),
2567 fn = built_in_decls[BUILT_IN_STRLEN];
2569 /* If the replacement _DECL isn't initialized, don't do the
2574 return expand_expr (build_function_call_expr (fn, newarglist),
2575 target, mode, EXPAND_NORMAL);
2581 /* Expand a call to __builtin_saveregs, generating the result in TARGET,
2582 if that's convenient. */
2585 expand_builtin_saveregs ()
2589 /* Don't do __builtin_saveregs more than once in a function.
2590 Save the result of the first call and reuse it. */
2591 if (saveregs_value != 0)
2592 return saveregs_value;
2594 /* When this function is called, it means that registers must be
2595 saved on entry to this function. So we migrate the call to the
2596 first insn of this function. */
2600 #ifdef EXPAND_BUILTIN_SAVEREGS
2601 /* Do whatever the machine needs done in this case. */
2602 val = EXPAND_BUILTIN_SAVEREGS ();
2604 /* ??? We used to try and build up a call to the out of line function,
2605 guessing about what registers needed saving etc. This became much
2606 harder with __builtin_va_start, since we don't have a tree for a
2607 call to __builtin_saveregs to fall back on. There was exactly one
2608 port (i860) that used this code, and I'm unconvinced it could actually
2609 handle the general case. So we no longer try to handle anything
2610 weird and make the backend absorb the evil. */
2612 error ("__builtin_saveregs not supported by this target");
2619 saveregs_value = val;
2621 /* Put the sequence after the NOTE that starts the function. If this
2622 is inside a SEQUENCE, make the outer-level insn chain current, so
2623 the code is placed at the start of the function. */
2624 push_topmost_sequence ();
2625 emit_insns_after (seq, get_insns ());
2626 pop_topmost_sequence ();
2631 /* __builtin_args_info (N) returns word N of the arg space info
2632 for the current function. The number and meanings of words
2633 is controlled by the definition of CUMULATIVE_ARGS. */
2636 expand_builtin_args_info (exp)
2639 tree arglist = TREE_OPERAND (exp, 1);
2640 int nwords = sizeof (CUMULATIVE_ARGS) / sizeof (int);
2641 int *word_ptr = (int *) ¤t_function_args_info;
2643 /* These are used by the code below that is if 0'ed away */
2645 tree type, elts, result;
2648 if (sizeof (CUMULATIVE_ARGS) % sizeof (int) != 0)
2653 if (!host_integerp (TREE_VALUE (arglist), 0))
2654 error ("argument of `__builtin_args_info' must be constant");
2657 HOST_WIDE_INT wordnum = tree_low_cst (TREE_VALUE (arglist), 0);
2659 if (wordnum < 0 || wordnum >= nwords)
2660 error ("argument of `__builtin_args_info' out of range");
2662 return GEN_INT (word_ptr[wordnum]);
2666 error ("missing argument in `__builtin_args_info'");
2671 for (i = 0; i < nwords; i++)
2672 elts = tree_cons (NULL_TREE, build_int_2 (word_ptr[i], 0));
2674 type = build_array_type (integer_type_node,
2675 build_index_type (build_int_2 (nwords, 0)));
2676 result = build (CONSTRUCTOR, type, NULL_TREE, nreverse (elts));
2677 TREE_CONSTANT (result) = 1;
2678 TREE_STATIC (result) = 1;
2679 result = build1 (INDIRECT_REF, build_pointer_type (type), result);
2680 TREE_CONSTANT (result) = 1;
2681 return expand_expr (result, NULL_RTX, VOIDmode, EXPAND_MEMORY_USE_BAD);
2685 /* Expand ARGLIST, from a call to __builtin_next_arg. */
2688 expand_builtin_next_arg (arglist)
2691 tree fntype = TREE_TYPE (current_function_decl);
2693 if ((TYPE_ARG_TYPES (fntype) == 0
2694 || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
2696 && ! current_function_varargs)
2698 error ("`va_start' used in function with fixed args");
2704 tree last_parm = tree_last (DECL_ARGUMENTS (current_function_decl));
2705 tree arg = TREE_VALUE (arglist);
2707 /* Strip off all nops for the sake of the comparison. This
2708 is not quite the same as STRIP_NOPS. It does more.
2709 We must also strip off INDIRECT_EXPR for C++ reference
2711 while (TREE_CODE (arg) == NOP_EXPR
2712 || TREE_CODE (arg) == CONVERT_EXPR
2713 || TREE_CODE (arg) == NON_LVALUE_EXPR
2714 || TREE_CODE (arg) == INDIRECT_REF)
2715 arg = TREE_OPERAND (arg, 0);
2716 if (arg != last_parm)
2717 warning ("second parameter of `va_start' not last named argument");
2719 else if (! current_function_varargs)
2720 /* Evidently an out of date version of <stdarg.h>; can't validate
2721 va_start's second argument, but can still work as intended. */
2722 warning ("`__builtin_next_arg' called without an argument");
2724 return expand_binop (Pmode, add_optab,
2725 current_function_internal_arg_pointer,
2726 current_function_arg_offset_rtx,
2727 NULL_RTX, 0, OPTAB_LIB_WIDEN);
2730 /* Make it easier for the backends by protecting the valist argument
2731 from multiple evaluations. */
2734 stabilize_va_list (valist, needs_lvalue)
2738 if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
2740 if (TREE_SIDE_EFFECTS (valist))
2741 valist = save_expr (valist);
2743 /* For this case, the backends will be expecting a pointer to
2744 TREE_TYPE (va_list_type_node), but it's possible we've
2745 actually been given an array (an actual va_list_type_node).
2747 if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
2749 tree p1 = build_pointer_type (TREE_TYPE (va_list_type_node));
2750 tree p2 = build_pointer_type (va_list_type_node);
2752 valist = build1 (ADDR_EXPR, p2, valist);
2753 valist = fold (build1 (NOP_EXPR, p1, valist));
2762 if (! TREE_SIDE_EFFECTS (valist))
2765 pt = build_pointer_type (va_list_type_node);
2766 valist = fold (build1 (ADDR_EXPR, pt, valist));
2767 TREE_SIDE_EFFECTS (valist) = 1;
2770 if (TREE_SIDE_EFFECTS (valist))
2771 valist = save_expr (valist);
2772 valist = fold (build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (valist)),
2779 /* The "standard" implementation of va_start: just assign `nextarg' to
2783 std_expand_builtin_va_start (stdarg_p, valist, nextarg)
2792 /* The dummy named parameter is declared as a 'word' sized
2793 object, but if a 'word' is smaller than an 'int', it would
2794 have been promoted to int when it was added to the arglist. */
2795 int align = PARM_BOUNDARY / BITS_PER_UNIT;
2796 int size = MAX (UNITS_PER_WORD,
2797 GET_MODE_SIZE (TYPE_MODE (integer_type_node)));
2798 int offset = ((size + align - 1) / align) * align;
2799 nextarg = plus_constant (nextarg, -offset);
2802 t = build (MODIFY_EXPR, TREE_TYPE (valist), valist,
2803 make_tree (ptr_type_node, nextarg));
2804 TREE_SIDE_EFFECTS (t) = 1;
2806 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
2809 /* Expand ARGLIST, which from a call to __builtin_stdarg_va_start or
2810 __builtin_varargs_va_start, depending on STDARG_P. */
2813 expand_builtin_va_start (stdarg_p, arglist)
2818 tree chain = arglist, valist;
2821 nextarg = expand_builtin_next_arg (chain = TREE_CHAIN (arglist));
2823 nextarg = expand_builtin_next_arg (NULL_TREE);
2825 if (TREE_CHAIN (chain))
2826 error ("too many arguments to function `va_start'");
2828 valist = stabilize_va_list (TREE_VALUE (arglist), 1);
2830 #ifdef EXPAND_BUILTIN_VA_START
2831 EXPAND_BUILTIN_VA_START (stdarg_p, valist, nextarg);
2833 std_expand_builtin_va_start (stdarg_p, valist, nextarg);
2839 /* The "standard" implementation of va_arg: read the value from the
2840 current (padded) address and increment by the (padded) size. */
2843 std_expand_builtin_va_arg (valist, type)
2847 HOST_WIDE_INT align;
2848 HOST_WIDE_INT rounded_size;
2851 /* Compute the rounded size of the type. */
2852 align = PARM_BOUNDARY / BITS_PER_UNIT;
2853 rounded_size = (((int_size_in_bytes (type) + align - 1) / align) * align);
2857 if (PAD_VARARGS_DOWN)
2859 /* Small args are padded downward. */
2862 = rounded_size > align ? rounded_size : int_size_in_bytes (type);
2864 addr_tree = build (PLUS_EXPR, TREE_TYPE (addr_tree), addr_tree,
2865 build_int_2 (rounded_size - adj, 0));
2868 addr = expand_expr (addr_tree, NULL_RTX, Pmode, EXPAND_NORMAL);
2869 addr = copy_to_reg (addr);
2871 /* Compute new value for AP. */
2872 t = build (MODIFY_EXPR, TREE_TYPE (valist), valist,
2873 build (PLUS_EXPR, TREE_TYPE (valist), valist,
2874 build_int_2 (rounded_size, 0)));
2875 TREE_SIDE_EFFECTS (t) = 1;
2876 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
2881 /* Expand __builtin_va_arg, which is not really a builtin function, but
2882 a very special sort of operator. */
2885 expand_builtin_va_arg (valist, type)
2889 tree promoted_type, want_va_type, have_va_type;
2891 /* Verify that valist is of the proper type. */
2893 want_va_type = va_list_type_node;
2894 have_va_type = TREE_TYPE (valist);
2895 if (TREE_CODE (want_va_type) == ARRAY_TYPE)
2897 /* If va_list is an array type, the argument may have decayed
2898 to a pointer type, e.g. by being passed to another function.
2899 In that case, unwrap both types so that we can compare the
2900 underlying records. */
2901 if (TREE_CODE (have_va_type) == ARRAY_TYPE
2902 || TREE_CODE (have_va_type) == POINTER_TYPE)
2904 want_va_type = TREE_TYPE (want_va_type);
2905 have_va_type = TREE_TYPE (have_va_type);
2908 if (TYPE_MAIN_VARIANT (want_va_type) != TYPE_MAIN_VARIANT (have_va_type))
2910 error ("first argument to `va_arg' not of type `va_list'");
2914 /* Generate a diagnostic for requesting data of a type that cannot
2915 be passed through `...' due to type promotion at the call site. */
2916 else if ((promoted_type = (*lang_type_promotes_to) (type)) != NULL_TREE)
2918 const char *name = "<anonymous type>", *pname = 0;
2919 static int gave_help;
2921 if (TYPE_NAME (type))
2923 if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE)
2924 name = IDENTIFIER_POINTER (TYPE_NAME (type));
2925 else if (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
2926 && DECL_NAME (TYPE_NAME (type)))
2927 name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type)));
2929 if (TYPE_NAME (promoted_type))
2931 if (TREE_CODE (TYPE_NAME (promoted_type)) == IDENTIFIER_NODE)
2932 pname = IDENTIFIER_POINTER (TYPE_NAME (promoted_type));
2933 else if (TREE_CODE (TYPE_NAME (promoted_type)) == TYPE_DECL
2934 && DECL_NAME (TYPE_NAME (promoted_type)))
2935 pname = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (promoted_type)));
2938 error ("`%s' is promoted to `%s' when passed through `...'", name, pname);
2942 error ("(so you should pass `%s' not `%s' to `va_arg')", pname, name);
2949 /* Make it easier for the backends by protecting the valist argument
2950 from multiple evaluations. */
2951 valist = stabilize_va_list (valist, 0);
2953 #ifdef EXPAND_BUILTIN_VA_ARG
2954 addr = EXPAND_BUILTIN_VA_ARG (valist, type);
2956 addr = std_expand_builtin_va_arg (valist, type);
2960 result = gen_rtx_MEM (TYPE_MODE (type), addr);
2961 set_mem_alias_set (result, get_varargs_alias_set ());
2966 /* Expand ARGLIST, from a call to __builtin_va_end. */
2969 expand_builtin_va_end (arglist)
2972 tree valist = TREE_VALUE (arglist);
2974 #ifdef EXPAND_BUILTIN_VA_END
2975 valist = stabilize_va_list (valist, 0);
2976 EXPAND_BUILTIN_VA_END(arglist);
2978 /* Evaluate for side effects, if needed. I hate macros that don't
2980 if (TREE_SIDE_EFFECTS (valist))
2981 expand_expr (valist, const0_rtx, VOIDmode, EXPAND_NORMAL);
2987 /* Expand ARGLIST, from a call to __builtin_va_copy. We do this as a
2988 builtin rather than just as an assignment in stdarg.h because of the
2989 nastiness of array-type va_list types. */
2992 expand_builtin_va_copy (arglist)
2997 dst = TREE_VALUE (arglist);
2998 src = TREE_VALUE (TREE_CHAIN (arglist));
3000 dst = stabilize_va_list (dst, 1);
3001 src = stabilize_va_list (src, 0);
3003 if (TREE_CODE (va_list_type_node) != ARRAY_TYPE)
3005 t = build (MODIFY_EXPR, va_list_type_node, dst, src);
3006 TREE_SIDE_EFFECTS (t) = 1;
3007 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
3011 rtx dstb, srcb, size;
3013 /* Evaluate to pointers. */
3014 dstb = expand_expr (dst, NULL_RTX, Pmode, EXPAND_NORMAL);
3015 srcb = expand_expr (src, NULL_RTX, Pmode, EXPAND_NORMAL);
3016 size = expand_expr (TYPE_SIZE_UNIT (va_list_type_node), NULL_RTX,
3017 VOIDmode, EXPAND_NORMAL);
3019 /* "Dereference" to BLKmode memories. */
3020 dstb = gen_rtx_MEM (BLKmode, dstb);
3021 set_mem_alias_set (dstb, get_alias_set (TREE_TYPE (TREE_TYPE (dst))));
3022 srcb = gen_rtx_MEM (BLKmode, srcb);
3023 set_mem_alias_set (srcb, get_alias_set (TREE_TYPE (TREE_TYPE (src))));
3026 emit_block_move (dstb, srcb, size, TYPE_ALIGN (va_list_type_node));
3032 /* Expand a call to one of the builtin functions __builtin_frame_address or
3033 __builtin_return_address. */
3036 expand_builtin_frame_address (exp)
3039 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
3040 tree arglist = TREE_OPERAND (exp, 1);
3042 /* The argument must be a nonnegative integer constant.
3043 It counts the number of frames to scan up the stack.
3044 The value is the return address saved in that frame. */
3046 /* Warning about missing arg was already issued. */
3048 else if (! host_integerp (TREE_VALUE (arglist), 1))
3050 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
3051 error ("invalid arg to `__builtin_frame_address'");
3053 error ("invalid arg to `__builtin_return_address'");
3059 = expand_builtin_return_addr (DECL_FUNCTION_CODE (fndecl),
3060 tree_low_cst (TREE_VALUE (arglist), 1),
3061 hard_frame_pointer_rtx);
3063 /* Some ports cannot access arbitrary stack frames. */
3066 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
3067 warning ("unsupported arg to `__builtin_frame_address'");
3069 warning ("unsupported arg to `__builtin_return_address'");
3073 /* For __builtin_frame_address, return what we've got. */
3074 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
3077 if (GET_CODE (tem) != REG
3078 && ! CONSTANT_P (tem))
3079 tem = copy_to_mode_reg (Pmode, tem);
3084 /* Expand a call to the alloca builtin, with arguments ARGLIST. Return 0 if
3085 we failed and the caller should emit a normal call, otherwise try to get
3086 the result in TARGET, if convenient. */
3089 expand_builtin_alloca (arglist, target)
3096 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
3099 /* Compute the argument. */
3100 op0 = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
3102 /* Allocate the desired space. */
3103 result = allocate_dynamic_stack_space (op0, target, BITS_PER_UNIT);
3105 #ifdef POINTERS_EXTEND_UNSIGNED
3106 result = convert_memory_address (ptr_mode, result);
3112 /* Expand a call to the ffs builtin. The arguments are in ARGLIST.
3113 Return 0 if a normal call should be emitted rather than expanding the
3114 function in-line. If convenient, the result should be placed in TARGET.
3115 SUBTARGET may be used as the target for computing one of EXP's operands. */
3118 expand_builtin_ffs (arglist, target, subtarget)
3120 rtx target, subtarget;
3123 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
3126 /* Compute the argument. */
3127 op0 = expand_expr (TREE_VALUE (arglist), subtarget, VOIDmode, 0);
3128 /* Compute ffs, into TARGET if possible.
3129 Set TARGET to wherever the result comes back. */
3130 target = expand_unop (TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist))),
3131 ffs_optab, op0, target, 1);
3137 /* If the string passed to fputs is a constant and is one character
3138 long, we attempt to transform this call into __builtin_fputc(). */
3141 expand_builtin_fputs (arglist, ignore)
3145 tree len, fn, fn_fputc = built_in_decls[BUILT_IN_FPUTC],
3146 fn_fwrite = built_in_decls[BUILT_IN_FWRITE];
3148 /* If the return value is used, or the replacement _DECL isn't
3149 initialized, don't do the transformation. */
3150 if (!ignore || !fn_fputc || !fn_fwrite)
3153 /* Verify the arguments in the original call. */
3154 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)
3155 || current_function_check_memory_usage)
3158 /* Get the length of the string passed to fputs. If the length
3159 can't be determined, punt. */
3160 if (!(len = c_strlen (TREE_VALUE (arglist)))
3161 || TREE_CODE (len) != INTEGER_CST)
3164 switch (compare_tree_int (len, 1))
3166 case -1: /* length is 0, delete the call entirely . */
3168 /* Evaluate and ignore the argument in case it has
3170 expand_expr (TREE_VALUE (TREE_CHAIN (arglist)), const0_rtx,
3171 VOIDmode, EXPAND_NORMAL);
3174 case 0: /* length is 1, call fputc. */
3176 const char *p = c_getstr (TREE_VALUE (arglist));
3180 /* New argument list transforming fputs(string, stream) to
3181 fputc(string[0], stream). */
3183 build_tree_list (NULL_TREE, TREE_VALUE (TREE_CHAIN (arglist)));
3185 tree_cons (NULL_TREE, build_int_2 (p[0], 0), arglist);
3191 case 1: /* length is greater than 1, call fwrite. */
3193 tree string_arg = TREE_VALUE (arglist);
3195 /* New argument list transforming fputs(string, stream) to
3196 fwrite(string, 1, len, stream). */
3197 arglist = build_tree_list (NULL_TREE, TREE_VALUE (TREE_CHAIN (arglist)));
3198 arglist = tree_cons (NULL_TREE, len, arglist);
3199 arglist = tree_cons (NULL_TREE, size_one_node, arglist);
3200 arglist = tree_cons (NULL_TREE, string_arg, arglist);
3208 return expand_expr (build_function_call_expr (fn, arglist),
3209 (ignore ? const0_rtx : NULL_RTX),
3210 VOIDmode, EXPAND_NORMAL);
3213 /* Expand a call to __builtin_expect. We return our argument and emit a
3214 NOTE_INSN_EXPECTED_VALUE note. This is the expansion of __builtin_expect in
3215 a non-jump context. */
3218 expand_builtin_expect (arglist, target)
3225 if (arglist == NULL_TREE
3226 || TREE_CHAIN (arglist) == NULL_TREE)
3228 exp = TREE_VALUE (arglist);
3229 c = TREE_VALUE (TREE_CHAIN (arglist));
3231 if (TREE_CODE (c) != INTEGER_CST)
3233 error ("second arg to `__builtin_expect' must be a constant");
3234 c = integer_zero_node;
3237 target = expand_expr (exp, target, VOIDmode, EXPAND_NORMAL);
3239 /* Don't bother with expected value notes for integral constants. */
3240 if (GET_CODE (target) != CONST_INT)
3242 /* We do need to force this into a register so that we can be
3243 moderately sure to be able to correctly interpret the branch
3245 target = force_reg (GET_MODE (target), target);
3247 rtx_c = expand_expr (c, NULL_RTX, GET_MODE (target), EXPAND_NORMAL);
3249 note = emit_note (NULL, NOTE_INSN_EXPECTED_VALUE);
3250 NOTE_EXPECTED_VALUE (note) = gen_rtx_EQ (VOIDmode, target, rtx_c);
3256 /* Like expand_builtin_expect, except do this in a jump context. This is
3257 called from do_jump if the conditional is a __builtin_expect. Return either
3258 a SEQUENCE of insns to emit the jump or NULL if we cannot optimize
3259 __builtin_expect. We need to optimize this at jump time so that machines
3260 like the PowerPC don't turn the test into a SCC operation, and then jump
3261 based on the test being 0/1. */
3264 expand_builtin_expect_jump (exp, if_false_label, if_true_label)
3269 tree arglist = TREE_OPERAND (exp, 1);
3270 tree arg0 = TREE_VALUE (arglist);
3271 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
3274 /* Only handle __builtin_expect (test, 0) and
3275 __builtin_expect (test, 1). */
3276 if (TREE_CODE (TREE_TYPE (arg1)) == INTEGER_TYPE
3277 && (integer_zerop (arg1) || integer_onep (arg1)))
3282 /* If we fail to locate an appropriate conditional jump, we'll
3283 fall back to normal evaluation. Ensure that the expression
3284 can be re-evaluated. */
3285 switch (unsafe_for_reeval (arg0))
3290 case 1: /* Mildly unsafe. */
3291 arg0 = unsave_expr (arg0);
3294 case 2: /* Wildly unsafe. */
3298 /* Expand the jump insns. */
3300 do_jump (arg0, if_false_label, if_true_label);
3301 ret = gen_sequence ();
3304 /* Now that the __builtin_expect has been validated, go through and add
3305 the expect's to each of the conditional jumps. If we run into an
3306 error, just give up and generate the 'safe' code of doing a SCC
3307 operation and then doing a branch on that. */
3308 for (j = 0; j < XVECLEN (ret, 0); j++)
3310 rtx insn = XVECEXP (ret, 0, j);
3313 if (GET_CODE (insn) == JUMP_INSN && any_condjump_p (insn)
3314 && (pattern = pc_set (insn)) != NULL_RTX)
3316 rtx ifelse = SET_SRC (pattern);
3320 if (GET_CODE (ifelse) != IF_THEN_ELSE)
3323 if (GET_CODE (XEXP (ifelse, 1)) == LABEL_REF)
3326 label = XEXP (XEXP (ifelse, 1), 0);
3328 /* An inverted jump reverses the probabilities. */
3329 else if (GET_CODE (XEXP (ifelse, 2)) == LABEL_REF)
3332 label = XEXP (XEXP (ifelse, 2), 0);
3334 /* We shouldn't have to worry about conditional returns during
3335 the expansion stage, but handle it gracefully anyway. */
3336 else if (GET_CODE (XEXP (ifelse, 1)) == RETURN)
3341 /* An inverted return reverses the probabilities. */
3342 else if (GET_CODE (XEXP (ifelse, 2)) == RETURN)
3350 /* If the test is expected to fail, reverse the
3352 if (integer_zerop (arg1))
3355 /* If we are jumping to the false label, reverse the
3357 if (label == NULL_RTX)
3358 ; /* conditional return */
3359 else if (label == if_false_label)
3361 else if (label != if_true_label)
3365 predict_insn_def (insn, PRED_BUILTIN_EXPECT, taken);
3369 /* If no jumps were modified, fail and do __builtin_expect the normal
3378 /* Expand an expression EXP that calls a built-in function,
3379 with result going to TARGET if that's convenient
3380 (and in mode MODE if that's convenient).
3381 SUBTARGET may be used as the target for computing one of EXP's operands.
3382 IGNORE is nonzero if the value is to be ignored. */
3385 expand_builtin (exp, target, subtarget, mode, ignore)
3389 enum machine_mode mode;
3392 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
3393 tree arglist = TREE_OPERAND (exp, 1);
3394 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
3396 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
3397 return (*targetm.expand_builtin) (exp, target, subtarget, mode, ignore);
3399 /* When not optimizing, generate calls to library functions for a certain
3401 if (! optimize && ! CALLED_AS_BUILT_IN (fndecl)
3402 && (fcode == BUILT_IN_SIN || fcode == BUILT_IN_COS
3403 || fcode == BUILT_IN_FSQRT || fcode == BUILT_IN_SQRTF
3404 || fcode == BUILT_IN_SQRTL || fcode == BUILT_IN_MEMSET
3405 || fcode == BUILT_IN_MEMCPY || fcode == BUILT_IN_MEMCMP
3406 || fcode == BUILT_IN_BCMP || fcode == BUILT_IN_BZERO
3407 || fcode == BUILT_IN_INDEX || fcode == BUILT_IN_RINDEX
3408 || fcode == BUILT_IN_STRCHR || fcode == BUILT_IN_STRRCHR
3409 || fcode == BUILT_IN_STRLEN || fcode == BUILT_IN_STRCPY
3410 || fcode == BUILT_IN_STRNCPY || fcode == BUILT_IN_STRNCMP
3411 || fcode == BUILT_IN_STRSTR || fcode == BUILT_IN_STRPBRK
3412 || fcode == BUILT_IN_STRCAT || fcode == BUILT_IN_STRNCAT
3413 || fcode == BUILT_IN_STRSPN || fcode == BUILT_IN_STRCSPN
3414 || fcode == BUILT_IN_STRCMP || fcode == BUILT_IN_FFS
3415 || fcode == BUILT_IN_PUTCHAR || fcode == BUILT_IN_PUTS
3416 || fcode == BUILT_IN_PRINTF || fcode == BUILT_IN_FPUTC
3417 || fcode == BUILT_IN_FPUTS || fcode == BUILT_IN_FWRITE))
3418 return expand_call (exp, target, ignore);
3424 case BUILT_IN_LLABS:
3425 case BUILT_IN_IMAXABS:
3427 case BUILT_IN_FABSF:
3428 case BUILT_IN_FABSL:
3429 /* build_function_call changes these into ABS_EXPR. */
3433 case BUILT_IN_CONJF:
3434 case BUILT_IN_CONJL:
3435 case BUILT_IN_CREAL:
3436 case BUILT_IN_CREALF:
3437 case BUILT_IN_CREALL:
3438 case BUILT_IN_CIMAG:
3439 case BUILT_IN_CIMAGF:
3440 case BUILT_IN_CIMAGL:
3441 /* expand_tree_builtin changes these into CONJ_EXPR, REALPART_EXPR
3442 and IMAGPART_EXPR. */
3451 /* Treat these like sqrt only if unsafe math optimizations are allowed,
3452 because of possible accuracy problems. */
3453 if (! flag_unsafe_math_optimizations)
3455 case BUILT_IN_FSQRT:
3456 case BUILT_IN_SQRTF:
3457 case BUILT_IN_SQRTL:
3458 target = expand_builtin_mathfn (exp, target, subtarget);
3466 case BUILT_IN_APPLY_ARGS:
3467 return expand_builtin_apply_args ();
3469 /* __builtin_apply (FUNCTION, ARGUMENTS, ARGSIZE) invokes
3470 FUNCTION with a copy of the parameters described by
3471 ARGUMENTS, and ARGSIZE. It returns a block of memory
3472 allocated on the stack into which is stored all the registers
3473 that might possibly be used for returning the result of a
3474 function. ARGUMENTS is the value returned by
3475 __builtin_apply_args. ARGSIZE is the number of bytes of
3476 arguments that must be copied. ??? How should this value be
3477 computed? We'll also need a safe worst case value for varargs
3479 case BUILT_IN_APPLY:
3480 if (!validate_arglist (arglist, POINTER_TYPE,
3481 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)
3482 && !validate_arglist (arglist, REFERENCE_TYPE,
3483 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3491 for (t = arglist, i = 0; t; t = TREE_CHAIN (t), i++)
3492 ops[i] = expand_expr (TREE_VALUE (t), NULL_RTX, VOIDmode, 0);
3494 return expand_builtin_apply (ops[0], ops[1], ops[2]);
3497 /* __builtin_return (RESULT) causes the function to return the
3498 value described by RESULT. RESULT is address of the block of
3499 memory returned by __builtin_apply. */
3500 case BUILT_IN_RETURN:
3501 if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
3502 expand_builtin_return (expand_expr (TREE_VALUE (arglist),
3503 NULL_RTX, VOIDmode, 0));
3506 case BUILT_IN_SAVEREGS:
3507 return expand_builtin_saveregs ();
3509 case BUILT_IN_ARGS_INFO:
3510 return expand_builtin_args_info (exp);
3512 /* Return the address of the first anonymous stack arg. */
3513 case BUILT_IN_NEXT_ARG:
3514 return expand_builtin_next_arg (arglist);
3516 case BUILT_IN_CLASSIFY_TYPE:
3517 return expand_builtin_classify_type (arglist);
3519 case BUILT_IN_CONSTANT_P:
3520 return expand_builtin_constant_p (exp);
3522 case BUILT_IN_FRAME_ADDRESS:
3523 case BUILT_IN_RETURN_ADDRESS:
3524 return expand_builtin_frame_address (exp);
3526 /* Returns the address of the area where the structure is returned.
3528 case BUILT_IN_AGGREGATE_INCOMING_ADDRESS:
3530 || ! AGGREGATE_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl)))
3531 || GET_CODE (DECL_RTL (DECL_RESULT (current_function_decl))) != MEM)
3534 return XEXP (DECL_RTL (DECL_RESULT (current_function_decl)), 0);
3536 case BUILT_IN_ALLOCA:
3537 target = expand_builtin_alloca (arglist, target);
3543 target = expand_builtin_ffs (arglist, target, subtarget);
3548 case BUILT_IN_STRLEN:
3549 target = expand_builtin_strlen (exp, target);
3554 case BUILT_IN_STRCPY:
3555 target = expand_builtin_strcpy (exp);
3560 case BUILT_IN_STRNCPY:
3561 target = expand_builtin_strncpy (arglist, target, mode);
3566 case BUILT_IN_STRCAT:
3567 target = expand_builtin_strcat (arglist, target, mode);
3572 case BUILT_IN_STRNCAT:
3573 target = expand_builtin_strncat (arglist, target, mode);
3578 case BUILT_IN_STRSPN:
3579 target = expand_builtin_strspn (arglist, target, mode);
3584 case BUILT_IN_STRCSPN:
3585 target = expand_builtin_strcspn (arglist, target, mode);
3590 case BUILT_IN_STRSTR:
3591 target = expand_builtin_strstr (arglist, target, mode);
3596 case BUILT_IN_STRPBRK:
3597 target = expand_builtin_strpbrk (arglist, target, mode);
3602 case BUILT_IN_INDEX:
3603 case BUILT_IN_STRCHR:
3604 target = expand_builtin_strchr (arglist, target, mode);
3609 case BUILT_IN_RINDEX:
3610 case BUILT_IN_STRRCHR:
3611 target = expand_builtin_strrchr (arglist, target, mode);
3616 case BUILT_IN_MEMCPY:
3617 target = expand_builtin_memcpy (arglist);
3622 case BUILT_IN_MEMSET:
3623 target = expand_builtin_memset (exp);
3628 case BUILT_IN_BZERO:
3629 target = expand_builtin_bzero (exp);
3634 case BUILT_IN_STRCMP:
3635 target = expand_builtin_strcmp (exp, target, mode);
3640 case BUILT_IN_STRNCMP:
3641 target = expand_builtin_strncmp (exp, target, mode);
3646 /* These comparison functions need an instruction that returns an actual
3647 index. An ordinary compare that just sets the condition codes
3649 #ifdef HAVE_cmpstrsi
3651 case BUILT_IN_MEMCMP:
3652 target = expand_builtin_memcmp (exp, arglist, target);
3658 case BUILT_IN_MEMCMP:
3662 case BUILT_IN_SETJMP:
3663 target = expand_builtin_setjmp (arglist, target);
3668 /* __builtin_longjmp is passed a pointer to an array of five words.
3669 It's similar to the C library longjmp function but works with
3670 __builtin_setjmp above. */
3671 case BUILT_IN_LONGJMP:
3672 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3676 rtx buf_addr = expand_expr (TREE_VALUE (arglist), subtarget,
3678 rtx value = expand_expr (TREE_VALUE (TREE_CHAIN (arglist)),
3679 NULL_RTX, VOIDmode, 0);
3681 if (value != const1_rtx)
3683 error ("__builtin_longjmp second argument must be 1");
3687 expand_builtin_longjmp (buf_addr, value);
3694 emit_insn (gen_trap ());
3697 error ("__builtin_trap not supported by this target");
3701 case BUILT_IN_PUTCHAR:
3703 case BUILT_IN_FPUTC:
3704 case BUILT_IN_FWRITE:
3706 case BUILT_IN_FPUTS:
3707 target = expand_builtin_fputs (arglist, ignore);
3712 /* Various hooks for the DWARF 2 __throw routine. */
3713 case BUILT_IN_UNWIND_INIT:
3714 expand_builtin_unwind_init ();
3716 case BUILT_IN_DWARF_CFA:
3717 return virtual_cfa_rtx;
3718 #ifdef DWARF2_UNWIND_INFO
3719 case BUILT_IN_DWARF_FP_REGNUM:
3720 return expand_builtin_dwarf_fp_regnum ();
3721 case BUILT_IN_INIT_DWARF_REG_SIZES:
3722 expand_builtin_init_dwarf_reg_sizes (TREE_VALUE (arglist));
3725 case BUILT_IN_FROB_RETURN_ADDR:
3726 return expand_builtin_frob_return_addr (TREE_VALUE (arglist));
3727 case BUILT_IN_EXTRACT_RETURN_ADDR:
3728 return expand_builtin_extract_return_addr (TREE_VALUE (arglist));
3729 case BUILT_IN_EH_RETURN:
3730 expand_builtin_eh_return (TREE_VALUE (arglist),
3731 TREE_VALUE (TREE_CHAIN (arglist)));
3733 #ifdef EH_RETURN_DATA_REGNO
3734 case BUILT_IN_EH_RETURN_DATA_REGNO:
3735 return expand_builtin_eh_return_data_regno (arglist);
3737 case BUILT_IN_VARARGS_START:
3738 return expand_builtin_va_start (0, arglist);
3739 case BUILT_IN_STDARG_START:
3740 return expand_builtin_va_start (1, arglist);
3741 case BUILT_IN_VA_END:
3742 return expand_builtin_va_end (arglist);
3743 case BUILT_IN_VA_COPY:
3744 return expand_builtin_va_copy (arglist);
3745 case BUILT_IN_EXPECT:
3746 return expand_builtin_expect (arglist, target);
3748 default: /* just do library call, if unknown builtin */
3749 error ("built-in function `%s' not currently supported",
3750 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
3753 /* The switch statement above can drop through to cause the function
3754 to be called normally. */
3755 return expand_call (exp, target, ignore);
3758 /* Fold a call to __builtin_constant_p, if we know it will evaluate to a
3759 constant. ARGLIST is the argument list of the call. */
3762 fold_builtin_constant_p (arglist)
3768 arglist = TREE_VALUE (arglist);
3770 /* We return 1 for a numeric type that's known to be a constant
3771 value at compile-time or for an aggregate type that's a
3772 literal constant. */
3773 STRIP_NOPS (arglist);
3775 /* If we know this is a constant, emit the constant of one. */
3776 if (TREE_CODE_CLASS (TREE_CODE (arglist)) == 'c'
3777 || (TREE_CODE (arglist) == CONSTRUCTOR
3778 && TREE_CONSTANT (arglist))
3779 || (TREE_CODE (arglist) == ADDR_EXPR
3780 && TREE_CODE (TREE_OPERAND (arglist, 0)) == STRING_CST))
3781 return integer_one_node;
3783 /* If we aren't going to be running CSE or this expression
3784 has side effects, show we don't know it to be a constant.
3785 Likewise if it's a pointer or aggregate type since in those
3786 case we only want literals, since those are only optimized
3787 when generating RTL, not later.
3788 And finally, if we are compiling an initializer, not code, we
3789 need to return a definite result now; there's not going to be any
3790 more optimization done. */
3791 if (TREE_SIDE_EFFECTS (arglist) || cse_not_expected
3792 || AGGREGATE_TYPE_P (TREE_TYPE (arglist))
3793 || POINTER_TYPE_P (TREE_TYPE (arglist))
3795 return integer_zero_node;
3800 /* Fold a call to __builtin_classify_type. */
3803 fold_builtin_classify_type (arglist)
3807 return build_int_2 (no_type_class, 0);
3809 return build_int_2 (type_to_class (TREE_TYPE (TREE_VALUE (arglist))), 0);
3812 /* Used by constant folding to eliminate some builtin calls early. EXP is
3813 the CALL_EXPR of a call to a builtin function. */
3819 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
3820 tree arglist = TREE_OPERAND (exp, 1);
3821 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
3823 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
3828 case BUILT_IN_CONSTANT_P:
3829 return fold_builtin_constant_p (arglist);
3831 case BUILT_IN_CLASSIFY_TYPE:
3832 return fold_builtin_classify_type (arglist);
3834 case BUILT_IN_STRLEN:
3835 if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
3837 tree len = c_strlen (TREE_VALUE (arglist));
3851 build_function_call_expr (fn, arglist)
3856 call_expr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
3857 call_expr = build (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)),
3858 call_expr, arglist);
3859 TREE_SIDE_EFFECTS (call_expr) = 1;
3860 return fold (call_expr);
3863 /* This function validates the types of a function call argument list
3864 represented as a tree chain of parameters against a specified list
3865 of tree_codes. If the last specifier is a 0, that represents an
3866 ellipses, otherwise the last specifier must be a VOID_TYPE. */
3869 validate_arglist VPARAMS ((tree arglist, ...))
3871 enum tree_code code;
3874 VA_OPEN (ap, arglist);
3875 VA_FIXEDARG (ap, tree, arglist);
3878 code = va_arg (ap, enum tree_code);
3882 /* This signifies an ellipses, any further arguments are all ok. */
3886 /* This signifies an endlink, if no arguments remain, return
3887 true, otherwise return false. */
3891 /* If no parameters remain or the parameter's code does not
3892 match the specified code, return false. Otherwise continue
3893 checking any remaining arguments. */
3894 if (arglist == 0 || code != TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))))
3898 arglist = TREE_CHAIN (arglist);
3901 /* We need gotos here since we can only have one VA_CLOSE in a
3909 /* Default version of target-specific builtin setup that does nothing. */
3912 default_init_builtins ()
3916 /* Default target-specific builtin expander that does nothing. */
3919 default_expand_builtin (exp, target, subtarget, mode, ignore)
3920 tree exp ATTRIBUTE_UNUSED;
3921 rtx target ATTRIBUTE_UNUSED;
3922 rtx subtarget ATTRIBUTE_UNUSED;
3923 enum machine_mode mode ATTRIBUTE_UNUSED;
3924 int ignore ATTRIBUTE_UNUSED;