1 /* Expand builtin functions.
2 Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3 2000, 2001, 2002, 2003, 2004, 2005 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_int_roundingfn (tree
, rtx
, rtx
);
98 static rtx
expand_builtin_args_info (tree
);
99 static rtx
expand_builtin_next_arg (void);
100 static rtx
expand_builtin_va_start (tree
);
101 static rtx
expand_builtin_va_end (tree
);
102 static rtx
expand_builtin_va_copy (tree
);
103 static rtx
expand_builtin_memcmp (tree
, tree
, rtx
, enum machine_mode
);
104 static rtx
expand_builtin_strcmp (tree
, rtx
, enum machine_mode
);
105 static rtx
expand_builtin_strncmp (tree
, rtx
, enum machine_mode
);
106 static rtx
builtin_memcpy_read_str (void *, HOST_WIDE_INT
, enum machine_mode
);
107 static rtx
expand_builtin_strcat (tree
, tree
, rtx
, enum machine_mode
);
108 static rtx
expand_builtin_strncat (tree
, rtx
, enum machine_mode
);
109 static rtx
expand_builtin_strspn (tree
, rtx
, enum machine_mode
);
110 static rtx
expand_builtin_strcspn (tree
, rtx
, enum machine_mode
);
111 static rtx
expand_builtin_memcpy (tree
, rtx
, enum machine_mode
);
112 static rtx
expand_builtin_mempcpy (tree
, tree
, rtx
, enum machine_mode
, int);
113 static rtx
expand_builtin_memmove (tree
, tree
, rtx
, enum machine_mode
, tree
);
114 static rtx
expand_builtin_bcopy (tree
);
115 static rtx
expand_builtin_strcpy (tree
, tree
, rtx
, enum machine_mode
);
116 static rtx
expand_builtin_stpcpy (tree
, rtx
, enum machine_mode
);
117 static rtx
builtin_strncpy_read_str (void *, HOST_WIDE_INT
, enum machine_mode
);
118 static rtx
expand_builtin_strncpy (tree
, rtx
, enum machine_mode
);
119 static rtx
builtin_memset_read_str (void *, HOST_WIDE_INT
, enum machine_mode
);
120 static rtx
builtin_memset_gen_str (void *, HOST_WIDE_INT
, enum machine_mode
);
121 static rtx
expand_builtin_memset (tree
, rtx
, enum machine_mode
, tree
);
122 static rtx
expand_builtin_bzero (tree
);
123 static rtx
expand_builtin_strlen (tree
, rtx
, enum machine_mode
);
124 static rtx
expand_builtin_strstr (tree
, tree
, rtx
, enum machine_mode
);
125 static rtx
expand_builtin_strpbrk (tree
, tree
, rtx
, enum machine_mode
);
126 static rtx
expand_builtin_strchr (tree
, tree
, rtx
, enum machine_mode
);
127 static rtx
expand_builtin_strrchr (tree
, tree
, rtx
, enum machine_mode
);
128 static rtx
expand_builtin_alloca (tree
, rtx
);
129 static rtx
expand_builtin_unop (enum machine_mode
, tree
, rtx
, rtx
, optab
);
130 static rtx
expand_builtin_frame_address (tree
, tree
);
131 static rtx
expand_builtin_fputs (tree
, rtx
, bool);
132 static rtx
expand_builtin_printf (tree
, rtx
, enum machine_mode
, bool);
133 static rtx
expand_builtin_fprintf (tree
, rtx
, enum machine_mode
, bool);
134 static rtx
expand_builtin_sprintf (tree
, rtx
, enum machine_mode
);
135 static tree
stabilize_va_list (tree
, int);
136 static rtx
expand_builtin_expect (tree
, rtx
);
137 static tree
fold_builtin_constant_p (tree
);
138 static tree
fold_builtin_classify_type (tree
);
139 static tree
fold_builtin_strlen (tree
);
140 static tree
fold_builtin_inf (tree
, int);
141 static tree
fold_builtin_nan (tree
, tree
, int);
142 static int validate_arglist (tree
, ...);
143 static bool integer_valued_real_p (tree
);
144 static tree
fold_trunc_transparent_mathfn (tree
, tree
);
145 static bool readonly_data_expr (tree
);
146 static rtx
expand_builtin_fabs (tree
, rtx
, rtx
);
147 static rtx
expand_builtin_signbit (tree
, rtx
);
148 static tree
fold_builtin_cabs (tree
, tree
);
149 static tree
fold_builtin_sqrt (tree
, tree
);
150 static tree
fold_builtin_cbrt (tree
, tree
);
151 static tree
fold_builtin_pow (tree
, tree
, tree
);
152 static tree
fold_builtin_powi (tree
, tree
, tree
);
153 static tree
fold_builtin_sin (tree
);
154 static tree
fold_builtin_cos (tree
, tree
, tree
);
155 static tree
fold_builtin_tan (tree
);
156 static tree
fold_builtin_atan (tree
, tree
);
157 static tree
fold_builtin_trunc (tree
, tree
);
158 static tree
fold_builtin_floor (tree
, tree
);
159 static tree
fold_builtin_ceil (tree
, tree
);
160 static tree
fold_builtin_round (tree
, tree
);
161 static tree
fold_builtin_int_roundingfn (tree
, tree
);
162 static tree
fold_builtin_bitop (tree
, tree
);
163 static tree
fold_builtin_memcpy (tree
, tree
);
164 static tree
fold_builtin_mempcpy (tree
, tree
, int);
165 static tree
fold_builtin_memmove (tree
, tree
);
166 static tree
fold_builtin_strchr (tree
, tree
);
167 static tree
fold_builtin_memcmp (tree
);
168 static tree
fold_builtin_strcmp (tree
);
169 static tree
fold_builtin_strncmp (tree
);
170 static tree
fold_builtin_signbit (tree
, tree
);
171 static tree
fold_builtin_copysign (tree
, tree
, tree
);
172 static tree
fold_builtin_isascii (tree
);
173 static tree
fold_builtin_toascii (tree
);
174 static tree
fold_builtin_isdigit (tree
);
175 static tree
fold_builtin_fabs (tree
, tree
);
176 static tree
fold_builtin_abs (tree
, tree
);
177 static tree
fold_builtin_unordered_cmp (tree
, tree
, enum tree_code
,
179 static tree
fold_builtin_1 (tree
, tree
, bool);
181 static tree
fold_builtin_strpbrk (tree
, tree
);
182 static tree
fold_builtin_strstr (tree
, tree
);
183 static tree
fold_builtin_strrchr (tree
, tree
);
184 static tree
fold_builtin_strcat (tree
);
185 static tree
fold_builtin_strncat (tree
);
186 static tree
fold_builtin_strspn (tree
);
187 static tree
fold_builtin_strcspn (tree
);
188 static tree
fold_builtin_sprintf (tree
, int);
190 static rtx
expand_builtin_object_size (tree
);
191 static rtx
expand_builtin_memory_chk (tree
, rtx
, enum machine_mode
,
192 enum built_in_function
);
193 static void maybe_emit_chk_warning (tree
, enum built_in_function
);
194 static void maybe_emit_sprintf_chk_warning (tree
, enum built_in_function
);
195 static tree
fold_builtin_object_size (tree
);
196 static tree
fold_builtin_strcat_chk (tree
, tree
);
197 static tree
fold_builtin_strncat_chk (tree
, tree
);
198 static tree
fold_builtin_sprintf_chk (tree
, enum built_in_function
);
199 static tree
fold_builtin_printf (tree
, tree
, bool, enum built_in_function
);
200 static tree
fold_builtin_fprintf (tree
, tree
, bool, enum built_in_function
);
202 /* Return true if NODE should be considered for inline expansion regardless
203 of the optimization level. This means whenever a function is invoked with
204 its "internal" name, which normally contains the prefix "__builtin". */
206 static bool called_as_built_in (tree node
)
208 const char *name
= IDENTIFIER_POINTER (DECL_NAME (node
));
209 if (strncmp (name
, "__builtin_", 10) == 0)
211 if (strncmp (name
, "__sync_", 7) == 0)
216 /* Return the alignment in bits of EXP, a pointer valued expression.
217 But don't return more than MAX_ALIGN no matter what.
218 The alignment returned is, by default, the alignment of the thing that
219 EXP points to. If it is not a POINTER_TYPE, 0 is returned.
221 Otherwise, look at the expression to see if we can do better, i.e., if the
222 expression is actually pointing at an object whose alignment is tighter. */
225 get_pointer_alignment (tree exp
, unsigned int max_align
)
227 unsigned int align
, inner
;
229 if (! POINTER_TYPE_P (TREE_TYPE (exp
)))
232 align
= TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp
)));
233 align
= MIN (align
, max_align
);
237 switch (TREE_CODE (exp
))
241 case NON_LVALUE_EXPR
:
242 exp
= TREE_OPERAND (exp
, 0);
243 if (! POINTER_TYPE_P (TREE_TYPE (exp
)))
246 inner
= TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp
)));
247 align
= MIN (inner
, max_align
);
251 /* If sum of pointer + int, restrict our maximum alignment to that
252 imposed by the integer. If not, we can't do any better than
254 if (! host_integerp (TREE_OPERAND (exp
, 1), 1))
257 while (((tree_low_cst (TREE_OPERAND (exp
, 1), 1))
258 & (max_align
/ BITS_PER_UNIT
- 1))
262 exp
= TREE_OPERAND (exp
, 0);
266 /* See what we are pointing at and look at its alignment. */
267 exp
= TREE_OPERAND (exp
, 0);
268 if (TREE_CODE (exp
) == FUNCTION_DECL
)
269 align
= FUNCTION_BOUNDARY
;
270 else if (DECL_P (exp
))
271 align
= DECL_ALIGN (exp
);
272 #ifdef CONSTANT_ALIGNMENT
273 else if (CONSTANT_CLASS_P (exp
))
274 align
= CONSTANT_ALIGNMENT (exp
, align
);
276 return MIN (align
, max_align
);
284 /* Compute the length of a C string. TREE_STRING_LENGTH is not the right
285 way, because it could contain a zero byte in the middle.
286 TREE_STRING_LENGTH is the size of the character array, not the string.
288 ONLY_VALUE should be nonzero if the result is not going to be emitted
289 into the instruction stream and zero if it is going to be expanded.
290 E.g. with i++ ? "foo" : "bar", if ONLY_VALUE is nonzero, constant 3
291 is returned, otherwise NULL, since
292 len = c_strlen (src, 1); if (len) expand_expr (len, ...); would not
293 evaluate the side-effects.
295 The value returned is of type `ssizetype'.
297 Unfortunately, string_constant can't access the values of const char
298 arrays with initializers, so neither can we do so here. */
301 c_strlen (tree src
, int only_value
)
304 HOST_WIDE_INT offset
;
309 if (TREE_CODE (src
) == COND_EXPR
310 && (only_value
|| !TREE_SIDE_EFFECTS (TREE_OPERAND (src
, 0))))
314 len1
= c_strlen (TREE_OPERAND (src
, 1), only_value
);
315 len2
= c_strlen (TREE_OPERAND (src
, 2), only_value
);
316 if (tree_int_cst_equal (len1
, len2
))
320 if (TREE_CODE (src
) == COMPOUND_EXPR
321 && (only_value
|| !TREE_SIDE_EFFECTS (TREE_OPERAND (src
, 0))))
322 return c_strlen (TREE_OPERAND (src
, 1), only_value
);
324 src
= string_constant (src
, &offset_node
);
328 max
= TREE_STRING_LENGTH (src
) - 1;
329 ptr
= TREE_STRING_POINTER (src
);
331 if (offset_node
&& TREE_CODE (offset_node
) != INTEGER_CST
)
333 /* If the string has an internal zero byte (e.g., "foo\0bar"), we can't
334 compute the offset to the following null if we don't know where to
335 start searching for it. */
338 for (i
= 0; i
< max
; i
++)
342 /* We don't know the starting offset, but we do know that the string
343 has no internal zero bytes. We can assume that the offset falls
344 within the bounds of the string; otherwise, the programmer deserves
345 what he gets. Subtract the offset from the length of the string,
346 and return that. This would perhaps not be valid if we were dealing
347 with named arrays in addition to literal string constants. */
349 return size_diffop (size_int (max
), offset_node
);
352 /* We have a known offset into the string. Start searching there for
353 a null character if we can represent it as a single HOST_WIDE_INT. */
354 if (offset_node
== 0)
356 else if (! host_integerp (offset_node
, 0))
359 offset
= tree_low_cst (offset_node
, 0);
361 /* If the offset is known to be out of bounds, warn, and call strlen at
363 if (offset
< 0 || offset
> max
)
365 warning (0, "offset outside bounds of constant string");
369 /* Use strlen to search for the first zero byte. Since any strings
370 constructed with build_string will have nulls appended, we win even
371 if we get handed something like (char[4])"abcd".
373 Since OFFSET is our starting index into the string, no further
374 calculation is needed. */
375 return ssize_int (strlen (ptr
+ offset
));
378 /* Return a char pointer for a C string if it is a string constant
379 or sum of string constant and integer constant. */
386 src
= string_constant (src
, &offset_node
);
390 if (offset_node
== 0)
391 return TREE_STRING_POINTER (src
);
392 else if (!host_integerp (offset_node
, 1)
393 || compare_tree_int (offset_node
, TREE_STRING_LENGTH (src
) - 1) > 0)
396 return TREE_STRING_POINTER (src
) + tree_low_cst (offset_node
, 1);
399 /* Return a CONST_INT or CONST_DOUBLE corresponding to target reading
400 GET_MODE_BITSIZE (MODE) bits from string constant STR. */
403 c_readstr (const char *str
, enum machine_mode mode
)
409 gcc_assert (GET_MODE_CLASS (mode
) == MODE_INT
);
414 for (i
= 0; i
< GET_MODE_SIZE (mode
); i
++)
417 if (WORDS_BIG_ENDIAN
)
418 j
= GET_MODE_SIZE (mode
) - i
- 1;
419 if (BYTES_BIG_ENDIAN
!= WORDS_BIG_ENDIAN
420 && GET_MODE_SIZE (mode
) > UNITS_PER_WORD
)
421 j
= j
+ UNITS_PER_WORD
- 2 * (j
% UNITS_PER_WORD
) - 1;
423 gcc_assert (j
<= 2 * HOST_BITS_PER_WIDE_INT
);
426 ch
= (unsigned char) str
[i
];
427 c
[j
/ HOST_BITS_PER_WIDE_INT
] |= ch
<< (j
% HOST_BITS_PER_WIDE_INT
);
429 return immed_double_const (c
[0], c
[1], mode
);
432 /* Cast a target constant CST to target CHAR and if that value fits into
433 host char type, return zero and put that value into variable pointed to by
437 target_char_cast (tree cst
, char *p
)
439 unsigned HOST_WIDE_INT val
, hostval
;
441 if (!host_integerp (cst
, 1)
442 || CHAR_TYPE_SIZE
> HOST_BITS_PER_WIDE_INT
)
445 val
= tree_low_cst (cst
, 1);
446 if (CHAR_TYPE_SIZE
< HOST_BITS_PER_WIDE_INT
)
447 val
&= (((unsigned HOST_WIDE_INT
) 1) << CHAR_TYPE_SIZE
) - 1;
450 if (HOST_BITS_PER_CHAR
< HOST_BITS_PER_WIDE_INT
)
451 hostval
&= (((unsigned HOST_WIDE_INT
) 1) << HOST_BITS_PER_CHAR
) - 1;
460 /* Similar to save_expr, but assumes that arbitrary code is not executed
461 in between the multiple evaluations. In particular, we assume that a
462 non-addressable local variable will not be modified. */
465 builtin_save_expr (tree exp
)
467 if (TREE_ADDRESSABLE (exp
) == 0
468 && (TREE_CODE (exp
) == PARM_DECL
469 || (TREE_CODE (exp
) == VAR_DECL
&& !TREE_STATIC (exp
))))
472 return save_expr (exp
);
475 /* Given TEM, a pointer to a stack frame, follow the dynamic chain COUNT
476 times to get the address of either a higher stack frame, or a return
477 address located within it (depending on FNDECL_CODE). */
480 expand_builtin_return_addr (enum built_in_function fndecl_code
, int count
)
484 #ifdef INITIAL_FRAME_ADDRESS_RTX
485 rtx tem
= INITIAL_FRAME_ADDRESS_RTX
;
489 /* For a zero count, we don't care what frame address we return, so frame
490 pointer elimination is OK, and using the soft frame pointer is OK.
491 For a non-zero count, we require a stable offset from the current frame
492 pointer to the previous one, so we must use the hard frame pointer, and
493 we must disable frame pointer elimination. */
495 tem
= frame_pointer_rtx
;
498 tem
= hard_frame_pointer_rtx
;
500 /* Tell reload not to eliminate the frame pointer. */
501 current_function_accesses_prior_frames
= 1;
505 /* Some machines need special handling before we can access
506 arbitrary frames. For example, on the sparc, we must first flush
507 all register windows to the stack. */
508 #ifdef SETUP_FRAME_ADDRESSES
510 SETUP_FRAME_ADDRESSES ();
513 /* On the sparc, the return address is not in the frame, it is in a
514 register. There is no way to access it off of the current frame
515 pointer, but it can be accessed off the previous frame pointer by
516 reading the value from the register window save area. */
517 #ifdef RETURN_ADDR_IN_PREVIOUS_FRAME
518 if (fndecl_code
== BUILT_IN_RETURN_ADDRESS
)
522 /* Scan back COUNT frames to the specified frame. */
523 for (i
= 0; i
< count
; i
++)
525 /* Assume the dynamic chain pointer is in the word that the
526 frame address points to, unless otherwise specified. */
527 #ifdef DYNAMIC_CHAIN_ADDRESS
528 tem
= DYNAMIC_CHAIN_ADDRESS (tem
);
530 tem
= memory_address (Pmode
, tem
);
531 tem
= gen_frame_mem (Pmode
, tem
);
532 tem
= copy_to_reg (tem
);
535 /* For __builtin_frame_address, return what we've got. */
536 if (fndecl_code
== BUILT_IN_FRAME_ADDRESS
)
539 /* For __builtin_return_address, Get the return address from that
541 #ifdef RETURN_ADDR_RTX
542 tem
= RETURN_ADDR_RTX (count
, tem
);
544 tem
= memory_address (Pmode
,
545 plus_constant (tem
, GET_MODE_SIZE (Pmode
)));
546 tem
= gen_frame_mem (Pmode
, tem
);
551 /* Alias set used for setjmp buffer. */
552 static HOST_WIDE_INT setjmp_alias_set
= -1;
554 /* Construct the leading half of a __builtin_setjmp call. Control will
555 return to RECEIVER_LABEL. This is used directly by sjlj exception
559 expand_builtin_setjmp_setup (rtx buf_addr
, rtx receiver_label
)
561 enum machine_mode sa_mode
= STACK_SAVEAREA_MODE (SAVE_NONLOCAL
);
565 if (setjmp_alias_set
== -1)
566 setjmp_alias_set
= new_alias_set ();
568 buf_addr
= convert_memory_address (Pmode
, buf_addr
);
570 buf_addr
= force_reg (Pmode
, force_operand (buf_addr
, NULL_RTX
));
572 /* We store the frame pointer and the address of receiver_label in
573 the buffer and use the rest of it for the stack save area, which
574 is machine-dependent. */
576 mem
= gen_rtx_MEM (Pmode
, buf_addr
);
577 set_mem_alias_set (mem
, setjmp_alias_set
);
578 emit_move_insn (mem
, targetm
.builtin_setjmp_frame_value ());
580 mem
= gen_rtx_MEM (Pmode
, plus_constant (buf_addr
, GET_MODE_SIZE (Pmode
))),
581 set_mem_alias_set (mem
, setjmp_alias_set
);
583 emit_move_insn (validize_mem (mem
),
584 force_reg (Pmode
, gen_rtx_LABEL_REF (Pmode
, receiver_label
)));
586 stack_save
= gen_rtx_MEM (sa_mode
,
587 plus_constant (buf_addr
,
588 2 * GET_MODE_SIZE (Pmode
)));
589 set_mem_alias_set (stack_save
, setjmp_alias_set
);
590 emit_stack_save (SAVE_NONLOCAL
, &stack_save
, NULL_RTX
);
592 /* If there is further processing to do, do it. */
593 #ifdef HAVE_builtin_setjmp_setup
594 if (HAVE_builtin_setjmp_setup
)
595 emit_insn (gen_builtin_setjmp_setup (buf_addr
));
598 /* Tell optimize_save_area_alloca that extra work is going to
599 need to go on during alloca. */
600 current_function_calls_setjmp
= 1;
602 /* Set this so all the registers get saved in our frame; we need to be
603 able to copy the saved values for any registers from frames we unwind. */
604 current_function_has_nonlocal_label
= 1;
607 /* Construct the trailing part of a __builtin_setjmp call.
608 This is used directly by sjlj exception handling code. */
611 expand_builtin_setjmp_receiver (rtx receiver_label ATTRIBUTE_UNUSED
)
613 /* Clobber the FP when we get here, so we have to make sure it's
614 marked as used by this function. */
615 emit_insn (gen_rtx_USE (VOIDmode
, hard_frame_pointer_rtx
));
617 /* Mark the static chain as clobbered here so life information
618 doesn't get messed up for it. */
619 emit_insn (gen_rtx_CLOBBER (VOIDmode
, static_chain_rtx
));
621 /* Now put in the code to restore the frame pointer, and argument
622 pointer, if needed. */
623 #ifdef HAVE_nonlocal_goto
624 if (! HAVE_nonlocal_goto
)
626 emit_move_insn (virtual_stack_vars_rtx
, hard_frame_pointer_rtx
);
628 #if ARG_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
629 if (fixed_regs
[ARG_POINTER_REGNUM
])
631 #ifdef ELIMINABLE_REGS
633 static const struct elims
{const int from
, to
;} elim_regs
[] = ELIMINABLE_REGS
;
635 for (i
= 0; i
< ARRAY_SIZE (elim_regs
); i
++)
636 if (elim_regs
[i
].from
== ARG_POINTER_REGNUM
637 && elim_regs
[i
].to
== HARD_FRAME_POINTER_REGNUM
)
640 if (i
== ARRAY_SIZE (elim_regs
))
643 /* Now restore our arg pointer from the address at which it
644 was saved in our stack frame. */
645 emit_move_insn (virtual_incoming_args_rtx
,
646 copy_to_reg (get_arg_pointer_save_area (cfun
)));
651 #ifdef HAVE_builtin_setjmp_receiver
652 if (HAVE_builtin_setjmp_receiver
)
653 emit_insn (gen_builtin_setjmp_receiver (receiver_label
));
656 #ifdef HAVE_nonlocal_goto_receiver
657 if (HAVE_nonlocal_goto_receiver
)
658 emit_insn (gen_nonlocal_goto_receiver ());
663 /* @@@ This is a kludge. Not all machine descriptions define a blockage
664 insn, but we must not allow the code we just generated to be reordered
665 by scheduling. Specifically, the update of the frame pointer must
666 happen immediately, not later. So emit an ASM_INPUT to act as blockage
668 emit_insn (gen_rtx_ASM_INPUT (VOIDmode
, ""));
671 /* __builtin_setjmp is passed a pointer to an array of five words (not
672 all will be used on all machines). It operates similarly to the C
673 library function of the same name, but is more efficient. Much of
674 the code below (and for longjmp) is copied from the handling of
677 NOTE: This is intended for use by GNAT and the exception handling
678 scheme in the compiler and will only work in the method used by
682 expand_builtin_setjmp (tree arglist
, rtx target
)
684 rtx buf_addr
, next_lab
, cont_lab
;
686 if (!validate_arglist (arglist
, POINTER_TYPE
, VOID_TYPE
))
689 if (target
== 0 || !REG_P (target
)
690 || REGNO (target
) < FIRST_PSEUDO_REGISTER
)
691 target
= gen_reg_rtx (TYPE_MODE (integer_type_node
));
693 buf_addr
= expand_expr (TREE_VALUE (arglist
), NULL_RTX
, VOIDmode
, 0);
695 next_lab
= gen_label_rtx ();
696 cont_lab
= gen_label_rtx ();
698 expand_builtin_setjmp_setup (buf_addr
, next_lab
);
700 /* Set TARGET to zero and branch to the continue label. Use emit_jump to
701 ensure that pending stack adjustments are flushed. */
702 emit_move_insn (target
, const0_rtx
);
703 emit_jump (cont_lab
);
705 emit_label (next_lab
);
707 expand_builtin_setjmp_receiver (next_lab
);
709 /* Set TARGET to one. */
710 emit_move_insn (target
, const1_rtx
);
711 emit_label (cont_lab
);
713 /* Tell flow about the strange goings on. Putting `next_lab' on
714 `nonlocal_goto_handler_labels' to indicates that function
715 calls may traverse the arc back to this label. */
717 current_function_has_nonlocal_label
= 1;
718 nonlocal_goto_handler_labels
719 = gen_rtx_EXPR_LIST (VOIDmode
, next_lab
, nonlocal_goto_handler_labels
);
724 /* __builtin_longjmp is passed a pointer to an array of five words (not
725 all will be used on all machines). It operates similarly to the C
726 library function of the same name, but is more efficient. Much of
727 the code below is copied from the handling of non-local gotos.
729 NOTE: This is intended for use by GNAT and the exception handling
730 scheme in the compiler and will only work in the method used by
734 expand_builtin_longjmp (rtx buf_addr
, rtx value
)
736 rtx fp
, lab
, stack
, insn
, last
;
737 enum machine_mode sa_mode
= STACK_SAVEAREA_MODE (SAVE_NONLOCAL
);
739 if (setjmp_alias_set
== -1)
740 setjmp_alias_set
= new_alias_set ();
742 buf_addr
= convert_memory_address (Pmode
, buf_addr
);
744 buf_addr
= force_reg (Pmode
, buf_addr
);
746 /* We used to store value in static_chain_rtx, but that fails if pointers
747 are smaller than integers. We instead require that the user must pass
748 a second argument of 1, because that is what builtin_setjmp will
749 return. This also makes EH slightly more efficient, since we are no
750 longer copying around a value that we don't care about. */
751 gcc_assert (value
== const1_rtx
);
753 last
= get_last_insn ();
754 #ifdef HAVE_builtin_longjmp
755 if (HAVE_builtin_longjmp
)
756 emit_insn (gen_builtin_longjmp (buf_addr
));
760 fp
= gen_rtx_MEM (Pmode
, buf_addr
);
761 lab
= gen_rtx_MEM (Pmode
, plus_constant (buf_addr
,
762 GET_MODE_SIZE (Pmode
)));
764 stack
= gen_rtx_MEM (sa_mode
, plus_constant (buf_addr
,
765 2 * GET_MODE_SIZE (Pmode
)));
766 set_mem_alias_set (fp
, setjmp_alias_set
);
767 set_mem_alias_set (lab
, setjmp_alias_set
);
768 set_mem_alias_set (stack
, setjmp_alias_set
);
770 /* Pick up FP, label, and SP from the block and jump. This code is
771 from expand_goto in stmt.c; see there for detailed comments. */
772 #if HAVE_nonlocal_goto
773 if (HAVE_nonlocal_goto
)
774 /* We have to pass a value to the nonlocal_goto pattern that will
775 get copied into the static_chain pointer, but it does not matter
776 what that value is, because builtin_setjmp does not use it. */
777 emit_insn (gen_nonlocal_goto (value
, lab
, stack
, fp
));
781 lab
= copy_to_reg (lab
);
783 emit_insn (gen_rtx_CLOBBER (VOIDmode
,
784 gen_rtx_MEM (BLKmode
,
785 gen_rtx_SCRATCH (VOIDmode
))));
786 emit_insn (gen_rtx_CLOBBER (VOIDmode
,
787 gen_rtx_MEM (BLKmode
,
788 hard_frame_pointer_rtx
)));
790 emit_move_insn (hard_frame_pointer_rtx
, fp
);
791 emit_stack_restore (SAVE_NONLOCAL
, stack
, NULL_RTX
);
793 emit_insn (gen_rtx_USE (VOIDmode
, hard_frame_pointer_rtx
));
794 emit_insn (gen_rtx_USE (VOIDmode
, stack_pointer_rtx
));
795 emit_indirect_jump (lab
);
799 /* Search backwards and mark the jump insn as a non-local goto.
800 Note that this precludes the use of __builtin_longjmp to a
801 __builtin_setjmp target in the same function. However, we've
802 already cautioned the user that these functions are for
803 internal exception handling use only. */
804 for (insn
= get_last_insn (); insn
; insn
= PREV_INSN (insn
))
806 gcc_assert (insn
!= last
);
810 REG_NOTES (insn
) = alloc_EXPR_LIST (REG_NON_LOCAL_GOTO
, const0_rtx
,
814 else if (CALL_P (insn
))
819 /* Expand a call to __builtin_nonlocal_goto. We're passed the target label
820 and the address of the save area. */
823 expand_builtin_nonlocal_goto (tree arglist
)
825 tree t_label
, t_save_area
;
826 rtx r_label
, r_save_area
, r_fp
, r_sp
, insn
;
828 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
831 t_label
= TREE_VALUE (arglist
);
832 arglist
= TREE_CHAIN (arglist
);
833 t_save_area
= TREE_VALUE (arglist
);
835 r_label
= expand_expr (t_label
, NULL_RTX
, VOIDmode
, 0);
836 r_label
= convert_memory_address (Pmode
, r_label
);
837 r_save_area
= expand_expr (t_save_area
, NULL_RTX
, VOIDmode
, 0);
838 r_save_area
= convert_memory_address (Pmode
, r_save_area
);
839 r_fp
= gen_rtx_MEM (Pmode
, r_save_area
);
840 r_sp
= gen_rtx_MEM (STACK_SAVEAREA_MODE (SAVE_NONLOCAL
),
841 plus_constant (r_save_area
, GET_MODE_SIZE (Pmode
)));
843 current_function_has_nonlocal_goto
= 1;
845 #if HAVE_nonlocal_goto
846 /* ??? We no longer need to pass the static chain value, afaik. */
847 if (HAVE_nonlocal_goto
)
848 emit_insn (gen_nonlocal_goto (const0_rtx
, r_label
, r_sp
, r_fp
));
852 r_label
= copy_to_reg (r_label
);
854 emit_insn (gen_rtx_CLOBBER (VOIDmode
,
855 gen_rtx_MEM (BLKmode
,
856 gen_rtx_SCRATCH (VOIDmode
))));
858 emit_insn (gen_rtx_CLOBBER (VOIDmode
,
859 gen_rtx_MEM (BLKmode
,
860 hard_frame_pointer_rtx
)));
862 /* Restore frame pointer for containing function.
863 This sets the actual hard register used for the frame pointer
864 to the location of the function's incoming static chain info.
865 The non-local goto handler will then adjust it to contain the
866 proper value and reload the argument pointer, if needed. */
867 emit_move_insn (hard_frame_pointer_rtx
, r_fp
);
868 emit_stack_restore (SAVE_NONLOCAL
, r_sp
, NULL_RTX
);
870 /* USE of hard_frame_pointer_rtx added for consistency;
871 not clear if really needed. */
872 emit_insn (gen_rtx_USE (VOIDmode
, hard_frame_pointer_rtx
));
873 emit_insn (gen_rtx_USE (VOIDmode
, stack_pointer_rtx
));
874 emit_indirect_jump (r_label
);
877 /* Search backwards to the jump insn and mark it as a
879 for (insn
= get_last_insn (); insn
; insn
= PREV_INSN (insn
))
883 REG_NOTES (insn
) = alloc_EXPR_LIST (REG_NON_LOCAL_GOTO
,
884 const0_rtx
, REG_NOTES (insn
));
887 else if (CALL_P (insn
))
894 /* __builtin_update_setjmp_buf is passed a pointer to an array of five words
895 (not all will be used on all machines) that was passed to __builtin_setjmp.
896 It updates the stack pointer in that block to correspond to the current
900 expand_builtin_update_setjmp_buf (rtx buf_addr
)
902 enum machine_mode sa_mode
= Pmode
;
906 #ifdef HAVE_save_stack_nonlocal
907 if (HAVE_save_stack_nonlocal
)
908 sa_mode
= insn_data
[(int) CODE_FOR_save_stack_nonlocal
].operand
[0].mode
;
910 #ifdef STACK_SAVEAREA_MODE
911 sa_mode
= STACK_SAVEAREA_MODE (SAVE_NONLOCAL
);
915 = gen_rtx_MEM (sa_mode
,
918 plus_constant (buf_addr
, 2 * GET_MODE_SIZE (Pmode
))));
922 emit_insn (gen_setjmp ());
925 emit_stack_save (SAVE_NONLOCAL
, &stack_save
, NULL_RTX
);
928 /* Expand a call to __builtin_prefetch. For a target that does not support
929 data prefetch, evaluate the memory address argument in case it has side
933 expand_builtin_prefetch (tree arglist
)
935 tree arg0
, arg1
, arg2
;
938 if (!validate_arglist (arglist
, POINTER_TYPE
, 0))
941 arg0
= TREE_VALUE (arglist
);
942 /* Arguments 1 and 2 are optional; argument 1 (read/write) defaults to
943 zero (read) and argument 2 (locality) defaults to 3 (high degree of
945 if (TREE_CHAIN (arglist
))
947 arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
948 if (TREE_CHAIN (TREE_CHAIN (arglist
)))
949 arg2
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
951 arg2
= build_int_cst (NULL_TREE
, 3);
955 arg1
= integer_zero_node
;
956 arg2
= build_int_cst (NULL_TREE
, 3);
959 /* Argument 0 is an address. */
960 op0
= expand_expr (arg0
, NULL_RTX
, Pmode
, EXPAND_NORMAL
);
962 /* Argument 1 (read/write flag) must be a compile-time constant int. */
963 if (TREE_CODE (arg1
) != INTEGER_CST
)
965 error ("second argument to %<__builtin_prefetch%> must be a constant");
966 arg1
= integer_zero_node
;
968 op1
= expand_expr (arg1
, NULL_RTX
, VOIDmode
, 0);
969 /* Argument 1 must be either zero or one. */
970 if (INTVAL (op1
) != 0 && INTVAL (op1
) != 1)
972 warning (0, "invalid second argument to %<__builtin_prefetch%>;"
977 /* Argument 2 (locality) must be a compile-time constant int. */
978 if (TREE_CODE (arg2
) != INTEGER_CST
)
980 error ("third argument to %<__builtin_prefetch%> must be a constant");
981 arg2
= integer_zero_node
;
983 op2
= expand_expr (arg2
, NULL_RTX
, VOIDmode
, 0);
984 /* Argument 2 must be 0, 1, 2, or 3. */
985 if (INTVAL (op2
) < 0 || INTVAL (op2
) > 3)
987 warning (0, "invalid third argument to %<__builtin_prefetch%>; using zero");
994 if ((! (*insn_data
[(int) CODE_FOR_prefetch
].operand
[0].predicate
)
996 insn_data
[(int) CODE_FOR_prefetch
].operand
[0].mode
))
997 || (GET_MODE (op0
) != Pmode
))
999 op0
= convert_memory_address (Pmode
, op0
);
1000 op0
= force_reg (Pmode
, op0
);
1002 emit_insn (gen_prefetch (op0
, op1
, op2
));
1006 /* Don't do anything with direct references to volatile memory, but
1007 generate code to handle other side effects. */
1008 if (!MEM_P (op0
) && side_effects_p (op0
))
1012 /* Get a MEM rtx for expression EXP which is the address of an operand
1013 to be used in a string instruction (cmpstrsi, movmemsi, ..). LEN is
1014 the maximum length of the block of memory that might be accessed or
1018 get_memory_rtx (tree exp
, tree len
)
1020 rtx addr
= expand_expr (exp
, NULL_RTX
, ptr_mode
, EXPAND_NORMAL
);
1021 rtx mem
= gen_rtx_MEM (BLKmode
, memory_address (BLKmode
, addr
));
1023 /* Get an expression we can use to find the attributes to assign to MEM.
1024 If it is an ADDR_EXPR, use the operand. Otherwise, dereference it if
1025 we can. First remove any nops. */
1026 while ((TREE_CODE (exp
) == NOP_EXPR
|| TREE_CODE (exp
) == CONVERT_EXPR
1027 || TREE_CODE (exp
) == NON_LVALUE_EXPR
)
1028 && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (exp
, 0))))
1029 exp
= TREE_OPERAND (exp
, 0);
1031 if (TREE_CODE (exp
) == ADDR_EXPR
)
1032 exp
= TREE_OPERAND (exp
, 0);
1033 else if (POINTER_TYPE_P (TREE_TYPE (exp
)))
1034 exp
= build1 (INDIRECT_REF
, TREE_TYPE (TREE_TYPE (exp
)), exp
);
1038 /* Honor attributes derived from exp, except for the alias set
1039 (as builtin stringops may alias with anything) and the size
1040 (as stringops may access multiple array elements). */
1043 set_mem_attributes (mem
, exp
, 0);
1045 /* Allow the string and memory builtins to overflow from one
1046 field into another, see http://gcc.gnu.org/PR23561.
1047 Thus avoid COMPONENT_REFs in MEM_EXPR unless we know the whole
1048 memory accessed by the string or memory builtin will fit
1049 within the field. */
1050 if (MEM_EXPR (mem
) && TREE_CODE (MEM_EXPR (mem
)) == COMPONENT_REF
)
1052 tree mem_expr
= MEM_EXPR (mem
);
1053 HOST_WIDE_INT offset
= -1, length
= -1;
1056 while (TREE_CODE (inner
) == ARRAY_REF
1057 || TREE_CODE (inner
) == NOP_EXPR
1058 || TREE_CODE (inner
) == CONVERT_EXPR
1059 || TREE_CODE (inner
) == NON_LVALUE_EXPR
1060 || TREE_CODE (inner
) == VIEW_CONVERT_EXPR
1061 || TREE_CODE (inner
) == SAVE_EXPR
)
1062 inner
= TREE_OPERAND (inner
, 0);
1064 gcc_assert (TREE_CODE (inner
) == COMPONENT_REF
);
1066 if (MEM_OFFSET (mem
)
1067 && GET_CODE (MEM_OFFSET (mem
)) == CONST_INT
)
1068 offset
= INTVAL (MEM_OFFSET (mem
));
1070 if (offset
>= 0 && len
&& host_integerp (len
, 0))
1071 length
= tree_low_cst (len
, 0);
1073 while (TREE_CODE (inner
) == COMPONENT_REF
)
1075 tree field
= TREE_OPERAND (inner
, 1);
1076 gcc_assert (! DECL_BIT_FIELD (field
));
1077 gcc_assert (TREE_CODE (mem_expr
) == COMPONENT_REF
);
1078 gcc_assert (field
== TREE_OPERAND (mem_expr
, 1));
1081 && TYPE_SIZE_UNIT (TREE_TYPE (inner
))
1082 && host_integerp (TYPE_SIZE_UNIT (TREE_TYPE (inner
)), 0))
1085 = tree_low_cst (TYPE_SIZE_UNIT (TREE_TYPE (inner
)), 0);
1086 /* If we can prove the memory starting at XEXP (mem, 0)
1087 and ending at XEXP (mem, 0) + LENGTH will fit into
1088 this field, we can keep that COMPONENT_REF in MEM_EXPR. */
1091 && offset
+ length
<= size
)
1096 && host_integerp (DECL_FIELD_OFFSET (field
), 0))
1097 offset
+= tree_low_cst (DECL_FIELD_OFFSET (field
), 0)
1098 + tree_low_cst (DECL_FIELD_BIT_OFFSET (field
), 1)
1106 mem_expr
= TREE_OPERAND (mem_expr
, 0);
1107 inner
= TREE_OPERAND (inner
, 0);
1110 if (mem_expr
== NULL
)
1112 if (mem_expr
!= MEM_EXPR (mem
))
1114 set_mem_expr (mem
, mem_expr
);
1115 set_mem_offset (mem
, offset
>= 0 ? GEN_INT (offset
) : NULL_RTX
);
1118 set_mem_alias_set (mem
, 0);
1119 set_mem_size (mem
, NULL_RTX
);
1125 /* Built-in functions to perform an untyped call and return. */
1127 /* For each register that may be used for calling a function, this
1128 gives a mode used to copy the register's value. VOIDmode indicates
1129 the register is not used for calling a function. If the machine
1130 has register windows, this gives only the outbound registers.
1131 INCOMING_REGNO gives the corresponding inbound register. */
1132 static enum machine_mode apply_args_mode
[FIRST_PSEUDO_REGISTER
];
1134 /* For each register that may be used for returning values, this gives
1135 a mode used to copy the register's value. VOIDmode indicates the
1136 register is not used for returning values. If the machine has
1137 register windows, this gives only the outbound registers.
1138 INCOMING_REGNO gives the corresponding inbound register. */
1139 static enum machine_mode apply_result_mode
[FIRST_PSEUDO_REGISTER
];
1141 /* For each register that may be used for calling a function, this
1142 gives the offset of that register into the block returned by
1143 __builtin_apply_args. 0 indicates that the register is not
1144 used for calling a function. */
1145 static int apply_args_reg_offset
[FIRST_PSEUDO_REGISTER
];
1147 /* Return the size required for the block returned by __builtin_apply_args,
1148 and initialize apply_args_mode. */
1151 apply_args_size (void)
1153 static int size
= -1;
1156 enum machine_mode mode
;
1158 /* The values computed by this function never change. */
1161 /* The first value is the incoming arg-pointer. */
1162 size
= GET_MODE_SIZE (Pmode
);
1164 /* The second value is the structure value address unless this is
1165 passed as an "invisible" first argument. */
1166 if (targetm
.calls
.struct_value_rtx (cfun
? TREE_TYPE (cfun
->decl
) : 0, 0))
1167 size
+= GET_MODE_SIZE (Pmode
);
1169 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
1170 if (FUNCTION_ARG_REGNO_P (regno
))
1172 mode
= reg_raw_mode
[regno
];
1174 gcc_assert (mode
!= VOIDmode
);
1176 align
= GET_MODE_ALIGNMENT (mode
) / BITS_PER_UNIT
;
1177 if (size
% align
!= 0)
1178 size
= CEIL (size
, align
) * align
;
1179 apply_args_reg_offset
[regno
] = size
;
1180 size
+= GET_MODE_SIZE (mode
);
1181 apply_args_mode
[regno
] = mode
;
1185 apply_args_mode
[regno
] = VOIDmode
;
1186 apply_args_reg_offset
[regno
] = 0;
1192 /* Return the size required for the block returned by __builtin_apply,
1193 and initialize apply_result_mode. */
1196 apply_result_size (void)
1198 static int size
= -1;
1200 enum machine_mode mode
;
1202 /* The values computed by this function never change. */
1207 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
1208 if (FUNCTION_VALUE_REGNO_P (regno
))
1210 mode
= reg_raw_mode
[regno
];
1212 gcc_assert (mode
!= VOIDmode
);
1214 align
= GET_MODE_ALIGNMENT (mode
) / BITS_PER_UNIT
;
1215 if (size
% align
!= 0)
1216 size
= CEIL (size
, align
) * align
;
1217 size
+= GET_MODE_SIZE (mode
);
1218 apply_result_mode
[regno
] = mode
;
1221 apply_result_mode
[regno
] = VOIDmode
;
1223 /* Allow targets that use untyped_call and untyped_return to override
1224 the size so that machine-specific information can be stored here. */
1225 #ifdef APPLY_RESULT_SIZE
1226 size
= APPLY_RESULT_SIZE
;
1232 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
1233 /* Create a vector describing the result block RESULT. If SAVEP is true,
1234 the result block is used to save the values; otherwise it is used to
1235 restore the values. */
1238 result_vector (int savep
, rtx result
)
1240 int regno
, size
, align
, nelts
;
1241 enum machine_mode mode
;
1243 rtx
*savevec
= alloca (FIRST_PSEUDO_REGISTER
* sizeof (rtx
));
1246 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
1247 if ((mode
= apply_result_mode
[regno
]) != VOIDmode
)
1249 align
= GET_MODE_ALIGNMENT (mode
) / BITS_PER_UNIT
;
1250 if (size
% align
!= 0)
1251 size
= CEIL (size
, align
) * align
;
1252 reg
= gen_rtx_REG (mode
, savep
? regno
: INCOMING_REGNO (regno
));
1253 mem
= adjust_address (result
, mode
, size
);
1254 savevec
[nelts
++] = (savep
1255 ? gen_rtx_SET (VOIDmode
, mem
, reg
)
1256 : gen_rtx_SET (VOIDmode
, reg
, mem
));
1257 size
+= GET_MODE_SIZE (mode
);
1259 return gen_rtx_PARALLEL (VOIDmode
, gen_rtvec_v (nelts
, savevec
));
1261 #endif /* HAVE_untyped_call or HAVE_untyped_return */
1263 /* Save the state required to perform an untyped call with the same
1264 arguments as were passed to the current function. */
1267 expand_builtin_apply_args_1 (void)
1270 int size
, align
, regno
;
1271 enum machine_mode mode
;
1272 rtx struct_incoming_value
= targetm
.calls
.struct_value_rtx (cfun
? TREE_TYPE (cfun
->decl
) : 0, 1);
1274 /* Create a block where the arg-pointer, structure value address,
1275 and argument registers can be saved. */
1276 registers
= assign_stack_local (BLKmode
, apply_args_size (), -1);
1278 /* Walk past the arg-pointer and structure value address. */
1279 size
= GET_MODE_SIZE (Pmode
);
1280 if (targetm
.calls
.struct_value_rtx (cfun
? TREE_TYPE (cfun
->decl
) : 0, 0))
1281 size
+= GET_MODE_SIZE (Pmode
);
1283 /* Save each register used in calling a function to the block. */
1284 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
1285 if ((mode
= apply_args_mode
[regno
]) != VOIDmode
)
1287 align
= GET_MODE_ALIGNMENT (mode
) / BITS_PER_UNIT
;
1288 if (size
% align
!= 0)
1289 size
= CEIL (size
, align
) * align
;
1291 tem
= gen_rtx_REG (mode
, INCOMING_REGNO (regno
));
1293 emit_move_insn (adjust_address (registers
, mode
, size
), tem
);
1294 size
+= GET_MODE_SIZE (mode
);
1297 /* Save the arg pointer to the block. */
1298 tem
= copy_to_reg (virtual_incoming_args_rtx
);
1299 #ifdef STACK_GROWS_DOWNWARD
1300 /* We need the pointer as the caller actually passed them to us, not
1301 as we might have pretended they were passed. Make sure it's a valid
1302 operand, as emit_move_insn isn't expected to handle a PLUS. */
1304 = force_operand (plus_constant (tem
, current_function_pretend_args_size
),
1307 emit_move_insn (adjust_address (registers
, Pmode
, 0), tem
);
1309 size
= GET_MODE_SIZE (Pmode
);
1311 /* Save the structure value address unless this is passed as an
1312 "invisible" first argument. */
1313 if (struct_incoming_value
)
1315 emit_move_insn (adjust_address (registers
, Pmode
, size
),
1316 copy_to_reg (struct_incoming_value
));
1317 size
+= GET_MODE_SIZE (Pmode
);
1320 /* Return the address of the block. */
1321 return copy_addr_to_reg (XEXP (registers
, 0));
1324 /* __builtin_apply_args returns block of memory allocated on
1325 the stack into which is stored the arg pointer, structure
1326 value address, static chain, and all the registers that might
1327 possibly be used in performing a function call. The code is
1328 moved to the start of the function so the incoming values are
1332 expand_builtin_apply_args (void)
1334 /* Don't do __builtin_apply_args more than once in a function.
1335 Save the result of the first call and reuse it. */
1336 if (apply_args_value
!= 0)
1337 return apply_args_value
;
1339 /* When this function is called, it means that registers must be
1340 saved on entry to this function. So we migrate the
1341 call to the first insn of this function. */
1346 temp
= expand_builtin_apply_args_1 ();
1350 apply_args_value
= temp
;
1352 /* Put the insns after the NOTE that starts the function.
1353 If this is inside a start_sequence, make the outer-level insn
1354 chain current, so the code is placed at the start of the
1356 push_topmost_sequence ();
1357 emit_insn_before (seq
, NEXT_INSN (entry_of_function ()));
1358 pop_topmost_sequence ();
1363 /* Perform an untyped call and save the state required to perform an
1364 untyped return of whatever value was returned by the given function. */
1367 expand_builtin_apply (rtx function
, rtx arguments
, rtx argsize
)
1369 int size
, align
, regno
;
1370 enum machine_mode mode
;
1371 rtx incoming_args
, result
, reg
, dest
, src
, call_insn
;
1372 rtx old_stack_level
= 0;
1373 rtx call_fusage
= 0;
1374 rtx struct_value
= targetm
.calls
.struct_value_rtx (cfun
? TREE_TYPE (cfun
->decl
) : 0, 0);
1376 arguments
= convert_memory_address (Pmode
, arguments
);
1378 /* Create a block where the return registers can be saved. */
1379 result
= assign_stack_local (BLKmode
, apply_result_size (), -1);
1381 /* Fetch the arg pointer from the ARGUMENTS block. */
1382 incoming_args
= gen_reg_rtx (Pmode
);
1383 emit_move_insn (incoming_args
, gen_rtx_MEM (Pmode
, arguments
));
1384 #ifndef STACK_GROWS_DOWNWARD
1385 incoming_args
= expand_simple_binop (Pmode
, MINUS
, incoming_args
, argsize
,
1386 incoming_args
, 0, OPTAB_LIB_WIDEN
);
1389 /* Push a new argument block and copy the arguments. Do not allow
1390 the (potential) memcpy call below to interfere with our stack
1392 do_pending_stack_adjust ();
1395 /* Save the stack with nonlocal if available. */
1396 #ifdef HAVE_save_stack_nonlocal
1397 if (HAVE_save_stack_nonlocal
)
1398 emit_stack_save (SAVE_NONLOCAL
, &old_stack_level
, NULL_RTX
);
1401 emit_stack_save (SAVE_BLOCK
, &old_stack_level
, NULL_RTX
);
1403 /* Allocate a block of memory onto the stack and copy the memory
1404 arguments to the outgoing arguments address. */
1405 allocate_dynamic_stack_space (argsize
, 0, BITS_PER_UNIT
);
1406 dest
= virtual_outgoing_args_rtx
;
1407 #ifndef STACK_GROWS_DOWNWARD
1408 if (GET_CODE (argsize
) == CONST_INT
)
1409 dest
= plus_constant (dest
, -INTVAL (argsize
));
1411 dest
= gen_rtx_PLUS (Pmode
, dest
, negate_rtx (Pmode
, argsize
));
1413 dest
= gen_rtx_MEM (BLKmode
, dest
);
1414 set_mem_align (dest
, PARM_BOUNDARY
);
1415 src
= gen_rtx_MEM (BLKmode
, incoming_args
);
1416 set_mem_align (src
, PARM_BOUNDARY
);
1417 emit_block_move (dest
, src
, argsize
, BLOCK_OP_NORMAL
);
1419 /* Refer to the argument block. */
1421 arguments
= gen_rtx_MEM (BLKmode
, arguments
);
1422 set_mem_align (arguments
, PARM_BOUNDARY
);
1424 /* Walk past the arg-pointer and structure value address. */
1425 size
= GET_MODE_SIZE (Pmode
);
1427 size
+= GET_MODE_SIZE (Pmode
);
1429 /* Restore each of the registers previously saved. Make USE insns
1430 for each of these registers for use in making the call. */
1431 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
1432 if ((mode
= apply_args_mode
[regno
]) != VOIDmode
)
1434 align
= GET_MODE_ALIGNMENT (mode
) / BITS_PER_UNIT
;
1435 if (size
% align
!= 0)
1436 size
= CEIL (size
, align
) * align
;
1437 reg
= gen_rtx_REG (mode
, regno
);
1438 emit_move_insn (reg
, adjust_address (arguments
, mode
, size
));
1439 use_reg (&call_fusage
, reg
);
1440 size
+= GET_MODE_SIZE (mode
);
1443 /* Restore the structure value address unless this is passed as an
1444 "invisible" first argument. */
1445 size
= GET_MODE_SIZE (Pmode
);
1448 rtx value
= gen_reg_rtx (Pmode
);
1449 emit_move_insn (value
, adjust_address (arguments
, Pmode
, size
));
1450 emit_move_insn (struct_value
, value
);
1451 if (REG_P (struct_value
))
1452 use_reg (&call_fusage
, struct_value
);
1453 size
+= GET_MODE_SIZE (Pmode
);
1456 /* All arguments and registers used for the call are set up by now! */
1457 function
= prepare_call_address (function
, NULL
, &call_fusage
, 0, 0);
1459 /* Ensure address is valid. SYMBOL_REF is already valid, so no need,
1460 and we don't want to load it into a register as an optimization,
1461 because prepare_call_address already did it if it should be done. */
1462 if (GET_CODE (function
) != SYMBOL_REF
)
1463 function
= memory_address (FUNCTION_MODE
, function
);
1465 /* Generate the actual call instruction and save the return value. */
1466 #ifdef HAVE_untyped_call
1467 if (HAVE_untyped_call
)
1468 emit_call_insn (gen_untyped_call (gen_rtx_MEM (FUNCTION_MODE
, function
),
1469 result
, result_vector (1, result
)));
1472 #ifdef HAVE_call_value
1473 if (HAVE_call_value
)
1477 /* Locate the unique return register. It is not possible to
1478 express a call that sets more than one return register using
1479 call_value; use untyped_call for that. In fact, untyped_call
1480 only needs to save the return registers in the given block. */
1481 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
1482 if ((mode
= apply_result_mode
[regno
]) != VOIDmode
)
1484 gcc_assert (!valreg
); /* HAVE_untyped_call required. */
1486 valreg
= gen_rtx_REG (mode
, regno
);
1489 emit_call_insn (GEN_CALL_VALUE (valreg
,
1490 gen_rtx_MEM (FUNCTION_MODE
, function
),
1491 const0_rtx
, NULL_RTX
, const0_rtx
));
1493 emit_move_insn (adjust_address (result
, GET_MODE (valreg
), 0), valreg
);
1499 /* Find the CALL insn we just emitted, and attach the register usage
1501 call_insn
= last_call_insn ();
1502 add_function_usage_to (call_insn
, call_fusage
);
1504 /* Restore the stack. */
1505 #ifdef HAVE_save_stack_nonlocal
1506 if (HAVE_save_stack_nonlocal
)
1507 emit_stack_restore (SAVE_NONLOCAL
, old_stack_level
, NULL_RTX
);
1510 emit_stack_restore (SAVE_BLOCK
, old_stack_level
, NULL_RTX
);
1514 /* Return the address of the result block. */
1515 result
= copy_addr_to_reg (XEXP (result
, 0));
1516 return convert_memory_address (ptr_mode
, result
);
1519 /* Perform an untyped return. */
1522 expand_builtin_return (rtx result
)
1524 int size
, align
, regno
;
1525 enum machine_mode mode
;
1527 rtx call_fusage
= 0;
1529 result
= convert_memory_address (Pmode
, result
);
1531 apply_result_size ();
1532 result
= gen_rtx_MEM (BLKmode
, result
);
1534 #ifdef HAVE_untyped_return
1535 if (HAVE_untyped_return
)
1537 emit_jump_insn (gen_untyped_return (result
, result_vector (0, result
)));
1543 /* Restore the return value and note that each value is used. */
1545 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
1546 if ((mode
= apply_result_mode
[regno
]) != VOIDmode
)
1548 align
= GET_MODE_ALIGNMENT (mode
) / BITS_PER_UNIT
;
1549 if (size
% align
!= 0)
1550 size
= CEIL (size
, align
) * align
;
1551 reg
= gen_rtx_REG (mode
, INCOMING_REGNO (regno
));
1552 emit_move_insn (reg
, adjust_address (result
, mode
, size
));
1554 push_to_sequence (call_fusage
);
1555 emit_insn (gen_rtx_USE (VOIDmode
, reg
));
1556 call_fusage
= get_insns ();
1558 size
+= GET_MODE_SIZE (mode
);
1561 /* Put the USE insns before the return. */
1562 emit_insn (call_fusage
);
1564 /* Return whatever values was restored by jumping directly to the end
1566 expand_naked_return ();
1569 /* Used by expand_builtin_classify_type and fold_builtin_classify_type. */
1571 static enum type_class
1572 type_to_class (tree type
)
1574 switch (TREE_CODE (type
))
1576 case VOID_TYPE
: return void_type_class
;
1577 case INTEGER_TYPE
: return integer_type_class
;
1578 case CHAR_TYPE
: return char_type_class
;
1579 case ENUMERAL_TYPE
: return enumeral_type_class
;
1580 case BOOLEAN_TYPE
: return boolean_type_class
;
1581 case POINTER_TYPE
: return pointer_type_class
;
1582 case REFERENCE_TYPE
: return reference_type_class
;
1583 case OFFSET_TYPE
: return offset_type_class
;
1584 case REAL_TYPE
: return real_type_class
;
1585 case COMPLEX_TYPE
: return complex_type_class
;
1586 case FUNCTION_TYPE
: return function_type_class
;
1587 case METHOD_TYPE
: return method_type_class
;
1588 case RECORD_TYPE
: return record_type_class
;
1590 case QUAL_UNION_TYPE
: return union_type_class
;
1591 case ARRAY_TYPE
: return (TYPE_STRING_FLAG (type
)
1592 ? string_type_class
: array_type_class
);
1593 case LANG_TYPE
: return lang_type_class
;
1594 default: return no_type_class
;
1598 /* Expand a call to __builtin_classify_type with arguments found in
1602 expand_builtin_classify_type (tree arglist
)
1605 return GEN_INT (type_to_class (TREE_TYPE (TREE_VALUE (arglist
))));
1606 return GEN_INT (no_type_class
);
1609 /* This helper macro, meant to be used in mathfn_built_in below,
1610 determines which among a set of three builtin math functions is
1611 appropriate for a given type mode. The `F' and `L' cases are
1612 automatically generated from the `double' case. */
1613 #define CASE_MATHFN(BUILT_IN_MATHFN) \
1614 case BUILT_IN_MATHFN: case BUILT_IN_MATHFN##F: case BUILT_IN_MATHFN##L: \
1615 fcode = BUILT_IN_MATHFN; fcodef = BUILT_IN_MATHFN##F ; \
1616 fcodel = BUILT_IN_MATHFN##L ; break;
1618 /* Return mathematic function equivalent to FN but operating directly
1619 on TYPE, if available. If we can't do the conversion, return zero. */
1621 mathfn_built_in (tree type
, enum built_in_function fn
)
1623 enum built_in_function fcode
, fcodef
, fcodel
;
1627 CASE_MATHFN (BUILT_IN_ACOS
)
1628 CASE_MATHFN (BUILT_IN_ACOSH
)
1629 CASE_MATHFN (BUILT_IN_ASIN
)
1630 CASE_MATHFN (BUILT_IN_ASINH
)
1631 CASE_MATHFN (BUILT_IN_ATAN
)
1632 CASE_MATHFN (BUILT_IN_ATAN2
)
1633 CASE_MATHFN (BUILT_IN_ATANH
)
1634 CASE_MATHFN (BUILT_IN_CBRT
)
1635 CASE_MATHFN (BUILT_IN_CEIL
)
1636 CASE_MATHFN (BUILT_IN_COPYSIGN
)
1637 CASE_MATHFN (BUILT_IN_COS
)
1638 CASE_MATHFN (BUILT_IN_COSH
)
1639 CASE_MATHFN (BUILT_IN_DREM
)
1640 CASE_MATHFN (BUILT_IN_ERF
)
1641 CASE_MATHFN (BUILT_IN_ERFC
)
1642 CASE_MATHFN (BUILT_IN_EXP
)
1643 CASE_MATHFN (BUILT_IN_EXP10
)
1644 CASE_MATHFN (BUILT_IN_EXP2
)
1645 CASE_MATHFN (BUILT_IN_EXPM1
)
1646 CASE_MATHFN (BUILT_IN_FABS
)
1647 CASE_MATHFN (BUILT_IN_FDIM
)
1648 CASE_MATHFN (BUILT_IN_FLOOR
)
1649 CASE_MATHFN (BUILT_IN_FMA
)
1650 CASE_MATHFN (BUILT_IN_FMAX
)
1651 CASE_MATHFN (BUILT_IN_FMIN
)
1652 CASE_MATHFN (BUILT_IN_FMOD
)
1653 CASE_MATHFN (BUILT_IN_FREXP
)
1654 CASE_MATHFN (BUILT_IN_GAMMA
)
1655 CASE_MATHFN (BUILT_IN_HUGE_VAL
)
1656 CASE_MATHFN (BUILT_IN_HYPOT
)
1657 CASE_MATHFN (BUILT_IN_ILOGB
)
1658 CASE_MATHFN (BUILT_IN_INF
)
1659 CASE_MATHFN (BUILT_IN_J0
)
1660 CASE_MATHFN (BUILT_IN_J1
)
1661 CASE_MATHFN (BUILT_IN_JN
)
1662 CASE_MATHFN (BUILT_IN_LCEIL
)
1663 CASE_MATHFN (BUILT_IN_LDEXP
)
1664 CASE_MATHFN (BUILT_IN_LFLOOR
)
1665 CASE_MATHFN (BUILT_IN_LGAMMA
)
1666 CASE_MATHFN (BUILT_IN_LLCEIL
)
1667 CASE_MATHFN (BUILT_IN_LLFLOOR
)
1668 CASE_MATHFN (BUILT_IN_LLRINT
)
1669 CASE_MATHFN (BUILT_IN_LLROUND
)
1670 CASE_MATHFN (BUILT_IN_LOG
)
1671 CASE_MATHFN (BUILT_IN_LOG10
)
1672 CASE_MATHFN (BUILT_IN_LOG1P
)
1673 CASE_MATHFN (BUILT_IN_LOG2
)
1674 CASE_MATHFN (BUILT_IN_LOGB
)
1675 CASE_MATHFN (BUILT_IN_LRINT
)
1676 CASE_MATHFN (BUILT_IN_LROUND
)
1677 CASE_MATHFN (BUILT_IN_MODF
)
1678 CASE_MATHFN (BUILT_IN_NAN
)
1679 CASE_MATHFN (BUILT_IN_NANS
)
1680 CASE_MATHFN (BUILT_IN_NEARBYINT
)
1681 CASE_MATHFN (BUILT_IN_NEXTAFTER
)
1682 CASE_MATHFN (BUILT_IN_NEXTTOWARD
)
1683 CASE_MATHFN (BUILT_IN_POW
)
1684 CASE_MATHFN (BUILT_IN_POWI
)
1685 CASE_MATHFN (BUILT_IN_POW10
)
1686 CASE_MATHFN (BUILT_IN_REMAINDER
)
1687 CASE_MATHFN (BUILT_IN_REMQUO
)
1688 CASE_MATHFN (BUILT_IN_RINT
)
1689 CASE_MATHFN (BUILT_IN_ROUND
)
1690 CASE_MATHFN (BUILT_IN_SCALB
)
1691 CASE_MATHFN (BUILT_IN_SCALBLN
)
1692 CASE_MATHFN (BUILT_IN_SCALBN
)
1693 CASE_MATHFN (BUILT_IN_SIGNIFICAND
)
1694 CASE_MATHFN (BUILT_IN_SIN
)
1695 CASE_MATHFN (BUILT_IN_SINCOS
)
1696 CASE_MATHFN (BUILT_IN_SINH
)
1697 CASE_MATHFN (BUILT_IN_SQRT
)
1698 CASE_MATHFN (BUILT_IN_TAN
)
1699 CASE_MATHFN (BUILT_IN_TANH
)
1700 CASE_MATHFN (BUILT_IN_TGAMMA
)
1701 CASE_MATHFN (BUILT_IN_TRUNC
)
1702 CASE_MATHFN (BUILT_IN_Y0
)
1703 CASE_MATHFN (BUILT_IN_Y1
)
1704 CASE_MATHFN (BUILT_IN_YN
)
1710 if (TYPE_MAIN_VARIANT (type
) == double_type_node
)
1711 return implicit_built_in_decls
[fcode
];
1712 else if (TYPE_MAIN_VARIANT (type
) == float_type_node
)
1713 return implicit_built_in_decls
[fcodef
];
1714 else if (TYPE_MAIN_VARIANT (type
) == long_double_type_node
)
1715 return implicit_built_in_decls
[fcodel
];
1720 /* If errno must be maintained, expand the RTL to check if the result,
1721 TARGET, of a built-in function call, EXP, is NaN, and if so set
1725 expand_errno_check (tree exp
, rtx target
)
1727 rtx lab
= gen_label_rtx ();
1729 /* Test the result; if it is NaN, set errno=EDOM because
1730 the argument was not in the domain. */
1731 emit_cmp_and_jump_insns (target
, target
, EQ
, 0, GET_MODE (target
),
1735 /* If this built-in doesn't throw an exception, set errno directly. */
1736 if (TREE_NOTHROW (TREE_OPERAND (TREE_OPERAND (exp
, 0), 0)))
1738 #ifdef GEN_ERRNO_RTX
1739 rtx errno_rtx
= GEN_ERRNO_RTX
;
1742 = gen_rtx_MEM (word_mode
, gen_rtx_SYMBOL_REF (Pmode
, "errno"));
1744 emit_move_insn (errno_rtx
, GEN_INT (TARGET_EDOM
));
1750 /* We can't set errno=EDOM directly; let the library call do it.
1751 Pop the arguments right away in case the call gets deleted. */
1753 expand_call (exp
, target
, 0);
1759 /* Expand a call to one of the builtin math functions (sqrt, exp, or log).
1760 Return 0 if a normal call should be emitted rather than expanding the
1761 function in-line. EXP is the expression that is a call to the builtin
1762 function; if convenient, the result should be placed in TARGET.
1763 SUBTARGET may be used as the target for computing one of EXP's operands. */
1766 expand_builtin_mathfn (tree exp
, rtx target
, rtx subtarget
)
1768 optab builtin_optab
;
1769 rtx op0
, insns
, before_call
;
1770 tree fndecl
= get_callee_fndecl (exp
);
1771 tree arglist
= TREE_OPERAND (exp
, 1);
1772 enum machine_mode mode
;
1773 bool errno_set
= false;
1776 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
1779 arg
= TREE_VALUE (arglist
);
1781 switch (DECL_FUNCTION_CODE (fndecl
))
1784 case BUILT_IN_SQRTF
:
1785 case BUILT_IN_SQRTL
:
1786 errno_set
= ! tree_expr_nonnegative_p (arg
);
1787 builtin_optab
= sqrt_optab
;
1792 errno_set
= true; builtin_optab
= exp_optab
; break;
1793 case BUILT_IN_EXP10
:
1794 case BUILT_IN_EXP10F
:
1795 case BUILT_IN_EXP10L
:
1796 case BUILT_IN_POW10
:
1797 case BUILT_IN_POW10F
:
1798 case BUILT_IN_POW10L
:
1799 errno_set
= true; builtin_optab
= exp10_optab
; break;
1801 case BUILT_IN_EXP2F
:
1802 case BUILT_IN_EXP2L
:
1803 errno_set
= true; builtin_optab
= exp2_optab
; break;
1804 case BUILT_IN_EXPM1
:
1805 case BUILT_IN_EXPM1F
:
1806 case BUILT_IN_EXPM1L
:
1807 errno_set
= true; builtin_optab
= expm1_optab
; break;
1809 case BUILT_IN_LOGBF
:
1810 case BUILT_IN_LOGBL
:
1811 errno_set
= true; builtin_optab
= logb_optab
; break;
1812 case BUILT_IN_ILOGB
:
1813 case BUILT_IN_ILOGBF
:
1814 case BUILT_IN_ILOGBL
:
1815 errno_set
= true; builtin_optab
= ilogb_optab
; break;
1819 errno_set
= true; builtin_optab
= log_optab
; break;
1820 case BUILT_IN_LOG10
:
1821 case BUILT_IN_LOG10F
:
1822 case BUILT_IN_LOG10L
:
1823 errno_set
= true; builtin_optab
= log10_optab
; break;
1825 case BUILT_IN_LOG2F
:
1826 case BUILT_IN_LOG2L
:
1827 errno_set
= true; builtin_optab
= log2_optab
; break;
1828 case BUILT_IN_LOG1P
:
1829 case BUILT_IN_LOG1PF
:
1830 case BUILT_IN_LOG1PL
:
1831 errno_set
= true; builtin_optab
= log1p_optab
; break;
1833 case BUILT_IN_ASINF
:
1834 case BUILT_IN_ASINL
:
1835 builtin_optab
= asin_optab
; break;
1837 case BUILT_IN_ACOSF
:
1838 case BUILT_IN_ACOSL
:
1839 builtin_optab
= acos_optab
; break;
1843 builtin_optab
= tan_optab
; break;
1845 case BUILT_IN_ATANF
:
1846 case BUILT_IN_ATANL
:
1847 builtin_optab
= atan_optab
; break;
1848 case BUILT_IN_FLOOR
:
1849 case BUILT_IN_FLOORF
:
1850 case BUILT_IN_FLOORL
:
1851 builtin_optab
= floor_optab
; break;
1853 case BUILT_IN_CEILF
:
1854 case BUILT_IN_CEILL
:
1855 builtin_optab
= ceil_optab
; break;
1856 case BUILT_IN_TRUNC
:
1857 case BUILT_IN_TRUNCF
:
1858 case BUILT_IN_TRUNCL
:
1859 builtin_optab
= btrunc_optab
; break;
1860 case BUILT_IN_ROUND
:
1861 case BUILT_IN_ROUNDF
:
1862 case BUILT_IN_ROUNDL
:
1863 builtin_optab
= round_optab
; break;
1864 case BUILT_IN_NEARBYINT
:
1865 case BUILT_IN_NEARBYINTF
:
1866 case BUILT_IN_NEARBYINTL
:
1867 builtin_optab
= nearbyint_optab
; break;
1869 case BUILT_IN_RINTF
:
1870 case BUILT_IN_RINTL
:
1871 builtin_optab
= rint_optab
; break;
1872 case BUILT_IN_LRINT
:
1873 case BUILT_IN_LRINTF
:
1874 case BUILT_IN_LRINTL
:
1875 case BUILT_IN_LLRINT
:
1876 case BUILT_IN_LLRINTF
:
1877 case BUILT_IN_LLRINTL
:
1878 builtin_optab
= lrint_optab
; break;
1883 /* Make a suitable register to place result in. */
1884 mode
= TYPE_MODE (TREE_TYPE (exp
));
1886 if (! flag_errno_math
|| ! HONOR_NANS (mode
))
1889 /* Before working hard, check whether the instruction is available. */
1890 if (builtin_optab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
)
1892 target
= gen_reg_rtx (mode
);
1894 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
1895 need to expand the argument again. This way, we will not perform
1896 side-effects more the once. */
1897 narg
= builtin_save_expr (arg
);
1901 arglist
= build_tree_list (NULL_TREE
, arg
);
1902 exp
= build_function_call_expr (fndecl
, arglist
);
1905 op0
= expand_expr (arg
, subtarget
, VOIDmode
, 0);
1909 /* Compute into TARGET.
1910 Set TARGET to wherever the result comes back. */
1911 target
= expand_unop (mode
, builtin_optab
, op0
, target
, 0);
1916 expand_errno_check (exp
, target
);
1918 /* Output the entire sequence. */
1919 insns
= get_insns ();
1925 /* If we were unable to expand via the builtin, stop the sequence
1926 (without outputting the insns) and call to the library function
1927 with the stabilized argument list. */
1931 before_call
= get_last_insn ();
1933 target
= expand_call (exp
, target
, target
== const0_rtx
);
1935 /* If this is a sqrt operation and we don't care about errno, try to
1936 attach a REG_EQUAL note with a SQRT rtx to the emitted libcall.
1937 This allows the semantics of the libcall to be visible to the RTL
1939 if (builtin_optab
== sqrt_optab
&& !errno_set
)
1941 /* Search backwards through the insns emitted by expand_call looking
1942 for the instruction with the REG_RETVAL note. */
1943 rtx last
= get_last_insn ();
1944 while (last
!= before_call
)
1946 if (find_reg_note (last
, REG_RETVAL
, NULL
))
1948 rtx note
= find_reg_note (last
, REG_EQUAL
, NULL
);
1949 /* Check that the REQ_EQUAL note is an EXPR_LIST with
1950 two elements, i.e. symbol_ref(sqrt) and the operand. */
1952 && GET_CODE (note
) == EXPR_LIST
1953 && GET_CODE (XEXP (note
, 0)) == EXPR_LIST
1954 && XEXP (XEXP (note
, 0), 1) != NULL_RTX
1955 && XEXP (XEXP (XEXP (note
, 0), 1), 1) == NULL_RTX
)
1957 rtx operand
= XEXP (XEXP (XEXP (note
, 0), 1), 0);
1958 /* Check operand is a register with expected mode. */
1961 && GET_MODE (operand
) == mode
)
1963 /* Replace the REG_EQUAL note with a SQRT rtx. */
1964 rtx equiv
= gen_rtx_SQRT (mode
, operand
);
1965 set_unique_reg_note (last
, REG_EQUAL
, equiv
);
1970 last
= PREV_INSN (last
);
1977 /* Expand a call to the builtin binary math functions (pow and atan2).
1978 Return 0 if a normal call should be emitted rather than expanding the
1979 function in-line. EXP is the expression that is a call to the builtin
1980 function; if convenient, the result should be placed in TARGET.
1981 SUBTARGET may be used as the target for computing one of EXP's
1985 expand_builtin_mathfn_2 (tree exp
, rtx target
, rtx subtarget
)
1987 optab builtin_optab
;
1988 rtx op0
, op1
, insns
;
1989 int op1_type
= REAL_TYPE
;
1990 tree fndecl
= get_callee_fndecl (exp
);
1991 tree arglist
= TREE_OPERAND (exp
, 1);
1992 tree arg0
, arg1
, temp
, narg
;
1993 enum machine_mode mode
;
1994 bool errno_set
= true;
1997 if ((DECL_FUNCTION_CODE (fndecl
) == BUILT_IN_LDEXP
)
1998 || (DECL_FUNCTION_CODE (fndecl
) == BUILT_IN_LDEXPF
)
1999 || (DECL_FUNCTION_CODE (fndecl
) == BUILT_IN_LDEXPL
))
2000 op1_type
= INTEGER_TYPE
;
2002 if (!validate_arglist (arglist
, REAL_TYPE
, op1_type
, VOID_TYPE
))
2005 arg0
= TREE_VALUE (arglist
);
2006 arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
2008 switch (DECL_FUNCTION_CODE (fndecl
))
2013 builtin_optab
= pow_optab
; break;
2014 case BUILT_IN_ATAN2
:
2015 case BUILT_IN_ATAN2F
:
2016 case BUILT_IN_ATAN2L
:
2017 builtin_optab
= atan2_optab
; break;
2018 case BUILT_IN_LDEXP
:
2019 case BUILT_IN_LDEXPF
:
2020 case BUILT_IN_LDEXPL
:
2021 builtin_optab
= ldexp_optab
; break;
2023 case BUILT_IN_FMODF
:
2024 case BUILT_IN_FMODL
:
2025 builtin_optab
= fmod_optab
; break;
2027 case BUILT_IN_DREMF
:
2028 case BUILT_IN_DREML
:
2029 builtin_optab
= drem_optab
; break;
2034 /* Make a suitable register to place result in. */
2035 mode
= TYPE_MODE (TREE_TYPE (exp
));
2037 /* Before working hard, check whether the instruction is available. */
2038 if (builtin_optab
->handlers
[(int) mode
].insn_code
== CODE_FOR_nothing
)
2041 target
= gen_reg_rtx (mode
);
2043 if (! flag_errno_math
|| ! HONOR_NANS (mode
))
2046 /* Always stabilize the argument list. */
2047 narg
= builtin_save_expr (arg1
);
2051 temp
= build_tree_list (NULL_TREE
, narg
);
2055 temp
= TREE_CHAIN (arglist
);
2057 narg
= builtin_save_expr (arg0
);
2061 arglist
= tree_cons (NULL_TREE
, narg
, temp
);
2065 arglist
= tree_cons (NULL_TREE
, arg0
, temp
);
2068 exp
= build_function_call_expr (fndecl
, arglist
);
2070 op0
= expand_expr (arg0
, subtarget
, VOIDmode
, 0);
2071 op1
= expand_expr (arg1
, 0, VOIDmode
, 0);
2075 /* Compute into TARGET.
2076 Set TARGET to wherever the result comes back. */
2077 target
= expand_binop (mode
, builtin_optab
, op0
, op1
,
2078 target
, 0, OPTAB_DIRECT
);
2080 /* If we were unable to expand via the builtin, stop the sequence
2081 (without outputting the insns) and call to the library function
2082 with the stabilized argument list. */
2086 return expand_call (exp
, target
, target
== const0_rtx
);
2090 expand_errno_check (exp
, target
);
2092 /* Output the entire sequence. */
2093 insns
= get_insns ();
2100 /* Expand a call to the builtin sin and cos math functions.
2101 Return 0 if a normal call should be emitted rather than expanding the
2102 function in-line. EXP is the expression that is a call to the builtin
2103 function; if convenient, the result should be placed in TARGET.
2104 SUBTARGET may be used as the target for computing one of EXP's
2108 expand_builtin_mathfn_3 (tree exp
, rtx target
, rtx subtarget
)
2110 optab builtin_optab
;
2112 tree fndecl
= get_callee_fndecl (exp
);
2113 tree arglist
= TREE_OPERAND (exp
, 1);
2114 enum machine_mode mode
;
2115 bool errno_set
= false;
2118 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
2121 arg
= TREE_VALUE (arglist
);
2123 switch (DECL_FUNCTION_CODE (fndecl
))
2131 builtin_optab
= sincos_optab
; break;
2136 /* Make a suitable register to place result in. */
2137 mode
= TYPE_MODE (TREE_TYPE (exp
));
2139 if (! flag_errno_math
|| ! HONOR_NANS (mode
))
2142 /* Check if sincos insn is available, otherwise fallback
2143 to sin or cos insn. */
2144 if (builtin_optab
->handlers
[(int) mode
].insn_code
== CODE_FOR_nothing
) {
2145 switch (DECL_FUNCTION_CODE (fndecl
))
2150 builtin_optab
= sin_optab
; break;
2154 builtin_optab
= cos_optab
; break;
2160 /* Before working hard, check whether the instruction is available. */
2161 if (builtin_optab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
)
2163 target
= gen_reg_rtx (mode
);
2165 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2166 need to expand the argument again. This way, we will not perform
2167 side-effects more the once. */
2168 narg
= save_expr (arg
);
2172 arglist
= build_tree_list (NULL_TREE
, arg
);
2173 exp
= build_function_call_expr (fndecl
, arglist
);
2176 op0
= expand_expr (arg
, subtarget
, VOIDmode
, 0);
2180 /* Compute into TARGET.
2181 Set TARGET to wherever the result comes back. */
2182 if (builtin_optab
== sincos_optab
)
2186 switch (DECL_FUNCTION_CODE (fndecl
))
2191 result
= expand_twoval_unop (builtin_optab
, op0
, 0, target
, 0);
2196 result
= expand_twoval_unop (builtin_optab
, op0
, target
, 0, 0);
2201 gcc_assert (result
);
2205 target
= expand_unop (mode
, builtin_optab
, op0
, target
, 0);
2211 expand_errno_check (exp
, target
);
2213 /* Output the entire sequence. */
2214 insns
= get_insns ();
2220 /* If we were unable to expand via the builtin, stop the sequence
2221 (without outputting the insns) and call to the library function
2222 with the stabilized argument list. */
2226 target
= expand_call (exp
, target
, target
== const0_rtx
);
2231 /* Expand a call to one of the builtin rounding functions (lfloor).
2232 If expanding via optab fails, lower expression to (int)(floor(x)).
2233 EXP is the expression that is a call to the builtin function;
2234 if convenient, the result should be placed in TARGET. SUBTARGET may
2235 be used as the target for computing one of EXP's operands. */
2238 expand_builtin_int_roundingfn (tree exp
, rtx target
, rtx subtarget
)
2240 optab builtin_optab
;
2241 rtx op0
, insns
, tmp
;
2242 tree fndecl
= get_callee_fndecl (exp
);
2243 tree arglist
= TREE_OPERAND (exp
, 1);
2244 enum built_in_function fallback_fn
;
2245 tree fallback_fndecl
;
2246 enum machine_mode mode
;
2249 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
2252 arg
= TREE_VALUE (arglist
);
2254 switch (DECL_FUNCTION_CODE (fndecl
))
2256 case BUILT_IN_LCEIL
:
2257 case BUILT_IN_LCEILF
:
2258 case BUILT_IN_LCEILL
:
2259 case BUILT_IN_LLCEIL
:
2260 case BUILT_IN_LLCEILF
:
2261 case BUILT_IN_LLCEILL
:
2262 builtin_optab
= lceil_optab
;
2263 fallback_fn
= BUILT_IN_CEIL
;
2266 case BUILT_IN_LFLOOR
:
2267 case BUILT_IN_LFLOORF
:
2268 case BUILT_IN_LFLOORL
:
2269 case BUILT_IN_LLFLOOR
:
2270 case BUILT_IN_LLFLOORF
:
2271 case BUILT_IN_LLFLOORL
:
2272 builtin_optab
= lfloor_optab
;
2273 fallback_fn
= BUILT_IN_FLOOR
;
2280 /* Make a suitable register to place result in. */
2281 mode
= TYPE_MODE (TREE_TYPE (exp
));
2283 /* Before working hard, check whether the instruction is available. */
2284 if (builtin_optab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
)
2286 target
= gen_reg_rtx (mode
);
2288 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2289 need to expand the argument again. This way, we will not perform
2290 side-effects more the once. */
2291 narg
= builtin_save_expr (arg
);
2295 arglist
= build_tree_list (NULL_TREE
, arg
);
2296 exp
= build_function_call_expr (fndecl
, arglist
);
2299 op0
= expand_expr (arg
, subtarget
, VOIDmode
, 0);
2303 /* Compute into TARGET.
2304 Set TARGET to wherever the result comes back. */
2305 target
= expand_unop (mode
, builtin_optab
, op0
, target
, 0);
2309 /* Output the entire sequence. */
2310 insns
= get_insns ();
2316 /* If we were unable to expand via the builtin, stop the sequence
2317 (without outputting the insns). */
2321 /* Fall back to floating point rounding optab. */
2322 fallback_fndecl
= mathfn_built_in (TREE_TYPE (arg
), fallback_fn
);
2323 /* We shouldn't get here on targets without TARGET_C99_FUNCTIONS.
2324 ??? Perhaps convert (int)floorf(x) into (int)floor((double)x). */
2325 gcc_assert (fallback_fndecl
!= NULL_TREE
);
2326 exp
= build_function_call_expr (fallback_fndecl
, arglist
);
2328 tmp
= expand_builtin_mathfn (exp
, NULL_RTX
, NULL_RTX
);
2330 /* Truncate the result of floating point optab to integer
2331 via expand_fix (). */
2332 target
= gen_reg_rtx (mode
);
2333 expand_fix (target
, tmp
, 0);
2338 /* To evaluate powi(x,n), the floating point value x raised to the
2339 constant integer exponent n, we use a hybrid algorithm that
2340 combines the "window method" with look-up tables. For an
2341 introduction to exponentiation algorithms and "addition chains",
2342 see section 4.6.3, "Evaluation of Powers" of Donald E. Knuth,
2343 "Seminumerical Algorithms", Vol. 2, "The Art of Computer Programming",
2344 3rd Edition, 1998, and Daniel M. Gordon, "A Survey of Fast Exponentiation
2345 Methods", Journal of Algorithms, Vol. 27, pp. 129-146, 1998. */
2347 /* Provide a default value for POWI_MAX_MULTS, the maximum number of
2348 multiplications to inline before calling the system library's pow
2349 function. powi(x,n) requires at worst 2*bits(n)-2 multiplications,
2350 so this default never requires calling pow, powf or powl. */
2352 #ifndef POWI_MAX_MULTS
2353 #define POWI_MAX_MULTS (2*HOST_BITS_PER_WIDE_INT-2)
2356 /* The size of the "optimal power tree" lookup table. All
2357 exponents less than this value are simply looked up in the
2358 powi_table below. This threshold is also used to size the
2359 cache of pseudo registers that hold intermediate results. */
2360 #define POWI_TABLE_SIZE 256
2362 /* The size, in bits of the window, used in the "window method"
2363 exponentiation algorithm. This is equivalent to a radix of
2364 (1<<POWI_WINDOW_SIZE) in the corresponding "m-ary method". */
2365 #define POWI_WINDOW_SIZE 3
2367 /* The following table is an efficient representation of an
2368 "optimal power tree". For each value, i, the corresponding
2369 value, j, in the table states than an optimal evaluation
2370 sequence for calculating pow(x,i) can be found by evaluating
2371 pow(x,j)*pow(x,i-j). An optimal power tree for the first
2372 100 integers is given in Knuth's "Seminumerical algorithms". */
2374 static const unsigned char powi_table
[POWI_TABLE_SIZE
] =
2376 0, 1, 1, 2, 2, 3, 3, 4, /* 0 - 7 */
2377 4, 6, 5, 6, 6, 10, 7, 9, /* 8 - 15 */
2378 8, 16, 9, 16, 10, 12, 11, 13, /* 16 - 23 */
2379 12, 17, 13, 18, 14, 24, 15, 26, /* 24 - 31 */
2380 16, 17, 17, 19, 18, 33, 19, 26, /* 32 - 39 */
2381 20, 25, 21, 40, 22, 27, 23, 44, /* 40 - 47 */
2382 24, 32, 25, 34, 26, 29, 27, 44, /* 48 - 55 */
2383 28, 31, 29, 34, 30, 60, 31, 36, /* 56 - 63 */
2384 32, 64, 33, 34, 34, 46, 35, 37, /* 64 - 71 */
2385 36, 65, 37, 50, 38, 48, 39, 69, /* 72 - 79 */
2386 40, 49, 41, 43, 42, 51, 43, 58, /* 80 - 87 */
2387 44, 64, 45, 47, 46, 59, 47, 76, /* 88 - 95 */
2388 48, 65, 49, 66, 50, 67, 51, 66, /* 96 - 103 */
2389 52, 70, 53, 74, 54, 104, 55, 74, /* 104 - 111 */
2390 56, 64, 57, 69, 58, 78, 59, 68, /* 112 - 119 */
2391 60, 61, 61, 80, 62, 75, 63, 68, /* 120 - 127 */
2392 64, 65, 65, 128, 66, 129, 67, 90, /* 128 - 135 */
2393 68, 73, 69, 131, 70, 94, 71, 88, /* 136 - 143 */
2394 72, 128, 73, 98, 74, 132, 75, 121, /* 144 - 151 */
2395 76, 102, 77, 124, 78, 132, 79, 106, /* 152 - 159 */
2396 80, 97, 81, 160, 82, 99, 83, 134, /* 160 - 167 */
2397 84, 86, 85, 95, 86, 160, 87, 100, /* 168 - 175 */
2398 88, 113, 89, 98, 90, 107, 91, 122, /* 176 - 183 */
2399 92, 111, 93, 102, 94, 126, 95, 150, /* 184 - 191 */
2400 96, 128, 97, 130, 98, 133, 99, 195, /* 192 - 199 */
2401 100, 128, 101, 123, 102, 164, 103, 138, /* 200 - 207 */
2402 104, 145, 105, 146, 106, 109, 107, 149, /* 208 - 215 */
2403 108, 200, 109, 146, 110, 170, 111, 157, /* 216 - 223 */
2404 112, 128, 113, 130, 114, 182, 115, 132, /* 224 - 231 */
2405 116, 200, 117, 132, 118, 158, 119, 206, /* 232 - 239 */
2406 120, 240, 121, 162, 122, 147, 123, 152, /* 240 - 247 */
2407 124, 166, 125, 214, 126, 138, 127, 153, /* 248 - 255 */
2411 /* Return the number of multiplications required to calculate
2412 powi(x,n) where n is less than POWI_TABLE_SIZE. This is a
2413 subroutine of powi_cost. CACHE is an array indicating
2414 which exponents have already been calculated. */
2417 powi_lookup_cost (unsigned HOST_WIDE_INT n
, bool *cache
)
2419 /* If we've already calculated this exponent, then this evaluation
2420 doesn't require any additional multiplications. */
2425 return powi_lookup_cost (n
- powi_table
[n
], cache
)
2426 + powi_lookup_cost (powi_table
[n
], cache
) + 1;
2429 /* Return the number of multiplications required to calculate
2430 powi(x,n) for an arbitrary x, given the exponent N. This
2431 function needs to be kept in sync with expand_powi below. */
2434 powi_cost (HOST_WIDE_INT n
)
2436 bool cache
[POWI_TABLE_SIZE
];
2437 unsigned HOST_WIDE_INT digit
;
2438 unsigned HOST_WIDE_INT val
;
2444 /* Ignore the reciprocal when calculating the cost. */
2445 val
= (n
< 0) ? -n
: n
;
2447 /* Initialize the exponent cache. */
2448 memset (cache
, 0, POWI_TABLE_SIZE
* sizeof (bool));
2453 while (val
>= POWI_TABLE_SIZE
)
2457 digit
= val
& ((1 << POWI_WINDOW_SIZE
) - 1);
2458 result
+= powi_lookup_cost (digit
, cache
)
2459 + POWI_WINDOW_SIZE
+ 1;
2460 val
>>= POWI_WINDOW_SIZE
;
2469 return result
+ powi_lookup_cost (val
, cache
);
2472 /* Recursive subroutine of expand_powi. This function takes the array,
2473 CACHE, of already calculated exponents and an exponent N and returns
2474 an RTX that corresponds to CACHE[1]**N, as calculated in mode MODE. */
2477 expand_powi_1 (enum machine_mode mode
, unsigned HOST_WIDE_INT n
, rtx
*cache
)
2479 unsigned HOST_WIDE_INT digit
;
2483 if (n
< POWI_TABLE_SIZE
)
2488 target
= gen_reg_rtx (mode
);
2491 op0
= expand_powi_1 (mode
, n
- powi_table
[n
], cache
);
2492 op1
= expand_powi_1 (mode
, powi_table
[n
], cache
);
2496 target
= gen_reg_rtx (mode
);
2497 digit
= n
& ((1 << POWI_WINDOW_SIZE
) - 1);
2498 op0
= expand_powi_1 (mode
, n
- digit
, cache
);
2499 op1
= expand_powi_1 (mode
, digit
, cache
);
2503 target
= gen_reg_rtx (mode
);
2504 op0
= expand_powi_1 (mode
, n
>> 1, cache
);
2508 result
= expand_mult (mode
, op0
, op1
, target
, 0);
2509 if (result
!= target
)
2510 emit_move_insn (target
, result
);
2514 /* Expand the RTL to evaluate powi(x,n) in mode MODE. X is the
2515 floating point operand in mode MODE, and N is the exponent. This
2516 function needs to be kept in sync with powi_cost above. */
2519 expand_powi (rtx x
, enum machine_mode mode
, HOST_WIDE_INT n
)
2521 unsigned HOST_WIDE_INT val
;
2522 rtx cache
[POWI_TABLE_SIZE
];
2526 return CONST1_RTX (mode
);
2528 val
= (n
< 0) ? -n
: n
;
2530 memset (cache
, 0, sizeof (cache
));
2533 result
= expand_powi_1 (mode
, (n
< 0) ? -n
: n
, cache
);
2535 /* If the original exponent was negative, reciprocate the result. */
2537 result
= expand_binop (mode
, sdiv_optab
, CONST1_RTX (mode
),
2538 result
, NULL_RTX
, 0, OPTAB_LIB_WIDEN
);
2543 /* Expand a call to the pow built-in mathematical function. Return 0 if
2544 a normal call should be emitted rather than expanding the function
2545 in-line. EXP is the expression that is a call to the builtin
2546 function; if convenient, the result should be placed in TARGET. */
2549 expand_builtin_pow (tree exp
, rtx target
, rtx subtarget
)
2551 tree arglist
= TREE_OPERAND (exp
, 1);
2554 if (! validate_arglist (arglist
, REAL_TYPE
, REAL_TYPE
, VOID_TYPE
))
2557 arg0
= TREE_VALUE (arglist
);
2558 arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
2560 if (TREE_CODE (arg1
) == REAL_CST
2561 && ! TREE_CONSTANT_OVERFLOW (arg1
))
2563 REAL_VALUE_TYPE cint
;
2567 c
= TREE_REAL_CST (arg1
);
2568 n
= real_to_integer (&c
);
2569 real_from_integer (&cint
, VOIDmode
, n
, n
< 0 ? -1 : 0, 0);
2570 if (real_identical (&c
, &cint
))
2572 /* If the exponent is -1, 0, 1 or 2, then expand_powi is exact.
2573 Otherwise, check the number of multiplications required.
2574 Note that pow never sets errno for an integer exponent. */
2575 if ((n
>= -1 && n
<= 2)
2576 || (flag_unsafe_math_optimizations
2578 && powi_cost (n
) <= POWI_MAX_MULTS
))
2580 enum machine_mode mode
= TYPE_MODE (TREE_TYPE (exp
));
2581 rtx op
= expand_expr (arg0
, subtarget
, VOIDmode
, 0);
2582 op
= force_reg (mode
, op
);
2583 return expand_powi (op
, mode
, n
);
2588 if (! flag_unsafe_math_optimizations
)
2590 return expand_builtin_mathfn_2 (exp
, target
, subtarget
);
2593 /* Expand a call to the powi built-in mathematical function. Return 0 if
2594 a normal call should be emitted rather than expanding the function
2595 in-line. EXP is the expression that is a call to the builtin
2596 function; if convenient, the result should be placed in TARGET. */
2599 expand_builtin_powi (tree exp
, rtx target
, rtx subtarget
)
2601 tree arglist
= TREE_OPERAND (exp
, 1);
2604 enum machine_mode mode
;
2605 enum machine_mode mode2
;
2607 if (! validate_arglist (arglist
, REAL_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
2610 arg0
= TREE_VALUE (arglist
);
2611 arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
2612 mode
= TYPE_MODE (TREE_TYPE (exp
));
2614 /* Handle constant power. */
2616 if (TREE_CODE (arg1
) == INTEGER_CST
2617 && ! TREE_CONSTANT_OVERFLOW (arg1
))
2619 HOST_WIDE_INT n
= TREE_INT_CST_LOW (arg1
);
2621 /* If the exponent is -1, 0, 1 or 2, then expand_powi is exact.
2622 Otherwise, check the number of multiplications required. */
2623 if ((TREE_INT_CST_HIGH (arg1
) == 0
2624 || TREE_INT_CST_HIGH (arg1
) == -1)
2625 && ((n
>= -1 && n
<= 2)
2627 && powi_cost (n
) <= POWI_MAX_MULTS
)))
2629 op0
= expand_expr (arg0
, subtarget
, VOIDmode
, 0);
2630 op0
= force_reg (mode
, op0
);
2631 return expand_powi (op0
, mode
, n
);
2635 /* Emit a libcall to libgcc. */
2637 /* Mode of the 2nd argument must match that of an int. */
2638 mode2
= mode_for_size (INT_TYPE_SIZE
, MODE_INT
, 0);
2640 if (target
== NULL_RTX
)
2641 target
= gen_reg_rtx (mode
);
2643 op0
= expand_expr (arg0
, subtarget
, mode
, 0);
2644 if (GET_MODE (op0
) != mode
)
2645 op0
= convert_to_mode (mode
, op0
, 0);
2646 op1
= expand_expr (arg1
, 0, mode2
, 0);
2647 if (GET_MODE (op1
) != mode2
)
2648 op1
= convert_to_mode (mode2
, op1
, 0);
2650 target
= emit_library_call_value (powi_optab
->handlers
[(int) mode
].libfunc
,
2651 target
, LCT_CONST_MAKE_BLOCK
, mode
, 2,
2652 op0
, mode
, op1
, mode2
);
2657 /* Expand expression EXP which is a call to the strlen builtin. Return 0
2658 if we failed the caller should emit a normal call, otherwise
2659 try to get the result in TARGET, if convenient. */
2662 expand_builtin_strlen (tree arglist
, rtx target
,
2663 enum machine_mode target_mode
)
2665 if (!validate_arglist (arglist
, POINTER_TYPE
, VOID_TYPE
))
2670 tree len
, src
= TREE_VALUE (arglist
);
2671 rtx result
, src_reg
, char_rtx
, before_strlen
;
2672 enum machine_mode insn_mode
= target_mode
, char_mode
;
2673 enum insn_code icode
= CODE_FOR_nothing
;
2676 /* If the length can be computed at compile-time, return it. */
2677 len
= c_strlen (src
, 0);
2679 return expand_expr (len
, target
, target_mode
, EXPAND_NORMAL
);
2681 /* If the length can be computed at compile-time and is constant
2682 integer, but there are side-effects in src, evaluate
2683 src for side-effects, then return len.
2684 E.g. x = strlen (i++ ? "xfoo" + 1 : "bar");
2685 can be optimized into: i++; x = 3; */
2686 len
= c_strlen (src
, 1);
2687 if (len
&& TREE_CODE (len
) == INTEGER_CST
)
2689 expand_expr (src
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
2690 return expand_expr (len
, target
, target_mode
, EXPAND_NORMAL
);
2693 align
= get_pointer_alignment (src
, BIGGEST_ALIGNMENT
) / BITS_PER_UNIT
;
2695 /* If SRC is not a pointer type, don't do this operation inline. */
2699 /* Bail out if we can't compute strlen in the right mode. */
2700 while (insn_mode
!= VOIDmode
)
2702 icode
= strlen_optab
->handlers
[(int) insn_mode
].insn_code
;
2703 if (icode
!= CODE_FOR_nothing
)
2706 insn_mode
= GET_MODE_WIDER_MODE (insn_mode
);
2708 if (insn_mode
== VOIDmode
)
2711 /* Make a place to write the result of the instruction. */
2715 && GET_MODE (result
) == insn_mode
2716 && REGNO (result
) >= FIRST_PSEUDO_REGISTER
))
2717 result
= gen_reg_rtx (insn_mode
);
2719 /* Make a place to hold the source address. We will not expand
2720 the actual source until we are sure that the expansion will
2721 not fail -- there are trees that cannot be expanded twice. */
2722 src_reg
= gen_reg_rtx (Pmode
);
2724 /* Mark the beginning of the strlen sequence so we can emit the
2725 source operand later. */
2726 before_strlen
= get_last_insn ();
2728 char_rtx
= const0_rtx
;
2729 char_mode
= insn_data
[(int) icode
].operand
[2].mode
;
2730 if (! (*insn_data
[(int) icode
].operand
[2].predicate
) (char_rtx
,
2732 char_rtx
= copy_to_mode_reg (char_mode
, char_rtx
);
2734 pat
= GEN_FCN (icode
) (result
, gen_rtx_MEM (BLKmode
, src_reg
),
2735 char_rtx
, GEN_INT (align
));
2740 /* Now that we are assured of success, expand the source. */
2742 pat
= expand_expr (src
, src_reg
, ptr_mode
, EXPAND_NORMAL
);
2744 emit_move_insn (src_reg
, pat
);
2749 emit_insn_after (pat
, before_strlen
);
2751 emit_insn_before (pat
, get_insns ());
2753 /* Return the value in the proper mode for this function. */
2754 if (GET_MODE (result
) == target_mode
)
2756 else if (target
!= 0)
2757 convert_move (target
, result
, 0);
2759 target
= convert_to_mode (target_mode
, result
, 0);
2765 /* Expand a call to the strstr builtin. Return 0 if we failed the
2766 caller should emit a normal call, otherwise try to get the result
2767 in TARGET, if convenient (and in mode MODE if that's convenient). */
2770 expand_builtin_strstr (tree arglist
, tree type
, rtx target
, enum machine_mode mode
)
2772 if (validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
2774 tree result
= fold_builtin_strstr (arglist
, type
);
2776 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
2781 /* Expand a call to the strchr builtin. Return 0 if we failed the
2782 caller should emit a normal call, otherwise try to get the result
2783 in TARGET, if convenient (and in mode MODE if that's convenient). */
2786 expand_builtin_strchr (tree arglist
, tree type
, rtx target
, enum machine_mode mode
)
2788 if (validate_arglist (arglist
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
2790 tree result
= fold_builtin_strchr (arglist
, type
);
2792 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
2794 /* FIXME: Should use strchrM optab so that ports can optimize this. */
2799 /* Expand a call to the strrchr builtin. Return 0 if we failed the
2800 caller should emit a normal call, otherwise try to get the result
2801 in TARGET, if convenient (and in mode MODE if that's convenient). */
2804 expand_builtin_strrchr (tree arglist
, tree type
, rtx target
, enum machine_mode mode
)
2806 if (validate_arglist (arglist
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
2808 tree result
= fold_builtin_strrchr (arglist
, type
);
2810 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
2815 /* Expand a call to the strpbrk builtin. Return 0 if we failed the
2816 caller should emit a normal call, otherwise try to get the result
2817 in TARGET, if convenient (and in mode MODE if that's convenient). */
2820 expand_builtin_strpbrk (tree arglist
, tree type
, rtx target
, enum machine_mode mode
)
2822 if (validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
2824 tree result
= fold_builtin_strpbrk (arglist
, type
);
2826 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
2831 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
2832 bytes from constant string DATA + OFFSET and return it as target
2836 builtin_memcpy_read_str (void *data
, HOST_WIDE_INT offset
,
2837 enum machine_mode mode
)
2839 const char *str
= (const char *) data
;
2841 gcc_assert (offset
>= 0
2842 && ((unsigned HOST_WIDE_INT
) offset
+ GET_MODE_SIZE (mode
)
2843 <= strlen (str
) + 1));
2845 return c_readstr (str
+ offset
, mode
);
2848 /* Expand a call to the memcpy builtin, with arguments in ARGLIST.
2849 Return 0 if we failed, the caller should emit a normal call,
2850 otherwise try to get the result in TARGET, if convenient (and in
2851 mode MODE if that's convenient). */
2853 expand_builtin_memcpy (tree exp
, rtx target
, enum machine_mode mode
)
2855 tree fndecl
= get_callee_fndecl (exp
);
2856 tree arglist
= TREE_OPERAND (exp
, 1);
2857 if (!validate_arglist (arglist
,
2858 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
2862 tree dest
= TREE_VALUE (arglist
);
2863 tree src
= TREE_VALUE (TREE_CHAIN (arglist
));
2864 tree len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
2865 const char *src_str
;
2866 unsigned int src_align
= get_pointer_alignment (src
, BIGGEST_ALIGNMENT
);
2867 unsigned int dest_align
2868 = get_pointer_alignment (dest
, BIGGEST_ALIGNMENT
);
2869 rtx dest_mem
, src_mem
, dest_addr
, len_rtx
;
2870 tree result
= fold_builtin_memcpy (fndecl
, arglist
);
2873 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
2875 /* If DEST is not a pointer type, call the normal function. */
2876 if (dest_align
== 0)
2879 /* If either SRC is not a pointer type, don't do this
2880 operation in-line. */
2884 dest_mem
= get_memory_rtx (dest
, len
);
2885 set_mem_align (dest_mem
, dest_align
);
2886 len_rtx
= expand_expr (len
, NULL_RTX
, VOIDmode
, 0);
2887 src_str
= c_getstr (src
);
2889 /* If SRC is a string constant and block move would be done
2890 by pieces, we can avoid loading the string from memory
2891 and only stored the computed constants. */
2893 && GET_CODE (len_rtx
) == CONST_INT
2894 && (unsigned HOST_WIDE_INT
) INTVAL (len_rtx
) <= strlen (src_str
) + 1
2895 && can_store_by_pieces (INTVAL (len_rtx
), builtin_memcpy_read_str
,
2896 (void *) src_str
, dest_align
))
2898 dest_mem
= store_by_pieces (dest_mem
, INTVAL (len_rtx
),
2899 builtin_memcpy_read_str
,
2900 (void *) src_str
, dest_align
, 0);
2901 dest_mem
= force_operand (XEXP (dest_mem
, 0), NULL_RTX
);
2902 dest_mem
= convert_memory_address (ptr_mode
, dest_mem
);
2906 src_mem
= get_memory_rtx (src
, len
);
2907 set_mem_align (src_mem
, src_align
);
2909 /* Copy word part most expediently. */
2910 dest_addr
= emit_block_move (dest_mem
, src_mem
, len_rtx
,
2911 CALL_EXPR_TAILCALL (exp
)
2912 ? BLOCK_OP_TAILCALL
: BLOCK_OP_NORMAL
);
2916 dest_addr
= force_operand (XEXP (dest_mem
, 0), NULL_RTX
);
2917 dest_addr
= convert_memory_address (ptr_mode
, dest_addr
);
2923 /* Expand a call to the mempcpy builtin, with arguments in ARGLIST.
2924 Return 0 if we failed; the caller should emit a normal call,
2925 otherwise try to get the result in TARGET, if convenient (and in
2926 mode MODE if that's convenient). If ENDP is 0 return the
2927 destination pointer, if ENDP is 1 return the end pointer ala
2928 mempcpy, and if ENDP is 2 return the end pointer minus one ala
2932 expand_builtin_mempcpy (tree arglist
, tree type
, rtx target
, enum machine_mode mode
,
2935 if (!validate_arglist (arglist
,
2936 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
2938 /* If return value is ignored, transform mempcpy into memcpy. */
2939 else if (target
== const0_rtx
)
2941 tree fn
= implicit_built_in_decls
[BUILT_IN_MEMCPY
];
2946 return expand_expr (build_function_call_expr (fn
, arglist
),
2947 target
, mode
, EXPAND_NORMAL
);
2951 tree dest
= TREE_VALUE (arglist
);
2952 tree src
= TREE_VALUE (TREE_CHAIN (arglist
));
2953 tree len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
2954 const char *src_str
;
2955 unsigned int src_align
= get_pointer_alignment (src
, BIGGEST_ALIGNMENT
);
2956 unsigned int dest_align
2957 = get_pointer_alignment (dest
, BIGGEST_ALIGNMENT
);
2958 rtx dest_mem
, src_mem
, len_rtx
;
2959 tree result
= fold_builtin_mempcpy (arglist
, type
, endp
);
2962 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
2964 /* If either SRC or DEST is not a pointer type, don't do this
2965 operation in-line. */
2966 if (dest_align
== 0 || src_align
== 0)
2969 /* If LEN is not constant, call the normal function. */
2970 if (! host_integerp (len
, 1))
2973 len_rtx
= expand_expr (len
, NULL_RTX
, VOIDmode
, 0);
2974 src_str
= c_getstr (src
);
2976 /* If SRC is a string constant and block move would be done
2977 by pieces, we can avoid loading the string from memory
2978 and only stored the computed constants. */
2980 && GET_CODE (len_rtx
) == CONST_INT
2981 && (unsigned HOST_WIDE_INT
) INTVAL (len_rtx
) <= strlen (src_str
) + 1
2982 && can_store_by_pieces (INTVAL (len_rtx
), builtin_memcpy_read_str
,
2983 (void *) src_str
, dest_align
))
2985 dest_mem
= get_memory_rtx (dest
, len
);
2986 set_mem_align (dest_mem
, dest_align
);
2987 dest_mem
= store_by_pieces (dest_mem
, INTVAL (len_rtx
),
2988 builtin_memcpy_read_str
,
2989 (void *) src_str
, dest_align
, endp
);
2990 dest_mem
= force_operand (XEXP (dest_mem
, 0), NULL_RTX
);
2991 dest_mem
= convert_memory_address (ptr_mode
, dest_mem
);
2995 if (GET_CODE (len_rtx
) == CONST_INT
2996 && can_move_by_pieces (INTVAL (len_rtx
),
2997 MIN (dest_align
, src_align
)))
2999 dest_mem
= get_memory_rtx (dest
, len
);
3000 set_mem_align (dest_mem
, dest_align
);
3001 src_mem
= get_memory_rtx (src
, len
);
3002 set_mem_align (src_mem
, src_align
);
3003 dest_mem
= move_by_pieces (dest_mem
, src_mem
, INTVAL (len_rtx
),
3004 MIN (dest_align
, src_align
), endp
);
3005 dest_mem
= force_operand (XEXP (dest_mem
, 0), NULL_RTX
);
3006 dest_mem
= convert_memory_address (ptr_mode
, dest_mem
);
3014 /* Expand expression EXP, which is a call to the memmove builtin. Return 0
3015 if we failed; the caller should emit a normal call. */
3018 expand_builtin_memmove (tree arglist
, tree type
, rtx target
,
3019 enum machine_mode mode
, tree orig_exp
)
3021 if (!validate_arglist (arglist
,
3022 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
3026 tree dest
= TREE_VALUE (arglist
);
3027 tree src
= TREE_VALUE (TREE_CHAIN (arglist
));
3028 tree len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
3030 unsigned int src_align
= get_pointer_alignment (src
, BIGGEST_ALIGNMENT
);
3031 unsigned int dest_align
3032 = get_pointer_alignment (dest
, BIGGEST_ALIGNMENT
);
3033 tree result
= fold_builtin_memmove (arglist
, type
);
3036 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
3038 /* If DEST is not a pointer type, call the normal function. */
3039 if (dest_align
== 0)
3042 /* If either SRC is not a pointer type, don't do this
3043 operation in-line. */
3047 /* If src is categorized for a readonly section we can use
3049 if (readonly_data_expr (src
))
3051 tree fn
= implicit_built_in_decls
[BUILT_IN_MEMCPY
];
3054 fn
= build_function_call_expr (fn
, arglist
);
3055 if (TREE_CODE (fn
) == CALL_EXPR
)
3056 CALL_EXPR_TAILCALL (fn
) = CALL_EXPR_TAILCALL (orig_exp
);
3057 return expand_expr (fn
, target
, mode
, EXPAND_NORMAL
);
3060 /* If length is 1 and we can expand memcpy call inline,
3061 it is ok to use memcpy as well. */
3062 if (integer_onep (len
))
3064 rtx ret
= expand_builtin_mempcpy (arglist
, type
, target
, mode
,
3070 /* Otherwise, call the normal function. */
3075 /* Expand expression EXP, which is a call to the bcopy builtin. Return 0
3076 if we failed the caller should emit a normal call. */
3079 expand_builtin_bcopy (tree exp
)
3081 tree arglist
= TREE_OPERAND (exp
, 1);
3082 tree type
= TREE_TYPE (exp
);
3083 tree src
, dest
, size
, newarglist
;
3085 if (!validate_arglist (arglist
,
3086 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
3089 src
= TREE_VALUE (arglist
);
3090 dest
= TREE_VALUE (TREE_CHAIN (arglist
));
3091 size
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
3093 /* New argument list transforming bcopy(ptr x, ptr y, int z) to
3094 memmove(ptr y, ptr x, size_t z). This is done this way
3095 so that if it isn't expanded inline, we fallback to
3096 calling bcopy instead of memmove. */
3098 newarglist
= build_tree_list (NULL_TREE
, fold_convert (sizetype
, size
));
3099 newarglist
= tree_cons (NULL_TREE
, src
, newarglist
);
3100 newarglist
= tree_cons (NULL_TREE
, dest
, newarglist
);
3102 return expand_builtin_memmove (newarglist
, type
, const0_rtx
, VOIDmode
, exp
);
3106 # define HAVE_movstr 0
3107 # define CODE_FOR_movstr CODE_FOR_nothing
3110 /* Expand into a movstr instruction, if one is available. Return 0 if
3111 we failed, the caller should emit a normal call, otherwise try to
3112 get the result in TARGET, if convenient. If ENDP is 0 return the
3113 destination pointer, if ENDP is 1 return the end pointer ala
3114 mempcpy, and if ENDP is 2 return the end pointer minus one ala
3118 expand_movstr (tree dest
, tree src
, rtx target
, int endp
)
3124 const struct insn_data
* data
;
3129 dest_mem
= get_memory_rtx (dest
, NULL
);
3130 src_mem
= get_memory_rtx (src
, NULL
);
3133 target
= force_reg (Pmode
, XEXP (dest_mem
, 0));
3134 dest_mem
= replace_equiv_address (dest_mem
, target
);
3135 end
= gen_reg_rtx (Pmode
);
3139 if (target
== 0 || target
== const0_rtx
)
3141 end
= gen_reg_rtx (Pmode
);
3149 data
= insn_data
+ CODE_FOR_movstr
;
3151 if (data
->operand
[0].mode
!= VOIDmode
)
3152 end
= gen_lowpart (data
->operand
[0].mode
, end
);
3154 insn
= data
->genfun (end
, dest_mem
, src_mem
);
3160 /* movstr is supposed to set end to the address of the NUL
3161 terminator. If the caller requested a mempcpy-like return value,
3163 if (endp
== 1 && target
!= const0_rtx
)
3165 rtx tem
= plus_constant (gen_lowpart (GET_MODE (target
), end
), 1);
3166 emit_move_insn (target
, force_operand (tem
, NULL_RTX
));
3172 /* Expand expression EXP, which is a call to the strcpy builtin. Return 0
3173 if we failed the caller should emit a normal call, otherwise try to get
3174 the result in TARGET, if convenient (and in mode MODE if that's
3178 expand_builtin_strcpy (tree fndecl
, tree arglist
, rtx target
, enum machine_mode mode
)
3180 if (validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
3182 tree result
= fold_builtin_strcpy (fndecl
, arglist
, 0);
3184 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
3186 return expand_movstr (TREE_VALUE (arglist
),
3187 TREE_VALUE (TREE_CHAIN (arglist
)),
3188 target
, /*endp=*/0);
3193 /* Expand a call to the stpcpy builtin, with arguments in ARGLIST.
3194 Return 0 if we failed the caller should emit a normal call,
3195 otherwise try to get the result in TARGET, if convenient (and in
3196 mode MODE if that's convenient). */
3199 expand_builtin_stpcpy (tree exp
, rtx target
, enum machine_mode mode
)
3201 tree arglist
= TREE_OPERAND (exp
, 1);
3202 /* If return value is ignored, transform stpcpy into strcpy. */
3203 if (target
== const0_rtx
)
3205 tree fn
= implicit_built_in_decls
[BUILT_IN_STRCPY
];
3209 return expand_expr (build_function_call_expr (fn
, arglist
),
3210 target
, mode
, EXPAND_NORMAL
);
3213 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
3217 tree dst
, src
, len
, lenp1
;
3221 /* Ensure we get an actual string whose length can be evaluated at
3222 compile-time, not an expression containing a string. This is
3223 because the latter will potentially produce pessimized code
3224 when used to produce the return value. */
3225 src
= TREE_VALUE (TREE_CHAIN (arglist
));
3226 if (! c_getstr (src
) || ! (len
= c_strlen (src
, 0)))
3227 return expand_movstr (TREE_VALUE (arglist
),
3228 TREE_VALUE (TREE_CHAIN (arglist
)),
3229 target
, /*endp=*/2);
3231 dst
= TREE_VALUE (arglist
);
3232 lenp1
= size_binop (PLUS_EXPR
, len
, ssize_int (1));
3233 narglist
= build_tree_list (NULL_TREE
, lenp1
);
3234 narglist
= tree_cons (NULL_TREE
, src
, narglist
);
3235 narglist
= tree_cons (NULL_TREE
, dst
, narglist
);
3236 ret
= expand_builtin_mempcpy (narglist
, TREE_TYPE (exp
),
3237 target
, mode
, /*endp=*/2);
3242 if (TREE_CODE (len
) == INTEGER_CST
)
3244 rtx len_rtx
= expand_expr (len
, NULL_RTX
, VOIDmode
, 0);
3246 if (GET_CODE (len_rtx
) == CONST_INT
)
3248 ret
= expand_builtin_strcpy (get_callee_fndecl (exp
),
3249 arglist
, target
, mode
);
3255 if (mode
!= VOIDmode
)
3256 target
= gen_reg_rtx (mode
);
3258 target
= gen_reg_rtx (GET_MODE (ret
));
3260 if (GET_MODE (target
) != GET_MODE (ret
))
3261 ret
= gen_lowpart (GET_MODE (target
), ret
);
3263 ret
= plus_constant (ret
, INTVAL (len_rtx
));
3264 ret
= emit_move_insn (target
, force_operand (ret
, NULL_RTX
));
3272 return expand_movstr (TREE_VALUE (arglist
),
3273 TREE_VALUE (TREE_CHAIN (arglist
)),
3274 target
, /*endp=*/2);
3278 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
3279 bytes from constant string DATA + OFFSET and return it as target
3283 builtin_strncpy_read_str (void *data
, HOST_WIDE_INT offset
,
3284 enum machine_mode mode
)
3286 const char *str
= (const char *) data
;
3288 if ((unsigned HOST_WIDE_INT
) offset
> strlen (str
))
3291 return c_readstr (str
+ offset
, mode
);
3294 /* Expand expression EXP, which is a call to the strncpy builtin. Return 0
3295 if we failed the caller should emit a normal call. */
3298 expand_builtin_strncpy (tree exp
, rtx target
, enum machine_mode mode
)
3300 tree fndecl
= get_callee_fndecl (exp
);
3301 tree arglist
= TREE_OPERAND (exp
, 1);
3302 if (validate_arglist (arglist
,
3303 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
3305 tree slen
= c_strlen (TREE_VALUE (TREE_CHAIN (arglist
)), 1);
3306 tree len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
3307 tree result
= fold_builtin_strncpy (fndecl
, arglist
, slen
);
3310 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
3312 /* We must be passed a constant len and src parameter. */
3313 if (!host_integerp (len
, 1) || !slen
|| !host_integerp (slen
, 1))
3316 slen
= size_binop (PLUS_EXPR
, slen
, ssize_int (1));
3318 /* We're required to pad with trailing zeros if the requested
3319 len is greater than strlen(s2)+1. In that case try to
3320 use store_by_pieces, if it fails, punt. */
3321 if (tree_int_cst_lt (slen
, len
))
3323 tree dest
= TREE_VALUE (arglist
);
3324 unsigned int dest_align
3325 = get_pointer_alignment (dest
, BIGGEST_ALIGNMENT
);
3326 const char *p
= c_getstr (TREE_VALUE (TREE_CHAIN (arglist
)));
3329 if (!p
|| dest_align
== 0 || !host_integerp (len
, 1)
3330 || !can_store_by_pieces (tree_low_cst (len
, 1),
3331 builtin_strncpy_read_str
,
3332 (void *) p
, dest_align
))
3335 dest_mem
= get_memory_rtx (dest
, len
);
3336 store_by_pieces (dest_mem
, tree_low_cst (len
, 1),
3337 builtin_strncpy_read_str
,
3338 (void *) p
, dest_align
, 0);
3339 dest_mem
= force_operand (XEXP (dest_mem
, 0), NULL_RTX
);
3340 dest_mem
= convert_memory_address (ptr_mode
, dest_mem
);
3347 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
3348 bytes from constant string DATA + OFFSET and return it as target
3352 builtin_memset_read_str (void *data
, HOST_WIDE_INT offset ATTRIBUTE_UNUSED
,
3353 enum machine_mode mode
)
3355 const char *c
= (const char *) data
;
3356 char *p
= alloca (GET_MODE_SIZE (mode
));
3358 memset (p
, *c
, GET_MODE_SIZE (mode
));
3360 return c_readstr (p
, mode
);
3363 /* Callback routine for store_by_pieces. Return the RTL of a register
3364 containing GET_MODE_SIZE (MODE) consecutive copies of the unsigned
3365 char value given in the RTL register data. For example, if mode is
3366 4 bytes wide, return the RTL for 0x01010101*data. */
3369 builtin_memset_gen_str (void *data
, HOST_WIDE_INT offset ATTRIBUTE_UNUSED
,
3370 enum machine_mode mode
)
3376 size
= GET_MODE_SIZE (mode
);
3381 memset (p
, 1, size
);
3382 coeff
= c_readstr (p
, mode
);
3384 target
= convert_to_mode (mode
, (rtx
) data
, 1);
3385 target
= expand_mult (mode
, target
, coeff
, NULL_RTX
, 1);
3386 return force_reg (mode
, target
);
3389 /* Expand expression EXP, which is a call to the memset builtin. Return 0
3390 if we failed the caller should emit a normal call, otherwise try to get
3391 the result in TARGET, if convenient (and in mode MODE if that's
3395 expand_builtin_memset (tree arglist
, rtx target
, enum machine_mode mode
,
3398 if (!validate_arglist (arglist
,
3399 POINTER_TYPE
, INTEGER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
3403 tree dest
= TREE_VALUE (arglist
);
3404 tree val
= TREE_VALUE (TREE_CHAIN (arglist
));
3405 tree len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
3408 unsigned int dest_align
3409 = get_pointer_alignment (dest
, BIGGEST_ALIGNMENT
);
3410 rtx dest_mem
, dest_addr
, len_rtx
;
3412 /* If DEST is not a pointer type, don't do this
3413 operation in-line. */
3414 if (dest_align
== 0)
3417 /* If the LEN parameter is zero, return DEST. */
3418 if (integer_zerop (len
))
3420 /* Evaluate and ignore VAL in case it has side-effects. */
3421 expand_expr (val
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
3422 return expand_expr (dest
, target
, mode
, EXPAND_NORMAL
);
3425 len_rtx
= expand_expr (len
, NULL_RTX
, VOIDmode
, 0);
3426 dest_mem
= get_memory_rtx (dest
, len
);
3428 if (TREE_CODE (val
) != INTEGER_CST
)
3432 val
= fold_build1 (CONVERT_EXPR
, unsigned_char_type_node
, val
);
3433 val_rtx
= expand_expr (val
, NULL_RTX
, VOIDmode
, 0);
3435 /* Assume that we can memset by pieces if we can store the
3436 * the coefficients by pieces (in the required modes).
3437 * We can't pass builtin_memset_gen_str as that emits RTL. */
3439 if (host_integerp (len
, 1)
3440 && !(optimize_size
&& tree_low_cst (len
, 1) > 1)
3441 && can_store_by_pieces (tree_low_cst (len
, 1),
3442 builtin_memset_read_str
, &c
, dest_align
))
3444 val_rtx
= force_reg (TYPE_MODE (unsigned_char_type_node
),
3446 store_by_pieces (dest_mem
, tree_low_cst (len
, 1),
3447 builtin_memset_gen_str
, val_rtx
, dest_align
, 0);
3449 else if (!set_storage_via_setmem(dest_mem
, len_rtx
, val_rtx
,
3453 dest_mem
= force_operand (XEXP (dest_mem
, 0), NULL_RTX
);
3454 dest_mem
= convert_memory_address (ptr_mode
, dest_mem
);
3458 if (target_char_cast (val
, &c
))
3463 if (host_integerp (len
, 1)
3464 && !(optimize_size
&& tree_low_cst (len
, 1) > 1)
3465 && can_store_by_pieces (tree_low_cst (len
, 1),
3466 builtin_memset_read_str
, &c
, dest_align
))
3467 store_by_pieces (dest_mem
, tree_low_cst (len
, 1),
3468 builtin_memset_read_str
, &c
, dest_align
, 0);
3469 else if (!set_storage_via_setmem (dest_mem
, len_rtx
, GEN_INT (c
),
3473 dest_mem
= force_operand (XEXP (dest_mem
, 0), NULL_RTX
);
3474 dest_mem
= convert_memory_address (ptr_mode
, dest_mem
);
3478 set_mem_align (dest_mem
, dest_align
);
3479 dest_addr
= clear_storage (dest_mem
, len_rtx
,
3480 CALL_EXPR_TAILCALL (orig_exp
)
3481 ? BLOCK_OP_TAILCALL
: BLOCK_OP_NORMAL
);
3485 dest_addr
= force_operand (XEXP (dest_mem
, 0), NULL_RTX
);
3486 dest_addr
= convert_memory_address (ptr_mode
, dest_addr
);
3493 /* Expand expression EXP, which is a call to the bzero builtin. Return 0
3494 if we failed the caller should emit a normal call. */
3497 expand_builtin_bzero (tree exp
)
3499 tree arglist
= TREE_OPERAND (exp
, 1);
3500 tree dest
, size
, newarglist
;
3502 if (!validate_arglist (arglist
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
3505 dest
= TREE_VALUE (arglist
);
3506 size
= TREE_VALUE (TREE_CHAIN (arglist
));
3508 /* New argument list transforming bzero(ptr x, int y) to
3509 memset(ptr x, int 0, size_t y). This is done this way
3510 so that if it isn't expanded inline, we fallback to
3511 calling bzero instead of memset. */
3513 newarglist
= build_tree_list (NULL_TREE
, fold_convert (sizetype
, size
));
3514 newarglist
= tree_cons (NULL_TREE
, integer_zero_node
, newarglist
);
3515 newarglist
= tree_cons (NULL_TREE
, dest
, newarglist
);
3517 return expand_builtin_memset (newarglist
, const0_rtx
, VOIDmode
, exp
);
3520 /* Expand expression EXP, which is a call to the memcmp built-in function.
3521 ARGLIST is the argument list for this call. Return 0 if we failed and the
3522 caller should emit a normal call, otherwise try to get the result in
3523 TARGET, if convenient (and in mode MODE, if that's convenient). */
3526 expand_builtin_memcmp (tree exp ATTRIBUTE_UNUSED
, tree arglist
, rtx target
,
3527 enum machine_mode mode
)
3529 if (!validate_arglist (arglist
,
3530 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
3534 tree result
= fold_builtin_memcmp (arglist
);
3536 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
3539 #if defined HAVE_cmpmemsi || defined HAVE_cmpstrnsi
3541 tree arg1
= TREE_VALUE (arglist
);
3542 tree arg2
= TREE_VALUE (TREE_CHAIN (arglist
));
3543 tree len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
3544 rtx arg1_rtx
, arg2_rtx
, arg3_rtx
;
3549 = get_pointer_alignment (arg1
, BIGGEST_ALIGNMENT
) / BITS_PER_UNIT
;
3551 = get_pointer_alignment (arg2
, BIGGEST_ALIGNMENT
) / BITS_PER_UNIT
;
3552 enum machine_mode insn_mode
;
3554 #ifdef HAVE_cmpmemsi
3556 insn_mode
= insn_data
[(int) CODE_FOR_cmpmemsi
].operand
[0].mode
;
3559 #ifdef HAVE_cmpstrnsi
3561 insn_mode
= insn_data
[(int) CODE_FOR_cmpstrnsi
].operand
[0].mode
;
3566 /* If we don't have POINTER_TYPE, call the function. */
3567 if (arg1_align
== 0 || arg2_align
== 0)
3570 /* Make a place to write the result of the instruction. */
3573 && REG_P (result
) && GET_MODE (result
) == insn_mode
3574 && REGNO (result
) >= FIRST_PSEUDO_REGISTER
))
3575 result
= gen_reg_rtx (insn_mode
);
3577 arg1_rtx
= get_memory_rtx (arg1
, len
);
3578 arg2_rtx
= get_memory_rtx (arg2
, len
);
3579 arg3_rtx
= expand_expr (len
, NULL_RTX
, VOIDmode
, 0);
3581 /* Set MEM_SIZE as appropriate. */
3582 if (GET_CODE (arg3_rtx
) == CONST_INT
)
3584 set_mem_size (arg1_rtx
, arg3_rtx
);
3585 set_mem_size (arg2_rtx
, arg3_rtx
);
3588 #ifdef HAVE_cmpmemsi
3590 insn
= gen_cmpmemsi (result
, arg1_rtx
, arg2_rtx
, arg3_rtx
,
3591 GEN_INT (MIN (arg1_align
, arg2_align
)));
3594 #ifdef HAVE_cmpstrnsi
3596 insn
= gen_cmpstrnsi (result
, arg1_rtx
, arg2_rtx
, arg3_rtx
,
3597 GEN_INT (MIN (arg1_align
, arg2_align
)));
3605 emit_library_call_value (memcmp_libfunc
, result
, LCT_PURE_MAKE_BLOCK
,
3606 TYPE_MODE (integer_type_node
), 3,
3607 XEXP (arg1_rtx
, 0), Pmode
,
3608 XEXP (arg2_rtx
, 0), Pmode
,
3609 convert_to_mode (TYPE_MODE (sizetype
), arg3_rtx
,
3610 TYPE_UNSIGNED (sizetype
)),
3611 TYPE_MODE (sizetype
));
3613 /* Return the value in the proper mode for this function. */
3614 mode
= TYPE_MODE (TREE_TYPE (exp
));
3615 if (GET_MODE (result
) == mode
)
3617 else if (target
!= 0)
3619 convert_move (target
, result
, 0);
3623 return convert_to_mode (mode
, result
, 0);
3630 /* Expand expression EXP, which is a call to the strcmp builtin. Return 0
3631 if we failed the caller should emit a normal call, otherwise try to get
3632 the result in TARGET, if convenient. */
3635 expand_builtin_strcmp (tree exp
, rtx target
, enum machine_mode mode
)
3637 tree arglist
= TREE_OPERAND (exp
, 1);
3639 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
3643 tree result
= fold_builtin_strcmp (arglist
);
3645 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
3648 #if defined HAVE_cmpstrsi || defined HAVE_cmpstrnsi
3649 if (cmpstr_optab
[SImode
] != CODE_FOR_nothing
3650 || cmpstrn_optab
[SImode
] != CODE_FOR_nothing
)
3652 rtx arg1_rtx
, arg2_rtx
;
3653 rtx result
, insn
= NULL_RTX
;
3656 tree arg1
= TREE_VALUE (arglist
);
3657 tree arg2
= TREE_VALUE (TREE_CHAIN (arglist
));
3659 = get_pointer_alignment (arg1
, BIGGEST_ALIGNMENT
) / BITS_PER_UNIT
;
3661 = get_pointer_alignment (arg2
, BIGGEST_ALIGNMENT
) / BITS_PER_UNIT
;
3663 /* If we don't have POINTER_TYPE, call the function. */
3664 if (arg1_align
== 0 || arg2_align
== 0)
3667 /* Stabilize the arguments in case gen_cmpstr(n)si fail. */
3668 arg1
= builtin_save_expr (arg1
);
3669 arg2
= builtin_save_expr (arg2
);
3671 arg1_rtx
= get_memory_rtx (arg1
, NULL
);
3672 arg2_rtx
= get_memory_rtx (arg2
, NULL
);
3674 #ifdef HAVE_cmpstrsi
3675 /* Try to call cmpstrsi. */
3678 enum machine_mode insn_mode
3679 = insn_data
[(int) CODE_FOR_cmpstrsi
].operand
[0].mode
;
3681 /* Make a place to write the result of the instruction. */
3684 && REG_P (result
) && GET_MODE (result
) == insn_mode
3685 && REGNO (result
) >= FIRST_PSEUDO_REGISTER
))
3686 result
= gen_reg_rtx (insn_mode
);
3688 insn
= gen_cmpstrsi (result
, arg1_rtx
, arg2_rtx
,
3689 GEN_INT (MIN (arg1_align
, arg2_align
)));
3693 /* Try to determine at least one length and call cmpstrnsi. */
3694 if (!insn
&& HAVE_cmpstrnsi
)
3699 enum machine_mode insn_mode
3700 = insn_data
[(int) CODE_FOR_cmpstrnsi
].operand
[0].mode
;
3701 tree len1
= c_strlen (arg1
, 1);
3702 tree len2
= c_strlen (arg2
, 1);
3705 len1
= size_binop (PLUS_EXPR
, ssize_int (1), len1
);
3707 len2
= size_binop (PLUS_EXPR
, ssize_int (1), len2
);
3709 /* If we don't have a constant length for the first, use the length
3710 of the second, if we know it. We don't require a constant for
3711 this case; some cost analysis could be done if both are available
3712 but neither is constant. For now, assume they're equally cheap,
3713 unless one has side effects. If both strings have constant lengths,
3720 else if (TREE_SIDE_EFFECTS (len1
))
3722 else if (TREE_SIDE_EFFECTS (len2
))
3724 else if (TREE_CODE (len1
) != INTEGER_CST
)
3726 else if (TREE_CODE (len2
) != INTEGER_CST
)
3728 else if (tree_int_cst_lt (len1
, len2
))
3733 /* If both arguments have side effects, we cannot optimize. */
3734 if (!len
|| TREE_SIDE_EFFECTS (len
))
3737 /* Stabilize the arguments in case gen_cmpstrnsi fails. */
3738 arg3_rtx
= expand_expr (len
, NULL_RTX
, VOIDmode
, 0);
3740 /* Make a place to write the result of the instruction. */
3743 && REG_P (result
) && GET_MODE (result
) == insn_mode
3744 && REGNO (result
) >= FIRST_PSEUDO_REGISTER
))
3745 result
= gen_reg_rtx (insn_mode
);
3747 insn
= gen_cmpstrnsi (result
, arg1_rtx
, arg2_rtx
, arg3_rtx
,
3748 GEN_INT (MIN (arg1_align
, arg2_align
)));
3756 /* Return the value in the proper mode for this function. */
3757 mode
= TYPE_MODE (TREE_TYPE (exp
));
3758 if (GET_MODE (result
) == mode
)
3761 return convert_to_mode (mode
, result
, 0);
3762 convert_move (target
, result
, 0);
3766 /* Expand the library call ourselves using a stabilized argument
3767 list to avoid re-evaluating the function's arguments twice. */
3768 arglist
= build_tree_list (NULL_TREE
, arg2
);
3769 arglist
= tree_cons (NULL_TREE
, arg1
, arglist
);
3770 fndecl
= get_callee_fndecl (exp
);
3771 fn
= build_function_call_expr (fndecl
, arglist
);
3772 if (TREE_CODE (fn
) == CALL_EXPR
)
3773 CALL_EXPR_TAILCALL (fn
) = CALL_EXPR_TAILCALL (exp
);
3774 return expand_call (fn
, target
, target
== const0_rtx
);
3780 /* Expand expression EXP, which is a call to the strncmp builtin. Return 0
3781 if we failed the caller should emit a normal call, otherwise try to get
3782 the result in TARGET, if convenient. */
3785 expand_builtin_strncmp (tree exp
, rtx target
, enum machine_mode mode
)
3787 tree arglist
= TREE_OPERAND (exp
, 1);
3789 if (!validate_arglist (arglist
,
3790 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
3794 tree result
= fold_builtin_strncmp (arglist
);
3796 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
3799 /* If c_strlen can determine an expression for one of the string
3800 lengths, and it doesn't have side effects, then emit cmpstrnsi
3801 using length MIN(strlen(string)+1, arg3). */
3802 #ifdef HAVE_cmpstrnsi
3805 tree arg1
= TREE_VALUE (arglist
);
3806 tree arg2
= TREE_VALUE (TREE_CHAIN (arglist
));
3807 tree arg3
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
3808 tree len
, len1
, len2
;
3809 rtx arg1_rtx
, arg2_rtx
, arg3_rtx
;
3814 = get_pointer_alignment (arg1
, BIGGEST_ALIGNMENT
) / BITS_PER_UNIT
;
3816 = get_pointer_alignment (arg2
, BIGGEST_ALIGNMENT
) / BITS_PER_UNIT
;
3817 enum machine_mode insn_mode
3818 = insn_data
[(int) CODE_FOR_cmpstrnsi
].operand
[0].mode
;
3820 len1
= c_strlen (arg1
, 1);
3821 len2
= c_strlen (arg2
, 1);
3824 len1
= size_binop (PLUS_EXPR
, ssize_int (1), len1
);
3826 len2
= size_binop (PLUS_EXPR
, ssize_int (1), len2
);
3828 /* If we don't have a constant length for the first, use the length
3829 of the second, if we know it. We don't require a constant for
3830 this case; some cost analysis could be done if both are available
3831 but neither is constant. For now, assume they're equally cheap,
3832 unless one has side effects. If both strings have constant lengths,
3839 else if (TREE_SIDE_EFFECTS (len1
))
3841 else if (TREE_SIDE_EFFECTS (len2
))
3843 else if (TREE_CODE (len1
) != INTEGER_CST
)
3845 else if (TREE_CODE (len2
) != INTEGER_CST
)
3847 else if (tree_int_cst_lt (len1
, len2
))
3852 /* If both arguments have side effects, we cannot optimize. */
3853 if (!len
|| TREE_SIDE_EFFECTS (len
))
3856 /* The actual new length parameter is MIN(len,arg3). */
3857 len
= fold_build2 (MIN_EXPR
, TREE_TYPE (len
), len
,
3858 fold_convert (TREE_TYPE (len
), arg3
));
3860 /* If we don't have POINTER_TYPE, call the function. */
3861 if (arg1_align
== 0 || arg2_align
== 0)
3864 /* Make a place to write the result of the instruction. */
3867 && REG_P (result
) && GET_MODE (result
) == insn_mode
3868 && REGNO (result
) >= FIRST_PSEUDO_REGISTER
))
3869 result
= gen_reg_rtx (insn_mode
);
3871 /* Stabilize the arguments in case gen_cmpstrnsi fails. */
3872 arg1
= builtin_save_expr (arg1
);
3873 arg2
= builtin_save_expr (arg2
);
3874 len
= builtin_save_expr (len
);
3876 arg1_rtx
= get_memory_rtx (arg1
, len
);
3877 arg2_rtx
= get_memory_rtx (arg2
, len
);
3878 arg3_rtx
= expand_expr (len
, NULL_RTX
, VOIDmode
, 0);
3879 insn
= gen_cmpstrnsi (result
, arg1_rtx
, arg2_rtx
, arg3_rtx
,
3880 GEN_INT (MIN (arg1_align
, arg2_align
)));
3885 /* Return the value in the proper mode for this function. */
3886 mode
= TYPE_MODE (TREE_TYPE (exp
));
3887 if (GET_MODE (result
) == mode
)
3890 return convert_to_mode (mode
, result
, 0);
3891 convert_move (target
, result
, 0);
3895 /* Expand the library call ourselves using a stabilized argument
3896 list to avoid re-evaluating the function's arguments twice. */
3897 arglist
= build_tree_list (NULL_TREE
, len
);
3898 arglist
= tree_cons (NULL_TREE
, arg2
, arglist
);
3899 arglist
= tree_cons (NULL_TREE
, arg1
, arglist
);
3900 fndecl
= get_callee_fndecl (exp
);
3901 fn
= build_function_call_expr (fndecl
, arglist
);
3902 if (TREE_CODE (fn
) == CALL_EXPR
)
3903 CALL_EXPR_TAILCALL (fn
) = CALL_EXPR_TAILCALL (exp
);
3904 return expand_call (fn
, target
, target
== const0_rtx
);
3910 /* Expand expression EXP, which is a call to the strcat builtin.
3911 Return 0 if we failed the caller should emit a normal call,
3912 otherwise try to get the result in TARGET, if convenient. */
3915 expand_builtin_strcat (tree fndecl
, tree arglist
, rtx target
, enum machine_mode mode
)
3917 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
3921 tree dst
= TREE_VALUE (arglist
),
3922 src
= TREE_VALUE (TREE_CHAIN (arglist
));
3923 const char *p
= c_getstr (src
);
3925 /* If the string length is zero, return the dst parameter. */
3926 if (p
&& *p
== '\0')
3927 return expand_expr (dst
, target
, mode
, EXPAND_NORMAL
);
3931 /* See if we can store by pieces into (dst + strlen(dst)). */
3932 tree newsrc
, newdst
,
3933 strlen_fn
= implicit_built_in_decls
[BUILT_IN_STRLEN
];
3936 /* Stabilize the argument list. */
3937 newsrc
= builtin_save_expr (src
);
3939 arglist
= build_tree_list (NULL_TREE
, newsrc
);
3941 arglist
= TREE_CHAIN (arglist
); /* Reusing arglist if safe. */
3943 dst
= builtin_save_expr (dst
);
3947 /* Create strlen (dst). */
3949 build_function_call_expr (strlen_fn
,
3950 build_tree_list (NULL_TREE
, dst
));
3951 /* Create (dst + (cast) strlen (dst)). */
3952 newdst
= fold_convert (TREE_TYPE (dst
), newdst
);
3953 newdst
= fold_build2 (PLUS_EXPR
, TREE_TYPE (dst
), dst
, newdst
);
3955 newdst
= builtin_save_expr (newdst
);
3956 arglist
= tree_cons (NULL_TREE
, newdst
, arglist
);
3958 if (!expand_builtin_strcpy (fndecl
, arglist
, target
, mode
))
3960 end_sequence (); /* Stop sequence. */
3964 /* Output the entire sequence. */
3965 insns
= get_insns ();
3969 return expand_expr (dst
, target
, mode
, EXPAND_NORMAL
);
3976 /* Expand expression EXP, which is a call to the strncat builtin.
3977 Return 0 if we failed the caller should emit a normal call,
3978 otherwise try to get the result in TARGET, if convenient. */
3981 expand_builtin_strncat (tree arglist
, rtx target
, enum machine_mode mode
)
3983 if (validate_arglist (arglist
,
3984 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
3986 tree result
= fold_builtin_strncat (arglist
);
3988 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
3993 /* Expand expression EXP, which is a call to the strspn builtin.
3994 Return 0 if we failed the caller should emit a normal call,
3995 otherwise try to get the result in TARGET, if convenient. */
3998 expand_builtin_strspn (tree arglist
, rtx target
, enum machine_mode mode
)
4000 if (validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
4002 tree result
= fold_builtin_strspn (arglist
);
4004 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
4009 /* Expand expression EXP, which is a call to the strcspn builtin.
4010 Return 0 if we failed the caller should emit a normal call,
4011 otherwise try to get the result in TARGET, if convenient. */
4014 expand_builtin_strcspn (tree arglist
, rtx target
, enum machine_mode mode
)
4016 if (validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
4018 tree result
= fold_builtin_strcspn (arglist
);
4020 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
4025 /* Expand a call to __builtin_saveregs, generating the result in TARGET,
4026 if that's convenient. */
4029 expand_builtin_saveregs (void)
4033 /* Don't do __builtin_saveregs more than once in a function.
4034 Save the result of the first call and reuse it. */
4035 if (saveregs_value
!= 0)
4036 return saveregs_value
;
4038 /* When this function is called, it means that registers must be
4039 saved on entry to this function. So we migrate the call to the
4040 first insn of this function. */
4044 /* Do whatever the machine needs done in this case. */
4045 val
= targetm
.calls
.expand_builtin_saveregs ();
4050 saveregs_value
= val
;
4052 /* Put the insns after the NOTE that starts the function. If this
4053 is inside a start_sequence, make the outer-level insn chain current, so
4054 the code is placed at the start of the function. */
4055 push_topmost_sequence ();
4056 emit_insn_after (seq
, entry_of_function ());
4057 pop_topmost_sequence ();
4062 /* __builtin_args_info (N) returns word N of the arg space info
4063 for the current function. The number and meanings of words
4064 is controlled by the definition of CUMULATIVE_ARGS. */
4067 expand_builtin_args_info (tree arglist
)
4069 int nwords
= sizeof (CUMULATIVE_ARGS
) / sizeof (int);
4070 int *word_ptr
= (int *) ¤t_function_args_info
;
4072 gcc_assert (sizeof (CUMULATIVE_ARGS
) % sizeof (int) == 0);
4076 if (!host_integerp (TREE_VALUE (arglist
), 0))
4077 error ("argument of %<__builtin_args_info%> must be constant");
4080 HOST_WIDE_INT wordnum
= tree_low_cst (TREE_VALUE (arglist
), 0);
4082 if (wordnum
< 0 || wordnum
>= nwords
)
4083 error ("argument of %<__builtin_args_info%> out of range");
4085 return GEN_INT (word_ptr
[wordnum
]);
4089 error ("missing argument in %<__builtin_args_info%>");
4094 /* Expand a call to __builtin_next_arg. */
4097 expand_builtin_next_arg (void)
4099 /* Checking arguments is already done in fold_builtin_next_arg
4100 that must be called before this function. */
4101 return expand_binop (Pmode
, add_optab
,
4102 current_function_internal_arg_pointer
,
4103 current_function_arg_offset_rtx
,
4104 NULL_RTX
, 0, OPTAB_LIB_WIDEN
);
4107 /* Make it easier for the backends by protecting the valist argument
4108 from multiple evaluations. */
4111 stabilize_va_list (tree valist
, int needs_lvalue
)
4113 if (TREE_CODE (va_list_type_node
) == ARRAY_TYPE
)
4115 if (TREE_SIDE_EFFECTS (valist
))
4116 valist
= save_expr (valist
);
4118 /* For this case, the backends will be expecting a pointer to
4119 TREE_TYPE (va_list_type_node), but it's possible we've
4120 actually been given an array (an actual va_list_type_node).
4122 if (TREE_CODE (TREE_TYPE (valist
)) == ARRAY_TYPE
)
4124 tree p1
= build_pointer_type (TREE_TYPE (va_list_type_node
));
4125 valist
= build_fold_addr_expr_with_type (valist
, p1
);
4134 if (! TREE_SIDE_EFFECTS (valist
))
4137 pt
= build_pointer_type (va_list_type_node
);
4138 valist
= fold_build1 (ADDR_EXPR
, pt
, valist
);
4139 TREE_SIDE_EFFECTS (valist
) = 1;
4142 if (TREE_SIDE_EFFECTS (valist
))
4143 valist
= save_expr (valist
);
4144 valist
= build_fold_indirect_ref (valist
);
4150 /* The "standard" definition of va_list is void*. */
4153 std_build_builtin_va_list (void)
4155 return ptr_type_node
;
4158 /* The "standard" implementation of va_start: just assign `nextarg' to
4162 std_expand_builtin_va_start (tree valist
, rtx nextarg
)
4166 t
= build2 (MODIFY_EXPR
, TREE_TYPE (valist
), valist
,
4167 make_tree (ptr_type_node
, nextarg
));
4168 TREE_SIDE_EFFECTS (t
) = 1;
4170 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
4173 /* Expand ARGLIST, from a call to __builtin_va_start. */
4176 expand_builtin_va_start (tree arglist
)
4181 chain
= TREE_CHAIN (arglist
);
4185 error ("too few arguments to function %<va_start%>");
4189 if (fold_builtin_next_arg (chain
))
4192 nextarg
= expand_builtin_next_arg ();
4193 valist
= stabilize_va_list (TREE_VALUE (arglist
), 1);
4195 #ifdef EXPAND_BUILTIN_VA_START
4196 EXPAND_BUILTIN_VA_START (valist
, nextarg
);
4198 std_expand_builtin_va_start (valist
, nextarg
);
4204 /* The "standard" implementation of va_arg: read the value from the
4205 current (padded) address and increment by the (padded) size. */
4208 std_gimplify_va_arg_expr (tree valist
, tree type
, tree
*pre_p
, tree
*post_p
)
4210 tree addr
, t
, type_size
, rounded_size
, valist_tmp
;
4211 unsigned HOST_WIDE_INT align
, boundary
;
4214 #ifdef ARGS_GROW_DOWNWARD
4215 /* All of the alignment and movement below is for args-grow-up machines.
4216 As of 2004, there are only 3 ARGS_GROW_DOWNWARD targets, and they all
4217 implement their own specialized gimplify_va_arg_expr routines. */
4221 indirect
= pass_by_reference (NULL
, TYPE_MODE (type
), type
, false);
4223 type
= build_pointer_type (type
);
4225 align
= PARM_BOUNDARY
/ BITS_PER_UNIT
;
4226 boundary
= FUNCTION_ARG_BOUNDARY (TYPE_MODE (type
), type
) / BITS_PER_UNIT
;
4228 /* Hoist the valist value into a temporary for the moment. */
4229 valist_tmp
= get_initialized_tmp_var (valist
, pre_p
, NULL
);
4231 /* va_list pointer is aligned to PARM_BOUNDARY. If argument actually
4232 requires greater alignment, we must perform dynamic alignment. */
4233 if (boundary
> align
)
4235 t
= fold_convert (TREE_TYPE (valist
), size_int (boundary
- 1));
4236 t
= build2 (MODIFY_EXPR
, TREE_TYPE (valist
), valist_tmp
,
4237 build2 (PLUS_EXPR
, TREE_TYPE (valist
), valist_tmp
, t
));
4238 gimplify_and_add (t
, pre_p
);
4240 t
= fold_convert (TREE_TYPE (valist
), size_int (-boundary
));
4241 t
= build2 (MODIFY_EXPR
, TREE_TYPE (valist
), valist_tmp
,
4242 build2 (BIT_AND_EXPR
, TREE_TYPE (valist
), valist_tmp
, t
));
4243 gimplify_and_add (t
, pre_p
);
4248 /* If the actual alignment is less than the alignment of the type,
4249 adjust the type accordingly so that we don't assume strict alignment
4250 when deferencing the pointer. */
4251 boundary
*= BITS_PER_UNIT
;
4252 if (boundary
< TYPE_ALIGN (type
))
4254 type
= build_variant_type_copy (type
);
4255 TYPE_ALIGN (type
) = boundary
;
4258 /* Compute the rounded size of the type. */
4259 type_size
= size_in_bytes (type
);
4260 rounded_size
= round_up (type_size
, align
);
4262 /* Reduce rounded_size so it's sharable with the postqueue. */
4263 gimplify_expr (&rounded_size
, pre_p
, post_p
, is_gimple_val
, fb_rvalue
);
4267 if (PAD_VARARGS_DOWN
&& !integer_zerop (rounded_size
))
4269 /* Small args are padded downward. */
4270 t
= fold_build2 (GT_EXPR
, sizetype
, rounded_size
, size_int (align
));
4271 t
= fold_build3 (COND_EXPR
, sizetype
, t
, size_zero_node
,
4272 size_binop (MINUS_EXPR
, rounded_size
, type_size
));
4273 t
= fold_convert (TREE_TYPE (addr
), t
);
4274 addr
= fold_build2 (PLUS_EXPR
, TREE_TYPE (addr
), addr
, t
);
4277 /* Compute new value for AP. */
4278 t
= fold_convert (TREE_TYPE (valist
), rounded_size
);
4279 t
= build2 (PLUS_EXPR
, TREE_TYPE (valist
), valist_tmp
, t
);
4280 t
= build2 (MODIFY_EXPR
, TREE_TYPE (valist
), valist
, t
);
4281 gimplify_and_add (t
, pre_p
);
4283 addr
= fold_convert (build_pointer_type (type
), addr
);
4286 addr
= build_va_arg_indirect_ref (addr
);
4288 return build_va_arg_indirect_ref (addr
);
4291 /* Build an indirect-ref expression over the given TREE, which represents a
4292 piece of a va_arg() expansion. */
4294 build_va_arg_indirect_ref (tree addr
)
4296 addr
= build_fold_indirect_ref (addr
);
4298 if (flag_mudflap
) /* Don't instrument va_arg INDIRECT_REF. */
4304 /* Return a dummy expression of type TYPE in order to keep going after an
4308 dummy_object (tree type
)
4310 tree t
= convert (build_pointer_type (type
), null_pointer_node
);
4311 return build1 (INDIRECT_REF
, type
, t
);
4314 /* Gimplify __builtin_va_arg, aka VA_ARG_EXPR, which is not really a
4315 builtin function, but a very special sort of operator. */
4317 enum gimplify_status
4318 gimplify_va_arg_expr (tree
*expr_p
, tree
*pre_p
, tree
*post_p
)
4320 tree promoted_type
, want_va_type
, have_va_type
;
4321 tree valist
= TREE_OPERAND (*expr_p
, 0);
4322 tree type
= TREE_TYPE (*expr_p
);
4325 /* Verify that valist is of the proper type. */
4326 want_va_type
= va_list_type_node
;
4327 have_va_type
= TREE_TYPE (valist
);
4329 if (have_va_type
== error_mark_node
)
4332 if (TREE_CODE (want_va_type
) == ARRAY_TYPE
)
4334 /* If va_list is an array type, the argument may have decayed
4335 to a pointer type, e.g. by being passed to another function.
4336 In that case, unwrap both types so that we can compare the
4337 underlying records. */
4338 if (TREE_CODE (have_va_type
) == ARRAY_TYPE
4339 || POINTER_TYPE_P (have_va_type
))
4341 want_va_type
= TREE_TYPE (want_va_type
);
4342 have_va_type
= TREE_TYPE (have_va_type
);
4346 if (TYPE_MAIN_VARIANT (want_va_type
) != TYPE_MAIN_VARIANT (have_va_type
))
4348 error ("first argument to %<va_arg%> not of type %<va_list%>");
4352 /* Generate a diagnostic for requesting data of a type that cannot
4353 be passed through `...' due to type promotion at the call site. */
4354 else if ((promoted_type
= lang_hooks
.types
.type_promotes_to (type
))
4357 static bool gave_help
;
4359 /* Unfortunately, this is merely undefined, rather than a constraint
4360 violation, so we cannot make this an error. If this call is never
4361 executed, the program is still strictly conforming. */
4362 warning (0, "%qT is promoted to %qT when passed through %<...%>",
4363 type
, promoted_type
);
4367 warning (0, "(so you should pass %qT not %qT to %<va_arg%>)",
4368 promoted_type
, type
);
4371 /* We can, however, treat "undefined" any way we please.
4372 Call abort to encourage the user to fix the program. */
4373 inform ("if this code is reached, the program will abort");
4374 t
= build_function_call_expr (implicit_built_in_decls
[BUILT_IN_TRAP
],
4376 append_to_statement_list (t
, pre_p
);
4378 /* This is dead code, but go ahead and finish so that the
4379 mode of the result comes out right. */
4380 *expr_p
= dummy_object (type
);
4385 /* Make it easier for the backends by protecting the valist argument
4386 from multiple evaluations. */
4387 if (TREE_CODE (va_list_type_node
) == ARRAY_TYPE
)
4389 /* For this case, the backends will be expecting a pointer to
4390 TREE_TYPE (va_list_type_node), but it's possible we've
4391 actually been given an array (an actual va_list_type_node).
4393 if (TREE_CODE (TREE_TYPE (valist
)) == ARRAY_TYPE
)
4395 tree p1
= build_pointer_type (TREE_TYPE (va_list_type_node
));
4396 valist
= build_fold_addr_expr_with_type (valist
, p1
);
4398 gimplify_expr (&valist
, pre_p
, post_p
, is_gimple_val
, fb_rvalue
);
4401 gimplify_expr (&valist
, pre_p
, post_p
, is_gimple_min_lval
, fb_lvalue
);
4403 if (!targetm
.gimplify_va_arg_expr
)
4404 /* FIXME:Once most targets are converted we should merely
4405 assert this is non-null. */
4408 *expr_p
= targetm
.gimplify_va_arg_expr (valist
, type
, pre_p
, post_p
);
4413 /* Expand ARGLIST, from a call to __builtin_va_end. */
4416 expand_builtin_va_end (tree arglist
)
4418 tree valist
= TREE_VALUE (arglist
);
4420 /* Evaluate for side effects, if needed. I hate macros that don't
4422 if (TREE_SIDE_EFFECTS (valist
))
4423 expand_expr (valist
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
4428 /* Expand ARGLIST, from a call to __builtin_va_copy. We do this as a
4429 builtin rather than just as an assignment in stdarg.h because of the
4430 nastiness of array-type va_list types. */
4433 expand_builtin_va_copy (tree arglist
)
4437 dst
= TREE_VALUE (arglist
);
4438 src
= TREE_VALUE (TREE_CHAIN (arglist
));
4440 dst
= stabilize_va_list (dst
, 1);
4441 src
= stabilize_va_list (src
, 0);
4443 if (TREE_CODE (va_list_type_node
) != ARRAY_TYPE
)
4445 t
= build2 (MODIFY_EXPR
, va_list_type_node
, dst
, src
);
4446 TREE_SIDE_EFFECTS (t
) = 1;
4447 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
4451 rtx dstb
, srcb
, size
;
4453 /* Evaluate to pointers. */
4454 dstb
= expand_expr (dst
, NULL_RTX
, Pmode
, EXPAND_NORMAL
);
4455 srcb
= expand_expr (src
, NULL_RTX
, Pmode
, EXPAND_NORMAL
);
4456 size
= expand_expr (TYPE_SIZE_UNIT (va_list_type_node
), NULL_RTX
,
4457 VOIDmode
, EXPAND_NORMAL
);
4459 dstb
= convert_memory_address (Pmode
, dstb
);
4460 srcb
= convert_memory_address (Pmode
, srcb
);
4462 /* "Dereference" to BLKmode memories. */
4463 dstb
= gen_rtx_MEM (BLKmode
, dstb
);
4464 set_mem_alias_set (dstb
, get_alias_set (TREE_TYPE (TREE_TYPE (dst
))));
4465 set_mem_align (dstb
, TYPE_ALIGN (va_list_type_node
));
4466 srcb
= gen_rtx_MEM (BLKmode
, srcb
);
4467 set_mem_alias_set (srcb
, get_alias_set (TREE_TYPE (TREE_TYPE (src
))));
4468 set_mem_align (srcb
, TYPE_ALIGN (va_list_type_node
));
4471 emit_block_move (dstb
, srcb
, size
, BLOCK_OP_NORMAL
);
4477 /* Expand a call to one of the builtin functions __builtin_frame_address or
4478 __builtin_return_address. */
4481 expand_builtin_frame_address (tree fndecl
, tree arglist
)
4483 /* The argument must be a nonnegative integer constant.
4484 It counts the number of frames to scan up the stack.
4485 The value is the return address saved in that frame. */
4487 /* Warning about missing arg was already issued. */
4489 else if (! host_integerp (TREE_VALUE (arglist
), 1))
4491 if (DECL_FUNCTION_CODE (fndecl
) == BUILT_IN_FRAME_ADDRESS
)
4492 error ("invalid argument to %<__builtin_frame_address%>");
4494 error ("invalid argument to %<__builtin_return_address%>");
4500 = expand_builtin_return_addr (DECL_FUNCTION_CODE (fndecl
),
4501 tree_low_cst (TREE_VALUE (arglist
), 1));
4503 /* Some ports cannot access arbitrary stack frames. */
4506 if (DECL_FUNCTION_CODE (fndecl
) == BUILT_IN_FRAME_ADDRESS
)
4507 warning (0, "unsupported argument to %<__builtin_frame_address%>");
4509 warning (0, "unsupported argument to %<__builtin_return_address%>");
4513 /* For __builtin_frame_address, return what we've got. */
4514 if (DECL_FUNCTION_CODE (fndecl
) == BUILT_IN_FRAME_ADDRESS
)
4518 && ! CONSTANT_P (tem
))
4519 tem
= copy_to_mode_reg (Pmode
, tem
);
4524 /* Expand a call to the alloca builtin, with arguments ARGLIST. Return 0 if
4525 we failed and the caller should emit a normal call, otherwise try to get
4526 the result in TARGET, if convenient. */
4529 expand_builtin_alloca (tree arglist
, rtx target
)
4534 /* In -fmudflap-instrumented code, alloca() and __builtin_alloca()
4535 should always expand to function calls. These can be intercepted
4540 if (!validate_arglist (arglist
, INTEGER_TYPE
, VOID_TYPE
))
4543 /* Compute the argument. */
4544 op0
= expand_expr (TREE_VALUE (arglist
), NULL_RTX
, VOIDmode
, 0);
4546 /* Allocate the desired space. */
4547 result
= allocate_dynamic_stack_space (op0
, target
, BITS_PER_UNIT
);
4548 result
= convert_memory_address (ptr_mode
, result
);
4553 /* Expand a call to a unary builtin. The arguments are in ARGLIST.
4554 Return 0 if a normal call should be emitted rather than expanding the
4555 function in-line. If convenient, the result should be placed in TARGET.
4556 SUBTARGET may be used as the target for computing one of EXP's operands. */
4559 expand_builtin_unop (enum machine_mode target_mode
, tree arglist
, rtx target
,
4560 rtx subtarget
, optab op_optab
)
4563 if (!validate_arglist (arglist
, INTEGER_TYPE
, VOID_TYPE
))
4566 /* Compute the argument. */
4567 op0
= expand_expr (TREE_VALUE (arglist
), subtarget
, VOIDmode
, 0);
4568 /* Compute op, into TARGET if possible.
4569 Set TARGET to wherever the result comes back. */
4570 target
= expand_unop (TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist
))),
4571 op_optab
, op0
, target
, 1);
4572 gcc_assert (target
);
4574 return convert_to_mode (target_mode
, target
, 0);
4577 /* If the string passed to fputs is a constant and is one character
4578 long, we attempt to transform this call into __builtin_fputc(). */
4581 expand_builtin_fputs (tree arglist
, rtx target
, bool unlocked
)
4583 /* Verify the arguments in the original call. */
4584 if (validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
4586 tree result
= fold_builtin_fputs (arglist
, (target
== const0_rtx
),
4587 unlocked
, NULL_TREE
);
4589 return expand_expr (result
, target
, VOIDmode
, EXPAND_NORMAL
);
4594 /* Expand a call to __builtin_expect. We return our argument and emit a
4595 NOTE_INSN_EXPECTED_VALUE note. This is the expansion of __builtin_expect in
4596 a non-jump context. */
4599 expand_builtin_expect (tree arglist
, rtx target
)
4604 if (arglist
== NULL_TREE
4605 || TREE_CHAIN (arglist
) == NULL_TREE
)
4607 exp
= TREE_VALUE (arglist
);
4608 c
= TREE_VALUE (TREE_CHAIN (arglist
));
4610 if (TREE_CODE (c
) != INTEGER_CST
)
4612 error ("second argument to %<__builtin_expect%> must be a constant");
4613 c
= integer_zero_node
;
4616 target
= expand_expr (exp
, target
, VOIDmode
, EXPAND_NORMAL
);
4618 /* Don't bother with expected value notes for integral constants. */
4619 if (flag_guess_branch_prob
&& GET_CODE (target
) != CONST_INT
)
4621 /* We do need to force this into a register so that we can be
4622 moderately sure to be able to correctly interpret the branch
4624 target
= force_reg (GET_MODE (target
), target
);
4626 rtx_c
= expand_expr (c
, NULL_RTX
, GET_MODE (target
), EXPAND_NORMAL
);
4628 note
= emit_note (NOTE_INSN_EXPECTED_VALUE
);
4629 NOTE_EXPECTED_VALUE (note
) = gen_rtx_EQ (VOIDmode
, target
, rtx_c
);
4635 /* Like expand_builtin_expect, except do this in a jump context. This is
4636 called from do_jump if the conditional is a __builtin_expect. Return either
4637 a list of insns to emit the jump or NULL if we cannot optimize
4638 __builtin_expect. We need to optimize this at jump time so that machines
4639 like the PowerPC don't turn the test into a SCC operation, and then jump
4640 based on the test being 0/1. */
4643 expand_builtin_expect_jump (tree exp
, rtx if_false_label
, rtx if_true_label
)
4645 tree arglist
= TREE_OPERAND (exp
, 1);
4646 tree arg0
= TREE_VALUE (arglist
);
4647 tree arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
4650 /* Only handle __builtin_expect (test, 0) and
4651 __builtin_expect (test, 1). */
4652 if (TREE_CODE (TREE_TYPE (arg1
)) == INTEGER_TYPE
4653 && (integer_zerop (arg1
) || integer_onep (arg1
)))
4655 rtx insn
, drop_through_label
, temp
;
4657 /* Expand the jump insns. */
4659 do_jump (arg0
, if_false_label
, if_true_label
);
4662 drop_through_label
= get_last_insn ();
4663 if (drop_through_label
&& NOTE_P (drop_through_label
))
4664 drop_through_label
= prev_nonnote_insn (drop_through_label
);
4665 if (drop_through_label
&& !LABEL_P (drop_through_label
))
4666 drop_through_label
= NULL_RTX
;
4669 if (! if_true_label
)
4670 if_true_label
= drop_through_label
;
4671 if (! if_false_label
)
4672 if_false_label
= drop_through_label
;
4674 /* Go through and add the expect's to each of the conditional jumps. */
4676 while (insn
!= NULL_RTX
)
4678 rtx next
= NEXT_INSN (insn
);
4680 if (JUMP_P (insn
) && any_condjump_p (insn
))
4682 rtx ifelse
= SET_SRC (pc_set (insn
));
4683 rtx then_dest
= XEXP (ifelse
, 1);
4684 rtx else_dest
= XEXP (ifelse
, 2);
4687 /* First check if we recognize any of the labels. */
4688 if (GET_CODE (then_dest
) == LABEL_REF
4689 && XEXP (then_dest
, 0) == if_true_label
)
4691 else if (GET_CODE (then_dest
) == LABEL_REF
4692 && XEXP (then_dest
, 0) == if_false_label
)
4694 else if (GET_CODE (else_dest
) == LABEL_REF
4695 && XEXP (else_dest
, 0) == if_false_label
)
4697 else if (GET_CODE (else_dest
) == LABEL_REF
4698 && XEXP (else_dest
, 0) == if_true_label
)
4700 /* Otherwise check where we drop through. */
4701 else if (else_dest
== pc_rtx
)
4703 if (next
&& NOTE_P (next
))
4704 next
= next_nonnote_insn (next
);
4706 if (next
&& JUMP_P (next
)
4707 && any_uncondjump_p (next
))
4708 temp
= XEXP (SET_SRC (pc_set (next
)), 0);
4712 /* TEMP is either a CODE_LABEL, NULL_RTX or something
4713 else that can't possibly match either target label. */
4714 if (temp
== if_false_label
)
4716 else if (temp
== if_true_label
)
4719 else if (then_dest
== pc_rtx
)
4721 if (next
&& NOTE_P (next
))
4722 next
= next_nonnote_insn (next
);
4724 if (next
&& JUMP_P (next
)
4725 && any_uncondjump_p (next
))
4726 temp
= XEXP (SET_SRC (pc_set (next
)), 0);
4730 if (temp
== if_false_label
)
4732 else if (temp
== if_true_label
)
4738 /* If the test is expected to fail, reverse the
4740 if (integer_zerop (arg1
))
4742 predict_insn_def (insn
, PRED_BUILTIN_EXPECT
, taken
);
4754 expand_builtin_trap (void)
4758 emit_insn (gen_trap ());
4761 emit_library_call (abort_libfunc
, LCT_NORETURN
, VOIDmode
, 0);
4765 /* Expand a call to fabs, fabsf or fabsl with arguments ARGLIST.
4766 Return 0 if a normal call should be emitted rather than expanding
4767 the function inline. If convenient, the result should be placed
4768 in TARGET. SUBTARGET may be used as the target for computing
4772 expand_builtin_fabs (tree arglist
, rtx target
, rtx subtarget
)
4774 enum machine_mode mode
;
4778 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
4781 arg
= TREE_VALUE (arglist
);
4782 mode
= TYPE_MODE (TREE_TYPE (arg
));
4783 op0
= expand_expr (arg
, subtarget
, VOIDmode
, 0);
4784 return expand_abs (mode
, op0
, target
, 0, safe_from_p (target
, arg
, 1));
4787 /* Expand a call to copysign, copysignf, or copysignl with arguments ARGLIST.
4788 Return NULL is a normal call should be emitted rather than expanding the
4789 function inline. If convenient, the result should be placed in TARGET.
4790 SUBTARGET may be used as the target for computing the operand. */
4793 expand_builtin_copysign (tree arglist
, rtx target
, rtx subtarget
)
4798 if (!validate_arglist (arglist
, REAL_TYPE
, REAL_TYPE
, VOID_TYPE
))
4801 arg
= TREE_VALUE (arglist
);
4802 op0
= expand_expr (arg
, subtarget
, VOIDmode
, 0);
4804 arg
= TREE_VALUE (TREE_CHAIN (arglist
));
4805 op1
= expand_expr (arg
, NULL
, VOIDmode
, 0);
4807 return expand_copysign (op0
, op1
, target
);
4810 /* Create a new constant string literal and return a char* pointer to it.
4811 The STRING_CST value is the LEN characters at STR. */
4813 build_string_literal (int len
, const char *str
)
4815 tree t
, elem
, index
, type
;
4817 t
= build_string (len
, str
);
4818 elem
= build_type_variant (char_type_node
, 1, 0);
4819 index
= build_index_type (build_int_cst (NULL_TREE
, len
- 1));
4820 type
= build_array_type (elem
, index
);
4821 TREE_TYPE (t
) = type
;
4822 TREE_CONSTANT (t
) = 1;
4823 TREE_INVARIANT (t
) = 1;
4824 TREE_READONLY (t
) = 1;
4825 TREE_STATIC (t
) = 1;
4827 type
= build_pointer_type (type
);
4828 t
= build1 (ADDR_EXPR
, type
, t
);
4830 type
= build_pointer_type (elem
);
4831 t
= build1 (NOP_EXPR
, type
, t
);
4835 /* Expand EXP, a call to printf or printf_unlocked.
4836 Return 0 if a normal call should be emitted rather than transforming
4837 the function inline. If convenient, the result should be placed in
4838 TARGET with mode MODE. UNLOCKED indicates this is a printf_unlocked
4841 expand_builtin_printf (tree exp
, rtx target
, enum machine_mode mode
,
4844 tree arglist
= TREE_OPERAND (exp
, 1);
4845 tree fn_putchar
= unlocked
4846 ? implicit_built_in_decls
[BUILT_IN_PUTCHAR_UNLOCKED
]
4847 : implicit_built_in_decls
[BUILT_IN_PUTCHAR
];
4848 tree fn_puts
= unlocked
? implicit_built_in_decls
[BUILT_IN_PUTS_UNLOCKED
]
4849 : implicit_built_in_decls
[BUILT_IN_PUTS
];
4850 const char *fmt_str
;
4853 /* If the return value is used, don't do the transformation. */
4854 if (target
!= const0_rtx
)
4857 /* Verify the required arguments in the original call. */
4860 fmt
= TREE_VALUE (arglist
);
4861 if (! POINTER_TYPE_P (TREE_TYPE (fmt
)))
4863 arglist
= TREE_CHAIN (arglist
);
4865 /* Check whether the format is a literal string constant. */
4866 fmt_str
= c_getstr (fmt
);
4867 if (fmt_str
== NULL
)
4870 /* If the format specifier was "%s\n", call __builtin_puts(arg). */
4871 if (strcmp (fmt_str
, "%s\n") == 0)
4874 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist
)))
4875 || TREE_CHAIN (arglist
))
4879 /* If the format specifier was "%c", call __builtin_putchar(arg). */
4880 else if (strcmp (fmt_str
, "%c") == 0)
4883 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist
))) != INTEGER_TYPE
4884 || TREE_CHAIN (arglist
))
4890 /* We can't handle anything else with % args or %% ... yet. */
4891 if (strchr (fmt_str
, '%'))
4897 /* If the format specifier was "", printf does nothing. */
4898 if (fmt_str
[0] == '\0')
4900 /* If the format specifier has length of 1, call putchar. */
4901 if (fmt_str
[1] == '\0')
4903 /* Given printf("c"), (where c is any one character,)
4904 convert "c"[0] to an int and pass that to the replacement
4906 arg
= build_int_cst (NULL_TREE
, fmt_str
[0]);
4907 arglist
= build_tree_list (NULL_TREE
, arg
);
4912 /* If the format specifier was "string\n", call puts("string"). */
4913 size_t len
= strlen (fmt_str
);
4914 if (fmt_str
[len
- 1] == '\n')
4916 /* Create a NUL-terminated string that's one char shorter
4917 than the original, stripping off the trailing '\n'. */
4918 char *newstr
= alloca (len
);
4919 memcpy (newstr
, fmt_str
, len
- 1);
4920 newstr
[len
- 1] = 0;
4922 arg
= build_string_literal (len
, newstr
);
4923 arglist
= build_tree_list (NULL_TREE
, arg
);
4927 /* We'd like to arrange to call fputs(string,stdout) here,
4928 but we need stdout and don't have a way to get it yet. */
4935 fn
= build_function_call_expr (fn
, arglist
);
4936 if (TREE_CODE (fn
) == CALL_EXPR
)
4937 CALL_EXPR_TAILCALL (fn
) = CALL_EXPR_TAILCALL (exp
);
4938 return expand_expr (fn
, target
, mode
, EXPAND_NORMAL
);
4941 /* Expand EXP, a call to fprintf or fprintf_unlocked.
4942 Return 0 if a normal call should be emitted rather than transforming
4943 the function inline. If convenient, the result should be placed in
4944 TARGET with mode MODE. UNLOCKED indicates this is a fprintf_unlocked
4947 expand_builtin_fprintf (tree exp
, rtx target
, enum machine_mode mode
,
4950 tree arglist
= TREE_OPERAND (exp
, 1);
4951 tree fn_fputc
= unlocked
? implicit_built_in_decls
[BUILT_IN_FPUTC_UNLOCKED
]
4952 : implicit_built_in_decls
[BUILT_IN_FPUTC
];
4953 tree fn_fputs
= unlocked
? implicit_built_in_decls
[BUILT_IN_FPUTS_UNLOCKED
]
4954 : implicit_built_in_decls
[BUILT_IN_FPUTS
];
4955 const char *fmt_str
;
4956 tree fn
, fmt
, fp
, arg
;
4958 /* If the return value is used, don't do the transformation. */
4959 if (target
!= const0_rtx
)
4962 /* Verify the required arguments in the original call. */
4965 fp
= TREE_VALUE (arglist
);
4966 if (! POINTER_TYPE_P (TREE_TYPE (fp
)))
4968 arglist
= TREE_CHAIN (arglist
);
4971 fmt
= TREE_VALUE (arglist
);
4972 if (! POINTER_TYPE_P (TREE_TYPE (fmt
)))
4974 arglist
= TREE_CHAIN (arglist
);
4976 /* Check whether the format is a literal string constant. */
4977 fmt_str
= c_getstr (fmt
);
4978 if (fmt_str
== NULL
)
4981 /* If the format specifier was "%s", call __builtin_fputs(arg,fp). */
4982 if (strcmp (fmt_str
, "%s") == 0)
4985 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist
)))
4986 || TREE_CHAIN (arglist
))
4988 arg
= TREE_VALUE (arglist
);
4989 arglist
= build_tree_list (NULL_TREE
, fp
);
4990 arglist
= tree_cons (NULL_TREE
, arg
, arglist
);
4993 /* If the format specifier was "%c", call __builtin_fputc(arg,fp). */
4994 else if (strcmp (fmt_str
, "%c") == 0)
4997 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist
))) != INTEGER_TYPE
4998 || TREE_CHAIN (arglist
))
5000 arg
= TREE_VALUE (arglist
);
5001 arglist
= build_tree_list (NULL_TREE
, fp
);
5002 arglist
= tree_cons (NULL_TREE
, arg
, arglist
);
5007 /* We can't handle anything else with % args or %% ... yet. */
5008 if (strchr (fmt_str
, '%'))
5014 /* If the format specifier was "", fprintf does nothing. */
5015 if (fmt_str
[0] == '\0')
5017 /* Evaluate and ignore FILE* argument for side-effects. */
5018 expand_expr (fp
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
5022 /* When "string" doesn't contain %, replace all cases of
5023 fprintf(stream,string) with fputs(string,stream). The fputs
5024 builtin will take care of special cases like length == 1. */
5025 arglist
= build_tree_list (NULL_TREE
, fp
);
5026 arglist
= tree_cons (NULL_TREE
, fmt
, arglist
);
5032 fn
= build_function_call_expr (fn
, arglist
);
5033 if (TREE_CODE (fn
) == CALL_EXPR
)
5034 CALL_EXPR_TAILCALL (fn
) = CALL_EXPR_TAILCALL (exp
);
5035 return expand_expr (fn
, target
, mode
, EXPAND_NORMAL
);
5038 /* Expand a call to sprintf with argument list ARGLIST. Return 0 if
5039 a normal call should be emitted rather than expanding the function
5040 inline. If convenient, the result should be placed in TARGET with
5044 expand_builtin_sprintf (tree arglist
, rtx target
, enum machine_mode mode
)
5046 tree orig_arglist
, dest
, fmt
;
5047 const char *fmt_str
;
5049 orig_arglist
= arglist
;
5051 /* Verify the required arguments in the original call. */
5054 dest
= TREE_VALUE (arglist
);
5055 if (! POINTER_TYPE_P (TREE_TYPE (dest
)))
5057 arglist
= TREE_CHAIN (arglist
);
5060 fmt
= TREE_VALUE (arglist
);
5061 if (! POINTER_TYPE_P (TREE_TYPE (fmt
)))
5063 arglist
= TREE_CHAIN (arglist
);
5065 /* Check whether the format is a literal string constant. */
5066 fmt_str
= c_getstr (fmt
);
5067 if (fmt_str
== NULL
)
5070 /* If the format doesn't contain % args or %%, use strcpy. */
5071 if (strchr (fmt_str
, '%') == 0)
5073 tree fn
= implicit_built_in_decls
[BUILT_IN_STRCPY
];
5076 if (arglist
|| ! fn
)
5078 expand_expr (build_function_call_expr (fn
, orig_arglist
),
5079 const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
5080 if (target
== const0_rtx
)
5082 exp
= build_int_cst (NULL_TREE
, strlen (fmt_str
));
5083 return expand_expr (exp
, target
, mode
, EXPAND_NORMAL
);
5085 /* If the format is "%s", use strcpy if the result isn't used. */
5086 else if (strcmp (fmt_str
, "%s") == 0)
5089 fn
= implicit_built_in_decls
[BUILT_IN_STRCPY
];
5094 if (! arglist
|| TREE_CHAIN (arglist
))
5096 arg
= TREE_VALUE (arglist
);
5097 if (! POINTER_TYPE_P (TREE_TYPE (arg
)))
5100 if (target
!= const0_rtx
)
5102 len
= c_strlen (arg
, 1);
5103 if (! len
|| TREE_CODE (len
) != INTEGER_CST
)
5109 arglist
= build_tree_list (NULL_TREE
, arg
);
5110 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
5111 expand_expr (build_function_call_expr (fn
, arglist
),
5112 const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
5114 if (target
== const0_rtx
)
5116 return expand_expr (len
, target
, mode
, EXPAND_NORMAL
);
5122 /* Expand a call to either the entry or exit function profiler. */
5125 expand_builtin_profile_func (bool exitp
)
5129 this = DECL_RTL (current_function_decl
);
5130 gcc_assert (MEM_P (this));
5131 this = XEXP (this, 0);
5134 which
= profile_function_exit_libfunc
;
5136 which
= profile_function_entry_libfunc
;
5138 emit_library_call (which
, LCT_NORMAL
, VOIDmode
, 2, this, Pmode
,
5139 expand_builtin_return_addr (BUILT_IN_RETURN_ADDRESS
,
5146 /* Given a trampoline address, make sure it satisfies TRAMPOLINE_ALIGNMENT. */
5149 round_trampoline_addr (rtx tramp
)
5151 rtx temp
, addend
, mask
;
5153 /* If we don't need too much alignment, we'll have been guaranteed
5154 proper alignment by get_trampoline_type. */
5155 if (TRAMPOLINE_ALIGNMENT
<= STACK_BOUNDARY
)
5158 /* Round address up to desired boundary. */
5159 temp
= gen_reg_rtx (Pmode
);
5160 addend
= GEN_INT (TRAMPOLINE_ALIGNMENT
/ BITS_PER_UNIT
- 1);
5161 mask
= GEN_INT (-TRAMPOLINE_ALIGNMENT
/ BITS_PER_UNIT
);
5163 temp
= expand_simple_binop (Pmode
, PLUS
, tramp
, addend
,
5164 temp
, 0, OPTAB_LIB_WIDEN
);
5165 tramp
= expand_simple_binop (Pmode
, AND
, temp
, mask
,
5166 temp
, 0, OPTAB_LIB_WIDEN
);
5172 expand_builtin_init_trampoline (tree arglist
)
5174 tree t_tramp
, t_func
, t_chain
;
5175 rtx r_tramp
, r_func
, r_chain
;
5176 #ifdef TRAMPOLINE_TEMPLATE
5180 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
,
5181 POINTER_TYPE
, VOID_TYPE
))
5184 t_tramp
= TREE_VALUE (arglist
);
5185 arglist
= TREE_CHAIN (arglist
);
5186 t_func
= TREE_VALUE (arglist
);
5187 arglist
= TREE_CHAIN (arglist
);
5188 t_chain
= TREE_VALUE (arglist
);
5190 r_tramp
= expand_expr (t_tramp
, NULL_RTX
, VOIDmode
, 0);
5191 r_func
= expand_expr (t_func
, NULL_RTX
, VOIDmode
, 0);
5192 r_chain
= expand_expr (t_chain
, NULL_RTX
, VOIDmode
, 0);
5194 /* Generate insns to initialize the trampoline. */
5195 r_tramp
= round_trampoline_addr (r_tramp
);
5196 #ifdef TRAMPOLINE_TEMPLATE
5197 blktramp
= gen_rtx_MEM (BLKmode
, r_tramp
);
5198 set_mem_align (blktramp
, TRAMPOLINE_ALIGNMENT
);
5199 emit_block_move (blktramp
, assemble_trampoline_template (),
5200 GEN_INT (TRAMPOLINE_SIZE
), BLOCK_OP_NORMAL
);
5202 trampolines_created
= 1;
5203 INITIALIZE_TRAMPOLINE (r_tramp
, r_func
, r_chain
);
5209 expand_builtin_adjust_trampoline (tree arglist
)
5213 if (!validate_arglist (arglist
, POINTER_TYPE
, VOID_TYPE
))
5216 tramp
= expand_expr (TREE_VALUE (arglist
), NULL_RTX
, VOIDmode
, 0);
5217 tramp
= round_trampoline_addr (tramp
);
5218 #ifdef TRAMPOLINE_ADJUST_ADDRESS
5219 TRAMPOLINE_ADJUST_ADDRESS (tramp
);
5225 /* Expand a call to the built-in signbit, signbitf or signbitl function.
5226 Return NULL_RTX if a normal call should be emitted rather than expanding
5227 the function in-line. EXP is the expression that is a call to the builtin
5228 function; if convenient, the result should be placed in TARGET. */
5231 expand_builtin_signbit (tree exp
, rtx target
)
5233 const struct real_format
*fmt
;
5234 enum machine_mode fmode
, imode
, rmode
;
5235 HOST_WIDE_INT hi
, lo
;
5240 arglist
= TREE_OPERAND (exp
, 1);
5241 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
5244 arg
= TREE_VALUE (arglist
);
5245 fmode
= TYPE_MODE (TREE_TYPE (arg
));
5246 rmode
= TYPE_MODE (TREE_TYPE (exp
));
5247 fmt
= REAL_MODE_FORMAT (fmode
);
5249 /* For floating point formats without a sign bit, implement signbit
5251 bitpos
= fmt
->signbit_ro
;
5254 /* But we can't do this if the format supports signed zero. */
5255 if (fmt
->has_signed_zero
&& HONOR_SIGNED_ZEROS (fmode
))
5258 arg
= fold_build2 (LT_EXPR
, TREE_TYPE (exp
), arg
,
5259 build_real (TREE_TYPE (arg
), dconst0
));
5260 return expand_expr (arg
, target
, VOIDmode
, EXPAND_NORMAL
);
5263 temp
= expand_expr (arg
, NULL_RTX
, VOIDmode
, 0);
5264 if (GET_MODE_SIZE (fmode
) <= UNITS_PER_WORD
)
5266 imode
= int_mode_for_mode (fmode
);
5267 if (imode
== BLKmode
)
5269 temp
= gen_lowpart (imode
, temp
);
5274 /* Handle targets with different FP word orders. */
5275 if (FLOAT_WORDS_BIG_ENDIAN
)
5276 word
= (GET_MODE_BITSIZE (fmode
) - bitpos
) / BITS_PER_WORD
;
5278 word
= bitpos
/ BITS_PER_WORD
;
5279 temp
= operand_subword_force (temp
, word
, fmode
);
5280 bitpos
= bitpos
% BITS_PER_WORD
;
5283 /* Force the intermediate word_mode (or narrower) result into a
5284 register. This avoids attempting to create paradoxical SUBREGs
5285 of floating point modes below. */
5286 temp
= force_reg (imode
, temp
);
5288 /* If the bitpos is within the "result mode" lowpart, the operation
5289 can be implement with a single bitwise AND. Otherwise, we need
5290 a right shift and an AND. */
5292 if (bitpos
< GET_MODE_BITSIZE (rmode
))
5294 if (bitpos
< HOST_BITS_PER_WIDE_INT
)
5297 lo
= (HOST_WIDE_INT
) 1 << bitpos
;
5301 hi
= (HOST_WIDE_INT
) 1 << (bitpos
- HOST_BITS_PER_WIDE_INT
);
5306 temp
= gen_lowpart (rmode
, temp
);
5307 temp
= expand_binop (rmode
, and_optab
, temp
,
5308 immed_double_const (lo
, hi
, rmode
),
5309 NULL_RTX
, 1, OPTAB_LIB_WIDEN
);
5313 /* Perform a logical right shift to place the signbit in the least
5314 significant bit, then truncate the result to the desired mode
5315 and mask just this bit. */
5316 temp
= expand_shift (RSHIFT_EXPR
, imode
, temp
,
5317 build_int_cst (NULL_TREE
, bitpos
), NULL_RTX
, 1);
5318 temp
= gen_lowpart (rmode
, temp
);
5319 temp
= expand_binop (rmode
, and_optab
, temp
, const1_rtx
,
5320 NULL_RTX
, 1, OPTAB_LIB_WIDEN
);
5326 /* Expand fork or exec calls. TARGET is the desired target of the
5327 call. ARGLIST is the list of arguments of the call. FN is the
5328 identificator of the actual function. IGNORE is nonzero if the
5329 value is to be ignored. */
5332 expand_builtin_fork_or_exec (tree fn
, tree arglist
, rtx target
, int ignore
)
5337 /* If we are not profiling, just call the function. */
5338 if (!profile_arc_flag
)
5341 /* Otherwise call the wrapper. This should be equivalent for the rest of
5342 compiler, so the code does not diverge, and the wrapper may run the
5343 code necessary for keeping the profiling sane. */
5345 switch (DECL_FUNCTION_CODE (fn
))
5348 id
= get_identifier ("__gcov_fork");
5351 case BUILT_IN_EXECL
:
5352 id
= get_identifier ("__gcov_execl");
5355 case BUILT_IN_EXECV
:
5356 id
= get_identifier ("__gcov_execv");
5359 case BUILT_IN_EXECLP
:
5360 id
= get_identifier ("__gcov_execlp");
5363 case BUILT_IN_EXECLE
:
5364 id
= get_identifier ("__gcov_execle");
5367 case BUILT_IN_EXECVP
:
5368 id
= get_identifier ("__gcov_execvp");
5371 case BUILT_IN_EXECVE
:
5372 id
= get_identifier ("__gcov_execve");
5379 decl
= build_decl (FUNCTION_DECL
, id
, TREE_TYPE (fn
));
5380 DECL_EXTERNAL (decl
) = 1;
5381 TREE_PUBLIC (decl
) = 1;
5382 DECL_ARTIFICIAL (decl
) = 1;
5383 TREE_NOTHROW (decl
) = 1;
5384 call
= build_function_call_expr (decl
, arglist
);
5386 return expand_call (call
, target
, ignore
);
5390 /* Reconstitute a mode for a __sync intrinsic operation. Since the type of
5391 the pointer in these functions is void*, the tree optimizers may remove
5392 casts. The mode computed in expand_builtin isn't reliable either, due
5393 to __sync_bool_compare_and_swap.
5395 FCODE_DIFF should be fcode - base, where base is the FOO_1 code for the
5396 group of builtins. This gives us log2 of the mode size. */
5398 static inline enum machine_mode
5399 get_builtin_sync_mode (int fcode_diff
)
5401 /* The size is not negotiable, so ask not to get BLKmode in return
5402 if the target indicates that a smaller size would be better. */
5403 return mode_for_size (BITS_PER_UNIT
<< fcode_diff
, MODE_INT
, 0);
5406 /* Expand the __sync_xxx_and_fetch and __sync_fetch_and_xxx intrinsics.
5407 ARGLIST is the operands list to the function. CODE is the rtx code
5408 that corresponds to the arithmetic or logical operation from the name;
5409 an exception here is that NOT actually means NAND. TARGET is an optional
5410 place for us to store the results; AFTER is true if this is the
5411 fetch_and_xxx form. IGNORE is true if we don't actually care about
5412 the result of the operation at all. */
5415 expand_builtin_sync_operation (enum machine_mode mode
, tree arglist
,
5416 enum rtx_code code
, bool after
,
5417 rtx target
, bool ignore
)
5421 /* Expand the operands. */
5422 addr
= expand_expr (TREE_VALUE (arglist
), NULL
, Pmode
, EXPAND_SUM
);
5424 arglist
= TREE_CHAIN (arglist
);
5425 val
= expand_expr (TREE_VALUE (arglist
), NULL
, mode
, EXPAND_NORMAL
);
5427 /* Note that we explicitly do not want any alias information for this
5428 memory, so that we kill all other live memories. Otherwise we don't
5429 satisfy the full barrier semantics of the intrinsic. */
5430 mem
= validize_mem (gen_rtx_MEM (mode
, addr
));
5431 MEM_VOLATILE_P (mem
) = 1;
5434 return expand_sync_operation (mem
, val
, code
);
5436 return expand_sync_fetch_operation (mem
, val
, code
, after
, target
);
5439 /* Expand the __sync_val_compare_and_swap and __sync_bool_compare_and_swap
5440 intrinsics. ARGLIST is the operands list to the function. IS_BOOL is
5441 true if this is the boolean form. TARGET is a place for us to store the
5442 results; this is NOT optional if IS_BOOL is true. */
5445 expand_builtin_compare_and_swap (enum machine_mode mode
, tree arglist
,
5446 bool is_bool
, rtx target
)
5448 rtx addr
, old_val
, new_val
, mem
;
5450 /* Expand the operands. */
5451 addr
= expand_expr (TREE_VALUE (arglist
), NULL
, Pmode
, EXPAND_SUM
);
5453 arglist
= TREE_CHAIN (arglist
);
5454 old_val
= expand_expr (TREE_VALUE (arglist
), NULL
, mode
, EXPAND_NORMAL
);
5456 arglist
= TREE_CHAIN (arglist
);
5457 new_val
= expand_expr (TREE_VALUE (arglist
), NULL
, mode
, EXPAND_NORMAL
);
5459 /* Note that we explicitly do not want any alias information for this
5460 memory, so that we kill all other live memories. Otherwise we don't
5461 satisfy the full barrier semantics of the intrinsic. */
5462 mem
= validize_mem (gen_rtx_MEM (mode
, addr
));
5463 MEM_VOLATILE_P (mem
) = 1;
5466 return expand_bool_compare_and_swap (mem
, old_val
, new_val
, target
);
5468 return expand_val_compare_and_swap (mem
, old_val
, new_val
, target
);
5471 /* Expand the __sync_lock_test_and_set intrinsic. Note that the most
5472 general form is actually an atomic exchange, and some targets only
5473 support a reduced form with the second argument being a constant 1.
5474 ARGLIST is the operands list to the function; TARGET is an optional
5475 place for us to store the results. */
5478 expand_builtin_lock_test_and_set (enum machine_mode mode
, tree arglist
,
5483 /* Expand the operands. */
5484 addr
= expand_expr (TREE_VALUE (arglist
), NULL
, Pmode
, EXPAND_NORMAL
);
5486 arglist
= TREE_CHAIN (arglist
);
5487 val
= expand_expr (TREE_VALUE (arglist
), NULL
, mode
, EXPAND_NORMAL
);
5489 /* Note that we explicitly do not want any alias information for this
5490 memory, so that we kill all other live memories. Otherwise we don't
5491 satisfy the barrier semantics of the intrinsic. */
5492 mem
= validize_mem (gen_rtx_MEM (mode
, addr
));
5493 MEM_VOLATILE_P (mem
) = 1;
5495 return expand_sync_lock_test_and_set (mem
, val
, target
);
5498 /* Expand the __sync_synchronize intrinsic. */
5501 expand_builtin_synchronize (void)
5505 #ifdef HAVE_memory_barrier
5506 if (HAVE_memory_barrier
)
5508 emit_insn (gen_memory_barrier ());
5513 /* If no explicit memory barrier instruction is available, create an
5514 empty asm stmt with a memory clobber. */
5515 x
= build4 (ASM_EXPR
, void_type_node
, build_string (0, ""), NULL
, NULL
,
5516 tree_cons (NULL
, build_string (6, "memory"), NULL
));
5517 ASM_VOLATILE_P (x
) = 1;
5518 expand_asm_expr (x
);
5521 /* Expand the __sync_lock_release intrinsic. ARGLIST is the operands list
5525 expand_builtin_lock_release (enum machine_mode mode
, tree arglist
)
5527 enum insn_code icode
;
5528 rtx addr
, mem
, insn
;
5529 rtx val
= const0_rtx
;
5531 /* Expand the operands. */
5532 addr
= expand_expr (TREE_VALUE (arglist
), NULL
, Pmode
, EXPAND_NORMAL
);
5534 /* Note that we explicitly do not want any alias information for this
5535 memory, so that we kill all other live memories. Otherwise we don't
5536 satisfy the barrier semantics of the intrinsic. */
5537 mem
= validize_mem (gen_rtx_MEM (mode
, addr
));
5538 MEM_VOLATILE_P (mem
) = 1;
5540 /* If there is an explicit operation in the md file, use it. */
5541 icode
= sync_lock_release
[mode
];
5542 if (icode
!= CODE_FOR_nothing
)
5544 if (!insn_data
[icode
].operand
[1].predicate (val
, mode
))
5545 val
= force_reg (mode
, val
);
5547 insn
= GEN_FCN (icode
) (mem
, val
);
5555 /* Otherwise we can implement this operation by emitting a barrier
5556 followed by a store of zero. */
5557 expand_builtin_synchronize ();
5558 emit_move_insn (mem
, val
);
5561 /* Expand an expression EXP that calls a built-in function,
5562 with result going to TARGET if that's convenient
5563 (and in mode MODE if that's convenient).
5564 SUBTARGET may be used as the target for computing one of EXP's operands.
5565 IGNORE is nonzero if the value is to be ignored. */
5568 expand_builtin (tree exp
, rtx target
, rtx subtarget
, enum machine_mode mode
,
5571 tree fndecl
= get_callee_fndecl (exp
);
5572 tree arglist
= TREE_OPERAND (exp
, 1);
5573 enum built_in_function fcode
= DECL_FUNCTION_CODE (fndecl
);
5574 enum machine_mode target_mode
= TYPE_MODE (TREE_TYPE (exp
));
5576 if (DECL_BUILT_IN_CLASS (fndecl
) == BUILT_IN_MD
)
5577 return targetm
.expand_builtin (exp
, target
, subtarget
, mode
, ignore
);
5579 /* When not optimizing, generate calls to library functions for a certain
5582 && !called_as_built_in (fndecl
)
5583 && DECL_ASSEMBLER_NAME_SET_P (fndecl
)
5584 && fcode
!= BUILT_IN_ALLOCA
)
5585 return expand_call (exp
, target
, ignore
);
5587 /* The built-in function expanders test for target == const0_rtx
5588 to determine whether the function's result will be ignored. */
5590 target
= const0_rtx
;
5592 /* If the result of a pure or const built-in function is ignored, and
5593 none of its arguments are volatile, we can avoid expanding the
5594 built-in call and just evaluate the arguments for side-effects. */
5595 if (target
== const0_rtx
5596 && (DECL_IS_PURE (fndecl
) || TREE_READONLY (fndecl
)))
5598 bool volatilep
= false;
5601 for (arg
= arglist
; arg
; arg
= TREE_CHAIN (arg
))
5602 if (TREE_THIS_VOLATILE (TREE_VALUE (arg
)))
5610 for (arg
= arglist
; arg
; arg
= TREE_CHAIN (arg
))
5611 expand_expr (TREE_VALUE (arg
), const0_rtx
,
5612 VOIDmode
, EXPAND_NORMAL
);
5620 case BUILT_IN_FABSF
:
5621 case BUILT_IN_FABSL
:
5622 target
= expand_builtin_fabs (arglist
, target
, subtarget
);
5627 case BUILT_IN_COPYSIGN
:
5628 case BUILT_IN_COPYSIGNF
:
5629 case BUILT_IN_COPYSIGNL
:
5630 target
= expand_builtin_copysign (arglist
, target
, subtarget
);
5635 /* Just do a normal library call if we were unable to fold
5638 case BUILT_IN_CABSF
:
5639 case BUILT_IN_CABSL
:
5645 case BUILT_IN_EXP10
:
5646 case BUILT_IN_EXP10F
:
5647 case BUILT_IN_EXP10L
:
5648 case BUILT_IN_POW10
:
5649 case BUILT_IN_POW10F
:
5650 case BUILT_IN_POW10L
:
5652 case BUILT_IN_EXP2F
:
5653 case BUILT_IN_EXP2L
:
5654 case BUILT_IN_EXPM1
:
5655 case BUILT_IN_EXPM1F
:
5656 case BUILT_IN_EXPM1L
:
5658 case BUILT_IN_LOGBF
:
5659 case BUILT_IN_LOGBL
:
5660 case BUILT_IN_ILOGB
:
5661 case BUILT_IN_ILOGBF
:
5662 case BUILT_IN_ILOGBL
:
5666 case BUILT_IN_LOG10
:
5667 case BUILT_IN_LOG10F
:
5668 case BUILT_IN_LOG10L
:
5670 case BUILT_IN_LOG2F
:
5671 case BUILT_IN_LOG2L
:
5672 case BUILT_IN_LOG1P
:
5673 case BUILT_IN_LOG1PF
:
5674 case BUILT_IN_LOG1PL
:
5679 case BUILT_IN_ASINF
:
5680 case BUILT_IN_ASINL
:
5682 case BUILT_IN_ACOSF
:
5683 case BUILT_IN_ACOSL
:
5685 case BUILT_IN_ATANF
:
5686 case BUILT_IN_ATANL
:
5687 /* Treat these like sqrt only if unsafe math optimizations are allowed,
5688 because of possible accuracy problems. */
5689 if (! flag_unsafe_math_optimizations
)
5692 case BUILT_IN_SQRTF
:
5693 case BUILT_IN_SQRTL
:
5694 case BUILT_IN_FLOOR
:
5695 case BUILT_IN_FLOORF
:
5696 case BUILT_IN_FLOORL
:
5698 case BUILT_IN_CEILF
:
5699 case BUILT_IN_CEILL
:
5700 case BUILT_IN_TRUNC
:
5701 case BUILT_IN_TRUNCF
:
5702 case BUILT_IN_TRUNCL
:
5703 case BUILT_IN_ROUND
:
5704 case BUILT_IN_ROUNDF
:
5705 case BUILT_IN_ROUNDL
:
5706 case BUILT_IN_NEARBYINT
:
5707 case BUILT_IN_NEARBYINTF
:
5708 case BUILT_IN_NEARBYINTL
:
5710 case BUILT_IN_RINTF
:
5711 case BUILT_IN_RINTL
:
5712 case BUILT_IN_LRINT
:
5713 case BUILT_IN_LRINTF
:
5714 case BUILT_IN_LRINTL
:
5715 case BUILT_IN_LLRINT
:
5716 case BUILT_IN_LLRINTF
:
5717 case BUILT_IN_LLRINTL
:
5718 target
= expand_builtin_mathfn (exp
, target
, subtarget
);
5723 case BUILT_IN_LCEIL
:
5724 case BUILT_IN_LCEILF
:
5725 case BUILT_IN_LCEILL
:
5726 case BUILT_IN_LLCEIL
:
5727 case BUILT_IN_LLCEILF
:
5728 case BUILT_IN_LLCEILL
:
5729 case BUILT_IN_LFLOOR
:
5730 case BUILT_IN_LFLOORF
:
5731 case BUILT_IN_LFLOORL
:
5732 case BUILT_IN_LLFLOOR
:
5733 case BUILT_IN_LLFLOORF
:
5734 case BUILT_IN_LLFLOORL
:
5735 target
= expand_builtin_int_roundingfn (exp
, target
, subtarget
);
5743 target
= expand_builtin_pow (exp
, target
, subtarget
);
5749 case BUILT_IN_POWIF
:
5750 case BUILT_IN_POWIL
:
5751 target
= expand_builtin_powi (exp
, target
, subtarget
);
5756 case BUILT_IN_ATAN2
:
5757 case BUILT_IN_ATAN2F
:
5758 case BUILT_IN_ATAN2L
:
5759 case BUILT_IN_LDEXP
:
5760 case BUILT_IN_LDEXPF
:
5761 case BUILT_IN_LDEXPL
:
5763 case BUILT_IN_FMODF
:
5764 case BUILT_IN_FMODL
:
5766 case BUILT_IN_DREMF
:
5767 case BUILT_IN_DREML
:
5768 if (! flag_unsafe_math_optimizations
)
5770 target
= expand_builtin_mathfn_2 (exp
, target
, subtarget
);
5781 if (! flag_unsafe_math_optimizations
)
5783 target
= expand_builtin_mathfn_3 (exp
, target
, subtarget
);
5788 case BUILT_IN_APPLY_ARGS
:
5789 return expand_builtin_apply_args ();
5791 /* __builtin_apply (FUNCTION, ARGUMENTS, ARGSIZE) invokes
5792 FUNCTION with a copy of the parameters described by
5793 ARGUMENTS, and ARGSIZE. It returns a block of memory
5794 allocated on the stack into which is stored all the registers
5795 that might possibly be used for returning the result of a
5796 function. ARGUMENTS is the value returned by
5797 __builtin_apply_args. ARGSIZE is the number of bytes of
5798 arguments that must be copied. ??? How should this value be
5799 computed? We'll also need a safe worst case value for varargs
5801 case BUILT_IN_APPLY
:
5802 if (!validate_arglist (arglist
, POINTER_TYPE
,
5803 POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
)
5804 && !validate_arglist (arglist
, REFERENCE_TYPE
,
5805 POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
5813 for (t
= arglist
, i
= 0; t
; t
= TREE_CHAIN (t
), i
++)
5814 ops
[i
] = expand_expr (TREE_VALUE (t
), NULL_RTX
, VOIDmode
, 0);
5816 return expand_builtin_apply (ops
[0], ops
[1], ops
[2]);
5819 /* __builtin_return (RESULT) causes the function to return the
5820 value described by RESULT. RESULT is address of the block of
5821 memory returned by __builtin_apply. */
5822 case BUILT_IN_RETURN
:
5823 if (validate_arglist (arglist
, POINTER_TYPE
, VOID_TYPE
))
5824 expand_builtin_return (expand_expr (TREE_VALUE (arglist
),
5825 NULL_RTX
, VOIDmode
, 0));
5828 case BUILT_IN_SAVEREGS
:
5829 return expand_builtin_saveregs ();
5831 case BUILT_IN_ARGS_INFO
:
5832 return expand_builtin_args_info (arglist
);
5834 /* Return the address of the first anonymous stack arg. */
5835 case BUILT_IN_NEXT_ARG
:
5836 if (fold_builtin_next_arg (arglist
))
5838 return expand_builtin_next_arg ();
5840 case BUILT_IN_CLASSIFY_TYPE
:
5841 return expand_builtin_classify_type (arglist
);
5843 case BUILT_IN_CONSTANT_P
:
5846 case BUILT_IN_FRAME_ADDRESS
:
5847 case BUILT_IN_RETURN_ADDRESS
:
5848 return expand_builtin_frame_address (fndecl
, arglist
);
5850 /* Returns the address of the area where the structure is returned.
5852 case BUILT_IN_AGGREGATE_INCOMING_ADDRESS
:
5854 || ! AGGREGATE_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl
)))
5855 || !MEM_P (DECL_RTL (DECL_RESULT (current_function_decl
))))
5858 return XEXP (DECL_RTL (DECL_RESULT (current_function_decl
)), 0);
5860 case BUILT_IN_ALLOCA
:
5861 target
= expand_builtin_alloca (arglist
, target
);
5866 case BUILT_IN_STACK_SAVE
:
5867 return expand_stack_save ();
5869 case BUILT_IN_STACK_RESTORE
:
5870 expand_stack_restore (TREE_VALUE (arglist
));
5875 case BUILT_IN_FFSLL
:
5876 case BUILT_IN_FFSIMAX
:
5877 target
= expand_builtin_unop (target_mode
, arglist
, target
,
5878 subtarget
, ffs_optab
);
5885 case BUILT_IN_CLZLL
:
5886 case BUILT_IN_CLZIMAX
:
5887 target
= expand_builtin_unop (target_mode
, arglist
, target
,
5888 subtarget
, clz_optab
);
5895 case BUILT_IN_CTZLL
:
5896 case BUILT_IN_CTZIMAX
:
5897 target
= expand_builtin_unop (target_mode
, arglist
, target
,
5898 subtarget
, ctz_optab
);
5903 case BUILT_IN_POPCOUNT
:
5904 case BUILT_IN_POPCOUNTL
:
5905 case BUILT_IN_POPCOUNTLL
:
5906 case BUILT_IN_POPCOUNTIMAX
:
5907 target
= expand_builtin_unop (target_mode
, arglist
, target
,
5908 subtarget
, popcount_optab
);
5913 case BUILT_IN_PARITY
:
5914 case BUILT_IN_PARITYL
:
5915 case BUILT_IN_PARITYLL
:
5916 case BUILT_IN_PARITYIMAX
:
5917 target
= expand_builtin_unop (target_mode
, arglist
, target
,
5918 subtarget
, parity_optab
);
5923 case BUILT_IN_STRLEN
:
5924 target
= expand_builtin_strlen (arglist
, target
, target_mode
);
5929 case BUILT_IN_STRCPY
:
5930 target
= expand_builtin_strcpy (fndecl
, arglist
, target
, mode
);
5935 case BUILT_IN_STRNCPY
:
5936 target
= expand_builtin_strncpy (exp
, target
, mode
);
5941 case BUILT_IN_STPCPY
:
5942 target
= expand_builtin_stpcpy (exp
, target
, mode
);
5947 case BUILT_IN_STRCAT
:
5948 target
= expand_builtin_strcat (fndecl
, arglist
, target
, mode
);
5953 case BUILT_IN_STRNCAT
:
5954 target
= expand_builtin_strncat (arglist
, target
, mode
);
5959 case BUILT_IN_STRSPN
:
5960 target
= expand_builtin_strspn (arglist
, target
, mode
);
5965 case BUILT_IN_STRCSPN
:
5966 target
= expand_builtin_strcspn (arglist
, target
, mode
);
5971 case BUILT_IN_STRSTR
:
5972 target
= expand_builtin_strstr (arglist
, TREE_TYPE (exp
), target
, mode
);
5977 case BUILT_IN_STRPBRK
:
5978 target
= expand_builtin_strpbrk (arglist
, TREE_TYPE (exp
), target
, mode
);
5983 case BUILT_IN_INDEX
:
5984 case BUILT_IN_STRCHR
:
5985 target
= expand_builtin_strchr (arglist
, TREE_TYPE (exp
), target
, mode
);
5990 case BUILT_IN_RINDEX
:
5991 case BUILT_IN_STRRCHR
:
5992 target
= expand_builtin_strrchr (arglist
, TREE_TYPE (exp
), target
, mode
);
5997 case BUILT_IN_MEMCPY
:
5998 target
= expand_builtin_memcpy (exp
, target
, mode
);
6003 case BUILT_IN_MEMPCPY
:
6004 target
= expand_builtin_mempcpy (arglist
, TREE_TYPE (exp
), target
, mode
, /*endp=*/ 1);
6009 case BUILT_IN_MEMMOVE
:
6010 target
= expand_builtin_memmove (arglist
, TREE_TYPE (exp
), target
,
6016 case BUILT_IN_BCOPY
:
6017 target
= expand_builtin_bcopy (exp
);
6022 case BUILT_IN_MEMSET
:
6023 target
= expand_builtin_memset (arglist
, target
, mode
, exp
);
6028 case BUILT_IN_BZERO
:
6029 target
= expand_builtin_bzero (exp
);
6034 case BUILT_IN_STRCMP
:
6035 target
= expand_builtin_strcmp (exp
, target
, mode
);
6040 case BUILT_IN_STRNCMP
:
6041 target
= expand_builtin_strncmp (exp
, target
, mode
);
6047 case BUILT_IN_MEMCMP
:
6048 target
= expand_builtin_memcmp (exp
, arglist
, target
, mode
);
6053 case BUILT_IN_SETJMP
:
6054 target
= expand_builtin_setjmp (arglist
, target
);
6059 /* __builtin_longjmp is passed a pointer to an array of five words.
6060 It's similar to the C library longjmp function but works with
6061 __builtin_setjmp above. */
6062 case BUILT_IN_LONGJMP
:
6063 if (!validate_arglist (arglist
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
6067 rtx buf_addr
= expand_expr (TREE_VALUE (arglist
), subtarget
,
6069 rtx value
= expand_expr (TREE_VALUE (TREE_CHAIN (arglist
)),
6070 NULL_RTX
, VOIDmode
, 0);
6072 if (value
!= const1_rtx
)
6074 error ("%<__builtin_longjmp%> second argument must be 1");
6078 expand_builtin_longjmp (buf_addr
, value
);
6082 case BUILT_IN_NONLOCAL_GOTO
:
6083 target
= expand_builtin_nonlocal_goto (arglist
);
6088 /* This updates the setjmp buffer that is its argument with the value
6089 of the current stack pointer. */
6090 case BUILT_IN_UPDATE_SETJMP_BUF
:
6091 if (validate_arglist (arglist
, POINTER_TYPE
, VOID_TYPE
))
6094 = expand_expr (TREE_VALUE (arglist
), NULL_RTX
, VOIDmode
, 0);
6096 expand_builtin_update_setjmp_buf (buf_addr
);
6102 expand_builtin_trap ();
6105 case BUILT_IN_PRINTF
:
6106 target
= expand_builtin_printf (exp
, target
, mode
, false);
6111 case BUILT_IN_PRINTF_UNLOCKED
:
6112 target
= expand_builtin_printf (exp
, target
, mode
, true);
6117 case BUILT_IN_FPUTS
:
6118 target
= expand_builtin_fputs (arglist
, target
, false);
6122 case BUILT_IN_FPUTS_UNLOCKED
:
6123 target
= expand_builtin_fputs (arglist
, target
, true);
6128 case BUILT_IN_FPRINTF
:
6129 target
= expand_builtin_fprintf (exp
, target
, mode
, false);
6134 case BUILT_IN_FPRINTF_UNLOCKED
:
6135 target
= expand_builtin_fprintf (exp
, target
, mode
, true);
6140 case BUILT_IN_SPRINTF
:
6141 target
= expand_builtin_sprintf (arglist
, target
, mode
);
6146 case BUILT_IN_SIGNBIT
:
6147 case BUILT_IN_SIGNBITF
:
6148 case BUILT_IN_SIGNBITL
:
6149 target
= expand_builtin_signbit (exp
, target
);
6154 /* Various hooks for the DWARF 2 __throw routine. */
6155 case BUILT_IN_UNWIND_INIT
:
6156 expand_builtin_unwind_init ();
6158 case BUILT_IN_DWARF_CFA
:
6159 return virtual_cfa_rtx
;
6160 #ifdef DWARF2_UNWIND_INFO
6161 case BUILT_IN_DWARF_SP_COLUMN
:
6162 return expand_builtin_dwarf_sp_column ();
6163 case BUILT_IN_INIT_DWARF_REG_SIZES
:
6164 expand_builtin_init_dwarf_reg_sizes (TREE_VALUE (arglist
));
6167 case BUILT_IN_FROB_RETURN_ADDR
:
6168 return expand_builtin_frob_return_addr (TREE_VALUE (arglist
));
6169 case BUILT_IN_EXTRACT_RETURN_ADDR
:
6170 return expand_builtin_extract_return_addr (TREE_VALUE (arglist
));
6171 case BUILT_IN_EH_RETURN
:
6172 expand_builtin_eh_return (TREE_VALUE (arglist
),
6173 TREE_VALUE (TREE_CHAIN (arglist
)));
6175 #ifdef EH_RETURN_DATA_REGNO
6176 case BUILT_IN_EH_RETURN_DATA_REGNO
:
6177 return expand_builtin_eh_return_data_regno (arglist
);
6179 case BUILT_IN_EXTEND_POINTER
:
6180 return expand_builtin_extend_pointer (TREE_VALUE (arglist
));
6182 case BUILT_IN_VA_START
:
6183 case BUILT_IN_STDARG_START
:
6184 return expand_builtin_va_start (arglist
);
6185 case BUILT_IN_VA_END
:
6186 return expand_builtin_va_end (arglist
);
6187 case BUILT_IN_VA_COPY
:
6188 return expand_builtin_va_copy (arglist
);
6189 case BUILT_IN_EXPECT
:
6190 return expand_builtin_expect (arglist
, target
);
6191 case BUILT_IN_PREFETCH
:
6192 expand_builtin_prefetch (arglist
);
6195 case BUILT_IN_PROFILE_FUNC_ENTER
:
6196 return expand_builtin_profile_func (false);
6197 case BUILT_IN_PROFILE_FUNC_EXIT
:
6198 return expand_builtin_profile_func (true);
6200 case BUILT_IN_INIT_TRAMPOLINE
:
6201 return expand_builtin_init_trampoline (arglist
);
6202 case BUILT_IN_ADJUST_TRAMPOLINE
:
6203 return expand_builtin_adjust_trampoline (arglist
);
6206 case BUILT_IN_EXECL
:
6207 case BUILT_IN_EXECV
:
6208 case BUILT_IN_EXECLP
:
6209 case BUILT_IN_EXECLE
:
6210 case BUILT_IN_EXECVP
:
6211 case BUILT_IN_EXECVE
:
6212 target
= expand_builtin_fork_or_exec (fndecl
, arglist
, target
, ignore
);
6217 case BUILT_IN_FETCH_AND_ADD_1
:
6218 case BUILT_IN_FETCH_AND_ADD_2
:
6219 case BUILT_IN_FETCH_AND_ADD_4
:
6220 case BUILT_IN_FETCH_AND_ADD_8
:
6221 case BUILT_IN_FETCH_AND_ADD_16
:
6222 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_FETCH_AND_ADD_1
);
6223 target
= expand_builtin_sync_operation (mode
, arglist
, PLUS
,
6224 false, target
, ignore
);
6229 case BUILT_IN_FETCH_AND_SUB_1
:
6230 case BUILT_IN_FETCH_AND_SUB_2
:
6231 case BUILT_IN_FETCH_AND_SUB_4
:
6232 case BUILT_IN_FETCH_AND_SUB_8
:
6233 case BUILT_IN_FETCH_AND_SUB_16
:
6234 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_FETCH_AND_SUB_1
);
6235 target
= expand_builtin_sync_operation (mode
, arglist
, MINUS
,
6236 false, target
, ignore
);
6241 case BUILT_IN_FETCH_AND_OR_1
:
6242 case BUILT_IN_FETCH_AND_OR_2
:
6243 case BUILT_IN_FETCH_AND_OR_4
:
6244 case BUILT_IN_FETCH_AND_OR_8
:
6245 case BUILT_IN_FETCH_AND_OR_16
:
6246 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_FETCH_AND_OR_1
);
6247 target
= expand_builtin_sync_operation (mode
, arglist
, IOR
,
6248 false, target
, ignore
);
6253 case BUILT_IN_FETCH_AND_AND_1
:
6254 case BUILT_IN_FETCH_AND_AND_2
:
6255 case BUILT_IN_FETCH_AND_AND_4
:
6256 case BUILT_IN_FETCH_AND_AND_8
:
6257 case BUILT_IN_FETCH_AND_AND_16
:
6258 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_FETCH_AND_AND_1
);
6259 target
= expand_builtin_sync_operation (mode
, arglist
, AND
,
6260 false, target
, ignore
);
6265 case BUILT_IN_FETCH_AND_XOR_1
:
6266 case BUILT_IN_FETCH_AND_XOR_2
:
6267 case BUILT_IN_FETCH_AND_XOR_4
:
6268 case BUILT_IN_FETCH_AND_XOR_8
:
6269 case BUILT_IN_FETCH_AND_XOR_16
:
6270 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_FETCH_AND_XOR_1
);
6271 target
= expand_builtin_sync_operation (mode
, arglist
, XOR
,
6272 false, target
, ignore
);
6277 case BUILT_IN_FETCH_AND_NAND_1
:
6278 case BUILT_IN_FETCH_AND_NAND_2
:
6279 case BUILT_IN_FETCH_AND_NAND_4
:
6280 case BUILT_IN_FETCH_AND_NAND_8
:
6281 case BUILT_IN_FETCH_AND_NAND_16
:
6282 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_FETCH_AND_NAND_1
);
6283 target
= expand_builtin_sync_operation (mode
, arglist
, NOT
,
6284 false, target
, ignore
);
6289 case BUILT_IN_ADD_AND_FETCH_1
:
6290 case BUILT_IN_ADD_AND_FETCH_2
:
6291 case BUILT_IN_ADD_AND_FETCH_4
:
6292 case BUILT_IN_ADD_AND_FETCH_8
:
6293 case BUILT_IN_ADD_AND_FETCH_16
:
6294 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_ADD_AND_FETCH_1
);
6295 target
= expand_builtin_sync_operation (mode
, arglist
, PLUS
,
6296 true, target
, ignore
);
6301 case BUILT_IN_SUB_AND_FETCH_1
:
6302 case BUILT_IN_SUB_AND_FETCH_2
:
6303 case BUILT_IN_SUB_AND_FETCH_4
:
6304 case BUILT_IN_SUB_AND_FETCH_8
:
6305 case BUILT_IN_SUB_AND_FETCH_16
:
6306 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_SUB_AND_FETCH_1
);
6307 target
= expand_builtin_sync_operation (mode
, arglist
, MINUS
,
6308 true, target
, ignore
);
6313 case BUILT_IN_OR_AND_FETCH_1
:
6314 case BUILT_IN_OR_AND_FETCH_2
:
6315 case BUILT_IN_OR_AND_FETCH_4
:
6316 case BUILT_IN_OR_AND_FETCH_8
:
6317 case BUILT_IN_OR_AND_FETCH_16
:
6318 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_OR_AND_FETCH_1
);
6319 target
= expand_builtin_sync_operation (mode
, arglist
, IOR
,
6320 true, target
, ignore
);
6325 case BUILT_IN_AND_AND_FETCH_1
:
6326 case BUILT_IN_AND_AND_FETCH_2
:
6327 case BUILT_IN_AND_AND_FETCH_4
:
6328 case BUILT_IN_AND_AND_FETCH_8
:
6329 case BUILT_IN_AND_AND_FETCH_16
:
6330 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_AND_AND_FETCH_1
);
6331 target
= expand_builtin_sync_operation (mode
, arglist
, AND
,
6332 true, target
, ignore
);
6337 case BUILT_IN_XOR_AND_FETCH_1
:
6338 case BUILT_IN_XOR_AND_FETCH_2
:
6339 case BUILT_IN_XOR_AND_FETCH_4
:
6340 case BUILT_IN_XOR_AND_FETCH_8
:
6341 case BUILT_IN_XOR_AND_FETCH_16
:
6342 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_XOR_AND_FETCH_1
);
6343 target
= expand_builtin_sync_operation (mode
, arglist
, XOR
,
6344 true, target
, ignore
);
6349 case BUILT_IN_NAND_AND_FETCH_1
:
6350 case BUILT_IN_NAND_AND_FETCH_2
:
6351 case BUILT_IN_NAND_AND_FETCH_4
:
6352 case BUILT_IN_NAND_AND_FETCH_8
:
6353 case BUILT_IN_NAND_AND_FETCH_16
:
6354 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_NAND_AND_FETCH_1
);
6355 target
= expand_builtin_sync_operation (mode
, arglist
, NOT
,
6356 true, target
, ignore
);
6361 case BUILT_IN_BOOL_COMPARE_AND_SWAP_1
:
6362 case BUILT_IN_BOOL_COMPARE_AND_SWAP_2
:
6363 case BUILT_IN_BOOL_COMPARE_AND_SWAP_4
:
6364 case BUILT_IN_BOOL_COMPARE_AND_SWAP_8
:
6365 case BUILT_IN_BOOL_COMPARE_AND_SWAP_16
:
6366 if (mode
== VOIDmode
)
6367 mode
= TYPE_MODE (boolean_type_node
);
6368 if (!target
|| !register_operand (target
, mode
))
6369 target
= gen_reg_rtx (mode
);
6371 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_BOOL_COMPARE_AND_SWAP_1
);
6372 target
= expand_builtin_compare_and_swap (mode
, arglist
, true, target
);
6377 case BUILT_IN_VAL_COMPARE_AND_SWAP_1
:
6378 case BUILT_IN_VAL_COMPARE_AND_SWAP_2
:
6379 case BUILT_IN_VAL_COMPARE_AND_SWAP_4
:
6380 case BUILT_IN_VAL_COMPARE_AND_SWAP_8
:
6381 case BUILT_IN_VAL_COMPARE_AND_SWAP_16
:
6382 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_VAL_COMPARE_AND_SWAP_1
);
6383 target
= expand_builtin_compare_and_swap (mode
, arglist
, false, target
);
6388 case BUILT_IN_LOCK_TEST_AND_SET_1
:
6389 case BUILT_IN_LOCK_TEST_AND_SET_2
:
6390 case BUILT_IN_LOCK_TEST_AND_SET_4
:
6391 case BUILT_IN_LOCK_TEST_AND_SET_8
:
6392 case BUILT_IN_LOCK_TEST_AND_SET_16
:
6393 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_LOCK_TEST_AND_SET_1
);
6394 target
= expand_builtin_lock_test_and_set (mode
, arglist
, target
);
6399 case BUILT_IN_LOCK_RELEASE_1
:
6400 case BUILT_IN_LOCK_RELEASE_2
:
6401 case BUILT_IN_LOCK_RELEASE_4
:
6402 case BUILT_IN_LOCK_RELEASE_8
:
6403 case BUILT_IN_LOCK_RELEASE_16
:
6404 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_LOCK_RELEASE_1
);
6405 expand_builtin_lock_release (mode
, arglist
);
6408 case BUILT_IN_SYNCHRONIZE
:
6409 expand_builtin_synchronize ();
6412 case BUILT_IN_OBJECT_SIZE
:
6413 return expand_builtin_object_size (exp
);
6415 case BUILT_IN_MEMCPY_CHK
:
6416 case BUILT_IN_MEMPCPY_CHK
:
6417 case BUILT_IN_MEMMOVE_CHK
:
6418 case BUILT_IN_MEMSET_CHK
:
6419 target
= expand_builtin_memory_chk (exp
, target
, mode
, fcode
);
6424 case BUILT_IN_STRCPY_CHK
:
6425 case BUILT_IN_STPCPY_CHK
:
6426 case BUILT_IN_STRNCPY_CHK
:
6427 case BUILT_IN_STRCAT_CHK
:
6428 case BUILT_IN_SNPRINTF_CHK
:
6429 case BUILT_IN_VSNPRINTF_CHK
:
6430 maybe_emit_chk_warning (exp
, fcode
);
6433 case BUILT_IN_SPRINTF_CHK
:
6434 case BUILT_IN_VSPRINTF_CHK
:
6435 maybe_emit_sprintf_chk_warning (exp
, fcode
);
6438 default: /* just do library call, if unknown builtin */
6442 /* The switch statement above can drop through to cause the function
6443 to be called normally. */
6444 return expand_call (exp
, target
, ignore
);
6447 /* Determine whether a tree node represents a call to a built-in
6448 function. If the tree T is a call to a built-in function with
6449 the right number of arguments of the appropriate types, return
6450 the DECL_FUNCTION_CODE of the call, e.g. BUILT_IN_SQRT.
6451 Otherwise the return value is END_BUILTINS. */
6453 enum built_in_function
6454 builtin_mathfn_code (tree t
)
6456 tree fndecl
, arglist
, parmlist
;
6457 tree argtype
, parmtype
;
6459 if (TREE_CODE (t
) != CALL_EXPR
6460 || TREE_CODE (TREE_OPERAND (t
, 0)) != ADDR_EXPR
)
6461 return END_BUILTINS
;
6463 fndecl
= get_callee_fndecl (t
);
6464 if (fndecl
== NULL_TREE
6465 || TREE_CODE (fndecl
) != FUNCTION_DECL
6466 || ! DECL_BUILT_IN (fndecl
)
6467 || DECL_BUILT_IN_CLASS (fndecl
) == BUILT_IN_MD
)
6468 return END_BUILTINS
;
6470 arglist
= TREE_OPERAND (t
, 1);
6471 parmlist
= TYPE_ARG_TYPES (TREE_TYPE (fndecl
));
6472 for (; parmlist
; parmlist
= TREE_CHAIN (parmlist
))
6474 /* If a function doesn't take a variable number of arguments,
6475 the last element in the list will have type `void'. */
6476 parmtype
= TREE_VALUE (parmlist
);
6477 if (VOID_TYPE_P (parmtype
))
6480 return END_BUILTINS
;
6481 return DECL_FUNCTION_CODE (fndecl
);
6485 return END_BUILTINS
;
6487 argtype
= TREE_TYPE (TREE_VALUE (arglist
));
6489 if (SCALAR_FLOAT_TYPE_P (parmtype
))
6491 if (! SCALAR_FLOAT_TYPE_P (argtype
))
6492 return END_BUILTINS
;
6494 else if (COMPLEX_FLOAT_TYPE_P (parmtype
))
6496 if (! COMPLEX_FLOAT_TYPE_P (argtype
))
6497 return END_BUILTINS
;
6499 else if (POINTER_TYPE_P (parmtype
))
6501 if (! POINTER_TYPE_P (argtype
))
6502 return END_BUILTINS
;
6504 else if (INTEGRAL_TYPE_P (parmtype
))
6506 if (! INTEGRAL_TYPE_P (argtype
))
6507 return END_BUILTINS
;
6510 return END_BUILTINS
;
6512 arglist
= TREE_CHAIN (arglist
);
6515 /* Variable-length argument list. */
6516 return DECL_FUNCTION_CODE (fndecl
);
6519 /* Fold a call to __builtin_constant_p, if we know it will evaluate to a
6520 constant. ARGLIST is the argument list of the call. */
6523 fold_builtin_constant_p (tree arglist
)
6528 arglist
= TREE_VALUE (arglist
);
6530 /* We return 1 for a numeric type that's known to be a constant
6531 value at compile-time or for an aggregate type that's a
6532 literal constant. */
6533 STRIP_NOPS (arglist
);
6535 /* If we know this is a constant, emit the constant of one. */
6536 if (CONSTANT_CLASS_P (arglist
)
6537 || (TREE_CODE (arglist
) == CONSTRUCTOR
6538 && TREE_CONSTANT (arglist
)))
6539 return integer_one_node
;
6540 if (TREE_CODE (arglist
) == ADDR_EXPR
)
6542 tree op
= TREE_OPERAND (arglist
, 0);
6543 if (TREE_CODE (op
) == STRING_CST
6544 || (TREE_CODE (op
) == ARRAY_REF
6545 && integer_zerop (TREE_OPERAND (op
, 1))
6546 && TREE_CODE (TREE_OPERAND (op
, 0)) == STRING_CST
))
6547 return integer_one_node
;
6550 /* If this expression has side effects, show we don't know it to be a
6551 constant. Likewise if it's a pointer or aggregate type since in
6552 those case we only want literals, since those are only optimized
6553 when generating RTL, not later.
6554 And finally, if we are compiling an initializer, not code, we
6555 need to return a definite result now; there's not going to be any
6556 more optimization done. */
6557 if (TREE_SIDE_EFFECTS (arglist
)
6558 || AGGREGATE_TYPE_P (TREE_TYPE (arglist
))
6559 || POINTER_TYPE_P (TREE_TYPE (arglist
))
6561 return integer_zero_node
;
6566 /* Fold a call to __builtin_expect, if we expect that a comparison against
6567 the argument will fold to a constant. In practice, this means a true
6568 constant or the address of a non-weak symbol. ARGLIST is the argument
6569 list of the call. */
6572 fold_builtin_expect (tree arglist
)
6579 arg
= TREE_VALUE (arglist
);
6581 /* If the argument isn't invariant, then there's nothing we can do. */
6582 if (!TREE_INVARIANT (arg
))
6585 /* If we're looking at an address of a weak decl, then do not fold. */
6588 if (TREE_CODE (inner
) == ADDR_EXPR
)
6592 inner
= TREE_OPERAND (inner
, 0);
6594 while (TREE_CODE (inner
) == COMPONENT_REF
6595 || TREE_CODE (inner
) == ARRAY_REF
);
6596 if (DECL_P (inner
) && DECL_WEAK (inner
))
6600 /* Otherwise, ARG already has the proper type for the return value. */
6604 /* Fold a call to __builtin_classify_type. */
6607 fold_builtin_classify_type (tree arglist
)
6610 return build_int_cst (NULL_TREE
, no_type_class
);
6612 return build_int_cst (NULL_TREE
,
6613 type_to_class (TREE_TYPE (TREE_VALUE (arglist
))));
6616 /* Fold a call to __builtin_strlen. */
6619 fold_builtin_strlen (tree arglist
)
6621 if (!validate_arglist (arglist
, POINTER_TYPE
, VOID_TYPE
))
6625 tree len
= c_strlen (TREE_VALUE (arglist
), 0);
6629 /* Convert from the internal "sizetype" type to "size_t". */
6631 len
= fold_convert (size_type_node
, len
);
6639 /* Fold a call to __builtin_inf or __builtin_huge_val. */
6642 fold_builtin_inf (tree type
, int warn
)
6644 REAL_VALUE_TYPE real
;
6646 /* __builtin_inff is intended to be usable to define INFINITY on all
6647 targets. If an infinity is not available, INFINITY expands "to a
6648 positive constant of type float that overflows at translation
6649 time", footnote "In this case, using INFINITY will violate the
6650 constraint in 6.4.4 and thus require a diagnostic." (C99 7.12#4).
6651 Thus we pedwarn to ensure this constraint violation is
6653 if (!MODE_HAS_INFINITIES (TYPE_MODE (type
)) && warn
)
6654 pedwarn ("target format does not support infinity");
6657 return build_real (type
, real
);
6660 /* Fold a call to __builtin_nan or __builtin_nans. */
6663 fold_builtin_nan (tree arglist
, tree type
, int quiet
)
6665 REAL_VALUE_TYPE real
;
6668 if (!validate_arglist (arglist
, POINTER_TYPE
, VOID_TYPE
))
6670 str
= c_getstr (TREE_VALUE (arglist
));
6674 if (!real_nan (&real
, str
, quiet
, TYPE_MODE (type
)))
6677 return build_real (type
, real
);
6680 /* Return true if the floating point expression T has an integer value.
6681 We also allow +Inf, -Inf and NaN to be considered integer values. */
6684 integer_valued_real_p (tree t
)
6686 switch (TREE_CODE (t
))
6693 case NON_LVALUE_EXPR
:
6694 return integer_valued_real_p (TREE_OPERAND (t
, 0));
6699 return integer_valued_real_p (TREE_OPERAND (t
, 1));
6706 return integer_valued_real_p (TREE_OPERAND (t
, 0))
6707 && integer_valued_real_p (TREE_OPERAND (t
, 1));
6710 return integer_valued_real_p (TREE_OPERAND (t
, 1))
6711 && integer_valued_real_p (TREE_OPERAND (t
, 2));
6714 if (! TREE_CONSTANT_OVERFLOW (t
))
6716 REAL_VALUE_TYPE c
, cint
;
6718 c
= TREE_REAL_CST (t
);
6719 real_trunc (&cint
, TYPE_MODE (TREE_TYPE (t
)), &c
);
6720 return real_identical (&c
, &cint
);
6725 tree type
= TREE_TYPE (TREE_OPERAND (t
, 0));
6726 if (TREE_CODE (type
) == INTEGER_TYPE
)
6728 if (TREE_CODE (type
) == REAL_TYPE
)
6729 return integer_valued_real_p (TREE_OPERAND (t
, 0));
6734 switch (builtin_mathfn_code (t
))
6737 case BUILT_IN_CEILF
:
6738 case BUILT_IN_CEILL
:
6739 case BUILT_IN_FLOOR
:
6740 case BUILT_IN_FLOORF
:
6741 case BUILT_IN_FLOORL
:
6742 case BUILT_IN_NEARBYINT
:
6743 case BUILT_IN_NEARBYINTF
:
6744 case BUILT_IN_NEARBYINTL
:
6746 case BUILT_IN_RINTF
:
6747 case BUILT_IN_RINTL
:
6748 case BUILT_IN_ROUND
:
6749 case BUILT_IN_ROUNDF
:
6750 case BUILT_IN_ROUNDL
:
6751 case BUILT_IN_TRUNC
:
6752 case BUILT_IN_TRUNCF
:
6753 case BUILT_IN_TRUNCL
:
6767 /* EXP is assumed to be builtin call where truncation can be propagated
6768 across (for instance floor((double)f) == (double)floorf (f).
6769 Do the transformation. */
6772 fold_trunc_transparent_mathfn (tree fndecl
, tree arglist
)
6774 enum built_in_function fcode
= DECL_FUNCTION_CODE (fndecl
);
6777 if (! validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
6780 arg
= TREE_VALUE (arglist
);
6781 /* Integer rounding functions are idempotent. */
6782 if (fcode
== builtin_mathfn_code (arg
))
6785 /* If argument is already integer valued, and we don't need to worry
6786 about setting errno, there's no need to perform rounding. */
6787 if (! flag_errno_math
&& integer_valued_real_p (arg
))
6792 tree arg0
= strip_float_extensions (arg
);
6793 tree ftype
= TREE_TYPE (TREE_TYPE (fndecl
));
6794 tree newtype
= TREE_TYPE (arg0
);
6797 if (TYPE_PRECISION (newtype
) < TYPE_PRECISION (ftype
)
6798 && (decl
= mathfn_built_in (newtype
, fcode
)))
6801 build_tree_list (NULL_TREE
, fold_convert (newtype
, arg0
));
6802 return fold_convert (ftype
,
6803 build_function_call_expr (decl
, arglist
));
6809 /* EXP is assumed to be builtin call which can narrow the FP type of
6810 the argument, for instance lround((double)f) -> lroundf (f). */
6813 fold_fixed_mathfn (tree fndecl
, tree arglist
)
6815 enum built_in_function fcode
= DECL_FUNCTION_CODE (fndecl
);
6818 if (! validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
6821 arg
= TREE_VALUE (arglist
);
6823 /* If argument is already integer valued, and we don't need to worry
6824 about setting errno, there's no need to perform rounding. */
6825 if (! flag_errno_math
&& integer_valued_real_p (arg
))
6826 return fold_build1 (FIX_TRUNC_EXPR
, TREE_TYPE (TREE_TYPE (fndecl
)), arg
);
6830 tree ftype
= TREE_TYPE (arg
);
6831 tree arg0
= strip_float_extensions (arg
);
6832 tree newtype
= TREE_TYPE (arg0
);
6835 if (TYPE_PRECISION (newtype
) < TYPE_PRECISION (ftype
)
6836 && (decl
= mathfn_built_in (newtype
, fcode
)))
6839 build_tree_list (NULL_TREE
, fold_convert (newtype
, arg0
));
6840 return build_function_call_expr (decl
, arglist
);
6846 /* Fold function call to builtin cabs, cabsf or cabsl. ARGLIST
6847 is the argument list and TYPE is the return type. Return
6848 NULL_TREE if no if no simplification can be made. */
6851 fold_builtin_cabs (tree arglist
, tree type
)
6855 if (!arglist
|| TREE_CHAIN (arglist
))
6858 arg
= TREE_VALUE (arglist
);
6859 if (TREE_CODE (TREE_TYPE (arg
)) != COMPLEX_TYPE
6860 || TREE_CODE (TREE_TYPE (TREE_TYPE (arg
))) != REAL_TYPE
)
6863 /* Evaluate cabs of a constant at compile-time. */
6864 if (flag_unsafe_math_optimizations
6865 && TREE_CODE (arg
) == COMPLEX_CST
6866 && TREE_CODE (TREE_REALPART (arg
)) == REAL_CST
6867 && TREE_CODE (TREE_IMAGPART (arg
)) == REAL_CST
6868 && ! TREE_CONSTANT_OVERFLOW (TREE_REALPART (arg
))
6869 && ! TREE_CONSTANT_OVERFLOW (TREE_IMAGPART (arg
)))
6871 REAL_VALUE_TYPE r
, i
;
6873 r
= TREE_REAL_CST (TREE_REALPART (arg
));
6874 i
= TREE_REAL_CST (TREE_IMAGPART (arg
));
6876 real_arithmetic (&r
, MULT_EXPR
, &r
, &r
);
6877 real_arithmetic (&i
, MULT_EXPR
, &i
, &i
);
6878 real_arithmetic (&r
, PLUS_EXPR
, &r
, &i
);
6879 if (real_sqrt (&r
, TYPE_MODE (type
), &r
)
6880 || ! flag_trapping_math
)
6881 return build_real (type
, r
);
6884 /* If either part is zero, cabs is fabs of the other. */
6885 if (TREE_CODE (arg
) == COMPLEX_EXPR
6886 && real_zerop (TREE_OPERAND (arg
, 0)))
6887 return fold_build1 (ABS_EXPR
, type
, TREE_OPERAND (arg
, 1));
6888 if (TREE_CODE (arg
) == COMPLEX_EXPR
6889 && real_zerop (TREE_OPERAND (arg
, 1)))
6890 return fold_build1 (ABS_EXPR
, type
, TREE_OPERAND (arg
, 0));
6892 /* Don't do this when optimizing for size. */
6893 if (flag_unsafe_math_optimizations
6894 && optimize
&& !optimize_size
)
6896 tree sqrtfn
= mathfn_built_in (type
, BUILT_IN_SQRT
);
6898 if (sqrtfn
!= NULL_TREE
)
6900 tree rpart
, ipart
, result
, arglist
;
6902 arg
= builtin_save_expr (arg
);
6904 rpart
= fold_build1 (REALPART_EXPR
, type
, arg
);
6905 ipart
= fold_build1 (IMAGPART_EXPR
, type
, arg
);
6907 rpart
= builtin_save_expr (rpart
);
6908 ipart
= builtin_save_expr (ipart
);
6910 result
= fold_build2 (PLUS_EXPR
, type
,
6911 fold_build2 (MULT_EXPR
, type
,
6913 fold_build2 (MULT_EXPR
, type
,
6916 arglist
= build_tree_list (NULL_TREE
, result
);
6917 return build_function_call_expr (sqrtfn
, arglist
);
6924 /* Fold a builtin function call to sqrt, sqrtf, or sqrtl. Return
6925 NULL_TREE if no simplification can be made. */
6928 fold_builtin_sqrt (tree arglist
, tree type
)
6931 enum built_in_function fcode
;
6932 tree arg
= TREE_VALUE (arglist
);
6934 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
6937 /* Optimize sqrt of constant value. */
6938 if (TREE_CODE (arg
) == REAL_CST
6939 && ! TREE_CONSTANT_OVERFLOW (arg
))
6941 REAL_VALUE_TYPE r
, x
;
6943 x
= TREE_REAL_CST (arg
);
6944 if (real_sqrt (&r
, TYPE_MODE (type
), &x
)
6945 || (!flag_trapping_math
&& !flag_errno_math
))
6946 return build_real (type
, r
);
6949 /* Optimize sqrt(expN(x)) = expN(x*0.5). */
6950 fcode
= builtin_mathfn_code (arg
);
6951 if (flag_unsafe_math_optimizations
&& BUILTIN_EXPONENT_P (fcode
))
6953 tree expfn
= TREE_OPERAND (TREE_OPERAND (arg
, 0), 0);
6954 arg
= fold_build2 (MULT_EXPR
, type
,
6955 TREE_VALUE (TREE_OPERAND (arg
, 1)),
6956 build_real (type
, dconsthalf
));
6957 arglist
= build_tree_list (NULL_TREE
, arg
);
6958 return build_function_call_expr (expfn
, arglist
);
6961 /* Optimize sqrt(Nroot(x)) -> pow(x,1/(2*N)). */
6962 if (flag_unsafe_math_optimizations
&& BUILTIN_ROOT_P (fcode
))
6964 tree powfn
= mathfn_built_in (type
, BUILT_IN_POW
);
6968 tree arg0
= TREE_VALUE (TREE_OPERAND (arg
, 1));
6970 /* The inner root was either sqrt or cbrt. */
6971 REAL_VALUE_TYPE dconstroot
=
6972 BUILTIN_SQRT_P (fcode
) ? dconsthalf
: dconstthird
;
6974 /* Adjust for the outer root. */
6975 SET_REAL_EXP (&dconstroot
, REAL_EXP (&dconstroot
) - 1);
6976 dconstroot
= real_value_truncate (TYPE_MODE (type
), dconstroot
);
6977 tree_root
= build_real (type
, dconstroot
);
6978 arglist
= tree_cons (NULL_TREE
, arg0
,
6979 build_tree_list (NULL_TREE
, tree_root
));
6980 return build_function_call_expr (powfn
, arglist
);
6984 /* Optimize sqrt(pow(x,y)) = pow(|x|,y*0.5). */
6985 if (flag_unsafe_math_optimizations
6986 && (fcode
== BUILT_IN_POW
6987 || fcode
== BUILT_IN_POWF
6988 || fcode
== BUILT_IN_POWL
))
6990 tree powfn
= TREE_OPERAND (TREE_OPERAND (arg
, 0), 0);
6991 tree arg0
= TREE_VALUE (TREE_OPERAND (arg
, 1));
6992 tree arg1
= TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg
, 1)));
6994 if (!tree_expr_nonnegative_p (arg0
))
6995 arg0
= build1 (ABS_EXPR
, type
, arg0
);
6996 narg1
= fold_build2 (MULT_EXPR
, type
, arg1
,
6997 build_real (type
, dconsthalf
));
6998 arglist
= tree_cons (NULL_TREE
, arg0
,
6999 build_tree_list (NULL_TREE
, narg1
));
7000 return build_function_call_expr (powfn
, arglist
);
7006 /* Fold a builtin function call to cbrt, cbrtf, or cbrtl. Return
7007 NULL_TREE if no simplification can be made. */
7009 fold_builtin_cbrt (tree arglist
, tree type
)
7011 tree arg
= TREE_VALUE (arglist
);
7012 const enum built_in_function fcode
= builtin_mathfn_code (arg
);
7014 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
7017 /* Optimize cbrt of constant value. */
7018 if (real_zerop (arg
) || real_onep (arg
) || real_minus_onep (arg
))
7021 if (flag_unsafe_math_optimizations
)
7023 /* Optimize cbrt(expN(x)) -> expN(x/3). */
7024 if (BUILTIN_EXPONENT_P (fcode
))
7026 tree expfn
= TREE_OPERAND (TREE_OPERAND (arg
, 0), 0);
7027 const REAL_VALUE_TYPE third_trunc
=
7028 real_value_truncate (TYPE_MODE (type
), dconstthird
);
7029 arg
= fold_build2 (MULT_EXPR
, type
,
7030 TREE_VALUE (TREE_OPERAND (arg
, 1)),
7031 build_real (type
, third_trunc
));
7032 arglist
= build_tree_list (NULL_TREE
, arg
);
7033 return build_function_call_expr (expfn
, arglist
);
7036 /* Optimize cbrt(sqrt(x)) -> pow(x,1/6). */
7037 if (BUILTIN_SQRT_P (fcode
))
7039 tree powfn
= mathfn_built_in (type
, BUILT_IN_POW
);
7043 tree arg0
= TREE_VALUE (TREE_OPERAND (arg
, 1));
7045 REAL_VALUE_TYPE dconstroot
= dconstthird
;
7047 SET_REAL_EXP (&dconstroot
, REAL_EXP (&dconstroot
) - 1);
7048 dconstroot
= real_value_truncate (TYPE_MODE (type
), dconstroot
);
7049 tree_root
= build_real (type
, dconstroot
);
7050 arglist
= tree_cons (NULL_TREE
, arg0
,
7051 build_tree_list (NULL_TREE
, tree_root
));
7052 return build_function_call_expr (powfn
, arglist
);
7056 /* Optimize cbrt(cbrt(x)) -> pow(x,1/9) iff x is nonnegative. */
7057 if (BUILTIN_CBRT_P (fcode
))
7059 tree arg0
= TREE_VALUE (TREE_OPERAND (arg
, 1));
7060 if (tree_expr_nonnegative_p (arg0
))
7062 tree powfn
= mathfn_built_in (type
, BUILT_IN_POW
);
7067 REAL_VALUE_TYPE dconstroot
;
7069 real_arithmetic (&dconstroot
, MULT_EXPR
, &dconstthird
, &dconstthird
);
7070 dconstroot
= real_value_truncate (TYPE_MODE (type
), dconstroot
);
7071 tree_root
= build_real (type
, dconstroot
);
7072 arglist
= tree_cons (NULL_TREE
, arg0
,
7073 build_tree_list (NULL_TREE
, tree_root
));
7074 return build_function_call_expr (powfn
, arglist
);
7079 /* Optimize cbrt(pow(x,y)) -> pow(x,y/3) iff x is nonnegative. */
7080 if (fcode
== BUILT_IN_POW
|| fcode
== BUILT_IN_POWF
7081 || fcode
== BUILT_IN_POWL
)
7083 tree arg00
= TREE_VALUE (TREE_OPERAND (arg
, 1));
7084 tree arg01
= TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg
, 1)));
7085 if (tree_expr_nonnegative_p (arg00
))
7087 tree powfn
= TREE_OPERAND (TREE_OPERAND (arg
, 0), 0);
7088 const REAL_VALUE_TYPE dconstroot
7089 = real_value_truncate (TYPE_MODE (type
), dconstthird
);
7090 tree narg01
= fold_build2 (MULT_EXPR
, type
, arg01
,
7091 build_real (type
, dconstroot
));
7092 arglist
= tree_cons (NULL_TREE
, arg00
,
7093 build_tree_list (NULL_TREE
, narg01
));
7094 return build_function_call_expr (powfn
, arglist
);
7101 /* Fold function call to builtin sin, sinf, or sinl. Return
7102 NULL_TREE if no simplification can be made. */
7104 fold_builtin_sin (tree arglist
)
7106 tree arg
= TREE_VALUE (arglist
);
7108 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
7111 /* Optimize sin (0.0) = 0.0. */
7112 if (real_zerop (arg
))
7118 /* Fold function call to builtin cos, cosf, or cosl. Return
7119 NULL_TREE if no simplification can be made. */
7121 fold_builtin_cos (tree arglist
, tree type
, tree fndecl
)
7123 tree arg
= TREE_VALUE (arglist
);
7125 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
7128 /* Optimize cos (0.0) = 1.0. */
7129 if (real_zerop (arg
))
7130 return build_real (type
, dconst1
);
7132 /* Optimize cos(-x) into cos (x). */
7133 if (TREE_CODE (arg
) == NEGATE_EXPR
)
7135 tree args
= build_tree_list (NULL_TREE
,
7136 TREE_OPERAND (arg
, 0));
7137 return build_function_call_expr (fndecl
, args
);
7143 /* Fold function call to builtin tan, tanf, or tanl. Return
7144 NULL_TREE if no simplification can be made. */
7146 fold_builtin_tan (tree arglist
)
7148 enum built_in_function fcode
;
7149 tree arg
= TREE_VALUE (arglist
);
7151 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
7154 /* Optimize tan(0.0) = 0.0. */
7155 if (real_zerop (arg
))
7158 /* Optimize tan(atan(x)) = x. */
7159 fcode
= builtin_mathfn_code (arg
);
7160 if (flag_unsafe_math_optimizations
7161 && (fcode
== BUILT_IN_ATAN
7162 || fcode
== BUILT_IN_ATANF
7163 || fcode
== BUILT_IN_ATANL
))
7164 return TREE_VALUE (TREE_OPERAND (arg
, 1));
7169 /* Fold function call to builtin atan, atanf, or atanl. Return
7170 NULL_TREE if no simplification can be made. */
7173 fold_builtin_atan (tree arglist
, tree type
)
7176 tree arg
= TREE_VALUE (arglist
);
7178 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
7181 /* Optimize atan(0.0) = 0.0. */
7182 if (real_zerop (arg
))
7185 /* Optimize atan(1.0) = pi/4. */
7186 if (real_onep (arg
))
7188 REAL_VALUE_TYPE cst
;
7190 real_convert (&cst
, TYPE_MODE (type
), &dconstpi
);
7191 SET_REAL_EXP (&cst
, REAL_EXP (&cst
) - 2);
7192 return build_real (type
, cst
);
7198 /* Fold function call to builtin trunc, truncf or truncl. Return
7199 NULL_TREE if no simplification can be made. */
7202 fold_builtin_trunc (tree fndecl
, tree arglist
)
7206 if (! validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
7209 /* Optimize trunc of constant value. */
7210 arg
= TREE_VALUE (arglist
);
7211 if (TREE_CODE (arg
) == REAL_CST
&& ! TREE_CONSTANT_OVERFLOW (arg
))
7213 REAL_VALUE_TYPE r
, x
;
7214 tree type
= TREE_TYPE (TREE_TYPE (fndecl
));
7216 x
= TREE_REAL_CST (arg
);
7217 real_trunc (&r
, TYPE_MODE (type
), &x
);
7218 return build_real (type
, r
);
7221 return fold_trunc_transparent_mathfn (fndecl
, arglist
);
7224 /* Fold function call to builtin floor, floorf or floorl. Return
7225 NULL_TREE if no simplification can be made. */
7228 fold_builtin_floor (tree fndecl
, tree arglist
)
7232 if (! validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
7235 /* Optimize floor of constant value. */
7236 arg
= TREE_VALUE (arglist
);
7237 if (TREE_CODE (arg
) == REAL_CST
&& ! TREE_CONSTANT_OVERFLOW (arg
))
7241 x
= TREE_REAL_CST (arg
);
7242 if (! REAL_VALUE_ISNAN (x
) || ! flag_errno_math
)
7244 tree type
= TREE_TYPE (TREE_TYPE (fndecl
));
7247 real_floor (&r
, TYPE_MODE (type
), &x
);
7248 return build_real (type
, r
);
7252 return fold_trunc_transparent_mathfn (fndecl
, arglist
);
7255 /* Fold function call to builtin ceil, ceilf or ceill. Return
7256 NULL_TREE if no simplification can be made. */
7259 fold_builtin_ceil (tree fndecl
, tree arglist
)
7263 if (! validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
7266 /* Optimize ceil of constant value. */
7267 arg
= TREE_VALUE (arglist
);
7268 if (TREE_CODE (arg
) == REAL_CST
&& ! TREE_CONSTANT_OVERFLOW (arg
))
7272 x
= TREE_REAL_CST (arg
);
7273 if (! REAL_VALUE_ISNAN (x
) || ! flag_errno_math
)
7275 tree type
= TREE_TYPE (TREE_TYPE (fndecl
));
7278 real_ceil (&r
, TYPE_MODE (type
), &x
);
7279 return build_real (type
, r
);
7283 return fold_trunc_transparent_mathfn (fndecl
, arglist
);
7286 /* Fold function call to builtin round, roundf or roundl. Return
7287 NULL_TREE if no simplification can be made. */
7290 fold_builtin_round (tree fndecl
, tree arglist
)
7294 if (! validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
7297 /* Optimize round of constant value. */
7298 arg
= TREE_VALUE (arglist
);
7299 if (TREE_CODE (arg
) == REAL_CST
&& ! TREE_CONSTANT_OVERFLOW (arg
))
7303 x
= TREE_REAL_CST (arg
);
7304 if (! REAL_VALUE_ISNAN (x
) || ! flag_errno_math
)
7306 tree type
= TREE_TYPE (TREE_TYPE (fndecl
));
7309 real_round (&r
, TYPE_MODE (type
), &x
);
7310 return build_real (type
, r
);
7314 return fold_trunc_transparent_mathfn (fndecl
, arglist
);
7317 /* Fold function call to builtin lround, lroundf or lroundl (or the
7318 corresponding long long versions) and other rounding functions.
7319 Return NULL_TREE if no simplification can be made. */
7322 fold_builtin_int_roundingfn (tree fndecl
, tree arglist
)
7326 if (! validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
7329 /* Optimize lround of constant value. */
7330 arg
= TREE_VALUE (arglist
);
7331 if (TREE_CODE (arg
) == REAL_CST
&& ! TREE_CONSTANT_OVERFLOW (arg
))
7333 const REAL_VALUE_TYPE x
= TREE_REAL_CST (arg
);
7335 if (! REAL_VALUE_ISNAN (x
) && ! REAL_VALUE_ISINF (x
))
7337 tree itype
= TREE_TYPE (TREE_TYPE (fndecl
));
7338 tree ftype
= TREE_TYPE (arg
), result
;
7339 HOST_WIDE_INT hi
, lo
;
7342 switch (DECL_FUNCTION_CODE (fndecl
))
7344 case BUILT_IN_LFLOOR
:
7345 case BUILT_IN_LFLOORF
:
7346 case BUILT_IN_LFLOORL
:
7347 case BUILT_IN_LLFLOOR
:
7348 case BUILT_IN_LLFLOORF
:
7349 case BUILT_IN_LLFLOORL
:
7350 real_floor (&r
, TYPE_MODE (ftype
), &x
);
7353 case BUILT_IN_LCEIL
:
7354 case BUILT_IN_LCEILF
:
7355 case BUILT_IN_LCEILL
:
7356 case BUILT_IN_LLCEIL
:
7357 case BUILT_IN_LLCEILF
:
7358 case BUILT_IN_LLCEILL
:
7359 real_ceil (&r
, TYPE_MODE (ftype
), &x
);
7362 case BUILT_IN_LROUND
:
7363 case BUILT_IN_LROUNDF
:
7364 case BUILT_IN_LROUNDL
:
7365 case BUILT_IN_LLROUND
:
7366 case BUILT_IN_LLROUNDF
:
7367 case BUILT_IN_LLROUNDL
:
7368 real_round (&r
, TYPE_MODE (ftype
), &x
);
7375 REAL_VALUE_TO_INT (&lo
, &hi
, r
);
7376 result
= build_int_cst_wide (NULL_TREE
, lo
, hi
);
7377 if (int_fits_type_p (result
, itype
))
7378 return fold_convert (itype
, result
);
7382 return fold_fixed_mathfn (fndecl
, arglist
);
7385 /* Fold function call to builtin ffs, clz, ctz, popcount and parity
7386 and their long and long long variants (i.e. ffsl and ffsll).
7387 Return NULL_TREE if no simplification can be made. */
7390 fold_builtin_bitop (tree fndecl
, tree arglist
)
7394 if (! validate_arglist (arglist
, INTEGER_TYPE
, VOID_TYPE
))
7397 /* Optimize for constant argument. */
7398 arg
= TREE_VALUE (arglist
);
7399 if (TREE_CODE (arg
) == INTEGER_CST
&& ! TREE_CONSTANT_OVERFLOW (arg
))
7401 HOST_WIDE_INT hi
, width
, result
;
7402 unsigned HOST_WIDE_INT lo
;
7405 type
= TREE_TYPE (arg
);
7406 width
= TYPE_PRECISION (type
);
7407 lo
= TREE_INT_CST_LOW (arg
);
7409 /* Clear all the bits that are beyond the type's precision. */
7410 if (width
> HOST_BITS_PER_WIDE_INT
)
7412 hi
= TREE_INT_CST_HIGH (arg
);
7413 if (width
< 2 * HOST_BITS_PER_WIDE_INT
)
7414 hi
&= ~((HOST_WIDE_INT
) (-1) >> (width
- HOST_BITS_PER_WIDE_INT
));
7419 if (width
< HOST_BITS_PER_WIDE_INT
)
7420 lo
&= ~((unsigned HOST_WIDE_INT
) (-1) << width
);
7423 switch (DECL_FUNCTION_CODE (fndecl
))
7427 case BUILT_IN_FFSLL
:
7429 result
= exact_log2 (lo
& -lo
) + 1;
7431 result
= HOST_BITS_PER_WIDE_INT
+ exact_log2 (hi
& -hi
) + 1;
7438 case BUILT_IN_CLZLL
:
7440 result
= width
- floor_log2 (hi
) - 1 - HOST_BITS_PER_WIDE_INT
;
7442 result
= width
- floor_log2 (lo
) - 1;
7443 else if (! CLZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type
), result
))
7449 case BUILT_IN_CTZLL
:
7451 result
= exact_log2 (lo
& -lo
);
7453 result
= HOST_BITS_PER_WIDE_INT
+ exact_log2 (hi
& -hi
);
7454 else if (! CTZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type
), result
))
7458 case BUILT_IN_POPCOUNT
:
7459 case BUILT_IN_POPCOUNTL
:
7460 case BUILT_IN_POPCOUNTLL
:
7463 result
++, lo
&= lo
- 1;
7465 result
++, hi
&= hi
- 1;
7468 case BUILT_IN_PARITY
:
7469 case BUILT_IN_PARITYL
:
7470 case BUILT_IN_PARITYLL
:
7473 result
++, lo
&= lo
- 1;
7475 result
++, hi
&= hi
- 1;
7483 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl
)), result
);
7489 /* Return true if EXPR is the real constant contained in VALUE. */
7492 real_dconstp (tree expr
, const REAL_VALUE_TYPE
*value
)
7496 return ((TREE_CODE (expr
) == REAL_CST
7497 && ! TREE_CONSTANT_OVERFLOW (expr
)
7498 && REAL_VALUES_EQUAL (TREE_REAL_CST (expr
), *value
))
7499 || (TREE_CODE (expr
) == COMPLEX_CST
7500 && real_dconstp (TREE_REALPART (expr
), value
)
7501 && real_zerop (TREE_IMAGPART (expr
))));
7504 /* A subroutine of fold_builtin to fold the various logarithmic
7505 functions. EXP is the CALL_EXPR of a call to a builtin logN
7506 function. VALUE is the base of the logN function. */
7509 fold_builtin_logarithm (tree fndecl
, tree arglist
,
7510 const REAL_VALUE_TYPE
*value
)
7512 if (validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
7514 tree type
= TREE_TYPE (TREE_TYPE (fndecl
));
7515 tree arg
= TREE_VALUE (arglist
);
7516 const enum built_in_function fcode
= builtin_mathfn_code (arg
);
7518 /* Optimize logN(1.0) = 0.0. */
7519 if (real_onep (arg
))
7520 return build_real (type
, dconst0
);
7522 /* Optimize logN(N) = 1.0. If N can't be truncated to MODE
7523 exactly, then only do this if flag_unsafe_math_optimizations. */
7524 if (exact_real_truncate (TYPE_MODE (type
), value
)
7525 || flag_unsafe_math_optimizations
)
7527 const REAL_VALUE_TYPE value_truncate
=
7528 real_value_truncate (TYPE_MODE (type
), *value
);
7529 if (real_dconstp (arg
, &value_truncate
))
7530 return build_real (type
, dconst1
);
7533 /* Special case, optimize logN(expN(x)) = x. */
7534 if (flag_unsafe_math_optimizations
7535 && ((value
== &dconste
7536 && (fcode
== BUILT_IN_EXP
7537 || fcode
== BUILT_IN_EXPF
7538 || fcode
== BUILT_IN_EXPL
))
7539 || (value
== &dconst2
7540 && (fcode
== BUILT_IN_EXP2
7541 || fcode
== BUILT_IN_EXP2F
7542 || fcode
== BUILT_IN_EXP2L
))
7543 || (value
== &dconst10
&& (BUILTIN_EXP10_P (fcode
)))))
7544 return fold_convert (type
, TREE_VALUE (TREE_OPERAND (arg
, 1)));
7546 /* Optimize logN(func()) for various exponential functions. We
7547 want to determine the value "x" and the power "exponent" in
7548 order to transform logN(x**exponent) into exponent*logN(x). */
7549 if (flag_unsafe_math_optimizations
)
7551 tree exponent
= 0, x
= 0;
7558 /* Prepare to do logN(exp(exponent) -> exponent*logN(e). */
7559 x
= build_real (type
,
7560 real_value_truncate (TYPE_MODE (type
), dconste
));
7561 exponent
= TREE_VALUE (TREE_OPERAND (arg
, 1));
7564 case BUILT_IN_EXP2F
:
7565 case BUILT_IN_EXP2L
:
7566 /* Prepare to do logN(exp2(exponent) -> exponent*logN(2). */
7567 x
= build_real (type
, dconst2
);
7568 exponent
= TREE_VALUE (TREE_OPERAND (arg
, 1));
7570 case BUILT_IN_EXP10
:
7571 case BUILT_IN_EXP10F
:
7572 case BUILT_IN_EXP10L
:
7573 case BUILT_IN_POW10
:
7574 case BUILT_IN_POW10F
:
7575 case BUILT_IN_POW10L
:
7576 /* Prepare to do logN(exp10(exponent) -> exponent*logN(10). */
7577 x
= build_real (type
, dconst10
);
7578 exponent
= TREE_VALUE (TREE_OPERAND (arg
, 1));
7581 case BUILT_IN_SQRTF
:
7582 case BUILT_IN_SQRTL
:
7583 /* Prepare to do logN(sqrt(x) -> 0.5*logN(x). */
7584 x
= TREE_VALUE (TREE_OPERAND (arg
, 1));
7585 exponent
= build_real (type
, dconsthalf
);
7588 case BUILT_IN_CBRTF
:
7589 case BUILT_IN_CBRTL
:
7590 /* Prepare to do logN(cbrt(x) -> (1/3)*logN(x). */
7591 x
= TREE_VALUE (TREE_OPERAND (arg
, 1));
7592 exponent
= build_real (type
, real_value_truncate (TYPE_MODE (type
),
7598 /* Prepare to do logN(pow(x,exponent) -> exponent*logN(x). */
7599 x
= TREE_VALUE (TREE_OPERAND (arg
, 1));
7600 exponent
= TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg
, 1)));
7606 /* Now perform the optimization. */
7610 arglist
= build_tree_list (NULL_TREE
, x
);
7611 logfn
= build_function_call_expr (fndecl
, arglist
);
7612 return fold_build2 (MULT_EXPR
, type
, exponent
, logfn
);
7620 /* Fold a builtin function call to pow, powf, or powl. Return
7621 NULL_TREE if no simplification can be made. */
7623 fold_builtin_pow (tree fndecl
, tree arglist
, tree type
)
7625 tree arg0
= TREE_VALUE (arglist
);
7626 tree arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
7628 if (!validate_arglist (arglist
, REAL_TYPE
, REAL_TYPE
, VOID_TYPE
))
7631 /* Optimize pow(1.0,y) = 1.0. */
7632 if (real_onep (arg0
))
7633 return omit_one_operand (type
, build_real (type
, dconst1
), arg1
);
7635 if (TREE_CODE (arg1
) == REAL_CST
7636 && ! TREE_CONSTANT_OVERFLOW (arg1
))
7638 REAL_VALUE_TYPE cint
;
7642 c
= TREE_REAL_CST (arg1
);
7644 /* Optimize pow(x,0.0) = 1.0. */
7645 if (REAL_VALUES_EQUAL (c
, dconst0
))
7646 return omit_one_operand (type
, build_real (type
, dconst1
),
7649 /* Optimize pow(x,1.0) = x. */
7650 if (REAL_VALUES_EQUAL (c
, dconst1
))
7653 /* Optimize pow(x,-1.0) = 1.0/x. */
7654 if (REAL_VALUES_EQUAL (c
, dconstm1
))
7655 return fold_build2 (RDIV_EXPR
, type
,
7656 build_real (type
, dconst1
), arg0
);
7658 /* Optimize pow(x,0.5) = sqrt(x). */
7659 if (flag_unsafe_math_optimizations
7660 && REAL_VALUES_EQUAL (c
, dconsthalf
))
7662 tree sqrtfn
= mathfn_built_in (type
, BUILT_IN_SQRT
);
7664 if (sqrtfn
!= NULL_TREE
)
7666 tree arglist
= build_tree_list (NULL_TREE
, arg0
);
7667 return build_function_call_expr (sqrtfn
, arglist
);
7671 /* Check for an integer exponent. */
7672 n
= real_to_integer (&c
);
7673 real_from_integer (&cint
, VOIDmode
, n
, n
< 0 ? -1 : 0, 0);
7674 if (real_identical (&c
, &cint
))
7676 /* Attempt to evaluate pow at compile-time. */
7677 if (TREE_CODE (arg0
) == REAL_CST
7678 && ! TREE_CONSTANT_OVERFLOW (arg0
))
7683 x
= TREE_REAL_CST (arg0
);
7684 inexact
= real_powi (&x
, TYPE_MODE (type
), &x
, n
);
7685 if (flag_unsafe_math_optimizations
|| !inexact
)
7686 return build_real (type
, x
);
7689 /* Strip sign ops from even integer powers. */
7690 if ((n
& 1) == 0 && flag_unsafe_math_optimizations
)
7692 tree narg0
= fold_strip_sign_ops (arg0
);
7695 arglist
= build_tree_list (NULL_TREE
, arg1
);
7696 arglist
= tree_cons (NULL_TREE
, narg0
, arglist
);
7697 return build_function_call_expr (fndecl
, arglist
);
7703 if (flag_unsafe_math_optimizations
)
7705 const enum built_in_function fcode
= builtin_mathfn_code (arg0
);
7707 /* Optimize pow(expN(x),y) = expN(x*y). */
7708 if (BUILTIN_EXPONENT_P (fcode
))
7710 tree expfn
= TREE_OPERAND (TREE_OPERAND (arg0
, 0), 0);
7711 tree arg
= TREE_VALUE (TREE_OPERAND (arg0
, 1));
7712 arg
= fold_build2 (MULT_EXPR
, type
, arg
, arg1
);
7713 arglist
= build_tree_list (NULL_TREE
, arg
);
7714 return build_function_call_expr (expfn
, arglist
);
7717 /* Optimize pow(sqrt(x),y) = pow(x,y*0.5). */
7718 if (BUILTIN_SQRT_P (fcode
))
7720 tree narg0
= TREE_VALUE (TREE_OPERAND (arg0
, 1));
7721 tree narg1
= fold_build2 (MULT_EXPR
, type
, arg1
,
7722 build_real (type
, dconsthalf
));
7724 arglist
= tree_cons (NULL_TREE
, narg0
,
7725 build_tree_list (NULL_TREE
, narg1
));
7726 return build_function_call_expr (fndecl
, arglist
);
7729 /* Optimize pow(cbrt(x),y) = pow(x,y/3) iff x is nonnegative. */
7730 if (BUILTIN_CBRT_P (fcode
))
7732 tree arg
= TREE_VALUE (TREE_OPERAND (arg0
, 1));
7733 if (tree_expr_nonnegative_p (arg
))
7735 const REAL_VALUE_TYPE dconstroot
7736 = real_value_truncate (TYPE_MODE (type
), dconstthird
);
7737 tree narg1
= fold_build2 (MULT_EXPR
, type
, arg1
,
7738 build_real (type
, dconstroot
));
7739 arglist
= tree_cons (NULL_TREE
, arg
,
7740 build_tree_list (NULL_TREE
, narg1
));
7741 return build_function_call_expr (fndecl
, arglist
);
7745 /* Optimize pow(pow(x,y),z) = pow(x,y*z). */
7746 if (fcode
== BUILT_IN_POW
|| fcode
== BUILT_IN_POWF
7747 || fcode
== BUILT_IN_POWL
)
7749 tree arg00
= TREE_VALUE (TREE_OPERAND (arg0
, 1));
7750 tree arg01
= TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg0
, 1)));
7751 tree narg1
= fold_build2 (MULT_EXPR
, type
, arg01
, arg1
);
7752 arglist
= tree_cons (NULL_TREE
, arg00
,
7753 build_tree_list (NULL_TREE
, narg1
));
7754 return build_function_call_expr (fndecl
, arglist
);
7761 /* Fold a builtin function call to powi, powif, or powil. Return
7762 NULL_TREE if no simplification can be made. */
7764 fold_builtin_powi (tree fndecl ATTRIBUTE_UNUSED
, tree arglist
, tree type
)
7766 tree arg0
= TREE_VALUE (arglist
);
7767 tree arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
7769 if (!validate_arglist (arglist
, REAL_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
7772 /* Optimize pow(1.0,y) = 1.0. */
7773 if (real_onep (arg0
))
7774 return omit_one_operand (type
, build_real (type
, dconst1
), arg1
);
7776 if (host_integerp (arg1
, 0))
7778 HOST_WIDE_INT c
= TREE_INT_CST_LOW (arg1
);
7780 /* Evaluate powi at compile-time. */
7781 if (TREE_CODE (arg0
) == REAL_CST
7782 && ! TREE_CONSTANT_OVERFLOW (arg0
))
7785 x
= TREE_REAL_CST (arg0
);
7786 real_powi (&x
, TYPE_MODE (type
), &x
, c
);
7787 return build_real (type
, x
);
7790 /* Optimize pow(x,0) = 1.0. */
7792 return omit_one_operand (type
, build_real (type
, dconst1
),
7795 /* Optimize pow(x,1) = x. */
7799 /* Optimize pow(x,-1) = 1.0/x. */
7801 return fold_build2 (RDIV_EXPR
, type
,
7802 build_real (type
, dconst1
), arg0
);
7808 /* A subroutine of fold_builtin to fold the various exponent
7809 functions. EXP is the CALL_EXPR of a call to a builtin function.
7810 VALUE is the value which will be raised to a power. */
7813 fold_builtin_exponent (tree fndecl
, tree arglist
,
7814 const REAL_VALUE_TYPE
*value
)
7816 if (validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
7818 tree type
= TREE_TYPE (TREE_TYPE (fndecl
));
7819 tree arg
= TREE_VALUE (arglist
);
7821 /* Optimize exp*(0.0) = 1.0. */
7822 if (real_zerop (arg
))
7823 return build_real (type
, dconst1
);
7825 /* Optimize expN(1.0) = N. */
7826 if (real_onep (arg
))
7828 REAL_VALUE_TYPE cst
;
7830 real_convert (&cst
, TYPE_MODE (type
), value
);
7831 return build_real (type
, cst
);
7834 /* Attempt to evaluate expN(integer) at compile-time. */
7835 if (flag_unsafe_math_optimizations
7836 && TREE_CODE (arg
) == REAL_CST
7837 && ! TREE_CONSTANT_OVERFLOW (arg
))
7839 REAL_VALUE_TYPE cint
;
7843 c
= TREE_REAL_CST (arg
);
7844 n
= real_to_integer (&c
);
7845 real_from_integer (&cint
, VOIDmode
, n
,
7847 if (real_identical (&c
, &cint
))
7851 real_powi (&x
, TYPE_MODE (type
), value
, n
);
7852 return build_real (type
, x
);
7856 /* Optimize expN(logN(x)) = x. */
7857 if (flag_unsafe_math_optimizations
)
7859 const enum built_in_function fcode
= builtin_mathfn_code (arg
);
7861 if ((value
== &dconste
7862 && (fcode
== BUILT_IN_LOG
7863 || fcode
== BUILT_IN_LOGF
7864 || fcode
== BUILT_IN_LOGL
))
7865 || (value
== &dconst2
7866 && (fcode
== BUILT_IN_LOG2
7867 || fcode
== BUILT_IN_LOG2F
7868 || fcode
== BUILT_IN_LOG2L
))
7869 || (value
== &dconst10
7870 && (fcode
== BUILT_IN_LOG10
7871 || fcode
== BUILT_IN_LOG10F
7872 || fcode
== BUILT_IN_LOG10L
)))
7873 return fold_convert (type
, TREE_VALUE (TREE_OPERAND (arg
, 1)));
7880 /* Fold function call to builtin memcpy. Return
7881 NULL_TREE if no simplification can be made. */
7884 fold_builtin_memcpy (tree fndecl
, tree arglist
)
7886 tree dest
, src
, len
;
7888 if (!validate_arglist (arglist
,
7889 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
7892 dest
= TREE_VALUE (arglist
);
7893 src
= TREE_VALUE (TREE_CHAIN (arglist
));
7894 len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
7896 /* If the LEN parameter is zero, return DEST. */
7897 if (integer_zerop (len
))
7898 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl
)), dest
, src
);
7900 /* If SRC and DEST are the same (and not volatile), return DEST. */
7901 if (operand_equal_p (src
, dest
, 0))
7902 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl
)), dest
, len
);
7907 /* Fold function call to builtin mempcpy. Return
7908 NULL_TREE if no simplification can be made. */
7911 fold_builtin_mempcpy (tree arglist
, tree type
, int endp
)
7913 if (validate_arglist (arglist
,
7914 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
7916 tree dest
= TREE_VALUE (arglist
);
7917 tree src
= TREE_VALUE (TREE_CHAIN (arglist
));
7918 tree len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
7920 /* If the LEN parameter is zero, return DEST. */
7921 if (integer_zerop (len
))
7922 return omit_one_operand (type
, dest
, src
);
7924 /* If SRC and DEST are the same (and not volatile), return DEST+LEN. */
7925 if (operand_equal_p (src
, dest
, 0))
7928 return omit_one_operand (type
, dest
, len
);
7931 len
= fold_build2 (MINUS_EXPR
, TREE_TYPE (len
), len
,
7934 len
= fold_convert (TREE_TYPE (dest
), len
);
7935 len
= fold_build2 (PLUS_EXPR
, TREE_TYPE (dest
), dest
, len
);
7936 return fold_convert (type
, len
);
7942 /* Fold function call to builtin memmove. Return
7943 NULL_TREE if no simplification can be made. */
7946 fold_builtin_memmove (tree arglist
, tree type
)
7948 tree dest
, src
, len
;
7950 if (!validate_arglist (arglist
,
7951 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
7954 dest
= TREE_VALUE (arglist
);
7955 src
= TREE_VALUE (TREE_CHAIN (arglist
));
7956 len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
7958 /* If the LEN parameter is zero, return DEST. */
7959 if (integer_zerop (len
))
7960 return omit_one_operand (type
, dest
, src
);
7962 /* If SRC and DEST are the same (and not volatile), return DEST. */
7963 if (operand_equal_p (src
, dest
, 0))
7964 return omit_one_operand (type
, dest
, len
);
7969 /* Fold function call to builtin strcpy. If LEN is not NULL, it represents
7970 the length of the string to be copied. Return NULL_TREE if no
7971 simplification can be made. */
7974 fold_builtin_strcpy (tree fndecl
, tree arglist
, tree len
)
7978 if (!validate_arglist (arglist
,
7979 POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
7982 dest
= TREE_VALUE (arglist
);
7983 src
= TREE_VALUE (TREE_CHAIN (arglist
));
7985 /* If SRC and DEST are the same (and not volatile), return DEST. */
7986 if (operand_equal_p (src
, dest
, 0))
7987 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl
)), dest
);
7992 fn
= implicit_built_in_decls
[BUILT_IN_MEMCPY
];
7998 len
= c_strlen (src
, 1);
7999 if (! len
|| TREE_SIDE_EFFECTS (len
))
8003 len
= size_binop (PLUS_EXPR
, len
, ssize_int (1));
8004 arglist
= build_tree_list (NULL_TREE
, len
);
8005 arglist
= tree_cons (NULL_TREE
, src
, arglist
);
8006 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
8007 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl
)),
8008 build_function_call_expr (fn
, arglist
));
8011 /* Fold function call to builtin strncpy. If SLEN is not NULL, it represents
8012 the length of the source string. Return NULL_TREE if no simplification
8016 fold_builtin_strncpy (tree fndecl
, tree arglist
, tree slen
)
8018 tree dest
, src
, len
, fn
;
8020 if (!validate_arglist (arglist
,
8021 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
8024 dest
= TREE_VALUE (arglist
);
8025 src
= TREE_VALUE (TREE_CHAIN (arglist
));
8026 len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
8028 /* If the LEN parameter is zero, return DEST. */
8029 if (integer_zerop (len
))
8030 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl
)), dest
, src
);
8032 /* We can't compare slen with len as constants below if len is not a
8034 if (len
== 0 || TREE_CODE (len
) != INTEGER_CST
)
8038 slen
= c_strlen (src
, 1);
8040 /* Now, we must be passed a constant src ptr parameter. */
8041 if (slen
== 0 || TREE_CODE (slen
) != INTEGER_CST
)
8044 slen
= size_binop (PLUS_EXPR
, slen
, ssize_int (1));
8046 /* We do not support simplification of this case, though we do
8047 support it when expanding trees into RTL. */
8048 /* FIXME: generate a call to __builtin_memset. */
8049 if (tree_int_cst_lt (slen
, len
))
8052 /* OK transform into builtin memcpy. */
8053 fn
= implicit_built_in_decls
[BUILT_IN_MEMCPY
];
8056 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl
)),
8057 build_function_call_expr (fn
, arglist
));
8060 /* Fold function call to builtin memcmp. Return
8061 NULL_TREE if no simplification can be made. */
8064 fold_builtin_memcmp (tree arglist
)
8066 tree arg1
, arg2
, len
;
8067 const char *p1
, *p2
;
8069 if (!validate_arglist (arglist
,
8070 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
8073 arg1
= TREE_VALUE (arglist
);
8074 arg2
= TREE_VALUE (TREE_CHAIN (arglist
));
8075 len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
8077 /* If the LEN parameter is zero, return zero. */
8078 if (integer_zerop (len
))
8079 return omit_two_operands (integer_type_node
, integer_zero_node
,
8082 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
8083 if (operand_equal_p (arg1
, arg2
, 0))
8084 return omit_one_operand (integer_type_node
, integer_zero_node
, len
);
8086 p1
= c_getstr (arg1
);
8087 p2
= c_getstr (arg2
);
8089 /* If all arguments are constant, and the value of len is not greater
8090 than the lengths of arg1 and arg2, evaluate at compile-time. */
8091 if (host_integerp (len
, 1) && p1
&& p2
8092 && compare_tree_int (len
, strlen (p1
) + 1) <= 0
8093 && compare_tree_int (len
, strlen (p2
) + 1) <= 0)
8095 const int r
= memcmp (p1
, p2
, tree_low_cst (len
, 1));
8098 return integer_one_node
;
8100 return integer_minus_one_node
;
8102 return integer_zero_node
;
8105 /* If len parameter is one, return an expression corresponding to
8106 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
8107 if (host_integerp (len
, 1) && tree_low_cst (len
, 1) == 1)
8109 tree cst_uchar_node
= build_type_variant (unsigned_char_type_node
, 1, 0);
8110 tree cst_uchar_ptr_node
8111 = build_pointer_type_for_mode (cst_uchar_node
, ptr_mode
, true);
8113 tree ind1
= fold_convert (integer_type_node
,
8114 build1 (INDIRECT_REF
, cst_uchar_node
,
8115 fold_convert (cst_uchar_ptr_node
,
8117 tree ind2
= fold_convert (integer_type_node
,
8118 build1 (INDIRECT_REF
, cst_uchar_node
,
8119 fold_convert (cst_uchar_ptr_node
,
8121 return fold_build2 (MINUS_EXPR
, integer_type_node
, ind1
, ind2
);
8127 /* Fold function call to builtin strcmp. Return
8128 NULL_TREE if no simplification can be made. */
8131 fold_builtin_strcmp (tree arglist
)
8134 const char *p1
, *p2
;
8136 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
8139 arg1
= TREE_VALUE (arglist
);
8140 arg2
= TREE_VALUE (TREE_CHAIN (arglist
));
8142 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
8143 if (operand_equal_p (arg1
, arg2
, 0))
8144 return integer_zero_node
;
8146 p1
= c_getstr (arg1
);
8147 p2
= c_getstr (arg2
);
8151 const int i
= strcmp (p1
, p2
);
8153 return integer_minus_one_node
;
8155 return integer_one_node
;
8157 return integer_zero_node
;
8160 /* If the second arg is "", return *(const unsigned char*)arg1. */
8161 if (p2
&& *p2
== '\0')
8163 tree cst_uchar_node
= build_type_variant (unsigned_char_type_node
, 1, 0);
8164 tree cst_uchar_ptr_node
8165 = build_pointer_type_for_mode (cst_uchar_node
, ptr_mode
, true);
8167 return fold_convert (integer_type_node
,
8168 build1 (INDIRECT_REF
, cst_uchar_node
,
8169 fold_convert (cst_uchar_ptr_node
,
8173 /* If the first arg is "", return -*(const unsigned char*)arg2. */
8174 if (p1
&& *p1
== '\0')
8176 tree cst_uchar_node
= build_type_variant (unsigned_char_type_node
, 1, 0);
8177 tree cst_uchar_ptr_node
8178 = build_pointer_type_for_mode (cst_uchar_node
, ptr_mode
, true);
8180 tree temp
= fold_convert (integer_type_node
,
8181 build1 (INDIRECT_REF
, cst_uchar_node
,
8182 fold_convert (cst_uchar_ptr_node
,
8184 return fold_build1 (NEGATE_EXPR
, integer_type_node
, temp
);
8190 /* Fold function call to builtin strncmp. Return
8191 NULL_TREE if no simplification can be made. */
8194 fold_builtin_strncmp (tree arglist
)
8196 tree arg1
, arg2
, len
;
8197 const char *p1
, *p2
;
8199 if (!validate_arglist (arglist
,
8200 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
8203 arg1
= TREE_VALUE (arglist
);
8204 arg2
= TREE_VALUE (TREE_CHAIN (arglist
));
8205 len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
8207 /* If the LEN parameter is zero, return zero. */
8208 if (integer_zerop (len
))
8209 return omit_two_operands (integer_type_node
, integer_zero_node
,
8212 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
8213 if (operand_equal_p (arg1
, arg2
, 0))
8214 return omit_one_operand (integer_type_node
, integer_zero_node
, len
);
8216 p1
= c_getstr (arg1
);
8217 p2
= c_getstr (arg2
);
8219 if (host_integerp (len
, 1) && p1
&& p2
)
8221 const int i
= strncmp (p1
, p2
, tree_low_cst (len
, 1));
8223 return integer_one_node
;
8225 return integer_minus_one_node
;
8227 return integer_zero_node
;
8230 /* If the second arg is "", and the length is greater than zero,
8231 return *(const unsigned char*)arg1. */
8232 if (p2
&& *p2
== '\0'
8233 && TREE_CODE (len
) == INTEGER_CST
8234 && tree_int_cst_sgn (len
) == 1)
8236 tree cst_uchar_node
= build_type_variant (unsigned_char_type_node
, 1, 0);
8237 tree cst_uchar_ptr_node
8238 = build_pointer_type_for_mode (cst_uchar_node
, ptr_mode
, true);
8240 return fold_convert (integer_type_node
,
8241 build1 (INDIRECT_REF
, cst_uchar_node
,
8242 fold_convert (cst_uchar_ptr_node
,
8246 /* If the first arg is "", and the length is greater than zero,
8247 return -*(const unsigned char*)arg2. */
8248 if (p1
&& *p1
== '\0'
8249 && TREE_CODE (len
) == INTEGER_CST
8250 && tree_int_cst_sgn (len
) == 1)
8252 tree cst_uchar_node
= build_type_variant (unsigned_char_type_node
, 1, 0);
8253 tree cst_uchar_ptr_node
8254 = build_pointer_type_for_mode (cst_uchar_node
, ptr_mode
, true);
8256 tree temp
= fold_convert (integer_type_node
,
8257 build1 (INDIRECT_REF
, cst_uchar_node
,
8258 fold_convert (cst_uchar_ptr_node
,
8260 return fold_build1 (NEGATE_EXPR
, integer_type_node
, temp
);
8263 /* If len parameter is one, return an expression corresponding to
8264 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
8265 if (host_integerp (len
, 1) && tree_low_cst (len
, 1) == 1)
8267 tree cst_uchar_node
= build_type_variant (unsigned_char_type_node
, 1, 0);
8268 tree cst_uchar_ptr_node
8269 = build_pointer_type_for_mode (cst_uchar_node
, ptr_mode
, true);
8271 tree ind1
= fold_convert (integer_type_node
,
8272 build1 (INDIRECT_REF
, cst_uchar_node
,
8273 fold_convert (cst_uchar_ptr_node
,
8275 tree ind2
= fold_convert (integer_type_node
,
8276 build1 (INDIRECT_REF
, cst_uchar_node
,
8277 fold_convert (cst_uchar_ptr_node
,
8279 return fold_build2 (MINUS_EXPR
, integer_type_node
, ind1
, ind2
);
8285 /* Fold function call to builtin signbit, signbitf or signbitl. Return
8286 NULL_TREE if no simplification can be made. */
8289 fold_builtin_signbit (tree fndecl
, tree arglist
)
8291 tree type
= TREE_TYPE (TREE_TYPE (fndecl
));
8294 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
8297 arg
= TREE_VALUE (arglist
);
8299 /* If ARG is a compile-time constant, determine the result. */
8300 if (TREE_CODE (arg
) == REAL_CST
8301 && !TREE_CONSTANT_OVERFLOW (arg
))
8305 c
= TREE_REAL_CST (arg
);
8306 temp
= REAL_VALUE_NEGATIVE (c
) ? integer_one_node
: integer_zero_node
;
8307 return fold_convert (type
, temp
);
8310 /* If ARG is non-negative, the result is always zero. */
8311 if (tree_expr_nonnegative_p (arg
))
8312 return omit_one_operand (type
, integer_zero_node
, arg
);
8314 /* If ARG's format doesn't have signed zeros, return "arg < 0.0". */
8315 if (!HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg
))))
8316 return fold_build2 (LT_EXPR
, type
, arg
,
8317 build_real (TREE_TYPE (arg
), dconst0
));
8322 /* Fold function call to builtin copysign, copysignf or copysignl.
8323 Return NULL_TREE if no simplification can be made. */
8326 fold_builtin_copysign (tree fndecl
, tree arglist
, tree type
)
8328 tree arg1
, arg2
, tem
;
8330 if (!validate_arglist (arglist
, REAL_TYPE
, REAL_TYPE
, VOID_TYPE
))
8333 arg1
= TREE_VALUE (arglist
);
8334 arg2
= TREE_VALUE (TREE_CHAIN (arglist
));
8336 /* copysign(X,X) is X. */
8337 if (operand_equal_p (arg1
, arg2
, 0))
8338 return fold_convert (type
, arg1
);
8340 /* If ARG1 and ARG2 are compile-time constants, determine the result. */
8341 if (TREE_CODE (arg1
) == REAL_CST
8342 && TREE_CODE (arg2
) == REAL_CST
8343 && !TREE_CONSTANT_OVERFLOW (arg1
)
8344 && !TREE_CONSTANT_OVERFLOW (arg2
))
8346 REAL_VALUE_TYPE c1
, c2
;
8348 c1
= TREE_REAL_CST (arg1
);
8349 c2
= TREE_REAL_CST (arg2
);
8350 real_copysign (&c1
, &c2
);
8351 return build_real (type
, c1
);
8355 /* copysign(X, Y) is fabs(X) when Y is always non-negative.
8356 Remember to evaluate Y for side-effects. */
8357 if (tree_expr_nonnegative_p (arg2
))
8358 return omit_one_operand (type
,
8359 fold_build1 (ABS_EXPR
, type
, arg1
),
8362 /* Strip sign changing operations for the first argument. */
8363 tem
= fold_strip_sign_ops (arg1
);
8366 arglist
= tree_cons (NULL_TREE
, tem
, TREE_CHAIN (arglist
));
8367 return build_function_call_expr (fndecl
, arglist
);
8373 /* Fold a call to builtin isascii. */
8376 fold_builtin_isascii (tree arglist
)
8378 if (! validate_arglist (arglist
, INTEGER_TYPE
, VOID_TYPE
))
8382 /* Transform isascii(c) -> ((c & ~0x7f) == 0). */
8383 tree arg
= TREE_VALUE (arglist
);
8385 arg
= build2 (BIT_AND_EXPR
, integer_type_node
, arg
,
8386 build_int_cst (NULL_TREE
,
8387 ~ (unsigned HOST_WIDE_INT
) 0x7f));
8388 arg
= fold_build2 (EQ_EXPR
, integer_type_node
,
8389 arg
, integer_zero_node
);
8391 if (in_gimple_form
&& !TREE_CONSTANT (arg
))
8398 /* Fold a call to builtin toascii. */
8401 fold_builtin_toascii (tree arglist
)
8403 if (! validate_arglist (arglist
, INTEGER_TYPE
, VOID_TYPE
))
8407 /* Transform toascii(c) -> (c & 0x7f). */
8408 tree arg
= TREE_VALUE (arglist
);
8410 return fold_build2 (BIT_AND_EXPR
, integer_type_node
, arg
,
8411 build_int_cst (NULL_TREE
, 0x7f));
8415 /* Fold a call to builtin isdigit. */
8418 fold_builtin_isdigit (tree arglist
)
8420 if (! validate_arglist (arglist
, INTEGER_TYPE
, VOID_TYPE
))
8424 /* Transform isdigit(c) -> (unsigned)(c) - '0' <= 9. */
8425 /* According to the C standard, isdigit is unaffected by locale.
8426 However, it definitely is affected by the target character set. */
8428 unsigned HOST_WIDE_INT target_digit0
8429 = lang_hooks
.to_target_charset ('0');
8431 if (target_digit0
== 0)
8434 arg
= fold_convert (unsigned_type_node
, TREE_VALUE (arglist
));
8435 arg
= build2 (MINUS_EXPR
, unsigned_type_node
, arg
,
8436 build_int_cst (unsigned_type_node
, target_digit0
));
8437 arg
= fold_build2 (LE_EXPR
, integer_type_node
, arg
,
8438 build_int_cst (unsigned_type_node
, 9));
8439 if (in_gimple_form
&& !TREE_CONSTANT (arg
))
8446 /* Fold a call to fabs, fabsf or fabsl. */
8449 fold_builtin_fabs (tree arglist
, tree type
)
8453 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
8456 arg
= TREE_VALUE (arglist
);
8457 arg
= fold_convert (type
, arg
);
8458 if (TREE_CODE (arg
) == REAL_CST
)
8459 return fold_abs_const (arg
, type
);
8460 return fold_build1 (ABS_EXPR
, type
, arg
);
8463 /* Fold a call to abs, labs, llabs or imaxabs. */
8466 fold_builtin_abs (tree arglist
, tree type
)
8470 if (!validate_arglist (arglist
, INTEGER_TYPE
, VOID_TYPE
))
8473 arg
= TREE_VALUE (arglist
);
8474 arg
= fold_convert (type
, arg
);
8475 if (TREE_CODE (arg
) == INTEGER_CST
)
8476 return fold_abs_const (arg
, type
);
8477 return fold_build1 (ABS_EXPR
, type
, arg
);
8480 /* Fold a call to __builtin_isnan(), __builtin_isinf, __builtin_finite.
8481 EXP is the CALL_EXPR for the call. */
8484 fold_builtin_classify (tree fndecl
, tree arglist
, int builtin_index
)
8486 tree type
= TREE_TYPE (TREE_TYPE (fndecl
));
8490 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
8492 /* Check that we have exactly one argument. */
8495 error ("too few arguments to function %qs",
8496 IDENTIFIER_POINTER (DECL_NAME (fndecl
)));
8497 return error_mark_node
;
8499 else if (TREE_CHAIN (arglist
) != 0)
8501 error ("too many arguments to function %qs",
8502 IDENTIFIER_POINTER (DECL_NAME (fndecl
)));
8503 return error_mark_node
;
8507 error ("non-floating-point argument to function %qs",
8508 IDENTIFIER_POINTER (DECL_NAME (fndecl
)));
8509 return error_mark_node
;
8513 arg
= TREE_VALUE (arglist
);
8514 switch (builtin_index
)
8516 case BUILT_IN_ISINF
:
8517 if (!MODE_HAS_INFINITIES (TYPE_MODE (TREE_TYPE (arg
))))
8518 return omit_one_operand (type
, integer_zero_node
, arg
);
8520 if (TREE_CODE (arg
) == REAL_CST
)
8522 r
= TREE_REAL_CST (arg
);
8523 if (real_isinf (&r
))
8524 return real_compare (GT_EXPR
, &r
, &dconst0
)
8525 ? integer_one_node
: integer_minus_one_node
;
8527 return integer_zero_node
;
8532 case BUILT_IN_FINITE
:
8533 if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg
)))
8534 && !MODE_HAS_INFINITIES (TYPE_MODE (TREE_TYPE (arg
))))
8535 return omit_one_operand (type
, integer_zero_node
, arg
);
8537 if (TREE_CODE (arg
) == REAL_CST
)
8539 r
= TREE_REAL_CST (arg
);
8540 return real_isinf (&r
) || real_isnan (&r
)
8541 ? integer_zero_node
: integer_one_node
;
8546 case BUILT_IN_ISNAN
:
8547 if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg
))))
8548 return omit_one_operand (type
, integer_zero_node
, arg
);
8550 if (TREE_CODE (arg
) == REAL_CST
)
8552 r
= TREE_REAL_CST (arg
);
8553 return real_isnan (&r
) ? integer_one_node
: integer_zero_node
;
8556 arg
= builtin_save_expr (arg
);
8557 return fold_build2 (UNORDERED_EXPR
, type
, arg
, arg
);
8564 /* Fold a call to an unordered comparison function such as
8565 __builtin_isgreater(). FNDECL is the FUNCTION_DECL for the function
8566 being called and ARGLIST is the argument list for the call.
8567 UNORDERED_CODE and ORDERED_CODE are comparison codes that give
8568 the opposite of the desired result. UNORDERED_CODE is used
8569 for modes that can hold NaNs and ORDERED_CODE is used for
8573 fold_builtin_unordered_cmp (tree fndecl
, tree arglist
,
8574 enum tree_code unordered_code
,
8575 enum tree_code ordered_code
)
8577 tree type
= TREE_TYPE (TREE_TYPE (fndecl
));
8578 enum tree_code code
;
8581 enum tree_code code0
, code1
;
8582 tree cmp_type
= NULL_TREE
;
8584 if (!validate_arglist (arglist
, REAL_TYPE
, REAL_TYPE
, VOID_TYPE
))
8586 /* Check that we have exactly two arguments. */
8587 if (arglist
== 0 || TREE_CHAIN (arglist
) == 0)
8589 error ("too few arguments to function %qs",
8590 IDENTIFIER_POINTER (DECL_NAME (fndecl
)));
8591 return error_mark_node
;
8593 else if (TREE_CHAIN (TREE_CHAIN (arglist
)) != 0)
8595 error ("too many arguments to function %qs",
8596 IDENTIFIER_POINTER (DECL_NAME (fndecl
)));
8597 return error_mark_node
;
8601 arg0
= TREE_VALUE (arglist
);
8602 arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
8604 type0
= TREE_TYPE (arg0
);
8605 type1
= TREE_TYPE (arg1
);
8607 code0
= TREE_CODE (type0
);
8608 code1
= TREE_CODE (type1
);
8610 if (code0
== REAL_TYPE
&& code1
== REAL_TYPE
)
8611 /* Choose the wider of two real types. */
8612 cmp_type
= TYPE_PRECISION (type0
) >= TYPE_PRECISION (type1
)
8614 else if (code0
== REAL_TYPE
&& code1
== INTEGER_TYPE
)
8616 else if (code0
== INTEGER_TYPE
&& code1
== REAL_TYPE
)
8620 error ("non-floating-point argument to function %qs",
8621 IDENTIFIER_POINTER (DECL_NAME (fndecl
)));
8622 return error_mark_node
;
8625 arg0
= fold_convert (cmp_type
, arg0
);
8626 arg1
= fold_convert (cmp_type
, arg1
);
8628 if (unordered_code
== UNORDERED_EXPR
)
8630 if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg0
))))
8631 return omit_two_operands (type
, integer_zero_node
, arg0
, arg1
);
8632 return fold_build2 (UNORDERED_EXPR
, type
, arg0
, arg1
);
8635 code
= MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg0
))) ? unordered_code
8637 return fold_build1 (TRUTH_NOT_EXPR
, type
,
8638 fold_build2 (code
, type
, arg0
, arg1
));
8641 /* Used by constant folding to simplify calls to builtin functions. EXP is
8642 the CALL_EXPR of a call to a builtin function. IGNORE is true if the
8643 result of the function call is ignored. This function returns NULL_TREE
8644 if no simplification was possible. */
8647 fold_builtin_1 (tree fndecl
, tree arglist
, bool ignore
)
8649 tree type
= TREE_TYPE (TREE_TYPE (fndecl
));
8650 enum built_in_function fcode
;
8652 if (DECL_BUILT_IN_CLASS (fndecl
) == BUILT_IN_MD
)
8653 return targetm
.fold_builtin (fndecl
, arglist
, ignore
);
8655 fcode
= DECL_FUNCTION_CODE (fndecl
);
8658 case BUILT_IN_FPUTS
:
8659 return fold_builtin_fputs (arglist
, ignore
, false, NULL_TREE
);
8661 case BUILT_IN_FPUTS_UNLOCKED
:
8662 return fold_builtin_fputs (arglist
, ignore
, true, NULL_TREE
);
8664 case BUILT_IN_STRSTR
:
8665 return fold_builtin_strstr (arglist
, type
);
8667 case BUILT_IN_STRCAT
:
8668 return fold_builtin_strcat (arglist
);
8670 case BUILT_IN_STRNCAT
:
8671 return fold_builtin_strncat (arglist
);
8673 case BUILT_IN_STRSPN
:
8674 return fold_builtin_strspn (arglist
);
8676 case BUILT_IN_STRCSPN
:
8677 return fold_builtin_strcspn (arglist
);
8679 case BUILT_IN_STRCHR
:
8680 case BUILT_IN_INDEX
:
8681 return fold_builtin_strchr (arglist
, type
);
8683 case BUILT_IN_STRRCHR
:
8684 case BUILT_IN_RINDEX
:
8685 return fold_builtin_strrchr (arglist
, type
);
8687 case BUILT_IN_STRCPY
:
8688 return fold_builtin_strcpy (fndecl
, arglist
, NULL_TREE
);
8690 case BUILT_IN_STRNCPY
:
8691 return fold_builtin_strncpy (fndecl
, arglist
, NULL_TREE
);
8693 case BUILT_IN_STRCMP
:
8694 return fold_builtin_strcmp (arglist
);
8696 case BUILT_IN_STRNCMP
:
8697 return fold_builtin_strncmp (arglist
);
8699 case BUILT_IN_STRPBRK
:
8700 return fold_builtin_strpbrk (arglist
, type
);
8703 case BUILT_IN_MEMCMP
:
8704 return fold_builtin_memcmp (arglist
);
8706 case BUILT_IN_SPRINTF
:
8707 return fold_builtin_sprintf (arglist
, ignore
);
8709 case BUILT_IN_CONSTANT_P
:
8713 val
= fold_builtin_constant_p (arglist
);
8714 /* Gimplification will pull the CALL_EXPR for the builtin out of
8715 an if condition. When not optimizing, we'll not CSE it back.
8716 To avoid link error types of regressions, return false now. */
8717 if (!val
&& !optimize
)
8718 val
= integer_zero_node
;
8723 case BUILT_IN_EXPECT
:
8724 return fold_builtin_expect (arglist
);
8726 case BUILT_IN_CLASSIFY_TYPE
:
8727 return fold_builtin_classify_type (arglist
);
8729 case BUILT_IN_STRLEN
:
8730 return fold_builtin_strlen (arglist
);
8733 case BUILT_IN_FABSF
:
8734 case BUILT_IN_FABSL
:
8735 return fold_builtin_fabs (arglist
, type
);
8739 case BUILT_IN_LLABS
:
8740 case BUILT_IN_IMAXABS
:
8741 return fold_builtin_abs (arglist
, type
);
8744 case BUILT_IN_CONJF
:
8745 case BUILT_IN_CONJL
:
8746 if (validate_arglist (arglist
, COMPLEX_TYPE
, VOID_TYPE
))
8747 return fold_build1 (CONJ_EXPR
, type
, TREE_VALUE (arglist
));
8750 case BUILT_IN_CREAL
:
8751 case BUILT_IN_CREALF
:
8752 case BUILT_IN_CREALL
:
8753 if (validate_arglist (arglist
, COMPLEX_TYPE
, VOID_TYPE
))
8754 return non_lvalue (fold_build1 (REALPART_EXPR
, type
,
8755 TREE_VALUE (arglist
)));
8758 case BUILT_IN_CIMAG
:
8759 case BUILT_IN_CIMAGF
:
8760 case BUILT_IN_CIMAGL
:
8761 if (validate_arglist (arglist
, COMPLEX_TYPE
, VOID_TYPE
))
8762 return non_lvalue (fold_build1 (IMAGPART_EXPR
, type
,
8763 TREE_VALUE (arglist
)));
8767 case BUILT_IN_CABSF
:
8768 case BUILT_IN_CABSL
:
8769 return fold_builtin_cabs (arglist
, type
);
8772 case BUILT_IN_SQRTF
:
8773 case BUILT_IN_SQRTL
:
8774 return fold_builtin_sqrt (arglist
, type
);
8777 case BUILT_IN_CBRTF
:
8778 case BUILT_IN_CBRTL
:
8779 return fold_builtin_cbrt (arglist
, type
);
8784 return fold_builtin_sin (arglist
);
8789 return fold_builtin_cos (arglist
, type
, fndecl
);
8794 return fold_builtin_exponent (fndecl
, arglist
, &dconste
);
8797 case BUILT_IN_EXP2F
:
8798 case BUILT_IN_EXP2L
:
8799 return fold_builtin_exponent (fndecl
, arglist
, &dconst2
);
8801 case BUILT_IN_EXP10
:
8802 case BUILT_IN_EXP10F
:
8803 case BUILT_IN_EXP10L
:
8804 case BUILT_IN_POW10
:
8805 case BUILT_IN_POW10F
:
8806 case BUILT_IN_POW10L
:
8807 return fold_builtin_exponent (fndecl
, arglist
, &dconst10
);
8812 return fold_builtin_logarithm (fndecl
, arglist
, &dconste
);
8815 case BUILT_IN_LOG2F
:
8816 case BUILT_IN_LOG2L
:
8817 return fold_builtin_logarithm (fndecl
, arglist
, &dconst2
);
8819 case BUILT_IN_LOG10
:
8820 case BUILT_IN_LOG10F
:
8821 case BUILT_IN_LOG10L
:
8822 return fold_builtin_logarithm (fndecl
, arglist
, &dconst10
);
8827 return fold_builtin_tan (arglist
);
8830 case BUILT_IN_ATANF
:
8831 case BUILT_IN_ATANL
:
8832 return fold_builtin_atan (arglist
, type
);
8837 return fold_builtin_pow (fndecl
, arglist
, type
);
8840 case BUILT_IN_POWIF
:
8841 case BUILT_IN_POWIL
:
8842 return fold_builtin_powi (fndecl
, arglist
, type
);
8847 return fold_builtin_inf (type
, true);
8849 case BUILT_IN_HUGE_VAL
:
8850 case BUILT_IN_HUGE_VALF
:
8851 case BUILT_IN_HUGE_VALL
:
8852 return fold_builtin_inf (type
, false);
8857 return fold_builtin_nan (arglist
, type
, true);
8860 case BUILT_IN_NANSF
:
8861 case BUILT_IN_NANSL
:
8862 return fold_builtin_nan (arglist
, type
, false);
8864 case BUILT_IN_FLOOR
:
8865 case BUILT_IN_FLOORF
:
8866 case BUILT_IN_FLOORL
:
8867 return fold_builtin_floor (fndecl
, arglist
);
8870 case BUILT_IN_CEILF
:
8871 case BUILT_IN_CEILL
:
8872 return fold_builtin_ceil (fndecl
, arglist
);
8874 case BUILT_IN_TRUNC
:
8875 case BUILT_IN_TRUNCF
:
8876 case BUILT_IN_TRUNCL
:
8877 return fold_builtin_trunc (fndecl
, arglist
);
8879 case BUILT_IN_ROUND
:
8880 case BUILT_IN_ROUNDF
:
8881 case BUILT_IN_ROUNDL
:
8882 return fold_builtin_round (fndecl
, arglist
);
8884 case BUILT_IN_NEARBYINT
:
8885 case BUILT_IN_NEARBYINTF
:
8886 case BUILT_IN_NEARBYINTL
:
8888 case BUILT_IN_RINTF
:
8889 case BUILT_IN_RINTL
:
8890 return fold_trunc_transparent_mathfn (fndecl
, arglist
);
8892 case BUILT_IN_LCEIL
:
8893 case BUILT_IN_LCEILF
:
8894 case BUILT_IN_LCEILL
:
8895 case BUILT_IN_LLCEIL
:
8896 case BUILT_IN_LLCEILF
:
8897 case BUILT_IN_LLCEILL
:
8898 case BUILT_IN_LFLOOR
:
8899 case BUILT_IN_LFLOORF
:
8900 case BUILT_IN_LFLOORL
:
8901 case BUILT_IN_LLFLOOR
:
8902 case BUILT_IN_LLFLOORF
:
8903 case BUILT_IN_LLFLOORL
:
8904 case BUILT_IN_LROUND
:
8905 case BUILT_IN_LROUNDF
:
8906 case BUILT_IN_LROUNDL
:
8907 case BUILT_IN_LLROUND
:
8908 case BUILT_IN_LLROUNDF
:
8909 case BUILT_IN_LLROUNDL
:
8910 return fold_builtin_int_roundingfn (fndecl
, arglist
);
8912 case BUILT_IN_LRINT
:
8913 case BUILT_IN_LRINTF
:
8914 case BUILT_IN_LRINTL
:
8915 case BUILT_IN_LLRINT
:
8916 case BUILT_IN_LLRINTF
:
8917 case BUILT_IN_LLRINTL
:
8918 return fold_fixed_mathfn (fndecl
, arglist
);
8922 case BUILT_IN_FFSLL
:
8925 case BUILT_IN_CLZLL
:
8928 case BUILT_IN_CTZLL
:
8929 case BUILT_IN_POPCOUNT
:
8930 case BUILT_IN_POPCOUNTL
:
8931 case BUILT_IN_POPCOUNTLL
:
8932 case BUILT_IN_PARITY
:
8933 case BUILT_IN_PARITYL
:
8934 case BUILT_IN_PARITYLL
:
8935 return fold_builtin_bitop (fndecl
, arglist
);
8937 case BUILT_IN_MEMCPY
:
8938 return fold_builtin_memcpy (fndecl
, arglist
);
8940 case BUILT_IN_MEMPCPY
:
8941 return fold_builtin_mempcpy (arglist
, type
, /*endp=*/1);
8943 case BUILT_IN_MEMMOVE
:
8944 return fold_builtin_memmove (arglist
, type
);
8946 case BUILT_IN_SIGNBIT
:
8947 case BUILT_IN_SIGNBITF
:
8948 case BUILT_IN_SIGNBITL
:
8949 return fold_builtin_signbit (fndecl
, arglist
);
8951 case BUILT_IN_ISASCII
:
8952 return fold_builtin_isascii (arglist
);
8954 case BUILT_IN_TOASCII
:
8955 return fold_builtin_toascii (arglist
);
8957 case BUILT_IN_ISDIGIT
:
8958 return fold_builtin_isdigit (arglist
);
8960 case BUILT_IN_COPYSIGN
:
8961 case BUILT_IN_COPYSIGNF
:
8962 case BUILT_IN_COPYSIGNL
:
8963 return fold_builtin_copysign (fndecl
, arglist
, type
);
8965 case BUILT_IN_FINITE
:
8966 case BUILT_IN_FINITEF
:
8967 case BUILT_IN_FINITEL
:
8968 return fold_builtin_classify (fndecl
, arglist
, BUILT_IN_FINITE
);
8970 case BUILT_IN_ISINF
:
8971 case BUILT_IN_ISINFF
:
8972 case BUILT_IN_ISINFL
:
8973 return fold_builtin_classify (fndecl
, arglist
, BUILT_IN_ISINF
);
8975 case BUILT_IN_ISNAN
:
8976 case BUILT_IN_ISNANF
:
8977 case BUILT_IN_ISNANL
:
8978 return fold_builtin_classify (fndecl
, arglist
, BUILT_IN_ISNAN
);
8980 case BUILT_IN_ISGREATER
:
8981 return fold_builtin_unordered_cmp (fndecl
, arglist
, UNLE_EXPR
, LE_EXPR
);
8982 case BUILT_IN_ISGREATEREQUAL
:
8983 return fold_builtin_unordered_cmp (fndecl
, arglist
, UNLT_EXPR
, LT_EXPR
);
8984 case BUILT_IN_ISLESS
:
8985 return fold_builtin_unordered_cmp (fndecl
, arglist
, UNGE_EXPR
, GE_EXPR
);
8986 case BUILT_IN_ISLESSEQUAL
:
8987 return fold_builtin_unordered_cmp (fndecl
, arglist
, UNGT_EXPR
, GT_EXPR
);
8988 case BUILT_IN_ISLESSGREATER
:
8989 return fold_builtin_unordered_cmp (fndecl
, arglist
, UNEQ_EXPR
, EQ_EXPR
);
8990 case BUILT_IN_ISUNORDERED
:
8991 return fold_builtin_unordered_cmp (fndecl
, arglist
, UNORDERED_EXPR
,
8994 /* We do the folding for va_start in the expander. */
8995 case BUILT_IN_VA_START
:
8998 case BUILT_IN_OBJECT_SIZE
:
8999 return fold_builtin_object_size (arglist
);
9000 case BUILT_IN_MEMCPY_CHK
:
9001 case BUILT_IN_MEMPCPY_CHK
:
9002 case BUILT_IN_MEMMOVE_CHK
:
9003 case BUILT_IN_MEMSET_CHK
:
9004 return fold_builtin_memory_chk (fndecl
, arglist
, NULL_TREE
, ignore
,
9005 DECL_FUNCTION_CODE (fndecl
));
9006 case BUILT_IN_STRCPY_CHK
:
9007 case BUILT_IN_STPCPY_CHK
:
9008 return fold_builtin_stxcpy_chk (fndecl
, arglist
, NULL_TREE
, ignore
,
9009 DECL_FUNCTION_CODE (fndecl
));
9010 case BUILT_IN_STRNCPY_CHK
:
9011 return fold_builtin_strncpy_chk (arglist
, NULL_TREE
);
9012 case BUILT_IN_STRCAT_CHK
:
9013 return fold_builtin_strcat_chk (fndecl
, arglist
);
9014 case BUILT_IN_STRNCAT_CHK
:
9015 return fold_builtin_strncat_chk (fndecl
, arglist
);
9016 case BUILT_IN_SPRINTF_CHK
:
9017 case BUILT_IN_VSPRINTF_CHK
:
9018 return fold_builtin_sprintf_chk (arglist
, DECL_FUNCTION_CODE (fndecl
));
9019 case BUILT_IN_SNPRINTF_CHK
:
9020 case BUILT_IN_VSNPRINTF_CHK
:
9021 return fold_builtin_snprintf_chk (arglist
, NULL_TREE
,
9022 DECL_FUNCTION_CODE (fndecl
));
9024 case BUILT_IN_PRINTF
:
9025 case BUILT_IN_PRINTF_UNLOCKED
:
9026 case BUILT_IN_VPRINTF
:
9027 case BUILT_IN_PRINTF_CHK
:
9028 case BUILT_IN_VPRINTF_CHK
:
9029 return fold_builtin_printf (fndecl
, arglist
, ignore
,
9030 DECL_FUNCTION_CODE (fndecl
));
9032 case BUILT_IN_FPRINTF
:
9033 case BUILT_IN_FPRINTF_UNLOCKED
:
9034 case BUILT_IN_VFPRINTF
:
9035 case BUILT_IN_FPRINTF_CHK
:
9036 case BUILT_IN_VFPRINTF_CHK
:
9037 return fold_builtin_fprintf (fndecl
, arglist
, ignore
,
9038 DECL_FUNCTION_CODE (fndecl
));
9047 /* A wrapper function for builtin folding that prevents warnings for
9048 "statement without effect" and the like, caused by removing the
9049 call node earlier than the warning is generated. */
9052 fold_builtin (tree fndecl
, tree arglist
, bool ignore
)
9054 tree exp
= fold_builtin_1 (fndecl
, arglist
, ignore
);
9057 exp
= build1 (NOP_EXPR
, TREE_TYPE (exp
), exp
);
9058 TREE_NO_WARNING (exp
) = 1;
9064 /* Conveniently construct a function call expression. */
9067 build_function_call_expr (tree fn
, tree arglist
)
9071 call_expr
= build1 (ADDR_EXPR
, build_pointer_type (TREE_TYPE (fn
)), fn
);
9072 return fold_build3 (CALL_EXPR
, TREE_TYPE (TREE_TYPE (fn
)),
9073 call_expr
, arglist
, NULL_TREE
);
9076 /* This function validates the types of a function call argument list
9077 represented as a tree chain of parameters against a specified list
9078 of tree_codes. If the last specifier is a 0, that represents an
9079 ellipses, otherwise the last specifier must be a VOID_TYPE. */
9082 validate_arglist (tree arglist
, ...)
9084 enum tree_code code
;
9088 va_start (ap
, arglist
);
9092 code
= va_arg (ap
, enum tree_code
);
9096 /* This signifies an ellipses, any further arguments are all ok. */
9100 /* This signifies an endlink, if no arguments remain, return
9101 true, otherwise return false. */
9105 /* If no parameters remain or the parameter's code does not
9106 match the specified code, return false. Otherwise continue
9107 checking any remaining arguments. */
9110 if (code
== POINTER_TYPE
)
9112 if (! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist
))))
9115 else if (code
!= TREE_CODE (TREE_TYPE (TREE_VALUE (arglist
))))
9119 arglist
= TREE_CHAIN (arglist
);
9123 /* We need gotos here since we can only have one VA_CLOSE in a
9131 /* Default target-specific builtin expander that does nothing. */
9134 default_expand_builtin (tree exp ATTRIBUTE_UNUSED
,
9135 rtx target ATTRIBUTE_UNUSED
,
9136 rtx subtarget ATTRIBUTE_UNUSED
,
9137 enum machine_mode mode ATTRIBUTE_UNUSED
,
9138 int ignore ATTRIBUTE_UNUSED
)
9143 /* Returns true is EXP represents data that would potentially reside
9144 in a readonly section. */
9147 readonly_data_expr (tree exp
)
9151 if (TREE_CODE (exp
) != ADDR_EXPR
)
9154 exp
= get_base_address (TREE_OPERAND (exp
, 0));
9158 /* Make sure we call decl_readonly_section only for trees it
9159 can handle (since it returns true for everything it doesn't
9161 if (TREE_CODE (exp
) == STRING_CST
9162 || TREE_CODE (exp
) == CONSTRUCTOR
9163 || (TREE_CODE (exp
) == VAR_DECL
&& TREE_STATIC (exp
)))
9164 return decl_readonly_section (exp
, 0);
9169 /* Simplify a call to the strstr builtin.
9171 Return 0 if no simplification was possible, otherwise return the
9172 simplified form of the call as a tree.
9174 The simplified form may be a constant or other expression which
9175 computes the same value, but in a more efficient manner (including
9176 calls to other builtin functions).
9178 The call may contain arguments which need to be evaluated, but
9179 which are not useful to determine the result of the call. In
9180 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9181 COMPOUND_EXPR will be an argument which must be evaluated.
9182 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9183 COMPOUND_EXPR in the chain will contain the tree for the simplified
9184 form of the builtin function call. */
9187 fold_builtin_strstr (tree arglist
, tree type
)
9189 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
9193 tree s1
= TREE_VALUE (arglist
), s2
= TREE_VALUE (TREE_CHAIN (arglist
));
9195 const char *p1
, *p2
;
9204 const char *r
= strstr (p1
, p2
);
9208 return build_int_cst (TREE_TYPE (s1
), 0);
9210 /* Return an offset into the constant string argument. */
9211 tem
= fold_build2 (PLUS_EXPR
, TREE_TYPE (s1
),
9212 s1
, build_int_cst (TREE_TYPE (s1
), r
- p1
));
9213 return fold_convert (type
, tem
);
9222 fn
= implicit_built_in_decls
[BUILT_IN_STRCHR
];
9226 /* New argument list transforming strstr(s1, s2) to
9227 strchr(s1, s2[0]). */
9228 arglist
= build_tree_list (NULL_TREE
,
9229 build_int_cst (NULL_TREE
, p2
[0]));
9230 arglist
= tree_cons (NULL_TREE
, s1
, arglist
);
9231 return build_function_call_expr (fn
, arglist
);
9235 /* Simplify a call to the strchr builtin.
9237 Return 0 if no simplification was possible, otherwise return the
9238 simplified form of the call as a tree.
9240 The simplified form may be a constant or other expression which
9241 computes the same value, but in a more efficient manner (including
9242 calls to other builtin functions).
9244 The call may contain arguments which need to be evaluated, but
9245 which are not useful to determine the result of the call. In
9246 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9247 COMPOUND_EXPR will be an argument which must be evaluated.
9248 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9249 COMPOUND_EXPR in the chain will contain the tree for the simplified
9250 form of the builtin function call. */
9253 fold_builtin_strchr (tree arglist
, tree type
)
9255 if (!validate_arglist (arglist
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
9259 tree s1
= TREE_VALUE (arglist
), s2
= TREE_VALUE (TREE_CHAIN (arglist
));
9262 if (TREE_CODE (s2
) != INTEGER_CST
)
9272 if (target_char_cast (s2
, &c
))
9278 return build_int_cst (TREE_TYPE (s1
), 0);
9280 /* Return an offset into the constant string argument. */
9281 tem
= fold_build2 (PLUS_EXPR
, TREE_TYPE (s1
),
9282 s1
, build_int_cst (TREE_TYPE (s1
), r
- p1
));
9283 return fold_convert (type
, tem
);
9289 /* Simplify a call to the strrchr builtin.
9291 Return 0 if no simplification was possible, otherwise return the
9292 simplified form of the call as a tree.
9294 The simplified form may be a constant or other expression which
9295 computes the same value, but in a more efficient manner (including
9296 calls to other builtin functions).
9298 The call may contain arguments which need to be evaluated, but
9299 which are not useful to determine the result of the call. In
9300 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9301 COMPOUND_EXPR will be an argument which must be evaluated.
9302 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9303 COMPOUND_EXPR in the chain will contain the tree for the simplified
9304 form of the builtin function call. */
9307 fold_builtin_strrchr (tree arglist
, tree type
)
9309 if (!validate_arglist (arglist
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
9313 tree s1
= TREE_VALUE (arglist
), s2
= TREE_VALUE (TREE_CHAIN (arglist
));
9317 if (TREE_CODE (s2
) != INTEGER_CST
)
9327 if (target_char_cast (s2
, &c
))
9330 r
= strrchr (p1
, c
);
9333 return build_int_cst (TREE_TYPE (s1
), 0);
9335 /* Return an offset into the constant string argument. */
9336 tem
= fold_build2 (PLUS_EXPR
, TREE_TYPE (s1
),
9337 s1
, build_int_cst (TREE_TYPE (s1
), r
- p1
));
9338 return fold_convert (type
, tem
);
9341 if (! integer_zerop (s2
))
9344 fn
= implicit_built_in_decls
[BUILT_IN_STRCHR
];
9348 /* Transform strrchr(s1, '\0') to strchr(s1, '\0'). */
9349 return build_function_call_expr (fn
, arglist
);
9353 /* Simplify a call to the strpbrk builtin.
9355 Return 0 if no simplification was possible, otherwise return the
9356 simplified form of the call as a tree.
9358 The simplified form may be a constant or other expression which
9359 computes the same value, but in a more efficient manner (including
9360 calls to other builtin functions).
9362 The call may contain arguments which need to be evaluated, but
9363 which are not useful to determine the result of the call. In
9364 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9365 COMPOUND_EXPR will be an argument which must be evaluated.
9366 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9367 COMPOUND_EXPR in the chain will contain the tree for the simplified
9368 form of the builtin function call. */
9371 fold_builtin_strpbrk (tree arglist
, tree type
)
9373 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
9377 tree s1
= TREE_VALUE (arglist
), s2
= TREE_VALUE (TREE_CHAIN (arglist
));
9379 const char *p1
, *p2
;
9388 const char *r
= strpbrk (p1
, p2
);
9392 return build_int_cst (TREE_TYPE (s1
), 0);
9394 /* Return an offset into the constant string argument. */
9395 tem
= fold_build2 (PLUS_EXPR
, TREE_TYPE (s1
),
9396 s1
, build_int_cst (TREE_TYPE (s1
), r
- p1
));
9397 return fold_convert (type
, tem
);
9401 /* strpbrk(x, "") == NULL.
9402 Evaluate and ignore s1 in case it had side-effects. */
9403 return omit_one_operand (TREE_TYPE (s1
), integer_zero_node
, s1
);
9406 return 0; /* Really call strpbrk. */
9408 fn
= implicit_built_in_decls
[BUILT_IN_STRCHR
];
9412 /* New argument list transforming strpbrk(s1, s2) to
9413 strchr(s1, s2[0]). */
9414 arglist
= build_tree_list (NULL_TREE
,
9415 build_int_cst (NULL_TREE
, p2
[0]));
9416 arglist
= tree_cons (NULL_TREE
, s1
, arglist
);
9417 return build_function_call_expr (fn
, arglist
);
9421 /* Simplify a call to the strcat builtin.
9423 Return 0 if no simplification was possible, otherwise return the
9424 simplified form of the call as a tree.
9426 The simplified form may be a constant or other expression which
9427 computes the same value, but in a more efficient manner (including
9428 calls to other builtin functions).
9430 The call may contain arguments which need to be evaluated, but
9431 which are not useful to determine the result of the call. In
9432 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9433 COMPOUND_EXPR will be an argument which must be evaluated.
9434 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9435 COMPOUND_EXPR in the chain will contain the tree for the simplified
9436 form of the builtin function call. */
9439 fold_builtin_strcat (tree arglist
)
9441 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
9445 tree dst
= TREE_VALUE (arglist
),
9446 src
= TREE_VALUE (TREE_CHAIN (arglist
));
9447 const char *p
= c_getstr (src
);
9449 /* If the string length is zero, return the dst parameter. */
9450 if (p
&& *p
== '\0')
9457 /* Simplify a call to the strncat builtin.
9459 Return 0 if no simplification was possible, otherwise return the
9460 simplified form of the call as a tree.
9462 The simplified form may be a constant or other expression which
9463 computes the same value, but in a more efficient manner (including
9464 calls to other builtin functions).
9466 The call may contain arguments which need to be evaluated, but
9467 which are not useful to determine the result of the call. In
9468 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9469 COMPOUND_EXPR will be an argument which must be evaluated.
9470 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9471 COMPOUND_EXPR in the chain will contain the tree for the simplified
9472 form of the builtin function call. */
9475 fold_builtin_strncat (tree arglist
)
9477 if (!validate_arglist (arglist
,
9478 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
9482 tree dst
= TREE_VALUE (arglist
);
9483 tree src
= TREE_VALUE (TREE_CHAIN (arglist
));
9484 tree len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
9485 const char *p
= c_getstr (src
);
9487 /* If the requested length is zero, or the src parameter string
9488 length is zero, return the dst parameter. */
9489 if (integer_zerop (len
) || (p
&& *p
== '\0'))
9490 return omit_two_operands (TREE_TYPE (dst
), dst
, src
, len
);
9492 /* If the requested len is greater than or equal to the string
9493 length, call strcat. */
9494 if (TREE_CODE (len
) == INTEGER_CST
&& p
9495 && compare_tree_int (len
, strlen (p
)) >= 0)
9498 = tree_cons (NULL_TREE
, dst
, build_tree_list (NULL_TREE
, src
));
9499 tree fn
= implicit_built_in_decls
[BUILT_IN_STRCAT
];
9501 /* If the replacement _DECL isn't initialized, don't do the
9506 return build_function_call_expr (fn
, newarglist
);
9512 /* Simplify a call to the strspn builtin.
9514 Return 0 if no simplification was possible, otherwise return the
9515 simplified form of the call as a tree.
9517 The simplified form may be a constant or other expression which
9518 computes the same value, but in a more efficient manner (including
9519 calls to other builtin functions).
9521 The call may contain arguments which need to be evaluated, but
9522 which are not useful to determine the result of the call. In
9523 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9524 COMPOUND_EXPR will be an argument which must be evaluated.
9525 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9526 COMPOUND_EXPR in the chain will contain the tree for the simplified
9527 form of the builtin function call. */
9530 fold_builtin_strspn (tree arglist
)
9532 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
9536 tree s1
= TREE_VALUE (arglist
), s2
= TREE_VALUE (TREE_CHAIN (arglist
));
9537 const char *p1
= c_getstr (s1
), *p2
= c_getstr (s2
);
9539 /* If both arguments are constants, evaluate at compile-time. */
9542 const size_t r
= strspn (p1
, p2
);
9543 return size_int (r
);
9546 /* If either argument is "", return 0. */
9547 if ((p1
&& *p1
== '\0') || (p2
&& *p2
== '\0'))
9548 /* Evaluate and ignore both arguments in case either one has
9550 return omit_two_operands (integer_type_node
, integer_zero_node
,
9556 /* Simplify a call to the strcspn builtin.
9558 Return 0 if no simplification was possible, otherwise return the
9559 simplified form of the call as a tree.
9561 The simplified form may be a constant or other expression which
9562 computes the same value, but in a more efficient manner (including
9563 calls to other builtin functions).
9565 The call may contain arguments which need to be evaluated, but
9566 which are not useful to determine the result of the call. In
9567 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9568 COMPOUND_EXPR will be an argument which must be evaluated.
9569 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9570 COMPOUND_EXPR in the chain will contain the tree for the simplified
9571 form of the builtin function call. */
9574 fold_builtin_strcspn (tree arglist
)
9576 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
9580 tree s1
= TREE_VALUE (arglist
), s2
= TREE_VALUE (TREE_CHAIN (arglist
));
9581 const char *p1
= c_getstr (s1
), *p2
= c_getstr (s2
);
9583 /* If both arguments are constants, evaluate at compile-time. */
9586 const size_t r
= strcspn (p1
, p2
);
9587 return size_int (r
);
9590 /* If the first argument is "", return 0. */
9591 if (p1
&& *p1
== '\0')
9593 /* Evaluate and ignore argument s2 in case it has
9595 return omit_one_operand (integer_type_node
,
9596 integer_zero_node
, s2
);
9599 /* If the second argument is "", return __builtin_strlen(s1). */
9600 if (p2
&& *p2
== '\0')
9602 tree newarglist
= build_tree_list (NULL_TREE
, s1
),
9603 fn
= implicit_built_in_decls
[BUILT_IN_STRLEN
];
9605 /* If the replacement _DECL isn't initialized, don't do the
9610 return build_function_call_expr (fn
, newarglist
);
9616 /* Fold a call to the fputs builtin. IGNORE is true if the value returned
9617 by the builtin will be ignored. UNLOCKED is true is true if this
9618 actually a call to fputs_unlocked. If LEN in non-NULL, it represents
9619 the known length of the string. Return NULL_TREE if no simplification
9623 fold_builtin_fputs (tree arglist
, bool ignore
, bool unlocked
, tree len
)
9626 tree fn_fputc
= unlocked
? implicit_built_in_decls
[BUILT_IN_FPUTC_UNLOCKED
]
9627 : implicit_built_in_decls
[BUILT_IN_FPUTC
];
9628 tree fn_fwrite
= unlocked
? implicit_built_in_decls
[BUILT_IN_FWRITE_UNLOCKED
]
9629 : implicit_built_in_decls
[BUILT_IN_FWRITE
];
9631 /* If the return value is used, or the replacement _DECL isn't
9632 initialized, don't do the transformation. */
9633 if (!ignore
|| !fn_fputc
|| !fn_fwrite
)
9636 /* Verify the arguments in the original call. */
9637 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
9641 len
= c_strlen (TREE_VALUE (arglist
), 0);
9643 /* Get the length of the string passed to fputs. If the length
9644 can't be determined, punt. */
9646 || TREE_CODE (len
) != INTEGER_CST
)
9649 switch (compare_tree_int (len
, 1))
9651 case -1: /* length is 0, delete the call entirely . */
9652 return omit_one_operand (integer_type_node
, integer_zero_node
,
9653 TREE_VALUE (TREE_CHAIN (arglist
)));
9655 case 0: /* length is 1, call fputc. */
9657 const char *p
= c_getstr (TREE_VALUE (arglist
));
9661 /* New argument list transforming fputs(string, stream) to
9662 fputc(string[0], stream). */
9663 arglist
= build_tree_list (NULL_TREE
,
9664 TREE_VALUE (TREE_CHAIN (arglist
)));
9665 arglist
= tree_cons (NULL_TREE
,
9666 build_int_cst (NULL_TREE
, p
[0]),
9673 case 1: /* length is greater than 1, call fwrite. */
9677 /* If optimizing for size keep fputs. */
9680 string_arg
= TREE_VALUE (arglist
);
9681 /* New argument list transforming fputs(string, stream) to
9682 fwrite(string, 1, len, stream). */
9683 arglist
= build_tree_list (NULL_TREE
,
9684 TREE_VALUE (TREE_CHAIN (arglist
)));
9685 arglist
= tree_cons (NULL_TREE
, len
, arglist
);
9686 arglist
= tree_cons (NULL_TREE
, size_one_node
, arglist
);
9687 arglist
= tree_cons (NULL_TREE
, string_arg
, arglist
);
9695 /* These optimizations are only performed when the result is ignored,
9696 hence there's no need to cast the result to integer_type_node. */
9697 return build_function_call_expr (fn
, arglist
);
9700 /* Fold the new_arg's arguments (ARGLIST). Returns true if there was an error
9701 produced. False otherwise. This is done so that we don't output the error
9702 or warning twice or three times. */
9704 fold_builtin_next_arg (tree arglist
)
9706 tree fntype
= TREE_TYPE (current_function_decl
);
9708 if (TYPE_ARG_TYPES (fntype
) == 0
9709 || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype
)))
9712 error ("%<va_start%> used in function with fixed args");
9717 /* Evidently an out of date version of <stdarg.h>; can't validate
9718 va_start's second argument, but can still work as intended. */
9719 warning (0, "%<__builtin_next_arg%> called without an argument");
9722 /* We use __builtin_va_start (ap, 0, 0) or __builtin_next_arg (0, 0)
9723 when we checked the arguments and if needed issued a warning. */
9724 else if (!TREE_CHAIN (arglist
)
9725 || !integer_zerop (TREE_VALUE (arglist
))
9726 || !integer_zerop (TREE_VALUE (TREE_CHAIN (arglist
)))
9727 || TREE_CHAIN (TREE_CHAIN (arglist
)))
9729 tree last_parm
= tree_last (DECL_ARGUMENTS (current_function_decl
));
9730 tree arg
= TREE_VALUE (arglist
);
9732 if (TREE_CHAIN (arglist
))
9734 error ("%<va_start%> used with too many arguments");
9738 /* Strip off all nops for the sake of the comparison. This
9739 is not quite the same as STRIP_NOPS. It does more.
9740 We must also strip off INDIRECT_EXPR for C++ reference
9742 while (TREE_CODE (arg
) == NOP_EXPR
9743 || TREE_CODE (arg
) == CONVERT_EXPR
9744 || TREE_CODE (arg
) == NON_LVALUE_EXPR
9745 || TREE_CODE (arg
) == INDIRECT_REF
)
9746 arg
= TREE_OPERAND (arg
, 0);
9747 if (arg
!= last_parm
)
9749 /* FIXME: Sometimes with the tree optimizers we can get the
9750 not the last argument even though the user used the last
9751 argument. We just warn and set the arg to be the last
9752 argument so that we will get wrong-code because of
9754 warning (0, "second parameter of %<va_start%> not last named argument");
9756 /* We want to verify the second parameter just once before the tree
9757 optimizers are run and then avoid keeping it in the tree,
9758 as otherwise we could warn even for correct code like:
9759 void foo (int i, ...)
9760 { va_list ap; i++; va_start (ap, i); va_end (ap); } */
9761 TREE_VALUE (arglist
) = integer_zero_node
;
9762 TREE_CHAIN (arglist
) = build_tree_list (NULL
, integer_zero_node
);
9768 /* Simplify a call to the sprintf builtin.
9770 Return 0 if no simplification was possible, otherwise return the
9771 simplified form of the call as a tree. If IGNORED is true, it means that
9772 the caller does not use the returned value of the function. */
9775 fold_builtin_sprintf (tree arglist
, int ignored
)
9777 tree call
, retval
, dest
, fmt
;
9778 const char *fmt_str
= NULL
;
9780 /* Verify the required arguments in the original call. We deal with two
9781 types of sprintf() calls: 'sprintf (str, fmt)' and
9782 'sprintf (dest, "%s", orig)'. */
9783 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
)
9784 && !validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, POINTER_TYPE
,
9788 /* Get the destination string and the format specifier. */
9789 dest
= TREE_VALUE (arglist
);
9790 fmt
= TREE_VALUE (TREE_CHAIN (arglist
));
9792 /* Check whether the format is a literal string constant. */
9793 fmt_str
= c_getstr (fmt
);
9794 if (fmt_str
== NULL
)
9800 /* If the format doesn't contain % args or %%, use strcpy. */
9801 if (strchr (fmt_str
, '%') == NULL
)
9803 tree fn
= implicit_built_in_decls
[BUILT_IN_STRCPY
];
9808 /* Convert sprintf (str, fmt) into strcpy (str, fmt) when
9809 'format' is known to contain no % formats. */
9810 arglist
= build_tree_list (NULL_TREE
, fmt
);
9811 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
9812 call
= build_function_call_expr (fn
, arglist
);
9814 retval
= build_int_cst (NULL_TREE
, strlen (fmt_str
));
9817 /* If the format is "%s", use strcpy if the result isn't used. */
9818 else if (fmt_str
&& strcmp (fmt_str
, "%s") == 0)
9821 fn
= implicit_built_in_decls
[BUILT_IN_STRCPY
];
9826 /* Convert sprintf (str1, "%s", str2) into strcpy (str1, str2). */
9827 orig
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
9828 arglist
= build_tree_list (NULL_TREE
, orig
);
9829 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
9832 retval
= c_strlen (orig
, 1);
9833 if (!retval
|| TREE_CODE (retval
) != INTEGER_CST
)
9836 call
= build_function_call_expr (fn
, arglist
);
9842 (TREE_TYPE (TREE_TYPE (implicit_built_in_decls
[BUILT_IN_SPRINTF
])),
9844 return build2 (COMPOUND_EXPR
, TREE_TYPE (retval
), call
, retval
);
9850 /* Expand a call to __builtin_object_size. */
9853 expand_builtin_object_size (tree exp
)
9856 int object_size_type
;
9857 tree fndecl
= get_callee_fndecl (exp
);
9858 tree arglist
= TREE_OPERAND (exp
, 1);
9859 location_t locus
= EXPR_LOCATION (exp
);
9861 if (!validate_arglist (arglist
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
9863 error ("%Hfirst argument of %D must be a pointer, second integer constant",
9865 expand_builtin_trap ();
9869 ost
= TREE_VALUE (TREE_CHAIN (arglist
));
9872 if (TREE_CODE (ost
) != INTEGER_CST
9873 || tree_int_cst_sgn (ost
) < 0
9874 || compare_tree_int (ost
, 3) > 0)
9876 error ("%Hlast argument of %D is not integer constant between 0 and 3",
9878 expand_builtin_trap ();
9882 object_size_type
= tree_low_cst (ost
, 0);
9884 return object_size_type
< 2 ? constm1_rtx
: const0_rtx
;
9887 /* Expand EXP, a call to the __mem{cpy,pcpy,move,set}_chk builtin.
9888 FCODE is the BUILT_IN_* to use.
9889 Return 0 if we failed; the caller should emit a normal call,
9890 otherwise try to get the result in TARGET, if convenient (and in
9891 mode MODE if that's convenient). */
9894 expand_builtin_memory_chk (tree exp
, rtx target
, enum machine_mode mode
,
9895 enum built_in_function fcode
)
9897 tree arglist
= TREE_OPERAND (exp
, 1);
9898 tree dest
, src
, len
, size
;
9900 if (!validate_arglist (arglist
,
9902 fcode
== BUILT_IN_MEMSET_CHK
9903 ? INTEGER_TYPE
: POINTER_TYPE
,
9904 INTEGER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
9907 dest
= TREE_VALUE (arglist
);
9908 src
= TREE_VALUE (TREE_CHAIN (arglist
));
9909 len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
9910 size
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist
))));
9912 if (! host_integerp (size
, 1))
9915 if (host_integerp (len
, 1) || integer_all_onesp (size
))
9919 if (! integer_all_onesp (size
) && tree_int_cst_lt (size
, len
))
9921 location_t locus
= EXPR_LOCATION (exp
);
9922 warning (0, "%Hcall to %D will always overflow destination buffer",
9923 &locus
, get_callee_fndecl (exp
));
9927 arglist
= build_tree_list (NULL_TREE
, len
);
9928 arglist
= tree_cons (NULL_TREE
, src
, arglist
);
9929 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
9932 /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume
9933 mem{cpy,pcpy,move,set} is available. */
9936 case BUILT_IN_MEMCPY_CHK
:
9937 fn
= built_in_decls
[BUILT_IN_MEMCPY
];
9939 case BUILT_IN_MEMPCPY_CHK
:
9940 fn
= built_in_decls
[BUILT_IN_MEMPCPY
];
9942 case BUILT_IN_MEMMOVE_CHK
:
9943 fn
= built_in_decls
[BUILT_IN_MEMMOVE
];
9945 case BUILT_IN_MEMSET_CHK
:
9946 fn
= built_in_decls
[BUILT_IN_MEMSET
];
9955 fn
= build_function_call_expr (fn
, arglist
);
9956 if (TREE_CODE (fn
) == CALL_EXPR
)
9957 CALL_EXPR_TAILCALL (fn
) = CALL_EXPR_TAILCALL (exp
);
9958 return expand_expr (fn
, target
, mode
, EXPAND_NORMAL
);
9960 else if (fcode
== BUILT_IN_MEMSET_CHK
)
9964 unsigned int dest_align
9965 = get_pointer_alignment (dest
, BIGGEST_ALIGNMENT
);
9967 /* If DEST is not a pointer type, call the normal function. */
9968 if (dest_align
== 0)
9971 /* If SRC and DEST are the same (and not volatile), do nothing. */
9972 if (operand_equal_p (src
, dest
, 0))
9976 if (fcode
!= BUILT_IN_MEMPCPY_CHK
)
9978 /* Evaluate and ignore LEN in case it has side-effects. */
9979 expand_expr (len
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
9980 return expand_expr (dest
, target
, mode
, EXPAND_NORMAL
);
9983 len
= fold_convert (TREE_TYPE (dest
), len
);
9984 expr
= fold_build2 (PLUS_EXPR
, TREE_TYPE (dest
), dest
, len
);
9985 return expand_expr (expr
, target
, mode
, EXPAND_NORMAL
);
9988 /* __memmove_chk special case. */
9989 if (fcode
== BUILT_IN_MEMMOVE_CHK
)
9991 unsigned int src_align
9992 = get_pointer_alignment (src
, BIGGEST_ALIGNMENT
);
9997 /* If src is categorized for a readonly section we can use
9998 normal __memcpy_chk. */
9999 if (readonly_data_expr (src
))
10001 tree fn
= built_in_decls
[BUILT_IN_MEMCPY_CHK
];
10004 fn
= build_function_call_expr (fn
, arglist
);
10005 if (TREE_CODE (fn
) == CALL_EXPR
)
10006 CALL_EXPR_TAILCALL (fn
) = CALL_EXPR_TAILCALL (exp
);
10007 return expand_expr (fn
, target
, mode
, EXPAND_NORMAL
);
10014 /* Emit warning if a buffer overflow is detected at compile time. */
10017 maybe_emit_chk_warning (tree exp
, enum built_in_function fcode
)
10019 int arg_mask
, is_strlen
= 0;
10020 tree arglist
= TREE_OPERAND (exp
, 1), a
;
10026 case BUILT_IN_STRCPY_CHK
:
10027 case BUILT_IN_STPCPY_CHK
:
10028 /* For __strcat_chk the warning will be emitted only if overflowing
10029 by at least strlen (dest) + 1 bytes. */
10030 case BUILT_IN_STRCAT_CHK
:
10034 case BUILT_IN_STRNCPY_CHK
:
10037 case BUILT_IN_SNPRINTF_CHK
:
10038 case BUILT_IN_VSNPRINTF_CHK
:
10042 gcc_unreachable ();
10047 for (a
= arglist
; a
&& arg_mask
; a
= TREE_CHAIN (a
), arg_mask
>>= 1)
10059 len
= TREE_VALUE (len
);
10060 size
= TREE_VALUE (size
);
10062 if (! host_integerp (size
, 1) || integer_all_onesp (size
))
10067 len
= c_strlen (len
, 1);
10068 if (! len
|| ! host_integerp (len
, 1) || tree_int_cst_lt (len
, size
))
10071 else if (! host_integerp (len
, 1) || ! tree_int_cst_lt (size
, len
))
10074 locus
= EXPR_LOCATION (exp
);
10075 warning (0, "%Hcall to %D will always overflow destination buffer",
10076 &locus
, get_callee_fndecl (exp
));
10079 /* Emit warning if a buffer overflow is detected at compile time
10080 in __sprintf_chk/__vsprintf_chk calls. */
10083 maybe_emit_sprintf_chk_warning (tree exp
, enum built_in_function fcode
)
10085 tree arglist
= TREE_OPERAND (exp
, 1);
10086 tree dest
, size
, len
, fmt
, flag
;
10087 const char *fmt_str
;
10089 /* Verify the required arguments in the original call. */
10092 dest
= TREE_VALUE (arglist
);
10093 arglist
= TREE_CHAIN (arglist
);
10096 flag
= TREE_VALUE (arglist
);
10097 arglist
= TREE_CHAIN (arglist
);
10100 size
= TREE_VALUE (arglist
);
10101 arglist
= TREE_CHAIN (arglist
);
10104 fmt
= TREE_VALUE (arglist
);
10105 arglist
= TREE_CHAIN (arglist
);
10107 if (! host_integerp (size
, 1) || integer_all_onesp (size
))
10110 /* Check whether the format is a literal string constant. */
10111 fmt_str
= c_getstr (fmt
);
10112 if (fmt_str
== NULL
)
10115 /* If the format doesn't contain % args or %%, we know its size. */
10116 if (strchr (fmt_str
, '%') == 0)
10117 len
= build_int_cstu (size_type_node
, strlen (fmt_str
));
10118 /* If the format is "%s" and first ... argument is a string literal,
10120 else if (fcode
== BUILT_IN_SPRINTF_CHK
&& strcmp (fmt_str
, "%s") == 0)
10126 arg
= TREE_VALUE (arglist
);
10127 if (! POINTER_TYPE_P (TREE_TYPE (arg
)))
10130 len
= c_strlen (arg
, 1);
10131 if (!len
|| ! host_integerp (len
, 1))
10137 if (! tree_int_cst_lt (len
, size
))
10139 location_t locus
= EXPR_LOCATION (exp
);
10140 warning (0, "%Hcall to %D will always overflow destination buffer",
10141 &locus
, get_callee_fndecl (exp
));
10145 /* Fold a call to __builtin_object_size, if possible. */
10148 fold_builtin_object_size (tree arglist
)
10150 tree ptr
, ost
, ret
= 0;
10151 int object_size_type
;
10153 if (!validate_arglist (arglist
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
10156 ptr
= TREE_VALUE (arglist
);
10157 ost
= TREE_VALUE (TREE_CHAIN (arglist
));
10160 if (TREE_CODE (ost
) != INTEGER_CST
10161 || tree_int_cst_sgn (ost
) < 0
10162 || compare_tree_int (ost
, 3) > 0)
10165 object_size_type
= tree_low_cst (ost
, 0);
10167 /* __builtin_object_size doesn't evaluate side-effects in its arguments;
10168 if there are any side-effects, it returns (size_t) -1 for types 0 and 1
10169 and (size_t) 0 for types 2 and 3. */
10170 if (TREE_SIDE_EFFECTS (ptr
))
10171 return fold_convert (size_type_node
,
10172 object_size_type
< 2
10173 ? integer_minus_one_node
: integer_zero_node
);
10175 if (TREE_CODE (ptr
) == ADDR_EXPR
)
10176 ret
= build_int_cstu (size_type_node
,
10177 compute_builtin_object_size (ptr
, object_size_type
));
10179 else if (TREE_CODE (ptr
) == SSA_NAME
)
10181 unsigned HOST_WIDE_INT bytes
;
10183 /* If object size is not known yet, delay folding until
10184 later. Maybe subsequent passes will help determining
10186 bytes
= compute_builtin_object_size (ptr
, object_size_type
);
10187 if (bytes
!= (unsigned HOST_WIDE_INT
) (object_size_type
< 2
10189 ret
= build_int_cstu (size_type_node
, bytes
);
10194 ret
= force_fit_type (ret
, -1, false, false);
10195 if (TREE_CONSTANT_OVERFLOW (ret
))
10202 /* Fold a call to the __mem{cpy,pcpy,move,set}_chk builtin.
10203 IGNORE is true, if return value can be ignored. FCODE is the BUILT_IN_*
10204 code of the builtin. If MAXLEN is not NULL, it is maximum length
10205 passed as third argument. */
10208 fold_builtin_memory_chk (tree fndecl
, tree arglist
, tree maxlen
, bool ignore
,
10209 enum built_in_function fcode
)
10211 tree dest
, src
, len
, size
, fn
;
10213 if (!validate_arglist (arglist
,
10215 fcode
== BUILT_IN_MEMSET_CHK
10216 ? INTEGER_TYPE
: POINTER_TYPE
,
10217 INTEGER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
10220 dest
= TREE_VALUE (arglist
);
10221 /* Actually val for __memset_chk, but it doesn't matter. */
10222 src
= TREE_VALUE (TREE_CHAIN (arglist
));
10223 len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
10224 size
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist
))));
10226 /* If SRC and DEST are the same (and not volatile), return DEST
10227 (resp. DEST+LEN for __mempcpy_chk). */
10228 if (fcode
!= BUILT_IN_MEMSET_CHK
&& operand_equal_p (src
, dest
, 0))
10230 if (fcode
!= BUILT_IN_MEMPCPY_CHK
)
10231 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl
)), dest
, len
);
10234 tree temp
= fold_convert (TREE_TYPE (dest
), len
);
10235 temp
= fold_build2 (PLUS_EXPR
, TREE_TYPE (dest
), dest
, temp
);
10236 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl
)), temp
);
10240 if (! host_integerp (size
, 1))
10243 if (! integer_all_onesp (size
))
10245 if (! host_integerp (len
, 1))
10247 /* If LEN is not constant, try MAXLEN too.
10248 For MAXLEN only allow optimizing into non-_ocs function
10249 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
10250 if (maxlen
== NULL_TREE
|| ! host_integerp (maxlen
, 1))
10252 if (fcode
== BUILT_IN_MEMPCPY_CHK
&& ignore
)
10254 /* (void) __mempcpy_chk () can be optimized into
10255 (void) __memcpy_chk (). */
10256 fn
= built_in_decls
[BUILT_IN_MEMCPY_CHK
];
10260 return build_function_call_expr (fn
, arglist
);
10268 if (tree_int_cst_lt (size
, maxlen
))
10272 arglist
= build_tree_list (NULL_TREE
, len
);
10273 arglist
= tree_cons (NULL_TREE
, src
, arglist
);
10274 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
10277 /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume
10278 mem{cpy,pcpy,move,set} is available. */
10281 case BUILT_IN_MEMCPY_CHK
:
10282 fn
= built_in_decls
[BUILT_IN_MEMCPY
];
10284 case BUILT_IN_MEMPCPY_CHK
:
10285 fn
= built_in_decls
[BUILT_IN_MEMPCPY
];
10287 case BUILT_IN_MEMMOVE_CHK
:
10288 fn
= built_in_decls
[BUILT_IN_MEMMOVE
];
10290 case BUILT_IN_MEMSET_CHK
:
10291 fn
= built_in_decls
[BUILT_IN_MEMSET
];
10300 return build_function_call_expr (fn
, arglist
);
10303 /* Fold a call to the __st[rp]cpy_chk builtin.
10304 IGNORE is true, if return value can be ignored. FCODE is the BUILT_IN_*
10305 code of the builtin. If MAXLEN is not NULL, it is maximum length of
10306 strings passed as second argument. */
10309 fold_builtin_stxcpy_chk (tree fndecl
, tree arglist
, tree maxlen
, bool ignore
,
10310 enum built_in_function fcode
)
10312 tree dest
, src
, size
, len
, fn
;
10314 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
,
10318 dest
= TREE_VALUE (arglist
);
10319 src
= TREE_VALUE (TREE_CHAIN (arglist
));
10320 size
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
10322 /* If SRC and DEST are the same (and not volatile), return DEST. */
10323 if (fcode
== BUILT_IN_STRCPY_CHK
&& operand_equal_p (src
, dest
, 0))
10324 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl
)), dest
);
10326 if (! host_integerp (size
, 1))
10329 if (! integer_all_onesp (size
))
10331 len
= c_strlen (src
, 1);
10332 if (! len
|| ! host_integerp (len
, 1))
10334 /* If LEN is not constant, try MAXLEN too.
10335 For MAXLEN only allow optimizing into non-_ocs function
10336 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
10337 if (maxlen
== NULL_TREE
|| ! host_integerp (maxlen
, 1))
10339 if (fcode
== BUILT_IN_STPCPY_CHK
)
10344 /* If return value of __stpcpy_chk is ignored,
10345 optimize into __strcpy_chk. */
10346 fn
= built_in_decls
[BUILT_IN_STRCPY_CHK
];
10350 return build_function_call_expr (fn
, arglist
);
10353 if (! len
|| TREE_SIDE_EFFECTS (len
))
10356 /* If c_strlen returned something, but not a constant,
10357 transform __strcpy_chk into __memcpy_chk. */
10358 fn
= built_in_decls
[BUILT_IN_MEMCPY_CHK
];
10362 len
= size_binop (PLUS_EXPR
, len
, ssize_int (1));
10363 arglist
= build_tree_list (NULL_TREE
, size
);
10364 arglist
= tree_cons (NULL_TREE
, len
, arglist
);
10365 arglist
= tree_cons (NULL_TREE
, src
, arglist
);
10366 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
10367 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl
)),
10368 build_function_call_expr (fn
, arglist
));
10374 if (! tree_int_cst_lt (maxlen
, size
))
10378 arglist
= build_tree_list (NULL_TREE
, src
);
10379 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
10381 /* If __builtin_st{r,p}cpy_chk is used, assume st{r,p}cpy is available. */
10382 fn
= built_in_decls
[fcode
== BUILT_IN_STPCPY_CHK
10383 ? BUILT_IN_STPCPY
: BUILT_IN_STRCPY
];
10387 return build_function_call_expr (fn
, arglist
);
10390 /* Fold a call to the __strncpy_chk builtin.
10391 If MAXLEN is not NULL, it is maximum length passed as third argument. */
10394 fold_builtin_strncpy_chk (tree arglist
, tree maxlen
)
10396 tree dest
, src
, size
, len
, fn
;
10398 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
,
10399 INTEGER_TYPE
, VOID_TYPE
))
10402 dest
= TREE_VALUE (arglist
);
10403 src
= TREE_VALUE (TREE_CHAIN (arglist
));
10404 len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
10405 size
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist
))));
10407 if (! host_integerp (size
, 1))
10410 if (! integer_all_onesp (size
))
10412 if (! host_integerp (len
, 1))
10414 /* If LEN is not constant, try MAXLEN too.
10415 For MAXLEN only allow optimizing into non-_ocs function
10416 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
10417 if (maxlen
== NULL_TREE
|| ! host_integerp (maxlen
, 1))
10423 if (tree_int_cst_lt (size
, maxlen
))
10427 arglist
= build_tree_list (NULL_TREE
, len
);
10428 arglist
= tree_cons (NULL_TREE
, src
, arglist
);
10429 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
10431 /* If __builtin_strncpy_chk is used, assume strncpy is available. */
10432 fn
= built_in_decls
[BUILT_IN_STRNCPY
];
10436 return build_function_call_expr (fn
, arglist
);
10439 /* Fold a call to the __strcat_chk builtin FNDECL with ARGLIST. */
10442 fold_builtin_strcat_chk (tree fndecl
, tree arglist
)
10444 tree dest
, src
, size
, fn
;
10447 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
,
10451 dest
= TREE_VALUE (arglist
);
10452 src
= TREE_VALUE (TREE_CHAIN (arglist
));
10453 size
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
10455 p
= c_getstr (src
);
10456 /* If the SRC parameter is "", return DEST. */
10457 if (p
&& *p
== '\0')
10458 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl
)), dest
, src
);
10460 if (! host_integerp (size
, 1) || ! integer_all_onesp (size
))
10463 arglist
= build_tree_list (NULL_TREE
, src
);
10464 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
10466 /* If __builtin_strcat_chk is used, assume strcat is available. */
10467 fn
= built_in_decls
[BUILT_IN_STRCAT
];
10471 return build_function_call_expr (fn
, arglist
);
10474 /* Fold a call to the __strncat_chk builtin EXP. */
10477 fold_builtin_strncat_chk (tree fndecl
, tree arglist
)
10479 tree dest
, src
, size
, len
, fn
;
10482 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
,
10483 INTEGER_TYPE
, VOID_TYPE
))
10486 dest
= TREE_VALUE (arglist
);
10487 src
= TREE_VALUE (TREE_CHAIN (arglist
));
10488 len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
10489 size
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist
))));
10491 p
= c_getstr (src
);
10492 /* If the SRC parameter is "" or if LEN is 0, return DEST. */
10493 if (p
&& *p
== '\0')
10494 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl
)), dest
, len
);
10495 else if (integer_zerop (len
))
10496 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl
)), dest
, src
);
10498 if (! host_integerp (size
, 1))
10501 if (! integer_all_onesp (size
))
10503 tree src_len
= c_strlen (src
, 1);
10505 && host_integerp (src_len
, 1)
10506 && host_integerp (len
, 1)
10507 && ! tree_int_cst_lt (len
, src_len
))
10509 /* If LEN >= strlen (SRC), optimize into __strcat_chk. */
10510 fn
= built_in_decls
[BUILT_IN_STRCAT_CHK
];
10514 arglist
= build_tree_list (NULL_TREE
, size
);
10515 arglist
= tree_cons (NULL_TREE
, src
, arglist
);
10516 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
10517 return build_function_call_expr (fn
, arglist
);
10522 arglist
= build_tree_list (NULL_TREE
, len
);
10523 arglist
= tree_cons (NULL_TREE
, src
, arglist
);
10524 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
10526 /* If __builtin_strncat_chk is used, assume strncat is available. */
10527 fn
= built_in_decls
[BUILT_IN_STRNCAT
];
10531 return build_function_call_expr (fn
, arglist
);
10534 /* Fold a call to __{,v}sprintf_chk with argument list ARGLIST. Return 0 if
10535 a normal call should be emitted rather than expanding the function
10536 inline. FCODE is either BUILT_IN_SPRINTF_CHK or BUILT_IN_VSPRINTF_CHK. */
10539 fold_builtin_sprintf_chk (tree arglist
, enum built_in_function fcode
)
10541 tree dest
, size
, len
, fn
, fmt
, flag
;
10542 const char *fmt_str
;
10544 /* Verify the required arguments in the original call. */
10547 dest
= TREE_VALUE (arglist
);
10548 if (! POINTER_TYPE_P (TREE_TYPE (dest
)))
10550 arglist
= TREE_CHAIN (arglist
);
10553 flag
= TREE_VALUE (arglist
);
10554 if (TREE_CODE (TREE_TYPE (flag
)) != INTEGER_TYPE
)
10556 arglist
= TREE_CHAIN (arglist
);
10559 size
= TREE_VALUE (arglist
);
10560 if (TREE_CODE (TREE_TYPE (size
)) != INTEGER_TYPE
)
10562 arglist
= TREE_CHAIN (arglist
);
10565 fmt
= TREE_VALUE (arglist
);
10566 if (! POINTER_TYPE_P (TREE_TYPE (fmt
)))
10568 arglist
= TREE_CHAIN (arglist
);
10570 if (! host_integerp (size
, 1))
10575 /* Check whether the format is a literal string constant. */
10576 fmt_str
= c_getstr (fmt
);
10577 if (fmt_str
!= NULL
)
10579 /* If the format doesn't contain % args or %%, we know the size. */
10580 if (strchr (fmt_str
, '%') == 0)
10582 if (fcode
!= BUILT_IN_SPRINTF_CHK
|| arglist
== NULL_TREE
)
10583 len
= build_int_cstu (size_type_node
, strlen (fmt_str
));
10585 /* If the format is "%s" and first ... argument is a string literal,
10586 we know the size too. */
10587 else if (fcode
== BUILT_IN_SPRINTF_CHK
&& strcmp (fmt_str
, "%s") == 0)
10591 if (arglist
&& !TREE_CHAIN (arglist
))
10593 arg
= TREE_VALUE (arglist
);
10594 if (POINTER_TYPE_P (TREE_TYPE (arg
)))
10596 len
= c_strlen (arg
, 1);
10597 if (! len
|| ! host_integerp (len
, 1))
10604 if (! integer_all_onesp (size
))
10606 if (! len
|| ! tree_int_cst_lt (len
, size
))
10610 /* Only convert __{,v}sprintf_chk to {,v}sprintf if flag is 0
10611 or if format doesn't contain % chars or is "%s". */
10612 if (! integer_zerop (flag
))
10614 if (fmt_str
== NULL
)
10616 if (strchr (fmt_str
, '%') != NULL
&& strcmp (fmt_str
, "%s"))
10620 arglist
= tree_cons (NULL_TREE
, fmt
, arglist
);
10621 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
10623 /* If __builtin_{,v}sprintf_chk is used, assume {,v}sprintf is available. */
10624 fn
= built_in_decls
[fcode
== BUILT_IN_VSPRINTF_CHK
10625 ? BUILT_IN_VSPRINTF
: BUILT_IN_SPRINTF
];
10629 return build_function_call_expr (fn
, arglist
);
10632 /* Fold a call to {,v}snprintf with argument list ARGLIST. Return 0 if
10633 a normal call should be emitted rather than expanding the function
10634 inline. FCODE is either BUILT_IN_SNPRINTF_CHK or
10635 BUILT_IN_VSNPRINTF_CHK. If MAXLEN is not NULL, it is maximum length
10636 passed as second argument. */
10639 fold_builtin_snprintf_chk (tree arglist
, tree maxlen
,
10640 enum built_in_function fcode
)
10642 tree dest
, size
, len
, fn
, fmt
, flag
;
10643 const char *fmt_str
;
10645 /* Verify the required arguments in the original call. */
10648 dest
= TREE_VALUE (arglist
);
10649 if (! POINTER_TYPE_P (TREE_TYPE (dest
)))
10651 arglist
= TREE_CHAIN (arglist
);
10654 len
= TREE_VALUE (arglist
);
10655 if (TREE_CODE (TREE_TYPE (len
)) != INTEGER_TYPE
)
10657 arglist
= TREE_CHAIN (arglist
);
10660 flag
= TREE_VALUE (arglist
);
10661 if (TREE_CODE (TREE_TYPE (len
)) != INTEGER_TYPE
)
10663 arglist
= TREE_CHAIN (arglist
);
10666 size
= TREE_VALUE (arglist
);
10667 if (TREE_CODE (TREE_TYPE (size
)) != INTEGER_TYPE
)
10669 arglist
= TREE_CHAIN (arglist
);
10672 fmt
= TREE_VALUE (arglist
);
10673 if (! POINTER_TYPE_P (TREE_TYPE (fmt
)))
10675 arglist
= TREE_CHAIN (arglist
);
10677 if (! host_integerp (size
, 1))
10680 if (! integer_all_onesp (size
))
10682 if (! host_integerp (len
, 1))
10684 /* If LEN is not constant, try MAXLEN too.
10685 For MAXLEN only allow optimizing into non-_ocs function
10686 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
10687 if (maxlen
== NULL_TREE
|| ! host_integerp (maxlen
, 1))
10693 if (tree_int_cst_lt (size
, maxlen
))
10697 /* Only convert __{,v}snprintf_chk to {,v}snprintf if flag is 0
10698 or if format doesn't contain % chars or is "%s". */
10699 if (! integer_zerop (flag
))
10701 fmt_str
= c_getstr (fmt
);
10702 if (fmt_str
== NULL
)
10704 if (strchr (fmt_str
, '%') != NULL
&& strcmp (fmt_str
, "%s"))
10708 arglist
= tree_cons (NULL_TREE
, fmt
, arglist
);
10709 arglist
= tree_cons (NULL_TREE
, len
, arglist
);
10710 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
10712 /* If __builtin_{,v}snprintf_chk is used, assume {,v}snprintf is
10714 fn
= built_in_decls
[fcode
== BUILT_IN_VSNPRINTF_CHK
10715 ? BUILT_IN_VSNPRINTF
: BUILT_IN_SNPRINTF
];
10719 return build_function_call_expr (fn
, arglist
);
10722 /* Fold a call to the {,v}printf{,_unlocked} and __{,v}printf_chk builtins.
10724 Return 0 if no simplification was possible, otherwise return the
10725 simplified form of the call as a tree. FCODE is the BUILT_IN_*
10726 code of the function to be simplified. */
10729 fold_builtin_printf (tree fndecl
, tree arglist
, bool ignore
,
10730 enum built_in_function fcode
)
10732 tree fmt
, fn
= NULL_TREE
, fn_putchar
, fn_puts
, arg
, call
;
10733 const char *fmt_str
= NULL
;
10735 /* If the return value is used, don't do the transformation. */
10739 /* Verify the required arguments in the original call. */
10740 if (fcode
== BUILT_IN_PRINTF_CHK
|| fcode
== BUILT_IN_VPRINTF_CHK
)
10746 flag
= TREE_VALUE (arglist
);
10747 if (TREE_CODE (TREE_TYPE (flag
)) != INTEGER_TYPE
10748 || TREE_SIDE_EFFECTS (flag
))
10750 arglist
= TREE_CHAIN (arglist
);
10755 fmt
= TREE_VALUE (arglist
);
10756 if (! POINTER_TYPE_P (TREE_TYPE (fmt
)))
10758 arglist
= TREE_CHAIN (arglist
);
10760 /* Check whether the format is a literal string constant. */
10761 fmt_str
= c_getstr (fmt
);
10762 if (fmt_str
== NULL
)
10765 if (fcode
== BUILT_IN_PRINTF_UNLOCKED
)
10767 fn_putchar
= implicit_built_in_decls
[BUILT_IN_PUTCHAR_UNLOCKED
];
10768 fn_puts
= implicit_built_in_decls
[BUILT_IN_PUTS_UNLOCKED
];
10772 fn_putchar
= implicit_built_in_decls
[BUILT_IN_PUTCHAR
];
10773 fn_puts
= implicit_built_in_decls
[BUILT_IN_PUTS
];
10776 if (strcmp (fmt_str
, "%s") == 0 || strchr (fmt_str
, '%') == NULL
)
10780 if (strcmp (fmt_str
, "%s") == 0)
10782 if (fcode
== BUILT_IN_VPRINTF
|| fcode
== BUILT_IN_VPRINTF_CHK
)
10786 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist
)))
10787 || TREE_CHAIN (arglist
))
10790 str
= c_getstr (TREE_VALUE (arglist
));
10796 /* The format specifier doesn't contain any '%' characters. */
10797 if (fcode
!= BUILT_IN_VPRINTF
&& fcode
!= BUILT_IN_VPRINTF_CHK
10803 /* If the string was "", printf does nothing. */
10804 if (str
[0] == '\0')
10805 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl
)), 0);
10807 /* If the string has length of 1, call putchar. */
10808 if (str
[1] == '\0')
10810 /* Given printf("c"), (where c is any one character,)
10811 convert "c"[0] to an int and pass that to the replacement
10813 arg
= build_int_cst (NULL_TREE
, str
[0]);
10814 arglist
= build_tree_list (NULL_TREE
, arg
);
10819 /* If the string was "string\n", call puts("string"). */
10820 size_t len
= strlen (str
);
10821 if (str
[len
- 1] == '\n')
10823 /* Create a NUL-terminated string that's one char shorter
10824 than the original, stripping off the trailing '\n'. */
10825 char *newstr
= alloca (len
);
10826 memcpy (newstr
, str
, len
- 1);
10827 newstr
[len
- 1] = 0;
10829 arg
= build_string_literal (len
, newstr
);
10830 arglist
= build_tree_list (NULL_TREE
, arg
);
10834 /* We'd like to arrange to call fputs(string,stdout) here,
10835 but we need stdout and don't have a way to get it yet. */
10840 /* The other optimizations can be done only on the non-va_list variants. */
10841 else if (fcode
== BUILT_IN_VPRINTF
|| fcode
== BUILT_IN_VPRINTF_CHK
)
10844 /* If the format specifier was "%s\n", call __builtin_puts(arg). */
10845 else if (strcmp (fmt_str
, "%s\n") == 0)
10848 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist
)))
10849 || TREE_CHAIN (arglist
))
10854 /* If the format specifier was "%c", call __builtin_putchar(arg). */
10855 else if (strcmp (fmt_str
, "%c") == 0)
10858 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist
))) != INTEGER_TYPE
10859 || TREE_CHAIN (arglist
))
10867 call
= build_function_call_expr (fn
, arglist
);
10868 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl
)), call
);
10871 /* Fold a call to the {,v}fprintf{,_unlocked} and __{,v}printf_chk builtins.
10873 Return 0 if no simplification was possible, otherwise return the
10874 simplified form of the call as a tree. FCODE is the BUILT_IN_*
10875 code of the function to be simplified. */
10878 fold_builtin_fprintf (tree fndecl
, tree arglist
, bool ignore
,
10879 enum built_in_function fcode
)
10881 tree fp
, fmt
, fn
= NULL_TREE
, fn_fputc
, fn_fputs
, arg
, call
;
10882 const char *fmt_str
= NULL
;
10884 /* If the return value is used, don't do the transformation. */
10888 /* Verify the required arguments in the original call. */
10891 fp
= TREE_VALUE (arglist
);
10892 if (! POINTER_TYPE_P (TREE_TYPE (fp
)))
10894 arglist
= TREE_CHAIN (arglist
);
10896 if (fcode
== BUILT_IN_FPRINTF_CHK
|| fcode
== BUILT_IN_VFPRINTF_CHK
)
10902 flag
= TREE_VALUE (arglist
);
10903 if (TREE_CODE (TREE_TYPE (flag
)) != INTEGER_TYPE
10904 || TREE_SIDE_EFFECTS (flag
))
10906 arglist
= TREE_CHAIN (arglist
);
10911 fmt
= TREE_VALUE (arglist
);
10912 if (! POINTER_TYPE_P (TREE_TYPE (fmt
)))
10914 arglist
= TREE_CHAIN (arglist
);
10916 /* Check whether the format is a literal string constant. */
10917 fmt_str
= c_getstr (fmt
);
10918 if (fmt_str
== NULL
)
10921 if (fcode
== BUILT_IN_FPRINTF_UNLOCKED
)
10923 fn_fputc
= implicit_built_in_decls
[BUILT_IN_FPUTC_UNLOCKED
];
10924 fn_fputs
= implicit_built_in_decls
[BUILT_IN_FPUTS_UNLOCKED
];
10928 fn_fputc
= implicit_built_in_decls
[BUILT_IN_FPUTC
];
10929 fn_fputs
= implicit_built_in_decls
[BUILT_IN_FPUTS
];
10932 /* If the format doesn't contain % args or %%, use strcpy. */
10933 if (strchr (fmt_str
, '%') == NULL
)
10935 if (fcode
!= BUILT_IN_VFPRINTF
&& fcode
!= BUILT_IN_VFPRINTF_CHK
10939 /* If the format specifier was "", fprintf does nothing. */
10940 if (fmt_str
[0] == '\0')
10942 /* If FP has side-effects, just wait until gimplification is
10944 if (TREE_SIDE_EFFECTS (fp
))
10947 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl
)), 0);
10950 /* When "string" doesn't contain %, replace all cases of
10951 fprintf (fp, string) with fputs (string, fp). The fputs
10952 builtin will take care of special cases like length == 1. */
10953 arglist
= build_tree_list (NULL_TREE
, fp
);
10954 arglist
= tree_cons (NULL_TREE
, fmt
, arglist
);
10958 /* The other optimizations can be done only on the non-va_list variants. */
10959 else if (fcode
== BUILT_IN_VFPRINTF
|| fcode
== BUILT_IN_VFPRINTF_CHK
)
10962 /* If the format specifier was "%s", call __builtin_fputs (arg, fp). */
10963 else if (strcmp (fmt_str
, "%s") == 0)
10966 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist
)))
10967 || TREE_CHAIN (arglist
))
10969 arg
= TREE_VALUE (arglist
);
10970 arglist
= build_tree_list (NULL_TREE
, fp
);
10971 arglist
= tree_cons (NULL_TREE
, arg
, arglist
);
10975 /* If the format specifier was "%c", call __builtin_fputc (arg, fp). */
10976 else if (strcmp (fmt_str
, "%c") == 0)
10979 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist
))) != INTEGER_TYPE
10980 || TREE_CHAIN (arglist
))
10982 arg
= TREE_VALUE (arglist
);
10983 arglist
= build_tree_list (NULL_TREE
, fp
);
10984 arglist
= tree_cons (NULL_TREE
, arg
, arglist
);
10991 call
= build_function_call_expr (fn
, arglist
);
10992 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl
)), call
);