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)
270 else if (! host_integerp (offset_node, 0))
273 offset = tree_low_cst (offset_node, 0);
275 /* If the offset is known to be out of bounds, warn, and call strlen at
277 if (offset < 0 || offset > max)
279 warning ("offset outside bounds of constant string");
283 /* Use strlen to search for the first zero byte. Since any strings
284 constructed with build_string will have nulls appended, we win even
285 if we get handed something like (char[4])"abcd".
287 Since OFFSET is our starting index into the string, no further
288 calculation is needed. */
289 return ssize_int (strlen (ptr + offset));
292 /* Return a char pointer for a C string if it is a string constant
293 or sum of string constant and integer constant. */
301 src = string_constant (src, &offset_node);
305 if (offset_node == 0)
306 return TREE_STRING_POINTER (src);
307 else if (!host_integerp (offset_node, 1)
308 || compare_tree_int (offset_node, TREE_STRING_LENGTH (src) - 1) > 0)
311 return TREE_STRING_POINTER (src) + tree_low_cst (offset_node, 1);
314 /* Return a CONST_INT or CONST_DOUBLE corresponding to target reading
315 GET_MODE_BITSIZE (MODE) bits from string constant STR. */
318 c_readstr (str, mode)
320 enum machine_mode mode;
326 if (GET_MODE_CLASS (mode) != MODE_INT)
331 for (i = 0; i < GET_MODE_SIZE (mode); i++)
334 if (WORDS_BIG_ENDIAN)
335 j = GET_MODE_SIZE (mode) - i - 1;
336 if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN
337 && GET_MODE_SIZE (mode) > UNITS_PER_WORD)
338 j = j + UNITS_PER_WORD - 2 * (j % UNITS_PER_WORD) - 1;
340 if (j > 2 * HOST_BITS_PER_WIDE_INT)
343 ch = (unsigned char) str[i];
344 c[j / HOST_BITS_PER_WIDE_INT] |= ch << (j % HOST_BITS_PER_WIDE_INT);
346 return immed_double_const (c[0], c[1], mode);
349 /* Cast a target constant CST to target CHAR and if that value fits into
350 host char type, return zero and put that value into variable pointed by
354 target_char_cast (cst, p)
358 unsigned HOST_WIDE_INT val, hostval;
360 if (!host_integerp (cst, 1)
361 || CHAR_TYPE_SIZE > HOST_BITS_PER_WIDE_INT)
364 val = tree_low_cst (cst, 1);
365 if (CHAR_TYPE_SIZE < HOST_BITS_PER_WIDE_INT)
366 val &= (((unsigned HOST_WIDE_INT) 1) << CHAR_TYPE_SIZE) - 1;
369 if (HOST_BITS_PER_CHAR < HOST_BITS_PER_WIDE_INT)
370 hostval &= (((unsigned HOST_WIDE_INT) 1) << HOST_BITS_PER_CHAR) - 1;
379 /* Given TEM, a pointer to a stack frame, follow the dynamic chain COUNT
380 times to get the address of either a higher stack frame, or a return
381 address located within it (depending on FNDECL_CODE). */
384 expand_builtin_return_addr (fndecl_code, count, tem)
385 enum built_in_function fndecl_code;
391 /* Some machines need special handling before we can access
392 arbitrary frames. For example, on the sparc, we must first flush
393 all register windows to the stack. */
394 #ifdef SETUP_FRAME_ADDRESSES
396 SETUP_FRAME_ADDRESSES ();
399 /* On the sparc, the return address is not in the frame, it is in a
400 register. There is no way to access it off of the current frame
401 pointer, but it can be accessed off the previous frame pointer by
402 reading the value from the register window save area. */
403 #ifdef RETURN_ADDR_IN_PREVIOUS_FRAME
404 if (fndecl_code == BUILT_IN_RETURN_ADDRESS)
408 /* Scan back COUNT frames to the specified frame. */
409 for (i = 0; i < count; i++)
411 /* Assume the dynamic chain pointer is in the word that the
412 frame address points to, unless otherwise specified. */
413 #ifdef DYNAMIC_CHAIN_ADDRESS
414 tem = DYNAMIC_CHAIN_ADDRESS (tem);
416 tem = memory_address (Pmode, tem);
417 tem = gen_rtx_MEM (Pmode, tem);
418 set_mem_alias_set (tem, get_frame_alias_set ());
419 tem = copy_to_reg (tem);
422 /* For __builtin_frame_address, return what we've got. */
423 if (fndecl_code == BUILT_IN_FRAME_ADDRESS)
426 /* For __builtin_return_address, Get the return address from that
428 #ifdef RETURN_ADDR_RTX
429 tem = RETURN_ADDR_RTX (count, tem);
431 tem = memory_address (Pmode,
432 plus_constant (tem, GET_MODE_SIZE (Pmode)));
433 tem = gen_rtx_MEM (Pmode, tem);
434 set_mem_alias_set (tem, get_frame_alias_set ());
439 /* Alias set used for setjmp buffer. */
440 static HOST_WIDE_INT setjmp_alias_set = -1;
442 /* Construct the leading half of a __builtin_setjmp call. Control will
443 return to RECEIVER_LABEL. This is used directly by sjlj exception
447 expand_builtin_setjmp_setup (buf_addr, receiver_label)
451 enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
455 if (setjmp_alias_set == -1)
456 setjmp_alias_set = new_alias_set ();
458 #ifdef POINTERS_EXTEND_UNSIGNED
459 buf_addr = convert_memory_address (Pmode, buf_addr);
462 buf_addr = force_reg (Pmode, force_operand (buf_addr, NULL_RTX));
466 /* We store the frame pointer and the address of receiver_label in
467 the buffer and use the rest of it for the stack save area, which
468 is machine-dependent. */
470 #ifndef BUILTIN_SETJMP_FRAME_VALUE
471 #define BUILTIN_SETJMP_FRAME_VALUE virtual_stack_vars_rtx
474 mem = gen_rtx_MEM (Pmode, buf_addr);
475 set_mem_alias_set (mem, setjmp_alias_set);
476 emit_move_insn (mem, BUILTIN_SETJMP_FRAME_VALUE);
478 mem = gen_rtx_MEM (Pmode, plus_constant (buf_addr, GET_MODE_SIZE (Pmode))),
479 set_mem_alias_set (mem, setjmp_alias_set);
481 emit_move_insn (validize_mem (mem),
482 force_reg (Pmode, gen_rtx_LABEL_REF (Pmode, receiver_label)));
484 stack_save = gen_rtx_MEM (sa_mode,
485 plus_constant (buf_addr,
486 2 * GET_MODE_SIZE (Pmode)));
487 set_mem_alias_set (stack_save, setjmp_alias_set);
488 emit_stack_save (SAVE_NONLOCAL, &stack_save, NULL_RTX);
490 /* If there is further processing to do, do it. */
491 #ifdef HAVE_builtin_setjmp_setup
492 if (HAVE_builtin_setjmp_setup)
493 emit_insn (gen_builtin_setjmp_setup (buf_addr));
496 /* Tell optimize_save_area_alloca that extra work is going to
497 need to go on during alloca. */
498 current_function_calls_setjmp = 1;
500 /* Set this so all the registers get saved in our frame; we need to be
501 able to copy the saved values for any registers from frames we unwind. */
502 current_function_has_nonlocal_label = 1;
505 /* Construct the trailing part of a __builtin_setjmp call.
506 This is used directly by sjlj exception handling code. */
509 expand_builtin_setjmp_receiver (receiver_label)
510 rtx receiver_label ATTRIBUTE_UNUSED;
512 /* Clobber the FP when we get here, so we have to make sure it's
513 marked as used by this function. */
514 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
516 /* Mark the static chain as clobbered here so life information
517 doesn't get messed up for it. */
518 emit_insn (gen_rtx_CLOBBER (VOIDmode, static_chain_rtx));
520 /* Now put in the code to restore the frame pointer, and argument
521 pointer, if needed. The code below is from expand_end_bindings
522 in stmt.c; see detailed documentation there. */
523 #ifdef HAVE_nonlocal_goto
524 if (! HAVE_nonlocal_goto)
526 emit_move_insn (virtual_stack_vars_rtx, hard_frame_pointer_rtx);
528 #if ARG_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
529 if (fixed_regs[ARG_POINTER_REGNUM])
531 #ifdef ELIMINABLE_REGS
533 static const struct elims {const int from, to;} elim_regs[] = ELIMINABLE_REGS;
535 for (i = 0; i < ARRAY_SIZE (elim_regs); i++)
536 if (elim_regs[i].from == ARG_POINTER_REGNUM
537 && elim_regs[i].to == HARD_FRAME_POINTER_REGNUM)
540 if (i == ARRAY_SIZE (elim_regs))
543 /* Now restore our arg pointer from the address at which it
544 was saved in our stack frame. */
545 emit_move_insn (virtual_incoming_args_rtx,
546 copy_to_reg (get_arg_pointer_save_area (cfun)));
551 #ifdef HAVE_builtin_setjmp_receiver
552 if (HAVE_builtin_setjmp_receiver)
553 emit_insn (gen_builtin_setjmp_receiver (receiver_label));
556 #ifdef HAVE_nonlocal_goto_receiver
557 if (HAVE_nonlocal_goto_receiver)
558 emit_insn (gen_nonlocal_goto_receiver ());
563 /* @@@ This is a kludge. Not all machine descriptions define a blockage
564 insn, but we must not allow the code we just generated to be reordered
565 by scheduling. Specifically, the update of the frame pointer must
566 happen immediately, not later. So emit an ASM_INPUT to act as blockage
568 emit_insn (gen_rtx_ASM_INPUT (VOIDmode, ""));
571 /* __builtin_setjmp is passed a pointer to an array of five words (not
572 all will be used on all machines). It operates similarly to the C
573 library function of the same name, but is more efficient. Much of
574 the code below (and for longjmp) is copied from the handling of
577 NOTE: This is intended for use by GNAT and the exception handling
578 scheme in the compiler and will only work in the method used by
582 expand_builtin_setjmp (arglist, target)
586 rtx buf_addr, next_lab, cont_lab;
588 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
591 if (target == 0 || GET_CODE (target) != REG
592 || REGNO (target) < FIRST_PSEUDO_REGISTER)
593 target = gen_reg_rtx (TYPE_MODE (integer_type_node));
595 buf_addr = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
597 next_lab = gen_label_rtx ();
598 cont_lab = gen_label_rtx ();
600 expand_builtin_setjmp_setup (buf_addr, next_lab);
602 /* Set TARGET to zero and branch to the continue label. */
603 emit_move_insn (target, const0_rtx);
604 emit_jump_insn (gen_jump (cont_lab));
606 emit_label (next_lab);
608 expand_builtin_setjmp_receiver (next_lab);
610 /* Set TARGET to one. */
611 emit_move_insn (target, const1_rtx);
612 emit_label (cont_lab);
614 /* Tell flow about the strange goings on. Putting `next_lab' on
615 `nonlocal_goto_handler_labels' to indicates that function
616 calls may traverse the arc back to this label. */
618 current_function_has_nonlocal_label = 1;
619 nonlocal_goto_handler_labels
620 = gen_rtx_EXPR_LIST (VOIDmode, next_lab, nonlocal_goto_handler_labels);
625 /* __builtin_longjmp is passed a pointer to an array of five words (not
626 all will be used on all machines). It operates similarly to the C
627 library function of the same name, but is more efficient. Much of
628 the code below is copied from the handling of non-local gotos.
630 NOTE: This is intended for use by GNAT and the exception handling
631 scheme in the compiler and will only work in the method used by
635 expand_builtin_longjmp (buf_addr, value)
638 rtx fp, lab, stack, insn;
639 enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
641 if (setjmp_alias_set == -1)
642 setjmp_alias_set = new_alias_set ();
644 #ifdef POINTERS_EXTEND_UNSIGNED
645 buf_addr = convert_memory_address (Pmode, buf_addr);
647 buf_addr = force_reg (Pmode, buf_addr);
649 /* We used to store value in static_chain_rtx, but that fails if pointers
650 are smaller than integers. We instead require that the user must pass
651 a second argument of 1, because that is what builtin_setjmp will
652 return. This also makes EH slightly more efficient, since we are no
653 longer copying around a value that we don't care about. */
654 if (value != const1_rtx)
657 current_function_calls_longjmp = 1;
659 #ifdef HAVE_builtin_longjmp
660 if (HAVE_builtin_longjmp)
661 emit_insn (gen_builtin_longjmp (buf_addr));
665 fp = gen_rtx_MEM (Pmode, buf_addr);
666 lab = gen_rtx_MEM (Pmode, plus_constant (buf_addr,
667 GET_MODE_SIZE (Pmode)));
669 stack = gen_rtx_MEM (sa_mode, plus_constant (buf_addr,
670 2 * GET_MODE_SIZE (Pmode)));
671 set_mem_alias_set (fp, setjmp_alias_set);
672 set_mem_alias_set (lab, setjmp_alias_set);
673 set_mem_alias_set (stack, setjmp_alias_set);
675 /* Pick up FP, label, and SP from the block and jump. This code is
676 from expand_goto in stmt.c; see there for detailed comments. */
677 #if HAVE_nonlocal_goto
678 if (HAVE_nonlocal_goto)
679 /* We have to pass a value to the nonlocal_goto pattern that will
680 get copied into the static_chain pointer, but it does not matter
681 what that value is, because builtin_setjmp does not use it. */
682 emit_insn (gen_nonlocal_goto (value, lab, stack, fp));
686 lab = copy_to_reg (lab);
688 emit_move_insn (hard_frame_pointer_rtx, fp);
689 emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
691 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
692 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
693 emit_indirect_jump (lab);
697 /* Search backwards and mark the jump insn as a non-local goto.
698 Note that this precludes the use of __builtin_longjmp to a
699 __builtin_setjmp target in the same function. However, we've
700 already cautioned the user that these functions are for
701 internal exception handling use only. */
702 for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
704 if (GET_CODE (insn) == JUMP_INSN)
706 REG_NOTES (insn) = alloc_EXPR_LIST (REG_NON_LOCAL_GOTO, const0_rtx,
710 else if (GET_CODE (insn) == CALL_INSN)
715 /* Get a MEM rtx for expression EXP which is the address of an operand
716 to be used to be used in a string instruction (cmpstrsi, movstrsi, ..). */
722 rtx mem = gen_rtx_MEM (BLKmode,
723 memory_address (BLKmode,
724 expand_expr (exp, NULL_RTX,
725 ptr_mode, EXPAND_SUM)));
727 /* Get an expression we can use to find the attributes to assign to MEM.
728 If it is an ADDR_EXPR, use the operand. Otherwise, dereference it if
729 we can. First remove any nops. */
730 while ((TREE_CODE (exp) == NOP_EXPR || TREE_CODE (exp) == CONVERT_EXPR
731 || TREE_CODE (exp) == NON_LVALUE_EXPR)
732 && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (exp, 0))))
733 exp = TREE_OPERAND (exp, 0);
735 if (TREE_CODE (exp) == ADDR_EXPR)
736 exp = TREE_OPERAND (exp, 0);
737 else if (POINTER_TYPE_P (TREE_TYPE (exp)))
738 exp = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (exp)), exp);
742 set_mem_attributes (mem, exp, 0);
743 /* memcpy, memset and other builtin stringops can alias with anything. */
744 set_mem_alias_set (mem, 0);
748 /* Built-in functions to perform an untyped call and return. */
750 /* For each register that may be used for calling a function, this
751 gives a mode used to copy the register's value. VOIDmode indicates
752 the register is not used for calling a function. If the machine
753 has register windows, this gives only the outbound registers.
754 INCOMING_REGNO gives the corresponding inbound register. */
755 static enum machine_mode apply_args_mode[FIRST_PSEUDO_REGISTER];
757 /* For each register that may be used for returning values, this gives
758 a mode used to copy the register's value. VOIDmode indicates the
759 register is not used for returning values. If the machine has
760 register windows, this gives only the outbound registers.
761 INCOMING_REGNO gives the corresponding inbound register. */
762 static enum machine_mode apply_result_mode[FIRST_PSEUDO_REGISTER];
764 /* For each register that may be used for calling a function, this
765 gives the offset of that register into the block returned by
766 __builtin_apply_args. 0 indicates that the register is not
767 used for calling a function. */
768 static int apply_args_reg_offset[FIRST_PSEUDO_REGISTER];
770 /* Return the offset of register REGNO into the block returned by
771 __builtin_apply_args. This is not declared static, since it is
772 needed in objc-act.c. */
775 apply_args_register_offset (regno)
780 /* Arguments are always put in outgoing registers (in the argument
781 block) if such make sense. */
782 #ifdef OUTGOING_REGNO
783 regno = OUTGOING_REGNO(regno);
785 return apply_args_reg_offset[regno];
788 /* Return the size required for the block returned by __builtin_apply_args,
789 and initialize apply_args_mode. */
794 static int size = -1;
796 enum machine_mode mode;
798 /* The values computed by this function never change. */
801 /* The first value is the incoming arg-pointer. */
802 size = GET_MODE_SIZE (Pmode);
804 /* The second value is the structure value address unless this is
805 passed as an "invisible" first argument. */
806 if (struct_value_rtx)
807 size += GET_MODE_SIZE (Pmode);
809 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
810 if (FUNCTION_ARG_REGNO_P (regno))
812 /* Search for the proper mode for copying this register's
813 value. I'm not sure this is right, but it works so far. */
814 enum machine_mode best_mode = VOIDmode;
816 for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT);
818 mode = GET_MODE_WIDER_MODE (mode))
819 if (HARD_REGNO_MODE_OK (regno, mode)
820 && HARD_REGNO_NREGS (regno, mode) == 1)
823 if (best_mode == VOIDmode)
824 for (mode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT);
826 mode = GET_MODE_WIDER_MODE (mode))
827 if (HARD_REGNO_MODE_OK (regno, mode)
828 && have_insn_for (SET, mode))
832 if (mode == VOIDmode)
835 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
836 if (size % align != 0)
837 size = CEIL (size, align) * align;
838 apply_args_reg_offset[regno] = size;
839 size += GET_MODE_SIZE (mode);
840 apply_args_mode[regno] = mode;
844 apply_args_mode[regno] = VOIDmode;
845 apply_args_reg_offset[regno] = 0;
851 /* Return the size required for the block returned by __builtin_apply,
852 and initialize apply_result_mode. */
857 static int size = -1;
859 enum machine_mode mode;
861 /* The values computed by this function never change. */
866 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
867 if (FUNCTION_VALUE_REGNO_P (regno))
869 /* Search for the proper mode for copying this register's
870 value. I'm not sure this is right, but it works so far. */
871 enum machine_mode best_mode = VOIDmode;
873 for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT);
875 mode = GET_MODE_WIDER_MODE (mode))
876 if (HARD_REGNO_MODE_OK (regno, mode))
879 if (best_mode == VOIDmode)
880 for (mode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT);
882 mode = GET_MODE_WIDER_MODE (mode))
883 if (HARD_REGNO_MODE_OK (regno, mode)
884 && have_insn_for (SET, mode))
888 if (mode == VOIDmode)
891 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
892 if (size % align != 0)
893 size = CEIL (size, align) * align;
894 size += GET_MODE_SIZE (mode);
895 apply_result_mode[regno] = mode;
898 apply_result_mode[regno] = VOIDmode;
900 /* Allow targets that use untyped_call and untyped_return to override
901 the size so that machine-specific information can be stored here. */
902 #ifdef APPLY_RESULT_SIZE
903 size = APPLY_RESULT_SIZE;
909 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
910 /* Create a vector describing the result block RESULT. If SAVEP is true,
911 the result block is used to save the values; otherwise it is used to
912 restore the values. */
915 result_vector (savep, result)
919 int regno, size, align, nelts;
920 enum machine_mode mode;
922 rtx *savevec = (rtx *) alloca (FIRST_PSEUDO_REGISTER * sizeof (rtx));
925 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
926 if ((mode = apply_result_mode[regno]) != VOIDmode)
928 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
929 if (size % align != 0)
930 size = CEIL (size, align) * align;
931 reg = gen_rtx_REG (mode, savep ? regno : INCOMING_REGNO (regno));
932 mem = adjust_address (result, mode, size);
933 savevec[nelts++] = (savep
934 ? gen_rtx_SET (VOIDmode, mem, reg)
935 : gen_rtx_SET (VOIDmode, reg, mem));
936 size += GET_MODE_SIZE (mode);
938 return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (nelts, savevec));
940 #endif /* HAVE_untyped_call or HAVE_untyped_return */
942 /* Save the state required to perform an untyped call with the same
943 arguments as were passed to the current function. */
946 expand_builtin_apply_args_1 ()
949 int size, align, regno;
950 enum machine_mode mode;
952 /* Create a block where the arg-pointer, structure value address,
953 and argument registers can be saved. */
954 registers = assign_stack_local (BLKmode, apply_args_size (), -1);
956 /* Walk past the arg-pointer and structure value address. */
957 size = GET_MODE_SIZE (Pmode);
958 if (struct_value_rtx)
959 size += GET_MODE_SIZE (Pmode);
961 /* Save each register used in calling a function to the block. */
962 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
963 if ((mode = apply_args_mode[regno]) != VOIDmode)
967 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
968 if (size % align != 0)
969 size = CEIL (size, align) * align;
971 tem = gen_rtx_REG (mode, INCOMING_REGNO (regno));
973 emit_move_insn (adjust_address (registers, mode, size), tem);
974 size += GET_MODE_SIZE (mode);
977 /* Save the arg pointer to the block. */
978 emit_move_insn (adjust_address (registers, Pmode, 0),
979 copy_to_reg (virtual_incoming_args_rtx));
980 size = GET_MODE_SIZE (Pmode);
982 /* Save the structure value address unless this is passed as an
983 "invisible" first argument. */
984 if (struct_value_incoming_rtx)
986 emit_move_insn (adjust_address (registers, Pmode, size),
987 copy_to_reg (struct_value_incoming_rtx));
988 size += GET_MODE_SIZE (Pmode);
991 /* Return the address of the block. */
992 return copy_addr_to_reg (XEXP (registers, 0));
995 /* __builtin_apply_args returns block of memory allocated on
996 the stack into which is stored the arg pointer, structure
997 value address, static chain, and all the registers that might
998 possibly be used in performing a function call. The code is
999 moved to the start of the function so the incoming values are
1003 expand_builtin_apply_args ()
1005 /* Don't do __builtin_apply_args more than once in a function.
1006 Save the result of the first call and reuse it. */
1007 if (apply_args_value != 0)
1008 return apply_args_value;
1010 /* When this function is called, it means that registers must be
1011 saved on entry to this function. So we migrate the
1012 call to the first insn of this function. */
1017 temp = expand_builtin_apply_args_1 ();
1021 apply_args_value = temp;
1023 /* Put the sequence after the NOTE that starts the function.
1024 If this is inside a SEQUENCE, make the outer-level insn
1025 chain current, so the code is placed at the start of the
1027 push_topmost_sequence ();
1028 emit_insns_before (seq, NEXT_INSN (get_insns ()));
1029 pop_topmost_sequence ();
1034 /* Perform an untyped call and save the state required to perform an
1035 untyped return of whatever value was returned by the given function. */
1038 expand_builtin_apply (function, arguments, argsize)
1039 rtx function, arguments, argsize;
1041 int size, align, regno;
1042 enum machine_mode mode;
1043 rtx incoming_args, result, reg, dest, call_insn;
1044 rtx old_stack_level = 0;
1045 rtx call_fusage = 0;
1047 /* Create a block where the return registers can be saved. */
1048 result = assign_stack_local (BLKmode, apply_result_size (), -1);
1050 /* Fetch the arg pointer from the ARGUMENTS block. */
1051 incoming_args = gen_reg_rtx (Pmode);
1052 emit_move_insn (incoming_args,
1053 gen_rtx_MEM (Pmode, arguments));
1054 #ifndef STACK_GROWS_DOWNWARD
1055 incoming_args = expand_simple_binop (Pmode, MINUS, incoming_args, argsize,
1056 incoming_args, 0, OPTAB_LIB_WIDEN);
1059 /* Perform postincrements before actually calling the function. */
1062 /* Push a new argument block and copy the arguments. Do not allow
1063 the (potential) memcpy call below to interfere with our stack
1065 do_pending_stack_adjust ();
1068 /* Save the stack with nonlocal if available */
1069 #ifdef HAVE_save_stack_nonlocal
1070 if (HAVE_save_stack_nonlocal)
1071 emit_stack_save (SAVE_NONLOCAL, &old_stack_level, NULL_RTX);
1074 emit_stack_save (SAVE_BLOCK, &old_stack_level, NULL_RTX);
1076 /* Push a block of memory onto the stack to store the memory arguments.
1077 Save the address in a register, and copy the memory arguments. ??? I
1078 haven't figured out how the calling convention macros effect this,
1079 but it's likely that the source and/or destination addresses in
1080 the block copy will need updating in machine specific ways. */
1081 dest = allocate_dynamic_stack_space (argsize, 0, BITS_PER_UNIT);
1082 emit_block_move (gen_rtx_MEM (BLKmode, dest),
1083 gen_rtx_MEM (BLKmode, incoming_args),
1084 argsize, PARM_BOUNDARY);
1086 /* Refer to the argument block. */
1088 arguments = gen_rtx_MEM (BLKmode, arguments);
1090 /* Walk past the arg-pointer and structure value address. */
1091 size = GET_MODE_SIZE (Pmode);
1092 if (struct_value_rtx)
1093 size += GET_MODE_SIZE (Pmode);
1095 /* Restore each of the registers previously saved. Make USE insns
1096 for each of these registers for use in making the call. */
1097 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1098 if ((mode = apply_args_mode[regno]) != VOIDmode)
1100 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1101 if (size % align != 0)
1102 size = CEIL (size, align) * align;
1103 reg = gen_rtx_REG (mode, regno);
1104 emit_move_insn (reg, adjust_address (arguments, mode, size));
1105 use_reg (&call_fusage, reg);
1106 size += GET_MODE_SIZE (mode);
1109 /* Restore the structure value address unless this is passed as an
1110 "invisible" first argument. */
1111 size = GET_MODE_SIZE (Pmode);
1112 if (struct_value_rtx)
1114 rtx value = gen_reg_rtx (Pmode);
1115 emit_move_insn (value, adjust_address (arguments, Pmode, size));
1116 emit_move_insn (struct_value_rtx, value);
1117 if (GET_CODE (struct_value_rtx) == REG)
1118 use_reg (&call_fusage, struct_value_rtx);
1119 size += GET_MODE_SIZE (Pmode);
1122 /* All arguments and registers used for the call are set up by now! */
1123 function = prepare_call_address (function, NULL_TREE, &call_fusage, 0, 0);
1125 /* Ensure address is valid. SYMBOL_REF is already valid, so no need,
1126 and we don't want to load it into a register as an optimization,
1127 because prepare_call_address already did it if it should be done. */
1128 if (GET_CODE (function) != SYMBOL_REF)
1129 function = memory_address (FUNCTION_MODE, function);
1131 /* Generate the actual call instruction and save the return value. */
1132 #ifdef HAVE_untyped_call
1133 if (HAVE_untyped_call)
1134 emit_call_insn (gen_untyped_call (gen_rtx_MEM (FUNCTION_MODE, function),
1135 result, result_vector (1, result)));
1138 #ifdef HAVE_call_value
1139 if (HAVE_call_value)
1143 /* Locate the unique return register. It is not possible to
1144 express a call that sets more than one return register using
1145 call_value; use untyped_call for that. In fact, untyped_call
1146 only needs to save the return registers in the given block. */
1147 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1148 if ((mode = apply_result_mode[regno]) != VOIDmode)
1151 abort (); /* HAVE_untyped_call required. */
1152 valreg = gen_rtx_REG (mode, regno);
1155 emit_call_insn (GEN_CALL_VALUE (valreg,
1156 gen_rtx_MEM (FUNCTION_MODE, function),
1157 const0_rtx, NULL_RTX, const0_rtx));
1159 emit_move_insn (adjust_address (result, GET_MODE (valreg), 0), valreg);
1165 /* Find the CALL insn we just emitted. */
1166 for (call_insn = get_last_insn ();
1167 call_insn && GET_CODE (call_insn) != CALL_INSN;
1168 call_insn = PREV_INSN (call_insn))
1174 /* Put the register usage information on the CALL. If there is already
1175 some usage information, put ours at the end. */
1176 if (CALL_INSN_FUNCTION_USAGE (call_insn))
1180 for (link = CALL_INSN_FUNCTION_USAGE (call_insn); XEXP (link, 1) != 0;
1181 link = XEXP (link, 1))
1184 XEXP (link, 1) = call_fusage;
1187 CALL_INSN_FUNCTION_USAGE (call_insn) = call_fusage;
1189 /* Restore the stack. */
1190 #ifdef HAVE_save_stack_nonlocal
1191 if (HAVE_save_stack_nonlocal)
1192 emit_stack_restore (SAVE_NONLOCAL, old_stack_level, NULL_RTX);
1195 emit_stack_restore (SAVE_BLOCK, old_stack_level, NULL_RTX);
1199 /* Return the address of the result block. */
1200 return copy_addr_to_reg (XEXP (result, 0));
1203 /* Perform an untyped return. */
1206 expand_builtin_return (result)
1209 int size, align, regno;
1210 enum machine_mode mode;
1212 rtx call_fusage = 0;
1214 apply_result_size ();
1215 result = gen_rtx_MEM (BLKmode, result);
1217 #ifdef HAVE_untyped_return
1218 if (HAVE_untyped_return)
1220 emit_jump_insn (gen_untyped_return (result, result_vector (0, result)));
1226 /* Restore the return value and note that each value is used. */
1228 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1229 if ((mode = apply_result_mode[regno]) != VOIDmode)
1231 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1232 if (size % align != 0)
1233 size = CEIL (size, align) * align;
1234 reg = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1235 emit_move_insn (reg, adjust_address (result, mode, size));
1237 push_to_sequence (call_fusage);
1238 emit_insn (gen_rtx_USE (VOIDmode, reg));
1239 call_fusage = get_insns ();
1241 size += GET_MODE_SIZE (mode);
1244 /* Put the USE insns before the return. */
1245 emit_insns (call_fusage);
1247 /* Return whatever values was restored by jumping directly to the end
1249 expand_null_return ();
1252 /* Used by expand_builtin_classify_type and fold_builtin_classify_type. */
1254 static enum type_class
1255 type_to_class (type)
1258 switch (TREE_CODE (type))
1260 case VOID_TYPE: return void_type_class;
1261 case INTEGER_TYPE: return integer_type_class;
1262 case CHAR_TYPE: return char_type_class;
1263 case ENUMERAL_TYPE: return enumeral_type_class;
1264 case BOOLEAN_TYPE: return boolean_type_class;
1265 case POINTER_TYPE: return pointer_type_class;
1266 case REFERENCE_TYPE: return reference_type_class;
1267 case OFFSET_TYPE: return offset_type_class;
1268 case REAL_TYPE: return real_type_class;
1269 case COMPLEX_TYPE: return complex_type_class;
1270 case FUNCTION_TYPE: return function_type_class;
1271 case METHOD_TYPE: return method_type_class;
1272 case RECORD_TYPE: return record_type_class;
1274 case QUAL_UNION_TYPE: return union_type_class;
1275 case ARRAY_TYPE: return (TYPE_STRING_FLAG (type)
1276 ? string_type_class : array_type_class);
1277 case SET_TYPE: return set_type_class;
1278 case FILE_TYPE: return file_type_class;
1279 case LANG_TYPE: return lang_type_class;
1280 default: return no_type_class;
1284 /* Expand a call to __builtin_classify_type with arguments found in
1288 expand_builtin_classify_type (arglist)
1292 return GEN_INT (type_to_class (TREE_TYPE (TREE_VALUE (arglist))));
1293 return GEN_INT (no_type_class);
1296 /* Expand expression EXP, which is a call to __builtin_constant_p. */
1299 expand_builtin_constant_p (exp)
1302 tree arglist = TREE_OPERAND (exp, 1);
1303 enum machine_mode value_mode = TYPE_MODE (TREE_TYPE (exp));
1308 arglist = TREE_VALUE (arglist);
1310 /* We have taken care of the easy cases during constant folding. This
1311 case is not obvious, so emit (constant_p_rtx (ARGLIST)) and let CSE get a
1312 chance to see if it can deduce whether ARGLIST is constant. */
1314 tmp = expand_expr (arglist, NULL_RTX, VOIDmode, 0);
1315 tmp = gen_rtx_CONSTANT_P_RTX (value_mode, tmp);
1319 /* Expand a call to one of the builtin math functions (sin, cos, or sqrt).
1320 Return 0 if a normal call should be emitted rather than expanding the
1321 function in-line. EXP is the expression that is a call to the builtin
1322 function; if convenient, the result should be placed in TARGET.
1323 SUBTARGET may be used as the target for computing one of EXP's operands. */
1326 expand_builtin_mathfn (exp, target, subtarget)
1328 rtx target, subtarget;
1330 optab builtin_optab;
1332 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
1333 tree arglist = TREE_OPERAND (exp, 1);
1335 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
1338 /* Stabilize and compute the argument. */
1339 if (TREE_CODE (TREE_VALUE (arglist)) != VAR_DECL
1340 && TREE_CODE (TREE_VALUE (arglist)) != PARM_DECL)
1342 exp = copy_node (exp);
1343 TREE_OPERAND (exp, 1) = arglist;
1344 /* Wrap the computation of the argument in a SAVE_EXPR. That
1345 way, if we need to expand the argument again (as in the
1346 flag_errno_math case below where we cannot directly set
1347 errno), we will not perform side-effects more than once.
1348 Note that here we're mutating the original EXP as well as the
1349 copy; that's the right thing to do in case the original EXP
1350 is expanded later. */
1351 TREE_VALUE (arglist) = save_expr (TREE_VALUE (arglist));
1352 arglist = copy_node (arglist);
1354 op0 = expand_expr (TREE_VALUE (arglist), subtarget, VOIDmode, 0);
1356 /* Make a suitable register to place result in. */
1357 target = gen_reg_rtx (TYPE_MODE (TREE_TYPE (exp)));
1362 switch (DECL_FUNCTION_CODE (fndecl))
1367 builtin_optab = sin_optab; break;
1371 builtin_optab = cos_optab; break;
1372 case BUILT_IN_FSQRT:
1373 case BUILT_IN_SQRTF:
1374 case BUILT_IN_SQRTL:
1375 builtin_optab = sqrt_optab; break;
1380 /* Compute into TARGET.
1381 Set TARGET to wherever the result comes back. */
1382 target = expand_unop (TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist))),
1383 builtin_optab, op0, target, 0);
1385 /* If we were unable to expand via the builtin, stop the
1386 sequence (without outputting the insns) and return 0, causing
1387 a call to the library function. */
1394 /* If errno must be maintained and if we are not allowing unsafe
1395 math optimizations, check the result. */
1397 if (flag_errno_math && ! flag_unsafe_math_optimizations)
1401 /* Don't define the builtin FP instructions
1402 if your machine is not IEEE. */
1403 if (TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT)
1406 lab1 = gen_label_rtx ();
1408 /* Test the result; if it is NaN, set errno=EDOM because
1409 the argument was not in the domain. */
1410 emit_cmp_and_jump_insns (target, target, EQ, 0, GET_MODE (target),
1415 #ifdef GEN_ERRNO_RTX
1416 rtx errno_rtx = GEN_ERRNO_RTX;
1419 = gen_rtx_MEM (word_mode, gen_rtx_SYMBOL_REF (Pmode, "errno"));
1422 emit_move_insn (errno_rtx, GEN_INT (TARGET_EDOM));
1425 /* We can't set errno=EDOM directly; let the library call do it.
1426 Pop the arguments right away in case the call gets deleted. */
1428 expand_call (exp, target, 0);
1435 /* Output the entire sequence. */
1436 insns = get_insns ();
1443 /* Expand expression EXP which is a call to the strlen builtin. Return 0
1444 if we failed the caller should emit a normal call, otherwise
1445 try to get the result in TARGET, if convenient. */
1448 expand_builtin_strlen (exp, target)
1452 tree arglist = TREE_OPERAND (exp, 1);
1453 enum machine_mode value_mode = TYPE_MODE (TREE_TYPE (exp));
1455 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
1460 tree src = TREE_VALUE (arglist);
1463 = get_pointer_alignment (src, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
1465 rtx result, src_reg, char_rtx, before_strlen;
1466 enum machine_mode insn_mode = value_mode, char_mode;
1467 enum insn_code icode = CODE_FOR_nothing;
1469 /* If SRC is not a pointer type, don't do this operation inline. */
1473 /* Bail out if we can't compute strlen in the right mode. */
1474 while (insn_mode != VOIDmode)
1476 icode = strlen_optab->handlers[(int) insn_mode].insn_code;
1477 if (icode != CODE_FOR_nothing)
1480 insn_mode = GET_MODE_WIDER_MODE (insn_mode);
1482 if (insn_mode == VOIDmode)
1485 /* Make a place to write the result of the instruction. */
1488 && GET_CODE (result) == REG
1489 && GET_MODE (result) == insn_mode
1490 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
1491 result = gen_reg_rtx (insn_mode);
1493 /* Make a place to hold the source address. We will not expand
1494 the actual source until we are sure that the expansion will
1495 not fail -- there are trees that cannot be expanded twice. */
1496 src_reg = gen_reg_rtx (Pmode);
1498 /* Mark the beginning of the strlen sequence so we can emit the
1499 source operand later. */
1500 before_strlen = get_last_insn();
1502 /* Check the string is readable and has an end. */
1503 if (current_function_check_memory_usage)
1504 emit_library_call (chkr_check_str_libfunc, LCT_CONST_MAKE_BLOCK,
1505 VOIDmode, 2, src_reg, Pmode,
1506 GEN_INT (MEMORY_USE_RO),
1507 TYPE_MODE (integer_type_node));
1509 char_rtx = const0_rtx;
1510 char_mode = insn_data[(int) icode].operand[2].mode;
1511 if (! (*insn_data[(int) icode].operand[2].predicate) (char_rtx,
1513 char_rtx = copy_to_mode_reg (char_mode, char_rtx);
1515 pat = GEN_FCN (icode) (result, gen_rtx_MEM (BLKmode, src_reg),
1516 char_rtx, GEN_INT (align));
1521 /* Now that we are assured of success, expand the source. */
1523 pat = memory_address (BLKmode,
1524 expand_expr (src, src_reg, ptr_mode, EXPAND_SUM));
1526 emit_move_insn (src_reg, pat);
1527 pat = gen_sequence ();
1531 emit_insn_after (pat, before_strlen);
1533 emit_insn_before (pat, get_insns ());
1535 /* Return the value in the proper mode for this function. */
1536 if (GET_MODE (result) == value_mode)
1538 else if (target != 0)
1539 convert_move (target, result, 0);
1541 target = convert_to_mode (value_mode, result, 0);
1547 /* Expand a call to the strstr builtin. Return 0 if we failed the
1548 caller should emit a normal call, otherwise try to get the result
1549 in TARGET, if convenient (and in mode MODE if that's convenient). */
1552 expand_builtin_strstr (arglist, target, mode)
1555 enum machine_mode mode;
1557 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)
1558 || current_function_check_memory_usage)
1562 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
1564 const char *p1, *p2;
1573 const char *r = strstr (p1, p2);
1578 /* Return an offset into the constant string argument. */
1579 return expand_expr (fold (build (PLUS_EXPR, TREE_TYPE (s1),
1580 s1, ssize_int (r - p1))),
1581 target, mode, EXPAND_NORMAL);
1585 return expand_expr (s1, target, mode, EXPAND_NORMAL);
1590 fn = built_in_decls[BUILT_IN_STRCHR];
1594 /* New argument list transforming strstr(s1, s2) to
1595 strchr(s1, s2[0]). */
1597 build_tree_list (NULL_TREE, build_int_2 (p2[0], 0));
1598 arglist = tree_cons (NULL_TREE, s1, arglist);
1599 return expand_expr (build_function_call_expr (fn, arglist),
1600 target, mode, EXPAND_NORMAL);
1604 /* Expand a call to the strchr builtin. Return 0 if we failed the
1605 caller should emit a normal call, otherwise try to get the result
1606 in TARGET, if convenient (and in mode MODE if that's convenient). */
1609 expand_builtin_strchr (arglist, target, mode)
1612 enum machine_mode mode;
1614 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)
1615 || current_function_check_memory_usage)
1619 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
1622 if (TREE_CODE (s2) != INTEGER_CST)
1631 if (target_char_cast (s2, &c))
1639 /* Return an offset into the constant string argument. */
1640 return expand_expr (fold (build (PLUS_EXPR, TREE_TYPE (s1),
1641 s1, ssize_int (r - p1))),
1642 target, mode, EXPAND_NORMAL);
1645 /* FIXME: Should use here strchrM optab so that ports can optimize
1651 /* Expand a call to the strrchr builtin. Return 0 if we failed the
1652 caller should emit a normal call, otherwise try to get the result
1653 in TARGET, if convenient (and in mode MODE if that's convenient). */
1656 expand_builtin_strrchr (arglist, target, mode)
1659 enum machine_mode mode;
1661 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)
1662 || current_function_check_memory_usage)
1666 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
1670 if (TREE_CODE (s2) != INTEGER_CST)
1679 if (target_char_cast (s2, &c))
1682 r = strrchr (p1, c);
1687 /* Return an offset into the constant string argument. */
1688 return expand_expr (fold (build (PLUS_EXPR, TREE_TYPE (s1),
1689 s1, ssize_int (r - p1))),
1690 target, mode, EXPAND_NORMAL);
1693 if (! integer_zerop (s2))
1696 fn = built_in_decls[BUILT_IN_STRCHR];
1700 /* Transform strrchr(s1, '\0') to strchr(s1, '\0'). */
1701 return expand_expr (build_function_call_expr (fn, arglist),
1702 target, mode, EXPAND_NORMAL);
1706 /* Expand a call to the strpbrk builtin. Return 0 if we failed the
1707 caller should emit a normal call, otherwise try to get the result
1708 in TARGET, if convenient (and in mode MODE if that's convenient). */
1711 expand_builtin_strpbrk (arglist, target, mode)
1714 enum machine_mode mode;
1716 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)
1717 || current_function_check_memory_usage)
1721 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
1723 const char *p1, *p2;
1732 const char *r = strpbrk (p1, p2);
1737 /* Return an offset into the constant string argument. */
1738 return expand_expr (fold (build (PLUS_EXPR, TREE_TYPE (s1),
1739 s1, ssize_int (r - p1))),
1740 target, mode, EXPAND_NORMAL);
1745 /* strpbrk(x, "") == NULL.
1746 Evaluate and ignore the arguments in case they had
1748 expand_expr (s1, const0_rtx, VOIDmode, EXPAND_NORMAL);
1753 return 0; /* Really call strpbrk. */
1755 fn = built_in_decls[BUILT_IN_STRCHR];
1759 /* New argument list transforming strpbrk(s1, s2) to
1760 strchr(s1, s2[0]). */
1762 build_tree_list (NULL_TREE, build_int_2 (p2[0], 0));
1763 arglist = tree_cons (NULL_TREE, s1, arglist);
1764 return expand_expr (build_function_call_expr (fn, arglist),
1765 target, mode, EXPAND_NORMAL);
1769 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
1770 bytes from constant string DATA + OFFSET and return it as target
1774 builtin_memcpy_read_str (data, offset, mode)
1776 HOST_WIDE_INT offset;
1777 enum machine_mode mode;
1779 const char *str = (const char *) data;
1782 || ((unsigned HOST_WIDE_INT) offset + GET_MODE_SIZE (mode)
1783 > strlen (str) + 1))
1784 abort (); /* Attempt to read past the end of constant string. */
1786 return c_readstr (str + offset, mode);
1789 /* Expand a call to the memcpy builtin, with arguments in ARGLIST. */
1792 expand_builtin_memcpy (arglist)
1795 if (!validate_arglist (arglist,
1796 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
1800 tree dest = TREE_VALUE (arglist);
1801 tree src = TREE_VALUE (TREE_CHAIN (arglist));
1802 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
1803 const char *src_str;
1805 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
1806 unsigned int dest_align
1807 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
1808 rtx dest_mem, src_mem, dest_addr, len_rtx;
1810 /* If either SRC or DEST is not a pointer type, don't do
1811 this operation in-line. */
1812 if (src_align == 0 || dest_align == 0)
1815 dest_mem = get_memory_rtx (dest);
1816 len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
1817 src_str = c_getstr (src);
1819 /* If SRC is a string constant and block move would be done
1820 by pieces, we can avoid loading the string from memory
1821 and only stored the computed constants. */
1823 && !current_function_check_memory_usage
1824 && GET_CODE (len_rtx) == CONST_INT
1825 && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
1826 && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
1827 (PTR) src_str, dest_align))
1829 store_by_pieces (dest_mem, INTVAL (len_rtx),
1830 builtin_memcpy_read_str,
1831 (PTR) src_str, dest_align);
1832 return force_operand (XEXP (dest_mem, 0), NULL_RTX);
1835 src_mem = get_memory_rtx (src);
1837 /* Just copy the rights of SRC to the rights of DEST. */
1838 if (current_function_check_memory_usage)
1839 emit_library_call (chkr_copy_bitmap_libfunc, LCT_CONST_MAKE_BLOCK,
1840 VOIDmode, 3, XEXP (dest_mem, 0), Pmode,
1841 XEXP (src_mem, 0), Pmode,
1842 len_rtx, TYPE_MODE (sizetype));
1844 /* Copy word part most expediently. */
1846 = emit_block_move (dest_mem, src_mem, len_rtx,
1847 MIN (src_align, dest_align));
1850 dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
1856 /* Expand expression EXP, which is a call to the strcpy builtin. Return 0
1857 if we failed the caller should emit a normal call. */
1860 expand_builtin_strcpy (exp)
1863 tree arglist = TREE_OPERAND (exp, 1);
1866 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
1870 tree len = c_strlen (TREE_VALUE (TREE_CHAIN (arglist)));
1875 len = size_binop (PLUS_EXPR, len, ssize_int (1));
1876 chainon (arglist, build_tree_list (NULL_TREE, len));
1879 result = expand_builtin_memcpy (arglist);
1882 TREE_CHAIN (TREE_CHAIN (arglist)) = 0;
1886 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
1887 bytes from constant string DATA + OFFSET and return it as target
1891 builtin_strncpy_read_str (data, offset, mode)
1893 HOST_WIDE_INT offset;
1894 enum machine_mode mode;
1896 const char *str = (const char *) data;
1898 if ((unsigned HOST_WIDE_INT) offset > strlen (str))
1901 return c_readstr (str + offset, mode);
1904 /* Expand expression EXP, which is a call to the strncpy builtin. Return 0
1905 if we failed the caller should emit a normal call. */
1908 expand_builtin_strncpy (arglist, target, mode)
1911 enum machine_mode mode;
1913 if (!validate_arglist (arglist,
1914 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
1918 tree slen = c_strlen (TREE_VALUE (TREE_CHAIN (arglist)));
1919 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
1921 /* We must be passed a constant len parameter. */
1922 if (TREE_CODE (len) != INTEGER_CST)
1925 /* If the len parameter is zero, return the dst parameter. */
1926 if (compare_tree_int (len, 0) == 0)
1928 /* Evaluate and ignore the src argument in case it has
1930 expand_expr (TREE_VALUE (TREE_CHAIN (arglist)), const0_rtx,
1931 VOIDmode, EXPAND_NORMAL);
1932 /* Return the dst parameter. */
1933 return expand_expr (TREE_VALUE (arglist), target, mode,
1937 /* Now, we must be passed a constant src ptr parameter. */
1938 if (slen == 0 || TREE_CODE (slen) != INTEGER_CST)
1941 slen = size_binop (PLUS_EXPR, slen, ssize_int (1));
1943 /* We're required to pad with trailing zeros if the requested
1944 len is greater than strlen(s2)+1. In that case try to
1945 use store_by_pieces, if it fails, punt. */
1946 if (tree_int_cst_lt (slen, len))
1948 tree dest = TREE_VALUE (arglist);
1949 unsigned int dest_align
1950 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
1951 const char *p = c_getstr (TREE_VALUE (TREE_CHAIN (arglist)));
1954 if (!p || dest_align == 0 || !host_integerp (len, 1)
1955 || !can_store_by_pieces (tree_low_cst (len, 1),
1956 builtin_strncpy_read_str,
1957 (PTR) p, dest_align))
1960 dest_mem = get_memory_rtx (dest);
1961 store_by_pieces (dest_mem, tree_low_cst (len, 1),
1962 builtin_strncpy_read_str,
1963 (PTR) p, dest_align);
1964 return force_operand (XEXP (dest_mem, 0), NULL_RTX);
1967 /* OK transform into builtin memcpy. */
1968 return expand_builtin_memcpy (arglist);
1972 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
1973 bytes from constant string DATA + OFFSET and return it as target
1977 builtin_memset_read_str (data, offset, mode)
1979 HOST_WIDE_INT offset ATTRIBUTE_UNUSED;
1980 enum machine_mode mode;
1982 const char *c = (const char *) data;
1983 char *p = alloca (GET_MODE_SIZE (mode));
1985 memset (p, *c, GET_MODE_SIZE (mode));
1987 return c_readstr (p, mode);
1990 /* Expand expression EXP, which is a call to the memset builtin. Return 0
1991 if we failed the caller should emit a normal call. */
1994 expand_builtin_memset (exp)
1997 tree arglist = TREE_OPERAND (exp, 1);
1999 if (!validate_arglist (arglist,
2000 POINTER_TYPE, INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
2004 tree dest = TREE_VALUE (arglist);
2005 tree val = TREE_VALUE (TREE_CHAIN (arglist));
2006 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2009 unsigned int dest_align
2010 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2011 rtx dest_mem, dest_addr, len_rtx;
2013 /* If DEST is not a pointer type, don't do this
2014 operation in-line. */
2015 if (dest_align == 0)
2018 if (TREE_CODE (val) != INTEGER_CST)
2021 if (target_char_cast (val, &c))
2026 if (!host_integerp (len, 1))
2028 if (current_function_check_memory_usage
2029 || !can_store_by_pieces (tree_low_cst (len, 1),
2030 builtin_memset_read_str,
2031 (PTR) &c, dest_align))
2034 dest_mem = get_memory_rtx (dest);
2035 store_by_pieces (dest_mem, tree_low_cst (len, 1),
2036 builtin_memset_read_str,
2037 (PTR) &c, dest_align);
2038 return force_operand (XEXP (dest_mem, 0), NULL_RTX);
2041 len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
2043 dest_mem = get_memory_rtx (dest);
2045 /* Just check DST is writable and mark it as readable. */
2046 if (current_function_check_memory_usage)
2047 emit_library_call (chkr_check_addr_libfunc, LCT_CONST_MAKE_BLOCK,
2048 VOIDmode, 3, XEXP (dest_mem, 0), Pmode,
2049 len_rtx, TYPE_MODE (sizetype),
2050 GEN_INT (MEMORY_USE_WO),
2051 TYPE_MODE (integer_type_node));
2054 dest_addr = clear_storage (dest_mem, len_rtx, dest_align);
2057 dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2063 /* Expand expression EXP, which is a call to the bzero builtin. Return 0
2064 if we failed the caller should emit a normal call. */
2067 expand_builtin_bzero (exp)
2070 tree arglist = TREE_OPERAND (exp, 1);
2071 tree dest, size, newarglist;
2074 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2077 dest = TREE_VALUE (arglist);
2078 size = TREE_VALUE (TREE_CHAIN (arglist));
2080 /* New argument list transforming bzero(ptr x, int y) to
2081 memset(ptr x, int 0, size_t y). */
2083 newarglist = build_tree_list (NULL_TREE, convert (sizetype, size));
2084 newarglist = tree_cons (NULL_TREE, integer_zero_node, newarglist);
2085 newarglist = tree_cons (NULL_TREE, dest, newarglist);
2087 TREE_OPERAND (exp, 1) = newarglist;
2088 result = expand_builtin_memset(exp);
2090 /* Always restore the original arguments. */
2091 TREE_OPERAND (exp, 1) = arglist;
2096 #ifdef HAVE_cmpstrsi
2098 /* Expand expression EXP, which is a call to the memcmp or the strcmp builtin.
2099 ARGLIST is the argument list for this call. Return 0 if we failed and the
2100 caller should emit a normal call, otherwise try to get the result in
2101 TARGET, if convenient. */
2104 expand_builtin_memcmp (exp, arglist, target)
2109 /* If we need to check memory accesses, call the library function. */
2110 if (current_function_check_memory_usage)
2113 if (!validate_arglist (arglist,
2114 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2118 enum machine_mode mode;
2119 tree arg1 = TREE_VALUE (arglist);
2120 tree arg2 = TREE_VALUE (TREE_CHAIN (arglist));
2121 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2122 rtx arg1_rtx, arg2_rtx, arg3_rtx;
2127 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
2129 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
2130 enum machine_mode insn_mode
2131 = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
2133 /* If we don't have POINTER_TYPE, call the function. */
2134 if (arg1_align == 0 || arg2_align == 0)
2137 /* Make a place to write the result of the instruction. */
2140 && GET_CODE (result) == REG && GET_MODE (result) == insn_mode
2141 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
2142 result = gen_reg_rtx (insn_mode);
2144 arg1_rtx = get_memory_rtx (arg1);
2145 arg2_rtx = get_memory_rtx (arg2);
2146 arg3_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
2150 insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
2151 GEN_INT (MIN (arg1_align, arg2_align)));
2156 emit_library_call_value (memcmp_libfunc, result, LCT_PURE_MAKE_BLOCK,
2157 TYPE_MODE (integer_type_node), 3,
2158 XEXP (arg1_rtx, 0), Pmode,
2159 XEXP (arg2_rtx, 0), Pmode,
2160 convert_to_mode (TYPE_MODE (sizetype), arg3_rtx,
2161 TREE_UNSIGNED (sizetype)),
2162 TYPE_MODE (sizetype));
2164 /* Return the value in the proper mode for this function. */
2165 mode = TYPE_MODE (TREE_TYPE (exp));
2166 if (GET_MODE (result) == mode)
2168 else if (target != 0)
2170 convert_move (target, result, 0);
2174 return convert_to_mode (mode, result, 0);
2179 /* Expand expression EXP, which is a call to the strcmp builtin. Return 0
2180 if we failed the caller should emit a normal call, otherwise try to get
2181 the result in TARGET, if convenient. */
2184 expand_builtin_strcmp (exp, target, mode)
2187 enum machine_mode mode;
2189 tree arglist = TREE_OPERAND (exp, 1);
2191 const char *p1, *p2;
2193 /* If we need to check memory accesses, call the library function. */
2194 if (current_function_check_memory_usage)
2197 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2200 arg1 = TREE_VALUE (arglist);
2201 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
2203 p1 = c_getstr (arg1);
2204 p2 = c_getstr (arg2);
2208 const int i = strcmp (p1, p2);
2209 return (i < 0 ? constm1_rtx : (i > 0 ? const1_rtx : const0_rtx));
2212 /* If either arg is "", return an expression corresponding to
2213 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
2214 if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
2216 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
2217 tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
2219 fold (build1 (CONVERT_EXPR, integer_type_node,
2220 build1 (INDIRECT_REF, cst_uchar_node,
2221 build1 (NOP_EXPR, cst_uchar_ptr_node, arg1))));
2223 fold (build1 (CONVERT_EXPR, integer_type_node,
2224 build1 (INDIRECT_REF, cst_uchar_node,
2225 build1 (NOP_EXPR, cst_uchar_ptr_node, arg2))));
2226 tree result = fold (build (MINUS_EXPR, integer_type_node, ind1, ind2));
2227 return expand_expr (result, target, mode, EXPAND_NORMAL);
2230 #ifdef HAVE_cmpstrsi
2231 if (! HAVE_cmpstrsi)
2235 tree len = c_strlen (arg1);
2236 tree len2 = c_strlen (arg2);
2240 len = size_binop (PLUS_EXPR, ssize_int (1), len);
2243 len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
2245 /* If we don't have a constant length for the first, use the length
2246 of the second, if we know it. We don't require a constant for
2247 this case; some cost analysis could be done if both are available
2248 but neither is constant. For now, assume they're equally cheap
2249 unless one has side effects.
2251 If both strings have constant lengths, use the smaller. This
2252 could arise if optimization results in strcpy being called with
2253 two fixed strings, or if the code was machine-generated. We should
2254 add some code to the `memcmp' handler below to deal with such
2255 situations, someday. */
2257 if (!len || TREE_CODE (len) != INTEGER_CST)
2259 if (len2 && !TREE_SIDE_EFFECTS (len2))
2264 else if (len2 && TREE_CODE (len2) == INTEGER_CST
2265 && tree_int_cst_lt (len2, len))
2268 /* If both arguments have side effects, we cannot optimize. */
2269 if (TREE_SIDE_EFFECTS (len))
2272 chainon (arglist, build_tree_list (NULL_TREE, len));
2273 result = expand_builtin_memcmp (exp, arglist, target);
2275 TREE_CHAIN (TREE_CHAIN (arglist)) = 0;
2284 /* Expand expression EXP, which is a call to the strncmp builtin. Return 0
2285 if we failed the caller should emit a normal call, otherwise try to get
2286 the result in TARGET, if convenient. */
2289 expand_builtin_strncmp (exp, target, mode)
2292 enum machine_mode mode;
2294 tree arglist = TREE_OPERAND (exp, 1);
2295 tree arg1, arg2, arg3;
2296 const char *p1, *p2;
2298 /* If we need to check memory accesses, call the library function. */
2299 if (current_function_check_memory_usage)
2302 if (!validate_arglist (arglist,
2303 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2306 arg1 = TREE_VALUE (arglist);
2307 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
2308 arg3 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2310 /* If the len parameter is zero, return zero. */
2311 if (host_integerp (arg3, 1) && tree_low_cst (arg3, 1) == 0)
2313 /* Evaluate and ignore arg1 and arg2 in case they have
2315 expand_expr (arg1, const0_rtx, VOIDmode, EXPAND_NORMAL);
2316 expand_expr (arg2, const0_rtx, VOIDmode, EXPAND_NORMAL);
2320 p1 = c_getstr (arg1);
2321 p2 = c_getstr (arg2);
2323 /* If all arguments are constant, evaluate at compile-time. */
2324 if (host_integerp (arg3, 1) && p1 && p2)
2326 const int r = strncmp (p1, p2, tree_low_cst (arg3, 1));
2327 return (r < 0 ? constm1_rtx : (r > 0 ? const1_rtx : const0_rtx));
2330 /* If len == 1 or (either string parameter is "" and (len >= 1)),
2331 return (*(const u_char*)arg1 - *(const u_char*)arg2). */
2332 if (host_integerp (arg3, 1)
2333 && (tree_low_cst (arg3, 1) == 1
2334 || (tree_low_cst (arg3, 1) > 1
2335 && ((p1 && *p1 == '\0') || (p2 && *p2 == '\0')))))
2337 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
2338 tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
2340 fold (build1 (CONVERT_EXPR, integer_type_node,
2341 build1 (INDIRECT_REF, cst_uchar_node,
2342 build1 (NOP_EXPR, cst_uchar_ptr_node, arg1))));
2344 fold (build1 (CONVERT_EXPR, integer_type_node,
2345 build1 (INDIRECT_REF, cst_uchar_node,
2346 build1 (NOP_EXPR, cst_uchar_ptr_node, arg2))));
2347 tree result = fold (build (MINUS_EXPR, integer_type_node, ind1, ind2));
2348 return expand_expr (result, target, mode, EXPAND_NORMAL);
2351 #ifdef HAVE_cmpstrsi
2352 /* If c_strlen can determine an expression for one of the string
2353 lengths, and it doesn't have side effects, then call
2354 expand_builtin_memcmp() using length MIN(strlen(string)+1, arg3). */
2357 tree newarglist, len = 0;
2359 /* Perhaps one of the strings is really constant, if so prefer
2360 that constant length over the other string's length. */
2362 len = c_strlen (arg1);
2364 len = c_strlen (arg2);
2366 /* If we still don't have a len, try either string arg as long
2367 as they don't have side effects. */
2368 if (!len && !TREE_SIDE_EFFECTS (arg1))
2369 len = c_strlen (arg1);
2370 if (!len && !TREE_SIDE_EFFECTS (arg2))
2371 len = c_strlen (arg2);
2372 /* If we still don't have a length, punt. */
2376 /* Add one to the string length. */
2377 len = fold (size_binop (PLUS_EXPR, len, ssize_int (1)));
2379 /* The actual new length parameter is MIN(len,arg3). */
2380 len = fold (build (MIN_EXPR, TREE_TYPE (len), len, arg3));
2382 newarglist = build_tree_list (NULL_TREE, len);
2383 newarglist = tree_cons (NULL_TREE, arg2, newarglist);
2384 newarglist = tree_cons (NULL_TREE, arg1, newarglist);
2385 return expand_builtin_memcmp (exp, newarglist, target);
2392 /* Expand expression EXP, which is a call to the strcat builtin.
2393 Return 0 if we failed the caller should emit a normal call,
2394 otherwise try to get the result in TARGET, if convenient. */
2397 expand_builtin_strcat (arglist, target, mode)
2400 enum machine_mode mode;
2402 /* If we need to check memory accesses, call the library function. */
2403 if (current_function_check_memory_usage)
2406 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2410 tree dst = TREE_VALUE (arglist),
2411 src = TREE_VALUE (TREE_CHAIN (arglist));
2412 const char *p = c_getstr (src);
2414 /* If the string length is zero, return the dst parameter. */
2415 if (p && *p == '\0')
2416 return expand_expr (dst, target, mode, EXPAND_NORMAL);
2422 /* Expand expression EXP, which is a call to the strncat builtin.
2423 Return 0 if we failed the caller should emit a normal call,
2424 otherwise try to get the result in TARGET, if convenient. */
2427 expand_builtin_strncat (arglist, target, mode)
2430 enum machine_mode mode;
2432 /* If we need to check memory accesses, call the library function. */
2433 if (current_function_check_memory_usage)
2436 if (!validate_arglist (arglist,
2437 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2441 tree dst = TREE_VALUE (arglist),
2442 src = TREE_VALUE (TREE_CHAIN (arglist)),
2443 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2444 const char *p = c_getstr (src);
2446 /* If the requested length is zero, or the src parameter string
2447 length is zero, return the dst parameter. */
2448 if ((TREE_CODE (len) == INTEGER_CST && compare_tree_int (len, 0) == 0)
2449 || (p && *p == '\0'))
2451 /* Evaluate and ignore the src and len parameters in case
2452 they have side-effects. */
2453 expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
2454 expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
2455 return expand_expr (dst, target, mode, EXPAND_NORMAL);
2458 /* If the requested len is greater than or equal to the string
2459 length, call strcat. */
2460 if (TREE_CODE (len) == INTEGER_CST && p
2461 && compare_tree_int (len, strlen (p)) >= 0)
2464 tree_cons (NULL_TREE, dst, build_tree_list (NULL_TREE, src)),
2465 fn = built_in_decls[BUILT_IN_STRCAT];
2467 /* If the replacement _DECL isn't initialized, don't do the
2472 return expand_expr (build_function_call_expr (fn, newarglist),
2473 target, mode, EXPAND_NORMAL);
2479 /* Expand expression EXP, which is a call to the strspn builtin.
2480 Return 0 if we failed the caller should emit a normal call,
2481 otherwise try to get the result in TARGET, if convenient. */
2484 expand_builtin_strspn (arglist, target, mode)
2487 enum machine_mode mode;
2489 /* If we need to check memory accesses, call the library function. */
2490 if (current_function_check_memory_usage)
2493 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2497 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
2498 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
2500 /* If both arguments are constants, evaluate at compile-time. */
2503 const size_t r = strspn (p1, p2);
2504 return expand_expr (size_int (r), target, mode, EXPAND_NORMAL);
2507 /* If either argument is "", return 0. */
2508 if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
2510 /* Evaluate and ignore both arguments in case either one has
2512 expand_expr (s1, const0_rtx, VOIDmode, EXPAND_NORMAL);
2513 expand_expr (s2, const0_rtx, VOIDmode, EXPAND_NORMAL);
2520 /* Expand expression EXP, which is a call to the strcspn builtin.
2521 Return 0 if we failed the caller should emit a normal call,
2522 otherwise try to get the result in TARGET, if convenient. */
2525 expand_builtin_strcspn (arglist, target, mode)
2528 enum machine_mode mode;
2530 /* If we need to check memory accesses, call the library function. */
2531 if (current_function_check_memory_usage)
2534 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2538 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
2539 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
2541 /* If both arguments are constants, evaluate at compile-time. */
2544 const size_t r = strcspn (p1, p2);
2545 return expand_expr (size_int (r), target, mode, EXPAND_NORMAL);
2548 /* If the first argument is "", return 0. */
2549 if (p1 && *p1 == '\0')
2551 /* Evaluate and ignore argument s2 in case it has
2553 expand_expr (s2, const0_rtx, VOIDmode, EXPAND_NORMAL);
2557 /* If the second argument is "", return __builtin_strlen(s1). */
2558 if (p2 && *p2 == '\0')
2560 tree newarglist = build_tree_list (NULL_TREE, s1),
2561 fn = built_in_decls[BUILT_IN_STRLEN];
2563 /* If the replacement _DECL isn't initialized, don't do the
2568 return expand_expr (build_function_call_expr (fn, newarglist),
2569 target, mode, EXPAND_NORMAL);
2575 /* Expand a call to __builtin_saveregs, generating the result in TARGET,
2576 if that's convenient. */
2579 expand_builtin_saveregs ()
2583 /* Don't do __builtin_saveregs more than once in a function.
2584 Save the result of the first call and reuse it. */
2585 if (saveregs_value != 0)
2586 return saveregs_value;
2588 /* When this function is called, it means that registers must be
2589 saved on entry to this function. So we migrate the call to the
2590 first insn of this function. */
2594 #ifdef EXPAND_BUILTIN_SAVEREGS
2595 /* Do whatever the machine needs done in this case. */
2596 val = EXPAND_BUILTIN_SAVEREGS ();
2598 /* ??? We used to try and build up a call to the out of line function,
2599 guessing about what registers needed saving etc. This became much
2600 harder with __builtin_va_start, since we don't have a tree for a
2601 call to __builtin_saveregs to fall back on. There was exactly one
2602 port (i860) that used this code, and I'm unconvinced it could actually
2603 handle the general case. So we no longer try to handle anything
2604 weird and make the backend absorb the evil. */
2606 error ("__builtin_saveregs not supported by this target");
2613 saveregs_value = val;
2615 /* Put the sequence after the NOTE that starts the function. If this
2616 is inside a SEQUENCE, make the outer-level insn chain current, so
2617 the code is placed at the start of the function. */
2618 push_topmost_sequence ();
2619 emit_insns_after (seq, get_insns ());
2620 pop_topmost_sequence ();
2625 /* __builtin_args_info (N) returns word N of the arg space info
2626 for the current function. The number and meanings of words
2627 is controlled by the definition of CUMULATIVE_ARGS. */
2630 expand_builtin_args_info (exp)
2633 tree arglist = TREE_OPERAND (exp, 1);
2634 int nwords = sizeof (CUMULATIVE_ARGS) / sizeof (int);
2635 int *word_ptr = (int *) ¤t_function_args_info;
2637 /* These are used by the code below that is if 0'ed away */
2639 tree type, elts, result;
2642 if (sizeof (CUMULATIVE_ARGS) % sizeof (int) != 0)
2647 if (!host_integerp (TREE_VALUE (arglist), 0))
2648 error ("argument of `__builtin_args_info' must be constant");
2651 HOST_WIDE_INT wordnum = tree_low_cst (TREE_VALUE (arglist), 0);
2653 if (wordnum < 0 || wordnum >= nwords)
2654 error ("argument of `__builtin_args_info' out of range");
2656 return GEN_INT (word_ptr[wordnum]);
2660 error ("missing argument in `__builtin_args_info'");
2665 for (i = 0; i < nwords; i++)
2666 elts = tree_cons (NULL_TREE, build_int_2 (word_ptr[i], 0));
2668 type = build_array_type (integer_type_node,
2669 build_index_type (build_int_2 (nwords, 0)));
2670 result = build (CONSTRUCTOR, type, NULL_TREE, nreverse (elts));
2671 TREE_CONSTANT (result) = 1;
2672 TREE_STATIC (result) = 1;
2673 result = build1 (INDIRECT_REF, build_pointer_type (type), result);
2674 TREE_CONSTANT (result) = 1;
2675 return expand_expr (result, NULL_RTX, VOIDmode, EXPAND_MEMORY_USE_BAD);
2679 /* Expand ARGLIST, from a call to __builtin_next_arg. */
2682 expand_builtin_next_arg (arglist)
2685 tree fntype = TREE_TYPE (current_function_decl);
2687 if ((TYPE_ARG_TYPES (fntype) == 0
2688 || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
2690 && ! current_function_varargs)
2692 error ("`va_start' used in function with fixed args");
2698 tree last_parm = tree_last (DECL_ARGUMENTS (current_function_decl));
2699 tree arg = TREE_VALUE (arglist);
2701 /* Strip off all nops for the sake of the comparison. This
2702 is not quite the same as STRIP_NOPS. It does more.
2703 We must also strip off INDIRECT_EXPR for C++ reference
2705 while (TREE_CODE (arg) == NOP_EXPR
2706 || TREE_CODE (arg) == CONVERT_EXPR
2707 || TREE_CODE (arg) == NON_LVALUE_EXPR
2708 || TREE_CODE (arg) == INDIRECT_REF)
2709 arg = TREE_OPERAND (arg, 0);
2710 if (arg != last_parm)
2711 warning ("second parameter of `va_start' not last named argument");
2713 else if (! current_function_varargs)
2714 /* Evidently an out of date version of <stdarg.h>; can't validate
2715 va_start's second argument, but can still work as intended. */
2716 warning ("`__builtin_next_arg' called without an argument");
2718 return expand_binop (Pmode, add_optab,
2719 current_function_internal_arg_pointer,
2720 current_function_arg_offset_rtx,
2721 NULL_RTX, 0, OPTAB_LIB_WIDEN);
2724 /* Make it easier for the backends by protecting the valist argument
2725 from multiple evaluations. */
2728 stabilize_va_list (valist, needs_lvalue)
2732 if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
2734 if (TREE_SIDE_EFFECTS (valist))
2735 valist = save_expr (valist);
2737 /* For this case, the backends will be expecting a pointer to
2738 TREE_TYPE (va_list_type_node), but it's possible we've
2739 actually been given an array (an actual va_list_type_node).
2741 if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
2743 tree p1 = build_pointer_type (TREE_TYPE (va_list_type_node));
2744 tree p2 = build_pointer_type (va_list_type_node);
2746 valist = build1 (ADDR_EXPR, p2, valist);
2747 valist = fold (build1 (NOP_EXPR, p1, valist));
2756 if (! TREE_SIDE_EFFECTS (valist))
2759 pt = build_pointer_type (va_list_type_node);
2760 valist = fold (build1 (ADDR_EXPR, pt, valist));
2761 TREE_SIDE_EFFECTS (valist) = 1;
2764 if (TREE_SIDE_EFFECTS (valist))
2765 valist = save_expr (valist);
2766 valist = fold (build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (valist)),
2773 /* The "standard" implementation of va_start: just assign `nextarg' to
2777 std_expand_builtin_va_start (stdarg_p, valist, nextarg)
2786 /* The dummy named parameter is declared as a 'word' sized
2787 object, but if a 'word' is smaller than an 'int', it would
2788 have been promoted to int when it was added to the arglist. */
2789 int align = PARM_BOUNDARY / BITS_PER_UNIT;
2790 int size = MAX (UNITS_PER_WORD,
2791 GET_MODE_SIZE (TYPE_MODE (integer_type_node)));
2792 int offset = ((size + align - 1) / align) * align;
2793 nextarg = plus_constant (nextarg, -offset);
2796 t = build (MODIFY_EXPR, TREE_TYPE (valist), valist,
2797 make_tree (ptr_type_node, nextarg));
2798 TREE_SIDE_EFFECTS (t) = 1;
2800 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
2803 /* Expand ARGLIST, which from a call to __builtin_stdarg_va_start or
2804 __builtin_varargs_va_start, depending on STDARG_P. */
2807 expand_builtin_va_start (stdarg_p, arglist)
2812 tree chain = arglist, valist;
2815 nextarg = expand_builtin_next_arg (chain = TREE_CHAIN (arglist));
2817 nextarg = expand_builtin_next_arg (NULL_TREE);
2819 if (TREE_CHAIN (chain))
2820 error ("too many arguments to function `va_start'");
2822 valist = stabilize_va_list (TREE_VALUE (arglist), 1);
2824 #ifdef EXPAND_BUILTIN_VA_START
2825 EXPAND_BUILTIN_VA_START (stdarg_p, valist, nextarg);
2827 std_expand_builtin_va_start (stdarg_p, valist, nextarg);
2833 /* The "standard" implementation of va_arg: read the value from the
2834 current (padded) address and increment by the (padded) size. */
2837 std_expand_builtin_va_arg (valist, type)
2841 HOST_WIDE_INT align;
2842 HOST_WIDE_INT rounded_size;
2845 /* Compute the rounded size of the type. */
2846 align = PARM_BOUNDARY / BITS_PER_UNIT;
2847 rounded_size = (((int_size_in_bytes (type) + align - 1) / align) * align);
2851 if (PAD_VARARGS_DOWN)
2853 /* Small args are padded downward. */
2856 = rounded_size > align ? rounded_size : int_size_in_bytes (type);
2858 addr_tree = build (PLUS_EXPR, TREE_TYPE (addr_tree), addr_tree,
2859 build_int_2 (rounded_size - adj, 0));
2862 addr = expand_expr (addr_tree, NULL_RTX, Pmode, EXPAND_NORMAL);
2863 addr = copy_to_reg (addr);
2865 /* Compute new value for AP. */
2866 t = build (MODIFY_EXPR, TREE_TYPE (valist), valist,
2867 build (PLUS_EXPR, TREE_TYPE (valist), valist,
2868 build_int_2 (rounded_size, 0)));
2869 TREE_SIDE_EFFECTS (t) = 1;
2870 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
2875 /* Expand __builtin_va_arg, which is not really a builtin function, but
2876 a very special sort of operator. */
2879 expand_builtin_va_arg (valist, type)
2883 tree promoted_type, want_va_type, have_va_type;
2885 /* Verify that valist is of the proper type. */
2887 want_va_type = va_list_type_node;
2888 have_va_type = TREE_TYPE (valist);
2889 if (TREE_CODE (want_va_type) == ARRAY_TYPE)
2891 /* If va_list is an array type, the argument may have decayed
2892 to a pointer type, e.g. by being passed to another function.
2893 In that case, unwrap both types so that we can compare the
2894 underlying records. */
2895 if (TREE_CODE (have_va_type) == ARRAY_TYPE
2896 || TREE_CODE (have_va_type) == POINTER_TYPE)
2898 want_va_type = TREE_TYPE (want_va_type);
2899 have_va_type = TREE_TYPE (have_va_type);
2902 if (TYPE_MAIN_VARIANT (want_va_type) != TYPE_MAIN_VARIANT (have_va_type))
2904 error ("first argument to `va_arg' not of type `va_list'");
2908 /* Generate a diagnostic for requesting data of a type that cannot
2909 be passed through `...' due to type promotion at the call site. */
2910 else if ((promoted_type = (*lang_type_promotes_to) (type)) != NULL_TREE)
2912 const char *name = "<anonymous type>", *pname = 0;
2913 static int gave_help;
2915 if (TYPE_NAME (type))
2917 if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE)
2918 name = IDENTIFIER_POINTER (TYPE_NAME (type));
2919 else if (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
2920 && DECL_NAME (TYPE_NAME (type)))
2921 name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type)));
2923 if (TYPE_NAME (promoted_type))
2925 if (TREE_CODE (TYPE_NAME (promoted_type)) == IDENTIFIER_NODE)
2926 pname = IDENTIFIER_POINTER (TYPE_NAME (promoted_type));
2927 else if (TREE_CODE (TYPE_NAME (promoted_type)) == TYPE_DECL
2928 && DECL_NAME (TYPE_NAME (promoted_type)))
2929 pname = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (promoted_type)));
2932 error ("`%s' is promoted to `%s' when passed through `...'", name, pname);
2936 error ("(so you should pass `%s' not `%s' to `va_arg')", pname, name);
2943 /* Make it easier for the backends by protecting the valist argument
2944 from multiple evaluations. */
2945 valist = stabilize_va_list (valist, 0);
2947 #ifdef EXPAND_BUILTIN_VA_ARG
2948 addr = EXPAND_BUILTIN_VA_ARG (valist, type);
2950 addr = std_expand_builtin_va_arg (valist, type);
2954 result = gen_rtx_MEM (TYPE_MODE (type), addr);
2955 set_mem_alias_set (result, get_varargs_alias_set ());
2960 /* Expand ARGLIST, from a call to __builtin_va_end. */
2963 expand_builtin_va_end (arglist)
2966 tree valist = TREE_VALUE (arglist);
2968 #ifdef EXPAND_BUILTIN_VA_END
2969 valist = stabilize_va_list (valist, 0);
2970 EXPAND_BUILTIN_VA_END(arglist);
2972 /* Evaluate for side effects, if needed. I hate macros that don't
2974 if (TREE_SIDE_EFFECTS (valist))
2975 expand_expr (valist, const0_rtx, VOIDmode, EXPAND_NORMAL);
2981 /* Expand ARGLIST, from a call to __builtin_va_copy. We do this as a
2982 builtin rather than just as an assignment in stdarg.h because of the
2983 nastiness of array-type va_list types. */
2986 expand_builtin_va_copy (arglist)
2991 dst = TREE_VALUE (arglist);
2992 src = TREE_VALUE (TREE_CHAIN (arglist));
2994 dst = stabilize_va_list (dst, 1);
2995 src = stabilize_va_list (src, 0);
2997 if (TREE_CODE (va_list_type_node) != ARRAY_TYPE)
2999 t = build (MODIFY_EXPR, va_list_type_node, dst, src);
3000 TREE_SIDE_EFFECTS (t) = 1;
3001 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
3005 rtx dstb, srcb, size;
3007 /* Evaluate to pointers. */
3008 dstb = expand_expr (dst, NULL_RTX, Pmode, EXPAND_NORMAL);
3009 srcb = expand_expr (src, NULL_RTX, Pmode, EXPAND_NORMAL);
3010 size = expand_expr (TYPE_SIZE_UNIT (va_list_type_node), NULL_RTX,
3011 VOIDmode, EXPAND_NORMAL);
3013 /* "Dereference" to BLKmode memories. */
3014 dstb = gen_rtx_MEM (BLKmode, dstb);
3015 set_mem_alias_set (dstb, get_alias_set (TREE_TYPE (TREE_TYPE (dst))));
3016 srcb = gen_rtx_MEM (BLKmode, srcb);
3017 set_mem_alias_set (srcb, get_alias_set (TREE_TYPE (TREE_TYPE (src))));
3020 emit_block_move (dstb, srcb, size, TYPE_ALIGN (va_list_type_node));
3026 /* Expand a call to one of the builtin functions __builtin_frame_address or
3027 __builtin_return_address. */
3030 expand_builtin_frame_address (exp)
3033 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
3034 tree arglist = TREE_OPERAND (exp, 1);
3036 /* The argument must be a nonnegative integer constant.
3037 It counts the number of frames to scan up the stack.
3038 The value is the return address saved in that frame. */
3040 /* Warning about missing arg was already issued. */
3042 else if (! host_integerp (TREE_VALUE (arglist), 1))
3044 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
3045 error ("invalid arg to `__builtin_frame_address'");
3047 error ("invalid arg to `__builtin_return_address'");
3053 = expand_builtin_return_addr (DECL_FUNCTION_CODE (fndecl),
3054 tree_low_cst (TREE_VALUE (arglist), 1),
3055 hard_frame_pointer_rtx);
3057 /* Some ports cannot access arbitrary stack frames. */
3060 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
3061 warning ("unsupported arg to `__builtin_frame_address'");
3063 warning ("unsupported arg to `__builtin_return_address'");
3067 /* For __builtin_frame_address, return what we've got. */
3068 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
3071 if (GET_CODE (tem) != REG
3072 && ! CONSTANT_P (tem))
3073 tem = copy_to_mode_reg (Pmode, tem);
3078 /* Expand a call to the alloca builtin, with arguments ARGLIST. Return 0 if
3079 we failed and the caller should emit a normal call, otherwise try to get
3080 the result in TARGET, if convenient. */
3083 expand_builtin_alloca (arglist, target)
3090 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
3093 /* Compute the argument. */
3094 op0 = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
3096 /* Allocate the desired space. */
3097 result = allocate_dynamic_stack_space (op0, target, BITS_PER_UNIT);
3099 #ifdef POINTERS_EXTEND_UNSIGNED
3100 result = convert_memory_address (ptr_mode, result);
3106 /* Expand a call to the ffs builtin. The arguments are in ARGLIST.
3107 Return 0 if a normal call should be emitted rather than expanding the
3108 function in-line. If convenient, the result should be placed in TARGET.
3109 SUBTARGET may be used as the target for computing one of EXP's operands. */
3112 expand_builtin_ffs (arglist, target, subtarget)
3114 rtx target, subtarget;
3117 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
3120 /* Compute the argument. */
3121 op0 = expand_expr (TREE_VALUE (arglist), subtarget, VOIDmode, 0);
3122 /* Compute ffs, into TARGET if possible.
3123 Set TARGET to wherever the result comes back. */
3124 target = expand_unop (TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist))),
3125 ffs_optab, op0, target, 1);
3131 /* If the string passed to fputs is a constant and is one character
3132 long, we attempt to transform this call into __builtin_fputc(). */
3135 expand_builtin_fputs (arglist, ignore)
3139 tree len, fn, fn_fputc = built_in_decls[BUILT_IN_FPUTC],
3140 fn_fwrite = built_in_decls[BUILT_IN_FWRITE];
3142 /* If the return value is used, or the replacement _DECL isn't
3143 initialized, don't do the transformation. */
3144 if (!ignore || !fn_fputc || !fn_fwrite)
3147 /* Verify the arguments in the original call. */
3148 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)
3149 || current_function_check_memory_usage)
3152 /* Get the length of the string passed to fputs. If the length
3153 can't be determined, punt. */
3154 if (!(len = c_strlen (TREE_VALUE (arglist)))
3155 || TREE_CODE (len) != INTEGER_CST)
3158 switch (compare_tree_int (len, 1))
3160 case -1: /* length is 0, delete the call entirely . */
3162 /* Evaluate and ignore the argument in case it has
3164 expand_expr (TREE_VALUE (TREE_CHAIN (arglist)), const0_rtx,
3165 VOIDmode, EXPAND_NORMAL);
3168 case 0: /* length is 1, call fputc. */
3170 const char *p = c_getstr (TREE_VALUE (arglist));
3174 /* New argument list transforming fputs(string, stream) to
3175 fputc(string[0], stream). */
3177 build_tree_list (NULL_TREE, TREE_VALUE (TREE_CHAIN (arglist)));
3179 tree_cons (NULL_TREE, build_int_2 (p[0], 0), arglist);
3185 case 1: /* length is greater than 1, call fwrite. */
3187 tree string_arg = TREE_VALUE (arglist);
3189 /* New argument list transforming fputs(string, stream) to
3190 fwrite(string, 1, len, stream). */
3191 arglist = build_tree_list (NULL_TREE, TREE_VALUE (TREE_CHAIN (arglist)));
3192 arglist = tree_cons (NULL_TREE, len, arglist);
3193 arglist = tree_cons (NULL_TREE, size_one_node, arglist);
3194 arglist = tree_cons (NULL_TREE, string_arg, arglist);
3202 return expand_expr (build_function_call_expr (fn, arglist),
3203 (ignore ? const0_rtx : NULL_RTX),
3204 VOIDmode, EXPAND_NORMAL);
3207 /* Expand a call to __builtin_expect. We return our argument and emit a
3208 NOTE_INSN_EXPECTED_VALUE note. This is the expansion of __builtin_expect in
3209 a non-jump context. */
3212 expand_builtin_expect (arglist, target)
3219 if (arglist == NULL_TREE
3220 || TREE_CHAIN (arglist) == NULL_TREE)
3222 exp = TREE_VALUE (arglist);
3223 c = TREE_VALUE (TREE_CHAIN (arglist));
3225 if (TREE_CODE (c) != INTEGER_CST)
3227 error ("second arg to `__builtin_expect' must be a constant");
3228 c = integer_zero_node;
3231 target = expand_expr (exp, target, VOIDmode, EXPAND_NORMAL);
3233 /* Don't bother with expected value notes for integral constants. */
3234 if (GET_CODE (target) != CONST_INT)
3236 /* We do need to force this into a register so that we can be
3237 moderately sure to be able to correctly interpret the branch
3239 target = force_reg (GET_MODE (target), target);
3241 rtx_c = expand_expr (c, NULL_RTX, GET_MODE (target), EXPAND_NORMAL);
3243 note = emit_note (NULL, NOTE_INSN_EXPECTED_VALUE);
3244 NOTE_EXPECTED_VALUE (note) = gen_rtx_EQ (VOIDmode, target, rtx_c);
3250 /* Like expand_builtin_expect, except do this in a jump context. This is
3251 called from do_jump if the conditional is a __builtin_expect. Return either
3252 a SEQUENCE of insns to emit the jump or NULL if we cannot optimize
3253 __builtin_expect. We need to optimize this at jump time so that machines
3254 like the PowerPC don't turn the test into a SCC operation, and then jump
3255 based on the test being 0/1. */
3258 expand_builtin_expect_jump (exp, if_false_label, if_true_label)
3263 tree arglist = TREE_OPERAND (exp, 1);
3264 tree arg0 = TREE_VALUE (arglist);
3265 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
3268 /* Only handle __builtin_expect (test, 0) and
3269 __builtin_expect (test, 1). */
3270 if (TREE_CODE (TREE_TYPE (arg1)) == INTEGER_TYPE
3271 && (integer_zerop (arg1) || integer_onep (arg1)))
3276 /* If we fail to locate an appropriate conditional jump, we'll
3277 fall back to normal evaluation. Ensure that the expression
3278 can be re-evaluated. */
3279 switch (unsafe_for_reeval (arg0))
3284 case 1: /* Mildly unsafe. */
3285 arg0 = unsave_expr (arg0);
3288 case 2: /* Wildly unsafe. */
3292 /* Expand the jump insns. */
3294 do_jump (arg0, if_false_label, if_true_label);
3295 ret = gen_sequence ();
3298 /* Now that the __builtin_expect has been validated, go through and add
3299 the expect's to each of the conditional jumps. If we run into an
3300 error, just give up and generate the 'safe' code of doing a SCC
3301 operation and then doing a branch on that. */
3302 for (j = 0; j < XVECLEN (ret, 0); j++)
3304 rtx insn = XVECEXP (ret, 0, j);
3307 if (GET_CODE (insn) == JUMP_INSN && any_condjump_p (insn)
3308 && (pattern = pc_set (insn)) != NULL_RTX)
3310 rtx ifelse = SET_SRC (pattern);
3314 if (GET_CODE (ifelse) != IF_THEN_ELSE)
3317 if (GET_CODE (XEXP (ifelse, 1)) == LABEL_REF)
3320 label = XEXP (XEXP (ifelse, 1), 0);
3322 /* An inverted jump reverses the probabilities. */
3323 else if (GET_CODE (XEXP (ifelse, 2)) == LABEL_REF)
3326 label = XEXP (XEXP (ifelse, 2), 0);
3328 /* We shouldn't have to worry about conditional returns during
3329 the expansion stage, but handle it gracefully anyway. */
3330 else if (GET_CODE (XEXP (ifelse, 1)) == RETURN)
3335 /* An inverted return reverses the probabilities. */
3336 else if (GET_CODE (XEXP (ifelse, 2)) == RETURN)
3344 /* If the test is expected to fail, reverse the
3346 if (integer_zerop (arg1))
3349 /* If we are jumping to the false label, reverse the
3351 if (label == NULL_RTX)
3352 ; /* conditional return */
3353 else if (label == if_false_label)
3355 else if (label != if_true_label)
3359 predict_insn_def (insn, PRED_BUILTIN_EXPECT, taken);
3363 /* If no jumps were modified, fail and do __builtin_expect the normal
3372 /* Expand an expression EXP that calls a built-in function,
3373 with result going to TARGET if that's convenient
3374 (and in mode MODE if that's convenient).
3375 SUBTARGET may be used as the target for computing one of EXP's operands.
3376 IGNORE is nonzero if the value is to be ignored. */
3379 expand_builtin (exp, target, subtarget, mode, ignore)
3383 enum machine_mode mode;
3386 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
3387 tree arglist = TREE_OPERAND (exp, 1);
3388 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
3390 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
3391 return (*targetm.expand_builtin) (exp, target, subtarget, mode, ignore);
3393 /* When not optimizing, generate calls to library functions for a certain
3395 if (! optimize && ! CALLED_AS_BUILT_IN (fndecl)
3396 && (fcode == BUILT_IN_SIN || fcode == BUILT_IN_COS
3397 || fcode == BUILT_IN_FSQRT || fcode == BUILT_IN_SQRTF
3398 || fcode == BUILT_IN_SQRTL || fcode == BUILT_IN_MEMSET
3399 || fcode == BUILT_IN_MEMCPY || fcode == BUILT_IN_MEMCMP
3400 || fcode == BUILT_IN_BCMP || fcode == BUILT_IN_BZERO
3401 || fcode == BUILT_IN_INDEX || fcode == BUILT_IN_RINDEX
3402 || fcode == BUILT_IN_STRCHR || fcode == BUILT_IN_STRRCHR
3403 || fcode == BUILT_IN_STRLEN || fcode == BUILT_IN_STRCPY
3404 || fcode == BUILT_IN_STRNCPY || fcode == BUILT_IN_STRNCMP
3405 || fcode == BUILT_IN_STRSTR || fcode == BUILT_IN_STRPBRK
3406 || fcode == BUILT_IN_STRCAT || fcode == BUILT_IN_STRNCAT
3407 || fcode == BUILT_IN_STRSPN || fcode == BUILT_IN_STRCSPN
3408 || fcode == BUILT_IN_STRCMP || fcode == BUILT_IN_FFS
3409 || fcode == BUILT_IN_PUTCHAR || fcode == BUILT_IN_PUTS
3410 || fcode == BUILT_IN_PRINTF || fcode == BUILT_IN_FPUTC
3411 || fcode == BUILT_IN_FPUTS || fcode == BUILT_IN_FWRITE))
3412 return expand_call (exp, target, ignore);
3418 case BUILT_IN_LLABS:
3419 case BUILT_IN_IMAXABS:
3421 case BUILT_IN_FABSF:
3422 case BUILT_IN_FABSL:
3423 /* build_function_call changes these into ABS_EXPR. */
3427 case BUILT_IN_CONJF:
3428 case BUILT_IN_CONJL:
3429 case BUILT_IN_CREAL:
3430 case BUILT_IN_CREALF:
3431 case BUILT_IN_CREALL:
3432 case BUILT_IN_CIMAG:
3433 case BUILT_IN_CIMAGF:
3434 case BUILT_IN_CIMAGL:
3435 /* expand_tree_builtin changes these into CONJ_EXPR, REALPART_EXPR
3436 and IMAGPART_EXPR. */
3445 /* Treat these like sqrt only if unsafe math optimizations are allowed,
3446 because of possible accuracy problems. */
3447 if (! flag_unsafe_math_optimizations)
3449 case BUILT_IN_FSQRT:
3450 case BUILT_IN_SQRTF:
3451 case BUILT_IN_SQRTL:
3452 target = expand_builtin_mathfn (exp, target, subtarget);
3460 case BUILT_IN_APPLY_ARGS:
3461 return expand_builtin_apply_args ();
3463 /* __builtin_apply (FUNCTION, ARGUMENTS, ARGSIZE) invokes
3464 FUNCTION with a copy of the parameters described by
3465 ARGUMENTS, and ARGSIZE. It returns a block of memory
3466 allocated on the stack into which is stored all the registers
3467 that might possibly be used for returning the result of a
3468 function. ARGUMENTS is the value returned by
3469 __builtin_apply_args. ARGSIZE is the number of bytes of
3470 arguments that must be copied. ??? How should this value be
3471 computed? We'll also need a safe worst case value for varargs
3473 case BUILT_IN_APPLY:
3474 if (!validate_arglist (arglist, POINTER_TYPE,
3475 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)
3476 && !validate_arglist (arglist, REFERENCE_TYPE,
3477 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3485 for (t = arglist, i = 0; t; t = TREE_CHAIN (t), i++)
3486 ops[i] = expand_expr (TREE_VALUE (t), NULL_RTX, VOIDmode, 0);
3488 return expand_builtin_apply (ops[0], ops[1], ops[2]);
3491 /* __builtin_return (RESULT) causes the function to return the
3492 value described by RESULT. RESULT is address of the block of
3493 memory returned by __builtin_apply. */
3494 case BUILT_IN_RETURN:
3495 if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
3496 expand_builtin_return (expand_expr (TREE_VALUE (arglist),
3497 NULL_RTX, VOIDmode, 0));
3500 case BUILT_IN_SAVEREGS:
3501 return expand_builtin_saveregs ();
3503 case BUILT_IN_ARGS_INFO:
3504 return expand_builtin_args_info (exp);
3506 /* Return the address of the first anonymous stack arg. */
3507 case BUILT_IN_NEXT_ARG:
3508 return expand_builtin_next_arg (arglist);
3510 case BUILT_IN_CLASSIFY_TYPE:
3511 return expand_builtin_classify_type (arglist);
3513 case BUILT_IN_CONSTANT_P:
3514 return expand_builtin_constant_p (exp);
3516 case BUILT_IN_FRAME_ADDRESS:
3517 case BUILT_IN_RETURN_ADDRESS:
3518 return expand_builtin_frame_address (exp);
3520 /* Returns the address of the area where the structure is returned.
3522 case BUILT_IN_AGGREGATE_INCOMING_ADDRESS:
3524 || ! AGGREGATE_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl)))
3525 || GET_CODE (DECL_RTL (DECL_RESULT (current_function_decl))) != MEM)
3528 return XEXP (DECL_RTL (DECL_RESULT (current_function_decl)), 0);
3530 case BUILT_IN_ALLOCA:
3531 target = expand_builtin_alloca (arglist, target);
3537 target = expand_builtin_ffs (arglist, target, subtarget);
3542 case BUILT_IN_STRLEN:
3543 target = expand_builtin_strlen (exp, target);
3548 case BUILT_IN_STRCPY:
3549 target = expand_builtin_strcpy (exp);
3554 case BUILT_IN_STRNCPY:
3555 target = expand_builtin_strncpy (arglist, target, mode);
3560 case BUILT_IN_STRCAT:
3561 target = expand_builtin_strcat (arglist, target, mode);
3566 case BUILT_IN_STRNCAT:
3567 target = expand_builtin_strncat (arglist, target, mode);
3572 case BUILT_IN_STRSPN:
3573 target = expand_builtin_strspn (arglist, target, mode);
3578 case BUILT_IN_STRCSPN:
3579 target = expand_builtin_strcspn (arglist, target, mode);
3584 case BUILT_IN_STRSTR:
3585 target = expand_builtin_strstr (arglist, target, mode);
3590 case BUILT_IN_STRPBRK:
3591 target = expand_builtin_strpbrk (arglist, target, mode);
3596 case BUILT_IN_INDEX:
3597 case BUILT_IN_STRCHR:
3598 target = expand_builtin_strchr (arglist, target, mode);
3603 case BUILT_IN_RINDEX:
3604 case BUILT_IN_STRRCHR:
3605 target = expand_builtin_strrchr (arglist, target, mode);
3610 case BUILT_IN_MEMCPY:
3611 target = expand_builtin_memcpy (arglist);
3616 case BUILT_IN_MEMSET:
3617 target = expand_builtin_memset (exp);
3622 case BUILT_IN_BZERO:
3623 target = expand_builtin_bzero (exp);
3628 case BUILT_IN_STRCMP:
3629 target = expand_builtin_strcmp (exp, target, mode);
3634 case BUILT_IN_STRNCMP:
3635 target = expand_builtin_strncmp (exp, target, mode);
3640 /* These comparison functions need an instruction that returns an actual
3641 index. An ordinary compare that just sets the condition codes
3643 #ifdef HAVE_cmpstrsi
3645 case BUILT_IN_MEMCMP:
3646 target = expand_builtin_memcmp (exp, arglist, target);
3652 case BUILT_IN_MEMCMP:
3656 case BUILT_IN_SETJMP:
3657 target = expand_builtin_setjmp (arglist, target);
3662 /* __builtin_longjmp is passed a pointer to an array of five words.
3663 It's similar to the C library longjmp function but works with
3664 __builtin_setjmp above. */
3665 case BUILT_IN_LONGJMP:
3666 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3670 rtx buf_addr = expand_expr (TREE_VALUE (arglist), subtarget,
3672 rtx value = expand_expr (TREE_VALUE (TREE_CHAIN (arglist)),
3673 NULL_RTX, VOIDmode, 0);
3675 if (value != const1_rtx)
3677 error ("__builtin_longjmp second argument must be 1");
3681 expand_builtin_longjmp (buf_addr, value);
3688 emit_insn (gen_trap ());
3691 error ("__builtin_trap not supported by this target");
3695 case BUILT_IN_PUTCHAR:
3697 case BUILT_IN_FPUTC:
3698 case BUILT_IN_FWRITE:
3700 case BUILT_IN_FPUTS:
3701 target = expand_builtin_fputs (arglist, ignore);
3706 /* Various hooks for the DWARF 2 __throw routine. */
3707 case BUILT_IN_UNWIND_INIT:
3708 expand_builtin_unwind_init ();
3710 case BUILT_IN_DWARF_CFA:
3711 return virtual_cfa_rtx;
3712 #ifdef DWARF2_UNWIND_INFO
3713 case BUILT_IN_DWARF_FP_REGNUM:
3714 return expand_builtin_dwarf_fp_regnum ();
3715 case BUILT_IN_INIT_DWARF_REG_SIZES:
3716 expand_builtin_init_dwarf_reg_sizes (TREE_VALUE (arglist));
3719 case BUILT_IN_FROB_RETURN_ADDR:
3720 return expand_builtin_frob_return_addr (TREE_VALUE (arglist));
3721 case BUILT_IN_EXTRACT_RETURN_ADDR:
3722 return expand_builtin_extract_return_addr (TREE_VALUE (arglist));
3723 case BUILT_IN_EH_RETURN:
3724 expand_builtin_eh_return (TREE_VALUE (arglist),
3725 TREE_VALUE (TREE_CHAIN (arglist)));
3727 #ifdef EH_RETURN_DATA_REGNO
3728 case BUILT_IN_EH_RETURN_DATA_REGNO:
3729 return expand_builtin_eh_return_data_regno (arglist);
3731 case BUILT_IN_VARARGS_START:
3732 return expand_builtin_va_start (0, arglist);
3733 case BUILT_IN_STDARG_START:
3734 return expand_builtin_va_start (1, arglist);
3735 case BUILT_IN_VA_END:
3736 return expand_builtin_va_end (arglist);
3737 case BUILT_IN_VA_COPY:
3738 return expand_builtin_va_copy (arglist);
3739 case BUILT_IN_EXPECT:
3740 return expand_builtin_expect (arglist, target);
3742 default: /* just do library call, if unknown builtin */
3743 error ("built-in function `%s' not currently supported",
3744 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
3747 /* The switch statement above can drop through to cause the function
3748 to be called normally. */
3749 return expand_call (exp, target, ignore);
3752 /* Fold a call to __builtin_constant_p, if we know it will evaluate to a
3753 constant. ARGLIST is the argument list of the call. */
3756 fold_builtin_constant_p (arglist)
3762 arglist = TREE_VALUE (arglist);
3764 /* We return 1 for a numeric type that's known to be a constant
3765 value at compile-time or for an aggregate type that's a
3766 literal constant. */
3767 STRIP_NOPS (arglist);
3769 /* If we know this is a constant, emit the constant of one. */
3770 if (TREE_CODE_CLASS (TREE_CODE (arglist)) == 'c'
3771 || (TREE_CODE (arglist) == CONSTRUCTOR
3772 && TREE_CONSTANT (arglist))
3773 || (TREE_CODE (arglist) == ADDR_EXPR
3774 && TREE_CODE (TREE_OPERAND (arglist, 0)) == STRING_CST))
3775 return integer_one_node;
3777 /* If we aren't going to be running CSE or this expression
3778 has side effects, show we don't know it to be a constant.
3779 Likewise if it's a pointer or aggregate type since in those
3780 case we only want literals, since those are only optimized
3781 when generating RTL, not later.
3782 And finally, if we are compiling an initializer, not code, we
3783 need to return a definite result now; there's not going to be any
3784 more optimization done. */
3785 if (TREE_SIDE_EFFECTS (arglist) || cse_not_expected
3786 || AGGREGATE_TYPE_P (TREE_TYPE (arglist))
3787 || POINTER_TYPE_P (TREE_TYPE (arglist))
3789 return integer_zero_node;
3794 /* Fold a call to __builtin_classify_type. */
3797 fold_builtin_classify_type (arglist)
3801 return build_int_2 (no_type_class, 0);
3803 return build_int_2 (type_to_class (TREE_TYPE (TREE_VALUE (arglist))), 0);
3806 /* Used by constant folding to eliminate some builtin calls early. EXP is
3807 the CALL_EXPR of a call to a builtin function. */
3813 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
3814 tree arglist = TREE_OPERAND (exp, 1);
3815 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
3817 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
3822 case BUILT_IN_CONSTANT_P:
3823 return fold_builtin_constant_p (arglist);
3825 case BUILT_IN_CLASSIFY_TYPE:
3826 return fold_builtin_classify_type (arglist);
3828 case BUILT_IN_STRLEN:
3829 if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
3831 tree len = c_strlen (TREE_VALUE (arglist));
3845 build_function_call_expr (fn, arglist)
3850 call_expr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
3851 call_expr = build (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)),
3852 call_expr, arglist);
3853 TREE_SIDE_EFFECTS (call_expr) = 1;
3854 return fold (call_expr);
3857 /* This function validates the types of a function call argument list
3858 represented as a tree chain of parameters against a specified list
3859 of tree_codes. If the last specifier is a 0, that represents an
3860 ellipses, otherwise the last specifier must be a VOID_TYPE. */
3863 validate_arglist VPARAMS ((tree arglist, ...))
3865 enum tree_code code;
3868 VA_OPEN (ap, arglist);
3869 VA_FIXEDARG (ap, tree, arglist);
3872 code = va_arg (ap, enum tree_code);
3876 /* This signifies an ellipses, any further arguments are all ok. */
3880 /* This signifies an endlink, if no arguments remain, return
3881 true, otherwise return false. */
3885 /* If no parameters remain or the parameter's code does not
3886 match the specified code, return false. Otherwise continue
3887 checking any remaining arguments. */
3888 if (arglist == 0 || code != TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))))
3892 arglist = TREE_CHAIN (arglist);
3895 /* We need gotos here since we can only have one VA_CLOSE in a
3903 /* Default version of target-specific builtin setup that does nothing. */
3906 default_init_builtins ()
3910 /* Default target-specific builtin expander that does nothing. */
3913 default_expand_builtin (exp, target, subtarget, mode, ignore)
3914 tree exp ATTRIBUTE_UNUSED;
3915 rtx target ATTRIBUTE_UNUSED;
3916 rtx subtarget ATTRIBUTE_UNUSED;
3917 enum machine_mode mode ATTRIBUTE_UNUSED;
3918 int ignore ATTRIBUTE_UNUSED;