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 tree
build_string_literal (int, const char *);
80 static int apply_args_size (void);
81 static int apply_result_size (void);
82 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
83 static rtx
result_vector (int, rtx
);
85 static rtx
expand_builtin_setjmp (tree
, rtx
);
86 static void expand_builtin_update_setjmp_buf (rtx
);
87 static void expand_builtin_prefetch (tree
);
88 static rtx
expand_builtin_apply_args (void);
89 static rtx
expand_builtin_apply_args_1 (void);
90 static rtx
expand_builtin_apply (rtx
, rtx
, rtx
);
91 static void expand_builtin_return (rtx
);
92 static enum type_class
type_to_class (tree
);
93 static rtx
expand_builtin_classify_type (tree
);
94 static void expand_errno_check (tree
, rtx
);
95 static rtx
expand_builtin_mathfn (tree
, rtx
, rtx
);
96 static rtx
expand_builtin_mathfn_2 (tree
, rtx
, rtx
);
97 static rtx
expand_builtin_mathfn_3 (tree
, rtx
, rtx
);
98 static rtx
expand_builtin_int_roundingfn (tree
, rtx
, rtx
);
99 static rtx
expand_builtin_args_info (tree
);
100 static rtx
expand_builtin_next_arg (void);
101 static rtx
expand_builtin_va_start (tree
);
102 static rtx
expand_builtin_va_end (tree
);
103 static rtx
expand_builtin_va_copy (tree
);
104 static rtx
expand_builtin_memcmp (tree
, tree
, rtx
, enum machine_mode
);
105 static rtx
expand_builtin_strcmp (tree
, rtx
, enum machine_mode
);
106 static rtx
expand_builtin_strncmp (tree
, rtx
, enum machine_mode
);
107 static rtx
builtin_memcpy_read_str (void *, HOST_WIDE_INT
, enum machine_mode
);
108 static rtx
expand_builtin_strcat (tree
, tree
, rtx
, enum machine_mode
);
109 static rtx
expand_builtin_strncat (tree
, rtx
, enum machine_mode
);
110 static rtx
expand_builtin_strspn (tree
, rtx
, enum machine_mode
);
111 static rtx
expand_builtin_strcspn (tree
, rtx
, enum machine_mode
);
112 static rtx
expand_builtin_memcpy (tree
, rtx
, enum machine_mode
);
113 static rtx
expand_builtin_mempcpy (tree
, tree
, rtx
, enum machine_mode
, int);
114 static rtx
expand_builtin_memmove (tree
, tree
, rtx
, enum machine_mode
, tree
);
115 static rtx
expand_builtin_bcopy (tree
);
116 static rtx
expand_builtin_strcpy (tree
, tree
, rtx
, enum machine_mode
);
117 static rtx
expand_builtin_stpcpy (tree
, rtx
, enum machine_mode
);
118 static rtx
builtin_strncpy_read_str (void *, HOST_WIDE_INT
, enum machine_mode
);
119 static rtx
expand_builtin_strncpy (tree
, rtx
, enum machine_mode
);
120 static rtx
builtin_memset_read_str (void *, HOST_WIDE_INT
, enum machine_mode
);
121 static rtx
builtin_memset_gen_str (void *, HOST_WIDE_INT
, enum machine_mode
);
122 static rtx
expand_builtin_memset (tree
, rtx
, enum machine_mode
, tree
);
123 static rtx
expand_builtin_bzero (tree
);
124 static rtx
expand_builtin_strlen (tree
, rtx
, enum machine_mode
);
125 static rtx
expand_builtin_strstr (tree
, tree
, rtx
, enum machine_mode
);
126 static rtx
expand_builtin_strpbrk (tree
, tree
, rtx
, enum machine_mode
);
127 static rtx
expand_builtin_strchr (tree
, tree
, rtx
, enum machine_mode
);
128 static rtx
expand_builtin_strrchr (tree
, tree
, rtx
, enum machine_mode
);
129 static rtx
expand_builtin_alloca (tree
, rtx
);
130 static rtx
expand_builtin_unop (enum machine_mode
, tree
, rtx
, rtx
, optab
);
131 static rtx
expand_builtin_frame_address (tree
, tree
);
132 static rtx
expand_builtin_fputs (tree
, rtx
, bool);
133 static rtx
expand_builtin_printf (tree
, rtx
, enum machine_mode
, bool);
134 static rtx
expand_builtin_fprintf (tree
, rtx
, enum machine_mode
, bool);
135 static rtx
expand_builtin_sprintf (tree
, rtx
, enum machine_mode
);
136 static tree
stabilize_va_list (tree
, int);
137 static rtx
expand_builtin_expect (tree
, rtx
);
138 static tree
fold_builtin_constant_p (tree
);
139 static tree
fold_builtin_classify_type (tree
);
140 static tree
fold_builtin_strlen (tree
);
141 static tree
fold_builtin_inf (tree
, int);
142 static tree
fold_builtin_nan (tree
, tree
, int);
143 static int validate_arglist (tree
, ...);
144 static bool integer_valued_real_p (tree
);
145 static tree
fold_trunc_transparent_mathfn (tree
, tree
);
146 static bool readonly_data_expr (tree
);
147 static rtx
expand_builtin_fabs (tree
, rtx
, rtx
);
148 static rtx
expand_builtin_signbit (tree
, rtx
);
149 static tree
fold_builtin_cabs (tree
, tree
);
150 static tree
fold_builtin_sqrt (tree
, tree
);
151 static tree
fold_builtin_cbrt (tree
, tree
);
152 static tree
fold_builtin_pow (tree
, tree
, tree
);
153 static tree
fold_builtin_powi (tree
, tree
, tree
);
154 static tree
fold_builtin_sin (tree
);
155 static tree
fold_builtin_cos (tree
, tree
, tree
);
156 static tree
fold_builtin_tan (tree
);
157 static tree
fold_builtin_atan (tree
, tree
);
158 static tree
fold_builtin_trunc (tree
, tree
);
159 static tree
fold_builtin_floor (tree
, tree
);
160 static tree
fold_builtin_ceil (tree
, tree
);
161 static tree
fold_builtin_round (tree
, tree
);
162 static tree
fold_builtin_int_roundingfn (tree
, tree
);
163 static tree
fold_builtin_bitop (tree
, tree
);
164 static tree
fold_builtin_memcpy (tree
, tree
);
165 static tree
fold_builtin_mempcpy (tree
, tree
, int);
166 static tree
fold_builtin_memmove (tree
, tree
);
167 static tree
fold_builtin_strchr (tree
, tree
);
168 static tree
fold_builtin_memcmp (tree
);
169 static tree
fold_builtin_strcmp (tree
);
170 static tree
fold_builtin_strncmp (tree
);
171 static tree
fold_builtin_signbit (tree
, tree
);
172 static tree
fold_builtin_copysign (tree
, tree
, tree
);
173 static tree
fold_builtin_isascii (tree
);
174 static tree
fold_builtin_toascii (tree
);
175 static tree
fold_builtin_isdigit (tree
);
176 static tree
fold_builtin_fabs (tree
, tree
);
177 static tree
fold_builtin_abs (tree
, tree
);
178 static tree
fold_builtin_unordered_cmp (tree
, tree
, enum tree_code
,
180 static tree
fold_builtin_1 (tree
, tree
, bool);
182 static tree
fold_builtin_strpbrk (tree
, tree
);
183 static tree
fold_builtin_strstr (tree
, tree
);
184 static tree
fold_builtin_strrchr (tree
, tree
);
185 static tree
fold_builtin_strcat (tree
);
186 static tree
fold_builtin_strncat (tree
);
187 static tree
fold_builtin_strspn (tree
);
188 static tree
fold_builtin_strcspn (tree
);
189 static tree
fold_builtin_sprintf (tree
, int);
191 static rtx
expand_builtin_object_size (tree
);
192 static rtx
expand_builtin_memory_chk (tree
, rtx
, enum machine_mode
,
193 enum built_in_function
);
194 static void maybe_emit_chk_warning (tree
, enum built_in_function
);
195 static void maybe_emit_sprintf_chk_warning (tree
, enum built_in_function
);
196 static tree
fold_builtin_object_size (tree
);
197 static tree
fold_builtin_strcat_chk (tree
, tree
);
198 static tree
fold_builtin_strncat_chk (tree
, tree
);
199 static tree
fold_builtin_sprintf_chk (tree
, enum built_in_function
);
200 static tree
fold_builtin_printf (tree
, tree
, bool, enum built_in_function
);
201 static tree
fold_builtin_fprintf (tree
, tree
, bool, enum built_in_function
);
203 /* Return true if NODE should be considered for inline expansion regardless
204 of the optimization level. This means whenever a function is invoked with
205 its "internal" name, which normally contains the prefix "__builtin". */
207 static bool called_as_built_in (tree node
)
209 const char *name
= IDENTIFIER_POINTER (DECL_NAME (node
));
210 if (strncmp (name
, "__builtin_", 10) == 0)
212 if (strncmp (name
, "__sync_", 7) == 0)
217 /* Return the alignment in bits of EXP, a pointer valued expression.
218 But don't return more than MAX_ALIGN no matter what.
219 The alignment returned is, by default, the alignment of the thing that
220 EXP points to. If it is not a POINTER_TYPE, 0 is returned.
222 Otherwise, look at the expression to see if we can do better, i.e., if the
223 expression is actually pointing at an object whose alignment is tighter. */
226 get_pointer_alignment (tree exp
, unsigned int max_align
)
228 unsigned int align
, inner
;
230 if (! POINTER_TYPE_P (TREE_TYPE (exp
)))
233 align
= TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp
)));
234 align
= MIN (align
, max_align
);
238 switch (TREE_CODE (exp
))
242 case NON_LVALUE_EXPR
:
243 exp
= TREE_OPERAND (exp
, 0);
244 if (! POINTER_TYPE_P (TREE_TYPE (exp
)))
247 inner
= TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp
)));
248 align
= MIN (inner
, max_align
);
252 /* If sum of pointer + int, restrict our maximum alignment to that
253 imposed by the integer. If not, we can't do any better than
255 if (! host_integerp (TREE_OPERAND (exp
, 1), 1))
258 while (((tree_low_cst (TREE_OPERAND (exp
, 1), 1))
259 & (max_align
/ BITS_PER_UNIT
- 1))
263 exp
= TREE_OPERAND (exp
, 0);
267 /* See what we are pointing at and look at its alignment. */
268 exp
= TREE_OPERAND (exp
, 0);
269 if (TREE_CODE (exp
) == FUNCTION_DECL
)
270 align
= FUNCTION_BOUNDARY
;
271 else if (DECL_P (exp
))
272 align
= DECL_ALIGN (exp
);
273 #ifdef CONSTANT_ALIGNMENT
274 else if (CONSTANT_CLASS_P (exp
))
275 align
= CONSTANT_ALIGNMENT (exp
, align
);
277 return MIN (align
, max_align
);
285 /* Compute the length of a C string. TREE_STRING_LENGTH is not the right
286 way, because it could contain a zero byte in the middle.
287 TREE_STRING_LENGTH is the size of the character array, not the string.
289 ONLY_VALUE should be nonzero if the result is not going to be emitted
290 into the instruction stream and zero if it is going to be expanded.
291 E.g. with i++ ? "foo" : "bar", if ONLY_VALUE is nonzero, constant 3
292 is returned, otherwise NULL, since
293 len = c_strlen (src, 1); if (len) expand_expr (len, ...); would not
294 evaluate the side-effects.
296 The value returned is of type `ssizetype'.
298 Unfortunately, string_constant can't access the values of const char
299 arrays with initializers, so neither can we do so here. */
302 c_strlen (tree src
, int only_value
)
305 HOST_WIDE_INT offset
;
310 if (TREE_CODE (src
) == COND_EXPR
311 && (only_value
|| !TREE_SIDE_EFFECTS (TREE_OPERAND (src
, 0))))
315 len1
= c_strlen (TREE_OPERAND (src
, 1), only_value
);
316 len2
= c_strlen (TREE_OPERAND (src
, 2), only_value
);
317 if (tree_int_cst_equal (len1
, len2
))
321 if (TREE_CODE (src
) == COMPOUND_EXPR
322 && (only_value
|| !TREE_SIDE_EFFECTS (TREE_OPERAND (src
, 0))))
323 return c_strlen (TREE_OPERAND (src
, 1), only_value
);
325 src
= string_constant (src
, &offset_node
);
329 max
= TREE_STRING_LENGTH (src
) - 1;
330 ptr
= TREE_STRING_POINTER (src
);
332 if (offset_node
&& TREE_CODE (offset_node
) != INTEGER_CST
)
334 /* If the string has an internal zero byte (e.g., "foo\0bar"), we can't
335 compute the offset to the following null if we don't know where to
336 start searching for it. */
339 for (i
= 0; i
< max
; i
++)
343 /* We don't know the starting offset, but we do know that the string
344 has no internal zero bytes. We can assume that the offset falls
345 within the bounds of the string; otherwise, the programmer deserves
346 what he gets. Subtract the offset from the length of the string,
347 and return that. This would perhaps not be valid if we were dealing
348 with named arrays in addition to literal string constants. */
350 return size_diffop (size_int (max
), offset_node
);
353 /* We have a known offset into the string. Start searching there for
354 a null character if we can represent it as a single HOST_WIDE_INT. */
355 if (offset_node
== 0)
357 else if (! host_integerp (offset_node
, 0))
360 offset
= tree_low_cst (offset_node
, 0);
362 /* If the offset is known to be out of bounds, warn, and call strlen at
364 if (offset
< 0 || offset
> max
)
366 warning (0, "offset outside bounds of constant string");
370 /* Use strlen to search for the first zero byte. Since any strings
371 constructed with build_string will have nulls appended, we win even
372 if we get handed something like (char[4])"abcd".
374 Since OFFSET is our starting index into the string, no further
375 calculation is needed. */
376 return ssize_int (strlen (ptr
+ offset
));
379 /* Return a char pointer for a C string if it is a string constant
380 or sum of string constant and integer constant. */
387 src
= string_constant (src
, &offset_node
);
391 if (offset_node
== 0)
392 return TREE_STRING_POINTER (src
);
393 else if (!host_integerp (offset_node
, 1)
394 || compare_tree_int (offset_node
, TREE_STRING_LENGTH (src
) - 1) > 0)
397 return TREE_STRING_POINTER (src
) + tree_low_cst (offset_node
, 1);
400 /* Return a CONST_INT or CONST_DOUBLE corresponding to target reading
401 GET_MODE_BITSIZE (MODE) bits from string constant STR. */
404 c_readstr (const char *str
, enum machine_mode mode
)
410 gcc_assert (GET_MODE_CLASS (mode
) == MODE_INT
);
415 for (i
= 0; i
< GET_MODE_SIZE (mode
); i
++)
418 if (WORDS_BIG_ENDIAN
)
419 j
= GET_MODE_SIZE (mode
) - i
- 1;
420 if (BYTES_BIG_ENDIAN
!= WORDS_BIG_ENDIAN
421 && GET_MODE_SIZE (mode
) > UNITS_PER_WORD
)
422 j
= j
+ UNITS_PER_WORD
- 2 * (j
% UNITS_PER_WORD
) - 1;
424 gcc_assert (j
<= 2 * HOST_BITS_PER_WIDE_INT
);
427 ch
= (unsigned char) str
[i
];
428 c
[j
/ HOST_BITS_PER_WIDE_INT
] |= ch
<< (j
% HOST_BITS_PER_WIDE_INT
);
430 return immed_double_const (c
[0], c
[1], mode
);
433 /* Cast a target constant CST to target CHAR and if that value fits into
434 host char type, return zero and put that value into variable pointed to by
438 target_char_cast (tree cst
, char *p
)
440 unsigned HOST_WIDE_INT val
, hostval
;
442 if (!host_integerp (cst
, 1)
443 || CHAR_TYPE_SIZE
> HOST_BITS_PER_WIDE_INT
)
446 val
= tree_low_cst (cst
, 1);
447 if (CHAR_TYPE_SIZE
< HOST_BITS_PER_WIDE_INT
)
448 val
&= (((unsigned HOST_WIDE_INT
) 1) << CHAR_TYPE_SIZE
) - 1;
451 if (HOST_BITS_PER_CHAR
< HOST_BITS_PER_WIDE_INT
)
452 hostval
&= (((unsigned HOST_WIDE_INT
) 1) << HOST_BITS_PER_CHAR
) - 1;
461 /* Similar to save_expr, but assumes that arbitrary code is not executed
462 in between the multiple evaluations. In particular, we assume that a
463 non-addressable local variable will not be modified. */
466 builtin_save_expr (tree exp
)
468 if (TREE_ADDRESSABLE (exp
) == 0
469 && (TREE_CODE (exp
) == PARM_DECL
470 || (TREE_CODE (exp
) == VAR_DECL
&& !TREE_STATIC (exp
))))
473 return save_expr (exp
);
476 /* Given TEM, a pointer to a stack frame, follow the dynamic chain COUNT
477 times to get the address of either a higher stack frame, or a return
478 address located within it (depending on FNDECL_CODE). */
481 expand_builtin_return_addr (enum built_in_function fndecl_code
, int count
)
485 #ifdef INITIAL_FRAME_ADDRESS_RTX
486 rtx tem
= INITIAL_FRAME_ADDRESS_RTX
;
490 /* For a zero count, we don't care what frame address we return, so frame
491 pointer elimination is OK, and using the soft frame pointer is OK.
492 For a non-zero count, we require a stable offset from the current frame
493 pointer to the previous one, so we must use the hard frame pointer, and
494 we must disable frame pointer elimination. */
496 tem
= frame_pointer_rtx
;
499 tem
= hard_frame_pointer_rtx
;
501 /* Tell reload not to eliminate the frame pointer. */
502 current_function_accesses_prior_frames
= 1;
506 /* Some machines need special handling before we can access
507 arbitrary frames. For example, on the sparc, we must first flush
508 all register windows to the stack. */
509 #ifdef SETUP_FRAME_ADDRESSES
511 SETUP_FRAME_ADDRESSES ();
514 /* On the sparc, the return address is not in the frame, it is in a
515 register. There is no way to access it off of the current frame
516 pointer, but it can be accessed off the previous frame pointer by
517 reading the value from the register window save area. */
518 #ifdef RETURN_ADDR_IN_PREVIOUS_FRAME
519 if (fndecl_code
== BUILT_IN_RETURN_ADDRESS
)
523 /* Scan back COUNT frames to the specified frame. */
524 for (i
= 0; i
< count
; i
++)
526 /* Assume the dynamic chain pointer is in the word that the
527 frame address points to, unless otherwise specified. */
528 #ifdef DYNAMIC_CHAIN_ADDRESS
529 tem
= DYNAMIC_CHAIN_ADDRESS (tem
);
531 tem
= memory_address (Pmode
, tem
);
532 tem
= gen_frame_mem (Pmode
, tem
);
533 tem
= copy_to_reg (tem
);
536 /* For __builtin_frame_address, return what we've got. */
537 if (fndecl_code
== BUILT_IN_FRAME_ADDRESS
)
540 /* For __builtin_return_address, Get the return address from that
542 #ifdef RETURN_ADDR_RTX
543 tem
= RETURN_ADDR_RTX (count
, tem
);
545 tem
= memory_address (Pmode
,
546 plus_constant (tem
, GET_MODE_SIZE (Pmode
)));
547 tem
= gen_frame_mem (Pmode
, tem
);
552 /* Alias set used for setjmp buffer. */
553 static HOST_WIDE_INT setjmp_alias_set
= -1;
555 /* Construct the leading half of a __builtin_setjmp call. Control will
556 return to RECEIVER_LABEL. This is used directly by sjlj exception
560 expand_builtin_setjmp_setup (rtx buf_addr
, rtx receiver_label
)
562 enum machine_mode sa_mode
= STACK_SAVEAREA_MODE (SAVE_NONLOCAL
);
566 if (setjmp_alias_set
== -1)
567 setjmp_alias_set
= new_alias_set ();
569 buf_addr
= convert_memory_address (Pmode
, buf_addr
);
571 buf_addr
= force_reg (Pmode
, force_operand (buf_addr
, NULL_RTX
));
573 /* We store the frame pointer and the address of receiver_label in
574 the buffer and use the rest of it for the stack save area, which
575 is machine-dependent. */
577 mem
= gen_rtx_MEM (Pmode
, buf_addr
);
578 set_mem_alias_set (mem
, setjmp_alias_set
);
579 emit_move_insn (mem
, targetm
.builtin_setjmp_frame_value ());
581 mem
= gen_rtx_MEM (Pmode
, plus_constant (buf_addr
, GET_MODE_SIZE (Pmode
))),
582 set_mem_alias_set (mem
, setjmp_alias_set
);
584 emit_move_insn (validize_mem (mem
),
585 force_reg (Pmode
, gen_rtx_LABEL_REF (Pmode
, receiver_label
)));
587 stack_save
= gen_rtx_MEM (sa_mode
,
588 plus_constant (buf_addr
,
589 2 * GET_MODE_SIZE (Pmode
)));
590 set_mem_alias_set (stack_save
, setjmp_alias_set
);
591 emit_stack_save (SAVE_NONLOCAL
, &stack_save
, NULL_RTX
);
593 /* If there is further processing to do, do it. */
594 #ifdef HAVE_builtin_setjmp_setup
595 if (HAVE_builtin_setjmp_setup
)
596 emit_insn (gen_builtin_setjmp_setup (buf_addr
));
599 /* Tell optimize_save_area_alloca that extra work is going to
600 need to go on during alloca. */
601 current_function_calls_setjmp
= 1;
603 /* Set this so all the registers get saved in our frame; we need to be
604 able to copy the saved values for any registers from frames we unwind. */
605 current_function_has_nonlocal_label
= 1;
608 /* Construct the trailing part of a __builtin_setjmp call.
609 This is used directly by sjlj exception handling code. */
612 expand_builtin_setjmp_receiver (rtx receiver_label ATTRIBUTE_UNUSED
)
614 /* Clobber the FP when we get here, so we have to make sure it's
615 marked as used by this function. */
616 emit_insn (gen_rtx_USE (VOIDmode
, hard_frame_pointer_rtx
));
618 /* Mark the static chain as clobbered here so life information
619 doesn't get messed up for it. */
620 emit_insn (gen_rtx_CLOBBER (VOIDmode
, static_chain_rtx
));
622 /* Now put in the code to restore the frame pointer, and argument
623 pointer, if needed. */
624 #ifdef HAVE_nonlocal_goto
625 if (! HAVE_nonlocal_goto
)
627 emit_move_insn (virtual_stack_vars_rtx
, hard_frame_pointer_rtx
);
629 #if ARG_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
630 if (fixed_regs
[ARG_POINTER_REGNUM
])
632 #ifdef ELIMINABLE_REGS
634 static const struct elims
{const int from
, to
;} elim_regs
[] = ELIMINABLE_REGS
;
636 for (i
= 0; i
< ARRAY_SIZE (elim_regs
); i
++)
637 if (elim_regs
[i
].from
== ARG_POINTER_REGNUM
638 && elim_regs
[i
].to
== HARD_FRAME_POINTER_REGNUM
)
641 if (i
== ARRAY_SIZE (elim_regs
))
644 /* Now restore our arg pointer from the address at which it
645 was saved in our stack frame. */
646 emit_move_insn (virtual_incoming_args_rtx
,
647 copy_to_reg (get_arg_pointer_save_area (cfun
)));
652 #ifdef HAVE_builtin_setjmp_receiver
653 if (HAVE_builtin_setjmp_receiver
)
654 emit_insn (gen_builtin_setjmp_receiver (receiver_label
));
657 #ifdef HAVE_nonlocal_goto_receiver
658 if (HAVE_nonlocal_goto_receiver
)
659 emit_insn (gen_nonlocal_goto_receiver ());
664 /* @@@ This is a kludge. Not all machine descriptions define a blockage
665 insn, but we must not allow the code we just generated to be reordered
666 by scheduling. Specifically, the update of the frame pointer must
667 happen immediately, not later. So emit an ASM_INPUT to act as blockage
669 emit_insn (gen_rtx_ASM_INPUT (VOIDmode
, ""));
672 /* __builtin_setjmp is passed a pointer to an array of five words (not
673 all will be used on all machines). It operates similarly to the C
674 library function of the same name, but is more efficient. Much of
675 the code below (and for longjmp) is copied from the handling of
678 NOTE: This is intended for use by GNAT and the exception handling
679 scheme in the compiler and will only work in the method used by
683 expand_builtin_setjmp (tree arglist
, rtx target
)
685 rtx buf_addr
, next_lab
, cont_lab
;
687 if (!validate_arglist (arglist
, POINTER_TYPE
, VOID_TYPE
))
690 if (target
== 0 || !REG_P (target
)
691 || REGNO (target
) < FIRST_PSEUDO_REGISTER
)
692 target
= gen_reg_rtx (TYPE_MODE (integer_type_node
));
694 buf_addr
= expand_expr (TREE_VALUE (arglist
), NULL_RTX
, VOIDmode
, 0);
696 next_lab
= gen_label_rtx ();
697 cont_lab
= gen_label_rtx ();
699 expand_builtin_setjmp_setup (buf_addr
, next_lab
);
701 /* Set TARGET to zero and branch to the continue label. Use emit_jump to
702 ensure that pending stack adjustments are flushed. */
703 emit_move_insn (target
, const0_rtx
);
704 emit_jump (cont_lab
);
706 emit_label (next_lab
);
708 expand_builtin_setjmp_receiver (next_lab
);
710 /* Set TARGET to one. */
711 emit_move_insn (target
, const1_rtx
);
712 emit_label (cont_lab
);
714 /* Tell flow about the strange goings on. Putting `next_lab' on
715 `nonlocal_goto_handler_labels' to indicates that function
716 calls may traverse the arc back to this label. */
718 current_function_has_nonlocal_label
= 1;
719 nonlocal_goto_handler_labels
720 = gen_rtx_EXPR_LIST (VOIDmode
, next_lab
, nonlocal_goto_handler_labels
);
725 /* __builtin_longjmp is passed a pointer to an array of five words (not
726 all will be used on all machines). It operates similarly to the C
727 library function of the same name, but is more efficient. Much of
728 the code below is copied from the handling of non-local gotos.
730 NOTE: This is intended for use by GNAT and the exception handling
731 scheme in the compiler and will only work in the method used by
735 expand_builtin_longjmp (rtx buf_addr
, rtx value
)
737 rtx fp
, lab
, stack
, insn
, last
;
738 enum machine_mode sa_mode
= STACK_SAVEAREA_MODE (SAVE_NONLOCAL
);
740 if (setjmp_alias_set
== -1)
741 setjmp_alias_set
= new_alias_set ();
743 buf_addr
= convert_memory_address (Pmode
, buf_addr
);
745 buf_addr
= force_reg (Pmode
, buf_addr
);
747 /* We used to store value in static_chain_rtx, but that fails if pointers
748 are smaller than integers. We instead require that the user must pass
749 a second argument of 1, because that is what builtin_setjmp will
750 return. This also makes EH slightly more efficient, since we are no
751 longer copying around a value that we don't care about. */
752 gcc_assert (value
== const1_rtx
);
754 last
= get_last_insn ();
755 #ifdef HAVE_builtin_longjmp
756 if (HAVE_builtin_longjmp
)
757 emit_insn (gen_builtin_longjmp (buf_addr
));
761 fp
= gen_rtx_MEM (Pmode
, buf_addr
);
762 lab
= gen_rtx_MEM (Pmode
, plus_constant (buf_addr
,
763 GET_MODE_SIZE (Pmode
)));
765 stack
= gen_rtx_MEM (sa_mode
, plus_constant (buf_addr
,
766 2 * GET_MODE_SIZE (Pmode
)));
767 set_mem_alias_set (fp
, setjmp_alias_set
);
768 set_mem_alias_set (lab
, setjmp_alias_set
);
769 set_mem_alias_set (stack
, setjmp_alias_set
);
771 /* Pick up FP, label, and SP from the block and jump. This code is
772 from expand_goto in stmt.c; see there for detailed comments. */
773 #if HAVE_nonlocal_goto
774 if (HAVE_nonlocal_goto
)
775 /* We have to pass a value to the nonlocal_goto pattern that will
776 get copied into the static_chain pointer, but it does not matter
777 what that value is, because builtin_setjmp does not use it. */
778 emit_insn (gen_nonlocal_goto (value
, lab
, stack
, fp
));
782 lab
= copy_to_reg (lab
);
784 emit_insn (gen_rtx_CLOBBER (VOIDmode
,
785 gen_rtx_MEM (BLKmode
,
786 gen_rtx_SCRATCH (VOIDmode
))));
787 emit_insn (gen_rtx_CLOBBER (VOIDmode
,
788 gen_rtx_MEM (BLKmode
,
789 hard_frame_pointer_rtx
)));
791 emit_move_insn (hard_frame_pointer_rtx
, fp
);
792 emit_stack_restore (SAVE_NONLOCAL
, stack
, NULL_RTX
);
794 emit_insn (gen_rtx_USE (VOIDmode
, hard_frame_pointer_rtx
));
795 emit_insn (gen_rtx_USE (VOIDmode
, stack_pointer_rtx
));
796 emit_indirect_jump (lab
);
800 /* Search backwards and mark the jump insn as a non-local goto.
801 Note that this precludes the use of __builtin_longjmp to a
802 __builtin_setjmp target in the same function. However, we've
803 already cautioned the user that these functions are for
804 internal exception handling use only. */
805 for (insn
= get_last_insn (); insn
; insn
= PREV_INSN (insn
))
807 gcc_assert (insn
!= last
);
811 REG_NOTES (insn
) = alloc_EXPR_LIST (REG_NON_LOCAL_GOTO
, const0_rtx
,
815 else if (CALL_P (insn
))
820 /* Expand a call to __builtin_nonlocal_goto. We're passed the target label
821 and the address of the save area. */
824 expand_builtin_nonlocal_goto (tree arglist
)
826 tree t_label
, t_save_area
;
827 rtx r_label
, r_save_area
, r_fp
, r_sp
, insn
;
829 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
832 t_label
= TREE_VALUE (arglist
);
833 arglist
= TREE_CHAIN (arglist
);
834 t_save_area
= TREE_VALUE (arglist
);
836 r_label
= expand_expr (t_label
, NULL_RTX
, VOIDmode
, 0);
837 r_label
= convert_memory_address (Pmode
, r_label
);
838 r_save_area
= expand_expr (t_save_area
, NULL_RTX
, VOIDmode
, 0);
839 r_save_area
= convert_memory_address (Pmode
, r_save_area
);
840 r_fp
= gen_rtx_MEM (Pmode
, r_save_area
);
841 r_sp
= gen_rtx_MEM (STACK_SAVEAREA_MODE (SAVE_NONLOCAL
),
842 plus_constant (r_save_area
, GET_MODE_SIZE (Pmode
)));
844 current_function_has_nonlocal_goto
= 1;
846 #if HAVE_nonlocal_goto
847 /* ??? We no longer need to pass the static chain value, afaik. */
848 if (HAVE_nonlocal_goto
)
849 emit_insn (gen_nonlocal_goto (const0_rtx
, r_label
, r_sp
, r_fp
));
853 r_label
= copy_to_reg (r_label
);
855 emit_insn (gen_rtx_CLOBBER (VOIDmode
,
856 gen_rtx_MEM (BLKmode
,
857 gen_rtx_SCRATCH (VOIDmode
))));
859 emit_insn (gen_rtx_CLOBBER (VOIDmode
,
860 gen_rtx_MEM (BLKmode
,
861 hard_frame_pointer_rtx
)));
863 /* Restore frame pointer for containing function.
864 This sets the actual hard register used for the frame pointer
865 to the location of the function's incoming static chain info.
866 The non-local goto handler will then adjust it to contain the
867 proper value and reload the argument pointer, if needed. */
868 emit_move_insn (hard_frame_pointer_rtx
, r_fp
);
869 emit_stack_restore (SAVE_NONLOCAL
, r_sp
, NULL_RTX
);
871 /* USE of hard_frame_pointer_rtx added for consistency;
872 not clear if really needed. */
873 emit_insn (gen_rtx_USE (VOIDmode
, hard_frame_pointer_rtx
));
874 emit_insn (gen_rtx_USE (VOIDmode
, stack_pointer_rtx
));
875 emit_indirect_jump (r_label
);
878 /* Search backwards to the jump insn and mark it as a
880 for (insn
= get_last_insn (); insn
; insn
= PREV_INSN (insn
))
884 REG_NOTES (insn
) = alloc_EXPR_LIST (REG_NON_LOCAL_GOTO
,
885 const0_rtx
, REG_NOTES (insn
));
888 else if (CALL_P (insn
))
895 /* __builtin_update_setjmp_buf is passed a pointer to an array of five words
896 (not all will be used on all machines) that was passed to __builtin_setjmp.
897 It updates the stack pointer in that block to correspond to the current
901 expand_builtin_update_setjmp_buf (rtx buf_addr
)
903 enum machine_mode sa_mode
= Pmode
;
907 #ifdef HAVE_save_stack_nonlocal
908 if (HAVE_save_stack_nonlocal
)
909 sa_mode
= insn_data
[(int) CODE_FOR_save_stack_nonlocal
].operand
[0].mode
;
911 #ifdef STACK_SAVEAREA_MODE
912 sa_mode
= STACK_SAVEAREA_MODE (SAVE_NONLOCAL
);
916 = gen_rtx_MEM (sa_mode
,
919 plus_constant (buf_addr
, 2 * GET_MODE_SIZE (Pmode
))));
923 emit_insn (gen_setjmp ());
926 emit_stack_save (SAVE_NONLOCAL
, &stack_save
, NULL_RTX
);
929 /* Expand a call to __builtin_prefetch. For a target that does not support
930 data prefetch, evaluate the memory address argument in case it has side
934 expand_builtin_prefetch (tree arglist
)
936 tree arg0
, arg1
, arg2
;
939 if (!validate_arglist (arglist
, POINTER_TYPE
, 0))
942 arg0
= TREE_VALUE (arglist
);
943 /* Arguments 1 and 2 are optional; argument 1 (read/write) defaults to
944 zero (read) and argument 2 (locality) defaults to 3 (high degree of
946 if (TREE_CHAIN (arglist
))
948 arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
949 if (TREE_CHAIN (TREE_CHAIN (arglist
)))
950 arg2
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
952 arg2
= build_int_cst (NULL_TREE
, 3);
956 arg1
= integer_zero_node
;
957 arg2
= build_int_cst (NULL_TREE
, 3);
960 /* Argument 0 is an address. */
961 op0
= expand_expr (arg0
, NULL_RTX
, Pmode
, EXPAND_NORMAL
);
963 /* Argument 1 (read/write flag) must be a compile-time constant int. */
964 if (TREE_CODE (arg1
) != INTEGER_CST
)
966 error ("second argument to %<__builtin_prefetch%> must be a constant");
967 arg1
= integer_zero_node
;
969 op1
= expand_expr (arg1
, NULL_RTX
, VOIDmode
, 0);
970 /* Argument 1 must be either zero or one. */
971 if (INTVAL (op1
) != 0 && INTVAL (op1
) != 1)
973 warning (0, "invalid second argument to %<__builtin_prefetch%>;"
978 /* Argument 2 (locality) must be a compile-time constant int. */
979 if (TREE_CODE (arg2
) != INTEGER_CST
)
981 error ("third argument to %<__builtin_prefetch%> must be a constant");
982 arg2
= integer_zero_node
;
984 op2
= expand_expr (arg2
, NULL_RTX
, VOIDmode
, 0);
985 /* Argument 2 must be 0, 1, 2, or 3. */
986 if (INTVAL (op2
) < 0 || INTVAL (op2
) > 3)
988 warning (0, "invalid third argument to %<__builtin_prefetch%>; using zero");
995 if ((! (*insn_data
[(int) CODE_FOR_prefetch
].operand
[0].predicate
)
997 insn_data
[(int) CODE_FOR_prefetch
].operand
[0].mode
))
998 || (GET_MODE (op0
) != Pmode
))
1000 op0
= convert_memory_address (Pmode
, op0
);
1001 op0
= force_reg (Pmode
, op0
);
1003 emit_insn (gen_prefetch (op0
, op1
, op2
));
1007 /* Don't do anything with direct references to volatile memory, but
1008 generate code to handle other side effects. */
1009 if (!MEM_P (op0
) && side_effects_p (op0
))
1013 /* Get a MEM rtx for expression EXP which is the address of an operand
1014 to be used in a string instruction (cmpstrsi, movmemsi, ..). LEN is
1015 the maximum length of the block of memory that might be accessed or
1019 get_memory_rtx (tree exp
, tree len
)
1021 rtx addr
= expand_expr (exp
, NULL_RTX
, ptr_mode
, EXPAND_NORMAL
);
1022 rtx mem
= gen_rtx_MEM (BLKmode
, memory_address (BLKmode
, addr
));
1024 /* Get an expression we can use to find the attributes to assign to MEM.
1025 If it is an ADDR_EXPR, use the operand. Otherwise, dereference it if
1026 we can. First remove any nops. */
1027 while ((TREE_CODE (exp
) == NOP_EXPR
|| TREE_CODE (exp
) == CONVERT_EXPR
1028 || TREE_CODE (exp
) == NON_LVALUE_EXPR
)
1029 && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (exp
, 0))))
1030 exp
= TREE_OPERAND (exp
, 0);
1032 if (TREE_CODE (exp
) == ADDR_EXPR
)
1033 exp
= TREE_OPERAND (exp
, 0);
1034 else if (POINTER_TYPE_P (TREE_TYPE (exp
)))
1035 exp
= build1 (INDIRECT_REF
, TREE_TYPE (TREE_TYPE (exp
)), exp
);
1039 /* Honor attributes derived from exp, except for the alias set
1040 (as builtin stringops may alias with anything) and the size
1041 (as stringops may access multiple array elements). */
1044 set_mem_attributes (mem
, exp
, 0);
1046 /* Allow the string and memory builtins to overflow from one
1047 field into another, see http://gcc.gnu.org/PR23561.
1048 Thus avoid COMPONENT_REFs in MEM_EXPR unless we know the whole
1049 memory accessed by the string or memory builtin will fit
1050 within the field. */
1051 if (MEM_EXPR (mem
) && TREE_CODE (MEM_EXPR (mem
)) == COMPONENT_REF
)
1053 tree mem_expr
= MEM_EXPR (mem
);
1054 HOST_WIDE_INT offset
= -1, length
= -1;
1057 while (TREE_CODE (inner
) == ARRAY_REF
1058 || TREE_CODE (inner
) == NOP_EXPR
1059 || TREE_CODE (inner
) == CONVERT_EXPR
1060 || TREE_CODE (inner
) == NON_LVALUE_EXPR
1061 || TREE_CODE (inner
) == VIEW_CONVERT_EXPR
1062 || TREE_CODE (inner
) == SAVE_EXPR
)
1063 inner
= TREE_OPERAND (inner
, 0);
1065 gcc_assert (TREE_CODE (inner
) == COMPONENT_REF
);
1067 if (MEM_OFFSET (mem
)
1068 && GET_CODE (MEM_OFFSET (mem
)) == CONST_INT
)
1069 offset
= INTVAL (MEM_OFFSET (mem
));
1071 if (offset
>= 0 && len
&& host_integerp (len
, 0))
1072 length
= tree_low_cst (len
, 0);
1074 while (TREE_CODE (inner
) == COMPONENT_REF
)
1076 tree field
= TREE_OPERAND (inner
, 1);
1077 gcc_assert (! DECL_BIT_FIELD (field
));
1078 gcc_assert (TREE_CODE (mem_expr
) == COMPONENT_REF
);
1079 gcc_assert (field
== TREE_OPERAND (mem_expr
, 1));
1082 && TYPE_SIZE_UNIT (TREE_TYPE (inner
))
1083 && host_integerp (TYPE_SIZE_UNIT (TREE_TYPE (inner
)), 0))
1086 = tree_low_cst (TYPE_SIZE_UNIT (TREE_TYPE (inner
)), 0);
1087 /* If we can prove the memory starting at XEXP (mem, 0)
1088 and ending at XEXP (mem, 0) + LENGTH will fit into
1089 this field, we can keep that COMPONENT_REF in MEM_EXPR. */
1092 && offset
+ length
<= size
)
1097 && host_integerp (DECL_FIELD_OFFSET (field
), 0))
1098 offset
+= tree_low_cst (DECL_FIELD_OFFSET (field
), 0)
1099 + tree_low_cst (DECL_FIELD_BIT_OFFSET (field
), 1)
1107 mem_expr
= TREE_OPERAND (mem_expr
, 0);
1108 inner
= TREE_OPERAND (inner
, 0);
1111 if (mem_expr
== NULL
)
1113 if (mem_expr
!= MEM_EXPR (mem
))
1115 set_mem_expr (mem
, mem_expr
);
1116 set_mem_offset (mem
, offset
>= 0 ? GEN_INT (offset
) : NULL_RTX
);
1119 set_mem_alias_set (mem
, 0);
1120 set_mem_size (mem
, NULL_RTX
);
1126 /* Built-in functions to perform an untyped call and return. */
1128 /* For each register that may be used for calling a function, this
1129 gives a mode used to copy the register's value. VOIDmode indicates
1130 the register is not used for calling a function. If the machine
1131 has register windows, this gives only the outbound registers.
1132 INCOMING_REGNO gives the corresponding inbound register. */
1133 static enum machine_mode apply_args_mode
[FIRST_PSEUDO_REGISTER
];
1135 /* For each register that may be used for returning values, this gives
1136 a mode used to copy the register's value. VOIDmode indicates the
1137 register is not used for returning values. If the machine has
1138 register windows, this gives only the outbound registers.
1139 INCOMING_REGNO gives the corresponding inbound register. */
1140 static enum machine_mode apply_result_mode
[FIRST_PSEUDO_REGISTER
];
1142 /* For each register that may be used for calling a function, this
1143 gives the offset of that register into the block returned by
1144 __builtin_apply_args. 0 indicates that the register is not
1145 used for calling a function. */
1146 static int apply_args_reg_offset
[FIRST_PSEUDO_REGISTER
];
1148 /* Return the size required for the block returned by __builtin_apply_args,
1149 and initialize apply_args_mode. */
1152 apply_args_size (void)
1154 static int size
= -1;
1157 enum machine_mode mode
;
1159 /* The values computed by this function never change. */
1162 /* The first value is the incoming arg-pointer. */
1163 size
= GET_MODE_SIZE (Pmode
);
1165 /* The second value is the structure value address unless this is
1166 passed as an "invisible" first argument. */
1167 if (targetm
.calls
.struct_value_rtx (cfun
? TREE_TYPE (cfun
->decl
) : 0, 0))
1168 size
+= GET_MODE_SIZE (Pmode
);
1170 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
1171 if (FUNCTION_ARG_REGNO_P (regno
))
1173 mode
= reg_raw_mode
[regno
];
1175 gcc_assert (mode
!= VOIDmode
);
1177 align
= GET_MODE_ALIGNMENT (mode
) / BITS_PER_UNIT
;
1178 if (size
% align
!= 0)
1179 size
= CEIL (size
, align
) * align
;
1180 apply_args_reg_offset
[regno
] = size
;
1181 size
+= GET_MODE_SIZE (mode
);
1182 apply_args_mode
[regno
] = mode
;
1186 apply_args_mode
[regno
] = VOIDmode
;
1187 apply_args_reg_offset
[regno
] = 0;
1193 /* Return the size required for the block returned by __builtin_apply,
1194 and initialize apply_result_mode. */
1197 apply_result_size (void)
1199 static int size
= -1;
1201 enum machine_mode mode
;
1203 /* The values computed by this function never change. */
1208 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
1209 if (FUNCTION_VALUE_REGNO_P (regno
))
1211 mode
= reg_raw_mode
[regno
];
1213 gcc_assert (mode
!= VOIDmode
);
1215 align
= GET_MODE_ALIGNMENT (mode
) / BITS_PER_UNIT
;
1216 if (size
% align
!= 0)
1217 size
= CEIL (size
, align
) * align
;
1218 size
+= GET_MODE_SIZE (mode
);
1219 apply_result_mode
[regno
] = mode
;
1222 apply_result_mode
[regno
] = VOIDmode
;
1224 /* Allow targets that use untyped_call and untyped_return to override
1225 the size so that machine-specific information can be stored here. */
1226 #ifdef APPLY_RESULT_SIZE
1227 size
= APPLY_RESULT_SIZE
;
1233 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
1234 /* Create a vector describing the result block RESULT. If SAVEP is true,
1235 the result block is used to save the values; otherwise it is used to
1236 restore the values. */
1239 result_vector (int savep
, rtx result
)
1241 int regno
, size
, align
, nelts
;
1242 enum machine_mode mode
;
1244 rtx
*savevec
= alloca (FIRST_PSEUDO_REGISTER
* sizeof (rtx
));
1247 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
1248 if ((mode
= apply_result_mode
[regno
]) != VOIDmode
)
1250 align
= GET_MODE_ALIGNMENT (mode
) / BITS_PER_UNIT
;
1251 if (size
% align
!= 0)
1252 size
= CEIL (size
, align
) * align
;
1253 reg
= gen_rtx_REG (mode
, savep
? regno
: INCOMING_REGNO (regno
));
1254 mem
= adjust_address (result
, mode
, size
);
1255 savevec
[nelts
++] = (savep
1256 ? gen_rtx_SET (VOIDmode
, mem
, reg
)
1257 : gen_rtx_SET (VOIDmode
, reg
, mem
));
1258 size
+= GET_MODE_SIZE (mode
);
1260 return gen_rtx_PARALLEL (VOIDmode
, gen_rtvec_v (nelts
, savevec
));
1262 #endif /* HAVE_untyped_call or HAVE_untyped_return */
1264 /* Save the state required to perform an untyped call with the same
1265 arguments as were passed to the current function. */
1268 expand_builtin_apply_args_1 (void)
1271 int size
, align
, regno
;
1272 enum machine_mode mode
;
1273 rtx struct_incoming_value
= targetm
.calls
.struct_value_rtx (cfun
? TREE_TYPE (cfun
->decl
) : 0, 1);
1275 /* Create a block where the arg-pointer, structure value address,
1276 and argument registers can be saved. */
1277 registers
= assign_stack_local (BLKmode
, apply_args_size (), -1);
1279 /* Walk past the arg-pointer and structure value address. */
1280 size
= GET_MODE_SIZE (Pmode
);
1281 if (targetm
.calls
.struct_value_rtx (cfun
? TREE_TYPE (cfun
->decl
) : 0, 0))
1282 size
+= GET_MODE_SIZE (Pmode
);
1284 /* Save each register used in calling a function to the block. */
1285 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
1286 if ((mode
= apply_args_mode
[regno
]) != VOIDmode
)
1288 align
= GET_MODE_ALIGNMENT (mode
) / BITS_PER_UNIT
;
1289 if (size
% align
!= 0)
1290 size
= CEIL (size
, align
) * align
;
1292 tem
= gen_rtx_REG (mode
, INCOMING_REGNO (regno
));
1294 emit_move_insn (adjust_address (registers
, mode
, size
), tem
);
1295 size
+= GET_MODE_SIZE (mode
);
1298 /* Save the arg pointer to the block. */
1299 tem
= copy_to_reg (virtual_incoming_args_rtx
);
1300 #ifdef STACK_GROWS_DOWNWARD
1301 /* We need the pointer as the caller actually passed them to us, not
1302 as we might have pretended they were passed. Make sure it's a valid
1303 operand, as emit_move_insn isn't expected to handle a PLUS. */
1305 = force_operand (plus_constant (tem
, current_function_pretend_args_size
),
1308 emit_move_insn (adjust_address (registers
, Pmode
, 0), tem
);
1310 size
= GET_MODE_SIZE (Pmode
);
1312 /* Save the structure value address unless this is passed as an
1313 "invisible" first argument. */
1314 if (struct_incoming_value
)
1316 emit_move_insn (adjust_address (registers
, Pmode
, size
),
1317 copy_to_reg (struct_incoming_value
));
1318 size
+= GET_MODE_SIZE (Pmode
);
1321 /* Return the address of the block. */
1322 return copy_addr_to_reg (XEXP (registers
, 0));
1325 /* __builtin_apply_args returns block of memory allocated on
1326 the stack into which is stored the arg pointer, structure
1327 value address, static chain, and all the registers that might
1328 possibly be used in performing a function call. The code is
1329 moved to the start of the function so the incoming values are
1333 expand_builtin_apply_args (void)
1335 /* Don't do __builtin_apply_args more than once in a function.
1336 Save the result of the first call and reuse it. */
1337 if (apply_args_value
!= 0)
1338 return apply_args_value
;
1340 /* When this function is called, it means that registers must be
1341 saved on entry to this function. So we migrate the
1342 call to the first insn of this function. */
1347 temp
= expand_builtin_apply_args_1 ();
1351 apply_args_value
= temp
;
1353 /* Put the insns after the NOTE that starts the function.
1354 If this is inside a start_sequence, make the outer-level insn
1355 chain current, so the code is placed at the start of the
1357 push_topmost_sequence ();
1358 emit_insn_before (seq
, NEXT_INSN (entry_of_function ()));
1359 pop_topmost_sequence ();
1364 /* Perform an untyped call and save the state required to perform an
1365 untyped return of whatever value was returned by the given function. */
1368 expand_builtin_apply (rtx function
, rtx arguments
, rtx argsize
)
1370 int size
, align
, regno
;
1371 enum machine_mode mode
;
1372 rtx incoming_args
, result
, reg
, dest
, src
, call_insn
;
1373 rtx old_stack_level
= 0;
1374 rtx call_fusage
= 0;
1375 rtx struct_value
= targetm
.calls
.struct_value_rtx (cfun
? TREE_TYPE (cfun
->decl
) : 0, 0);
1377 arguments
= convert_memory_address (Pmode
, arguments
);
1379 /* Create a block where the return registers can be saved. */
1380 result
= assign_stack_local (BLKmode
, apply_result_size (), -1);
1382 /* Fetch the arg pointer from the ARGUMENTS block. */
1383 incoming_args
= gen_reg_rtx (Pmode
);
1384 emit_move_insn (incoming_args
, gen_rtx_MEM (Pmode
, arguments
));
1385 #ifndef STACK_GROWS_DOWNWARD
1386 incoming_args
= expand_simple_binop (Pmode
, MINUS
, incoming_args
, argsize
,
1387 incoming_args
, 0, OPTAB_LIB_WIDEN
);
1390 /* Push a new argument block and copy the arguments. Do not allow
1391 the (potential) memcpy call below to interfere with our stack
1393 do_pending_stack_adjust ();
1396 /* Save the stack with nonlocal if available. */
1397 #ifdef HAVE_save_stack_nonlocal
1398 if (HAVE_save_stack_nonlocal
)
1399 emit_stack_save (SAVE_NONLOCAL
, &old_stack_level
, NULL_RTX
);
1402 emit_stack_save (SAVE_BLOCK
, &old_stack_level
, NULL_RTX
);
1404 /* Allocate a block of memory onto the stack and copy the memory
1405 arguments to the outgoing arguments address. */
1406 allocate_dynamic_stack_space (argsize
, 0, BITS_PER_UNIT
);
1407 dest
= virtual_outgoing_args_rtx
;
1408 #ifndef STACK_GROWS_DOWNWARD
1409 if (GET_CODE (argsize
) == CONST_INT
)
1410 dest
= plus_constant (dest
, -INTVAL (argsize
));
1412 dest
= gen_rtx_PLUS (Pmode
, dest
, negate_rtx (Pmode
, argsize
));
1414 dest
= gen_rtx_MEM (BLKmode
, dest
);
1415 set_mem_align (dest
, PARM_BOUNDARY
);
1416 src
= gen_rtx_MEM (BLKmode
, incoming_args
);
1417 set_mem_align (src
, PARM_BOUNDARY
);
1418 emit_block_move (dest
, src
, argsize
, BLOCK_OP_NORMAL
);
1420 /* Refer to the argument block. */
1422 arguments
= gen_rtx_MEM (BLKmode
, arguments
);
1423 set_mem_align (arguments
, PARM_BOUNDARY
);
1425 /* Walk past the arg-pointer and structure value address. */
1426 size
= GET_MODE_SIZE (Pmode
);
1428 size
+= GET_MODE_SIZE (Pmode
);
1430 /* Restore each of the registers previously saved. Make USE insns
1431 for each of these registers for use in making the call. */
1432 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
1433 if ((mode
= apply_args_mode
[regno
]) != VOIDmode
)
1435 align
= GET_MODE_ALIGNMENT (mode
) / BITS_PER_UNIT
;
1436 if (size
% align
!= 0)
1437 size
= CEIL (size
, align
) * align
;
1438 reg
= gen_rtx_REG (mode
, regno
);
1439 emit_move_insn (reg
, adjust_address (arguments
, mode
, size
));
1440 use_reg (&call_fusage
, reg
);
1441 size
+= GET_MODE_SIZE (mode
);
1444 /* Restore the structure value address unless this is passed as an
1445 "invisible" first argument. */
1446 size
= GET_MODE_SIZE (Pmode
);
1449 rtx value
= gen_reg_rtx (Pmode
);
1450 emit_move_insn (value
, adjust_address (arguments
, Pmode
, size
));
1451 emit_move_insn (struct_value
, value
);
1452 if (REG_P (struct_value
))
1453 use_reg (&call_fusage
, struct_value
);
1454 size
+= GET_MODE_SIZE (Pmode
);
1457 /* All arguments and registers used for the call are set up by now! */
1458 function
= prepare_call_address (function
, NULL
, &call_fusage
, 0, 0);
1460 /* Ensure address is valid. SYMBOL_REF is already valid, so no need,
1461 and we don't want to load it into a register as an optimization,
1462 because prepare_call_address already did it if it should be done. */
1463 if (GET_CODE (function
) != SYMBOL_REF
)
1464 function
= memory_address (FUNCTION_MODE
, function
);
1466 /* Generate the actual call instruction and save the return value. */
1467 #ifdef HAVE_untyped_call
1468 if (HAVE_untyped_call
)
1469 emit_call_insn (gen_untyped_call (gen_rtx_MEM (FUNCTION_MODE
, function
),
1470 result
, result_vector (1, result
)));
1473 #ifdef HAVE_call_value
1474 if (HAVE_call_value
)
1478 /* Locate the unique return register. It is not possible to
1479 express a call that sets more than one return register using
1480 call_value; use untyped_call for that. In fact, untyped_call
1481 only needs to save the return registers in the given block. */
1482 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
1483 if ((mode
= apply_result_mode
[regno
]) != VOIDmode
)
1485 gcc_assert (!valreg
); /* HAVE_untyped_call required. */
1487 valreg
= gen_rtx_REG (mode
, regno
);
1490 emit_call_insn (GEN_CALL_VALUE (valreg
,
1491 gen_rtx_MEM (FUNCTION_MODE
, function
),
1492 const0_rtx
, NULL_RTX
, const0_rtx
));
1494 emit_move_insn (adjust_address (result
, GET_MODE (valreg
), 0), valreg
);
1500 /* Find the CALL insn we just emitted, and attach the register usage
1502 call_insn
= last_call_insn ();
1503 add_function_usage_to (call_insn
, call_fusage
);
1505 /* Restore the stack. */
1506 #ifdef HAVE_save_stack_nonlocal
1507 if (HAVE_save_stack_nonlocal
)
1508 emit_stack_restore (SAVE_NONLOCAL
, old_stack_level
, NULL_RTX
);
1511 emit_stack_restore (SAVE_BLOCK
, old_stack_level
, NULL_RTX
);
1515 /* Return the address of the result block. */
1516 result
= copy_addr_to_reg (XEXP (result
, 0));
1517 return convert_memory_address (ptr_mode
, result
);
1520 /* Perform an untyped return. */
1523 expand_builtin_return (rtx result
)
1525 int size
, align
, regno
;
1526 enum machine_mode mode
;
1528 rtx call_fusage
= 0;
1530 result
= convert_memory_address (Pmode
, result
);
1532 apply_result_size ();
1533 result
= gen_rtx_MEM (BLKmode
, result
);
1535 #ifdef HAVE_untyped_return
1536 if (HAVE_untyped_return
)
1538 emit_jump_insn (gen_untyped_return (result
, result_vector (0, result
)));
1544 /* Restore the return value and note that each value is used. */
1546 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
1547 if ((mode
= apply_result_mode
[regno
]) != VOIDmode
)
1549 align
= GET_MODE_ALIGNMENT (mode
) / BITS_PER_UNIT
;
1550 if (size
% align
!= 0)
1551 size
= CEIL (size
, align
) * align
;
1552 reg
= gen_rtx_REG (mode
, INCOMING_REGNO (regno
));
1553 emit_move_insn (reg
, adjust_address (result
, mode
, size
));
1555 push_to_sequence (call_fusage
);
1556 emit_insn (gen_rtx_USE (VOIDmode
, reg
));
1557 call_fusage
= get_insns ();
1559 size
+= GET_MODE_SIZE (mode
);
1562 /* Put the USE insns before the return. */
1563 emit_insn (call_fusage
);
1565 /* Return whatever values was restored by jumping directly to the end
1567 expand_naked_return ();
1570 /* Used by expand_builtin_classify_type and fold_builtin_classify_type. */
1572 static enum type_class
1573 type_to_class (tree type
)
1575 switch (TREE_CODE (type
))
1577 case VOID_TYPE
: return void_type_class
;
1578 case INTEGER_TYPE
: return integer_type_class
;
1579 case CHAR_TYPE
: return char_type_class
;
1580 case ENUMERAL_TYPE
: return enumeral_type_class
;
1581 case BOOLEAN_TYPE
: return boolean_type_class
;
1582 case POINTER_TYPE
: return pointer_type_class
;
1583 case REFERENCE_TYPE
: return reference_type_class
;
1584 case OFFSET_TYPE
: return offset_type_class
;
1585 case REAL_TYPE
: return real_type_class
;
1586 case COMPLEX_TYPE
: return complex_type_class
;
1587 case FUNCTION_TYPE
: return function_type_class
;
1588 case METHOD_TYPE
: return method_type_class
;
1589 case RECORD_TYPE
: return record_type_class
;
1591 case QUAL_UNION_TYPE
: return union_type_class
;
1592 case ARRAY_TYPE
: return (TYPE_STRING_FLAG (type
)
1593 ? string_type_class
: array_type_class
);
1594 case LANG_TYPE
: return lang_type_class
;
1595 default: return no_type_class
;
1599 /* Expand a call to __builtin_classify_type with arguments found in
1603 expand_builtin_classify_type (tree arglist
)
1606 return GEN_INT (type_to_class (TREE_TYPE (TREE_VALUE (arglist
))));
1607 return GEN_INT (no_type_class
);
1610 /* This helper macro, meant to be used in mathfn_built_in below,
1611 determines which among a set of three builtin math functions is
1612 appropriate for a given type mode. The `F' and `L' cases are
1613 automatically generated from the `double' case. */
1614 #define CASE_MATHFN(BUILT_IN_MATHFN) \
1615 case BUILT_IN_MATHFN: case BUILT_IN_MATHFN##F: case BUILT_IN_MATHFN##L: \
1616 fcode = BUILT_IN_MATHFN; fcodef = BUILT_IN_MATHFN##F ; \
1617 fcodel = BUILT_IN_MATHFN##L ; break;
1619 /* Return mathematic function equivalent to FN but operating directly
1620 on TYPE, if available. If we can't do the conversion, return zero. */
1622 mathfn_built_in (tree type
, enum built_in_function fn
)
1624 enum built_in_function fcode
, fcodef
, fcodel
;
1628 CASE_MATHFN (BUILT_IN_ACOS
)
1629 CASE_MATHFN (BUILT_IN_ACOSH
)
1630 CASE_MATHFN (BUILT_IN_ASIN
)
1631 CASE_MATHFN (BUILT_IN_ASINH
)
1632 CASE_MATHFN (BUILT_IN_ATAN
)
1633 CASE_MATHFN (BUILT_IN_ATAN2
)
1634 CASE_MATHFN (BUILT_IN_ATANH
)
1635 CASE_MATHFN (BUILT_IN_CBRT
)
1636 CASE_MATHFN (BUILT_IN_CEIL
)
1637 CASE_MATHFN (BUILT_IN_COPYSIGN
)
1638 CASE_MATHFN (BUILT_IN_COS
)
1639 CASE_MATHFN (BUILT_IN_COSH
)
1640 CASE_MATHFN (BUILT_IN_DREM
)
1641 CASE_MATHFN (BUILT_IN_ERF
)
1642 CASE_MATHFN (BUILT_IN_ERFC
)
1643 CASE_MATHFN (BUILT_IN_EXP
)
1644 CASE_MATHFN (BUILT_IN_EXP10
)
1645 CASE_MATHFN (BUILT_IN_EXP2
)
1646 CASE_MATHFN (BUILT_IN_EXPM1
)
1647 CASE_MATHFN (BUILT_IN_FABS
)
1648 CASE_MATHFN (BUILT_IN_FDIM
)
1649 CASE_MATHFN (BUILT_IN_FLOOR
)
1650 CASE_MATHFN (BUILT_IN_FMA
)
1651 CASE_MATHFN (BUILT_IN_FMAX
)
1652 CASE_MATHFN (BUILT_IN_FMIN
)
1653 CASE_MATHFN (BUILT_IN_FMOD
)
1654 CASE_MATHFN (BUILT_IN_FREXP
)
1655 CASE_MATHFN (BUILT_IN_GAMMA
)
1656 CASE_MATHFN (BUILT_IN_HUGE_VAL
)
1657 CASE_MATHFN (BUILT_IN_HYPOT
)
1658 CASE_MATHFN (BUILT_IN_ILOGB
)
1659 CASE_MATHFN (BUILT_IN_INF
)
1660 CASE_MATHFN (BUILT_IN_J0
)
1661 CASE_MATHFN (BUILT_IN_J1
)
1662 CASE_MATHFN (BUILT_IN_JN
)
1663 CASE_MATHFN (BUILT_IN_LCEIL
)
1664 CASE_MATHFN (BUILT_IN_LDEXP
)
1665 CASE_MATHFN (BUILT_IN_LFLOOR
)
1666 CASE_MATHFN (BUILT_IN_LGAMMA
)
1667 CASE_MATHFN (BUILT_IN_LLCEIL
)
1668 CASE_MATHFN (BUILT_IN_LLFLOOR
)
1669 CASE_MATHFN (BUILT_IN_LLRINT
)
1670 CASE_MATHFN (BUILT_IN_LLROUND
)
1671 CASE_MATHFN (BUILT_IN_LOG
)
1672 CASE_MATHFN (BUILT_IN_LOG10
)
1673 CASE_MATHFN (BUILT_IN_LOG1P
)
1674 CASE_MATHFN (BUILT_IN_LOG2
)
1675 CASE_MATHFN (BUILT_IN_LOGB
)
1676 CASE_MATHFN (BUILT_IN_LRINT
)
1677 CASE_MATHFN (BUILT_IN_LROUND
)
1678 CASE_MATHFN (BUILT_IN_MODF
)
1679 CASE_MATHFN (BUILT_IN_NAN
)
1680 CASE_MATHFN (BUILT_IN_NANS
)
1681 CASE_MATHFN (BUILT_IN_NEARBYINT
)
1682 CASE_MATHFN (BUILT_IN_NEXTAFTER
)
1683 CASE_MATHFN (BUILT_IN_NEXTTOWARD
)
1684 CASE_MATHFN (BUILT_IN_POW
)
1685 CASE_MATHFN (BUILT_IN_POWI
)
1686 CASE_MATHFN (BUILT_IN_POW10
)
1687 CASE_MATHFN (BUILT_IN_REMAINDER
)
1688 CASE_MATHFN (BUILT_IN_REMQUO
)
1689 CASE_MATHFN (BUILT_IN_RINT
)
1690 CASE_MATHFN (BUILT_IN_ROUND
)
1691 CASE_MATHFN (BUILT_IN_SCALB
)
1692 CASE_MATHFN (BUILT_IN_SCALBLN
)
1693 CASE_MATHFN (BUILT_IN_SCALBN
)
1694 CASE_MATHFN (BUILT_IN_SIGNIFICAND
)
1695 CASE_MATHFN (BUILT_IN_SIN
)
1696 CASE_MATHFN (BUILT_IN_SINCOS
)
1697 CASE_MATHFN (BUILT_IN_SINH
)
1698 CASE_MATHFN (BUILT_IN_SQRT
)
1699 CASE_MATHFN (BUILT_IN_TAN
)
1700 CASE_MATHFN (BUILT_IN_TANH
)
1701 CASE_MATHFN (BUILT_IN_TGAMMA
)
1702 CASE_MATHFN (BUILT_IN_TRUNC
)
1703 CASE_MATHFN (BUILT_IN_Y0
)
1704 CASE_MATHFN (BUILT_IN_Y1
)
1705 CASE_MATHFN (BUILT_IN_YN
)
1711 if (TYPE_MAIN_VARIANT (type
) == double_type_node
)
1712 return implicit_built_in_decls
[fcode
];
1713 else if (TYPE_MAIN_VARIANT (type
) == float_type_node
)
1714 return implicit_built_in_decls
[fcodef
];
1715 else if (TYPE_MAIN_VARIANT (type
) == long_double_type_node
)
1716 return implicit_built_in_decls
[fcodel
];
1721 /* If errno must be maintained, expand the RTL to check if the result,
1722 TARGET, of a built-in function call, EXP, is NaN, and if so set
1726 expand_errno_check (tree exp
, rtx target
)
1728 rtx lab
= gen_label_rtx ();
1730 /* Test the result; if it is NaN, set errno=EDOM because
1731 the argument was not in the domain. */
1732 emit_cmp_and_jump_insns (target
, target
, EQ
, 0, GET_MODE (target
),
1736 /* If this built-in doesn't throw an exception, set errno directly. */
1737 if (TREE_NOTHROW (TREE_OPERAND (TREE_OPERAND (exp
, 0), 0)))
1739 #ifdef GEN_ERRNO_RTX
1740 rtx errno_rtx
= GEN_ERRNO_RTX
;
1743 = gen_rtx_MEM (word_mode
, gen_rtx_SYMBOL_REF (Pmode
, "errno"));
1745 emit_move_insn (errno_rtx
, GEN_INT (TARGET_EDOM
));
1751 /* We can't set errno=EDOM directly; let the library call do it.
1752 Pop the arguments right away in case the call gets deleted. */
1754 expand_call (exp
, target
, 0);
1760 /* Expand a call to one of the builtin math functions (sqrt, exp, or log).
1761 Return 0 if a normal call should be emitted rather than expanding the
1762 function in-line. EXP is the expression that is a call to the builtin
1763 function; if convenient, the result should be placed in TARGET.
1764 SUBTARGET may be used as the target for computing one of EXP's operands. */
1767 expand_builtin_mathfn (tree exp
, rtx target
, rtx subtarget
)
1769 optab builtin_optab
;
1770 rtx op0
, insns
, before_call
;
1771 tree fndecl
= get_callee_fndecl (exp
);
1772 tree arglist
= TREE_OPERAND (exp
, 1);
1773 enum machine_mode mode
;
1774 bool errno_set
= false;
1777 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
1780 arg
= TREE_VALUE (arglist
);
1782 switch (DECL_FUNCTION_CODE (fndecl
))
1785 case BUILT_IN_SQRTF
:
1786 case BUILT_IN_SQRTL
:
1787 errno_set
= ! tree_expr_nonnegative_p (arg
);
1788 builtin_optab
= sqrt_optab
;
1793 errno_set
= true; builtin_optab
= exp_optab
; break;
1794 case BUILT_IN_EXP10
:
1795 case BUILT_IN_EXP10F
:
1796 case BUILT_IN_EXP10L
:
1797 case BUILT_IN_POW10
:
1798 case BUILT_IN_POW10F
:
1799 case BUILT_IN_POW10L
:
1800 errno_set
= true; builtin_optab
= exp10_optab
; break;
1802 case BUILT_IN_EXP2F
:
1803 case BUILT_IN_EXP2L
:
1804 errno_set
= true; builtin_optab
= exp2_optab
; break;
1805 case BUILT_IN_EXPM1
:
1806 case BUILT_IN_EXPM1F
:
1807 case BUILT_IN_EXPM1L
:
1808 errno_set
= true; builtin_optab
= expm1_optab
; break;
1810 case BUILT_IN_LOGBF
:
1811 case BUILT_IN_LOGBL
:
1812 errno_set
= true; builtin_optab
= logb_optab
; break;
1813 case BUILT_IN_ILOGB
:
1814 case BUILT_IN_ILOGBF
:
1815 case BUILT_IN_ILOGBL
:
1816 errno_set
= true; builtin_optab
= ilogb_optab
; break;
1820 errno_set
= true; builtin_optab
= log_optab
; break;
1821 case BUILT_IN_LOG10
:
1822 case BUILT_IN_LOG10F
:
1823 case BUILT_IN_LOG10L
:
1824 errno_set
= true; builtin_optab
= log10_optab
; break;
1826 case BUILT_IN_LOG2F
:
1827 case BUILT_IN_LOG2L
:
1828 errno_set
= true; builtin_optab
= log2_optab
; break;
1829 case BUILT_IN_LOG1P
:
1830 case BUILT_IN_LOG1PF
:
1831 case BUILT_IN_LOG1PL
:
1832 errno_set
= true; builtin_optab
= log1p_optab
; break;
1834 case BUILT_IN_ASINF
:
1835 case BUILT_IN_ASINL
:
1836 builtin_optab
= asin_optab
; break;
1838 case BUILT_IN_ACOSF
:
1839 case BUILT_IN_ACOSL
:
1840 builtin_optab
= acos_optab
; break;
1844 builtin_optab
= tan_optab
; break;
1846 case BUILT_IN_ATANF
:
1847 case BUILT_IN_ATANL
:
1848 builtin_optab
= atan_optab
; break;
1849 case BUILT_IN_FLOOR
:
1850 case BUILT_IN_FLOORF
:
1851 case BUILT_IN_FLOORL
:
1852 builtin_optab
= floor_optab
; break;
1854 case BUILT_IN_CEILF
:
1855 case BUILT_IN_CEILL
:
1856 builtin_optab
= ceil_optab
; break;
1857 case BUILT_IN_TRUNC
:
1858 case BUILT_IN_TRUNCF
:
1859 case BUILT_IN_TRUNCL
:
1860 builtin_optab
= btrunc_optab
; break;
1861 case BUILT_IN_ROUND
:
1862 case BUILT_IN_ROUNDF
:
1863 case BUILT_IN_ROUNDL
:
1864 builtin_optab
= round_optab
; break;
1865 case BUILT_IN_NEARBYINT
:
1866 case BUILT_IN_NEARBYINTF
:
1867 case BUILT_IN_NEARBYINTL
:
1868 builtin_optab
= nearbyint_optab
; break;
1870 case BUILT_IN_RINTF
:
1871 case BUILT_IN_RINTL
:
1872 builtin_optab
= rint_optab
; break;
1873 case BUILT_IN_LRINT
:
1874 case BUILT_IN_LRINTF
:
1875 case BUILT_IN_LRINTL
:
1876 case BUILT_IN_LLRINT
:
1877 case BUILT_IN_LLRINTF
:
1878 case BUILT_IN_LLRINTL
:
1879 builtin_optab
= lrint_optab
; break;
1884 /* Make a suitable register to place result in. */
1885 mode
= TYPE_MODE (TREE_TYPE (exp
));
1887 if (! flag_errno_math
|| ! HONOR_NANS (mode
))
1890 /* Before working hard, check whether the instruction is available. */
1891 if (builtin_optab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
)
1893 target
= gen_reg_rtx (mode
);
1895 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
1896 need to expand the argument again. This way, we will not perform
1897 side-effects more the once. */
1898 narg
= builtin_save_expr (arg
);
1902 arglist
= build_tree_list (NULL_TREE
, arg
);
1903 exp
= build_function_call_expr (fndecl
, arglist
);
1906 op0
= expand_expr (arg
, subtarget
, VOIDmode
, 0);
1910 /* Compute into TARGET.
1911 Set TARGET to wherever the result comes back. */
1912 target
= expand_unop (mode
, builtin_optab
, op0
, target
, 0);
1917 expand_errno_check (exp
, target
);
1919 /* Output the entire sequence. */
1920 insns
= get_insns ();
1926 /* If we were unable to expand via the builtin, stop the sequence
1927 (without outputting the insns) and call to the library function
1928 with the stabilized argument list. */
1932 before_call
= get_last_insn ();
1934 target
= expand_call (exp
, target
, target
== const0_rtx
);
1936 /* If this is a sqrt operation and we don't care about errno, try to
1937 attach a REG_EQUAL note with a SQRT rtx to the emitted libcall.
1938 This allows the semantics of the libcall to be visible to the RTL
1940 if (builtin_optab
== sqrt_optab
&& !errno_set
)
1942 /* Search backwards through the insns emitted by expand_call looking
1943 for the instruction with the REG_RETVAL note. */
1944 rtx last
= get_last_insn ();
1945 while (last
!= before_call
)
1947 if (find_reg_note (last
, REG_RETVAL
, NULL
))
1949 rtx note
= find_reg_note (last
, REG_EQUAL
, NULL
);
1950 /* Check that the REQ_EQUAL note is an EXPR_LIST with
1951 two elements, i.e. symbol_ref(sqrt) and the operand. */
1953 && GET_CODE (note
) == EXPR_LIST
1954 && GET_CODE (XEXP (note
, 0)) == EXPR_LIST
1955 && XEXP (XEXP (note
, 0), 1) != NULL_RTX
1956 && XEXP (XEXP (XEXP (note
, 0), 1), 1) == NULL_RTX
)
1958 rtx operand
= XEXP (XEXP (XEXP (note
, 0), 1), 0);
1959 /* Check operand is a register with expected mode. */
1962 && GET_MODE (operand
) == mode
)
1964 /* Replace the REG_EQUAL note with a SQRT rtx. */
1965 rtx equiv
= gen_rtx_SQRT (mode
, operand
);
1966 set_unique_reg_note (last
, REG_EQUAL
, equiv
);
1971 last
= PREV_INSN (last
);
1978 /* Expand a call to the builtin binary math functions (pow and atan2).
1979 Return 0 if a normal call should be emitted rather than expanding the
1980 function in-line. EXP is the expression that is a call to the builtin
1981 function; if convenient, the result should be placed in TARGET.
1982 SUBTARGET may be used as the target for computing one of EXP's
1986 expand_builtin_mathfn_2 (tree exp
, rtx target
, rtx subtarget
)
1988 optab builtin_optab
;
1989 rtx op0
, op1
, insns
;
1990 int op1_type
= REAL_TYPE
;
1991 tree fndecl
= get_callee_fndecl (exp
);
1992 tree arglist
= TREE_OPERAND (exp
, 1);
1993 tree arg0
, arg1
, temp
, narg
;
1994 enum machine_mode mode
;
1995 bool errno_set
= true;
1998 if ((DECL_FUNCTION_CODE (fndecl
) == BUILT_IN_LDEXP
)
1999 || (DECL_FUNCTION_CODE (fndecl
) == BUILT_IN_LDEXPF
)
2000 || (DECL_FUNCTION_CODE (fndecl
) == BUILT_IN_LDEXPL
))
2001 op1_type
= INTEGER_TYPE
;
2003 if (!validate_arglist (arglist
, REAL_TYPE
, op1_type
, VOID_TYPE
))
2006 arg0
= TREE_VALUE (arglist
);
2007 arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
2009 switch (DECL_FUNCTION_CODE (fndecl
))
2014 builtin_optab
= pow_optab
; break;
2015 case BUILT_IN_ATAN2
:
2016 case BUILT_IN_ATAN2F
:
2017 case BUILT_IN_ATAN2L
:
2018 builtin_optab
= atan2_optab
; break;
2019 case BUILT_IN_LDEXP
:
2020 case BUILT_IN_LDEXPF
:
2021 case BUILT_IN_LDEXPL
:
2022 builtin_optab
= ldexp_optab
; break;
2024 case BUILT_IN_FMODF
:
2025 case BUILT_IN_FMODL
:
2026 builtin_optab
= fmod_optab
; break;
2028 case BUILT_IN_DREMF
:
2029 case BUILT_IN_DREML
:
2030 builtin_optab
= drem_optab
; break;
2035 /* Make a suitable register to place result in. */
2036 mode
= TYPE_MODE (TREE_TYPE (exp
));
2038 /* Before working hard, check whether the instruction is available. */
2039 if (builtin_optab
->handlers
[(int) mode
].insn_code
== CODE_FOR_nothing
)
2042 target
= gen_reg_rtx (mode
);
2044 if (! flag_errno_math
|| ! HONOR_NANS (mode
))
2047 /* Always stabilize the argument list. */
2048 narg
= builtin_save_expr (arg1
);
2052 temp
= build_tree_list (NULL_TREE
, narg
);
2056 temp
= TREE_CHAIN (arglist
);
2058 narg
= builtin_save_expr (arg0
);
2062 arglist
= tree_cons (NULL_TREE
, narg
, temp
);
2066 arglist
= tree_cons (NULL_TREE
, arg0
, temp
);
2069 exp
= build_function_call_expr (fndecl
, arglist
);
2071 op0
= expand_expr (arg0
, subtarget
, VOIDmode
, 0);
2072 op1
= expand_expr (arg1
, 0, VOIDmode
, 0);
2076 /* Compute into TARGET.
2077 Set TARGET to wherever the result comes back. */
2078 target
= expand_binop (mode
, builtin_optab
, op0
, op1
,
2079 target
, 0, OPTAB_DIRECT
);
2081 /* If we were unable to expand via the builtin, stop the sequence
2082 (without outputting the insns) and call to the library function
2083 with the stabilized argument list. */
2087 return expand_call (exp
, target
, target
== const0_rtx
);
2091 expand_errno_check (exp
, target
);
2093 /* Output the entire sequence. */
2094 insns
= get_insns ();
2101 /* Expand a call to the builtin sin and cos math functions.
2102 Return 0 if a normal call should be emitted rather than expanding the
2103 function in-line. EXP is the expression that is a call to the builtin
2104 function; if convenient, the result should be placed in TARGET.
2105 SUBTARGET may be used as the target for computing one of EXP's
2109 expand_builtin_mathfn_3 (tree exp
, rtx target
, rtx subtarget
)
2111 optab builtin_optab
;
2113 tree fndecl
= get_callee_fndecl (exp
);
2114 tree arglist
= TREE_OPERAND (exp
, 1);
2115 enum machine_mode mode
;
2116 bool errno_set
= false;
2119 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
2122 arg
= TREE_VALUE (arglist
);
2124 switch (DECL_FUNCTION_CODE (fndecl
))
2132 builtin_optab
= sincos_optab
; break;
2137 /* Make a suitable register to place result in. */
2138 mode
= TYPE_MODE (TREE_TYPE (exp
));
2140 if (! flag_errno_math
|| ! HONOR_NANS (mode
))
2143 /* Check if sincos insn is available, otherwise fallback
2144 to sin or cos insn. */
2145 if (builtin_optab
->handlers
[(int) mode
].insn_code
== CODE_FOR_nothing
) {
2146 switch (DECL_FUNCTION_CODE (fndecl
))
2151 builtin_optab
= sin_optab
; break;
2155 builtin_optab
= cos_optab
; break;
2161 /* Before working hard, check whether the instruction is available. */
2162 if (builtin_optab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
)
2164 target
= gen_reg_rtx (mode
);
2166 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2167 need to expand the argument again. This way, we will not perform
2168 side-effects more the once. */
2169 narg
= save_expr (arg
);
2173 arglist
= build_tree_list (NULL_TREE
, arg
);
2174 exp
= build_function_call_expr (fndecl
, arglist
);
2177 op0
= expand_expr (arg
, subtarget
, VOIDmode
, 0);
2181 /* Compute into TARGET.
2182 Set TARGET to wherever the result comes back. */
2183 if (builtin_optab
== sincos_optab
)
2187 switch (DECL_FUNCTION_CODE (fndecl
))
2192 result
= expand_twoval_unop (builtin_optab
, op0
, 0, target
, 0);
2197 result
= expand_twoval_unop (builtin_optab
, op0
, target
, 0, 0);
2202 gcc_assert (result
);
2206 target
= expand_unop (mode
, builtin_optab
, op0
, target
, 0);
2212 expand_errno_check (exp
, target
);
2214 /* Output the entire sequence. */
2215 insns
= get_insns ();
2221 /* If we were unable to expand via the builtin, stop the sequence
2222 (without outputting the insns) and call to the library function
2223 with the stabilized argument list. */
2227 target
= expand_call (exp
, target
, target
== const0_rtx
);
2232 /* Expand a call to one of the builtin rounding functions (lfloor).
2233 If expanding via optab fails, lower expression to (int)(floor(x)).
2234 EXP is the expression that is a call to the builtin function;
2235 if convenient, the result should be placed in TARGET. SUBTARGET may
2236 be used as the target for computing one of EXP's operands. */
2239 expand_builtin_int_roundingfn (tree exp
, rtx target
, rtx subtarget
)
2241 optab builtin_optab
;
2242 rtx op0
, insns
, tmp
;
2243 tree fndecl
= get_callee_fndecl (exp
);
2244 tree arglist
= TREE_OPERAND (exp
, 1);
2245 enum built_in_function fallback_fn
;
2246 tree fallback_fndecl
;
2247 enum machine_mode mode
;
2250 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
2253 arg
= TREE_VALUE (arglist
);
2255 switch (DECL_FUNCTION_CODE (fndecl
))
2257 case BUILT_IN_LCEIL
:
2258 case BUILT_IN_LCEILF
:
2259 case BUILT_IN_LCEILL
:
2260 case BUILT_IN_LLCEIL
:
2261 case BUILT_IN_LLCEILF
:
2262 case BUILT_IN_LLCEILL
:
2263 builtin_optab
= lceil_optab
;
2264 fallback_fn
= BUILT_IN_CEIL
;
2267 case BUILT_IN_LFLOOR
:
2268 case BUILT_IN_LFLOORF
:
2269 case BUILT_IN_LFLOORL
:
2270 case BUILT_IN_LLFLOOR
:
2271 case BUILT_IN_LLFLOORF
:
2272 case BUILT_IN_LLFLOORL
:
2273 builtin_optab
= lfloor_optab
;
2274 fallback_fn
= BUILT_IN_FLOOR
;
2281 /* Make a suitable register to place result in. */
2282 mode
= TYPE_MODE (TREE_TYPE (exp
));
2284 /* Before working hard, check whether the instruction is available. */
2285 if (builtin_optab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
)
2287 target
= gen_reg_rtx (mode
);
2289 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2290 need to expand the argument again. This way, we will not perform
2291 side-effects more the once. */
2292 narg
= builtin_save_expr (arg
);
2296 arglist
= build_tree_list (NULL_TREE
, arg
);
2297 exp
= build_function_call_expr (fndecl
, arglist
);
2300 op0
= expand_expr (arg
, subtarget
, VOIDmode
, 0);
2304 /* Compute into TARGET.
2305 Set TARGET to wherever the result comes back. */
2306 target
= expand_unop (mode
, builtin_optab
, op0
, target
, 0);
2310 /* Output the entire sequence. */
2311 insns
= get_insns ();
2317 /* If we were unable to expand via the builtin, stop the sequence
2318 (without outputting the insns). */
2322 /* Fall back to floating point rounding optab. */
2323 fallback_fndecl
= mathfn_built_in (TREE_TYPE (arg
), fallback_fn
);
2324 /* We shouldn't get here on targets without TARGET_C99_FUNCTIONS.
2325 ??? Perhaps convert (int)floorf(x) into (int)floor((double)x). */
2326 gcc_assert (fallback_fndecl
!= NULL_TREE
);
2327 exp
= build_function_call_expr (fallback_fndecl
, arglist
);
2329 tmp
= expand_builtin_mathfn (exp
, NULL_RTX
, NULL_RTX
);
2331 /* Truncate the result of floating point optab to integer
2332 via expand_fix (). */
2333 target
= gen_reg_rtx (mode
);
2334 expand_fix (target
, tmp
, 0);
2339 /* To evaluate powi(x,n), the floating point value x raised to the
2340 constant integer exponent n, we use a hybrid algorithm that
2341 combines the "window method" with look-up tables. For an
2342 introduction to exponentiation algorithms and "addition chains",
2343 see section 4.6.3, "Evaluation of Powers" of Donald E. Knuth,
2344 "Seminumerical Algorithms", Vol. 2, "The Art of Computer Programming",
2345 3rd Edition, 1998, and Daniel M. Gordon, "A Survey of Fast Exponentiation
2346 Methods", Journal of Algorithms, Vol. 27, pp. 129-146, 1998. */
2348 /* Provide a default value for POWI_MAX_MULTS, the maximum number of
2349 multiplications to inline before calling the system library's pow
2350 function. powi(x,n) requires at worst 2*bits(n)-2 multiplications,
2351 so this default never requires calling pow, powf or powl. */
2353 #ifndef POWI_MAX_MULTS
2354 #define POWI_MAX_MULTS (2*HOST_BITS_PER_WIDE_INT-2)
2357 /* The size of the "optimal power tree" lookup table. All
2358 exponents less than this value are simply looked up in the
2359 powi_table below. This threshold is also used to size the
2360 cache of pseudo registers that hold intermediate results. */
2361 #define POWI_TABLE_SIZE 256
2363 /* The size, in bits of the window, used in the "window method"
2364 exponentiation algorithm. This is equivalent to a radix of
2365 (1<<POWI_WINDOW_SIZE) in the corresponding "m-ary method". */
2366 #define POWI_WINDOW_SIZE 3
2368 /* The following table is an efficient representation of an
2369 "optimal power tree". For each value, i, the corresponding
2370 value, j, in the table states than an optimal evaluation
2371 sequence for calculating pow(x,i) can be found by evaluating
2372 pow(x,j)*pow(x,i-j). An optimal power tree for the first
2373 100 integers is given in Knuth's "Seminumerical algorithms". */
2375 static const unsigned char powi_table
[POWI_TABLE_SIZE
] =
2377 0, 1, 1, 2, 2, 3, 3, 4, /* 0 - 7 */
2378 4, 6, 5, 6, 6, 10, 7, 9, /* 8 - 15 */
2379 8, 16, 9, 16, 10, 12, 11, 13, /* 16 - 23 */
2380 12, 17, 13, 18, 14, 24, 15, 26, /* 24 - 31 */
2381 16, 17, 17, 19, 18, 33, 19, 26, /* 32 - 39 */
2382 20, 25, 21, 40, 22, 27, 23, 44, /* 40 - 47 */
2383 24, 32, 25, 34, 26, 29, 27, 44, /* 48 - 55 */
2384 28, 31, 29, 34, 30, 60, 31, 36, /* 56 - 63 */
2385 32, 64, 33, 34, 34, 46, 35, 37, /* 64 - 71 */
2386 36, 65, 37, 50, 38, 48, 39, 69, /* 72 - 79 */
2387 40, 49, 41, 43, 42, 51, 43, 58, /* 80 - 87 */
2388 44, 64, 45, 47, 46, 59, 47, 76, /* 88 - 95 */
2389 48, 65, 49, 66, 50, 67, 51, 66, /* 96 - 103 */
2390 52, 70, 53, 74, 54, 104, 55, 74, /* 104 - 111 */
2391 56, 64, 57, 69, 58, 78, 59, 68, /* 112 - 119 */
2392 60, 61, 61, 80, 62, 75, 63, 68, /* 120 - 127 */
2393 64, 65, 65, 128, 66, 129, 67, 90, /* 128 - 135 */
2394 68, 73, 69, 131, 70, 94, 71, 88, /* 136 - 143 */
2395 72, 128, 73, 98, 74, 132, 75, 121, /* 144 - 151 */
2396 76, 102, 77, 124, 78, 132, 79, 106, /* 152 - 159 */
2397 80, 97, 81, 160, 82, 99, 83, 134, /* 160 - 167 */
2398 84, 86, 85, 95, 86, 160, 87, 100, /* 168 - 175 */
2399 88, 113, 89, 98, 90, 107, 91, 122, /* 176 - 183 */
2400 92, 111, 93, 102, 94, 126, 95, 150, /* 184 - 191 */
2401 96, 128, 97, 130, 98, 133, 99, 195, /* 192 - 199 */
2402 100, 128, 101, 123, 102, 164, 103, 138, /* 200 - 207 */
2403 104, 145, 105, 146, 106, 109, 107, 149, /* 208 - 215 */
2404 108, 200, 109, 146, 110, 170, 111, 157, /* 216 - 223 */
2405 112, 128, 113, 130, 114, 182, 115, 132, /* 224 - 231 */
2406 116, 200, 117, 132, 118, 158, 119, 206, /* 232 - 239 */
2407 120, 240, 121, 162, 122, 147, 123, 152, /* 240 - 247 */
2408 124, 166, 125, 214, 126, 138, 127, 153, /* 248 - 255 */
2412 /* Return the number of multiplications required to calculate
2413 powi(x,n) where n is less than POWI_TABLE_SIZE. This is a
2414 subroutine of powi_cost. CACHE is an array indicating
2415 which exponents have already been calculated. */
2418 powi_lookup_cost (unsigned HOST_WIDE_INT n
, bool *cache
)
2420 /* If we've already calculated this exponent, then this evaluation
2421 doesn't require any additional multiplications. */
2426 return powi_lookup_cost (n
- powi_table
[n
], cache
)
2427 + powi_lookup_cost (powi_table
[n
], cache
) + 1;
2430 /* Return the number of multiplications required to calculate
2431 powi(x,n) for an arbitrary x, given the exponent N. This
2432 function needs to be kept in sync with expand_powi below. */
2435 powi_cost (HOST_WIDE_INT n
)
2437 bool cache
[POWI_TABLE_SIZE
];
2438 unsigned HOST_WIDE_INT digit
;
2439 unsigned HOST_WIDE_INT val
;
2445 /* Ignore the reciprocal when calculating the cost. */
2446 val
= (n
< 0) ? -n
: n
;
2448 /* Initialize the exponent cache. */
2449 memset (cache
, 0, POWI_TABLE_SIZE
* sizeof (bool));
2454 while (val
>= POWI_TABLE_SIZE
)
2458 digit
= val
& ((1 << POWI_WINDOW_SIZE
) - 1);
2459 result
+= powi_lookup_cost (digit
, cache
)
2460 + POWI_WINDOW_SIZE
+ 1;
2461 val
>>= POWI_WINDOW_SIZE
;
2470 return result
+ powi_lookup_cost (val
, cache
);
2473 /* Recursive subroutine of expand_powi. This function takes the array,
2474 CACHE, of already calculated exponents and an exponent N and returns
2475 an RTX that corresponds to CACHE[1]**N, as calculated in mode MODE. */
2478 expand_powi_1 (enum machine_mode mode
, unsigned HOST_WIDE_INT n
, rtx
*cache
)
2480 unsigned HOST_WIDE_INT digit
;
2484 if (n
< POWI_TABLE_SIZE
)
2489 target
= gen_reg_rtx (mode
);
2492 op0
= expand_powi_1 (mode
, n
- powi_table
[n
], cache
);
2493 op1
= expand_powi_1 (mode
, powi_table
[n
], cache
);
2497 target
= gen_reg_rtx (mode
);
2498 digit
= n
& ((1 << POWI_WINDOW_SIZE
) - 1);
2499 op0
= expand_powi_1 (mode
, n
- digit
, cache
);
2500 op1
= expand_powi_1 (mode
, digit
, cache
);
2504 target
= gen_reg_rtx (mode
);
2505 op0
= expand_powi_1 (mode
, n
>> 1, cache
);
2509 result
= expand_mult (mode
, op0
, op1
, target
, 0);
2510 if (result
!= target
)
2511 emit_move_insn (target
, result
);
2515 /* Expand the RTL to evaluate powi(x,n) in mode MODE. X is the
2516 floating point operand in mode MODE, and N is the exponent. This
2517 function needs to be kept in sync with powi_cost above. */
2520 expand_powi (rtx x
, enum machine_mode mode
, HOST_WIDE_INT n
)
2522 unsigned HOST_WIDE_INT val
;
2523 rtx cache
[POWI_TABLE_SIZE
];
2527 return CONST1_RTX (mode
);
2529 val
= (n
< 0) ? -n
: n
;
2531 memset (cache
, 0, sizeof (cache
));
2534 result
= expand_powi_1 (mode
, (n
< 0) ? -n
: n
, cache
);
2536 /* If the original exponent was negative, reciprocate the result. */
2538 result
= expand_binop (mode
, sdiv_optab
, CONST1_RTX (mode
),
2539 result
, NULL_RTX
, 0, OPTAB_LIB_WIDEN
);
2544 /* Expand a call to the pow built-in mathematical function. Return 0 if
2545 a normal call should be emitted rather than expanding the function
2546 in-line. EXP is the expression that is a call to the builtin
2547 function; if convenient, the result should be placed in TARGET. */
2550 expand_builtin_pow (tree exp
, rtx target
, rtx subtarget
)
2552 tree arglist
= TREE_OPERAND (exp
, 1);
2555 if (! validate_arglist (arglist
, REAL_TYPE
, REAL_TYPE
, VOID_TYPE
))
2558 arg0
= TREE_VALUE (arglist
);
2559 arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
2561 if (TREE_CODE (arg1
) == REAL_CST
2562 && ! TREE_CONSTANT_OVERFLOW (arg1
))
2564 REAL_VALUE_TYPE cint
;
2568 c
= TREE_REAL_CST (arg1
);
2569 n
= real_to_integer (&c
);
2570 real_from_integer (&cint
, VOIDmode
, n
, n
< 0 ? -1 : 0, 0);
2571 if (real_identical (&c
, &cint
))
2573 /* If the exponent is -1, 0, 1 or 2, then expand_powi is exact.
2574 Otherwise, check the number of multiplications required.
2575 Note that pow never sets errno for an integer exponent. */
2576 if ((n
>= -1 && n
<= 2)
2577 || (flag_unsafe_math_optimizations
2579 && powi_cost (n
) <= POWI_MAX_MULTS
))
2581 enum machine_mode mode
= TYPE_MODE (TREE_TYPE (exp
));
2582 rtx op
= expand_expr (arg0
, subtarget
, VOIDmode
, 0);
2583 op
= force_reg (mode
, op
);
2584 return expand_powi (op
, mode
, n
);
2589 if (! flag_unsafe_math_optimizations
)
2591 return expand_builtin_mathfn_2 (exp
, target
, subtarget
);
2594 /* Expand a call to the powi built-in mathematical function. Return 0 if
2595 a normal call should be emitted rather than expanding the function
2596 in-line. EXP is the expression that is a call to the builtin
2597 function; if convenient, the result should be placed in TARGET. */
2600 expand_builtin_powi (tree exp
, rtx target
, rtx subtarget
)
2602 tree arglist
= TREE_OPERAND (exp
, 1);
2605 enum machine_mode mode
;
2606 enum machine_mode mode2
;
2608 if (! validate_arglist (arglist
, REAL_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
2611 arg0
= TREE_VALUE (arglist
);
2612 arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
2613 mode
= TYPE_MODE (TREE_TYPE (exp
));
2615 /* Handle constant power. */
2617 if (TREE_CODE (arg1
) == INTEGER_CST
2618 && ! TREE_CONSTANT_OVERFLOW (arg1
))
2620 HOST_WIDE_INT n
= TREE_INT_CST_LOW (arg1
);
2622 /* If the exponent is -1, 0, 1 or 2, then expand_powi is exact.
2623 Otherwise, check the number of multiplications required. */
2624 if ((TREE_INT_CST_HIGH (arg1
) == 0
2625 || TREE_INT_CST_HIGH (arg1
) == -1)
2626 && ((n
>= -1 && n
<= 2)
2628 && powi_cost (n
) <= POWI_MAX_MULTS
)))
2630 op0
= expand_expr (arg0
, subtarget
, VOIDmode
, 0);
2631 op0
= force_reg (mode
, op0
);
2632 return expand_powi (op0
, mode
, n
);
2636 /* Emit a libcall to libgcc. */
2638 /* Mode of the 2nd argument must match that of an int. */
2639 mode2
= mode_for_size (INT_TYPE_SIZE
, MODE_INT
, 0);
2641 if (target
== NULL_RTX
)
2642 target
= gen_reg_rtx (mode
);
2644 op0
= expand_expr (arg0
, subtarget
, mode
, 0);
2645 if (GET_MODE (op0
) != mode
)
2646 op0
= convert_to_mode (mode
, op0
, 0);
2647 op1
= expand_expr (arg1
, 0, mode2
, 0);
2648 if (GET_MODE (op1
) != mode2
)
2649 op1
= convert_to_mode (mode2
, op1
, 0);
2651 target
= emit_library_call_value (powi_optab
->handlers
[(int) mode
].libfunc
,
2652 target
, LCT_CONST_MAKE_BLOCK
, mode
, 2,
2653 op0
, mode
, op1
, mode2
);
2658 /* Expand expression EXP which is a call to the strlen builtin. Return 0
2659 if we failed the caller should emit a normal call, otherwise
2660 try to get the result in TARGET, if convenient. */
2663 expand_builtin_strlen (tree arglist
, rtx target
,
2664 enum machine_mode target_mode
)
2666 if (!validate_arglist (arglist
, POINTER_TYPE
, VOID_TYPE
))
2671 tree len
, src
= TREE_VALUE (arglist
);
2672 rtx result
, src_reg
, char_rtx
, before_strlen
;
2673 enum machine_mode insn_mode
= target_mode
, char_mode
;
2674 enum insn_code icode
= CODE_FOR_nothing
;
2677 /* If the length can be computed at compile-time, return it. */
2678 len
= c_strlen (src
, 0);
2680 return expand_expr (len
, target
, target_mode
, EXPAND_NORMAL
);
2682 /* If the length can be computed at compile-time and is constant
2683 integer, but there are side-effects in src, evaluate
2684 src for side-effects, then return len.
2685 E.g. x = strlen (i++ ? "xfoo" + 1 : "bar");
2686 can be optimized into: i++; x = 3; */
2687 len
= c_strlen (src
, 1);
2688 if (len
&& TREE_CODE (len
) == INTEGER_CST
)
2690 expand_expr (src
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
2691 return expand_expr (len
, target
, target_mode
, EXPAND_NORMAL
);
2694 align
= get_pointer_alignment (src
, BIGGEST_ALIGNMENT
) / BITS_PER_UNIT
;
2696 /* If SRC is not a pointer type, don't do this operation inline. */
2700 /* Bail out if we can't compute strlen in the right mode. */
2701 while (insn_mode
!= VOIDmode
)
2703 icode
= strlen_optab
->handlers
[(int) insn_mode
].insn_code
;
2704 if (icode
!= CODE_FOR_nothing
)
2707 insn_mode
= GET_MODE_WIDER_MODE (insn_mode
);
2709 if (insn_mode
== VOIDmode
)
2712 /* Make a place to write the result of the instruction. */
2716 && GET_MODE (result
) == insn_mode
2717 && REGNO (result
) >= FIRST_PSEUDO_REGISTER
))
2718 result
= gen_reg_rtx (insn_mode
);
2720 /* Make a place to hold the source address. We will not expand
2721 the actual source until we are sure that the expansion will
2722 not fail -- there are trees that cannot be expanded twice. */
2723 src_reg
= gen_reg_rtx (Pmode
);
2725 /* Mark the beginning of the strlen sequence so we can emit the
2726 source operand later. */
2727 before_strlen
= get_last_insn ();
2729 char_rtx
= const0_rtx
;
2730 char_mode
= insn_data
[(int) icode
].operand
[2].mode
;
2731 if (! (*insn_data
[(int) icode
].operand
[2].predicate
) (char_rtx
,
2733 char_rtx
= copy_to_mode_reg (char_mode
, char_rtx
);
2735 pat
= GEN_FCN (icode
) (result
, gen_rtx_MEM (BLKmode
, src_reg
),
2736 char_rtx
, GEN_INT (align
));
2741 /* Now that we are assured of success, expand the source. */
2743 pat
= expand_expr (src
, src_reg
, ptr_mode
, EXPAND_NORMAL
);
2745 emit_move_insn (src_reg
, pat
);
2750 emit_insn_after (pat
, before_strlen
);
2752 emit_insn_before (pat
, get_insns ());
2754 /* Return the value in the proper mode for this function. */
2755 if (GET_MODE (result
) == target_mode
)
2757 else if (target
!= 0)
2758 convert_move (target
, result
, 0);
2760 target
= convert_to_mode (target_mode
, result
, 0);
2766 /* Expand a call to the strstr builtin. Return 0 if we failed the
2767 caller should emit a normal call, otherwise try to get the result
2768 in TARGET, if convenient (and in mode MODE if that's convenient). */
2771 expand_builtin_strstr (tree arglist
, tree type
, rtx target
, enum machine_mode mode
)
2773 if (validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
2775 tree result
= fold_builtin_strstr (arglist
, type
);
2777 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
2782 /* Expand a call to the strchr builtin. Return 0 if we failed the
2783 caller should emit a normal call, otherwise try to get the result
2784 in TARGET, if convenient (and in mode MODE if that's convenient). */
2787 expand_builtin_strchr (tree arglist
, tree type
, rtx target
, enum machine_mode mode
)
2789 if (validate_arglist (arglist
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
2791 tree result
= fold_builtin_strchr (arglist
, type
);
2793 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
2795 /* FIXME: Should use strchrM optab so that ports can optimize this. */
2800 /* Expand a call to the strrchr builtin. Return 0 if we failed the
2801 caller should emit a normal call, otherwise try to get the result
2802 in TARGET, if convenient (and in mode MODE if that's convenient). */
2805 expand_builtin_strrchr (tree arglist
, tree type
, rtx target
, enum machine_mode mode
)
2807 if (validate_arglist (arglist
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
2809 tree result
= fold_builtin_strrchr (arglist
, type
);
2811 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
2816 /* Expand a call to the strpbrk builtin. Return 0 if we failed the
2817 caller should emit a normal call, otherwise try to get the result
2818 in TARGET, if convenient (and in mode MODE if that's convenient). */
2821 expand_builtin_strpbrk (tree arglist
, tree type
, rtx target
, enum machine_mode mode
)
2823 if (validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
2825 tree result
= fold_builtin_strpbrk (arglist
, type
);
2827 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
2832 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
2833 bytes from constant string DATA + OFFSET and return it as target
2837 builtin_memcpy_read_str (void *data
, HOST_WIDE_INT offset
,
2838 enum machine_mode mode
)
2840 const char *str
= (const char *) data
;
2842 gcc_assert (offset
>= 0
2843 && ((unsigned HOST_WIDE_INT
) offset
+ GET_MODE_SIZE (mode
)
2844 <= strlen (str
) + 1));
2846 return c_readstr (str
+ offset
, mode
);
2849 /* Expand a call to the memcpy builtin, with arguments in ARGLIST.
2850 Return 0 if we failed, the caller should emit a normal call,
2851 otherwise try to get the result in TARGET, if convenient (and in
2852 mode MODE if that's convenient). */
2854 expand_builtin_memcpy (tree exp
, rtx target
, enum machine_mode mode
)
2856 tree fndecl
= get_callee_fndecl (exp
);
2857 tree arglist
= TREE_OPERAND (exp
, 1);
2858 if (!validate_arglist (arglist
,
2859 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
2863 tree dest
= TREE_VALUE (arglist
);
2864 tree src
= TREE_VALUE (TREE_CHAIN (arglist
));
2865 tree len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
2866 const char *src_str
;
2867 unsigned int src_align
= get_pointer_alignment (src
, BIGGEST_ALIGNMENT
);
2868 unsigned int dest_align
2869 = get_pointer_alignment (dest
, BIGGEST_ALIGNMENT
);
2870 rtx dest_mem
, src_mem
, dest_addr
, len_rtx
;
2871 tree result
= fold_builtin_memcpy (fndecl
, arglist
);
2874 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
2876 /* If DEST is not a pointer type, call the normal function. */
2877 if (dest_align
== 0)
2880 /* If either SRC is not a pointer type, don't do this
2881 operation in-line. */
2885 dest_mem
= get_memory_rtx (dest
, len
);
2886 set_mem_align (dest_mem
, dest_align
);
2887 len_rtx
= expand_expr (len
, NULL_RTX
, VOIDmode
, 0);
2888 src_str
= c_getstr (src
);
2890 /* If SRC is a string constant and block move would be done
2891 by pieces, we can avoid loading the string from memory
2892 and only stored the computed constants. */
2894 && GET_CODE (len_rtx
) == CONST_INT
2895 && (unsigned HOST_WIDE_INT
) INTVAL (len_rtx
) <= strlen (src_str
) + 1
2896 && can_store_by_pieces (INTVAL (len_rtx
), builtin_memcpy_read_str
,
2897 (void *) src_str
, dest_align
))
2899 dest_mem
= store_by_pieces (dest_mem
, INTVAL (len_rtx
),
2900 builtin_memcpy_read_str
,
2901 (void *) src_str
, dest_align
, 0);
2902 dest_mem
= force_operand (XEXP (dest_mem
, 0), NULL_RTX
);
2903 dest_mem
= convert_memory_address (ptr_mode
, dest_mem
);
2907 src_mem
= get_memory_rtx (src
, len
);
2908 set_mem_align (src_mem
, src_align
);
2910 /* Copy word part most expediently. */
2911 dest_addr
= emit_block_move (dest_mem
, src_mem
, len_rtx
,
2912 CALL_EXPR_TAILCALL (exp
)
2913 ? BLOCK_OP_TAILCALL
: BLOCK_OP_NORMAL
);
2917 dest_addr
= force_operand (XEXP (dest_mem
, 0), NULL_RTX
);
2918 dest_addr
= convert_memory_address (ptr_mode
, dest_addr
);
2924 /* Expand a call to the mempcpy builtin, with arguments in ARGLIST.
2925 Return 0 if we failed; the caller should emit a normal call,
2926 otherwise try to get the result in TARGET, if convenient (and in
2927 mode MODE if that's convenient). If ENDP is 0 return the
2928 destination pointer, if ENDP is 1 return the end pointer ala
2929 mempcpy, and if ENDP is 2 return the end pointer minus one ala
2933 expand_builtin_mempcpy (tree arglist
, tree type
, rtx target
, enum machine_mode mode
,
2936 if (!validate_arglist (arglist
,
2937 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
2939 /* If return value is ignored, transform mempcpy into memcpy. */
2940 else if (target
== const0_rtx
)
2942 tree fn
= implicit_built_in_decls
[BUILT_IN_MEMCPY
];
2947 return expand_expr (build_function_call_expr (fn
, arglist
),
2948 target
, mode
, EXPAND_NORMAL
);
2952 tree dest
= TREE_VALUE (arglist
);
2953 tree src
= TREE_VALUE (TREE_CHAIN (arglist
));
2954 tree len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
2955 const char *src_str
;
2956 unsigned int src_align
= get_pointer_alignment (src
, BIGGEST_ALIGNMENT
);
2957 unsigned int dest_align
2958 = get_pointer_alignment (dest
, BIGGEST_ALIGNMENT
);
2959 rtx dest_mem
, src_mem
, len_rtx
;
2960 tree result
= fold_builtin_mempcpy (arglist
, type
, endp
);
2963 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
2965 /* If either SRC or DEST is not a pointer type, don't do this
2966 operation in-line. */
2967 if (dest_align
== 0 || src_align
== 0)
2970 /* If LEN is not constant, call the normal function. */
2971 if (! host_integerp (len
, 1))
2974 len_rtx
= expand_expr (len
, NULL_RTX
, VOIDmode
, 0);
2975 src_str
= c_getstr (src
);
2977 /* If SRC is a string constant and block move would be done
2978 by pieces, we can avoid loading the string from memory
2979 and only stored the computed constants. */
2981 && GET_CODE (len_rtx
) == CONST_INT
2982 && (unsigned HOST_WIDE_INT
) INTVAL (len_rtx
) <= strlen (src_str
) + 1
2983 && can_store_by_pieces (INTVAL (len_rtx
), builtin_memcpy_read_str
,
2984 (void *) src_str
, dest_align
))
2986 dest_mem
= get_memory_rtx (dest
, len
);
2987 set_mem_align (dest_mem
, dest_align
);
2988 dest_mem
= store_by_pieces (dest_mem
, INTVAL (len_rtx
),
2989 builtin_memcpy_read_str
,
2990 (void *) src_str
, dest_align
, endp
);
2991 dest_mem
= force_operand (XEXP (dest_mem
, 0), NULL_RTX
);
2992 dest_mem
= convert_memory_address (ptr_mode
, dest_mem
);
2996 if (GET_CODE (len_rtx
) == CONST_INT
2997 && can_move_by_pieces (INTVAL (len_rtx
),
2998 MIN (dest_align
, src_align
)))
3000 dest_mem
= get_memory_rtx (dest
, len
);
3001 set_mem_align (dest_mem
, dest_align
);
3002 src_mem
= get_memory_rtx (src
, len
);
3003 set_mem_align (src_mem
, src_align
);
3004 dest_mem
= move_by_pieces (dest_mem
, src_mem
, INTVAL (len_rtx
),
3005 MIN (dest_align
, src_align
), endp
);
3006 dest_mem
= force_operand (XEXP (dest_mem
, 0), NULL_RTX
);
3007 dest_mem
= convert_memory_address (ptr_mode
, dest_mem
);
3015 /* Expand expression EXP, which is a call to the memmove builtin. Return 0
3016 if we failed; the caller should emit a normal call. */
3019 expand_builtin_memmove (tree arglist
, tree type
, rtx target
,
3020 enum machine_mode mode
, tree orig_exp
)
3022 if (!validate_arglist (arglist
,
3023 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
3027 tree dest
= TREE_VALUE (arglist
);
3028 tree src
= TREE_VALUE (TREE_CHAIN (arglist
));
3029 tree len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
3031 unsigned int src_align
= get_pointer_alignment (src
, BIGGEST_ALIGNMENT
);
3032 unsigned int dest_align
3033 = get_pointer_alignment (dest
, BIGGEST_ALIGNMENT
);
3034 tree result
= fold_builtin_memmove (arglist
, type
);
3037 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
3039 /* If DEST is not a pointer type, call the normal function. */
3040 if (dest_align
== 0)
3043 /* If either SRC is not a pointer type, don't do this
3044 operation in-line. */
3048 /* If src is categorized for a readonly section we can use
3050 if (readonly_data_expr (src
))
3052 tree fn
= implicit_built_in_decls
[BUILT_IN_MEMCPY
];
3055 fn
= build_function_call_expr (fn
, arglist
);
3056 if (TREE_CODE (fn
) == CALL_EXPR
)
3057 CALL_EXPR_TAILCALL (fn
) = CALL_EXPR_TAILCALL (orig_exp
);
3058 return expand_expr (fn
, target
, mode
, EXPAND_NORMAL
);
3061 /* If length is 1 and we can expand memcpy call inline,
3062 it is ok to use memcpy as well. */
3063 if (integer_onep (len
))
3065 rtx ret
= expand_builtin_mempcpy (arglist
, type
, target
, mode
,
3071 /* Otherwise, call the normal function. */
3076 /* Expand expression EXP, which is a call to the bcopy builtin. Return 0
3077 if we failed the caller should emit a normal call. */
3080 expand_builtin_bcopy (tree exp
)
3082 tree arglist
= TREE_OPERAND (exp
, 1);
3083 tree type
= TREE_TYPE (exp
);
3084 tree src
, dest
, size
, newarglist
;
3086 if (!validate_arglist (arglist
,
3087 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
3090 src
= TREE_VALUE (arglist
);
3091 dest
= TREE_VALUE (TREE_CHAIN (arglist
));
3092 size
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
3094 /* New argument list transforming bcopy(ptr x, ptr y, int z) to
3095 memmove(ptr y, ptr x, size_t z). This is done this way
3096 so that if it isn't expanded inline, we fallback to
3097 calling bcopy instead of memmove. */
3099 newarglist
= build_tree_list (NULL_TREE
, fold_convert (sizetype
, size
));
3100 newarglist
= tree_cons (NULL_TREE
, src
, newarglist
);
3101 newarglist
= tree_cons (NULL_TREE
, dest
, newarglist
);
3103 return expand_builtin_memmove (newarglist
, type
, const0_rtx
, VOIDmode
, exp
);
3107 # define HAVE_movstr 0
3108 # define CODE_FOR_movstr CODE_FOR_nothing
3111 /* Expand into a movstr instruction, if one is available. Return 0 if
3112 we failed, the caller should emit a normal call, otherwise try to
3113 get the result in TARGET, if convenient. If ENDP is 0 return the
3114 destination pointer, if ENDP is 1 return the end pointer ala
3115 mempcpy, and if ENDP is 2 return the end pointer minus one ala
3119 expand_movstr (tree dest
, tree src
, rtx target
, int endp
)
3125 const struct insn_data
* data
;
3130 dest_mem
= get_memory_rtx (dest
, NULL
);
3131 src_mem
= get_memory_rtx (src
, NULL
);
3134 target
= force_reg (Pmode
, XEXP (dest_mem
, 0));
3135 dest_mem
= replace_equiv_address (dest_mem
, target
);
3136 end
= gen_reg_rtx (Pmode
);
3140 if (target
== 0 || target
== const0_rtx
)
3142 end
= gen_reg_rtx (Pmode
);
3150 data
= insn_data
+ CODE_FOR_movstr
;
3152 if (data
->operand
[0].mode
!= VOIDmode
)
3153 end
= gen_lowpart (data
->operand
[0].mode
, end
);
3155 insn
= data
->genfun (end
, dest_mem
, src_mem
);
3161 /* movstr is supposed to set end to the address of the NUL
3162 terminator. If the caller requested a mempcpy-like return value,
3164 if (endp
== 1 && target
!= const0_rtx
)
3166 rtx tem
= plus_constant (gen_lowpart (GET_MODE (target
), end
), 1);
3167 emit_move_insn (target
, force_operand (tem
, NULL_RTX
));
3173 /* Expand expression EXP, which is a call to the strcpy builtin. Return 0
3174 if we failed the caller should emit a normal call, otherwise try to get
3175 the result in TARGET, if convenient (and in mode MODE if that's
3179 expand_builtin_strcpy (tree fndecl
, tree arglist
, rtx target
, enum machine_mode mode
)
3181 if (validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
3183 tree result
= fold_builtin_strcpy (fndecl
, arglist
, 0);
3185 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
3187 return expand_movstr (TREE_VALUE (arglist
),
3188 TREE_VALUE (TREE_CHAIN (arglist
)),
3189 target
, /*endp=*/0);
3194 /* Expand a call to the stpcpy builtin, with arguments in ARGLIST.
3195 Return 0 if we failed the caller should emit a normal call,
3196 otherwise try to get the result in TARGET, if convenient (and in
3197 mode MODE if that's convenient). */
3200 expand_builtin_stpcpy (tree exp
, rtx target
, enum machine_mode mode
)
3202 tree arglist
= TREE_OPERAND (exp
, 1);
3203 /* If return value is ignored, transform stpcpy into strcpy. */
3204 if (target
== const0_rtx
)
3206 tree fn
= implicit_built_in_decls
[BUILT_IN_STRCPY
];
3210 return expand_expr (build_function_call_expr (fn
, arglist
),
3211 target
, mode
, EXPAND_NORMAL
);
3214 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
3218 tree dst
, src
, len
, lenp1
;
3222 /* Ensure we get an actual string whose length can be evaluated at
3223 compile-time, not an expression containing a string. This is
3224 because the latter will potentially produce pessimized code
3225 when used to produce the return value. */
3226 src
= TREE_VALUE (TREE_CHAIN (arglist
));
3227 if (! c_getstr (src
) || ! (len
= c_strlen (src
, 0)))
3228 return expand_movstr (TREE_VALUE (arglist
),
3229 TREE_VALUE (TREE_CHAIN (arglist
)),
3230 target
, /*endp=*/2);
3232 dst
= TREE_VALUE (arglist
);
3233 lenp1
= size_binop (PLUS_EXPR
, len
, ssize_int (1));
3234 narglist
= build_tree_list (NULL_TREE
, lenp1
);
3235 narglist
= tree_cons (NULL_TREE
, src
, narglist
);
3236 narglist
= tree_cons (NULL_TREE
, dst
, narglist
);
3237 ret
= expand_builtin_mempcpy (narglist
, TREE_TYPE (exp
),
3238 target
, mode
, /*endp=*/2);
3243 if (TREE_CODE (len
) == INTEGER_CST
)
3245 rtx len_rtx
= expand_expr (len
, NULL_RTX
, VOIDmode
, 0);
3247 if (GET_CODE (len_rtx
) == CONST_INT
)
3249 ret
= expand_builtin_strcpy (get_callee_fndecl (exp
),
3250 arglist
, target
, mode
);
3256 if (mode
!= VOIDmode
)
3257 target
= gen_reg_rtx (mode
);
3259 target
= gen_reg_rtx (GET_MODE (ret
));
3261 if (GET_MODE (target
) != GET_MODE (ret
))
3262 ret
= gen_lowpart (GET_MODE (target
), ret
);
3264 ret
= plus_constant (ret
, INTVAL (len_rtx
));
3265 ret
= emit_move_insn (target
, force_operand (ret
, NULL_RTX
));
3273 return expand_movstr (TREE_VALUE (arglist
),
3274 TREE_VALUE (TREE_CHAIN (arglist
)),
3275 target
, /*endp=*/2);
3279 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
3280 bytes from constant string DATA + OFFSET and return it as target
3284 builtin_strncpy_read_str (void *data
, HOST_WIDE_INT offset
,
3285 enum machine_mode mode
)
3287 const char *str
= (const char *) data
;
3289 if ((unsigned HOST_WIDE_INT
) offset
> strlen (str
))
3292 return c_readstr (str
+ offset
, mode
);
3295 /* Expand expression EXP, which is a call to the strncpy builtin. Return 0
3296 if we failed the caller should emit a normal call. */
3299 expand_builtin_strncpy (tree exp
, rtx target
, enum machine_mode mode
)
3301 tree fndecl
= get_callee_fndecl (exp
);
3302 tree arglist
= TREE_OPERAND (exp
, 1);
3303 if (validate_arglist (arglist
,
3304 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
3306 tree slen
= c_strlen (TREE_VALUE (TREE_CHAIN (arglist
)), 1);
3307 tree len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
3308 tree result
= fold_builtin_strncpy (fndecl
, arglist
, slen
);
3311 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
3313 /* We must be passed a constant len and src parameter. */
3314 if (!host_integerp (len
, 1) || !slen
|| !host_integerp (slen
, 1))
3317 slen
= size_binop (PLUS_EXPR
, slen
, ssize_int (1));
3319 /* We're required to pad with trailing zeros if the requested
3320 len is greater than strlen(s2)+1. In that case try to
3321 use store_by_pieces, if it fails, punt. */
3322 if (tree_int_cst_lt (slen
, len
))
3324 tree dest
= TREE_VALUE (arglist
);
3325 unsigned int dest_align
3326 = get_pointer_alignment (dest
, BIGGEST_ALIGNMENT
);
3327 const char *p
= c_getstr (TREE_VALUE (TREE_CHAIN (arglist
)));
3330 if (!p
|| dest_align
== 0 || !host_integerp (len
, 1)
3331 || !can_store_by_pieces (tree_low_cst (len
, 1),
3332 builtin_strncpy_read_str
,
3333 (void *) p
, dest_align
))
3336 dest_mem
= get_memory_rtx (dest
, len
);
3337 store_by_pieces (dest_mem
, tree_low_cst (len
, 1),
3338 builtin_strncpy_read_str
,
3339 (void *) p
, dest_align
, 0);
3340 dest_mem
= force_operand (XEXP (dest_mem
, 0), NULL_RTX
);
3341 dest_mem
= convert_memory_address (ptr_mode
, dest_mem
);
3348 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
3349 bytes from constant string DATA + OFFSET and return it as target
3353 builtin_memset_read_str (void *data
, HOST_WIDE_INT offset ATTRIBUTE_UNUSED
,
3354 enum machine_mode mode
)
3356 const char *c
= (const char *) data
;
3357 char *p
= alloca (GET_MODE_SIZE (mode
));
3359 memset (p
, *c
, GET_MODE_SIZE (mode
));
3361 return c_readstr (p
, mode
);
3364 /* Callback routine for store_by_pieces. Return the RTL of a register
3365 containing GET_MODE_SIZE (MODE) consecutive copies of the unsigned
3366 char value given in the RTL register data. For example, if mode is
3367 4 bytes wide, return the RTL for 0x01010101*data. */
3370 builtin_memset_gen_str (void *data
, HOST_WIDE_INT offset ATTRIBUTE_UNUSED
,
3371 enum machine_mode mode
)
3377 size
= GET_MODE_SIZE (mode
);
3382 memset (p
, 1, size
);
3383 coeff
= c_readstr (p
, mode
);
3385 target
= convert_to_mode (mode
, (rtx
) data
, 1);
3386 target
= expand_mult (mode
, target
, coeff
, NULL_RTX
, 1);
3387 return force_reg (mode
, target
);
3390 /* Expand expression EXP, which is a call to the memset builtin. Return 0
3391 if we failed the caller should emit a normal call, otherwise try to get
3392 the result in TARGET, if convenient (and in mode MODE if that's
3396 expand_builtin_memset (tree arglist
, rtx target
, enum machine_mode mode
,
3399 if (!validate_arglist (arglist
,
3400 POINTER_TYPE
, INTEGER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
3404 tree dest
= TREE_VALUE (arglist
);
3405 tree val
= TREE_VALUE (TREE_CHAIN (arglist
));
3406 tree len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
3409 unsigned int dest_align
3410 = get_pointer_alignment (dest
, BIGGEST_ALIGNMENT
);
3411 rtx dest_mem
, dest_addr
, len_rtx
;
3413 /* If DEST is not a pointer type, don't do this
3414 operation in-line. */
3415 if (dest_align
== 0)
3418 /* If the LEN parameter is zero, return DEST. */
3419 if (integer_zerop (len
))
3421 /* Evaluate and ignore VAL in case it has side-effects. */
3422 expand_expr (val
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
3423 return expand_expr (dest
, target
, mode
, EXPAND_NORMAL
);
3426 len_rtx
= expand_expr (len
, NULL_RTX
, VOIDmode
, 0);
3427 dest_mem
= get_memory_rtx (dest
, len
);
3429 if (TREE_CODE (val
) != INTEGER_CST
)
3433 val
= fold_build1 (CONVERT_EXPR
, unsigned_char_type_node
, val
);
3434 val_rtx
= expand_expr (val
, NULL_RTX
, VOIDmode
, 0);
3436 /* Assume that we can memset by pieces if we can store the
3437 * the coefficients by pieces (in the required modes).
3438 * We can't pass builtin_memset_gen_str as that emits RTL. */
3440 if (host_integerp (len
, 1)
3441 && !(optimize_size
&& tree_low_cst (len
, 1) > 1)
3442 && can_store_by_pieces (tree_low_cst (len
, 1),
3443 builtin_memset_read_str
, &c
, dest_align
))
3445 val_rtx
= force_reg (TYPE_MODE (unsigned_char_type_node
),
3447 store_by_pieces (dest_mem
, tree_low_cst (len
, 1),
3448 builtin_memset_gen_str
, val_rtx
, dest_align
, 0);
3450 else if (!set_storage_via_setmem(dest_mem
, len_rtx
, val_rtx
,
3454 dest_mem
= force_operand (XEXP (dest_mem
, 0), NULL_RTX
);
3455 dest_mem
= convert_memory_address (ptr_mode
, dest_mem
);
3459 if (target_char_cast (val
, &c
))
3464 if (host_integerp (len
, 1)
3465 && !(optimize_size
&& tree_low_cst (len
, 1) > 1)
3466 && can_store_by_pieces (tree_low_cst (len
, 1),
3467 builtin_memset_read_str
, &c
, dest_align
))
3468 store_by_pieces (dest_mem
, tree_low_cst (len
, 1),
3469 builtin_memset_read_str
, &c
, dest_align
, 0);
3470 else if (!set_storage_via_setmem (dest_mem
, len_rtx
, GEN_INT (c
),
3474 dest_mem
= force_operand (XEXP (dest_mem
, 0), NULL_RTX
);
3475 dest_mem
= convert_memory_address (ptr_mode
, dest_mem
);
3479 set_mem_align (dest_mem
, dest_align
);
3480 dest_addr
= clear_storage (dest_mem
, len_rtx
,
3481 CALL_EXPR_TAILCALL (orig_exp
)
3482 ? BLOCK_OP_TAILCALL
: BLOCK_OP_NORMAL
);
3486 dest_addr
= force_operand (XEXP (dest_mem
, 0), NULL_RTX
);
3487 dest_addr
= convert_memory_address (ptr_mode
, dest_addr
);
3494 /* Expand expression EXP, which is a call to the bzero builtin. Return 0
3495 if we failed the caller should emit a normal call. */
3498 expand_builtin_bzero (tree exp
)
3500 tree arglist
= TREE_OPERAND (exp
, 1);
3501 tree dest
, size
, newarglist
;
3503 if (!validate_arglist (arglist
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
3506 dest
= TREE_VALUE (arglist
);
3507 size
= TREE_VALUE (TREE_CHAIN (arglist
));
3509 /* New argument list transforming bzero(ptr x, int y) to
3510 memset(ptr x, int 0, size_t y). This is done this way
3511 so that if it isn't expanded inline, we fallback to
3512 calling bzero instead of memset. */
3514 newarglist
= build_tree_list (NULL_TREE
, fold_convert (sizetype
, size
));
3515 newarglist
= tree_cons (NULL_TREE
, integer_zero_node
, newarglist
);
3516 newarglist
= tree_cons (NULL_TREE
, dest
, newarglist
);
3518 return expand_builtin_memset (newarglist
, const0_rtx
, VOIDmode
, exp
);
3521 /* Expand expression EXP, which is a call to the memcmp built-in function.
3522 ARGLIST is the argument list for this call. Return 0 if we failed and the
3523 caller should emit a normal call, otherwise try to get the result in
3524 TARGET, if convenient (and in mode MODE, if that's convenient). */
3527 expand_builtin_memcmp (tree exp ATTRIBUTE_UNUSED
, tree arglist
, rtx target
,
3528 enum machine_mode mode
)
3530 if (!validate_arglist (arglist
,
3531 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
3535 tree result
= fold_builtin_memcmp (arglist
);
3537 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
3540 #if defined HAVE_cmpmemsi || defined HAVE_cmpstrnsi
3542 tree arg1
= TREE_VALUE (arglist
);
3543 tree arg2
= TREE_VALUE (TREE_CHAIN (arglist
));
3544 tree len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
3545 rtx arg1_rtx
, arg2_rtx
, arg3_rtx
;
3550 = get_pointer_alignment (arg1
, BIGGEST_ALIGNMENT
) / BITS_PER_UNIT
;
3552 = get_pointer_alignment (arg2
, BIGGEST_ALIGNMENT
) / BITS_PER_UNIT
;
3553 enum machine_mode insn_mode
;
3555 #ifdef HAVE_cmpmemsi
3557 insn_mode
= insn_data
[(int) CODE_FOR_cmpmemsi
].operand
[0].mode
;
3560 #ifdef HAVE_cmpstrnsi
3562 insn_mode
= insn_data
[(int) CODE_FOR_cmpstrnsi
].operand
[0].mode
;
3567 /* If we don't have POINTER_TYPE, call the function. */
3568 if (arg1_align
== 0 || arg2_align
== 0)
3571 /* Make a place to write the result of the instruction. */
3574 && REG_P (result
) && GET_MODE (result
) == insn_mode
3575 && REGNO (result
) >= FIRST_PSEUDO_REGISTER
))
3576 result
= gen_reg_rtx (insn_mode
);
3578 arg1_rtx
= get_memory_rtx (arg1
, len
);
3579 arg2_rtx
= get_memory_rtx (arg2
, len
);
3580 arg3_rtx
= expand_expr (len
, NULL_RTX
, VOIDmode
, 0);
3582 /* Set MEM_SIZE as appropriate. */
3583 if (GET_CODE (arg3_rtx
) == CONST_INT
)
3585 set_mem_size (arg1_rtx
, arg3_rtx
);
3586 set_mem_size (arg2_rtx
, arg3_rtx
);
3589 #ifdef HAVE_cmpmemsi
3591 insn
= gen_cmpmemsi (result
, arg1_rtx
, arg2_rtx
, arg3_rtx
,
3592 GEN_INT (MIN (arg1_align
, arg2_align
)));
3595 #ifdef HAVE_cmpstrnsi
3597 insn
= gen_cmpstrnsi (result
, arg1_rtx
, arg2_rtx
, arg3_rtx
,
3598 GEN_INT (MIN (arg1_align
, arg2_align
)));
3606 emit_library_call_value (memcmp_libfunc
, result
, LCT_PURE_MAKE_BLOCK
,
3607 TYPE_MODE (integer_type_node
), 3,
3608 XEXP (arg1_rtx
, 0), Pmode
,
3609 XEXP (arg2_rtx
, 0), Pmode
,
3610 convert_to_mode (TYPE_MODE (sizetype
), arg3_rtx
,
3611 TYPE_UNSIGNED (sizetype
)),
3612 TYPE_MODE (sizetype
));
3614 /* Return the value in the proper mode for this function. */
3615 mode
= TYPE_MODE (TREE_TYPE (exp
));
3616 if (GET_MODE (result
) == mode
)
3618 else if (target
!= 0)
3620 convert_move (target
, result
, 0);
3624 return convert_to_mode (mode
, result
, 0);
3631 /* Expand expression EXP, which is a call to the strcmp builtin. Return 0
3632 if we failed the caller should emit a normal call, otherwise try to get
3633 the result in TARGET, if convenient. */
3636 expand_builtin_strcmp (tree exp
, rtx target
, enum machine_mode mode
)
3638 tree arglist
= TREE_OPERAND (exp
, 1);
3640 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
3644 tree result
= fold_builtin_strcmp (arglist
);
3646 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
3649 #if defined HAVE_cmpstrsi || defined HAVE_cmpstrnsi
3650 if (cmpstr_optab
[SImode
] != CODE_FOR_nothing
3651 || cmpstrn_optab
[SImode
] != CODE_FOR_nothing
)
3653 rtx arg1_rtx
, arg2_rtx
;
3654 rtx result
, insn
= NULL_RTX
;
3657 tree arg1
= TREE_VALUE (arglist
);
3658 tree arg2
= TREE_VALUE (TREE_CHAIN (arglist
));
3660 = get_pointer_alignment (arg1
, BIGGEST_ALIGNMENT
) / BITS_PER_UNIT
;
3662 = get_pointer_alignment (arg2
, BIGGEST_ALIGNMENT
) / BITS_PER_UNIT
;
3664 /* If we don't have POINTER_TYPE, call the function. */
3665 if (arg1_align
== 0 || arg2_align
== 0)
3668 /* Stabilize the arguments in case gen_cmpstr(n)si fail. */
3669 arg1
= builtin_save_expr (arg1
);
3670 arg2
= builtin_save_expr (arg2
);
3672 arg1_rtx
= get_memory_rtx (arg1
, NULL
);
3673 arg2_rtx
= get_memory_rtx (arg2
, NULL
);
3675 #ifdef HAVE_cmpstrsi
3676 /* Try to call cmpstrsi. */
3679 enum machine_mode insn_mode
3680 = insn_data
[(int) CODE_FOR_cmpstrsi
].operand
[0].mode
;
3682 /* Make a place to write the result of the instruction. */
3685 && REG_P (result
) && GET_MODE (result
) == insn_mode
3686 && REGNO (result
) >= FIRST_PSEUDO_REGISTER
))
3687 result
= gen_reg_rtx (insn_mode
);
3689 insn
= gen_cmpstrsi (result
, arg1_rtx
, arg2_rtx
,
3690 GEN_INT (MIN (arg1_align
, arg2_align
)));
3694 /* Try to determine at least one length and call cmpstrnsi. */
3695 if (!insn
&& HAVE_cmpstrnsi
)
3700 enum machine_mode insn_mode
3701 = insn_data
[(int) CODE_FOR_cmpstrnsi
].operand
[0].mode
;
3702 tree len1
= c_strlen (arg1
, 1);
3703 tree len2
= c_strlen (arg2
, 1);
3706 len1
= size_binop (PLUS_EXPR
, ssize_int (1), len1
);
3708 len2
= size_binop (PLUS_EXPR
, ssize_int (1), len2
);
3710 /* If we don't have a constant length for the first, use the length
3711 of the second, if we know it. We don't require a constant for
3712 this case; some cost analysis could be done if both are available
3713 but neither is constant. For now, assume they're equally cheap,
3714 unless one has side effects. If both strings have constant lengths,
3721 else if (TREE_SIDE_EFFECTS (len1
))
3723 else if (TREE_SIDE_EFFECTS (len2
))
3725 else if (TREE_CODE (len1
) != INTEGER_CST
)
3727 else if (TREE_CODE (len2
) != INTEGER_CST
)
3729 else if (tree_int_cst_lt (len1
, len2
))
3734 /* If both arguments have side effects, we cannot optimize. */
3735 if (!len
|| TREE_SIDE_EFFECTS (len
))
3738 /* Stabilize the arguments in case gen_cmpstrnsi fails. */
3739 arg3_rtx
= expand_expr (len
, NULL_RTX
, VOIDmode
, 0);
3741 /* Make a place to write the result of the instruction. */
3744 && REG_P (result
) && GET_MODE (result
) == insn_mode
3745 && REGNO (result
) >= FIRST_PSEUDO_REGISTER
))
3746 result
= gen_reg_rtx (insn_mode
);
3748 insn
= gen_cmpstrnsi (result
, arg1_rtx
, arg2_rtx
, arg3_rtx
,
3749 GEN_INT (MIN (arg1_align
, arg2_align
)));
3757 /* Return the value in the proper mode for this function. */
3758 mode
= TYPE_MODE (TREE_TYPE (exp
));
3759 if (GET_MODE (result
) == mode
)
3762 return convert_to_mode (mode
, result
, 0);
3763 convert_move (target
, result
, 0);
3767 /* Expand the library call ourselves using a stabilized argument
3768 list to avoid re-evaluating the function's arguments twice. */
3769 arglist
= build_tree_list (NULL_TREE
, arg2
);
3770 arglist
= tree_cons (NULL_TREE
, arg1
, arglist
);
3771 fndecl
= get_callee_fndecl (exp
);
3772 fn
= build_function_call_expr (fndecl
, arglist
);
3773 if (TREE_CODE (fn
) == CALL_EXPR
)
3774 CALL_EXPR_TAILCALL (fn
) = CALL_EXPR_TAILCALL (exp
);
3775 return expand_call (fn
, target
, target
== const0_rtx
);
3781 /* Expand expression EXP, which is a call to the strncmp builtin. Return 0
3782 if we failed the caller should emit a normal call, otherwise try to get
3783 the result in TARGET, if convenient. */
3786 expand_builtin_strncmp (tree exp
, rtx target
, enum machine_mode mode
)
3788 tree arglist
= TREE_OPERAND (exp
, 1);
3790 if (!validate_arglist (arglist
,
3791 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
3795 tree result
= fold_builtin_strncmp (arglist
);
3797 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
3800 /* If c_strlen can determine an expression for one of the string
3801 lengths, and it doesn't have side effects, then emit cmpstrnsi
3802 using length MIN(strlen(string)+1, arg3). */
3803 #ifdef HAVE_cmpstrnsi
3806 tree arg1
= TREE_VALUE (arglist
);
3807 tree arg2
= TREE_VALUE (TREE_CHAIN (arglist
));
3808 tree arg3
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
3809 tree len
, len1
, len2
;
3810 rtx arg1_rtx
, arg2_rtx
, arg3_rtx
;
3815 = get_pointer_alignment (arg1
, BIGGEST_ALIGNMENT
) / BITS_PER_UNIT
;
3817 = get_pointer_alignment (arg2
, BIGGEST_ALIGNMENT
) / BITS_PER_UNIT
;
3818 enum machine_mode insn_mode
3819 = insn_data
[(int) CODE_FOR_cmpstrnsi
].operand
[0].mode
;
3821 len1
= c_strlen (arg1
, 1);
3822 len2
= c_strlen (arg2
, 1);
3825 len1
= size_binop (PLUS_EXPR
, ssize_int (1), len1
);
3827 len2
= size_binop (PLUS_EXPR
, ssize_int (1), len2
);
3829 /* If we don't have a constant length for the first, use the length
3830 of the second, if we know it. We don't require a constant for
3831 this case; some cost analysis could be done if both are available
3832 but neither is constant. For now, assume they're equally cheap,
3833 unless one has side effects. If both strings have constant lengths,
3840 else if (TREE_SIDE_EFFECTS (len1
))
3842 else if (TREE_SIDE_EFFECTS (len2
))
3844 else if (TREE_CODE (len1
) != INTEGER_CST
)
3846 else if (TREE_CODE (len2
) != INTEGER_CST
)
3848 else if (tree_int_cst_lt (len1
, len2
))
3853 /* If both arguments have side effects, we cannot optimize. */
3854 if (!len
|| TREE_SIDE_EFFECTS (len
))
3857 /* The actual new length parameter is MIN(len,arg3). */
3858 len
= fold_build2 (MIN_EXPR
, TREE_TYPE (len
), len
,
3859 fold_convert (TREE_TYPE (len
), arg3
));
3861 /* If we don't have POINTER_TYPE, call the function. */
3862 if (arg1_align
== 0 || arg2_align
== 0)
3865 /* Make a place to write the result of the instruction. */
3868 && REG_P (result
) && GET_MODE (result
) == insn_mode
3869 && REGNO (result
) >= FIRST_PSEUDO_REGISTER
))
3870 result
= gen_reg_rtx (insn_mode
);
3872 /* Stabilize the arguments in case gen_cmpstrnsi fails. */
3873 arg1
= builtin_save_expr (arg1
);
3874 arg2
= builtin_save_expr (arg2
);
3875 len
= builtin_save_expr (len
);
3877 arg1_rtx
= get_memory_rtx (arg1
, len
);
3878 arg2_rtx
= get_memory_rtx (arg2
, len
);
3879 arg3_rtx
= expand_expr (len
, NULL_RTX
, VOIDmode
, 0);
3880 insn
= gen_cmpstrnsi (result
, arg1_rtx
, arg2_rtx
, arg3_rtx
,
3881 GEN_INT (MIN (arg1_align
, arg2_align
)));
3886 /* Return the value in the proper mode for this function. */
3887 mode
= TYPE_MODE (TREE_TYPE (exp
));
3888 if (GET_MODE (result
) == mode
)
3891 return convert_to_mode (mode
, result
, 0);
3892 convert_move (target
, result
, 0);
3896 /* Expand the library call ourselves using a stabilized argument
3897 list to avoid re-evaluating the function's arguments twice. */
3898 arglist
= build_tree_list (NULL_TREE
, len
);
3899 arglist
= tree_cons (NULL_TREE
, arg2
, arglist
);
3900 arglist
= tree_cons (NULL_TREE
, arg1
, arglist
);
3901 fndecl
= get_callee_fndecl (exp
);
3902 fn
= build_function_call_expr (fndecl
, arglist
);
3903 if (TREE_CODE (fn
) == CALL_EXPR
)
3904 CALL_EXPR_TAILCALL (fn
) = CALL_EXPR_TAILCALL (exp
);
3905 return expand_call (fn
, target
, target
== const0_rtx
);
3911 /* Expand expression EXP, which is a call to the strcat builtin.
3912 Return 0 if we failed the caller should emit a normal call,
3913 otherwise try to get the result in TARGET, if convenient. */
3916 expand_builtin_strcat (tree fndecl
, tree arglist
, rtx target
, enum machine_mode mode
)
3918 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
3922 tree dst
= TREE_VALUE (arglist
),
3923 src
= TREE_VALUE (TREE_CHAIN (arglist
));
3924 const char *p
= c_getstr (src
);
3926 /* If the string length is zero, return the dst parameter. */
3927 if (p
&& *p
== '\0')
3928 return expand_expr (dst
, target
, mode
, EXPAND_NORMAL
);
3932 /* See if we can store by pieces into (dst + strlen(dst)). */
3933 tree newsrc
, newdst
,
3934 strlen_fn
= implicit_built_in_decls
[BUILT_IN_STRLEN
];
3937 /* Stabilize the argument list. */
3938 newsrc
= builtin_save_expr (src
);
3940 arglist
= build_tree_list (NULL_TREE
, newsrc
);
3942 arglist
= TREE_CHAIN (arglist
); /* Reusing arglist if safe. */
3944 dst
= builtin_save_expr (dst
);
3948 /* Create strlen (dst). */
3950 build_function_call_expr (strlen_fn
,
3951 build_tree_list (NULL_TREE
, dst
));
3952 /* Create (dst + (cast) strlen (dst)). */
3953 newdst
= fold_convert (TREE_TYPE (dst
), newdst
);
3954 newdst
= fold_build2 (PLUS_EXPR
, TREE_TYPE (dst
), dst
, newdst
);
3956 newdst
= builtin_save_expr (newdst
);
3957 arglist
= tree_cons (NULL_TREE
, newdst
, arglist
);
3959 if (!expand_builtin_strcpy (fndecl
, arglist
, target
, mode
))
3961 end_sequence (); /* Stop sequence. */
3965 /* Output the entire sequence. */
3966 insns
= get_insns ();
3970 return expand_expr (dst
, target
, mode
, EXPAND_NORMAL
);
3977 /* Expand expression EXP, which is a call to the strncat builtin.
3978 Return 0 if we failed the caller should emit a normal call,
3979 otherwise try to get the result in TARGET, if convenient. */
3982 expand_builtin_strncat (tree arglist
, rtx target
, enum machine_mode mode
)
3984 if (validate_arglist (arglist
,
3985 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
3987 tree result
= fold_builtin_strncat (arglist
);
3989 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
3994 /* Expand expression EXP, which is a call to the strspn builtin.
3995 Return 0 if we failed the caller should emit a normal call,
3996 otherwise try to get the result in TARGET, if convenient. */
3999 expand_builtin_strspn (tree arglist
, rtx target
, enum machine_mode mode
)
4001 if (validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
4003 tree result
= fold_builtin_strspn (arglist
);
4005 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
4010 /* Expand expression EXP, which is a call to the strcspn builtin.
4011 Return 0 if we failed the caller should emit a normal call,
4012 otherwise try to get the result in TARGET, if convenient. */
4015 expand_builtin_strcspn (tree arglist
, rtx target
, enum machine_mode mode
)
4017 if (validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
4019 tree result
= fold_builtin_strcspn (arglist
);
4021 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
4026 /* Expand a call to __builtin_saveregs, generating the result in TARGET,
4027 if that's convenient. */
4030 expand_builtin_saveregs (void)
4034 /* Don't do __builtin_saveregs more than once in a function.
4035 Save the result of the first call and reuse it. */
4036 if (saveregs_value
!= 0)
4037 return saveregs_value
;
4039 /* When this function is called, it means that registers must be
4040 saved on entry to this function. So we migrate the call to the
4041 first insn of this function. */
4045 /* Do whatever the machine needs done in this case. */
4046 val
= targetm
.calls
.expand_builtin_saveregs ();
4051 saveregs_value
= val
;
4053 /* Put the insns after the NOTE that starts the function. If this
4054 is inside a start_sequence, make the outer-level insn chain current, so
4055 the code is placed at the start of the function. */
4056 push_topmost_sequence ();
4057 emit_insn_after (seq
, entry_of_function ());
4058 pop_topmost_sequence ();
4063 /* __builtin_args_info (N) returns word N of the arg space info
4064 for the current function. The number and meanings of words
4065 is controlled by the definition of CUMULATIVE_ARGS. */
4068 expand_builtin_args_info (tree arglist
)
4070 int nwords
= sizeof (CUMULATIVE_ARGS
) / sizeof (int);
4071 int *word_ptr
= (int *) ¤t_function_args_info
;
4073 gcc_assert (sizeof (CUMULATIVE_ARGS
) % sizeof (int) == 0);
4077 if (!host_integerp (TREE_VALUE (arglist
), 0))
4078 error ("argument of %<__builtin_args_info%> must be constant");
4081 HOST_WIDE_INT wordnum
= tree_low_cst (TREE_VALUE (arglist
), 0);
4083 if (wordnum
< 0 || wordnum
>= nwords
)
4084 error ("argument of %<__builtin_args_info%> out of range");
4086 return GEN_INT (word_ptr
[wordnum
]);
4090 error ("missing argument in %<__builtin_args_info%>");
4095 /* Expand a call to __builtin_next_arg. */
4098 expand_builtin_next_arg (void)
4100 /* Checking arguments is already done in fold_builtin_next_arg
4101 that must be called before this function. */
4102 return expand_binop (Pmode
, add_optab
,
4103 current_function_internal_arg_pointer
,
4104 current_function_arg_offset_rtx
,
4105 NULL_RTX
, 0, OPTAB_LIB_WIDEN
);
4108 /* Make it easier for the backends by protecting the valist argument
4109 from multiple evaluations. */
4112 stabilize_va_list (tree valist
, int needs_lvalue
)
4114 if (TREE_CODE (va_list_type_node
) == ARRAY_TYPE
)
4116 if (TREE_SIDE_EFFECTS (valist
))
4117 valist
= save_expr (valist
);
4119 /* For this case, the backends will be expecting a pointer to
4120 TREE_TYPE (va_list_type_node), but it's possible we've
4121 actually been given an array (an actual va_list_type_node).
4123 if (TREE_CODE (TREE_TYPE (valist
)) == ARRAY_TYPE
)
4125 tree p1
= build_pointer_type (TREE_TYPE (va_list_type_node
));
4126 valist
= build_fold_addr_expr_with_type (valist
, p1
);
4135 if (! TREE_SIDE_EFFECTS (valist
))
4138 pt
= build_pointer_type (va_list_type_node
);
4139 valist
= fold_build1 (ADDR_EXPR
, pt
, valist
);
4140 TREE_SIDE_EFFECTS (valist
) = 1;
4143 if (TREE_SIDE_EFFECTS (valist
))
4144 valist
= save_expr (valist
);
4145 valist
= build_fold_indirect_ref (valist
);
4151 /* The "standard" definition of va_list is void*. */
4154 std_build_builtin_va_list (void)
4156 return ptr_type_node
;
4159 /* The "standard" implementation of va_start: just assign `nextarg' to
4163 std_expand_builtin_va_start (tree valist
, rtx nextarg
)
4167 t
= build2 (MODIFY_EXPR
, TREE_TYPE (valist
), valist
,
4168 make_tree (ptr_type_node
, nextarg
));
4169 TREE_SIDE_EFFECTS (t
) = 1;
4171 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
4174 /* Expand ARGLIST, from a call to __builtin_va_start. */
4177 expand_builtin_va_start (tree arglist
)
4182 chain
= TREE_CHAIN (arglist
);
4186 error ("too few arguments to function %<va_start%>");
4190 if (fold_builtin_next_arg (chain
))
4193 nextarg
= expand_builtin_next_arg ();
4194 valist
= stabilize_va_list (TREE_VALUE (arglist
), 1);
4196 #ifdef EXPAND_BUILTIN_VA_START
4197 EXPAND_BUILTIN_VA_START (valist
, nextarg
);
4199 std_expand_builtin_va_start (valist
, nextarg
);
4205 /* The "standard" implementation of va_arg: read the value from the
4206 current (padded) address and increment by the (padded) size. */
4209 std_gimplify_va_arg_expr (tree valist
, tree type
, tree
*pre_p
, tree
*post_p
)
4211 tree addr
, t
, type_size
, rounded_size
, valist_tmp
;
4212 unsigned HOST_WIDE_INT align
, boundary
;
4215 #ifdef ARGS_GROW_DOWNWARD
4216 /* All of the alignment and movement below is for args-grow-up machines.
4217 As of 2004, there are only 3 ARGS_GROW_DOWNWARD targets, and they all
4218 implement their own specialized gimplify_va_arg_expr routines. */
4222 indirect
= pass_by_reference (NULL
, TYPE_MODE (type
), type
, false);
4224 type
= build_pointer_type (type
);
4226 align
= PARM_BOUNDARY
/ BITS_PER_UNIT
;
4227 boundary
= FUNCTION_ARG_BOUNDARY (TYPE_MODE (type
), type
) / BITS_PER_UNIT
;
4229 /* Hoist the valist value into a temporary for the moment. */
4230 valist_tmp
= get_initialized_tmp_var (valist
, pre_p
, NULL
);
4232 /* va_list pointer is aligned to PARM_BOUNDARY. If argument actually
4233 requires greater alignment, we must perform dynamic alignment. */
4234 if (boundary
> align
)
4236 t
= fold_convert (TREE_TYPE (valist
), size_int (boundary
- 1));
4237 t
= build2 (MODIFY_EXPR
, TREE_TYPE (valist
), valist_tmp
,
4238 build2 (PLUS_EXPR
, TREE_TYPE (valist
), valist_tmp
, t
));
4239 gimplify_and_add (t
, pre_p
);
4241 t
= fold_convert (TREE_TYPE (valist
), size_int (-boundary
));
4242 t
= build2 (MODIFY_EXPR
, TREE_TYPE (valist
), valist_tmp
,
4243 build2 (BIT_AND_EXPR
, TREE_TYPE (valist
), valist_tmp
, t
));
4244 gimplify_and_add (t
, pre_p
);
4249 /* If the actual alignment is less than the alignment of the type,
4250 adjust the type accordingly so that we don't assume strict alignment
4251 when deferencing the pointer. */
4252 boundary
*= BITS_PER_UNIT
;
4253 if (boundary
< TYPE_ALIGN (type
))
4255 type
= build_variant_type_copy (type
);
4256 TYPE_ALIGN (type
) = boundary
;
4259 /* Compute the rounded size of the type. */
4260 type_size
= size_in_bytes (type
);
4261 rounded_size
= round_up (type_size
, align
);
4263 /* Reduce rounded_size so it's sharable with the postqueue. */
4264 gimplify_expr (&rounded_size
, pre_p
, post_p
, is_gimple_val
, fb_rvalue
);
4268 if (PAD_VARARGS_DOWN
&& !integer_zerop (rounded_size
))
4270 /* Small args are padded downward. */
4271 t
= fold_build2 (GT_EXPR
, sizetype
, rounded_size
, size_int (align
));
4272 t
= fold_build3 (COND_EXPR
, sizetype
, t
, size_zero_node
,
4273 size_binop (MINUS_EXPR
, rounded_size
, type_size
));
4274 t
= fold_convert (TREE_TYPE (addr
), t
);
4275 addr
= fold_build2 (PLUS_EXPR
, TREE_TYPE (addr
), addr
, t
);
4278 /* Compute new value for AP. */
4279 t
= fold_convert (TREE_TYPE (valist
), rounded_size
);
4280 t
= build2 (PLUS_EXPR
, TREE_TYPE (valist
), valist_tmp
, t
);
4281 t
= build2 (MODIFY_EXPR
, TREE_TYPE (valist
), valist
, t
);
4282 gimplify_and_add (t
, pre_p
);
4284 addr
= fold_convert (build_pointer_type (type
), addr
);
4287 addr
= build_va_arg_indirect_ref (addr
);
4289 return build_va_arg_indirect_ref (addr
);
4292 /* Build an indirect-ref expression over the given TREE, which represents a
4293 piece of a va_arg() expansion. */
4295 build_va_arg_indirect_ref (tree addr
)
4297 addr
= build_fold_indirect_ref (addr
);
4299 if (flag_mudflap
) /* Don't instrument va_arg INDIRECT_REF. */
4305 /* Return a dummy expression of type TYPE in order to keep going after an
4309 dummy_object (tree type
)
4311 tree t
= convert (build_pointer_type (type
), null_pointer_node
);
4312 return build1 (INDIRECT_REF
, type
, t
);
4315 /* Gimplify __builtin_va_arg, aka VA_ARG_EXPR, which is not really a
4316 builtin function, but a very special sort of operator. */
4318 enum gimplify_status
4319 gimplify_va_arg_expr (tree
*expr_p
, tree
*pre_p
, tree
*post_p
)
4321 tree promoted_type
, want_va_type
, have_va_type
;
4322 tree valist
= TREE_OPERAND (*expr_p
, 0);
4323 tree type
= TREE_TYPE (*expr_p
);
4326 /* Verify that valist is of the proper type. */
4327 want_va_type
= va_list_type_node
;
4328 have_va_type
= TREE_TYPE (valist
);
4330 if (have_va_type
== error_mark_node
)
4333 if (TREE_CODE (want_va_type
) == ARRAY_TYPE
)
4335 /* If va_list is an array type, the argument may have decayed
4336 to a pointer type, e.g. by being passed to another function.
4337 In that case, unwrap both types so that we can compare the
4338 underlying records. */
4339 if (TREE_CODE (have_va_type
) == ARRAY_TYPE
4340 || POINTER_TYPE_P (have_va_type
))
4342 want_va_type
= TREE_TYPE (want_va_type
);
4343 have_va_type
= TREE_TYPE (have_va_type
);
4347 if (TYPE_MAIN_VARIANT (want_va_type
) != TYPE_MAIN_VARIANT (have_va_type
))
4349 error ("first argument to %<va_arg%> not of type %<va_list%>");
4353 /* Generate a diagnostic for requesting data of a type that cannot
4354 be passed through `...' due to type promotion at the call site. */
4355 else if ((promoted_type
= lang_hooks
.types
.type_promotes_to (type
))
4358 static bool gave_help
;
4360 /* Unfortunately, this is merely undefined, rather than a constraint
4361 violation, so we cannot make this an error. If this call is never
4362 executed, the program is still strictly conforming. */
4363 warning (0, "%qT is promoted to %qT when passed through %<...%>",
4364 type
, promoted_type
);
4368 warning (0, "(so you should pass %qT not %qT to %<va_arg%>)",
4369 promoted_type
, type
);
4372 /* We can, however, treat "undefined" any way we please.
4373 Call abort to encourage the user to fix the program. */
4374 inform ("if this code is reached, the program will abort");
4375 t
= build_function_call_expr (implicit_built_in_decls
[BUILT_IN_TRAP
],
4377 append_to_statement_list (t
, pre_p
);
4379 /* This is dead code, but go ahead and finish so that the
4380 mode of the result comes out right. */
4381 *expr_p
= dummy_object (type
);
4386 /* Make it easier for the backends by protecting the valist argument
4387 from multiple evaluations. */
4388 if (TREE_CODE (va_list_type_node
) == ARRAY_TYPE
)
4390 /* For this case, the backends will be expecting a pointer to
4391 TREE_TYPE (va_list_type_node), but it's possible we've
4392 actually been given an array (an actual va_list_type_node).
4394 if (TREE_CODE (TREE_TYPE (valist
)) == ARRAY_TYPE
)
4396 tree p1
= build_pointer_type (TREE_TYPE (va_list_type_node
));
4397 valist
= build_fold_addr_expr_with_type (valist
, p1
);
4399 gimplify_expr (&valist
, pre_p
, post_p
, is_gimple_val
, fb_rvalue
);
4402 gimplify_expr (&valist
, pre_p
, post_p
, is_gimple_min_lval
, fb_lvalue
);
4404 if (!targetm
.gimplify_va_arg_expr
)
4405 /* FIXME:Once most targets are converted we should merely
4406 assert this is non-null. */
4409 *expr_p
= targetm
.gimplify_va_arg_expr (valist
, type
, pre_p
, post_p
);
4414 /* Expand ARGLIST, from a call to __builtin_va_end. */
4417 expand_builtin_va_end (tree arglist
)
4419 tree valist
= TREE_VALUE (arglist
);
4421 /* Evaluate for side effects, if needed. I hate macros that don't
4423 if (TREE_SIDE_EFFECTS (valist
))
4424 expand_expr (valist
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
4429 /* Expand ARGLIST, from a call to __builtin_va_copy. We do this as a
4430 builtin rather than just as an assignment in stdarg.h because of the
4431 nastiness of array-type va_list types. */
4434 expand_builtin_va_copy (tree arglist
)
4438 dst
= TREE_VALUE (arglist
);
4439 src
= TREE_VALUE (TREE_CHAIN (arglist
));
4441 dst
= stabilize_va_list (dst
, 1);
4442 src
= stabilize_va_list (src
, 0);
4444 if (TREE_CODE (va_list_type_node
) != ARRAY_TYPE
)
4446 t
= build2 (MODIFY_EXPR
, va_list_type_node
, dst
, src
);
4447 TREE_SIDE_EFFECTS (t
) = 1;
4448 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
4452 rtx dstb
, srcb
, size
;
4454 /* Evaluate to pointers. */
4455 dstb
= expand_expr (dst
, NULL_RTX
, Pmode
, EXPAND_NORMAL
);
4456 srcb
= expand_expr (src
, NULL_RTX
, Pmode
, EXPAND_NORMAL
);
4457 size
= expand_expr (TYPE_SIZE_UNIT (va_list_type_node
), NULL_RTX
,
4458 VOIDmode
, EXPAND_NORMAL
);
4460 dstb
= convert_memory_address (Pmode
, dstb
);
4461 srcb
= convert_memory_address (Pmode
, srcb
);
4463 /* "Dereference" to BLKmode memories. */
4464 dstb
= gen_rtx_MEM (BLKmode
, dstb
);
4465 set_mem_alias_set (dstb
, get_alias_set (TREE_TYPE (TREE_TYPE (dst
))));
4466 set_mem_align (dstb
, TYPE_ALIGN (va_list_type_node
));
4467 srcb
= gen_rtx_MEM (BLKmode
, srcb
);
4468 set_mem_alias_set (srcb
, get_alias_set (TREE_TYPE (TREE_TYPE (src
))));
4469 set_mem_align (srcb
, TYPE_ALIGN (va_list_type_node
));
4472 emit_block_move (dstb
, srcb
, size
, BLOCK_OP_NORMAL
);
4478 /* Expand a call to one of the builtin functions __builtin_frame_address or
4479 __builtin_return_address. */
4482 expand_builtin_frame_address (tree fndecl
, tree arglist
)
4484 /* The argument must be a nonnegative integer constant.
4485 It counts the number of frames to scan up the stack.
4486 The value is the return address saved in that frame. */
4488 /* Warning about missing arg was already issued. */
4490 else if (! host_integerp (TREE_VALUE (arglist
), 1))
4492 if (DECL_FUNCTION_CODE (fndecl
) == BUILT_IN_FRAME_ADDRESS
)
4493 error ("invalid argument to %<__builtin_frame_address%>");
4495 error ("invalid argument to %<__builtin_return_address%>");
4501 = expand_builtin_return_addr (DECL_FUNCTION_CODE (fndecl
),
4502 tree_low_cst (TREE_VALUE (arglist
), 1));
4504 /* Some ports cannot access arbitrary stack frames. */
4507 if (DECL_FUNCTION_CODE (fndecl
) == BUILT_IN_FRAME_ADDRESS
)
4508 warning (0, "unsupported argument to %<__builtin_frame_address%>");
4510 warning (0, "unsupported argument to %<__builtin_return_address%>");
4514 /* For __builtin_frame_address, return what we've got. */
4515 if (DECL_FUNCTION_CODE (fndecl
) == BUILT_IN_FRAME_ADDRESS
)
4519 && ! CONSTANT_P (tem
))
4520 tem
= copy_to_mode_reg (Pmode
, tem
);
4525 /* Expand a call to the alloca builtin, with arguments ARGLIST. Return 0 if
4526 we failed and the caller should emit a normal call, otherwise try to get
4527 the result in TARGET, if convenient. */
4530 expand_builtin_alloca (tree arglist
, rtx target
)
4535 /* In -fmudflap-instrumented code, alloca() and __builtin_alloca()
4536 should always expand to function calls. These can be intercepted
4541 if (!validate_arglist (arglist
, INTEGER_TYPE
, VOID_TYPE
))
4544 /* Compute the argument. */
4545 op0
= expand_expr (TREE_VALUE (arglist
), NULL_RTX
, VOIDmode
, 0);
4547 /* Allocate the desired space. */
4548 result
= allocate_dynamic_stack_space (op0
, target
, BITS_PER_UNIT
);
4549 result
= convert_memory_address (ptr_mode
, result
);
4554 /* Expand a call to a unary builtin. The arguments are in ARGLIST.
4555 Return 0 if a normal call should be emitted rather than expanding the
4556 function in-line. If convenient, the result should be placed in TARGET.
4557 SUBTARGET may be used as the target for computing one of EXP's operands. */
4560 expand_builtin_unop (enum machine_mode target_mode
, tree arglist
, rtx target
,
4561 rtx subtarget
, optab op_optab
)
4564 if (!validate_arglist (arglist
, INTEGER_TYPE
, VOID_TYPE
))
4567 /* Compute the argument. */
4568 op0
= expand_expr (TREE_VALUE (arglist
), subtarget
, VOIDmode
, 0);
4569 /* Compute op, into TARGET if possible.
4570 Set TARGET to wherever the result comes back. */
4571 target
= expand_unop (TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist
))),
4572 op_optab
, op0
, target
, 1);
4573 gcc_assert (target
);
4575 return convert_to_mode (target_mode
, target
, 0);
4578 /* If the string passed to fputs is a constant and is one character
4579 long, we attempt to transform this call into __builtin_fputc(). */
4582 expand_builtin_fputs (tree arglist
, rtx target
, bool unlocked
)
4584 /* Verify the arguments in the original call. */
4585 if (validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
4587 tree result
= fold_builtin_fputs (arglist
, (target
== const0_rtx
),
4588 unlocked
, NULL_TREE
);
4590 return expand_expr (result
, target
, VOIDmode
, EXPAND_NORMAL
);
4595 /* Expand a call to __builtin_expect. We return our argument and emit a
4596 NOTE_INSN_EXPECTED_VALUE note. This is the expansion of __builtin_expect in
4597 a non-jump context. */
4600 expand_builtin_expect (tree arglist
, rtx target
)
4605 if (arglist
== NULL_TREE
4606 || TREE_CHAIN (arglist
) == NULL_TREE
)
4608 exp
= TREE_VALUE (arglist
);
4609 c
= TREE_VALUE (TREE_CHAIN (arglist
));
4611 if (TREE_CODE (c
) != INTEGER_CST
)
4613 error ("second argument to %<__builtin_expect%> must be a constant");
4614 c
= integer_zero_node
;
4617 target
= expand_expr (exp
, target
, VOIDmode
, EXPAND_NORMAL
);
4619 /* Don't bother with expected value notes for integral constants. */
4620 if (flag_guess_branch_prob
&& GET_CODE (target
) != CONST_INT
)
4622 /* We do need to force this into a register so that we can be
4623 moderately sure to be able to correctly interpret the branch
4625 target
= force_reg (GET_MODE (target
), target
);
4627 rtx_c
= expand_expr (c
, NULL_RTX
, GET_MODE (target
), EXPAND_NORMAL
);
4629 note
= emit_note (NOTE_INSN_EXPECTED_VALUE
);
4630 NOTE_EXPECTED_VALUE (note
) = gen_rtx_EQ (VOIDmode
, target
, rtx_c
);
4636 /* Like expand_builtin_expect, except do this in a jump context. This is
4637 called from do_jump if the conditional is a __builtin_expect. Return either
4638 a list of insns to emit the jump or NULL if we cannot optimize
4639 __builtin_expect. We need to optimize this at jump time so that machines
4640 like the PowerPC don't turn the test into a SCC operation, and then jump
4641 based on the test being 0/1. */
4644 expand_builtin_expect_jump (tree exp
, rtx if_false_label
, rtx if_true_label
)
4646 tree arglist
= TREE_OPERAND (exp
, 1);
4647 tree arg0
= TREE_VALUE (arglist
);
4648 tree arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
4651 /* Only handle __builtin_expect (test, 0) and
4652 __builtin_expect (test, 1). */
4653 if (TREE_CODE (TREE_TYPE (arg1
)) == INTEGER_TYPE
4654 && (integer_zerop (arg1
) || integer_onep (arg1
)))
4656 rtx insn
, drop_through_label
, temp
;
4658 /* Expand the jump insns. */
4660 do_jump (arg0
, if_false_label
, if_true_label
);
4663 drop_through_label
= get_last_insn ();
4664 if (drop_through_label
&& NOTE_P (drop_through_label
))
4665 drop_through_label
= prev_nonnote_insn (drop_through_label
);
4666 if (drop_through_label
&& !LABEL_P (drop_through_label
))
4667 drop_through_label
= NULL_RTX
;
4670 if (! if_true_label
)
4671 if_true_label
= drop_through_label
;
4672 if (! if_false_label
)
4673 if_false_label
= drop_through_label
;
4675 /* Go through and add the expect's to each of the conditional jumps. */
4677 while (insn
!= NULL_RTX
)
4679 rtx next
= NEXT_INSN (insn
);
4681 if (JUMP_P (insn
) && any_condjump_p (insn
))
4683 rtx ifelse
= SET_SRC (pc_set (insn
));
4684 rtx then_dest
= XEXP (ifelse
, 1);
4685 rtx else_dest
= XEXP (ifelse
, 2);
4688 /* First check if we recognize any of the labels. */
4689 if (GET_CODE (then_dest
) == LABEL_REF
4690 && XEXP (then_dest
, 0) == if_true_label
)
4692 else if (GET_CODE (then_dest
) == LABEL_REF
4693 && XEXP (then_dest
, 0) == if_false_label
)
4695 else if (GET_CODE (else_dest
) == LABEL_REF
4696 && XEXP (else_dest
, 0) == if_false_label
)
4698 else if (GET_CODE (else_dest
) == LABEL_REF
4699 && XEXP (else_dest
, 0) == if_true_label
)
4701 /* Otherwise check where we drop through. */
4702 else if (else_dest
== pc_rtx
)
4704 if (next
&& NOTE_P (next
))
4705 next
= next_nonnote_insn (next
);
4707 if (next
&& JUMP_P (next
)
4708 && any_uncondjump_p (next
))
4709 temp
= XEXP (SET_SRC (pc_set (next
)), 0);
4713 /* TEMP is either a CODE_LABEL, NULL_RTX or something
4714 else that can't possibly match either target label. */
4715 if (temp
== if_false_label
)
4717 else if (temp
== if_true_label
)
4720 else if (then_dest
== pc_rtx
)
4722 if (next
&& NOTE_P (next
))
4723 next
= next_nonnote_insn (next
);
4725 if (next
&& JUMP_P (next
)
4726 && any_uncondjump_p (next
))
4727 temp
= XEXP (SET_SRC (pc_set (next
)), 0);
4731 if (temp
== if_false_label
)
4733 else if (temp
== if_true_label
)
4739 /* If the test is expected to fail, reverse the
4741 if (integer_zerop (arg1
))
4743 predict_insn_def (insn
, PRED_BUILTIN_EXPECT
, taken
);
4755 expand_builtin_trap (void)
4759 emit_insn (gen_trap ());
4762 emit_library_call (abort_libfunc
, LCT_NORETURN
, VOIDmode
, 0);
4766 /* Expand a call to fabs, fabsf or fabsl with arguments ARGLIST.
4767 Return 0 if a normal call should be emitted rather than expanding
4768 the function inline. If convenient, the result should be placed
4769 in TARGET. SUBTARGET may be used as the target for computing
4773 expand_builtin_fabs (tree arglist
, rtx target
, rtx subtarget
)
4775 enum machine_mode mode
;
4779 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
4782 arg
= TREE_VALUE (arglist
);
4783 mode
= TYPE_MODE (TREE_TYPE (arg
));
4784 op0
= expand_expr (arg
, subtarget
, VOIDmode
, 0);
4785 return expand_abs (mode
, op0
, target
, 0, safe_from_p (target
, arg
, 1));
4788 /* Expand a call to copysign, copysignf, or copysignl with arguments ARGLIST.
4789 Return NULL is a normal call should be emitted rather than expanding the
4790 function inline. If convenient, the result should be placed in TARGET.
4791 SUBTARGET may be used as the target for computing the operand. */
4794 expand_builtin_copysign (tree arglist
, rtx target
, rtx subtarget
)
4799 if (!validate_arglist (arglist
, REAL_TYPE
, REAL_TYPE
, VOID_TYPE
))
4802 arg
= TREE_VALUE (arglist
);
4803 op0
= expand_expr (arg
, subtarget
, VOIDmode
, 0);
4805 arg
= TREE_VALUE (TREE_CHAIN (arglist
));
4806 op1
= expand_expr (arg
, NULL
, VOIDmode
, 0);
4808 return expand_copysign (op0
, op1
, target
);
4811 /* Create a new constant string literal and return a char* pointer to it.
4812 The STRING_CST value is the LEN characters at STR. */
4814 build_string_literal (int len
, const char *str
)
4816 tree t
, elem
, index
, type
;
4818 t
= build_string (len
, str
);
4819 elem
= build_type_variant (char_type_node
, 1, 0);
4820 index
= build_index_type (build_int_cst (NULL_TREE
, len
- 1));
4821 type
= build_array_type (elem
, index
);
4822 TREE_TYPE (t
) = type
;
4823 TREE_CONSTANT (t
) = 1;
4824 TREE_INVARIANT (t
) = 1;
4825 TREE_READONLY (t
) = 1;
4826 TREE_STATIC (t
) = 1;
4828 type
= build_pointer_type (type
);
4829 t
= build1 (ADDR_EXPR
, type
, t
);
4831 type
= build_pointer_type (elem
);
4832 t
= build1 (NOP_EXPR
, type
, t
);
4836 /* Expand EXP, a call to printf or printf_unlocked.
4837 Return 0 if a normal call should be emitted rather than transforming
4838 the function inline. If convenient, the result should be placed in
4839 TARGET with mode MODE. UNLOCKED indicates this is a printf_unlocked
4842 expand_builtin_printf (tree exp
, rtx target
, enum machine_mode mode
,
4845 tree arglist
= TREE_OPERAND (exp
, 1);
4846 tree fn_putchar
= unlocked
4847 ? implicit_built_in_decls
[BUILT_IN_PUTCHAR_UNLOCKED
]
4848 : implicit_built_in_decls
[BUILT_IN_PUTCHAR
];
4849 tree fn_puts
= unlocked
? implicit_built_in_decls
[BUILT_IN_PUTS_UNLOCKED
]
4850 : implicit_built_in_decls
[BUILT_IN_PUTS
];
4851 const char *fmt_str
;
4854 /* If the return value is used, don't do the transformation. */
4855 if (target
!= const0_rtx
)
4858 /* Verify the required arguments in the original call. */
4861 fmt
= TREE_VALUE (arglist
);
4862 if (! POINTER_TYPE_P (TREE_TYPE (fmt
)))
4864 arglist
= TREE_CHAIN (arglist
);
4866 /* Check whether the format is a literal string constant. */
4867 fmt_str
= c_getstr (fmt
);
4868 if (fmt_str
== NULL
)
4871 /* If the format specifier was "%s\n", call __builtin_puts(arg). */
4872 if (strcmp (fmt_str
, "%s\n") == 0)
4875 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist
)))
4876 || TREE_CHAIN (arglist
))
4880 /* If the format specifier was "%c", call __builtin_putchar(arg). */
4881 else if (strcmp (fmt_str
, "%c") == 0)
4884 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist
))) != INTEGER_TYPE
4885 || TREE_CHAIN (arglist
))
4891 /* We can't handle anything else with % args or %% ... yet. */
4892 if (strchr (fmt_str
, '%'))
4898 /* If the format specifier was "", printf does nothing. */
4899 if (fmt_str
[0] == '\0')
4901 /* If the format specifier has length of 1, call putchar. */
4902 if (fmt_str
[1] == '\0')
4904 /* Given printf("c"), (where c is any one character,)
4905 convert "c"[0] to an int and pass that to the replacement
4907 arg
= build_int_cst (NULL_TREE
, fmt_str
[0]);
4908 arglist
= build_tree_list (NULL_TREE
, arg
);
4913 /* If the format specifier was "string\n", call puts("string"). */
4914 size_t len
= strlen (fmt_str
);
4915 if (fmt_str
[len
- 1] == '\n')
4917 /* Create a NUL-terminated string that's one char shorter
4918 than the original, stripping off the trailing '\n'. */
4919 char *newstr
= alloca (len
);
4920 memcpy (newstr
, fmt_str
, len
- 1);
4921 newstr
[len
- 1] = 0;
4923 arg
= build_string_literal (len
, newstr
);
4924 arglist
= build_tree_list (NULL_TREE
, arg
);
4928 /* We'd like to arrange to call fputs(string,stdout) here,
4929 but we need stdout and don't have a way to get it yet. */
4936 fn
= build_function_call_expr (fn
, arglist
);
4937 if (TREE_CODE (fn
) == CALL_EXPR
)
4938 CALL_EXPR_TAILCALL (fn
) = CALL_EXPR_TAILCALL (exp
);
4939 return expand_expr (fn
, target
, mode
, EXPAND_NORMAL
);
4942 /* Expand EXP, a call to fprintf or fprintf_unlocked.
4943 Return 0 if a normal call should be emitted rather than transforming
4944 the function inline. If convenient, the result should be placed in
4945 TARGET with mode MODE. UNLOCKED indicates this is a fprintf_unlocked
4948 expand_builtin_fprintf (tree exp
, rtx target
, enum machine_mode mode
,
4951 tree arglist
= TREE_OPERAND (exp
, 1);
4952 tree fn_fputc
= unlocked
? implicit_built_in_decls
[BUILT_IN_FPUTC_UNLOCKED
]
4953 : implicit_built_in_decls
[BUILT_IN_FPUTC
];
4954 tree fn_fputs
= unlocked
? implicit_built_in_decls
[BUILT_IN_FPUTS_UNLOCKED
]
4955 : implicit_built_in_decls
[BUILT_IN_FPUTS
];
4956 const char *fmt_str
;
4957 tree fn
, fmt
, fp
, arg
;
4959 /* If the return value is used, don't do the transformation. */
4960 if (target
!= const0_rtx
)
4963 /* Verify the required arguments in the original call. */
4966 fp
= TREE_VALUE (arglist
);
4967 if (! POINTER_TYPE_P (TREE_TYPE (fp
)))
4969 arglist
= TREE_CHAIN (arglist
);
4972 fmt
= TREE_VALUE (arglist
);
4973 if (! POINTER_TYPE_P (TREE_TYPE (fmt
)))
4975 arglist
= TREE_CHAIN (arglist
);
4977 /* Check whether the format is a literal string constant. */
4978 fmt_str
= c_getstr (fmt
);
4979 if (fmt_str
== NULL
)
4982 /* If the format specifier was "%s", call __builtin_fputs(arg,fp). */
4983 if (strcmp (fmt_str
, "%s") == 0)
4986 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist
)))
4987 || TREE_CHAIN (arglist
))
4989 arg
= TREE_VALUE (arglist
);
4990 arglist
= build_tree_list (NULL_TREE
, fp
);
4991 arglist
= tree_cons (NULL_TREE
, arg
, arglist
);
4994 /* If the format specifier was "%c", call __builtin_fputc(arg,fp). */
4995 else if (strcmp (fmt_str
, "%c") == 0)
4998 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist
))) != INTEGER_TYPE
4999 || TREE_CHAIN (arglist
))
5001 arg
= TREE_VALUE (arglist
);
5002 arglist
= build_tree_list (NULL_TREE
, fp
);
5003 arglist
= tree_cons (NULL_TREE
, arg
, arglist
);
5008 /* We can't handle anything else with % args or %% ... yet. */
5009 if (strchr (fmt_str
, '%'))
5015 /* If the format specifier was "", fprintf does nothing. */
5016 if (fmt_str
[0] == '\0')
5018 /* Evaluate and ignore FILE* argument for side-effects. */
5019 expand_expr (fp
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
5023 /* When "string" doesn't contain %, replace all cases of
5024 fprintf(stream,string) with fputs(string,stream). The fputs
5025 builtin will take care of special cases like length == 1. */
5026 arglist
= build_tree_list (NULL_TREE
, fp
);
5027 arglist
= tree_cons (NULL_TREE
, fmt
, arglist
);
5033 fn
= build_function_call_expr (fn
, arglist
);
5034 if (TREE_CODE (fn
) == CALL_EXPR
)
5035 CALL_EXPR_TAILCALL (fn
) = CALL_EXPR_TAILCALL (exp
);
5036 return expand_expr (fn
, target
, mode
, EXPAND_NORMAL
);
5039 /* Expand a call to sprintf with argument list ARGLIST. Return 0 if
5040 a normal call should be emitted rather than expanding the function
5041 inline. If convenient, the result should be placed in TARGET with
5045 expand_builtin_sprintf (tree arglist
, rtx target
, enum machine_mode mode
)
5047 tree orig_arglist
, dest
, fmt
;
5048 const char *fmt_str
;
5050 orig_arglist
= arglist
;
5052 /* Verify the required arguments in the original call. */
5055 dest
= TREE_VALUE (arglist
);
5056 if (! POINTER_TYPE_P (TREE_TYPE (dest
)))
5058 arglist
= TREE_CHAIN (arglist
);
5061 fmt
= TREE_VALUE (arglist
);
5062 if (! POINTER_TYPE_P (TREE_TYPE (fmt
)))
5064 arglist
= TREE_CHAIN (arglist
);
5066 /* Check whether the format is a literal string constant. */
5067 fmt_str
= c_getstr (fmt
);
5068 if (fmt_str
== NULL
)
5071 /* If the format doesn't contain % args or %%, use strcpy. */
5072 if (strchr (fmt_str
, '%') == 0)
5074 tree fn
= implicit_built_in_decls
[BUILT_IN_STRCPY
];
5077 if (arglist
|| ! fn
)
5079 expand_expr (build_function_call_expr (fn
, orig_arglist
),
5080 const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
5081 if (target
== const0_rtx
)
5083 exp
= build_int_cst (NULL_TREE
, strlen (fmt_str
));
5084 return expand_expr (exp
, target
, mode
, EXPAND_NORMAL
);
5086 /* If the format is "%s", use strcpy if the result isn't used. */
5087 else if (strcmp (fmt_str
, "%s") == 0)
5090 fn
= implicit_built_in_decls
[BUILT_IN_STRCPY
];
5095 if (! arglist
|| TREE_CHAIN (arglist
))
5097 arg
= TREE_VALUE (arglist
);
5098 if (! POINTER_TYPE_P (TREE_TYPE (arg
)))
5101 if (target
!= const0_rtx
)
5103 len
= c_strlen (arg
, 1);
5104 if (! len
|| TREE_CODE (len
) != INTEGER_CST
)
5110 arglist
= build_tree_list (NULL_TREE
, arg
);
5111 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
5112 expand_expr (build_function_call_expr (fn
, arglist
),
5113 const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
5115 if (target
== const0_rtx
)
5117 return expand_expr (len
, target
, mode
, EXPAND_NORMAL
);
5123 /* Expand a call to either the entry or exit function profiler. */
5126 expand_builtin_profile_func (bool exitp
)
5130 this = DECL_RTL (current_function_decl
);
5131 gcc_assert (MEM_P (this));
5132 this = XEXP (this, 0);
5135 which
= profile_function_exit_libfunc
;
5137 which
= profile_function_entry_libfunc
;
5139 emit_library_call (which
, LCT_NORMAL
, VOIDmode
, 2, this, Pmode
,
5140 expand_builtin_return_addr (BUILT_IN_RETURN_ADDRESS
,
5147 /* Given a trampoline address, make sure it satisfies TRAMPOLINE_ALIGNMENT. */
5150 round_trampoline_addr (rtx tramp
)
5152 rtx temp
, addend
, mask
;
5154 /* If we don't need too much alignment, we'll have been guaranteed
5155 proper alignment by get_trampoline_type. */
5156 if (TRAMPOLINE_ALIGNMENT
<= STACK_BOUNDARY
)
5159 /* Round address up to desired boundary. */
5160 temp
= gen_reg_rtx (Pmode
);
5161 addend
= GEN_INT (TRAMPOLINE_ALIGNMENT
/ BITS_PER_UNIT
- 1);
5162 mask
= GEN_INT (-TRAMPOLINE_ALIGNMENT
/ BITS_PER_UNIT
);
5164 temp
= expand_simple_binop (Pmode
, PLUS
, tramp
, addend
,
5165 temp
, 0, OPTAB_LIB_WIDEN
);
5166 tramp
= expand_simple_binop (Pmode
, AND
, temp
, mask
,
5167 temp
, 0, OPTAB_LIB_WIDEN
);
5173 expand_builtin_init_trampoline (tree arglist
)
5175 tree t_tramp
, t_func
, t_chain
;
5176 rtx r_tramp
, r_func
, r_chain
;
5177 #ifdef TRAMPOLINE_TEMPLATE
5181 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
,
5182 POINTER_TYPE
, VOID_TYPE
))
5185 t_tramp
= TREE_VALUE (arglist
);
5186 arglist
= TREE_CHAIN (arglist
);
5187 t_func
= TREE_VALUE (arglist
);
5188 arglist
= TREE_CHAIN (arglist
);
5189 t_chain
= TREE_VALUE (arglist
);
5191 r_tramp
= expand_expr (t_tramp
, NULL_RTX
, VOIDmode
, 0);
5192 r_func
= expand_expr (t_func
, NULL_RTX
, VOIDmode
, 0);
5193 r_chain
= expand_expr (t_chain
, NULL_RTX
, VOIDmode
, 0);
5195 /* Generate insns to initialize the trampoline. */
5196 r_tramp
= round_trampoline_addr (r_tramp
);
5197 #ifdef TRAMPOLINE_TEMPLATE
5198 blktramp
= gen_rtx_MEM (BLKmode
, r_tramp
);
5199 set_mem_align (blktramp
, TRAMPOLINE_ALIGNMENT
);
5200 emit_block_move (blktramp
, assemble_trampoline_template (),
5201 GEN_INT (TRAMPOLINE_SIZE
), BLOCK_OP_NORMAL
);
5203 trampolines_created
= 1;
5204 INITIALIZE_TRAMPOLINE (r_tramp
, r_func
, r_chain
);
5210 expand_builtin_adjust_trampoline (tree arglist
)
5214 if (!validate_arglist (arglist
, POINTER_TYPE
, VOID_TYPE
))
5217 tramp
= expand_expr (TREE_VALUE (arglist
), NULL_RTX
, VOIDmode
, 0);
5218 tramp
= round_trampoline_addr (tramp
);
5219 #ifdef TRAMPOLINE_ADJUST_ADDRESS
5220 TRAMPOLINE_ADJUST_ADDRESS (tramp
);
5226 /* Expand a call to the built-in signbit, signbitf or signbitl function.
5227 Return NULL_RTX if a normal call should be emitted rather than expanding
5228 the function in-line. EXP is the expression that is a call to the builtin
5229 function; if convenient, the result should be placed in TARGET. */
5232 expand_builtin_signbit (tree exp
, rtx target
)
5234 const struct real_format
*fmt
;
5235 enum machine_mode fmode
, imode
, rmode
;
5236 HOST_WIDE_INT hi
, lo
;
5241 arglist
= TREE_OPERAND (exp
, 1);
5242 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
5245 arg
= TREE_VALUE (arglist
);
5246 fmode
= TYPE_MODE (TREE_TYPE (arg
));
5247 rmode
= TYPE_MODE (TREE_TYPE (exp
));
5248 fmt
= REAL_MODE_FORMAT (fmode
);
5250 /* For floating point formats without a sign bit, implement signbit
5252 bitpos
= fmt
->signbit_ro
;
5255 /* But we can't do this if the format supports signed zero. */
5256 if (fmt
->has_signed_zero
&& HONOR_SIGNED_ZEROS (fmode
))
5259 arg
= fold_build2 (LT_EXPR
, TREE_TYPE (exp
), arg
,
5260 build_real (TREE_TYPE (arg
), dconst0
));
5261 return expand_expr (arg
, target
, VOIDmode
, EXPAND_NORMAL
);
5264 temp
= expand_expr (arg
, NULL_RTX
, VOIDmode
, 0);
5265 if (GET_MODE_SIZE (fmode
) <= UNITS_PER_WORD
)
5267 imode
= int_mode_for_mode (fmode
);
5268 if (imode
== BLKmode
)
5270 temp
= gen_lowpart (imode
, temp
);
5275 /* Handle targets with different FP word orders. */
5276 if (FLOAT_WORDS_BIG_ENDIAN
)
5277 word
= (GET_MODE_BITSIZE (fmode
) - bitpos
) / BITS_PER_WORD
;
5279 word
= bitpos
/ BITS_PER_WORD
;
5280 temp
= operand_subword_force (temp
, word
, fmode
);
5281 bitpos
= bitpos
% BITS_PER_WORD
;
5284 /* Force the intermediate word_mode (or narrower) result into a
5285 register. This avoids attempting to create paradoxical SUBREGs
5286 of floating point modes below. */
5287 temp
= force_reg (imode
, temp
);
5289 /* If the bitpos is within the "result mode" lowpart, the operation
5290 can be implement with a single bitwise AND. Otherwise, we need
5291 a right shift and an AND. */
5293 if (bitpos
< GET_MODE_BITSIZE (rmode
))
5295 if (bitpos
< HOST_BITS_PER_WIDE_INT
)
5298 lo
= (HOST_WIDE_INT
) 1 << bitpos
;
5302 hi
= (HOST_WIDE_INT
) 1 << (bitpos
- HOST_BITS_PER_WIDE_INT
);
5307 temp
= gen_lowpart (rmode
, temp
);
5308 temp
= expand_binop (rmode
, and_optab
, temp
,
5309 immed_double_const (lo
, hi
, rmode
),
5310 NULL_RTX
, 1, OPTAB_LIB_WIDEN
);
5314 /* Perform a logical right shift to place the signbit in the least
5315 significant bit, then truncate the result to the desired mode
5316 and mask just this bit. */
5317 temp
= expand_shift (RSHIFT_EXPR
, imode
, temp
,
5318 build_int_cst (NULL_TREE
, bitpos
), NULL_RTX
, 1);
5319 temp
= gen_lowpart (rmode
, temp
);
5320 temp
= expand_binop (rmode
, and_optab
, temp
, const1_rtx
,
5321 NULL_RTX
, 1, OPTAB_LIB_WIDEN
);
5327 /* Expand fork or exec calls. TARGET is the desired target of the
5328 call. ARGLIST is the list of arguments of the call. FN is the
5329 identificator of the actual function. IGNORE is nonzero if the
5330 value is to be ignored. */
5333 expand_builtin_fork_or_exec (tree fn
, tree arglist
, rtx target
, int ignore
)
5338 /* If we are not profiling, just call the function. */
5339 if (!profile_arc_flag
)
5342 /* Otherwise call the wrapper. This should be equivalent for the rest of
5343 compiler, so the code does not diverge, and the wrapper may run the
5344 code necessary for keeping the profiling sane. */
5346 switch (DECL_FUNCTION_CODE (fn
))
5349 id
= get_identifier ("__gcov_fork");
5352 case BUILT_IN_EXECL
:
5353 id
= get_identifier ("__gcov_execl");
5356 case BUILT_IN_EXECV
:
5357 id
= get_identifier ("__gcov_execv");
5360 case BUILT_IN_EXECLP
:
5361 id
= get_identifier ("__gcov_execlp");
5364 case BUILT_IN_EXECLE
:
5365 id
= get_identifier ("__gcov_execle");
5368 case BUILT_IN_EXECVP
:
5369 id
= get_identifier ("__gcov_execvp");
5372 case BUILT_IN_EXECVE
:
5373 id
= get_identifier ("__gcov_execve");
5380 decl
= build_decl (FUNCTION_DECL
, id
, TREE_TYPE (fn
));
5381 DECL_EXTERNAL (decl
) = 1;
5382 TREE_PUBLIC (decl
) = 1;
5383 DECL_ARTIFICIAL (decl
) = 1;
5384 TREE_NOTHROW (decl
) = 1;
5385 call
= build_function_call_expr (decl
, arglist
);
5387 return expand_call (call
, target
, ignore
);
5391 /* Reconstitute a mode for a __sync intrinsic operation. Since the type of
5392 the pointer in these functions is void*, the tree optimizers may remove
5393 casts. The mode computed in expand_builtin isn't reliable either, due
5394 to __sync_bool_compare_and_swap.
5396 FCODE_DIFF should be fcode - base, where base is the FOO_1 code for the
5397 group of builtins. This gives us log2 of the mode size. */
5399 static inline enum machine_mode
5400 get_builtin_sync_mode (int fcode_diff
)
5402 /* The size is not negotiable, so ask not to get BLKmode in return
5403 if the target indicates that a smaller size would be better. */
5404 return mode_for_size (BITS_PER_UNIT
<< fcode_diff
, MODE_INT
, 0);
5407 /* Expand the __sync_xxx_and_fetch and __sync_fetch_and_xxx intrinsics.
5408 ARGLIST is the operands list to the function. CODE is the rtx code
5409 that corresponds to the arithmetic or logical operation from the name;
5410 an exception here is that NOT actually means NAND. TARGET is an optional
5411 place for us to store the results; AFTER is true if this is the
5412 fetch_and_xxx form. IGNORE is true if we don't actually care about
5413 the result of the operation at all. */
5416 expand_builtin_sync_operation (enum machine_mode mode
, tree arglist
,
5417 enum rtx_code code
, bool after
,
5418 rtx target
, bool ignore
)
5422 /* Expand the operands. */
5423 addr
= expand_expr (TREE_VALUE (arglist
), NULL
, Pmode
, EXPAND_SUM
);
5425 arglist
= TREE_CHAIN (arglist
);
5426 val
= expand_expr (TREE_VALUE (arglist
), NULL
, mode
, EXPAND_NORMAL
);
5428 /* Note that we explicitly do not want any alias information for this
5429 memory, so that we kill all other live memories. Otherwise we don't
5430 satisfy the full barrier semantics of the intrinsic. */
5431 mem
= validize_mem (gen_rtx_MEM (mode
, addr
));
5432 MEM_VOLATILE_P (mem
) = 1;
5435 return expand_sync_operation (mem
, val
, code
);
5437 return expand_sync_fetch_operation (mem
, val
, code
, after
, target
);
5440 /* Expand the __sync_val_compare_and_swap and __sync_bool_compare_and_swap
5441 intrinsics. ARGLIST is the operands list to the function. IS_BOOL is
5442 true if this is the boolean form. TARGET is a place for us to store the
5443 results; this is NOT optional if IS_BOOL is true. */
5446 expand_builtin_compare_and_swap (enum machine_mode mode
, tree arglist
,
5447 bool is_bool
, rtx target
)
5449 rtx addr
, old_val
, new_val
, mem
;
5451 /* Expand the operands. */
5452 addr
= expand_expr (TREE_VALUE (arglist
), NULL
, Pmode
, EXPAND_SUM
);
5454 arglist
= TREE_CHAIN (arglist
);
5455 old_val
= expand_expr (TREE_VALUE (arglist
), NULL
, mode
, EXPAND_NORMAL
);
5457 arglist
= TREE_CHAIN (arglist
);
5458 new_val
= expand_expr (TREE_VALUE (arglist
), NULL
, mode
, EXPAND_NORMAL
);
5460 /* Note that we explicitly do not want any alias information for this
5461 memory, so that we kill all other live memories. Otherwise we don't
5462 satisfy the full barrier semantics of the intrinsic. */
5463 mem
= validize_mem (gen_rtx_MEM (mode
, addr
));
5464 MEM_VOLATILE_P (mem
) = 1;
5467 return expand_bool_compare_and_swap (mem
, old_val
, new_val
, target
);
5469 return expand_val_compare_and_swap (mem
, old_val
, new_val
, target
);
5472 /* Expand the __sync_lock_test_and_set intrinsic. Note that the most
5473 general form is actually an atomic exchange, and some targets only
5474 support a reduced form with the second argument being a constant 1.
5475 ARGLIST is the operands list to the function; TARGET is an optional
5476 place for us to store the results. */
5479 expand_builtin_lock_test_and_set (enum machine_mode mode
, tree arglist
,
5484 /* Expand the operands. */
5485 addr
= expand_expr (TREE_VALUE (arglist
), NULL
, Pmode
, EXPAND_NORMAL
);
5487 arglist
= TREE_CHAIN (arglist
);
5488 val
= expand_expr (TREE_VALUE (arglist
), NULL
, mode
, EXPAND_NORMAL
);
5490 /* Note that we explicitly do not want any alias information for this
5491 memory, so that we kill all other live memories. Otherwise we don't
5492 satisfy the barrier semantics of the intrinsic. */
5493 mem
= validize_mem (gen_rtx_MEM (mode
, addr
));
5494 MEM_VOLATILE_P (mem
) = 1;
5496 return expand_sync_lock_test_and_set (mem
, val
, target
);
5499 /* Expand the __sync_synchronize intrinsic. */
5502 expand_builtin_synchronize (void)
5506 #ifdef HAVE_memory_barrier
5507 if (HAVE_memory_barrier
)
5509 emit_insn (gen_memory_barrier ());
5514 /* If no explicit memory barrier instruction is available, create an
5515 empty asm stmt with a memory clobber. */
5516 x
= build4 (ASM_EXPR
, void_type_node
, build_string (0, ""), NULL
, NULL
,
5517 tree_cons (NULL
, build_string (6, "memory"), NULL
));
5518 ASM_VOLATILE_P (x
) = 1;
5519 expand_asm_expr (x
);
5522 /* Expand the __sync_lock_release intrinsic. ARGLIST is the operands list
5526 expand_builtin_lock_release (enum machine_mode mode
, tree arglist
)
5528 enum insn_code icode
;
5529 rtx addr
, mem
, insn
;
5530 rtx val
= const0_rtx
;
5532 /* Expand the operands. */
5533 addr
= expand_expr (TREE_VALUE (arglist
), NULL
, Pmode
, EXPAND_NORMAL
);
5535 /* Note that we explicitly do not want any alias information for this
5536 memory, so that we kill all other live memories. Otherwise we don't
5537 satisfy the barrier semantics of the intrinsic. */
5538 mem
= validize_mem (gen_rtx_MEM (mode
, addr
));
5539 MEM_VOLATILE_P (mem
) = 1;
5541 /* If there is an explicit operation in the md file, use it. */
5542 icode
= sync_lock_release
[mode
];
5543 if (icode
!= CODE_FOR_nothing
)
5545 if (!insn_data
[icode
].operand
[1].predicate (val
, mode
))
5546 val
= force_reg (mode
, val
);
5548 insn
= GEN_FCN (icode
) (mem
, val
);
5556 /* Otherwise we can implement this operation by emitting a barrier
5557 followed by a store of zero. */
5558 expand_builtin_synchronize ();
5559 emit_move_insn (mem
, val
);
5562 /* Expand an expression EXP that calls a built-in function,
5563 with result going to TARGET if that's convenient
5564 (and in mode MODE if that's convenient).
5565 SUBTARGET may be used as the target for computing one of EXP's operands.
5566 IGNORE is nonzero if the value is to be ignored. */
5569 expand_builtin (tree exp
, rtx target
, rtx subtarget
, enum machine_mode mode
,
5572 tree fndecl
= get_callee_fndecl (exp
);
5573 tree arglist
= TREE_OPERAND (exp
, 1);
5574 enum built_in_function fcode
= DECL_FUNCTION_CODE (fndecl
);
5575 enum machine_mode target_mode
= TYPE_MODE (TREE_TYPE (exp
));
5577 if (DECL_BUILT_IN_CLASS (fndecl
) == BUILT_IN_MD
)
5578 return targetm
.expand_builtin (exp
, target
, subtarget
, mode
, ignore
);
5580 /* When not optimizing, generate calls to library functions for a certain
5583 && !called_as_built_in (fndecl
)
5584 && DECL_ASSEMBLER_NAME_SET_P (fndecl
)
5585 && fcode
!= BUILT_IN_ALLOCA
)
5586 return expand_call (exp
, target
, ignore
);
5588 /* The built-in function expanders test for target == const0_rtx
5589 to determine whether the function's result will be ignored. */
5591 target
= const0_rtx
;
5593 /* If the result of a pure or const built-in function is ignored, and
5594 none of its arguments are volatile, we can avoid expanding the
5595 built-in call and just evaluate the arguments for side-effects. */
5596 if (target
== const0_rtx
5597 && (DECL_IS_PURE (fndecl
) || TREE_READONLY (fndecl
)))
5599 bool volatilep
= false;
5602 for (arg
= arglist
; arg
; arg
= TREE_CHAIN (arg
))
5603 if (TREE_THIS_VOLATILE (TREE_VALUE (arg
)))
5611 for (arg
= arglist
; arg
; arg
= TREE_CHAIN (arg
))
5612 expand_expr (TREE_VALUE (arg
), const0_rtx
,
5613 VOIDmode
, EXPAND_NORMAL
);
5621 case BUILT_IN_FABSF
:
5622 case BUILT_IN_FABSL
:
5623 target
= expand_builtin_fabs (arglist
, target
, subtarget
);
5628 case BUILT_IN_COPYSIGN
:
5629 case BUILT_IN_COPYSIGNF
:
5630 case BUILT_IN_COPYSIGNL
:
5631 target
= expand_builtin_copysign (arglist
, target
, subtarget
);
5636 /* Just do a normal library call if we were unable to fold
5639 case BUILT_IN_CABSF
:
5640 case BUILT_IN_CABSL
:
5646 case BUILT_IN_EXP10
:
5647 case BUILT_IN_EXP10F
:
5648 case BUILT_IN_EXP10L
:
5649 case BUILT_IN_POW10
:
5650 case BUILT_IN_POW10F
:
5651 case BUILT_IN_POW10L
:
5653 case BUILT_IN_EXP2F
:
5654 case BUILT_IN_EXP2L
:
5655 case BUILT_IN_EXPM1
:
5656 case BUILT_IN_EXPM1F
:
5657 case BUILT_IN_EXPM1L
:
5659 case BUILT_IN_LOGBF
:
5660 case BUILT_IN_LOGBL
:
5661 case BUILT_IN_ILOGB
:
5662 case BUILT_IN_ILOGBF
:
5663 case BUILT_IN_ILOGBL
:
5667 case BUILT_IN_LOG10
:
5668 case BUILT_IN_LOG10F
:
5669 case BUILT_IN_LOG10L
:
5671 case BUILT_IN_LOG2F
:
5672 case BUILT_IN_LOG2L
:
5673 case BUILT_IN_LOG1P
:
5674 case BUILT_IN_LOG1PF
:
5675 case BUILT_IN_LOG1PL
:
5680 case BUILT_IN_ASINF
:
5681 case BUILT_IN_ASINL
:
5683 case BUILT_IN_ACOSF
:
5684 case BUILT_IN_ACOSL
:
5686 case BUILT_IN_ATANF
:
5687 case BUILT_IN_ATANL
:
5688 /* Treat these like sqrt only if unsafe math optimizations are allowed,
5689 because of possible accuracy problems. */
5690 if (! flag_unsafe_math_optimizations
)
5693 case BUILT_IN_SQRTF
:
5694 case BUILT_IN_SQRTL
:
5695 case BUILT_IN_FLOOR
:
5696 case BUILT_IN_FLOORF
:
5697 case BUILT_IN_FLOORL
:
5699 case BUILT_IN_CEILF
:
5700 case BUILT_IN_CEILL
:
5701 case BUILT_IN_TRUNC
:
5702 case BUILT_IN_TRUNCF
:
5703 case BUILT_IN_TRUNCL
:
5704 case BUILT_IN_ROUND
:
5705 case BUILT_IN_ROUNDF
:
5706 case BUILT_IN_ROUNDL
:
5707 case BUILT_IN_NEARBYINT
:
5708 case BUILT_IN_NEARBYINTF
:
5709 case BUILT_IN_NEARBYINTL
:
5711 case BUILT_IN_RINTF
:
5712 case BUILT_IN_RINTL
:
5713 case BUILT_IN_LRINT
:
5714 case BUILT_IN_LRINTF
:
5715 case BUILT_IN_LRINTL
:
5716 case BUILT_IN_LLRINT
:
5717 case BUILT_IN_LLRINTF
:
5718 case BUILT_IN_LLRINTL
:
5719 target
= expand_builtin_mathfn (exp
, target
, subtarget
);
5724 case BUILT_IN_LCEIL
:
5725 case BUILT_IN_LCEILF
:
5726 case BUILT_IN_LCEILL
:
5727 case BUILT_IN_LLCEIL
:
5728 case BUILT_IN_LLCEILF
:
5729 case BUILT_IN_LLCEILL
:
5730 case BUILT_IN_LFLOOR
:
5731 case BUILT_IN_LFLOORF
:
5732 case BUILT_IN_LFLOORL
:
5733 case BUILT_IN_LLFLOOR
:
5734 case BUILT_IN_LLFLOORF
:
5735 case BUILT_IN_LLFLOORL
:
5736 target
= expand_builtin_int_roundingfn (exp
, target
, subtarget
);
5744 target
= expand_builtin_pow (exp
, target
, subtarget
);
5750 case BUILT_IN_POWIF
:
5751 case BUILT_IN_POWIL
:
5752 target
= expand_builtin_powi (exp
, target
, subtarget
);
5757 case BUILT_IN_ATAN2
:
5758 case BUILT_IN_ATAN2F
:
5759 case BUILT_IN_ATAN2L
:
5760 case BUILT_IN_LDEXP
:
5761 case BUILT_IN_LDEXPF
:
5762 case BUILT_IN_LDEXPL
:
5764 case BUILT_IN_FMODF
:
5765 case BUILT_IN_FMODL
:
5767 case BUILT_IN_DREMF
:
5768 case BUILT_IN_DREML
:
5769 if (! flag_unsafe_math_optimizations
)
5771 target
= expand_builtin_mathfn_2 (exp
, target
, subtarget
);
5782 if (! flag_unsafe_math_optimizations
)
5784 target
= expand_builtin_mathfn_3 (exp
, target
, subtarget
);
5789 case BUILT_IN_APPLY_ARGS
:
5790 return expand_builtin_apply_args ();
5792 /* __builtin_apply (FUNCTION, ARGUMENTS, ARGSIZE) invokes
5793 FUNCTION with a copy of the parameters described by
5794 ARGUMENTS, and ARGSIZE. It returns a block of memory
5795 allocated on the stack into which is stored all the registers
5796 that might possibly be used for returning the result of a
5797 function. ARGUMENTS is the value returned by
5798 __builtin_apply_args. ARGSIZE is the number of bytes of
5799 arguments that must be copied. ??? How should this value be
5800 computed? We'll also need a safe worst case value for varargs
5802 case BUILT_IN_APPLY
:
5803 if (!validate_arglist (arglist
, POINTER_TYPE
,
5804 POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
)
5805 && !validate_arglist (arglist
, REFERENCE_TYPE
,
5806 POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
5814 for (t
= arglist
, i
= 0; t
; t
= TREE_CHAIN (t
), i
++)
5815 ops
[i
] = expand_expr (TREE_VALUE (t
), NULL_RTX
, VOIDmode
, 0);
5817 return expand_builtin_apply (ops
[0], ops
[1], ops
[2]);
5820 /* __builtin_return (RESULT) causes the function to return the
5821 value described by RESULT. RESULT is address of the block of
5822 memory returned by __builtin_apply. */
5823 case BUILT_IN_RETURN
:
5824 if (validate_arglist (arglist
, POINTER_TYPE
, VOID_TYPE
))
5825 expand_builtin_return (expand_expr (TREE_VALUE (arglist
),
5826 NULL_RTX
, VOIDmode
, 0));
5829 case BUILT_IN_SAVEREGS
:
5830 return expand_builtin_saveregs ();
5832 case BUILT_IN_ARGS_INFO
:
5833 return expand_builtin_args_info (arglist
);
5835 /* Return the address of the first anonymous stack arg. */
5836 case BUILT_IN_NEXT_ARG
:
5837 if (fold_builtin_next_arg (arglist
))
5839 return expand_builtin_next_arg ();
5841 case BUILT_IN_CLASSIFY_TYPE
:
5842 return expand_builtin_classify_type (arglist
);
5844 case BUILT_IN_CONSTANT_P
:
5847 case BUILT_IN_FRAME_ADDRESS
:
5848 case BUILT_IN_RETURN_ADDRESS
:
5849 return expand_builtin_frame_address (fndecl
, arglist
);
5851 /* Returns the address of the area where the structure is returned.
5853 case BUILT_IN_AGGREGATE_INCOMING_ADDRESS
:
5855 || ! AGGREGATE_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl
)))
5856 || !MEM_P (DECL_RTL (DECL_RESULT (current_function_decl
))))
5859 return XEXP (DECL_RTL (DECL_RESULT (current_function_decl
)), 0);
5861 case BUILT_IN_ALLOCA
:
5862 target
= expand_builtin_alloca (arglist
, target
);
5867 case BUILT_IN_STACK_SAVE
:
5868 return expand_stack_save ();
5870 case BUILT_IN_STACK_RESTORE
:
5871 expand_stack_restore (TREE_VALUE (arglist
));
5876 case BUILT_IN_FFSLL
:
5877 case BUILT_IN_FFSIMAX
:
5878 target
= expand_builtin_unop (target_mode
, arglist
, target
,
5879 subtarget
, ffs_optab
);
5886 case BUILT_IN_CLZLL
:
5887 case BUILT_IN_CLZIMAX
:
5888 target
= expand_builtin_unop (target_mode
, arglist
, target
,
5889 subtarget
, clz_optab
);
5896 case BUILT_IN_CTZLL
:
5897 case BUILT_IN_CTZIMAX
:
5898 target
= expand_builtin_unop (target_mode
, arglist
, target
,
5899 subtarget
, ctz_optab
);
5904 case BUILT_IN_POPCOUNT
:
5905 case BUILT_IN_POPCOUNTL
:
5906 case BUILT_IN_POPCOUNTLL
:
5907 case BUILT_IN_POPCOUNTIMAX
:
5908 target
= expand_builtin_unop (target_mode
, arglist
, target
,
5909 subtarget
, popcount_optab
);
5914 case BUILT_IN_PARITY
:
5915 case BUILT_IN_PARITYL
:
5916 case BUILT_IN_PARITYLL
:
5917 case BUILT_IN_PARITYIMAX
:
5918 target
= expand_builtin_unop (target_mode
, arglist
, target
,
5919 subtarget
, parity_optab
);
5924 case BUILT_IN_STRLEN
:
5925 target
= expand_builtin_strlen (arglist
, target
, target_mode
);
5930 case BUILT_IN_STRCPY
:
5931 target
= expand_builtin_strcpy (fndecl
, arglist
, target
, mode
);
5936 case BUILT_IN_STRNCPY
:
5937 target
= expand_builtin_strncpy (exp
, target
, mode
);
5942 case BUILT_IN_STPCPY
:
5943 target
= expand_builtin_stpcpy (exp
, target
, mode
);
5948 case BUILT_IN_STRCAT
:
5949 target
= expand_builtin_strcat (fndecl
, arglist
, target
, mode
);
5954 case BUILT_IN_STRNCAT
:
5955 target
= expand_builtin_strncat (arglist
, target
, mode
);
5960 case BUILT_IN_STRSPN
:
5961 target
= expand_builtin_strspn (arglist
, target
, mode
);
5966 case BUILT_IN_STRCSPN
:
5967 target
= expand_builtin_strcspn (arglist
, target
, mode
);
5972 case BUILT_IN_STRSTR
:
5973 target
= expand_builtin_strstr (arglist
, TREE_TYPE (exp
), target
, mode
);
5978 case BUILT_IN_STRPBRK
:
5979 target
= expand_builtin_strpbrk (arglist
, TREE_TYPE (exp
), target
, mode
);
5984 case BUILT_IN_INDEX
:
5985 case BUILT_IN_STRCHR
:
5986 target
= expand_builtin_strchr (arglist
, TREE_TYPE (exp
), target
, mode
);
5991 case BUILT_IN_RINDEX
:
5992 case BUILT_IN_STRRCHR
:
5993 target
= expand_builtin_strrchr (arglist
, TREE_TYPE (exp
), target
, mode
);
5998 case BUILT_IN_MEMCPY
:
5999 target
= expand_builtin_memcpy (exp
, target
, mode
);
6004 case BUILT_IN_MEMPCPY
:
6005 target
= expand_builtin_mempcpy (arglist
, TREE_TYPE (exp
), target
, mode
, /*endp=*/ 1);
6010 case BUILT_IN_MEMMOVE
:
6011 target
= expand_builtin_memmove (arglist
, TREE_TYPE (exp
), target
,
6017 case BUILT_IN_BCOPY
:
6018 target
= expand_builtin_bcopy (exp
);
6023 case BUILT_IN_MEMSET
:
6024 target
= expand_builtin_memset (arglist
, target
, mode
, exp
);
6029 case BUILT_IN_BZERO
:
6030 target
= expand_builtin_bzero (exp
);
6035 case BUILT_IN_STRCMP
:
6036 target
= expand_builtin_strcmp (exp
, target
, mode
);
6041 case BUILT_IN_STRNCMP
:
6042 target
= expand_builtin_strncmp (exp
, target
, mode
);
6048 case BUILT_IN_MEMCMP
:
6049 target
= expand_builtin_memcmp (exp
, arglist
, target
, mode
);
6054 case BUILT_IN_SETJMP
:
6055 target
= expand_builtin_setjmp (arglist
, target
);
6060 /* __builtin_longjmp is passed a pointer to an array of five words.
6061 It's similar to the C library longjmp function but works with
6062 __builtin_setjmp above. */
6063 case BUILT_IN_LONGJMP
:
6064 if (!validate_arglist (arglist
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
6068 rtx buf_addr
= expand_expr (TREE_VALUE (arglist
), subtarget
,
6070 rtx value
= expand_expr (TREE_VALUE (TREE_CHAIN (arglist
)),
6071 NULL_RTX
, VOIDmode
, 0);
6073 if (value
!= const1_rtx
)
6075 error ("%<__builtin_longjmp%> second argument must be 1");
6079 expand_builtin_longjmp (buf_addr
, value
);
6083 case BUILT_IN_NONLOCAL_GOTO
:
6084 target
= expand_builtin_nonlocal_goto (arglist
);
6089 /* This updates the setjmp buffer that is its argument with the value
6090 of the current stack pointer. */
6091 case BUILT_IN_UPDATE_SETJMP_BUF
:
6092 if (validate_arglist (arglist
, POINTER_TYPE
, VOID_TYPE
))
6095 = expand_expr (TREE_VALUE (arglist
), NULL_RTX
, VOIDmode
, 0);
6097 expand_builtin_update_setjmp_buf (buf_addr
);
6103 expand_builtin_trap ();
6106 case BUILT_IN_PRINTF
:
6107 target
= expand_builtin_printf (exp
, target
, mode
, false);
6112 case BUILT_IN_PRINTF_UNLOCKED
:
6113 target
= expand_builtin_printf (exp
, target
, mode
, true);
6118 case BUILT_IN_FPUTS
:
6119 target
= expand_builtin_fputs (arglist
, target
, false);
6123 case BUILT_IN_FPUTS_UNLOCKED
:
6124 target
= expand_builtin_fputs (arglist
, target
, true);
6129 case BUILT_IN_FPRINTF
:
6130 target
= expand_builtin_fprintf (exp
, target
, mode
, false);
6135 case BUILT_IN_FPRINTF_UNLOCKED
:
6136 target
= expand_builtin_fprintf (exp
, target
, mode
, true);
6141 case BUILT_IN_SPRINTF
:
6142 target
= expand_builtin_sprintf (arglist
, target
, mode
);
6147 case BUILT_IN_SIGNBIT
:
6148 case BUILT_IN_SIGNBITF
:
6149 case BUILT_IN_SIGNBITL
:
6150 target
= expand_builtin_signbit (exp
, target
);
6155 /* Various hooks for the DWARF 2 __throw routine. */
6156 case BUILT_IN_UNWIND_INIT
:
6157 expand_builtin_unwind_init ();
6159 case BUILT_IN_DWARF_CFA
:
6160 return virtual_cfa_rtx
;
6161 #ifdef DWARF2_UNWIND_INFO
6162 case BUILT_IN_DWARF_SP_COLUMN
:
6163 return expand_builtin_dwarf_sp_column ();
6164 case BUILT_IN_INIT_DWARF_REG_SIZES
:
6165 expand_builtin_init_dwarf_reg_sizes (TREE_VALUE (arglist
));
6168 case BUILT_IN_FROB_RETURN_ADDR
:
6169 return expand_builtin_frob_return_addr (TREE_VALUE (arglist
));
6170 case BUILT_IN_EXTRACT_RETURN_ADDR
:
6171 return expand_builtin_extract_return_addr (TREE_VALUE (arglist
));
6172 case BUILT_IN_EH_RETURN
:
6173 expand_builtin_eh_return (TREE_VALUE (arglist
),
6174 TREE_VALUE (TREE_CHAIN (arglist
)));
6176 #ifdef EH_RETURN_DATA_REGNO
6177 case BUILT_IN_EH_RETURN_DATA_REGNO
:
6178 return expand_builtin_eh_return_data_regno (arglist
);
6180 case BUILT_IN_EXTEND_POINTER
:
6181 return expand_builtin_extend_pointer (TREE_VALUE (arglist
));
6183 case BUILT_IN_VA_START
:
6184 case BUILT_IN_STDARG_START
:
6185 return expand_builtin_va_start (arglist
);
6186 case BUILT_IN_VA_END
:
6187 return expand_builtin_va_end (arglist
);
6188 case BUILT_IN_VA_COPY
:
6189 return expand_builtin_va_copy (arglist
);
6190 case BUILT_IN_EXPECT
:
6191 return expand_builtin_expect (arglist
, target
);
6192 case BUILT_IN_PREFETCH
:
6193 expand_builtin_prefetch (arglist
);
6196 case BUILT_IN_PROFILE_FUNC_ENTER
:
6197 return expand_builtin_profile_func (false);
6198 case BUILT_IN_PROFILE_FUNC_EXIT
:
6199 return expand_builtin_profile_func (true);
6201 case BUILT_IN_INIT_TRAMPOLINE
:
6202 return expand_builtin_init_trampoline (arglist
);
6203 case BUILT_IN_ADJUST_TRAMPOLINE
:
6204 return expand_builtin_adjust_trampoline (arglist
);
6207 case BUILT_IN_EXECL
:
6208 case BUILT_IN_EXECV
:
6209 case BUILT_IN_EXECLP
:
6210 case BUILT_IN_EXECLE
:
6211 case BUILT_IN_EXECVP
:
6212 case BUILT_IN_EXECVE
:
6213 target
= expand_builtin_fork_or_exec (fndecl
, arglist
, target
, ignore
);
6218 case BUILT_IN_FETCH_AND_ADD_1
:
6219 case BUILT_IN_FETCH_AND_ADD_2
:
6220 case BUILT_IN_FETCH_AND_ADD_4
:
6221 case BUILT_IN_FETCH_AND_ADD_8
:
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 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_FETCH_AND_SUB_1
);
6234 target
= expand_builtin_sync_operation (mode
, arglist
, MINUS
,
6235 false, target
, ignore
);
6240 case BUILT_IN_FETCH_AND_OR_1
:
6241 case BUILT_IN_FETCH_AND_OR_2
:
6242 case BUILT_IN_FETCH_AND_OR_4
:
6243 case BUILT_IN_FETCH_AND_OR_8
:
6244 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_FETCH_AND_OR_1
);
6245 target
= expand_builtin_sync_operation (mode
, arglist
, IOR
,
6246 false, target
, ignore
);
6251 case BUILT_IN_FETCH_AND_AND_1
:
6252 case BUILT_IN_FETCH_AND_AND_2
:
6253 case BUILT_IN_FETCH_AND_AND_4
:
6254 case BUILT_IN_FETCH_AND_AND_8
:
6255 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_FETCH_AND_AND_1
);
6256 target
= expand_builtin_sync_operation (mode
, arglist
, AND
,
6257 false, target
, ignore
);
6262 case BUILT_IN_FETCH_AND_XOR_1
:
6263 case BUILT_IN_FETCH_AND_XOR_2
:
6264 case BUILT_IN_FETCH_AND_XOR_4
:
6265 case BUILT_IN_FETCH_AND_XOR_8
:
6266 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_FETCH_AND_XOR_1
);
6267 target
= expand_builtin_sync_operation (mode
, arglist
, XOR
,
6268 false, target
, ignore
);
6273 case BUILT_IN_FETCH_AND_NAND_1
:
6274 case BUILT_IN_FETCH_AND_NAND_2
:
6275 case BUILT_IN_FETCH_AND_NAND_4
:
6276 case BUILT_IN_FETCH_AND_NAND_8
:
6277 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_FETCH_AND_NAND_1
);
6278 target
= expand_builtin_sync_operation (mode
, arglist
, NOT
,
6279 false, target
, ignore
);
6284 case BUILT_IN_ADD_AND_FETCH_1
:
6285 case BUILT_IN_ADD_AND_FETCH_2
:
6286 case BUILT_IN_ADD_AND_FETCH_4
:
6287 case BUILT_IN_ADD_AND_FETCH_8
:
6288 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_ADD_AND_FETCH_1
);
6289 target
= expand_builtin_sync_operation (mode
, arglist
, PLUS
,
6290 true, target
, ignore
);
6295 case BUILT_IN_SUB_AND_FETCH_1
:
6296 case BUILT_IN_SUB_AND_FETCH_2
:
6297 case BUILT_IN_SUB_AND_FETCH_4
:
6298 case BUILT_IN_SUB_AND_FETCH_8
:
6299 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_SUB_AND_FETCH_1
);
6300 target
= expand_builtin_sync_operation (mode
, arglist
, MINUS
,
6301 true, target
, ignore
);
6306 case BUILT_IN_OR_AND_FETCH_1
:
6307 case BUILT_IN_OR_AND_FETCH_2
:
6308 case BUILT_IN_OR_AND_FETCH_4
:
6309 case BUILT_IN_OR_AND_FETCH_8
:
6310 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_OR_AND_FETCH_1
);
6311 target
= expand_builtin_sync_operation (mode
, arglist
, IOR
,
6312 true, target
, ignore
);
6317 case BUILT_IN_AND_AND_FETCH_1
:
6318 case BUILT_IN_AND_AND_FETCH_2
:
6319 case BUILT_IN_AND_AND_FETCH_4
:
6320 case BUILT_IN_AND_AND_FETCH_8
:
6321 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_AND_AND_FETCH_1
);
6322 target
= expand_builtin_sync_operation (mode
, arglist
, AND
,
6323 true, target
, ignore
);
6328 case BUILT_IN_XOR_AND_FETCH_1
:
6329 case BUILT_IN_XOR_AND_FETCH_2
:
6330 case BUILT_IN_XOR_AND_FETCH_4
:
6331 case BUILT_IN_XOR_AND_FETCH_8
:
6332 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_XOR_AND_FETCH_1
);
6333 target
= expand_builtin_sync_operation (mode
, arglist
, XOR
,
6334 true, target
, ignore
);
6339 case BUILT_IN_NAND_AND_FETCH_1
:
6340 case BUILT_IN_NAND_AND_FETCH_2
:
6341 case BUILT_IN_NAND_AND_FETCH_4
:
6342 case BUILT_IN_NAND_AND_FETCH_8
:
6343 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_NAND_AND_FETCH_1
);
6344 target
= expand_builtin_sync_operation (mode
, arglist
, NOT
,
6345 true, target
, ignore
);
6350 case BUILT_IN_BOOL_COMPARE_AND_SWAP_1
:
6351 case BUILT_IN_BOOL_COMPARE_AND_SWAP_2
:
6352 case BUILT_IN_BOOL_COMPARE_AND_SWAP_4
:
6353 case BUILT_IN_BOOL_COMPARE_AND_SWAP_8
:
6354 if (mode
== VOIDmode
)
6355 mode
= TYPE_MODE (boolean_type_node
);
6356 if (!target
|| !register_operand (target
, mode
))
6357 target
= gen_reg_rtx (mode
);
6359 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_BOOL_COMPARE_AND_SWAP_1
);
6360 target
= expand_builtin_compare_and_swap (mode
, arglist
, true, target
);
6365 case BUILT_IN_VAL_COMPARE_AND_SWAP_1
:
6366 case BUILT_IN_VAL_COMPARE_AND_SWAP_2
:
6367 case BUILT_IN_VAL_COMPARE_AND_SWAP_4
:
6368 case BUILT_IN_VAL_COMPARE_AND_SWAP_8
:
6369 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_VAL_COMPARE_AND_SWAP_1
);
6370 target
= expand_builtin_compare_and_swap (mode
, arglist
, false, target
);
6375 case BUILT_IN_LOCK_TEST_AND_SET_1
:
6376 case BUILT_IN_LOCK_TEST_AND_SET_2
:
6377 case BUILT_IN_LOCK_TEST_AND_SET_4
:
6378 case BUILT_IN_LOCK_TEST_AND_SET_8
:
6379 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_LOCK_TEST_AND_SET_1
);
6380 target
= expand_builtin_lock_test_and_set (mode
, arglist
, target
);
6385 case BUILT_IN_LOCK_RELEASE_1
:
6386 case BUILT_IN_LOCK_RELEASE_2
:
6387 case BUILT_IN_LOCK_RELEASE_4
:
6388 case BUILT_IN_LOCK_RELEASE_8
:
6389 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_LOCK_RELEASE_1
);
6390 expand_builtin_lock_release (mode
, arglist
);
6393 case BUILT_IN_SYNCHRONIZE
:
6394 expand_builtin_synchronize ();
6397 case BUILT_IN_OBJECT_SIZE
:
6398 return expand_builtin_object_size (exp
);
6400 case BUILT_IN_MEMCPY_CHK
:
6401 case BUILT_IN_MEMPCPY_CHK
:
6402 case BUILT_IN_MEMMOVE_CHK
:
6403 case BUILT_IN_MEMSET_CHK
:
6404 target
= expand_builtin_memory_chk (exp
, target
, mode
, fcode
);
6409 case BUILT_IN_STRCPY_CHK
:
6410 case BUILT_IN_STPCPY_CHK
:
6411 case BUILT_IN_STRNCPY_CHK
:
6412 case BUILT_IN_STRCAT_CHK
:
6413 case BUILT_IN_SNPRINTF_CHK
:
6414 case BUILT_IN_VSNPRINTF_CHK
:
6415 maybe_emit_chk_warning (exp
, fcode
);
6418 case BUILT_IN_SPRINTF_CHK
:
6419 case BUILT_IN_VSPRINTF_CHK
:
6420 maybe_emit_sprintf_chk_warning (exp
, fcode
);
6423 default: /* just do library call, if unknown builtin */
6427 /* The switch statement above can drop through to cause the function
6428 to be called normally. */
6429 return expand_call (exp
, target
, ignore
);
6432 /* Determine whether a tree node represents a call to a built-in
6433 function. If the tree T is a call to a built-in function with
6434 the right number of arguments of the appropriate types, return
6435 the DECL_FUNCTION_CODE of the call, e.g. BUILT_IN_SQRT.
6436 Otherwise the return value is END_BUILTINS. */
6438 enum built_in_function
6439 builtin_mathfn_code (tree t
)
6441 tree fndecl
, arglist
, parmlist
;
6442 tree argtype
, parmtype
;
6444 if (TREE_CODE (t
) != CALL_EXPR
6445 || TREE_CODE (TREE_OPERAND (t
, 0)) != ADDR_EXPR
)
6446 return END_BUILTINS
;
6448 fndecl
= get_callee_fndecl (t
);
6449 if (fndecl
== NULL_TREE
6450 || TREE_CODE (fndecl
) != FUNCTION_DECL
6451 || ! DECL_BUILT_IN (fndecl
)
6452 || DECL_BUILT_IN_CLASS (fndecl
) == BUILT_IN_MD
)
6453 return END_BUILTINS
;
6455 arglist
= TREE_OPERAND (t
, 1);
6456 parmlist
= TYPE_ARG_TYPES (TREE_TYPE (fndecl
));
6457 for (; parmlist
; parmlist
= TREE_CHAIN (parmlist
))
6459 /* If a function doesn't take a variable number of arguments,
6460 the last element in the list will have type `void'. */
6461 parmtype
= TREE_VALUE (parmlist
);
6462 if (VOID_TYPE_P (parmtype
))
6465 return END_BUILTINS
;
6466 return DECL_FUNCTION_CODE (fndecl
);
6470 return END_BUILTINS
;
6472 argtype
= TREE_TYPE (TREE_VALUE (arglist
));
6474 if (SCALAR_FLOAT_TYPE_P (parmtype
))
6476 if (! SCALAR_FLOAT_TYPE_P (argtype
))
6477 return END_BUILTINS
;
6479 else if (COMPLEX_FLOAT_TYPE_P (parmtype
))
6481 if (! COMPLEX_FLOAT_TYPE_P (argtype
))
6482 return END_BUILTINS
;
6484 else if (POINTER_TYPE_P (parmtype
))
6486 if (! POINTER_TYPE_P (argtype
))
6487 return END_BUILTINS
;
6489 else if (INTEGRAL_TYPE_P (parmtype
))
6491 if (! INTEGRAL_TYPE_P (argtype
))
6492 return END_BUILTINS
;
6495 return END_BUILTINS
;
6497 arglist
= TREE_CHAIN (arglist
);
6500 /* Variable-length argument list. */
6501 return DECL_FUNCTION_CODE (fndecl
);
6504 /* Fold a call to __builtin_constant_p, if we know it will evaluate to a
6505 constant. ARGLIST is the argument list of the call. */
6508 fold_builtin_constant_p (tree arglist
)
6513 arglist
= TREE_VALUE (arglist
);
6515 /* We return 1 for a numeric type that's known to be a constant
6516 value at compile-time or for an aggregate type that's a
6517 literal constant. */
6518 STRIP_NOPS (arglist
);
6520 /* If we know this is a constant, emit the constant of one. */
6521 if (CONSTANT_CLASS_P (arglist
)
6522 || (TREE_CODE (arglist
) == CONSTRUCTOR
6523 && TREE_CONSTANT (arglist
)))
6524 return integer_one_node
;
6525 if (TREE_CODE (arglist
) == ADDR_EXPR
)
6527 tree op
= TREE_OPERAND (arglist
, 0);
6528 if (TREE_CODE (op
) == STRING_CST
6529 || (TREE_CODE (op
) == ARRAY_REF
6530 && integer_zerop (TREE_OPERAND (op
, 1))
6531 && TREE_CODE (TREE_OPERAND (op
, 0)) == STRING_CST
))
6532 return integer_one_node
;
6535 /* If this expression has side effects, show we don't know it to be a
6536 constant. Likewise if it's a pointer or aggregate type since in
6537 those case we only want literals, since those are only optimized
6538 when generating RTL, not later.
6539 And finally, if we are compiling an initializer, not code, we
6540 need to return a definite result now; there's not going to be any
6541 more optimization done. */
6542 if (TREE_SIDE_EFFECTS (arglist
)
6543 || AGGREGATE_TYPE_P (TREE_TYPE (arglist
))
6544 || POINTER_TYPE_P (TREE_TYPE (arglist
))
6546 return integer_zero_node
;
6551 /* Fold a call to __builtin_expect, if we expect that a comparison against
6552 the argument will fold to a constant. In practice, this means a true
6553 constant or the address of a non-weak symbol. ARGLIST is the argument
6554 list of the call. */
6557 fold_builtin_expect (tree arglist
)
6564 arg
= TREE_VALUE (arglist
);
6566 /* If the argument isn't invariant, then there's nothing we can do. */
6567 if (!TREE_INVARIANT (arg
))
6570 /* If we're looking at an address of a weak decl, then do not fold. */
6573 if (TREE_CODE (inner
) == ADDR_EXPR
)
6577 inner
= TREE_OPERAND (inner
, 0);
6579 while (TREE_CODE (inner
) == COMPONENT_REF
6580 || TREE_CODE (inner
) == ARRAY_REF
);
6581 if (DECL_P (inner
) && DECL_WEAK (inner
))
6585 /* Otherwise, ARG already has the proper type for the return value. */
6589 /* Fold a call to __builtin_classify_type. */
6592 fold_builtin_classify_type (tree arglist
)
6595 return build_int_cst (NULL_TREE
, no_type_class
);
6597 return build_int_cst (NULL_TREE
,
6598 type_to_class (TREE_TYPE (TREE_VALUE (arglist
))));
6601 /* Fold a call to __builtin_strlen. */
6604 fold_builtin_strlen (tree arglist
)
6606 if (!validate_arglist (arglist
, POINTER_TYPE
, VOID_TYPE
))
6610 tree len
= c_strlen (TREE_VALUE (arglist
), 0);
6614 /* Convert from the internal "sizetype" type to "size_t". */
6616 len
= fold_convert (size_type_node
, len
);
6624 /* Fold a call to __builtin_inf or __builtin_huge_val. */
6627 fold_builtin_inf (tree type
, int warn
)
6629 REAL_VALUE_TYPE real
;
6631 /* __builtin_inff is intended to be usable to define INFINITY on all
6632 targets. If an infinity is not available, INFINITY expands "to a
6633 positive constant of type float that overflows at translation
6634 time", footnote "In this case, using INFINITY will violate the
6635 constraint in 6.4.4 and thus require a diagnostic." (C99 7.12#4).
6636 Thus we pedwarn to ensure this constraint violation is
6638 if (!MODE_HAS_INFINITIES (TYPE_MODE (type
)) && warn
)
6639 pedwarn ("target format does not support infinity");
6642 return build_real (type
, real
);
6645 /* Fold a call to __builtin_nan or __builtin_nans. */
6648 fold_builtin_nan (tree arglist
, tree type
, int quiet
)
6650 REAL_VALUE_TYPE real
;
6653 if (!validate_arglist (arglist
, POINTER_TYPE
, VOID_TYPE
))
6655 str
= c_getstr (TREE_VALUE (arglist
));
6659 if (!real_nan (&real
, str
, quiet
, TYPE_MODE (type
)))
6662 return build_real (type
, real
);
6665 /* Return true if the floating point expression T has an integer value.
6666 We also allow +Inf, -Inf and NaN to be considered integer values. */
6669 integer_valued_real_p (tree t
)
6671 switch (TREE_CODE (t
))
6678 case NON_LVALUE_EXPR
:
6679 return integer_valued_real_p (TREE_OPERAND (t
, 0));
6684 return integer_valued_real_p (TREE_OPERAND (t
, 1));
6691 return integer_valued_real_p (TREE_OPERAND (t
, 0))
6692 && integer_valued_real_p (TREE_OPERAND (t
, 1));
6695 return integer_valued_real_p (TREE_OPERAND (t
, 1))
6696 && integer_valued_real_p (TREE_OPERAND (t
, 2));
6699 if (! TREE_CONSTANT_OVERFLOW (t
))
6701 REAL_VALUE_TYPE c
, cint
;
6703 c
= TREE_REAL_CST (t
);
6704 real_trunc (&cint
, TYPE_MODE (TREE_TYPE (t
)), &c
);
6705 return real_identical (&c
, &cint
);
6711 tree type
= TREE_TYPE (TREE_OPERAND (t
, 0));
6712 if (TREE_CODE (type
) == INTEGER_TYPE
)
6714 if (TREE_CODE (type
) == REAL_TYPE
)
6715 return integer_valued_real_p (TREE_OPERAND (t
, 0));
6720 switch (builtin_mathfn_code (t
))
6723 case BUILT_IN_CEILF
:
6724 case BUILT_IN_CEILL
:
6725 case BUILT_IN_FLOOR
:
6726 case BUILT_IN_FLOORF
:
6727 case BUILT_IN_FLOORL
:
6728 case BUILT_IN_NEARBYINT
:
6729 case BUILT_IN_NEARBYINTF
:
6730 case BUILT_IN_NEARBYINTL
:
6732 case BUILT_IN_RINTF
:
6733 case BUILT_IN_RINTL
:
6734 case BUILT_IN_ROUND
:
6735 case BUILT_IN_ROUNDF
:
6736 case BUILT_IN_ROUNDL
:
6737 case BUILT_IN_TRUNC
:
6738 case BUILT_IN_TRUNCF
:
6739 case BUILT_IN_TRUNCL
:
6753 /* EXP is assumed to be builtin call where truncation can be propagated
6754 across (for instance floor((double)f) == (double)floorf (f).
6755 Do the transformation. */
6758 fold_trunc_transparent_mathfn (tree fndecl
, tree arglist
)
6760 enum built_in_function fcode
= DECL_FUNCTION_CODE (fndecl
);
6763 if (! validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
6766 arg
= TREE_VALUE (arglist
);
6767 /* Integer rounding functions are idempotent. */
6768 if (fcode
== builtin_mathfn_code (arg
))
6771 /* If argument is already integer valued, and we don't need to worry
6772 about setting errno, there's no need to perform rounding. */
6773 if (! flag_errno_math
&& integer_valued_real_p (arg
))
6778 tree arg0
= strip_float_extensions (arg
);
6779 tree ftype
= TREE_TYPE (TREE_TYPE (fndecl
));
6780 tree newtype
= TREE_TYPE (arg0
);
6783 if (TYPE_PRECISION (newtype
) < TYPE_PRECISION (ftype
)
6784 && (decl
= mathfn_built_in (newtype
, fcode
)))
6787 build_tree_list (NULL_TREE
, fold_convert (newtype
, arg0
));
6788 return fold_convert (ftype
,
6789 build_function_call_expr (decl
, arglist
));
6795 /* EXP is assumed to be builtin call which can narrow the FP type of
6796 the argument, for instance lround((double)f) -> lroundf (f). */
6799 fold_fixed_mathfn (tree fndecl
, tree arglist
)
6801 enum built_in_function fcode
= DECL_FUNCTION_CODE (fndecl
);
6804 if (! validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
6807 arg
= TREE_VALUE (arglist
);
6809 /* If argument is already integer valued, and we don't need to worry
6810 about setting errno, there's no need to perform rounding. */
6811 if (! flag_errno_math
&& integer_valued_real_p (arg
))
6812 return fold_build1 (FIX_TRUNC_EXPR
, TREE_TYPE (TREE_TYPE (fndecl
)), arg
);
6816 tree ftype
= TREE_TYPE (arg
);
6817 tree arg0
= strip_float_extensions (arg
);
6818 tree newtype
= TREE_TYPE (arg0
);
6821 if (TYPE_PRECISION (newtype
) < TYPE_PRECISION (ftype
)
6822 && (decl
= mathfn_built_in (newtype
, fcode
)))
6825 build_tree_list (NULL_TREE
, fold_convert (newtype
, arg0
));
6826 return build_function_call_expr (decl
, arglist
);
6832 /* Fold function call to builtin cabs, cabsf or cabsl. ARGLIST
6833 is the argument list and TYPE is the return type. Return
6834 NULL_TREE if no if no simplification can be made. */
6837 fold_builtin_cabs (tree arglist
, tree type
)
6841 if (!arglist
|| TREE_CHAIN (arglist
))
6844 arg
= TREE_VALUE (arglist
);
6845 if (TREE_CODE (TREE_TYPE (arg
)) != COMPLEX_TYPE
6846 || TREE_CODE (TREE_TYPE (TREE_TYPE (arg
))) != REAL_TYPE
)
6849 /* Evaluate cabs of a constant at compile-time. */
6850 if (flag_unsafe_math_optimizations
6851 && TREE_CODE (arg
) == COMPLEX_CST
6852 && TREE_CODE (TREE_REALPART (arg
)) == REAL_CST
6853 && TREE_CODE (TREE_IMAGPART (arg
)) == REAL_CST
6854 && ! TREE_CONSTANT_OVERFLOW (TREE_REALPART (arg
))
6855 && ! TREE_CONSTANT_OVERFLOW (TREE_IMAGPART (arg
)))
6857 REAL_VALUE_TYPE r
, i
;
6859 r
= TREE_REAL_CST (TREE_REALPART (arg
));
6860 i
= TREE_REAL_CST (TREE_IMAGPART (arg
));
6862 real_arithmetic (&r
, MULT_EXPR
, &r
, &r
);
6863 real_arithmetic (&i
, MULT_EXPR
, &i
, &i
);
6864 real_arithmetic (&r
, PLUS_EXPR
, &r
, &i
);
6865 if (real_sqrt (&r
, TYPE_MODE (type
), &r
)
6866 || ! flag_trapping_math
)
6867 return build_real (type
, r
);
6870 /* If either part is zero, cabs is fabs of the other. */
6871 if (TREE_CODE (arg
) == COMPLEX_EXPR
6872 && real_zerop (TREE_OPERAND (arg
, 0)))
6873 return fold_build1 (ABS_EXPR
, type
, TREE_OPERAND (arg
, 1));
6874 if (TREE_CODE (arg
) == COMPLEX_EXPR
6875 && real_zerop (TREE_OPERAND (arg
, 1)))
6876 return fold_build1 (ABS_EXPR
, type
, TREE_OPERAND (arg
, 0));
6878 /* Don't do this when optimizing for size. */
6879 if (flag_unsafe_math_optimizations
6880 && optimize
&& !optimize_size
)
6882 tree sqrtfn
= mathfn_built_in (type
, BUILT_IN_SQRT
);
6884 if (sqrtfn
!= NULL_TREE
)
6886 tree rpart
, ipart
, result
, arglist
;
6888 arg
= builtin_save_expr (arg
);
6890 rpart
= fold_build1 (REALPART_EXPR
, type
, arg
);
6891 ipart
= fold_build1 (IMAGPART_EXPR
, type
, arg
);
6893 rpart
= builtin_save_expr (rpart
);
6894 ipart
= builtin_save_expr (ipart
);
6896 result
= fold_build2 (PLUS_EXPR
, type
,
6897 fold_build2 (MULT_EXPR
, type
,
6899 fold_build2 (MULT_EXPR
, type
,
6902 arglist
= build_tree_list (NULL_TREE
, result
);
6903 return build_function_call_expr (sqrtfn
, arglist
);
6910 /* Fold a builtin function call to sqrt, sqrtf, or sqrtl. Return
6911 NULL_TREE if no simplification can be made. */
6914 fold_builtin_sqrt (tree arglist
, tree type
)
6917 enum built_in_function fcode
;
6918 tree arg
= TREE_VALUE (arglist
);
6920 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
6923 /* Optimize sqrt of constant value. */
6924 if (TREE_CODE (arg
) == REAL_CST
6925 && ! TREE_CONSTANT_OVERFLOW (arg
))
6927 REAL_VALUE_TYPE r
, x
;
6929 x
= TREE_REAL_CST (arg
);
6930 if (real_sqrt (&r
, TYPE_MODE (type
), &x
)
6931 || (!flag_trapping_math
&& !flag_errno_math
))
6932 return build_real (type
, r
);
6935 /* Optimize sqrt(expN(x)) = expN(x*0.5). */
6936 fcode
= builtin_mathfn_code (arg
);
6937 if (flag_unsafe_math_optimizations
&& BUILTIN_EXPONENT_P (fcode
))
6939 tree expfn
= TREE_OPERAND (TREE_OPERAND (arg
, 0), 0);
6940 arg
= fold_build2 (MULT_EXPR
, type
,
6941 TREE_VALUE (TREE_OPERAND (arg
, 1)),
6942 build_real (type
, dconsthalf
));
6943 arglist
= build_tree_list (NULL_TREE
, arg
);
6944 return build_function_call_expr (expfn
, arglist
);
6947 /* Optimize sqrt(Nroot(x)) -> pow(x,1/(2*N)). */
6948 if (flag_unsafe_math_optimizations
&& BUILTIN_ROOT_P (fcode
))
6950 tree powfn
= mathfn_built_in (type
, BUILT_IN_POW
);
6954 tree arg0
= TREE_VALUE (TREE_OPERAND (arg
, 1));
6956 /* The inner root was either sqrt or cbrt. */
6957 REAL_VALUE_TYPE dconstroot
=
6958 BUILTIN_SQRT_P (fcode
) ? dconsthalf
: dconstthird
;
6960 /* Adjust for the outer root. */
6961 SET_REAL_EXP (&dconstroot
, REAL_EXP (&dconstroot
) - 1);
6962 dconstroot
= real_value_truncate (TYPE_MODE (type
), dconstroot
);
6963 tree_root
= build_real (type
, dconstroot
);
6964 arglist
= tree_cons (NULL_TREE
, arg0
,
6965 build_tree_list (NULL_TREE
, tree_root
));
6966 return build_function_call_expr (powfn
, arglist
);
6970 /* Optimize sqrt(pow(x,y)) = pow(|x|,y*0.5). */
6971 if (flag_unsafe_math_optimizations
6972 && (fcode
== BUILT_IN_POW
6973 || fcode
== BUILT_IN_POWF
6974 || fcode
== BUILT_IN_POWL
))
6976 tree powfn
= TREE_OPERAND (TREE_OPERAND (arg
, 0), 0);
6977 tree arg0
= TREE_VALUE (TREE_OPERAND (arg
, 1));
6978 tree arg1
= TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg
, 1)));
6980 if (!tree_expr_nonnegative_p (arg0
))
6981 arg0
= build1 (ABS_EXPR
, type
, arg0
);
6982 narg1
= fold_build2 (MULT_EXPR
, type
, arg1
,
6983 build_real (type
, dconsthalf
));
6984 arglist
= tree_cons (NULL_TREE
, arg0
,
6985 build_tree_list (NULL_TREE
, narg1
));
6986 return build_function_call_expr (powfn
, arglist
);
6992 /* Fold a builtin function call to cbrt, cbrtf, or cbrtl. Return
6993 NULL_TREE if no simplification can be made. */
6995 fold_builtin_cbrt (tree arglist
, tree type
)
6997 tree arg
= TREE_VALUE (arglist
);
6998 const enum built_in_function fcode
= builtin_mathfn_code (arg
);
7000 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
7003 /* Optimize cbrt of constant value. */
7004 if (real_zerop (arg
) || real_onep (arg
) || real_minus_onep (arg
))
7007 if (flag_unsafe_math_optimizations
)
7009 /* Optimize cbrt(expN(x)) -> expN(x/3). */
7010 if (BUILTIN_EXPONENT_P (fcode
))
7012 tree expfn
= TREE_OPERAND (TREE_OPERAND (arg
, 0), 0);
7013 const REAL_VALUE_TYPE third_trunc
=
7014 real_value_truncate (TYPE_MODE (type
), dconstthird
);
7015 arg
= fold_build2 (MULT_EXPR
, type
,
7016 TREE_VALUE (TREE_OPERAND (arg
, 1)),
7017 build_real (type
, third_trunc
));
7018 arglist
= build_tree_list (NULL_TREE
, arg
);
7019 return build_function_call_expr (expfn
, arglist
);
7022 /* Optimize cbrt(sqrt(x)) -> pow(x,1/6). */
7023 if (BUILTIN_SQRT_P (fcode
))
7025 tree powfn
= mathfn_built_in (type
, BUILT_IN_POW
);
7029 tree arg0
= TREE_VALUE (TREE_OPERAND (arg
, 1));
7031 REAL_VALUE_TYPE dconstroot
= dconstthird
;
7033 SET_REAL_EXP (&dconstroot
, REAL_EXP (&dconstroot
) - 1);
7034 dconstroot
= real_value_truncate (TYPE_MODE (type
), dconstroot
);
7035 tree_root
= build_real (type
, dconstroot
);
7036 arglist
= tree_cons (NULL_TREE
, arg0
,
7037 build_tree_list (NULL_TREE
, tree_root
));
7038 return build_function_call_expr (powfn
, arglist
);
7042 /* Optimize cbrt(cbrt(x)) -> pow(x,1/9) iff x is nonnegative. */
7043 if (BUILTIN_CBRT_P (fcode
))
7045 tree arg0
= TREE_VALUE (TREE_OPERAND (arg
, 1));
7046 if (tree_expr_nonnegative_p (arg0
))
7048 tree powfn
= mathfn_built_in (type
, BUILT_IN_POW
);
7053 REAL_VALUE_TYPE dconstroot
;
7055 real_arithmetic (&dconstroot
, MULT_EXPR
, &dconstthird
, &dconstthird
);
7056 dconstroot
= real_value_truncate (TYPE_MODE (type
), dconstroot
);
7057 tree_root
= build_real (type
, dconstroot
);
7058 arglist
= tree_cons (NULL_TREE
, arg0
,
7059 build_tree_list (NULL_TREE
, tree_root
));
7060 return build_function_call_expr (powfn
, arglist
);
7065 /* Optimize cbrt(pow(x,y)) -> pow(x,y/3) iff x is nonnegative. */
7066 if (fcode
== BUILT_IN_POW
|| fcode
== BUILT_IN_POWF
7067 || fcode
== BUILT_IN_POWL
)
7069 tree arg00
= TREE_VALUE (TREE_OPERAND (arg
, 1));
7070 tree arg01
= TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg
, 1)));
7071 if (tree_expr_nonnegative_p (arg00
))
7073 tree powfn
= TREE_OPERAND (TREE_OPERAND (arg
, 0), 0);
7074 const REAL_VALUE_TYPE dconstroot
7075 = real_value_truncate (TYPE_MODE (type
), dconstthird
);
7076 tree narg01
= fold_build2 (MULT_EXPR
, type
, arg01
,
7077 build_real (type
, dconstroot
));
7078 arglist
= tree_cons (NULL_TREE
, arg00
,
7079 build_tree_list (NULL_TREE
, narg01
));
7080 return build_function_call_expr (powfn
, arglist
);
7087 /* Fold function call to builtin sin, sinf, or sinl. Return
7088 NULL_TREE if no simplification can be made. */
7090 fold_builtin_sin (tree arglist
)
7092 tree arg
= TREE_VALUE (arglist
);
7094 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
7097 /* Optimize sin (0.0) = 0.0. */
7098 if (real_zerop (arg
))
7104 /* Fold function call to builtin cos, cosf, or cosl. Return
7105 NULL_TREE if no simplification can be made. */
7107 fold_builtin_cos (tree arglist
, tree type
, tree fndecl
)
7109 tree arg
= TREE_VALUE (arglist
);
7111 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
7114 /* Optimize cos (0.0) = 1.0. */
7115 if (real_zerop (arg
))
7116 return build_real (type
, dconst1
);
7118 /* Optimize cos(-x) into cos (x). */
7119 if (TREE_CODE (arg
) == NEGATE_EXPR
)
7121 tree args
= build_tree_list (NULL_TREE
,
7122 TREE_OPERAND (arg
, 0));
7123 return build_function_call_expr (fndecl
, args
);
7129 /* Fold function call to builtin tan, tanf, or tanl. Return
7130 NULL_TREE if no simplification can be made. */
7132 fold_builtin_tan (tree arglist
)
7134 enum built_in_function fcode
;
7135 tree arg
= TREE_VALUE (arglist
);
7137 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
7140 /* Optimize tan(0.0) = 0.0. */
7141 if (real_zerop (arg
))
7144 /* Optimize tan(atan(x)) = x. */
7145 fcode
= builtin_mathfn_code (arg
);
7146 if (flag_unsafe_math_optimizations
7147 && (fcode
== BUILT_IN_ATAN
7148 || fcode
== BUILT_IN_ATANF
7149 || fcode
== BUILT_IN_ATANL
))
7150 return TREE_VALUE (TREE_OPERAND (arg
, 1));
7155 /* Fold function call to builtin atan, atanf, or atanl. Return
7156 NULL_TREE if no simplification can be made. */
7159 fold_builtin_atan (tree arglist
, tree type
)
7162 tree arg
= TREE_VALUE (arglist
);
7164 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
7167 /* Optimize atan(0.0) = 0.0. */
7168 if (real_zerop (arg
))
7171 /* Optimize atan(1.0) = pi/4. */
7172 if (real_onep (arg
))
7174 REAL_VALUE_TYPE cst
;
7176 real_convert (&cst
, TYPE_MODE (type
), &dconstpi
);
7177 SET_REAL_EXP (&cst
, REAL_EXP (&cst
) - 2);
7178 return build_real (type
, cst
);
7184 /* Fold function call to builtin trunc, truncf or truncl. Return
7185 NULL_TREE if no simplification can be made. */
7188 fold_builtin_trunc (tree fndecl
, tree arglist
)
7192 if (! validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
7195 /* Optimize trunc of constant value. */
7196 arg
= TREE_VALUE (arglist
);
7197 if (TREE_CODE (arg
) == REAL_CST
&& ! TREE_CONSTANT_OVERFLOW (arg
))
7199 REAL_VALUE_TYPE r
, x
;
7200 tree type
= TREE_TYPE (TREE_TYPE (fndecl
));
7202 x
= TREE_REAL_CST (arg
);
7203 real_trunc (&r
, TYPE_MODE (type
), &x
);
7204 return build_real (type
, r
);
7207 return fold_trunc_transparent_mathfn (fndecl
, arglist
);
7210 /* Fold function call to builtin floor, floorf or floorl. Return
7211 NULL_TREE if no simplification can be made. */
7214 fold_builtin_floor (tree fndecl
, tree arglist
)
7218 if (! validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
7221 /* Optimize floor of constant value. */
7222 arg
= TREE_VALUE (arglist
);
7223 if (TREE_CODE (arg
) == REAL_CST
&& ! TREE_CONSTANT_OVERFLOW (arg
))
7227 x
= TREE_REAL_CST (arg
);
7228 if (! REAL_VALUE_ISNAN (x
) || ! flag_errno_math
)
7230 tree type
= TREE_TYPE (TREE_TYPE (fndecl
));
7233 real_floor (&r
, TYPE_MODE (type
), &x
);
7234 return build_real (type
, r
);
7238 return fold_trunc_transparent_mathfn (fndecl
, arglist
);
7241 /* Fold function call to builtin ceil, ceilf or ceill. Return
7242 NULL_TREE if no simplification can be made. */
7245 fold_builtin_ceil (tree fndecl
, tree arglist
)
7249 if (! validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
7252 /* Optimize ceil of constant value. */
7253 arg
= TREE_VALUE (arglist
);
7254 if (TREE_CODE (arg
) == REAL_CST
&& ! TREE_CONSTANT_OVERFLOW (arg
))
7258 x
= TREE_REAL_CST (arg
);
7259 if (! REAL_VALUE_ISNAN (x
) || ! flag_errno_math
)
7261 tree type
= TREE_TYPE (TREE_TYPE (fndecl
));
7264 real_ceil (&r
, TYPE_MODE (type
), &x
);
7265 return build_real (type
, r
);
7269 return fold_trunc_transparent_mathfn (fndecl
, arglist
);
7272 /* Fold function call to builtin round, roundf or roundl. Return
7273 NULL_TREE if no simplification can be made. */
7276 fold_builtin_round (tree fndecl
, tree arglist
)
7280 if (! validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
7283 /* Optimize round of constant value. */
7284 arg
= TREE_VALUE (arglist
);
7285 if (TREE_CODE (arg
) == REAL_CST
&& ! TREE_CONSTANT_OVERFLOW (arg
))
7289 x
= TREE_REAL_CST (arg
);
7290 if (! REAL_VALUE_ISNAN (x
) || ! flag_errno_math
)
7292 tree type
= TREE_TYPE (TREE_TYPE (fndecl
));
7295 real_round (&r
, TYPE_MODE (type
), &x
);
7296 return build_real (type
, r
);
7300 return fold_trunc_transparent_mathfn (fndecl
, arglist
);
7303 /* Fold function call to builtin lround, lroundf or lroundl (or the
7304 corresponding long long versions) and other rounding functions.
7305 Return NULL_TREE if no simplification can be made. */
7308 fold_builtin_int_roundingfn (tree fndecl
, tree arglist
)
7312 if (! validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
7315 /* Optimize lround of constant value. */
7316 arg
= TREE_VALUE (arglist
);
7317 if (TREE_CODE (arg
) == REAL_CST
&& ! TREE_CONSTANT_OVERFLOW (arg
))
7319 const REAL_VALUE_TYPE x
= TREE_REAL_CST (arg
);
7321 if (! REAL_VALUE_ISNAN (x
) && ! REAL_VALUE_ISINF (x
))
7323 tree itype
= TREE_TYPE (TREE_TYPE (fndecl
));
7324 tree ftype
= TREE_TYPE (arg
), result
;
7325 HOST_WIDE_INT hi
, lo
;
7328 switch (DECL_FUNCTION_CODE (fndecl
))
7330 case BUILT_IN_LFLOOR
:
7331 case BUILT_IN_LFLOORF
:
7332 case BUILT_IN_LFLOORL
:
7333 case BUILT_IN_LLFLOOR
:
7334 case BUILT_IN_LLFLOORF
:
7335 case BUILT_IN_LLFLOORL
:
7336 real_floor (&r
, TYPE_MODE (ftype
), &x
);
7339 case BUILT_IN_LCEIL
:
7340 case BUILT_IN_LCEILF
:
7341 case BUILT_IN_LCEILL
:
7342 case BUILT_IN_LLCEIL
:
7343 case BUILT_IN_LLCEILF
:
7344 case BUILT_IN_LLCEILL
:
7345 real_ceil (&r
, TYPE_MODE (ftype
), &x
);
7348 case BUILT_IN_LROUND
:
7349 case BUILT_IN_LROUNDF
:
7350 case BUILT_IN_LROUNDL
:
7351 case BUILT_IN_LLROUND
:
7352 case BUILT_IN_LLROUNDF
:
7353 case BUILT_IN_LLROUNDL
:
7354 real_round (&r
, TYPE_MODE (ftype
), &x
);
7361 REAL_VALUE_TO_INT (&lo
, &hi
, r
);
7362 result
= build_int_cst_wide (NULL_TREE
, lo
, hi
);
7363 if (int_fits_type_p (result
, itype
))
7364 return fold_convert (itype
, result
);
7368 return fold_fixed_mathfn (fndecl
, arglist
);
7371 /* Fold function call to builtin ffs, clz, ctz, popcount and parity
7372 and their long and long long variants (i.e. ffsl and ffsll).
7373 Return NULL_TREE if no simplification can be made. */
7376 fold_builtin_bitop (tree fndecl
, tree arglist
)
7380 if (! validate_arglist (arglist
, INTEGER_TYPE
, VOID_TYPE
))
7383 /* Optimize for constant argument. */
7384 arg
= TREE_VALUE (arglist
);
7385 if (TREE_CODE (arg
) == INTEGER_CST
&& ! TREE_CONSTANT_OVERFLOW (arg
))
7387 HOST_WIDE_INT hi
, width
, result
;
7388 unsigned HOST_WIDE_INT lo
;
7391 type
= TREE_TYPE (arg
);
7392 width
= TYPE_PRECISION (type
);
7393 lo
= TREE_INT_CST_LOW (arg
);
7395 /* Clear all the bits that are beyond the type's precision. */
7396 if (width
> HOST_BITS_PER_WIDE_INT
)
7398 hi
= TREE_INT_CST_HIGH (arg
);
7399 if (width
< 2 * HOST_BITS_PER_WIDE_INT
)
7400 hi
&= ~((HOST_WIDE_INT
) (-1) >> (width
- HOST_BITS_PER_WIDE_INT
));
7405 if (width
< HOST_BITS_PER_WIDE_INT
)
7406 lo
&= ~((unsigned HOST_WIDE_INT
) (-1) << width
);
7409 switch (DECL_FUNCTION_CODE (fndecl
))
7413 case BUILT_IN_FFSLL
:
7415 result
= exact_log2 (lo
& -lo
) + 1;
7417 result
= HOST_BITS_PER_WIDE_INT
+ exact_log2 (hi
& -hi
) + 1;
7424 case BUILT_IN_CLZLL
:
7426 result
= width
- floor_log2 (hi
) - 1 - HOST_BITS_PER_WIDE_INT
;
7428 result
= width
- floor_log2 (lo
) - 1;
7429 else if (! CLZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type
), result
))
7435 case BUILT_IN_CTZLL
:
7437 result
= exact_log2 (lo
& -lo
);
7439 result
= HOST_BITS_PER_WIDE_INT
+ exact_log2 (hi
& -hi
);
7440 else if (! CTZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type
), result
))
7444 case BUILT_IN_POPCOUNT
:
7445 case BUILT_IN_POPCOUNTL
:
7446 case BUILT_IN_POPCOUNTLL
:
7449 result
++, lo
&= lo
- 1;
7451 result
++, hi
&= hi
- 1;
7454 case BUILT_IN_PARITY
:
7455 case BUILT_IN_PARITYL
:
7456 case BUILT_IN_PARITYLL
:
7459 result
++, lo
&= lo
- 1;
7461 result
++, hi
&= hi
- 1;
7469 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl
)), result
);
7475 /* Return true if EXPR is the real constant contained in VALUE. */
7478 real_dconstp (tree expr
, const REAL_VALUE_TYPE
*value
)
7482 return ((TREE_CODE (expr
) == REAL_CST
7483 && ! TREE_CONSTANT_OVERFLOW (expr
)
7484 && REAL_VALUES_EQUAL (TREE_REAL_CST (expr
), *value
))
7485 || (TREE_CODE (expr
) == COMPLEX_CST
7486 && real_dconstp (TREE_REALPART (expr
), value
)
7487 && real_zerop (TREE_IMAGPART (expr
))));
7490 /* A subroutine of fold_builtin to fold the various logarithmic
7491 functions. EXP is the CALL_EXPR of a call to a builtin logN
7492 function. VALUE is the base of the logN function. */
7495 fold_builtin_logarithm (tree fndecl
, tree arglist
,
7496 const REAL_VALUE_TYPE
*value
)
7498 if (validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
7500 tree type
= TREE_TYPE (TREE_TYPE (fndecl
));
7501 tree arg
= TREE_VALUE (arglist
);
7502 const enum built_in_function fcode
= builtin_mathfn_code (arg
);
7504 /* Optimize logN(1.0) = 0.0. */
7505 if (real_onep (arg
))
7506 return build_real (type
, dconst0
);
7508 /* Optimize logN(N) = 1.0. If N can't be truncated to MODE
7509 exactly, then only do this if flag_unsafe_math_optimizations. */
7510 if (exact_real_truncate (TYPE_MODE (type
), value
)
7511 || flag_unsafe_math_optimizations
)
7513 const REAL_VALUE_TYPE value_truncate
=
7514 real_value_truncate (TYPE_MODE (type
), *value
);
7515 if (real_dconstp (arg
, &value_truncate
))
7516 return build_real (type
, dconst1
);
7519 /* Special case, optimize logN(expN(x)) = x. */
7520 if (flag_unsafe_math_optimizations
7521 && ((value
== &dconste
7522 && (fcode
== BUILT_IN_EXP
7523 || fcode
== BUILT_IN_EXPF
7524 || fcode
== BUILT_IN_EXPL
))
7525 || (value
== &dconst2
7526 && (fcode
== BUILT_IN_EXP2
7527 || fcode
== BUILT_IN_EXP2F
7528 || fcode
== BUILT_IN_EXP2L
))
7529 || (value
== &dconst10
&& (BUILTIN_EXP10_P (fcode
)))))
7530 return fold_convert (type
, TREE_VALUE (TREE_OPERAND (arg
, 1)));
7532 /* Optimize logN(func()) for various exponential functions. We
7533 want to determine the value "x" and the power "exponent" in
7534 order to transform logN(x**exponent) into exponent*logN(x). */
7535 if (flag_unsafe_math_optimizations
)
7537 tree exponent
= 0, x
= 0;
7544 /* Prepare to do logN(exp(exponent) -> exponent*logN(e). */
7545 x
= build_real (type
,
7546 real_value_truncate (TYPE_MODE (type
), dconste
));
7547 exponent
= TREE_VALUE (TREE_OPERAND (arg
, 1));
7550 case BUILT_IN_EXP2F
:
7551 case BUILT_IN_EXP2L
:
7552 /* Prepare to do logN(exp2(exponent) -> exponent*logN(2). */
7553 x
= build_real (type
, dconst2
);
7554 exponent
= TREE_VALUE (TREE_OPERAND (arg
, 1));
7556 case BUILT_IN_EXP10
:
7557 case BUILT_IN_EXP10F
:
7558 case BUILT_IN_EXP10L
:
7559 case BUILT_IN_POW10
:
7560 case BUILT_IN_POW10F
:
7561 case BUILT_IN_POW10L
:
7562 /* Prepare to do logN(exp10(exponent) -> exponent*logN(10). */
7563 x
= build_real (type
, dconst10
);
7564 exponent
= TREE_VALUE (TREE_OPERAND (arg
, 1));
7567 case BUILT_IN_SQRTF
:
7568 case BUILT_IN_SQRTL
:
7569 /* Prepare to do logN(sqrt(x) -> 0.5*logN(x). */
7570 x
= TREE_VALUE (TREE_OPERAND (arg
, 1));
7571 exponent
= build_real (type
, dconsthalf
);
7574 case BUILT_IN_CBRTF
:
7575 case BUILT_IN_CBRTL
:
7576 /* Prepare to do logN(cbrt(x) -> (1/3)*logN(x). */
7577 x
= TREE_VALUE (TREE_OPERAND (arg
, 1));
7578 exponent
= build_real (type
, real_value_truncate (TYPE_MODE (type
),
7584 /* Prepare to do logN(pow(x,exponent) -> exponent*logN(x). */
7585 x
= TREE_VALUE (TREE_OPERAND (arg
, 1));
7586 exponent
= TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg
, 1)));
7592 /* Now perform the optimization. */
7596 arglist
= build_tree_list (NULL_TREE
, x
);
7597 logfn
= build_function_call_expr (fndecl
, arglist
);
7598 return fold_build2 (MULT_EXPR
, type
, exponent
, logfn
);
7606 /* Fold a builtin function call to pow, powf, or powl. Return
7607 NULL_TREE if no simplification can be made. */
7609 fold_builtin_pow (tree fndecl
, tree arglist
, tree type
)
7611 tree arg0
= TREE_VALUE (arglist
);
7612 tree arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
7614 if (!validate_arglist (arglist
, REAL_TYPE
, REAL_TYPE
, VOID_TYPE
))
7617 /* Optimize pow(1.0,y) = 1.0. */
7618 if (real_onep (arg0
))
7619 return omit_one_operand (type
, build_real (type
, dconst1
), arg1
);
7621 if (TREE_CODE (arg1
) == REAL_CST
7622 && ! TREE_CONSTANT_OVERFLOW (arg1
))
7624 REAL_VALUE_TYPE cint
;
7628 c
= TREE_REAL_CST (arg1
);
7630 /* Optimize pow(x,0.0) = 1.0. */
7631 if (REAL_VALUES_EQUAL (c
, dconst0
))
7632 return omit_one_operand (type
, build_real (type
, dconst1
),
7635 /* Optimize pow(x,1.0) = x. */
7636 if (REAL_VALUES_EQUAL (c
, dconst1
))
7639 /* Optimize pow(x,-1.0) = 1.0/x. */
7640 if (REAL_VALUES_EQUAL (c
, dconstm1
))
7641 return fold_build2 (RDIV_EXPR
, type
,
7642 build_real (type
, dconst1
), arg0
);
7644 /* Optimize pow(x,0.5) = sqrt(x). */
7645 if (flag_unsafe_math_optimizations
7646 && REAL_VALUES_EQUAL (c
, dconsthalf
))
7648 tree sqrtfn
= mathfn_built_in (type
, BUILT_IN_SQRT
);
7650 if (sqrtfn
!= NULL_TREE
)
7652 tree arglist
= build_tree_list (NULL_TREE
, arg0
);
7653 return build_function_call_expr (sqrtfn
, arglist
);
7657 /* Check for an integer exponent. */
7658 n
= real_to_integer (&c
);
7659 real_from_integer (&cint
, VOIDmode
, n
, n
< 0 ? -1 : 0, 0);
7660 if (real_identical (&c
, &cint
))
7662 /* Attempt to evaluate pow at compile-time. */
7663 if (TREE_CODE (arg0
) == REAL_CST
7664 && ! TREE_CONSTANT_OVERFLOW (arg0
))
7669 x
= TREE_REAL_CST (arg0
);
7670 inexact
= real_powi (&x
, TYPE_MODE (type
), &x
, n
);
7671 if (flag_unsafe_math_optimizations
|| !inexact
)
7672 return build_real (type
, x
);
7675 /* Strip sign ops from even integer powers. */
7676 if ((n
& 1) == 0 && flag_unsafe_math_optimizations
)
7678 tree narg0
= fold_strip_sign_ops (arg0
);
7681 arglist
= build_tree_list (NULL_TREE
, arg1
);
7682 arglist
= tree_cons (NULL_TREE
, narg0
, arglist
);
7683 return build_function_call_expr (fndecl
, arglist
);
7689 if (flag_unsafe_math_optimizations
)
7691 const enum built_in_function fcode
= builtin_mathfn_code (arg0
);
7693 /* Optimize pow(expN(x),y) = expN(x*y). */
7694 if (BUILTIN_EXPONENT_P (fcode
))
7696 tree expfn
= TREE_OPERAND (TREE_OPERAND (arg0
, 0), 0);
7697 tree arg
= TREE_VALUE (TREE_OPERAND (arg0
, 1));
7698 arg
= fold_build2 (MULT_EXPR
, type
, arg
, arg1
);
7699 arglist
= build_tree_list (NULL_TREE
, arg
);
7700 return build_function_call_expr (expfn
, arglist
);
7703 /* Optimize pow(sqrt(x),y) = pow(x,y*0.5). */
7704 if (BUILTIN_SQRT_P (fcode
))
7706 tree narg0
= TREE_VALUE (TREE_OPERAND (arg0
, 1));
7707 tree narg1
= fold_build2 (MULT_EXPR
, type
, arg1
,
7708 build_real (type
, dconsthalf
));
7710 arglist
= tree_cons (NULL_TREE
, narg0
,
7711 build_tree_list (NULL_TREE
, narg1
));
7712 return build_function_call_expr (fndecl
, arglist
);
7715 /* Optimize pow(cbrt(x),y) = pow(x,y/3) iff x is nonnegative. */
7716 if (BUILTIN_CBRT_P (fcode
))
7718 tree arg
= TREE_VALUE (TREE_OPERAND (arg0
, 1));
7719 if (tree_expr_nonnegative_p (arg
))
7721 const REAL_VALUE_TYPE dconstroot
7722 = real_value_truncate (TYPE_MODE (type
), dconstthird
);
7723 tree narg1
= fold_build2 (MULT_EXPR
, type
, arg1
,
7724 build_real (type
, dconstroot
));
7725 arglist
= tree_cons (NULL_TREE
, arg
,
7726 build_tree_list (NULL_TREE
, narg1
));
7727 return build_function_call_expr (fndecl
, arglist
);
7731 /* Optimize pow(pow(x,y),z) = pow(x,y*z). */
7732 if (fcode
== BUILT_IN_POW
|| fcode
== BUILT_IN_POWF
7733 || fcode
== BUILT_IN_POWL
)
7735 tree arg00
= TREE_VALUE (TREE_OPERAND (arg0
, 1));
7736 tree arg01
= TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg0
, 1)));
7737 tree narg1
= fold_build2 (MULT_EXPR
, type
, arg01
, arg1
);
7738 arglist
= tree_cons (NULL_TREE
, arg00
,
7739 build_tree_list (NULL_TREE
, narg1
));
7740 return build_function_call_expr (fndecl
, arglist
);
7747 /* Fold a builtin function call to powi, powif, or powil. Return
7748 NULL_TREE if no simplification can be made. */
7750 fold_builtin_powi (tree fndecl ATTRIBUTE_UNUSED
, tree arglist
, tree type
)
7752 tree arg0
= TREE_VALUE (arglist
);
7753 tree arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
7755 if (!validate_arglist (arglist
, REAL_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
7758 /* Optimize pow(1.0,y) = 1.0. */
7759 if (real_onep (arg0
))
7760 return omit_one_operand (type
, build_real (type
, dconst1
), arg1
);
7762 if (host_integerp (arg1
, 0))
7764 HOST_WIDE_INT c
= TREE_INT_CST_LOW (arg1
);
7766 /* Evaluate powi at compile-time. */
7767 if (TREE_CODE (arg0
) == REAL_CST
7768 && ! TREE_CONSTANT_OVERFLOW (arg0
))
7771 x
= TREE_REAL_CST (arg0
);
7772 real_powi (&x
, TYPE_MODE (type
), &x
, c
);
7773 return build_real (type
, x
);
7776 /* Optimize pow(x,0) = 1.0. */
7778 return omit_one_operand (type
, build_real (type
, dconst1
),
7781 /* Optimize pow(x,1) = x. */
7785 /* Optimize pow(x,-1) = 1.0/x. */
7787 return fold_build2 (RDIV_EXPR
, type
,
7788 build_real (type
, dconst1
), arg0
);
7794 /* A subroutine of fold_builtin to fold the various exponent
7795 functions. EXP is the CALL_EXPR of a call to a builtin function.
7796 VALUE is the value which will be raised to a power. */
7799 fold_builtin_exponent (tree fndecl
, tree arglist
,
7800 const REAL_VALUE_TYPE
*value
)
7802 if (validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
7804 tree type
= TREE_TYPE (TREE_TYPE (fndecl
));
7805 tree arg
= TREE_VALUE (arglist
);
7807 /* Optimize exp*(0.0) = 1.0. */
7808 if (real_zerop (arg
))
7809 return build_real (type
, dconst1
);
7811 /* Optimize expN(1.0) = N. */
7812 if (real_onep (arg
))
7814 REAL_VALUE_TYPE cst
;
7816 real_convert (&cst
, TYPE_MODE (type
), value
);
7817 return build_real (type
, cst
);
7820 /* Attempt to evaluate expN(integer) at compile-time. */
7821 if (flag_unsafe_math_optimizations
7822 && TREE_CODE (arg
) == REAL_CST
7823 && ! TREE_CONSTANT_OVERFLOW (arg
))
7825 REAL_VALUE_TYPE cint
;
7829 c
= TREE_REAL_CST (arg
);
7830 n
= real_to_integer (&c
);
7831 real_from_integer (&cint
, VOIDmode
, n
,
7833 if (real_identical (&c
, &cint
))
7837 real_powi (&x
, TYPE_MODE (type
), value
, n
);
7838 return build_real (type
, x
);
7842 /* Optimize expN(logN(x)) = x. */
7843 if (flag_unsafe_math_optimizations
)
7845 const enum built_in_function fcode
= builtin_mathfn_code (arg
);
7847 if ((value
== &dconste
7848 && (fcode
== BUILT_IN_LOG
7849 || fcode
== BUILT_IN_LOGF
7850 || fcode
== BUILT_IN_LOGL
))
7851 || (value
== &dconst2
7852 && (fcode
== BUILT_IN_LOG2
7853 || fcode
== BUILT_IN_LOG2F
7854 || fcode
== BUILT_IN_LOG2L
))
7855 || (value
== &dconst10
7856 && (fcode
== BUILT_IN_LOG10
7857 || fcode
== BUILT_IN_LOG10F
7858 || fcode
== BUILT_IN_LOG10L
)))
7859 return fold_convert (type
, TREE_VALUE (TREE_OPERAND (arg
, 1)));
7866 /* Fold function call to builtin memcpy. Return
7867 NULL_TREE if no simplification can be made. */
7870 fold_builtin_memcpy (tree fndecl
, tree arglist
)
7872 tree dest
, src
, len
;
7874 if (!validate_arglist (arglist
,
7875 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
7878 dest
= TREE_VALUE (arglist
);
7879 src
= TREE_VALUE (TREE_CHAIN (arglist
));
7880 len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
7882 /* If the LEN parameter is zero, return DEST. */
7883 if (integer_zerop (len
))
7884 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl
)), dest
, src
);
7886 /* If SRC and DEST are the same (and not volatile), return DEST. */
7887 if (operand_equal_p (src
, dest
, 0))
7888 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl
)), dest
, len
);
7893 /* Fold function call to builtin mempcpy. Return
7894 NULL_TREE if no simplification can be made. */
7897 fold_builtin_mempcpy (tree arglist
, tree type
, int endp
)
7899 if (validate_arglist (arglist
,
7900 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
7902 tree dest
= TREE_VALUE (arglist
);
7903 tree src
= TREE_VALUE (TREE_CHAIN (arglist
));
7904 tree len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
7906 /* If the LEN parameter is zero, return DEST. */
7907 if (integer_zerop (len
))
7908 return omit_one_operand (type
, dest
, src
);
7910 /* If SRC and DEST are the same (and not volatile), return DEST+LEN. */
7911 if (operand_equal_p (src
, dest
, 0))
7914 return omit_one_operand (type
, dest
, len
);
7917 len
= fold_build2 (MINUS_EXPR
, TREE_TYPE (len
), len
,
7920 len
= fold_convert (TREE_TYPE (dest
), len
);
7921 len
= fold_build2 (PLUS_EXPR
, TREE_TYPE (dest
), dest
, len
);
7922 return fold_convert (type
, len
);
7928 /* Fold function call to builtin memmove. Return
7929 NULL_TREE if no simplification can be made. */
7932 fold_builtin_memmove (tree arglist
, tree type
)
7934 tree dest
, src
, len
;
7936 if (!validate_arglist (arglist
,
7937 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
7940 dest
= TREE_VALUE (arglist
);
7941 src
= TREE_VALUE (TREE_CHAIN (arglist
));
7942 len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
7944 /* If the LEN parameter is zero, return DEST. */
7945 if (integer_zerop (len
))
7946 return omit_one_operand (type
, dest
, src
);
7948 /* If SRC and DEST are the same (and not volatile), return DEST. */
7949 if (operand_equal_p (src
, dest
, 0))
7950 return omit_one_operand (type
, dest
, len
);
7955 /* Fold function call to builtin strcpy. If LEN is not NULL, it represents
7956 the length of the string to be copied. Return NULL_TREE if no
7957 simplification can be made. */
7960 fold_builtin_strcpy (tree fndecl
, tree arglist
, tree len
)
7964 if (!validate_arglist (arglist
,
7965 POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
7968 dest
= TREE_VALUE (arglist
);
7969 src
= TREE_VALUE (TREE_CHAIN (arglist
));
7971 /* If SRC and DEST are the same (and not volatile), return DEST. */
7972 if (operand_equal_p (src
, dest
, 0))
7973 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl
)), dest
);
7978 fn
= implicit_built_in_decls
[BUILT_IN_MEMCPY
];
7984 len
= c_strlen (src
, 1);
7985 if (! len
|| TREE_SIDE_EFFECTS (len
))
7989 len
= size_binop (PLUS_EXPR
, len
, ssize_int (1));
7990 arglist
= build_tree_list (NULL_TREE
, len
);
7991 arglist
= tree_cons (NULL_TREE
, src
, arglist
);
7992 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
7993 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl
)),
7994 build_function_call_expr (fn
, arglist
));
7997 /* Fold function call to builtin strncpy. If SLEN is not NULL, it represents
7998 the length of the source string. Return NULL_TREE if no simplification
8002 fold_builtin_strncpy (tree fndecl
, tree arglist
, tree slen
)
8004 tree dest
, src
, len
, fn
;
8006 if (!validate_arglist (arglist
,
8007 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
8010 dest
= TREE_VALUE (arglist
);
8011 src
= TREE_VALUE (TREE_CHAIN (arglist
));
8012 len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
8014 /* If the LEN parameter is zero, return DEST. */
8015 if (integer_zerop (len
))
8016 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl
)), dest
, src
);
8018 /* We can't compare slen with len as constants below if len is not a
8020 if (len
== 0 || TREE_CODE (len
) != INTEGER_CST
)
8024 slen
= c_strlen (src
, 1);
8026 /* Now, we must be passed a constant src ptr parameter. */
8027 if (slen
== 0 || TREE_CODE (slen
) != INTEGER_CST
)
8030 slen
= size_binop (PLUS_EXPR
, slen
, ssize_int (1));
8032 /* We do not support simplification of this case, though we do
8033 support it when expanding trees into RTL. */
8034 /* FIXME: generate a call to __builtin_memset. */
8035 if (tree_int_cst_lt (slen
, len
))
8038 /* OK transform into builtin memcpy. */
8039 fn
= implicit_built_in_decls
[BUILT_IN_MEMCPY
];
8042 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl
)),
8043 build_function_call_expr (fn
, arglist
));
8046 /* Fold function call to builtin memcmp. Return
8047 NULL_TREE if no simplification can be made. */
8050 fold_builtin_memcmp (tree arglist
)
8052 tree arg1
, arg2
, len
;
8053 const char *p1
, *p2
;
8055 if (!validate_arglist (arglist
,
8056 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
8059 arg1
= TREE_VALUE (arglist
);
8060 arg2
= TREE_VALUE (TREE_CHAIN (arglist
));
8061 len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
8063 /* If the LEN parameter is zero, return zero. */
8064 if (integer_zerop (len
))
8065 return omit_two_operands (integer_type_node
, integer_zero_node
,
8068 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
8069 if (operand_equal_p (arg1
, arg2
, 0))
8070 return omit_one_operand (integer_type_node
, integer_zero_node
, len
);
8072 p1
= c_getstr (arg1
);
8073 p2
= c_getstr (arg2
);
8075 /* If all arguments are constant, and the value of len is not greater
8076 than the lengths of arg1 and arg2, evaluate at compile-time. */
8077 if (host_integerp (len
, 1) && p1
&& p2
8078 && compare_tree_int (len
, strlen (p1
) + 1) <= 0
8079 && compare_tree_int (len
, strlen (p2
) + 1) <= 0)
8081 const int r
= memcmp (p1
, p2
, tree_low_cst (len
, 1));
8084 return integer_one_node
;
8086 return integer_minus_one_node
;
8088 return integer_zero_node
;
8091 /* If len parameter is one, return an expression corresponding to
8092 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
8093 if (host_integerp (len
, 1) && tree_low_cst (len
, 1) == 1)
8095 tree cst_uchar_node
= build_type_variant (unsigned_char_type_node
, 1, 0);
8096 tree cst_uchar_ptr_node
8097 = build_pointer_type_for_mode (cst_uchar_node
, ptr_mode
, true);
8099 tree ind1
= fold_convert (integer_type_node
,
8100 build1 (INDIRECT_REF
, cst_uchar_node
,
8101 fold_convert (cst_uchar_ptr_node
,
8103 tree ind2
= fold_convert (integer_type_node
,
8104 build1 (INDIRECT_REF
, cst_uchar_node
,
8105 fold_convert (cst_uchar_ptr_node
,
8107 return fold_build2 (MINUS_EXPR
, integer_type_node
, ind1
, ind2
);
8113 /* Fold function call to builtin strcmp. Return
8114 NULL_TREE if no simplification can be made. */
8117 fold_builtin_strcmp (tree arglist
)
8120 const char *p1
, *p2
;
8122 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
8125 arg1
= TREE_VALUE (arglist
);
8126 arg2
= TREE_VALUE (TREE_CHAIN (arglist
));
8128 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
8129 if (operand_equal_p (arg1
, arg2
, 0))
8130 return integer_zero_node
;
8132 p1
= c_getstr (arg1
);
8133 p2
= c_getstr (arg2
);
8137 const int i
= strcmp (p1
, p2
);
8139 return integer_minus_one_node
;
8141 return integer_one_node
;
8143 return integer_zero_node
;
8146 /* If the second arg is "", return *(const unsigned char*)arg1. */
8147 if (p2
&& *p2
== '\0')
8149 tree cst_uchar_node
= build_type_variant (unsigned_char_type_node
, 1, 0);
8150 tree cst_uchar_ptr_node
8151 = build_pointer_type_for_mode (cst_uchar_node
, ptr_mode
, true);
8153 return fold_convert (integer_type_node
,
8154 build1 (INDIRECT_REF
, cst_uchar_node
,
8155 fold_convert (cst_uchar_ptr_node
,
8159 /* If the first arg is "", return -*(const unsigned char*)arg2. */
8160 if (p1
&& *p1
== '\0')
8162 tree cst_uchar_node
= build_type_variant (unsigned_char_type_node
, 1, 0);
8163 tree cst_uchar_ptr_node
8164 = build_pointer_type_for_mode (cst_uchar_node
, ptr_mode
, true);
8166 tree temp
= fold_convert (integer_type_node
,
8167 build1 (INDIRECT_REF
, cst_uchar_node
,
8168 fold_convert (cst_uchar_ptr_node
,
8170 return fold_build1 (NEGATE_EXPR
, integer_type_node
, temp
);
8176 /* Fold function call to builtin strncmp. Return
8177 NULL_TREE if no simplification can be made. */
8180 fold_builtin_strncmp (tree arglist
)
8182 tree arg1
, arg2
, len
;
8183 const char *p1
, *p2
;
8185 if (!validate_arglist (arglist
,
8186 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
8189 arg1
= TREE_VALUE (arglist
);
8190 arg2
= TREE_VALUE (TREE_CHAIN (arglist
));
8191 len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
8193 /* If the LEN parameter is zero, return zero. */
8194 if (integer_zerop (len
))
8195 return omit_two_operands (integer_type_node
, integer_zero_node
,
8198 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
8199 if (operand_equal_p (arg1
, arg2
, 0))
8200 return omit_one_operand (integer_type_node
, integer_zero_node
, len
);
8202 p1
= c_getstr (arg1
);
8203 p2
= c_getstr (arg2
);
8205 if (host_integerp (len
, 1) && p1
&& p2
)
8207 const int i
= strncmp (p1
, p2
, tree_low_cst (len
, 1));
8209 return integer_one_node
;
8211 return integer_minus_one_node
;
8213 return integer_zero_node
;
8216 /* If the second arg is "", and the length is greater than zero,
8217 return *(const unsigned char*)arg1. */
8218 if (p2
&& *p2
== '\0'
8219 && TREE_CODE (len
) == INTEGER_CST
8220 && tree_int_cst_sgn (len
) == 1)
8222 tree cst_uchar_node
= build_type_variant (unsigned_char_type_node
, 1, 0);
8223 tree cst_uchar_ptr_node
8224 = build_pointer_type_for_mode (cst_uchar_node
, ptr_mode
, true);
8226 return fold_convert (integer_type_node
,
8227 build1 (INDIRECT_REF
, cst_uchar_node
,
8228 fold_convert (cst_uchar_ptr_node
,
8232 /* If the first arg is "", and the length is greater than zero,
8233 return -*(const unsigned char*)arg2. */
8234 if (p1
&& *p1
== '\0'
8235 && TREE_CODE (len
) == INTEGER_CST
8236 && tree_int_cst_sgn (len
) == 1)
8238 tree cst_uchar_node
= build_type_variant (unsigned_char_type_node
, 1, 0);
8239 tree cst_uchar_ptr_node
8240 = build_pointer_type_for_mode (cst_uchar_node
, ptr_mode
, true);
8242 tree temp
= fold_convert (integer_type_node
,
8243 build1 (INDIRECT_REF
, cst_uchar_node
,
8244 fold_convert (cst_uchar_ptr_node
,
8246 return fold_build1 (NEGATE_EXPR
, integer_type_node
, temp
);
8249 /* If len parameter is one, return an expression corresponding to
8250 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
8251 if (host_integerp (len
, 1) && tree_low_cst (len
, 1) == 1)
8253 tree cst_uchar_node
= build_type_variant (unsigned_char_type_node
, 1, 0);
8254 tree cst_uchar_ptr_node
8255 = build_pointer_type_for_mode (cst_uchar_node
, ptr_mode
, true);
8257 tree ind1
= fold_convert (integer_type_node
,
8258 build1 (INDIRECT_REF
, cst_uchar_node
,
8259 fold_convert (cst_uchar_ptr_node
,
8261 tree ind2
= fold_convert (integer_type_node
,
8262 build1 (INDIRECT_REF
, cst_uchar_node
,
8263 fold_convert (cst_uchar_ptr_node
,
8265 return fold_build2 (MINUS_EXPR
, integer_type_node
, ind1
, ind2
);
8271 /* Fold function call to builtin signbit, signbitf or signbitl. Return
8272 NULL_TREE if no simplification can be made. */
8275 fold_builtin_signbit (tree fndecl
, tree arglist
)
8277 tree type
= TREE_TYPE (TREE_TYPE (fndecl
));
8280 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
8283 arg
= TREE_VALUE (arglist
);
8285 /* If ARG is a compile-time constant, determine the result. */
8286 if (TREE_CODE (arg
) == REAL_CST
8287 && !TREE_CONSTANT_OVERFLOW (arg
))
8291 c
= TREE_REAL_CST (arg
);
8292 temp
= REAL_VALUE_NEGATIVE (c
) ? integer_one_node
: integer_zero_node
;
8293 return fold_convert (type
, temp
);
8296 /* If ARG is non-negative, the result is always zero. */
8297 if (tree_expr_nonnegative_p (arg
))
8298 return omit_one_operand (type
, integer_zero_node
, arg
);
8300 /* If ARG's format doesn't have signed zeros, return "arg < 0.0". */
8301 if (!HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg
))))
8302 return fold_build2 (LT_EXPR
, type
, arg
,
8303 build_real (TREE_TYPE (arg
), dconst0
));
8308 /* Fold function call to builtin copysign, copysignf or copysignl.
8309 Return NULL_TREE if no simplification can be made. */
8312 fold_builtin_copysign (tree fndecl
, tree arglist
, tree type
)
8314 tree arg1
, arg2
, tem
;
8316 if (!validate_arglist (arglist
, REAL_TYPE
, REAL_TYPE
, VOID_TYPE
))
8319 arg1
= TREE_VALUE (arglist
);
8320 arg2
= TREE_VALUE (TREE_CHAIN (arglist
));
8322 /* copysign(X,X) is X. */
8323 if (operand_equal_p (arg1
, arg2
, 0))
8324 return fold_convert (type
, arg1
);
8326 /* If ARG1 and ARG2 are compile-time constants, determine the result. */
8327 if (TREE_CODE (arg1
) == REAL_CST
8328 && TREE_CODE (arg2
) == REAL_CST
8329 && !TREE_CONSTANT_OVERFLOW (arg1
)
8330 && !TREE_CONSTANT_OVERFLOW (arg2
))
8332 REAL_VALUE_TYPE c1
, c2
;
8334 c1
= TREE_REAL_CST (arg1
);
8335 c2
= TREE_REAL_CST (arg2
);
8336 real_copysign (&c1
, &c2
);
8337 return build_real (type
, c1
);
8341 /* copysign(X, Y) is fabs(X) when Y is always non-negative.
8342 Remember to evaluate Y for side-effects. */
8343 if (tree_expr_nonnegative_p (arg2
))
8344 return omit_one_operand (type
,
8345 fold_build1 (ABS_EXPR
, type
, arg1
),
8348 /* Strip sign changing operations for the first argument. */
8349 tem
= fold_strip_sign_ops (arg1
);
8352 arglist
= tree_cons (NULL_TREE
, tem
, TREE_CHAIN (arglist
));
8353 return build_function_call_expr (fndecl
, arglist
);
8359 /* Fold a call to builtin isascii. */
8362 fold_builtin_isascii (tree arglist
)
8364 if (! validate_arglist (arglist
, INTEGER_TYPE
, VOID_TYPE
))
8368 /* Transform isascii(c) -> ((c & ~0x7f) == 0). */
8369 tree arg
= TREE_VALUE (arglist
);
8371 arg
= build2 (BIT_AND_EXPR
, integer_type_node
, arg
,
8372 build_int_cst (NULL_TREE
,
8373 ~ (unsigned HOST_WIDE_INT
) 0x7f));
8374 arg
= fold_build2 (EQ_EXPR
, integer_type_node
,
8375 arg
, integer_zero_node
);
8377 if (in_gimple_form
&& !TREE_CONSTANT (arg
))
8384 /* Fold a call to builtin toascii. */
8387 fold_builtin_toascii (tree arglist
)
8389 if (! validate_arglist (arglist
, INTEGER_TYPE
, VOID_TYPE
))
8393 /* Transform toascii(c) -> (c & 0x7f). */
8394 tree arg
= TREE_VALUE (arglist
);
8396 return fold_build2 (BIT_AND_EXPR
, integer_type_node
, arg
,
8397 build_int_cst (NULL_TREE
, 0x7f));
8401 /* Fold a call to builtin isdigit. */
8404 fold_builtin_isdigit (tree arglist
)
8406 if (! validate_arglist (arglist
, INTEGER_TYPE
, VOID_TYPE
))
8410 /* Transform isdigit(c) -> (unsigned)(c) - '0' <= 9. */
8411 /* According to the C standard, isdigit is unaffected by locale.
8412 However, it definitely is affected by the target character set. */
8414 unsigned HOST_WIDE_INT target_digit0
8415 = lang_hooks
.to_target_charset ('0');
8417 if (target_digit0
== 0)
8420 arg
= fold_convert (unsigned_type_node
, TREE_VALUE (arglist
));
8421 arg
= build2 (MINUS_EXPR
, unsigned_type_node
, arg
,
8422 build_int_cst (unsigned_type_node
, target_digit0
));
8423 arg
= fold_build2 (LE_EXPR
, integer_type_node
, arg
,
8424 build_int_cst (unsigned_type_node
, 9));
8425 if (in_gimple_form
&& !TREE_CONSTANT (arg
))
8432 /* Fold a call to fabs, fabsf or fabsl. */
8435 fold_builtin_fabs (tree arglist
, tree type
)
8439 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
8442 arg
= TREE_VALUE (arglist
);
8443 arg
= fold_convert (type
, arg
);
8444 if (TREE_CODE (arg
) == REAL_CST
)
8445 return fold_abs_const (arg
, type
);
8446 return fold_build1 (ABS_EXPR
, type
, arg
);
8449 /* Fold a call to abs, labs, llabs or imaxabs. */
8452 fold_builtin_abs (tree arglist
, tree type
)
8456 if (!validate_arglist (arglist
, INTEGER_TYPE
, VOID_TYPE
))
8459 arg
= TREE_VALUE (arglist
);
8460 arg
= fold_convert (type
, arg
);
8461 if (TREE_CODE (arg
) == INTEGER_CST
)
8462 return fold_abs_const (arg
, type
);
8463 return fold_build1 (ABS_EXPR
, type
, arg
);
8466 /* Fold a call to __builtin_isnan(), __builtin_isinf, __builtin_finite.
8467 EXP is the CALL_EXPR for the call. */
8470 fold_builtin_classify (tree fndecl
, tree arglist
, int builtin_index
)
8472 tree type
= TREE_TYPE (TREE_TYPE (fndecl
));
8476 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
8478 /* Check that we have exactly one argument. */
8481 error ("too few arguments to function %qs",
8482 IDENTIFIER_POINTER (DECL_NAME (fndecl
)));
8483 return error_mark_node
;
8485 else if (TREE_CHAIN (arglist
) != 0)
8487 error ("too many arguments to function %qs",
8488 IDENTIFIER_POINTER (DECL_NAME (fndecl
)));
8489 return error_mark_node
;
8493 error ("non-floating-point argument to function %qs",
8494 IDENTIFIER_POINTER (DECL_NAME (fndecl
)));
8495 return error_mark_node
;
8499 arg
= TREE_VALUE (arglist
);
8500 switch (builtin_index
)
8502 case BUILT_IN_ISINF
:
8503 if (!MODE_HAS_INFINITIES (TYPE_MODE (TREE_TYPE (arg
))))
8504 return omit_one_operand (type
, integer_zero_node
, arg
);
8506 if (TREE_CODE (arg
) == REAL_CST
)
8508 r
= TREE_REAL_CST (arg
);
8509 if (real_isinf (&r
))
8510 return real_compare (GT_EXPR
, &r
, &dconst0
)
8511 ? integer_one_node
: integer_minus_one_node
;
8513 return integer_zero_node
;
8518 case BUILT_IN_FINITE
:
8519 if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg
)))
8520 && !MODE_HAS_INFINITIES (TYPE_MODE (TREE_TYPE (arg
))))
8521 return omit_one_operand (type
, integer_zero_node
, arg
);
8523 if (TREE_CODE (arg
) == REAL_CST
)
8525 r
= TREE_REAL_CST (arg
);
8526 return real_isinf (&r
) || real_isnan (&r
)
8527 ? integer_zero_node
: integer_one_node
;
8532 case BUILT_IN_ISNAN
:
8533 if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg
))))
8534 return omit_one_operand (type
, integer_zero_node
, arg
);
8536 if (TREE_CODE (arg
) == REAL_CST
)
8538 r
= TREE_REAL_CST (arg
);
8539 return real_isnan (&r
) ? integer_one_node
: integer_zero_node
;
8542 arg
= builtin_save_expr (arg
);
8543 return fold_build2 (UNORDERED_EXPR
, type
, arg
, arg
);
8550 /* Fold a call to an unordered comparison function such as
8551 __builtin_isgreater(). FNDECL is the FUNCTION_DECL for the function
8552 being called and ARGLIST is the argument list for the call.
8553 UNORDERED_CODE and ORDERED_CODE are comparison codes that give
8554 the opposite of the desired result. UNORDERED_CODE is used
8555 for modes that can hold NaNs and ORDERED_CODE is used for
8559 fold_builtin_unordered_cmp (tree fndecl
, tree arglist
,
8560 enum tree_code unordered_code
,
8561 enum tree_code ordered_code
)
8563 tree type
= TREE_TYPE (TREE_TYPE (fndecl
));
8564 enum tree_code code
;
8567 enum tree_code code0
, code1
;
8568 tree cmp_type
= NULL_TREE
;
8570 if (!validate_arglist (arglist
, REAL_TYPE
, REAL_TYPE
, VOID_TYPE
))
8572 /* Check that we have exactly two arguments. */
8573 if (arglist
== 0 || TREE_CHAIN (arglist
) == 0)
8575 error ("too few arguments to function %qs",
8576 IDENTIFIER_POINTER (DECL_NAME (fndecl
)));
8577 return error_mark_node
;
8579 else if (TREE_CHAIN (TREE_CHAIN (arglist
)) != 0)
8581 error ("too many arguments to function %qs",
8582 IDENTIFIER_POINTER (DECL_NAME (fndecl
)));
8583 return error_mark_node
;
8587 arg0
= TREE_VALUE (arglist
);
8588 arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
8590 type0
= TREE_TYPE (arg0
);
8591 type1
= TREE_TYPE (arg1
);
8593 code0
= TREE_CODE (type0
);
8594 code1
= TREE_CODE (type1
);
8596 if (code0
== REAL_TYPE
&& code1
== REAL_TYPE
)
8597 /* Choose the wider of two real types. */
8598 cmp_type
= TYPE_PRECISION (type0
) >= TYPE_PRECISION (type1
)
8600 else if (code0
== REAL_TYPE
&& code1
== INTEGER_TYPE
)
8602 else if (code0
== INTEGER_TYPE
&& code1
== REAL_TYPE
)
8606 error ("non-floating-point argument to function %qs",
8607 IDENTIFIER_POINTER (DECL_NAME (fndecl
)));
8608 return error_mark_node
;
8611 arg0
= fold_convert (cmp_type
, arg0
);
8612 arg1
= fold_convert (cmp_type
, arg1
);
8614 if (unordered_code
== UNORDERED_EXPR
)
8616 if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg0
))))
8617 return omit_two_operands (type
, integer_zero_node
, arg0
, arg1
);
8618 return fold_build2 (UNORDERED_EXPR
, type
, arg0
, arg1
);
8621 code
= MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg0
))) ? unordered_code
8623 return fold_build1 (TRUTH_NOT_EXPR
, type
,
8624 fold_build2 (code
, type
, arg0
, arg1
));
8627 /* Used by constant folding to simplify calls to builtin functions. EXP is
8628 the CALL_EXPR of a call to a builtin function. IGNORE is true if the
8629 result of the function call is ignored. This function returns NULL_TREE
8630 if no simplification was possible. */
8633 fold_builtin_1 (tree fndecl
, tree arglist
, bool ignore
)
8635 tree type
= TREE_TYPE (TREE_TYPE (fndecl
));
8636 enum built_in_function fcode
;
8638 if (DECL_BUILT_IN_CLASS (fndecl
) == BUILT_IN_MD
)
8639 return targetm
.fold_builtin (fndecl
, arglist
, ignore
);
8641 fcode
= DECL_FUNCTION_CODE (fndecl
);
8644 case BUILT_IN_FPUTS
:
8645 return fold_builtin_fputs (arglist
, ignore
, false, NULL_TREE
);
8647 case BUILT_IN_FPUTS_UNLOCKED
:
8648 return fold_builtin_fputs (arglist
, ignore
, true, NULL_TREE
);
8650 case BUILT_IN_STRSTR
:
8651 return fold_builtin_strstr (arglist
, type
);
8653 case BUILT_IN_STRCAT
:
8654 return fold_builtin_strcat (arglist
);
8656 case BUILT_IN_STRNCAT
:
8657 return fold_builtin_strncat (arglist
);
8659 case BUILT_IN_STRSPN
:
8660 return fold_builtin_strspn (arglist
);
8662 case BUILT_IN_STRCSPN
:
8663 return fold_builtin_strcspn (arglist
);
8665 case BUILT_IN_STRCHR
:
8666 case BUILT_IN_INDEX
:
8667 return fold_builtin_strchr (arglist
, type
);
8669 case BUILT_IN_STRRCHR
:
8670 case BUILT_IN_RINDEX
:
8671 return fold_builtin_strrchr (arglist
, type
);
8673 case BUILT_IN_STRCPY
:
8674 return fold_builtin_strcpy (fndecl
, arglist
, NULL_TREE
);
8676 case BUILT_IN_STRNCPY
:
8677 return fold_builtin_strncpy (fndecl
, arglist
, NULL_TREE
);
8679 case BUILT_IN_STRCMP
:
8680 return fold_builtin_strcmp (arglist
);
8682 case BUILT_IN_STRNCMP
:
8683 return fold_builtin_strncmp (arglist
);
8685 case BUILT_IN_STRPBRK
:
8686 return fold_builtin_strpbrk (arglist
, type
);
8689 case BUILT_IN_MEMCMP
:
8690 return fold_builtin_memcmp (arglist
);
8692 case BUILT_IN_SPRINTF
:
8693 return fold_builtin_sprintf (arglist
, ignore
);
8695 case BUILT_IN_CONSTANT_P
:
8699 val
= fold_builtin_constant_p (arglist
);
8700 /* Gimplification will pull the CALL_EXPR for the builtin out of
8701 an if condition. When not optimizing, we'll not CSE it back.
8702 To avoid link error types of regressions, return false now. */
8703 if (!val
&& !optimize
)
8704 val
= integer_zero_node
;
8709 case BUILT_IN_EXPECT
:
8710 return fold_builtin_expect (arglist
);
8712 case BUILT_IN_CLASSIFY_TYPE
:
8713 return fold_builtin_classify_type (arglist
);
8715 case BUILT_IN_STRLEN
:
8716 return fold_builtin_strlen (arglist
);
8719 case BUILT_IN_FABSF
:
8720 case BUILT_IN_FABSL
:
8721 return fold_builtin_fabs (arglist
, type
);
8725 case BUILT_IN_LLABS
:
8726 case BUILT_IN_IMAXABS
:
8727 return fold_builtin_abs (arglist
, type
);
8730 case BUILT_IN_CONJF
:
8731 case BUILT_IN_CONJL
:
8732 if (validate_arglist (arglist
, COMPLEX_TYPE
, VOID_TYPE
))
8733 return fold_build1 (CONJ_EXPR
, type
, TREE_VALUE (arglist
));
8736 case BUILT_IN_CREAL
:
8737 case BUILT_IN_CREALF
:
8738 case BUILT_IN_CREALL
:
8739 if (validate_arglist (arglist
, COMPLEX_TYPE
, VOID_TYPE
))
8740 return non_lvalue (fold_build1 (REALPART_EXPR
, type
,
8741 TREE_VALUE (arglist
)));
8744 case BUILT_IN_CIMAG
:
8745 case BUILT_IN_CIMAGF
:
8746 case BUILT_IN_CIMAGL
:
8747 if (validate_arglist (arglist
, COMPLEX_TYPE
, VOID_TYPE
))
8748 return non_lvalue (fold_build1 (IMAGPART_EXPR
, type
,
8749 TREE_VALUE (arglist
)));
8753 case BUILT_IN_CABSF
:
8754 case BUILT_IN_CABSL
:
8755 return fold_builtin_cabs (arglist
, type
);
8758 case BUILT_IN_SQRTF
:
8759 case BUILT_IN_SQRTL
:
8760 return fold_builtin_sqrt (arglist
, type
);
8763 case BUILT_IN_CBRTF
:
8764 case BUILT_IN_CBRTL
:
8765 return fold_builtin_cbrt (arglist
, type
);
8770 return fold_builtin_sin (arglist
);
8775 return fold_builtin_cos (arglist
, type
, fndecl
);
8780 return fold_builtin_exponent (fndecl
, arglist
, &dconste
);
8783 case BUILT_IN_EXP2F
:
8784 case BUILT_IN_EXP2L
:
8785 return fold_builtin_exponent (fndecl
, arglist
, &dconst2
);
8787 case BUILT_IN_EXP10
:
8788 case BUILT_IN_EXP10F
:
8789 case BUILT_IN_EXP10L
:
8790 case BUILT_IN_POW10
:
8791 case BUILT_IN_POW10F
:
8792 case BUILT_IN_POW10L
:
8793 return fold_builtin_exponent (fndecl
, arglist
, &dconst10
);
8798 return fold_builtin_logarithm (fndecl
, arglist
, &dconste
);
8801 case BUILT_IN_LOG2F
:
8802 case BUILT_IN_LOG2L
:
8803 return fold_builtin_logarithm (fndecl
, arglist
, &dconst2
);
8805 case BUILT_IN_LOG10
:
8806 case BUILT_IN_LOG10F
:
8807 case BUILT_IN_LOG10L
:
8808 return fold_builtin_logarithm (fndecl
, arglist
, &dconst10
);
8813 return fold_builtin_tan (arglist
);
8816 case BUILT_IN_ATANF
:
8817 case BUILT_IN_ATANL
:
8818 return fold_builtin_atan (arglist
, type
);
8823 return fold_builtin_pow (fndecl
, arglist
, type
);
8826 case BUILT_IN_POWIF
:
8827 case BUILT_IN_POWIL
:
8828 return fold_builtin_powi (fndecl
, arglist
, type
);
8833 return fold_builtin_inf (type
, true);
8835 case BUILT_IN_HUGE_VAL
:
8836 case BUILT_IN_HUGE_VALF
:
8837 case BUILT_IN_HUGE_VALL
:
8838 return fold_builtin_inf (type
, false);
8843 return fold_builtin_nan (arglist
, type
, true);
8846 case BUILT_IN_NANSF
:
8847 case BUILT_IN_NANSL
:
8848 return fold_builtin_nan (arglist
, type
, false);
8850 case BUILT_IN_FLOOR
:
8851 case BUILT_IN_FLOORF
:
8852 case BUILT_IN_FLOORL
:
8853 return fold_builtin_floor (fndecl
, arglist
);
8856 case BUILT_IN_CEILF
:
8857 case BUILT_IN_CEILL
:
8858 return fold_builtin_ceil (fndecl
, arglist
);
8860 case BUILT_IN_TRUNC
:
8861 case BUILT_IN_TRUNCF
:
8862 case BUILT_IN_TRUNCL
:
8863 return fold_builtin_trunc (fndecl
, arglist
);
8865 case BUILT_IN_ROUND
:
8866 case BUILT_IN_ROUNDF
:
8867 case BUILT_IN_ROUNDL
:
8868 return fold_builtin_round (fndecl
, arglist
);
8870 case BUILT_IN_NEARBYINT
:
8871 case BUILT_IN_NEARBYINTF
:
8872 case BUILT_IN_NEARBYINTL
:
8874 case BUILT_IN_RINTF
:
8875 case BUILT_IN_RINTL
:
8876 return fold_trunc_transparent_mathfn (fndecl
, arglist
);
8878 case BUILT_IN_LCEIL
:
8879 case BUILT_IN_LCEILF
:
8880 case BUILT_IN_LCEILL
:
8881 case BUILT_IN_LLCEIL
:
8882 case BUILT_IN_LLCEILF
:
8883 case BUILT_IN_LLCEILL
:
8884 case BUILT_IN_LFLOOR
:
8885 case BUILT_IN_LFLOORF
:
8886 case BUILT_IN_LFLOORL
:
8887 case BUILT_IN_LLFLOOR
:
8888 case BUILT_IN_LLFLOORF
:
8889 case BUILT_IN_LLFLOORL
:
8890 case BUILT_IN_LROUND
:
8891 case BUILT_IN_LROUNDF
:
8892 case BUILT_IN_LROUNDL
:
8893 case BUILT_IN_LLROUND
:
8894 case BUILT_IN_LLROUNDF
:
8895 case BUILT_IN_LLROUNDL
:
8896 return fold_builtin_int_roundingfn (fndecl
, arglist
);
8898 case BUILT_IN_LRINT
:
8899 case BUILT_IN_LRINTF
:
8900 case BUILT_IN_LRINTL
:
8901 case BUILT_IN_LLRINT
:
8902 case BUILT_IN_LLRINTF
:
8903 case BUILT_IN_LLRINTL
:
8904 return fold_fixed_mathfn (fndecl
, arglist
);
8908 case BUILT_IN_FFSLL
:
8911 case BUILT_IN_CLZLL
:
8914 case BUILT_IN_CTZLL
:
8915 case BUILT_IN_POPCOUNT
:
8916 case BUILT_IN_POPCOUNTL
:
8917 case BUILT_IN_POPCOUNTLL
:
8918 case BUILT_IN_PARITY
:
8919 case BUILT_IN_PARITYL
:
8920 case BUILT_IN_PARITYLL
:
8921 return fold_builtin_bitop (fndecl
, arglist
);
8923 case BUILT_IN_MEMCPY
:
8924 return fold_builtin_memcpy (fndecl
, arglist
);
8926 case BUILT_IN_MEMPCPY
:
8927 return fold_builtin_mempcpy (arglist
, type
, /*endp=*/1);
8929 case BUILT_IN_MEMMOVE
:
8930 return fold_builtin_memmove (arglist
, type
);
8932 case BUILT_IN_SIGNBIT
:
8933 case BUILT_IN_SIGNBITF
:
8934 case BUILT_IN_SIGNBITL
:
8935 return fold_builtin_signbit (fndecl
, arglist
);
8937 case BUILT_IN_ISASCII
:
8938 return fold_builtin_isascii (arglist
);
8940 case BUILT_IN_TOASCII
:
8941 return fold_builtin_toascii (arglist
);
8943 case BUILT_IN_ISDIGIT
:
8944 return fold_builtin_isdigit (arglist
);
8946 case BUILT_IN_COPYSIGN
:
8947 case BUILT_IN_COPYSIGNF
:
8948 case BUILT_IN_COPYSIGNL
:
8949 return fold_builtin_copysign (fndecl
, arglist
, type
);
8951 case BUILT_IN_FINITE
:
8952 case BUILT_IN_FINITEF
:
8953 case BUILT_IN_FINITEL
:
8954 return fold_builtin_classify (fndecl
, arglist
, BUILT_IN_FINITE
);
8956 case BUILT_IN_ISINF
:
8957 case BUILT_IN_ISINFF
:
8958 case BUILT_IN_ISINFL
:
8959 return fold_builtin_classify (fndecl
, arglist
, BUILT_IN_ISINF
);
8961 case BUILT_IN_ISNAN
:
8962 case BUILT_IN_ISNANF
:
8963 case BUILT_IN_ISNANL
:
8964 return fold_builtin_classify (fndecl
, arglist
, BUILT_IN_ISNAN
);
8966 case BUILT_IN_ISGREATER
:
8967 return fold_builtin_unordered_cmp (fndecl
, arglist
, UNLE_EXPR
, LE_EXPR
);
8968 case BUILT_IN_ISGREATEREQUAL
:
8969 return fold_builtin_unordered_cmp (fndecl
, arglist
, UNLT_EXPR
, LT_EXPR
);
8970 case BUILT_IN_ISLESS
:
8971 return fold_builtin_unordered_cmp (fndecl
, arglist
, UNGE_EXPR
, GE_EXPR
);
8972 case BUILT_IN_ISLESSEQUAL
:
8973 return fold_builtin_unordered_cmp (fndecl
, arglist
, UNGT_EXPR
, GT_EXPR
);
8974 case BUILT_IN_ISLESSGREATER
:
8975 return fold_builtin_unordered_cmp (fndecl
, arglist
, UNEQ_EXPR
, EQ_EXPR
);
8976 case BUILT_IN_ISUNORDERED
:
8977 return fold_builtin_unordered_cmp (fndecl
, arglist
, UNORDERED_EXPR
,
8980 /* We do the folding for va_start in the expander. */
8981 case BUILT_IN_VA_START
:
8984 case BUILT_IN_OBJECT_SIZE
:
8985 return fold_builtin_object_size (arglist
);
8986 case BUILT_IN_MEMCPY_CHK
:
8987 case BUILT_IN_MEMPCPY_CHK
:
8988 case BUILT_IN_MEMMOVE_CHK
:
8989 case BUILT_IN_MEMSET_CHK
:
8990 return fold_builtin_memory_chk (fndecl
, arglist
, NULL_TREE
, ignore
,
8991 DECL_FUNCTION_CODE (fndecl
));
8992 case BUILT_IN_STRCPY_CHK
:
8993 case BUILT_IN_STPCPY_CHK
:
8994 return fold_builtin_stxcpy_chk (fndecl
, arglist
, NULL_TREE
, ignore
,
8995 DECL_FUNCTION_CODE (fndecl
));
8996 case BUILT_IN_STRNCPY_CHK
:
8997 return fold_builtin_strncpy_chk (arglist
, NULL_TREE
);
8998 case BUILT_IN_STRCAT_CHK
:
8999 return fold_builtin_strcat_chk (fndecl
, arglist
);
9000 case BUILT_IN_STRNCAT_CHK
:
9001 return fold_builtin_strncat_chk (fndecl
, arglist
);
9002 case BUILT_IN_SPRINTF_CHK
:
9003 case BUILT_IN_VSPRINTF_CHK
:
9004 return fold_builtin_sprintf_chk (arglist
, DECL_FUNCTION_CODE (fndecl
));
9005 case BUILT_IN_SNPRINTF_CHK
:
9006 case BUILT_IN_VSNPRINTF_CHK
:
9007 return fold_builtin_snprintf_chk (arglist
, NULL_TREE
,
9008 DECL_FUNCTION_CODE (fndecl
));
9010 case BUILT_IN_PRINTF
:
9011 case BUILT_IN_PRINTF_UNLOCKED
:
9012 case BUILT_IN_VPRINTF
:
9013 case BUILT_IN_PRINTF_CHK
:
9014 case BUILT_IN_VPRINTF_CHK
:
9015 return fold_builtin_printf (fndecl
, arglist
, ignore
,
9016 DECL_FUNCTION_CODE (fndecl
));
9018 case BUILT_IN_FPRINTF
:
9019 case BUILT_IN_FPRINTF_UNLOCKED
:
9020 case BUILT_IN_VFPRINTF
:
9021 case BUILT_IN_FPRINTF_CHK
:
9022 case BUILT_IN_VFPRINTF_CHK
:
9023 return fold_builtin_fprintf (fndecl
, arglist
, ignore
,
9024 DECL_FUNCTION_CODE (fndecl
));
9033 /* A wrapper function for builtin folding that prevents warnings for
9034 "statement without effect" and the like, caused by removing the
9035 call node earlier than the warning is generated. */
9038 fold_builtin (tree fndecl
, tree arglist
, bool ignore
)
9040 tree exp
= fold_builtin_1 (fndecl
, arglist
, ignore
);
9043 exp
= build1 (NOP_EXPR
, TREE_TYPE (exp
), exp
);
9044 TREE_NO_WARNING (exp
) = 1;
9050 /* Conveniently construct a function call expression. */
9053 build_function_call_expr (tree fn
, tree arglist
)
9057 call_expr
= build1 (ADDR_EXPR
, build_pointer_type (TREE_TYPE (fn
)), fn
);
9058 return fold_build3 (CALL_EXPR
, TREE_TYPE (TREE_TYPE (fn
)),
9059 call_expr
, arglist
, NULL_TREE
);
9062 /* This function validates the types of a function call argument list
9063 represented as a tree chain of parameters against a specified list
9064 of tree_codes. If the last specifier is a 0, that represents an
9065 ellipses, otherwise the last specifier must be a VOID_TYPE. */
9068 validate_arglist (tree arglist
, ...)
9070 enum tree_code code
;
9074 va_start (ap
, arglist
);
9078 code
= va_arg (ap
, enum tree_code
);
9082 /* This signifies an ellipses, any further arguments are all ok. */
9086 /* This signifies an endlink, if no arguments remain, return
9087 true, otherwise return false. */
9091 /* If no parameters remain or the parameter's code does not
9092 match the specified code, return false. Otherwise continue
9093 checking any remaining arguments. */
9096 if (code
== POINTER_TYPE
)
9098 if (! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist
))))
9101 else if (code
!= TREE_CODE (TREE_TYPE (TREE_VALUE (arglist
))))
9105 arglist
= TREE_CHAIN (arglist
);
9109 /* We need gotos here since we can only have one VA_CLOSE in a
9117 /* Default target-specific builtin expander that does nothing. */
9120 default_expand_builtin (tree exp ATTRIBUTE_UNUSED
,
9121 rtx target ATTRIBUTE_UNUSED
,
9122 rtx subtarget ATTRIBUTE_UNUSED
,
9123 enum machine_mode mode ATTRIBUTE_UNUSED
,
9124 int ignore ATTRIBUTE_UNUSED
)
9129 /* Returns true is EXP represents data that would potentially reside
9130 in a readonly section. */
9133 readonly_data_expr (tree exp
)
9137 if (TREE_CODE (exp
) != ADDR_EXPR
)
9140 exp
= get_base_address (TREE_OPERAND (exp
, 0));
9144 /* Make sure we call decl_readonly_section only for trees it
9145 can handle (since it returns true for everything it doesn't
9147 if (TREE_CODE (exp
) == STRING_CST
9148 || TREE_CODE (exp
) == CONSTRUCTOR
9149 || (TREE_CODE (exp
) == VAR_DECL
&& TREE_STATIC (exp
)))
9150 return decl_readonly_section (exp
, 0);
9155 /* Simplify a call to the strstr builtin.
9157 Return 0 if no simplification was possible, otherwise return the
9158 simplified form of the call as a tree.
9160 The simplified form may be a constant or other expression which
9161 computes the same value, but in a more efficient manner (including
9162 calls to other builtin functions).
9164 The call may contain arguments which need to be evaluated, but
9165 which are not useful to determine the result of the call. In
9166 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9167 COMPOUND_EXPR will be an argument which must be evaluated.
9168 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9169 COMPOUND_EXPR in the chain will contain the tree for the simplified
9170 form of the builtin function call. */
9173 fold_builtin_strstr (tree arglist
, tree type
)
9175 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
9179 tree s1
= TREE_VALUE (arglist
), s2
= TREE_VALUE (TREE_CHAIN (arglist
));
9181 const char *p1
, *p2
;
9190 const char *r
= strstr (p1
, p2
);
9194 return build_int_cst (TREE_TYPE (s1
), 0);
9196 /* Return an offset into the constant string argument. */
9197 tem
= fold_build2 (PLUS_EXPR
, TREE_TYPE (s1
),
9198 s1
, build_int_cst (TREE_TYPE (s1
), r
- p1
));
9199 return fold_convert (type
, tem
);
9202 /* The argument is const char *, and the result is char *, so we need
9203 a type conversion here to avoid a warning. */
9205 return fold_convert (type
, s1
);
9210 fn
= implicit_built_in_decls
[BUILT_IN_STRCHR
];
9214 /* New argument list transforming strstr(s1, s2) to
9215 strchr(s1, s2[0]). */
9216 arglist
= build_tree_list (NULL_TREE
,
9217 build_int_cst (NULL_TREE
, p2
[0]));
9218 arglist
= tree_cons (NULL_TREE
, s1
, arglist
);
9219 return build_function_call_expr (fn
, arglist
);
9223 /* Simplify a call to the strchr builtin.
9225 Return 0 if no simplification was possible, otherwise return the
9226 simplified form of the call as a tree.
9228 The simplified form may be a constant or other expression which
9229 computes the same value, but in a more efficient manner (including
9230 calls to other builtin functions).
9232 The call may contain arguments which need to be evaluated, but
9233 which are not useful to determine the result of the call. In
9234 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9235 COMPOUND_EXPR will be an argument which must be evaluated.
9236 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9237 COMPOUND_EXPR in the chain will contain the tree for the simplified
9238 form of the builtin function call. */
9241 fold_builtin_strchr (tree arglist
, tree type
)
9243 if (!validate_arglist (arglist
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
9247 tree s1
= TREE_VALUE (arglist
), s2
= TREE_VALUE (TREE_CHAIN (arglist
));
9250 if (TREE_CODE (s2
) != INTEGER_CST
)
9260 if (target_char_cast (s2
, &c
))
9266 return build_int_cst (TREE_TYPE (s1
), 0);
9268 /* Return an offset into the constant string argument. */
9269 tem
= fold_build2 (PLUS_EXPR
, TREE_TYPE (s1
),
9270 s1
, build_int_cst (TREE_TYPE (s1
), r
- p1
));
9271 return fold_convert (type
, tem
);
9277 /* Simplify a call to the strrchr builtin.
9279 Return 0 if no simplification was possible, otherwise return the
9280 simplified form of the call as a tree.
9282 The simplified form may be a constant or other expression which
9283 computes the same value, but in a more efficient manner (including
9284 calls to other builtin functions).
9286 The call may contain arguments which need to be evaluated, but
9287 which are not useful to determine the result of the call. In
9288 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9289 COMPOUND_EXPR will be an argument which must be evaluated.
9290 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9291 COMPOUND_EXPR in the chain will contain the tree for the simplified
9292 form of the builtin function call. */
9295 fold_builtin_strrchr (tree arglist
, tree type
)
9297 if (!validate_arglist (arglist
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
9301 tree s1
= TREE_VALUE (arglist
), s2
= TREE_VALUE (TREE_CHAIN (arglist
));
9305 if (TREE_CODE (s2
) != INTEGER_CST
)
9315 if (target_char_cast (s2
, &c
))
9318 r
= strrchr (p1
, c
);
9321 return build_int_cst (TREE_TYPE (s1
), 0);
9323 /* Return an offset into the constant string argument. */
9324 tem
= fold_build2 (PLUS_EXPR
, TREE_TYPE (s1
),
9325 s1
, build_int_cst (TREE_TYPE (s1
), r
- p1
));
9326 return fold_convert (type
, tem
);
9329 if (! integer_zerop (s2
))
9332 fn
= implicit_built_in_decls
[BUILT_IN_STRCHR
];
9336 /* Transform strrchr(s1, '\0') to strchr(s1, '\0'). */
9337 return build_function_call_expr (fn
, arglist
);
9341 /* Simplify a call to the strpbrk builtin.
9343 Return 0 if no simplification was possible, otherwise return the
9344 simplified form of the call as a tree.
9346 The simplified form may be a constant or other expression which
9347 computes the same value, but in a more efficient manner (including
9348 calls to other builtin functions).
9350 The call may contain arguments which need to be evaluated, but
9351 which are not useful to determine the result of the call. In
9352 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9353 COMPOUND_EXPR will be an argument which must be evaluated.
9354 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9355 COMPOUND_EXPR in the chain will contain the tree for the simplified
9356 form of the builtin function call. */
9359 fold_builtin_strpbrk (tree arglist
, tree type
)
9361 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
9365 tree s1
= TREE_VALUE (arglist
), s2
= TREE_VALUE (TREE_CHAIN (arglist
));
9367 const char *p1
, *p2
;
9376 const char *r
= strpbrk (p1
, p2
);
9380 return build_int_cst (TREE_TYPE (s1
), 0);
9382 /* Return an offset into the constant string argument. */
9383 tem
= fold_build2 (PLUS_EXPR
, TREE_TYPE (s1
),
9384 s1
, build_int_cst (TREE_TYPE (s1
), r
- p1
));
9385 return fold_convert (type
, tem
);
9389 /* strpbrk(x, "") == NULL.
9390 Evaluate and ignore s1 in case it had side-effects. */
9391 return omit_one_operand (TREE_TYPE (s1
), integer_zero_node
, s1
);
9394 return 0; /* Really call strpbrk. */
9396 fn
= implicit_built_in_decls
[BUILT_IN_STRCHR
];
9400 /* New argument list transforming strpbrk(s1, s2) to
9401 strchr(s1, s2[0]). */
9402 arglist
= build_tree_list (NULL_TREE
,
9403 build_int_cst (NULL_TREE
, p2
[0]));
9404 arglist
= tree_cons (NULL_TREE
, s1
, arglist
);
9405 return build_function_call_expr (fn
, arglist
);
9409 /* Simplify a call to the strcat builtin.
9411 Return 0 if no simplification was possible, otherwise return the
9412 simplified form of the call as a tree.
9414 The simplified form may be a constant or other expression which
9415 computes the same value, but in a more efficient manner (including
9416 calls to other builtin functions).
9418 The call may contain arguments which need to be evaluated, but
9419 which are not useful to determine the result of the call. In
9420 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9421 COMPOUND_EXPR will be an argument which must be evaluated.
9422 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9423 COMPOUND_EXPR in the chain will contain the tree for the simplified
9424 form of the builtin function call. */
9427 fold_builtin_strcat (tree arglist
)
9429 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
9433 tree dst
= TREE_VALUE (arglist
),
9434 src
= TREE_VALUE (TREE_CHAIN (arglist
));
9435 const char *p
= c_getstr (src
);
9437 /* If the string length is zero, return the dst parameter. */
9438 if (p
&& *p
== '\0')
9445 /* Simplify a call to the strncat builtin.
9447 Return 0 if no simplification was possible, otherwise return the
9448 simplified form of the call as a tree.
9450 The simplified form may be a constant or other expression which
9451 computes the same value, but in a more efficient manner (including
9452 calls to other builtin functions).
9454 The call may contain arguments which need to be evaluated, but
9455 which are not useful to determine the result of the call. In
9456 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9457 COMPOUND_EXPR will be an argument which must be evaluated.
9458 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9459 COMPOUND_EXPR in the chain will contain the tree for the simplified
9460 form of the builtin function call. */
9463 fold_builtin_strncat (tree arglist
)
9465 if (!validate_arglist (arglist
,
9466 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
9470 tree dst
= TREE_VALUE (arglist
);
9471 tree src
= TREE_VALUE (TREE_CHAIN (arglist
));
9472 tree len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
9473 const char *p
= c_getstr (src
);
9475 /* If the requested length is zero, or the src parameter string
9476 length is zero, return the dst parameter. */
9477 if (integer_zerop (len
) || (p
&& *p
== '\0'))
9478 return omit_two_operands (TREE_TYPE (dst
), dst
, src
, len
);
9480 /* If the requested len is greater than or equal to the string
9481 length, call strcat. */
9482 if (TREE_CODE (len
) == INTEGER_CST
&& p
9483 && compare_tree_int (len
, strlen (p
)) >= 0)
9486 = tree_cons (NULL_TREE
, dst
, build_tree_list (NULL_TREE
, src
));
9487 tree fn
= implicit_built_in_decls
[BUILT_IN_STRCAT
];
9489 /* If the replacement _DECL isn't initialized, don't do the
9494 return build_function_call_expr (fn
, newarglist
);
9500 /* Simplify a call to the strspn builtin.
9502 Return 0 if no simplification was possible, otherwise return the
9503 simplified form of the call as a tree.
9505 The simplified form may be a constant or other expression which
9506 computes the same value, but in a more efficient manner (including
9507 calls to other builtin functions).
9509 The call may contain arguments which need to be evaluated, but
9510 which are not useful to determine the result of the call. In
9511 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9512 COMPOUND_EXPR will be an argument which must be evaluated.
9513 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9514 COMPOUND_EXPR in the chain will contain the tree for the simplified
9515 form of the builtin function call. */
9518 fold_builtin_strspn (tree arglist
)
9520 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
9524 tree s1
= TREE_VALUE (arglist
), s2
= TREE_VALUE (TREE_CHAIN (arglist
));
9525 const char *p1
= c_getstr (s1
), *p2
= c_getstr (s2
);
9527 /* If both arguments are constants, evaluate at compile-time. */
9530 const size_t r
= strspn (p1
, p2
);
9531 return size_int (r
);
9534 /* If either argument is "", return 0. */
9535 if ((p1
&& *p1
== '\0') || (p2
&& *p2
== '\0'))
9536 /* Evaluate and ignore both arguments in case either one has
9538 return omit_two_operands (integer_type_node
, integer_zero_node
,
9544 /* Simplify a call to the strcspn builtin.
9546 Return 0 if no simplification was possible, otherwise return the
9547 simplified form of the call as a tree.
9549 The simplified form may be a constant or other expression which
9550 computes the same value, but in a more efficient manner (including
9551 calls to other builtin functions).
9553 The call may contain arguments which need to be evaluated, but
9554 which are not useful to determine the result of the call. In
9555 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9556 COMPOUND_EXPR will be an argument which must be evaluated.
9557 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9558 COMPOUND_EXPR in the chain will contain the tree for the simplified
9559 form of the builtin function call. */
9562 fold_builtin_strcspn (tree arglist
)
9564 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
9568 tree s1
= TREE_VALUE (arglist
), s2
= TREE_VALUE (TREE_CHAIN (arglist
));
9569 const char *p1
= c_getstr (s1
), *p2
= c_getstr (s2
);
9571 /* If both arguments are constants, evaluate at compile-time. */
9574 const size_t r
= strcspn (p1
, p2
);
9575 return size_int (r
);
9578 /* If the first argument is "", return 0. */
9579 if (p1
&& *p1
== '\0')
9581 /* Evaluate and ignore argument s2 in case it has
9583 return omit_one_operand (integer_type_node
,
9584 integer_zero_node
, s2
);
9587 /* If the second argument is "", return __builtin_strlen(s1). */
9588 if (p2
&& *p2
== '\0')
9590 tree newarglist
= build_tree_list (NULL_TREE
, s1
),
9591 fn
= implicit_built_in_decls
[BUILT_IN_STRLEN
];
9593 /* If the replacement _DECL isn't initialized, don't do the
9598 return build_function_call_expr (fn
, newarglist
);
9604 /* Fold a call to the fputs builtin. IGNORE is true if the value returned
9605 by the builtin will be ignored. UNLOCKED is true is true if this
9606 actually a call to fputs_unlocked. If LEN in non-NULL, it represents
9607 the known length of the string. Return NULL_TREE if no simplification
9611 fold_builtin_fputs (tree arglist
, bool ignore
, bool unlocked
, tree len
)
9614 tree fn_fputc
= unlocked
? implicit_built_in_decls
[BUILT_IN_FPUTC_UNLOCKED
]
9615 : implicit_built_in_decls
[BUILT_IN_FPUTC
];
9616 tree fn_fwrite
= unlocked
? implicit_built_in_decls
[BUILT_IN_FWRITE_UNLOCKED
]
9617 : implicit_built_in_decls
[BUILT_IN_FWRITE
];
9619 /* If the return value is used, or the replacement _DECL isn't
9620 initialized, don't do the transformation. */
9621 if (!ignore
|| !fn_fputc
|| !fn_fwrite
)
9624 /* Verify the arguments in the original call. */
9625 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
9629 len
= c_strlen (TREE_VALUE (arglist
), 0);
9631 /* Get the length of the string passed to fputs. If the length
9632 can't be determined, punt. */
9634 || TREE_CODE (len
) != INTEGER_CST
)
9637 switch (compare_tree_int (len
, 1))
9639 case -1: /* length is 0, delete the call entirely . */
9640 return omit_one_operand (integer_type_node
, integer_zero_node
,
9641 TREE_VALUE (TREE_CHAIN (arglist
)));
9643 case 0: /* length is 1, call fputc. */
9645 const char *p
= c_getstr (TREE_VALUE (arglist
));
9649 /* New argument list transforming fputs(string, stream) to
9650 fputc(string[0], stream). */
9651 arglist
= build_tree_list (NULL_TREE
,
9652 TREE_VALUE (TREE_CHAIN (arglist
)));
9653 arglist
= tree_cons (NULL_TREE
,
9654 build_int_cst (NULL_TREE
, p
[0]),
9661 case 1: /* length is greater than 1, call fwrite. */
9665 /* If optimizing for size keep fputs. */
9668 string_arg
= TREE_VALUE (arglist
);
9669 /* New argument list transforming fputs(string, stream) to
9670 fwrite(string, 1, len, stream). */
9671 arglist
= build_tree_list (NULL_TREE
,
9672 TREE_VALUE (TREE_CHAIN (arglist
)));
9673 arglist
= tree_cons (NULL_TREE
, len
, arglist
);
9674 arglist
= tree_cons (NULL_TREE
, size_one_node
, arglist
);
9675 arglist
= tree_cons (NULL_TREE
, string_arg
, arglist
);
9683 /* These optimizations are only performed when the result is ignored,
9684 hence there's no need to cast the result to integer_type_node. */
9685 return build_function_call_expr (fn
, arglist
);
9688 /* Fold the new_arg's arguments (ARGLIST). Returns true if there was an error
9689 produced. False otherwise. This is done so that we don't output the error
9690 or warning twice or three times. */
9692 fold_builtin_next_arg (tree arglist
)
9694 tree fntype
= TREE_TYPE (current_function_decl
);
9696 if (TYPE_ARG_TYPES (fntype
) == 0
9697 || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype
)))
9700 error ("%<va_start%> used in function with fixed args");
9705 /* Evidently an out of date version of <stdarg.h>; can't validate
9706 va_start's second argument, but can still work as intended. */
9707 warning (0, "%<__builtin_next_arg%> called without an argument");
9710 /* We use __builtin_va_start (ap, 0, 0) or __builtin_next_arg (0, 0)
9711 when we checked the arguments and if needed issued a warning. */
9712 else if (!TREE_CHAIN (arglist
)
9713 || !integer_zerop (TREE_VALUE (arglist
))
9714 || !integer_zerop (TREE_VALUE (TREE_CHAIN (arglist
)))
9715 || TREE_CHAIN (TREE_CHAIN (arglist
)))
9717 tree last_parm
= tree_last (DECL_ARGUMENTS (current_function_decl
));
9718 tree arg
= TREE_VALUE (arglist
);
9720 if (TREE_CHAIN (arglist
))
9722 error ("%<va_start%> used with too many arguments");
9726 /* Strip off all nops for the sake of the comparison. This
9727 is not quite the same as STRIP_NOPS. It does more.
9728 We must also strip off INDIRECT_EXPR for C++ reference
9730 while (TREE_CODE (arg
) == NOP_EXPR
9731 || TREE_CODE (arg
) == CONVERT_EXPR
9732 || TREE_CODE (arg
) == NON_LVALUE_EXPR
9733 || TREE_CODE (arg
) == INDIRECT_REF
)
9734 arg
= TREE_OPERAND (arg
, 0);
9735 if (arg
!= last_parm
)
9737 /* FIXME: Sometimes with the tree optimizers we can get the
9738 not the last argument even though the user used the last
9739 argument. We just warn and set the arg to be the last
9740 argument so that we will get wrong-code because of
9742 warning (0, "second parameter of %<va_start%> not last named argument");
9744 /* We want to verify the second parameter just once before the tree
9745 optimizers are run and then avoid keeping it in the tree,
9746 as otherwise we could warn even for correct code like:
9747 void foo (int i, ...)
9748 { va_list ap; i++; va_start (ap, i); va_end (ap); } */
9749 TREE_VALUE (arglist
) = integer_zero_node
;
9750 TREE_CHAIN (arglist
) = build_tree_list (NULL
, integer_zero_node
);
9756 /* Simplify a call to the sprintf builtin.
9758 Return 0 if no simplification was possible, otherwise return the
9759 simplified form of the call as a tree. If IGNORED is true, it means that
9760 the caller does not use the returned value of the function. */
9763 fold_builtin_sprintf (tree arglist
, int ignored
)
9765 tree call
, retval
, dest
, fmt
;
9766 const char *fmt_str
= NULL
;
9768 /* Verify the required arguments in the original call. We deal with two
9769 types of sprintf() calls: 'sprintf (str, fmt)' and
9770 'sprintf (dest, "%s", orig)'. */
9771 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
)
9772 && !validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, POINTER_TYPE
,
9776 /* Get the destination string and the format specifier. */
9777 dest
= TREE_VALUE (arglist
);
9778 fmt
= TREE_VALUE (TREE_CHAIN (arglist
));
9780 /* Check whether the format is a literal string constant. */
9781 fmt_str
= c_getstr (fmt
);
9782 if (fmt_str
== NULL
)
9788 /* If the format doesn't contain % args or %%, use strcpy. */
9789 if (strchr (fmt_str
, '%') == NULL
)
9791 tree fn
= implicit_built_in_decls
[BUILT_IN_STRCPY
];
9796 /* Convert sprintf (str, fmt) into strcpy (str, fmt) when
9797 'format' is known to contain no % formats. */
9798 arglist
= build_tree_list (NULL_TREE
, fmt
);
9799 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
9800 call
= build_function_call_expr (fn
, arglist
);
9802 retval
= build_int_cst (NULL_TREE
, strlen (fmt_str
));
9805 /* If the format is "%s", use strcpy if the result isn't used. */
9806 else if (fmt_str
&& strcmp (fmt_str
, "%s") == 0)
9809 fn
= implicit_built_in_decls
[BUILT_IN_STRCPY
];
9814 /* Convert sprintf (str1, "%s", str2) into strcpy (str1, str2). */
9815 orig
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
9816 arglist
= build_tree_list (NULL_TREE
, orig
);
9817 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
9820 retval
= c_strlen (orig
, 1);
9821 if (!retval
|| TREE_CODE (retval
) != INTEGER_CST
)
9824 call
= build_function_call_expr (fn
, arglist
);
9830 (TREE_TYPE (TREE_TYPE (implicit_built_in_decls
[BUILT_IN_SPRINTF
])),
9832 return build2 (COMPOUND_EXPR
, TREE_TYPE (retval
), call
, retval
);
9838 /* Expand a call to __builtin_object_size. */
9841 expand_builtin_object_size (tree exp
)
9844 int object_size_type
;
9845 tree fndecl
= get_callee_fndecl (exp
);
9846 tree arglist
= TREE_OPERAND (exp
, 1);
9847 location_t locus
= EXPR_LOCATION (exp
);
9849 if (!validate_arglist (arglist
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
9851 error ("%Hfirst argument of %D must be a pointer, second integer constant",
9853 expand_builtin_trap ();
9857 ost
= TREE_VALUE (TREE_CHAIN (arglist
));
9860 if (TREE_CODE (ost
) != INTEGER_CST
9861 || tree_int_cst_sgn (ost
) < 0
9862 || compare_tree_int (ost
, 3) > 0)
9864 error ("%Hlast argument of %D is not integer constant between 0 and 3",
9866 expand_builtin_trap ();
9870 object_size_type
= tree_low_cst (ost
, 0);
9872 return object_size_type
< 2 ? constm1_rtx
: const0_rtx
;
9875 /* Expand EXP, a call to the __mem{cpy,pcpy,move,set}_chk builtin.
9876 FCODE is the BUILT_IN_* to use.
9877 Return 0 if we failed; the caller should emit a normal call,
9878 otherwise try to get the result in TARGET, if convenient (and in
9879 mode MODE if that's convenient). */
9882 expand_builtin_memory_chk (tree exp
, rtx target
, enum machine_mode mode
,
9883 enum built_in_function fcode
)
9885 tree arglist
= TREE_OPERAND (exp
, 1);
9886 tree dest
, src
, len
, size
;
9888 if (!validate_arglist (arglist
,
9890 fcode
== BUILT_IN_MEMSET_CHK
9891 ? INTEGER_TYPE
: POINTER_TYPE
,
9892 INTEGER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
9895 dest
= TREE_VALUE (arglist
);
9896 src
= TREE_VALUE (TREE_CHAIN (arglist
));
9897 len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
9898 size
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist
))));
9900 if (! host_integerp (size
, 1))
9903 if (host_integerp (len
, 1) || integer_all_onesp (size
))
9907 if (! integer_all_onesp (size
) && tree_int_cst_lt (size
, len
))
9909 location_t locus
= EXPR_LOCATION (exp
);
9910 warning (0, "%Hcall to %D will always overflow destination buffer",
9911 &locus
, get_callee_fndecl (exp
));
9915 arglist
= build_tree_list (NULL_TREE
, len
);
9916 arglist
= tree_cons (NULL_TREE
, src
, arglist
);
9917 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
9920 /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume
9921 mem{cpy,pcpy,move,set} is available. */
9924 case BUILT_IN_MEMCPY_CHK
:
9925 fn
= built_in_decls
[BUILT_IN_MEMCPY
];
9927 case BUILT_IN_MEMPCPY_CHK
:
9928 fn
= built_in_decls
[BUILT_IN_MEMPCPY
];
9930 case BUILT_IN_MEMMOVE_CHK
:
9931 fn
= built_in_decls
[BUILT_IN_MEMMOVE
];
9933 case BUILT_IN_MEMSET_CHK
:
9934 fn
= built_in_decls
[BUILT_IN_MEMSET
];
9943 fn
= build_function_call_expr (fn
, arglist
);
9944 if (TREE_CODE (fn
) == CALL_EXPR
)
9945 CALL_EXPR_TAILCALL (fn
) = CALL_EXPR_TAILCALL (exp
);
9946 return expand_expr (fn
, target
, mode
, EXPAND_NORMAL
);
9948 else if (fcode
== BUILT_IN_MEMSET_CHK
)
9952 unsigned int dest_align
9953 = get_pointer_alignment (dest
, BIGGEST_ALIGNMENT
);
9955 /* If DEST is not a pointer type, call the normal function. */
9956 if (dest_align
== 0)
9959 /* If SRC and DEST are the same (and not volatile), do nothing. */
9960 if (operand_equal_p (src
, dest
, 0))
9964 if (fcode
!= BUILT_IN_MEMPCPY_CHK
)
9966 /* Evaluate and ignore LEN in case it has side-effects. */
9967 expand_expr (len
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
9968 return expand_expr (dest
, target
, mode
, EXPAND_NORMAL
);
9971 len
= fold_convert (TREE_TYPE (dest
), len
);
9972 expr
= fold_build2 (PLUS_EXPR
, TREE_TYPE (dest
), dest
, len
);
9973 return expand_expr (expr
, target
, mode
, EXPAND_NORMAL
);
9976 /* __memmove_chk special case. */
9977 if (fcode
== BUILT_IN_MEMMOVE_CHK
)
9979 unsigned int src_align
9980 = get_pointer_alignment (src
, BIGGEST_ALIGNMENT
);
9985 /* If src is categorized for a readonly section we can use
9986 normal __memcpy_chk. */
9987 if (readonly_data_expr (src
))
9989 tree fn
= built_in_decls
[BUILT_IN_MEMCPY_CHK
];
9992 fn
= build_function_call_expr (fn
, arglist
);
9993 if (TREE_CODE (fn
) == CALL_EXPR
)
9994 CALL_EXPR_TAILCALL (fn
) = CALL_EXPR_TAILCALL (exp
);
9995 return expand_expr (fn
, target
, mode
, EXPAND_NORMAL
);
10002 /* Emit warning if a buffer overflow is detected at compile time. */
10005 maybe_emit_chk_warning (tree exp
, enum built_in_function fcode
)
10007 int arg_mask
, is_strlen
= 0;
10008 tree arglist
= TREE_OPERAND (exp
, 1), a
;
10014 case BUILT_IN_STRCPY_CHK
:
10015 case BUILT_IN_STPCPY_CHK
:
10016 /* For __strcat_chk the warning will be emitted only if overflowing
10017 by at least strlen (dest) + 1 bytes. */
10018 case BUILT_IN_STRCAT_CHK
:
10022 case BUILT_IN_STRNCPY_CHK
:
10025 case BUILT_IN_SNPRINTF_CHK
:
10026 case BUILT_IN_VSNPRINTF_CHK
:
10030 gcc_unreachable ();
10035 for (a
= arglist
; a
&& arg_mask
; a
= TREE_CHAIN (a
), arg_mask
>>= 1)
10047 len
= TREE_VALUE (len
);
10048 size
= TREE_VALUE (size
);
10050 if (! host_integerp (size
, 1) || integer_all_onesp (size
))
10055 len
= c_strlen (len
, 1);
10056 if (! len
|| ! host_integerp (len
, 1) || tree_int_cst_lt (len
, size
))
10059 else if (! host_integerp (len
, 1) || ! tree_int_cst_lt (size
, len
))
10062 locus
= EXPR_LOCATION (exp
);
10063 warning (0, "%Hcall to %D will always overflow destination buffer",
10064 &locus
, get_callee_fndecl (exp
));
10067 /* Emit warning if a buffer overflow is detected at compile time
10068 in __sprintf_chk/__vsprintf_chk calls. */
10071 maybe_emit_sprintf_chk_warning (tree exp
, enum built_in_function fcode
)
10073 tree arglist
= TREE_OPERAND (exp
, 1);
10074 tree dest
, size
, len
, fmt
, flag
;
10075 const char *fmt_str
;
10077 /* Verify the required arguments in the original call. */
10080 dest
= TREE_VALUE (arglist
);
10081 arglist
= TREE_CHAIN (arglist
);
10084 flag
= TREE_VALUE (arglist
);
10085 arglist
= TREE_CHAIN (arglist
);
10088 size
= TREE_VALUE (arglist
);
10089 arglist
= TREE_CHAIN (arglist
);
10092 fmt
= TREE_VALUE (arglist
);
10093 arglist
= TREE_CHAIN (arglist
);
10095 if (! host_integerp (size
, 1) || integer_all_onesp (size
))
10098 /* Check whether the format is a literal string constant. */
10099 fmt_str
= c_getstr (fmt
);
10100 if (fmt_str
== NULL
)
10103 /* If the format doesn't contain % args or %%, we know its size. */
10104 if (strchr (fmt_str
, '%') == 0)
10105 len
= build_int_cstu (size_type_node
, strlen (fmt_str
));
10106 /* If the format is "%s" and first ... argument is a string literal,
10108 else if (fcode
== BUILT_IN_SPRINTF_CHK
&& strcmp (fmt_str
, "%s") == 0)
10114 arg
= TREE_VALUE (arglist
);
10115 if (! POINTER_TYPE_P (TREE_TYPE (arg
)))
10118 len
= c_strlen (arg
, 1);
10119 if (!len
|| ! host_integerp (len
, 1))
10125 if (! tree_int_cst_lt (len
, size
))
10127 location_t locus
= EXPR_LOCATION (exp
);
10128 warning (0, "%Hcall to %D will always overflow destination buffer",
10129 &locus
, get_callee_fndecl (exp
));
10133 /* Fold a call to __builtin_object_size, if possible. */
10136 fold_builtin_object_size (tree arglist
)
10138 tree ptr
, ost
, ret
= 0;
10139 int object_size_type
;
10141 if (!validate_arglist (arglist
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
10144 ptr
= TREE_VALUE (arglist
);
10145 ost
= TREE_VALUE (TREE_CHAIN (arglist
));
10148 if (TREE_CODE (ost
) != INTEGER_CST
10149 || tree_int_cst_sgn (ost
) < 0
10150 || compare_tree_int (ost
, 3) > 0)
10153 object_size_type
= tree_low_cst (ost
, 0);
10155 /* __builtin_object_size doesn't evaluate side-effects in its arguments;
10156 if there are any side-effects, it returns (size_t) -1 for types 0 and 1
10157 and (size_t) 0 for types 2 and 3. */
10158 if (TREE_SIDE_EFFECTS (ptr
))
10159 return fold_convert (size_type_node
,
10160 object_size_type
< 2
10161 ? integer_minus_one_node
: integer_zero_node
);
10163 if (TREE_CODE (ptr
) == ADDR_EXPR
)
10164 ret
= build_int_cstu (size_type_node
,
10165 compute_builtin_object_size (ptr
, object_size_type
));
10167 else if (TREE_CODE (ptr
) == SSA_NAME
)
10169 unsigned HOST_WIDE_INT bytes
;
10171 /* If object size is not known yet, delay folding until
10172 later. Maybe subsequent passes will help determining
10174 bytes
= compute_builtin_object_size (ptr
, object_size_type
);
10175 if (bytes
!= (unsigned HOST_WIDE_INT
) (object_size_type
< 2
10177 ret
= build_int_cstu (size_type_node
, bytes
);
10182 ret
= force_fit_type (ret
, -1, false, false);
10183 if (TREE_CONSTANT_OVERFLOW (ret
))
10190 /* Fold a call to the __mem{cpy,pcpy,move,set}_chk builtin.
10191 IGNORE is true, if return value can be ignored. FCODE is the BUILT_IN_*
10192 code of the builtin. If MAXLEN is not NULL, it is maximum length
10193 passed as third argument. */
10196 fold_builtin_memory_chk (tree fndecl
, tree arglist
, tree maxlen
, bool ignore
,
10197 enum built_in_function fcode
)
10199 tree dest
, src
, len
, size
, fn
;
10201 if (!validate_arglist (arglist
,
10203 fcode
== BUILT_IN_MEMSET_CHK
10204 ? INTEGER_TYPE
: POINTER_TYPE
,
10205 INTEGER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
10208 dest
= TREE_VALUE (arglist
);
10209 /* Actually val for __memset_chk, but it doesn't matter. */
10210 src
= TREE_VALUE (TREE_CHAIN (arglist
));
10211 len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
10212 size
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist
))));
10214 /* If SRC and DEST are the same (and not volatile), return DEST
10215 (resp. DEST+LEN for __mempcpy_chk). */
10216 if (fcode
!= BUILT_IN_MEMSET_CHK
&& operand_equal_p (src
, dest
, 0))
10218 if (fcode
!= BUILT_IN_MEMPCPY_CHK
)
10219 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl
)), dest
, len
);
10222 tree temp
= fold_convert (TREE_TYPE (dest
), len
);
10223 temp
= fold_build2 (PLUS_EXPR
, TREE_TYPE (dest
), dest
, temp
);
10224 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl
)), temp
);
10228 if (! host_integerp (size
, 1))
10231 if (! integer_all_onesp (size
))
10233 if (! host_integerp (len
, 1))
10235 /* If LEN is not constant, try MAXLEN too.
10236 For MAXLEN only allow optimizing into non-_ocs function
10237 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
10238 if (maxlen
== NULL_TREE
|| ! host_integerp (maxlen
, 1))
10240 if (fcode
== BUILT_IN_MEMPCPY_CHK
&& ignore
)
10242 /* (void) __mempcpy_chk () can be optimized into
10243 (void) __memcpy_chk (). */
10244 fn
= built_in_decls
[BUILT_IN_MEMCPY_CHK
];
10248 return build_function_call_expr (fn
, arglist
);
10256 if (tree_int_cst_lt (size
, maxlen
))
10260 arglist
= build_tree_list (NULL_TREE
, len
);
10261 arglist
= tree_cons (NULL_TREE
, src
, arglist
);
10262 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
10265 /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume
10266 mem{cpy,pcpy,move,set} is available. */
10269 case BUILT_IN_MEMCPY_CHK
:
10270 fn
= built_in_decls
[BUILT_IN_MEMCPY
];
10272 case BUILT_IN_MEMPCPY_CHK
:
10273 fn
= built_in_decls
[BUILT_IN_MEMPCPY
];
10275 case BUILT_IN_MEMMOVE_CHK
:
10276 fn
= built_in_decls
[BUILT_IN_MEMMOVE
];
10278 case BUILT_IN_MEMSET_CHK
:
10279 fn
= built_in_decls
[BUILT_IN_MEMSET
];
10288 return build_function_call_expr (fn
, arglist
);
10291 /* Fold a call to the __st[rp]cpy_chk builtin.
10292 IGNORE is true, if return value can be ignored. FCODE is the BUILT_IN_*
10293 code of the builtin. If MAXLEN is not NULL, it is maximum length of
10294 strings passed as second argument. */
10297 fold_builtin_stxcpy_chk (tree fndecl
, tree arglist
, tree maxlen
, bool ignore
,
10298 enum built_in_function fcode
)
10300 tree dest
, src
, size
, len
, fn
;
10302 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
,
10306 dest
= TREE_VALUE (arglist
);
10307 src
= TREE_VALUE (TREE_CHAIN (arglist
));
10308 size
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
10310 /* If SRC and DEST are the same (and not volatile), return DEST. */
10311 if (fcode
== BUILT_IN_STRCPY_CHK
&& operand_equal_p (src
, dest
, 0))
10312 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl
)), dest
);
10314 if (! host_integerp (size
, 1))
10317 if (! integer_all_onesp (size
))
10319 len
= c_strlen (src
, 1);
10320 if (! len
|| ! host_integerp (len
, 1))
10322 /* If LEN is not constant, try MAXLEN too.
10323 For MAXLEN only allow optimizing into non-_ocs function
10324 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
10325 if (maxlen
== NULL_TREE
|| ! host_integerp (maxlen
, 1))
10327 if (fcode
== BUILT_IN_STPCPY_CHK
)
10332 /* If return value of __stpcpy_chk is ignored,
10333 optimize into __strcpy_chk. */
10334 fn
= built_in_decls
[BUILT_IN_STRCPY_CHK
];
10338 return build_function_call_expr (fn
, arglist
);
10341 if (! len
|| TREE_SIDE_EFFECTS (len
))
10344 /* If c_strlen returned something, but not a constant,
10345 transform __strcpy_chk into __memcpy_chk. */
10346 fn
= built_in_decls
[BUILT_IN_MEMCPY_CHK
];
10350 len
= size_binop (PLUS_EXPR
, len
, ssize_int (1));
10351 arglist
= build_tree_list (NULL_TREE
, size
);
10352 arglist
= tree_cons (NULL_TREE
, len
, arglist
);
10353 arglist
= tree_cons (NULL_TREE
, src
, arglist
);
10354 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
10355 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl
)),
10356 build_function_call_expr (fn
, arglist
));
10362 if (! tree_int_cst_lt (maxlen
, size
))
10366 arglist
= build_tree_list (NULL_TREE
, src
);
10367 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
10369 /* If __builtin_st{r,p}cpy_chk is used, assume st{r,p}cpy is available. */
10370 fn
= built_in_decls
[fcode
== BUILT_IN_STPCPY_CHK
10371 ? BUILT_IN_STPCPY
: BUILT_IN_STRCPY
];
10375 return build_function_call_expr (fn
, arglist
);
10378 /* Fold a call to the __strncpy_chk builtin.
10379 If MAXLEN is not NULL, it is maximum length passed as third argument. */
10382 fold_builtin_strncpy_chk (tree arglist
, tree maxlen
)
10384 tree dest
, src
, size
, len
, fn
;
10386 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
,
10387 INTEGER_TYPE
, VOID_TYPE
))
10390 dest
= TREE_VALUE (arglist
);
10391 src
= TREE_VALUE (TREE_CHAIN (arglist
));
10392 len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
10393 size
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist
))));
10395 if (! host_integerp (size
, 1))
10398 if (! integer_all_onesp (size
))
10400 if (! host_integerp (len
, 1))
10402 /* If LEN is not constant, try MAXLEN too.
10403 For MAXLEN only allow optimizing into non-_ocs function
10404 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
10405 if (maxlen
== NULL_TREE
|| ! host_integerp (maxlen
, 1))
10411 if (tree_int_cst_lt (size
, maxlen
))
10415 arglist
= build_tree_list (NULL_TREE
, len
);
10416 arglist
= tree_cons (NULL_TREE
, src
, arglist
);
10417 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
10419 /* If __builtin_strncpy_chk is used, assume strncpy is available. */
10420 fn
= built_in_decls
[BUILT_IN_STRNCPY
];
10424 return build_function_call_expr (fn
, arglist
);
10427 /* Fold a call to the __strcat_chk builtin FNDECL with ARGLIST. */
10430 fold_builtin_strcat_chk (tree fndecl
, tree arglist
)
10432 tree dest
, src
, size
, fn
;
10435 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
,
10439 dest
= TREE_VALUE (arglist
);
10440 src
= TREE_VALUE (TREE_CHAIN (arglist
));
10441 size
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
10443 p
= c_getstr (src
);
10444 /* If the SRC parameter is "", return DEST. */
10445 if (p
&& *p
== '\0')
10446 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl
)), dest
, src
);
10448 if (! host_integerp (size
, 1) || ! integer_all_onesp (size
))
10451 arglist
= build_tree_list (NULL_TREE
, src
);
10452 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
10454 /* If __builtin_strcat_chk is used, assume strcat is available. */
10455 fn
= built_in_decls
[BUILT_IN_STRCAT
];
10459 return build_function_call_expr (fn
, arglist
);
10462 /* Fold a call to the __strncat_chk builtin EXP. */
10465 fold_builtin_strncat_chk (tree fndecl
, tree arglist
)
10467 tree dest
, src
, size
, len
, fn
;
10470 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
,
10471 INTEGER_TYPE
, VOID_TYPE
))
10474 dest
= TREE_VALUE (arglist
);
10475 src
= TREE_VALUE (TREE_CHAIN (arglist
));
10476 len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
10477 size
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist
))));
10479 p
= c_getstr (src
);
10480 /* If the SRC parameter is "" or if LEN is 0, return DEST. */
10481 if (p
&& *p
== '\0')
10482 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl
)), dest
, len
);
10483 else if (integer_zerop (len
))
10484 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl
)), dest
, src
);
10486 if (! host_integerp (size
, 1))
10489 if (! integer_all_onesp (size
))
10491 tree src_len
= c_strlen (src
, 1);
10493 && host_integerp (src_len
, 1)
10494 && host_integerp (len
, 1)
10495 && ! tree_int_cst_lt (len
, src_len
))
10497 /* If LEN >= strlen (SRC), optimize into __strcat_chk. */
10498 fn
= built_in_decls
[BUILT_IN_STRCAT_CHK
];
10502 arglist
= build_tree_list (NULL_TREE
, size
);
10503 arglist
= tree_cons (NULL_TREE
, src
, arglist
);
10504 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
10505 return build_function_call_expr (fn
, arglist
);
10510 arglist
= build_tree_list (NULL_TREE
, len
);
10511 arglist
= tree_cons (NULL_TREE
, src
, arglist
);
10512 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
10514 /* If __builtin_strncat_chk is used, assume strncat is available. */
10515 fn
= built_in_decls
[BUILT_IN_STRNCAT
];
10519 return build_function_call_expr (fn
, arglist
);
10522 /* Fold a call to __{,v}sprintf_chk with argument list ARGLIST. Return 0 if
10523 a normal call should be emitted rather than expanding the function
10524 inline. FCODE is either BUILT_IN_SPRINTF_CHK or BUILT_IN_VSPRINTF_CHK. */
10527 fold_builtin_sprintf_chk (tree arglist
, enum built_in_function fcode
)
10529 tree dest
, size
, len
, fn
, fmt
, flag
;
10530 const char *fmt_str
;
10532 /* Verify the required arguments in the original call. */
10535 dest
= TREE_VALUE (arglist
);
10536 if (! POINTER_TYPE_P (TREE_TYPE (dest
)))
10538 arglist
= TREE_CHAIN (arglist
);
10541 flag
= TREE_VALUE (arglist
);
10542 if (TREE_CODE (TREE_TYPE (flag
)) != INTEGER_TYPE
)
10544 arglist
= TREE_CHAIN (arglist
);
10547 size
= TREE_VALUE (arglist
);
10548 if (TREE_CODE (TREE_TYPE (size
)) != INTEGER_TYPE
)
10550 arglist
= TREE_CHAIN (arglist
);
10553 fmt
= TREE_VALUE (arglist
);
10554 if (! POINTER_TYPE_P (TREE_TYPE (fmt
)))
10556 arglist
= TREE_CHAIN (arglist
);
10558 if (! host_integerp (size
, 1))
10563 /* Check whether the format is a literal string constant. */
10564 fmt_str
= c_getstr (fmt
);
10565 if (fmt_str
!= NULL
)
10567 /* If the format doesn't contain % args or %%, we know the size. */
10568 if (strchr (fmt_str
, '%') == 0)
10570 if (fcode
!= BUILT_IN_SPRINTF_CHK
|| arglist
== NULL_TREE
)
10571 len
= build_int_cstu (size_type_node
, strlen (fmt_str
));
10573 /* If the format is "%s" and first ... argument is a string literal,
10574 we know the size too. */
10575 else if (fcode
== BUILT_IN_SPRINTF_CHK
&& strcmp (fmt_str
, "%s") == 0)
10579 if (arglist
&& !TREE_CHAIN (arglist
))
10581 arg
= TREE_VALUE (arglist
);
10582 if (POINTER_TYPE_P (TREE_TYPE (arg
)))
10584 len
= c_strlen (arg
, 1);
10585 if (! len
|| ! host_integerp (len
, 1))
10592 if (! integer_all_onesp (size
))
10594 if (! len
|| ! tree_int_cst_lt (len
, size
))
10598 /* Only convert __{,v}sprintf_chk to {,v}sprintf if flag is 0
10599 or if format doesn't contain % chars or is "%s". */
10600 if (! integer_zerop (flag
))
10602 if (fmt_str
== NULL
)
10604 if (strchr (fmt_str
, '%') != NULL
&& strcmp (fmt_str
, "%s"))
10608 arglist
= tree_cons (NULL_TREE
, fmt
, arglist
);
10609 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
10611 /* If __builtin_{,v}sprintf_chk is used, assume {,v}sprintf is available. */
10612 fn
= built_in_decls
[fcode
== BUILT_IN_VSPRINTF_CHK
10613 ? BUILT_IN_VSPRINTF
: BUILT_IN_SPRINTF
];
10617 return build_function_call_expr (fn
, arglist
);
10620 /* Fold a call to {,v}snprintf with argument list ARGLIST. Return 0 if
10621 a normal call should be emitted rather than expanding the function
10622 inline. FCODE is either BUILT_IN_SNPRINTF_CHK or
10623 BUILT_IN_VSNPRINTF_CHK. If MAXLEN is not NULL, it is maximum length
10624 passed as second argument. */
10627 fold_builtin_snprintf_chk (tree arglist
, tree maxlen
,
10628 enum built_in_function fcode
)
10630 tree dest
, size
, len
, fn
, fmt
, flag
;
10631 const char *fmt_str
;
10633 /* Verify the required arguments in the original call. */
10636 dest
= TREE_VALUE (arglist
);
10637 if (! POINTER_TYPE_P (TREE_TYPE (dest
)))
10639 arglist
= TREE_CHAIN (arglist
);
10642 len
= TREE_VALUE (arglist
);
10643 if (TREE_CODE (TREE_TYPE (len
)) != INTEGER_TYPE
)
10645 arglist
= TREE_CHAIN (arglist
);
10648 flag
= TREE_VALUE (arglist
);
10649 if (TREE_CODE (TREE_TYPE (len
)) != INTEGER_TYPE
)
10651 arglist
= TREE_CHAIN (arglist
);
10654 size
= TREE_VALUE (arglist
);
10655 if (TREE_CODE (TREE_TYPE (size
)) != INTEGER_TYPE
)
10657 arglist
= TREE_CHAIN (arglist
);
10660 fmt
= TREE_VALUE (arglist
);
10661 if (! POINTER_TYPE_P (TREE_TYPE (fmt
)))
10663 arglist
= TREE_CHAIN (arglist
);
10665 if (! host_integerp (size
, 1))
10668 if (! integer_all_onesp (size
))
10670 if (! host_integerp (len
, 1))
10672 /* If LEN is not constant, try MAXLEN too.
10673 For MAXLEN only allow optimizing into non-_ocs function
10674 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
10675 if (maxlen
== NULL_TREE
|| ! host_integerp (maxlen
, 1))
10681 if (tree_int_cst_lt (size
, maxlen
))
10685 /* Only convert __{,v}snprintf_chk to {,v}snprintf if flag is 0
10686 or if format doesn't contain % chars or is "%s". */
10687 if (! integer_zerop (flag
))
10689 fmt_str
= c_getstr (fmt
);
10690 if (fmt_str
== NULL
)
10692 if (strchr (fmt_str
, '%') != NULL
&& strcmp (fmt_str
, "%s"))
10696 arglist
= tree_cons (NULL_TREE
, fmt
, arglist
);
10697 arglist
= tree_cons (NULL_TREE
, len
, arglist
);
10698 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
10700 /* If __builtin_{,v}snprintf_chk is used, assume {,v}snprintf is
10702 fn
= built_in_decls
[fcode
== BUILT_IN_VSNPRINTF_CHK
10703 ? BUILT_IN_VSNPRINTF
: BUILT_IN_SNPRINTF
];
10707 return build_function_call_expr (fn
, arglist
);
10710 /* Fold a call to the {,v}printf{,_unlocked} and __{,v}printf_chk builtins.
10712 Return 0 if no simplification was possible, otherwise return the
10713 simplified form of the call as a tree. FCODE is the BUILT_IN_*
10714 code of the function to be simplified. */
10717 fold_builtin_printf (tree fndecl
, tree arglist
, bool ignore
,
10718 enum built_in_function fcode
)
10720 tree fmt
, fn
= NULL_TREE
, fn_putchar
, fn_puts
, arg
, call
;
10721 const char *fmt_str
= NULL
;
10723 /* If the return value is used, don't do the transformation. */
10727 /* Verify the required arguments in the original call. */
10728 if (fcode
== BUILT_IN_PRINTF_CHK
|| fcode
== BUILT_IN_VPRINTF_CHK
)
10734 flag
= TREE_VALUE (arglist
);
10735 if (TREE_CODE (TREE_TYPE (flag
)) != INTEGER_TYPE
10736 || TREE_SIDE_EFFECTS (flag
))
10738 arglist
= TREE_CHAIN (arglist
);
10743 fmt
= TREE_VALUE (arglist
);
10744 if (! POINTER_TYPE_P (TREE_TYPE (fmt
)))
10746 arglist
= TREE_CHAIN (arglist
);
10748 /* Check whether the format is a literal string constant. */
10749 fmt_str
= c_getstr (fmt
);
10750 if (fmt_str
== NULL
)
10753 if (fcode
== BUILT_IN_PRINTF_UNLOCKED
)
10755 fn_putchar
= implicit_built_in_decls
[BUILT_IN_PUTCHAR_UNLOCKED
];
10756 fn_puts
= implicit_built_in_decls
[BUILT_IN_PUTS_UNLOCKED
];
10760 fn_putchar
= implicit_built_in_decls
[BUILT_IN_PUTCHAR
];
10761 fn_puts
= implicit_built_in_decls
[BUILT_IN_PUTS
];
10764 if (strcmp (fmt_str
, "%s") == 0 || strchr (fmt_str
, '%') == NULL
)
10768 if (strcmp (fmt_str
, "%s") == 0)
10770 if (fcode
== BUILT_IN_VPRINTF
|| fcode
== BUILT_IN_VPRINTF_CHK
)
10774 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist
)))
10775 || TREE_CHAIN (arglist
))
10778 str
= c_getstr (TREE_VALUE (arglist
));
10784 /* The format specifier doesn't contain any '%' characters. */
10785 if (fcode
!= BUILT_IN_VPRINTF
&& fcode
!= BUILT_IN_VPRINTF_CHK
10791 /* If the string was "", printf does nothing. */
10792 if (str
[0] == '\0')
10793 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl
)), 0);
10795 /* If the string has length of 1, call putchar. */
10796 if (str
[1] == '\0')
10798 /* Given printf("c"), (where c is any one character,)
10799 convert "c"[0] to an int and pass that to the replacement
10801 arg
= build_int_cst (NULL_TREE
, str
[0]);
10802 arglist
= build_tree_list (NULL_TREE
, arg
);
10807 /* If the string was "string\n", call puts("string"). */
10808 size_t len
= strlen (str
);
10809 if (str
[len
- 1] == '\n')
10811 /* Create a NUL-terminated string that's one char shorter
10812 than the original, stripping off the trailing '\n'. */
10813 char *newstr
= alloca (len
);
10814 memcpy (newstr
, str
, len
- 1);
10815 newstr
[len
- 1] = 0;
10817 arg
= build_string_literal (len
, newstr
);
10818 arglist
= build_tree_list (NULL_TREE
, arg
);
10822 /* We'd like to arrange to call fputs(string,stdout) here,
10823 but we need stdout and don't have a way to get it yet. */
10828 /* The other optimizations can be done only on the non-va_list variants. */
10829 else if (fcode
== BUILT_IN_VPRINTF
|| fcode
== BUILT_IN_VPRINTF_CHK
)
10832 /* If the format specifier was "%s\n", call __builtin_puts(arg). */
10833 else if (strcmp (fmt_str
, "%s\n") == 0)
10836 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist
)))
10837 || TREE_CHAIN (arglist
))
10842 /* If the format specifier was "%c", call __builtin_putchar(arg). */
10843 else if (strcmp (fmt_str
, "%c") == 0)
10846 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist
))) != INTEGER_TYPE
10847 || TREE_CHAIN (arglist
))
10855 call
= build_function_call_expr (fn
, arglist
);
10856 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl
)), call
);
10859 /* Fold a call to the {,v}fprintf{,_unlocked} and __{,v}printf_chk builtins.
10861 Return 0 if no simplification was possible, otherwise return the
10862 simplified form of the call as a tree. FCODE is the BUILT_IN_*
10863 code of the function to be simplified. */
10866 fold_builtin_fprintf (tree fndecl
, tree arglist
, bool ignore
,
10867 enum built_in_function fcode
)
10869 tree fp
, fmt
, fn
= NULL_TREE
, fn_fputc
, fn_fputs
, arg
, call
;
10870 const char *fmt_str
= NULL
;
10872 /* If the return value is used, don't do the transformation. */
10876 /* Verify the required arguments in the original call. */
10879 fp
= TREE_VALUE (arglist
);
10880 if (! POINTER_TYPE_P (TREE_TYPE (fp
)))
10882 arglist
= TREE_CHAIN (arglist
);
10884 if (fcode
== BUILT_IN_FPRINTF_CHK
|| fcode
== BUILT_IN_VFPRINTF_CHK
)
10890 flag
= TREE_VALUE (arglist
);
10891 if (TREE_CODE (TREE_TYPE (flag
)) != INTEGER_TYPE
10892 || TREE_SIDE_EFFECTS (flag
))
10894 arglist
= TREE_CHAIN (arglist
);
10899 fmt
= TREE_VALUE (arglist
);
10900 if (! POINTER_TYPE_P (TREE_TYPE (fmt
)))
10902 arglist
= TREE_CHAIN (arglist
);
10904 /* Check whether the format is a literal string constant. */
10905 fmt_str
= c_getstr (fmt
);
10906 if (fmt_str
== NULL
)
10909 if (fcode
== BUILT_IN_FPRINTF_UNLOCKED
)
10911 fn_fputc
= implicit_built_in_decls
[BUILT_IN_FPUTC_UNLOCKED
];
10912 fn_fputs
= implicit_built_in_decls
[BUILT_IN_FPUTS_UNLOCKED
];
10916 fn_fputc
= implicit_built_in_decls
[BUILT_IN_FPUTC
];
10917 fn_fputs
= implicit_built_in_decls
[BUILT_IN_FPUTS
];
10920 /* If the format doesn't contain % args or %%, use strcpy. */
10921 if (strchr (fmt_str
, '%') == NULL
)
10923 if (fcode
!= BUILT_IN_VFPRINTF
&& fcode
!= BUILT_IN_VFPRINTF_CHK
10927 /* If the format specifier was "", fprintf does nothing. */
10928 if (fmt_str
[0] == '\0')
10930 /* If FP has side-effects, just wait until gimplification is
10932 if (TREE_SIDE_EFFECTS (fp
))
10935 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl
)), 0);
10938 /* When "string" doesn't contain %, replace all cases of
10939 fprintf (fp, string) with fputs (string, fp). The fputs
10940 builtin will take care of special cases like length == 1. */
10941 arglist
= build_tree_list (NULL_TREE
, fp
);
10942 arglist
= tree_cons (NULL_TREE
, fmt
, arglist
);
10946 /* The other optimizations can be done only on the non-va_list variants. */
10947 else if (fcode
== BUILT_IN_VFPRINTF
|| fcode
== BUILT_IN_VFPRINTF_CHK
)
10950 /* If the format specifier was "%s", call __builtin_fputs (arg, fp). */
10951 else if (strcmp (fmt_str
, "%s") == 0)
10954 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist
)))
10955 || TREE_CHAIN (arglist
))
10957 arg
= TREE_VALUE (arglist
);
10958 arglist
= build_tree_list (NULL_TREE
, fp
);
10959 arglist
= tree_cons (NULL_TREE
, arg
, arglist
);
10963 /* If the format specifier was "%c", call __builtin_fputc (arg, fp). */
10964 else if (strcmp (fmt_str
, "%c") == 0)
10967 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist
))) != INTEGER_TYPE
10968 || TREE_CHAIN (arglist
))
10970 arg
= TREE_VALUE (arglist
);
10971 arglist
= build_tree_list (NULL_TREE
, fp
);
10972 arglist
= tree_cons (NULL_TREE
, arg
, arglist
);
10979 call
= build_function_call_expr (fn
, arglist
);
10980 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl
)), call
);