1 /* Expand builtin functions.
2 Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
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
24 #include "coretypes.h"
32 #include "hard-reg-set.h"
35 #include "insn-config.h"
41 #include "typeclass.h"
46 #include "langhooks.h"
48 #define CALLED_AS_BUILT_IN(NODE) \
49 (!strncmp (IDENTIFIER_POINTER (DECL_NAME (NODE)), "__builtin_", 10))
51 /* Register mappings for target machines without register windows. */
52 #ifndef INCOMING_REGNO
53 #define INCOMING_REGNO(OUT) (OUT)
55 #ifndef OUTGOING_REGNO
56 #define OUTGOING_REGNO(IN) (IN)
59 #ifndef PAD_VARARGS_DOWN
60 #define PAD_VARARGS_DOWN BYTES_BIG_ENDIAN
63 /* Define the names of the builtin function types and codes. */
64 const char *const built_in_class_names
[4]
65 = {"NOT_BUILT_IN", "BUILT_IN_FRONTEND", "BUILT_IN_MD", "BUILT_IN_NORMAL"};
67 #define DEF_BUILTIN(X, N, C, T, LT, B, F, NA, AT, IM) STRINGX(X),
68 const char *const built_in_names
[(int) END_BUILTINS
] =
70 #include "builtins.def"
74 /* Setup an array of _DECL trees, make sure each element is
75 initialized to NULL_TREE. */
76 tree built_in_decls
[(int) END_BUILTINS
];
77 /* Declarations used when constructing the builtin implicitly in the compiler.
78 It may be NULL_TREE when this is invalid (for instance runtime is not
79 required to implement the function call in all cases. */
80 tree implicit_built_in_decls
[(int) END_BUILTINS
];
82 static int get_pointer_alignment
PARAMS ((tree
, unsigned int));
83 static tree c_strlen
PARAMS ((tree
));
84 static const char *c_getstr
PARAMS ((tree
));
85 static rtx c_readstr
PARAMS ((const char *,
87 static int target_char_cast
PARAMS ((tree
, char *));
88 static rtx get_memory_rtx
PARAMS ((tree
));
89 static int apply_args_size
PARAMS ((void));
90 static int apply_result_size
PARAMS ((void));
91 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
92 static rtx result_vector
PARAMS ((int, rtx
));
94 static rtx expand_builtin_setjmp
PARAMS ((tree
, rtx
));
95 static void expand_builtin_prefetch
PARAMS ((tree
));
96 static rtx expand_builtin_apply_args
PARAMS ((void));
97 static rtx expand_builtin_apply_args_1
PARAMS ((void));
98 static rtx expand_builtin_apply
PARAMS ((rtx
, rtx
, rtx
));
99 static void expand_builtin_return
PARAMS ((rtx
));
100 static enum type_class type_to_class
PARAMS ((tree
));
101 static rtx expand_builtin_classify_type
PARAMS ((tree
));
102 static void expand_errno_check
PARAMS ((tree
, rtx
));
103 static rtx expand_builtin_mathfn
PARAMS ((tree
, rtx
, rtx
));
104 static rtx expand_builtin_mathfn_2
PARAMS ((tree
, rtx
, rtx
));
105 static rtx expand_builtin_constant_p
PARAMS ((tree
));
106 static rtx expand_builtin_args_info
PARAMS ((tree
));
107 static rtx expand_builtin_next_arg
PARAMS ((tree
));
108 static rtx expand_builtin_va_start
PARAMS ((tree
));
109 static rtx expand_builtin_va_end
PARAMS ((tree
));
110 static rtx expand_builtin_va_copy
PARAMS ((tree
));
111 static rtx expand_builtin_memcmp
PARAMS ((tree
, tree
, rtx
,
113 static rtx expand_builtin_strcmp
PARAMS ((tree
, rtx
,
115 static rtx expand_builtin_strncmp
PARAMS ((tree
, rtx
,
117 static rtx builtin_memcpy_read_str
PARAMS ((PTR
, HOST_WIDE_INT
,
119 static rtx expand_builtin_strcat
PARAMS ((tree
, rtx
,
121 static rtx expand_builtin_strncat
PARAMS ((tree
, rtx
,
123 static rtx expand_builtin_strspn
PARAMS ((tree
, rtx
,
125 static rtx expand_builtin_strcspn
PARAMS ((tree
, rtx
,
127 static rtx expand_builtin_memcpy
PARAMS ((tree
, rtx
,
128 enum machine_mode
, int));
129 static rtx expand_builtin_strcpy
PARAMS ((tree
, rtx
,
131 static rtx expand_builtin_stpcpy
PARAMS ((tree
, rtx
,
133 static rtx builtin_strncpy_read_str
PARAMS ((PTR
, HOST_WIDE_INT
,
135 static rtx expand_builtin_strncpy
PARAMS ((tree
, rtx
,
137 static rtx builtin_memset_read_str
PARAMS ((PTR
, HOST_WIDE_INT
,
139 static rtx builtin_memset_gen_str
PARAMS ((PTR
, HOST_WIDE_INT
,
141 static rtx expand_builtin_memset
PARAMS ((tree
, rtx
,
143 static rtx expand_builtin_bzero
PARAMS ((tree
));
144 static rtx expand_builtin_strlen
PARAMS ((tree
, rtx
));
145 static rtx expand_builtin_strstr
PARAMS ((tree
, rtx
,
147 static rtx expand_builtin_strpbrk
PARAMS ((tree
, rtx
,
149 static rtx expand_builtin_strchr
PARAMS ((tree
, rtx
,
151 static rtx expand_builtin_strrchr
PARAMS ((tree
, rtx
,
153 static rtx expand_builtin_alloca
PARAMS ((tree
, rtx
));
154 static rtx expand_builtin_unop
PARAMS ((enum machine_mode
,
155 tree
, rtx
, rtx
, optab
));
156 static rtx expand_builtin_frame_address
PARAMS ((tree
));
157 static rtx expand_builtin_fputs
PARAMS ((tree
, int, int));
158 static tree stabilize_va_list
PARAMS ((tree
, int));
159 static rtx expand_builtin_expect
PARAMS ((tree
, rtx
));
160 static tree fold_builtin_constant_p
PARAMS ((tree
));
161 static tree fold_builtin_classify_type
PARAMS ((tree
));
162 static tree fold_builtin_inf
PARAMS ((tree
, int));
163 static tree fold_builtin_nan
PARAMS ((tree
, tree
, int));
164 static int validate_arglist
PARAMS ((tree
, ...));
165 static tree fold_trunc_transparent_mathfn
PARAMS ((tree
));
167 /* Return the alignment in bits of EXP, a pointer valued expression.
168 But don't return more than MAX_ALIGN no matter what.
169 The alignment returned is, by default, the alignment of the thing that
170 EXP points to. If it is not a POINTER_TYPE, 0 is returned.
172 Otherwise, look at the expression to see if we can do better, i.e., if the
173 expression is actually pointing at an object whose alignment is tighter. */
176 get_pointer_alignment (exp
, max_align
)
178 unsigned int max_align
;
180 unsigned int align
, inner
;
182 if (TREE_CODE (TREE_TYPE (exp
)) != POINTER_TYPE
)
185 align
= TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp
)));
186 align
= MIN (align
, max_align
);
190 switch (TREE_CODE (exp
))
194 case NON_LVALUE_EXPR
:
195 exp
= TREE_OPERAND (exp
, 0);
196 if (TREE_CODE (TREE_TYPE (exp
)) != POINTER_TYPE
)
199 inner
= TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp
)));
200 align
= MIN (inner
, max_align
);
204 /* If sum of pointer + int, restrict our maximum alignment to that
205 imposed by the integer. If not, we can't do any better than
207 if (! host_integerp (TREE_OPERAND (exp
, 1), 1))
210 while (((tree_low_cst (TREE_OPERAND (exp
, 1), 1))
211 & (max_align
/ BITS_PER_UNIT
- 1))
215 exp
= TREE_OPERAND (exp
, 0);
219 /* See what we are pointing at and look at its alignment. */
220 exp
= TREE_OPERAND (exp
, 0);
221 if (TREE_CODE (exp
) == FUNCTION_DECL
)
222 align
= FUNCTION_BOUNDARY
;
223 else if (DECL_P (exp
))
224 align
= DECL_ALIGN (exp
);
225 #ifdef CONSTANT_ALIGNMENT
226 else if (TREE_CODE_CLASS (TREE_CODE (exp
)) == 'c')
227 align
= CONSTANT_ALIGNMENT (exp
, align
);
229 return MIN (align
, max_align
);
237 /* Compute the length of a C string. TREE_STRING_LENGTH is not the right
238 way, because it could contain a zero byte in the middle.
239 TREE_STRING_LENGTH is the size of the character array, not the string.
241 The value returned is of type `ssizetype'.
243 Unfortunately, string_constant can't access the values of const char
244 arrays with initializers, so neither can we do so here. */
251 HOST_WIDE_INT offset
;
255 src
= string_constant (src
, &offset_node
);
259 max
= TREE_STRING_LENGTH (src
) - 1;
260 ptr
= TREE_STRING_POINTER (src
);
262 if (offset_node
&& TREE_CODE (offset_node
) != INTEGER_CST
)
264 /* If the string has an internal zero byte (e.g., "foo\0bar"), we can't
265 compute the offset to the following null if we don't know where to
266 start searching for it. */
269 for (i
= 0; i
< max
; i
++)
273 /* We don't know the starting offset, but we do know that the string
274 has no internal zero bytes. We can assume that the offset falls
275 within the bounds of the string; otherwise, the programmer deserves
276 what he gets. Subtract the offset from the length of the string,
277 and return that. This would perhaps not be valid if we were dealing
278 with named arrays in addition to literal string constants. */
280 return size_diffop (size_int (max
), offset_node
);
283 /* We have a known offset into the string. Start searching there for
284 a null character if we can represent it as a single HOST_WIDE_INT. */
285 if (offset_node
== 0)
287 else if (! host_integerp (offset_node
, 0))
290 offset
= tree_low_cst (offset_node
, 0);
292 /* If the offset is known to be out of bounds, warn, and call strlen at
294 if (offset
< 0 || offset
> max
)
296 warning ("offset outside bounds of constant string");
300 /* Use strlen to search for the first zero byte. Since any strings
301 constructed with build_string will have nulls appended, we win even
302 if we get handed something like (char[4])"abcd".
304 Since OFFSET is our starting index into the string, no further
305 calculation is needed. */
306 return ssize_int (strlen (ptr
+ offset
));
309 /* Return a char pointer for a C string if it is a string constant
310 or sum of string constant and integer constant. */
318 src
= string_constant (src
, &offset_node
);
322 if (offset_node
== 0)
323 return TREE_STRING_POINTER (src
);
324 else if (!host_integerp (offset_node
, 1)
325 || compare_tree_int (offset_node
, TREE_STRING_LENGTH (src
) - 1) > 0)
328 return TREE_STRING_POINTER (src
) + tree_low_cst (offset_node
, 1);
331 /* Return a CONST_INT or CONST_DOUBLE corresponding to target reading
332 GET_MODE_BITSIZE (MODE) bits from string constant STR. */
335 c_readstr (str
, mode
)
337 enum machine_mode mode
;
343 if (GET_MODE_CLASS (mode
) != MODE_INT
)
348 for (i
= 0; i
< GET_MODE_SIZE (mode
); i
++)
351 if (WORDS_BIG_ENDIAN
)
352 j
= GET_MODE_SIZE (mode
) - i
- 1;
353 if (BYTES_BIG_ENDIAN
!= WORDS_BIG_ENDIAN
354 && GET_MODE_SIZE (mode
) > UNITS_PER_WORD
)
355 j
= j
+ UNITS_PER_WORD
- 2 * (j
% UNITS_PER_WORD
) - 1;
357 if (j
> 2 * HOST_BITS_PER_WIDE_INT
)
360 ch
= (unsigned char) str
[i
];
361 c
[j
/ HOST_BITS_PER_WIDE_INT
] |= ch
<< (j
% HOST_BITS_PER_WIDE_INT
);
363 return immed_double_const (c
[0], c
[1], mode
);
366 /* Cast a target constant CST to target CHAR and if that value fits into
367 host char type, return zero and put that value into variable pointed by
371 target_char_cast (cst
, p
)
375 unsigned HOST_WIDE_INT val
, hostval
;
377 if (!host_integerp (cst
, 1)
378 || CHAR_TYPE_SIZE
> HOST_BITS_PER_WIDE_INT
)
381 val
= tree_low_cst (cst
, 1);
382 if (CHAR_TYPE_SIZE
< HOST_BITS_PER_WIDE_INT
)
383 val
&= (((unsigned HOST_WIDE_INT
) 1) << CHAR_TYPE_SIZE
) - 1;
386 if (HOST_BITS_PER_CHAR
< HOST_BITS_PER_WIDE_INT
)
387 hostval
&= (((unsigned HOST_WIDE_INT
) 1) << HOST_BITS_PER_CHAR
) - 1;
396 /* Given TEM, a pointer to a stack frame, follow the dynamic chain COUNT
397 times to get the address of either a higher stack frame, or a return
398 address located within it (depending on FNDECL_CODE). */
401 expand_builtin_return_addr (fndecl_code
, count
, tem
)
402 enum built_in_function fndecl_code
;
408 /* Some machines need special handling before we can access
409 arbitrary frames. For example, on the sparc, we must first flush
410 all register windows to the stack. */
411 #ifdef SETUP_FRAME_ADDRESSES
413 SETUP_FRAME_ADDRESSES ();
416 /* On the sparc, the return address is not in the frame, it is in a
417 register. There is no way to access it off of the current frame
418 pointer, but it can be accessed off the previous frame pointer by
419 reading the value from the register window save area. */
420 #ifdef RETURN_ADDR_IN_PREVIOUS_FRAME
421 if (fndecl_code
== BUILT_IN_RETURN_ADDRESS
)
425 /* Scan back COUNT frames to the specified frame. */
426 for (i
= 0; i
< count
; i
++)
428 /* Assume the dynamic chain pointer is in the word that the
429 frame address points to, unless otherwise specified. */
430 #ifdef DYNAMIC_CHAIN_ADDRESS
431 tem
= DYNAMIC_CHAIN_ADDRESS (tem
);
433 tem
= memory_address (Pmode
, tem
);
434 tem
= gen_rtx_MEM (Pmode
, tem
);
435 set_mem_alias_set (tem
, get_frame_alias_set ());
436 tem
= copy_to_reg (tem
);
439 /* For __builtin_frame_address, return what we've got. */
440 if (fndecl_code
== BUILT_IN_FRAME_ADDRESS
)
443 /* For __builtin_return_address, Get the return address from that
445 #ifdef RETURN_ADDR_RTX
446 tem
= RETURN_ADDR_RTX (count
, tem
);
448 tem
= memory_address (Pmode
,
449 plus_constant (tem
, GET_MODE_SIZE (Pmode
)));
450 tem
= gen_rtx_MEM (Pmode
, tem
);
451 set_mem_alias_set (tem
, get_frame_alias_set ());
456 /* Alias set used for setjmp buffer. */
457 static HOST_WIDE_INT setjmp_alias_set
= -1;
459 /* Construct the leading half of a __builtin_setjmp call. Control will
460 return to RECEIVER_LABEL. This is used directly by sjlj exception
464 expand_builtin_setjmp_setup (buf_addr
, receiver_label
)
468 enum machine_mode sa_mode
= STACK_SAVEAREA_MODE (SAVE_NONLOCAL
);
472 if (setjmp_alias_set
== -1)
473 setjmp_alias_set
= new_alias_set ();
475 #ifdef POINTERS_EXTEND_UNSIGNED
476 if (GET_MODE (buf_addr
) != Pmode
)
477 buf_addr
= convert_memory_address (Pmode
, buf_addr
);
480 buf_addr
= force_reg (Pmode
, force_operand (buf_addr
, NULL_RTX
));
484 /* We store the frame pointer and the address of receiver_label in
485 the buffer and use the rest of it for the stack save area, which
486 is machine-dependent. */
488 #ifndef BUILTIN_SETJMP_FRAME_VALUE
489 #define BUILTIN_SETJMP_FRAME_VALUE virtual_stack_vars_rtx
492 mem
= gen_rtx_MEM (Pmode
, buf_addr
);
493 set_mem_alias_set (mem
, setjmp_alias_set
);
494 emit_move_insn (mem
, BUILTIN_SETJMP_FRAME_VALUE
);
496 mem
= gen_rtx_MEM (Pmode
, plus_constant (buf_addr
, GET_MODE_SIZE (Pmode
))),
497 set_mem_alias_set (mem
, setjmp_alias_set
);
499 emit_move_insn (validize_mem (mem
),
500 force_reg (Pmode
, gen_rtx_LABEL_REF (Pmode
, receiver_label
)));
502 stack_save
= gen_rtx_MEM (sa_mode
,
503 plus_constant (buf_addr
,
504 2 * GET_MODE_SIZE (Pmode
)));
505 set_mem_alias_set (stack_save
, setjmp_alias_set
);
506 emit_stack_save (SAVE_NONLOCAL
, &stack_save
, NULL_RTX
);
508 /* If there is further processing to do, do it. */
509 #ifdef HAVE_builtin_setjmp_setup
510 if (HAVE_builtin_setjmp_setup
)
511 emit_insn (gen_builtin_setjmp_setup (buf_addr
));
514 /* Tell optimize_save_area_alloca that extra work is going to
515 need to go on during alloca. */
516 current_function_calls_setjmp
= 1;
518 /* Set this so all the registers get saved in our frame; we need to be
519 able to copy the saved values for any registers from frames we unwind. */
520 current_function_has_nonlocal_label
= 1;
523 /* Construct the trailing part of a __builtin_setjmp call.
524 This is used directly by sjlj exception handling code. */
527 expand_builtin_setjmp_receiver (receiver_label
)
528 rtx receiver_label ATTRIBUTE_UNUSED
;
530 /* Clobber the FP when we get here, so we have to make sure it's
531 marked as used by this function. */
532 emit_insn (gen_rtx_USE (VOIDmode
, hard_frame_pointer_rtx
));
534 /* Mark the static chain as clobbered here so life information
535 doesn't get messed up for it. */
536 emit_insn (gen_rtx_CLOBBER (VOIDmode
, static_chain_rtx
));
538 /* Now put in the code to restore the frame pointer, and argument
539 pointer, if needed. The code below is from expand_end_bindings
540 in stmt.c; see detailed documentation there. */
541 #ifdef HAVE_nonlocal_goto
542 if (! HAVE_nonlocal_goto
)
544 emit_move_insn (virtual_stack_vars_rtx
, hard_frame_pointer_rtx
);
546 #if ARG_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
547 if (fixed_regs
[ARG_POINTER_REGNUM
])
549 #ifdef ELIMINABLE_REGS
551 static const struct elims
{const int from
, to
;} elim_regs
[] = ELIMINABLE_REGS
;
553 for (i
= 0; i
< ARRAY_SIZE (elim_regs
); i
++)
554 if (elim_regs
[i
].from
== ARG_POINTER_REGNUM
555 && elim_regs
[i
].to
== HARD_FRAME_POINTER_REGNUM
)
558 if (i
== ARRAY_SIZE (elim_regs
))
561 /* Now restore our arg pointer from the address at which it
562 was saved in our stack frame. */
563 emit_move_insn (virtual_incoming_args_rtx
,
564 copy_to_reg (get_arg_pointer_save_area (cfun
)));
569 #ifdef HAVE_builtin_setjmp_receiver
570 if (HAVE_builtin_setjmp_receiver
)
571 emit_insn (gen_builtin_setjmp_receiver (receiver_label
));
574 #ifdef HAVE_nonlocal_goto_receiver
575 if (HAVE_nonlocal_goto_receiver
)
576 emit_insn (gen_nonlocal_goto_receiver ());
581 /* @@@ This is a kludge. Not all machine descriptions define a blockage
582 insn, but we must not allow the code we just generated to be reordered
583 by scheduling. Specifically, the update of the frame pointer must
584 happen immediately, not later. So emit an ASM_INPUT to act as blockage
586 emit_insn (gen_rtx_ASM_INPUT (VOIDmode
, ""));
589 /* __builtin_setjmp is passed a pointer to an array of five words (not
590 all will be used on all machines). It operates similarly to the C
591 library function of the same name, but is more efficient. Much of
592 the code below (and for longjmp) is copied from the handling of
595 NOTE: This is intended for use by GNAT and the exception handling
596 scheme in the compiler and will only work in the method used by
600 expand_builtin_setjmp (arglist
, target
)
604 rtx buf_addr
, next_lab
, cont_lab
;
606 if (!validate_arglist (arglist
, POINTER_TYPE
, VOID_TYPE
))
609 if (target
== 0 || GET_CODE (target
) != REG
610 || REGNO (target
) < FIRST_PSEUDO_REGISTER
)
611 target
= gen_reg_rtx (TYPE_MODE (integer_type_node
));
613 buf_addr
= expand_expr (TREE_VALUE (arglist
), NULL_RTX
, VOIDmode
, 0);
615 next_lab
= gen_label_rtx ();
616 cont_lab
= gen_label_rtx ();
618 expand_builtin_setjmp_setup (buf_addr
, next_lab
);
620 /* Set TARGET to zero and branch to the continue label. */
621 emit_move_insn (target
, const0_rtx
);
622 emit_jump_insn (gen_jump (cont_lab
));
624 emit_label (next_lab
);
626 expand_builtin_setjmp_receiver (next_lab
);
628 /* Set TARGET to one. */
629 emit_move_insn (target
, const1_rtx
);
630 emit_label (cont_lab
);
632 /* Tell flow about the strange goings on. Putting `next_lab' on
633 `nonlocal_goto_handler_labels' to indicates that function
634 calls may traverse the arc back to this label. */
636 current_function_has_nonlocal_label
= 1;
637 nonlocal_goto_handler_labels
638 = gen_rtx_EXPR_LIST (VOIDmode
, next_lab
, nonlocal_goto_handler_labels
);
643 /* __builtin_longjmp is passed a pointer to an array of five words (not
644 all will be used on all machines). It operates similarly to the C
645 library function of the same name, but is more efficient. Much of
646 the code below is copied from the handling of non-local gotos.
648 NOTE: This is intended for use by GNAT and the exception handling
649 scheme in the compiler and will only work in the method used by
653 expand_builtin_longjmp (buf_addr
, value
)
656 rtx fp
, lab
, stack
, insn
, last
;
657 enum machine_mode sa_mode
= STACK_SAVEAREA_MODE (SAVE_NONLOCAL
);
659 if (setjmp_alias_set
== -1)
660 setjmp_alias_set
= new_alias_set ();
662 #ifdef POINTERS_EXTEND_UNSIGNED
663 if (GET_MODE (buf_addr
) != Pmode
)
664 buf_addr
= convert_memory_address (Pmode
, buf_addr
);
667 buf_addr
= force_reg (Pmode
, buf_addr
);
669 /* We used to store value in static_chain_rtx, but that fails if pointers
670 are smaller than integers. We instead require that the user must pass
671 a second argument of 1, because that is what builtin_setjmp will
672 return. This also makes EH slightly more efficient, since we are no
673 longer copying around a value that we don't care about. */
674 if (value
!= const1_rtx
)
677 current_function_calls_longjmp
= 1;
679 last
= get_last_insn ();
680 #ifdef HAVE_builtin_longjmp
681 if (HAVE_builtin_longjmp
)
682 emit_insn (gen_builtin_longjmp (buf_addr
));
686 fp
= gen_rtx_MEM (Pmode
, buf_addr
);
687 lab
= gen_rtx_MEM (Pmode
, plus_constant (buf_addr
,
688 GET_MODE_SIZE (Pmode
)));
690 stack
= gen_rtx_MEM (sa_mode
, plus_constant (buf_addr
,
691 2 * GET_MODE_SIZE (Pmode
)));
692 set_mem_alias_set (fp
, setjmp_alias_set
);
693 set_mem_alias_set (lab
, setjmp_alias_set
);
694 set_mem_alias_set (stack
, setjmp_alias_set
);
696 /* Pick up FP, label, and SP from the block and jump. This code is
697 from expand_goto in stmt.c; see there for detailed comments. */
698 #if HAVE_nonlocal_goto
699 if (HAVE_nonlocal_goto
)
700 /* We have to pass a value to the nonlocal_goto pattern that will
701 get copied into the static_chain pointer, but it does not matter
702 what that value is, because builtin_setjmp does not use it. */
703 emit_insn (gen_nonlocal_goto (value
, lab
, stack
, fp
));
707 lab
= copy_to_reg (lab
);
709 emit_move_insn (hard_frame_pointer_rtx
, fp
);
710 emit_stack_restore (SAVE_NONLOCAL
, stack
, NULL_RTX
);
712 emit_insn (gen_rtx_USE (VOIDmode
, hard_frame_pointer_rtx
));
713 emit_insn (gen_rtx_USE (VOIDmode
, stack_pointer_rtx
));
714 emit_indirect_jump (lab
);
718 /* Search backwards and mark the jump insn as a non-local goto.
719 Note that this precludes the use of __builtin_longjmp to a
720 __builtin_setjmp target in the same function. However, we've
721 already cautioned the user that these functions are for
722 internal exception handling use only. */
723 for (insn
= get_last_insn (); insn
; insn
= PREV_INSN (insn
))
727 if (GET_CODE (insn
) == JUMP_INSN
)
729 REG_NOTES (insn
) = alloc_EXPR_LIST (REG_NON_LOCAL_GOTO
, const0_rtx
,
733 else if (GET_CODE (insn
) == CALL_INSN
)
738 /* Expand a call to __builtin_prefetch. For a target that does not support
739 data prefetch, evaluate the memory address argument in case it has side
743 expand_builtin_prefetch (arglist
)
746 tree arg0
, arg1
, arg2
;
749 if (!validate_arglist (arglist
, POINTER_TYPE
, 0))
752 arg0
= TREE_VALUE (arglist
);
753 /* Arguments 1 and 2 are optional; argument 1 (read/write) defaults to
754 zero (read) and argument 2 (locality) defaults to 3 (high degree of
756 if (TREE_CHAIN (arglist
))
758 arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
759 if (TREE_CHAIN (TREE_CHAIN (arglist
)))
760 arg2
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
762 arg2
= build_int_2 (3, 0);
766 arg1
= integer_zero_node
;
767 arg2
= build_int_2 (3, 0);
770 /* Argument 0 is an address. */
771 op0
= expand_expr (arg0
, NULL_RTX
, Pmode
, EXPAND_NORMAL
);
773 /* Argument 1 (read/write flag) must be a compile-time constant int. */
774 if (TREE_CODE (arg1
) != INTEGER_CST
)
776 error ("second arg to `__builtin_prefetch' must be a constant");
777 arg1
= integer_zero_node
;
779 op1
= expand_expr (arg1
, NULL_RTX
, VOIDmode
, 0);
780 /* Argument 1 must be either zero or one. */
781 if (INTVAL (op1
) != 0 && INTVAL (op1
) != 1)
783 warning ("invalid second arg to __builtin_prefetch; using zero");
787 /* Argument 2 (locality) must be a compile-time constant int. */
788 if (TREE_CODE (arg2
) != INTEGER_CST
)
790 error ("third arg to `__builtin_prefetch' must be a constant");
791 arg2
= integer_zero_node
;
793 op2
= expand_expr (arg2
, NULL_RTX
, VOIDmode
, 0);
794 /* Argument 2 must be 0, 1, 2, or 3. */
795 if (INTVAL (op2
) < 0 || INTVAL (op2
) > 3)
797 warning ("invalid third arg to __builtin_prefetch; using zero");
804 if ((! (*insn_data
[(int) CODE_FOR_prefetch
].operand
[0].predicate
)
806 insn_data
[(int) CODE_FOR_prefetch
].operand
[0].mode
))
807 || (GET_MODE(op0
) != Pmode
))
809 #ifdef POINTERS_EXTEND_UNSIGNED
810 if (GET_MODE(op0
) != Pmode
)
811 op0
= convert_memory_address (Pmode
, op0
);
813 op0
= force_reg (Pmode
, op0
);
815 emit_insn (gen_prefetch (op0
, op1
, op2
));
819 op0
= protect_from_queue (op0
, 0);
820 /* Don't do anything with direct references to volatile memory, but
821 generate code to handle other side effects. */
822 if (GET_CODE (op0
) != MEM
&& side_effects_p (op0
))
826 /* Get a MEM rtx for expression EXP which is the address of an operand
827 to be used to be used in a string instruction (cmpstrsi, movstrsi, ..). */
833 rtx addr
= expand_expr (exp
, NULL_RTX
, ptr_mode
, EXPAND_SUM
);
836 #ifdef POINTERS_EXTEND_UNSIGNED
837 if (GET_MODE (addr
) != Pmode
)
838 addr
= convert_memory_address (Pmode
, addr
);
841 mem
= gen_rtx_MEM (BLKmode
, memory_address (BLKmode
, addr
));
843 /* Get an expression we can use to find the attributes to assign to MEM.
844 If it is an ADDR_EXPR, use the operand. Otherwise, dereference it if
845 we can. First remove any nops. */
846 while ((TREE_CODE (exp
) == NOP_EXPR
|| TREE_CODE (exp
) == CONVERT_EXPR
847 || TREE_CODE (exp
) == NON_LVALUE_EXPR
)
848 && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (exp
, 0))))
849 exp
= TREE_OPERAND (exp
, 0);
851 if (TREE_CODE (exp
) == ADDR_EXPR
)
853 exp
= TREE_OPERAND (exp
, 0);
854 set_mem_attributes (mem
, exp
, 0);
856 else if (POINTER_TYPE_P (TREE_TYPE (exp
)))
858 exp
= build1 (INDIRECT_REF
, TREE_TYPE (TREE_TYPE (exp
)), exp
);
859 /* memcpy, memset and other builtin stringops can alias with anything. */
860 set_mem_alias_set (mem
, 0);
866 /* Built-in functions to perform an untyped call and return. */
868 /* For each register that may be used for calling a function, this
869 gives a mode used to copy the register's value. VOIDmode indicates
870 the register is not used for calling a function. If the machine
871 has register windows, this gives only the outbound registers.
872 INCOMING_REGNO gives the corresponding inbound register. */
873 static enum machine_mode apply_args_mode
[FIRST_PSEUDO_REGISTER
];
875 /* For each register that may be used for returning values, this gives
876 a mode used to copy the register's value. VOIDmode indicates the
877 register is not used for returning values. If the machine has
878 register windows, this gives only the outbound registers.
879 INCOMING_REGNO gives the corresponding inbound register. */
880 static enum machine_mode apply_result_mode
[FIRST_PSEUDO_REGISTER
];
882 /* For each register that may be used for calling a function, this
883 gives the offset of that register into the block returned by
884 __builtin_apply_args. 0 indicates that the register is not
885 used for calling a function. */
886 static int apply_args_reg_offset
[FIRST_PSEUDO_REGISTER
];
888 /* Return the offset of register REGNO into the block returned by
889 __builtin_apply_args. This is not declared static, since it is
890 needed in objc-act.c. */
893 apply_args_register_offset (regno
)
898 /* Arguments are always put in outgoing registers (in the argument
899 block) if such make sense. */
900 #ifdef OUTGOING_REGNO
901 regno
= OUTGOING_REGNO (regno
);
903 return apply_args_reg_offset
[regno
];
906 /* Return the size required for the block returned by __builtin_apply_args,
907 and initialize apply_args_mode. */
912 static int size
= -1;
915 enum machine_mode mode
;
917 /* The values computed by this function never change. */
920 /* The first value is the incoming arg-pointer. */
921 size
= GET_MODE_SIZE (Pmode
);
923 /* The second value is the structure value address unless this is
924 passed as an "invisible" first argument. */
925 if (struct_value_rtx
)
926 size
+= GET_MODE_SIZE (Pmode
);
928 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
929 if (FUNCTION_ARG_REGNO_P (regno
))
931 /* Search for the proper mode for copying this register's
932 value. I'm not sure this is right, but it works so far. */
933 enum machine_mode best_mode
= VOIDmode
;
935 for (mode
= GET_CLASS_NARROWEST_MODE (MODE_INT
);
937 mode
= GET_MODE_WIDER_MODE (mode
))
938 if (HARD_REGNO_MODE_OK (regno
, mode
)
939 && HARD_REGNO_NREGS (regno
, mode
) == 1)
942 if (best_mode
== VOIDmode
)
943 for (mode
= GET_CLASS_NARROWEST_MODE (MODE_FLOAT
);
945 mode
= GET_MODE_WIDER_MODE (mode
))
946 if (HARD_REGNO_MODE_OK (regno
, mode
)
947 && have_insn_for (SET
, mode
))
950 if (best_mode
== VOIDmode
)
951 for (mode
= GET_CLASS_NARROWEST_MODE (MODE_VECTOR_FLOAT
);
953 mode
= GET_MODE_WIDER_MODE (mode
))
954 if (HARD_REGNO_MODE_OK (regno
, mode
)
955 && have_insn_for (SET
, mode
))
958 if (best_mode
== VOIDmode
)
959 for (mode
= GET_CLASS_NARROWEST_MODE (MODE_VECTOR_INT
);
961 mode
= GET_MODE_WIDER_MODE (mode
))
962 if (HARD_REGNO_MODE_OK (regno
, mode
)
963 && have_insn_for (SET
, mode
))
967 if (mode
== VOIDmode
)
970 align
= GET_MODE_ALIGNMENT (mode
) / BITS_PER_UNIT
;
971 if (size
% align
!= 0)
972 size
= CEIL (size
, align
) * align
;
973 apply_args_reg_offset
[regno
] = size
;
974 size
+= GET_MODE_SIZE (mode
);
975 apply_args_mode
[regno
] = mode
;
979 apply_args_mode
[regno
] = VOIDmode
;
980 apply_args_reg_offset
[regno
] = 0;
986 /* Return the size required for the block returned by __builtin_apply,
987 and initialize apply_result_mode. */
992 static int size
= -1;
994 enum machine_mode mode
;
996 /* The values computed by this function never change. */
1001 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
1002 if (FUNCTION_VALUE_REGNO_P (regno
))
1004 /* Search for the proper mode for copying this register's
1005 value. I'm not sure this is right, but it works so far. */
1006 enum machine_mode best_mode
= VOIDmode
;
1008 for (mode
= GET_CLASS_NARROWEST_MODE (MODE_INT
);
1010 mode
= GET_MODE_WIDER_MODE (mode
))
1011 if (HARD_REGNO_MODE_OK (regno
, mode
))
1014 if (best_mode
== VOIDmode
)
1015 for (mode
= GET_CLASS_NARROWEST_MODE (MODE_FLOAT
);
1017 mode
= GET_MODE_WIDER_MODE (mode
))
1018 if (HARD_REGNO_MODE_OK (regno
, mode
)
1019 && have_insn_for (SET
, mode
))
1022 if (best_mode
== VOIDmode
)
1023 for (mode
= GET_CLASS_NARROWEST_MODE (MODE_VECTOR_FLOAT
);
1025 mode
= GET_MODE_WIDER_MODE (mode
))
1026 if (HARD_REGNO_MODE_OK (regno
, mode
)
1027 && have_insn_for (SET
, mode
))
1030 if (best_mode
== VOIDmode
)
1031 for (mode
= GET_CLASS_NARROWEST_MODE (MODE_VECTOR_INT
);
1033 mode
= GET_MODE_WIDER_MODE (mode
))
1034 if (HARD_REGNO_MODE_OK (regno
, mode
)
1035 && have_insn_for (SET
, mode
))
1039 if (mode
== VOIDmode
)
1042 align
= GET_MODE_ALIGNMENT (mode
) / BITS_PER_UNIT
;
1043 if (size
% align
!= 0)
1044 size
= CEIL (size
, align
) * align
;
1045 size
+= GET_MODE_SIZE (mode
);
1046 apply_result_mode
[regno
] = mode
;
1049 apply_result_mode
[regno
] = VOIDmode
;
1051 /* Allow targets that use untyped_call and untyped_return to override
1052 the size so that machine-specific information can be stored here. */
1053 #ifdef APPLY_RESULT_SIZE
1054 size
= APPLY_RESULT_SIZE
;
1060 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
1061 /* Create a vector describing the result block RESULT. If SAVEP is true,
1062 the result block is used to save the values; otherwise it is used to
1063 restore the values. */
1066 result_vector (savep
, result
)
1070 int regno
, size
, align
, nelts
;
1071 enum machine_mode mode
;
1073 rtx
*savevec
= (rtx
*) alloca (FIRST_PSEUDO_REGISTER
* sizeof (rtx
));
1076 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
1077 if ((mode
= apply_result_mode
[regno
]) != VOIDmode
)
1079 align
= GET_MODE_ALIGNMENT (mode
) / BITS_PER_UNIT
;
1080 if (size
% align
!= 0)
1081 size
= CEIL (size
, align
) * align
;
1082 reg
= gen_rtx_REG (mode
, savep
? regno
: INCOMING_REGNO (regno
));
1083 mem
= adjust_address (result
, mode
, size
);
1084 savevec
[nelts
++] = (savep
1085 ? gen_rtx_SET (VOIDmode
, mem
, reg
)
1086 : gen_rtx_SET (VOIDmode
, reg
, mem
));
1087 size
+= GET_MODE_SIZE (mode
);
1089 return gen_rtx_PARALLEL (VOIDmode
, gen_rtvec_v (nelts
, savevec
));
1091 #endif /* HAVE_untyped_call or HAVE_untyped_return */
1093 /* Save the state required to perform an untyped call with the same
1094 arguments as were passed to the current function. */
1097 expand_builtin_apply_args_1 ()
1100 int size
, align
, regno
;
1101 enum machine_mode mode
;
1103 /* Create a block where the arg-pointer, structure value address,
1104 and argument registers can be saved. */
1105 registers
= assign_stack_local (BLKmode
, apply_args_size (), -1);
1107 /* Walk past the arg-pointer and structure value address. */
1108 size
= GET_MODE_SIZE (Pmode
);
1109 if (struct_value_rtx
)
1110 size
+= GET_MODE_SIZE (Pmode
);
1112 /* Save each register used in calling a function to the block. */
1113 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
1114 if ((mode
= apply_args_mode
[regno
]) != VOIDmode
)
1118 align
= GET_MODE_ALIGNMENT (mode
) / BITS_PER_UNIT
;
1119 if (size
% align
!= 0)
1120 size
= CEIL (size
, align
) * align
;
1122 tem
= gen_rtx_REG (mode
, INCOMING_REGNO (regno
));
1124 emit_move_insn (adjust_address (registers
, mode
, size
), tem
);
1125 size
+= GET_MODE_SIZE (mode
);
1128 /* Save the arg pointer to the block. */
1129 emit_move_insn (adjust_address (registers
, Pmode
, 0),
1130 copy_to_reg (virtual_incoming_args_rtx
));
1131 size
= GET_MODE_SIZE (Pmode
);
1133 /* Save the structure value address unless this is passed as an
1134 "invisible" first argument. */
1135 if (struct_value_incoming_rtx
)
1137 emit_move_insn (adjust_address (registers
, Pmode
, size
),
1138 copy_to_reg (struct_value_incoming_rtx
));
1139 size
+= GET_MODE_SIZE (Pmode
);
1142 /* Return the address of the block. */
1143 return copy_addr_to_reg (XEXP (registers
, 0));
1146 /* __builtin_apply_args returns block of memory allocated on
1147 the stack into which is stored the arg pointer, structure
1148 value address, static chain, and all the registers that might
1149 possibly be used in performing a function call. The code is
1150 moved to the start of the function so the incoming values are
1154 expand_builtin_apply_args ()
1156 /* Don't do __builtin_apply_args more than once in a function.
1157 Save the result of the first call and reuse it. */
1158 if (apply_args_value
!= 0)
1159 return apply_args_value
;
1161 /* When this function is called, it means that registers must be
1162 saved on entry to this function. So we migrate the
1163 call to the first insn of this function. */
1168 temp
= expand_builtin_apply_args_1 ();
1172 apply_args_value
= temp
;
1174 /* Put the insns after the NOTE that starts the function.
1175 If this is inside a start_sequence, make the outer-level insn
1176 chain current, so the code is placed at the start of the
1178 push_topmost_sequence ();
1179 emit_insn_before (seq
, NEXT_INSN (get_insns ()));
1180 pop_topmost_sequence ();
1185 /* Perform an untyped call and save the state required to perform an
1186 untyped return of whatever value was returned by the given function. */
1189 expand_builtin_apply (function
, arguments
, argsize
)
1190 rtx function
, arguments
, argsize
;
1192 int size
, align
, regno
;
1193 enum machine_mode mode
;
1194 rtx incoming_args
, result
, reg
, dest
, src
, call_insn
;
1195 rtx old_stack_level
= 0;
1196 rtx call_fusage
= 0;
1198 #ifdef POINTERS_EXTEND_UNSIGNED
1199 if (GET_MODE (arguments
) != Pmode
)
1200 arguments
= convert_memory_address (Pmode
, arguments
);
1203 /* Create a block where the return registers can be saved. */
1204 result
= assign_stack_local (BLKmode
, apply_result_size (), -1);
1206 /* Fetch the arg pointer from the ARGUMENTS block. */
1207 incoming_args
= gen_reg_rtx (Pmode
);
1208 emit_move_insn (incoming_args
, gen_rtx_MEM (Pmode
, arguments
));
1209 #ifndef STACK_GROWS_DOWNWARD
1210 incoming_args
= expand_simple_binop (Pmode
, MINUS
, incoming_args
, argsize
,
1211 incoming_args
, 0, OPTAB_LIB_WIDEN
);
1214 /* Perform postincrements before actually calling the function. */
1217 /* Push a new argument block and copy the arguments. Do not allow
1218 the (potential) memcpy call below to interfere with our stack
1220 do_pending_stack_adjust ();
1223 /* Save the stack with nonlocal if available */
1224 #ifdef HAVE_save_stack_nonlocal
1225 if (HAVE_save_stack_nonlocal
)
1226 emit_stack_save (SAVE_NONLOCAL
, &old_stack_level
, NULL_RTX
);
1229 emit_stack_save (SAVE_BLOCK
, &old_stack_level
, NULL_RTX
);
1231 /* Push a block of memory onto the stack to store the memory arguments.
1232 Save the address in a register, and copy the memory arguments. ??? I
1233 haven't figured out how the calling convention macros effect this,
1234 but it's likely that the source and/or destination addresses in
1235 the block copy will need updating in machine specific ways. */
1236 dest
= allocate_dynamic_stack_space (argsize
, 0, BITS_PER_UNIT
);
1237 dest
= gen_rtx_MEM (BLKmode
, dest
);
1238 set_mem_align (dest
, PARM_BOUNDARY
);
1239 src
= gen_rtx_MEM (BLKmode
, incoming_args
);
1240 set_mem_align (src
, PARM_BOUNDARY
);
1241 emit_block_move (dest
, src
, argsize
, BLOCK_OP_NORMAL
);
1243 /* Refer to the argument block. */
1245 arguments
= gen_rtx_MEM (BLKmode
, arguments
);
1246 set_mem_align (arguments
, PARM_BOUNDARY
);
1248 /* Walk past the arg-pointer and structure value address. */
1249 size
= GET_MODE_SIZE (Pmode
);
1250 if (struct_value_rtx
)
1251 size
+= GET_MODE_SIZE (Pmode
);
1253 /* Restore each of the registers previously saved. Make USE insns
1254 for each of these registers for use in making the call. */
1255 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
1256 if ((mode
= apply_args_mode
[regno
]) != VOIDmode
)
1258 align
= GET_MODE_ALIGNMENT (mode
) / BITS_PER_UNIT
;
1259 if (size
% align
!= 0)
1260 size
= CEIL (size
, align
) * align
;
1261 reg
= gen_rtx_REG (mode
, regno
);
1262 emit_move_insn (reg
, adjust_address (arguments
, mode
, size
));
1263 use_reg (&call_fusage
, reg
);
1264 size
+= GET_MODE_SIZE (mode
);
1267 /* Restore the structure value address unless this is passed as an
1268 "invisible" first argument. */
1269 size
= GET_MODE_SIZE (Pmode
);
1270 if (struct_value_rtx
)
1272 rtx value
= gen_reg_rtx (Pmode
);
1273 emit_move_insn (value
, adjust_address (arguments
, Pmode
, size
));
1274 emit_move_insn (struct_value_rtx
, value
);
1275 if (GET_CODE (struct_value_rtx
) == REG
)
1276 use_reg (&call_fusage
, struct_value_rtx
);
1277 size
+= GET_MODE_SIZE (Pmode
);
1280 /* All arguments and registers used for the call are set up by now! */
1281 function
= prepare_call_address (function
, NULL_TREE
, &call_fusage
, 0, 0);
1283 /* Ensure address is valid. SYMBOL_REF is already valid, so no need,
1284 and we don't want to load it into a register as an optimization,
1285 because prepare_call_address already did it if it should be done. */
1286 if (GET_CODE (function
) != SYMBOL_REF
)
1287 function
= memory_address (FUNCTION_MODE
, function
);
1289 /* Generate the actual call instruction and save the return value. */
1290 #ifdef HAVE_untyped_call
1291 if (HAVE_untyped_call
)
1292 emit_call_insn (gen_untyped_call (gen_rtx_MEM (FUNCTION_MODE
, function
),
1293 result
, result_vector (1, result
)));
1296 #ifdef HAVE_call_value
1297 if (HAVE_call_value
)
1301 /* Locate the unique return register. It is not possible to
1302 express a call that sets more than one return register using
1303 call_value; use untyped_call for that. In fact, untyped_call
1304 only needs to save the return registers in the given block. */
1305 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
1306 if ((mode
= apply_result_mode
[regno
]) != VOIDmode
)
1309 abort (); /* HAVE_untyped_call required. */
1310 valreg
= gen_rtx_REG (mode
, regno
);
1313 emit_call_insn (GEN_CALL_VALUE (valreg
,
1314 gen_rtx_MEM (FUNCTION_MODE
, function
),
1315 const0_rtx
, NULL_RTX
, const0_rtx
));
1317 emit_move_insn (adjust_address (result
, GET_MODE (valreg
), 0), valreg
);
1323 /* Find the CALL insn we just emitted. */
1324 for (call_insn
= get_last_insn ();
1325 call_insn
&& GET_CODE (call_insn
) != CALL_INSN
;
1326 call_insn
= PREV_INSN (call_insn
))
1332 /* Put the register usage information on the CALL. If there is already
1333 some usage information, put ours at the end. */
1334 if (CALL_INSN_FUNCTION_USAGE (call_insn
))
1338 for (link
= CALL_INSN_FUNCTION_USAGE (call_insn
); XEXP (link
, 1) != 0;
1339 link
= XEXP (link
, 1))
1342 XEXP (link
, 1) = call_fusage
;
1345 CALL_INSN_FUNCTION_USAGE (call_insn
) = call_fusage
;
1347 /* Restore the stack. */
1348 #ifdef HAVE_save_stack_nonlocal
1349 if (HAVE_save_stack_nonlocal
)
1350 emit_stack_restore (SAVE_NONLOCAL
, old_stack_level
, NULL_RTX
);
1353 emit_stack_restore (SAVE_BLOCK
, old_stack_level
, NULL_RTX
);
1357 /* Return the address of the result block. */
1358 return copy_addr_to_reg (XEXP (result
, 0));
1361 /* Perform an untyped return. */
1364 expand_builtin_return (result
)
1367 int size
, align
, regno
;
1368 enum machine_mode mode
;
1370 rtx call_fusage
= 0;
1372 #ifdef POINTERS_EXTEND_UNSIGNED
1373 if (GET_MODE (result
) != Pmode
)
1374 result
= convert_memory_address (Pmode
, result
);
1377 apply_result_size ();
1378 result
= gen_rtx_MEM (BLKmode
, result
);
1380 #ifdef HAVE_untyped_return
1381 if (HAVE_untyped_return
)
1383 emit_jump_insn (gen_untyped_return (result
, result_vector (0, result
)));
1389 /* Restore the return value and note that each value is used. */
1391 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
1392 if ((mode
= apply_result_mode
[regno
]) != VOIDmode
)
1394 align
= GET_MODE_ALIGNMENT (mode
) / BITS_PER_UNIT
;
1395 if (size
% align
!= 0)
1396 size
= CEIL (size
, align
) * align
;
1397 reg
= gen_rtx_REG (mode
, INCOMING_REGNO (regno
));
1398 emit_move_insn (reg
, adjust_address (result
, mode
, size
));
1400 push_to_sequence (call_fusage
);
1401 emit_insn (gen_rtx_USE (VOIDmode
, reg
));
1402 call_fusage
= get_insns ();
1404 size
+= GET_MODE_SIZE (mode
);
1407 /* Put the USE insns before the return. */
1408 emit_insn (call_fusage
);
1410 /* Return whatever values was restored by jumping directly to the end
1412 expand_null_return ();
1415 /* Used by expand_builtin_classify_type and fold_builtin_classify_type. */
1417 static enum type_class
1418 type_to_class (type
)
1421 switch (TREE_CODE (type
))
1423 case VOID_TYPE
: return void_type_class
;
1424 case INTEGER_TYPE
: return integer_type_class
;
1425 case CHAR_TYPE
: return char_type_class
;
1426 case ENUMERAL_TYPE
: return enumeral_type_class
;
1427 case BOOLEAN_TYPE
: return boolean_type_class
;
1428 case POINTER_TYPE
: return pointer_type_class
;
1429 case REFERENCE_TYPE
: return reference_type_class
;
1430 case OFFSET_TYPE
: return offset_type_class
;
1431 case REAL_TYPE
: return real_type_class
;
1432 case COMPLEX_TYPE
: return complex_type_class
;
1433 case FUNCTION_TYPE
: return function_type_class
;
1434 case METHOD_TYPE
: return method_type_class
;
1435 case RECORD_TYPE
: return record_type_class
;
1437 case QUAL_UNION_TYPE
: return union_type_class
;
1438 case ARRAY_TYPE
: return (TYPE_STRING_FLAG (type
)
1439 ? string_type_class
: array_type_class
);
1440 case SET_TYPE
: return set_type_class
;
1441 case FILE_TYPE
: return file_type_class
;
1442 case LANG_TYPE
: return lang_type_class
;
1443 default: return no_type_class
;
1447 /* Expand a call to __builtin_classify_type with arguments found in
1451 expand_builtin_classify_type (arglist
)
1455 return GEN_INT (type_to_class (TREE_TYPE (TREE_VALUE (arglist
))));
1456 return GEN_INT (no_type_class
);
1459 /* Expand expression EXP, which is a call to __builtin_constant_p. */
1462 expand_builtin_constant_p (exp
)
1465 tree arglist
= TREE_OPERAND (exp
, 1);
1466 enum machine_mode value_mode
= TYPE_MODE (TREE_TYPE (exp
));
1471 arglist
= TREE_VALUE (arglist
);
1473 /* We have taken care of the easy cases during constant folding. This
1474 case is not obvious, so emit (constant_p_rtx (ARGLIST)) and let CSE
1475 get a chance to see if it can deduce whether ARGLIST is constant. */
1477 current_function_calls_constant_p
= 1;
1479 tmp
= expand_expr (arglist
, NULL_RTX
, VOIDmode
, 0);
1480 tmp
= gen_rtx_CONSTANT_P_RTX (value_mode
, tmp
);
1484 /* Return mathematic function equivalent to FN but operating directly on TYPE,
1487 mathfn_built_in (type
, fn
)
1489 enum built_in_function fn
;
1491 enum built_in_function fcode
= NOT_BUILT_IN
;
1492 if (TYPE_MODE (type
) == TYPE_MODE (double_type_node
))
1496 case BUILT_IN_SQRTF
:
1497 case BUILT_IN_SQRTL
:
1498 fcode
= BUILT_IN_SQRT
;
1503 fcode
= BUILT_IN_SIN
;
1508 fcode
= BUILT_IN_COS
;
1513 fcode
= BUILT_IN_EXP
;
1518 fcode
= BUILT_IN_LOG
;
1520 case BUILT_IN_FLOOR
:
1521 case BUILT_IN_FLOORF
:
1522 case BUILT_IN_FLOORL
:
1523 fcode
= BUILT_IN_FLOOR
;
1526 case BUILT_IN_CEILF
:
1527 case BUILT_IN_CEILL
:
1528 fcode
= BUILT_IN_CEIL
;
1530 case BUILT_IN_TRUNC
:
1531 case BUILT_IN_TRUNCF
:
1532 case BUILT_IN_TRUNCL
:
1533 fcode
= BUILT_IN_TRUNC
;
1535 case BUILT_IN_ROUND
:
1536 case BUILT_IN_ROUNDF
:
1537 case BUILT_IN_ROUNDL
:
1538 fcode
= BUILT_IN_ROUND
;
1540 case BUILT_IN_NEARBYINT
:
1541 case BUILT_IN_NEARBYINTF
:
1542 case BUILT_IN_NEARBYINTL
:
1543 fcode
= BUILT_IN_NEARBYINT
;
1548 else if (TYPE_MODE (type
) == TYPE_MODE (float_type_node
))
1552 case BUILT_IN_SQRTF
:
1553 case BUILT_IN_SQRTL
:
1554 fcode
= BUILT_IN_SQRTF
;
1559 fcode
= BUILT_IN_SINF
;
1564 fcode
= BUILT_IN_COSF
;
1569 fcode
= BUILT_IN_EXPF
;
1574 fcode
= BUILT_IN_LOGF
;
1576 case BUILT_IN_FLOOR
:
1577 case BUILT_IN_FLOORF
:
1578 case BUILT_IN_FLOORL
:
1579 fcode
= BUILT_IN_FLOORF
;
1582 case BUILT_IN_CEILF
:
1583 case BUILT_IN_CEILL
:
1584 fcode
= BUILT_IN_CEILF
;
1586 case BUILT_IN_TRUNC
:
1587 case BUILT_IN_TRUNCF
:
1588 case BUILT_IN_TRUNCL
:
1589 fcode
= BUILT_IN_TRUNCF
;
1591 case BUILT_IN_ROUND
:
1592 case BUILT_IN_ROUNDF
:
1593 case BUILT_IN_ROUNDL
:
1594 fcode
= BUILT_IN_ROUNDF
;
1596 case BUILT_IN_NEARBYINT
:
1597 case BUILT_IN_NEARBYINTF
:
1598 case BUILT_IN_NEARBYINTL
:
1599 fcode
= BUILT_IN_NEARBYINTF
;
1604 else if (TYPE_MODE (type
) == TYPE_MODE (long_double_type_node
))
1608 case BUILT_IN_SQRTF
:
1609 case BUILT_IN_SQRTL
:
1610 fcode
= BUILT_IN_SQRTL
;
1615 fcode
= BUILT_IN_SINL
;
1620 fcode
= BUILT_IN_COSL
;
1625 fcode
= BUILT_IN_EXPL
;
1630 fcode
= BUILT_IN_LOGL
;
1632 case BUILT_IN_FLOOR
:
1633 case BUILT_IN_FLOORF
:
1634 case BUILT_IN_FLOORL
:
1635 fcode
= BUILT_IN_FLOORL
;
1638 case BUILT_IN_CEILF
:
1639 case BUILT_IN_CEILL
:
1640 fcode
= BUILT_IN_CEILL
;
1642 case BUILT_IN_TRUNC
:
1643 case BUILT_IN_TRUNCF
:
1644 case BUILT_IN_TRUNCL
:
1645 fcode
= BUILT_IN_TRUNCL
;
1647 case BUILT_IN_ROUND
:
1648 case BUILT_IN_ROUNDF
:
1649 case BUILT_IN_ROUNDL
:
1650 fcode
= BUILT_IN_ROUNDL
;
1652 case BUILT_IN_NEARBYINT
:
1653 case BUILT_IN_NEARBYINTF
:
1654 case BUILT_IN_NEARBYINTL
:
1655 fcode
= BUILT_IN_NEARBYINTL
;
1660 return implicit_built_in_decls
[fcode
];
1663 /* If errno must be maintained, expand the RTL to check if the result,
1664 TARGET, of a built-in function call, EXP, is NaN, and if so set
1668 expand_errno_check (exp
, target
)
1674 if (flag_errno_math
&& HONOR_NANS (GET_MODE (target
)))
1676 lab
= gen_label_rtx ();
1678 /* Test the result; if it is NaN, set errno=EDOM because
1679 the argument was not in the domain. */
1680 emit_cmp_and_jump_insns (target
, target
, EQ
, 0, GET_MODE (target
),
1685 #ifdef GEN_ERRNO_RTX
1686 rtx errno_rtx
= GEN_ERRNO_RTX
;
1689 = gen_rtx_MEM (word_mode
, gen_rtx_SYMBOL_REF (Pmode
, "errno"));
1692 emit_move_insn (errno_rtx
, GEN_INT (TARGET_EDOM
));
1695 /* We can't set errno=EDOM directly; let the library call do it.
1696 Pop the arguments right away in case the call gets deleted. */
1698 expand_call (exp
, target
, 0);
1707 /* Expand a call to one of the builtin math functions (sin, cos, or sqrt).
1708 Return 0 if a normal call should be emitted rather than expanding the
1709 function in-line. EXP is the expression that is a call to the builtin
1710 function; if convenient, the result should be placed in TARGET.
1711 SUBTARGET may be used as the target for computing one of EXP's operands. */
1714 expand_builtin_mathfn (exp
, target
, subtarget
)
1716 rtx target
, subtarget
;
1718 optab builtin_optab
;
1720 tree fndecl
= TREE_OPERAND (TREE_OPERAND (exp
, 0), 0);
1721 tree arglist
= TREE_OPERAND (exp
, 1);
1722 enum machine_mode argmode
;
1723 bool errno_set
= true;
1725 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
1728 /* Stabilize and compute the argument. */
1729 if (TREE_CODE (TREE_VALUE (arglist
)) != VAR_DECL
1730 && TREE_CODE (TREE_VALUE (arglist
)) != PARM_DECL
)
1732 exp
= copy_node (exp
);
1733 TREE_OPERAND (exp
, 1) = arglist
;
1734 /* Wrap the computation of the argument in a SAVE_EXPR. That
1735 way, if we need to expand the argument again (as in the
1736 flag_errno_math case below where we cannot directly set
1737 errno), we will not perform side-effects more than once.
1738 Note that here we're mutating the original EXP as well as the
1739 copy; that's the right thing to do in case the original EXP
1740 is expanded later. */
1741 TREE_VALUE (arglist
) = save_expr (TREE_VALUE (arglist
));
1742 arglist
= copy_node (arglist
);
1744 op0
= expand_expr (TREE_VALUE (arglist
), subtarget
, VOIDmode
, 0);
1746 /* Make a suitable register to place result in. */
1747 target
= gen_reg_rtx (TYPE_MODE (TREE_TYPE (exp
)));
1752 switch (DECL_FUNCTION_CODE (fndecl
))
1757 builtin_optab
= sin_optab
; break;
1761 builtin_optab
= cos_optab
; break;
1763 case BUILT_IN_SQRTF
:
1764 case BUILT_IN_SQRTL
:
1765 builtin_optab
= sqrt_optab
; break;
1769 builtin_optab
= exp_optab
; break;
1773 builtin_optab
= log_optab
; break;
1774 case BUILT_IN_FLOOR
:
1775 case BUILT_IN_FLOORF
:
1776 case BUILT_IN_FLOORL
:
1777 errno_set
= false ; builtin_optab
= floor_optab
; break;
1779 case BUILT_IN_CEILF
:
1780 case BUILT_IN_CEILL
:
1781 errno_set
= false ; builtin_optab
= ceil_optab
; break;
1782 case BUILT_IN_TRUNC
:
1783 case BUILT_IN_TRUNCF
:
1784 case BUILT_IN_TRUNCL
:
1785 errno_set
= false ; builtin_optab
= trunc_optab
; break;
1786 case BUILT_IN_ROUND
:
1787 case BUILT_IN_ROUNDF
:
1788 case BUILT_IN_ROUNDL
:
1789 errno_set
= false ; builtin_optab
= round_optab
; break;
1790 case BUILT_IN_NEARBYINT
:
1791 case BUILT_IN_NEARBYINTF
:
1792 case BUILT_IN_NEARBYINTL
:
1793 errno_set
= false ; builtin_optab
= nearbyint_optab
; break;
1798 /* Compute into TARGET.
1799 Set TARGET to wherever the result comes back. */
1800 argmode
= TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist
)));
1801 target
= expand_unop (argmode
, builtin_optab
, op0
, target
, 0);
1803 /* If we were unable to expand via the builtin, stop the
1804 sequence (without outputting the insns) and return 0, causing
1805 a call to the library function. */
1813 expand_errno_check (exp
, target
);
1815 /* Output the entire sequence. */
1816 insns
= get_insns ();
1823 /* Expand a call to the builtin binary math functions (pow and atan2).
1824 Return 0 if a normal call should be emitted rather than expanding the
1825 function in-line. EXP is the expression that is a call to the builtin
1826 function; if convenient, the result should be placed in TARGET.
1827 SUBTARGET may be used as the target for computing one of EXP's
1831 expand_builtin_mathfn_2 (exp
, target
, subtarget
)
1833 rtx target
, subtarget
;
1835 optab builtin_optab
;
1836 rtx op0
, op1
, insns
;
1837 tree fndecl
= TREE_OPERAND (TREE_OPERAND (exp
, 0), 0);
1838 tree arglist
= TREE_OPERAND (exp
, 1);
1840 enum machine_mode argmode
;
1841 bool errno_set
= true;
1844 if (!validate_arglist (arglist
, REAL_TYPE
, REAL_TYPE
, VOID_TYPE
))
1847 arg0
= TREE_VALUE (arglist
);
1848 arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
1850 /* Stabilize the arguments. */
1851 if (TREE_CODE (arg0
) != VAR_DECL
&& TREE_CODE (arg0
) != PARM_DECL
)
1853 arg0
= save_expr (arg0
);
1854 TREE_VALUE (arglist
) = arg0
;
1857 if (TREE_CODE (arg1
) != VAR_DECL
&& TREE_CODE (arg1
) != PARM_DECL
)
1859 arg1
= save_expr (arg1
);
1860 TREE_VALUE (TREE_CHAIN (arglist
)) = arg1
;
1866 exp
= copy_node (exp
);
1867 arglist
= tree_cons (NULL_TREE
, arg0
,
1868 build_tree_list (NULL_TREE
, arg1
));
1869 TREE_OPERAND (exp
, 1) = arglist
;
1872 op0
= expand_expr (arg0
, subtarget
, VOIDmode
, 0);
1873 op1
= expand_expr (arg1
, 0, VOIDmode
, 0);
1875 /* Make a suitable register to place result in. */
1876 target
= gen_reg_rtx (TYPE_MODE (TREE_TYPE (exp
)));
1881 switch (DECL_FUNCTION_CODE (fndecl
))
1886 builtin_optab
= pow_optab
; break;
1887 case BUILT_IN_ATAN2
:
1888 case BUILT_IN_ATAN2F
:
1889 case BUILT_IN_ATAN2L
:
1890 builtin_optab
= atan2_optab
; break;
1895 /* Compute into TARGET.
1896 Set TARGET to wherever the result comes back. */
1897 argmode
= TYPE_MODE (TREE_TYPE (arg0
));
1898 target
= expand_binop (argmode
, builtin_optab
, op0
, op1
,
1899 target
, 0, OPTAB_DIRECT
);
1901 /* If we were unable to expand via the builtin, stop the
1902 sequence (without outputting the insns) and return 0, causing
1903 a call to the library function. */
1911 expand_errno_check (exp
, target
);
1913 /* Output the entire sequence. */
1914 insns
= get_insns ();
1921 /* Expand expression EXP which is a call to the strlen builtin. Return 0
1922 if we failed the caller should emit a normal call, otherwise
1923 try to get the result in TARGET, if convenient. */
1926 expand_builtin_strlen (exp
, target
)
1930 tree arglist
= TREE_OPERAND (exp
, 1);
1931 enum machine_mode value_mode
= TYPE_MODE (TREE_TYPE (exp
));
1933 if (!validate_arglist (arglist
, POINTER_TYPE
, VOID_TYPE
))
1938 tree len
, src
= TREE_VALUE (arglist
);
1939 rtx result
, src_reg
, char_rtx
, before_strlen
;
1940 enum machine_mode insn_mode
= value_mode
, char_mode
;
1941 enum insn_code icode
= CODE_FOR_nothing
;
1944 /* If the length can be computed at compile-time, return it. */
1945 len
= c_strlen (src
);
1947 return expand_expr (len
, target
, value_mode
, EXPAND_NORMAL
);
1949 align
= get_pointer_alignment (src
, BIGGEST_ALIGNMENT
) / BITS_PER_UNIT
;
1951 /* If SRC is not a pointer type, don't do this operation inline. */
1955 /* Bail out if we can't compute strlen in the right mode. */
1956 while (insn_mode
!= VOIDmode
)
1958 icode
= strlen_optab
->handlers
[(int) insn_mode
].insn_code
;
1959 if (icode
!= CODE_FOR_nothing
)
1962 insn_mode
= GET_MODE_WIDER_MODE (insn_mode
);
1964 if (insn_mode
== VOIDmode
)
1967 /* Make a place to write the result of the instruction. */
1970 && GET_CODE (result
) == REG
1971 && GET_MODE (result
) == insn_mode
1972 && REGNO (result
) >= FIRST_PSEUDO_REGISTER
))
1973 result
= gen_reg_rtx (insn_mode
);
1975 /* Make a place to hold the source address. We will not expand
1976 the actual source until we are sure that the expansion will
1977 not fail -- there are trees that cannot be expanded twice. */
1978 src_reg
= gen_reg_rtx (Pmode
);
1980 /* Mark the beginning of the strlen sequence so we can emit the
1981 source operand later. */
1982 before_strlen
= get_last_insn ();
1984 char_rtx
= const0_rtx
;
1985 char_mode
= insn_data
[(int) icode
].operand
[2].mode
;
1986 if (! (*insn_data
[(int) icode
].operand
[2].predicate
) (char_rtx
,
1988 char_rtx
= copy_to_mode_reg (char_mode
, char_rtx
);
1990 pat
= GEN_FCN (icode
) (result
, gen_rtx_MEM (BLKmode
, src_reg
),
1991 char_rtx
, GEN_INT (align
));
1996 /* Now that we are assured of success, expand the source. */
1998 pat
= memory_address (BLKmode
,
1999 expand_expr (src
, src_reg
, ptr_mode
, EXPAND_SUM
));
2001 emit_move_insn (src_reg
, pat
);
2006 emit_insn_after (pat
, before_strlen
);
2008 emit_insn_before (pat
, get_insns ());
2010 /* Return the value in the proper mode for this function. */
2011 if (GET_MODE (result
) == value_mode
)
2013 else if (target
!= 0)
2014 convert_move (target
, result
, 0);
2016 target
= convert_to_mode (value_mode
, result
, 0);
2022 /* Expand a call to the strstr builtin. Return 0 if we failed the
2023 caller should emit a normal call, otherwise try to get the result
2024 in TARGET, if convenient (and in mode MODE if that's convenient). */
2027 expand_builtin_strstr (arglist
, target
, mode
)
2030 enum machine_mode mode
;
2032 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
2036 tree s1
= TREE_VALUE (arglist
), s2
= TREE_VALUE (TREE_CHAIN (arglist
));
2038 const char *p1
, *p2
;
2047 const char *r
= strstr (p1
, p2
);
2052 /* Return an offset into the constant string argument. */
2053 return expand_expr (fold (build (PLUS_EXPR
, TREE_TYPE (s1
),
2054 s1
, ssize_int (r
- p1
))),
2055 target
, mode
, EXPAND_NORMAL
);
2059 return expand_expr (s1
, target
, mode
, EXPAND_NORMAL
);
2064 fn
= implicit_built_in_decls
[BUILT_IN_STRCHR
];
2068 /* New argument list transforming strstr(s1, s2) to
2069 strchr(s1, s2[0]). */
2071 build_tree_list (NULL_TREE
, build_int_2 (p2
[0], 0));
2072 arglist
= tree_cons (NULL_TREE
, s1
, arglist
);
2073 return expand_expr (build_function_call_expr (fn
, arglist
),
2074 target
, mode
, EXPAND_NORMAL
);
2078 /* Expand a call to the strchr builtin. Return 0 if we failed the
2079 caller should emit a normal call, otherwise try to get the result
2080 in TARGET, if convenient (and in mode MODE if that's convenient). */
2083 expand_builtin_strchr (arglist
, target
, mode
)
2086 enum machine_mode mode
;
2088 if (!validate_arglist (arglist
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
2092 tree s1
= TREE_VALUE (arglist
), s2
= TREE_VALUE (TREE_CHAIN (arglist
));
2095 if (TREE_CODE (s2
) != INTEGER_CST
)
2104 if (target_char_cast (s2
, &c
))
2112 /* Return an offset into the constant string argument. */
2113 return expand_expr (fold (build (PLUS_EXPR
, TREE_TYPE (s1
),
2114 s1
, ssize_int (r
- p1
))),
2115 target
, mode
, EXPAND_NORMAL
);
2118 /* FIXME: Should use here strchrM optab so that ports can optimize
2124 /* Expand a call to the strrchr builtin. Return 0 if we failed the
2125 caller should emit a normal call, otherwise try to get the result
2126 in TARGET, if convenient (and in mode MODE if that's convenient). */
2129 expand_builtin_strrchr (arglist
, target
, mode
)
2132 enum machine_mode mode
;
2134 if (!validate_arglist (arglist
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
2138 tree s1
= TREE_VALUE (arglist
), s2
= TREE_VALUE (TREE_CHAIN (arglist
));
2142 if (TREE_CODE (s2
) != INTEGER_CST
)
2151 if (target_char_cast (s2
, &c
))
2154 r
= strrchr (p1
, c
);
2159 /* Return an offset into the constant string argument. */
2160 return expand_expr (fold (build (PLUS_EXPR
, TREE_TYPE (s1
),
2161 s1
, ssize_int (r
- p1
))),
2162 target
, mode
, EXPAND_NORMAL
);
2165 if (! integer_zerop (s2
))
2168 fn
= implicit_built_in_decls
[BUILT_IN_STRCHR
];
2172 /* Transform strrchr(s1, '\0') to strchr(s1, '\0'). */
2173 return expand_expr (build_function_call_expr (fn
, arglist
),
2174 target
, mode
, EXPAND_NORMAL
);
2178 /* Expand a call to the strpbrk builtin. Return 0 if we failed the
2179 caller should emit a normal call, otherwise try to get the result
2180 in TARGET, if convenient (and in mode MODE if that's convenient). */
2183 expand_builtin_strpbrk (arglist
, target
, mode
)
2186 enum machine_mode mode
;
2188 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
2192 tree s1
= TREE_VALUE (arglist
), s2
= TREE_VALUE (TREE_CHAIN (arglist
));
2194 const char *p1
, *p2
;
2203 const char *r
= strpbrk (p1
, p2
);
2208 /* Return an offset into the constant string argument. */
2209 return expand_expr (fold (build (PLUS_EXPR
, TREE_TYPE (s1
),
2210 s1
, ssize_int (r
- p1
))),
2211 target
, mode
, EXPAND_NORMAL
);
2216 /* strpbrk(x, "") == NULL.
2217 Evaluate and ignore the arguments in case they had
2219 expand_expr (s1
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
2224 return 0; /* Really call strpbrk. */
2226 fn
= implicit_built_in_decls
[BUILT_IN_STRCHR
];
2230 /* New argument list transforming strpbrk(s1, s2) to
2231 strchr(s1, s2[0]). */
2233 build_tree_list (NULL_TREE
, build_int_2 (p2
[0], 0));
2234 arglist
= tree_cons (NULL_TREE
, s1
, arglist
);
2235 return expand_expr (build_function_call_expr (fn
, arglist
),
2236 target
, mode
, EXPAND_NORMAL
);
2240 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
2241 bytes from constant string DATA + OFFSET and return it as target
2245 builtin_memcpy_read_str (data
, offset
, mode
)
2247 HOST_WIDE_INT offset
;
2248 enum machine_mode mode
;
2250 const char *str
= (const char *) data
;
2253 || ((unsigned HOST_WIDE_INT
) offset
+ GET_MODE_SIZE (mode
)
2254 > strlen (str
) + 1))
2255 abort (); /* Attempt to read past the end of constant string. */
2257 return c_readstr (str
+ offset
, mode
);
2260 /* Expand a call to the memcpy builtin, with arguments in ARGLIST.
2261 Return 0 if we failed, the caller should emit a normal call,
2262 otherwise try to get the result in TARGET, if convenient (and in
2263 mode MODE if that's convenient). If ENDP is 0 return the
2264 destination pointer, if ENDP is 1 return the end pointer ala
2265 mempcpy, and if ENDP is 2 return the end pointer minus one ala
2268 expand_builtin_memcpy (arglist
, target
, mode
, endp
)
2271 enum machine_mode mode
;
2274 if (!validate_arglist (arglist
,
2275 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
2279 tree dest
= TREE_VALUE (arglist
);
2280 tree src
= TREE_VALUE (TREE_CHAIN (arglist
));
2281 tree len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
2282 const char *src_str
;
2284 unsigned int src_align
= get_pointer_alignment (src
, BIGGEST_ALIGNMENT
);
2285 unsigned int dest_align
2286 = get_pointer_alignment (dest
, BIGGEST_ALIGNMENT
);
2287 rtx dest_mem
, src_mem
, dest_addr
, len_rtx
;
2289 /* If DEST is not a pointer type, call the normal function. */
2290 if (dest_align
== 0)
2293 /* If the LEN parameter is zero, return DEST. */
2294 if (host_integerp (len
, 1) && tree_low_cst (len
, 1) == 0)
2296 /* Evaluate and ignore SRC in case it has side-effects. */
2297 expand_expr (src
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
2298 return expand_expr (dest
, target
, mode
, EXPAND_NORMAL
);
2301 /* If either SRC is not a pointer type, don't do this
2302 operation in-line. */
2306 dest_mem
= get_memory_rtx (dest
);
2307 set_mem_align (dest_mem
, dest_align
);
2308 len_rtx
= expand_expr (len
, NULL_RTX
, VOIDmode
, 0);
2309 src_str
= c_getstr (src
);
2311 /* If SRC is a string constant and block move would be done
2312 by pieces, we can avoid loading the string from memory
2313 and only stored the computed constants. */
2315 && GET_CODE (len_rtx
) == CONST_INT
2316 && (unsigned HOST_WIDE_INT
) INTVAL (len_rtx
) <= strlen (src_str
) + 1
2317 && can_store_by_pieces (INTVAL (len_rtx
), builtin_memcpy_read_str
,
2318 (PTR
) src_str
, dest_align
))
2320 store_by_pieces (dest_mem
, INTVAL (len_rtx
),
2321 builtin_memcpy_read_str
,
2322 (PTR
) src_str
, dest_align
);
2323 dest_mem
= force_operand (XEXP (dest_mem
, 0), NULL_RTX
);
2324 #ifdef POINTERS_EXTEND_UNSIGNED
2325 if (GET_MODE (dest_mem
) != ptr_mode
)
2326 dest_mem
= convert_memory_address (ptr_mode
, dest_mem
);
2330 rtx result
= gen_rtx_PLUS (GET_MODE (dest_mem
), dest_mem
, len_rtx
);
2332 result
= simplify_gen_binary (MINUS
, GET_MODE (result
), result
, const1_rtx
);
2339 src_mem
= get_memory_rtx (src
);
2340 set_mem_align (src_mem
, src_align
);
2342 /* Copy word part most expediently. */
2343 dest_addr
= emit_block_move (dest_mem
, src_mem
, len_rtx
,
2348 dest_addr
= force_operand (XEXP (dest_mem
, 0), NULL_RTX
);
2349 #ifdef POINTERS_EXTEND_UNSIGNED
2350 if (GET_MODE (dest_addr
) != ptr_mode
)
2351 dest_addr
= convert_memory_address (ptr_mode
, dest_addr
);
2357 rtx result
= gen_rtx_PLUS (GET_MODE (dest_addr
), dest_addr
, len_rtx
);
2359 result
= simplify_gen_binary (MINUS
, GET_MODE (result
), result
, const1_rtx
);
2367 /* Expand expression EXP, which is a call to the strcpy builtin. Return 0
2368 if we failed the caller should emit a normal call, otherwise try to get
2369 the result in TARGET, if convenient (and in mode MODE if that's
2373 expand_builtin_strcpy (exp
, target
, mode
)
2376 enum machine_mode mode
;
2378 tree arglist
= TREE_OPERAND (exp
, 1);
2381 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
2384 fn
= implicit_built_in_decls
[BUILT_IN_MEMCPY
];
2388 len
= c_strlen (TREE_VALUE (TREE_CHAIN (arglist
)));
2392 len
= size_binop (PLUS_EXPR
, len
, ssize_int (1));
2393 chainon (arglist
, build_tree_list (NULL_TREE
, len
));
2394 return expand_expr (build_function_call_expr (fn
, arglist
),
2395 target
, mode
, EXPAND_NORMAL
);
2398 /* Expand a call to the stpcpy builtin, with arguments in ARGLIST.
2399 Return 0 if we failed the caller should emit a normal call,
2400 otherwise try to get the result in TARGET, if convenient (and in
2401 mode MODE if that's convenient). */
2404 expand_builtin_stpcpy (arglist
, target
, mode
)
2407 enum machine_mode mode
;
2409 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
2413 tree len
= c_strlen (TREE_VALUE (TREE_CHAIN (arglist
)));
2417 len
= fold (size_binop (PLUS_EXPR
, len
, ssize_int (1)));
2418 chainon (arglist
, build_tree_list (NULL_TREE
, len
));
2419 return expand_builtin_memcpy (arglist
, target
, mode
, /*endp=*/2);
2423 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
2424 bytes from constant string DATA + OFFSET and return it as target
2428 builtin_strncpy_read_str (data
, offset
, mode
)
2430 HOST_WIDE_INT offset
;
2431 enum machine_mode mode
;
2433 const char *str
= (const char *) data
;
2435 if ((unsigned HOST_WIDE_INT
) offset
> strlen (str
))
2438 return c_readstr (str
+ offset
, mode
);
2441 /* Expand expression EXP, which is a call to the strncpy builtin. Return 0
2442 if we failed the caller should emit a normal call. */
2445 expand_builtin_strncpy (arglist
, target
, mode
)
2448 enum machine_mode mode
;
2450 if (!validate_arglist (arglist
,
2451 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
2455 tree slen
= c_strlen (TREE_VALUE (TREE_CHAIN (arglist
)));
2456 tree len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
2459 /* We must be passed a constant len parameter. */
2460 if (TREE_CODE (len
) != INTEGER_CST
)
2463 /* If the len parameter is zero, return the dst parameter. */
2464 if (integer_zerop (len
))
2466 /* Evaluate and ignore the src argument in case it has
2468 expand_expr (TREE_VALUE (TREE_CHAIN (arglist
)), const0_rtx
,
2469 VOIDmode
, EXPAND_NORMAL
);
2470 /* Return the dst parameter. */
2471 return expand_expr (TREE_VALUE (arglist
), target
, mode
,
2475 /* Now, we must be passed a constant src ptr parameter. */
2476 if (slen
== 0 || TREE_CODE (slen
) != INTEGER_CST
)
2479 slen
= size_binop (PLUS_EXPR
, slen
, ssize_int (1));
2481 /* We're required to pad with trailing zeros if the requested
2482 len is greater than strlen(s2)+1. In that case try to
2483 use store_by_pieces, if it fails, punt. */
2484 if (tree_int_cst_lt (slen
, len
))
2486 tree dest
= TREE_VALUE (arglist
);
2487 unsigned int dest_align
2488 = get_pointer_alignment (dest
, BIGGEST_ALIGNMENT
);
2489 const char *p
= c_getstr (TREE_VALUE (TREE_CHAIN (arglist
)));
2492 if (!p
|| dest_align
== 0 || !host_integerp (len
, 1)
2493 || !can_store_by_pieces (tree_low_cst (len
, 1),
2494 builtin_strncpy_read_str
,
2495 (PTR
) p
, dest_align
))
2498 dest_mem
= get_memory_rtx (dest
);
2499 store_by_pieces (dest_mem
, tree_low_cst (len
, 1),
2500 builtin_strncpy_read_str
,
2501 (PTR
) p
, dest_align
);
2502 dest_mem
= force_operand (XEXP (dest_mem
, 0), NULL_RTX
);
2503 #ifdef POINTERS_EXTEND_UNSIGNED
2504 if (GET_MODE (dest_mem
) != ptr_mode
)
2505 dest_mem
= convert_memory_address (ptr_mode
, dest_mem
);
2510 /* OK transform into builtin memcpy. */
2511 fn
= implicit_built_in_decls
[BUILT_IN_MEMCPY
];
2514 return expand_expr (build_function_call_expr (fn
, arglist
),
2515 target
, mode
, EXPAND_NORMAL
);
2519 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
2520 bytes from constant string DATA + OFFSET and return it as target
2524 builtin_memset_read_str (data
, offset
, mode
)
2526 HOST_WIDE_INT offset ATTRIBUTE_UNUSED
;
2527 enum machine_mode mode
;
2529 const char *c
= (const char *) data
;
2530 char *p
= alloca (GET_MODE_SIZE (mode
));
2532 memset (p
, *c
, GET_MODE_SIZE (mode
));
2534 return c_readstr (p
, mode
);
2537 /* Callback routine for store_by_pieces. Return the RTL of a register
2538 containing GET_MODE_SIZE (MODE) consecutive copies of the unsigned
2539 char value given in the RTL register data. For example, if mode is
2540 4 bytes wide, return the RTL for 0x01010101*data. */
2543 builtin_memset_gen_str (data
, offset
, mode
)
2545 HOST_WIDE_INT offset ATTRIBUTE_UNUSED
;
2546 enum machine_mode mode
;
2552 size
= GET_MODE_SIZE (mode
);
2557 memset (p
, 1, size
);
2558 coeff
= c_readstr (p
, mode
);
2560 target
= convert_to_mode (mode
, (rtx
) data
, 1);
2561 target
= expand_mult (mode
, target
, coeff
, NULL_RTX
, 1);
2562 return force_reg (mode
, target
);
2565 /* Expand expression EXP, which is a call to the memset builtin. Return 0
2566 if we failed the caller should emit a normal call, otherwise try to get
2567 the result in TARGET, if convenient (and in mode MODE if that's
2571 expand_builtin_memset (exp
, target
, mode
)
2574 enum machine_mode mode
;
2576 tree arglist
= TREE_OPERAND (exp
, 1);
2578 if (!validate_arglist (arglist
,
2579 POINTER_TYPE
, INTEGER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
2583 tree dest
= TREE_VALUE (arglist
);
2584 tree val
= TREE_VALUE (TREE_CHAIN (arglist
));
2585 tree len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
2588 unsigned int dest_align
2589 = get_pointer_alignment (dest
, BIGGEST_ALIGNMENT
);
2590 rtx dest_mem
, dest_addr
, len_rtx
;
2592 /* If DEST is not a pointer type, don't do this
2593 operation in-line. */
2594 if (dest_align
== 0)
2597 /* If the LEN parameter is zero, return DEST. */
2598 if (host_integerp (len
, 1) && tree_low_cst (len
, 1) == 0)
2600 /* Evaluate and ignore VAL in case it has side-effects. */
2601 expand_expr (val
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
2602 return expand_expr (dest
, target
, mode
, EXPAND_NORMAL
);
2605 if (TREE_CODE (val
) != INTEGER_CST
)
2609 if (!host_integerp (len
, 1))
2612 if (optimize_size
&& tree_low_cst (len
, 1) > 1)
2615 /* Assume that we can memset by pieces if we can store the
2616 * the coefficients by pieces (in the required modes).
2617 * We can't pass builtin_memset_gen_str as that emits RTL. */
2619 if (!can_store_by_pieces (tree_low_cst (len
, 1),
2620 builtin_memset_read_str
,
2621 (PTR
) &c
, dest_align
))
2624 val
= fold (build1 (CONVERT_EXPR
, unsigned_char_type_node
, val
));
2625 val_rtx
= expand_expr (val
, NULL_RTX
, VOIDmode
, 0);
2626 val_rtx
= force_reg (TYPE_MODE (unsigned_char_type_node
),
2628 dest_mem
= get_memory_rtx (dest
);
2629 store_by_pieces (dest_mem
, tree_low_cst (len
, 1),
2630 builtin_memset_gen_str
,
2631 (PTR
) val_rtx
, dest_align
);
2632 dest_mem
= force_operand (XEXP (dest_mem
, 0), NULL_RTX
);
2633 #ifdef POINTERS_EXTEND_UNSIGNED
2634 if (GET_MODE (dest_mem
) != ptr_mode
)
2635 dest_mem
= convert_memory_address (ptr_mode
, dest_mem
);
2640 if (target_char_cast (val
, &c
))
2645 if (!host_integerp (len
, 1))
2647 if (!can_store_by_pieces (tree_low_cst (len
, 1),
2648 builtin_memset_read_str
, (PTR
) &c
,
2652 dest_mem
= get_memory_rtx (dest
);
2653 store_by_pieces (dest_mem
, tree_low_cst (len
, 1),
2654 builtin_memset_read_str
,
2655 (PTR
) &c
, dest_align
);
2656 dest_mem
= force_operand (XEXP (dest_mem
, 0), NULL_RTX
);
2657 #ifdef POINTERS_EXTEND_UNSIGNED
2658 if (GET_MODE (dest_mem
) != ptr_mode
)
2659 dest_mem
= convert_memory_address (ptr_mode
, dest_mem
);
2664 len_rtx
= expand_expr (len
, NULL_RTX
, VOIDmode
, 0);
2666 dest_mem
= get_memory_rtx (dest
);
2667 set_mem_align (dest_mem
, dest_align
);
2668 dest_addr
= clear_storage (dest_mem
, len_rtx
);
2672 dest_addr
= force_operand (XEXP (dest_mem
, 0), NULL_RTX
);
2673 #ifdef POINTERS_EXTEND_UNSIGNED
2674 if (GET_MODE (dest_addr
) != ptr_mode
)
2675 dest_addr
= convert_memory_address (ptr_mode
, dest_addr
);
2683 /* Expand expression EXP, which is a call to the bzero builtin. Return 0
2684 if we failed the caller should emit a normal call. */
2687 expand_builtin_bzero (exp
)
2690 tree arglist
= TREE_OPERAND (exp
, 1);
2691 tree dest
, size
, newarglist
;
2694 if (!validate_arglist (arglist
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
2697 dest
= TREE_VALUE (arglist
);
2698 size
= TREE_VALUE (TREE_CHAIN (arglist
));
2700 /* New argument list transforming bzero(ptr x, int y) to
2701 memset(ptr x, int 0, size_t y). This is done this way
2702 so that if it isn't expanded inline, we fallback to
2703 calling bzero instead of memset. */
2705 newarglist
= build_tree_list (NULL_TREE
, convert (sizetype
, size
));
2706 newarglist
= tree_cons (NULL_TREE
, integer_zero_node
, newarglist
);
2707 newarglist
= tree_cons (NULL_TREE
, dest
, newarglist
);
2709 TREE_OPERAND (exp
, 1) = newarglist
;
2710 result
= expand_builtin_memset (exp
, const0_rtx
, VOIDmode
);
2712 /* Always restore the original arguments. */
2713 TREE_OPERAND (exp
, 1) = arglist
;
2718 /* Expand expression EXP, which is a call to the memcmp built-in function.
2719 ARGLIST is the argument list for this call. Return 0 if we failed and the
2720 caller should emit a normal call, otherwise try to get the result in
2721 TARGET, if convenient (and in mode MODE, if that's convenient). */
2724 expand_builtin_memcmp (exp
, arglist
, target
, mode
)
2725 tree exp ATTRIBUTE_UNUSED
;
2728 enum machine_mode mode
;
2730 tree arg1
, arg2
, len
;
2731 const char *p1
, *p2
;
2733 if (!validate_arglist (arglist
,
2734 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
2737 arg1
= TREE_VALUE (arglist
);
2738 arg2
= TREE_VALUE (TREE_CHAIN (arglist
));
2739 len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
2741 /* If the len parameter is zero, return zero. */
2742 if (host_integerp (len
, 1) && tree_low_cst (len
, 1) == 0)
2744 /* Evaluate and ignore arg1 and arg2 in case they have
2746 expand_expr (arg1
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
2747 expand_expr (arg2
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
2751 p1
= c_getstr (arg1
);
2752 p2
= c_getstr (arg2
);
2754 /* If all arguments are constant, and the value of len is not greater
2755 than the lengths of arg1 and arg2, evaluate at compile-time. */
2756 if (host_integerp (len
, 1) && p1
&& p2
2757 && compare_tree_int (len
, strlen (p1
) + 1) <= 0
2758 && compare_tree_int (len
, strlen (p2
) + 1) <= 0)
2760 const int r
= memcmp (p1
, p2
, tree_low_cst (len
, 1));
2762 return (r
< 0 ? constm1_rtx
: (r
> 0 ? const1_rtx
: const0_rtx
));
2765 /* If len parameter is one, return an expression corresponding to
2766 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
2767 if (host_integerp (len
, 1) && tree_low_cst (len
, 1) == 1)
2769 tree cst_uchar_node
= build_type_variant (unsigned_char_type_node
, 1, 0);
2770 tree cst_uchar_ptr_node
= build_pointer_type (cst_uchar_node
);
2772 fold (build1 (CONVERT_EXPR
, integer_type_node
,
2773 build1 (INDIRECT_REF
, cst_uchar_node
,
2774 build1 (NOP_EXPR
, cst_uchar_ptr_node
, arg1
))));
2776 fold (build1 (CONVERT_EXPR
, integer_type_node
,
2777 build1 (INDIRECT_REF
, cst_uchar_node
,
2778 build1 (NOP_EXPR
, cst_uchar_ptr_node
, arg2
))));
2779 tree result
= fold (build (MINUS_EXPR
, integer_type_node
, ind1
, ind2
));
2780 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
2783 #ifdef HAVE_cmpstrsi
2785 rtx arg1_rtx
, arg2_rtx
, arg3_rtx
;
2790 = get_pointer_alignment (arg1
, BIGGEST_ALIGNMENT
) / BITS_PER_UNIT
;
2792 = get_pointer_alignment (arg2
, BIGGEST_ALIGNMENT
) / BITS_PER_UNIT
;
2793 enum machine_mode insn_mode
2794 = insn_data
[(int) CODE_FOR_cmpstrsi
].operand
[0].mode
;
2796 /* If we don't have POINTER_TYPE, call the function. */
2797 if (arg1_align
== 0 || arg2_align
== 0)
2800 /* Make a place to write the result of the instruction. */
2803 && GET_CODE (result
) == REG
&& GET_MODE (result
) == insn_mode
2804 && REGNO (result
) >= FIRST_PSEUDO_REGISTER
))
2805 result
= gen_reg_rtx (insn_mode
);
2807 arg1_rtx
= get_memory_rtx (arg1
);
2808 arg2_rtx
= get_memory_rtx (arg2
);
2809 arg3_rtx
= expand_expr (len
, NULL_RTX
, VOIDmode
, 0);
2813 insn
= gen_cmpstrsi (result
, arg1_rtx
, arg2_rtx
, arg3_rtx
,
2814 GEN_INT (MIN (arg1_align
, arg2_align
)));
2819 emit_library_call_value (memcmp_libfunc
, result
, LCT_PURE_MAKE_BLOCK
,
2820 TYPE_MODE (integer_type_node
), 3,
2821 XEXP (arg1_rtx
, 0), Pmode
,
2822 XEXP (arg2_rtx
, 0), Pmode
,
2823 convert_to_mode (TYPE_MODE (sizetype
), arg3_rtx
,
2824 TREE_UNSIGNED (sizetype
)),
2825 TYPE_MODE (sizetype
));
2827 /* Return the value in the proper mode for this function. */
2828 mode
= TYPE_MODE (TREE_TYPE (exp
));
2829 if (GET_MODE (result
) == mode
)
2831 else if (target
!= 0)
2833 convert_move (target
, result
, 0);
2837 return convert_to_mode (mode
, result
, 0);
2844 /* Expand expression EXP, which is a call to the strcmp builtin. Return 0
2845 if we failed the caller should emit a normal call, otherwise try to get
2846 the result in TARGET, if convenient. */
2849 expand_builtin_strcmp (exp
, target
, mode
)
2852 enum machine_mode mode
;
2854 tree arglist
= TREE_OPERAND (exp
, 1);
2856 const char *p1
, *p2
;
2858 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
2861 arg1
= TREE_VALUE (arglist
);
2862 arg2
= TREE_VALUE (TREE_CHAIN (arglist
));
2864 p1
= c_getstr (arg1
);
2865 p2
= c_getstr (arg2
);
2869 const int i
= strcmp (p1
, p2
);
2870 return (i
< 0 ? constm1_rtx
: (i
> 0 ? const1_rtx
: const0_rtx
));
2873 /* If either arg is "", return an expression corresponding to
2874 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
2875 if ((p1
&& *p1
== '\0') || (p2
&& *p2
== '\0'))
2877 tree cst_uchar_node
= build_type_variant (unsigned_char_type_node
, 1, 0);
2878 tree cst_uchar_ptr_node
= build_pointer_type (cst_uchar_node
);
2880 fold (build1 (CONVERT_EXPR
, integer_type_node
,
2881 build1 (INDIRECT_REF
, cst_uchar_node
,
2882 build1 (NOP_EXPR
, cst_uchar_ptr_node
, arg1
))));
2884 fold (build1 (CONVERT_EXPR
, integer_type_node
,
2885 build1 (INDIRECT_REF
, cst_uchar_node
,
2886 build1 (NOP_EXPR
, cst_uchar_ptr_node
, arg2
))));
2887 tree result
= fold (build (MINUS_EXPR
, integer_type_node
, ind1
, ind2
));
2888 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
2891 #ifdef HAVE_cmpstrsi
2894 tree len
, len1
, len2
;
2895 rtx arg1_rtx
, arg2_rtx
, arg3_rtx
;
2899 = get_pointer_alignment (arg1
, BIGGEST_ALIGNMENT
) / BITS_PER_UNIT
;
2901 = get_pointer_alignment (arg2
, BIGGEST_ALIGNMENT
) / BITS_PER_UNIT
;
2902 enum machine_mode insn_mode
2903 = insn_data
[(int) CODE_FOR_cmpstrsi
].operand
[0].mode
;
2905 len1
= c_strlen (arg1
);
2906 len2
= c_strlen (arg2
);
2909 len1
= size_binop (PLUS_EXPR
, ssize_int (1), len1
);
2911 len2
= size_binop (PLUS_EXPR
, ssize_int (1), len2
);
2913 /* If we don't have a constant length for the first, use the length
2914 of the second, if we know it. We don't require a constant for
2915 this case; some cost analysis could be done if both are available
2916 but neither is constant. For now, assume they're equally cheap,
2917 unless one has side effects. If both strings have constant lengths,
2924 else if (TREE_SIDE_EFFECTS (len1
))
2926 else if (TREE_SIDE_EFFECTS (len2
))
2928 else if (TREE_CODE (len1
) != INTEGER_CST
)
2930 else if (TREE_CODE (len2
) != INTEGER_CST
)
2932 else if (tree_int_cst_lt (len1
, len2
))
2937 /* If both arguments have side effects, we cannot optimize. */
2938 if (!len
|| TREE_SIDE_EFFECTS (len
))
2941 /* If we don't have POINTER_TYPE, call the function. */
2942 if (arg1_align
== 0 || arg2_align
== 0)
2945 /* Make a place to write the result of the instruction. */
2948 && GET_CODE (result
) == REG
&& GET_MODE (result
) == insn_mode
2949 && REGNO (result
) >= FIRST_PSEUDO_REGISTER
))
2950 result
= gen_reg_rtx (insn_mode
);
2952 arg1_rtx
= get_memory_rtx (arg1
);
2953 arg2_rtx
= get_memory_rtx (arg2
);
2954 arg3_rtx
= expand_expr (len
, NULL_RTX
, VOIDmode
, 0);
2955 insn
= gen_cmpstrsi (result
, arg1_rtx
, arg2_rtx
, arg3_rtx
,
2956 GEN_INT (MIN (arg1_align
, arg2_align
)));
2962 /* Return the value in the proper mode for this function. */
2963 mode
= TYPE_MODE (TREE_TYPE (exp
));
2964 if (GET_MODE (result
) == mode
)
2967 return convert_to_mode (mode
, result
, 0);
2968 convert_move (target
, result
, 0);
2975 /* Expand expression EXP, which is a call to the strncmp builtin. Return 0
2976 if we failed the caller should emit a normal call, otherwise try to get
2977 the result in TARGET, if convenient. */
2980 expand_builtin_strncmp (exp
, target
, mode
)
2983 enum machine_mode mode
;
2985 tree arglist
= TREE_OPERAND (exp
, 1);
2986 tree arg1
, arg2
, arg3
;
2987 const char *p1
, *p2
;
2989 if (!validate_arglist (arglist
,
2990 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
2993 arg1
= TREE_VALUE (arglist
);
2994 arg2
= TREE_VALUE (TREE_CHAIN (arglist
));
2995 arg3
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
2997 /* If the len parameter is zero, return zero. */
2998 if (host_integerp (arg3
, 1) && tree_low_cst (arg3
, 1) == 0)
3000 /* Evaluate and ignore arg1 and arg2 in case they have
3002 expand_expr (arg1
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
3003 expand_expr (arg2
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
3007 p1
= c_getstr (arg1
);
3008 p2
= c_getstr (arg2
);
3010 /* If all arguments are constant, evaluate at compile-time. */
3011 if (host_integerp (arg3
, 1) && p1
&& p2
)
3013 const int r
= strncmp (p1
, p2
, tree_low_cst (arg3
, 1));
3014 return (r
< 0 ? constm1_rtx
: (r
> 0 ? const1_rtx
: const0_rtx
));
3017 /* If len == 1 or (either string parameter is "" and (len >= 1)),
3018 return (*(const u_char*)arg1 - *(const u_char*)arg2). */
3019 if (host_integerp (arg3
, 1)
3020 && (tree_low_cst (arg3
, 1) == 1
3021 || (tree_low_cst (arg3
, 1) > 1
3022 && ((p1
&& *p1
== '\0') || (p2
&& *p2
== '\0')))))
3024 tree cst_uchar_node
= build_type_variant (unsigned_char_type_node
, 1, 0);
3025 tree cst_uchar_ptr_node
= build_pointer_type (cst_uchar_node
);
3027 fold (build1 (CONVERT_EXPR
, integer_type_node
,
3028 build1 (INDIRECT_REF
, cst_uchar_node
,
3029 build1 (NOP_EXPR
, cst_uchar_ptr_node
, arg1
))));
3031 fold (build1 (CONVERT_EXPR
, integer_type_node
,
3032 build1 (INDIRECT_REF
, cst_uchar_node
,
3033 build1 (NOP_EXPR
, cst_uchar_ptr_node
, arg2
))));
3034 tree result
= fold (build (MINUS_EXPR
, integer_type_node
, ind1
, ind2
));
3035 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
3038 /* If c_strlen can determine an expression for one of the string
3039 lengths, and it doesn't have side effects, then emit cmpstrsi
3040 using length MIN(strlen(string)+1, arg3). */
3041 #ifdef HAVE_cmpstrsi
3044 tree len
, len1
, len2
;
3045 rtx arg1_rtx
, arg2_rtx
, arg3_rtx
;
3049 = get_pointer_alignment (arg1
, BIGGEST_ALIGNMENT
) / BITS_PER_UNIT
;
3051 = get_pointer_alignment (arg2
, BIGGEST_ALIGNMENT
) / BITS_PER_UNIT
;
3052 enum machine_mode insn_mode
3053 = insn_data
[(int) CODE_FOR_cmpstrsi
].operand
[0].mode
;
3055 len1
= c_strlen (arg1
);
3056 len2
= c_strlen (arg2
);
3059 len1
= size_binop (PLUS_EXPR
, ssize_int (1), len1
);
3061 len2
= size_binop (PLUS_EXPR
, ssize_int (1), len2
);
3063 /* If we don't have a constant length for the first, use the length
3064 of the second, if we know it. We don't require a constant for
3065 this case; some cost analysis could be done if both are available
3066 but neither is constant. For now, assume they're equally cheap,
3067 unless one has side effects. If both strings have constant lengths,
3074 else if (TREE_SIDE_EFFECTS (len1
))
3076 else if (TREE_SIDE_EFFECTS (len2
))
3078 else if (TREE_CODE (len1
) != INTEGER_CST
)
3080 else if (TREE_CODE (len2
) != INTEGER_CST
)
3082 else if (tree_int_cst_lt (len1
, len2
))
3087 /* If both arguments have side effects, we cannot optimize. */
3088 if (!len
|| TREE_SIDE_EFFECTS (len
))
3091 /* The actual new length parameter is MIN(len,arg3). */
3092 len
= fold (build (MIN_EXPR
, TREE_TYPE (len
), len
, arg3
));
3094 /* If we don't have POINTER_TYPE, call the function. */
3095 if (arg1_align
== 0 || arg2_align
== 0)
3098 /* Make a place to write the result of the instruction. */
3101 && GET_CODE (result
) == REG
&& GET_MODE (result
) == insn_mode
3102 && REGNO (result
) >= FIRST_PSEUDO_REGISTER
))
3103 result
= gen_reg_rtx (insn_mode
);
3105 arg1_rtx
= get_memory_rtx (arg1
);
3106 arg2_rtx
= get_memory_rtx (arg2
);
3107 arg3_rtx
= expand_expr (len
, NULL_RTX
, VOIDmode
, 0);
3108 insn
= gen_cmpstrsi (result
, arg1_rtx
, arg2_rtx
, arg3_rtx
,
3109 GEN_INT (MIN (arg1_align
, arg2_align
)));
3115 /* Return the value in the proper mode for this function. */
3116 mode
= TYPE_MODE (TREE_TYPE (exp
));
3117 if (GET_MODE (result
) == mode
)
3120 return convert_to_mode (mode
, result
, 0);
3121 convert_move (target
, result
, 0);
3128 /* Expand expression EXP, which is a call to the strcat builtin.
3129 Return 0 if we failed the caller should emit a normal call,
3130 otherwise try to get the result in TARGET, if convenient. */
3133 expand_builtin_strcat (arglist
, target
, mode
)
3136 enum machine_mode mode
;
3138 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
3142 tree dst
= TREE_VALUE (arglist
),
3143 src
= TREE_VALUE (TREE_CHAIN (arglist
));
3144 const char *p
= c_getstr (src
);
3146 /* If the string length is zero, return the dst parameter. */
3147 if (p
&& *p
== '\0')
3148 return expand_expr (dst
, target
, mode
, EXPAND_NORMAL
);
3154 /* Expand expression EXP, which is a call to the strncat builtin.
3155 Return 0 if we failed the caller should emit a normal call,
3156 otherwise try to get the result in TARGET, if convenient. */
3159 expand_builtin_strncat (arglist
, target
, mode
)
3162 enum machine_mode mode
;
3164 if (!validate_arglist (arglist
,
3165 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
3169 tree dst
= TREE_VALUE (arglist
),
3170 src
= TREE_VALUE (TREE_CHAIN (arglist
)),
3171 len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
3172 const char *p
= c_getstr (src
);
3174 /* If the requested length is zero, or the src parameter string
3175 length is zero, return the dst parameter. */
3176 if (integer_zerop (len
) || (p
&& *p
== '\0'))
3178 /* Evaluate and ignore the src and len parameters in case
3179 they have side-effects. */
3180 expand_expr (src
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
3181 expand_expr (len
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
3182 return expand_expr (dst
, target
, mode
, EXPAND_NORMAL
);
3185 /* If the requested len is greater than or equal to the string
3186 length, call strcat. */
3187 if (TREE_CODE (len
) == INTEGER_CST
&& p
3188 && compare_tree_int (len
, strlen (p
)) >= 0)
3191 = tree_cons (NULL_TREE
, dst
, build_tree_list (NULL_TREE
, src
));
3192 tree fn
= implicit_built_in_decls
[BUILT_IN_STRCAT
];
3194 /* If the replacement _DECL isn't initialized, don't do the
3199 return expand_expr (build_function_call_expr (fn
, newarglist
),
3200 target
, mode
, EXPAND_NORMAL
);
3206 /* Expand expression EXP, which is a call to the strspn builtin.
3207 Return 0 if we failed the caller should emit a normal call,
3208 otherwise try to get the result in TARGET, if convenient. */
3211 expand_builtin_strspn (arglist
, target
, mode
)
3214 enum machine_mode mode
;
3216 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
3220 tree s1
= TREE_VALUE (arglist
), s2
= TREE_VALUE (TREE_CHAIN (arglist
));
3221 const char *p1
= c_getstr (s1
), *p2
= c_getstr (s2
);
3223 /* If both arguments are constants, evaluate at compile-time. */
3226 const size_t r
= strspn (p1
, p2
);
3227 return expand_expr (size_int (r
), target
, mode
, EXPAND_NORMAL
);
3230 /* If either argument is "", return 0. */
3231 if ((p1
&& *p1
== '\0') || (p2
&& *p2
== '\0'))
3233 /* Evaluate and ignore both arguments in case either one has
3235 expand_expr (s1
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
3236 expand_expr (s2
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
3243 /* Expand expression EXP, which is a call to the strcspn builtin.
3244 Return 0 if we failed the caller should emit a normal call,
3245 otherwise try to get the result in TARGET, if convenient. */
3248 expand_builtin_strcspn (arglist
, target
, mode
)
3251 enum machine_mode mode
;
3253 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
3257 tree s1
= TREE_VALUE (arglist
), s2
= TREE_VALUE (TREE_CHAIN (arglist
));
3258 const char *p1
= c_getstr (s1
), *p2
= c_getstr (s2
);
3260 /* If both arguments are constants, evaluate at compile-time. */
3263 const size_t r
= strcspn (p1
, p2
);
3264 return expand_expr (size_int (r
), target
, mode
, EXPAND_NORMAL
);
3267 /* If the first argument is "", return 0. */
3268 if (p1
&& *p1
== '\0')
3270 /* Evaluate and ignore argument s2 in case it has
3272 expand_expr (s2
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
3276 /* If the second argument is "", return __builtin_strlen(s1). */
3277 if (p2
&& *p2
== '\0')
3279 tree newarglist
= build_tree_list (NULL_TREE
, s1
),
3280 fn
= implicit_built_in_decls
[BUILT_IN_STRLEN
];
3282 /* If the replacement _DECL isn't initialized, don't do the
3287 return expand_expr (build_function_call_expr (fn
, newarglist
),
3288 target
, mode
, EXPAND_NORMAL
);
3294 /* Expand a call to __builtin_saveregs, generating the result in TARGET,
3295 if that's convenient. */
3298 expand_builtin_saveregs ()
3302 /* Don't do __builtin_saveregs more than once in a function.
3303 Save the result of the first call and reuse it. */
3304 if (saveregs_value
!= 0)
3305 return saveregs_value
;
3307 /* When this function is called, it means that registers must be
3308 saved on entry to this function. So we migrate the call to the
3309 first insn of this function. */
3313 #ifdef EXPAND_BUILTIN_SAVEREGS
3314 /* Do whatever the machine needs done in this case. */
3315 val
= EXPAND_BUILTIN_SAVEREGS ();
3317 /* ??? We used to try and build up a call to the out of line function,
3318 guessing about what registers needed saving etc. This became much
3319 harder with __builtin_va_start, since we don't have a tree for a
3320 call to __builtin_saveregs to fall back on. There was exactly one
3321 port (i860) that used this code, and I'm unconvinced it could actually
3322 handle the general case. So we no longer try to handle anything
3323 weird and make the backend absorb the evil. */
3325 error ("__builtin_saveregs not supported by this target");
3332 saveregs_value
= val
;
3334 /* Put the insns after the NOTE that starts the function. If this
3335 is inside a start_sequence, make the outer-level insn chain current, so
3336 the code is placed at the start of the function. */
3337 push_topmost_sequence ();
3338 emit_insn_after (seq
, get_insns ());
3339 pop_topmost_sequence ();
3344 /* __builtin_args_info (N) returns word N of the arg space info
3345 for the current function. The number and meanings of words
3346 is controlled by the definition of CUMULATIVE_ARGS. */
3349 expand_builtin_args_info (exp
)
3352 tree arglist
= TREE_OPERAND (exp
, 1);
3353 int nwords
= sizeof (CUMULATIVE_ARGS
) / sizeof (int);
3354 int *word_ptr
= (int *) ¤t_function_args_info
;
3356 if (sizeof (CUMULATIVE_ARGS
) % sizeof (int) != 0)
3361 if (!host_integerp (TREE_VALUE (arglist
), 0))
3362 error ("argument of `__builtin_args_info' must be constant");
3365 HOST_WIDE_INT wordnum
= tree_low_cst (TREE_VALUE (arglist
), 0);
3367 if (wordnum
< 0 || wordnum
>= nwords
)
3368 error ("argument of `__builtin_args_info' out of range");
3370 return GEN_INT (word_ptr
[wordnum
]);
3374 error ("missing argument in `__builtin_args_info'");
3379 /* Expand ARGLIST, from a call to __builtin_next_arg. */
3382 expand_builtin_next_arg (arglist
)
3385 tree fntype
= TREE_TYPE (current_function_decl
);
3387 if (TYPE_ARG_TYPES (fntype
) == 0
3388 || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype
)))
3391 error ("`va_start' used in function with fixed args");
3397 tree last_parm
= tree_last (DECL_ARGUMENTS (current_function_decl
));
3398 tree arg
= TREE_VALUE (arglist
);
3400 /* Strip off all nops for the sake of the comparison. This
3401 is not quite the same as STRIP_NOPS. It does more.
3402 We must also strip off INDIRECT_EXPR for C++ reference
3404 while (TREE_CODE (arg
) == NOP_EXPR
3405 || TREE_CODE (arg
) == CONVERT_EXPR
3406 || TREE_CODE (arg
) == NON_LVALUE_EXPR
3407 || TREE_CODE (arg
) == INDIRECT_REF
)
3408 arg
= TREE_OPERAND (arg
, 0);
3409 if (arg
!= last_parm
)
3410 warning ("second parameter of `va_start' not last named argument");
3413 /* Evidently an out of date version of <stdarg.h>; can't validate
3414 va_start's second argument, but can still work as intended. */
3415 warning ("`__builtin_next_arg' called without an argument");
3417 return expand_binop (Pmode
, add_optab
,
3418 current_function_internal_arg_pointer
,
3419 current_function_arg_offset_rtx
,
3420 NULL_RTX
, 0, OPTAB_LIB_WIDEN
);
3423 /* Make it easier for the backends by protecting the valist argument
3424 from multiple evaluations. */
3427 stabilize_va_list (valist
, needs_lvalue
)
3431 if (TREE_CODE (va_list_type_node
) == ARRAY_TYPE
)
3433 if (TREE_SIDE_EFFECTS (valist
))
3434 valist
= save_expr (valist
);
3436 /* For this case, the backends will be expecting a pointer to
3437 TREE_TYPE (va_list_type_node), but it's possible we've
3438 actually been given an array (an actual va_list_type_node).
3440 if (TREE_CODE (TREE_TYPE (valist
)) == ARRAY_TYPE
)
3442 tree p1
= build_pointer_type (TREE_TYPE (va_list_type_node
));
3443 tree p2
= build_pointer_type (va_list_type_node
);
3445 valist
= build1 (ADDR_EXPR
, p2
, valist
);
3446 valist
= fold (build1 (NOP_EXPR
, p1
, valist
));
3455 if (! TREE_SIDE_EFFECTS (valist
))
3458 pt
= build_pointer_type (va_list_type_node
);
3459 valist
= fold (build1 (ADDR_EXPR
, pt
, valist
));
3460 TREE_SIDE_EFFECTS (valist
) = 1;
3463 if (TREE_SIDE_EFFECTS (valist
))
3464 valist
= save_expr (valist
);
3465 valist
= fold (build1 (INDIRECT_REF
, TREE_TYPE (TREE_TYPE (valist
)),
3472 /* The "standard" implementation of va_start: just assign `nextarg' to
3476 std_expand_builtin_va_start (valist
, nextarg
)
3482 t
= build (MODIFY_EXPR
, TREE_TYPE (valist
), valist
,
3483 make_tree (ptr_type_node
, nextarg
));
3484 TREE_SIDE_EFFECTS (t
) = 1;
3486 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
3489 /* Expand ARGLIST, from a call to __builtin_va_start. */
3492 expand_builtin_va_start (arglist
)
3498 chain
= TREE_CHAIN (arglist
);
3500 if (TREE_CHAIN (chain
))
3501 error ("too many arguments to function `va_start'");
3503 nextarg
= expand_builtin_next_arg (chain
);
3504 valist
= stabilize_va_list (TREE_VALUE (arglist
), 1);
3506 #ifdef EXPAND_BUILTIN_VA_START
3507 EXPAND_BUILTIN_VA_START (valist
, nextarg
);
3509 std_expand_builtin_va_start (valist
, nextarg
);
3515 /* The "standard" implementation of va_arg: read the value from the
3516 current (padded) address and increment by the (padded) size. */
3519 std_expand_builtin_va_arg (valist
, type
)
3522 tree addr_tree
, t
, type_size
= NULL
;
3523 tree align
, alignm1
;
3527 /* Compute the rounded size of the type. */
3528 align
= size_int (PARM_BOUNDARY
/ BITS_PER_UNIT
);
3529 alignm1
= size_int (PARM_BOUNDARY
/ BITS_PER_UNIT
- 1);
3530 if (type
== error_mark_node
3531 || (type_size
= TYPE_SIZE_UNIT (TYPE_MAIN_VARIANT (type
))) == NULL
3532 || TREE_OVERFLOW (type_size
))
3533 rounded_size
= size_zero_node
;
3535 rounded_size
= fold (build (MULT_EXPR
, sizetype
,
3536 fold (build (TRUNC_DIV_EXPR
, sizetype
,
3537 fold (build (PLUS_EXPR
, sizetype
,
3538 type_size
, alignm1
)),
3544 if (PAD_VARARGS_DOWN
&& ! integer_zerop (rounded_size
))
3546 /* Small args are padded downward. */
3547 addr_tree
= fold (build (PLUS_EXPR
, TREE_TYPE (addr_tree
), addr_tree
,
3548 fold (build (COND_EXPR
, sizetype
,
3549 fold (build (GT_EXPR
, sizetype
,
3553 fold (build (MINUS_EXPR
, sizetype
,
3558 addr
= expand_expr (addr_tree
, NULL_RTX
, Pmode
, EXPAND_NORMAL
);
3559 addr
= copy_to_reg (addr
);
3561 /* Compute new value for AP. */
3562 if (! integer_zerop (rounded_size
))
3564 t
= build (MODIFY_EXPR
, TREE_TYPE (valist
), valist
,
3565 build (PLUS_EXPR
, TREE_TYPE (valist
), valist
,
3567 TREE_SIDE_EFFECTS (t
) = 1;
3568 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
3574 /* Expand __builtin_va_arg, which is not really a builtin function, but
3575 a very special sort of operator. */
3578 expand_builtin_va_arg (valist
, type
)
3582 tree promoted_type
, want_va_type
, have_va_type
;
3584 /* Verify that valist is of the proper type. */
3586 want_va_type
= va_list_type_node
;
3587 have_va_type
= TREE_TYPE (valist
);
3588 if (TREE_CODE (want_va_type
) == ARRAY_TYPE
)
3590 /* If va_list is an array type, the argument may have decayed
3591 to a pointer type, e.g. by being passed to another function.
3592 In that case, unwrap both types so that we can compare the
3593 underlying records. */
3594 if (TREE_CODE (have_va_type
) == ARRAY_TYPE
3595 || TREE_CODE (have_va_type
) == POINTER_TYPE
)
3597 want_va_type
= TREE_TYPE (want_va_type
);
3598 have_va_type
= TREE_TYPE (have_va_type
);
3601 if (TYPE_MAIN_VARIANT (want_va_type
) != TYPE_MAIN_VARIANT (have_va_type
))
3603 error ("first argument to `va_arg' not of type `va_list'");
3607 /* Generate a diagnostic for requesting data of a type that cannot
3608 be passed through `...' due to type promotion at the call site. */
3609 else if ((promoted_type
= (*lang_hooks
.types
.type_promotes_to
) (type
))
3612 const char *name
= "<anonymous type>", *pname
= 0;
3613 static bool gave_help
;
3615 if (TYPE_NAME (type
))
3617 if (TREE_CODE (TYPE_NAME (type
)) == IDENTIFIER_NODE
)
3618 name
= IDENTIFIER_POINTER (TYPE_NAME (type
));
3619 else if (TREE_CODE (TYPE_NAME (type
)) == TYPE_DECL
3620 && DECL_NAME (TYPE_NAME (type
)))
3621 name
= IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type
)));
3623 if (TYPE_NAME (promoted_type
))
3625 if (TREE_CODE (TYPE_NAME (promoted_type
)) == IDENTIFIER_NODE
)
3626 pname
= IDENTIFIER_POINTER (TYPE_NAME (promoted_type
));
3627 else if (TREE_CODE (TYPE_NAME (promoted_type
)) == TYPE_DECL
3628 && DECL_NAME (TYPE_NAME (promoted_type
)))
3629 pname
= IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (promoted_type
)));
3632 /* Unfortunately, this is merely undefined, rather than a constraint
3633 violation, so we cannot make this an error. If this call is never
3634 executed, the program is still strictly conforming. */
3635 warning ("`%s' is promoted to `%s' when passed through `...'",
3640 warning ("(so you should pass `%s' not `%s' to `va_arg')",
3644 /* We can, however, treat "undefined" any way we please.
3645 Call abort to encourage the user to fix the program. */
3646 expand_builtin_trap ();
3648 /* This is dead code, but go ahead and finish so that the
3649 mode of the result comes out right. */
3654 /* Make it easier for the backends by protecting the valist argument
3655 from multiple evaluations. */
3656 valist
= stabilize_va_list (valist
, 0);
3658 #ifdef EXPAND_BUILTIN_VA_ARG
3659 addr
= EXPAND_BUILTIN_VA_ARG (valist
, type
);
3661 addr
= std_expand_builtin_va_arg (valist
, type
);
3665 #ifdef POINTERS_EXTEND_UNSIGNED
3666 if (GET_MODE (addr
) != Pmode
)
3667 addr
= convert_memory_address (Pmode
, addr
);
3670 result
= gen_rtx_MEM (TYPE_MODE (type
), addr
);
3671 set_mem_alias_set (result
, get_varargs_alias_set ());
3676 /* Expand ARGLIST, from a call to __builtin_va_end. */
3679 expand_builtin_va_end (arglist
)
3682 tree valist
= TREE_VALUE (arglist
);
3684 #ifdef EXPAND_BUILTIN_VA_END
3685 valist
= stabilize_va_list (valist
, 0);
3686 EXPAND_BUILTIN_VA_END (arglist
);
3688 /* Evaluate for side effects, if needed. I hate macros that don't
3690 if (TREE_SIDE_EFFECTS (valist
))
3691 expand_expr (valist
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
3697 /* Expand ARGLIST, from a call to __builtin_va_copy. We do this as a
3698 builtin rather than just as an assignment in stdarg.h because of the
3699 nastiness of array-type va_list types. */
3702 expand_builtin_va_copy (arglist
)
3707 dst
= TREE_VALUE (arglist
);
3708 src
= TREE_VALUE (TREE_CHAIN (arglist
));
3710 dst
= stabilize_va_list (dst
, 1);
3711 src
= stabilize_va_list (src
, 0);
3713 if (TREE_CODE (va_list_type_node
) != ARRAY_TYPE
)
3715 t
= build (MODIFY_EXPR
, va_list_type_node
, dst
, src
);
3716 TREE_SIDE_EFFECTS (t
) = 1;
3717 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
3721 rtx dstb
, srcb
, size
;
3723 /* Evaluate to pointers. */
3724 dstb
= expand_expr (dst
, NULL_RTX
, Pmode
, EXPAND_NORMAL
);
3725 srcb
= expand_expr (src
, NULL_RTX
, Pmode
, EXPAND_NORMAL
);
3726 size
= expand_expr (TYPE_SIZE_UNIT (va_list_type_node
), NULL_RTX
,
3727 VOIDmode
, EXPAND_NORMAL
);
3729 #ifdef POINTERS_EXTEND_UNSIGNED
3730 if (GET_MODE (dstb
) != Pmode
)
3731 dstb
= convert_memory_address (Pmode
, dstb
);
3733 if (GET_MODE (srcb
) != Pmode
)
3734 srcb
= convert_memory_address (Pmode
, srcb
);
3737 /* "Dereference" to BLKmode memories. */
3738 dstb
= gen_rtx_MEM (BLKmode
, dstb
);
3739 set_mem_alias_set (dstb
, get_alias_set (TREE_TYPE (TREE_TYPE (dst
))));
3740 set_mem_align (dstb
, TYPE_ALIGN (va_list_type_node
));
3741 srcb
= gen_rtx_MEM (BLKmode
, srcb
);
3742 set_mem_alias_set (srcb
, get_alias_set (TREE_TYPE (TREE_TYPE (src
))));
3743 set_mem_align (srcb
, TYPE_ALIGN (va_list_type_node
));
3746 emit_block_move (dstb
, srcb
, size
, BLOCK_OP_NORMAL
);
3752 /* Expand a call to one of the builtin functions __builtin_frame_address or
3753 __builtin_return_address. */
3756 expand_builtin_frame_address (exp
)
3759 tree fndecl
= TREE_OPERAND (TREE_OPERAND (exp
, 0), 0);
3760 tree arglist
= TREE_OPERAND (exp
, 1);
3762 /* The argument must be a nonnegative integer constant.
3763 It counts the number of frames to scan up the stack.
3764 The value is the return address saved in that frame. */
3766 /* Warning about missing arg was already issued. */
3768 else if (! host_integerp (TREE_VALUE (arglist
), 1))
3770 if (DECL_FUNCTION_CODE (fndecl
) == BUILT_IN_FRAME_ADDRESS
)
3771 error ("invalid arg to `__builtin_frame_address'");
3773 error ("invalid arg to `__builtin_return_address'");
3779 = expand_builtin_return_addr (DECL_FUNCTION_CODE (fndecl
),
3780 tree_low_cst (TREE_VALUE (arglist
), 1),
3781 hard_frame_pointer_rtx
);
3783 /* Some ports cannot access arbitrary stack frames. */
3786 if (DECL_FUNCTION_CODE (fndecl
) == BUILT_IN_FRAME_ADDRESS
)
3787 warning ("unsupported arg to `__builtin_frame_address'");
3789 warning ("unsupported arg to `__builtin_return_address'");
3793 /* For __builtin_frame_address, return what we've got. */
3794 if (DECL_FUNCTION_CODE (fndecl
) == BUILT_IN_FRAME_ADDRESS
)
3797 if (GET_CODE (tem
) != REG
3798 && ! CONSTANT_P (tem
))
3799 tem
= copy_to_mode_reg (Pmode
, tem
);
3804 /* Expand a call to the alloca builtin, with arguments ARGLIST. Return 0 if
3805 we failed and the caller should emit a normal call, otherwise try to get
3806 the result in TARGET, if convenient. */
3809 expand_builtin_alloca (arglist
, target
)
3816 if (!validate_arglist (arglist
, INTEGER_TYPE
, VOID_TYPE
))
3819 /* Compute the argument. */
3820 op0
= expand_expr (TREE_VALUE (arglist
), NULL_RTX
, VOIDmode
, 0);
3822 /* Allocate the desired space. */
3823 result
= allocate_dynamic_stack_space (op0
, target
, BITS_PER_UNIT
);
3825 #ifdef POINTERS_EXTEND_UNSIGNED
3826 if (GET_MODE (result
) != ptr_mode
)
3827 result
= convert_memory_address (ptr_mode
, result
);
3833 /* Expand a call to a unary builtin. The arguments are in ARGLIST.
3834 Return 0 if a normal call should be emitted rather than expanding the
3835 function in-line. If convenient, the result should be placed in TARGET.
3836 SUBTARGET may be used as the target for computing one of EXP's operands. */
3839 expand_builtin_unop (target_mode
, arglist
, target
, subtarget
, op_optab
)
3840 enum machine_mode target_mode
;
3842 rtx target
, subtarget
;
3846 if (!validate_arglist (arglist
, INTEGER_TYPE
, VOID_TYPE
))
3849 /* Compute the argument. */
3850 op0
= expand_expr (TREE_VALUE (arglist
), subtarget
, VOIDmode
, 0);
3851 /* Compute op, into TARGET if possible.
3852 Set TARGET to wherever the result comes back. */
3853 target
= expand_unop (TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist
))),
3854 op_optab
, op0
, target
, 1);
3858 return convert_to_mode (target_mode
, target
, 0);
3861 /* If the string passed to fputs is a constant and is one character
3862 long, we attempt to transform this call into __builtin_fputc(). */
3865 expand_builtin_fputs (arglist
, ignore
, unlocked
)
3871 tree fn_fputc
= unlocked
? implicit_built_in_decls
[BUILT_IN_FPUTC_UNLOCKED
]
3872 : implicit_built_in_decls
[BUILT_IN_FPUTC
];
3873 tree fn_fwrite
= unlocked
? implicit_built_in_decls
[BUILT_IN_FWRITE_UNLOCKED
]
3874 : implicit_built_in_decls
[BUILT_IN_FWRITE
];
3876 /* If the return value is used, or the replacement _DECL isn't
3877 initialized, don't do the transformation. */
3878 if (!ignore
|| !fn_fputc
|| !fn_fwrite
)
3881 /* Verify the arguments in the original call. */
3882 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
3885 /* Get the length of the string passed to fputs. If the length
3886 can't be determined, punt. */
3887 if (!(len
= c_strlen (TREE_VALUE (arglist
)))
3888 || TREE_CODE (len
) != INTEGER_CST
)
3891 switch (compare_tree_int (len
, 1))
3893 case -1: /* length is 0, delete the call entirely . */
3895 /* Evaluate and ignore the argument in case it has
3897 expand_expr (TREE_VALUE (TREE_CHAIN (arglist
)), const0_rtx
,
3898 VOIDmode
, EXPAND_NORMAL
);
3901 case 0: /* length is 1, call fputc. */
3903 const char *p
= c_getstr (TREE_VALUE (arglist
));
3907 /* New argument list transforming fputs(string, stream) to
3908 fputc(string[0], stream). */
3910 build_tree_list (NULL_TREE
, TREE_VALUE (TREE_CHAIN (arglist
)));
3912 tree_cons (NULL_TREE
, build_int_2 (p
[0], 0), arglist
);
3918 case 1: /* length is greater than 1, call fwrite. */
3922 /* If optimizing for size keep fputs. */
3925 string_arg
= TREE_VALUE (arglist
);
3926 /* New argument list transforming fputs(string, stream) to
3927 fwrite(string, 1, len, stream). */
3928 arglist
= build_tree_list (NULL_TREE
, TREE_VALUE (TREE_CHAIN (arglist
)));
3929 arglist
= tree_cons (NULL_TREE
, len
, arglist
);
3930 arglist
= tree_cons (NULL_TREE
, size_one_node
, arglist
);
3931 arglist
= tree_cons (NULL_TREE
, string_arg
, arglist
);
3939 return expand_expr (build_function_call_expr (fn
, arglist
),
3940 (ignore
? const0_rtx
: NULL_RTX
),
3941 VOIDmode
, EXPAND_NORMAL
);
3944 /* Expand a call to __builtin_expect. We return our argument and emit a
3945 NOTE_INSN_EXPECTED_VALUE note. This is the expansion of __builtin_expect in
3946 a non-jump context. */
3949 expand_builtin_expect (arglist
, target
)
3956 if (arglist
== NULL_TREE
3957 || TREE_CHAIN (arglist
) == NULL_TREE
)
3959 exp
= TREE_VALUE (arglist
);
3960 c
= TREE_VALUE (TREE_CHAIN (arglist
));
3962 if (TREE_CODE (c
) != INTEGER_CST
)
3964 error ("second arg to `__builtin_expect' must be a constant");
3965 c
= integer_zero_node
;
3968 target
= expand_expr (exp
, target
, VOIDmode
, EXPAND_NORMAL
);
3970 /* Don't bother with expected value notes for integral constants. */
3971 if (flag_guess_branch_prob
&& GET_CODE (target
) != CONST_INT
)
3973 /* We do need to force this into a register so that we can be
3974 moderately sure to be able to correctly interpret the branch
3976 target
= force_reg (GET_MODE (target
), target
);
3978 rtx_c
= expand_expr (c
, NULL_RTX
, GET_MODE (target
), EXPAND_NORMAL
);
3980 note
= emit_note (NULL
, NOTE_INSN_EXPECTED_VALUE
);
3981 NOTE_EXPECTED_VALUE (note
) = gen_rtx_EQ (VOIDmode
, target
, rtx_c
);
3987 /* Like expand_builtin_expect, except do this in a jump context. This is
3988 called from do_jump if the conditional is a __builtin_expect. Return either
3989 a list of insns to emit the jump or NULL if we cannot optimize
3990 __builtin_expect. We need to optimize this at jump time so that machines
3991 like the PowerPC don't turn the test into a SCC operation, and then jump
3992 based on the test being 0/1. */
3995 expand_builtin_expect_jump (exp
, if_false_label
, if_true_label
)
4000 tree arglist
= TREE_OPERAND (exp
, 1);
4001 tree arg0
= TREE_VALUE (arglist
);
4002 tree arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
4005 /* Only handle __builtin_expect (test, 0) and
4006 __builtin_expect (test, 1). */
4007 if (TREE_CODE (TREE_TYPE (arg1
)) == INTEGER_TYPE
4008 && (integer_zerop (arg1
) || integer_onep (arg1
)))
4013 /* If we fail to locate an appropriate conditional jump, we'll
4014 fall back to normal evaluation. Ensure that the expression
4015 can be re-evaluated. */
4016 switch (unsafe_for_reeval (arg0
))
4021 case 1: /* Mildly unsafe. */
4022 arg0
= unsave_expr (arg0
);
4025 case 2: /* Wildly unsafe. */
4029 /* Expand the jump insns. */
4031 do_jump (arg0
, if_false_label
, if_true_label
);
4035 /* Now that the __builtin_expect has been validated, go through and add
4036 the expect's to each of the conditional jumps. If we run into an
4037 error, just give up and generate the 'safe' code of doing a SCC
4038 operation and then doing a branch on that. */
4040 while (insn
!= NULL_RTX
)
4042 rtx next
= NEXT_INSN (insn
);
4045 if (GET_CODE (insn
) == JUMP_INSN
&& any_condjump_p (insn
)
4046 && (pattern
= pc_set (insn
)) != NULL_RTX
)
4048 rtx ifelse
= SET_SRC (pattern
);
4052 if (GET_CODE (ifelse
) != IF_THEN_ELSE
)
4055 if (GET_CODE (XEXP (ifelse
, 1)) == LABEL_REF
)
4058 label
= XEXP (XEXP (ifelse
, 1), 0);
4060 /* An inverted jump reverses the probabilities. */
4061 else if (GET_CODE (XEXP (ifelse
, 2)) == LABEL_REF
)
4064 label
= XEXP (XEXP (ifelse
, 2), 0);
4066 /* We shouldn't have to worry about conditional returns during
4067 the expansion stage, but handle it gracefully anyway. */
4068 else if (GET_CODE (XEXP (ifelse
, 1)) == RETURN
)
4073 /* An inverted return reverses the probabilities. */
4074 else if (GET_CODE (XEXP (ifelse
, 2)) == RETURN
)
4082 /* If the test is expected to fail, reverse the
4084 if (integer_zerop (arg1
))
4087 /* If we are jumping to the false label, reverse the
4089 if (label
== NULL_RTX
)
4090 ; /* conditional return */
4091 else if (label
== if_false_label
)
4093 else if (label
!= if_true_label
)
4097 predict_insn_def (insn
, PRED_BUILTIN_EXPECT
, taken
);
4104 /* If no jumps were modified, fail and do __builtin_expect the normal
4114 expand_builtin_trap ()
4118 emit_insn (gen_trap ());
4121 emit_library_call (abort_libfunc
, LCT_NORETURN
, VOIDmode
, 0);
4125 /* Expand an expression EXP that calls a built-in function,
4126 with result going to TARGET if that's convenient
4127 (and in mode MODE if that's convenient).
4128 SUBTARGET may be used as the target for computing one of EXP's operands.
4129 IGNORE is nonzero if the value is to be ignored. */
4132 expand_builtin (exp
, target
, subtarget
, mode
, ignore
)
4136 enum machine_mode mode
;
4139 tree fndecl
= TREE_OPERAND (TREE_OPERAND (exp
, 0), 0);
4140 tree arglist
= TREE_OPERAND (exp
, 1);
4141 enum built_in_function fcode
= DECL_FUNCTION_CODE (fndecl
);
4142 enum machine_mode target_mode
= TYPE_MODE (TREE_TYPE (exp
));
4144 /* Perform postincrements before expanding builtin functions. Â */
4147 if (DECL_BUILT_IN_CLASS (fndecl
) == BUILT_IN_MD
)
4148 return (*targetm
.expand_builtin
) (exp
, target
, subtarget
, mode
, ignore
);
4150 /* When not optimizing, generate calls to library functions for a certain
4152 if (!optimize
&& !CALLED_AS_BUILT_IN (fndecl
))
4156 case BUILT_IN_SQRTF
:
4157 case BUILT_IN_SQRTL
:
4173 case BUILT_IN_ATAN2
:
4174 case BUILT_IN_ATAN2F
:
4175 case BUILT_IN_ATAN2L
:
4176 case BUILT_IN_MEMSET
:
4177 case BUILT_IN_MEMCPY
:
4178 case BUILT_IN_MEMCMP
:
4179 case BUILT_IN_MEMPCPY
:
4181 case BUILT_IN_BZERO
:
4182 case BUILT_IN_INDEX
:
4183 case BUILT_IN_RINDEX
:
4184 case BUILT_IN_STPCPY
:
4185 case BUILT_IN_STRCHR
:
4186 case BUILT_IN_STRRCHR
:
4187 case BUILT_IN_STRLEN
:
4188 case BUILT_IN_STRCPY
:
4189 case BUILT_IN_STRNCPY
:
4190 case BUILT_IN_STRNCMP
:
4191 case BUILT_IN_STRSTR
:
4192 case BUILT_IN_STRPBRK
:
4193 case BUILT_IN_STRCAT
:
4194 case BUILT_IN_STRNCAT
:
4195 case BUILT_IN_STRSPN
:
4196 case BUILT_IN_STRCSPN
:
4197 case BUILT_IN_STRCMP
:
4199 case BUILT_IN_PUTCHAR
:
4201 case BUILT_IN_PRINTF
:
4202 case BUILT_IN_FPUTC
:
4203 case BUILT_IN_FPUTS
:
4204 case BUILT_IN_FWRITE
:
4205 case BUILT_IN_PUTCHAR_UNLOCKED
:
4206 case BUILT_IN_PUTS_UNLOCKED
:
4207 case BUILT_IN_PRINTF_UNLOCKED
:
4208 case BUILT_IN_FPUTC_UNLOCKED
:
4209 case BUILT_IN_FPUTS_UNLOCKED
:
4210 case BUILT_IN_FWRITE_UNLOCKED
:
4211 case BUILT_IN_FLOOR
:
4212 case BUILT_IN_FLOORF
:
4213 case BUILT_IN_FLOORL
:
4215 case BUILT_IN_CEILF
:
4216 case BUILT_IN_CEILL
:
4217 case BUILT_IN_TRUNC
:
4218 case BUILT_IN_TRUNCF
:
4219 case BUILT_IN_TRUNCL
:
4220 case BUILT_IN_ROUND
:
4221 case BUILT_IN_ROUNDF
:
4222 case BUILT_IN_ROUNDL
:
4223 case BUILT_IN_NEARBYINT
:
4224 case BUILT_IN_NEARBYINTF
:
4225 case BUILT_IN_NEARBYINTL
:
4226 return expand_call (exp
, target
, ignore
);
4232 /* The built-in function expanders test for target == const0_rtx
4233 to determine whether the function's result will be ignored. */
4235 target
= const0_rtx
;
4237 /* If the result of a pure or const built-in function is ignored, and
4238 none of its arguments are volatile, we can avoid expanding the
4239 built-in call and just evaluate the arguments for side-effects. */
4240 if (target
== const0_rtx
4241 && (DECL_IS_PURE (fndecl
) || TREE_READONLY (fndecl
)))
4243 bool volatilep
= false;
4246 for (arg
= arglist
; arg
; arg
= TREE_CHAIN (arg
))
4247 if (TREE_THIS_VOLATILE (TREE_VALUE (arg
)))
4255 for (arg
= arglist
; arg
; arg
= TREE_CHAIN (arg
))
4256 expand_expr (TREE_VALUE (arg
), const0_rtx
,
4257 VOIDmode
, EXPAND_NORMAL
);
4266 case BUILT_IN_LLABS
:
4267 case BUILT_IN_IMAXABS
:
4269 case BUILT_IN_FABSF
:
4270 case BUILT_IN_FABSL
:
4271 /* build_function_call changes these into ABS_EXPR. */
4275 case BUILT_IN_CONJF
:
4276 case BUILT_IN_CONJL
:
4277 case BUILT_IN_CREAL
:
4278 case BUILT_IN_CREALF
:
4279 case BUILT_IN_CREALL
:
4280 case BUILT_IN_CIMAG
:
4281 case BUILT_IN_CIMAGF
:
4282 case BUILT_IN_CIMAGL
:
4283 /* expand_tree_builtin changes these into CONJ_EXPR, REALPART_EXPR
4284 and IMAGPART_EXPR. */
4299 /* Treat these like sqrt only if unsafe math optimizations are allowed,
4300 because of possible accuracy problems. */
4301 if (! flag_unsafe_math_optimizations
)
4304 case BUILT_IN_SQRTF
:
4305 case BUILT_IN_SQRTL
:
4306 case BUILT_IN_FLOOR
:
4307 case BUILT_IN_FLOORF
:
4308 case BUILT_IN_FLOORL
:
4310 case BUILT_IN_CEILF
:
4311 case BUILT_IN_CEILL
:
4312 case BUILT_IN_TRUNC
:
4313 case BUILT_IN_TRUNCF
:
4314 case BUILT_IN_TRUNCL
:
4315 case BUILT_IN_ROUND
:
4316 case BUILT_IN_ROUNDF
:
4317 case BUILT_IN_ROUNDL
:
4318 case BUILT_IN_NEARBYINT
:
4319 case BUILT_IN_NEARBYINTF
:
4320 case BUILT_IN_NEARBYINTL
:
4321 target
= expand_builtin_mathfn (exp
, target
, subtarget
);
4329 case BUILT_IN_ATAN2
:
4330 case BUILT_IN_ATAN2F
:
4331 case BUILT_IN_ATAN2L
:
4332 if (! flag_unsafe_math_optimizations
)
4334 target
= expand_builtin_mathfn_2 (exp
, target
, subtarget
);
4339 case BUILT_IN_APPLY_ARGS
:
4340 return expand_builtin_apply_args ();
4342 /* __builtin_apply (FUNCTION, ARGUMENTS, ARGSIZE) invokes
4343 FUNCTION with a copy of the parameters described by
4344 ARGUMENTS, and ARGSIZE. It returns a block of memory
4345 allocated on the stack into which is stored all the registers
4346 that might possibly be used for returning the result of a
4347 function. ARGUMENTS is the value returned by
4348 __builtin_apply_args. ARGSIZE is the number of bytes of
4349 arguments that must be copied. ??? How should this value be
4350 computed? We'll also need a safe worst case value for varargs
4352 case BUILT_IN_APPLY
:
4353 if (!validate_arglist (arglist
, POINTER_TYPE
,
4354 POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
)
4355 && !validate_arglist (arglist
, REFERENCE_TYPE
,
4356 POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
4364 for (t
= arglist
, i
= 0; t
; t
= TREE_CHAIN (t
), i
++)
4365 ops
[i
] = expand_expr (TREE_VALUE (t
), NULL_RTX
, VOIDmode
, 0);
4367 return expand_builtin_apply (ops
[0], ops
[1], ops
[2]);
4370 /* __builtin_return (RESULT) causes the function to return the
4371 value described by RESULT. RESULT is address of the block of
4372 memory returned by __builtin_apply. */
4373 case BUILT_IN_RETURN
:
4374 if (validate_arglist (arglist
, POINTER_TYPE
, VOID_TYPE
))
4375 expand_builtin_return (expand_expr (TREE_VALUE (arglist
),
4376 NULL_RTX
, VOIDmode
, 0));
4379 case BUILT_IN_SAVEREGS
:
4380 return expand_builtin_saveregs ();
4382 case BUILT_IN_ARGS_INFO
:
4383 return expand_builtin_args_info (exp
);
4385 /* Return the address of the first anonymous stack arg. */
4386 case BUILT_IN_NEXT_ARG
:
4387 return expand_builtin_next_arg (arglist
);
4389 case BUILT_IN_CLASSIFY_TYPE
:
4390 return expand_builtin_classify_type (arglist
);
4392 case BUILT_IN_CONSTANT_P
:
4393 return expand_builtin_constant_p (exp
);
4395 case BUILT_IN_FRAME_ADDRESS
:
4396 case BUILT_IN_RETURN_ADDRESS
:
4397 return expand_builtin_frame_address (exp
);
4399 /* Returns the address of the area where the structure is returned.
4401 case BUILT_IN_AGGREGATE_INCOMING_ADDRESS
:
4403 || ! AGGREGATE_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl
)))
4404 || GET_CODE (DECL_RTL (DECL_RESULT (current_function_decl
))) != MEM
)
4407 return XEXP (DECL_RTL (DECL_RESULT (current_function_decl
)), 0);
4409 case BUILT_IN_ALLOCA
:
4410 target
= expand_builtin_alloca (arglist
, target
);
4417 case BUILT_IN_FFSLL
:
4418 target
= expand_builtin_unop (target_mode
, arglist
, target
,
4419 subtarget
, ffs_optab
);
4426 case BUILT_IN_CLZLL
:
4427 target
= expand_builtin_unop (target_mode
, arglist
, target
,
4428 subtarget
, clz_optab
);
4435 case BUILT_IN_CTZLL
:
4436 target
= expand_builtin_unop (target_mode
, arglist
, target
,
4437 subtarget
, ctz_optab
);
4442 case BUILT_IN_POPCOUNT
:
4443 case BUILT_IN_POPCOUNTL
:
4444 case BUILT_IN_POPCOUNTLL
:
4445 target
= expand_builtin_unop (target_mode
, arglist
, target
,
4446 subtarget
, popcount_optab
);
4451 case BUILT_IN_PARITY
:
4452 case BUILT_IN_PARITYL
:
4453 case BUILT_IN_PARITYLL
:
4454 target
= expand_builtin_unop (target_mode
, arglist
, target
,
4455 subtarget
, parity_optab
);
4460 case BUILT_IN_STRLEN
:
4461 target
= expand_builtin_strlen (exp
, target
);
4466 case BUILT_IN_STRCPY
:
4467 target
= expand_builtin_strcpy (exp
, target
, mode
);
4472 case BUILT_IN_STRNCPY
:
4473 target
= expand_builtin_strncpy (arglist
, target
, mode
);
4478 case BUILT_IN_STPCPY
:
4479 target
= expand_builtin_stpcpy (arglist
, target
, mode
);
4484 case BUILT_IN_STRCAT
:
4485 target
= expand_builtin_strcat (arglist
, target
, mode
);
4490 case BUILT_IN_STRNCAT
:
4491 target
= expand_builtin_strncat (arglist
, target
, mode
);
4496 case BUILT_IN_STRSPN
:
4497 target
= expand_builtin_strspn (arglist
, target
, mode
);
4502 case BUILT_IN_STRCSPN
:
4503 target
= expand_builtin_strcspn (arglist
, target
, mode
);
4508 case BUILT_IN_STRSTR
:
4509 target
= expand_builtin_strstr (arglist
, target
, mode
);
4514 case BUILT_IN_STRPBRK
:
4515 target
= expand_builtin_strpbrk (arglist
, target
, mode
);
4520 case BUILT_IN_INDEX
:
4521 case BUILT_IN_STRCHR
:
4522 target
= expand_builtin_strchr (arglist
, target
, mode
);
4527 case BUILT_IN_RINDEX
:
4528 case BUILT_IN_STRRCHR
:
4529 target
= expand_builtin_strrchr (arglist
, target
, mode
);
4534 case BUILT_IN_MEMCPY
:
4535 target
= expand_builtin_memcpy (arglist
, target
, mode
, /*endp=*/0);
4540 case BUILT_IN_MEMPCPY
:
4541 target
= expand_builtin_memcpy (arglist
, target
, mode
, /*endp=*/1);
4546 case BUILT_IN_MEMSET
:
4547 target
= expand_builtin_memset (exp
, target
, mode
);
4552 case BUILT_IN_BZERO
:
4553 target
= expand_builtin_bzero (exp
);
4558 case BUILT_IN_STRCMP
:
4559 target
= expand_builtin_strcmp (exp
, target
, mode
);
4564 case BUILT_IN_STRNCMP
:
4565 target
= expand_builtin_strncmp (exp
, target
, mode
);
4571 case BUILT_IN_MEMCMP
:
4572 target
= expand_builtin_memcmp (exp
, arglist
, target
, mode
);
4577 case BUILT_IN_SETJMP
:
4578 target
= expand_builtin_setjmp (arglist
, target
);
4583 /* __builtin_longjmp is passed a pointer to an array of five words.
4584 It's similar to the C library longjmp function but works with
4585 __builtin_setjmp above. */
4586 case BUILT_IN_LONGJMP
:
4587 if (!validate_arglist (arglist
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
4591 rtx buf_addr
= expand_expr (TREE_VALUE (arglist
), subtarget
,
4593 rtx value
= expand_expr (TREE_VALUE (TREE_CHAIN (arglist
)),
4594 NULL_RTX
, VOIDmode
, 0);
4596 if (value
!= const1_rtx
)
4598 error ("__builtin_longjmp second argument must be 1");
4602 expand_builtin_longjmp (buf_addr
, value
);
4607 expand_builtin_trap ();
4610 case BUILT_IN_FPUTS
:
4611 target
= expand_builtin_fputs (arglist
, ignore
,/*unlocked=*/ 0);
4615 case BUILT_IN_FPUTS_UNLOCKED
:
4616 target
= expand_builtin_fputs (arglist
, ignore
,/*unlocked=*/ 1);
4621 /* Various hooks for the DWARF 2 __throw routine. */
4622 case BUILT_IN_UNWIND_INIT
:
4623 expand_builtin_unwind_init ();
4625 case BUILT_IN_DWARF_CFA
:
4626 return virtual_cfa_rtx
;
4627 #ifdef DWARF2_UNWIND_INFO
4628 case BUILT_IN_DWARF_FP_REGNUM
:
4629 return expand_builtin_dwarf_fp_regnum ();
4630 case BUILT_IN_INIT_DWARF_REG_SIZES
:
4631 expand_builtin_init_dwarf_reg_sizes (TREE_VALUE (arglist
));
4634 case BUILT_IN_FROB_RETURN_ADDR
:
4635 return expand_builtin_frob_return_addr (TREE_VALUE (arglist
));
4636 case BUILT_IN_EXTRACT_RETURN_ADDR
:
4637 return expand_builtin_extract_return_addr (TREE_VALUE (arglist
));
4638 case BUILT_IN_EH_RETURN
:
4639 expand_builtin_eh_return (TREE_VALUE (arglist
),
4640 TREE_VALUE (TREE_CHAIN (arglist
)));
4642 #ifdef EH_RETURN_DATA_REGNO
4643 case BUILT_IN_EH_RETURN_DATA_REGNO
:
4644 return expand_builtin_eh_return_data_regno (arglist
);
4646 case BUILT_IN_VA_START
:
4647 case BUILT_IN_STDARG_START
:
4648 return expand_builtin_va_start (arglist
);
4649 case BUILT_IN_VA_END
:
4650 return expand_builtin_va_end (arglist
);
4651 case BUILT_IN_VA_COPY
:
4652 return expand_builtin_va_copy (arglist
);
4653 case BUILT_IN_EXPECT
:
4654 return expand_builtin_expect (arglist
, target
);
4655 case BUILT_IN_PREFETCH
:
4656 expand_builtin_prefetch (arglist
);
4660 default: /* just do library call, if unknown builtin */
4661 if (!DECL_ASSEMBLER_NAME_SET_P (fndecl
))
4662 error ("built-in function `%s' not currently supported",
4663 IDENTIFIER_POINTER (DECL_NAME (fndecl
)));
4666 /* The switch statement above can drop through to cause the function
4667 to be called normally. */
4668 return expand_call (exp
, target
, ignore
);
4671 /* Determine whether a tree node represents a call to a built-in
4672 math function. If the tree T is a call to a built-in function
4673 taking a single real argument, then the return value is the
4674 DECL_FUNCTION_CODE of the call, e.g. BUILT_IN_SQRT. Otherwise
4675 the return value is END_BUILTINS. */
4677 enum built_in_function
4678 builtin_mathfn_code (t
)
4681 tree fndecl
, arglist
;
4683 if (TREE_CODE (t
) != CALL_EXPR
4684 || TREE_CODE (TREE_OPERAND (t
, 0)) != ADDR_EXPR
)
4685 return END_BUILTINS
;
4687 fndecl
= TREE_OPERAND (TREE_OPERAND (t
, 0), 0);
4688 if (TREE_CODE (fndecl
) != FUNCTION_DECL
4689 || ! DECL_BUILT_IN (fndecl
)
4690 || DECL_BUILT_IN_CLASS (fndecl
) == BUILT_IN_MD
)
4691 return END_BUILTINS
;
4693 arglist
= TREE_OPERAND (t
, 1);
4695 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist
))) != REAL_TYPE
)
4696 return END_BUILTINS
;
4698 arglist
= TREE_CHAIN (arglist
);
4699 switch (DECL_FUNCTION_CODE (fndecl
))
4704 case BUILT_IN_ATAN2
:
4705 case BUILT_IN_ATAN2F
:
4706 case BUILT_IN_ATAN2L
:
4708 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist
))) != REAL_TYPE
4709 || TREE_CHAIN (arglist
))
4710 return END_BUILTINS
;
4715 return END_BUILTINS
;
4719 return DECL_FUNCTION_CODE (fndecl
);
4722 /* Fold a call to __builtin_constant_p, if we know it will evaluate to a
4723 constant. ARGLIST is the argument list of the call. */
4726 fold_builtin_constant_p (arglist
)
4732 arglist
= TREE_VALUE (arglist
);
4734 /* We return 1 for a numeric type that's known to be a constant
4735 value at compile-time or for an aggregate type that's a
4736 literal constant. */
4737 STRIP_NOPS (arglist
);
4739 /* If we know this is a constant, emit the constant of one. */
4740 if (TREE_CODE_CLASS (TREE_CODE (arglist
)) == 'c'
4741 || (TREE_CODE (arglist
) == CONSTRUCTOR
4742 && TREE_CONSTANT (arglist
))
4743 || (TREE_CODE (arglist
) == ADDR_EXPR
4744 && TREE_CODE (TREE_OPERAND (arglist
, 0)) == STRING_CST
))
4745 return integer_one_node
;
4747 /* If we aren't going to be running CSE or this expression
4748 has side effects, show we don't know it to be a constant.
4749 Likewise if it's a pointer or aggregate type since in those
4750 case we only want literals, since those are only optimized
4751 when generating RTL, not later.
4752 And finally, if we are compiling an initializer, not code, we
4753 need to return a definite result now; there's not going to be any
4754 more optimization done. */
4755 if (TREE_SIDE_EFFECTS (arglist
) || cse_not_expected
4756 || AGGREGATE_TYPE_P (TREE_TYPE (arglist
))
4757 || POINTER_TYPE_P (TREE_TYPE (arglist
))
4759 return integer_zero_node
;
4764 /* Fold a call to __builtin_classify_type. */
4767 fold_builtin_classify_type (arglist
)
4771 return build_int_2 (no_type_class
, 0);
4773 return build_int_2 (type_to_class (TREE_TYPE (TREE_VALUE (arglist
))), 0);
4776 /* Fold a call to __builtin_inf or __builtin_huge_val. */
4779 fold_builtin_inf (type
, warn
)
4783 REAL_VALUE_TYPE real
;
4785 if (!MODE_HAS_INFINITIES (TYPE_MODE (type
)) && warn
)
4786 warning ("target format does not support infinity");
4789 return build_real (type
, real
);
4792 /* Fold a call to __builtin_nan or __builtin_nans. */
4795 fold_builtin_nan (arglist
, type
, quiet
)
4799 REAL_VALUE_TYPE real
;
4802 if (!validate_arglist (arglist
, POINTER_TYPE
, VOID_TYPE
))
4804 str
= c_getstr (TREE_VALUE (arglist
));
4808 if (!real_nan (&real
, str
, quiet
, TYPE_MODE (type
)))
4811 return build_real (type
, real
);
4814 /* EXP is assumed to me builtin call where truncation can be propagated
4815 across (for instance floor((double)f) == (double)floorf (f).
4816 Do the transformation. */
4818 fold_trunc_transparent_mathfn (exp
)
4821 tree fndecl
= TREE_OPERAND (TREE_OPERAND (exp
, 0), 0);
4822 tree arglist
= TREE_OPERAND (exp
, 1);
4823 enum built_in_function fcode
= DECL_FUNCTION_CODE (fndecl
);
4825 if (optimize
&& validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
4827 tree arg0
= strip_float_extensions (TREE_VALUE (arglist
));
4828 tree ftype
= TREE_TYPE (exp
);
4829 tree newtype
= TREE_TYPE (arg0
);
4832 if (TYPE_PRECISION (newtype
) < TYPE_PRECISION (ftype
)
4833 && (decl
= mathfn_built_in (newtype
, fcode
)))
4836 build_tree_list (NULL_TREE
, fold (convert (newtype
, arg0
)));
4837 return convert (ftype
,
4838 build_function_call_expr (decl
, arglist
));
4844 /* Used by constant folding to eliminate some builtin calls early. EXP is
4845 the CALL_EXPR of a call to a builtin function. */
4851 tree fndecl
= TREE_OPERAND (TREE_OPERAND (exp
, 0), 0);
4852 tree arglist
= TREE_OPERAND (exp
, 1);
4853 tree type
= TREE_TYPE (TREE_TYPE (fndecl
));
4855 if (DECL_BUILT_IN_CLASS (fndecl
) == BUILT_IN_MD
)
4858 switch (DECL_FUNCTION_CODE (fndecl
))
4860 case BUILT_IN_CONSTANT_P
:
4861 return fold_builtin_constant_p (arglist
);
4863 case BUILT_IN_CLASSIFY_TYPE
:
4864 return fold_builtin_classify_type (arglist
);
4866 case BUILT_IN_STRLEN
:
4867 if (validate_arglist (arglist
, POINTER_TYPE
, VOID_TYPE
))
4869 tree len
= c_strlen (TREE_VALUE (arglist
));
4872 /* Convert from the internal "sizetype" type to "size_t". */
4874 len
= convert (size_type_node
, len
);
4881 case BUILT_IN_SQRTF
:
4882 case BUILT_IN_SQRTL
:
4883 if (validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
4885 enum built_in_function fcode
;
4886 tree arg
= TREE_VALUE (arglist
);
4888 /* Optimize sqrt of constant value. */
4889 if (TREE_CODE (arg
) == REAL_CST
4890 && ! TREE_CONSTANT_OVERFLOW (arg
))
4892 enum machine_mode mode
;
4893 REAL_VALUE_TYPE r
, x
;
4895 x
= TREE_REAL_CST (arg
);
4896 mode
= TYPE_MODE (type
);
4897 if (real_sqrt (&r
, mode
, &x
)
4898 || (!flag_trapping_math
&& !flag_errno_math
))
4899 return build_real (type
, r
);
4902 /* Optimize sqrt(exp(x)) = exp(x*0.5). */
4903 fcode
= builtin_mathfn_code (arg
);
4904 if (flag_unsafe_math_optimizations
4905 && (fcode
== BUILT_IN_EXP
4906 || fcode
== BUILT_IN_EXPF
4907 || fcode
== BUILT_IN_EXPL
))
4909 tree expfn
= TREE_OPERAND (TREE_OPERAND (arg
, 0), 0);
4910 arg
= fold (build (MULT_EXPR
, type
,
4911 TREE_VALUE (TREE_OPERAND (arg
, 1)),
4912 build_real (type
, dconsthalf
)));
4913 arglist
= build_tree_list (NULL_TREE
, arg
);
4914 return build_function_call_expr (expfn
, arglist
);
4917 /* Optimize sqrt(pow(x,y)) = pow(x,y*0.5). */
4918 if (flag_unsafe_math_optimizations
4919 && (fcode
== BUILT_IN_POW
4920 || fcode
== BUILT_IN_POWF
4921 || fcode
== BUILT_IN_POWL
))
4923 tree powfn
= TREE_OPERAND (TREE_OPERAND (arg
, 0), 0);
4924 tree arg0
= TREE_VALUE (TREE_OPERAND (arg
, 1));
4925 tree arg1
= TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg
, 1)));
4926 tree narg1
= fold (build (MULT_EXPR
, type
, arg1
,
4927 build_real (type
, dconsthalf
)));
4928 arglist
= tree_cons (NULL_TREE
, arg0
,
4929 build_tree_list (NULL_TREE
, narg1
));
4930 return build_function_call_expr (powfn
, arglist
);
4938 if (validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
4940 tree arg
= TREE_VALUE (arglist
);
4942 /* Optimize sin(0.0) = 0.0. */
4943 if (real_zerop (arg
))
4944 return build_real (type
, dconst0
);
4951 if (validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
4953 tree arg
= TREE_VALUE (arglist
);
4955 /* Optimize cos(0.0) = 1.0. */
4956 if (real_zerop (arg
))
4957 return build_real (type
, dconst1
);
4964 if (validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
4966 enum built_in_function fcode
;
4967 tree arg
= TREE_VALUE (arglist
);
4969 /* Optimize exp(0.0) = 1.0. */
4970 if (real_zerop (arg
))
4971 return build_real (type
, dconst1
);
4973 /* Optimize exp(log(x)) = x. */
4974 fcode
= builtin_mathfn_code (arg
);
4975 if (flag_unsafe_math_optimizations
4976 && (fcode
== BUILT_IN_LOG
4977 || fcode
== BUILT_IN_LOGF
4978 || fcode
== BUILT_IN_LOGL
))
4979 return TREE_VALUE (TREE_OPERAND (arg
, 1));
4986 if (validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
4988 enum built_in_function fcode
;
4989 tree arg
= TREE_VALUE (arglist
);
4991 /* Optimize log(1.0) = 0.0. */
4992 if (real_onep (arg
))
4993 return build_real (type
, dconst0
);
4995 /* Optimize log(exp(x)) = x. */
4996 fcode
= builtin_mathfn_code (arg
);
4997 if (flag_unsafe_math_optimizations
4998 && (fcode
== BUILT_IN_EXP
4999 || fcode
== BUILT_IN_EXPF
5000 || fcode
== BUILT_IN_EXPL
))
5001 return TREE_VALUE (TREE_OPERAND (arg
, 1));
5003 /* Optimize log(sqrt(x)) = log(x)*0.5. */
5004 if (flag_unsafe_math_optimizations
5005 && (fcode
== BUILT_IN_SQRT
5006 || fcode
== BUILT_IN_SQRTF
5007 || fcode
== BUILT_IN_SQRTL
))
5009 tree logfn
= build_function_call_expr (fndecl
,
5010 TREE_OPERAND (arg
, 1));
5011 return fold (build (MULT_EXPR
, type
, logfn
,
5012 build_real (type
, dconsthalf
)));
5015 /* Optimize log(pow(x,y)) = y*log(x). */
5016 if (flag_unsafe_math_optimizations
5017 && (fcode
== BUILT_IN_POW
5018 || fcode
== BUILT_IN_POWF
5019 || fcode
== BUILT_IN_POWL
))
5021 tree arg0
, arg1
, logfn
;
5023 arg0
= TREE_VALUE (TREE_OPERAND (arg
, 1));
5024 arg1
= TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg
, 1)));
5025 arglist
= build_tree_list (NULL_TREE
, arg0
);
5026 logfn
= build_function_call_expr (fndecl
, arglist
);
5027 return fold (build (MULT_EXPR
, type
, arg1
, logfn
));
5035 if (validate_arglist (arglist
, REAL_TYPE
, REAL_TYPE
, VOID_TYPE
))
5037 enum built_in_function fcode
;
5038 tree arg0
= TREE_VALUE (arglist
);
5039 tree arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
5041 /* Optimize pow(1.0,y) = 1.0. */
5042 if (real_onep (arg0
))
5043 return omit_one_operand (type
, build_real (type
, dconst1
), arg1
);
5045 if (TREE_CODE (arg1
) == REAL_CST
5046 && ! TREE_CONSTANT_OVERFLOW (arg1
))
5049 c
= TREE_REAL_CST (arg1
);
5051 /* Optimize pow(x,0.0) = 1.0. */
5052 if (REAL_VALUES_EQUAL (c
, dconst0
))
5053 return omit_one_operand (type
, build_real (type
, dconst1
),
5056 /* Optimize pow(x,1.0) = x. */
5057 if (REAL_VALUES_EQUAL (c
, dconst1
))
5060 /* Optimize pow(x,-1.0) = 1.0/x. */
5061 if (REAL_VALUES_EQUAL (c
, dconstm1
))
5062 return fold (build (RDIV_EXPR
, type
,
5063 build_real (type
, dconst1
),
5066 /* Optimize pow(x,2.0) = x*x. */
5067 if (REAL_VALUES_EQUAL (c
, dconst2
)
5068 && (*lang_hooks
.decls
.global_bindings_p
) () == 0
5069 && ! contains_placeholder_p (arg0
))
5071 arg0
= save_expr (arg0
);
5072 return fold (build (MULT_EXPR
, type
, arg0
, arg0
));
5075 /* Optimize pow(x,-2.0) = 1.0/(x*x). */
5076 if (flag_unsafe_math_optimizations
5077 && REAL_VALUES_EQUAL (c
, dconstm2
)
5078 && (*lang_hooks
.decls
.global_bindings_p
) () == 0
5079 && ! contains_placeholder_p (arg0
))
5081 arg0
= save_expr (arg0
);
5082 return fold (build (RDIV_EXPR
, type
,
5083 build_real (type
, dconst1
),
5084 fold (build (MULT_EXPR
, type
,
5088 /* Optimize pow(x,0.5) = sqrt(x). */
5089 if (flag_unsafe_math_optimizations
5090 && REAL_VALUES_EQUAL (c
, dconsthalf
))
5094 fcode
= DECL_FUNCTION_CODE (fndecl
);
5095 if (fcode
== BUILT_IN_POW
)
5096 sqrtfn
= implicit_built_in_decls
[BUILT_IN_SQRT
];
5097 else if (fcode
== BUILT_IN_POWF
)
5098 sqrtfn
= implicit_built_in_decls
[BUILT_IN_SQRTF
];
5099 else if (fcode
== BUILT_IN_POWL
)
5100 sqrtfn
= implicit_built_in_decls
[BUILT_IN_SQRTL
];
5104 if (sqrtfn
!= NULL_TREE
)
5106 tree arglist
= build_tree_list (NULL_TREE
, arg0
);
5107 return build_function_call_expr (sqrtfn
, arglist
);
5112 /* Optimize pow(exp(x),y) = exp(x*y). */
5113 fcode
= builtin_mathfn_code (arg0
);
5114 if (flag_unsafe_math_optimizations
5115 && (fcode
== BUILT_IN_EXP
5116 || fcode
== BUILT_IN_EXPF
5117 || fcode
== BUILT_IN_EXPL
))
5119 tree expfn
= TREE_OPERAND (TREE_OPERAND (arg0
, 0), 0);
5120 tree arg
= TREE_VALUE (TREE_OPERAND (arg0
, 1));
5121 arg
= fold (build (MULT_EXPR
, type
, arg
, arg1
));
5122 arglist
= build_tree_list (NULL_TREE
, arg
);
5123 return build_function_call_expr (expfn
, arglist
);
5126 /* Optimize pow(sqrt(x),y) = pow(x,y*0.5). */
5127 if (flag_unsafe_math_optimizations
5128 && (fcode
== BUILT_IN_SQRT
5129 || fcode
== BUILT_IN_SQRTF
5130 || fcode
== BUILT_IN_SQRTL
))
5132 tree narg0
= TREE_VALUE (TREE_OPERAND (arg0
, 1));
5133 tree narg1
= fold (build (MULT_EXPR
, type
, arg1
,
5134 build_real (type
, dconsthalf
)));
5136 arglist
= tree_cons (NULL_TREE
, narg0
,
5137 build_tree_list (NULL_TREE
, narg1
));
5138 return build_function_call_expr (fndecl
, arglist
);
5141 /* Optimize pow(pow(x,y),z) = pow(x,y*z). */
5142 if (flag_unsafe_math_optimizations
5143 && (fcode
== BUILT_IN_POW
5144 || fcode
== BUILT_IN_POWF
5145 || fcode
== BUILT_IN_POWL
))
5147 tree arg00
= TREE_VALUE (TREE_OPERAND (arg0
, 1));
5148 tree arg01
= TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg0
, 1)));
5149 tree narg1
= fold (build (MULT_EXPR
, type
, arg01
, arg1
));
5150 arglist
= tree_cons (NULL_TREE
, arg00
,
5151 build_tree_list (NULL_TREE
, narg1
));
5152 return build_function_call_expr (fndecl
, arglist
);
5160 return fold_builtin_inf (type
, true);
5162 case BUILT_IN_HUGE_VAL
:
5163 case BUILT_IN_HUGE_VALF
:
5164 case BUILT_IN_HUGE_VALL
:
5165 return fold_builtin_inf (type
, false);
5170 return fold_builtin_nan (arglist
, type
, true);
5173 case BUILT_IN_NANSF
:
5174 case BUILT_IN_NANSL
:
5175 return fold_builtin_nan (arglist
, type
, false);
5177 case BUILT_IN_FLOOR
:
5178 case BUILT_IN_FLOORF
:
5179 case BUILT_IN_FLOORL
:
5181 case BUILT_IN_CEILF
:
5182 case BUILT_IN_CEILL
:
5183 case BUILT_IN_TRUNC
:
5184 case BUILT_IN_TRUNCF
:
5185 case BUILT_IN_TRUNCL
:
5186 case BUILT_IN_ROUND
:
5187 case BUILT_IN_ROUNDF
:
5188 case BUILT_IN_ROUNDL
:
5189 case BUILT_IN_NEARBYINT
:
5190 case BUILT_IN_NEARBYINTF
:
5191 case BUILT_IN_NEARBYINTL
:
5192 return fold_trunc_transparent_mathfn (exp
);
5201 /* Conveniently construct a function call expression. */
5204 build_function_call_expr (fn
, arglist
)
5209 call_expr
= build1 (ADDR_EXPR
, build_pointer_type (TREE_TYPE (fn
)), fn
);
5210 call_expr
= build (CALL_EXPR
, TREE_TYPE (TREE_TYPE (fn
)),
5211 call_expr
, arglist
);
5212 TREE_SIDE_EFFECTS (call_expr
) = 1;
5213 return fold (call_expr
);
5216 /* This function validates the types of a function call argument list
5217 represented as a tree chain of parameters against a specified list
5218 of tree_codes. If the last specifier is a 0, that represents an
5219 ellipses, otherwise the last specifier must be a VOID_TYPE. */
5222 validate_arglist
VPARAMS ((tree arglist
, ...))
5224 enum tree_code code
;
5227 VA_OPEN (ap
, arglist
);
5228 VA_FIXEDARG (ap
, tree
, arglist
);
5232 code
= va_arg (ap
, enum tree_code
);
5236 /* This signifies an ellipses, any further arguments are all ok. */
5240 /* This signifies an endlink, if no arguments remain, return
5241 true, otherwise return false. */
5245 /* If no parameters remain or the parameter's code does not
5246 match the specified code, return false. Otherwise continue
5247 checking any remaining arguments. */
5249 || code
!= TREE_CODE (TREE_TYPE (TREE_VALUE (arglist
))))
5253 arglist
= TREE_CHAIN (arglist
);
5257 /* We need gotos here since we can only have one VA_CLOSE in a
5265 /* Default version of target-specific builtin setup that does nothing. */
5268 default_init_builtins ()
5272 /* Default target-specific builtin expander that does nothing. */
5275 default_expand_builtin (exp
, target
, subtarget
, mode
, ignore
)
5276 tree exp ATTRIBUTE_UNUSED
;
5277 rtx target ATTRIBUTE_UNUSED
;
5278 rtx subtarget ATTRIBUTE_UNUSED
;
5279 enum machine_mode mode ATTRIBUTE_UNUSED
;
5280 int ignore ATTRIBUTE_UNUSED
;
5285 /* Instantiate all remaining CONSTANT_P_RTX nodes. */
5288 purge_builtin_constant_p ()
5290 rtx insn
, set
, arg
, new, note
;
5292 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
5294 && (set
= single_set (insn
)) != NULL_RTX
5295 && (GET_CODE (arg
= SET_SRC (set
)) == CONSTANT_P_RTX
5296 || (GET_CODE (arg
) == SUBREG
5297 && (GET_CODE (arg
= SUBREG_REG (arg
))
5298 == CONSTANT_P_RTX
))))
5300 arg
= XEXP (arg
, 0);
5301 new = CONSTANT_P (arg
) ? const1_rtx
: const0_rtx
;
5302 validate_change (insn
, &SET_SRC (set
), new, 0);
5304 /* Remove the REG_EQUAL note from the insn. */
5305 if ((note
= find_reg_note (insn
, REG_EQUAL
, NULL_RTX
)) != 0)
5306 remove_note (insn
, note
);