1 /* Expand builtin functions.
2 Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3 2000, 2001, 2002, 2003, 2004, 2005, 2006 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, 51 Franklin Street, Fifth Floor, Boston, MA
24 #include "coretypes.h"
30 #include "tree-gimple.h"
33 #include "hard-reg-set.h"
36 #include "insn-config.h"
42 #include "typeclass.h"
47 #include "langhooks.h"
48 #include "basic-block.h"
49 #include "tree-mudflap.h"
51 #ifndef PAD_VARARGS_DOWN
52 #define PAD_VARARGS_DOWN BYTES_BIG_ENDIAN
55 /* Define the names of the builtin function types and codes. */
56 const char *const built_in_class_names
[4]
57 = {"NOT_BUILT_IN", "BUILT_IN_FRONTEND", "BUILT_IN_MD", "BUILT_IN_NORMAL"};
59 #define DEF_BUILTIN(X, N, C, T, LT, B, F, NA, AT, IM, COND) #X,
60 const char * built_in_names
[(int) END_BUILTINS
] =
62 #include "builtins.def"
66 /* Setup an array of _DECL trees, make sure each element is
67 initialized to NULL_TREE. */
68 tree built_in_decls
[(int) END_BUILTINS
];
69 /* Declarations used when constructing the builtin implicitly in the compiler.
70 It may be NULL_TREE when this is invalid (for instance runtime is not
71 required to implement the function call in all cases). */
72 tree implicit_built_in_decls
[(int) END_BUILTINS
];
74 static int get_pointer_alignment (tree
, unsigned int);
75 static const char *c_getstr (tree
);
76 static rtx
c_readstr (const char *, enum machine_mode
);
77 static int target_char_cast (tree
, char *);
78 static rtx
get_memory_rtx (tree
, tree
);
79 static int apply_args_size (void);
80 static int apply_result_size (void);
81 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
82 static rtx
result_vector (int, rtx
);
84 static rtx
expand_builtin_setjmp (tree
, rtx
);
85 static void expand_builtin_update_setjmp_buf (rtx
);
86 static void expand_builtin_prefetch (tree
);
87 static rtx
expand_builtin_apply_args (void);
88 static rtx
expand_builtin_apply_args_1 (void);
89 static rtx
expand_builtin_apply (rtx
, rtx
, rtx
);
90 static void expand_builtin_return (rtx
);
91 static enum type_class
type_to_class (tree
);
92 static rtx
expand_builtin_classify_type (tree
);
93 static void expand_errno_check (tree
, rtx
);
94 static rtx
expand_builtin_mathfn (tree
, rtx
, rtx
);
95 static rtx
expand_builtin_mathfn_2 (tree
, rtx
, rtx
);
96 static rtx
expand_builtin_mathfn_3 (tree
, rtx
, rtx
);
97 static rtx
expand_builtin_sincos (tree
);
98 static rtx
expand_builtin_int_roundingfn (tree
, rtx
, rtx
);
99 static rtx
expand_builtin_args_info (tree
);
100 static rtx
expand_builtin_next_arg (void);
101 static rtx
expand_builtin_va_start (tree
);
102 static rtx
expand_builtin_va_end (tree
);
103 static rtx
expand_builtin_va_copy (tree
);
104 static rtx
expand_builtin_memcmp (tree
, tree
, rtx
, enum machine_mode
);
105 static rtx
expand_builtin_strcmp (tree
, rtx
, enum machine_mode
);
106 static rtx
expand_builtin_strncmp (tree
, rtx
, enum machine_mode
);
107 static rtx
builtin_memcpy_read_str (void *, HOST_WIDE_INT
, enum machine_mode
);
108 static rtx
expand_builtin_strcat (tree
, tree
, rtx
, enum machine_mode
);
109 static rtx
expand_builtin_strncat (tree
, rtx
, enum machine_mode
);
110 static rtx
expand_builtin_strspn (tree
, rtx
, enum machine_mode
);
111 static rtx
expand_builtin_strcspn (tree
, rtx
, enum machine_mode
);
112 static rtx
expand_builtin_memcpy (tree
, rtx
, enum machine_mode
);
113 static rtx
expand_builtin_mempcpy (tree
, tree
, rtx
, enum machine_mode
, int);
114 static rtx
expand_builtin_memmove (tree
, tree
, rtx
, enum machine_mode
, tree
);
115 static rtx
expand_builtin_bcopy (tree
);
116 static rtx
expand_builtin_strcpy (tree
, tree
, rtx
, enum machine_mode
);
117 static rtx
expand_builtin_stpcpy (tree
, rtx
, enum machine_mode
);
118 static rtx
builtin_strncpy_read_str (void *, HOST_WIDE_INT
, enum machine_mode
);
119 static rtx
expand_builtin_strncpy (tree
, rtx
, enum machine_mode
);
120 static rtx
builtin_memset_read_str (void *, HOST_WIDE_INT
, enum machine_mode
);
121 static rtx
builtin_memset_gen_str (void *, HOST_WIDE_INT
, enum machine_mode
);
122 static rtx
expand_builtin_memset (tree
, rtx
, enum machine_mode
, tree
);
123 static rtx
expand_builtin_bzero (tree
);
124 static rtx
expand_builtin_strlen (tree
, rtx
, enum machine_mode
);
125 static rtx
expand_builtin_strstr (tree
, tree
, rtx
, enum machine_mode
);
126 static rtx
expand_builtin_strpbrk (tree
, tree
, rtx
, enum machine_mode
);
127 static rtx
expand_builtin_strchr (tree
, tree
, rtx
, enum machine_mode
);
128 static rtx
expand_builtin_strrchr (tree
, tree
, rtx
, enum machine_mode
);
129 static rtx
expand_builtin_alloca (tree
, rtx
);
130 static rtx
expand_builtin_unop (enum machine_mode
, tree
, rtx
, rtx
, optab
);
131 static rtx
expand_builtin_frame_address (tree
, tree
);
132 static rtx
expand_builtin_fputs (tree
, rtx
, bool);
133 static rtx
expand_builtin_printf (tree
, rtx
, enum machine_mode
, bool);
134 static rtx
expand_builtin_fprintf (tree
, rtx
, enum machine_mode
, bool);
135 static rtx
expand_builtin_sprintf (tree
, rtx
, enum machine_mode
);
136 static tree
stabilize_va_list (tree
, int);
137 static rtx
expand_builtin_expect (tree
, rtx
);
138 static tree
fold_builtin_constant_p (tree
);
139 static tree
fold_builtin_classify_type (tree
);
140 static tree
fold_builtin_strlen (tree
);
141 static tree
fold_builtin_inf (tree
, int);
142 static tree
fold_builtin_nan (tree
, tree
, int);
143 static int validate_arglist (tree
, ...);
144 static bool integer_valued_real_p (tree
);
145 static tree
fold_trunc_transparent_mathfn (tree
, tree
);
146 static bool readonly_data_expr (tree
);
147 static rtx
expand_builtin_fabs (tree
, rtx
, rtx
);
148 static rtx
expand_builtin_signbit (tree
, rtx
);
149 static tree
fold_builtin_cabs (tree
, tree
);
150 static tree
fold_builtin_sqrt (tree
, tree
);
151 static tree
fold_builtin_cbrt (tree
, tree
);
152 static tree
fold_builtin_pow (tree
, tree
, tree
);
153 static tree
fold_builtin_powi (tree
, tree
, tree
);
154 static tree
fold_builtin_sin (tree
);
155 static tree
fold_builtin_cos (tree
, tree
, tree
);
156 static tree
fold_builtin_tan (tree
);
157 static tree
fold_builtin_atan (tree
, tree
);
158 static tree
fold_builtin_trunc (tree
, tree
);
159 static tree
fold_builtin_floor (tree
, tree
);
160 static tree
fold_builtin_ceil (tree
, tree
);
161 static tree
fold_builtin_round (tree
, tree
);
162 static tree
fold_builtin_int_roundingfn (tree
, tree
);
163 static tree
fold_builtin_bitop (tree
, tree
);
164 static tree
fold_builtin_memcpy (tree
, tree
);
165 static tree
fold_builtin_mempcpy (tree
, tree
, int);
166 static tree
fold_builtin_memmove (tree
, tree
);
167 static tree
fold_builtin_strchr (tree
, tree
);
168 static tree
fold_builtin_memcmp (tree
);
169 static tree
fold_builtin_strcmp (tree
);
170 static tree
fold_builtin_strncmp (tree
);
171 static tree
fold_builtin_signbit (tree
, tree
);
172 static tree
fold_builtin_copysign (tree
, tree
, tree
);
173 static tree
fold_builtin_isascii (tree
);
174 static tree
fold_builtin_toascii (tree
);
175 static tree
fold_builtin_isdigit (tree
);
176 static tree
fold_builtin_fabs (tree
, tree
);
177 static tree
fold_builtin_abs (tree
, tree
);
178 static tree
fold_builtin_unordered_cmp (tree
, tree
, enum tree_code
,
180 static tree
fold_builtin_1 (tree
, tree
, bool);
182 static tree
fold_builtin_strpbrk (tree
, tree
);
183 static tree
fold_builtin_strstr (tree
, tree
);
184 static tree
fold_builtin_strrchr (tree
, tree
);
185 static tree
fold_builtin_strcat (tree
);
186 static tree
fold_builtin_strncat (tree
);
187 static tree
fold_builtin_strspn (tree
);
188 static tree
fold_builtin_strcspn (tree
);
189 static tree
fold_builtin_sprintf (tree
, int);
191 static rtx
expand_builtin_object_size (tree
);
192 static rtx
expand_builtin_memory_chk (tree
, rtx
, enum machine_mode
,
193 enum built_in_function
);
194 static void maybe_emit_chk_warning (tree
, enum built_in_function
);
195 static void maybe_emit_sprintf_chk_warning (tree
, enum built_in_function
);
196 static tree
fold_builtin_object_size (tree
);
197 static tree
fold_builtin_strcat_chk (tree
, tree
);
198 static tree
fold_builtin_strncat_chk (tree
, tree
);
199 static tree
fold_builtin_sprintf_chk (tree
, enum built_in_function
);
200 static tree
fold_builtin_printf (tree
, tree
, bool, enum built_in_function
);
201 static tree
fold_builtin_fprintf (tree
, tree
, bool, enum built_in_function
);
202 static bool init_target_chars (void);
204 static unsigned HOST_WIDE_INT target_newline
;
205 static unsigned HOST_WIDE_INT target_percent
;
206 static unsigned HOST_WIDE_INT target_c
;
207 static unsigned HOST_WIDE_INT target_s
;
208 static char target_percent_c
[3];
209 static char target_percent_s
[3];
210 static char target_percent_s_newline
[4];
212 /* Return true if NODE should be considered for inline expansion regardless
213 of the optimization level. This means whenever a function is invoked with
214 its "internal" name, which normally contains the prefix "__builtin". */
216 static bool called_as_built_in (tree node
)
218 const char *name
= IDENTIFIER_POINTER (DECL_NAME (node
));
219 if (strncmp (name
, "__builtin_", 10) == 0)
221 if (strncmp (name
, "__sync_", 7) == 0)
226 /* Return the alignment in bits of EXP, a pointer valued expression.
227 But don't return more than MAX_ALIGN no matter what.
228 The alignment returned is, by default, the alignment of the thing that
229 EXP points to. If it is not a POINTER_TYPE, 0 is returned.
231 Otherwise, look at the expression to see if we can do better, i.e., if the
232 expression is actually pointing at an object whose alignment is tighter. */
235 get_pointer_alignment (tree exp
, unsigned int max_align
)
237 unsigned int align
, inner
;
239 if (! POINTER_TYPE_P (TREE_TYPE (exp
)))
242 align
= TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp
)));
243 align
= MIN (align
, max_align
);
247 switch (TREE_CODE (exp
))
251 case NON_LVALUE_EXPR
:
252 exp
= TREE_OPERAND (exp
, 0);
253 if (! POINTER_TYPE_P (TREE_TYPE (exp
)))
256 inner
= TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp
)));
257 align
= MIN (inner
, max_align
);
261 /* If sum of pointer + int, restrict our maximum alignment to that
262 imposed by the integer. If not, we can't do any better than
264 if (! host_integerp (TREE_OPERAND (exp
, 1), 1))
267 while (((tree_low_cst (TREE_OPERAND (exp
, 1), 1))
268 & (max_align
/ BITS_PER_UNIT
- 1))
272 exp
= TREE_OPERAND (exp
, 0);
276 /* See what we are pointing at and look at its alignment. */
277 exp
= TREE_OPERAND (exp
, 0);
278 while (handled_component_p (exp
))
280 if (TREE_CODE (exp
) == COMPONENT_REF
)
281 align
= MIN (align
, DECL_ALIGN (TREE_OPERAND (exp
, 1)));
282 exp
= TREE_OPERAND (exp
, 0);
284 if (TREE_CODE (exp
) == FUNCTION_DECL
)
285 align
= MIN (align
, FUNCTION_BOUNDARY
);
286 else if (DECL_P (exp
))
287 align
= MIN (align
, DECL_ALIGN (exp
));
288 #ifdef CONSTANT_ALIGNMENT
289 else if (CONSTANT_CLASS_P (exp
))
290 align
= MIN (align
, (unsigned)CONSTANT_ALIGNMENT (exp
, align
));
300 /* Compute the length of a C string. TREE_STRING_LENGTH is not the right
301 way, because it could contain a zero byte in the middle.
302 TREE_STRING_LENGTH is the size of the character array, not the string.
304 ONLY_VALUE should be nonzero if the result is not going to be emitted
305 into the instruction stream and zero if it is going to be expanded.
306 E.g. with i++ ? "foo" : "bar", if ONLY_VALUE is nonzero, constant 3
307 is returned, otherwise NULL, since
308 len = c_strlen (src, 1); if (len) expand_expr (len, ...); would not
309 evaluate the side-effects.
311 The value returned is of type `ssizetype'.
313 Unfortunately, string_constant can't access the values of const char
314 arrays with initializers, so neither can we do so here. */
317 c_strlen (tree src
, int only_value
)
320 HOST_WIDE_INT offset
;
325 if (TREE_CODE (src
) == COND_EXPR
326 && (only_value
|| !TREE_SIDE_EFFECTS (TREE_OPERAND (src
, 0))))
330 len1
= c_strlen (TREE_OPERAND (src
, 1), only_value
);
331 len2
= c_strlen (TREE_OPERAND (src
, 2), only_value
);
332 if (tree_int_cst_equal (len1
, len2
))
336 if (TREE_CODE (src
) == COMPOUND_EXPR
337 && (only_value
|| !TREE_SIDE_EFFECTS (TREE_OPERAND (src
, 0))))
338 return c_strlen (TREE_OPERAND (src
, 1), only_value
);
340 src
= string_constant (src
, &offset_node
);
344 max
= TREE_STRING_LENGTH (src
) - 1;
345 ptr
= TREE_STRING_POINTER (src
);
347 if (offset_node
&& TREE_CODE (offset_node
) != INTEGER_CST
)
349 /* If the string has an internal zero byte (e.g., "foo\0bar"), we can't
350 compute the offset to the following null if we don't know where to
351 start searching for it. */
354 for (i
= 0; i
< max
; i
++)
358 /* We don't know the starting offset, but we do know that the string
359 has no internal zero bytes. We can assume that the offset falls
360 within the bounds of the string; otherwise, the programmer deserves
361 what he gets. Subtract the offset from the length of the string,
362 and return that. This would perhaps not be valid if we were dealing
363 with named arrays in addition to literal string constants. */
365 return size_diffop (size_int (max
), offset_node
);
368 /* We have a known offset into the string. Start searching there for
369 a null character if we can represent it as a single HOST_WIDE_INT. */
370 if (offset_node
== 0)
372 else if (! host_integerp (offset_node
, 0))
375 offset
= tree_low_cst (offset_node
, 0);
377 /* If the offset is known to be out of bounds, warn, and call strlen at
379 if (offset
< 0 || offset
> max
)
381 warning (0, "offset outside bounds of constant string");
385 /* Use strlen to search for the first zero byte. Since any strings
386 constructed with build_string will have nulls appended, we win even
387 if we get handed something like (char[4])"abcd".
389 Since OFFSET is our starting index into the string, no further
390 calculation is needed. */
391 return ssize_int (strlen (ptr
+ offset
));
394 /* Return a char pointer for a C string if it is a string constant
395 or sum of string constant and integer constant. */
402 src
= string_constant (src
, &offset_node
);
406 if (offset_node
== 0)
407 return TREE_STRING_POINTER (src
);
408 else if (!host_integerp (offset_node
, 1)
409 || compare_tree_int (offset_node
, TREE_STRING_LENGTH (src
) - 1) > 0)
412 return TREE_STRING_POINTER (src
) + tree_low_cst (offset_node
, 1);
415 /* Return a CONST_INT or CONST_DOUBLE corresponding to target reading
416 GET_MODE_BITSIZE (MODE) bits from string constant STR. */
419 c_readstr (const char *str
, enum machine_mode mode
)
425 gcc_assert (GET_MODE_CLASS (mode
) == MODE_INT
);
430 for (i
= 0; i
< GET_MODE_SIZE (mode
); i
++)
433 if (WORDS_BIG_ENDIAN
)
434 j
= GET_MODE_SIZE (mode
) - i
- 1;
435 if (BYTES_BIG_ENDIAN
!= WORDS_BIG_ENDIAN
436 && GET_MODE_SIZE (mode
) > UNITS_PER_WORD
)
437 j
= j
+ UNITS_PER_WORD
- 2 * (j
% UNITS_PER_WORD
) - 1;
439 gcc_assert (j
<= 2 * HOST_BITS_PER_WIDE_INT
);
442 ch
= (unsigned char) str
[i
];
443 c
[j
/ HOST_BITS_PER_WIDE_INT
] |= ch
<< (j
% HOST_BITS_PER_WIDE_INT
);
445 return immed_double_const (c
[0], c
[1], mode
);
448 /* Cast a target constant CST to target CHAR and if that value fits into
449 host char type, return zero and put that value into variable pointed to by
453 target_char_cast (tree cst
, char *p
)
455 unsigned HOST_WIDE_INT val
, hostval
;
457 if (!host_integerp (cst
, 1)
458 || CHAR_TYPE_SIZE
> HOST_BITS_PER_WIDE_INT
)
461 val
= tree_low_cst (cst
, 1);
462 if (CHAR_TYPE_SIZE
< HOST_BITS_PER_WIDE_INT
)
463 val
&= (((unsigned HOST_WIDE_INT
) 1) << CHAR_TYPE_SIZE
) - 1;
466 if (HOST_BITS_PER_CHAR
< HOST_BITS_PER_WIDE_INT
)
467 hostval
&= (((unsigned HOST_WIDE_INT
) 1) << HOST_BITS_PER_CHAR
) - 1;
476 /* Similar to save_expr, but assumes that arbitrary code is not executed
477 in between the multiple evaluations. In particular, we assume that a
478 non-addressable local variable will not be modified. */
481 builtin_save_expr (tree exp
)
483 if (TREE_ADDRESSABLE (exp
) == 0
484 && (TREE_CODE (exp
) == PARM_DECL
485 || (TREE_CODE (exp
) == VAR_DECL
&& !TREE_STATIC (exp
))))
488 return save_expr (exp
);
491 /* Given TEM, a pointer to a stack frame, follow the dynamic chain COUNT
492 times to get the address of either a higher stack frame, or a return
493 address located within it (depending on FNDECL_CODE). */
496 expand_builtin_return_addr (enum built_in_function fndecl_code
, int count
)
500 #ifdef INITIAL_FRAME_ADDRESS_RTX
501 rtx tem
= INITIAL_FRAME_ADDRESS_RTX
;
505 /* For a zero count, we don't care what frame address we return, so frame
506 pointer elimination is OK, and using the soft frame pointer is OK.
507 For a nonzero count, we require a stable offset from the current frame
508 pointer to the previous one, so we must use the hard frame pointer, and
509 we must disable frame pointer elimination. */
511 tem
= frame_pointer_rtx
;
514 tem
= hard_frame_pointer_rtx
;
516 /* Tell reload not to eliminate the frame pointer. */
517 current_function_accesses_prior_frames
= 1;
521 /* Some machines need special handling before we can access
522 arbitrary frames. For example, on the sparc, we must first flush
523 all register windows to the stack. */
524 #ifdef SETUP_FRAME_ADDRESSES
526 SETUP_FRAME_ADDRESSES ();
529 /* On the sparc, the return address is not in the frame, it is in a
530 register. There is no way to access it off of the current frame
531 pointer, but it can be accessed off the previous frame pointer by
532 reading the value from the register window save area. */
533 #ifdef RETURN_ADDR_IN_PREVIOUS_FRAME
534 if (fndecl_code
== BUILT_IN_RETURN_ADDRESS
)
538 /* Scan back COUNT frames to the specified frame. */
539 for (i
= 0; i
< count
; i
++)
541 /* Assume the dynamic chain pointer is in the word that the
542 frame address points to, unless otherwise specified. */
543 #ifdef DYNAMIC_CHAIN_ADDRESS
544 tem
= DYNAMIC_CHAIN_ADDRESS (tem
);
546 tem
= memory_address (Pmode
, tem
);
547 tem
= gen_frame_mem (Pmode
, tem
);
548 tem
= copy_to_reg (tem
);
551 /* For __builtin_frame_address, return what we've got. */
552 if (fndecl_code
== BUILT_IN_FRAME_ADDRESS
)
555 /* For __builtin_return_address, Get the return address from that
557 #ifdef RETURN_ADDR_RTX
558 tem
= RETURN_ADDR_RTX (count
, tem
);
560 tem
= memory_address (Pmode
,
561 plus_constant (tem
, GET_MODE_SIZE (Pmode
)));
562 tem
= gen_frame_mem (Pmode
, tem
);
567 /* Alias set used for setjmp buffer. */
568 static HOST_WIDE_INT setjmp_alias_set
= -1;
570 /* Construct the leading half of a __builtin_setjmp call. Control will
571 return to RECEIVER_LABEL. This is used directly by sjlj exception
575 expand_builtin_setjmp_setup (rtx buf_addr
, rtx receiver_label
)
577 enum machine_mode sa_mode
= STACK_SAVEAREA_MODE (SAVE_NONLOCAL
);
581 if (setjmp_alias_set
== -1)
582 setjmp_alias_set
= new_alias_set ();
584 buf_addr
= convert_memory_address (Pmode
, buf_addr
);
586 buf_addr
= force_reg (Pmode
, force_operand (buf_addr
, NULL_RTX
));
588 /* We store the frame pointer and the address of receiver_label in
589 the buffer and use the rest of it for the stack save area, which
590 is machine-dependent. */
592 mem
= gen_rtx_MEM (Pmode
, buf_addr
);
593 set_mem_alias_set (mem
, setjmp_alias_set
);
594 emit_move_insn (mem
, targetm
.builtin_setjmp_frame_value ());
596 mem
= gen_rtx_MEM (Pmode
, plus_constant (buf_addr
, GET_MODE_SIZE (Pmode
))),
597 set_mem_alias_set (mem
, setjmp_alias_set
);
599 emit_move_insn (validize_mem (mem
),
600 force_reg (Pmode
, gen_rtx_LABEL_REF (Pmode
, receiver_label
)));
602 stack_save
= gen_rtx_MEM (sa_mode
,
603 plus_constant (buf_addr
,
604 2 * GET_MODE_SIZE (Pmode
)));
605 set_mem_alias_set (stack_save
, setjmp_alias_set
);
606 emit_stack_save (SAVE_NONLOCAL
, &stack_save
, NULL_RTX
);
608 /* If there is further processing to do, do it. */
609 #ifdef HAVE_builtin_setjmp_setup
610 if (HAVE_builtin_setjmp_setup
)
611 emit_insn (gen_builtin_setjmp_setup (buf_addr
));
614 /* Tell optimize_save_area_alloca that extra work is going to
615 need to go on during alloca. */
616 current_function_calls_setjmp
= 1;
618 /* Set this so all the registers get saved in our frame; we need to be
619 able to copy the saved values for any registers from frames we unwind. */
620 current_function_has_nonlocal_label
= 1;
623 /* Construct the trailing part of a __builtin_setjmp call.
624 This is used directly by sjlj exception handling code. */
627 expand_builtin_setjmp_receiver (rtx receiver_label ATTRIBUTE_UNUSED
)
629 /* Clobber the FP when we get here, so we have to make sure it's
630 marked as used by this function. */
631 emit_insn (gen_rtx_USE (VOIDmode
, hard_frame_pointer_rtx
));
633 /* Mark the static chain as clobbered here so life information
634 doesn't get messed up for it. */
635 emit_insn (gen_rtx_CLOBBER (VOIDmode
, static_chain_rtx
));
637 /* Now put in the code to restore the frame pointer, and argument
638 pointer, if needed. */
639 #ifdef HAVE_nonlocal_goto
640 if (! HAVE_nonlocal_goto
)
642 emit_move_insn (virtual_stack_vars_rtx
, hard_frame_pointer_rtx
);
644 #if ARG_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
645 if (fixed_regs
[ARG_POINTER_REGNUM
])
647 #ifdef ELIMINABLE_REGS
649 static const struct elims
{const int from
, to
;} elim_regs
[] = ELIMINABLE_REGS
;
651 for (i
= 0; i
< ARRAY_SIZE (elim_regs
); i
++)
652 if (elim_regs
[i
].from
== ARG_POINTER_REGNUM
653 && elim_regs
[i
].to
== HARD_FRAME_POINTER_REGNUM
)
656 if (i
== ARRAY_SIZE (elim_regs
))
659 /* Now restore our arg pointer from the address at which it
660 was saved in our stack frame. */
661 emit_move_insn (virtual_incoming_args_rtx
,
662 copy_to_reg (get_arg_pointer_save_area (cfun
)));
667 #ifdef HAVE_builtin_setjmp_receiver
668 if (HAVE_builtin_setjmp_receiver
)
669 emit_insn (gen_builtin_setjmp_receiver (receiver_label
));
672 #ifdef HAVE_nonlocal_goto_receiver
673 if (HAVE_nonlocal_goto_receiver
)
674 emit_insn (gen_nonlocal_goto_receiver ());
679 /* @@@ This is a kludge. Not all machine descriptions define a blockage
680 insn, but we must not allow the code we just generated to be reordered
681 by scheduling. Specifically, the update of the frame pointer must
682 happen immediately, not later. So emit an ASM_INPUT to act as blockage
684 emit_insn (gen_rtx_ASM_INPUT (VOIDmode
, ""));
687 /* __builtin_setjmp is passed a pointer to an array of five words (not
688 all will be used on all machines). It operates similarly to the C
689 library function of the same name, but is more efficient. Much of
690 the code below (and for longjmp) is copied from the handling of
693 NOTE: This is intended for use by GNAT and the exception handling
694 scheme in the compiler and will only work in the method used by
698 expand_builtin_setjmp (tree arglist
, rtx target
)
700 rtx buf_addr
, next_lab
, cont_lab
;
702 if (!validate_arglist (arglist
, POINTER_TYPE
, VOID_TYPE
))
705 if (target
== 0 || !REG_P (target
)
706 || REGNO (target
) < FIRST_PSEUDO_REGISTER
)
707 target
= gen_reg_rtx (TYPE_MODE (integer_type_node
));
709 buf_addr
= expand_normal (TREE_VALUE (arglist
));
711 next_lab
= gen_label_rtx ();
712 cont_lab
= gen_label_rtx ();
714 expand_builtin_setjmp_setup (buf_addr
, next_lab
);
716 /* Set TARGET to zero and branch to the continue label. Use emit_jump to
717 ensure that pending stack adjustments are flushed. */
718 emit_move_insn (target
, const0_rtx
);
719 emit_jump (cont_lab
);
721 emit_label (next_lab
);
723 expand_builtin_setjmp_receiver (next_lab
);
725 /* Set TARGET to one. */
726 emit_move_insn (target
, const1_rtx
);
727 emit_label (cont_lab
);
729 /* Tell flow about the strange goings on. Putting `next_lab' on
730 `nonlocal_goto_handler_labels' to indicates that function
731 calls may traverse the arc back to this label. */
733 current_function_has_nonlocal_label
= 1;
734 nonlocal_goto_handler_labels
735 = gen_rtx_EXPR_LIST (VOIDmode
, next_lab
, nonlocal_goto_handler_labels
);
740 /* __builtin_longjmp is passed a pointer to an array of five words (not
741 all will be used on all machines). It operates similarly to the C
742 library function of the same name, but is more efficient. Much of
743 the code below is copied from the handling of non-local gotos.
745 NOTE: This is intended for use by GNAT and the exception handling
746 scheme in the compiler and will only work in the method used by
750 expand_builtin_longjmp (rtx buf_addr
, rtx value
)
752 rtx fp
, lab
, stack
, insn
, last
;
753 enum machine_mode sa_mode
= STACK_SAVEAREA_MODE (SAVE_NONLOCAL
);
755 if (setjmp_alias_set
== -1)
756 setjmp_alias_set
= new_alias_set ();
758 buf_addr
= convert_memory_address (Pmode
, buf_addr
);
760 buf_addr
= force_reg (Pmode
, buf_addr
);
762 /* We used to store value in static_chain_rtx, but that fails if pointers
763 are smaller than integers. We instead require that the user must pass
764 a second argument of 1, because that is what builtin_setjmp will
765 return. This also makes EH slightly more efficient, since we are no
766 longer copying around a value that we don't care about. */
767 gcc_assert (value
== const1_rtx
);
769 last
= get_last_insn ();
770 #ifdef HAVE_builtin_longjmp
771 if (HAVE_builtin_longjmp
)
772 emit_insn (gen_builtin_longjmp (buf_addr
));
776 fp
= gen_rtx_MEM (Pmode
, buf_addr
);
777 lab
= gen_rtx_MEM (Pmode
, plus_constant (buf_addr
,
778 GET_MODE_SIZE (Pmode
)));
780 stack
= gen_rtx_MEM (sa_mode
, plus_constant (buf_addr
,
781 2 * GET_MODE_SIZE (Pmode
)));
782 set_mem_alias_set (fp
, setjmp_alias_set
);
783 set_mem_alias_set (lab
, setjmp_alias_set
);
784 set_mem_alias_set (stack
, setjmp_alias_set
);
786 /* Pick up FP, label, and SP from the block and jump. This code is
787 from expand_goto in stmt.c; see there for detailed comments. */
788 #if HAVE_nonlocal_goto
789 if (HAVE_nonlocal_goto
)
790 /* We have to pass a value to the nonlocal_goto pattern that will
791 get copied into the static_chain pointer, but it does not matter
792 what that value is, because builtin_setjmp does not use it. */
793 emit_insn (gen_nonlocal_goto (value
, lab
, stack
, fp
));
797 lab
= copy_to_reg (lab
);
799 emit_insn (gen_rtx_CLOBBER (VOIDmode
,
800 gen_rtx_MEM (BLKmode
,
801 gen_rtx_SCRATCH (VOIDmode
))));
802 emit_insn (gen_rtx_CLOBBER (VOIDmode
,
803 gen_rtx_MEM (BLKmode
,
804 hard_frame_pointer_rtx
)));
806 emit_move_insn (hard_frame_pointer_rtx
, fp
);
807 emit_stack_restore (SAVE_NONLOCAL
, stack
, NULL_RTX
);
809 emit_insn (gen_rtx_USE (VOIDmode
, hard_frame_pointer_rtx
));
810 emit_insn (gen_rtx_USE (VOIDmode
, stack_pointer_rtx
));
811 emit_indirect_jump (lab
);
815 /* Search backwards and mark the jump insn as a non-local goto.
816 Note that this precludes the use of __builtin_longjmp to a
817 __builtin_setjmp target in the same function. However, we've
818 already cautioned the user that these functions are for
819 internal exception handling use only. */
820 for (insn
= get_last_insn (); insn
; insn
= PREV_INSN (insn
))
822 gcc_assert (insn
!= last
);
826 REG_NOTES (insn
) = alloc_EXPR_LIST (REG_NON_LOCAL_GOTO
, const0_rtx
,
830 else if (CALL_P (insn
))
835 /* Expand a call to __builtin_nonlocal_goto. We're passed the target label
836 and the address of the save area. */
839 expand_builtin_nonlocal_goto (tree arglist
)
841 tree t_label
, t_save_area
;
842 rtx r_label
, r_save_area
, r_fp
, r_sp
, insn
;
844 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
847 t_label
= TREE_VALUE (arglist
);
848 arglist
= TREE_CHAIN (arglist
);
849 t_save_area
= TREE_VALUE (arglist
);
851 r_label
= expand_normal (t_label
);
852 r_label
= convert_memory_address (Pmode
, r_label
);
853 r_save_area
= expand_normal (t_save_area
);
854 r_save_area
= convert_memory_address (Pmode
, r_save_area
);
855 r_fp
= gen_rtx_MEM (Pmode
, r_save_area
);
856 r_sp
= gen_rtx_MEM (STACK_SAVEAREA_MODE (SAVE_NONLOCAL
),
857 plus_constant (r_save_area
, GET_MODE_SIZE (Pmode
)));
859 current_function_has_nonlocal_goto
= 1;
861 #if HAVE_nonlocal_goto
862 /* ??? We no longer need to pass the static chain value, afaik. */
863 if (HAVE_nonlocal_goto
)
864 emit_insn (gen_nonlocal_goto (const0_rtx
, r_label
, r_sp
, r_fp
));
868 r_label
= copy_to_reg (r_label
);
870 emit_insn (gen_rtx_CLOBBER (VOIDmode
,
871 gen_rtx_MEM (BLKmode
,
872 gen_rtx_SCRATCH (VOIDmode
))));
874 emit_insn (gen_rtx_CLOBBER (VOIDmode
,
875 gen_rtx_MEM (BLKmode
,
876 hard_frame_pointer_rtx
)));
878 /* Restore frame pointer for containing function.
879 This sets the actual hard register used for the frame pointer
880 to the location of the function's incoming static chain info.
881 The non-local goto handler will then adjust it to contain the
882 proper value and reload the argument pointer, if needed. */
883 emit_move_insn (hard_frame_pointer_rtx
, r_fp
);
884 emit_stack_restore (SAVE_NONLOCAL
, r_sp
, NULL_RTX
);
886 /* USE of hard_frame_pointer_rtx added for consistency;
887 not clear if really needed. */
888 emit_insn (gen_rtx_USE (VOIDmode
, hard_frame_pointer_rtx
));
889 emit_insn (gen_rtx_USE (VOIDmode
, stack_pointer_rtx
));
890 emit_indirect_jump (r_label
);
893 /* Search backwards to the jump insn and mark it as a
895 for (insn
= get_last_insn (); insn
; insn
= PREV_INSN (insn
))
899 REG_NOTES (insn
) = alloc_EXPR_LIST (REG_NON_LOCAL_GOTO
,
900 const0_rtx
, REG_NOTES (insn
));
903 else if (CALL_P (insn
))
910 /* __builtin_update_setjmp_buf is passed a pointer to an array of five words
911 (not all will be used on all machines) that was passed to __builtin_setjmp.
912 It updates the stack pointer in that block to correspond to the current
916 expand_builtin_update_setjmp_buf (rtx buf_addr
)
918 enum machine_mode sa_mode
= Pmode
;
922 #ifdef HAVE_save_stack_nonlocal
923 if (HAVE_save_stack_nonlocal
)
924 sa_mode
= insn_data
[(int) CODE_FOR_save_stack_nonlocal
].operand
[0].mode
;
926 #ifdef STACK_SAVEAREA_MODE
927 sa_mode
= STACK_SAVEAREA_MODE (SAVE_NONLOCAL
);
931 = gen_rtx_MEM (sa_mode
,
934 plus_constant (buf_addr
, 2 * GET_MODE_SIZE (Pmode
))));
938 emit_insn (gen_setjmp ());
941 emit_stack_save (SAVE_NONLOCAL
, &stack_save
, NULL_RTX
);
944 /* Expand a call to __builtin_prefetch. For a target that does not support
945 data prefetch, evaluate the memory address argument in case it has side
949 expand_builtin_prefetch (tree arglist
)
951 tree arg0
, arg1
, arg2
;
954 if (!validate_arglist (arglist
, POINTER_TYPE
, 0))
957 arg0
= TREE_VALUE (arglist
);
958 /* Arguments 1 and 2 are optional; argument 1 (read/write) defaults to
959 zero (read) and argument 2 (locality) defaults to 3 (high degree of
961 if (TREE_CHAIN (arglist
))
963 arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
964 if (TREE_CHAIN (TREE_CHAIN (arglist
)))
965 arg2
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
967 arg2
= build_int_cst (NULL_TREE
, 3);
971 arg1
= integer_zero_node
;
972 arg2
= build_int_cst (NULL_TREE
, 3);
975 /* Argument 0 is an address. */
976 op0
= expand_expr (arg0
, NULL_RTX
, Pmode
, EXPAND_NORMAL
);
978 /* Argument 1 (read/write flag) must be a compile-time constant int. */
979 if (TREE_CODE (arg1
) != INTEGER_CST
)
981 error ("second argument to %<__builtin_prefetch%> must be a constant");
982 arg1
= integer_zero_node
;
984 op1
= expand_normal (arg1
);
985 /* Argument 1 must be either zero or one. */
986 if (INTVAL (op1
) != 0 && INTVAL (op1
) != 1)
988 warning (0, "invalid second argument to %<__builtin_prefetch%>;"
993 /* Argument 2 (locality) must be a compile-time constant int. */
994 if (TREE_CODE (arg2
) != INTEGER_CST
)
996 error ("third argument to %<__builtin_prefetch%> must be a constant");
997 arg2
= integer_zero_node
;
999 op2
= expand_normal (arg2
);
1000 /* Argument 2 must be 0, 1, 2, or 3. */
1001 if (INTVAL (op2
) < 0 || INTVAL (op2
) > 3)
1003 warning (0, "invalid third argument to %<__builtin_prefetch%>; using zero");
1007 #ifdef HAVE_prefetch
1010 if ((! (*insn_data
[(int) CODE_FOR_prefetch
].operand
[0].predicate
)
1012 insn_data
[(int) CODE_FOR_prefetch
].operand
[0].mode
))
1013 || (GET_MODE (op0
) != Pmode
))
1015 op0
= convert_memory_address (Pmode
, op0
);
1016 op0
= force_reg (Pmode
, op0
);
1018 emit_insn (gen_prefetch (op0
, op1
, op2
));
1022 /* Don't do anything with direct references to volatile memory, but
1023 generate code to handle other side effects. */
1024 if (!MEM_P (op0
) && side_effects_p (op0
))
1028 /* Get a MEM rtx for expression EXP which is the address of an operand
1029 to be used in a string instruction (cmpstrsi, movmemsi, ..). LEN is
1030 the maximum length of the block of memory that might be accessed or
1034 get_memory_rtx (tree exp
, tree len
)
1036 rtx addr
= expand_expr (exp
, NULL_RTX
, ptr_mode
, EXPAND_NORMAL
);
1037 rtx mem
= gen_rtx_MEM (BLKmode
, memory_address (BLKmode
, addr
));
1039 /* Get an expression we can use to find the attributes to assign to MEM.
1040 If it is an ADDR_EXPR, use the operand. Otherwise, dereference it if
1041 we can. First remove any nops. */
1042 while ((TREE_CODE (exp
) == NOP_EXPR
|| TREE_CODE (exp
) == CONVERT_EXPR
1043 || TREE_CODE (exp
) == NON_LVALUE_EXPR
)
1044 && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (exp
, 0))))
1045 exp
= TREE_OPERAND (exp
, 0);
1047 if (TREE_CODE (exp
) == ADDR_EXPR
)
1048 exp
= TREE_OPERAND (exp
, 0);
1049 else if (POINTER_TYPE_P (TREE_TYPE (exp
)))
1050 exp
= build1 (INDIRECT_REF
, TREE_TYPE (TREE_TYPE (exp
)), exp
);
1054 /* Honor attributes derived from exp, except for the alias set
1055 (as builtin stringops may alias with anything) and the size
1056 (as stringops may access multiple array elements). */
1059 set_mem_attributes (mem
, exp
, 0);
1061 /* Allow the string and memory builtins to overflow from one
1062 field into another, see http://gcc.gnu.org/PR23561.
1063 Thus avoid COMPONENT_REFs in MEM_EXPR unless we know the whole
1064 memory accessed by the string or memory builtin will fit
1065 within the field. */
1066 if (MEM_EXPR (mem
) && TREE_CODE (MEM_EXPR (mem
)) == COMPONENT_REF
)
1068 tree mem_expr
= MEM_EXPR (mem
);
1069 HOST_WIDE_INT offset
= -1, length
= -1;
1072 while (TREE_CODE (inner
) == ARRAY_REF
1073 || TREE_CODE (inner
) == NOP_EXPR
1074 || TREE_CODE (inner
) == CONVERT_EXPR
1075 || TREE_CODE (inner
) == NON_LVALUE_EXPR
1076 || TREE_CODE (inner
) == VIEW_CONVERT_EXPR
1077 || TREE_CODE (inner
) == SAVE_EXPR
)
1078 inner
= TREE_OPERAND (inner
, 0);
1080 gcc_assert (TREE_CODE (inner
) == COMPONENT_REF
);
1082 if (MEM_OFFSET (mem
)
1083 && GET_CODE (MEM_OFFSET (mem
)) == CONST_INT
)
1084 offset
= INTVAL (MEM_OFFSET (mem
));
1086 if (offset
>= 0 && len
&& host_integerp (len
, 0))
1087 length
= tree_low_cst (len
, 0);
1089 while (TREE_CODE (inner
) == COMPONENT_REF
)
1091 tree field
= TREE_OPERAND (inner
, 1);
1092 gcc_assert (! DECL_BIT_FIELD (field
));
1093 gcc_assert (TREE_CODE (mem_expr
) == COMPONENT_REF
);
1094 gcc_assert (field
== TREE_OPERAND (mem_expr
, 1));
1097 && TYPE_SIZE_UNIT (TREE_TYPE (inner
))
1098 && host_integerp (TYPE_SIZE_UNIT (TREE_TYPE (inner
)), 0))
1101 = tree_low_cst (TYPE_SIZE_UNIT (TREE_TYPE (inner
)), 0);
1102 /* If we can prove the memory starting at XEXP (mem, 0)
1103 and ending at XEXP (mem, 0) + LENGTH will fit into
1104 this field, we can keep that COMPONENT_REF in MEM_EXPR. */
1107 && offset
+ length
<= size
)
1112 && host_integerp (DECL_FIELD_OFFSET (field
), 0))
1113 offset
+= tree_low_cst (DECL_FIELD_OFFSET (field
), 0)
1114 + tree_low_cst (DECL_FIELD_BIT_OFFSET (field
), 1)
1122 mem_expr
= TREE_OPERAND (mem_expr
, 0);
1123 inner
= TREE_OPERAND (inner
, 0);
1126 if (mem_expr
== NULL
)
1128 if (mem_expr
!= MEM_EXPR (mem
))
1130 set_mem_expr (mem
, mem_expr
);
1131 set_mem_offset (mem
, offset
>= 0 ? GEN_INT (offset
) : NULL_RTX
);
1134 set_mem_alias_set (mem
, 0);
1135 set_mem_size (mem
, NULL_RTX
);
1141 /* Built-in functions to perform an untyped call and return. */
1143 /* For each register that may be used for calling a function, this
1144 gives a mode used to copy the register's value. VOIDmode indicates
1145 the register is not used for calling a function. If the machine
1146 has register windows, this gives only the outbound registers.
1147 INCOMING_REGNO gives the corresponding inbound register. */
1148 static enum machine_mode apply_args_mode
[FIRST_PSEUDO_REGISTER
];
1150 /* For each register that may be used for returning values, this gives
1151 a mode used to copy the register's value. VOIDmode indicates the
1152 register is not used for returning values. If the machine has
1153 register windows, this gives only the outbound registers.
1154 INCOMING_REGNO gives the corresponding inbound register. */
1155 static enum machine_mode apply_result_mode
[FIRST_PSEUDO_REGISTER
];
1157 /* For each register that may be used for calling a function, this
1158 gives the offset of that register into the block returned by
1159 __builtin_apply_args. 0 indicates that the register is not
1160 used for calling a function. */
1161 static int apply_args_reg_offset
[FIRST_PSEUDO_REGISTER
];
1163 /* Return the size required for the block returned by __builtin_apply_args,
1164 and initialize apply_args_mode. */
1167 apply_args_size (void)
1169 static int size
= -1;
1172 enum machine_mode mode
;
1174 /* The values computed by this function never change. */
1177 /* The first value is the incoming arg-pointer. */
1178 size
= GET_MODE_SIZE (Pmode
);
1180 /* The second value is the structure value address unless this is
1181 passed as an "invisible" first argument. */
1182 if (targetm
.calls
.struct_value_rtx (cfun
? TREE_TYPE (cfun
->decl
) : 0, 0))
1183 size
+= GET_MODE_SIZE (Pmode
);
1185 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
1186 if (FUNCTION_ARG_REGNO_P (regno
))
1188 mode
= reg_raw_mode
[regno
];
1190 gcc_assert (mode
!= VOIDmode
);
1192 align
= GET_MODE_ALIGNMENT (mode
) / BITS_PER_UNIT
;
1193 if (size
% align
!= 0)
1194 size
= CEIL (size
, align
) * align
;
1195 apply_args_reg_offset
[regno
] = size
;
1196 size
+= GET_MODE_SIZE (mode
);
1197 apply_args_mode
[regno
] = mode
;
1201 apply_args_mode
[regno
] = VOIDmode
;
1202 apply_args_reg_offset
[regno
] = 0;
1208 /* Return the size required for the block returned by __builtin_apply,
1209 and initialize apply_result_mode. */
1212 apply_result_size (void)
1214 static int size
= -1;
1216 enum machine_mode mode
;
1218 /* The values computed by this function never change. */
1223 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
1224 if (FUNCTION_VALUE_REGNO_P (regno
))
1226 mode
= reg_raw_mode
[regno
];
1228 gcc_assert (mode
!= VOIDmode
);
1230 align
= GET_MODE_ALIGNMENT (mode
) / BITS_PER_UNIT
;
1231 if (size
% align
!= 0)
1232 size
= CEIL (size
, align
) * align
;
1233 size
+= GET_MODE_SIZE (mode
);
1234 apply_result_mode
[regno
] = mode
;
1237 apply_result_mode
[regno
] = VOIDmode
;
1239 /* Allow targets that use untyped_call and untyped_return to override
1240 the size so that machine-specific information can be stored here. */
1241 #ifdef APPLY_RESULT_SIZE
1242 size
= APPLY_RESULT_SIZE
;
1248 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
1249 /* Create a vector describing the result block RESULT. If SAVEP is true,
1250 the result block is used to save the values; otherwise it is used to
1251 restore the values. */
1254 result_vector (int savep
, rtx result
)
1256 int regno
, size
, align
, nelts
;
1257 enum machine_mode mode
;
1259 rtx
*savevec
= alloca (FIRST_PSEUDO_REGISTER
* sizeof (rtx
));
1262 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
1263 if ((mode
= apply_result_mode
[regno
]) != VOIDmode
)
1265 align
= GET_MODE_ALIGNMENT (mode
) / BITS_PER_UNIT
;
1266 if (size
% align
!= 0)
1267 size
= CEIL (size
, align
) * align
;
1268 reg
= gen_rtx_REG (mode
, savep
? regno
: INCOMING_REGNO (regno
));
1269 mem
= adjust_address (result
, mode
, size
);
1270 savevec
[nelts
++] = (savep
1271 ? gen_rtx_SET (VOIDmode
, mem
, reg
)
1272 : gen_rtx_SET (VOIDmode
, reg
, mem
));
1273 size
+= GET_MODE_SIZE (mode
);
1275 return gen_rtx_PARALLEL (VOIDmode
, gen_rtvec_v (nelts
, savevec
));
1277 #endif /* HAVE_untyped_call or HAVE_untyped_return */
1279 /* Save the state required to perform an untyped call with the same
1280 arguments as were passed to the current function. */
1283 expand_builtin_apply_args_1 (void)
1286 int size
, align
, regno
;
1287 enum machine_mode mode
;
1288 rtx struct_incoming_value
= targetm
.calls
.struct_value_rtx (cfun
? TREE_TYPE (cfun
->decl
) : 0, 1);
1290 /* Create a block where the arg-pointer, structure value address,
1291 and argument registers can be saved. */
1292 registers
= assign_stack_local (BLKmode
, apply_args_size (), -1);
1294 /* Walk past the arg-pointer and structure value address. */
1295 size
= GET_MODE_SIZE (Pmode
);
1296 if (targetm
.calls
.struct_value_rtx (cfun
? TREE_TYPE (cfun
->decl
) : 0, 0))
1297 size
+= GET_MODE_SIZE (Pmode
);
1299 /* Save each register used in calling a function to the block. */
1300 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
1301 if ((mode
= apply_args_mode
[regno
]) != VOIDmode
)
1303 align
= GET_MODE_ALIGNMENT (mode
) / BITS_PER_UNIT
;
1304 if (size
% align
!= 0)
1305 size
= CEIL (size
, align
) * align
;
1307 tem
= gen_rtx_REG (mode
, INCOMING_REGNO (regno
));
1309 emit_move_insn (adjust_address (registers
, mode
, size
), tem
);
1310 size
+= GET_MODE_SIZE (mode
);
1313 /* Save the arg pointer to the block. */
1314 tem
= copy_to_reg (virtual_incoming_args_rtx
);
1315 #ifdef STACK_GROWS_DOWNWARD
1316 /* We need the pointer as the caller actually passed them to us, not
1317 as we might have pretended they were passed. Make sure it's a valid
1318 operand, as emit_move_insn isn't expected to handle a PLUS. */
1320 = force_operand (plus_constant (tem
, current_function_pretend_args_size
),
1323 emit_move_insn (adjust_address (registers
, Pmode
, 0), tem
);
1325 size
= GET_MODE_SIZE (Pmode
);
1327 /* Save the structure value address unless this is passed as an
1328 "invisible" first argument. */
1329 if (struct_incoming_value
)
1331 emit_move_insn (adjust_address (registers
, Pmode
, size
),
1332 copy_to_reg (struct_incoming_value
));
1333 size
+= GET_MODE_SIZE (Pmode
);
1336 /* Return the address of the block. */
1337 return copy_addr_to_reg (XEXP (registers
, 0));
1340 /* __builtin_apply_args returns block of memory allocated on
1341 the stack into which is stored the arg pointer, structure
1342 value address, static chain, and all the registers that might
1343 possibly be used in performing a function call. The code is
1344 moved to the start of the function so the incoming values are
1348 expand_builtin_apply_args (void)
1350 /* Don't do __builtin_apply_args more than once in a function.
1351 Save the result of the first call and reuse it. */
1352 if (apply_args_value
!= 0)
1353 return apply_args_value
;
1355 /* When this function is called, it means that registers must be
1356 saved on entry to this function. So we migrate the
1357 call to the first insn of this function. */
1362 temp
= expand_builtin_apply_args_1 ();
1366 apply_args_value
= temp
;
1368 /* Put the insns after the NOTE that starts the function.
1369 If this is inside a start_sequence, make the outer-level insn
1370 chain current, so the code is placed at the start of the
1372 push_topmost_sequence ();
1373 emit_insn_before (seq
, NEXT_INSN (entry_of_function ()));
1374 pop_topmost_sequence ();
1379 /* Perform an untyped call and save the state required to perform an
1380 untyped return of whatever value was returned by the given function. */
1383 expand_builtin_apply (rtx function
, rtx arguments
, rtx argsize
)
1385 int size
, align
, regno
;
1386 enum machine_mode mode
;
1387 rtx incoming_args
, result
, reg
, dest
, src
, call_insn
;
1388 rtx old_stack_level
= 0;
1389 rtx call_fusage
= 0;
1390 rtx struct_value
= targetm
.calls
.struct_value_rtx (cfun
? TREE_TYPE (cfun
->decl
) : 0, 0);
1392 arguments
= convert_memory_address (Pmode
, arguments
);
1394 /* Create a block where the return registers can be saved. */
1395 result
= assign_stack_local (BLKmode
, apply_result_size (), -1);
1397 /* Fetch the arg pointer from the ARGUMENTS block. */
1398 incoming_args
= gen_reg_rtx (Pmode
);
1399 emit_move_insn (incoming_args
, gen_rtx_MEM (Pmode
, arguments
));
1400 #ifndef STACK_GROWS_DOWNWARD
1401 incoming_args
= expand_simple_binop (Pmode
, MINUS
, incoming_args
, argsize
,
1402 incoming_args
, 0, OPTAB_LIB_WIDEN
);
1405 /* Push a new argument block and copy the arguments. Do not allow
1406 the (potential) memcpy call below to interfere with our stack
1408 do_pending_stack_adjust ();
1411 /* Save the stack with nonlocal if available. */
1412 #ifdef HAVE_save_stack_nonlocal
1413 if (HAVE_save_stack_nonlocal
)
1414 emit_stack_save (SAVE_NONLOCAL
, &old_stack_level
, NULL_RTX
);
1417 emit_stack_save (SAVE_BLOCK
, &old_stack_level
, NULL_RTX
);
1419 /* Allocate a block of memory onto the stack and copy the memory
1420 arguments to the outgoing arguments address. */
1421 allocate_dynamic_stack_space (argsize
, 0, BITS_PER_UNIT
);
1422 dest
= virtual_outgoing_args_rtx
;
1423 #ifndef STACK_GROWS_DOWNWARD
1424 if (GET_CODE (argsize
) == CONST_INT
)
1425 dest
= plus_constant (dest
, -INTVAL (argsize
));
1427 dest
= gen_rtx_PLUS (Pmode
, dest
, negate_rtx (Pmode
, argsize
));
1429 dest
= gen_rtx_MEM (BLKmode
, dest
);
1430 set_mem_align (dest
, PARM_BOUNDARY
);
1431 src
= gen_rtx_MEM (BLKmode
, incoming_args
);
1432 set_mem_align (src
, PARM_BOUNDARY
);
1433 emit_block_move (dest
, src
, argsize
, BLOCK_OP_NORMAL
);
1435 /* Refer to the argument block. */
1437 arguments
= gen_rtx_MEM (BLKmode
, arguments
);
1438 set_mem_align (arguments
, PARM_BOUNDARY
);
1440 /* Walk past the arg-pointer and structure value address. */
1441 size
= GET_MODE_SIZE (Pmode
);
1443 size
+= GET_MODE_SIZE (Pmode
);
1445 /* Restore each of the registers previously saved. Make USE insns
1446 for each of these registers for use in making the call. */
1447 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
1448 if ((mode
= apply_args_mode
[regno
]) != VOIDmode
)
1450 align
= GET_MODE_ALIGNMENT (mode
) / BITS_PER_UNIT
;
1451 if (size
% align
!= 0)
1452 size
= CEIL (size
, align
) * align
;
1453 reg
= gen_rtx_REG (mode
, regno
);
1454 emit_move_insn (reg
, adjust_address (arguments
, mode
, size
));
1455 use_reg (&call_fusage
, reg
);
1456 size
+= GET_MODE_SIZE (mode
);
1459 /* Restore the structure value address unless this is passed as an
1460 "invisible" first argument. */
1461 size
= GET_MODE_SIZE (Pmode
);
1464 rtx value
= gen_reg_rtx (Pmode
);
1465 emit_move_insn (value
, adjust_address (arguments
, Pmode
, size
));
1466 emit_move_insn (struct_value
, value
);
1467 if (REG_P (struct_value
))
1468 use_reg (&call_fusage
, struct_value
);
1469 size
+= GET_MODE_SIZE (Pmode
);
1472 /* All arguments and registers used for the call are set up by now! */
1473 function
= prepare_call_address (function
, NULL
, &call_fusage
, 0, 0);
1475 /* Ensure address is valid. SYMBOL_REF is already valid, so no need,
1476 and we don't want to load it into a register as an optimization,
1477 because prepare_call_address already did it if it should be done. */
1478 if (GET_CODE (function
) != SYMBOL_REF
)
1479 function
= memory_address (FUNCTION_MODE
, function
);
1481 /* Generate the actual call instruction and save the return value. */
1482 #ifdef HAVE_untyped_call
1483 if (HAVE_untyped_call
)
1484 emit_call_insn (gen_untyped_call (gen_rtx_MEM (FUNCTION_MODE
, function
),
1485 result
, result_vector (1, result
)));
1488 #ifdef HAVE_call_value
1489 if (HAVE_call_value
)
1493 /* Locate the unique return register. It is not possible to
1494 express a call that sets more than one return register using
1495 call_value; use untyped_call for that. In fact, untyped_call
1496 only needs to save the return registers in the given block. */
1497 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
1498 if ((mode
= apply_result_mode
[regno
]) != VOIDmode
)
1500 gcc_assert (!valreg
); /* HAVE_untyped_call required. */
1502 valreg
= gen_rtx_REG (mode
, regno
);
1505 emit_call_insn (GEN_CALL_VALUE (valreg
,
1506 gen_rtx_MEM (FUNCTION_MODE
, function
),
1507 const0_rtx
, NULL_RTX
, const0_rtx
));
1509 emit_move_insn (adjust_address (result
, GET_MODE (valreg
), 0), valreg
);
1515 /* Find the CALL insn we just emitted, and attach the register usage
1517 call_insn
= last_call_insn ();
1518 add_function_usage_to (call_insn
, call_fusage
);
1520 /* Restore the stack. */
1521 #ifdef HAVE_save_stack_nonlocal
1522 if (HAVE_save_stack_nonlocal
)
1523 emit_stack_restore (SAVE_NONLOCAL
, old_stack_level
, NULL_RTX
);
1526 emit_stack_restore (SAVE_BLOCK
, old_stack_level
, NULL_RTX
);
1530 /* Return the address of the result block. */
1531 result
= copy_addr_to_reg (XEXP (result
, 0));
1532 return convert_memory_address (ptr_mode
, result
);
1535 /* Perform an untyped return. */
1538 expand_builtin_return (rtx result
)
1540 int size
, align
, regno
;
1541 enum machine_mode mode
;
1543 rtx call_fusage
= 0;
1545 result
= convert_memory_address (Pmode
, result
);
1547 apply_result_size ();
1548 result
= gen_rtx_MEM (BLKmode
, result
);
1550 #ifdef HAVE_untyped_return
1551 if (HAVE_untyped_return
)
1553 emit_jump_insn (gen_untyped_return (result
, result_vector (0, result
)));
1559 /* Restore the return value and note that each value is used. */
1561 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
1562 if ((mode
= apply_result_mode
[regno
]) != VOIDmode
)
1564 align
= GET_MODE_ALIGNMENT (mode
) / BITS_PER_UNIT
;
1565 if (size
% align
!= 0)
1566 size
= CEIL (size
, align
) * align
;
1567 reg
= gen_rtx_REG (mode
, INCOMING_REGNO (regno
));
1568 emit_move_insn (reg
, adjust_address (result
, mode
, size
));
1570 push_to_sequence (call_fusage
);
1571 emit_insn (gen_rtx_USE (VOIDmode
, reg
));
1572 call_fusage
= get_insns ();
1574 size
+= GET_MODE_SIZE (mode
);
1577 /* Put the USE insns before the return. */
1578 emit_insn (call_fusage
);
1580 /* Return whatever values was restored by jumping directly to the end
1582 expand_naked_return ();
1585 /* Used by expand_builtin_classify_type and fold_builtin_classify_type. */
1587 static enum type_class
1588 type_to_class (tree type
)
1590 switch (TREE_CODE (type
))
1592 case VOID_TYPE
: return void_type_class
;
1593 case INTEGER_TYPE
: return integer_type_class
;
1594 case ENUMERAL_TYPE
: return enumeral_type_class
;
1595 case BOOLEAN_TYPE
: return boolean_type_class
;
1596 case POINTER_TYPE
: return pointer_type_class
;
1597 case REFERENCE_TYPE
: return reference_type_class
;
1598 case OFFSET_TYPE
: return offset_type_class
;
1599 case REAL_TYPE
: return real_type_class
;
1600 case COMPLEX_TYPE
: return complex_type_class
;
1601 case FUNCTION_TYPE
: return function_type_class
;
1602 case METHOD_TYPE
: return method_type_class
;
1603 case RECORD_TYPE
: return record_type_class
;
1605 case QUAL_UNION_TYPE
: return union_type_class
;
1606 case ARRAY_TYPE
: return (TYPE_STRING_FLAG (type
)
1607 ? string_type_class
: array_type_class
);
1608 case LANG_TYPE
: return lang_type_class
;
1609 default: return no_type_class
;
1613 /* Expand a call to __builtin_classify_type with arguments found in
1617 expand_builtin_classify_type (tree arglist
)
1620 return GEN_INT (type_to_class (TREE_TYPE (TREE_VALUE (arglist
))));
1621 return GEN_INT (no_type_class
);
1624 /* This helper macro, meant to be used in mathfn_built_in below,
1625 determines which among a set of three builtin math functions is
1626 appropriate for a given type mode. The `F' and `L' cases are
1627 automatically generated from the `double' case. */
1628 #define CASE_MATHFN(BUILT_IN_MATHFN) \
1629 case BUILT_IN_MATHFN: case BUILT_IN_MATHFN##F: case BUILT_IN_MATHFN##L: \
1630 fcode = BUILT_IN_MATHFN; fcodef = BUILT_IN_MATHFN##F ; \
1631 fcodel = BUILT_IN_MATHFN##L ; break;
1633 /* Return mathematic function equivalent to FN but operating directly
1634 on TYPE, if available. If we can't do the conversion, return zero. */
1636 mathfn_built_in (tree type
, enum built_in_function fn
)
1638 enum built_in_function fcode
, fcodef
, fcodel
;
1642 CASE_MATHFN (BUILT_IN_ACOS
)
1643 CASE_MATHFN (BUILT_IN_ACOSH
)
1644 CASE_MATHFN (BUILT_IN_ASIN
)
1645 CASE_MATHFN (BUILT_IN_ASINH
)
1646 CASE_MATHFN (BUILT_IN_ATAN
)
1647 CASE_MATHFN (BUILT_IN_ATAN2
)
1648 CASE_MATHFN (BUILT_IN_ATANH
)
1649 CASE_MATHFN (BUILT_IN_CBRT
)
1650 CASE_MATHFN (BUILT_IN_CEIL
)
1651 CASE_MATHFN (BUILT_IN_COPYSIGN
)
1652 CASE_MATHFN (BUILT_IN_COS
)
1653 CASE_MATHFN (BUILT_IN_COSH
)
1654 CASE_MATHFN (BUILT_IN_DREM
)
1655 CASE_MATHFN (BUILT_IN_ERF
)
1656 CASE_MATHFN (BUILT_IN_ERFC
)
1657 CASE_MATHFN (BUILT_IN_EXP
)
1658 CASE_MATHFN (BUILT_IN_EXP10
)
1659 CASE_MATHFN (BUILT_IN_EXP2
)
1660 CASE_MATHFN (BUILT_IN_EXPM1
)
1661 CASE_MATHFN (BUILT_IN_FABS
)
1662 CASE_MATHFN (BUILT_IN_FDIM
)
1663 CASE_MATHFN (BUILT_IN_FLOOR
)
1664 CASE_MATHFN (BUILT_IN_FMA
)
1665 CASE_MATHFN (BUILT_IN_FMAX
)
1666 CASE_MATHFN (BUILT_IN_FMIN
)
1667 CASE_MATHFN (BUILT_IN_FMOD
)
1668 CASE_MATHFN (BUILT_IN_FREXP
)
1669 CASE_MATHFN (BUILT_IN_GAMMA
)
1670 CASE_MATHFN (BUILT_IN_HUGE_VAL
)
1671 CASE_MATHFN (BUILT_IN_HYPOT
)
1672 CASE_MATHFN (BUILT_IN_ILOGB
)
1673 CASE_MATHFN (BUILT_IN_INF
)
1674 CASE_MATHFN (BUILT_IN_J0
)
1675 CASE_MATHFN (BUILT_IN_J1
)
1676 CASE_MATHFN (BUILT_IN_JN
)
1677 CASE_MATHFN (BUILT_IN_LCEIL
)
1678 CASE_MATHFN (BUILT_IN_LDEXP
)
1679 CASE_MATHFN (BUILT_IN_LFLOOR
)
1680 CASE_MATHFN (BUILT_IN_LGAMMA
)
1681 CASE_MATHFN (BUILT_IN_LLCEIL
)
1682 CASE_MATHFN (BUILT_IN_LLFLOOR
)
1683 CASE_MATHFN (BUILT_IN_LLRINT
)
1684 CASE_MATHFN (BUILT_IN_LLROUND
)
1685 CASE_MATHFN (BUILT_IN_LOG
)
1686 CASE_MATHFN (BUILT_IN_LOG10
)
1687 CASE_MATHFN (BUILT_IN_LOG1P
)
1688 CASE_MATHFN (BUILT_IN_LOG2
)
1689 CASE_MATHFN (BUILT_IN_LOGB
)
1690 CASE_MATHFN (BUILT_IN_LRINT
)
1691 CASE_MATHFN (BUILT_IN_LROUND
)
1692 CASE_MATHFN (BUILT_IN_MODF
)
1693 CASE_MATHFN (BUILT_IN_NAN
)
1694 CASE_MATHFN (BUILT_IN_NANS
)
1695 CASE_MATHFN (BUILT_IN_NEARBYINT
)
1696 CASE_MATHFN (BUILT_IN_NEXTAFTER
)
1697 CASE_MATHFN (BUILT_IN_NEXTTOWARD
)
1698 CASE_MATHFN (BUILT_IN_POW
)
1699 CASE_MATHFN (BUILT_IN_POWI
)
1700 CASE_MATHFN (BUILT_IN_POW10
)
1701 CASE_MATHFN (BUILT_IN_REMAINDER
)
1702 CASE_MATHFN (BUILT_IN_REMQUO
)
1703 CASE_MATHFN (BUILT_IN_RINT
)
1704 CASE_MATHFN (BUILT_IN_ROUND
)
1705 CASE_MATHFN (BUILT_IN_SCALB
)
1706 CASE_MATHFN (BUILT_IN_SCALBLN
)
1707 CASE_MATHFN (BUILT_IN_SCALBN
)
1708 CASE_MATHFN (BUILT_IN_SIGNIFICAND
)
1709 CASE_MATHFN (BUILT_IN_SIN
)
1710 CASE_MATHFN (BUILT_IN_SINCOS
)
1711 CASE_MATHFN (BUILT_IN_SINH
)
1712 CASE_MATHFN (BUILT_IN_SQRT
)
1713 CASE_MATHFN (BUILT_IN_TAN
)
1714 CASE_MATHFN (BUILT_IN_TANH
)
1715 CASE_MATHFN (BUILT_IN_TGAMMA
)
1716 CASE_MATHFN (BUILT_IN_TRUNC
)
1717 CASE_MATHFN (BUILT_IN_Y0
)
1718 CASE_MATHFN (BUILT_IN_Y1
)
1719 CASE_MATHFN (BUILT_IN_YN
)
1725 if (TYPE_MAIN_VARIANT (type
) == double_type_node
)
1726 return implicit_built_in_decls
[fcode
];
1727 else if (TYPE_MAIN_VARIANT (type
) == float_type_node
)
1728 return implicit_built_in_decls
[fcodef
];
1729 else if (TYPE_MAIN_VARIANT (type
) == long_double_type_node
)
1730 return implicit_built_in_decls
[fcodel
];
1735 /* If errno must be maintained, expand the RTL to check if the result,
1736 TARGET, of a built-in function call, EXP, is NaN, and if so set
1740 expand_errno_check (tree exp
, rtx target
)
1742 rtx lab
= gen_label_rtx ();
1744 /* Test the result; if it is NaN, set errno=EDOM because
1745 the argument was not in the domain. */
1746 emit_cmp_and_jump_insns (target
, target
, EQ
, 0, GET_MODE (target
),
1750 /* If this built-in doesn't throw an exception, set errno directly. */
1751 if (TREE_NOTHROW (TREE_OPERAND (TREE_OPERAND (exp
, 0), 0)))
1753 #ifdef GEN_ERRNO_RTX
1754 rtx errno_rtx
= GEN_ERRNO_RTX
;
1757 = gen_rtx_MEM (word_mode
, gen_rtx_SYMBOL_REF (Pmode
, "errno"));
1759 emit_move_insn (errno_rtx
, GEN_INT (TARGET_EDOM
));
1765 /* We can't set errno=EDOM directly; let the library call do it.
1766 Pop the arguments right away in case the call gets deleted. */
1768 expand_call (exp
, target
, 0);
1774 /* Expand a call to one of the builtin math functions (sqrt, exp, or log).
1775 Return 0 if a normal call should be emitted rather than expanding the
1776 function in-line. EXP is the expression that is a call to the builtin
1777 function; if convenient, the result should be placed in TARGET.
1778 SUBTARGET may be used as the target for computing one of EXP's operands. */
1781 expand_builtin_mathfn (tree exp
, rtx target
, rtx subtarget
)
1783 optab builtin_optab
;
1784 rtx op0
, insns
, before_call
;
1785 tree fndecl
= get_callee_fndecl (exp
);
1786 tree arglist
= TREE_OPERAND (exp
, 1);
1787 enum machine_mode mode
;
1788 bool errno_set
= false;
1791 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
1794 arg
= TREE_VALUE (arglist
);
1796 switch (DECL_FUNCTION_CODE (fndecl
))
1798 CASE_FLT_FN (BUILT_IN_SQRT
):
1799 errno_set
= ! tree_expr_nonnegative_p (arg
);
1800 builtin_optab
= sqrt_optab
;
1802 CASE_FLT_FN (BUILT_IN_EXP
):
1803 errno_set
= true; builtin_optab
= exp_optab
; break;
1804 CASE_FLT_FN (BUILT_IN_EXP10
):
1805 CASE_FLT_FN (BUILT_IN_POW10
):
1806 errno_set
= true; builtin_optab
= exp10_optab
; break;
1807 CASE_FLT_FN (BUILT_IN_EXP2
):
1808 errno_set
= true; builtin_optab
= exp2_optab
; break;
1809 CASE_FLT_FN (BUILT_IN_EXPM1
):
1810 errno_set
= true; builtin_optab
= expm1_optab
; break;
1811 CASE_FLT_FN (BUILT_IN_LOGB
):
1812 errno_set
= true; builtin_optab
= logb_optab
; break;
1813 CASE_FLT_FN (BUILT_IN_ILOGB
):
1814 errno_set
= true; builtin_optab
= ilogb_optab
; break;
1815 CASE_FLT_FN (BUILT_IN_LOG
):
1816 errno_set
= true; builtin_optab
= log_optab
; break;
1817 CASE_FLT_FN (BUILT_IN_LOG10
):
1818 errno_set
= true; builtin_optab
= log10_optab
; break;
1819 CASE_FLT_FN (BUILT_IN_LOG2
):
1820 errno_set
= true; builtin_optab
= log2_optab
; break;
1821 CASE_FLT_FN (BUILT_IN_LOG1P
):
1822 errno_set
= true; builtin_optab
= log1p_optab
; break;
1823 CASE_FLT_FN (BUILT_IN_ASIN
):
1824 builtin_optab
= asin_optab
; break;
1825 CASE_FLT_FN (BUILT_IN_ACOS
):
1826 builtin_optab
= acos_optab
; break;
1827 CASE_FLT_FN (BUILT_IN_TAN
):
1828 builtin_optab
= tan_optab
; break;
1829 CASE_FLT_FN (BUILT_IN_ATAN
):
1830 builtin_optab
= atan_optab
; break;
1831 CASE_FLT_FN (BUILT_IN_FLOOR
):
1832 builtin_optab
= floor_optab
; break;
1833 CASE_FLT_FN (BUILT_IN_CEIL
):
1834 builtin_optab
= ceil_optab
; break;
1835 CASE_FLT_FN (BUILT_IN_TRUNC
):
1836 builtin_optab
= btrunc_optab
; break;
1837 CASE_FLT_FN (BUILT_IN_ROUND
):
1838 builtin_optab
= round_optab
; break;
1839 CASE_FLT_FN (BUILT_IN_NEARBYINT
):
1840 builtin_optab
= nearbyint_optab
; break;
1841 CASE_FLT_FN (BUILT_IN_RINT
):
1842 builtin_optab
= rint_optab
; break;
1843 CASE_FLT_FN (BUILT_IN_LRINT
):
1844 CASE_FLT_FN (BUILT_IN_LLRINT
):
1845 builtin_optab
= lrint_optab
; break;
1850 /* Make a suitable register to place result in. */
1851 mode
= TYPE_MODE (TREE_TYPE (exp
));
1853 if (! flag_errno_math
|| ! HONOR_NANS (mode
))
1856 /* Before working hard, check whether the instruction is available. */
1857 if (builtin_optab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
)
1859 target
= gen_reg_rtx (mode
);
1861 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
1862 need to expand the argument again. This way, we will not perform
1863 side-effects more the once. */
1864 narg
= builtin_save_expr (arg
);
1868 arglist
= build_tree_list (NULL_TREE
, arg
);
1869 exp
= build_function_call_expr (fndecl
, arglist
);
1872 op0
= expand_expr (arg
, subtarget
, VOIDmode
, 0);
1876 /* Compute into TARGET.
1877 Set TARGET to wherever the result comes back. */
1878 target
= expand_unop (mode
, builtin_optab
, op0
, target
, 0);
1883 expand_errno_check (exp
, target
);
1885 /* Output the entire sequence. */
1886 insns
= get_insns ();
1892 /* If we were unable to expand via the builtin, stop the sequence
1893 (without outputting the insns) and call to the library function
1894 with the stabilized argument list. */
1898 before_call
= get_last_insn ();
1900 target
= expand_call (exp
, target
, target
== const0_rtx
);
1902 /* If this is a sqrt operation and we don't care about errno, try to
1903 attach a REG_EQUAL note with a SQRT rtx to the emitted libcall.
1904 This allows the semantics of the libcall to be visible to the RTL
1906 if (builtin_optab
== sqrt_optab
&& !errno_set
)
1908 /* Search backwards through the insns emitted by expand_call looking
1909 for the instruction with the REG_RETVAL note. */
1910 rtx last
= get_last_insn ();
1911 while (last
!= before_call
)
1913 if (find_reg_note (last
, REG_RETVAL
, NULL
))
1915 rtx note
= find_reg_note (last
, REG_EQUAL
, NULL
);
1916 /* Check that the REQ_EQUAL note is an EXPR_LIST with
1917 two elements, i.e. symbol_ref(sqrt) and the operand. */
1919 && GET_CODE (note
) == EXPR_LIST
1920 && GET_CODE (XEXP (note
, 0)) == EXPR_LIST
1921 && XEXP (XEXP (note
, 0), 1) != NULL_RTX
1922 && XEXP (XEXP (XEXP (note
, 0), 1), 1) == NULL_RTX
)
1924 rtx operand
= XEXP (XEXP (XEXP (note
, 0), 1), 0);
1925 /* Check operand is a register with expected mode. */
1928 && GET_MODE (operand
) == mode
)
1930 /* Replace the REG_EQUAL note with a SQRT rtx. */
1931 rtx equiv
= gen_rtx_SQRT (mode
, operand
);
1932 set_unique_reg_note (last
, REG_EQUAL
, equiv
);
1937 last
= PREV_INSN (last
);
1944 /* Expand a call to the builtin binary math functions (pow and atan2).
1945 Return 0 if a normal call should be emitted rather than expanding the
1946 function in-line. EXP is the expression that is a call to the builtin
1947 function; if convenient, the result should be placed in TARGET.
1948 SUBTARGET may be used as the target for computing one of EXP's
1952 expand_builtin_mathfn_2 (tree exp
, rtx target
, rtx subtarget
)
1954 optab builtin_optab
;
1955 rtx op0
, op1
, insns
;
1956 int op1_type
= REAL_TYPE
;
1957 tree fndecl
= get_callee_fndecl (exp
);
1958 tree arglist
= TREE_OPERAND (exp
, 1);
1959 tree arg0
, arg1
, temp
, narg
;
1960 enum machine_mode mode
;
1961 bool errno_set
= true;
1964 if ((DECL_FUNCTION_CODE (fndecl
) == BUILT_IN_LDEXP
)
1965 || (DECL_FUNCTION_CODE (fndecl
) == BUILT_IN_LDEXPF
)
1966 || (DECL_FUNCTION_CODE (fndecl
) == BUILT_IN_LDEXPL
))
1967 op1_type
= INTEGER_TYPE
;
1969 if (!validate_arglist (arglist
, REAL_TYPE
, op1_type
, VOID_TYPE
))
1972 arg0
= TREE_VALUE (arglist
);
1973 arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
1975 switch (DECL_FUNCTION_CODE (fndecl
))
1977 CASE_FLT_FN (BUILT_IN_POW
):
1978 builtin_optab
= pow_optab
; break;
1979 CASE_FLT_FN (BUILT_IN_ATAN2
):
1980 builtin_optab
= atan2_optab
; break;
1981 CASE_FLT_FN (BUILT_IN_LDEXP
):
1982 builtin_optab
= ldexp_optab
; break;
1983 CASE_FLT_FN (BUILT_IN_FMOD
):
1984 builtin_optab
= fmod_optab
; break;
1985 CASE_FLT_FN (BUILT_IN_DREM
):
1986 builtin_optab
= drem_optab
; break;
1991 /* Make a suitable register to place result in. */
1992 mode
= TYPE_MODE (TREE_TYPE (exp
));
1994 /* Before working hard, check whether the instruction is available. */
1995 if (builtin_optab
->handlers
[(int) mode
].insn_code
== CODE_FOR_nothing
)
1998 target
= gen_reg_rtx (mode
);
2000 if (! flag_errno_math
|| ! HONOR_NANS (mode
))
2003 /* Always stabilize the argument list. */
2004 narg
= builtin_save_expr (arg1
);
2008 temp
= build_tree_list (NULL_TREE
, narg
);
2012 temp
= TREE_CHAIN (arglist
);
2014 narg
= builtin_save_expr (arg0
);
2018 arglist
= tree_cons (NULL_TREE
, narg
, temp
);
2022 arglist
= tree_cons (NULL_TREE
, arg0
, temp
);
2025 exp
= build_function_call_expr (fndecl
, arglist
);
2027 op0
= expand_expr (arg0
, subtarget
, VOIDmode
, EXPAND_NORMAL
);
2028 op1
= expand_normal (arg1
);
2032 /* Compute into TARGET.
2033 Set TARGET to wherever the result comes back. */
2034 target
= expand_binop (mode
, builtin_optab
, op0
, op1
,
2035 target
, 0, OPTAB_DIRECT
);
2037 /* If we were unable to expand via the builtin, stop the sequence
2038 (without outputting the insns) and call to the library function
2039 with the stabilized argument list. */
2043 return expand_call (exp
, target
, target
== const0_rtx
);
2047 expand_errno_check (exp
, target
);
2049 /* Output the entire sequence. */
2050 insns
= get_insns ();
2057 /* Expand a call to the builtin sin and cos math functions.
2058 Return 0 if a normal call should be emitted rather than expanding the
2059 function in-line. EXP is the expression that is a call to the builtin
2060 function; if convenient, the result should be placed in TARGET.
2061 SUBTARGET may be used as the target for computing one of EXP's
2065 expand_builtin_mathfn_3 (tree exp
, rtx target
, rtx subtarget
)
2067 optab builtin_optab
;
2069 tree fndecl
= get_callee_fndecl (exp
);
2070 tree arglist
= TREE_OPERAND (exp
, 1);
2071 enum machine_mode mode
;
2074 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
2077 arg
= TREE_VALUE (arglist
);
2079 switch (DECL_FUNCTION_CODE (fndecl
))
2081 CASE_FLT_FN (BUILT_IN_SIN
):
2082 CASE_FLT_FN (BUILT_IN_COS
):
2083 builtin_optab
= sincos_optab
; break;
2088 /* Make a suitable register to place result in. */
2089 mode
= TYPE_MODE (TREE_TYPE (exp
));
2091 /* Check if sincos insn is available, otherwise fallback
2092 to sin or cos insn. */
2093 if (builtin_optab
->handlers
[(int) mode
].insn_code
== CODE_FOR_nothing
) {
2094 switch (DECL_FUNCTION_CODE (fndecl
))
2096 CASE_FLT_FN (BUILT_IN_SIN
):
2097 builtin_optab
= sin_optab
; break;
2098 CASE_FLT_FN (BUILT_IN_COS
):
2099 builtin_optab
= cos_optab
; break;
2105 /* Before working hard, check whether the instruction is available. */
2106 if (builtin_optab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
)
2108 target
= gen_reg_rtx (mode
);
2110 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2111 need to expand the argument again. This way, we will not perform
2112 side-effects more the once. */
2113 narg
= save_expr (arg
);
2117 arglist
= build_tree_list (NULL_TREE
, arg
);
2118 exp
= build_function_call_expr (fndecl
, arglist
);
2121 op0
= expand_expr (arg
, subtarget
, VOIDmode
, 0);
2125 /* Compute into TARGET.
2126 Set TARGET to wherever the result comes back. */
2127 if (builtin_optab
== sincos_optab
)
2131 switch (DECL_FUNCTION_CODE (fndecl
))
2133 CASE_FLT_FN (BUILT_IN_SIN
):
2134 result
= expand_twoval_unop (builtin_optab
, op0
, 0, target
, 0);
2136 CASE_FLT_FN (BUILT_IN_COS
):
2137 result
= expand_twoval_unop (builtin_optab
, op0
, target
, 0, 0);
2142 gcc_assert (result
);
2146 target
= expand_unop (mode
, builtin_optab
, op0
, target
, 0);
2151 /* Output the entire sequence. */
2152 insns
= get_insns ();
2158 /* If we were unable to expand via the builtin, stop the sequence
2159 (without outputting the insns) and call to the library function
2160 with the stabilized argument list. */
2164 target
= expand_call (exp
, target
, target
== const0_rtx
);
2169 /* Expand a call to the builtin sincos math function.
2170 Return 0 if a normal call should be emitted rather than expanding the
2171 function in-line. EXP is the expression that is a call to the builtin
2175 expand_builtin_sincos (tree exp
)
2177 rtx op0
, op1
, op2
, target1
, target2
;
2178 tree arglist
= TREE_OPERAND (exp
, 1);
2179 enum machine_mode mode
;
2180 tree arg
, sinp
, cosp
;
2183 if (!validate_arglist (arglist
, REAL_TYPE
,
2184 POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
2187 arg
= TREE_VALUE (arglist
);
2188 sinp
= TREE_VALUE (TREE_CHAIN (arglist
));
2189 cosp
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
2191 /* Make a suitable register to place result in. */
2192 mode
= TYPE_MODE (TREE_TYPE (arg
));
2194 /* Check if sincos insn is available, otherwise emit the call. */
2195 if (sincos_optab
->handlers
[(int) mode
].insn_code
== CODE_FOR_nothing
)
2198 target1
= gen_reg_rtx (mode
);
2199 target2
= gen_reg_rtx (mode
);
2201 op0
= expand_normal (arg
);
2202 op1
= expand_normal (build_fold_indirect_ref (sinp
));
2203 op2
= expand_normal (build_fold_indirect_ref (cosp
));
2205 /* Compute into target1 and target2.
2206 Set TARGET to wherever the result comes back. */
2207 result
= expand_twoval_unop (sincos_optab
, op0
, target2
, target1
, 0);
2208 gcc_assert (result
);
2210 /* Move target1 and target2 to the memory locations indicated
2212 emit_move_insn (op1
, target1
);
2213 emit_move_insn (op2
, target2
);
2218 /* Expand a call to one of the builtin rounding functions (lfloor).
2219 If expanding via optab fails, lower expression to (int)(floor(x)).
2220 EXP is the expression that is a call to the builtin function;
2221 if convenient, the result should be placed in TARGET. SUBTARGET may
2222 be used as the target for computing one of EXP's operands. */
2225 expand_builtin_int_roundingfn (tree exp
, rtx target
, rtx subtarget
)
2227 optab builtin_optab
;
2228 rtx op0
, insns
, tmp
;
2229 tree fndecl
= get_callee_fndecl (exp
);
2230 tree arglist
= TREE_OPERAND (exp
, 1);
2231 enum built_in_function fallback_fn
;
2232 tree fallback_fndecl
;
2233 enum machine_mode mode
;
2236 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
2239 arg
= TREE_VALUE (arglist
);
2241 switch (DECL_FUNCTION_CODE (fndecl
))
2243 CASE_FLT_FN (BUILT_IN_LCEIL
):
2244 CASE_FLT_FN (BUILT_IN_LLCEIL
):
2245 builtin_optab
= lceil_optab
;
2246 fallback_fn
= BUILT_IN_CEIL
;
2249 CASE_FLT_FN (BUILT_IN_LFLOOR
):
2250 CASE_FLT_FN (BUILT_IN_LLFLOOR
):
2251 builtin_optab
= lfloor_optab
;
2252 fallback_fn
= BUILT_IN_FLOOR
;
2259 /* Make a suitable register to place result in. */
2260 mode
= TYPE_MODE (TREE_TYPE (exp
));
2262 /* Before working hard, check whether the instruction is available. */
2263 if (builtin_optab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
)
2265 target
= gen_reg_rtx (mode
);
2267 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2268 need to expand the argument again. This way, we will not perform
2269 side-effects more the once. */
2270 narg
= builtin_save_expr (arg
);
2274 arglist
= build_tree_list (NULL_TREE
, arg
);
2275 exp
= build_function_call_expr (fndecl
, arglist
);
2278 op0
= expand_expr (arg
, subtarget
, VOIDmode
, 0);
2282 /* Compute into TARGET.
2283 Set TARGET to wherever the result comes back. */
2284 target
= expand_unop (mode
, builtin_optab
, op0
, target
, 0);
2288 /* Output the entire sequence. */
2289 insns
= get_insns ();
2295 /* If we were unable to expand via the builtin, stop the sequence
2296 (without outputting the insns). */
2300 /* Fall back to floating point rounding optab. */
2301 fallback_fndecl
= mathfn_built_in (TREE_TYPE (arg
), fallback_fn
);
2302 /* We shouldn't get here on targets without TARGET_C99_FUNCTIONS.
2303 ??? Perhaps convert (int)floorf(x) into (int)floor((double)x). */
2304 gcc_assert (fallback_fndecl
!= NULL_TREE
);
2305 exp
= build_function_call_expr (fallback_fndecl
, arglist
);
2307 tmp
= expand_builtin_mathfn (exp
, NULL_RTX
, NULL_RTX
);
2309 /* Truncate the result of floating point optab to integer
2310 via expand_fix (). */
2311 target
= gen_reg_rtx (mode
);
2312 expand_fix (target
, tmp
, 0);
2317 /* To evaluate powi(x,n), the floating point value x raised to the
2318 constant integer exponent n, we use a hybrid algorithm that
2319 combines the "window method" with look-up tables. For an
2320 introduction to exponentiation algorithms and "addition chains",
2321 see section 4.6.3, "Evaluation of Powers" of Donald E. Knuth,
2322 "Seminumerical Algorithms", Vol. 2, "The Art of Computer Programming",
2323 3rd Edition, 1998, and Daniel M. Gordon, "A Survey of Fast Exponentiation
2324 Methods", Journal of Algorithms, Vol. 27, pp. 129-146, 1998. */
2326 /* Provide a default value for POWI_MAX_MULTS, the maximum number of
2327 multiplications to inline before calling the system library's pow
2328 function. powi(x,n) requires at worst 2*bits(n)-2 multiplications,
2329 so this default never requires calling pow, powf or powl. */
2331 #ifndef POWI_MAX_MULTS
2332 #define POWI_MAX_MULTS (2*HOST_BITS_PER_WIDE_INT-2)
2335 /* The size of the "optimal power tree" lookup table. All
2336 exponents less than this value are simply looked up in the
2337 powi_table below. This threshold is also used to size the
2338 cache of pseudo registers that hold intermediate results. */
2339 #define POWI_TABLE_SIZE 256
2341 /* The size, in bits of the window, used in the "window method"
2342 exponentiation algorithm. This is equivalent to a radix of
2343 (1<<POWI_WINDOW_SIZE) in the corresponding "m-ary method". */
2344 #define POWI_WINDOW_SIZE 3
2346 /* The following table is an efficient representation of an
2347 "optimal power tree". For each value, i, the corresponding
2348 value, j, in the table states than an optimal evaluation
2349 sequence for calculating pow(x,i) can be found by evaluating
2350 pow(x,j)*pow(x,i-j). An optimal power tree for the first
2351 100 integers is given in Knuth's "Seminumerical algorithms". */
2353 static const unsigned char powi_table
[POWI_TABLE_SIZE
] =
2355 0, 1, 1, 2, 2, 3, 3, 4, /* 0 - 7 */
2356 4, 6, 5, 6, 6, 10, 7, 9, /* 8 - 15 */
2357 8, 16, 9, 16, 10, 12, 11, 13, /* 16 - 23 */
2358 12, 17, 13, 18, 14, 24, 15, 26, /* 24 - 31 */
2359 16, 17, 17, 19, 18, 33, 19, 26, /* 32 - 39 */
2360 20, 25, 21, 40, 22, 27, 23, 44, /* 40 - 47 */
2361 24, 32, 25, 34, 26, 29, 27, 44, /* 48 - 55 */
2362 28, 31, 29, 34, 30, 60, 31, 36, /* 56 - 63 */
2363 32, 64, 33, 34, 34, 46, 35, 37, /* 64 - 71 */
2364 36, 65, 37, 50, 38, 48, 39, 69, /* 72 - 79 */
2365 40, 49, 41, 43, 42, 51, 43, 58, /* 80 - 87 */
2366 44, 64, 45, 47, 46, 59, 47, 76, /* 88 - 95 */
2367 48, 65, 49, 66, 50, 67, 51, 66, /* 96 - 103 */
2368 52, 70, 53, 74, 54, 104, 55, 74, /* 104 - 111 */
2369 56, 64, 57, 69, 58, 78, 59, 68, /* 112 - 119 */
2370 60, 61, 61, 80, 62, 75, 63, 68, /* 120 - 127 */
2371 64, 65, 65, 128, 66, 129, 67, 90, /* 128 - 135 */
2372 68, 73, 69, 131, 70, 94, 71, 88, /* 136 - 143 */
2373 72, 128, 73, 98, 74, 132, 75, 121, /* 144 - 151 */
2374 76, 102, 77, 124, 78, 132, 79, 106, /* 152 - 159 */
2375 80, 97, 81, 160, 82, 99, 83, 134, /* 160 - 167 */
2376 84, 86, 85, 95, 86, 160, 87, 100, /* 168 - 175 */
2377 88, 113, 89, 98, 90, 107, 91, 122, /* 176 - 183 */
2378 92, 111, 93, 102, 94, 126, 95, 150, /* 184 - 191 */
2379 96, 128, 97, 130, 98, 133, 99, 195, /* 192 - 199 */
2380 100, 128, 101, 123, 102, 164, 103, 138, /* 200 - 207 */
2381 104, 145, 105, 146, 106, 109, 107, 149, /* 208 - 215 */
2382 108, 200, 109, 146, 110, 170, 111, 157, /* 216 - 223 */
2383 112, 128, 113, 130, 114, 182, 115, 132, /* 224 - 231 */
2384 116, 200, 117, 132, 118, 158, 119, 206, /* 232 - 239 */
2385 120, 240, 121, 162, 122, 147, 123, 152, /* 240 - 247 */
2386 124, 166, 125, 214, 126, 138, 127, 153, /* 248 - 255 */
2390 /* Return the number of multiplications required to calculate
2391 powi(x,n) where n is less than POWI_TABLE_SIZE. This is a
2392 subroutine of powi_cost. CACHE is an array indicating
2393 which exponents have already been calculated. */
2396 powi_lookup_cost (unsigned HOST_WIDE_INT n
, bool *cache
)
2398 /* If we've already calculated this exponent, then this evaluation
2399 doesn't require any additional multiplications. */
2404 return powi_lookup_cost (n
- powi_table
[n
], cache
)
2405 + powi_lookup_cost (powi_table
[n
], cache
) + 1;
2408 /* Return the number of multiplications required to calculate
2409 powi(x,n) for an arbitrary x, given the exponent N. This
2410 function needs to be kept in sync with expand_powi below. */
2413 powi_cost (HOST_WIDE_INT n
)
2415 bool cache
[POWI_TABLE_SIZE
];
2416 unsigned HOST_WIDE_INT digit
;
2417 unsigned HOST_WIDE_INT val
;
2423 /* Ignore the reciprocal when calculating the cost. */
2424 val
= (n
< 0) ? -n
: n
;
2426 /* Initialize the exponent cache. */
2427 memset (cache
, 0, POWI_TABLE_SIZE
* sizeof (bool));
2432 while (val
>= POWI_TABLE_SIZE
)
2436 digit
= val
& ((1 << POWI_WINDOW_SIZE
) - 1);
2437 result
+= powi_lookup_cost (digit
, cache
)
2438 + POWI_WINDOW_SIZE
+ 1;
2439 val
>>= POWI_WINDOW_SIZE
;
2448 return result
+ powi_lookup_cost (val
, cache
);
2451 /* Recursive subroutine of expand_powi. This function takes the array,
2452 CACHE, of already calculated exponents and an exponent N and returns
2453 an RTX that corresponds to CACHE[1]**N, as calculated in mode MODE. */
2456 expand_powi_1 (enum machine_mode mode
, unsigned HOST_WIDE_INT n
, rtx
*cache
)
2458 unsigned HOST_WIDE_INT digit
;
2462 if (n
< POWI_TABLE_SIZE
)
2467 target
= gen_reg_rtx (mode
);
2470 op0
= expand_powi_1 (mode
, n
- powi_table
[n
], cache
);
2471 op1
= expand_powi_1 (mode
, powi_table
[n
], cache
);
2475 target
= gen_reg_rtx (mode
);
2476 digit
= n
& ((1 << POWI_WINDOW_SIZE
) - 1);
2477 op0
= expand_powi_1 (mode
, n
- digit
, cache
);
2478 op1
= expand_powi_1 (mode
, digit
, cache
);
2482 target
= gen_reg_rtx (mode
);
2483 op0
= expand_powi_1 (mode
, n
>> 1, cache
);
2487 result
= expand_mult (mode
, op0
, op1
, target
, 0);
2488 if (result
!= target
)
2489 emit_move_insn (target
, result
);
2493 /* Expand the RTL to evaluate powi(x,n) in mode MODE. X is the
2494 floating point operand in mode MODE, and N is the exponent. This
2495 function needs to be kept in sync with powi_cost above. */
2498 expand_powi (rtx x
, enum machine_mode mode
, HOST_WIDE_INT n
)
2500 unsigned HOST_WIDE_INT val
;
2501 rtx cache
[POWI_TABLE_SIZE
];
2505 return CONST1_RTX (mode
);
2507 val
= (n
< 0) ? -n
: n
;
2509 memset (cache
, 0, sizeof (cache
));
2512 result
= expand_powi_1 (mode
, (n
< 0) ? -n
: n
, cache
);
2514 /* If the original exponent was negative, reciprocate the result. */
2516 result
= expand_binop (mode
, sdiv_optab
, CONST1_RTX (mode
),
2517 result
, NULL_RTX
, 0, OPTAB_LIB_WIDEN
);
2522 /* Expand a call to the pow built-in mathematical function. Return 0 if
2523 a normal call should be emitted rather than expanding the function
2524 in-line. EXP is the expression that is a call to the builtin
2525 function; if convenient, the result should be placed in TARGET. */
2528 expand_builtin_pow (tree exp
, rtx target
, rtx subtarget
)
2530 tree arglist
= TREE_OPERAND (exp
, 1);
2533 if (! validate_arglist (arglist
, REAL_TYPE
, REAL_TYPE
, VOID_TYPE
))
2536 arg0
= TREE_VALUE (arglist
);
2537 arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
2539 if (TREE_CODE (arg1
) == REAL_CST
2540 && ! TREE_CONSTANT_OVERFLOW (arg1
))
2542 REAL_VALUE_TYPE cint
;
2546 c
= TREE_REAL_CST (arg1
);
2547 n
= real_to_integer (&c
);
2548 real_from_integer (&cint
, VOIDmode
, n
, n
< 0 ? -1 : 0, 0);
2549 if (real_identical (&c
, &cint
))
2551 /* If the exponent is -1, 0, 1 or 2, then expand_powi is exact.
2552 Otherwise, check the number of multiplications required.
2553 Note that pow never sets errno for an integer exponent. */
2554 if ((n
>= -1 && n
<= 2)
2555 || (flag_unsafe_math_optimizations
2557 && powi_cost (n
) <= POWI_MAX_MULTS
))
2559 enum machine_mode mode
= TYPE_MODE (TREE_TYPE (exp
));
2560 rtx op
= expand_expr (arg0
, subtarget
, VOIDmode
, 0);
2561 op
= force_reg (mode
, op
);
2562 return expand_powi (op
, mode
, n
);
2567 if (! flag_unsafe_math_optimizations
)
2569 return expand_builtin_mathfn_2 (exp
, target
, subtarget
);
2572 /* Expand a call to the powi built-in mathematical function. Return 0 if
2573 a normal call should be emitted rather than expanding the function
2574 in-line. EXP is the expression that is a call to the builtin
2575 function; if convenient, the result should be placed in TARGET. */
2578 expand_builtin_powi (tree exp
, rtx target
, rtx subtarget
)
2580 tree arglist
= TREE_OPERAND (exp
, 1);
2583 enum machine_mode mode
;
2584 enum machine_mode mode2
;
2586 if (! validate_arglist (arglist
, REAL_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
2589 arg0
= TREE_VALUE (arglist
);
2590 arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
2591 mode
= TYPE_MODE (TREE_TYPE (exp
));
2593 /* Handle constant power. */
2595 if (TREE_CODE (arg1
) == INTEGER_CST
2596 && ! TREE_CONSTANT_OVERFLOW (arg1
))
2598 HOST_WIDE_INT n
= TREE_INT_CST_LOW (arg1
);
2600 /* If the exponent is -1, 0, 1 or 2, then expand_powi is exact.
2601 Otherwise, check the number of multiplications required. */
2602 if ((TREE_INT_CST_HIGH (arg1
) == 0
2603 || TREE_INT_CST_HIGH (arg1
) == -1)
2604 && ((n
>= -1 && n
<= 2)
2606 && powi_cost (n
) <= POWI_MAX_MULTS
)))
2608 op0
= expand_expr (arg0
, subtarget
, VOIDmode
, 0);
2609 op0
= force_reg (mode
, op0
);
2610 return expand_powi (op0
, mode
, n
);
2614 /* Emit a libcall to libgcc. */
2616 /* Mode of the 2nd argument must match that of an int. */
2617 mode2
= mode_for_size (INT_TYPE_SIZE
, MODE_INT
, 0);
2619 if (target
== NULL_RTX
)
2620 target
= gen_reg_rtx (mode
);
2622 op0
= expand_expr (arg0
, subtarget
, mode
, 0);
2623 if (GET_MODE (op0
) != mode
)
2624 op0
= convert_to_mode (mode
, op0
, 0);
2625 op1
= expand_expr (arg1
, 0, mode2
, 0);
2626 if (GET_MODE (op1
) != mode2
)
2627 op1
= convert_to_mode (mode2
, op1
, 0);
2629 target
= emit_library_call_value (powi_optab
->handlers
[(int) mode
].libfunc
,
2630 target
, LCT_CONST_MAKE_BLOCK
, mode
, 2,
2631 op0
, mode
, op1
, mode2
);
2636 /* Expand expression EXP which is a call to the strlen builtin. Return 0
2637 if we failed the caller should emit a normal call, otherwise
2638 try to get the result in TARGET, if convenient. */
2641 expand_builtin_strlen (tree arglist
, rtx target
,
2642 enum machine_mode target_mode
)
2644 if (!validate_arglist (arglist
, POINTER_TYPE
, VOID_TYPE
))
2649 tree len
, src
= TREE_VALUE (arglist
);
2650 rtx result
, src_reg
, char_rtx
, before_strlen
;
2651 enum machine_mode insn_mode
= target_mode
, char_mode
;
2652 enum insn_code icode
= CODE_FOR_nothing
;
2655 /* If the length can be computed at compile-time, return it. */
2656 len
= c_strlen (src
, 0);
2658 return expand_expr (len
, target
, target_mode
, EXPAND_NORMAL
);
2660 /* If the length can be computed at compile-time and is constant
2661 integer, but there are side-effects in src, evaluate
2662 src for side-effects, then return len.
2663 E.g. x = strlen (i++ ? "xfoo" + 1 : "bar");
2664 can be optimized into: i++; x = 3; */
2665 len
= c_strlen (src
, 1);
2666 if (len
&& TREE_CODE (len
) == INTEGER_CST
)
2668 expand_expr (src
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
2669 return expand_expr (len
, target
, target_mode
, EXPAND_NORMAL
);
2672 align
= get_pointer_alignment (src
, BIGGEST_ALIGNMENT
) / BITS_PER_UNIT
;
2674 /* If SRC is not a pointer type, don't do this operation inline. */
2678 /* Bail out if we can't compute strlen in the right mode. */
2679 while (insn_mode
!= VOIDmode
)
2681 icode
= strlen_optab
->handlers
[(int) insn_mode
].insn_code
;
2682 if (icode
!= CODE_FOR_nothing
)
2685 insn_mode
= GET_MODE_WIDER_MODE (insn_mode
);
2687 if (insn_mode
== VOIDmode
)
2690 /* Make a place to write the result of the instruction. */
2694 && GET_MODE (result
) == insn_mode
2695 && REGNO (result
) >= FIRST_PSEUDO_REGISTER
))
2696 result
= gen_reg_rtx (insn_mode
);
2698 /* Make a place to hold the source address. We will not expand
2699 the actual source until we are sure that the expansion will
2700 not fail -- there are trees that cannot be expanded twice. */
2701 src_reg
= gen_reg_rtx (Pmode
);
2703 /* Mark the beginning of the strlen sequence so we can emit the
2704 source operand later. */
2705 before_strlen
= get_last_insn ();
2707 char_rtx
= const0_rtx
;
2708 char_mode
= insn_data
[(int) icode
].operand
[2].mode
;
2709 if (! (*insn_data
[(int) icode
].operand
[2].predicate
) (char_rtx
,
2711 char_rtx
= copy_to_mode_reg (char_mode
, char_rtx
);
2713 pat
= GEN_FCN (icode
) (result
, gen_rtx_MEM (BLKmode
, src_reg
),
2714 char_rtx
, GEN_INT (align
));
2719 /* Now that we are assured of success, expand the source. */
2721 pat
= expand_expr (src
, src_reg
, ptr_mode
, EXPAND_NORMAL
);
2723 emit_move_insn (src_reg
, pat
);
2728 emit_insn_after (pat
, before_strlen
);
2730 emit_insn_before (pat
, get_insns ());
2732 /* Return the value in the proper mode for this function. */
2733 if (GET_MODE (result
) == target_mode
)
2735 else if (target
!= 0)
2736 convert_move (target
, result
, 0);
2738 target
= convert_to_mode (target_mode
, result
, 0);
2744 /* Expand a call to the strstr builtin. Return 0 if we failed the
2745 caller should emit a normal call, otherwise try to get the result
2746 in TARGET, if convenient (and in mode MODE if that's convenient). */
2749 expand_builtin_strstr (tree arglist
, tree type
, rtx target
, enum machine_mode mode
)
2751 if (validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
2753 tree result
= fold_builtin_strstr (arglist
, type
);
2755 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
2760 /* Expand a call to the strchr builtin. Return 0 if we failed the
2761 caller should emit a normal call, otherwise try to get the result
2762 in TARGET, if convenient (and in mode MODE if that's convenient). */
2765 expand_builtin_strchr (tree arglist
, tree type
, rtx target
, enum machine_mode mode
)
2767 if (validate_arglist (arglist
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
2769 tree result
= fold_builtin_strchr (arglist
, type
);
2771 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
2773 /* FIXME: Should use strchrM optab so that ports can optimize this. */
2778 /* Expand a call to the strrchr builtin. Return 0 if we failed the
2779 caller should emit a normal call, otherwise try to get the result
2780 in TARGET, if convenient (and in mode MODE if that's convenient). */
2783 expand_builtin_strrchr (tree arglist
, tree type
, rtx target
, enum machine_mode mode
)
2785 if (validate_arglist (arglist
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
2787 tree result
= fold_builtin_strrchr (arglist
, type
);
2789 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
2794 /* Expand a call to the strpbrk builtin. Return 0 if we failed the
2795 caller should emit a normal call, otherwise try to get the result
2796 in TARGET, if convenient (and in mode MODE if that's convenient). */
2799 expand_builtin_strpbrk (tree arglist
, tree type
, rtx target
, enum machine_mode mode
)
2801 if (validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
2803 tree result
= fold_builtin_strpbrk (arglist
, type
);
2805 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
2810 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
2811 bytes from constant string DATA + OFFSET and return it as target
2815 builtin_memcpy_read_str (void *data
, HOST_WIDE_INT offset
,
2816 enum machine_mode mode
)
2818 const char *str
= (const char *) data
;
2820 gcc_assert (offset
>= 0
2821 && ((unsigned HOST_WIDE_INT
) offset
+ GET_MODE_SIZE (mode
)
2822 <= strlen (str
) + 1));
2824 return c_readstr (str
+ offset
, mode
);
2827 /* Expand a call to the memcpy builtin, with arguments in ARGLIST.
2828 Return 0 if we failed, the caller should emit a normal call,
2829 otherwise try to get the result in TARGET, if convenient (and in
2830 mode MODE if that's convenient). */
2832 expand_builtin_memcpy (tree exp
, rtx target
, enum machine_mode mode
)
2834 tree fndecl
= get_callee_fndecl (exp
);
2835 tree arglist
= TREE_OPERAND (exp
, 1);
2836 if (!validate_arglist (arglist
,
2837 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
2841 tree dest
= TREE_VALUE (arglist
);
2842 tree src
= TREE_VALUE (TREE_CHAIN (arglist
));
2843 tree len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
2844 const char *src_str
;
2845 unsigned int src_align
= get_pointer_alignment (src
, BIGGEST_ALIGNMENT
);
2846 unsigned int dest_align
2847 = get_pointer_alignment (dest
, BIGGEST_ALIGNMENT
);
2848 rtx dest_mem
, src_mem
, dest_addr
, len_rtx
;
2849 tree result
= fold_builtin_memcpy (fndecl
, arglist
);
2852 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
2854 /* If DEST is not a pointer type, call the normal function. */
2855 if (dest_align
== 0)
2858 /* If either SRC is not a pointer type, don't do this
2859 operation in-line. */
2863 dest_mem
= get_memory_rtx (dest
, len
);
2864 set_mem_align (dest_mem
, dest_align
);
2865 len_rtx
= expand_normal (len
);
2866 src_str
= c_getstr (src
);
2868 /* If SRC is a string constant and block move would be done
2869 by pieces, we can avoid loading the string from memory
2870 and only stored the computed constants. */
2872 && GET_CODE (len_rtx
) == CONST_INT
2873 && (unsigned HOST_WIDE_INT
) INTVAL (len_rtx
) <= strlen (src_str
) + 1
2874 && can_store_by_pieces (INTVAL (len_rtx
), builtin_memcpy_read_str
,
2875 (void *) src_str
, dest_align
))
2877 dest_mem
= store_by_pieces (dest_mem
, INTVAL (len_rtx
),
2878 builtin_memcpy_read_str
,
2879 (void *) src_str
, dest_align
, 0);
2880 dest_mem
= force_operand (XEXP (dest_mem
, 0), NULL_RTX
);
2881 dest_mem
= convert_memory_address (ptr_mode
, dest_mem
);
2885 src_mem
= get_memory_rtx (src
, len
);
2886 set_mem_align (src_mem
, src_align
);
2888 /* Copy word part most expediently. */
2889 dest_addr
= emit_block_move (dest_mem
, src_mem
, len_rtx
,
2890 CALL_EXPR_TAILCALL (exp
)
2891 ? BLOCK_OP_TAILCALL
: BLOCK_OP_NORMAL
);
2895 dest_addr
= force_operand (XEXP (dest_mem
, 0), NULL_RTX
);
2896 dest_addr
= convert_memory_address (ptr_mode
, dest_addr
);
2902 /* Expand a call to the mempcpy builtin, with arguments in ARGLIST.
2903 Return 0 if we failed; the caller should emit a normal call,
2904 otherwise try to get the result in TARGET, if convenient (and in
2905 mode MODE if that's convenient). If ENDP is 0 return the
2906 destination pointer, if ENDP is 1 return the end pointer ala
2907 mempcpy, and if ENDP is 2 return the end pointer minus one ala
2911 expand_builtin_mempcpy (tree arglist
, tree type
, rtx target
, enum machine_mode mode
,
2914 if (!validate_arglist (arglist
,
2915 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
2917 /* If return value is ignored, transform mempcpy into memcpy. */
2918 else if (target
== const0_rtx
)
2920 tree fn
= implicit_built_in_decls
[BUILT_IN_MEMCPY
];
2925 return expand_expr (build_function_call_expr (fn
, arglist
),
2926 target
, mode
, EXPAND_NORMAL
);
2930 tree dest
= TREE_VALUE (arglist
);
2931 tree src
= TREE_VALUE (TREE_CHAIN (arglist
));
2932 tree len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
2933 const char *src_str
;
2934 unsigned int src_align
= get_pointer_alignment (src
, BIGGEST_ALIGNMENT
);
2935 unsigned int dest_align
2936 = get_pointer_alignment (dest
, BIGGEST_ALIGNMENT
);
2937 rtx dest_mem
, src_mem
, len_rtx
;
2938 tree result
= fold_builtin_mempcpy (arglist
, type
, endp
);
2941 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
2943 /* If either SRC or DEST is not a pointer type, don't do this
2944 operation in-line. */
2945 if (dest_align
== 0 || src_align
== 0)
2948 /* If LEN is not constant, call the normal function. */
2949 if (! host_integerp (len
, 1))
2952 len_rtx
= expand_normal (len
);
2953 src_str
= c_getstr (src
);
2955 /* If SRC is a string constant and block move would be done
2956 by pieces, we can avoid loading the string from memory
2957 and only stored the computed constants. */
2959 && GET_CODE (len_rtx
) == CONST_INT
2960 && (unsigned HOST_WIDE_INT
) INTVAL (len_rtx
) <= strlen (src_str
) + 1
2961 && can_store_by_pieces (INTVAL (len_rtx
), builtin_memcpy_read_str
,
2962 (void *) src_str
, dest_align
))
2964 dest_mem
= get_memory_rtx (dest
, len
);
2965 set_mem_align (dest_mem
, dest_align
);
2966 dest_mem
= store_by_pieces (dest_mem
, INTVAL (len_rtx
),
2967 builtin_memcpy_read_str
,
2968 (void *) src_str
, dest_align
, endp
);
2969 dest_mem
= force_operand (XEXP (dest_mem
, 0), NULL_RTX
);
2970 dest_mem
= convert_memory_address (ptr_mode
, dest_mem
);
2974 if (GET_CODE (len_rtx
) == CONST_INT
2975 && can_move_by_pieces (INTVAL (len_rtx
),
2976 MIN (dest_align
, src_align
)))
2978 dest_mem
= get_memory_rtx (dest
, len
);
2979 set_mem_align (dest_mem
, dest_align
);
2980 src_mem
= get_memory_rtx (src
, len
);
2981 set_mem_align (src_mem
, src_align
);
2982 dest_mem
= move_by_pieces (dest_mem
, src_mem
, INTVAL (len_rtx
),
2983 MIN (dest_align
, src_align
), endp
);
2984 dest_mem
= force_operand (XEXP (dest_mem
, 0), NULL_RTX
);
2985 dest_mem
= convert_memory_address (ptr_mode
, dest_mem
);
2993 /* Expand expression EXP, which is a call to the memmove builtin. Return 0
2994 if we failed; the caller should emit a normal call. */
2997 expand_builtin_memmove (tree arglist
, tree type
, rtx target
,
2998 enum machine_mode mode
, tree orig_exp
)
3000 if (!validate_arglist (arglist
,
3001 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
3005 tree dest
= TREE_VALUE (arglist
);
3006 tree src
= TREE_VALUE (TREE_CHAIN (arglist
));
3007 tree len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
3009 unsigned int src_align
= get_pointer_alignment (src
, BIGGEST_ALIGNMENT
);
3010 unsigned int dest_align
3011 = get_pointer_alignment (dest
, BIGGEST_ALIGNMENT
);
3012 tree result
= fold_builtin_memmove (arglist
, type
);
3015 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
3017 /* If DEST is not a pointer type, call the normal function. */
3018 if (dest_align
== 0)
3021 /* If either SRC is not a pointer type, don't do this
3022 operation in-line. */
3026 /* If src is categorized for a readonly section we can use
3028 if (readonly_data_expr (src
))
3030 tree fn
= implicit_built_in_decls
[BUILT_IN_MEMCPY
];
3033 fn
= build_function_call_expr (fn
, arglist
);
3034 if (TREE_CODE (fn
) == CALL_EXPR
)
3035 CALL_EXPR_TAILCALL (fn
) = CALL_EXPR_TAILCALL (orig_exp
);
3036 return expand_expr (fn
, target
, mode
, EXPAND_NORMAL
);
3039 /* If length is 1 and we can expand memcpy call inline,
3040 it is ok to use memcpy as well. */
3041 if (integer_onep (len
))
3043 rtx ret
= expand_builtin_mempcpy (arglist
, type
, target
, mode
,
3049 /* Otherwise, call the normal function. */
3054 /* Expand expression EXP, which is a call to the bcopy builtin. Return 0
3055 if we failed the caller should emit a normal call. */
3058 expand_builtin_bcopy (tree exp
)
3060 tree arglist
= TREE_OPERAND (exp
, 1);
3061 tree type
= TREE_TYPE (exp
);
3062 tree src
, dest
, size
, newarglist
;
3064 if (!validate_arglist (arglist
,
3065 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
3068 src
= TREE_VALUE (arglist
);
3069 dest
= TREE_VALUE (TREE_CHAIN (arglist
));
3070 size
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
3072 /* New argument list transforming bcopy(ptr x, ptr y, int z) to
3073 memmove(ptr y, ptr x, size_t z). This is done this way
3074 so that if it isn't expanded inline, we fallback to
3075 calling bcopy instead of memmove. */
3077 newarglist
= build_tree_list (NULL_TREE
, fold_convert (sizetype
, size
));
3078 newarglist
= tree_cons (NULL_TREE
, src
, newarglist
);
3079 newarglist
= tree_cons (NULL_TREE
, dest
, newarglist
);
3081 return expand_builtin_memmove (newarglist
, type
, const0_rtx
, VOIDmode
, exp
);
3085 # define HAVE_movstr 0
3086 # define CODE_FOR_movstr CODE_FOR_nothing
3089 /* Expand into a movstr instruction, if one is available. Return 0 if
3090 we failed, the caller should emit a normal call, otherwise try to
3091 get the result in TARGET, if convenient. If ENDP is 0 return the
3092 destination pointer, if ENDP is 1 return the end pointer ala
3093 mempcpy, and if ENDP is 2 return the end pointer minus one ala
3097 expand_movstr (tree dest
, tree src
, rtx target
, int endp
)
3103 const struct insn_data
* data
;
3108 dest_mem
= get_memory_rtx (dest
, NULL
);
3109 src_mem
= get_memory_rtx (src
, NULL
);
3112 target
= force_reg (Pmode
, XEXP (dest_mem
, 0));
3113 dest_mem
= replace_equiv_address (dest_mem
, target
);
3114 end
= gen_reg_rtx (Pmode
);
3118 if (target
== 0 || target
== const0_rtx
)
3120 end
= gen_reg_rtx (Pmode
);
3128 data
= insn_data
+ CODE_FOR_movstr
;
3130 if (data
->operand
[0].mode
!= VOIDmode
)
3131 end
= gen_lowpart (data
->operand
[0].mode
, end
);
3133 insn
= data
->genfun (end
, dest_mem
, src_mem
);
3139 /* movstr is supposed to set end to the address of the NUL
3140 terminator. If the caller requested a mempcpy-like return value,
3142 if (endp
== 1 && target
!= const0_rtx
)
3144 rtx tem
= plus_constant (gen_lowpart (GET_MODE (target
), end
), 1);
3145 emit_move_insn (target
, force_operand (tem
, NULL_RTX
));
3151 /* Expand expression EXP, which is a call to the strcpy builtin. Return 0
3152 if we failed the caller should emit a normal call, otherwise try to get
3153 the result in TARGET, if convenient (and in mode MODE if that's
3157 expand_builtin_strcpy (tree fndecl
, tree arglist
, rtx target
, enum machine_mode mode
)
3159 if (validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
3161 tree result
= fold_builtin_strcpy (fndecl
, arglist
, 0);
3163 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
3165 return expand_movstr (TREE_VALUE (arglist
),
3166 TREE_VALUE (TREE_CHAIN (arglist
)),
3167 target
, /*endp=*/0);
3172 /* Expand a call to the stpcpy builtin, with arguments in ARGLIST.
3173 Return 0 if we failed the caller should emit a normal call,
3174 otherwise try to get the result in TARGET, if convenient (and in
3175 mode MODE if that's convenient). */
3178 expand_builtin_stpcpy (tree exp
, rtx target
, enum machine_mode mode
)
3180 tree arglist
= TREE_OPERAND (exp
, 1);
3181 /* If return value is ignored, transform stpcpy into strcpy. */
3182 if (target
== const0_rtx
)
3184 tree fn
= implicit_built_in_decls
[BUILT_IN_STRCPY
];
3188 return expand_expr (build_function_call_expr (fn
, arglist
),
3189 target
, mode
, EXPAND_NORMAL
);
3192 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
3196 tree dst
, src
, len
, lenp1
;
3200 /* Ensure we get an actual string whose length can be evaluated at
3201 compile-time, not an expression containing a string. This is
3202 because the latter will potentially produce pessimized code
3203 when used to produce the return value. */
3204 src
= TREE_VALUE (TREE_CHAIN (arglist
));
3205 if (! c_getstr (src
) || ! (len
= c_strlen (src
, 0)))
3206 return expand_movstr (TREE_VALUE (arglist
),
3207 TREE_VALUE (TREE_CHAIN (arglist
)),
3208 target
, /*endp=*/2);
3210 dst
= TREE_VALUE (arglist
);
3211 lenp1
= size_binop (PLUS_EXPR
, len
, ssize_int (1));
3212 narglist
= build_tree_list (NULL_TREE
, lenp1
);
3213 narglist
= tree_cons (NULL_TREE
, src
, narglist
);
3214 narglist
= tree_cons (NULL_TREE
, dst
, narglist
);
3215 ret
= expand_builtin_mempcpy (narglist
, TREE_TYPE (exp
),
3216 target
, mode
, /*endp=*/2);
3221 if (TREE_CODE (len
) == INTEGER_CST
)
3223 rtx len_rtx
= expand_normal (len
);
3225 if (GET_CODE (len_rtx
) == CONST_INT
)
3227 ret
= expand_builtin_strcpy (get_callee_fndecl (exp
),
3228 arglist
, target
, mode
);
3234 if (mode
!= VOIDmode
)
3235 target
= gen_reg_rtx (mode
);
3237 target
= gen_reg_rtx (GET_MODE (ret
));
3239 if (GET_MODE (target
) != GET_MODE (ret
))
3240 ret
= gen_lowpart (GET_MODE (target
), ret
);
3242 ret
= plus_constant (ret
, INTVAL (len_rtx
));
3243 ret
= emit_move_insn (target
, force_operand (ret
, NULL_RTX
));
3251 return expand_movstr (TREE_VALUE (arglist
),
3252 TREE_VALUE (TREE_CHAIN (arglist
)),
3253 target
, /*endp=*/2);
3257 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
3258 bytes from constant string DATA + OFFSET and return it as target
3262 builtin_strncpy_read_str (void *data
, HOST_WIDE_INT offset
,
3263 enum machine_mode mode
)
3265 const char *str
= (const char *) data
;
3267 if ((unsigned HOST_WIDE_INT
) offset
> strlen (str
))
3270 return c_readstr (str
+ offset
, mode
);
3273 /* Expand expression EXP, which is a call to the strncpy builtin. Return 0
3274 if we failed the caller should emit a normal call. */
3277 expand_builtin_strncpy (tree exp
, rtx target
, enum machine_mode mode
)
3279 tree fndecl
= get_callee_fndecl (exp
);
3280 tree arglist
= TREE_OPERAND (exp
, 1);
3281 if (validate_arglist (arglist
,
3282 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
3284 tree slen
= c_strlen (TREE_VALUE (TREE_CHAIN (arglist
)), 1);
3285 tree len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
3286 tree result
= fold_builtin_strncpy (fndecl
, arglist
, slen
);
3289 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
3291 /* We must be passed a constant len and src parameter. */
3292 if (!host_integerp (len
, 1) || !slen
|| !host_integerp (slen
, 1))
3295 slen
= size_binop (PLUS_EXPR
, slen
, ssize_int (1));
3297 /* We're required to pad with trailing zeros if the requested
3298 len is greater than strlen(s2)+1. In that case try to
3299 use store_by_pieces, if it fails, punt. */
3300 if (tree_int_cst_lt (slen
, len
))
3302 tree dest
= TREE_VALUE (arglist
);
3303 unsigned int dest_align
3304 = get_pointer_alignment (dest
, BIGGEST_ALIGNMENT
);
3305 const char *p
= c_getstr (TREE_VALUE (TREE_CHAIN (arglist
)));
3308 if (!p
|| dest_align
== 0 || !host_integerp (len
, 1)
3309 || !can_store_by_pieces (tree_low_cst (len
, 1),
3310 builtin_strncpy_read_str
,
3311 (void *) p
, dest_align
))
3314 dest_mem
= get_memory_rtx (dest
, len
);
3315 store_by_pieces (dest_mem
, tree_low_cst (len
, 1),
3316 builtin_strncpy_read_str
,
3317 (void *) p
, dest_align
, 0);
3318 dest_mem
= force_operand (XEXP (dest_mem
, 0), NULL_RTX
);
3319 dest_mem
= convert_memory_address (ptr_mode
, dest_mem
);
3326 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
3327 bytes from constant string DATA + OFFSET and return it as target
3331 builtin_memset_read_str (void *data
, HOST_WIDE_INT offset ATTRIBUTE_UNUSED
,
3332 enum machine_mode mode
)
3334 const char *c
= (const char *) data
;
3335 char *p
= alloca (GET_MODE_SIZE (mode
));
3337 memset (p
, *c
, GET_MODE_SIZE (mode
));
3339 return c_readstr (p
, mode
);
3342 /* Callback routine for store_by_pieces. Return the RTL of a register
3343 containing GET_MODE_SIZE (MODE) consecutive copies of the unsigned
3344 char value given in the RTL register data. For example, if mode is
3345 4 bytes wide, return the RTL for 0x01010101*data. */
3348 builtin_memset_gen_str (void *data
, HOST_WIDE_INT offset ATTRIBUTE_UNUSED
,
3349 enum machine_mode mode
)
3355 size
= GET_MODE_SIZE (mode
);
3360 memset (p
, 1, size
);
3361 coeff
= c_readstr (p
, mode
);
3363 target
= convert_to_mode (mode
, (rtx
) data
, 1);
3364 target
= expand_mult (mode
, target
, coeff
, NULL_RTX
, 1);
3365 return force_reg (mode
, target
);
3368 /* Expand expression EXP, which is a call to the memset builtin. Return 0
3369 if we failed the caller should emit a normal call, otherwise try to get
3370 the result in TARGET, if convenient (and in mode MODE if that's
3374 expand_builtin_memset (tree arglist
, rtx target
, enum machine_mode mode
,
3377 if (!validate_arglist (arglist
,
3378 POINTER_TYPE
, INTEGER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
3382 tree dest
= TREE_VALUE (arglist
);
3383 tree val
= TREE_VALUE (TREE_CHAIN (arglist
));
3384 tree len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
3387 unsigned int dest_align
3388 = get_pointer_alignment (dest
, BIGGEST_ALIGNMENT
);
3389 rtx dest_mem
, dest_addr
, len_rtx
;
3391 /* If DEST is not a pointer type, don't do this
3392 operation in-line. */
3393 if (dest_align
== 0)
3396 /* If the LEN parameter is zero, return DEST. */
3397 if (integer_zerop (len
))
3399 /* Evaluate and ignore VAL in case it has side-effects. */
3400 expand_expr (val
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
3401 return expand_expr (dest
, target
, mode
, EXPAND_NORMAL
);
3404 len_rtx
= expand_normal (len
);
3405 dest_mem
= get_memory_rtx (dest
, len
);
3407 if (TREE_CODE (val
) != INTEGER_CST
)
3411 val
= fold_build1 (CONVERT_EXPR
, unsigned_char_type_node
, val
);
3412 val_rtx
= expand_normal (val
);
3414 /* Assume that we can memset by pieces if we can store the
3415 * the coefficients by pieces (in the required modes).
3416 * We can't pass builtin_memset_gen_str as that emits RTL. */
3418 if (host_integerp (len
, 1)
3419 && !(optimize_size
&& tree_low_cst (len
, 1) > 1)
3420 && can_store_by_pieces (tree_low_cst (len
, 1),
3421 builtin_memset_read_str
, &c
, dest_align
))
3423 val_rtx
= force_reg (TYPE_MODE (unsigned_char_type_node
),
3425 store_by_pieces (dest_mem
, tree_low_cst (len
, 1),
3426 builtin_memset_gen_str
, val_rtx
, dest_align
, 0);
3428 else if (!set_storage_via_setmem(dest_mem
, len_rtx
, val_rtx
,
3432 dest_mem
= force_operand (XEXP (dest_mem
, 0), NULL_RTX
);
3433 dest_mem
= convert_memory_address (ptr_mode
, dest_mem
);
3437 if (target_char_cast (val
, &c
))
3442 if (host_integerp (len
, 1)
3443 && !(optimize_size
&& tree_low_cst (len
, 1) > 1)
3444 && can_store_by_pieces (tree_low_cst (len
, 1),
3445 builtin_memset_read_str
, &c
, dest_align
))
3446 store_by_pieces (dest_mem
, tree_low_cst (len
, 1),
3447 builtin_memset_read_str
, &c
, dest_align
, 0);
3448 else if (!set_storage_via_setmem (dest_mem
, len_rtx
, GEN_INT (c
),
3452 dest_mem
= force_operand (XEXP (dest_mem
, 0), NULL_RTX
);
3453 dest_mem
= convert_memory_address (ptr_mode
, dest_mem
);
3457 set_mem_align (dest_mem
, dest_align
);
3458 dest_addr
= clear_storage (dest_mem
, len_rtx
,
3459 CALL_EXPR_TAILCALL (orig_exp
)
3460 ? BLOCK_OP_TAILCALL
: BLOCK_OP_NORMAL
);
3464 dest_addr
= force_operand (XEXP (dest_mem
, 0), NULL_RTX
);
3465 dest_addr
= convert_memory_address (ptr_mode
, dest_addr
);
3472 /* Expand expression EXP, which is a call to the bzero builtin. Return 0
3473 if we failed the caller should emit a normal call. */
3476 expand_builtin_bzero (tree exp
)
3478 tree arglist
= TREE_OPERAND (exp
, 1);
3479 tree dest
, size
, newarglist
;
3481 if (!validate_arglist (arglist
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
3484 dest
= TREE_VALUE (arglist
);
3485 size
= TREE_VALUE (TREE_CHAIN (arglist
));
3487 /* New argument list transforming bzero(ptr x, int y) to
3488 memset(ptr x, int 0, size_t y). This is done this way
3489 so that if it isn't expanded inline, we fallback to
3490 calling bzero instead of memset. */
3492 newarglist
= build_tree_list (NULL_TREE
, fold_convert (sizetype
, size
));
3493 newarglist
= tree_cons (NULL_TREE
, integer_zero_node
, newarglist
);
3494 newarglist
= tree_cons (NULL_TREE
, dest
, newarglist
);
3496 return expand_builtin_memset (newarglist
, const0_rtx
, VOIDmode
, exp
);
3499 /* Expand expression EXP, which is a call to the memcmp built-in function.
3500 ARGLIST is the argument list for this call. Return 0 if we failed and the
3501 caller should emit a normal call, otherwise try to get the result in
3502 TARGET, if convenient (and in mode MODE, if that's convenient). */
3505 expand_builtin_memcmp (tree exp ATTRIBUTE_UNUSED
, tree arglist
, rtx target
,
3506 enum machine_mode mode
)
3508 if (!validate_arglist (arglist
,
3509 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
3513 tree result
= fold_builtin_memcmp (arglist
);
3515 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
3518 #if defined HAVE_cmpmemsi || defined HAVE_cmpstrnsi
3520 tree arg1
= TREE_VALUE (arglist
);
3521 tree arg2
= TREE_VALUE (TREE_CHAIN (arglist
));
3522 tree len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
3523 rtx arg1_rtx
, arg2_rtx
, arg3_rtx
;
3528 = get_pointer_alignment (arg1
, BIGGEST_ALIGNMENT
) / BITS_PER_UNIT
;
3530 = get_pointer_alignment (arg2
, BIGGEST_ALIGNMENT
) / BITS_PER_UNIT
;
3531 enum machine_mode insn_mode
;
3533 #ifdef HAVE_cmpmemsi
3535 insn_mode
= insn_data
[(int) CODE_FOR_cmpmemsi
].operand
[0].mode
;
3538 #ifdef HAVE_cmpstrnsi
3540 insn_mode
= insn_data
[(int) CODE_FOR_cmpstrnsi
].operand
[0].mode
;
3545 /* If we don't have POINTER_TYPE, call the function. */
3546 if (arg1_align
== 0 || arg2_align
== 0)
3549 /* Make a place to write the result of the instruction. */
3552 && REG_P (result
) && GET_MODE (result
) == insn_mode
3553 && REGNO (result
) >= FIRST_PSEUDO_REGISTER
))
3554 result
= gen_reg_rtx (insn_mode
);
3556 arg1_rtx
= get_memory_rtx (arg1
, len
);
3557 arg2_rtx
= get_memory_rtx (arg2
, len
);
3558 arg3_rtx
= expand_normal (len
);
3560 /* Set MEM_SIZE as appropriate. */
3561 if (GET_CODE (arg3_rtx
) == CONST_INT
)
3563 set_mem_size (arg1_rtx
, arg3_rtx
);
3564 set_mem_size (arg2_rtx
, arg3_rtx
);
3567 #ifdef HAVE_cmpmemsi
3569 insn
= gen_cmpmemsi (result
, arg1_rtx
, arg2_rtx
, arg3_rtx
,
3570 GEN_INT (MIN (arg1_align
, arg2_align
)));
3573 #ifdef HAVE_cmpstrnsi
3575 insn
= gen_cmpstrnsi (result
, arg1_rtx
, arg2_rtx
, arg3_rtx
,
3576 GEN_INT (MIN (arg1_align
, arg2_align
)));
3584 emit_library_call_value (memcmp_libfunc
, result
, LCT_PURE_MAKE_BLOCK
,
3585 TYPE_MODE (integer_type_node
), 3,
3586 XEXP (arg1_rtx
, 0), Pmode
,
3587 XEXP (arg2_rtx
, 0), Pmode
,
3588 convert_to_mode (TYPE_MODE (sizetype
), arg3_rtx
,
3589 TYPE_UNSIGNED (sizetype
)),
3590 TYPE_MODE (sizetype
));
3592 /* Return the value in the proper mode for this function. */
3593 mode
= TYPE_MODE (TREE_TYPE (exp
));
3594 if (GET_MODE (result
) == mode
)
3596 else if (target
!= 0)
3598 convert_move (target
, result
, 0);
3602 return convert_to_mode (mode
, result
, 0);
3609 /* Expand expression EXP, which is a call to the strcmp builtin. Return 0
3610 if we failed the caller should emit a normal call, otherwise try to get
3611 the result in TARGET, if convenient. */
3614 expand_builtin_strcmp (tree exp
, rtx target
, enum machine_mode mode
)
3616 tree arglist
= TREE_OPERAND (exp
, 1);
3618 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
3622 tree result
= fold_builtin_strcmp (arglist
);
3624 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
3627 #if defined HAVE_cmpstrsi || defined HAVE_cmpstrnsi
3628 if (cmpstr_optab
[SImode
] != CODE_FOR_nothing
3629 || cmpstrn_optab
[SImode
] != CODE_FOR_nothing
)
3631 rtx arg1_rtx
, arg2_rtx
;
3632 rtx result
, insn
= NULL_RTX
;
3635 tree arg1
= TREE_VALUE (arglist
);
3636 tree arg2
= TREE_VALUE (TREE_CHAIN (arglist
));
3638 = get_pointer_alignment (arg1
, BIGGEST_ALIGNMENT
) / BITS_PER_UNIT
;
3640 = get_pointer_alignment (arg2
, BIGGEST_ALIGNMENT
) / BITS_PER_UNIT
;
3642 /* If we don't have POINTER_TYPE, call the function. */
3643 if (arg1_align
== 0 || arg2_align
== 0)
3646 /* Stabilize the arguments in case gen_cmpstr(n)si fail. */
3647 arg1
= builtin_save_expr (arg1
);
3648 arg2
= builtin_save_expr (arg2
);
3650 arg1_rtx
= get_memory_rtx (arg1
, NULL
);
3651 arg2_rtx
= get_memory_rtx (arg2
, NULL
);
3653 #ifdef HAVE_cmpstrsi
3654 /* Try to call cmpstrsi. */
3657 enum machine_mode insn_mode
3658 = insn_data
[(int) CODE_FOR_cmpstrsi
].operand
[0].mode
;
3660 /* Make a place to write the result of the instruction. */
3663 && REG_P (result
) && GET_MODE (result
) == insn_mode
3664 && REGNO (result
) >= FIRST_PSEUDO_REGISTER
))
3665 result
= gen_reg_rtx (insn_mode
);
3667 insn
= gen_cmpstrsi (result
, arg1_rtx
, arg2_rtx
,
3668 GEN_INT (MIN (arg1_align
, arg2_align
)));
3672 /* Try to determine at least one length and call cmpstrnsi. */
3673 if (!insn
&& HAVE_cmpstrnsi
)
3678 enum machine_mode insn_mode
3679 = insn_data
[(int) CODE_FOR_cmpstrnsi
].operand
[0].mode
;
3680 tree len1
= c_strlen (arg1
, 1);
3681 tree len2
= c_strlen (arg2
, 1);
3684 len1
= size_binop (PLUS_EXPR
, ssize_int (1), len1
);
3686 len2
= size_binop (PLUS_EXPR
, ssize_int (1), len2
);
3688 /* If we don't have a constant length for the first, use the length
3689 of the second, if we know it. We don't require a constant for
3690 this case; some cost analysis could be done if both are available
3691 but neither is constant. For now, assume they're equally cheap,
3692 unless one has side effects. If both strings have constant lengths,
3699 else if (TREE_SIDE_EFFECTS (len1
))
3701 else if (TREE_SIDE_EFFECTS (len2
))
3703 else if (TREE_CODE (len1
) != INTEGER_CST
)
3705 else if (TREE_CODE (len2
) != INTEGER_CST
)
3707 else if (tree_int_cst_lt (len1
, len2
))
3712 /* If both arguments have side effects, we cannot optimize. */
3713 if (!len
|| TREE_SIDE_EFFECTS (len
))
3716 /* Stabilize the arguments in case gen_cmpstrnsi fails. */
3717 arg3_rtx
= expand_normal (len
);
3719 /* Make a place to write the result of the instruction. */
3722 && REG_P (result
) && GET_MODE (result
) == insn_mode
3723 && REGNO (result
) >= FIRST_PSEUDO_REGISTER
))
3724 result
= gen_reg_rtx (insn_mode
);
3726 insn
= gen_cmpstrnsi (result
, arg1_rtx
, arg2_rtx
, arg3_rtx
,
3727 GEN_INT (MIN (arg1_align
, arg2_align
)));
3735 /* Return the value in the proper mode for this function. */
3736 mode
= TYPE_MODE (TREE_TYPE (exp
));
3737 if (GET_MODE (result
) == mode
)
3740 return convert_to_mode (mode
, result
, 0);
3741 convert_move (target
, result
, 0);
3745 /* Expand the library call ourselves using a stabilized argument
3746 list to avoid re-evaluating the function's arguments twice. */
3747 arglist
= build_tree_list (NULL_TREE
, arg2
);
3748 arglist
= tree_cons (NULL_TREE
, arg1
, arglist
);
3749 fndecl
= get_callee_fndecl (exp
);
3750 fn
= build_function_call_expr (fndecl
, arglist
);
3751 if (TREE_CODE (fn
) == CALL_EXPR
)
3752 CALL_EXPR_TAILCALL (fn
) = CALL_EXPR_TAILCALL (exp
);
3753 return expand_call (fn
, target
, target
== const0_rtx
);
3759 /* Expand expression EXP, which is a call to the strncmp builtin. Return 0
3760 if we failed the caller should emit a normal call, otherwise try to get
3761 the result in TARGET, if convenient. */
3764 expand_builtin_strncmp (tree exp
, rtx target
, enum machine_mode mode
)
3766 tree arglist
= TREE_OPERAND (exp
, 1);
3768 if (!validate_arglist (arglist
,
3769 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
3773 tree result
= fold_builtin_strncmp (arglist
);
3775 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
3778 /* If c_strlen can determine an expression for one of the string
3779 lengths, and it doesn't have side effects, then emit cmpstrnsi
3780 using length MIN(strlen(string)+1, arg3). */
3781 #ifdef HAVE_cmpstrnsi
3784 tree arg1
= TREE_VALUE (arglist
);
3785 tree arg2
= TREE_VALUE (TREE_CHAIN (arglist
));
3786 tree arg3
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
3787 tree len
, len1
, len2
;
3788 rtx arg1_rtx
, arg2_rtx
, arg3_rtx
;
3793 = get_pointer_alignment (arg1
, BIGGEST_ALIGNMENT
) / BITS_PER_UNIT
;
3795 = get_pointer_alignment (arg2
, BIGGEST_ALIGNMENT
) / BITS_PER_UNIT
;
3796 enum machine_mode insn_mode
3797 = insn_data
[(int) CODE_FOR_cmpstrnsi
].operand
[0].mode
;
3799 len1
= c_strlen (arg1
, 1);
3800 len2
= c_strlen (arg2
, 1);
3803 len1
= size_binop (PLUS_EXPR
, ssize_int (1), len1
);
3805 len2
= size_binop (PLUS_EXPR
, ssize_int (1), len2
);
3807 /* If we don't have a constant length for the first, use the length
3808 of the second, if we know it. We don't require a constant for
3809 this case; some cost analysis could be done if both are available
3810 but neither is constant. For now, assume they're equally cheap,
3811 unless one has side effects. If both strings have constant lengths,
3818 else if (TREE_SIDE_EFFECTS (len1
))
3820 else if (TREE_SIDE_EFFECTS (len2
))
3822 else if (TREE_CODE (len1
) != INTEGER_CST
)
3824 else if (TREE_CODE (len2
) != INTEGER_CST
)
3826 else if (tree_int_cst_lt (len1
, len2
))
3831 /* If both arguments have side effects, we cannot optimize. */
3832 if (!len
|| TREE_SIDE_EFFECTS (len
))
3835 /* The actual new length parameter is MIN(len,arg3). */
3836 len
= fold_build2 (MIN_EXPR
, TREE_TYPE (len
), len
,
3837 fold_convert (TREE_TYPE (len
), arg3
));
3839 /* If we don't have POINTER_TYPE, call the function. */
3840 if (arg1_align
== 0 || arg2_align
== 0)
3843 /* Make a place to write the result of the instruction. */
3846 && REG_P (result
) && GET_MODE (result
) == insn_mode
3847 && REGNO (result
) >= FIRST_PSEUDO_REGISTER
))
3848 result
= gen_reg_rtx (insn_mode
);
3850 /* Stabilize the arguments in case gen_cmpstrnsi fails. */
3851 arg1
= builtin_save_expr (arg1
);
3852 arg2
= builtin_save_expr (arg2
);
3853 len
= builtin_save_expr (len
);
3855 arg1_rtx
= get_memory_rtx (arg1
, len
);
3856 arg2_rtx
= get_memory_rtx (arg2
, len
);
3857 arg3_rtx
= expand_normal (len
);
3858 insn
= gen_cmpstrnsi (result
, arg1_rtx
, arg2_rtx
, arg3_rtx
,
3859 GEN_INT (MIN (arg1_align
, arg2_align
)));
3864 /* Return the value in the proper mode for this function. */
3865 mode
= TYPE_MODE (TREE_TYPE (exp
));
3866 if (GET_MODE (result
) == mode
)
3869 return convert_to_mode (mode
, result
, 0);
3870 convert_move (target
, result
, 0);
3874 /* Expand the library call ourselves using a stabilized argument
3875 list to avoid re-evaluating the function's arguments twice. */
3876 arglist
= build_tree_list (NULL_TREE
, len
);
3877 arglist
= tree_cons (NULL_TREE
, arg2
, arglist
);
3878 arglist
= tree_cons (NULL_TREE
, arg1
, arglist
);
3879 fndecl
= get_callee_fndecl (exp
);
3880 fn
= build_function_call_expr (fndecl
, arglist
);
3881 if (TREE_CODE (fn
) == CALL_EXPR
)
3882 CALL_EXPR_TAILCALL (fn
) = CALL_EXPR_TAILCALL (exp
);
3883 return expand_call (fn
, target
, target
== const0_rtx
);
3889 /* Expand expression EXP, which is a call to the strcat builtin.
3890 Return 0 if we failed the caller should emit a normal call,
3891 otherwise try to get the result in TARGET, if convenient. */
3894 expand_builtin_strcat (tree fndecl
, tree arglist
, rtx target
, enum machine_mode mode
)
3896 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
3900 tree dst
= TREE_VALUE (arglist
),
3901 src
= TREE_VALUE (TREE_CHAIN (arglist
));
3902 const char *p
= c_getstr (src
);
3904 /* If the string length is zero, return the dst parameter. */
3905 if (p
&& *p
== '\0')
3906 return expand_expr (dst
, target
, mode
, EXPAND_NORMAL
);
3910 /* See if we can store by pieces into (dst + strlen(dst)). */
3911 tree newsrc
, newdst
,
3912 strlen_fn
= implicit_built_in_decls
[BUILT_IN_STRLEN
];
3915 /* Stabilize the argument list. */
3916 newsrc
= builtin_save_expr (src
);
3918 arglist
= build_tree_list (NULL_TREE
, newsrc
);
3920 arglist
= TREE_CHAIN (arglist
); /* Reusing arglist if safe. */
3922 dst
= builtin_save_expr (dst
);
3926 /* Create strlen (dst). */
3928 build_function_call_expr (strlen_fn
,
3929 build_tree_list (NULL_TREE
, dst
));
3930 /* Create (dst + (cast) strlen (dst)). */
3931 newdst
= fold_convert (TREE_TYPE (dst
), newdst
);
3932 newdst
= fold_build2 (PLUS_EXPR
, TREE_TYPE (dst
), dst
, newdst
);
3934 newdst
= builtin_save_expr (newdst
);
3935 arglist
= tree_cons (NULL_TREE
, newdst
, arglist
);
3937 if (!expand_builtin_strcpy (fndecl
, arglist
, target
, mode
))
3939 end_sequence (); /* Stop sequence. */
3943 /* Output the entire sequence. */
3944 insns
= get_insns ();
3948 return expand_expr (dst
, target
, mode
, EXPAND_NORMAL
);
3955 /* Expand expression EXP, which is a call to the strncat builtin.
3956 Return 0 if we failed the caller should emit a normal call,
3957 otherwise try to get the result in TARGET, if convenient. */
3960 expand_builtin_strncat (tree arglist
, rtx target
, enum machine_mode mode
)
3962 if (validate_arglist (arglist
,
3963 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
3965 tree result
= fold_builtin_strncat (arglist
);
3967 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
3972 /* Expand expression EXP, which is a call to the strspn builtin.
3973 Return 0 if we failed the caller should emit a normal call,
3974 otherwise try to get the result in TARGET, if convenient. */
3977 expand_builtin_strspn (tree arglist
, rtx target
, enum machine_mode mode
)
3979 if (validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
3981 tree result
= fold_builtin_strspn (arglist
);
3983 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
3988 /* Expand expression EXP, which is a call to the strcspn builtin.
3989 Return 0 if we failed the caller should emit a normal call,
3990 otherwise try to get the result in TARGET, if convenient. */
3993 expand_builtin_strcspn (tree arglist
, rtx target
, enum machine_mode mode
)
3995 if (validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
3997 tree result
= fold_builtin_strcspn (arglist
);
3999 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
4004 /* Expand a call to __builtin_saveregs, generating the result in TARGET,
4005 if that's convenient. */
4008 expand_builtin_saveregs (void)
4012 /* Don't do __builtin_saveregs more than once in a function.
4013 Save the result of the first call and reuse it. */
4014 if (saveregs_value
!= 0)
4015 return saveregs_value
;
4017 /* When this function is called, it means that registers must be
4018 saved on entry to this function. So we migrate the call to the
4019 first insn of this function. */
4023 /* Do whatever the machine needs done in this case. */
4024 val
= targetm
.calls
.expand_builtin_saveregs ();
4029 saveregs_value
= val
;
4031 /* Put the insns after the NOTE that starts the function. If this
4032 is inside a start_sequence, make the outer-level insn chain current, so
4033 the code is placed at the start of the function. */
4034 push_topmost_sequence ();
4035 emit_insn_after (seq
, entry_of_function ());
4036 pop_topmost_sequence ();
4041 /* __builtin_args_info (N) returns word N of the arg space info
4042 for the current function. The number and meanings of words
4043 is controlled by the definition of CUMULATIVE_ARGS. */
4046 expand_builtin_args_info (tree arglist
)
4048 int nwords
= sizeof (CUMULATIVE_ARGS
) / sizeof (int);
4049 int *word_ptr
= (int *) ¤t_function_args_info
;
4051 gcc_assert (sizeof (CUMULATIVE_ARGS
) % sizeof (int) == 0);
4055 if (!host_integerp (TREE_VALUE (arglist
), 0))
4056 error ("argument of %<__builtin_args_info%> must be constant");
4059 HOST_WIDE_INT wordnum
= tree_low_cst (TREE_VALUE (arglist
), 0);
4061 if (wordnum
< 0 || wordnum
>= nwords
)
4062 error ("argument of %<__builtin_args_info%> out of range");
4064 return GEN_INT (word_ptr
[wordnum
]);
4068 error ("missing argument in %<__builtin_args_info%>");
4073 /* Expand a call to __builtin_next_arg. */
4076 expand_builtin_next_arg (void)
4078 /* Checking arguments is already done in fold_builtin_next_arg
4079 that must be called before this function. */
4080 return expand_binop (Pmode
, add_optab
,
4081 current_function_internal_arg_pointer
,
4082 current_function_arg_offset_rtx
,
4083 NULL_RTX
, 0, OPTAB_LIB_WIDEN
);
4086 /* Make it easier for the backends by protecting the valist argument
4087 from multiple evaluations. */
4090 stabilize_va_list (tree valist
, int needs_lvalue
)
4092 if (TREE_CODE (va_list_type_node
) == ARRAY_TYPE
)
4094 if (TREE_SIDE_EFFECTS (valist
))
4095 valist
= save_expr (valist
);
4097 /* For this case, the backends will be expecting a pointer to
4098 TREE_TYPE (va_list_type_node), but it's possible we've
4099 actually been given an array (an actual va_list_type_node).
4101 if (TREE_CODE (TREE_TYPE (valist
)) == ARRAY_TYPE
)
4103 tree p1
= build_pointer_type (TREE_TYPE (va_list_type_node
));
4104 valist
= build_fold_addr_expr_with_type (valist
, p1
);
4113 if (! TREE_SIDE_EFFECTS (valist
))
4116 pt
= build_pointer_type (va_list_type_node
);
4117 valist
= fold_build1 (ADDR_EXPR
, pt
, valist
);
4118 TREE_SIDE_EFFECTS (valist
) = 1;
4121 if (TREE_SIDE_EFFECTS (valist
))
4122 valist
= save_expr (valist
);
4123 valist
= build_fold_indirect_ref (valist
);
4129 /* The "standard" definition of va_list is void*. */
4132 std_build_builtin_va_list (void)
4134 return ptr_type_node
;
4137 /* The "standard" implementation of va_start: just assign `nextarg' to
4141 std_expand_builtin_va_start (tree valist
, rtx nextarg
)
4145 t
= build2 (MODIFY_EXPR
, TREE_TYPE (valist
), valist
,
4146 make_tree (ptr_type_node
, nextarg
));
4147 TREE_SIDE_EFFECTS (t
) = 1;
4149 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
4152 /* Expand ARGLIST, from a call to __builtin_va_start. */
4155 expand_builtin_va_start (tree arglist
)
4160 chain
= TREE_CHAIN (arglist
);
4164 error ("too few arguments to function %<va_start%>");
4168 if (fold_builtin_next_arg (chain
))
4171 nextarg
= expand_builtin_next_arg ();
4172 valist
= stabilize_va_list (TREE_VALUE (arglist
), 1);
4174 #ifdef EXPAND_BUILTIN_VA_START
4175 EXPAND_BUILTIN_VA_START (valist
, nextarg
);
4177 std_expand_builtin_va_start (valist
, nextarg
);
4183 /* The "standard" implementation of va_arg: read the value from the
4184 current (padded) address and increment by the (padded) size. */
4187 std_gimplify_va_arg_expr (tree valist
, tree type
, tree
*pre_p
, tree
*post_p
)
4189 tree addr
, t
, type_size
, rounded_size
, valist_tmp
;
4190 unsigned HOST_WIDE_INT align
, boundary
;
4193 #ifdef ARGS_GROW_DOWNWARD
4194 /* All of the alignment and movement below is for args-grow-up machines.
4195 As of 2004, there are only 3 ARGS_GROW_DOWNWARD targets, and they all
4196 implement their own specialized gimplify_va_arg_expr routines. */
4200 indirect
= pass_by_reference (NULL
, TYPE_MODE (type
), type
, false);
4202 type
= build_pointer_type (type
);
4204 align
= PARM_BOUNDARY
/ BITS_PER_UNIT
;
4205 boundary
= FUNCTION_ARG_BOUNDARY (TYPE_MODE (type
), type
) / BITS_PER_UNIT
;
4207 /* Hoist the valist value into a temporary for the moment. */
4208 valist_tmp
= get_initialized_tmp_var (valist
, pre_p
, NULL
);
4210 /* va_list pointer is aligned to PARM_BOUNDARY. If argument actually
4211 requires greater alignment, we must perform dynamic alignment. */
4212 if (boundary
> align
4213 && !integer_zerop (TYPE_SIZE (type
)))
4215 t
= fold_convert (TREE_TYPE (valist
), size_int (boundary
- 1));
4216 t
= build2 (MODIFY_EXPR
, TREE_TYPE (valist
), valist_tmp
,
4217 build2 (PLUS_EXPR
, TREE_TYPE (valist
), valist_tmp
, t
));
4218 gimplify_and_add (t
, pre_p
);
4220 t
= fold_convert (TREE_TYPE (valist
), size_int (-boundary
));
4221 t
= build2 (MODIFY_EXPR
, TREE_TYPE (valist
), valist_tmp
,
4222 build2 (BIT_AND_EXPR
, TREE_TYPE (valist
), valist_tmp
, t
));
4223 gimplify_and_add (t
, pre_p
);
4228 /* If the actual alignment is less than the alignment of the type,
4229 adjust the type accordingly so that we don't assume strict alignment
4230 when deferencing the pointer. */
4231 boundary
*= BITS_PER_UNIT
;
4232 if (boundary
< TYPE_ALIGN (type
))
4234 type
= build_variant_type_copy (type
);
4235 TYPE_ALIGN (type
) = boundary
;
4238 /* Compute the rounded size of the type. */
4239 type_size
= size_in_bytes (type
);
4240 rounded_size
= round_up (type_size
, align
);
4242 /* Reduce rounded_size so it's sharable with the postqueue. */
4243 gimplify_expr (&rounded_size
, pre_p
, post_p
, is_gimple_val
, fb_rvalue
);
4247 if (PAD_VARARGS_DOWN
&& !integer_zerop (rounded_size
))
4249 /* Small args are padded downward. */
4250 t
= fold_build2 (GT_EXPR
, sizetype
, rounded_size
, size_int (align
));
4251 t
= fold_build3 (COND_EXPR
, sizetype
, t
, size_zero_node
,
4252 size_binop (MINUS_EXPR
, rounded_size
, type_size
));
4253 t
= fold_convert (TREE_TYPE (addr
), t
);
4254 addr
= fold_build2 (PLUS_EXPR
, TREE_TYPE (addr
), addr
, t
);
4257 /* Compute new value for AP. */
4258 t
= fold_convert (TREE_TYPE (valist
), rounded_size
);
4259 t
= build2 (PLUS_EXPR
, TREE_TYPE (valist
), valist_tmp
, t
);
4260 t
= build2 (MODIFY_EXPR
, TREE_TYPE (valist
), valist
, t
);
4261 gimplify_and_add (t
, pre_p
);
4263 addr
= fold_convert (build_pointer_type (type
), addr
);
4266 addr
= build_va_arg_indirect_ref (addr
);
4268 return build_va_arg_indirect_ref (addr
);
4271 /* Build an indirect-ref expression over the given TREE, which represents a
4272 piece of a va_arg() expansion. */
4274 build_va_arg_indirect_ref (tree addr
)
4276 addr
= build_fold_indirect_ref (addr
);
4278 if (flag_mudflap
) /* Don't instrument va_arg INDIRECT_REF. */
4284 /* Return a dummy expression of type TYPE in order to keep going after an
4288 dummy_object (tree type
)
4290 tree t
= convert (build_pointer_type (type
), null_pointer_node
);
4291 return build1 (INDIRECT_REF
, type
, t
);
4294 /* Gimplify __builtin_va_arg, aka VA_ARG_EXPR, which is not really a
4295 builtin function, but a very special sort of operator. */
4297 enum gimplify_status
4298 gimplify_va_arg_expr (tree
*expr_p
, tree
*pre_p
, tree
*post_p
)
4300 tree promoted_type
, want_va_type
, have_va_type
;
4301 tree valist
= TREE_OPERAND (*expr_p
, 0);
4302 tree type
= TREE_TYPE (*expr_p
);
4305 /* Verify that valist is of the proper type. */
4306 want_va_type
= va_list_type_node
;
4307 have_va_type
= TREE_TYPE (valist
);
4309 if (have_va_type
== error_mark_node
)
4312 if (TREE_CODE (want_va_type
) == ARRAY_TYPE
)
4314 /* If va_list is an array type, the argument may have decayed
4315 to a pointer type, e.g. by being passed to another function.
4316 In that case, unwrap both types so that we can compare the
4317 underlying records. */
4318 if (TREE_CODE (have_va_type
) == ARRAY_TYPE
4319 || POINTER_TYPE_P (have_va_type
))
4321 want_va_type
= TREE_TYPE (want_va_type
);
4322 have_va_type
= TREE_TYPE (have_va_type
);
4326 if (TYPE_MAIN_VARIANT (want_va_type
) != TYPE_MAIN_VARIANT (have_va_type
))
4328 error ("first argument to %<va_arg%> not of type %<va_list%>");
4332 /* Generate a diagnostic for requesting data of a type that cannot
4333 be passed through `...' due to type promotion at the call site. */
4334 else if ((promoted_type
= lang_hooks
.types
.type_promotes_to (type
))
4337 static bool gave_help
;
4339 /* Unfortunately, this is merely undefined, rather than a constraint
4340 violation, so we cannot make this an error. If this call is never
4341 executed, the program is still strictly conforming. */
4342 warning (0, "%qT is promoted to %qT when passed through %<...%>",
4343 type
, promoted_type
);
4347 warning (0, "(so you should pass %qT not %qT to %<va_arg%>)",
4348 promoted_type
, type
);
4351 /* We can, however, treat "undefined" any way we please.
4352 Call abort to encourage the user to fix the program. */
4353 inform ("if this code is reached, the program will abort");
4354 t
= build_function_call_expr (implicit_built_in_decls
[BUILT_IN_TRAP
],
4356 append_to_statement_list (t
, pre_p
);
4358 /* This is dead code, but go ahead and finish so that the
4359 mode of the result comes out right. */
4360 *expr_p
= dummy_object (type
);
4365 /* Make it easier for the backends by protecting the valist argument
4366 from multiple evaluations. */
4367 if (TREE_CODE (va_list_type_node
) == ARRAY_TYPE
)
4369 /* For this case, the backends will be expecting a pointer to
4370 TREE_TYPE (va_list_type_node), but it's possible we've
4371 actually been given an array (an actual va_list_type_node).
4373 if (TREE_CODE (TREE_TYPE (valist
)) == ARRAY_TYPE
)
4375 tree p1
= build_pointer_type (TREE_TYPE (va_list_type_node
));
4376 valist
= build_fold_addr_expr_with_type (valist
, p1
);
4378 gimplify_expr (&valist
, pre_p
, post_p
, is_gimple_val
, fb_rvalue
);
4381 gimplify_expr (&valist
, pre_p
, post_p
, is_gimple_min_lval
, fb_lvalue
);
4383 if (!targetm
.gimplify_va_arg_expr
)
4384 /* FIXME:Once most targets are converted we should merely
4385 assert this is non-null. */
4388 *expr_p
= targetm
.gimplify_va_arg_expr (valist
, type
, pre_p
, post_p
);
4393 /* Expand ARGLIST, from a call to __builtin_va_end. */
4396 expand_builtin_va_end (tree arglist
)
4398 tree valist
= TREE_VALUE (arglist
);
4400 /* Evaluate for side effects, if needed. I hate macros that don't
4402 if (TREE_SIDE_EFFECTS (valist
))
4403 expand_expr (valist
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
4408 /* Expand ARGLIST, from a call to __builtin_va_copy. We do this as a
4409 builtin rather than just as an assignment in stdarg.h because of the
4410 nastiness of array-type va_list types. */
4413 expand_builtin_va_copy (tree arglist
)
4417 dst
= TREE_VALUE (arglist
);
4418 src
= TREE_VALUE (TREE_CHAIN (arglist
));
4420 dst
= stabilize_va_list (dst
, 1);
4421 src
= stabilize_va_list (src
, 0);
4423 if (TREE_CODE (va_list_type_node
) != ARRAY_TYPE
)
4425 t
= build2 (MODIFY_EXPR
, va_list_type_node
, dst
, src
);
4426 TREE_SIDE_EFFECTS (t
) = 1;
4427 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
4431 rtx dstb
, srcb
, size
;
4433 /* Evaluate to pointers. */
4434 dstb
= expand_expr (dst
, NULL_RTX
, Pmode
, EXPAND_NORMAL
);
4435 srcb
= expand_expr (src
, NULL_RTX
, Pmode
, EXPAND_NORMAL
);
4436 size
= expand_expr (TYPE_SIZE_UNIT (va_list_type_node
), NULL_RTX
,
4437 VOIDmode
, EXPAND_NORMAL
);
4439 dstb
= convert_memory_address (Pmode
, dstb
);
4440 srcb
= convert_memory_address (Pmode
, srcb
);
4442 /* "Dereference" to BLKmode memories. */
4443 dstb
= gen_rtx_MEM (BLKmode
, dstb
);
4444 set_mem_alias_set (dstb
, get_alias_set (TREE_TYPE (TREE_TYPE (dst
))));
4445 set_mem_align (dstb
, TYPE_ALIGN (va_list_type_node
));
4446 srcb
= gen_rtx_MEM (BLKmode
, srcb
);
4447 set_mem_alias_set (srcb
, get_alias_set (TREE_TYPE (TREE_TYPE (src
))));
4448 set_mem_align (srcb
, TYPE_ALIGN (va_list_type_node
));
4451 emit_block_move (dstb
, srcb
, size
, BLOCK_OP_NORMAL
);
4457 /* Expand a call to one of the builtin functions __builtin_frame_address or
4458 __builtin_return_address. */
4461 expand_builtin_frame_address (tree fndecl
, tree arglist
)
4463 /* The argument must be a nonnegative integer constant.
4464 It counts the number of frames to scan up the stack.
4465 The value is the return address saved in that frame. */
4467 /* Warning about missing arg was already issued. */
4469 else if (! host_integerp (TREE_VALUE (arglist
), 1))
4471 if (DECL_FUNCTION_CODE (fndecl
) == BUILT_IN_FRAME_ADDRESS
)
4472 error ("invalid argument to %<__builtin_frame_address%>");
4474 error ("invalid argument to %<__builtin_return_address%>");
4480 = expand_builtin_return_addr (DECL_FUNCTION_CODE (fndecl
),
4481 tree_low_cst (TREE_VALUE (arglist
), 1));
4483 /* Some ports cannot access arbitrary stack frames. */
4486 if (DECL_FUNCTION_CODE (fndecl
) == BUILT_IN_FRAME_ADDRESS
)
4487 warning (0, "unsupported argument to %<__builtin_frame_address%>");
4489 warning (0, "unsupported argument to %<__builtin_return_address%>");
4493 /* For __builtin_frame_address, return what we've got. */
4494 if (DECL_FUNCTION_CODE (fndecl
) == BUILT_IN_FRAME_ADDRESS
)
4498 && ! CONSTANT_P (tem
))
4499 tem
= copy_to_mode_reg (Pmode
, tem
);
4504 /* Expand a call to the alloca builtin, with arguments ARGLIST. Return 0 if
4505 we failed and the caller should emit a normal call, otherwise try to get
4506 the result in TARGET, if convenient. */
4509 expand_builtin_alloca (tree arglist
, rtx target
)
4514 /* In -fmudflap-instrumented code, alloca() and __builtin_alloca()
4515 should always expand to function calls. These can be intercepted
4520 if (!validate_arglist (arglist
, INTEGER_TYPE
, VOID_TYPE
))
4523 /* Compute the argument. */
4524 op0
= expand_normal (TREE_VALUE (arglist
));
4526 /* Allocate the desired space. */
4527 result
= allocate_dynamic_stack_space (op0
, target
, BITS_PER_UNIT
);
4528 result
= convert_memory_address (ptr_mode
, result
);
4533 /* Expand a call to a unary builtin. The arguments are in ARGLIST.
4534 Return 0 if a normal call should be emitted rather than expanding the
4535 function in-line. If convenient, the result should be placed in TARGET.
4536 SUBTARGET may be used as the target for computing one of EXP's operands. */
4539 expand_builtin_unop (enum machine_mode target_mode
, tree arglist
, rtx target
,
4540 rtx subtarget
, optab op_optab
)
4543 if (!validate_arglist (arglist
, INTEGER_TYPE
, VOID_TYPE
))
4546 /* Compute the argument. */
4547 op0
= expand_expr (TREE_VALUE (arglist
), subtarget
, VOIDmode
, 0);
4548 /* Compute op, into TARGET if possible.
4549 Set TARGET to wherever the result comes back. */
4550 target
= expand_unop (TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist
))),
4551 op_optab
, op0
, target
, 1);
4552 gcc_assert (target
);
4554 return convert_to_mode (target_mode
, target
, 0);
4557 /* If the string passed to fputs is a constant and is one character
4558 long, we attempt to transform this call into __builtin_fputc(). */
4561 expand_builtin_fputs (tree arglist
, rtx target
, bool unlocked
)
4563 /* Verify the arguments in the original call. */
4564 if (validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
4566 tree result
= fold_builtin_fputs (arglist
, (target
== const0_rtx
),
4567 unlocked
, NULL_TREE
);
4569 return expand_expr (result
, target
, VOIDmode
, EXPAND_NORMAL
);
4574 /* Expand a call to __builtin_expect. We return our argument and emit a
4575 NOTE_INSN_EXPECTED_VALUE note. This is the expansion of __builtin_expect in
4576 a non-jump context. */
4579 expand_builtin_expect (tree arglist
, rtx target
)
4584 if (arglist
== NULL_TREE
4585 || TREE_CHAIN (arglist
) == NULL_TREE
)
4587 exp
= TREE_VALUE (arglist
);
4588 c
= TREE_VALUE (TREE_CHAIN (arglist
));
4590 if (TREE_CODE (c
) != INTEGER_CST
)
4592 error ("second argument to %<__builtin_expect%> must be a constant");
4593 c
= integer_zero_node
;
4596 target
= expand_expr (exp
, target
, VOIDmode
, EXPAND_NORMAL
);
4598 /* Don't bother with expected value notes for integral constants. */
4599 if (flag_guess_branch_prob
&& GET_CODE (target
) != CONST_INT
)
4601 /* We do need to force this into a register so that we can be
4602 moderately sure to be able to correctly interpret the branch
4604 target
= force_reg (GET_MODE (target
), target
);
4606 rtx_c
= expand_expr (c
, NULL_RTX
, GET_MODE (target
), EXPAND_NORMAL
);
4608 note
= emit_note (NOTE_INSN_EXPECTED_VALUE
);
4609 NOTE_EXPECTED_VALUE (note
) = gen_rtx_EQ (VOIDmode
, target
, rtx_c
);
4615 /* Like expand_builtin_expect, except do this in a jump context. This is
4616 called from do_jump if the conditional is a __builtin_expect. Return either
4617 a list of insns to emit the jump or NULL if we cannot optimize
4618 __builtin_expect. We need to optimize this at jump time so that machines
4619 like the PowerPC don't turn the test into a SCC operation, and then jump
4620 based on the test being 0/1. */
4623 expand_builtin_expect_jump (tree exp
, rtx if_false_label
, rtx if_true_label
)
4625 tree arglist
= TREE_OPERAND (exp
, 1);
4626 tree arg0
= TREE_VALUE (arglist
);
4627 tree arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
4630 /* Only handle __builtin_expect (test, 0) and
4631 __builtin_expect (test, 1). */
4632 if (TREE_CODE (TREE_TYPE (arg1
)) == INTEGER_TYPE
4633 && (integer_zerop (arg1
) || integer_onep (arg1
)))
4635 rtx insn
, drop_through_label
, temp
;
4637 /* Expand the jump insns. */
4639 do_jump (arg0
, if_false_label
, if_true_label
);
4642 drop_through_label
= get_last_insn ();
4643 if (drop_through_label
&& NOTE_P (drop_through_label
))
4644 drop_through_label
= prev_nonnote_insn (drop_through_label
);
4645 if (drop_through_label
&& !LABEL_P (drop_through_label
))
4646 drop_through_label
= NULL_RTX
;
4649 if (! if_true_label
)
4650 if_true_label
= drop_through_label
;
4651 if (! if_false_label
)
4652 if_false_label
= drop_through_label
;
4654 /* Go through and add the expect's to each of the conditional jumps. */
4656 while (insn
!= NULL_RTX
)
4658 rtx next
= NEXT_INSN (insn
);
4660 if (JUMP_P (insn
) && any_condjump_p (insn
))
4662 rtx ifelse
= SET_SRC (pc_set (insn
));
4663 rtx then_dest
= XEXP (ifelse
, 1);
4664 rtx else_dest
= XEXP (ifelse
, 2);
4667 /* First check if we recognize any of the labels. */
4668 if (GET_CODE (then_dest
) == LABEL_REF
4669 && XEXP (then_dest
, 0) == if_true_label
)
4671 else if (GET_CODE (then_dest
) == LABEL_REF
4672 && XEXP (then_dest
, 0) == if_false_label
)
4674 else if (GET_CODE (else_dest
) == LABEL_REF
4675 && XEXP (else_dest
, 0) == if_false_label
)
4677 else if (GET_CODE (else_dest
) == LABEL_REF
4678 && XEXP (else_dest
, 0) == if_true_label
)
4680 /* Otherwise check where we drop through. */
4681 else if (else_dest
== pc_rtx
)
4683 if (next
&& NOTE_P (next
))
4684 next
= next_nonnote_insn (next
);
4686 if (next
&& JUMP_P (next
)
4687 && any_uncondjump_p (next
))
4688 temp
= XEXP (SET_SRC (pc_set (next
)), 0);
4692 /* TEMP is either a CODE_LABEL, NULL_RTX or something
4693 else that can't possibly match either target label. */
4694 if (temp
== if_false_label
)
4696 else if (temp
== if_true_label
)
4699 else if (then_dest
== pc_rtx
)
4701 if (next
&& NOTE_P (next
))
4702 next
= next_nonnote_insn (next
);
4704 if (next
&& JUMP_P (next
)
4705 && any_uncondjump_p (next
))
4706 temp
= XEXP (SET_SRC (pc_set (next
)), 0);
4710 if (temp
== if_false_label
)
4712 else if (temp
== if_true_label
)
4718 /* If the test is expected to fail, reverse the
4720 if (integer_zerop (arg1
))
4722 predict_insn_def (insn
, PRED_BUILTIN_EXPECT
, taken
);
4734 expand_builtin_trap (void)
4738 emit_insn (gen_trap ());
4741 emit_library_call (abort_libfunc
, LCT_NORETURN
, VOIDmode
, 0);
4745 /* Expand a call to fabs, fabsf or fabsl with arguments ARGLIST.
4746 Return 0 if a normal call should be emitted rather than expanding
4747 the function inline. If convenient, the result should be placed
4748 in TARGET. SUBTARGET may be used as the target for computing
4752 expand_builtin_fabs (tree arglist
, rtx target
, rtx subtarget
)
4754 enum machine_mode mode
;
4758 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
4761 arg
= TREE_VALUE (arglist
);
4762 mode
= TYPE_MODE (TREE_TYPE (arg
));
4763 op0
= expand_expr (arg
, subtarget
, VOIDmode
, 0);
4764 return expand_abs (mode
, op0
, target
, 0, safe_from_p (target
, arg
, 1));
4767 /* Expand a call to copysign, copysignf, or copysignl with arguments ARGLIST.
4768 Return NULL is a normal call should be emitted rather than expanding the
4769 function inline. If convenient, the result should be placed in TARGET.
4770 SUBTARGET may be used as the target for computing the operand. */
4773 expand_builtin_copysign (tree arglist
, rtx target
, rtx subtarget
)
4778 if (!validate_arglist (arglist
, REAL_TYPE
, REAL_TYPE
, VOID_TYPE
))
4781 arg
= TREE_VALUE (arglist
);
4782 op0
= expand_expr (arg
, subtarget
, VOIDmode
, EXPAND_NORMAL
);
4784 arg
= TREE_VALUE (TREE_CHAIN (arglist
));
4785 op1
= expand_normal (arg
);
4787 return expand_copysign (op0
, op1
, target
);
4790 /* Create a new constant string literal and return a char* pointer to it.
4791 The STRING_CST value is the LEN characters at STR. */
4793 build_string_literal (int len
, const char *str
)
4795 tree t
, elem
, index
, type
;
4797 t
= build_string (len
, str
);
4798 elem
= build_type_variant (char_type_node
, 1, 0);
4799 index
= build_index_type (build_int_cst (NULL_TREE
, len
- 1));
4800 type
= build_array_type (elem
, index
);
4801 TREE_TYPE (t
) = type
;
4802 TREE_CONSTANT (t
) = 1;
4803 TREE_INVARIANT (t
) = 1;
4804 TREE_READONLY (t
) = 1;
4805 TREE_STATIC (t
) = 1;
4807 type
= build_pointer_type (type
);
4808 t
= build1 (ADDR_EXPR
, type
, t
);
4810 type
= build_pointer_type (elem
);
4811 t
= build1 (NOP_EXPR
, type
, t
);
4815 /* Expand EXP, a call to printf or printf_unlocked.
4816 Return 0 if a normal call should be emitted rather than transforming
4817 the function inline. If convenient, the result should be placed in
4818 TARGET with mode MODE. UNLOCKED indicates this is a printf_unlocked
4821 expand_builtin_printf (tree exp
, rtx target
, enum machine_mode mode
,
4824 tree arglist
= TREE_OPERAND (exp
, 1);
4825 /* If we're using an unlocked function, assume the other unlocked
4826 functions exist explicitly. */
4827 tree
const fn_putchar
= unlocked
? built_in_decls
[BUILT_IN_PUTCHAR_UNLOCKED
]
4828 : implicit_built_in_decls
[BUILT_IN_PUTCHAR
];
4829 tree
const fn_puts
= unlocked
? built_in_decls
[BUILT_IN_PUTS_UNLOCKED
]
4830 : implicit_built_in_decls
[BUILT_IN_PUTS
];
4831 const char *fmt_str
;
4834 /* If the return value is used, don't do the transformation. */
4835 if (target
!= const0_rtx
)
4838 /* Verify the required arguments in the original call. */
4841 fmt
= TREE_VALUE (arglist
);
4842 if (! POINTER_TYPE_P (TREE_TYPE (fmt
)))
4844 arglist
= TREE_CHAIN (arglist
);
4846 /* Check whether the format is a literal string constant. */
4847 fmt_str
= c_getstr (fmt
);
4848 if (fmt_str
== NULL
)
4851 if (!init_target_chars())
4854 /* If the format specifier was "%s\n", call __builtin_puts(arg). */
4855 if (strcmp (fmt_str
, target_percent_s_newline
) == 0)
4858 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist
)))
4859 || TREE_CHAIN (arglist
))
4863 /* If the format specifier was "%c", call __builtin_putchar(arg). */
4864 else if (strcmp (fmt_str
, target_percent_c
) == 0)
4867 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist
))) != INTEGER_TYPE
4868 || TREE_CHAIN (arglist
))
4874 /* We can't handle anything else with % args or %% ... yet. */
4875 if (strchr (fmt_str
, target_percent
))
4881 /* If the format specifier was "", printf does nothing. */
4882 if (fmt_str
[0] == '\0')
4884 /* If the format specifier has length of 1, call putchar. */
4885 if (fmt_str
[1] == '\0')
4887 /* Given printf("c"), (where c is any one character,)
4888 convert "c"[0] to an int and pass that to the replacement
4890 arg
= build_int_cst (NULL_TREE
, fmt_str
[0]);
4891 arglist
= build_tree_list (NULL_TREE
, arg
);
4896 /* If the format specifier was "string\n", call puts("string"). */
4897 size_t len
= strlen (fmt_str
);
4898 if ((unsigned char)fmt_str
[len
- 1] == target_newline
)
4900 /* Create a NUL-terminated string that's one char shorter
4901 than the original, stripping off the trailing '\n'. */
4902 char *newstr
= alloca (len
);
4903 memcpy (newstr
, fmt_str
, len
- 1);
4904 newstr
[len
- 1] = 0;
4906 arg
= build_string_literal (len
, newstr
);
4907 arglist
= build_tree_list (NULL_TREE
, arg
);
4911 /* We'd like to arrange to call fputs(string,stdout) here,
4912 but we need stdout and don't have a way to get it yet. */
4919 fn
= build_function_call_expr (fn
, arglist
);
4920 if (TREE_CODE (fn
) == CALL_EXPR
)
4921 CALL_EXPR_TAILCALL (fn
) = CALL_EXPR_TAILCALL (exp
);
4922 return expand_expr (fn
, target
, mode
, EXPAND_NORMAL
);
4925 /* Expand EXP, a call to fprintf or fprintf_unlocked.
4926 Return 0 if a normal call should be emitted rather than transforming
4927 the function inline. If convenient, the result should be placed in
4928 TARGET with mode MODE. UNLOCKED indicates this is a fprintf_unlocked
4931 expand_builtin_fprintf (tree exp
, rtx target
, enum machine_mode mode
,
4934 tree arglist
= TREE_OPERAND (exp
, 1);
4935 /* If we're using an unlocked function, assume the other unlocked
4936 functions exist explicitly. */
4937 tree
const fn_fputc
= unlocked
? built_in_decls
[BUILT_IN_FPUTC_UNLOCKED
]
4938 : implicit_built_in_decls
[BUILT_IN_FPUTC
];
4939 tree
const fn_fputs
= unlocked
? built_in_decls
[BUILT_IN_FPUTS_UNLOCKED
]
4940 : implicit_built_in_decls
[BUILT_IN_FPUTS
];
4941 const char *fmt_str
;
4942 tree fn
, fmt
, fp
, arg
;
4944 /* If the return value is used, don't do the transformation. */
4945 if (target
!= const0_rtx
)
4948 /* Verify the required arguments in the original call. */
4951 fp
= TREE_VALUE (arglist
);
4952 if (! POINTER_TYPE_P (TREE_TYPE (fp
)))
4954 arglist
= TREE_CHAIN (arglist
);
4957 fmt
= TREE_VALUE (arglist
);
4958 if (! POINTER_TYPE_P (TREE_TYPE (fmt
)))
4960 arglist
= TREE_CHAIN (arglist
);
4962 /* Check whether the format is a literal string constant. */
4963 fmt_str
= c_getstr (fmt
);
4964 if (fmt_str
== NULL
)
4967 if (!init_target_chars())
4970 /* If the format specifier was "%s", call __builtin_fputs(arg,fp). */
4971 if (strcmp (fmt_str
, target_percent_s
) == 0)
4974 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist
)))
4975 || TREE_CHAIN (arglist
))
4977 arg
= TREE_VALUE (arglist
);
4978 arglist
= build_tree_list (NULL_TREE
, fp
);
4979 arglist
= tree_cons (NULL_TREE
, arg
, arglist
);
4982 /* If the format specifier was "%c", call __builtin_fputc(arg,fp). */
4983 else if (strcmp (fmt_str
, target_percent_c
) == 0)
4986 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist
))) != INTEGER_TYPE
4987 || TREE_CHAIN (arglist
))
4989 arg
= TREE_VALUE (arglist
);
4990 arglist
= build_tree_list (NULL_TREE
, fp
);
4991 arglist
= tree_cons (NULL_TREE
, arg
, arglist
);
4996 /* We can't handle anything else with % args or %% ... yet. */
4997 if (strchr (fmt_str
, target_percent
))
5003 /* If the format specifier was "", fprintf does nothing. */
5004 if (fmt_str
[0] == '\0')
5006 /* Evaluate and ignore FILE* argument for side-effects. */
5007 expand_expr (fp
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
5011 /* When "string" doesn't contain %, replace all cases of
5012 fprintf(stream,string) with fputs(string,stream). The fputs
5013 builtin will take care of special cases like length == 1. */
5014 arglist
= build_tree_list (NULL_TREE
, fp
);
5015 arglist
= tree_cons (NULL_TREE
, fmt
, arglist
);
5021 fn
= build_function_call_expr (fn
, arglist
);
5022 if (TREE_CODE (fn
) == CALL_EXPR
)
5023 CALL_EXPR_TAILCALL (fn
) = CALL_EXPR_TAILCALL (exp
);
5024 return expand_expr (fn
, target
, mode
, EXPAND_NORMAL
);
5027 /* Expand a call to sprintf with argument list ARGLIST. Return 0 if
5028 a normal call should be emitted rather than expanding the function
5029 inline. If convenient, the result should be placed in TARGET with
5033 expand_builtin_sprintf (tree arglist
, rtx target
, enum machine_mode mode
)
5035 tree orig_arglist
, dest
, fmt
;
5036 const char *fmt_str
;
5038 orig_arglist
= arglist
;
5040 /* Verify the required arguments in the original call. */
5043 dest
= TREE_VALUE (arglist
);
5044 if (! POINTER_TYPE_P (TREE_TYPE (dest
)))
5046 arglist
= TREE_CHAIN (arglist
);
5049 fmt
= TREE_VALUE (arglist
);
5050 if (! POINTER_TYPE_P (TREE_TYPE (fmt
)))
5052 arglist
= TREE_CHAIN (arglist
);
5054 /* Check whether the format is a literal string constant. */
5055 fmt_str
= c_getstr (fmt
);
5056 if (fmt_str
== NULL
)
5059 if (!init_target_chars())
5062 /* If the format doesn't contain % args or %%, use strcpy. */
5063 if (strchr (fmt_str
, target_percent
) == 0)
5065 tree fn
= implicit_built_in_decls
[BUILT_IN_STRCPY
];
5068 if (arglist
|| ! fn
)
5070 expand_expr (build_function_call_expr (fn
, orig_arglist
),
5071 const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
5072 if (target
== const0_rtx
)
5074 exp
= build_int_cst (NULL_TREE
, strlen (fmt_str
));
5075 return expand_expr (exp
, target
, mode
, EXPAND_NORMAL
);
5077 /* If the format is "%s", use strcpy if the result isn't used. */
5078 else if (strcmp (fmt_str
, target_percent_s
) == 0)
5081 fn
= implicit_built_in_decls
[BUILT_IN_STRCPY
];
5086 if (! arglist
|| TREE_CHAIN (arglist
))
5088 arg
= TREE_VALUE (arglist
);
5089 if (! POINTER_TYPE_P (TREE_TYPE (arg
)))
5092 if (target
!= const0_rtx
)
5094 len
= c_strlen (arg
, 1);
5095 if (! len
|| TREE_CODE (len
) != INTEGER_CST
)
5101 arglist
= build_tree_list (NULL_TREE
, arg
);
5102 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
5103 expand_expr (build_function_call_expr (fn
, arglist
),
5104 const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
5106 if (target
== const0_rtx
)
5108 return expand_expr (len
, target
, mode
, EXPAND_NORMAL
);
5114 /* Expand a call to either the entry or exit function profiler. */
5117 expand_builtin_profile_func (bool exitp
)
5121 this = DECL_RTL (current_function_decl
);
5122 gcc_assert (MEM_P (this));
5123 this = XEXP (this, 0);
5126 which
= profile_function_exit_libfunc
;
5128 which
= profile_function_entry_libfunc
;
5130 emit_library_call (which
, LCT_NORMAL
, VOIDmode
, 2, this, Pmode
,
5131 expand_builtin_return_addr (BUILT_IN_RETURN_ADDRESS
,
5138 /* Given a trampoline address, make sure it satisfies TRAMPOLINE_ALIGNMENT. */
5141 round_trampoline_addr (rtx tramp
)
5143 rtx temp
, addend
, mask
;
5145 /* If we don't need too much alignment, we'll have been guaranteed
5146 proper alignment by get_trampoline_type. */
5147 if (TRAMPOLINE_ALIGNMENT
<= STACK_BOUNDARY
)
5150 /* Round address up to desired boundary. */
5151 temp
= gen_reg_rtx (Pmode
);
5152 addend
= GEN_INT (TRAMPOLINE_ALIGNMENT
/ BITS_PER_UNIT
- 1);
5153 mask
= GEN_INT (-TRAMPOLINE_ALIGNMENT
/ BITS_PER_UNIT
);
5155 temp
= expand_simple_binop (Pmode
, PLUS
, tramp
, addend
,
5156 temp
, 0, OPTAB_LIB_WIDEN
);
5157 tramp
= expand_simple_binop (Pmode
, AND
, temp
, mask
,
5158 temp
, 0, OPTAB_LIB_WIDEN
);
5164 expand_builtin_init_trampoline (tree arglist
)
5166 tree t_tramp
, t_func
, t_chain
;
5167 rtx r_tramp
, r_func
, r_chain
;
5168 #ifdef TRAMPOLINE_TEMPLATE
5172 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
,
5173 POINTER_TYPE
, VOID_TYPE
))
5176 t_tramp
= TREE_VALUE (arglist
);
5177 arglist
= TREE_CHAIN (arglist
);
5178 t_func
= TREE_VALUE (arglist
);
5179 arglist
= TREE_CHAIN (arglist
);
5180 t_chain
= TREE_VALUE (arglist
);
5182 r_tramp
= expand_normal (t_tramp
);
5183 r_func
= expand_normal (t_func
);
5184 r_chain
= expand_normal (t_chain
);
5186 /* Generate insns to initialize the trampoline. */
5187 r_tramp
= round_trampoline_addr (r_tramp
);
5188 #ifdef TRAMPOLINE_TEMPLATE
5189 blktramp
= gen_rtx_MEM (BLKmode
, r_tramp
);
5190 set_mem_align (blktramp
, TRAMPOLINE_ALIGNMENT
);
5191 emit_block_move (blktramp
, assemble_trampoline_template (),
5192 GEN_INT (TRAMPOLINE_SIZE
), BLOCK_OP_NORMAL
);
5194 trampolines_created
= 1;
5195 INITIALIZE_TRAMPOLINE (r_tramp
, r_func
, r_chain
);
5201 expand_builtin_adjust_trampoline (tree arglist
)
5205 if (!validate_arglist (arglist
, POINTER_TYPE
, VOID_TYPE
))
5208 tramp
= expand_normal (TREE_VALUE (arglist
));
5209 tramp
= round_trampoline_addr (tramp
);
5210 #ifdef TRAMPOLINE_ADJUST_ADDRESS
5211 TRAMPOLINE_ADJUST_ADDRESS (tramp
);
5217 /* Expand a call to the built-in signbit, signbitf or signbitl function.
5218 Return NULL_RTX if a normal call should be emitted rather than expanding
5219 the function in-line. EXP is the expression that is a call to the builtin
5220 function; if convenient, the result should be placed in TARGET. */
5223 expand_builtin_signbit (tree exp
, rtx target
)
5225 const struct real_format
*fmt
;
5226 enum machine_mode fmode
, imode
, rmode
;
5227 HOST_WIDE_INT hi
, lo
;
5232 arglist
= TREE_OPERAND (exp
, 1);
5233 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
5236 arg
= TREE_VALUE (arglist
);
5237 fmode
= TYPE_MODE (TREE_TYPE (arg
));
5238 rmode
= TYPE_MODE (TREE_TYPE (exp
));
5239 fmt
= REAL_MODE_FORMAT (fmode
);
5241 /* For floating point formats without a sign bit, implement signbit
5243 bitpos
= fmt
->signbit_ro
;
5246 /* But we can't do this if the format supports signed zero. */
5247 if (fmt
->has_signed_zero
&& HONOR_SIGNED_ZEROS (fmode
))
5250 arg
= fold_build2 (LT_EXPR
, TREE_TYPE (exp
), arg
,
5251 build_real (TREE_TYPE (arg
), dconst0
));
5252 return expand_expr (arg
, target
, VOIDmode
, EXPAND_NORMAL
);
5255 temp
= expand_normal (arg
);
5256 if (GET_MODE_SIZE (fmode
) <= UNITS_PER_WORD
)
5258 imode
= int_mode_for_mode (fmode
);
5259 if (imode
== BLKmode
)
5261 temp
= gen_lowpart (imode
, temp
);
5266 /* Handle targets with different FP word orders. */
5267 if (FLOAT_WORDS_BIG_ENDIAN
)
5268 word
= (GET_MODE_BITSIZE (fmode
) - bitpos
) / BITS_PER_WORD
;
5270 word
= bitpos
/ BITS_PER_WORD
;
5271 temp
= operand_subword_force (temp
, word
, fmode
);
5272 bitpos
= bitpos
% BITS_PER_WORD
;
5275 /* Force the intermediate word_mode (or narrower) result into a
5276 register. This avoids attempting to create paradoxical SUBREGs
5277 of floating point modes below. */
5278 temp
= force_reg (imode
, temp
);
5280 /* If the bitpos is within the "result mode" lowpart, the operation
5281 can be implement with a single bitwise AND. Otherwise, we need
5282 a right shift and an AND. */
5284 if (bitpos
< GET_MODE_BITSIZE (rmode
))
5286 if (bitpos
< HOST_BITS_PER_WIDE_INT
)
5289 lo
= (HOST_WIDE_INT
) 1 << bitpos
;
5293 hi
= (HOST_WIDE_INT
) 1 << (bitpos
- HOST_BITS_PER_WIDE_INT
);
5298 temp
= gen_lowpart (rmode
, temp
);
5299 temp
= expand_binop (rmode
, and_optab
, temp
,
5300 immed_double_const (lo
, hi
, rmode
),
5301 NULL_RTX
, 1, OPTAB_LIB_WIDEN
);
5305 /* Perform a logical right shift to place the signbit in the least
5306 significant bit, then truncate the result to the desired mode
5307 and mask just this bit. */
5308 temp
= expand_shift (RSHIFT_EXPR
, imode
, temp
,
5309 build_int_cst (NULL_TREE
, bitpos
), NULL_RTX
, 1);
5310 temp
= gen_lowpart (rmode
, temp
);
5311 temp
= expand_binop (rmode
, and_optab
, temp
, const1_rtx
,
5312 NULL_RTX
, 1, OPTAB_LIB_WIDEN
);
5318 /* Expand fork or exec calls. TARGET is the desired target of the
5319 call. ARGLIST is the list of arguments of the call. FN is the
5320 identificator of the actual function. IGNORE is nonzero if the
5321 value is to be ignored. */
5324 expand_builtin_fork_or_exec (tree fn
, tree arglist
, rtx target
, int ignore
)
5329 /* If we are not profiling, just call the function. */
5330 if (!profile_arc_flag
)
5333 /* Otherwise call the wrapper. This should be equivalent for the rest of
5334 compiler, so the code does not diverge, and the wrapper may run the
5335 code necessary for keeping the profiling sane. */
5337 switch (DECL_FUNCTION_CODE (fn
))
5340 id
= get_identifier ("__gcov_fork");
5343 case BUILT_IN_EXECL
:
5344 id
= get_identifier ("__gcov_execl");
5347 case BUILT_IN_EXECV
:
5348 id
= get_identifier ("__gcov_execv");
5351 case BUILT_IN_EXECLP
:
5352 id
= get_identifier ("__gcov_execlp");
5355 case BUILT_IN_EXECLE
:
5356 id
= get_identifier ("__gcov_execle");
5359 case BUILT_IN_EXECVP
:
5360 id
= get_identifier ("__gcov_execvp");
5363 case BUILT_IN_EXECVE
:
5364 id
= get_identifier ("__gcov_execve");
5371 decl
= build_decl (FUNCTION_DECL
, id
, TREE_TYPE (fn
));
5372 DECL_EXTERNAL (decl
) = 1;
5373 TREE_PUBLIC (decl
) = 1;
5374 DECL_ARTIFICIAL (decl
) = 1;
5375 TREE_NOTHROW (decl
) = 1;
5376 call
= build_function_call_expr (decl
, arglist
);
5378 return expand_call (call
, target
, ignore
);
5382 /* Reconstitute a mode for a __sync intrinsic operation. Since the type of
5383 the pointer in these functions is void*, the tree optimizers may remove
5384 casts. The mode computed in expand_builtin isn't reliable either, due
5385 to __sync_bool_compare_and_swap.
5387 FCODE_DIFF should be fcode - base, where base is the FOO_1 code for the
5388 group of builtins. This gives us log2 of the mode size. */
5390 static inline enum machine_mode
5391 get_builtin_sync_mode (int fcode_diff
)
5393 /* The size is not negotiable, so ask not to get BLKmode in return
5394 if the target indicates that a smaller size would be better. */
5395 return mode_for_size (BITS_PER_UNIT
<< fcode_diff
, MODE_INT
, 0);
5398 /* Expand the memory expression LOC and return the appropriate memory operand
5399 for the builtin_sync operations. */
5402 get_builtin_sync_mem (tree loc
, enum machine_mode mode
)
5406 addr
= expand_expr (loc
, NULL
, Pmode
, EXPAND_SUM
);
5408 /* Note that we explicitly do not want any alias information for this
5409 memory, so that we kill all other live memories. Otherwise we don't
5410 satisfy the full barrier semantics of the intrinsic. */
5411 mem
= validize_mem (gen_rtx_MEM (mode
, addr
));
5413 set_mem_align (mem
, get_pointer_alignment (loc
, BIGGEST_ALIGNMENT
));
5414 set_mem_alias_set (mem
, ALIAS_SET_MEMORY_BARRIER
);
5415 MEM_VOLATILE_P (mem
) = 1;
5420 /* Expand the __sync_xxx_and_fetch and __sync_fetch_and_xxx intrinsics.
5421 ARGLIST is the operands list to the function. CODE is the rtx code
5422 that corresponds to the arithmetic or logical operation from the name;
5423 an exception here is that NOT actually means NAND. TARGET is an optional
5424 place for us to store the results; AFTER is true if this is the
5425 fetch_and_xxx form. IGNORE is true if we don't actually care about
5426 the result of the operation at all. */
5429 expand_builtin_sync_operation (enum machine_mode mode
, tree arglist
,
5430 enum rtx_code code
, bool after
,
5431 rtx target
, bool ignore
)
5435 /* Expand the operands. */
5436 mem
= get_builtin_sync_mem (TREE_VALUE (arglist
), mode
);
5438 arglist
= TREE_CHAIN (arglist
);
5439 val
= expand_expr (TREE_VALUE (arglist
), NULL
, mode
, EXPAND_NORMAL
);
5442 return expand_sync_operation (mem
, val
, code
);
5444 return expand_sync_fetch_operation (mem
, val
, code
, after
, target
);
5447 /* Expand the __sync_val_compare_and_swap and __sync_bool_compare_and_swap
5448 intrinsics. ARGLIST is the operands list to the function. IS_BOOL is
5449 true if this is the boolean form. TARGET is a place for us to store the
5450 results; this is NOT optional if IS_BOOL is true. */
5453 expand_builtin_compare_and_swap (enum machine_mode mode
, tree arglist
,
5454 bool is_bool
, rtx target
)
5456 rtx old_val
, new_val
, mem
;
5458 /* Expand the operands. */
5459 mem
= get_builtin_sync_mem (TREE_VALUE (arglist
), mode
);
5461 arglist
= TREE_CHAIN (arglist
);
5462 old_val
= expand_expr (TREE_VALUE (arglist
), NULL
, mode
, EXPAND_NORMAL
);
5464 arglist
= TREE_CHAIN (arglist
);
5465 new_val
= expand_expr (TREE_VALUE (arglist
), NULL
, mode
, EXPAND_NORMAL
);
5468 return expand_bool_compare_and_swap (mem
, old_val
, new_val
, target
);
5470 return expand_val_compare_and_swap (mem
, old_val
, new_val
, target
);
5473 /* Expand the __sync_lock_test_and_set intrinsic. Note that the most
5474 general form is actually an atomic exchange, and some targets only
5475 support a reduced form with the second argument being a constant 1.
5476 ARGLIST is the operands list to the function; TARGET is an optional
5477 place for us to store the results. */
5480 expand_builtin_lock_test_and_set (enum machine_mode mode
, tree arglist
,
5485 /* Expand the operands. */
5486 mem
= get_builtin_sync_mem (TREE_VALUE (arglist
), mode
);
5488 arglist
= TREE_CHAIN (arglist
);
5489 val
= expand_expr (TREE_VALUE (arglist
), NULL
, mode
, EXPAND_NORMAL
);
5491 return expand_sync_lock_test_and_set (mem
, val
, target
);
5494 /* Expand the __sync_synchronize intrinsic. */
5497 expand_builtin_synchronize (void)
5501 #ifdef HAVE_memory_barrier
5502 if (HAVE_memory_barrier
)
5504 emit_insn (gen_memory_barrier ());
5509 /* If no explicit memory barrier instruction is available, create an
5510 empty asm stmt with a memory clobber. */
5511 x
= build4 (ASM_EXPR
, void_type_node
, build_string (0, ""), NULL
, NULL
,
5512 tree_cons (NULL
, build_string (6, "memory"), NULL
));
5513 ASM_VOLATILE_P (x
) = 1;
5514 expand_asm_expr (x
);
5517 /* Expand the __sync_lock_release intrinsic. ARGLIST is the operands list
5521 expand_builtin_lock_release (enum machine_mode mode
, tree arglist
)
5523 enum insn_code icode
;
5525 rtx val
= const0_rtx
;
5527 /* Expand the operands. */
5528 mem
= get_builtin_sync_mem (TREE_VALUE (arglist
), mode
);
5530 /* If there is an explicit operation in the md file, use it. */
5531 icode
= sync_lock_release
[mode
];
5532 if (icode
!= CODE_FOR_nothing
)
5534 if (!insn_data
[icode
].operand
[1].predicate (val
, mode
))
5535 val
= force_reg (mode
, val
);
5537 insn
= GEN_FCN (icode
) (mem
, val
);
5545 /* Otherwise we can implement this operation by emitting a barrier
5546 followed by a store of zero. */
5547 expand_builtin_synchronize ();
5548 emit_move_insn (mem
, val
);
5551 /* Expand an expression EXP that calls a built-in function,
5552 with result going to TARGET if that's convenient
5553 (and in mode MODE if that's convenient).
5554 SUBTARGET may be used as the target for computing one of EXP's operands.
5555 IGNORE is nonzero if the value is to be ignored. */
5558 expand_builtin (tree exp
, rtx target
, rtx subtarget
, enum machine_mode mode
,
5561 tree fndecl
= get_callee_fndecl (exp
);
5562 tree arglist
= TREE_OPERAND (exp
, 1);
5563 enum built_in_function fcode
= DECL_FUNCTION_CODE (fndecl
);
5564 enum machine_mode target_mode
= TYPE_MODE (TREE_TYPE (exp
));
5566 if (DECL_BUILT_IN_CLASS (fndecl
) == BUILT_IN_MD
)
5567 return targetm
.expand_builtin (exp
, target
, subtarget
, mode
, ignore
);
5570 /* Try expanding the builtin via the generic target hook. */
5571 rtx tmp
= targetm
.expand_library_builtin (exp
, target
, subtarget
,
5573 if (tmp
!= NULL_RTX
)
5577 /* When not optimizing, generate calls to library functions for a certain
5580 && !called_as_built_in (fndecl
)
5581 && DECL_ASSEMBLER_NAME_SET_P (fndecl
)
5582 && fcode
!= BUILT_IN_ALLOCA
)
5583 return expand_call (exp
, target
, ignore
);
5585 /* The built-in function expanders test for target == const0_rtx
5586 to determine whether the function's result will be ignored. */
5588 target
= const0_rtx
;
5590 /* If the result of a pure or const built-in function is ignored, and
5591 none of its arguments are volatile, we can avoid expanding the
5592 built-in call and just evaluate the arguments for side-effects. */
5593 if (target
== const0_rtx
5594 && (DECL_IS_PURE (fndecl
) || TREE_READONLY (fndecl
)))
5596 bool volatilep
= false;
5599 for (arg
= arglist
; arg
; arg
= TREE_CHAIN (arg
))
5600 if (TREE_THIS_VOLATILE (TREE_VALUE (arg
)))
5608 for (arg
= arglist
; arg
; arg
= TREE_CHAIN (arg
))
5609 expand_expr (TREE_VALUE (arg
), const0_rtx
,
5610 VOIDmode
, EXPAND_NORMAL
);
5617 CASE_FLT_FN (BUILT_IN_FABS
):
5618 target
= expand_builtin_fabs (arglist
, target
, subtarget
);
5623 CASE_FLT_FN (BUILT_IN_COPYSIGN
):
5624 target
= expand_builtin_copysign (arglist
, target
, subtarget
);
5629 /* Just do a normal library call if we were unable to fold
5631 CASE_FLT_FN (BUILT_IN_CABS
):
5634 CASE_FLT_FN (BUILT_IN_EXP
):
5635 CASE_FLT_FN (BUILT_IN_EXP10
):
5636 CASE_FLT_FN (BUILT_IN_POW10
):
5637 CASE_FLT_FN (BUILT_IN_EXP2
):
5638 CASE_FLT_FN (BUILT_IN_EXPM1
):
5639 CASE_FLT_FN (BUILT_IN_LOGB
):
5640 CASE_FLT_FN (BUILT_IN_ILOGB
):
5641 CASE_FLT_FN (BUILT_IN_LOG
):
5642 CASE_FLT_FN (BUILT_IN_LOG10
):
5643 CASE_FLT_FN (BUILT_IN_LOG2
):
5644 CASE_FLT_FN (BUILT_IN_LOG1P
):
5645 CASE_FLT_FN (BUILT_IN_TAN
):
5646 CASE_FLT_FN (BUILT_IN_ASIN
):
5647 CASE_FLT_FN (BUILT_IN_ACOS
):
5648 CASE_FLT_FN (BUILT_IN_ATAN
):
5649 /* Treat these like sqrt only if unsafe math optimizations are allowed,
5650 because of possible accuracy problems. */
5651 if (! flag_unsafe_math_optimizations
)
5653 CASE_FLT_FN (BUILT_IN_SQRT
):
5654 CASE_FLT_FN (BUILT_IN_FLOOR
):
5655 CASE_FLT_FN (BUILT_IN_CEIL
):
5656 CASE_FLT_FN (BUILT_IN_TRUNC
):
5657 CASE_FLT_FN (BUILT_IN_ROUND
):
5658 CASE_FLT_FN (BUILT_IN_NEARBYINT
):
5659 CASE_FLT_FN (BUILT_IN_RINT
):
5660 CASE_FLT_FN (BUILT_IN_LRINT
):
5661 CASE_FLT_FN (BUILT_IN_LLRINT
):
5662 target
= expand_builtin_mathfn (exp
, target
, subtarget
);
5667 CASE_FLT_FN (BUILT_IN_LCEIL
):
5668 CASE_FLT_FN (BUILT_IN_LLCEIL
):
5669 CASE_FLT_FN (BUILT_IN_LFLOOR
):
5670 CASE_FLT_FN (BUILT_IN_LLFLOOR
):
5671 target
= expand_builtin_int_roundingfn (exp
, target
, subtarget
);
5676 CASE_FLT_FN (BUILT_IN_POW
):
5677 target
= expand_builtin_pow (exp
, target
, subtarget
);
5682 CASE_FLT_FN (BUILT_IN_POWI
):
5683 target
= expand_builtin_powi (exp
, target
, subtarget
);
5688 CASE_FLT_FN (BUILT_IN_ATAN2
):
5689 CASE_FLT_FN (BUILT_IN_LDEXP
):
5690 CASE_FLT_FN (BUILT_IN_FMOD
):
5691 CASE_FLT_FN (BUILT_IN_DREM
):
5692 if (! flag_unsafe_math_optimizations
)
5694 target
= expand_builtin_mathfn_2 (exp
, target
, subtarget
);
5699 CASE_FLT_FN (BUILT_IN_SIN
):
5700 CASE_FLT_FN (BUILT_IN_COS
):
5701 if (! flag_unsafe_math_optimizations
)
5703 target
= expand_builtin_mathfn_3 (exp
, target
, subtarget
);
5708 CASE_FLT_FN (BUILT_IN_SINCOS
):
5709 if (! flag_unsafe_math_optimizations
)
5711 target
= expand_builtin_sincos (exp
);
5716 case BUILT_IN_APPLY_ARGS
:
5717 return expand_builtin_apply_args ();
5719 /* __builtin_apply (FUNCTION, ARGUMENTS, ARGSIZE) invokes
5720 FUNCTION with a copy of the parameters described by
5721 ARGUMENTS, and ARGSIZE. It returns a block of memory
5722 allocated on the stack into which is stored all the registers
5723 that might possibly be used for returning the result of a
5724 function. ARGUMENTS is the value returned by
5725 __builtin_apply_args. ARGSIZE is the number of bytes of
5726 arguments that must be copied. ??? How should this value be
5727 computed? We'll also need a safe worst case value for varargs
5729 case BUILT_IN_APPLY
:
5730 if (!validate_arglist (arglist
, POINTER_TYPE
,
5731 POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
)
5732 && !validate_arglist (arglist
, REFERENCE_TYPE
,
5733 POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
5741 for (t
= arglist
, i
= 0; t
; t
= TREE_CHAIN (t
), i
++)
5742 ops
[i
] = expand_normal (TREE_VALUE (t
));
5744 return expand_builtin_apply (ops
[0], ops
[1], ops
[2]);
5747 /* __builtin_return (RESULT) causes the function to return the
5748 value described by RESULT. RESULT is address of the block of
5749 memory returned by __builtin_apply. */
5750 case BUILT_IN_RETURN
:
5751 if (validate_arglist (arglist
, POINTER_TYPE
, VOID_TYPE
))
5752 expand_builtin_return (expand_normal (TREE_VALUE (arglist
)));
5755 case BUILT_IN_SAVEREGS
:
5756 return expand_builtin_saveregs ();
5758 case BUILT_IN_ARGS_INFO
:
5759 return expand_builtin_args_info (arglist
);
5761 /* Return the address of the first anonymous stack arg. */
5762 case BUILT_IN_NEXT_ARG
:
5763 if (fold_builtin_next_arg (arglist
))
5765 return expand_builtin_next_arg ();
5767 case BUILT_IN_CLASSIFY_TYPE
:
5768 return expand_builtin_classify_type (arglist
);
5770 case BUILT_IN_CONSTANT_P
:
5773 case BUILT_IN_FRAME_ADDRESS
:
5774 case BUILT_IN_RETURN_ADDRESS
:
5775 return expand_builtin_frame_address (fndecl
, arglist
);
5777 /* Returns the address of the area where the structure is returned.
5779 case BUILT_IN_AGGREGATE_INCOMING_ADDRESS
:
5781 || ! AGGREGATE_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl
)))
5782 || !MEM_P (DECL_RTL (DECL_RESULT (current_function_decl
))))
5785 return XEXP (DECL_RTL (DECL_RESULT (current_function_decl
)), 0);
5787 case BUILT_IN_ALLOCA
:
5788 target
= expand_builtin_alloca (arglist
, target
);
5793 case BUILT_IN_STACK_SAVE
:
5794 return expand_stack_save ();
5796 case BUILT_IN_STACK_RESTORE
:
5797 expand_stack_restore (TREE_VALUE (arglist
));
5800 CASE_INT_FN (BUILT_IN_FFS
):
5801 case BUILT_IN_FFSIMAX
:
5802 target
= expand_builtin_unop (target_mode
, arglist
, target
,
5803 subtarget
, ffs_optab
);
5808 CASE_INT_FN (BUILT_IN_CLZ
):
5809 case BUILT_IN_CLZIMAX
:
5810 target
= expand_builtin_unop (target_mode
, arglist
, target
,
5811 subtarget
, clz_optab
);
5816 CASE_INT_FN (BUILT_IN_CTZ
):
5817 case BUILT_IN_CTZIMAX
:
5818 target
= expand_builtin_unop (target_mode
, arglist
, target
,
5819 subtarget
, ctz_optab
);
5824 CASE_INT_FN (BUILT_IN_POPCOUNT
):
5825 case BUILT_IN_POPCOUNTIMAX
:
5826 target
= expand_builtin_unop (target_mode
, arglist
, target
,
5827 subtarget
, popcount_optab
);
5832 CASE_INT_FN (BUILT_IN_PARITY
):
5833 case BUILT_IN_PARITYIMAX
:
5834 target
= expand_builtin_unop (target_mode
, arglist
, target
,
5835 subtarget
, parity_optab
);
5840 case BUILT_IN_STRLEN
:
5841 target
= expand_builtin_strlen (arglist
, target
, target_mode
);
5846 case BUILT_IN_STRCPY
:
5847 target
= expand_builtin_strcpy (fndecl
, arglist
, target
, mode
);
5852 case BUILT_IN_STRNCPY
:
5853 target
= expand_builtin_strncpy (exp
, target
, mode
);
5858 case BUILT_IN_STPCPY
:
5859 target
= expand_builtin_stpcpy (exp
, target
, mode
);
5864 case BUILT_IN_STRCAT
:
5865 target
= expand_builtin_strcat (fndecl
, arglist
, target
, mode
);
5870 case BUILT_IN_STRNCAT
:
5871 target
= expand_builtin_strncat (arglist
, target
, mode
);
5876 case BUILT_IN_STRSPN
:
5877 target
= expand_builtin_strspn (arglist
, target
, mode
);
5882 case BUILT_IN_STRCSPN
:
5883 target
= expand_builtin_strcspn (arglist
, target
, mode
);
5888 case BUILT_IN_STRSTR
:
5889 target
= expand_builtin_strstr (arglist
, TREE_TYPE (exp
), target
, mode
);
5894 case BUILT_IN_STRPBRK
:
5895 target
= expand_builtin_strpbrk (arglist
, TREE_TYPE (exp
), target
, mode
);
5900 case BUILT_IN_INDEX
:
5901 case BUILT_IN_STRCHR
:
5902 target
= expand_builtin_strchr (arglist
, TREE_TYPE (exp
), target
, mode
);
5907 case BUILT_IN_RINDEX
:
5908 case BUILT_IN_STRRCHR
:
5909 target
= expand_builtin_strrchr (arglist
, TREE_TYPE (exp
), target
, mode
);
5914 case BUILT_IN_MEMCPY
:
5915 target
= expand_builtin_memcpy (exp
, target
, mode
);
5920 case BUILT_IN_MEMPCPY
:
5921 target
= expand_builtin_mempcpy (arglist
, TREE_TYPE (exp
), target
, mode
, /*endp=*/ 1);
5926 case BUILT_IN_MEMMOVE
:
5927 target
= expand_builtin_memmove (arglist
, TREE_TYPE (exp
), target
,
5933 case BUILT_IN_BCOPY
:
5934 target
= expand_builtin_bcopy (exp
);
5939 case BUILT_IN_MEMSET
:
5940 target
= expand_builtin_memset (arglist
, target
, mode
, exp
);
5945 case BUILT_IN_BZERO
:
5946 target
= expand_builtin_bzero (exp
);
5951 case BUILT_IN_STRCMP
:
5952 target
= expand_builtin_strcmp (exp
, target
, mode
);
5957 case BUILT_IN_STRNCMP
:
5958 target
= expand_builtin_strncmp (exp
, target
, mode
);
5964 case BUILT_IN_MEMCMP
:
5965 target
= expand_builtin_memcmp (exp
, arglist
, target
, mode
);
5970 case BUILT_IN_SETJMP
:
5971 target
= expand_builtin_setjmp (arglist
, target
);
5976 /* __builtin_longjmp is passed a pointer to an array of five words.
5977 It's similar to the C library longjmp function but works with
5978 __builtin_setjmp above. */
5979 case BUILT_IN_LONGJMP
:
5980 if (!validate_arglist (arglist
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
5984 rtx buf_addr
= expand_expr (TREE_VALUE (arglist
), subtarget
,
5985 VOIDmode
, EXPAND_NORMAL
);
5986 rtx value
= expand_normal (TREE_VALUE (TREE_CHAIN (arglist
)));
5988 if (value
!= const1_rtx
)
5990 error ("%<__builtin_longjmp%> second argument must be 1");
5994 expand_builtin_longjmp (buf_addr
, value
);
5998 case BUILT_IN_NONLOCAL_GOTO
:
5999 target
= expand_builtin_nonlocal_goto (arglist
);
6004 /* This updates the setjmp buffer that is its argument with the value
6005 of the current stack pointer. */
6006 case BUILT_IN_UPDATE_SETJMP_BUF
:
6007 if (validate_arglist (arglist
, POINTER_TYPE
, VOID_TYPE
))
6010 = expand_normal (TREE_VALUE (arglist
));
6012 expand_builtin_update_setjmp_buf (buf_addr
);
6018 expand_builtin_trap ();
6021 case BUILT_IN_PRINTF
:
6022 target
= expand_builtin_printf (exp
, target
, mode
, false);
6027 case BUILT_IN_PRINTF_UNLOCKED
:
6028 target
= expand_builtin_printf (exp
, target
, mode
, true);
6033 case BUILT_IN_FPUTS
:
6034 target
= expand_builtin_fputs (arglist
, target
, false);
6038 case BUILT_IN_FPUTS_UNLOCKED
:
6039 target
= expand_builtin_fputs (arglist
, target
, true);
6044 case BUILT_IN_FPRINTF
:
6045 target
= expand_builtin_fprintf (exp
, target
, mode
, false);
6050 case BUILT_IN_FPRINTF_UNLOCKED
:
6051 target
= expand_builtin_fprintf (exp
, target
, mode
, true);
6056 case BUILT_IN_SPRINTF
:
6057 target
= expand_builtin_sprintf (arglist
, target
, mode
);
6062 CASE_FLT_FN (BUILT_IN_SIGNBIT
):
6063 target
= expand_builtin_signbit (exp
, target
);
6068 /* Various hooks for the DWARF 2 __throw routine. */
6069 case BUILT_IN_UNWIND_INIT
:
6070 expand_builtin_unwind_init ();
6072 case BUILT_IN_DWARF_CFA
:
6073 return virtual_cfa_rtx
;
6074 #ifdef DWARF2_UNWIND_INFO
6075 case BUILT_IN_DWARF_SP_COLUMN
:
6076 return expand_builtin_dwarf_sp_column ();
6077 case BUILT_IN_INIT_DWARF_REG_SIZES
:
6078 expand_builtin_init_dwarf_reg_sizes (TREE_VALUE (arglist
));
6081 case BUILT_IN_FROB_RETURN_ADDR
:
6082 return expand_builtin_frob_return_addr (TREE_VALUE (arglist
));
6083 case BUILT_IN_EXTRACT_RETURN_ADDR
:
6084 return expand_builtin_extract_return_addr (TREE_VALUE (arglist
));
6085 case BUILT_IN_EH_RETURN
:
6086 expand_builtin_eh_return (TREE_VALUE (arglist
),
6087 TREE_VALUE (TREE_CHAIN (arglist
)));
6089 #ifdef EH_RETURN_DATA_REGNO
6090 case BUILT_IN_EH_RETURN_DATA_REGNO
:
6091 return expand_builtin_eh_return_data_regno (arglist
);
6093 case BUILT_IN_EXTEND_POINTER
:
6094 return expand_builtin_extend_pointer (TREE_VALUE (arglist
));
6096 case BUILT_IN_VA_START
:
6097 case BUILT_IN_STDARG_START
:
6098 return expand_builtin_va_start (arglist
);
6099 case BUILT_IN_VA_END
:
6100 return expand_builtin_va_end (arglist
);
6101 case BUILT_IN_VA_COPY
:
6102 return expand_builtin_va_copy (arglist
);
6103 case BUILT_IN_EXPECT
:
6104 return expand_builtin_expect (arglist
, target
);
6105 case BUILT_IN_PREFETCH
:
6106 expand_builtin_prefetch (arglist
);
6109 case BUILT_IN_PROFILE_FUNC_ENTER
:
6110 return expand_builtin_profile_func (false);
6111 case BUILT_IN_PROFILE_FUNC_EXIT
:
6112 return expand_builtin_profile_func (true);
6114 case BUILT_IN_INIT_TRAMPOLINE
:
6115 return expand_builtin_init_trampoline (arglist
);
6116 case BUILT_IN_ADJUST_TRAMPOLINE
:
6117 return expand_builtin_adjust_trampoline (arglist
);
6120 case BUILT_IN_EXECL
:
6121 case BUILT_IN_EXECV
:
6122 case BUILT_IN_EXECLP
:
6123 case BUILT_IN_EXECLE
:
6124 case BUILT_IN_EXECVP
:
6125 case BUILT_IN_EXECVE
:
6126 target
= expand_builtin_fork_or_exec (fndecl
, arglist
, target
, ignore
);
6131 case BUILT_IN_FETCH_AND_ADD_1
:
6132 case BUILT_IN_FETCH_AND_ADD_2
:
6133 case BUILT_IN_FETCH_AND_ADD_4
:
6134 case BUILT_IN_FETCH_AND_ADD_8
:
6135 case BUILT_IN_FETCH_AND_ADD_16
:
6136 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_FETCH_AND_ADD_1
);
6137 target
= expand_builtin_sync_operation (mode
, arglist
, PLUS
,
6138 false, target
, ignore
);
6143 case BUILT_IN_FETCH_AND_SUB_1
:
6144 case BUILT_IN_FETCH_AND_SUB_2
:
6145 case BUILT_IN_FETCH_AND_SUB_4
:
6146 case BUILT_IN_FETCH_AND_SUB_8
:
6147 case BUILT_IN_FETCH_AND_SUB_16
:
6148 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_FETCH_AND_SUB_1
);
6149 target
= expand_builtin_sync_operation (mode
, arglist
, MINUS
,
6150 false, target
, ignore
);
6155 case BUILT_IN_FETCH_AND_OR_1
:
6156 case BUILT_IN_FETCH_AND_OR_2
:
6157 case BUILT_IN_FETCH_AND_OR_4
:
6158 case BUILT_IN_FETCH_AND_OR_8
:
6159 case BUILT_IN_FETCH_AND_OR_16
:
6160 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_FETCH_AND_OR_1
);
6161 target
= expand_builtin_sync_operation (mode
, arglist
, IOR
,
6162 false, target
, ignore
);
6167 case BUILT_IN_FETCH_AND_AND_1
:
6168 case BUILT_IN_FETCH_AND_AND_2
:
6169 case BUILT_IN_FETCH_AND_AND_4
:
6170 case BUILT_IN_FETCH_AND_AND_8
:
6171 case BUILT_IN_FETCH_AND_AND_16
:
6172 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_FETCH_AND_AND_1
);
6173 target
= expand_builtin_sync_operation (mode
, arglist
, AND
,
6174 false, target
, ignore
);
6179 case BUILT_IN_FETCH_AND_XOR_1
:
6180 case BUILT_IN_FETCH_AND_XOR_2
:
6181 case BUILT_IN_FETCH_AND_XOR_4
:
6182 case BUILT_IN_FETCH_AND_XOR_8
:
6183 case BUILT_IN_FETCH_AND_XOR_16
:
6184 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_FETCH_AND_XOR_1
);
6185 target
= expand_builtin_sync_operation (mode
, arglist
, XOR
,
6186 false, target
, ignore
);
6191 case BUILT_IN_FETCH_AND_NAND_1
:
6192 case BUILT_IN_FETCH_AND_NAND_2
:
6193 case BUILT_IN_FETCH_AND_NAND_4
:
6194 case BUILT_IN_FETCH_AND_NAND_8
:
6195 case BUILT_IN_FETCH_AND_NAND_16
:
6196 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_FETCH_AND_NAND_1
);
6197 target
= expand_builtin_sync_operation (mode
, arglist
, NOT
,
6198 false, target
, ignore
);
6203 case BUILT_IN_ADD_AND_FETCH_1
:
6204 case BUILT_IN_ADD_AND_FETCH_2
:
6205 case BUILT_IN_ADD_AND_FETCH_4
:
6206 case BUILT_IN_ADD_AND_FETCH_8
:
6207 case BUILT_IN_ADD_AND_FETCH_16
:
6208 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_ADD_AND_FETCH_1
);
6209 target
= expand_builtin_sync_operation (mode
, arglist
, PLUS
,
6210 true, target
, ignore
);
6215 case BUILT_IN_SUB_AND_FETCH_1
:
6216 case BUILT_IN_SUB_AND_FETCH_2
:
6217 case BUILT_IN_SUB_AND_FETCH_4
:
6218 case BUILT_IN_SUB_AND_FETCH_8
:
6219 case BUILT_IN_SUB_AND_FETCH_16
:
6220 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_SUB_AND_FETCH_1
);
6221 target
= expand_builtin_sync_operation (mode
, arglist
, MINUS
,
6222 true, target
, ignore
);
6227 case BUILT_IN_OR_AND_FETCH_1
:
6228 case BUILT_IN_OR_AND_FETCH_2
:
6229 case BUILT_IN_OR_AND_FETCH_4
:
6230 case BUILT_IN_OR_AND_FETCH_8
:
6231 case BUILT_IN_OR_AND_FETCH_16
:
6232 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_OR_AND_FETCH_1
);
6233 target
= expand_builtin_sync_operation (mode
, arglist
, IOR
,
6234 true, target
, ignore
);
6239 case BUILT_IN_AND_AND_FETCH_1
:
6240 case BUILT_IN_AND_AND_FETCH_2
:
6241 case BUILT_IN_AND_AND_FETCH_4
:
6242 case BUILT_IN_AND_AND_FETCH_8
:
6243 case BUILT_IN_AND_AND_FETCH_16
:
6244 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_AND_AND_FETCH_1
);
6245 target
= expand_builtin_sync_operation (mode
, arglist
, AND
,
6246 true, target
, ignore
);
6251 case BUILT_IN_XOR_AND_FETCH_1
:
6252 case BUILT_IN_XOR_AND_FETCH_2
:
6253 case BUILT_IN_XOR_AND_FETCH_4
:
6254 case BUILT_IN_XOR_AND_FETCH_8
:
6255 case BUILT_IN_XOR_AND_FETCH_16
:
6256 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_XOR_AND_FETCH_1
);
6257 target
= expand_builtin_sync_operation (mode
, arglist
, XOR
,
6258 true, target
, ignore
);
6263 case BUILT_IN_NAND_AND_FETCH_1
:
6264 case BUILT_IN_NAND_AND_FETCH_2
:
6265 case BUILT_IN_NAND_AND_FETCH_4
:
6266 case BUILT_IN_NAND_AND_FETCH_8
:
6267 case BUILT_IN_NAND_AND_FETCH_16
:
6268 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_NAND_AND_FETCH_1
);
6269 target
= expand_builtin_sync_operation (mode
, arglist
, NOT
,
6270 true, target
, ignore
);
6275 case BUILT_IN_BOOL_COMPARE_AND_SWAP_1
:
6276 case BUILT_IN_BOOL_COMPARE_AND_SWAP_2
:
6277 case BUILT_IN_BOOL_COMPARE_AND_SWAP_4
:
6278 case BUILT_IN_BOOL_COMPARE_AND_SWAP_8
:
6279 case BUILT_IN_BOOL_COMPARE_AND_SWAP_16
:
6280 if (mode
== VOIDmode
)
6281 mode
= TYPE_MODE (boolean_type_node
);
6282 if (!target
|| !register_operand (target
, mode
))
6283 target
= gen_reg_rtx (mode
);
6285 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_BOOL_COMPARE_AND_SWAP_1
);
6286 target
= expand_builtin_compare_and_swap (mode
, arglist
, true, target
);
6291 case BUILT_IN_VAL_COMPARE_AND_SWAP_1
:
6292 case BUILT_IN_VAL_COMPARE_AND_SWAP_2
:
6293 case BUILT_IN_VAL_COMPARE_AND_SWAP_4
:
6294 case BUILT_IN_VAL_COMPARE_AND_SWAP_8
:
6295 case BUILT_IN_VAL_COMPARE_AND_SWAP_16
:
6296 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_VAL_COMPARE_AND_SWAP_1
);
6297 target
= expand_builtin_compare_and_swap (mode
, arglist
, false, target
);
6302 case BUILT_IN_LOCK_TEST_AND_SET_1
:
6303 case BUILT_IN_LOCK_TEST_AND_SET_2
:
6304 case BUILT_IN_LOCK_TEST_AND_SET_4
:
6305 case BUILT_IN_LOCK_TEST_AND_SET_8
:
6306 case BUILT_IN_LOCK_TEST_AND_SET_16
:
6307 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_LOCK_TEST_AND_SET_1
);
6308 target
= expand_builtin_lock_test_and_set (mode
, arglist
, target
);
6313 case BUILT_IN_LOCK_RELEASE_1
:
6314 case BUILT_IN_LOCK_RELEASE_2
:
6315 case BUILT_IN_LOCK_RELEASE_4
:
6316 case BUILT_IN_LOCK_RELEASE_8
:
6317 case BUILT_IN_LOCK_RELEASE_16
:
6318 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_LOCK_RELEASE_1
);
6319 expand_builtin_lock_release (mode
, arglist
);
6322 case BUILT_IN_SYNCHRONIZE
:
6323 expand_builtin_synchronize ();
6326 case BUILT_IN_OBJECT_SIZE
:
6327 return expand_builtin_object_size (exp
);
6329 case BUILT_IN_MEMCPY_CHK
:
6330 case BUILT_IN_MEMPCPY_CHK
:
6331 case BUILT_IN_MEMMOVE_CHK
:
6332 case BUILT_IN_MEMSET_CHK
:
6333 target
= expand_builtin_memory_chk (exp
, target
, mode
, fcode
);
6338 case BUILT_IN_STRCPY_CHK
:
6339 case BUILT_IN_STPCPY_CHK
:
6340 case BUILT_IN_STRNCPY_CHK
:
6341 case BUILT_IN_STRCAT_CHK
:
6342 case BUILT_IN_SNPRINTF_CHK
:
6343 case BUILT_IN_VSNPRINTF_CHK
:
6344 maybe_emit_chk_warning (exp
, fcode
);
6347 case BUILT_IN_SPRINTF_CHK
:
6348 case BUILT_IN_VSPRINTF_CHK
:
6349 maybe_emit_sprintf_chk_warning (exp
, fcode
);
6352 default: /* just do library call, if unknown builtin */
6356 /* The switch statement above can drop through to cause the function
6357 to be called normally. */
6358 return expand_call (exp
, target
, ignore
);
6361 /* Determine whether a tree node represents a call to a built-in
6362 function. If the tree T is a call to a built-in function with
6363 the right number of arguments of the appropriate types, return
6364 the DECL_FUNCTION_CODE of the call, e.g. BUILT_IN_SQRT.
6365 Otherwise the return value is END_BUILTINS. */
6367 enum built_in_function
6368 builtin_mathfn_code (tree t
)
6370 tree fndecl
, arglist
, parmlist
;
6371 tree argtype
, parmtype
;
6373 if (TREE_CODE (t
) != CALL_EXPR
6374 || TREE_CODE (TREE_OPERAND (t
, 0)) != ADDR_EXPR
)
6375 return END_BUILTINS
;
6377 fndecl
= get_callee_fndecl (t
);
6378 if (fndecl
== NULL_TREE
6379 || TREE_CODE (fndecl
) != FUNCTION_DECL
6380 || ! DECL_BUILT_IN (fndecl
)
6381 || DECL_BUILT_IN_CLASS (fndecl
) == BUILT_IN_MD
)
6382 return END_BUILTINS
;
6384 arglist
= TREE_OPERAND (t
, 1);
6385 parmlist
= TYPE_ARG_TYPES (TREE_TYPE (fndecl
));
6386 for (; parmlist
; parmlist
= TREE_CHAIN (parmlist
))
6388 /* If a function doesn't take a variable number of arguments,
6389 the last element in the list will have type `void'. */
6390 parmtype
= TREE_VALUE (parmlist
);
6391 if (VOID_TYPE_P (parmtype
))
6394 return END_BUILTINS
;
6395 return DECL_FUNCTION_CODE (fndecl
);
6399 return END_BUILTINS
;
6401 argtype
= TREE_TYPE (TREE_VALUE (arglist
));
6403 if (SCALAR_FLOAT_TYPE_P (parmtype
))
6405 if (! SCALAR_FLOAT_TYPE_P (argtype
))
6406 return END_BUILTINS
;
6408 else if (COMPLEX_FLOAT_TYPE_P (parmtype
))
6410 if (! COMPLEX_FLOAT_TYPE_P (argtype
))
6411 return END_BUILTINS
;
6413 else if (POINTER_TYPE_P (parmtype
))
6415 if (! POINTER_TYPE_P (argtype
))
6416 return END_BUILTINS
;
6418 else if (INTEGRAL_TYPE_P (parmtype
))
6420 if (! INTEGRAL_TYPE_P (argtype
))
6421 return END_BUILTINS
;
6424 return END_BUILTINS
;
6426 arglist
= TREE_CHAIN (arglist
);
6429 /* Variable-length argument list. */
6430 return DECL_FUNCTION_CODE (fndecl
);
6433 /* Fold a call to __builtin_constant_p, if we know it will evaluate to a
6434 constant. ARGLIST is the argument list of the call. */
6437 fold_builtin_constant_p (tree arglist
)
6442 arglist
= TREE_VALUE (arglist
);
6444 /* We return 1 for a numeric type that's known to be a constant
6445 value at compile-time or for an aggregate type that's a
6446 literal constant. */
6447 STRIP_NOPS (arglist
);
6449 /* If we know this is a constant, emit the constant of one. */
6450 if (CONSTANT_CLASS_P (arglist
)
6451 || (TREE_CODE (arglist
) == CONSTRUCTOR
6452 && TREE_CONSTANT (arglist
)))
6453 return integer_one_node
;
6454 if (TREE_CODE (arglist
) == ADDR_EXPR
)
6456 tree op
= TREE_OPERAND (arglist
, 0);
6457 if (TREE_CODE (op
) == STRING_CST
6458 || (TREE_CODE (op
) == ARRAY_REF
6459 && integer_zerop (TREE_OPERAND (op
, 1))
6460 && TREE_CODE (TREE_OPERAND (op
, 0)) == STRING_CST
))
6461 return integer_one_node
;
6464 /* If this expression has side effects, show we don't know it to be a
6465 constant. Likewise if it's a pointer or aggregate type since in
6466 those case we only want literals, since those are only optimized
6467 when generating RTL, not later.
6468 And finally, if we are compiling an initializer, not code, we
6469 need to return a definite result now; there's not going to be any
6470 more optimization done. */
6471 if (TREE_SIDE_EFFECTS (arglist
)
6472 || AGGREGATE_TYPE_P (TREE_TYPE (arglist
))
6473 || POINTER_TYPE_P (TREE_TYPE (arglist
))
6475 return integer_zero_node
;
6480 /* Fold a call to __builtin_expect, if we expect that a comparison against
6481 the argument will fold to a constant. In practice, this means a true
6482 constant or the address of a non-weak symbol. ARGLIST is the argument
6483 list of the call. */
6486 fold_builtin_expect (tree arglist
)
6493 arg
= TREE_VALUE (arglist
);
6495 /* If the argument isn't invariant, then there's nothing we can do. */
6496 if (!TREE_INVARIANT (arg
))
6499 /* If we're looking at an address of a weak decl, then do not fold. */
6502 if (TREE_CODE (inner
) == ADDR_EXPR
)
6506 inner
= TREE_OPERAND (inner
, 0);
6508 while (TREE_CODE (inner
) == COMPONENT_REF
6509 || TREE_CODE (inner
) == ARRAY_REF
);
6510 if (DECL_P (inner
) && DECL_WEAK (inner
))
6514 /* Otherwise, ARG already has the proper type for the return value. */
6518 /* Fold a call to __builtin_classify_type. */
6521 fold_builtin_classify_type (tree arglist
)
6524 return build_int_cst (NULL_TREE
, no_type_class
);
6526 return build_int_cst (NULL_TREE
,
6527 type_to_class (TREE_TYPE (TREE_VALUE (arglist
))));
6530 /* Fold a call to __builtin_strlen. */
6533 fold_builtin_strlen (tree arglist
)
6535 if (!validate_arglist (arglist
, POINTER_TYPE
, VOID_TYPE
))
6539 tree len
= c_strlen (TREE_VALUE (arglist
), 0);
6543 /* Convert from the internal "sizetype" type to "size_t". */
6545 len
= fold_convert (size_type_node
, len
);
6553 /* Fold a call to __builtin_inf or __builtin_huge_val. */
6556 fold_builtin_inf (tree type
, int warn
)
6558 REAL_VALUE_TYPE real
;
6560 /* __builtin_inff is intended to be usable to define INFINITY on all
6561 targets. If an infinity is not available, INFINITY expands "to a
6562 positive constant of type float that overflows at translation
6563 time", footnote "In this case, using INFINITY will violate the
6564 constraint in 6.4.4 and thus require a diagnostic." (C99 7.12#4).
6565 Thus we pedwarn to ensure this constraint violation is
6567 if (!MODE_HAS_INFINITIES (TYPE_MODE (type
)) && warn
)
6568 pedwarn ("target format does not support infinity");
6571 return build_real (type
, real
);
6574 /* Fold a call to __builtin_nan or __builtin_nans. */
6577 fold_builtin_nan (tree arglist
, tree type
, int quiet
)
6579 REAL_VALUE_TYPE real
;
6582 if (!validate_arglist (arglist
, POINTER_TYPE
, VOID_TYPE
))
6584 str
= c_getstr (TREE_VALUE (arglist
));
6588 if (!real_nan (&real
, str
, quiet
, TYPE_MODE (type
)))
6591 return build_real (type
, real
);
6594 /* Return true if the floating point expression T has an integer value.
6595 We also allow +Inf, -Inf and NaN to be considered integer values. */
6598 integer_valued_real_p (tree t
)
6600 switch (TREE_CODE (t
))
6607 case NON_LVALUE_EXPR
:
6608 return integer_valued_real_p (TREE_OPERAND (t
, 0));
6613 return integer_valued_real_p (TREE_OPERAND (t
, 1));
6620 return integer_valued_real_p (TREE_OPERAND (t
, 0))
6621 && integer_valued_real_p (TREE_OPERAND (t
, 1));
6624 return integer_valued_real_p (TREE_OPERAND (t
, 1))
6625 && integer_valued_real_p (TREE_OPERAND (t
, 2));
6628 if (! TREE_CONSTANT_OVERFLOW (t
))
6630 REAL_VALUE_TYPE c
, cint
;
6632 c
= TREE_REAL_CST (t
);
6633 real_trunc (&cint
, TYPE_MODE (TREE_TYPE (t
)), &c
);
6634 return real_identical (&c
, &cint
);
6640 tree type
= TREE_TYPE (TREE_OPERAND (t
, 0));
6641 if (TREE_CODE (type
) == INTEGER_TYPE
)
6643 if (TREE_CODE (type
) == REAL_TYPE
)
6644 return integer_valued_real_p (TREE_OPERAND (t
, 0));
6649 switch (builtin_mathfn_code (t
))
6651 CASE_FLT_FN (BUILT_IN_CEIL
):
6652 CASE_FLT_FN (BUILT_IN_FLOOR
):
6653 CASE_FLT_FN (BUILT_IN_NEARBYINT
):
6654 CASE_FLT_FN (BUILT_IN_RINT
):
6655 CASE_FLT_FN (BUILT_IN_ROUND
):
6656 CASE_FLT_FN (BUILT_IN_TRUNC
):
6670 /* EXP is assumed to be builtin call where truncation can be propagated
6671 across (for instance floor((double)f) == (double)floorf (f).
6672 Do the transformation. */
6675 fold_trunc_transparent_mathfn (tree fndecl
, tree arglist
)
6677 enum built_in_function fcode
= DECL_FUNCTION_CODE (fndecl
);
6680 if (! validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
6683 arg
= TREE_VALUE (arglist
);
6684 /* Integer rounding functions are idempotent. */
6685 if (fcode
== builtin_mathfn_code (arg
))
6688 /* If argument is already integer valued, and we don't need to worry
6689 about setting errno, there's no need to perform rounding. */
6690 if (! flag_errno_math
&& integer_valued_real_p (arg
))
6695 tree arg0
= strip_float_extensions (arg
);
6696 tree ftype
= TREE_TYPE (TREE_TYPE (fndecl
));
6697 tree newtype
= TREE_TYPE (arg0
);
6700 if (TYPE_PRECISION (newtype
) < TYPE_PRECISION (ftype
)
6701 && (decl
= mathfn_built_in (newtype
, fcode
)))
6704 build_tree_list (NULL_TREE
, fold_convert (newtype
, arg0
));
6705 return fold_convert (ftype
,
6706 build_function_call_expr (decl
, arglist
));
6712 /* EXP is assumed to be builtin call which can narrow the FP type of
6713 the argument, for instance lround((double)f) -> lroundf (f). */
6716 fold_fixed_mathfn (tree fndecl
, tree arglist
)
6718 enum built_in_function fcode
= DECL_FUNCTION_CODE (fndecl
);
6721 if (! validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
6724 arg
= TREE_VALUE (arglist
);
6726 /* If argument is already integer valued, and we don't need to worry
6727 about setting errno, there's no need to perform rounding. */
6728 if (! flag_errno_math
&& integer_valued_real_p (arg
))
6729 return fold_build1 (FIX_TRUNC_EXPR
, TREE_TYPE (TREE_TYPE (fndecl
)), arg
);
6733 tree ftype
= TREE_TYPE (arg
);
6734 tree arg0
= strip_float_extensions (arg
);
6735 tree newtype
= TREE_TYPE (arg0
);
6738 if (TYPE_PRECISION (newtype
) < TYPE_PRECISION (ftype
)
6739 && (decl
= mathfn_built_in (newtype
, fcode
)))
6742 build_tree_list (NULL_TREE
, fold_convert (newtype
, arg0
));
6743 return build_function_call_expr (decl
, arglist
);
6749 /* Fold function call to builtin cabs, cabsf or cabsl. ARGLIST
6750 is the argument list and TYPE is the return type. Return
6751 NULL_TREE if no if no simplification can be made. */
6754 fold_builtin_cabs (tree arglist
, tree type
)
6758 if (!arglist
|| TREE_CHAIN (arglist
))
6761 arg
= TREE_VALUE (arglist
);
6762 if (TREE_CODE (TREE_TYPE (arg
)) != COMPLEX_TYPE
6763 || TREE_CODE (TREE_TYPE (TREE_TYPE (arg
))) != REAL_TYPE
)
6766 /* Evaluate cabs of a constant at compile-time. */
6767 if (flag_unsafe_math_optimizations
6768 && TREE_CODE (arg
) == COMPLEX_CST
6769 && TREE_CODE (TREE_REALPART (arg
)) == REAL_CST
6770 && TREE_CODE (TREE_IMAGPART (arg
)) == REAL_CST
6771 && ! TREE_CONSTANT_OVERFLOW (TREE_REALPART (arg
))
6772 && ! TREE_CONSTANT_OVERFLOW (TREE_IMAGPART (arg
)))
6774 REAL_VALUE_TYPE r
, i
;
6776 r
= TREE_REAL_CST (TREE_REALPART (arg
));
6777 i
= TREE_REAL_CST (TREE_IMAGPART (arg
));
6779 real_arithmetic (&r
, MULT_EXPR
, &r
, &r
);
6780 real_arithmetic (&i
, MULT_EXPR
, &i
, &i
);
6781 real_arithmetic (&r
, PLUS_EXPR
, &r
, &i
);
6782 if (real_sqrt (&r
, TYPE_MODE (type
), &r
)
6783 || ! flag_trapping_math
)
6784 return build_real (type
, r
);
6787 /* If either part is zero, cabs is fabs of the other. */
6788 if (TREE_CODE (arg
) == COMPLEX_EXPR
6789 && real_zerop (TREE_OPERAND (arg
, 0)))
6790 return fold_build1 (ABS_EXPR
, type
, TREE_OPERAND (arg
, 1));
6791 if (TREE_CODE (arg
) == COMPLEX_EXPR
6792 && real_zerop (TREE_OPERAND (arg
, 1)))
6793 return fold_build1 (ABS_EXPR
, type
, TREE_OPERAND (arg
, 0));
6795 /* Don't do this when optimizing for size. */
6796 if (flag_unsafe_math_optimizations
6797 && optimize
&& !optimize_size
)
6799 tree sqrtfn
= mathfn_built_in (type
, BUILT_IN_SQRT
);
6801 if (sqrtfn
!= NULL_TREE
)
6803 tree rpart
, ipart
, result
, arglist
;
6805 arg
= builtin_save_expr (arg
);
6807 rpart
= fold_build1 (REALPART_EXPR
, type
, arg
);
6808 ipart
= fold_build1 (IMAGPART_EXPR
, type
, arg
);
6810 rpart
= builtin_save_expr (rpart
);
6811 ipart
= builtin_save_expr (ipart
);
6813 result
= fold_build2 (PLUS_EXPR
, type
,
6814 fold_build2 (MULT_EXPR
, type
,
6816 fold_build2 (MULT_EXPR
, type
,
6819 arglist
= build_tree_list (NULL_TREE
, result
);
6820 return build_function_call_expr (sqrtfn
, arglist
);
6827 /* Fold a builtin function call to sqrt, sqrtf, or sqrtl. Return
6828 NULL_TREE if no simplification can be made. */
6831 fold_builtin_sqrt (tree arglist
, tree type
)
6834 enum built_in_function fcode
;
6835 tree arg
= TREE_VALUE (arglist
);
6837 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
6840 /* Optimize sqrt of constant value. */
6841 if (TREE_CODE (arg
) == REAL_CST
6842 && ! TREE_CONSTANT_OVERFLOW (arg
))
6844 REAL_VALUE_TYPE r
, x
;
6846 x
= TREE_REAL_CST (arg
);
6847 if (real_sqrt (&r
, TYPE_MODE (type
), &x
)
6848 || (!flag_trapping_math
&& !flag_errno_math
))
6849 return build_real (type
, r
);
6852 /* Optimize sqrt(expN(x)) = expN(x*0.5). */
6853 fcode
= builtin_mathfn_code (arg
);
6854 if (flag_unsafe_math_optimizations
&& BUILTIN_EXPONENT_P (fcode
))
6856 tree expfn
= TREE_OPERAND (TREE_OPERAND (arg
, 0), 0);
6857 arg
= fold_build2 (MULT_EXPR
, type
,
6858 TREE_VALUE (TREE_OPERAND (arg
, 1)),
6859 build_real (type
, dconsthalf
));
6860 arglist
= build_tree_list (NULL_TREE
, arg
);
6861 return build_function_call_expr (expfn
, arglist
);
6864 /* Optimize sqrt(Nroot(x)) -> pow(x,1/(2*N)). */
6865 if (flag_unsafe_math_optimizations
&& BUILTIN_ROOT_P (fcode
))
6867 tree powfn
= mathfn_built_in (type
, BUILT_IN_POW
);
6871 tree arg0
= TREE_VALUE (TREE_OPERAND (arg
, 1));
6873 /* The inner root was either sqrt or cbrt. */
6874 REAL_VALUE_TYPE dconstroot
=
6875 BUILTIN_SQRT_P (fcode
) ? dconsthalf
: dconstthird
;
6877 /* Adjust for the outer root. */
6878 SET_REAL_EXP (&dconstroot
, REAL_EXP (&dconstroot
) - 1);
6879 dconstroot
= real_value_truncate (TYPE_MODE (type
), dconstroot
);
6880 tree_root
= build_real (type
, dconstroot
);
6881 arglist
= tree_cons (NULL_TREE
, arg0
,
6882 build_tree_list (NULL_TREE
, tree_root
));
6883 return build_function_call_expr (powfn
, arglist
);
6887 /* Optimize sqrt(pow(x,y)) = pow(|x|,y*0.5). */
6888 if (flag_unsafe_math_optimizations
6889 && (fcode
== BUILT_IN_POW
6890 || fcode
== BUILT_IN_POWF
6891 || fcode
== BUILT_IN_POWL
))
6893 tree powfn
= TREE_OPERAND (TREE_OPERAND (arg
, 0), 0);
6894 tree arg0
= TREE_VALUE (TREE_OPERAND (arg
, 1));
6895 tree arg1
= TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg
, 1)));
6897 if (!tree_expr_nonnegative_p (arg0
))
6898 arg0
= build1 (ABS_EXPR
, type
, arg0
);
6899 narg1
= fold_build2 (MULT_EXPR
, type
, arg1
,
6900 build_real (type
, dconsthalf
));
6901 arglist
= tree_cons (NULL_TREE
, arg0
,
6902 build_tree_list (NULL_TREE
, narg1
));
6903 return build_function_call_expr (powfn
, arglist
);
6909 /* Fold a builtin function call to cbrt, cbrtf, or cbrtl. Return
6910 NULL_TREE if no simplification can be made. */
6912 fold_builtin_cbrt (tree arglist
, tree type
)
6914 tree arg
= TREE_VALUE (arglist
);
6915 const enum built_in_function fcode
= builtin_mathfn_code (arg
);
6917 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
6920 /* Optimize cbrt of constant value. */
6921 if (real_zerop (arg
) || real_onep (arg
) || real_minus_onep (arg
))
6924 if (flag_unsafe_math_optimizations
)
6926 /* Optimize cbrt(expN(x)) -> expN(x/3). */
6927 if (BUILTIN_EXPONENT_P (fcode
))
6929 tree expfn
= TREE_OPERAND (TREE_OPERAND (arg
, 0), 0);
6930 const REAL_VALUE_TYPE third_trunc
=
6931 real_value_truncate (TYPE_MODE (type
), dconstthird
);
6932 arg
= fold_build2 (MULT_EXPR
, type
,
6933 TREE_VALUE (TREE_OPERAND (arg
, 1)),
6934 build_real (type
, third_trunc
));
6935 arglist
= build_tree_list (NULL_TREE
, arg
);
6936 return build_function_call_expr (expfn
, arglist
);
6939 /* Optimize cbrt(sqrt(x)) -> pow(x,1/6). */
6940 if (BUILTIN_SQRT_P (fcode
))
6942 tree powfn
= mathfn_built_in (type
, BUILT_IN_POW
);
6946 tree arg0
= TREE_VALUE (TREE_OPERAND (arg
, 1));
6948 REAL_VALUE_TYPE dconstroot
= dconstthird
;
6950 SET_REAL_EXP (&dconstroot
, REAL_EXP (&dconstroot
) - 1);
6951 dconstroot
= real_value_truncate (TYPE_MODE (type
), dconstroot
);
6952 tree_root
= build_real (type
, dconstroot
);
6953 arglist
= tree_cons (NULL_TREE
, arg0
,
6954 build_tree_list (NULL_TREE
, tree_root
));
6955 return build_function_call_expr (powfn
, arglist
);
6959 /* Optimize cbrt(cbrt(x)) -> pow(x,1/9) iff x is nonnegative. */
6960 if (BUILTIN_CBRT_P (fcode
))
6962 tree arg0
= TREE_VALUE (TREE_OPERAND (arg
, 1));
6963 if (tree_expr_nonnegative_p (arg0
))
6965 tree powfn
= mathfn_built_in (type
, BUILT_IN_POW
);
6970 REAL_VALUE_TYPE dconstroot
;
6972 real_arithmetic (&dconstroot
, MULT_EXPR
, &dconstthird
, &dconstthird
);
6973 dconstroot
= real_value_truncate (TYPE_MODE (type
), dconstroot
);
6974 tree_root
= build_real (type
, dconstroot
);
6975 arglist
= tree_cons (NULL_TREE
, arg0
,
6976 build_tree_list (NULL_TREE
, tree_root
));
6977 return build_function_call_expr (powfn
, arglist
);
6982 /* Optimize cbrt(pow(x,y)) -> pow(x,y/3) iff x is nonnegative. */
6983 if (fcode
== BUILT_IN_POW
|| fcode
== BUILT_IN_POWF
6984 || fcode
== BUILT_IN_POWL
)
6986 tree arg00
= TREE_VALUE (TREE_OPERAND (arg
, 1));
6987 tree arg01
= TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg
, 1)));
6988 if (tree_expr_nonnegative_p (arg00
))
6990 tree powfn
= TREE_OPERAND (TREE_OPERAND (arg
, 0), 0);
6991 const REAL_VALUE_TYPE dconstroot
6992 = real_value_truncate (TYPE_MODE (type
), dconstthird
);
6993 tree narg01
= fold_build2 (MULT_EXPR
, type
, arg01
,
6994 build_real (type
, dconstroot
));
6995 arglist
= tree_cons (NULL_TREE
, arg00
,
6996 build_tree_list (NULL_TREE
, narg01
));
6997 return build_function_call_expr (powfn
, arglist
);
7004 /* Fold function call to builtin sin, sinf, or sinl. Return
7005 NULL_TREE if no simplification can be made. */
7007 fold_builtin_sin (tree arglist
)
7009 tree arg
= TREE_VALUE (arglist
);
7011 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
7014 /* Optimize sin (0.0) = 0.0. */
7015 if (real_zerop (arg
))
7021 /* Fold function call to builtin cos, cosf, or cosl. Return
7022 NULL_TREE if no simplification can be made. */
7024 fold_builtin_cos (tree arglist
, tree type
, tree fndecl
)
7026 tree arg
= TREE_VALUE (arglist
);
7028 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
7031 /* Optimize cos (0.0) = 1.0. */
7032 if (real_zerop (arg
))
7033 return build_real (type
, dconst1
);
7035 /* Optimize cos(-x) into cos (x). */
7036 if (TREE_CODE (arg
) == NEGATE_EXPR
)
7038 tree args
= build_tree_list (NULL_TREE
,
7039 TREE_OPERAND (arg
, 0));
7040 return build_function_call_expr (fndecl
, args
);
7046 /* Fold function call to builtin tan, tanf, or tanl. Return
7047 NULL_TREE if no simplification can be made. */
7049 fold_builtin_tan (tree arglist
)
7051 enum built_in_function fcode
;
7052 tree arg
= TREE_VALUE (arglist
);
7054 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
7057 /* Optimize tan(0.0) = 0.0. */
7058 if (real_zerop (arg
))
7061 /* Optimize tan(atan(x)) = x. */
7062 fcode
= builtin_mathfn_code (arg
);
7063 if (flag_unsafe_math_optimizations
7064 && (fcode
== BUILT_IN_ATAN
7065 || fcode
== BUILT_IN_ATANF
7066 || fcode
== BUILT_IN_ATANL
))
7067 return TREE_VALUE (TREE_OPERAND (arg
, 1));
7072 /* Fold function call to builtin atan, atanf, or atanl. Return
7073 NULL_TREE if no simplification can be made. */
7076 fold_builtin_atan (tree arglist
, tree type
)
7079 tree arg
= TREE_VALUE (arglist
);
7081 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
7084 /* Optimize atan(0.0) = 0.0. */
7085 if (real_zerop (arg
))
7088 /* Optimize atan(1.0) = pi/4. */
7089 if (real_onep (arg
))
7091 REAL_VALUE_TYPE cst
;
7093 real_convert (&cst
, TYPE_MODE (type
), &dconstpi
);
7094 SET_REAL_EXP (&cst
, REAL_EXP (&cst
) - 2);
7095 return build_real (type
, cst
);
7101 /* Fold function call to builtin trunc, truncf or truncl. Return
7102 NULL_TREE if no simplification can be made. */
7105 fold_builtin_trunc (tree fndecl
, tree arglist
)
7109 if (! validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
7112 /* Optimize trunc of constant value. */
7113 arg
= TREE_VALUE (arglist
);
7114 if (TREE_CODE (arg
) == REAL_CST
&& ! TREE_CONSTANT_OVERFLOW (arg
))
7116 REAL_VALUE_TYPE r
, x
;
7117 tree type
= TREE_TYPE (TREE_TYPE (fndecl
));
7119 x
= TREE_REAL_CST (arg
);
7120 real_trunc (&r
, TYPE_MODE (type
), &x
);
7121 return build_real (type
, r
);
7124 return fold_trunc_transparent_mathfn (fndecl
, arglist
);
7127 /* Fold function call to builtin floor, floorf or floorl. Return
7128 NULL_TREE if no simplification can be made. */
7131 fold_builtin_floor (tree fndecl
, tree arglist
)
7135 if (! validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
7138 /* Optimize floor of constant value. */
7139 arg
= TREE_VALUE (arglist
);
7140 if (TREE_CODE (arg
) == REAL_CST
&& ! TREE_CONSTANT_OVERFLOW (arg
))
7144 x
= TREE_REAL_CST (arg
);
7145 if (! REAL_VALUE_ISNAN (x
) || ! flag_errno_math
)
7147 tree type
= TREE_TYPE (TREE_TYPE (fndecl
));
7150 real_floor (&r
, TYPE_MODE (type
), &x
);
7151 return build_real (type
, r
);
7155 return fold_trunc_transparent_mathfn (fndecl
, arglist
);
7158 /* Fold function call to builtin ceil, ceilf or ceill. Return
7159 NULL_TREE if no simplification can be made. */
7162 fold_builtin_ceil (tree fndecl
, tree arglist
)
7166 if (! validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
7169 /* Optimize ceil of constant value. */
7170 arg
= TREE_VALUE (arglist
);
7171 if (TREE_CODE (arg
) == REAL_CST
&& ! TREE_CONSTANT_OVERFLOW (arg
))
7175 x
= TREE_REAL_CST (arg
);
7176 if (! REAL_VALUE_ISNAN (x
) || ! flag_errno_math
)
7178 tree type
= TREE_TYPE (TREE_TYPE (fndecl
));
7181 real_ceil (&r
, TYPE_MODE (type
), &x
);
7182 return build_real (type
, r
);
7186 return fold_trunc_transparent_mathfn (fndecl
, arglist
);
7189 /* Fold function call to builtin round, roundf or roundl. Return
7190 NULL_TREE if no simplification can be made. */
7193 fold_builtin_round (tree fndecl
, tree arglist
)
7197 if (! validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
7200 /* Optimize round of constant value. */
7201 arg
= TREE_VALUE (arglist
);
7202 if (TREE_CODE (arg
) == REAL_CST
&& ! TREE_CONSTANT_OVERFLOW (arg
))
7206 x
= TREE_REAL_CST (arg
);
7207 if (! REAL_VALUE_ISNAN (x
) || ! flag_errno_math
)
7209 tree type
= TREE_TYPE (TREE_TYPE (fndecl
));
7212 real_round (&r
, TYPE_MODE (type
), &x
);
7213 return build_real (type
, r
);
7217 return fold_trunc_transparent_mathfn (fndecl
, arglist
);
7220 /* Fold function call to builtin lround, lroundf or lroundl (or the
7221 corresponding long long versions) and other rounding functions.
7222 Return NULL_TREE if no simplification can be made. */
7225 fold_builtin_int_roundingfn (tree fndecl
, tree arglist
)
7229 if (! validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
7232 /* Optimize lround of constant value. */
7233 arg
= TREE_VALUE (arglist
);
7234 if (TREE_CODE (arg
) == REAL_CST
&& ! TREE_CONSTANT_OVERFLOW (arg
))
7236 const REAL_VALUE_TYPE x
= TREE_REAL_CST (arg
);
7238 if (! REAL_VALUE_ISNAN (x
) && ! REAL_VALUE_ISINF (x
))
7240 tree itype
= TREE_TYPE (TREE_TYPE (fndecl
));
7241 tree ftype
= TREE_TYPE (arg
), result
;
7242 HOST_WIDE_INT hi
, lo
;
7245 switch (DECL_FUNCTION_CODE (fndecl
))
7247 CASE_FLT_FN (BUILT_IN_LFLOOR
):
7248 CASE_FLT_FN (BUILT_IN_LLFLOOR
):
7249 real_floor (&r
, TYPE_MODE (ftype
), &x
);
7252 CASE_FLT_FN (BUILT_IN_LCEIL
):
7253 CASE_FLT_FN (BUILT_IN_LLCEIL
):
7254 real_ceil (&r
, TYPE_MODE (ftype
), &x
);
7257 CASE_FLT_FN (BUILT_IN_LROUND
):
7258 CASE_FLT_FN (BUILT_IN_LLROUND
):
7259 real_round (&r
, TYPE_MODE (ftype
), &x
);
7266 REAL_VALUE_TO_INT (&lo
, &hi
, r
);
7267 result
= build_int_cst_wide (NULL_TREE
, lo
, hi
);
7268 if (int_fits_type_p (result
, itype
))
7269 return fold_convert (itype
, result
);
7273 return fold_fixed_mathfn (fndecl
, arglist
);
7276 /* Fold function call to builtin ffs, clz, ctz, popcount and parity
7277 and their long and long long variants (i.e. ffsl and ffsll).
7278 Return NULL_TREE if no simplification can be made. */
7281 fold_builtin_bitop (tree fndecl
, tree arglist
)
7285 if (! validate_arglist (arglist
, INTEGER_TYPE
, VOID_TYPE
))
7288 /* Optimize for constant argument. */
7289 arg
= TREE_VALUE (arglist
);
7290 if (TREE_CODE (arg
) == INTEGER_CST
&& ! TREE_CONSTANT_OVERFLOW (arg
))
7292 HOST_WIDE_INT hi
, width
, result
;
7293 unsigned HOST_WIDE_INT lo
;
7296 type
= TREE_TYPE (arg
);
7297 width
= TYPE_PRECISION (type
);
7298 lo
= TREE_INT_CST_LOW (arg
);
7300 /* Clear all the bits that are beyond the type's precision. */
7301 if (width
> HOST_BITS_PER_WIDE_INT
)
7303 hi
= TREE_INT_CST_HIGH (arg
);
7304 if (width
< 2 * HOST_BITS_PER_WIDE_INT
)
7305 hi
&= ~((HOST_WIDE_INT
) (-1) >> (width
- HOST_BITS_PER_WIDE_INT
));
7310 if (width
< HOST_BITS_PER_WIDE_INT
)
7311 lo
&= ~((unsigned HOST_WIDE_INT
) (-1) << width
);
7314 switch (DECL_FUNCTION_CODE (fndecl
))
7316 CASE_INT_FN (BUILT_IN_FFS
):
7318 result
= exact_log2 (lo
& -lo
) + 1;
7320 result
= HOST_BITS_PER_WIDE_INT
+ exact_log2 (hi
& -hi
) + 1;
7325 CASE_INT_FN (BUILT_IN_CLZ
):
7327 result
= width
- floor_log2 (hi
) - 1 - HOST_BITS_PER_WIDE_INT
;
7329 result
= width
- floor_log2 (lo
) - 1;
7330 else if (! CLZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type
), result
))
7334 CASE_INT_FN (BUILT_IN_CTZ
):
7336 result
= exact_log2 (lo
& -lo
);
7338 result
= HOST_BITS_PER_WIDE_INT
+ exact_log2 (hi
& -hi
);
7339 else if (! CTZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type
), result
))
7343 CASE_INT_FN (BUILT_IN_POPCOUNT
):
7346 result
++, lo
&= lo
- 1;
7348 result
++, hi
&= hi
- 1;
7351 CASE_INT_FN (BUILT_IN_PARITY
):
7354 result
++, lo
&= lo
- 1;
7356 result
++, hi
&= hi
- 1;
7364 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl
)), result
);
7370 /* Return true if EXPR is the real constant contained in VALUE. */
7373 real_dconstp (tree expr
, const REAL_VALUE_TYPE
*value
)
7377 return ((TREE_CODE (expr
) == REAL_CST
7378 && ! TREE_CONSTANT_OVERFLOW (expr
)
7379 && REAL_VALUES_EQUAL (TREE_REAL_CST (expr
), *value
))
7380 || (TREE_CODE (expr
) == COMPLEX_CST
7381 && real_dconstp (TREE_REALPART (expr
), value
)
7382 && real_zerop (TREE_IMAGPART (expr
))));
7385 /* A subroutine of fold_builtin to fold the various logarithmic
7386 functions. EXP is the CALL_EXPR of a call to a builtin logN
7387 function. VALUE is the base of the logN function. */
7390 fold_builtin_logarithm (tree fndecl
, tree arglist
,
7391 const REAL_VALUE_TYPE
*value
)
7393 if (validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
7395 tree type
= TREE_TYPE (TREE_TYPE (fndecl
));
7396 tree arg
= TREE_VALUE (arglist
);
7397 const enum built_in_function fcode
= builtin_mathfn_code (arg
);
7399 /* Optimize logN(1.0) = 0.0. */
7400 if (real_onep (arg
))
7401 return build_real (type
, dconst0
);
7403 /* Optimize logN(N) = 1.0. If N can't be truncated to MODE
7404 exactly, then only do this if flag_unsafe_math_optimizations. */
7405 if (exact_real_truncate (TYPE_MODE (type
), value
)
7406 || flag_unsafe_math_optimizations
)
7408 const REAL_VALUE_TYPE value_truncate
=
7409 real_value_truncate (TYPE_MODE (type
), *value
);
7410 if (real_dconstp (arg
, &value_truncate
))
7411 return build_real (type
, dconst1
);
7414 /* Special case, optimize logN(expN(x)) = x. */
7415 if (flag_unsafe_math_optimizations
7416 && ((value
== &dconste
7417 && (fcode
== BUILT_IN_EXP
7418 || fcode
== BUILT_IN_EXPF
7419 || fcode
== BUILT_IN_EXPL
))
7420 || (value
== &dconst2
7421 && (fcode
== BUILT_IN_EXP2
7422 || fcode
== BUILT_IN_EXP2F
7423 || fcode
== BUILT_IN_EXP2L
))
7424 || (value
== &dconst10
&& (BUILTIN_EXP10_P (fcode
)))))
7425 return fold_convert (type
, TREE_VALUE (TREE_OPERAND (arg
, 1)));
7427 /* Optimize logN(func()) for various exponential functions. We
7428 want to determine the value "x" and the power "exponent" in
7429 order to transform logN(x**exponent) into exponent*logN(x). */
7430 if (flag_unsafe_math_optimizations
)
7432 tree exponent
= 0, x
= 0;
7436 CASE_FLT_FN (BUILT_IN_EXP
):
7437 /* Prepare to do logN(exp(exponent) -> exponent*logN(e). */
7438 x
= build_real (type
,
7439 real_value_truncate (TYPE_MODE (type
), dconste
));
7440 exponent
= TREE_VALUE (TREE_OPERAND (arg
, 1));
7442 CASE_FLT_FN (BUILT_IN_EXP2
):
7443 /* Prepare to do logN(exp2(exponent) -> exponent*logN(2). */
7444 x
= build_real (type
, dconst2
);
7445 exponent
= TREE_VALUE (TREE_OPERAND (arg
, 1));
7447 CASE_FLT_FN (BUILT_IN_EXP10
):
7448 CASE_FLT_FN (BUILT_IN_POW10
):
7449 /* Prepare to do logN(exp10(exponent) -> exponent*logN(10). */
7450 x
= build_real (type
, dconst10
);
7451 exponent
= TREE_VALUE (TREE_OPERAND (arg
, 1));
7453 CASE_FLT_FN (BUILT_IN_SQRT
):
7454 /* Prepare to do logN(sqrt(x) -> 0.5*logN(x). */
7455 x
= TREE_VALUE (TREE_OPERAND (arg
, 1));
7456 exponent
= build_real (type
, dconsthalf
);
7458 CASE_FLT_FN (BUILT_IN_CBRT
):
7459 /* Prepare to do logN(cbrt(x) -> (1/3)*logN(x). */
7460 x
= TREE_VALUE (TREE_OPERAND (arg
, 1));
7461 exponent
= build_real (type
, real_value_truncate (TYPE_MODE (type
),
7464 CASE_FLT_FN (BUILT_IN_POW
):
7465 /* Prepare to do logN(pow(x,exponent) -> exponent*logN(x). */
7466 x
= TREE_VALUE (TREE_OPERAND (arg
, 1));
7467 exponent
= TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg
, 1)));
7473 /* Now perform the optimization. */
7477 arglist
= build_tree_list (NULL_TREE
, x
);
7478 logfn
= build_function_call_expr (fndecl
, arglist
);
7479 return fold_build2 (MULT_EXPR
, type
, exponent
, logfn
);
7487 /* Fold a builtin function call to pow, powf, or powl. Return
7488 NULL_TREE if no simplification can be made. */
7490 fold_builtin_pow (tree fndecl
, tree arglist
, tree type
)
7492 tree arg0
= TREE_VALUE (arglist
);
7493 tree arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
7495 if (!validate_arglist (arglist
, REAL_TYPE
, REAL_TYPE
, VOID_TYPE
))
7498 /* Optimize pow(1.0,y) = 1.0. */
7499 if (real_onep (arg0
))
7500 return omit_one_operand (type
, build_real (type
, dconst1
), arg1
);
7502 if (TREE_CODE (arg1
) == REAL_CST
7503 && ! TREE_CONSTANT_OVERFLOW (arg1
))
7505 REAL_VALUE_TYPE cint
;
7509 c
= TREE_REAL_CST (arg1
);
7511 /* Optimize pow(x,0.0) = 1.0. */
7512 if (REAL_VALUES_EQUAL (c
, dconst0
))
7513 return omit_one_operand (type
, build_real (type
, dconst1
),
7516 /* Optimize pow(x,1.0) = x. */
7517 if (REAL_VALUES_EQUAL (c
, dconst1
))
7520 /* Optimize pow(x,-1.0) = 1.0/x. */
7521 if (REAL_VALUES_EQUAL (c
, dconstm1
))
7522 return fold_build2 (RDIV_EXPR
, type
,
7523 build_real (type
, dconst1
), arg0
);
7525 /* Optimize pow(x,0.5) = sqrt(x). */
7526 if (flag_unsafe_math_optimizations
7527 && REAL_VALUES_EQUAL (c
, dconsthalf
))
7529 tree sqrtfn
= mathfn_built_in (type
, BUILT_IN_SQRT
);
7531 if (sqrtfn
!= NULL_TREE
)
7533 tree arglist
= build_tree_list (NULL_TREE
, arg0
);
7534 return build_function_call_expr (sqrtfn
, arglist
);
7538 /* Check for an integer exponent. */
7539 n
= real_to_integer (&c
);
7540 real_from_integer (&cint
, VOIDmode
, n
, n
< 0 ? -1 : 0, 0);
7541 if (real_identical (&c
, &cint
))
7543 /* Attempt to evaluate pow at compile-time. */
7544 if (TREE_CODE (arg0
) == REAL_CST
7545 && ! TREE_CONSTANT_OVERFLOW (arg0
))
7550 x
= TREE_REAL_CST (arg0
);
7551 inexact
= real_powi (&x
, TYPE_MODE (type
), &x
, n
);
7552 if (flag_unsafe_math_optimizations
|| !inexact
)
7553 return build_real (type
, x
);
7556 /* Strip sign ops from even integer powers. */
7557 if ((n
& 1) == 0 && flag_unsafe_math_optimizations
)
7559 tree narg0
= fold_strip_sign_ops (arg0
);
7562 arglist
= build_tree_list (NULL_TREE
, arg1
);
7563 arglist
= tree_cons (NULL_TREE
, narg0
, arglist
);
7564 return build_function_call_expr (fndecl
, arglist
);
7570 if (flag_unsafe_math_optimizations
)
7572 const enum built_in_function fcode
= builtin_mathfn_code (arg0
);
7574 /* Optimize pow(expN(x),y) = expN(x*y). */
7575 if (BUILTIN_EXPONENT_P (fcode
))
7577 tree expfn
= TREE_OPERAND (TREE_OPERAND (arg0
, 0), 0);
7578 tree arg
= TREE_VALUE (TREE_OPERAND (arg0
, 1));
7579 arg
= fold_build2 (MULT_EXPR
, type
, arg
, arg1
);
7580 arglist
= build_tree_list (NULL_TREE
, arg
);
7581 return build_function_call_expr (expfn
, arglist
);
7584 /* Optimize pow(sqrt(x),y) = pow(x,y*0.5). */
7585 if (BUILTIN_SQRT_P (fcode
))
7587 tree narg0
= TREE_VALUE (TREE_OPERAND (arg0
, 1));
7588 tree narg1
= fold_build2 (MULT_EXPR
, type
, arg1
,
7589 build_real (type
, dconsthalf
));
7591 arglist
= tree_cons (NULL_TREE
, narg0
,
7592 build_tree_list (NULL_TREE
, narg1
));
7593 return build_function_call_expr (fndecl
, arglist
);
7596 /* Optimize pow(cbrt(x),y) = pow(x,y/3) iff x is nonnegative. */
7597 if (BUILTIN_CBRT_P (fcode
))
7599 tree arg
= TREE_VALUE (TREE_OPERAND (arg0
, 1));
7600 if (tree_expr_nonnegative_p (arg
))
7602 const REAL_VALUE_TYPE dconstroot
7603 = real_value_truncate (TYPE_MODE (type
), dconstthird
);
7604 tree narg1
= fold_build2 (MULT_EXPR
, type
, arg1
,
7605 build_real (type
, dconstroot
));
7606 arglist
= tree_cons (NULL_TREE
, arg
,
7607 build_tree_list (NULL_TREE
, narg1
));
7608 return build_function_call_expr (fndecl
, arglist
);
7612 /* Optimize pow(pow(x,y),z) = pow(x,y*z). */
7613 if (fcode
== BUILT_IN_POW
|| fcode
== BUILT_IN_POWF
7614 || fcode
== BUILT_IN_POWL
)
7616 tree arg00
= TREE_VALUE (TREE_OPERAND (arg0
, 1));
7617 tree arg01
= TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg0
, 1)));
7618 tree narg1
= fold_build2 (MULT_EXPR
, type
, arg01
, arg1
);
7619 arglist
= tree_cons (NULL_TREE
, arg00
,
7620 build_tree_list (NULL_TREE
, narg1
));
7621 return build_function_call_expr (fndecl
, arglist
);
7628 /* Fold a builtin function call to powi, powif, or powil. Return
7629 NULL_TREE if no simplification can be made. */
7631 fold_builtin_powi (tree fndecl ATTRIBUTE_UNUSED
, tree arglist
, tree type
)
7633 tree arg0
= TREE_VALUE (arglist
);
7634 tree arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
7636 if (!validate_arglist (arglist
, REAL_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
7639 /* Optimize pow(1.0,y) = 1.0. */
7640 if (real_onep (arg0
))
7641 return omit_one_operand (type
, build_real (type
, dconst1
), arg1
);
7643 if (host_integerp (arg1
, 0))
7645 HOST_WIDE_INT c
= TREE_INT_CST_LOW (arg1
);
7647 /* Evaluate powi at compile-time. */
7648 if (TREE_CODE (arg0
) == REAL_CST
7649 && ! TREE_CONSTANT_OVERFLOW (arg0
))
7652 x
= TREE_REAL_CST (arg0
);
7653 real_powi (&x
, TYPE_MODE (type
), &x
, c
);
7654 return build_real (type
, x
);
7657 /* Optimize pow(x,0) = 1.0. */
7659 return omit_one_operand (type
, build_real (type
, dconst1
),
7662 /* Optimize pow(x,1) = x. */
7666 /* Optimize pow(x,-1) = 1.0/x. */
7668 return fold_build2 (RDIV_EXPR
, type
,
7669 build_real (type
, dconst1
), arg0
);
7675 /* A subroutine of fold_builtin to fold the various exponent
7676 functions. EXP is the CALL_EXPR of a call to a builtin function.
7677 VALUE is the value which will be raised to a power. */
7680 fold_builtin_exponent (tree fndecl
, tree arglist
,
7681 const REAL_VALUE_TYPE
*value
)
7683 if (validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
7685 tree type
= TREE_TYPE (TREE_TYPE (fndecl
));
7686 tree arg
= TREE_VALUE (arglist
);
7688 /* Optimize exp*(0.0) = 1.0. */
7689 if (real_zerop (arg
))
7690 return build_real (type
, dconst1
);
7692 /* Optimize expN(1.0) = N. */
7693 if (real_onep (arg
))
7695 REAL_VALUE_TYPE cst
;
7697 real_convert (&cst
, TYPE_MODE (type
), value
);
7698 return build_real (type
, cst
);
7701 /* Attempt to evaluate expN(integer) at compile-time. */
7702 if (flag_unsafe_math_optimizations
7703 && TREE_CODE (arg
) == REAL_CST
7704 && ! TREE_CONSTANT_OVERFLOW (arg
))
7706 REAL_VALUE_TYPE cint
;
7710 c
= TREE_REAL_CST (arg
);
7711 n
= real_to_integer (&c
);
7712 real_from_integer (&cint
, VOIDmode
, n
,
7714 if (real_identical (&c
, &cint
))
7718 real_powi (&x
, TYPE_MODE (type
), value
, n
);
7719 return build_real (type
, x
);
7723 /* Optimize expN(logN(x)) = x. */
7724 if (flag_unsafe_math_optimizations
)
7726 const enum built_in_function fcode
= builtin_mathfn_code (arg
);
7728 if ((value
== &dconste
7729 && (fcode
== BUILT_IN_LOG
7730 || fcode
== BUILT_IN_LOGF
7731 || fcode
== BUILT_IN_LOGL
))
7732 || (value
== &dconst2
7733 && (fcode
== BUILT_IN_LOG2
7734 || fcode
== BUILT_IN_LOG2F
7735 || fcode
== BUILT_IN_LOG2L
))
7736 || (value
== &dconst10
7737 && (fcode
== BUILT_IN_LOG10
7738 || fcode
== BUILT_IN_LOG10F
7739 || fcode
== BUILT_IN_LOG10L
)))
7740 return fold_convert (type
, TREE_VALUE (TREE_OPERAND (arg
, 1)));
7747 /* Fold function call to builtin memcpy. Return
7748 NULL_TREE if no simplification can be made. */
7751 fold_builtin_memcpy (tree fndecl
, tree arglist
)
7753 tree dest
, src
, len
;
7755 if (!validate_arglist (arglist
,
7756 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
7759 dest
= TREE_VALUE (arglist
);
7760 src
= TREE_VALUE (TREE_CHAIN (arglist
));
7761 len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
7763 /* If the LEN parameter is zero, return DEST. */
7764 if (integer_zerop (len
))
7765 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl
)), dest
, src
);
7767 /* If SRC and DEST are the same (and not volatile), return DEST. */
7768 if (operand_equal_p (src
, dest
, 0))
7769 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl
)), dest
, len
);
7774 /* Fold function call to builtin mempcpy. Return
7775 NULL_TREE if no simplification can be made. */
7778 fold_builtin_mempcpy (tree arglist
, tree type
, int endp
)
7780 if (validate_arglist (arglist
,
7781 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
7783 tree dest
= TREE_VALUE (arglist
);
7784 tree src
= TREE_VALUE (TREE_CHAIN (arglist
));
7785 tree len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
7787 /* If the LEN parameter is zero, return DEST. */
7788 if (integer_zerop (len
))
7789 return omit_one_operand (type
, dest
, src
);
7791 /* If SRC and DEST are the same (and not volatile), return DEST+LEN. */
7792 if (operand_equal_p (src
, dest
, 0))
7795 return omit_one_operand (type
, dest
, len
);
7798 len
= fold_build2 (MINUS_EXPR
, TREE_TYPE (len
), len
,
7801 len
= fold_convert (TREE_TYPE (dest
), len
);
7802 len
= fold_build2 (PLUS_EXPR
, TREE_TYPE (dest
), dest
, len
);
7803 return fold_convert (type
, len
);
7809 /* Fold function call to builtin memmove. Return
7810 NULL_TREE if no simplification can be made. */
7813 fold_builtin_memmove (tree arglist
, tree type
)
7815 tree dest
, src
, len
;
7817 if (!validate_arglist (arglist
,
7818 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
7821 dest
= TREE_VALUE (arglist
);
7822 src
= TREE_VALUE (TREE_CHAIN (arglist
));
7823 len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
7825 /* If the LEN parameter is zero, return DEST. */
7826 if (integer_zerop (len
))
7827 return omit_one_operand (type
, dest
, src
);
7829 /* If SRC and DEST are the same (and not volatile), return DEST. */
7830 if (operand_equal_p (src
, dest
, 0))
7831 return omit_one_operand (type
, dest
, len
);
7836 /* Fold function call to builtin strcpy. If LEN is not NULL, it represents
7837 the length of the string to be copied. Return NULL_TREE if no
7838 simplification can be made. */
7841 fold_builtin_strcpy (tree fndecl
, tree arglist
, tree len
)
7845 if (!validate_arglist (arglist
,
7846 POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
7849 dest
= TREE_VALUE (arglist
);
7850 src
= TREE_VALUE (TREE_CHAIN (arglist
));
7852 /* If SRC and DEST are the same (and not volatile), return DEST. */
7853 if (operand_equal_p (src
, dest
, 0))
7854 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl
)), dest
);
7859 fn
= implicit_built_in_decls
[BUILT_IN_MEMCPY
];
7865 len
= c_strlen (src
, 1);
7866 if (! len
|| TREE_SIDE_EFFECTS (len
))
7870 len
= size_binop (PLUS_EXPR
, len
, ssize_int (1));
7871 arglist
= build_tree_list (NULL_TREE
, len
);
7872 arglist
= tree_cons (NULL_TREE
, src
, arglist
);
7873 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
7874 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl
)),
7875 build_function_call_expr (fn
, arglist
));
7878 /* Fold function call to builtin strncpy. If SLEN is not NULL, it represents
7879 the length of the source string. Return NULL_TREE if no simplification
7883 fold_builtin_strncpy (tree fndecl
, tree arglist
, tree slen
)
7885 tree dest
, src
, len
, fn
;
7887 if (!validate_arglist (arglist
,
7888 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
7891 dest
= TREE_VALUE (arglist
);
7892 src
= TREE_VALUE (TREE_CHAIN (arglist
));
7893 len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
7895 /* If the LEN parameter is zero, return DEST. */
7896 if (integer_zerop (len
))
7897 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl
)), dest
, src
);
7899 /* We can't compare slen with len as constants below if len is not a
7901 if (len
== 0 || TREE_CODE (len
) != INTEGER_CST
)
7905 slen
= c_strlen (src
, 1);
7907 /* Now, we must be passed a constant src ptr parameter. */
7908 if (slen
== 0 || TREE_CODE (slen
) != INTEGER_CST
)
7911 slen
= size_binop (PLUS_EXPR
, slen
, ssize_int (1));
7913 /* We do not support simplification of this case, though we do
7914 support it when expanding trees into RTL. */
7915 /* FIXME: generate a call to __builtin_memset. */
7916 if (tree_int_cst_lt (slen
, len
))
7919 /* OK transform into builtin memcpy. */
7920 fn
= implicit_built_in_decls
[BUILT_IN_MEMCPY
];
7923 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl
)),
7924 build_function_call_expr (fn
, arglist
));
7927 /* Fold function call to builtin memcmp. Return
7928 NULL_TREE if no simplification can be made. */
7931 fold_builtin_memcmp (tree arglist
)
7933 tree arg1
, arg2
, len
;
7934 const char *p1
, *p2
;
7936 if (!validate_arglist (arglist
,
7937 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
7940 arg1
= TREE_VALUE (arglist
);
7941 arg2
= TREE_VALUE (TREE_CHAIN (arglist
));
7942 len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
7944 /* If the LEN parameter is zero, return zero. */
7945 if (integer_zerop (len
))
7946 return omit_two_operands (integer_type_node
, integer_zero_node
,
7949 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
7950 if (operand_equal_p (arg1
, arg2
, 0))
7951 return omit_one_operand (integer_type_node
, integer_zero_node
, len
);
7953 p1
= c_getstr (arg1
);
7954 p2
= c_getstr (arg2
);
7956 /* If all arguments are constant, and the value of len is not greater
7957 than the lengths of arg1 and arg2, evaluate at compile-time. */
7958 if (host_integerp (len
, 1) && p1
&& p2
7959 && compare_tree_int (len
, strlen (p1
) + 1) <= 0
7960 && compare_tree_int (len
, strlen (p2
) + 1) <= 0)
7962 const int r
= memcmp (p1
, p2
, tree_low_cst (len
, 1));
7965 return integer_one_node
;
7967 return integer_minus_one_node
;
7969 return integer_zero_node
;
7972 /* If len parameter is one, return an expression corresponding to
7973 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
7974 if (host_integerp (len
, 1) && tree_low_cst (len
, 1) == 1)
7976 tree cst_uchar_node
= build_type_variant (unsigned_char_type_node
, 1, 0);
7977 tree cst_uchar_ptr_node
7978 = build_pointer_type_for_mode (cst_uchar_node
, ptr_mode
, true);
7980 tree ind1
= fold_convert (integer_type_node
,
7981 build1 (INDIRECT_REF
, cst_uchar_node
,
7982 fold_convert (cst_uchar_ptr_node
,
7984 tree ind2
= fold_convert (integer_type_node
,
7985 build1 (INDIRECT_REF
, cst_uchar_node
,
7986 fold_convert (cst_uchar_ptr_node
,
7988 return fold_build2 (MINUS_EXPR
, integer_type_node
, ind1
, ind2
);
7994 /* Fold function call to builtin strcmp. Return
7995 NULL_TREE if no simplification can be made. */
7998 fold_builtin_strcmp (tree arglist
)
8001 const char *p1
, *p2
;
8003 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
8006 arg1
= TREE_VALUE (arglist
);
8007 arg2
= TREE_VALUE (TREE_CHAIN (arglist
));
8009 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
8010 if (operand_equal_p (arg1
, arg2
, 0))
8011 return integer_zero_node
;
8013 p1
= c_getstr (arg1
);
8014 p2
= c_getstr (arg2
);
8018 const int i
= strcmp (p1
, p2
);
8020 return integer_minus_one_node
;
8022 return integer_one_node
;
8024 return integer_zero_node
;
8027 /* If the second arg is "", return *(const unsigned char*)arg1. */
8028 if (p2
&& *p2
== '\0')
8030 tree cst_uchar_node
= build_type_variant (unsigned_char_type_node
, 1, 0);
8031 tree cst_uchar_ptr_node
8032 = build_pointer_type_for_mode (cst_uchar_node
, ptr_mode
, true);
8034 return fold_convert (integer_type_node
,
8035 build1 (INDIRECT_REF
, cst_uchar_node
,
8036 fold_convert (cst_uchar_ptr_node
,
8040 /* If the first arg is "", return -*(const unsigned char*)arg2. */
8041 if (p1
&& *p1
== '\0')
8043 tree cst_uchar_node
= build_type_variant (unsigned_char_type_node
, 1, 0);
8044 tree cst_uchar_ptr_node
8045 = build_pointer_type_for_mode (cst_uchar_node
, ptr_mode
, true);
8047 tree temp
= fold_convert (integer_type_node
,
8048 build1 (INDIRECT_REF
, cst_uchar_node
,
8049 fold_convert (cst_uchar_ptr_node
,
8051 return fold_build1 (NEGATE_EXPR
, integer_type_node
, temp
);
8057 /* Fold function call to builtin strncmp. Return
8058 NULL_TREE if no simplification can be made. */
8061 fold_builtin_strncmp (tree arglist
)
8063 tree arg1
, arg2
, len
;
8064 const char *p1
, *p2
;
8066 if (!validate_arglist (arglist
,
8067 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
8070 arg1
= TREE_VALUE (arglist
);
8071 arg2
= TREE_VALUE (TREE_CHAIN (arglist
));
8072 len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
8074 /* If the LEN parameter is zero, return zero. */
8075 if (integer_zerop (len
))
8076 return omit_two_operands (integer_type_node
, integer_zero_node
,
8079 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
8080 if (operand_equal_p (arg1
, arg2
, 0))
8081 return omit_one_operand (integer_type_node
, integer_zero_node
, len
);
8083 p1
= c_getstr (arg1
);
8084 p2
= c_getstr (arg2
);
8086 if (host_integerp (len
, 1) && p1
&& p2
)
8088 const int i
= strncmp (p1
, p2
, tree_low_cst (len
, 1));
8090 return integer_one_node
;
8092 return integer_minus_one_node
;
8094 return integer_zero_node
;
8097 /* If the second arg is "", and the length is greater than zero,
8098 return *(const unsigned char*)arg1. */
8099 if (p2
&& *p2
== '\0'
8100 && TREE_CODE (len
) == INTEGER_CST
8101 && tree_int_cst_sgn (len
) == 1)
8103 tree cst_uchar_node
= build_type_variant (unsigned_char_type_node
, 1, 0);
8104 tree cst_uchar_ptr_node
8105 = build_pointer_type_for_mode (cst_uchar_node
, ptr_mode
, true);
8107 return fold_convert (integer_type_node
,
8108 build1 (INDIRECT_REF
, cst_uchar_node
,
8109 fold_convert (cst_uchar_ptr_node
,
8113 /* If the first arg is "", and the length is greater than zero,
8114 return -*(const unsigned char*)arg2. */
8115 if (p1
&& *p1
== '\0'
8116 && TREE_CODE (len
) == INTEGER_CST
8117 && tree_int_cst_sgn (len
) == 1)
8119 tree cst_uchar_node
= build_type_variant (unsigned_char_type_node
, 1, 0);
8120 tree cst_uchar_ptr_node
8121 = build_pointer_type_for_mode (cst_uchar_node
, ptr_mode
, true);
8123 tree temp
= fold_convert (integer_type_node
,
8124 build1 (INDIRECT_REF
, cst_uchar_node
,
8125 fold_convert (cst_uchar_ptr_node
,
8127 return fold_build1 (NEGATE_EXPR
, integer_type_node
, temp
);
8130 /* If len parameter is one, return an expression corresponding to
8131 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
8132 if (host_integerp (len
, 1) && tree_low_cst (len
, 1) == 1)
8134 tree cst_uchar_node
= build_type_variant (unsigned_char_type_node
, 1, 0);
8135 tree cst_uchar_ptr_node
8136 = build_pointer_type_for_mode (cst_uchar_node
, ptr_mode
, true);
8138 tree ind1
= fold_convert (integer_type_node
,
8139 build1 (INDIRECT_REF
, cst_uchar_node
,
8140 fold_convert (cst_uchar_ptr_node
,
8142 tree ind2
= fold_convert (integer_type_node
,
8143 build1 (INDIRECT_REF
, cst_uchar_node
,
8144 fold_convert (cst_uchar_ptr_node
,
8146 return fold_build2 (MINUS_EXPR
, integer_type_node
, ind1
, ind2
);
8152 /* Fold function call to builtin signbit, signbitf or signbitl. Return
8153 NULL_TREE if no simplification can be made. */
8156 fold_builtin_signbit (tree fndecl
, tree arglist
)
8158 tree type
= TREE_TYPE (TREE_TYPE (fndecl
));
8161 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
8164 arg
= TREE_VALUE (arglist
);
8166 /* If ARG is a compile-time constant, determine the result. */
8167 if (TREE_CODE (arg
) == REAL_CST
8168 && !TREE_CONSTANT_OVERFLOW (arg
))
8172 c
= TREE_REAL_CST (arg
);
8173 temp
= REAL_VALUE_NEGATIVE (c
) ? integer_one_node
: integer_zero_node
;
8174 return fold_convert (type
, temp
);
8177 /* If ARG is non-negative, the result is always zero. */
8178 if (tree_expr_nonnegative_p (arg
))
8179 return omit_one_operand (type
, integer_zero_node
, arg
);
8181 /* If ARG's format doesn't have signed zeros, return "arg < 0.0". */
8182 if (!HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg
))))
8183 return fold_build2 (LT_EXPR
, type
, arg
,
8184 build_real (TREE_TYPE (arg
), dconst0
));
8189 /* Fold function call to builtin copysign, copysignf or copysignl.
8190 Return NULL_TREE if no simplification can be made. */
8193 fold_builtin_copysign (tree fndecl
, tree arglist
, tree type
)
8195 tree arg1
, arg2
, tem
;
8197 if (!validate_arglist (arglist
, REAL_TYPE
, REAL_TYPE
, VOID_TYPE
))
8200 arg1
= TREE_VALUE (arglist
);
8201 arg2
= TREE_VALUE (TREE_CHAIN (arglist
));
8203 /* copysign(X,X) is X. */
8204 if (operand_equal_p (arg1
, arg2
, 0))
8205 return fold_convert (type
, arg1
);
8207 /* If ARG1 and ARG2 are compile-time constants, determine the result. */
8208 if (TREE_CODE (arg1
) == REAL_CST
8209 && TREE_CODE (arg2
) == REAL_CST
8210 && !TREE_CONSTANT_OVERFLOW (arg1
)
8211 && !TREE_CONSTANT_OVERFLOW (arg2
))
8213 REAL_VALUE_TYPE c1
, c2
;
8215 c1
= TREE_REAL_CST (arg1
);
8216 c2
= TREE_REAL_CST (arg2
);
8217 /* c1.sign := c2.sign. */
8218 real_copysign (&c1
, &c2
);
8219 return build_real (type
, c1
);
8222 /* copysign(X, Y) is fabs(X) when Y is always non-negative.
8223 Remember to evaluate Y for side-effects. */
8224 if (tree_expr_nonnegative_p (arg2
))
8225 return omit_one_operand (type
,
8226 fold_build1 (ABS_EXPR
, type
, arg1
),
8229 /* Strip sign changing operations for the first argument. */
8230 tem
= fold_strip_sign_ops (arg1
);
8233 arglist
= tree_cons (NULL_TREE
, tem
, TREE_CHAIN (arglist
));
8234 return build_function_call_expr (fndecl
, arglist
);
8240 /* Fold a call to builtin isascii. */
8243 fold_builtin_isascii (tree arglist
)
8245 if (! validate_arglist (arglist
, INTEGER_TYPE
, VOID_TYPE
))
8249 /* Transform isascii(c) -> ((c & ~0x7f) == 0). */
8250 tree arg
= TREE_VALUE (arglist
);
8252 arg
= build2 (BIT_AND_EXPR
, integer_type_node
, arg
,
8253 build_int_cst (NULL_TREE
,
8254 ~ (unsigned HOST_WIDE_INT
) 0x7f));
8255 arg
= fold_build2 (EQ_EXPR
, integer_type_node
,
8256 arg
, integer_zero_node
);
8258 if (in_gimple_form
&& !TREE_CONSTANT (arg
))
8265 /* Fold a call to builtin toascii. */
8268 fold_builtin_toascii (tree arglist
)
8270 if (! validate_arglist (arglist
, INTEGER_TYPE
, VOID_TYPE
))
8274 /* Transform toascii(c) -> (c & 0x7f). */
8275 tree arg
= TREE_VALUE (arglist
);
8277 return fold_build2 (BIT_AND_EXPR
, integer_type_node
, arg
,
8278 build_int_cst (NULL_TREE
, 0x7f));
8282 /* Fold a call to builtin isdigit. */
8285 fold_builtin_isdigit (tree arglist
)
8287 if (! validate_arglist (arglist
, INTEGER_TYPE
, VOID_TYPE
))
8291 /* Transform isdigit(c) -> (unsigned)(c) - '0' <= 9. */
8292 /* According to the C standard, isdigit is unaffected by locale.
8293 However, it definitely is affected by the target character set. */
8295 unsigned HOST_WIDE_INT target_digit0
8296 = lang_hooks
.to_target_charset ('0');
8298 if (target_digit0
== 0)
8301 arg
= fold_convert (unsigned_type_node
, TREE_VALUE (arglist
));
8302 arg
= build2 (MINUS_EXPR
, unsigned_type_node
, arg
,
8303 build_int_cst (unsigned_type_node
, target_digit0
));
8304 arg
= fold_build2 (LE_EXPR
, integer_type_node
, arg
,
8305 build_int_cst (unsigned_type_node
, 9));
8306 if (in_gimple_form
&& !TREE_CONSTANT (arg
))
8313 /* Fold a call to fabs, fabsf or fabsl. */
8316 fold_builtin_fabs (tree arglist
, tree type
)
8320 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
8323 arg
= TREE_VALUE (arglist
);
8324 arg
= fold_convert (type
, arg
);
8325 if (TREE_CODE (arg
) == REAL_CST
)
8326 return fold_abs_const (arg
, type
);
8327 return fold_build1 (ABS_EXPR
, type
, arg
);
8330 /* Fold a call to abs, labs, llabs or imaxabs. */
8333 fold_builtin_abs (tree arglist
, tree type
)
8337 if (!validate_arglist (arglist
, INTEGER_TYPE
, VOID_TYPE
))
8340 arg
= TREE_VALUE (arglist
);
8341 arg
= fold_convert (type
, arg
);
8342 if (TREE_CODE (arg
) == INTEGER_CST
)
8343 return fold_abs_const (arg
, type
);
8344 return fold_build1 (ABS_EXPR
, type
, arg
);
8347 /* Fold a call to __builtin_isnan(), __builtin_isinf, __builtin_finite.
8348 EXP is the CALL_EXPR for the call. */
8351 fold_builtin_classify (tree fndecl
, tree arglist
, int builtin_index
)
8353 tree type
= TREE_TYPE (TREE_TYPE (fndecl
));
8357 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
8359 /* Check that we have exactly one argument. */
8362 error ("too few arguments to function %qs",
8363 IDENTIFIER_POINTER (DECL_NAME (fndecl
)));
8364 return error_mark_node
;
8366 else if (TREE_CHAIN (arglist
) != 0)
8368 error ("too many arguments to function %qs",
8369 IDENTIFIER_POINTER (DECL_NAME (fndecl
)));
8370 return error_mark_node
;
8374 error ("non-floating-point argument to function %qs",
8375 IDENTIFIER_POINTER (DECL_NAME (fndecl
)));
8376 return error_mark_node
;
8380 arg
= TREE_VALUE (arglist
);
8381 switch (builtin_index
)
8383 case BUILT_IN_ISINF
:
8384 if (!MODE_HAS_INFINITIES (TYPE_MODE (TREE_TYPE (arg
))))
8385 return omit_one_operand (type
, integer_zero_node
, arg
);
8387 if (TREE_CODE (arg
) == REAL_CST
)
8389 r
= TREE_REAL_CST (arg
);
8390 if (real_isinf (&r
))
8391 return real_compare (GT_EXPR
, &r
, &dconst0
)
8392 ? integer_one_node
: integer_minus_one_node
;
8394 return integer_zero_node
;
8399 case BUILT_IN_FINITE
:
8400 if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg
)))
8401 && !MODE_HAS_INFINITIES (TYPE_MODE (TREE_TYPE (arg
))))
8402 return omit_one_operand (type
, integer_zero_node
, arg
);
8404 if (TREE_CODE (arg
) == REAL_CST
)
8406 r
= TREE_REAL_CST (arg
);
8407 return real_isinf (&r
) || real_isnan (&r
)
8408 ? integer_zero_node
: integer_one_node
;
8413 case BUILT_IN_ISNAN
:
8414 if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg
))))
8415 return omit_one_operand (type
, integer_zero_node
, arg
);
8417 if (TREE_CODE (arg
) == REAL_CST
)
8419 r
= TREE_REAL_CST (arg
);
8420 return real_isnan (&r
) ? integer_one_node
: integer_zero_node
;
8423 arg
= builtin_save_expr (arg
);
8424 return fold_build2 (UNORDERED_EXPR
, type
, arg
, arg
);
8431 /* Fold a call to an unordered comparison function such as
8432 __builtin_isgreater(). FNDECL is the FUNCTION_DECL for the function
8433 being called and ARGLIST is the argument list for the call.
8434 UNORDERED_CODE and ORDERED_CODE are comparison codes that give
8435 the opposite of the desired result. UNORDERED_CODE is used
8436 for modes that can hold NaNs and ORDERED_CODE is used for
8440 fold_builtin_unordered_cmp (tree fndecl
, tree arglist
,
8441 enum tree_code unordered_code
,
8442 enum tree_code ordered_code
)
8444 tree type
= TREE_TYPE (TREE_TYPE (fndecl
));
8445 enum tree_code code
;
8448 enum tree_code code0
, code1
;
8449 tree cmp_type
= NULL_TREE
;
8451 if (!validate_arglist (arglist
, REAL_TYPE
, REAL_TYPE
, VOID_TYPE
))
8453 /* Check that we have exactly two arguments. */
8454 if (arglist
== 0 || TREE_CHAIN (arglist
) == 0)
8456 error ("too few arguments to function %qs",
8457 IDENTIFIER_POINTER (DECL_NAME (fndecl
)));
8458 return error_mark_node
;
8460 else if (TREE_CHAIN (TREE_CHAIN (arglist
)) != 0)
8462 error ("too many arguments to function %qs",
8463 IDENTIFIER_POINTER (DECL_NAME (fndecl
)));
8464 return error_mark_node
;
8468 arg0
= TREE_VALUE (arglist
);
8469 arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
8471 type0
= TREE_TYPE (arg0
);
8472 type1
= TREE_TYPE (arg1
);
8474 code0
= TREE_CODE (type0
);
8475 code1
= TREE_CODE (type1
);
8477 if (code0
== REAL_TYPE
&& code1
== REAL_TYPE
)
8478 /* Choose the wider of two real types. */
8479 cmp_type
= TYPE_PRECISION (type0
) >= TYPE_PRECISION (type1
)
8481 else if (code0
== REAL_TYPE
&& code1
== INTEGER_TYPE
)
8483 else if (code0
== INTEGER_TYPE
&& code1
== REAL_TYPE
)
8487 error ("non-floating-point argument to function %qs",
8488 IDENTIFIER_POINTER (DECL_NAME (fndecl
)));
8489 return error_mark_node
;
8492 arg0
= fold_convert (cmp_type
, arg0
);
8493 arg1
= fold_convert (cmp_type
, arg1
);
8495 if (unordered_code
== UNORDERED_EXPR
)
8497 if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg0
))))
8498 return omit_two_operands (type
, integer_zero_node
, arg0
, arg1
);
8499 return fold_build2 (UNORDERED_EXPR
, type
, arg0
, arg1
);
8502 code
= MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg0
))) ? unordered_code
8504 return fold_build1 (TRUTH_NOT_EXPR
, type
,
8505 fold_build2 (code
, type
, arg0
, arg1
));
8508 /* Used by constant folding to simplify calls to builtin functions. EXP is
8509 the CALL_EXPR of a call to a builtin function. IGNORE is true if the
8510 result of the function call is ignored. This function returns NULL_TREE
8511 if no simplification was possible. */
8514 fold_builtin_1 (tree fndecl
, tree arglist
, bool ignore
)
8516 tree type
= TREE_TYPE (TREE_TYPE (fndecl
));
8517 enum built_in_function fcode
;
8519 if (DECL_BUILT_IN_CLASS (fndecl
) == BUILT_IN_MD
)
8520 return targetm
.fold_builtin (fndecl
, arglist
, ignore
);
8522 fcode
= DECL_FUNCTION_CODE (fndecl
);
8525 case BUILT_IN_FPUTS
:
8526 return fold_builtin_fputs (arglist
, ignore
, false, NULL_TREE
);
8528 case BUILT_IN_FPUTS_UNLOCKED
:
8529 return fold_builtin_fputs (arglist
, ignore
, true, NULL_TREE
);
8531 case BUILT_IN_STRSTR
:
8532 return fold_builtin_strstr (arglist
, type
);
8534 case BUILT_IN_STRCAT
:
8535 return fold_builtin_strcat (arglist
);
8537 case BUILT_IN_STRNCAT
:
8538 return fold_builtin_strncat (arglist
);
8540 case BUILT_IN_STRSPN
:
8541 return fold_builtin_strspn (arglist
);
8543 case BUILT_IN_STRCSPN
:
8544 return fold_builtin_strcspn (arglist
);
8546 case BUILT_IN_STRCHR
:
8547 case BUILT_IN_INDEX
:
8548 return fold_builtin_strchr (arglist
, type
);
8550 case BUILT_IN_STRRCHR
:
8551 case BUILT_IN_RINDEX
:
8552 return fold_builtin_strrchr (arglist
, type
);
8554 case BUILT_IN_STRCPY
:
8555 return fold_builtin_strcpy (fndecl
, arglist
, NULL_TREE
);
8557 case BUILT_IN_STRNCPY
:
8558 return fold_builtin_strncpy (fndecl
, arglist
, NULL_TREE
);
8560 case BUILT_IN_STRCMP
:
8561 return fold_builtin_strcmp (arglist
);
8563 case BUILT_IN_STRNCMP
:
8564 return fold_builtin_strncmp (arglist
);
8566 case BUILT_IN_STRPBRK
:
8567 return fold_builtin_strpbrk (arglist
, type
);
8570 case BUILT_IN_MEMCMP
:
8571 return fold_builtin_memcmp (arglist
);
8573 case BUILT_IN_SPRINTF
:
8574 return fold_builtin_sprintf (arglist
, ignore
);
8576 case BUILT_IN_CONSTANT_P
:
8580 val
= fold_builtin_constant_p (arglist
);
8581 /* Gimplification will pull the CALL_EXPR for the builtin out of
8582 an if condition. When not optimizing, we'll not CSE it back.
8583 To avoid link error types of regressions, return false now. */
8584 if (!val
&& !optimize
)
8585 val
= integer_zero_node
;
8590 case BUILT_IN_EXPECT
:
8591 return fold_builtin_expect (arglist
);
8593 case BUILT_IN_CLASSIFY_TYPE
:
8594 return fold_builtin_classify_type (arglist
);
8596 case BUILT_IN_STRLEN
:
8597 return fold_builtin_strlen (arglist
);
8599 CASE_FLT_FN (BUILT_IN_FABS
):
8600 return fold_builtin_fabs (arglist
, type
);
8604 case BUILT_IN_LLABS
:
8605 case BUILT_IN_IMAXABS
:
8606 return fold_builtin_abs (arglist
, type
);
8608 CASE_FLT_FN (BUILT_IN_CONJ
):
8609 if (validate_arglist (arglist
, COMPLEX_TYPE
, VOID_TYPE
))
8610 return fold_build1 (CONJ_EXPR
, type
, TREE_VALUE (arglist
));
8613 CASE_FLT_FN (BUILT_IN_CREAL
):
8614 if (validate_arglist (arglist
, COMPLEX_TYPE
, VOID_TYPE
))
8615 return non_lvalue (fold_build1 (REALPART_EXPR
, type
,
8616 TREE_VALUE (arglist
)));
8619 CASE_FLT_FN (BUILT_IN_CIMAG
):
8620 if (validate_arglist (arglist
, COMPLEX_TYPE
, VOID_TYPE
))
8621 return non_lvalue (fold_build1 (IMAGPART_EXPR
, type
,
8622 TREE_VALUE (arglist
)));
8625 CASE_FLT_FN (BUILT_IN_CABS
):
8626 return fold_builtin_cabs (arglist
, type
);
8628 CASE_FLT_FN (BUILT_IN_SQRT
):
8629 return fold_builtin_sqrt (arglist
, type
);
8631 CASE_FLT_FN (BUILT_IN_CBRT
):
8632 return fold_builtin_cbrt (arglist
, type
);
8634 CASE_FLT_FN (BUILT_IN_SIN
):
8635 return fold_builtin_sin (arglist
);
8637 CASE_FLT_FN (BUILT_IN_COS
):
8638 return fold_builtin_cos (arglist
, type
, fndecl
);
8640 CASE_FLT_FN (BUILT_IN_EXP
):
8641 return fold_builtin_exponent (fndecl
, arglist
, &dconste
);
8643 CASE_FLT_FN (BUILT_IN_EXP2
):
8644 return fold_builtin_exponent (fndecl
, arglist
, &dconst2
);
8646 CASE_FLT_FN (BUILT_IN_EXP10
):
8647 CASE_FLT_FN (BUILT_IN_POW10
):
8648 return fold_builtin_exponent (fndecl
, arglist
, &dconst10
);
8650 CASE_FLT_FN (BUILT_IN_LOG
):
8651 return fold_builtin_logarithm (fndecl
, arglist
, &dconste
);
8653 CASE_FLT_FN (BUILT_IN_LOG2
):
8654 return fold_builtin_logarithm (fndecl
, arglist
, &dconst2
);
8656 CASE_FLT_FN (BUILT_IN_LOG10
):
8657 return fold_builtin_logarithm (fndecl
, arglist
, &dconst10
);
8659 CASE_FLT_FN (BUILT_IN_TAN
):
8660 return fold_builtin_tan (arglist
);
8662 CASE_FLT_FN (BUILT_IN_ATAN
):
8663 return fold_builtin_atan (arglist
, type
);
8665 CASE_FLT_FN (BUILT_IN_POW
):
8666 return fold_builtin_pow (fndecl
, arglist
, type
);
8668 CASE_FLT_FN (BUILT_IN_POWI
):
8669 return fold_builtin_powi (fndecl
, arglist
, type
);
8671 CASE_FLT_FN (BUILT_IN_INF
):
8672 case BUILT_IN_INFD32
:
8673 case BUILT_IN_INFD64
:
8674 case BUILT_IN_INFD128
:
8675 return fold_builtin_inf (type
, true);
8677 CASE_FLT_FN (BUILT_IN_HUGE_VAL
):
8678 return fold_builtin_inf (type
, false);
8680 CASE_FLT_FN (BUILT_IN_NAN
):
8681 case BUILT_IN_NAND32
:
8682 case BUILT_IN_NAND64
:
8683 case BUILT_IN_NAND128
:
8684 return fold_builtin_nan (arglist
, type
, true);
8686 CASE_FLT_FN (BUILT_IN_NANS
):
8687 return fold_builtin_nan (arglist
, type
, false);
8689 CASE_FLT_FN (BUILT_IN_FLOOR
):
8690 return fold_builtin_floor (fndecl
, arglist
);
8692 CASE_FLT_FN (BUILT_IN_CEIL
):
8693 return fold_builtin_ceil (fndecl
, arglist
);
8695 CASE_FLT_FN (BUILT_IN_TRUNC
):
8696 return fold_builtin_trunc (fndecl
, arglist
);
8698 CASE_FLT_FN (BUILT_IN_ROUND
):
8699 return fold_builtin_round (fndecl
, arglist
);
8701 CASE_FLT_FN (BUILT_IN_NEARBYINT
):
8702 CASE_FLT_FN (BUILT_IN_RINT
):
8703 return fold_trunc_transparent_mathfn (fndecl
, arglist
);
8705 CASE_FLT_FN (BUILT_IN_LCEIL
):
8706 CASE_FLT_FN (BUILT_IN_LLCEIL
):
8707 CASE_FLT_FN (BUILT_IN_LFLOOR
):
8708 CASE_FLT_FN (BUILT_IN_LLFLOOR
):
8709 CASE_FLT_FN (BUILT_IN_LROUND
):
8710 CASE_FLT_FN (BUILT_IN_LLROUND
):
8711 return fold_builtin_int_roundingfn (fndecl
, arglist
);
8713 CASE_FLT_FN (BUILT_IN_LRINT
):
8714 CASE_FLT_FN (BUILT_IN_LLRINT
):
8715 return fold_fixed_mathfn (fndecl
, arglist
);
8717 CASE_INT_FN (BUILT_IN_FFS
):
8718 CASE_INT_FN (BUILT_IN_CLZ
):
8719 CASE_INT_FN (BUILT_IN_CTZ
):
8720 CASE_INT_FN (BUILT_IN_POPCOUNT
):
8721 CASE_INT_FN (BUILT_IN_PARITY
):
8722 return fold_builtin_bitop (fndecl
, arglist
);
8724 case BUILT_IN_MEMCPY
:
8725 return fold_builtin_memcpy (fndecl
, arglist
);
8727 case BUILT_IN_MEMPCPY
:
8728 return fold_builtin_mempcpy (arglist
, type
, /*endp=*/1);
8730 case BUILT_IN_MEMMOVE
:
8731 return fold_builtin_memmove (arglist
, type
);
8733 CASE_FLT_FN (BUILT_IN_SIGNBIT
):
8734 return fold_builtin_signbit (fndecl
, arglist
);
8736 case BUILT_IN_ISASCII
:
8737 return fold_builtin_isascii (arglist
);
8739 case BUILT_IN_TOASCII
:
8740 return fold_builtin_toascii (arglist
);
8742 case BUILT_IN_ISDIGIT
:
8743 return fold_builtin_isdigit (arglist
);
8745 CASE_FLT_FN (BUILT_IN_COPYSIGN
):
8746 return fold_builtin_copysign (fndecl
, arglist
, type
);
8748 CASE_FLT_FN (BUILT_IN_FINITE
):
8749 case BUILT_IN_FINITED32
:
8750 case BUILT_IN_FINITED64
:
8751 case BUILT_IN_FINITED128
:
8752 return fold_builtin_classify (fndecl
, arglist
, BUILT_IN_FINITE
);
8754 CASE_FLT_FN (BUILT_IN_ISINF
):
8755 case BUILT_IN_ISINFD32
:
8756 case BUILT_IN_ISINFD64
:
8757 case BUILT_IN_ISINFD128
:
8758 return fold_builtin_classify (fndecl
, arglist
, BUILT_IN_ISINF
);
8760 CASE_FLT_FN (BUILT_IN_ISNAN
):
8761 case BUILT_IN_ISNAND32
:
8762 case BUILT_IN_ISNAND64
:
8763 case BUILT_IN_ISNAND128
:
8764 return fold_builtin_classify (fndecl
, arglist
, BUILT_IN_ISNAN
);
8766 case BUILT_IN_ISGREATER
:
8767 return fold_builtin_unordered_cmp (fndecl
, arglist
, UNLE_EXPR
, LE_EXPR
);
8768 case BUILT_IN_ISGREATEREQUAL
:
8769 return fold_builtin_unordered_cmp (fndecl
, arglist
, UNLT_EXPR
, LT_EXPR
);
8770 case BUILT_IN_ISLESS
:
8771 return fold_builtin_unordered_cmp (fndecl
, arglist
, UNGE_EXPR
, GE_EXPR
);
8772 case BUILT_IN_ISLESSEQUAL
:
8773 return fold_builtin_unordered_cmp (fndecl
, arglist
, UNGT_EXPR
, GT_EXPR
);
8774 case BUILT_IN_ISLESSGREATER
:
8775 return fold_builtin_unordered_cmp (fndecl
, arglist
, UNEQ_EXPR
, EQ_EXPR
);
8776 case BUILT_IN_ISUNORDERED
:
8777 return fold_builtin_unordered_cmp (fndecl
, arglist
, UNORDERED_EXPR
,
8780 /* We do the folding for va_start in the expander. */
8781 case BUILT_IN_VA_START
:
8784 case BUILT_IN_OBJECT_SIZE
:
8785 return fold_builtin_object_size (arglist
);
8786 case BUILT_IN_MEMCPY_CHK
:
8787 case BUILT_IN_MEMPCPY_CHK
:
8788 case BUILT_IN_MEMMOVE_CHK
:
8789 case BUILT_IN_MEMSET_CHK
:
8790 return fold_builtin_memory_chk (fndecl
, arglist
, NULL_TREE
, ignore
,
8791 DECL_FUNCTION_CODE (fndecl
));
8792 case BUILT_IN_STRCPY_CHK
:
8793 case BUILT_IN_STPCPY_CHK
:
8794 return fold_builtin_stxcpy_chk (fndecl
, arglist
, NULL_TREE
, ignore
,
8795 DECL_FUNCTION_CODE (fndecl
));
8796 case BUILT_IN_STRNCPY_CHK
:
8797 return fold_builtin_strncpy_chk (arglist
, NULL_TREE
);
8798 case BUILT_IN_STRCAT_CHK
:
8799 return fold_builtin_strcat_chk (fndecl
, arglist
);
8800 case BUILT_IN_STRNCAT_CHK
:
8801 return fold_builtin_strncat_chk (fndecl
, arglist
);
8802 case BUILT_IN_SPRINTF_CHK
:
8803 case BUILT_IN_VSPRINTF_CHK
:
8804 return fold_builtin_sprintf_chk (arglist
, DECL_FUNCTION_CODE (fndecl
));
8805 case BUILT_IN_SNPRINTF_CHK
:
8806 case BUILT_IN_VSNPRINTF_CHK
:
8807 return fold_builtin_snprintf_chk (arglist
, NULL_TREE
,
8808 DECL_FUNCTION_CODE (fndecl
));
8810 case BUILT_IN_PRINTF
:
8811 case BUILT_IN_PRINTF_UNLOCKED
:
8812 case BUILT_IN_VPRINTF
:
8813 case BUILT_IN_PRINTF_CHK
:
8814 case BUILT_IN_VPRINTF_CHK
:
8815 return fold_builtin_printf (fndecl
, arglist
, ignore
,
8816 DECL_FUNCTION_CODE (fndecl
));
8818 case BUILT_IN_FPRINTF
:
8819 case BUILT_IN_FPRINTF_UNLOCKED
:
8820 case BUILT_IN_VFPRINTF
:
8821 case BUILT_IN_FPRINTF_CHK
:
8822 case BUILT_IN_VFPRINTF_CHK
:
8823 return fold_builtin_fprintf (fndecl
, arglist
, ignore
,
8824 DECL_FUNCTION_CODE (fndecl
));
8833 /* A wrapper function for builtin folding that prevents warnings for
8834 "statement without effect" and the like, caused by removing the
8835 call node earlier than the warning is generated. */
8838 fold_builtin (tree fndecl
, tree arglist
, bool ignore
)
8840 tree exp
= fold_builtin_1 (fndecl
, arglist
, ignore
);
8843 exp
= build1 (NOP_EXPR
, TREE_TYPE (exp
), exp
);
8844 TREE_NO_WARNING (exp
) = 1;
8850 /* Conveniently construct a function call expression. */
8853 build_function_call_expr (tree fn
, tree arglist
)
8857 call_expr
= build1 (ADDR_EXPR
, build_pointer_type (TREE_TYPE (fn
)), fn
);
8858 return fold_build3 (CALL_EXPR
, TREE_TYPE (TREE_TYPE (fn
)),
8859 call_expr
, arglist
, NULL_TREE
);
8862 /* This function validates the types of a function call argument list
8863 represented as a tree chain of parameters against a specified list
8864 of tree_codes. If the last specifier is a 0, that represents an
8865 ellipses, otherwise the last specifier must be a VOID_TYPE. */
8868 validate_arglist (tree arglist
, ...)
8870 enum tree_code code
;
8874 va_start (ap
, arglist
);
8878 code
= va_arg (ap
, enum tree_code
);
8882 /* This signifies an ellipses, any further arguments are all ok. */
8886 /* This signifies an endlink, if no arguments remain, return
8887 true, otherwise return false. */
8891 /* If no parameters remain or the parameter's code does not
8892 match the specified code, return false. Otherwise continue
8893 checking any remaining arguments. */
8896 if (code
== POINTER_TYPE
)
8898 if (! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist
))))
8901 else if (code
!= TREE_CODE (TREE_TYPE (TREE_VALUE (arglist
))))
8905 arglist
= TREE_CHAIN (arglist
);
8909 /* We need gotos here since we can only have one VA_CLOSE in a
8917 /* Default target-specific builtin expander that does nothing. */
8920 default_expand_builtin (tree exp ATTRIBUTE_UNUSED
,
8921 rtx target ATTRIBUTE_UNUSED
,
8922 rtx subtarget ATTRIBUTE_UNUSED
,
8923 enum machine_mode mode ATTRIBUTE_UNUSED
,
8924 int ignore ATTRIBUTE_UNUSED
)
8929 /* Default target-specific library builtin expander that does nothing. */
8932 default_expand_library_builtin (tree exp ATTRIBUTE_UNUSED
,
8933 rtx target ATTRIBUTE_UNUSED
,
8934 rtx subtarget ATTRIBUTE_UNUSED
,
8935 enum machine_mode mode ATTRIBUTE_UNUSED
,
8936 int ignore ATTRIBUTE_UNUSED
)
8941 /* Returns true is EXP represents data that would potentially reside
8942 in a readonly section. */
8945 readonly_data_expr (tree exp
)
8949 if (TREE_CODE (exp
) != ADDR_EXPR
)
8952 exp
= get_base_address (TREE_OPERAND (exp
, 0));
8956 /* Make sure we call decl_readonly_section only for trees it
8957 can handle (since it returns true for everything it doesn't
8959 if (TREE_CODE (exp
) == STRING_CST
8960 || TREE_CODE (exp
) == CONSTRUCTOR
8961 || (TREE_CODE (exp
) == VAR_DECL
&& TREE_STATIC (exp
)))
8962 return decl_readonly_section (exp
, 0);
8967 /* Simplify a call to the strstr builtin.
8969 Return 0 if no simplification was possible, otherwise return the
8970 simplified form of the call as a tree.
8972 The simplified form may be a constant or other expression which
8973 computes the same value, but in a more efficient manner (including
8974 calls to other builtin functions).
8976 The call may contain arguments which need to be evaluated, but
8977 which are not useful to determine the result of the call. In
8978 this case we return a chain of COMPOUND_EXPRs. The LHS of each
8979 COMPOUND_EXPR will be an argument which must be evaluated.
8980 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
8981 COMPOUND_EXPR in the chain will contain the tree for the simplified
8982 form of the builtin function call. */
8985 fold_builtin_strstr (tree arglist
, tree type
)
8987 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
8991 tree s1
= TREE_VALUE (arglist
), s2
= TREE_VALUE (TREE_CHAIN (arglist
));
8993 const char *p1
, *p2
;
9002 const char *r
= strstr (p1
, p2
);
9006 return build_int_cst (TREE_TYPE (s1
), 0);
9008 /* Return an offset into the constant string argument. */
9009 tem
= fold_build2 (PLUS_EXPR
, TREE_TYPE (s1
),
9010 s1
, build_int_cst (TREE_TYPE (s1
), r
- p1
));
9011 return fold_convert (type
, tem
);
9014 /* The argument is const char *, and the result is char *, so we need
9015 a type conversion here to avoid a warning. */
9017 return fold_convert (type
, s1
);
9022 fn
= implicit_built_in_decls
[BUILT_IN_STRCHR
];
9026 /* New argument list transforming strstr(s1, s2) to
9027 strchr(s1, s2[0]). */
9028 arglist
= build_tree_list (NULL_TREE
,
9029 build_int_cst (NULL_TREE
, p2
[0]));
9030 arglist
= tree_cons (NULL_TREE
, s1
, arglist
);
9031 return build_function_call_expr (fn
, arglist
);
9035 /* Simplify a call to the strchr builtin.
9037 Return 0 if no simplification was possible, otherwise return the
9038 simplified form of the call as a tree.
9040 The simplified form may be a constant or other expression which
9041 computes the same value, but in a more efficient manner (including
9042 calls to other builtin functions).
9044 The call may contain arguments which need to be evaluated, but
9045 which are not useful to determine the result of the call. In
9046 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9047 COMPOUND_EXPR will be an argument which must be evaluated.
9048 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9049 COMPOUND_EXPR in the chain will contain the tree for the simplified
9050 form of the builtin function call. */
9053 fold_builtin_strchr (tree arglist
, tree type
)
9055 if (!validate_arglist (arglist
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
9059 tree s1
= TREE_VALUE (arglist
), s2
= TREE_VALUE (TREE_CHAIN (arglist
));
9062 if (TREE_CODE (s2
) != INTEGER_CST
)
9072 if (target_char_cast (s2
, &c
))
9078 return build_int_cst (TREE_TYPE (s1
), 0);
9080 /* Return an offset into the constant string argument. */
9081 tem
= fold_build2 (PLUS_EXPR
, TREE_TYPE (s1
),
9082 s1
, build_int_cst (TREE_TYPE (s1
), r
- p1
));
9083 return fold_convert (type
, tem
);
9089 /* Simplify a call to the strrchr builtin.
9091 Return 0 if no simplification was possible, otherwise return the
9092 simplified form of the call as a tree.
9094 The simplified form may be a constant or other expression which
9095 computes the same value, but in a more efficient manner (including
9096 calls to other builtin functions).
9098 The call may contain arguments which need to be evaluated, but
9099 which are not useful to determine the result of the call. In
9100 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9101 COMPOUND_EXPR will be an argument which must be evaluated.
9102 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9103 COMPOUND_EXPR in the chain will contain the tree for the simplified
9104 form of the builtin function call. */
9107 fold_builtin_strrchr (tree arglist
, tree type
)
9109 if (!validate_arglist (arglist
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
9113 tree s1
= TREE_VALUE (arglist
), s2
= TREE_VALUE (TREE_CHAIN (arglist
));
9117 if (TREE_CODE (s2
) != INTEGER_CST
)
9127 if (target_char_cast (s2
, &c
))
9130 r
= strrchr (p1
, c
);
9133 return build_int_cst (TREE_TYPE (s1
), 0);
9135 /* Return an offset into the constant string argument. */
9136 tem
= fold_build2 (PLUS_EXPR
, TREE_TYPE (s1
),
9137 s1
, build_int_cst (TREE_TYPE (s1
), r
- p1
));
9138 return fold_convert (type
, tem
);
9141 if (! integer_zerop (s2
))
9144 fn
= implicit_built_in_decls
[BUILT_IN_STRCHR
];
9148 /* Transform strrchr(s1, '\0') to strchr(s1, '\0'). */
9149 return build_function_call_expr (fn
, arglist
);
9153 /* Simplify a call to the strpbrk builtin.
9155 Return 0 if no simplification was possible, otherwise return the
9156 simplified form of the call as a tree.
9158 The simplified form may be a constant or other expression which
9159 computes the same value, but in a more efficient manner (including
9160 calls to other builtin functions).
9162 The call may contain arguments which need to be evaluated, but
9163 which are not useful to determine the result of the call. In
9164 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9165 COMPOUND_EXPR will be an argument which must be evaluated.
9166 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9167 COMPOUND_EXPR in the chain will contain the tree for the simplified
9168 form of the builtin function call. */
9171 fold_builtin_strpbrk (tree arglist
, tree type
)
9173 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
9177 tree s1
= TREE_VALUE (arglist
), s2
= TREE_VALUE (TREE_CHAIN (arglist
));
9179 const char *p1
, *p2
;
9188 const char *r
= strpbrk (p1
, p2
);
9192 return build_int_cst (TREE_TYPE (s1
), 0);
9194 /* Return an offset into the constant string argument. */
9195 tem
= fold_build2 (PLUS_EXPR
, TREE_TYPE (s1
),
9196 s1
, build_int_cst (TREE_TYPE (s1
), r
- p1
));
9197 return fold_convert (type
, tem
);
9201 /* strpbrk(x, "") == NULL.
9202 Evaluate and ignore s1 in case it had side-effects. */
9203 return omit_one_operand (TREE_TYPE (s1
), integer_zero_node
, s1
);
9206 return 0; /* Really call strpbrk. */
9208 fn
= implicit_built_in_decls
[BUILT_IN_STRCHR
];
9212 /* New argument list transforming strpbrk(s1, s2) to
9213 strchr(s1, s2[0]). */
9214 arglist
= build_tree_list (NULL_TREE
,
9215 build_int_cst (NULL_TREE
, p2
[0]));
9216 arglist
= tree_cons (NULL_TREE
, s1
, arglist
);
9217 return build_function_call_expr (fn
, arglist
);
9221 /* Simplify a call to the strcat builtin.
9223 Return 0 if no simplification was possible, otherwise return the
9224 simplified form of the call as a tree.
9226 The simplified form may be a constant or other expression which
9227 computes the same value, but in a more efficient manner (including
9228 calls to other builtin functions).
9230 The call may contain arguments which need to be evaluated, but
9231 which are not useful to determine the result of the call. In
9232 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9233 COMPOUND_EXPR will be an argument which must be evaluated.
9234 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9235 COMPOUND_EXPR in the chain will contain the tree for the simplified
9236 form of the builtin function call. */
9239 fold_builtin_strcat (tree arglist
)
9241 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
9245 tree dst
= TREE_VALUE (arglist
),
9246 src
= TREE_VALUE (TREE_CHAIN (arglist
));
9247 const char *p
= c_getstr (src
);
9249 /* If the string length is zero, return the dst parameter. */
9250 if (p
&& *p
== '\0')
9257 /* Simplify a call to the strncat builtin.
9259 Return 0 if no simplification was possible, otherwise return the
9260 simplified form of the call as a tree.
9262 The simplified form may be a constant or other expression which
9263 computes the same value, but in a more efficient manner (including
9264 calls to other builtin functions).
9266 The call may contain arguments which need to be evaluated, but
9267 which are not useful to determine the result of the call. In
9268 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9269 COMPOUND_EXPR will be an argument which must be evaluated.
9270 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9271 COMPOUND_EXPR in the chain will contain the tree for the simplified
9272 form of the builtin function call. */
9275 fold_builtin_strncat (tree arglist
)
9277 if (!validate_arglist (arglist
,
9278 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
9282 tree dst
= TREE_VALUE (arglist
);
9283 tree src
= TREE_VALUE (TREE_CHAIN (arglist
));
9284 tree len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
9285 const char *p
= c_getstr (src
);
9287 /* If the requested length is zero, or the src parameter string
9288 length is zero, return the dst parameter. */
9289 if (integer_zerop (len
) || (p
&& *p
== '\0'))
9290 return omit_two_operands (TREE_TYPE (dst
), dst
, src
, len
);
9292 /* If the requested len is greater than or equal to the string
9293 length, call strcat. */
9294 if (TREE_CODE (len
) == INTEGER_CST
&& p
9295 && compare_tree_int (len
, strlen (p
)) >= 0)
9298 = tree_cons (NULL_TREE
, dst
, build_tree_list (NULL_TREE
, src
));
9299 tree fn
= implicit_built_in_decls
[BUILT_IN_STRCAT
];
9301 /* If the replacement _DECL isn't initialized, don't do the
9306 return build_function_call_expr (fn
, newarglist
);
9312 /* Simplify a call to the strspn builtin.
9314 Return 0 if no simplification was possible, otherwise return the
9315 simplified form of the call as a tree.
9317 The simplified form may be a constant or other expression which
9318 computes the same value, but in a more efficient manner (including
9319 calls to other builtin functions).
9321 The call may contain arguments which need to be evaluated, but
9322 which are not useful to determine the result of the call. In
9323 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9324 COMPOUND_EXPR will be an argument which must be evaluated.
9325 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9326 COMPOUND_EXPR in the chain will contain the tree for the simplified
9327 form of the builtin function call. */
9330 fold_builtin_strspn (tree arglist
)
9332 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
9336 tree s1
= TREE_VALUE (arglist
), s2
= TREE_VALUE (TREE_CHAIN (arglist
));
9337 const char *p1
= c_getstr (s1
), *p2
= c_getstr (s2
);
9339 /* If both arguments are constants, evaluate at compile-time. */
9342 const size_t r
= strspn (p1
, p2
);
9343 return size_int (r
);
9346 /* If either argument is "", return 0. */
9347 if ((p1
&& *p1
== '\0') || (p2
&& *p2
== '\0'))
9348 /* Evaluate and ignore both arguments in case either one has
9350 return omit_two_operands (integer_type_node
, integer_zero_node
,
9356 /* Simplify a call to the strcspn builtin.
9358 Return 0 if no simplification was possible, otherwise return the
9359 simplified form of the call as a tree.
9361 The simplified form may be a constant or other expression which
9362 computes the same value, but in a more efficient manner (including
9363 calls to other builtin functions).
9365 The call may contain arguments which need to be evaluated, but
9366 which are not useful to determine the result of the call. In
9367 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9368 COMPOUND_EXPR will be an argument which must be evaluated.
9369 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9370 COMPOUND_EXPR in the chain will contain the tree for the simplified
9371 form of the builtin function call. */
9374 fold_builtin_strcspn (tree arglist
)
9376 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
9380 tree s1
= TREE_VALUE (arglist
), s2
= TREE_VALUE (TREE_CHAIN (arglist
));
9381 const char *p1
= c_getstr (s1
), *p2
= c_getstr (s2
);
9383 /* If both arguments are constants, evaluate at compile-time. */
9386 const size_t r
= strcspn (p1
, p2
);
9387 return size_int (r
);
9390 /* If the first argument is "", return 0. */
9391 if (p1
&& *p1
== '\0')
9393 /* Evaluate and ignore argument s2 in case it has
9395 return omit_one_operand (integer_type_node
,
9396 integer_zero_node
, s2
);
9399 /* If the second argument is "", return __builtin_strlen(s1). */
9400 if (p2
&& *p2
== '\0')
9402 tree newarglist
= build_tree_list (NULL_TREE
, s1
),
9403 fn
= implicit_built_in_decls
[BUILT_IN_STRLEN
];
9405 /* If the replacement _DECL isn't initialized, don't do the
9410 return build_function_call_expr (fn
, newarglist
);
9416 /* Fold a call to the fputs builtin. IGNORE is true if the value returned
9417 by the builtin will be ignored. UNLOCKED is true is true if this
9418 actually a call to fputs_unlocked. If LEN in non-NULL, it represents
9419 the known length of the string. Return NULL_TREE if no simplification
9423 fold_builtin_fputs (tree arglist
, bool ignore
, bool unlocked
, tree len
)
9426 /* If we're using an unlocked function, assume the other unlocked
9427 functions exist explicitly. */
9428 tree
const fn_fputc
= unlocked
? built_in_decls
[BUILT_IN_FPUTC_UNLOCKED
]
9429 : implicit_built_in_decls
[BUILT_IN_FPUTC
];
9430 tree
const fn_fwrite
= unlocked
? built_in_decls
[BUILT_IN_FWRITE_UNLOCKED
]
9431 : implicit_built_in_decls
[BUILT_IN_FWRITE
];
9433 /* If the return value is used, don't do the transformation. */
9437 /* Verify the arguments in the original call. */
9438 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
9442 len
= c_strlen (TREE_VALUE (arglist
), 0);
9444 /* Get the length of the string passed to fputs. If the length
9445 can't be determined, punt. */
9447 || TREE_CODE (len
) != INTEGER_CST
)
9450 switch (compare_tree_int (len
, 1))
9452 case -1: /* length is 0, delete the call entirely . */
9453 return omit_one_operand (integer_type_node
, integer_zero_node
,
9454 TREE_VALUE (TREE_CHAIN (arglist
)));
9456 case 0: /* length is 1, call fputc. */
9458 const char *p
= c_getstr (TREE_VALUE (arglist
));
9462 /* New argument list transforming fputs(string, stream) to
9463 fputc(string[0], stream). */
9464 arglist
= build_tree_list (NULL_TREE
,
9465 TREE_VALUE (TREE_CHAIN (arglist
)));
9466 arglist
= tree_cons (NULL_TREE
,
9467 build_int_cst (NULL_TREE
, p
[0]),
9474 case 1: /* length is greater than 1, call fwrite. */
9478 /* If optimizing for size keep fputs. */
9481 string_arg
= TREE_VALUE (arglist
);
9482 /* New argument list transforming fputs(string, stream) to
9483 fwrite(string, 1, len, stream). */
9484 arglist
= build_tree_list (NULL_TREE
,
9485 TREE_VALUE (TREE_CHAIN (arglist
)));
9486 arglist
= tree_cons (NULL_TREE
, len
, arglist
);
9487 arglist
= tree_cons (NULL_TREE
, size_one_node
, arglist
);
9488 arglist
= tree_cons (NULL_TREE
, string_arg
, arglist
);
9496 /* If the replacement _DECL isn't initialized, don't do the
9501 /* These optimizations are only performed when the result is ignored,
9502 hence there's no need to cast the result to integer_type_node. */
9503 return build_function_call_expr (fn
, arglist
);
9506 /* Fold the new_arg's arguments (ARGLIST). Returns true if there was an error
9507 produced. False otherwise. This is done so that we don't output the error
9508 or warning twice or three times. */
9510 fold_builtin_next_arg (tree arglist
)
9512 tree fntype
= TREE_TYPE (current_function_decl
);
9514 if (TYPE_ARG_TYPES (fntype
) == 0
9515 || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype
)))
9518 error ("%<va_start%> used in function with fixed args");
9523 /* Evidently an out of date version of <stdarg.h>; can't validate
9524 va_start's second argument, but can still work as intended. */
9525 warning (0, "%<__builtin_next_arg%> called without an argument");
9528 /* We use __builtin_va_start (ap, 0, 0) or __builtin_next_arg (0, 0)
9529 when we checked the arguments and if needed issued a warning. */
9530 else if (!TREE_CHAIN (arglist
)
9531 || !integer_zerop (TREE_VALUE (arglist
))
9532 || !integer_zerop (TREE_VALUE (TREE_CHAIN (arglist
)))
9533 || TREE_CHAIN (TREE_CHAIN (arglist
)))
9535 tree last_parm
= tree_last (DECL_ARGUMENTS (current_function_decl
));
9536 tree arg
= TREE_VALUE (arglist
);
9538 if (TREE_CHAIN (arglist
))
9540 error ("%<va_start%> used with too many arguments");
9544 /* Strip off all nops for the sake of the comparison. This
9545 is not quite the same as STRIP_NOPS. It does more.
9546 We must also strip off INDIRECT_EXPR for C++ reference
9548 while (TREE_CODE (arg
) == NOP_EXPR
9549 || TREE_CODE (arg
) == CONVERT_EXPR
9550 || TREE_CODE (arg
) == NON_LVALUE_EXPR
9551 || TREE_CODE (arg
) == INDIRECT_REF
)
9552 arg
= TREE_OPERAND (arg
, 0);
9553 if (arg
!= last_parm
)
9555 /* FIXME: Sometimes with the tree optimizers we can get the
9556 not the last argument even though the user used the last
9557 argument. We just warn and set the arg to be the last
9558 argument so that we will get wrong-code because of
9560 warning (0, "second parameter of %<va_start%> not last named argument");
9562 /* We want to verify the second parameter just once before the tree
9563 optimizers are run and then avoid keeping it in the tree,
9564 as otherwise we could warn even for correct code like:
9565 void foo (int i, ...)
9566 { va_list ap; i++; va_start (ap, i); va_end (ap); } */
9567 TREE_VALUE (arglist
) = integer_zero_node
;
9568 TREE_CHAIN (arglist
) = build_tree_list (NULL
, integer_zero_node
);
9574 /* Simplify a call to the sprintf builtin.
9576 Return 0 if no simplification was possible, otherwise return the
9577 simplified form of the call as a tree. If IGNORED is true, it means that
9578 the caller does not use the returned value of the function. */
9581 fold_builtin_sprintf (tree arglist
, int ignored
)
9583 tree call
, retval
, dest
, fmt
;
9584 const char *fmt_str
= NULL
;
9586 /* Verify the required arguments in the original call. We deal with two
9587 types of sprintf() calls: 'sprintf (str, fmt)' and
9588 'sprintf (dest, "%s", orig)'. */
9589 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
)
9590 && !validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, POINTER_TYPE
,
9594 /* Get the destination string and the format specifier. */
9595 dest
= TREE_VALUE (arglist
);
9596 fmt
= TREE_VALUE (TREE_CHAIN (arglist
));
9598 /* Check whether the format is a literal string constant. */
9599 fmt_str
= c_getstr (fmt
);
9600 if (fmt_str
== NULL
)
9606 if (!init_target_chars())
9609 /* If the format doesn't contain % args or %%, use strcpy. */
9610 if (strchr (fmt_str
, target_percent
) == NULL
)
9612 tree fn
= implicit_built_in_decls
[BUILT_IN_STRCPY
];
9617 /* Convert sprintf (str, fmt) into strcpy (str, fmt) when
9618 'format' is known to contain no % formats. */
9619 arglist
= build_tree_list (NULL_TREE
, fmt
);
9620 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
9621 call
= build_function_call_expr (fn
, arglist
);
9623 retval
= build_int_cst (NULL_TREE
, strlen (fmt_str
));
9626 /* If the format is "%s", use strcpy if the result isn't used. */
9627 else if (fmt_str
&& strcmp (fmt_str
, target_percent_s
) == 0)
9630 fn
= implicit_built_in_decls
[BUILT_IN_STRCPY
];
9635 /* Convert sprintf (str1, "%s", str2) into strcpy (str1, str2). */
9636 orig
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
9637 arglist
= build_tree_list (NULL_TREE
, orig
);
9638 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
9641 retval
= c_strlen (orig
, 1);
9642 if (!retval
|| TREE_CODE (retval
) != INTEGER_CST
)
9645 call
= build_function_call_expr (fn
, arglist
);
9651 (TREE_TYPE (TREE_TYPE (implicit_built_in_decls
[BUILT_IN_SPRINTF
])),
9653 return build2 (COMPOUND_EXPR
, TREE_TYPE (retval
), call
, retval
);
9659 /* Expand a call to __builtin_object_size. */
9662 expand_builtin_object_size (tree exp
)
9665 int object_size_type
;
9666 tree fndecl
= get_callee_fndecl (exp
);
9667 tree arglist
= TREE_OPERAND (exp
, 1);
9668 location_t locus
= EXPR_LOCATION (exp
);
9670 if (!validate_arglist (arglist
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
9672 error ("%Hfirst argument of %D must be a pointer, second integer constant",
9674 expand_builtin_trap ();
9678 ost
= TREE_VALUE (TREE_CHAIN (arglist
));
9681 if (TREE_CODE (ost
) != INTEGER_CST
9682 || tree_int_cst_sgn (ost
) < 0
9683 || compare_tree_int (ost
, 3) > 0)
9685 error ("%Hlast argument of %D is not integer constant between 0 and 3",
9687 expand_builtin_trap ();
9691 object_size_type
= tree_low_cst (ost
, 0);
9693 return object_size_type
< 2 ? constm1_rtx
: const0_rtx
;
9696 /* Expand EXP, a call to the __mem{cpy,pcpy,move,set}_chk builtin.
9697 FCODE is the BUILT_IN_* to use.
9698 Return 0 if we failed; the caller should emit a normal call,
9699 otherwise try to get the result in TARGET, if convenient (and in
9700 mode MODE if that's convenient). */
9703 expand_builtin_memory_chk (tree exp
, rtx target
, enum machine_mode mode
,
9704 enum built_in_function fcode
)
9706 tree arglist
= TREE_OPERAND (exp
, 1);
9707 tree dest
, src
, len
, size
;
9709 if (!validate_arglist (arglist
,
9711 fcode
== BUILT_IN_MEMSET_CHK
9712 ? INTEGER_TYPE
: POINTER_TYPE
,
9713 INTEGER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
9716 dest
= TREE_VALUE (arglist
);
9717 src
= TREE_VALUE (TREE_CHAIN (arglist
));
9718 len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
9719 size
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist
))));
9721 if (! host_integerp (size
, 1))
9724 if (host_integerp (len
, 1) || integer_all_onesp (size
))
9728 if (! integer_all_onesp (size
) && tree_int_cst_lt (size
, len
))
9730 location_t locus
= EXPR_LOCATION (exp
);
9731 warning (0, "%Hcall to %D will always overflow destination buffer",
9732 &locus
, get_callee_fndecl (exp
));
9736 arglist
= build_tree_list (NULL_TREE
, len
);
9737 arglist
= tree_cons (NULL_TREE
, src
, arglist
);
9738 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
9741 /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume
9742 mem{cpy,pcpy,move,set} is available. */
9745 case BUILT_IN_MEMCPY_CHK
:
9746 fn
= built_in_decls
[BUILT_IN_MEMCPY
];
9748 case BUILT_IN_MEMPCPY_CHK
:
9749 fn
= built_in_decls
[BUILT_IN_MEMPCPY
];
9751 case BUILT_IN_MEMMOVE_CHK
:
9752 fn
= built_in_decls
[BUILT_IN_MEMMOVE
];
9754 case BUILT_IN_MEMSET_CHK
:
9755 fn
= built_in_decls
[BUILT_IN_MEMSET
];
9764 fn
= build_function_call_expr (fn
, arglist
);
9765 if (TREE_CODE (fn
) == CALL_EXPR
)
9766 CALL_EXPR_TAILCALL (fn
) = CALL_EXPR_TAILCALL (exp
);
9767 return expand_expr (fn
, target
, mode
, EXPAND_NORMAL
);
9769 else if (fcode
== BUILT_IN_MEMSET_CHK
)
9773 unsigned int dest_align
9774 = get_pointer_alignment (dest
, BIGGEST_ALIGNMENT
);
9776 /* If DEST is not a pointer type, call the normal function. */
9777 if (dest_align
== 0)
9780 /* If SRC and DEST are the same (and not volatile), do nothing. */
9781 if (operand_equal_p (src
, dest
, 0))
9785 if (fcode
!= BUILT_IN_MEMPCPY_CHK
)
9787 /* Evaluate and ignore LEN in case it has side-effects. */
9788 expand_expr (len
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
9789 return expand_expr (dest
, target
, mode
, EXPAND_NORMAL
);
9792 len
= fold_convert (TREE_TYPE (dest
), len
);
9793 expr
= fold_build2 (PLUS_EXPR
, TREE_TYPE (dest
), dest
, len
);
9794 return expand_expr (expr
, target
, mode
, EXPAND_NORMAL
);
9797 /* __memmove_chk special case. */
9798 if (fcode
== BUILT_IN_MEMMOVE_CHK
)
9800 unsigned int src_align
9801 = get_pointer_alignment (src
, BIGGEST_ALIGNMENT
);
9806 /* If src is categorized for a readonly section we can use
9807 normal __memcpy_chk. */
9808 if (readonly_data_expr (src
))
9810 tree fn
= built_in_decls
[BUILT_IN_MEMCPY_CHK
];
9813 fn
= build_function_call_expr (fn
, arglist
);
9814 if (TREE_CODE (fn
) == CALL_EXPR
)
9815 CALL_EXPR_TAILCALL (fn
) = CALL_EXPR_TAILCALL (exp
);
9816 return expand_expr (fn
, target
, mode
, EXPAND_NORMAL
);
9823 /* Emit warning if a buffer overflow is detected at compile time. */
9826 maybe_emit_chk_warning (tree exp
, enum built_in_function fcode
)
9828 int arg_mask
, is_strlen
= 0;
9829 tree arglist
= TREE_OPERAND (exp
, 1), a
;
9835 case BUILT_IN_STRCPY_CHK
:
9836 case BUILT_IN_STPCPY_CHK
:
9837 /* For __strcat_chk the warning will be emitted only if overflowing
9838 by at least strlen (dest) + 1 bytes. */
9839 case BUILT_IN_STRCAT_CHK
:
9843 case BUILT_IN_STRNCPY_CHK
:
9846 case BUILT_IN_SNPRINTF_CHK
:
9847 case BUILT_IN_VSNPRINTF_CHK
:
9856 for (a
= arglist
; a
&& arg_mask
; a
= TREE_CHAIN (a
), arg_mask
>>= 1)
9868 len
= TREE_VALUE (len
);
9869 size
= TREE_VALUE (size
);
9871 if (! host_integerp (size
, 1) || integer_all_onesp (size
))
9876 len
= c_strlen (len
, 1);
9877 if (! len
|| ! host_integerp (len
, 1) || tree_int_cst_lt (len
, size
))
9880 else if (! host_integerp (len
, 1) || ! tree_int_cst_lt (size
, len
))
9883 locus
= EXPR_LOCATION (exp
);
9884 warning (0, "%Hcall to %D will always overflow destination buffer",
9885 &locus
, get_callee_fndecl (exp
));
9888 /* Emit warning if a buffer overflow is detected at compile time
9889 in __sprintf_chk/__vsprintf_chk calls. */
9892 maybe_emit_sprintf_chk_warning (tree exp
, enum built_in_function fcode
)
9894 tree arglist
= TREE_OPERAND (exp
, 1);
9895 tree dest
, size
, len
, fmt
, flag
;
9896 const char *fmt_str
;
9898 /* Verify the required arguments in the original call. */
9901 dest
= TREE_VALUE (arglist
);
9902 arglist
= TREE_CHAIN (arglist
);
9905 flag
= TREE_VALUE (arglist
);
9906 arglist
= TREE_CHAIN (arglist
);
9909 size
= TREE_VALUE (arglist
);
9910 arglist
= TREE_CHAIN (arglist
);
9913 fmt
= TREE_VALUE (arglist
);
9914 arglist
= TREE_CHAIN (arglist
);
9916 if (! host_integerp (size
, 1) || integer_all_onesp (size
))
9919 /* Check whether the format is a literal string constant. */
9920 fmt_str
= c_getstr (fmt
);
9921 if (fmt_str
== NULL
)
9924 if (!init_target_chars())
9927 /* If the format doesn't contain % args or %%, we know its size. */
9928 if (strchr (fmt_str
, target_percent
) == 0)
9929 len
= build_int_cstu (size_type_node
, strlen (fmt_str
));
9930 /* If the format is "%s" and first ... argument is a string literal,
9932 else if (fcode
== BUILT_IN_SPRINTF_CHK
&& strcmp (fmt_str
, target_percent_s
) == 0)
9938 arg
= TREE_VALUE (arglist
);
9939 if (! POINTER_TYPE_P (TREE_TYPE (arg
)))
9942 len
= c_strlen (arg
, 1);
9943 if (!len
|| ! host_integerp (len
, 1))
9949 if (! tree_int_cst_lt (len
, size
))
9951 location_t locus
= EXPR_LOCATION (exp
);
9952 warning (0, "%Hcall to %D will always overflow destination buffer",
9953 &locus
, get_callee_fndecl (exp
));
9957 /* Fold a call to __builtin_object_size, if possible. */
9960 fold_builtin_object_size (tree arglist
)
9962 tree ptr
, ost
, ret
= 0;
9963 int object_size_type
;
9965 if (!validate_arglist (arglist
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
9968 ptr
= TREE_VALUE (arglist
);
9969 ost
= TREE_VALUE (TREE_CHAIN (arglist
));
9972 if (TREE_CODE (ost
) != INTEGER_CST
9973 || tree_int_cst_sgn (ost
) < 0
9974 || compare_tree_int (ost
, 3) > 0)
9977 object_size_type
= tree_low_cst (ost
, 0);
9979 /* __builtin_object_size doesn't evaluate side-effects in its arguments;
9980 if there are any side-effects, it returns (size_t) -1 for types 0 and 1
9981 and (size_t) 0 for types 2 and 3. */
9982 if (TREE_SIDE_EFFECTS (ptr
))
9983 return fold_convert (size_type_node
,
9984 object_size_type
< 2
9985 ? integer_minus_one_node
: integer_zero_node
);
9987 if (TREE_CODE (ptr
) == ADDR_EXPR
)
9988 ret
= build_int_cstu (size_type_node
,
9989 compute_builtin_object_size (ptr
, object_size_type
));
9991 else if (TREE_CODE (ptr
) == SSA_NAME
)
9993 unsigned HOST_WIDE_INT bytes
;
9995 /* If object size is not known yet, delay folding until
9996 later. Maybe subsequent passes will help determining
9998 bytes
= compute_builtin_object_size (ptr
, object_size_type
);
9999 if (bytes
!= (unsigned HOST_WIDE_INT
) (object_size_type
< 2
10001 ret
= build_int_cstu (size_type_node
, bytes
);
10006 ret
= force_fit_type (ret
, -1, false, false);
10007 if (TREE_CONSTANT_OVERFLOW (ret
))
10014 /* Fold a call to the __mem{cpy,pcpy,move,set}_chk builtin.
10015 IGNORE is true, if return value can be ignored. FCODE is the BUILT_IN_*
10016 code of the builtin. If MAXLEN is not NULL, it is maximum length
10017 passed as third argument. */
10020 fold_builtin_memory_chk (tree fndecl
, tree arglist
, tree maxlen
, bool ignore
,
10021 enum built_in_function fcode
)
10023 tree dest
, src
, len
, size
, fn
;
10025 if (!validate_arglist (arglist
,
10027 fcode
== BUILT_IN_MEMSET_CHK
10028 ? INTEGER_TYPE
: POINTER_TYPE
,
10029 INTEGER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
10032 dest
= TREE_VALUE (arglist
);
10033 /* Actually val for __memset_chk, but it doesn't matter. */
10034 src
= TREE_VALUE (TREE_CHAIN (arglist
));
10035 len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
10036 size
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist
))));
10038 /* If SRC and DEST are the same (and not volatile), return DEST
10039 (resp. DEST+LEN for __mempcpy_chk). */
10040 if (fcode
!= BUILT_IN_MEMSET_CHK
&& operand_equal_p (src
, dest
, 0))
10042 if (fcode
!= BUILT_IN_MEMPCPY_CHK
)
10043 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl
)), dest
, len
);
10046 tree temp
= fold_convert (TREE_TYPE (dest
), len
);
10047 temp
= fold_build2 (PLUS_EXPR
, TREE_TYPE (dest
), dest
, temp
);
10048 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl
)), temp
);
10052 if (! host_integerp (size
, 1))
10055 if (! integer_all_onesp (size
))
10057 if (! host_integerp (len
, 1))
10059 /* If LEN is not constant, try MAXLEN too.
10060 For MAXLEN only allow optimizing into non-_ocs function
10061 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
10062 if (maxlen
== NULL_TREE
|| ! host_integerp (maxlen
, 1))
10064 if (fcode
== BUILT_IN_MEMPCPY_CHK
&& ignore
)
10066 /* (void) __mempcpy_chk () can be optimized into
10067 (void) __memcpy_chk (). */
10068 fn
= built_in_decls
[BUILT_IN_MEMCPY_CHK
];
10072 return build_function_call_expr (fn
, arglist
);
10080 if (tree_int_cst_lt (size
, maxlen
))
10084 arglist
= build_tree_list (NULL_TREE
, len
);
10085 arglist
= tree_cons (NULL_TREE
, src
, arglist
);
10086 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
10089 /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume
10090 mem{cpy,pcpy,move,set} is available. */
10093 case BUILT_IN_MEMCPY_CHK
:
10094 fn
= built_in_decls
[BUILT_IN_MEMCPY
];
10096 case BUILT_IN_MEMPCPY_CHK
:
10097 fn
= built_in_decls
[BUILT_IN_MEMPCPY
];
10099 case BUILT_IN_MEMMOVE_CHK
:
10100 fn
= built_in_decls
[BUILT_IN_MEMMOVE
];
10102 case BUILT_IN_MEMSET_CHK
:
10103 fn
= built_in_decls
[BUILT_IN_MEMSET
];
10112 return build_function_call_expr (fn
, arglist
);
10115 /* Fold a call to the __st[rp]cpy_chk builtin.
10116 IGNORE is true, if return value can be ignored. FCODE is the BUILT_IN_*
10117 code of the builtin. If MAXLEN is not NULL, it is maximum length of
10118 strings passed as second argument. */
10121 fold_builtin_stxcpy_chk (tree fndecl
, tree arglist
, tree maxlen
, bool ignore
,
10122 enum built_in_function fcode
)
10124 tree dest
, src
, size
, len
, fn
;
10126 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
,
10130 dest
= TREE_VALUE (arglist
);
10131 src
= TREE_VALUE (TREE_CHAIN (arglist
));
10132 size
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
10134 /* If SRC and DEST are the same (and not volatile), return DEST. */
10135 if (fcode
== BUILT_IN_STRCPY_CHK
&& operand_equal_p (src
, dest
, 0))
10136 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl
)), dest
);
10138 if (! host_integerp (size
, 1))
10141 if (! integer_all_onesp (size
))
10143 len
= c_strlen (src
, 1);
10144 if (! len
|| ! host_integerp (len
, 1))
10146 /* If LEN is not constant, try MAXLEN too.
10147 For MAXLEN only allow optimizing into non-_ocs function
10148 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
10149 if (maxlen
== NULL_TREE
|| ! host_integerp (maxlen
, 1))
10151 if (fcode
== BUILT_IN_STPCPY_CHK
)
10156 /* If return value of __stpcpy_chk is ignored,
10157 optimize into __strcpy_chk. */
10158 fn
= built_in_decls
[BUILT_IN_STRCPY_CHK
];
10162 return build_function_call_expr (fn
, arglist
);
10165 if (! len
|| TREE_SIDE_EFFECTS (len
))
10168 /* If c_strlen returned something, but not a constant,
10169 transform __strcpy_chk into __memcpy_chk. */
10170 fn
= built_in_decls
[BUILT_IN_MEMCPY_CHK
];
10174 len
= size_binop (PLUS_EXPR
, len
, ssize_int (1));
10175 arglist
= build_tree_list (NULL_TREE
, size
);
10176 arglist
= tree_cons (NULL_TREE
, len
, arglist
);
10177 arglist
= tree_cons (NULL_TREE
, src
, arglist
);
10178 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
10179 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl
)),
10180 build_function_call_expr (fn
, arglist
));
10186 if (! tree_int_cst_lt (maxlen
, size
))
10190 arglist
= build_tree_list (NULL_TREE
, src
);
10191 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
10193 /* If __builtin_st{r,p}cpy_chk is used, assume st{r,p}cpy is available. */
10194 fn
= built_in_decls
[fcode
== BUILT_IN_STPCPY_CHK
10195 ? BUILT_IN_STPCPY
: BUILT_IN_STRCPY
];
10199 return build_function_call_expr (fn
, arglist
);
10202 /* Fold a call to the __strncpy_chk builtin.
10203 If MAXLEN is not NULL, it is maximum length passed as third argument. */
10206 fold_builtin_strncpy_chk (tree arglist
, tree maxlen
)
10208 tree dest
, src
, size
, len
, fn
;
10210 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
,
10211 INTEGER_TYPE
, VOID_TYPE
))
10214 dest
= TREE_VALUE (arglist
);
10215 src
= TREE_VALUE (TREE_CHAIN (arglist
));
10216 len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
10217 size
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist
))));
10219 if (! host_integerp (size
, 1))
10222 if (! integer_all_onesp (size
))
10224 if (! host_integerp (len
, 1))
10226 /* If LEN is not constant, try MAXLEN too.
10227 For MAXLEN only allow optimizing into non-_ocs function
10228 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
10229 if (maxlen
== NULL_TREE
|| ! host_integerp (maxlen
, 1))
10235 if (tree_int_cst_lt (size
, maxlen
))
10239 arglist
= build_tree_list (NULL_TREE
, len
);
10240 arglist
= tree_cons (NULL_TREE
, src
, arglist
);
10241 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
10243 /* If __builtin_strncpy_chk is used, assume strncpy is available. */
10244 fn
= built_in_decls
[BUILT_IN_STRNCPY
];
10248 return build_function_call_expr (fn
, arglist
);
10251 /* Fold a call to the __strcat_chk builtin FNDECL with ARGLIST. */
10254 fold_builtin_strcat_chk (tree fndecl
, tree arglist
)
10256 tree dest
, src
, size
, fn
;
10259 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
,
10263 dest
= TREE_VALUE (arglist
);
10264 src
= TREE_VALUE (TREE_CHAIN (arglist
));
10265 size
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
10267 p
= c_getstr (src
);
10268 /* If the SRC parameter is "", return DEST. */
10269 if (p
&& *p
== '\0')
10270 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl
)), dest
, src
);
10272 if (! host_integerp (size
, 1) || ! integer_all_onesp (size
))
10275 arglist
= build_tree_list (NULL_TREE
, src
);
10276 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
10278 /* If __builtin_strcat_chk is used, assume strcat is available. */
10279 fn
= built_in_decls
[BUILT_IN_STRCAT
];
10283 return build_function_call_expr (fn
, arglist
);
10286 /* Fold a call to the __strncat_chk builtin EXP. */
10289 fold_builtin_strncat_chk (tree fndecl
, tree arglist
)
10291 tree dest
, src
, size
, len
, fn
;
10294 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
,
10295 INTEGER_TYPE
, VOID_TYPE
))
10298 dest
= TREE_VALUE (arglist
);
10299 src
= TREE_VALUE (TREE_CHAIN (arglist
));
10300 len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
10301 size
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist
))));
10303 p
= c_getstr (src
);
10304 /* If the SRC parameter is "" or if LEN is 0, return DEST. */
10305 if (p
&& *p
== '\0')
10306 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl
)), dest
, len
);
10307 else if (integer_zerop (len
))
10308 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl
)), dest
, src
);
10310 if (! host_integerp (size
, 1))
10313 if (! integer_all_onesp (size
))
10315 tree src_len
= c_strlen (src
, 1);
10317 && host_integerp (src_len
, 1)
10318 && host_integerp (len
, 1)
10319 && ! tree_int_cst_lt (len
, src_len
))
10321 /* If LEN >= strlen (SRC), optimize into __strcat_chk. */
10322 fn
= built_in_decls
[BUILT_IN_STRCAT_CHK
];
10326 arglist
= build_tree_list (NULL_TREE
, size
);
10327 arglist
= tree_cons (NULL_TREE
, src
, arglist
);
10328 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
10329 return build_function_call_expr (fn
, arglist
);
10334 arglist
= build_tree_list (NULL_TREE
, len
);
10335 arglist
= tree_cons (NULL_TREE
, src
, arglist
);
10336 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
10338 /* If __builtin_strncat_chk is used, assume strncat is available. */
10339 fn
= built_in_decls
[BUILT_IN_STRNCAT
];
10343 return build_function_call_expr (fn
, arglist
);
10346 /* Fold a call to __{,v}sprintf_chk with argument list ARGLIST. Return 0 if
10347 a normal call should be emitted rather than expanding the function
10348 inline. FCODE is either BUILT_IN_SPRINTF_CHK or BUILT_IN_VSPRINTF_CHK. */
10351 fold_builtin_sprintf_chk (tree arglist
, enum built_in_function fcode
)
10353 tree dest
, size
, len
, fn
, fmt
, flag
;
10354 const char *fmt_str
;
10356 /* Verify the required arguments in the original call. */
10359 dest
= TREE_VALUE (arglist
);
10360 if (! POINTER_TYPE_P (TREE_TYPE (dest
)))
10362 arglist
= TREE_CHAIN (arglist
);
10365 flag
= TREE_VALUE (arglist
);
10366 if (TREE_CODE (TREE_TYPE (flag
)) != INTEGER_TYPE
)
10368 arglist
= TREE_CHAIN (arglist
);
10371 size
= TREE_VALUE (arglist
);
10372 if (TREE_CODE (TREE_TYPE (size
)) != INTEGER_TYPE
)
10374 arglist
= TREE_CHAIN (arglist
);
10377 fmt
= TREE_VALUE (arglist
);
10378 if (! POINTER_TYPE_P (TREE_TYPE (fmt
)))
10380 arglist
= TREE_CHAIN (arglist
);
10382 if (! host_integerp (size
, 1))
10387 if (!init_target_chars())
10390 /* Check whether the format is a literal string constant. */
10391 fmt_str
= c_getstr (fmt
);
10392 if (fmt_str
!= NULL
)
10394 /* If the format doesn't contain % args or %%, we know the size. */
10395 if (strchr (fmt_str
, target_percent
) == 0)
10397 if (fcode
!= BUILT_IN_SPRINTF_CHK
|| arglist
== NULL_TREE
)
10398 len
= build_int_cstu (size_type_node
, strlen (fmt_str
));
10400 /* If the format is "%s" and first ... argument is a string literal,
10401 we know the size too. */
10402 else if (fcode
== BUILT_IN_SPRINTF_CHK
&& strcmp (fmt_str
, target_percent_s
) == 0)
10406 if (arglist
&& !TREE_CHAIN (arglist
))
10408 arg
= TREE_VALUE (arglist
);
10409 if (POINTER_TYPE_P (TREE_TYPE (arg
)))
10411 len
= c_strlen (arg
, 1);
10412 if (! len
|| ! host_integerp (len
, 1))
10419 if (! integer_all_onesp (size
))
10421 if (! len
|| ! tree_int_cst_lt (len
, size
))
10425 /* Only convert __{,v}sprintf_chk to {,v}sprintf if flag is 0
10426 or if format doesn't contain % chars or is "%s". */
10427 if (! integer_zerop (flag
))
10429 if (fmt_str
== NULL
)
10431 if (strchr (fmt_str
, target_percent
) != NULL
&& strcmp (fmt_str
, target_percent_s
))
10435 arglist
= tree_cons (NULL_TREE
, fmt
, arglist
);
10436 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
10438 /* If __builtin_{,v}sprintf_chk is used, assume {,v}sprintf is available. */
10439 fn
= built_in_decls
[fcode
== BUILT_IN_VSPRINTF_CHK
10440 ? BUILT_IN_VSPRINTF
: BUILT_IN_SPRINTF
];
10444 return build_function_call_expr (fn
, arglist
);
10447 /* Fold a call to {,v}snprintf with argument list ARGLIST. Return 0 if
10448 a normal call should be emitted rather than expanding the function
10449 inline. FCODE is either BUILT_IN_SNPRINTF_CHK or
10450 BUILT_IN_VSNPRINTF_CHK. If MAXLEN is not NULL, it is maximum length
10451 passed as second argument. */
10454 fold_builtin_snprintf_chk (tree arglist
, tree maxlen
,
10455 enum built_in_function fcode
)
10457 tree dest
, size
, len
, fn
, fmt
, flag
;
10458 const char *fmt_str
;
10460 /* Verify the required arguments in the original call. */
10463 dest
= TREE_VALUE (arglist
);
10464 if (! POINTER_TYPE_P (TREE_TYPE (dest
)))
10466 arglist
= TREE_CHAIN (arglist
);
10469 len
= TREE_VALUE (arglist
);
10470 if (TREE_CODE (TREE_TYPE (len
)) != INTEGER_TYPE
)
10472 arglist
= TREE_CHAIN (arglist
);
10475 flag
= TREE_VALUE (arglist
);
10476 if (TREE_CODE (TREE_TYPE (len
)) != INTEGER_TYPE
)
10478 arglist
= TREE_CHAIN (arglist
);
10481 size
= TREE_VALUE (arglist
);
10482 if (TREE_CODE (TREE_TYPE (size
)) != INTEGER_TYPE
)
10484 arglist
= TREE_CHAIN (arglist
);
10487 fmt
= TREE_VALUE (arglist
);
10488 if (! POINTER_TYPE_P (TREE_TYPE (fmt
)))
10490 arglist
= TREE_CHAIN (arglist
);
10492 if (! host_integerp (size
, 1))
10495 if (! integer_all_onesp (size
))
10497 if (! host_integerp (len
, 1))
10499 /* If LEN is not constant, try MAXLEN too.
10500 For MAXLEN only allow optimizing into non-_ocs function
10501 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
10502 if (maxlen
== NULL_TREE
|| ! host_integerp (maxlen
, 1))
10508 if (tree_int_cst_lt (size
, maxlen
))
10512 if (!init_target_chars())
10515 /* Only convert __{,v}snprintf_chk to {,v}snprintf if flag is 0
10516 or if format doesn't contain % chars or is "%s". */
10517 if (! integer_zerop (flag
))
10519 fmt_str
= c_getstr (fmt
);
10520 if (fmt_str
== NULL
)
10522 if (strchr (fmt_str
, target_percent
) != NULL
&& strcmp (fmt_str
, target_percent_s
))
10526 arglist
= tree_cons (NULL_TREE
, fmt
, arglist
);
10527 arglist
= tree_cons (NULL_TREE
, len
, arglist
);
10528 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
10530 /* If __builtin_{,v}snprintf_chk is used, assume {,v}snprintf is
10532 fn
= built_in_decls
[fcode
== BUILT_IN_VSNPRINTF_CHK
10533 ? BUILT_IN_VSNPRINTF
: BUILT_IN_SNPRINTF
];
10537 return build_function_call_expr (fn
, arglist
);
10540 /* Fold a call to the {,v}printf{,_unlocked} and __{,v}printf_chk builtins.
10542 Return 0 if no simplification was possible, otherwise return the
10543 simplified form of the call as a tree. FCODE is the BUILT_IN_*
10544 code of the function to be simplified. */
10547 fold_builtin_printf (tree fndecl
, tree arglist
, bool ignore
,
10548 enum built_in_function fcode
)
10550 tree fmt
, fn
= NULL_TREE
, fn_putchar
, fn_puts
, arg
, call
;
10551 const char *fmt_str
= NULL
;
10553 /* If the return value is used, don't do the transformation. */
10557 /* Verify the required arguments in the original call. */
10558 if (fcode
== BUILT_IN_PRINTF_CHK
|| fcode
== BUILT_IN_VPRINTF_CHK
)
10564 flag
= TREE_VALUE (arglist
);
10565 if (TREE_CODE (TREE_TYPE (flag
)) != INTEGER_TYPE
10566 || TREE_SIDE_EFFECTS (flag
))
10568 arglist
= TREE_CHAIN (arglist
);
10573 fmt
= TREE_VALUE (arglist
);
10574 if (! POINTER_TYPE_P (TREE_TYPE (fmt
)))
10576 arglist
= TREE_CHAIN (arglist
);
10578 /* Check whether the format is a literal string constant. */
10579 fmt_str
= c_getstr (fmt
);
10580 if (fmt_str
== NULL
)
10583 if (fcode
== BUILT_IN_PRINTF_UNLOCKED
)
10585 /* If we're using an unlocked function, assume the other
10586 unlocked functions exist explicitly. */
10587 fn_putchar
= built_in_decls
[BUILT_IN_PUTCHAR_UNLOCKED
];
10588 fn_puts
= built_in_decls
[BUILT_IN_PUTS_UNLOCKED
];
10592 fn_putchar
= implicit_built_in_decls
[BUILT_IN_PUTCHAR
];
10593 fn_puts
= implicit_built_in_decls
[BUILT_IN_PUTS
];
10596 if (!init_target_chars())
10599 if (strcmp (fmt_str
, target_percent_s
) == 0 || strchr (fmt_str
, target_percent
) == NULL
)
10603 if (strcmp (fmt_str
, target_percent_s
) == 0)
10605 if (fcode
== BUILT_IN_VPRINTF
|| fcode
== BUILT_IN_VPRINTF_CHK
)
10609 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist
)))
10610 || TREE_CHAIN (arglist
))
10613 str
= c_getstr (TREE_VALUE (arglist
));
10619 /* The format specifier doesn't contain any '%' characters. */
10620 if (fcode
!= BUILT_IN_VPRINTF
&& fcode
!= BUILT_IN_VPRINTF_CHK
10626 /* If the string was "", printf does nothing. */
10627 if (str
[0] == '\0')
10628 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl
)), 0);
10630 /* If the string has length of 1, call putchar. */
10631 if (str
[1] == '\0')
10633 /* Given printf("c"), (where c is any one character,)
10634 convert "c"[0] to an int and pass that to the replacement
10636 arg
= build_int_cst (NULL_TREE
, str
[0]);
10637 arglist
= build_tree_list (NULL_TREE
, arg
);
10642 /* If the string was "string\n", call puts("string"). */
10643 size_t len
= strlen (str
);
10644 if ((unsigned char)str
[len
- 1] == target_newline
)
10646 /* Create a NUL-terminated string that's one char shorter
10647 than the original, stripping off the trailing '\n'. */
10648 char *newstr
= alloca (len
);
10649 memcpy (newstr
, str
, len
- 1);
10650 newstr
[len
- 1] = 0;
10652 arg
= build_string_literal (len
, newstr
);
10653 arglist
= build_tree_list (NULL_TREE
, arg
);
10657 /* We'd like to arrange to call fputs(string,stdout) here,
10658 but we need stdout and don't have a way to get it yet. */
10663 /* The other optimizations can be done only on the non-va_list variants. */
10664 else if (fcode
== BUILT_IN_VPRINTF
|| fcode
== BUILT_IN_VPRINTF_CHK
)
10667 /* If the format specifier was "%s\n", call __builtin_puts(arg). */
10668 else if (strcmp (fmt_str
, target_percent_s_newline
) == 0)
10671 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist
)))
10672 || TREE_CHAIN (arglist
))
10677 /* If the format specifier was "%c", call __builtin_putchar(arg). */
10678 else if (strcmp (fmt_str
, target_percent_c
) == 0)
10681 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist
))) != INTEGER_TYPE
10682 || TREE_CHAIN (arglist
))
10690 call
= build_function_call_expr (fn
, arglist
);
10691 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl
)), call
);
10694 /* Fold a call to the {,v}fprintf{,_unlocked} and __{,v}printf_chk builtins.
10696 Return 0 if no simplification was possible, otherwise return the
10697 simplified form of the call as a tree. FCODE is the BUILT_IN_*
10698 code of the function to be simplified. */
10701 fold_builtin_fprintf (tree fndecl
, tree arglist
, bool ignore
,
10702 enum built_in_function fcode
)
10704 tree fp
, fmt
, fn
= NULL_TREE
, fn_fputc
, fn_fputs
, arg
, call
;
10705 const char *fmt_str
= NULL
;
10707 /* If the return value is used, don't do the transformation. */
10711 /* Verify the required arguments in the original call. */
10714 fp
= TREE_VALUE (arglist
);
10715 if (! POINTER_TYPE_P (TREE_TYPE (fp
)))
10717 arglist
= TREE_CHAIN (arglist
);
10719 if (fcode
== BUILT_IN_FPRINTF_CHK
|| fcode
== BUILT_IN_VFPRINTF_CHK
)
10725 flag
= TREE_VALUE (arglist
);
10726 if (TREE_CODE (TREE_TYPE (flag
)) != INTEGER_TYPE
10727 || TREE_SIDE_EFFECTS (flag
))
10729 arglist
= TREE_CHAIN (arglist
);
10734 fmt
= TREE_VALUE (arglist
);
10735 if (! POINTER_TYPE_P (TREE_TYPE (fmt
)))
10737 arglist
= TREE_CHAIN (arglist
);
10739 /* Check whether the format is a literal string constant. */
10740 fmt_str
= c_getstr (fmt
);
10741 if (fmt_str
== NULL
)
10744 if (fcode
== BUILT_IN_FPRINTF_UNLOCKED
)
10746 /* If we're using an unlocked function, assume the other
10747 unlocked functions exist explicitly. */
10748 fn_fputc
= built_in_decls
[BUILT_IN_FPUTC_UNLOCKED
];
10749 fn_fputs
= built_in_decls
[BUILT_IN_FPUTS_UNLOCKED
];
10753 fn_fputc
= implicit_built_in_decls
[BUILT_IN_FPUTC
];
10754 fn_fputs
= implicit_built_in_decls
[BUILT_IN_FPUTS
];
10757 if (!init_target_chars())
10760 /* If the format doesn't contain % args or %%, use strcpy. */
10761 if (strchr (fmt_str
, target_percent
) == NULL
)
10763 if (fcode
!= BUILT_IN_VFPRINTF
&& fcode
!= BUILT_IN_VFPRINTF_CHK
10767 /* If the format specifier was "", fprintf does nothing. */
10768 if (fmt_str
[0] == '\0')
10770 /* If FP has side-effects, just wait until gimplification is
10772 if (TREE_SIDE_EFFECTS (fp
))
10775 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl
)), 0);
10778 /* When "string" doesn't contain %, replace all cases of
10779 fprintf (fp, string) with fputs (string, fp). The fputs
10780 builtin will take care of special cases like length == 1. */
10781 arglist
= build_tree_list (NULL_TREE
, fp
);
10782 arglist
= tree_cons (NULL_TREE
, fmt
, arglist
);
10786 /* The other optimizations can be done only on the non-va_list variants. */
10787 else if (fcode
== BUILT_IN_VFPRINTF
|| fcode
== BUILT_IN_VFPRINTF_CHK
)
10790 /* If the format specifier was "%s", call __builtin_fputs (arg, fp). */
10791 else if (strcmp (fmt_str
, target_percent_s
) == 0)
10794 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist
)))
10795 || TREE_CHAIN (arglist
))
10797 arg
= TREE_VALUE (arglist
);
10798 arglist
= build_tree_list (NULL_TREE
, fp
);
10799 arglist
= tree_cons (NULL_TREE
, arg
, arglist
);
10803 /* If the format specifier was "%c", call __builtin_fputc (arg, fp). */
10804 else if (strcmp (fmt_str
, target_percent_c
) == 0)
10807 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist
))) != INTEGER_TYPE
10808 || TREE_CHAIN (arglist
))
10810 arg
= TREE_VALUE (arglist
);
10811 arglist
= build_tree_list (NULL_TREE
, fp
);
10812 arglist
= tree_cons (NULL_TREE
, arg
, arglist
);
10819 call
= build_function_call_expr (fn
, arglist
);
10820 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl
)), call
);
10823 /* Initialize format string characters in the target charset. */
10826 init_target_chars (void)
10831 target_newline
= lang_hooks
.to_target_charset ('\n');
10832 target_percent
= lang_hooks
.to_target_charset ('%');
10833 target_c
= lang_hooks
.to_target_charset ('c');
10834 target_s
= lang_hooks
.to_target_charset ('s');
10835 if (target_newline
== 0 || target_percent
== 0 || target_c
== 0
10839 target_percent_c
[0] = target_percent
;
10840 target_percent_c
[1] = target_c
;
10841 target_percent_c
[2] = '\0';
10843 target_percent_s
[0] = target_percent
;
10844 target_percent_s
[1] = target_s
;
10845 target_percent_s
[2] = '\0';
10847 target_percent_s_newline
[0] = target_percent
;
10848 target_percent_s_newline
[1] = target_s
;
10849 target_percent_s_newline
[2] = target_newline
;
10850 target_percent_s_newline
[3] = '\0';