1 /* Expand builtin functions.
2 Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING. If not, write to the Free
19 Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
24 #include "coretypes.h"
30 #include "tree-gimple.h"
33 #include "hard-reg-set.h"
36 #include "insn-config.h"
42 #include "typeclass.h"
47 #include "langhooks.h"
48 #include "basic-block.h"
49 #include "tree-mudflap.h"
50 #include "tree-flow.h"
52 #ifndef PAD_VARARGS_DOWN
53 #define PAD_VARARGS_DOWN BYTES_BIG_ENDIAN
56 /* Define the names of the builtin function types and codes. */
57 const char *const built_in_class_names
[4]
58 = {"NOT_BUILT_IN", "BUILT_IN_FRONTEND", "BUILT_IN_MD", "BUILT_IN_NORMAL"};
60 #define DEF_BUILTIN(X, N, C, T, LT, B, F, NA, AT, IM, COND) #X,
61 const char * built_in_names
[(int) END_BUILTINS
] =
63 #include "builtins.def"
67 /* Setup an array of _DECL trees, make sure each element is
68 initialized to NULL_TREE. */
69 tree built_in_decls
[(int) END_BUILTINS
];
70 /* Declarations used when constructing the builtin implicitly in the compiler.
71 It may be NULL_TREE when this is invalid (for instance runtime is not
72 required to implement the function call in all cases). */
73 tree implicit_built_in_decls
[(int) END_BUILTINS
];
75 static const char *c_getstr (tree
);
76 static rtx
c_readstr (const char *, enum machine_mode
);
77 static int target_char_cast (tree
, char *);
78 static rtx
get_memory_rtx (tree
, tree
);
79 static int apply_args_size (void);
80 static int apply_result_size (void);
81 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
82 static rtx
result_vector (int, rtx
);
84 static void expand_builtin_update_setjmp_buf (rtx
);
85 static void expand_builtin_prefetch (tree
);
86 static rtx
expand_builtin_apply_args (void);
87 static rtx
expand_builtin_apply_args_1 (void);
88 static rtx
expand_builtin_apply (rtx
, rtx
, rtx
);
89 static void expand_builtin_return (rtx
);
90 static enum type_class
type_to_class (tree
);
91 static rtx
expand_builtin_classify_type (tree
);
92 static void expand_errno_check (tree
, rtx
);
93 static rtx
expand_builtin_mathfn (tree
, rtx
, rtx
);
94 static rtx
expand_builtin_mathfn_2 (tree
, rtx
, rtx
);
95 static rtx
expand_builtin_mathfn_3 (tree
, rtx
, rtx
);
96 static rtx
expand_builtin_sincos (tree
);
97 static rtx
expand_builtin_cexpi (tree
, rtx
, rtx
);
98 static rtx
expand_builtin_int_roundingfn (tree
, rtx
, rtx
);
99 static rtx
expand_builtin_int_roundingfn_2 (tree
, rtx
, rtx
);
100 static rtx
expand_builtin_args_info (tree
);
101 static rtx
expand_builtin_next_arg (void);
102 static rtx
expand_builtin_va_start (tree
);
103 static rtx
expand_builtin_va_end (tree
);
104 static rtx
expand_builtin_va_copy (tree
);
105 static rtx
expand_builtin_memcmp (tree
, tree
, rtx
, enum machine_mode
);
106 static rtx
expand_builtin_strcmp (tree
, rtx
, enum machine_mode
);
107 static rtx
expand_builtin_strncmp (tree
, rtx
, enum machine_mode
);
108 static rtx
builtin_memcpy_read_str (void *, HOST_WIDE_INT
, enum machine_mode
);
109 static rtx
expand_builtin_strcat (tree
, tree
, rtx
, enum machine_mode
);
110 static rtx
expand_builtin_strncat (tree
, rtx
, enum machine_mode
);
111 static rtx
expand_builtin_strspn (tree
, rtx
, enum machine_mode
);
112 static rtx
expand_builtin_strcspn (tree
, rtx
, enum machine_mode
);
113 static rtx
expand_builtin_memcpy (tree
, rtx
, enum machine_mode
);
114 static rtx
expand_builtin_mempcpy (tree
, tree
, rtx
, enum machine_mode
, int);
115 static rtx
expand_builtin_memmove (tree
, tree
, rtx
, enum machine_mode
);
116 static rtx
expand_builtin_bcopy (tree
);
117 static rtx
expand_builtin_strcpy (tree
, tree
, rtx
, enum machine_mode
);
118 static rtx
expand_builtin_stpcpy (tree
, rtx
, enum machine_mode
);
119 static rtx
builtin_strncpy_read_str (void *, HOST_WIDE_INT
, enum machine_mode
);
120 static rtx
expand_builtin_strncpy (tree
, rtx
, 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 bool integer_valued_real_p (tree
);
144 static tree
fold_trunc_transparent_mathfn (tree
, tree
);
145 static bool readonly_data_expr (tree
);
146 static rtx
expand_builtin_fabs (tree
, rtx
, rtx
);
147 static rtx
expand_builtin_signbit (tree
, rtx
);
148 static tree
fold_builtin_sqrt (tree
, tree
);
149 static tree
fold_builtin_cbrt (tree
, tree
);
150 static tree
fold_builtin_pow (tree
, tree
, tree
);
151 static tree
fold_builtin_powi (tree
, tree
, tree
);
152 static tree
fold_builtin_cos (tree
, tree
, tree
);
153 static tree
fold_builtin_cosh (tree
, tree
, tree
);
154 static tree
fold_builtin_tan (tree
, tree
);
155 static tree
fold_builtin_trunc (tree
, tree
);
156 static tree
fold_builtin_floor (tree
, tree
);
157 static tree
fold_builtin_ceil (tree
, tree
);
158 static tree
fold_builtin_round (tree
, tree
);
159 static tree
fold_builtin_int_roundingfn (tree
, tree
);
160 static tree
fold_builtin_bitop (tree
, tree
);
161 static tree
fold_builtin_memory_op (tree
, tree
, bool, int);
162 static tree
fold_builtin_strchr (tree
, tree
);
163 static tree
fold_builtin_memcmp (tree
);
164 static tree
fold_builtin_strcmp (tree
);
165 static tree
fold_builtin_strncmp (tree
);
166 static tree
fold_builtin_signbit (tree
, tree
);
167 static tree
fold_builtin_copysign (tree
, tree
, tree
);
168 static tree
fold_builtin_isascii (tree
);
169 static tree
fold_builtin_toascii (tree
);
170 static tree
fold_builtin_isdigit (tree
);
171 static tree
fold_builtin_fabs (tree
, tree
);
172 static tree
fold_builtin_abs (tree
, tree
);
173 static tree
fold_builtin_unordered_cmp (tree
, tree
, enum tree_code
,
175 static tree
fold_builtin_1 (tree
, tree
, bool);
177 static tree
fold_builtin_strpbrk (tree
, tree
);
178 static tree
fold_builtin_strstr (tree
, tree
);
179 static tree
fold_builtin_strrchr (tree
, tree
);
180 static tree
fold_builtin_strcat (tree
);
181 static tree
fold_builtin_strncat (tree
);
182 static tree
fold_builtin_strspn (tree
);
183 static tree
fold_builtin_strcspn (tree
);
184 static tree
fold_builtin_sprintf (tree
, int);
186 static rtx
expand_builtin_object_size (tree
);
187 static rtx
expand_builtin_memory_chk (tree
, rtx
, enum machine_mode
,
188 enum built_in_function
);
189 static void maybe_emit_chk_warning (tree
, enum built_in_function
);
190 static void maybe_emit_sprintf_chk_warning (tree
, enum built_in_function
);
191 static tree
fold_builtin_object_size (tree
);
192 static tree
fold_builtin_strcat_chk (tree
, tree
);
193 static tree
fold_builtin_strncat_chk (tree
, tree
);
194 static tree
fold_builtin_sprintf_chk (tree
, enum built_in_function
);
195 static tree
fold_builtin_printf (tree
, tree
, bool, enum built_in_function
);
196 static tree
fold_builtin_fprintf (tree
, tree
, bool, enum built_in_function
);
197 static bool init_target_chars (void);
199 static unsigned HOST_WIDE_INT target_newline
;
200 static unsigned HOST_WIDE_INT target_percent
;
201 static unsigned HOST_WIDE_INT target_c
;
202 static unsigned HOST_WIDE_INT target_s
;
203 static char target_percent_c
[3];
204 static char target_percent_s
[3];
205 static char target_percent_s_newline
[4];
206 static tree
do_mpfr_arg1 (tree
, tree
, int (*)(mpfr_ptr
, mpfr_srcptr
, mp_rnd_t
),
207 const REAL_VALUE_TYPE
*, const REAL_VALUE_TYPE
*, bool);
208 static tree
do_mpfr_arg2 (tree
, tree
, tree
,
209 int (*)(mpfr_ptr
, mpfr_srcptr
, mpfr_srcptr
, mp_rnd_t
));
210 static tree
do_mpfr_arg3 (tree
, tree
, tree
, tree
,
211 int (*)(mpfr_ptr
, mpfr_srcptr
, mpfr_srcptr
, mpfr_srcptr
, mp_rnd_t
));
212 static tree
do_mpfr_sincos (tree
, tree
, tree
);
214 /* Return true if NODE should be considered for inline expansion regardless
215 of the optimization level. This means whenever a function is invoked with
216 its "internal" name, which normally contains the prefix "__builtin". */
218 static bool called_as_built_in (tree node
)
220 const char *name
= IDENTIFIER_POINTER (DECL_NAME (node
));
221 if (strncmp (name
, "__builtin_", 10) == 0)
223 if (strncmp (name
, "__sync_", 7) == 0)
228 /* Return the alignment in bits of EXP, a pointer valued expression.
229 But don't return more than MAX_ALIGN no matter what.
230 The alignment returned is, by default, the alignment of the thing that
231 EXP points to. If it is not a POINTER_TYPE, 0 is returned.
233 Otherwise, look at the expression to see if we can do better, i.e., if the
234 expression is actually pointing at an object whose alignment is tighter. */
237 get_pointer_alignment (tree exp
, unsigned int max_align
)
239 unsigned int align
, inner
;
241 /* We rely on TER to compute accurate alignment information. */
242 if (!(optimize
&& flag_tree_ter
))
245 if (!POINTER_TYPE_P (TREE_TYPE (exp
)))
248 align
= TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp
)));
249 align
= MIN (align
, max_align
);
253 switch (TREE_CODE (exp
))
257 case NON_LVALUE_EXPR
:
258 exp
= TREE_OPERAND (exp
, 0);
259 if (! POINTER_TYPE_P (TREE_TYPE (exp
)))
262 inner
= TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp
)));
263 align
= MIN (inner
, max_align
);
267 /* If sum of pointer + int, restrict our maximum alignment to that
268 imposed by the integer. If not, we can't do any better than
270 if (! host_integerp (TREE_OPERAND (exp
, 1), 1))
273 while (((tree_low_cst (TREE_OPERAND (exp
, 1), 1))
274 & (max_align
/ BITS_PER_UNIT
- 1))
278 exp
= TREE_OPERAND (exp
, 0);
282 /* See what we are pointing at and look at its alignment. */
283 exp
= TREE_OPERAND (exp
, 0);
285 if (handled_component_p (exp
))
287 HOST_WIDE_INT bitsize
, bitpos
;
289 enum machine_mode mode
;
290 int unsignedp
, volatilep
;
292 exp
= get_inner_reference (exp
, &bitsize
, &bitpos
, &offset
,
293 &mode
, &unsignedp
, &volatilep
, true);
295 inner
= MIN (inner
, (unsigned) (bitpos
& -bitpos
));
296 if (offset
&& TREE_CODE (offset
) == PLUS_EXPR
297 && host_integerp (TREE_OPERAND (offset
, 1), 1))
299 /* Any overflow in calculating offset_bits won't change
302 = ((unsigned) tree_low_cst (TREE_OPERAND (offset
, 1), 1)
306 inner
= MIN (inner
, (offset_bits
& -offset_bits
));
307 offset
= TREE_OPERAND (offset
, 0);
309 if (offset
&& TREE_CODE (offset
) == MULT_EXPR
310 && host_integerp (TREE_OPERAND (offset
, 1), 1))
312 /* Any overflow in calculating offset_factor won't change
314 unsigned offset_factor
315 = ((unsigned) tree_low_cst (TREE_OPERAND (offset
, 1), 1)
319 inner
= MIN (inner
, (offset_factor
& -offset_factor
));
322 inner
= MIN (inner
, BITS_PER_UNIT
);
324 if (TREE_CODE (exp
) == FUNCTION_DECL
)
325 align
= FUNCTION_BOUNDARY
;
326 else if (DECL_P (exp
))
327 align
= MIN (inner
, DECL_ALIGN (exp
));
328 #ifdef CONSTANT_ALIGNMENT
329 else if (CONSTANT_CLASS_P (exp
))
330 align
= MIN (inner
, (unsigned)CONSTANT_ALIGNMENT (exp
, align
));
332 else if (TREE_CODE (exp
) == VIEW_CONVERT_EXPR
333 || TREE_CODE (exp
) == INDIRECT_REF
)
334 align
= MIN (TYPE_ALIGN (TREE_TYPE (exp
)), inner
);
336 align
= MIN (align
, inner
);
337 return MIN (align
, max_align
);
345 /* Compute the length of a C string. TREE_STRING_LENGTH is not the right
346 way, because it could contain a zero byte in the middle.
347 TREE_STRING_LENGTH is the size of the character array, not the string.
349 ONLY_VALUE should be nonzero if the result is not going to be emitted
350 into the instruction stream and zero if it is going to be expanded.
351 E.g. with i++ ? "foo" : "bar", if ONLY_VALUE is nonzero, constant 3
352 is returned, otherwise NULL, since
353 len = c_strlen (src, 1); if (len) expand_expr (len, ...); would not
354 evaluate the side-effects.
356 The value returned is of type `ssizetype'.
358 Unfortunately, string_constant can't access the values of const char
359 arrays with initializers, so neither can we do so here. */
362 c_strlen (tree src
, int only_value
)
365 HOST_WIDE_INT offset
;
370 if (TREE_CODE (src
) == COND_EXPR
371 && (only_value
|| !TREE_SIDE_EFFECTS (TREE_OPERAND (src
, 0))))
375 len1
= c_strlen (TREE_OPERAND (src
, 1), only_value
);
376 len2
= c_strlen (TREE_OPERAND (src
, 2), only_value
);
377 if (tree_int_cst_equal (len1
, len2
))
381 if (TREE_CODE (src
) == COMPOUND_EXPR
382 && (only_value
|| !TREE_SIDE_EFFECTS (TREE_OPERAND (src
, 0))))
383 return c_strlen (TREE_OPERAND (src
, 1), only_value
);
385 src
= string_constant (src
, &offset_node
);
389 max
= TREE_STRING_LENGTH (src
) - 1;
390 ptr
= TREE_STRING_POINTER (src
);
392 if (offset_node
&& TREE_CODE (offset_node
) != INTEGER_CST
)
394 /* If the string has an internal zero byte (e.g., "foo\0bar"), we can't
395 compute the offset to the following null if we don't know where to
396 start searching for it. */
399 for (i
= 0; i
< max
; i
++)
403 /* We don't know the starting offset, but we do know that the string
404 has no internal zero bytes. We can assume that the offset falls
405 within the bounds of the string; otherwise, the programmer deserves
406 what he gets. Subtract the offset from the length of the string,
407 and return that. This would perhaps not be valid if we were dealing
408 with named arrays in addition to literal string constants. */
410 return size_diffop (size_int (max
), offset_node
);
413 /* We have a known offset into the string. Start searching there for
414 a null character if we can represent it as a single HOST_WIDE_INT. */
415 if (offset_node
== 0)
417 else if (! host_integerp (offset_node
, 0))
420 offset
= tree_low_cst (offset_node
, 0);
422 /* If the offset is known to be out of bounds, warn, and call strlen at
424 if (offset
< 0 || offset
> max
)
426 warning (0, "offset outside bounds of constant string");
430 /* Use strlen to search for the first zero byte. Since any strings
431 constructed with build_string will have nulls appended, we win even
432 if we get handed something like (char[4])"abcd".
434 Since OFFSET is our starting index into the string, no further
435 calculation is needed. */
436 return ssize_int (strlen (ptr
+ offset
));
439 /* Return a char pointer for a C string if it is a string constant
440 or sum of string constant and integer constant. */
447 src
= string_constant (src
, &offset_node
);
451 if (offset_node
== 0)
452 return TREE_STRING_POINTER (src
);
453 else if (!host_integerp (offset_node
, 1)
454 || compare_tree_int (offset_node
, TREE_STRING_LENGTH (src
) - 1) > 0)
457 return TREE_STRING_POINTER (src
) + tree_low_cst (offset_node
, 1);
460 /* Return a CONST_INT or CONST_DOUBLE corresponding to target reading
461 GET_MODE_BITSIZE (MODE) bits from string constant STR. */
464 c_readstr (const char *str
, enum machine_mode mode
)
470 gcc_assert (GET_MODE_CLASS (mode
) == MODE_INT
);
475 for (i
= 0; i
< GET_MODE_SIZE (mode
); i
++)
478 if (WORDS_BIG_ENDIAN
)
479 j
= GET_MODE_SIZE (mode
) - i
- 1;
480 if (BYTES_BIG_ENDIAN
!= WORDS_BIG_ENDIAN
481 && GET_MODE_SIZE (mode
) > UNITS_PER_WORD
)
482 j
= j
+ UNITS_PER_WORD
- 2 * (j
% UNITS_PER_WORD
) - 1;
484 gcc_assert (j
<= 2 * HOST_BITS_PER_WIDE_INT
);
487 ch
= (unsigned char) str
[i
];
488 c
[j
/ HOST_BITS_PER_WIDE_INT
] |= ch
<< (j
% HOST_BITS_PER_WIDE_INT
);
490 return immed_double_const (c
[0], c
[1], mode
);
493 /* Cast a target constant CST to target CHAR and if that value fits into
494 host char type, return zero and put that value into variable pointed to by
498 target_char_cast (tree cst
, char *p
)
500 unsigned HOST_WIDE_INT val
, hostval
;
502 if (!host_integerp (cst
, 1)
503 || CHAR_TYPE_SIZE
> HOST_BITS_PER_WIDE_INT
)
506 val
= tree_low_cst (cst
, 1);
507 if (CHAR_TYPE_SIZE
< HOST_BITS_PER_WIDE_INT
)
508 val
&= (((unsigned HOST_WIDE_INT
) 1) << CHAR_TYPE_SIZE
) - 1;
511 if (HOST_BITS_PER_CHAR
< HOST_BITS_PER_WIDE_INT
)
512 hostval
&= (((unsigned HOST_WIDE_INT
) 1) << HOST_BITS_PER_CHAR
) - 1;
521 /* Similar to save_expr, but assumes that arbitrary code is not executed
522 in between the multiple evaluations. In particular, we assume that a
523 non-addressable local variable will not be modified. */
526 builtin_save_expr (tree exp
)
528 if (TREE_ADDRESSABLE (exp
) == 0
529 && (TREE_CODE (exp
) == PARM_DECL
530 || (TREE_CODE (exp
) == VAR_DECL
&& !TREE_STATIC (exp
))))
533 return save_expr (exp
);
536 /* Given TEM, a pointer to a stack frame, follow the dynamic chain COUNT
537 times to get the address of either a higher stack frame, or a return
538 address located within it (depending on FNDECL_CODE). */
541 expand_builtin_return_addr (enum built_in_function fndecl_code
, int count
)
545 #ifdef INITIAL_FRAME_ADDRESS_RTX
546 rtx tem
= INITIAL_FRAME_ADDRESS_RTX
;
550 /* For a zero count with __builtin_return_address, we don't care what
551 frame address we return, because target-specific definitions will
552 override us. Therefore frame pointer elimination is OK, and using
553 the soft frame pointer is OK.
555 For a nonzero count, or a zero count with __builtin_frame_address,
556 we require a stable offset from the current frame pointer to the
557 previous one, so we must use the hard frame pointer, and
558 we must disable frame pointer elimination. */
559 if (count
== 0 && fndecl_code
== BUILT_IN_RETURN_ADDRESS
)
560 tem
= frame_pointer_rtx
;
563 tem
= hard_frame_pointer_rtx
;
565 /* Tell reload not to eliminate the frame pointer. */
566 current_function_accesses_prior_frames
= 1;
570 /* Some machines need special handling before we can access
571 arbitrary frames. For example, on the SPARC, we must first flush
572 all register windows to the stack. */
573 #ifdef SETUP_FRAME_ADDRESSES
575 SETUP_FRAME_ADDRESSES ();
578 /* On the SPARC, the return address is not in the frame, it is in a
579 register. There is no way to access it off of the current frame
580 pointer, but it can be accessed off the previous frame pointer by
581 reading the value from the register window save area. */
582 #ifdef RETURN_ADDR_IN_PREVIOUS_FRAME
583 if (fndecl_code
== BUILT_IN_RETURN_ADDRESS
)
587 /* Scan back COUNT frames to the specified frame. */
588 for (i
= 0; i
< count
; i
++)
590 /* Assume the dynamic chain pointer is in the word that the
591 frame address points to, unless otherwise specified. */
592 #ifdef DYNAMIC_CHAIN_ADDRESS
593 tem
= DYNAMIC_CHAIN_ADDRESS (tem
);
595 tem
= memory_address (Pmode
, tem
);
596 tem
= gen_frame_mem (Pmode
, tem
);
597 tem
= copy_to_reg (tem
);
600 /* For __builtin_frame_address, return what we've got. But, on
601 the SPARC for example, we may have to add a bias. */
602 if (fndecl_code
== BUILT_IN_FRAME_ADDRESS
)
603 #ifdef FRAME_ADDR_RTX
604 return FRAME_ADDR_RTX (tem
);
609 /* For __builtin_return_address, get the return address from that frame. */
610 #ifdef RETURN_ADDR_RTX
611 tem
= RETURN_ADDR_RTX (count
, tem
);
613 tem
= memory_address (Pmode
,
614 plus_constant (tem
, GET_MODE_SIZE (Pmode
)));
615 tem
= gen_frame_mem (Pmode
, tem
);
620 /* Alias set used for setjmp buffer. */
621 static HOST_WIDE_INT setjmp_alias_set
= -1;
623 /* Construct the leading half of a __builtin_setjmp call. Control will
624 return to RECEIVER_LABEL. This is also called directly by the SJLJ
625 exception handling code. */
628 expand_builtin_setjmp_setup (rtx buf_addr
, rtx receiver_label
)
630 enum machine_mode sa_mode
= STACK_SAVEAREA_MODE (SAVE_NONLOCAL
);
634 if (setjmp_alias_set
== -1)
635 setjmp_alias_set
= new_alias_set ();
637 buf_addr
= convert_memory_address (Pmode
, buf_addr
);
639 buf_addr
= force_reg (Pmode
, force_operand (buf_addr
, NULL_RTX
));
641 /* We store the frame pointer and the address of receiver_label in
642 the buffer and use the rest of it for the stack save area, which
643 is machine-dependent. */
645 mem
= gen_rtx_MEM (Pmode
, buf_addr
);
646 set_mem_alias_set (mem
, setjmp_alias_set
);
647 emit_move_insn (mem
, targetm
.builtin_setjmp_frame_value ());
649 mem
= gen_rtx_MEM (Pmode
, plus_constant (buf_addr
, GET_MODE_SIZE (Pmode
))),
650 set_mem_alias_set (mem
, setjmp_alias_set
);
652 emit_move_insn (validize_mem (mem
),
653 force_reg (Pmode
, gen_rtx_LABEL_REF (Pmode
, receiver_label
)));
655 stack_save
= gen_rtx_MEM (sa_mode
,
656 plus_constant (buf_addr
,
657 2 * GET_MODE_SIZE (Pmode
)));
658 set_mem_alias_set (stack_save
, setjmp_alias_set
);
659 emit_stack_save (SAVE_NONLOCAL
, &stack_save
, NULL_RTX
);
661 /* If there is further processing to do, do it. */
662 #ifdef HAVE_builtin_setjmp_setup
663 if (HAVE_builtin_setjmp_setup
)
664 emit_insn (gen_builtin_setjmp_setup (buf_addr
));
667 /* Tell optimize_save_area_alloca that extra work is going to
668 need to go on during alloca. */
669 current_function_calls_setjmp
= 1;
671 /* Set this so all the registers get saved in our frame; we need to be
672 able to copy the saved values for any registers from frames we unwind. */
673 current_function_has_nonlocal_label
= 1;
676 /* Construct the trailing part of a __builtin_setjmp call. This is
677 also called directly by the SJLJ exception handling code. */
680 expand_builtin_setjmp_receiver (rtx receiver_label ATTRIBUTE_UNUSED
)
682 /* Clobber the FP when we get here, so we have to make sure it's
683 marked as used by this function. */
684 emit_insn (gen_rtx_USE (VOIDmode
, hard_frame_pointer_rtx
));
686 /* Mark the static chain as clobbered here so life information
687 doesn't get messed up for it. */
688 emit_insn (gen_rtx_CLOBBER (VOIDmode
, static_chain_rtx
));
690 /* Now put in the code to restore the frame pointer, and argument
691 pointer, if needed. */
692 #ifdef HAVE_nonlocal_goto
693 if (! HAVE_nonlocal_goto
)
696 emit_move_insn (virtual_stack_vars_rtx
, hard_frame_pointer_rtx
);
697 /* This might change the hard frame pointer in ways that aren't
698 apparent to early optimization passes, so force a clobber. */
699 emit_insn (gen_rtx_CLOBBER (VOIDmode
, hard_frame_pointer_rtx
));
702 #if ARG_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
703 if (fixed_regs
[ARG_POINTER_REGNUM
])
705 #ifdef ELIMINABLE_REGS
707 static const struct elims
{const int from
, to
;} elim_regs
[] = ELIMINABLE_REGS
;
709 for (i
= 0; i
< ARRAY_SIZE (elim_regs
); i
++)
710 if (elim_regs
[i
].from
== ARG_POINTER_REGNUM
711 && elim_regs
[i
].to
== HARD_FRAME_POINTER_REGNUM
)
714 if (i
== ARRAY_SIZE (elim_regs
))
717 /* Now restore our arg pointer from the address at which it
718 was saved in our stack frame. */
719 emit_move_insn (virtual_incoming_args_rtx
,
720 copy_to_reg (get_arg_pointer_save_area (cfun
)));
725 #ifdef HAVE_builtin_setjmp_receiver
726 if (HAVE_builtin_setjmp_receiver
)
727 emit_insn (gen_builtin_setjmp_receiver (receiver_label
));
730 #ifdef HAVE_nonlocal_goto_receiver
731 if (HAVE_nonlocal_goto_receiver
)
732 emit_insn (gen_nonlocal_goto_receiver ());
737 /* @@@ This is a kludge. Not all machine descriptions define a blockage
738 insn, but we must not allow the code we just generated to be reordered
739 by scheduling. Specifically, the update of the frame pointer must
740 happen immediately, not later. So emit an ASM_INPUT to act as blockage
742 emit_insn (gen_rtx_ASM_INPUT (VOIDmode
, ""));
745 /* __builtin_longjmp is passed a pointer to an array of five words (not
746 all will be used on all machines). It operates similarly to the C
747 library function of the same name, but is more efficient. Much of
748 the code below is copied from the handling of non-local gotos. */
751 expand_builtin_longjmp (rtx buf_addr
, rtx value
)
753 rtx fp
, lab
, stack
, insn
, last
;
754 enum machine_mode sa_mode
= STACK_SAVEAREA_MODE (SAVE_NONLOCAL
);
756 if (setjmp_alias_set
== -1)
757 setjmp_alias_set
= new_alias_set ();
759 buf_addr
= convert_memory_address (Pmode
, buf_addr
);
761 buf_addr
= force_reg (Pmode
, buf_addr
);
763 /* We used to store value in static_chain_rtx, but that fails if pointers
764 are smaller than integers. We instead require that the user must pass
765 a second argument of 1, because that is what builtin_setjmp will
766 return. This also makes EH slightly more efficient, since we are no
767 longer copying around a value that we don't care about. */
768 gcc_assert (value
== const1_rtx
);
770 last
= get_last_insn ();
771 #ifdef HAVE_builtin_longjmp
772 if (HAVE_builtin_longjmp
)
773 emit_insn (gen_builtin_longjmp (buf_addr
));
777 fp
= gen_rtx_MEM (Pmode
, buf_addr
);
778 lab
= gen_rtx_MEM (Pmode
, plus_constant (buf_addr
,
779 GET_MODE_SIZE (Pmode
)));
781 stack
= gen_rtx_MEM (sa_mode
, plus_constant (buf_addr
,
782 2 * GET_MODE_SIZE (Pmode
)));
783 set_mem_alias_set (fp
, setjmp_alias_set
);
784 set_mem_alias_set (lab
, setjmp_alias_set
);
785 set_mem_alias_set (stack
, setjmp_alias_set
);
787 /* Pick up FP, label, and SP from the block and jump. This code is
788 from expand_goto in stmt.c; see there for detailed comments. */
789 #ifdef HAVE_nonlocal_goto
790 if (HAVE_nonlocal_goto
)
791 /* We have to pass a value to the nonlocal_goto pattern that will
792 get copied into the static_chain pointer, but it does not matter
793 what that value is, because builtin_setjmp does not use it. */
794 emit_insn (gen_nonlocal_goto (value
, lab
, stack
, fp
));
798 lab
= copy_to_reg (lab
);
800 emit_insn (gen_rtx_CLOBBER (VOIDmode
,
801 gen_rtx_MEM (BLKmode
,
802 gen_rtx_SCRATCH (VOIDmode
))));
803 emit_insn (gen_rtx_CLOBBER (VOIDmode
,
804 gen_rtx_MEM (BLKmode
,
805 hard_frame_pointer_rtx
)));
807 emit_move_insn (hard_frame_pointer_rtx
, fp
);
808 emit_stack_restore (SAVE_NONLOCAL
, stack
, NULL_RTX
);
810 emit_insn (gen_rtx_USE (VOIDmode
, hard_frame_pointer_rtx
));
811 emit_insn (gen_rtx_USE (VOIDmode
, stack_pointer_rtx
));
812 emit_indirect_jump (lab
);
816 /* Search backwards and mark the jump insn as a non-local goto.
817 Note that this precludes the use of __builtin_longjmp to a
818 __builtin_setjmp target in the same function. However, we've
819 already cautioned the user that these functions are for
820 internal exception handling use only. */
821 for (insn
= get_last_insn (); insn
; insn
= PREV_INSN (insn
))
823 gcc_assert (insn
!= last
);
827 REG_NOTES (insn
) = alloc_EXPR_LIST (REG_NON_LOCAL_GOTO
, const0_rtx
,
831 else if (CALL_P (insn
))
836 /* Expand a call to __builtin_nonlocal_goto. We're passed the target label
837 and the address of the save area. */
840 expand_builtin_nonlocal_goto (tree arglist
)
842 tree t_label
, t_save_area
;
843 rtx r_label
, r_save_area
, r_fp
, r_sp
, insn
;
845 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
848 t_label
= TREE_VALUE (arglist
);
849 arglist
= TREE_CHAIN (arglist
);
850 t_save_area
= TREE_VALUE (arglist
);
852 r_label
= expand_normal (t_label
);
853 r_label
= convert_memory_address (Pmode
, r_label
);
854 r_save_area
= expand_normal (t_save_area
);
855 r_save_area
= convert_memory_address (Pmode
, r_save_area
);
856 r_fp
= gen_rtx_MEM (Pmode
, r_save_area
);
857 r_sp
= gen_rtx_MEM (STACK_SAVEAREA_MODE (SAVE_NONLOCAL
),
858 plus_constant (r_save_area
, GET_MODE_SIZE (Pmode
)));
860 current_function_has_nonlocal_goto
= 1;
862 #ifdef HAVE_nonlocal_goto
863 /* ??? We no longer need to pass the static chain value, afaik. */
864 if (HAVE_nonlocal_goto
)
865 emit_insn (gen_nonlocal_goto (const0_rtx
, r_label
, r_sp
, r_fp
));
869 r_label
= copy_to_reg (r_label
);
871 emit_insn (gen_rtx_CLOBBER (VOIDmode
,
872 gen_rtx_MEM (BLKmode
,
873 gen_rtx_SCRATCH (VOIDmode
))));
875 emit_insn (gen_rtx_CLOBBER (VOIDmode
,
876 gen_rtx_MEM (BLKmode
,
877 hard_frame_pointer_rtx
)));
879 /* Restore frame pointer for containing function.
880 This sets the actual hard register used for the frame pointer
881 to the location of the function's incoming static chain info.
882 The non-local goto handler will then adjust it to contain the
883 proper value and reload the argument pointer, if needed. */
884 emit_move_insn (hard_frame_pointer_rtx
, r_fp
);
885 emit_stack_restore (SAVE_NONLOCAL
, r_sp
, NULL_RTX
);
887 /* USE of hard_frame_pointer_rtx added for consistency;
888 not clear if really needed. */
889 emit_insn (gen_rtx_USE (VOIDmode
, hard_frame_pointer_rtx
));
890 emit_insn (gen_rtx_USE (VOIDmode
, stack_pointer_rtx
));
891 emit_indirect_jump (r_label
);
894 /* Search backwards to the jump insn and mark it as a
896 for (insn
= get_last_insn (); insn
; insn
= PREV_INSN (insn
))
900 REG_NOTES (insn
) = alloc_EXPR_LIST (REG_NON_LOCAL_GOTO
,
901 const0_rtx
, REG_NOTES (insn
));
904 else if (CALL_P (insn
))
911 /* __builtin_update_setjmp_buf is passed a pointer to an array of five words
912 (not all will be used on all machines) that was passed to __builtin_setjmp.
913 It updates the stack pointer in that block to correspond to the current
917 expand_builtin_update_setjmp_buf (rtx buf_addr
)
919 enum machine_mode sa_mode
= Pmode
;
923 #ifdef HAVE_save_stack_nonlocal
924 if (HAVE_save_stack_nonlocal
)
925 sa_mode
= insn_data
[(int) CODE_FOR_save_stack_nonlocal
].operand
[0].mode
;
927 #ifdef STACK_SAVEAREA_MODE
928 sa_mode
= STACK_SAVEAREA_MODE (SAVE_NONLOCAL
);
932 = gen_rtx_MEM (sa_mode
,
935 plus_constant (buf_addr
, 2 * GET_MODE_SIZE (Pmode
))));
939 emit_insn (gen_setjmp ());
942 emit_stack_save (SAVE_NONLOCAL
, &stack_save
, NULL_RTX
);
945 /* Expand a call to __builtin_prefetch. For a target that does not support
946 data prefetch, evaluate the memory address argument in case it has side
950 expand_builtin_prefetch (tree arglist
)
952 tree arg0
, arg1
, arg2
;
955 if (!validate_arglist (arglist
, POINTER_TYPE
, 0))
958 arg0
= TREE_VALUE (arglist
);
959 /* Arguments 1 and 2 are optional; argument 1 (read/write) defaults to
960 zero (read) and argument 2 (locality) defaults to 3 (high degree of
962 if (TREE_CHAIN (arglist
))
964 arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
965 if (TREE_CHAIN (TREE_CHAIN (arglist
)))
966 arg2
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
968 arg2
= build_int_cst (NULL_TREE
, 3);
972 arg1
= integer_zero_node
;
973 arg2
= build_int_cst (NULL_TREE
, 3);
976 /* Argument 0 is an address. */
977 op0
= expand_expr (arg0
, NULL_RTX
, Pmode
, EXPAND_NORMAL
);
979 /* Argument 1 (read/write flag) must be a compile-time constant int. */
980 if (TREE_CODE (arg1
) != INTEGER_CST
)
982 error ("second argument to %<__builtin_prefetch%> must be a constant");
983 arg1
= integer_zero_node
;
985 op1
= expand_normal (arg1
);
986 /* Argument 1 must be either zero or one. */
987 if (INTVAL (op1
) != 0 && INTVAL (op1
) != 1)
989 warning (0, "invalid second argument to %<__builtin_prefetch%>;"
994 /* Argument 2 (locality) must be a compile-time constant int. */
995 if (TREE_CODE (arg2
) != INTEGER_CST
)
997 error ("third argument to %<__builtin_prefetch%> must be a constant");
998 arg2
= integer_zero_node
;
1000 op2
= expand_normal (arg2
);
1001 /* Argument 2 must be 0, 1, 2, or 3. */
1002 if (INTVAL (op2
) < 0 || INTVAL (op2
) > 3)
1004 warning (0, "invalid third argument to %<__builtin_prefetch%>; using zero");
1008 #ifdef HAVE_prefetch
1011 if ((! (*insn_data
[(int) CODE_FOR_prefetch
].operand
[0].predicate
)
1013 insn_data
[(int) CODE_FOR_prefetch
].operand
[0].mode
))
1014 || (GET_MODE (op0
) != Pmode
))
1016 op0
= convert_memory_address (Pmode
, op0
);
1017 op0
= force_reg (Pmode
, op0
);
1019 emit_insn (gen_prefetch (op0
, op1
, op2
));
1023 /* Don't do anything with direct references to volatile memory, but
1024 generate code to handle other side effects. */
1025 if (!MEM_P (op0
) && side_effects_p (op0
))
1029 /* Get a MEM rtx for expression EXP which is the address of an operand
1030 to be used in a string instruction (cmpstrsi, movmemsi, ..). LEN is
1031 the maximum length of the block of memory that might be accessed or
1035 get_memory_rtx (tree exp
, tree len
)
1037 rtx addr
= expand_expr (exp
, NULL_RTX
, ptr_mode
, EXPAND_NORMAL
);
1038 rtx mem
= gen_rtx_MEM (BLKmode
, memory_address (BLKmode
, addr
));
1040 /* Get an expression we can use to find the attributes to assign to MEM.
1041 If it is an ADDR_EXPR, use the operand. Otherwise, dereference it if
1042 we can. First remove any nops. */
1043 while ((TREE_CODE (exp
) == NOP_EXPR
|| TREE_CODE (exp
) == CONVERT_EXPR
1044 || TREE_CODE (exp
) == NON_LVALUE_EXPR
)
1045 && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (exp
, 0))))
1046 exp
= TREE_OPERAND (exp
, 0);
1048 if (TREE_CODE (exp
) == ADDR_EXPR
)
1049 exp
= TREE_OPERAND (exp
, 0);
1050 else if (POINTER_TYPE_P (TREE_TYPE (exp
)))
1051 exp
= build1 (INDIRECT_REF
, TREE_TYPE (TREE_TYPE (exp
)), exp
);
1055 /* Honor attributes derived from exp, except for the alias set
1056 (as builtin stringops may alias with anything) and the size
1057 (as stringops may access multiple array elements). */
1060 set_mem_attributes (mem
, exp
, 0);
1062 /* Allow the string and memory builtins to overflow from one
1063 field into another, see http://gcc.gnu.org/PR23561.
1064 Thus avoid COMPONENT_REFs in MEM_EXPR unless we know the whole
1065 memory accessed by the string or memory builtin will fit
1066 within the field. */
1067 if (MEM_EXPR (mem
) && TREE_CODE (MEM_EXPR (mem
)) == COMPONENT_REF
)
1069 tree mem_expr
= MEM_EXPR (mem
);
1070 HOST_WIDE_INT offset
= -1, length
= -1;
1073 while (TREE_CODE (inner
) == ARRAY_REF
1074 || TREE_CODE (inner
) == NOP_EXPR
1075 || TREE_CODE (inner
) == CONVERT_EXPR
1076 || TREE_CODE (inner
) == NON_LVALUE_EXPR
1077 || TREE_CODE (inner
) == VIEW_CONVERT_EXPR
1078 || TREE_CODE (inner
) == SAVE_EXPR
)
1079 inner
= TREE_OPERAND (inner
, 0);
1081 gcc_assert (TREE_CODE (inner
) == COMPONENT_REF
);
1083 if (MEM_OFFSET (mem
)
1084 && GET_CODE (MEM_OFFSET (mem
)) == CONST_INT
)
1085 offset
= INTVAL (MEM_OFFSET (mem
));
1087 if (offset
>= 0 && len
&& host_integerp (len
, 0))
1088 length
= tree_low_cst (len
, 0);
1090 while (TREE_CODE (inner
) == COMPONENT_REF
)
1092 tree field
= TREE_OPERAND (inner
, 1);
1093 gcc_assert (! DECL_BIT_FIELD (field
));
1094 gcc_assert (TREE_CODE (mem_expr
) == COMPONENT_REF
);
1095 gcc_assert (field
== TREE_OPERAND (mem_expr
, 1));
1098 && TYPE_SIZE_UNIT (TREE_TYPE (inner
))
1099 && host_integerp (TYPE_SIZE_UNIT (TREE_TYPE (inner
)), 0))
1102 = tree_low_cst (TYPE_SIZE_UNIT (TREE_TYPE (inner
)), 0);
1103 /* If we can prove the memory starting at XEXP (mem, 0)
1104 and ending at XEXP (mem, 0) + LENGTH will fit into
1105 this field, we can keep that COMPONENT_REF in MEM_EXPR. */
1108 && offset
+ length
<= size
)
1113 && host_integerp (DECL_FIELD_OFFSET (field
), 0))
1114 offset
+= tree_low_cst (DECL_FIELD_OFFSET (field
), 0)
1115 + tree_low_cst (DECL_FIELD_BIT_OFFSET (field
), 1)
1123 mem_expr
= TREE_OPERAND (mem_expr
, 0);
1124 inner
= TREE_OPERAND (inner
, 0);
1127 if (mem_expr
== NULL
)
1129 if (mem_expr
!= MEM_EXPR (mem
))
1131 set_mem_expr (mem
, mem_expr
);
1132 set_mem_offset (mem
, offset
>= 0 ? GEN_INT (offset
) : NULL_RTX
);
1135 set_mem_alias_set (mem
, 0);
1136 set_mem_size (mem
, NULL_RTX
);
1142 /* Built-in functions to perform an untyped call and return. */
1144 /* For each register that may be used for calling a function, this
1145 gives a mode used to copy the register's value. VOIDmode indicates
1146 the register is not used for calling a function. If the machine
1147 has register windows, this gives only the outbound registers.
1148 INCOMING_REGNO gives the corresponding inbound register. */
1149 static enum machine_mode apply_args_mode
[FIRST_PSEUDO_REGISTER
];
1151 /* For each register that may be used for returning values, this gives
1152 a mode used to copy the register's value. VOIDmode indicates the
1153 register is not used for returning values. If the machine has
1154 register windows, this gives only the outbound registers.
1155 INCOMING_REGNO gives the corresponding inbound register. */
1156 static enum machine_mode apply_result_mode
[FIRST_PSEUDO_REGISTER
];
1158 /* For each register that may be used for calling a function, this
1159 gives the offset of that register into the block returned by
1160 __builtin_apply_args. 0 indicates that the register is not
1161 used for calling a function. */
1162 static int apply_args_reg_offset
[FIRST_PSEUDO_REGISTER
];
1164 /* Return the size required for the block returned by __builtin_apply_args,
1165 and initialize apply_args_mode. */
1168 apply_args_size (void)
1170 static int size
= -1;
1173 enum machine_mode mode
;
1175 /* The values computed by this function never change. */
1178 /* The first value is the incoming arg-pointer. */
1179 size
= GET_MODE_SIZE (Pmode
);
1181 /* The second value is the structure value address unless this is
1182 passed as an "invisible" first argument. */
1183 if (targetm
.calls
.struct_value_rtx (cfun
? TREE_TYPE (cfun
->decl
) : 0, 0))
1184 size
+= GET_MODE_SIZE (Pmode
);
1186 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
1187 if (FUNCTION_ARG_REGNO_P (regno
))
1189 mode
= reg_raw_mode
[regno
];
1191 gcc_assert (mode
!= VOIDmode
);
1193 align
= GET_MODE_ALIGNMENT (mode
) / BITS_PER_UNIT
;
1194 if (size
% align
!= 0)
1195 size
= CEIL (size
, align
) * align
;
1196 apply_args_reg_offset
[regno
] = size
;
1197 size
+= GET_MODE_SIZE (mode
);
1198 apply_args_mode
[regno
] = mode
;
1202 apply_args_mode
[regno
] = VOIDmode
;
1203 apply_args_reg_offset
[regno
] = 0;
1209 /* Return the size required for the block returned by __builtin_apply,
1210 and initialize apply_result_mode. */
1213 apply_result_size (void)
1215 static int size
= -1;
1217 enum machine_mode mode
;
1219 /* The values computed by this function never change. */
1224 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
1225 if (FUNCTION_VALUE_REGNO_P (regno
))
1227 mode
= reg_raw_mode
[regno
];
1229 gcc_assert (mode
!= VOIDmode
);
1231 align
= GET_MODE_ALIGNMENT (mode
) / BITS_PER_UNIT
;
1232 if (size
% align
!= 0)
1233 size
= CEIL (size
, align
) * align
;
1234 size
+= GET_MODE_SIZE (mode
);
1235 apply_result_mode
[regno
] = mode
;
1238 apply_result_mode
[regno
] = VOIDmode
;
1240 /* Allow targets that use untyped_call and untyped_return to override
1241 the size so that machine-specific information can be stored here. */
1242 #ifdef APPLY_RESULT_SIZE
1243 size
= APPLY_RESULT_SIZE
;
1249 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
1250 /* Create a vector describing the result block RESULT. If SAVEP is true,
1251 the result block is used to save the values; otherwise it is used to
1252 restore the values. */
1255 result_vector (int savep
, rtx result
)
1257 int regno
, size
, align
, nelts
;
1258 enum machine_mode mode
;
1260 rtx
*savevec
= alloca (FIRST_PSEUDO_REGISTER
* sizeof (rtx
));
1263 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
1264 if ((mode
= apply_result_mode
[regno
]) != VOIDmode
)
1266 align
= GET_MODE_ALIGNMENT (mode
) / BITS_PER_UNIT
;
1267 if (size
% align
!= 0)
1268 size
= CEIL (size
, align
) * align
;
1269 reg
= gen_rtx_REG (mode
, savep
? regno
: INCOMING_REGNO (regno
));
1270 mem
= adjust_address (result
, mode
, size
);
1271 savevec
[nelts
++] = (savep
1272 ? gen_rtx_SET (VOIDmode
, mem
, reg
)
1273 : gen_rtx_SET (VOIDmode
, reg
, mem
));
1274 size
+= GET_MODE_SIZE (mode
);
1276 return gen_rtx_PARALLEL (VOIDmode
, gen_rtvec_v (nelts
, savevec
));
1278 #endif /* HAVE_untyped_call or HAVE_untyped_return */
1280 /* Save the state required to perform an untyped call with the same
1281 arguments as were passed to the current function. */
1284 expand_builtin_apply_args_1 (void)
1287 int size
, align
, regno
;
1288 enum machine_mode mode
;
1289 rtx struct_incoming_value
= targetm
.calls
.struct_value_rtx (cfun
? TREE_TYPE (cfun
->decl
) : 0, 1);
1291 /* Create a block where the arg-pointer, structure value address,
1292 and argument registers can be saved. */
1293 registers
= assign_stack_local (BLKmode
, apply_args_size (), -1);
1295 /* Walk past the arg-pointer and structure value address. */
1296 size
= GET_MODE_SIZE (Pmode
);
1297 if (targetm
.calls
.struct_value_rtx (cfun
? TREE_TYPE (cfun
->decl
) : 0, 0))
1298 size
+= GET_MODE_SIZE (Pmode
);
1300 /* Save each register used in calling a function to the block. */
1301 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
1302 if ((mode
= apply_args_mode
[regno
]) != VOIDmode
)
1304 align
= GET_MODE_ALIGNMENT (mode
) / BITS_PER_UNIT
;
1305 if (size
% align
!= 0)
1306 size
= CEIL (size
, align
) * align
;
1308 tem
= gen_rtx_REG (mode
, INCOMING_REGNO (regno
));
1310 emit_move_insn (adjust_address (registers
, mode
, size
), tem
);
1311 size
+= GET_MODE_SIZE (mode
);
1314 /* Save the arg pointer to the block. */
1315 tem
= copy_to_reg (virtual_incoming_args_rtx
);
1316 #ifdef STACK_GROWS_DOWNWARD
1317 /* We need the pointer as the caller actually passed them to us, not
1318 as we might have pretended they were passed. Make sure it's a valid
1319 operand, as emit_move_insn isn't expected to handle a PLUS. */
1321 = force_operand (plus_constant (tem
, current_function_pretend_args_size
),
1324 emit_move_insn (adjust_address (registers
, Pmode
, 0), tem
);
1326 size
= GET_MODE_SIZE (Pmode
);
1328 /* Save the structure value address unless this is passed as an
1329 "invisible" first argument. */
1330 if (struct_incoming_value
)
1332 emit_move_insn (adjust_address (registers
, Pmode
, size
),
1333 copy_to_reg (struct_incoming_value
));
1334 size
+= GET_MODE_SIZE (Pmode
);
1337 /* Return the address of the block. */
1338 return copy_addr_to_reg (XEXP (registers
, 0));
1341 /* __builtin_apply_args returns block of memory allocated on
1342 the stack into which is stored the arg pointer, structure
1343 value address, static chain, and all the registers that might
1344 possibly be used in performing a function call. The code is
1345 moved to the start of the function so the incoming values are
1349 expand_builtin_apply_args (void)
1351 /* Don't do __builtin_apply_args more than once in a function.
1352 Save the result of the first call and reuse it. */
1353 if (apply_args_value
!= 0)
1354 return apply_args_value
;
1356 /* When this function is called, it means that registers must be
1357 saved on entry to this function. So we migrate the
1358 call to the first insn of this function. */
1363 temp
= expand_builtin_apply_args_1 ();
1367 apply_args_value
= temp
;
1369 /* Put the insns after the NOTE that starts the function.
1370 If this is inside a start_sequence, make the outer-level insn
1371 chain current, so the code is placed at the start of the
1373 push_topmost_sequence ();
1374 emit_insn_before (seq
, NEXT_INSN (entry_of_function ()));
1375 pop_topmost_sequence ();
1380 /* Perform an untyped call and save the state required to perform an
1381 untyped return of whatever value was returned by the given function. */
1384 expand_builtin_apply (rtx function
, rtx arguments
, rtx argsize
)
1386 int size
, align
, regno
;
1387 enum machine_mode mode
;
1388 rtx incoming_args
, result
, reg
, dest
, src
, call_insn
;
1389 rtx old_stack_level
= 0;
1390 rtx call_fusage
= 0;
1391 rtx struct_value
= targetm
.calls
.struct_value_rtx (cfun
? TREE_TYPE (cfun
->decl
) : 0, 0);
1393 arguments
= convert_memory_address (Pmode
, arguments
);
1395 /* Create a block where the return registers can be saved. */
1396 result
= assign_stack_local (BLKmode
, apply_result_size (), -1);
1398 /* Fetch the arg pointer from the ARGUMENTS block. */
1399 incoming_args
= gen_reg_rtx (Pmode
);
1400 emit_move_insn (incoming_args
, gen_rtx_MEM (Pmode
, arguments
));
1401 #ifndef STACK_GROWS_DOWNWARD
1402 incoming_args
= expand_simple_binop (Pmode
, MINUS
, incoming_args
, argsize
,
1403 incoming_args
, 0, OPTAB_LIB_WIDEN
);
1406 /* Push a new argument block and copy the arguments. Do not allow
1407 the (potential) memcpy call below to interfere with our stack
1409 do_pending_stack_adjust ();
1412 /* Save the stack with nonlocal if available. */
1413 #ifdef HAVE_save_stack_nonlocal
1414 if (HAVE_save_stack_nonlocal
)
1415 emit_stack_save (SAVE_NONLOCAL
, &old_stack_level
, NULL_RTX
);
1418 emit_stack_save (SAVE_BLOCK
, &old_stack_level
, NULL_RTX
);
1420 /* Allocate a block of memory onto the stack and copy the memory
1421 arguments to the outgoing arguments address. */
1422 allocate_dynamic_stack_space (argsize
, 0, BITS_PER_UNIT
);
1423 dest
= virtual_outgoing_args_rtx
;
1424 #ifndef STACK_GROWS_DOWNWARD
1425 if (GET_CODE (argsize
) == CONST_INT
)
1426 dest
= plus_constant (dest
, -INTVAL (argsize
));
1428 dest
= gen_rtx_PLUS (Pmode
, dest
, negate_rtx (Pmode
, argsize
));
1430 dest
= gen_rtx_MEM (BLKmode
, dest
);
1431 set_mem_align (dest
, PARM_BOUNDARY
);
1432 src
= gen_rtx_MEM (BLKmode
, incoming_args
);
1433 set_mem_align (src
, PARM_BOUNDARY
);
1434 emit_block_move (dest
, src
, argsize
, BLOCK_OP_NORMAL
);
1436 /* Refer to the argument block. */
1438 arguments
= gen_rtx_MEM (BLKmode
, arguments
);
1439 set_mem_align (arguments
, PARM_BOUNDARY
);
1441 /* Walk past the arg-pointer and structure value address. */
1442 size
= GET_MODE_SIZE (Pmode
);
1444 size
+= GET_MODE_SIZE (Pmode
);
1446 /* Restore each of the registers previously saved. Make USE insns
1447 for each of these registers for use in making the call. */
1448 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
1449 if ((mode
= apply_args_mode
[regno
]) != VOIDmode
)
1451 align
= GET_MODE_ALIGNMENT (mode
) / BITS_PER_UNIT
;
1452 if (size
% align
!= 0)
1453 size
= CEIL (size
, align
) * align
;
1454 reg
= gen_rtx_REG (mode
, regno
);
1455 emit_move_insn (reg
, adjust_address (arguments
, mode
, size
));
1456 use_reg (&call_fusage
, reg
);
1457 size
+= GET_MODE_SIZE (mode
);
1460 /* Restore the structure value address unless this is passed as an
1461 "invisible" first argument. */
1462 size
= GET_MODE_SIZE (Pmode
);
1465 rtx value
= gen_reg_rtx (Pmode
);
1466 emit_move_insn (value
, adjust_address (arguments
, Pmode
, size
));
1467 emit_move_insn (struct_value
, value
);
1468 if (REG_P (struct_value
))
1469 use_reg (&call_fusage
, struct_value
);
1470 size
+= GET_MODE_SIZE (Pmode
);
1473 /* All arguments and registers used for the call are set up by now! */
1474 function
= prepare_call_address (function
, NULL
, &call_fusage
, 0, 0);
1476 /* Ensure address is valid. SYMBOL_REF is already valid, so no need,
1477 and we don't want to load it into a register as an optimization,
1478 because prepare_call_address already did it if it should be done. */
1479 if (GET_CODE (function
) != SYMBOL_REF
)
1480 function
= memory_address (FUNCTION_MODE
, function
);
1482 /* Generate the actual call instruction and save the return value. */
1483 #ifdef HAVE_untyped_call
1484 if (HAVE_untyped_call
)
1485 emit_call_insn (gen_untyped_call (gen_rtx_MEM (FUNCTION_MODE
, function
),
1486 result
, result_vector (1, result
)));
1489 #ifdef HAVE_call_value
1490 if (HAVE_call_value
)
1494 /* Locate the unique return register. It is not possible to
1495 express a call that sets more than one return register using
1496 call_value; use untyped_call for that. In fact, untyped_call
1497 only needs to save the return registers in the given block. */
1498 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
1499 if ((mode
= apply_result_mode
[regno
]) != VOIDmode
)
1501 gcc_assert (!valreg
); /* HAVE_untyped_call required. */
1503 valreg
= gen_rtx_REG (mode
, regno
);
1506 emit_call_insn (GEN_CALL_VALUE (valreg
,
1507 gen_rtx_MEM (FUNCTION_MODE
, function
),
1508 const0_rtx
, NULL_RTX
, const0_rtx
));
1510 emit_move_insn (adjust_address (result
, GET_MODE (valreg
), 0), valreg
);
1516 /* Find the CALL insn we just emitted, and attach the register usage
1518 call_insn
= last_call_insn ();
1519 add_function_usage_to (call_insn
, call_fusage
);
1521 /* Restore the stack. */
1522 #ifdef HAVE_save_stack_nonlocal
1523 if (HAVE_save_stack_nonlocal
)
1524 emit_stack_restore (SAVE_NONLOCAL
, old_stack_level
, NULL_RTX
);
1527 emit_stack_restore (SAVE_BLOCK
, old_stack_level
, NULL_RTX
);
1531 /* Return the address of the result block. */
1532 result
= copy_addr_to_reg (XEXP (result
, 0));
1533 return convert_memory_address (ptr_mode
, result
);
1536 /* Perform an untyped return. */
1539 expand_builtin_return (rtx result
)
1541 int size
, align
, regno
;
1542 enum machine_mode mode
;
1544 rtx call_fusage
= 0;
1546 result
= convert_memory_address (Pmode
, result
);
1548 apply_result_size ();
1549 result
= gen_rtx_MEM (BLKmode
, result
);
1551 #ifdef HAVE_untyped_return
1552 if (HAVE_untyped_return
)
1554 emit_jump_insn (gen_untyped_return (result
, result_vector (0, result
)));
1560 /* Restore the return value and note that each value is used. */
1562 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
1563 if ((mode
= apply_result_mode
[regno
]) != VOIDmode
)
1565 align
= GET_MODE_ALIGNMENT (mode
) / BITS_PER_UNIT
;
1566 if (size
% align
!= 0)
1567 size
= CEIL (size
, align
) * align
;
1568 reg
= gen_rtx_REG (mode
, INCOMING_REGNO (regno
));
1569 emit_move_insn (reg
, adjust_address (result
, mode
, size
));
1571 push_to_sequence (call_fusage
);
1572 emit_insn (gen_rtx_USE (VOIDmode
, reg
));
1573 call_fusage
= get_insns ();
1575 size
+= GET_MODE_SIZE (mode
);
1578 /* Put the USE insns before the return. */
1579 emit_insn (call_fusage
);
1581 /* Return whatever values was restored by jumping directly to the end
1583 expand_naked_return ();
1586 /* Used by expand_builtin_classify_type and fold_builtin_classify_type. */
1588 static enum type_class
1589 type_to_class (tree type
)
1591 switch (TREE_CODE (type
))
1593 case VOID_TYPE
: return void_type_class
;
1594 case INTEGER_TYPE
: return integer_type_class
;
1595 case ENUMERAL_TYPE
: return enumeral_type_class
;
1596 case BOOLEAN_TYPE
: return boolean_type_class
;
1597 case POINTER_TYPE
: return pointer_type_class
;
1598 case REFERENCE_TYPE
: return reference_type_class
;
1599 case OFFSET_TYPE
: return offset_type_class
;
1600 case REAL_TYPE
: return real_type_class
;
1601 case COMPLEX_TYPE
: return complex_type_class
;
1602 case FUNCTION_TYPE
: return function_type_class
;
1603 case METHOD_TYPE
: return method_type_class
;
1604 case RECORD_TYPE
: return record_type_class
;
1606 case QUAL_UNION_TYPE
: return union_type_class
;
1607 case ARRAY_TYPE
: return (TYPE_STRING_FLAG (type
)
1608 ? string_type_class
: array_type_class
);
1609 case LANG_TYPE
: return lang_type_class
;
1610 default: return no_type_class
;
1614 /* Expand a call to __builtin_classify_type with arguments found in
1618 expand_builtin_classify_type (tree arglist
)
1621 return GEN_INT (type_to_class (TREE_TYPE (TREE_VALUE (arglist
))));
1622 return GEN_INT (no_type_class
);
1625 /* This helper macro, meant to be used in mathfn_built_in below,
1626 determines which among a set of three builtin math functions is
1627 appropriate for a given type mode. The `F' and `L' cases are
1628 automatically generated from the `double' case. */
1629 #define CASE_MATHFN(BUILT_IN_MATHFN) \
1630 case BUILT_IN_MATHFN: case BUILT_IN_MATHFN##F: case BUILT_IN_MATHFN##L: \
1631 fcode = BUILT_IN_MATHFN; fcodef = BUILT_IN_MATHFN##F ; \
1632 fcodel = BUILT_IN_MATHFN##L ; break;
1634 /* Return mathematic function equivalent to FN but operating directly
1635 on TYPE, if available. If we can't do the conversion, return zero. */
1637 mathfn_built_in (tree type
, enum built_in_function fn
)
1639 enum built_in_function fcode
, fcodef
, fcodel
;
1643 CASE_MATHFN (BUILT_IN_ACOS
)
1644 CASE_MATHFN (BUILT_IN_ACOSH
)
1645 CASE_MATHFN (BUILT_IN_ASIN
)
1646 CASE_MATHFN (BUILT_IN_ASINH
)
1647 CASE_MATHFN (BUILT_IN_ATAN
)
1648 CASE_MATHFN (BUILT_IN_ATAN2
)
1649 CASE_MATHFN (BUILT_IN_ATANH
)
1650 CASE_MATHFN (BUILT_IN_CBRT
)
1651 CASE_MATHFN (BUILT_IN_CEIL
)
1652 CASE_MATHFN (BUILT_IN_CEXPI
)
1653 CASE_MATHFN (BUILT_IN_COPYSIGN
)
1654 CASE_MATHFN (BUILT_IN_COS
)
1655 CASE_MATHFN (BUILT_IN_COSH
)
1656 CASE_MATHFN (BUILT_IN_DREM
)
1657 CASE_MATHFN (BUILT_IN_ERF
)
1658 CASE_MATHFN (BUILT_IN_ERFC
)
1659 CASE_MATHFN (BUILT_IN_EXP
)
1660 CASE_MATHFN (BUILT_IN_EXP10
)
1661 CASE_MATHFN (BUILT_IN_EXP2
)
1662 CASE_MATHFN (BUILT_IN_EXPM1
)
1663 CASE_MATHFN (BUILT_IN_FABS
)
1664 CASE_MATHFN (BUILT_IN_FDIM
)
1665 CASE_MATHFN (BUILT_IN_FLOOR
)
1666 CASE_MATHFN (BUILT_IN_FMA
)
1667 CASE_MATHFN (BUILT_IN_FMAX
)
1668 CASE_MATHFN (BUILT_IN_FMIN
)
1669 CASE_MATHFN (BUILT_IN_FMOD
)
1670 CASE_MATHFN (BUILT_IN_FREXP
)
1671 CASE_MATHFN (BUILT_IN_GAMMA
)
1672 CASE_MATHFN (BUILT_IN_HUGE_VAL
)
1673 CASE_MATHFN (BUILT_IN_HYPOT
)
1674 CASE_MATHFN (BUILT_IN_ILOGB
)
1675 CASE_MATHFN (BUILT_IN_INF
)
1676 CASE_MATHFN (BUILT_IN_J0
)
1677 CASE_MATHFN (BUILT_IN_J1
)
1678 CASE_MATHFN (BUILT_IN_JN
)
1679 CASE_MATHFN (BUILT_IN_LCEIL
)
1680 CASE_MATHFN (BUILT_IN_LDEXP
)
1681 CASE_MATHFN (BUILT_IN_LFLOOR
)
1682 CASE_MATHFN (BUILT_IN_LGAMMA
)
1683 CASE_MATHFN (BUILT_IN_LLCEIL
)
1684 CASE_MATHFN (BUILT_IN_LLFLOOR
)
1685 CASE_MATHFN (BUILT_IN_LLRINT
)
1686 CASE_MATHFN (BUILT_IN_LLROUND
)
1687 CASE_MATHFN (BUILT_IN_LOG
)
1688 CASE_MATHFN (BUILT_IN_LOG10
)
1689 CASE_MATHFN (BUILT_IN_LOG1P
)
1690 CASE_MATHFN (BUILT_IN_LOG2
)
1691 CASE_MATHFN (BUILT_IN_LOGB
)
1692 CASE_MATHFN (BUILT_IN_LRINT
)
1693 CASE_MATHFN (BUILT_IN_LROUND
)
1694 CASE_MATHFN (BUILT_IN_MODF
)
1695 CASE_MATHFN (BUILT_IN_NAN
)
1696 CASE_MATHFN (BUILT_IN_NANS
)
1697 CASE_MATHFN (BUILT_IN_NEARBYINT
)
1698 CASE_MATHFN (BUILT_IN_NEXTAFTER
)
1699 CASE_MATHFN (BUILT_IN_NEXTTOWARD
)
1700 CASE_MATHFN (BUILT_IN_POW
)
1701 CASE_MATHFN (BUILT_IN_POWI
)
1702 CASE_MATHFN (BUILT_IN_POW10
)
1703 CASE_MATHFN (BUILT_IN_REMAINDER
)
1704 CASE_MATHFN (BUILT_IN_REMQUO
)
1705 CASE_MATHFN (BUILT_IN_RINT
)
1706 CASE_MATHFN (BUILT_IN_ROUND
)
1707 CASE_MATHFN (BUILT_IN_SCALB
)
1708 CASE_MATHFN (BUILT_IN_SCALBLN
)
1709 CASE_MATHFN (BUILT_IN_SCALBN
)
1710 CASE_MATHFN (BUILT_IN_SIGNIFICAND
)
1711 CASE_MATHFN (BUILT_IN_SIN
)
1712 CASE_MATHFN (BUILT_IN_SINCOS
)
1713 CASE_MATHFN (BUILT_IN_SINH
)
1714 CASE_MATHFN (BUILT_IN_SQRT
)
1715 CASE_MATHFN (BUILT_IN_TAN
)
1716 CASE_MATHFN (BUILT_IN_TANH
)
1717 CASE_MATHFN (BUILT_IN_TGAMMA
)
1718 CASE_MATHFN (BUILT_IN_TRUNC
)
1719 CASE_MATHFN (BUILT_IN_Y0
)
1720 CASE_MATHFN (BUILT_IN_Y1
)
1721 CASE_MATHFN (BUILT_IN_YN
)
1727 if (TYPE_MAIN_VARIANT (type
) == double_type_node
)
1728 return implicit_built_in_decls
[fcode
];
1729 else if (TYPE_MAIN_VARIANT (type
) == float_type_node
)
1730 return implicit_built_in_decls
[fcodef
];
1731 else if (TYPE_MAIN_VARIANT (type
) == long_double_type_node
)
1732 return implicit_built_in_decls
[fcodel
];
1737 /* If errno must be maintained, expand the RTL to check if the result,
1738 TARGET, of a built-in function call, EXP, is NaN, and if so set
1742 expand_errno_check (tree exp
, rtx target
)
1744 rtx lab
= gen_label_rtx ();
1746 /* Test the result; if it is NaN, set errno=EDOM because
1747 the argument was not in the domain. */
1748 emit_cmp_and_jump_insns (target
, target
, EQ
, 0, GET_MODE (target
),
1752 /* If this built-in doesn't throw an exception, set errno directly. */
1753 if (TREE_NOTHROW (TREE_OPERAND (TREE_OPERAND (exp
, 0), 0)))
1755 #ifdef GEN_ERRNO_RTX
1756 rtx errno_rtx
= GEN_ERRNO_RTX
;
1759 = gen_rtx_MEM (word_mode
, gen_rtx_SYMBOL_REF (Pmode
, "errno"));
1761 emit_move_insn (errno_rtx
, GEN_INT (TARGET_EDOM
));
1767 /* We can't set errno=EDOM directly; let the library call do it.
1768 Pop the arguments right away in case the call gets deleted. */
1770 expand_call (exp
, target
, 0);
1776 /* Expand a call to one of the builtin math functions (sqrt, exp, or log).
1777 Return 0 if a normal call should be emitted rather than expanding the
1778 function in-line. EXP is the expression that is a call to the builtin
1779 function; if convenient, the result should be placed in TARGET.
1780 SUBTARGET may be used as the target for computing one of EXP's operands. */
1783 expand_builtin_mathfn (tree exp
, rtx target
, rtx subtarget
)
1785 optab builtin_optab
;
1786 rtx op0
, insns
, before_call
;
1787 tree fndecl
= get_callee_fndecl (exp
);
1788 tree arglist
= TREE_OPERAND (exp
, 1);
1789 enum machine_mode mode
;
1790 bool errno_set
= false;
1793 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
1796 arg
= TREE_VALUE (arglist
);
1798 switch (DECL_FUNCTION_CODE (fndecl
))
1800 CASE_FLT_FN (BUILT_IN_SQRT
):
1801 errno_set
= ! tree_expr_nonnegative_p (arg
);
1802 builtin_optab
= sqrt_optab
;
1804 CASE_FLT_FN (BUILT_IN_EXP
):
1805 errno_set
= true; builtin_optab
= exp_optab
; break;
1806 CASE_FLT_FN (BUILT_IN_EXP10
):
1807 CASE_FLT_FN (BUILT_IN_POW10
):
1808 errno_set
= true; builtin_optab
= exp10_optab
; break;
1809 CASE_FLT_FN (BUILT_IN_EXP2
):
1810 errno_set
= true; builtin_optab
= exp2_optab
; break;
1811 CASE_FLT_FN (BUILT_IN_EXPM1
):
1812 errno_set
= true; builtin_optab
= expm1_optab
; break;
1813 CASE_FLT_FN (BUILT_IN_LOGB
):
1814 errno_set
= true; builtin_optab
= logb_optab
; break;
1815 CASE_FLT_FN (BUILT_IN_ILOGB
):
1816 errno_set
= true; builtin_optab
= ilogb_optab
; break;
1817 CASE_FLT_FN (BUILT_IN_LOG
):
1818 errno_set
= true; builtin_optab
= log_optab
; break;
1819 CASE_FLT_FN (BUILT_IN_LOG10
):
1820 errno_set
= true; builtin_optab
= log10_optab
; break;
1821 CASE_FLT_FN (BUILT_IN_LOG2
):
1822 errno_set
= true; builtin_optab
= log2_optab
; break;
1823 CASE_FLT_FN (BUILT_IN_LOG1P
):
1824 errno_set
= true; builtin_optab
= log1p_optab
; break;
1825 CASE_FLT_FN (BUILT_IN_ASIN
):
1826 builtin_optab
= asin_optab
; break;
1827 CASE_FLT_FN (BUILT_IN_ACOS
):
1828 builtin_optab
= acos_optab
; break;
1829 CASE_FLT_FN (BUILT_IN_TAN
):
1830 builtin_optab
= tan_optab
; break;
1831 CASE_FLT_FN (BUILT_IN_ATAN
):
1832 builtin_optab
= atan_optab
; break;
1833 CASE_FLT_FN (BUILT_IN_FLOOR
):
1834 builtin_optab
= floor_optab
; break;
1835 CASE_FLT_FN (BUILT_IN_CEIL
):
1836 builtin_optab
= ceil_optab
; break;
1837 CASE_FLT_FN (BUILT_IN_TRUNC
):
1838 builtin_optab
= btrunc_optab
; break;
1839 CASE_FLT_FN (BUILT_IN_ROUND
):
1840 builtin_optab
= round_optab
; break;
1841 CASE_FLT_FN (BUILT_IN_NEARBYINT
):
1842 builtin_optab
= nearbyint_optab
;
1843 if (flag_trapping_math
)
1845 /* Else fallthrough and expand as rint. */
1846 CASE_FLT_FN (BUILT_IN_RINT
):
1847 builtin_optab
= rint_optab
; break;
1852 /* Make a suitable register to place result in. */
1853 mode
= TYPE_MODE (TREE_TYPE (exp
));
1855 if (! flag_errno_math
|| ! HONOR_NANS (mode
))
1858 /* Before working hard, check whether the instruction is available. */
1859 if (builtin_optab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
)
1861 target
= gen_reg_rtx (mode
);
1863 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
1864 need to expand the argument again. This way, we will not perform
1865 side-effects more the once. */
1866 narg
= builtin_save_expr (arg
);
1870 arglist
= build_tree_list (NULL_TREE
, arg
);
1871 exp
= build_function_call_expr (fndecl
, arglist
);
1874 op0
= expand_expr (arg
, subtarget
, VOIDmode
, 0);
1878 /* Compute into TARGET.
1879 Set TARGET to wherever the result comes back. */
1880 target
= expand_unop (mode
, builtin_optab
, op0
, target
, 0);
1885 expand_errno_check (exp
, target
);
1887 /* Output the entire sequence. */
1888 insns
= get_insns ();
1894 /* If we were unable to expand via the builtin, stop the sequence
1895 (without outputting the insns) and call to the library function
1896 with the stabilized argument list. */
1900 before_call
= get_last_insn ();
1902 target
= expand_call (exp
, target
, target
== const0_rtx
);
1904 /* If this is a sqrt operation and we don't care about errno, try to
1905 attach a REG_EQUAL note with a SQRT rtx to the emitted libcall.
1906 This allows the semantics of the libcall to be visible to the RTL
1908 if (builtin_optab
== sqrt_optab
&& !errno_set
)
1910 /* Search backwards through the insns emitted by expand_call looking
1911 for the instruction with the REG_RETVAL note. */
1912 rtx last
= get_last_insn ();
1913 while (last
!= before_call
)
1915 if (find_reg_note (last
, REG_RETVAL
, NULL
))
1917 rtx note
= find_reg_note (last
, REG_EQUAL
, NULL
);
1918 /* Check that the REQ_EQUAL note is an EXPR_LIST with
1919 two elements, i.e. symbol_ref(sqrt) and the operand. */
1921 && GET_CODE (note
) == EXPR_LIST
1922 && GET_CODE (XEXP (note
, 0)) == EXPR_LIST
1923 && XEXP (XEXP (note
, 0), 1) != NULL_RTX
1924 && XEXP (XEXP (XEXP (note
, 0), 1), 1) == NULL_RTX
)
1926 rtx operand
= XEXP (XEXP (XEXP (note
, 0), 1), 0);
1927 /* Check operand is a register with expected mode. */
1930 && GET_MODE (operand
) == mode
)
1932 /* Replace the REG_EQUAL note with a SQRT rtx. */
1933 rtx equiv
= gen_rtx_SQRT (mode
, operand
);
1934 set_unique_reg_note (last
, REG_EQUAL
, equiv
);
1939 last
= PREV_INSN (last
);
1946 /* Expand a call to the builtin binary math functions (pow and atan2).
1947 Return 0 if a normal call should be emitted rather than expanding the
1948 function in-line. EXP is the expression that is a call to the builtin
1949 function; if convenient, the result should be placed in TARGET.
1950 SUBTARGET may be used as the target for computing one of EXP's
1954 expand_builtin_mathfn_2 (tree exp
, rtx target
, rtx subtarget
)
1956 optab builtin_optab
;
1957 rtx op0
, op1
, insns
;
1958 int op1_type
= REAL_TYPE
;
1959 tree fndecl
= get_callee_fndecl (exp
);
1960 tree arglist
= TREE_OPERAND (exp
, 1);
1961 tree arg0
, arg1
, temp
, narg
;
1962 enum machine_mode mode
;
1963 bool errno_set
= true;
1966 if ((DECL_FUNCTION_CODE (fndecl
) == BUILT_IN_LDEXP
)
1967 || (DECL_FUNCTION_CODE (fndecl
) == BUILT_IN_LDEXPF
)
1968 || (DECL_FUNCTION_CODE (fndecl
) == BUILT_IN_LDEXPL
))
1969 op1_type
= INTEGER_TYPE
;
1971 if (!validate_arglist (arglist
, REAL_TYPE
, op1_type
, VOID_TYPE
))
1974 arg0
= TREE_VALUE (arglist
);
1975 arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
1977 switch (DECL_FUNCTION_CODE (fndecl
))
1979 CASE_FLT_FN (BUILT_IN_POW
):
1980 builtin_optab
= pow_optab
; break;
1981 CASE_FLT_FN (BUILT_IN_ATAN2
):
1982 builtin_optab
= atan2_optab
; break;
1983 CASE_FLT_FN (BUILT_IN_LDEXP
):
1984 builtin_optab
= ldexp_optab
; break;
1985 CASE_FLT_FN (BUILT_IN_FMOD
):
1986 builtin_optab
= fmod_optab
; break;
1987 CASE_FLT_FN (BUILT_IN_REMAINDER
):
1988 CASE_FLT_FN (BUILT_IN_DREM
):
1989 builtin_optab
= remainder_optab
; break;
1994 /* Make a suitable register to place result in. */
1995 mode
= TYPE_MODE (TREE_TYPE (exp
));
1997 /* Before working hard, check whether the instruction is available. */
1998 if (builtin_optab
->handlers
[(int) mode
].insn_code
== CODE_FOR_nothing
)
2001 target
= gen_reg_rtx (mode
);
2003 if (! flag_errno_math
|| ! HONOR_NANS (mode
))
2006 /* Always stabilize the argument list. */
2007 narg
= builtin_save_expr (arg1
);
2011 temp
= build_tree_list (NULL_TREE
, narg
);
2015 temp
= TREE_CHAIN (arglist
);
2017 narg
= builtin_save_expr (arg0
);
2021 arglist
= tree_cons (NULL_TREE
, narg
, temp
);
2025 arglist
= tree_cons (NULL_TREE
, arg0
, temp
);
2028 exp
= build_function_call_expr (fndecl
, arglist
);
2030 op0
= expand_expr (arg0
, subtarget
, VOIDmode
, EXPAND_NORMAL
);
2031 op1
= expand_normal (arg1
);
2035 /* Compute into TARGET.
2036 Set TARGET to wherever the result comes back. */
2037 target
= expand_binop (mode
, builtin_optab
, op0
, op1
,
2038 target
, 0, OPTAB_DIRECT
);
2040 /* If we were unable to expand via the builtin, stop the sequence
2041 (without outputting the insns) and call to the library function
2042 with the stabilized argument list. */
2046 return expand_call (exp
, target
, target
== const0_rtx
);
2050 expand_errno_check (exp
, target
);
2052 /* Output the entire sequence. */
2053 insns
= get_insns ();
2060 /* Expand a call to the builtin sin and cos math functions.
2061 Return 0 if a normal call should be emitted rather than expanding the
2062 function in-line. EXP is the expression that is a call to the builtin
2063 function; if convenient, the result should be placed in TARGET.
2064 SUBTARGET may be used as the target for computing one of EXP's
2068 expand_builtin_mathfn_3 (tree exp
, rtx target
, rtx subtarget
)
2070 optab builtin_optab
;
2072 tree fndecl
= get_callee_fndecl (exp
);
2073 tree arglist
= TREE_OPERAND (exp
, 1);
2074 enum machine_mode mode
;
2077 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
2080 arg
= TREE_VALUE (arglist
);
2082 switch (DECL_FUNCTION_CODE (fndecl
))
2084 CASE_FLT_FN (BUILT_IN_SIN
):
2085 CASE_FLT_FN (BUILT_IN_COS
):
2086 builtin_optab
= sincos_optab
; break;
2091 /* Make a suitable register to place result in. */
2092 mode
= TYPE_MODE (TREE_TYPE (exp
));
2094 /* Check if sincos insn is available, otherwise fallback
2095 to sin or cos insn. */
2096 if (builtin_optab
->handlers
[(int) mode
].insn_code
== CODE_FOR_nothing
)
2097 switch (DECL_FUNCTION_CODE (fndecl
))
2099 CASE_FLT_FN (BUILT_IN_SIN
):
2100 builtin_optab
= sin_optab
; break;
2101 CASE_FLT_FN (BUILT_IN_COS
):
2102 builtin_optab
= cos_optab
; break;
2107 /* Before working hard, check whether the instruction is available. */
2108 if (builtin_optab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
)
2110 target
= gen_reg_rtx (mode
);
2112 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2113 need to expand the argument again. This way, we will not perform
2114 side-effects more the once. */
2115 narg
= save_expr (arg
);
2119 arglist
= build_tree_list (NULL_TREE
, arg
);
2120 exp
= build_function_call_expr (fndecl
, arglist
);
2123 op0
= expand_expr (arg
, subtarget
, VOIDmode
, 0);
2127 /* Compute into TARGET.
2128 Set TARGET to wherever the result comes back. */
2129 if (builtin_optab
== sincos_optab
)
2133 switch (DECL_FUNCTION_CODE (fndecl
))
2135 CASE_FLT_FN (BUILT_IN_SIN
):
2136 result
= expand_twoval_unop (builtin_optab
, op0
, 0, target
, 0);
2138 CASE_FLT_FN (BUILT_IN_COS
):
2139 result
= expand_twoval_unop (builtin_optab
, op0
, target
, 0, 0);
2144 gcc_assert (result
);
2148 target
= expand_unop (mode
, builtin_optab
, op0
, target
, 0);
2153 /* Output the entire sequence. */
2154 insns
= get_insns ();
2160 /* If we were unable to expand via the builtin, stop the sequence
2161 (without outputting the insns) and call to the library function
2162 with the stabilized argument list. */
2166 target
= expand_call (exp
, target
, target
== const0_rtx
);
2171 /* Expand a call to the builtin sincos math function.
2172 Return 0 if a normal call should be emitted rather than expanding the
2173 function in-line. EXP is the expression that is a call to the builtin
2177 expand_builtin_sincos (tree exp
)
2179 rtx op0
, op1
, op2
, target1
, target2
;
2180 tree arglist
= TREE_OPERAND (exp
, 1);
2181 enum machine_mode mode
;
2182 tree arg
, sinp
, cosp
;
2185 if (!validate_arglist (arglist
, REAL_TYPE
,
2186 POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
2189 arg
= TREE_VALUE (arglist
);
2190 sinp
= TREE_VALUE (TREE_CHAIN (arglist
));
2191 cosp
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
2193 /* Make a suitable register to place result in. */
2194 mode
= TYPE_MODE (TREE_TYPE (arg
));
2196 /* Check if sincos insn is available, otherwise emit the call. */
2197 if (sincos_optab
->handlers
[(int) mode
].insn_code
== CODE_FOR_nothing
)
2200 target1
= gen_reg_rtx (mode
);
2201 target2
= gen_reg_rtx (mode
);
2203 op0
= expand_normal (arg
);
2204 op1
= expand_normal (build_fold_indirect_ref (sinp
));
2205 op2
= expand_normal (build_fold_indirect_ref (cosp
));
2207 /* Compute into target1 and target2.
2208 Set TARGET to wherever the result comes back. */
2209 result
= expand_twoval_unop (sincos_optab
, op0
, target2
, target1
, 0);
2210 gcc_assert (result
);
2212 /* Move target1 and target2 to the memory locations indicated
2214 emit_move_insn (op1
, target1
);
2215 emit_move_insn (op2
, target2
);
2220 /* Expand a call to the internal cexpi builtin to the sincos math function.
2221 EXP is the expression that is a call to the builtin function; if convenient,
2222 the result should be placed in TARGET. SUBTARGET may be used as the target
2223 for computing one of EXP's operands. */
2226 expand_builtin_cexpi (tree exp
, rtx target
, rtx subtarget
)
2228 tree fndecl
= get_callee_fndecl (exp
);
2229 tree arglist
= TREE_OPERAND (exp
, 1);
2230 enum machine_mode mode
;
2234 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
2237 arg
= TREE_VALUE (arglist
);
2238 type
= TREE_TYPE (arg
);
2239 mode
= TYPE_MODE (TREE_TYPE (arg
));
2241 /* Try expanding via a sincos optab, fall back to emitting a libcall
2242 to sincos. We are sure we have sincos either way because cexpi
2243 is only generated from sincos. */
2244 if (sincos_optab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
)
2246 op1
= gen_reg_rtx (mode
);
2247 op2
= gen_reg_rtx (mode
);
2249 op0
= expand_expr (arg
, subtarget
, VOIDmode
, 0);
2251 /* Compute into op1 and op2. */
2252 expand_twoval_unop (sincos_optab
, op0
, op2
, op1
, 0);
2256 tree call
, narglist
, fn
= NULL_TREE
;
2260 if (DECL_FUNCTION_CODE (fndecl
) == BUILT_IN_CEXPIF
)
2261 fn
= built_in_decls
[BUILT_IN_SINCOSF
];
2262 else if (DECL_FUNCTION_CODE (fndecl
) == BUILT_IN_CEXPI
)
2263 fn
= built_in_decls
[BUILT_IN_SINCOS
];
2264 else if (DECL_FUNCTION_CODE (fndecl
) == BUILT_IN_CEXPIL
)
2265 fn
= built_in_decls
[BUILT_IN_SINCOSL
];
2268 op1
= assign_temp (TREE_TYPE (arg
), 0, 1, 1);
2269 op2
= assign_temp (TREE_TYPE (arg
), 0, 1, 1);
2270 op1a
= copy_to_mode_reg (Pmode
, XEXP (op1
, 0));
2271 op2a
= copy_to_mode_reg (Pmode
, XEXP (op2
, 0));
2272 top1
= make_tree (build_pointer_type (TREE_TYPE (arg
)), op1a
);
2273 top2
= make_tree (build_pointer_type (TREE_TYPE (arg
)), op2a
);
2275 narglist
= build_tree_list (NULL_TREE
, top2
);
2276 narglist
= tree_cons (NULL_TREE
, top1
, narglist
);
2277 narglist
= tree_cons (NULL_TREE
, arg
, narglist
);
2279 /* Make sure not to fold the sincos call again. */
2280 call
= build1 (ADDR_EXPR
, build_pointer_type (TREE_TYPE (fn
)), fn
);
2281 expand_normal (build3 (CALL_EXPR
, TREE_TYPE (TREE_TYPE (fn
)),
2282 call
, narglist
, NULL_TREE
));
2285 /* Now build the proper return type. */
2286 return expand_expr (build2 (COMPLEX_EXPR
, build_complex_type (type
),
2287 make_tree (TREE_TYPE (arg
), op2
),
2288 make_tree (TREE_TYPE (arg
), op1
)),
2289 target
, VOIDmode
, 0);
2292 /* Expand a call to one of the builtin rounding functions gcc defines
2293 as an extension (lfloor and lceil). As these are gcc extensions we
2294 do not need to worry about setting errno to EDOM.
2295 If expanding via optab fails, lower expression to (int)(floor(x)).
2296 EXP is the expression that is a call to the builtin function;
2297 if convenient, the result should be placed in TARGET. SUBTARGET may
2298 be used as the target for computing one of EXP's operands. */
2301 expand_builtin_int_roundingfn (tree exp
, rtx target
, rtx subtarget
)
2303 convert_optab builtin_optab
;
2304 rtx op0
, insns
, tmp
;
2305 tree fndecl
= get_callee_fndecl (exp
);
2306 tree arglist
= TREE_OPERAND (exp
, 1);
2307 enum built_in_function fallback_fn
;
2308 tree fallback_fndecl
;
2309 enum machine_mode mode
;
2312 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
2315 arg
= TREE_VALUE (arglist
);
2317 switch (DECL_FUNCTION_CODE (fndecl
))
2319 CASE_FLT_FN (BUILT_IN_LCEIL
):
2320 CASE_FLT_FN (BUILT_IN_LLCEIL
):
2321 builtin_optab
= lceil_optab
;
2322 fallback_fn
= BUILT_IN_CEIL
;
2325 CASE_FLT_FN (BUILT_IN_LFLOOR
):
2326 CASE_FLT_FN (BUILT_IN_LLFLOOR
):
2327 builtin_optab
= lfloor_optab
;
2328 fallback_fn
= BUILT_IN_FLOOR
;
2335 /* Make a suitable register to place result in. */
2336 mode
= TYPE_MODE (TREE_TYPE (exp
));
2338 target
= gen_reg_rtx (mode
);
2340 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2341 need to expand the argument again. This way, we will not perform
2342 side-effects more the once. */
2343 narg
= builtin_save_expr (arg
);
2347 arglist
= build_tree_list (NULL_TREE
, arg
);
2348 exp
= build_function_call_expr (fndecl
, arglist
);
2351 op0
= expand_expr (arg
, subtarget
, VOIDmode
, 0);
2355 /* Compute into TARGET. */
2356 if (expand_sfix_optab (target
, op0
, builtin_optab
))
2358 /* Output the entire sequence. */
2359 insns
= get_insns ();
2365 /* If we were unable to expand via the builtin, stop the sequence
2366 (without outputting the insns). */
2369 /* Fall back to floating point rounding optab. */
2370 fallback_fndecl
= mathfn_built_in (TREE_TYPE (arg
), fallback_fn
);
2371 /* We shouldn't get here on targets without TARGET_C99_FUNCTIONS.
2372 ??? Perhaps convert (int)floorf(x) into (int)floor((double)x). */
2373 gcc_assert (fallback_fndecl
!= NULL_TREE
);
2374 exp
= build_function_call_expr (fallback_fndecl
, arglist
);
2376 tmp
= expand_normal (exp
);
2378 /* Truncate the result of floating point optab to integer
2379 via expand_fix (). */
2380 target
= gen_reg_rtx (mode
);
2381 expand_fix (target
, tmp
, 0);
2386 /* Expand a call to one of the builtin math functions doing integer
2388 Return 0 if a normal call should be emitted rather than expanding the
2389 function in-line. EXP is the expression that is a call to the builtin
2390 function; if convenient, the result should be placed in TARGET.
2391 SUBTARGET may be used as the target for computing one of EXP's operands. */
2394 expand_builtin_int_roundingfn_2 (tree exp
, rtx target
, rtx subtarget
)
2396 convert_optab builtin_optab
;
2398 tree fndecl
= get_callee_fndecl (exp
);
2399 tree arglist
= TREE_OPERAND (exp
, 1);
2400 enum machine_mode mode
;
2403 /* There's no easy way to detect the case we need to set EDOM. */
2404 if (flag_errno_math
)
2407 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
2410 arg
= TREE_VALUE (arglist
);
2412 switch (DECL_FUNCTION_CODE (fndecl
))
2414 CASE_FLT_FN (BUILT_IN_LRINT
):
2415 CASE_FLT_FN (BUILT_IN_LLRINT
):
2416 builtin_optab
= lrint_optab
; break;
2417 CASE_FLT_FN (BUILT_IN_LROUND
):
2418 CASE_FLT_FN (BUILT_IN_LLROUND
):
2419 builtin_optab
= lround_optab
; break;
2424 /* Make a suitable register to place result in. */
2425 mode
= TYPE_MODE (TREE_TYPE (exp
));
2427 target
= gen_reg_rtx (mode
);
2429 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2430 need to expand the argument again. This way, we will not perform
2431 side-effects more the once. */
2432 narg
= builtin_save_expr (arg
);
2436 arglist
= build_tree_list (NULL_TREE
, arg
);
2437 exp
= build_function_call_expr (fndecl
, arglist
);
2440 op0
= expand_expr (arg
, subtarget
, VOIDmode
, 0);
2444 if (expand_sfix_optab (target
, op0
, builtin_optab
))
2446 /* Output the entire sequence. */
2447 insns
= get_insns ();
2453 /* If we were unable to expand via the builtin, stop the sequence
2454 (without outputting the insns) and call to the library function
2455 with the stabilized argument list. */
2458 target
= expand_call (exp
, target
, target
== const0_rtx
);
2463 /* To evaluate powi(x,n), the floating point value x raised to the
2464 constant integer exponent n, we use a hybrid algorithm that
2465 combines the "window method" with look-up tables. For an
2466 introduction to exponentiation algorithms and "addition chains",
2467 see section 4.6.3, "Evaluation of Powers" of Donald E. Knuth,
2468 "Seminumerical Algorithms", Vol. 2, "The Art of Computer Programming",
2469 3rd Edition, 1998, and Daniel M. Gordon, "A Survey of Fast Exponentiation
2470 Methods", Journal of Algorithms, Vol. 27, pp. 129-146, 1998. */
2472 /* Provide a default value for POWI_MAX_MULTS, the maximum number of
2473 multiplications to inline before calling the system library's pow
2474 function. powi(x,n) requires at worst 2*bits(n)-2 multiplications,
2475 so this default never requires calling pow, powf or powl. */
2477 #ifndef POWI_MAX_MULTS
2478 #define POWI_MAX_MULTS (2*HOST_BITS_PER_WIDE_INT-2)
2481 /* The size of the "optimal power tree" lookup table. All
2482 exponents less than this value are simply looked up in the
2483 powi_table below. This threshold is also used to size the
2484 cache of pseudo registers that hold intermediate results. */
2485 #define POWI_TABLE_SIZE 256
2487 /* The size, in bits of the window, used in the "window method"
2488 exponentiation algorithm. This is equivalent to a radix of
2489 (1<<POWI_WINDOW_SIZE) in the corresponding "m-ary method". */
2490 #define POWI_WINDOW_SIZE 3
2492 /* The following table is an efficient representation of an
2493 "optimal power tree". For each value, i, the corresponding
2494 value, j, in the table states than an optimal evaluation
2495 sequence for calculating pow(x,i) can be found by evaluating
2496 pow(x,j)*pow(x,i-j). An optimal power tree for the first
2497 100 integers is given in Knuth's "Seminumerical algorithms". */
2499 static const unsigned char powi_table
[POWI_TABLE_SIZE
] =
2501 0, 1, 1, 2, 2, 3, 3, 4, /* 0 - 7 */
2502 4, 6, 5, 6, 6, 10, 7, 9, /* 8 - 15 */
2503 8, 16, 9, 16, 10, 12, 11, 13, /* 16 - 23 */
2504 12, 17, 13, 18, 14, 24, 15, 26, /* 24 - 31 */
2505 16, 17, 17, 19, 18, 33, 19, 26, /* 32 - 39 */
2506 20, 25, 21, 40, 22, 27, 23, 44, /* 40 - 47 */
2507 24, 32, 25, 34, 26, 29, 27, 44, /* 48 - 55 */
2508 28, 31, 29, 34, 30, 60, 31, 36, /* 56 - 63 */
2509 32, 64, 33, 34, 34, 46, 35, 37, /* 64 - 71 */
2510 36, 65, 37, 50, 38, 48, 39, 69, /* 72 - 79 */
2511 40, 49, 41, 43, 42, 51, 43, 58, /* 80 - 87 */
2512 44, 64, 45, 47, 46, 59, 47, 76, /* 88 - 95 */
2513 48, 65, 49, 66, 50, 67, 51, 66, /* 96 - 103 */
2514 52, 70, 53, 74, 54, 104, 55, 74, /* 104 - 111 */
2515 56, 64, 57, 69, 58, 78, 59, 68, /* 112 - 119 */
2516 60, 61, 61, 80, 62, 75, 63, 68, /* 120 - 127 */
2517 64, 65, 65, 128, 66, 129, 67, 90, /* 128 - 135 */
2518 68, 73, 69, 131, 70, 94, 71, 88, /* 136 - 143 */
2519 72, 128, 73, 98, 74, 132, 75, 121, /* 144 - 151 */
2520 76, 102, 77, 124, 78, 132, 79, 106, /* 152 - 159 */
2521 80, 97, 81, 160, 82, 99, 83, 134, /* 160 - 167 */
2522 84, 86, 85, 95, 86, 160, 87, 100, /* 168 - 175 */
2523 88, 113, 89, 98, 90, 107, 91, 122, /* 176 - 183 */
2524 92, 111, 93, 102, 94, 126, 95, 150, /* 184 - 191 */
2525 96, 128, 97, 130, 98, 133, 99, 195, /* 192 - 199 */
2526 100, 128, 101, 123, 102, 164, 103, 138, /* 200 - 207 */
2527 104, 145, 105, 146, 106, 109, 107, 149, /* 208 - 215 */
2528 108, 200, 109, 146, 110, 170, 111, 157, /* 216 - 223 */
2529 112, 128, 113, 130, 114, 182, 115, 132, /* 224 - 231 */
2530 116, 200, 117, 132, 118, 158, 119, 206, /* 232 - 239 */
2531 120, 240, 121, 162, 122, 147, 123, 152, /* 240 - 247 */
2532 124, 166, 125, 214, 126, 138, 127, 153, /* 248 - 255 */
2536 /* Return the number of multiplications required to calculate
2537 powi(x,n) where n is less than POWI_TABLE_SIZE. This is a
2538 subroutine of powi_cost. CACHE is an array indicating
2539 which exponents have already been calculated. */
2542 powi_lookup_cost (unsigned HOST_WIDE_INT n
, bool *cache
)
2544 /* If we've already calculated this exponent, then this evaluation
2545 doesn't require any additional multiplications. */
2550 return powi_lookup_cost (n
- powi_table
[n
], cache
)
2551 + powi_lookup_cost (powi_table
[n
], cache
) + 1;
2554 /* Return the number of multiplications required to calculate
2555 powi(x,n) for an arbitrary x, given the exponent N. This
2556 function needs to be kept in sync with expand_powi below. */
2559 powi_cost (HOST_WIDE_INT n
)
2561 bool cache
[POWI_TABLE_SIZE
];
2562 unsigned HOST_WIDE_INT digit
;
2563 unsigned HOST_WIDE_INT val
;
2569 /* Ignore the reciprocal when calculating the cost. */
2570 val
= (n
< 0) ? -n
: n
;
2572 /* Initialize the exponent cache. */
2573 memset (cache
, 0, POWI_TABLE_SIZE
* sizeof (bool));
2578 while (val
>= POWI_TABLE_SIZE
)
2582 digit
= val
& ((1 << POWI_WINDOW_SIZE
) - 1);
2583 result
+= powi_lookup_cost (digit
, cache
)
2584 + POWI_WINDOW_SIZE
+ 1;
2585 val
>>= POWI_WINDOW_SIZE
;
2594 return result
+ powi_lookup_cost (val
, cache
);
2597 /* Recursive subroutine of expand_powi. This function takes the array,
2598 CACHE, of already calculated exponents and an exponent N and returns
2599 an RTX that corresponds to CACHE[1]**N, as calculated in mode MODE. */
2602 expand_powi_1 (enum machine_mode mode
, unsigned HOST_WIDE_INT n
, rtx
*cache
)
2604 unsigned HOST_WIDE_INT digit
;
2608 if (n
< POWI_TABLE_SIZE
)
2613 target
= gen_reg_rtx (mode
);
2616 op0
= expand_powi_1 (mode
, n
- powi_table
[n
], cache
);
2617 op1
= expand_powi_1 (mode
, powi_table
[n
], cache
);
2621 target
= gen_reg_rtx (mode
);
2622 digit
= n
& ((1 << POWI_WINDOW_SIZE
) - 1);
2623 op0
= expand_powi_1 (mode
, n
- digit
, cache
);
2624 op1
= expand_powi_1 (mode
, digit
, cache
);
2628 target
= gen_reg_rtx (mode
);
2629 op0
= expand_powi_1 (mode
, n
>> 1, cache
);
2633 result
= expand_mult (mode
, op0
, op1
, target
, 0);
2634 if (result
!= target
)
2635 emit_move_insn (target
, result
);
2639 /* Expand the RTL to evaluate powi(x,n) in mode MODE. X is the
2640 floating point operand in mode MODE, and N is the exponent. This
2641 function needs to be kept in sync with powi_cost above. */
2644 expand_powi (rtx x
, enum machine_mode mode
, HOST_WIDE_INT n
)
2646 unsigned HOST_WIDE_INT val
;
2647 rtx cache
[POWI_TABLE_SIZE
];
2651 return CONST1_RTX (mode
);
2653 val
= (n
< 0) ? -n
: n
;
2655 memset (cache
, 0, sizeof (cache
));
2658 result
= expand_powi_1 (mode
, (n
< 0) ? -n
: n
, cache
);
2660 /* If the original exponent was negative, reciprocate the result. */
2662 result
= expand_binop (mode
, sdiv_optab
, CONST1_RTX (mode
),
2663 result
, NULL_RTX
, 0, OPTAB_LIB_WIDEN
);
2668 /* Expand a call to the pow built-in mathematical function. Return 0 if
2669 a normal call should be emitted rather than expanding the function
2670 in-line. EXP is the expression that is a call to the builtin
2671 function; if convenient, the result should be placed in TARGET. */
2674 expand_builtin_pow (tree exp
, rtx target
, rtx subtarget
)
2676 tree arg0
, arg1
, fn
, narg0
, narglist
;
2677 tree arglist
= TREE_OPERAND (exp
, 1);
2678 tree type
= TREE_TYPE (exp
);
2679 REAL_VALUE_TYPE cint
, c
, c2
;
2682 enum machine_mode mode
= TYPE_MODE (type
);
2684 if (! validate_arglist (arglist
, REAL_TYPE
, REAL_TYPE
, VOID_TYPE
))
2687 arg0
= TREE_VALUE (arglist
);
2688 arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
2690 if (TREE_CODE (arg1
) != REAL_CST
2691 || TREE_CONSTANT_OVERFLOW (arg1
))
2692 return expand_builtin_mathfn_2 (exp
, target
, subtarget
);
2694 /* Handle constant exponents. */
2696 /* For integer valued exponents we can expand to an optimal multiplication
2697 sequence using expand_powi. */
2698 c
= TREE_REAL_CST (arg1
);
2699 n
= real_to_integer (&c
);
2700 real_from_integer (&cint
, VOIDmode
, n
, n
< 0 ? -1 : 0, 0);
2701 if (real_identical (&c
, &cint
)
2702 && ((n
>= -1 && n
<= 2)
2703 || (flag_unsafe_math_optimizations
2705 && powi_cost (n
) <= POWI_MAX_MULTS
)))
2707 op
= expand_expr (arg0
, subtarget
, VOIDmode
, 0);
2710 op
= force_reg (mode
, op
);
2711 op
= expand_powi (op
, mode
, n
);
2716 narg0
= builtin_save_expr (arg0
);
2717 narglist
= build_tree_list (NULL_TREE
, narg0
);
2719 /* If the exponent is not integer valued, check if it is half of an integer.
2720 In this case we can expand to sqrt (x) * x**(n/2). */
2721 fn
= mathfn_built_in (type
, BUILT_IN_SQRT
);
2722 if (fn
!= NULL_TREE
)
2724 real_arithmetic (&c2
, MULT_EXPR
, &c
, &dconst2
);
2725 n
= real_to_integer (&c2
);
2726 real_from_integer (&cint
, VOIDmode
, n
, n
< 0 ? -1 : 0, 0);
2727 if (real_identical (&c2
, &cint
)
2728 && ((flag_unsafe_math_optimizations
2730 && powi_cost (n
/2) <= POWI_MAX_MULTS
)
2733 tree call_expr
= build_function_call_expr (fn
, narglist
);
2734 op
= expand_builtin (call_expr
, NULL_RTX
, subtarget
, mode
, 0);
2737 op2
= expand_expr (narg0
, subtarget
, VOIDmode
, 0);
2738 op2
= force_reg (mode
, op2
);
2739 op2
= expand_powi (op2
, mode
, abs (n
/ 2));
2740 op
= expand_simple_binop (mode
, MULT
, op
, op2
, NULL_RTX
,
2741 0, OPTAB_LIB_WIDEN
);
2742 /* If the original exponent was negative, reciprocate the
2745 op
= expand_binop (mode
, sdiv_optab
, CONST1_RTX (mode
),
2746 op
, NULL_RTX
, 0, OPTAB_LIB_WIDEN
);
2752 /* Try if the exponent is a third of an integer. In this case
2753 we can expand to x**(n/3) * cbrt(x)**(n%3). As cbrt (x) is
2754 different from pow (x, 1./3.) due to rounding and behavior
2755 with negative x we need to constrain this transformation to
2756 unsafe math and positive x or finite math. */
2757 fn
= mathfn_built_in (type
, BUILT_IN_CBRT
);
2759 && flag_unsafe_math_optimizations
2760 && (tree_expr_nonnegative_p (arg0
)
2761 || !HONOR_NANS (mode
)))
2763 real_arithmetic (&c2
, MULT_EXPR
, &c
, &dconst3
);
2764 real_round (&c2
, mode
, &c2
);
2765 n
= real_to_integer (&c2
);
2766 real_from_integer (&cint
, VOIDmode
, n
, n
< 0 ? -1 : 0, 0);
2767 real_arithmetic (&c2
, RDIV_EXPR
, &cint
, &dconst3
);
2768 real_convert (&c2
, mode
, &c2
);
2769 if (real_identical (&c2
, &c
)
2771 && powi_cost (n
/3) <= POWI_MAX_MULTS
)
2774 tree call_expr
= build_function_call_expr (fn
, narglist
);
2775 op
= expand_builtin (call_expr
, NULL_RTX
, subtarget
, mode
, 0);
2776 if (abs (n
) % 3 == 2)
2777 op
= expand_simple_binop (mode
, MULT
, op
, op
, op
,
2778 0, OPTAB_LIB_WIDEN
);
2781 op2
= expand_expr (narg0
, subtarget
, VOIDmode
, 0);
2782 op2
= force_reg (mode
, op2
);
2783 op2
= expand_powi (op2
, mode
, abs (n
/ 3));
2784 op
= expand_simple_binop (mode
, MULT
, op
, op2
, NULL_RTX
,
2785 0, OPTAB_LIB_WIDEN
);
2786 /* If the original exponent was negative, reciprocate the
2789 op
= expand_binop (mode
, sdiv_optab
, CONST1_RTX (mode
),
2790 op
, NULL_RTX
, 0, OPTAB_LIB_WIDEN
);
2796 /* Fall back to optab expansion. */
2797 return expand_builtin_mathfn_2 (exp
, target
, subtarget
);
2800 /* Expand a call to the powi built-in mathematical function. Return 0 if
2801 a normal call should be emitted rather than expanding the function
2802 in-line. EXP is the expression that is a call to the builtin
2803 function; if convenient, the result should be placed in TARGET. */
2806 expand_builtin_powi (tree exp
, rtx target
, rtx subtarget
)
2808 tree arglist
= TREE_OPERAND (exp
, 1);
2811 enum machine_mode mode
;
2812 enum machine_mode mode2
;
2814 if (! validate_arglist (arglist
, REAL_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
2817 arg0
= TREE_VALUE (arglist
);
2818 arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
2819 mode
= TYPE_MODE (TREE_TYPE (exp
));
2821 /* Handle constant power. */
2823 if (TREE_CODE (arg1
) == INTEGER_CST
2824 && ! TREE_CONSTANT_OVERFLOW (arg1
))
2826 HOST_WIDE_INT n
= TREE_INT_CST_LOW (arg1
);
2828 /* If the exponent is -1, 0, 1 or 2, then expand_powi is exact.
2829 Otherwise, check the number of multiplications required. */
2830 if ((TREE_INT_CST_HIGH (arg1
) == 0
2831 || TREE_INT_CST_HIGH (arg1
) == -1)
2832 && ((n
>= -1 && n
<= 2)
2834 && powi_cost (n
) <= POWI_MAX_MULTS
)))
2836 op0
= expand_expr (arg0
, subtarget
, VOIDmode
, 0);
2837 op0
= force_reg (mode
, op0
);
2838 return expand_powi (op0
, mode
, n
);
2842 /* Emit a libcall to libgcc. */
2844 /* Mode of the 2nd argument must match that of an int. */
2845 mode2
= mode_for_size (INT_TYPE_SIZE
, MODE_INT
, 0);
2847 if (target
== NULL_RTX
)
2848 target
= gen_reg_rtx (mode
);
2850 op0
= expand_expr (arg0
, subtarget
, mode
, 0);
2851 if (GET_MODE (op0
) != mode
)
2852 op0
= convert_to_mode (mode
, op0
, 0);
2853 op1
= expand_expr (arg1
, 0, mode2
, 0);
2854 if (GET_MODE (op1
) != mode2
)
2855 op1
= convert_to_mode (mode2
, op1
, 0);
2857 target
= emit_library_call_value (powi_optab
->handlers
[(int) mode
].libfunc
,
2858 target
, LCT_CONST_MAKE_BLOCK
, mode
, 2,
2859 op0
, mode
, op1
, mode2
);
2864 /* Expand expression EXP which is a call to the strlen builtin. Return 0
2865 if we failed the caller should emit a normal call, otherwise
2866 try to get the result in TARGET, if convenient. */
2869 expand_builtin_strlen (tree arglist
, rtx target
,
2870 enum machine_mode target_mode
)
2872 if (!validate_arglist (arglist
, POINTER_TYPE
, VOID_TYPE
))
2877 tree len
, src
= TREE_VALUE (arglist
);
2878 rtx result
, src_reg
, char_rtx
, before_strlen
;
2879 enum machine_mode insn_mode
= target_mode
, char_mode
;
2880 enum insn_code icode
= CODE_FOR_nothing
;
2883 /* If the length can be computed at compile-time, return it. */
2884 len
= c_strlen (src
, 0);
2886 return expand_expr (len
, target
, target_mode
, EXPAND_NORMAL
);
2888 /* If the length can be computed at compile-time and is constant
2889 integer, but there are side-effects in src, evaluate
2890 src for side-effects, then return len.
2891 E.g. x = strlen (i++ ? "xfoo" + 1 : "bar");
2892 can be optimized into: i++; x = 3; */
2893 len
= c_strlen (src
, 1);
2894 if (len
&& TREE_CODE (len
) == INTEGER_CST
)
2896 expand_expr (src
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
2897 return expand_expr (len
, target
, target_mode
, EXPAND_NORMAL
);
2900 align
= get_pointer_alignment (src
, BIGGEST_ALIGNMENT
) / BITS_PER_UNIT
;
2902 /* If SRC is not a pointer type, don't do this operation inline. */
2906 /* Bail out if we can't compute strlen in the right mode. */
2907 while (insn_mode
!= VOIDmode
)
2909 icode
= strlen_optab
->handlers
[(int) insn_mode
].insn_code
;
2910 if (icode
!= CODE_FOR_nothing
)
2913 insn_mode
= GET_MODE_WIDER_MODE (insn_mode
);
2915 if (insn_mode
== VOIDmode
)
2918 /* Make a place to write the result of the instruction. */
2922 && GET_MODE (result
) == insn_mode
2923 && REGNO (result
) >= FIRST_PSEUDO_REGISTER
))
2924 result
= gen_reg_rtx (insn_mode
);
2926 /* Make a place to hold the source address. We will not expand
2927 the actual source until we are sure that the expansion will
2928 not fail -- there are trees that cannot be expanded twice. */
2929 src_reg
= gen_reg_rtx (Pmode
);
2931 /* Mark the beginning of the strlen sequence so we can emit the
2932 source operand later. */
2933 before_strlen
= get_last_insn ();
2935 char_rtx
= const0_rtx
;
2936 char_mode
= insn_data
[(int) icode
].operand
[2].mode
;
2937 if (! (*insn_data
[(int) icode
].operand
[2].predicate
) (char_rtx
,
2939 char_rtx
= copy_to_mode_reg (char_mode
, char_rtx
);
2941 pat
= GEN_FCN (icode
) (result
, gen_rtx_MEM (BLKmode
, src_reg
),
2942 char_rtx
, GEN_INT (align
));
2947 /* Now that we are assured of success, expand the source. */
2949 pat
= expand_expr (src
, src_reg
, ptr_mode
, EXPAND_NORMAL
);
2951 emit_move_insn (src_reg
, pat
);
2956 emit_insn_after (pat
, before_strlen
);
2958 emit_insn_before (pat
, get_insns ());
2960 /* Return the value in the proper mode for this function. */
2961 if (GET_MODE (result
) == target_mode
)
2963 else if (target
!= 0)
2964 convert_move (target
, result
, 0);
2966 target
= convert_to_mode (target_mode
, result
, 0);
2972 /* Expand a call to the strstr builtin. Return 0 if we failed the
2973 caller should emit a normal call, otherwise try to get the result
2974 in TARGET, if convenient (and in mode MODE if that's convenient). */
2977 expand_builtin_strstr (tree arglist
, tree type
, rtx target
, enum machine_mode mode
)
2979 if (validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
2981 tree result
= fold_builtin_strstr (arglist
, type
);
2983 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
2988 /* Expand a call to the strchr builtin. Return 0 if we failed the
2989 caller should emit a normal call, otherwise try to get the result
2990 in TARGET, if convenient (and in mode MODE if that's convenient). */
2993 expand_builtin_strchr (tree arglist
, tree type
, rtx target
, enum machine_mode mode
)
2995 if (validate_arglist (arglist
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
2997 tree result
= fold_builtin_strchr (arglist
, type
);
2999 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
3001 /* FIXME: Should use strchrM optab so that ports can optimize this. */
3006 /* Expand a call to the strrchr builtin. Return 0 if we failed the
3007 caller should emit a normal call, otherwise try to get the result
3008 in TARGET, if convenient (and in mode MODE if that's convenient). */
3011 expand_builtin_strrchr (tree arglist
, tree type
, rtx target
, enum machine_mode mode
)
3013 if (validate_arglist (arglist
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
3015 tree result
= fold_builtin_strrchr (arglist
, type
);
3017 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
3022 /* Expand a call to the strpbrk builtin. Return 0 if we failed the
3023 caller should emit a normal call, otherwise try to get the result
3024 in TARGET, if convenient (and in mode MODE if that's convenient). */
3027 expand_builtin_strpbrk (tree arglist
, tree type
, rtx target
, enum machine_mode mode
)
3029 if (validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
3031 tree result
= fold_builtin_strpbrk (arglist
, type
);
3033 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
3038 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
3039 bytes from constant string DATA + OFFSET and return it as target
3043 builtin_memcpy_read_str (void *data
, HOST_WIDE_INT offset
,
3044 enum machine_mode mode
)
3046 const char *str
= (const char *) data
;
3048 gcc_assert (offset
>= 0
3049 && ((unsigned HOST_WIDE_INT
) offset
+ GET_MODE_SIZE (mode
)
3050 <= strlen (str
) + 1));
3052 return c_readstr (str
+ offset
, mode
);
3055 /* Expand a call to the memcpy builtin, with arguments in ARGLIST.
3056 Return 0 if we failed, the caller should emit a normal call,
3057 otherwise try to get the result in TARGET, if convenient (and in
3058 mode MODE if that's convenient). */
3060 expand_builtin_memcpy (tree exp
, rtx target
, enum machine_mode mode
)
3062 tree fndecl
= get_callee_fndecl (exp
);
3063 tree arglist
= TREE_OPERAND (exp
, 1);
3064 if (!validate_arglist (arglist
,
3065 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
3069 tree dest
= TREE_VALUE (arglist
);
3070 tree src
= TREE_VALUE (TREE_CHAIN (arglist
));
3071 tree len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
3072 const char *src_str
;
3073 unsigned int src_align
= get_pointer_alignment (src
, BIGGEST_ALIGNMENT
);
3074 unsigned int dest_align
3075 = get_pointer_alignment (dest
, BIGGEST_ALIGNMENT
);
3076 rtx dest_mem
, src_mem
, dest_addr
, len_rtx
;
3077 tree result
= fold_builtin_memory_op (arglist
, TREE_TYPE (TREE_TYPE (fndecl
)),
3082 while (TREE_CODE (result
) == COMPOUND_EXPR
)
3084 expand_expr (TREE_OPERAND (result
, 0), const0_rtx
, VOIDmode
,
3086 result
= TREE_OPERAND (result
, 1);
3088 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
3091 /* If DEST is not a pointer type, call the normal function. */
3092 if (dest_align
== 0)
3095 /* If either SRC is not a pointer type, don't do this
3096 operation in-line. */
3100 dest_mem
= get_memory_rtx (dest
, len
);
3101 set_mem_align (dest_mem
, dest_align
);
3102 len_rtx
= expand_normal (len
);
3103 src_str
= c_getstr (src
);
3105 /* If SRC is a string constant and block move would be done
3106 by pieces, we can avoid loading the string from memory
3107 and only stored the computed constants. */
3109 && GET_CODE (len_rtx
) == CONST_INT
3110 && (unsigned HOST_WIDE_INT
) INTVAL (len_rtx
) <= strlen (src_str
) + 1
3111 && can_store_by_pieces (INTVAL (len_rtx
), builtin_memcpy_read_str
,
3112 (void *) src_str
, dest_align
))
3114 dest_mem
= store_by_pieces (dest_mem
, INTVAL (len_rtx
),
3115 builtin_memcpy_read_str
,
3116 (void *) src_str
, dest_align
, 0);
3117 dest_mem
= force_operand (XEXP (dest_mem
, 0), NULL_RTX
);
3118 dest_mem
= convert_memory_address (ptr_mode
, dest_mem
);
3122 src_mem
= get_memory_rtx (src
, len
);
3123 set_mem_align (src_mem
, src_align
);
3125 /* Copy word part most expediently. */
3126 dest_addr
= emit_block_move (dest_mem
, src_mem
, len_rtx
,
3127 CALL_EXPR_TAILCALL (exp
)
3128 ? BLOCK_OP_TAILCALL
: BLOCK_OP_NORMAL
);
3132 dest_addr
= force_operand (XEXP (dest_mem
, 0), NULL_RTX
);
3133 dest_addr
= convert_memory_address (ptr_mode
, dest_addr
);
3139 /* Expand a call to the mempcpy builtin, with arguments in ARGLIST.
3140 Return 0 if we failed; the caller should emit a normal call,
3141 otherwise try to get the result in TARGET, if convenient (and in
3142 mode MODE if that's convenient). If ENDP is 0 return the
3143 destination pointer, if ENDP is 1 return the end pointer ala
3144 mempcpy, and if ENDP is 2 return the end pointer minus one ala
3148 expand_builtin_mempcpy (tree arglist
, tree type
, rtx target
, enum machine_mode mode
,
3151 if (!validate_arglist (arglist
,
3152 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
3154 /* If return value is ignored, transform mempcpy into memcpy. */
3155 else if (target
== const0_rtx
)
3157 tree fn
= implicit_built_in_decls
[BUILT_IN_MEMCPY
];
3162 return expand_expr (build_function_call_expr (fn
, arglist
),
3163 target
, mode
, EXPAND_NORMAL
);
3167 tree dest
= TREE_VALUE (arglist
);
3168 tree src
= TREE_VALUE (TREE_CHAIN (arglist
));
3169 tree len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
3170 const char *src_str
;
3171 unsigned int src_align
= get_pointer_alignment (src
, BIGGEST_ALIGNMENT
);
3172 unsigned int dest_align
3173 = get_pointer_alignment (dest
, BIGGEST_ALIGNMENT
);
3174 rtx dest_mem
, src_mem
, len_rtx
;
3175 tree result
= fold_builtin_memory_op (arglist
, type
, false, endp
);
3179 while (TREE_CODE (result
) == COMPOUND_EXPR
)
3181 expand_expr (TREE_OPERAND (result
, 0), const0_rtx
, VOIDmode
,
3183 result
= TREE_OPERAND (result
, 1);
3185 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
3188 /* If either SRC or DEST is not a pointer type, don't do this
3189 operation in-line. */
3190 if (dest_align
== 0 || src_align
== 0)
3193 /* If LEN is not constant, call the normal function. */
3194 if (! host_integerp (len
, 1))
3197 len_rtx
= expand_normal (len
);
3198 src_str
= c_getstr (src
);
3200 /* If SRC is a string constant and block move would be done
3201 by pieces, we can avoid loading the string from memory
3202 and only stored the computed constants. */
3204 && GET_CODE (len_rtx
) == CONST_INT
3205 && (unsigned HOST_WIDE_INT
) INTVAL (len_rtx
) <= strlen (src_str
) + 1
3206 && can_store_by_pieces (INTVAL (len_rtx
), builtin_memcpy_read_str
,
3207 (void *) src_str
, dest_align
))
3209 dest_mem
= get_memory_rtx (dest
, len
);
3210 set_mem_align (dest_mem
, dest_align
);
3211 dest_mem
= store_by_pieces (dest_mem
, INTVAL (len_rtx
),
3212 builtin_memcpy_read_str
,
3213 (void *) src_str
, dest_align
, endp
);
3214 dest_mem
= force_operand (XEXP (dest_mem
, 0), NULL_RTX
);
3215 dest_mem
= convert_memory_address (ptr_mode
, dest_mem
);
3219 if (GET_CODE (len_rtx
) == CONST_INT
3220 && can_move_by_pieces (INTVAL (len_rtx
),
3221 MIN (dest_align
, src_align
)))
3223 dest_mem
= get_memory_rtx (dest
, len
);
3224 set_mem_align (dest_mem
, dest_align
);
3225 src_mem
= get_memory_rtx (src
, len
);
3226 set_mem_align (src_mem
, src_align
);
3227 dest_mem
= move_by_pieces (dest_mem
, src_mem
, INTVAL (len_rtx
),
3228 MIN (dest_align
, src_align
), endp
);
3229 dest_mem
= force_operand (XEXP (dest_mem
, 0), NULL_RTX
);
3230 dest_mem
= convert_memory_address (ptr_mode
, dest_mem
);
3238 /* Expand expression EXP, which is a call to the memmove builtin. Return 0
3239 if we failed; the caller should emit a normal call. */
3242 expand_builtin_memmove (tree arglist
, tree type
, rtx target
,
3243 enum machine_mode mode
)
3245 if (!validate_arglist (arglist
,
3246 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
3250 tree result
= fold_builtin_memory_op (arglist
, type
, false, /*endp=*/3);
3254 while (TREE_CODE (result
) == COMPOUND_EXPR
)
3256 expand_expr (TREE_OPERAND (result
, 0), const0_rtx
, VOIDmode
,
3258 result
= TREE_OPERAND (result
, 1);
3260 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
3263 /* Otherwise, call the normal function. */
3268 /* Expand expression EXP, which is a call to the bcopy builtin. Return 0
3269 if we failed the caller should emit a normal call. */
3272 expand_builtin_bcopy (tree exp
)
3274 tree arglist
= TREE_OPERAND (exp
, 1);
3275 tree type
= TREE_TYPE (exp
);
3276 tree src
, dest
, size
, newarglist
;
3278 if (!validate_arglist (arglist
,
3279 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
3282 src
= TREE_VALUE (arglist
);
3283 dest
= TREE_VALUE (TREE_CHAIN (arglist
));
3284 size
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
3286 /* New argument list transforming bcopy(ptr x, ptr y, int z) to
3287 memmove(ptr y, ptr x, size_t z). This is done this way
3288 so that if it isn't expanded inline, we fallback to
3289 calling bcopy instead of memmove. */
3291 newarglist
= build_tree_list (NULL_TREE
, fold_convert (sizetype
, size
));
3292 newarglist
= tree_cons (NULL_TREE
, src
, newarglist
);
3293 newarglist
= tree_cons (NULL_TREE
, dest
, newarglist
);
3295 return expand_builtin_memmove (newarglist
, type
, const0_rtx
, VOIDmode
);
3299 # define HAVE_movstr 0
3300 # define CODE_FOR_movstr CODE_FOR_nothing
3303 /* Expand into a movstr instruction, if one is available. Return 0 if
3304 we failed, the caller should emit a normal call, otherwise try to
3305 get the result in TARGET, if convenient. If ENDP is 0 return the
3306 destination pointer, if ENDP is 1 return the end pointer ala
3307 mempcpy, and if ENDP is 2 return the end pointer minus one ala
3311 expand_movstr (tree dest
, tree src
, rtx target
, int endp
)
3317 const struct insn_data
* data
;
3322 dest_mem
= get_memory_rtx (dest
, NULL
);
3323 src_mem
= get_memory_rtx (src
, NULL
);
3326 target
= force_reg (Pmode
, XEXP (dest_mem
, 0));
3327 dest_mem
= replace_equiv_address (dest_mem
, target
);
3328 end
= gen_reg_rtx (Pmode
);
3332 if (target
== 0 || target
== const0_rtx
)
3334 end
= gen_reg_rtx (Pmode
);
3342 data
= insn_data
+ CODE_FOR_movstr
;
3344 if (data
->operand
[0].mode
!= VOIDmode
)
3345 end
= gen_lowpart (data
->operand
[0].mode
, end
);
3347 insn
= data
->genfun (end
, dest_mem
, src_mem
);
3353 /* movstr is supposed to set end to the address of the NUL
3354 terminator. If the caller requested a mempcpy-like return value,
3356 if (endp
== 1 && target
!= const0_rtx
)
3358 rtx tem
= plus_constant (gen_lowpart (GET_MODE (target
), end
), 1);
3359 emit_move_insn (target
, force_operand (tem
, NULL_RTX
));
3365 /* Expand expression EXP, which is a call to the strcpy builtin. Return 0
3366 if we failed the caller should emit a normal call, otherwise try to get
3367 the result in TARGET, if convenient (and in mode MODE if that's
3371 expand_builtin_strcpy (tree fndecl
, tree arglist
, rtx target
, enum machine_mode mode
)
3373 if (validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
3375 tree result
= fold_builtin_strcpy (fndecl
, arglist
, 0);
3378 while (TREE_CODE (result
) == COMPOUND_EXPR
)
3380 expand_expr (TREE_OPERAND (result
, 0), const0_rtx
, VOIDmode
,
3382 result
= TREE_OPERAND (result
, 1);
3384 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
3387 return expand_movstr (TREE_VALUE (arglist
),
3388 TREE_VALUE (TREE_CHAIN (arglist
)),
3389 target
, /*endp=*/0);
3394 /* Expand a call to the stpcpy builtin, with arguments in ARGLIST.
3395 Return 0 if we failed the caller should emit a normal call,
3396 otherwise try to get the result in TARGET, if convenient (and in
3397 mode MODE if that's convenient). */
3400 expand_builtin_stpcpy (tree exp
, rtx target
, enum machine_mode mode
)
3402 tree arglist
= TREE_OPERAND (exp
, 1);
3403 /* If return value is ignored, transform stpcpy into strcpy. */
3404 if (target
== const0_rtx
)
3406 tree fn
= implicit_built_in_decls
[BUILT_IN_STRCPY
];
3410 return expand_expr (build_function_call_expr (fn
, arglist
),
3411 target
, mode
, EXPAND_NORMAL
);
3414 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
3418 tree dst
, src
, len
, lenp1
;
3422 /* Ensure we get an actual string whose length can be evaluated at
3423 compile-time, not an expression containing a string. This is
3424 because the latter will potentially produce pessimized code
3425 when used to produce the return value. */
3426 src
= TREE_VALUE (TREE_CHAIN (arglist
));
3427 if (! c_getstr (src
) || ! (len
= c_strlen (src
, 0)))
3428 return expand_movstr (TREE_VALUE (arglist
),
3429 TREE_VALUE (TREE_CHAIN (arglist
)),
3430 target
, /*endp=*/2);
3432 dst
= TREE_VALUE (arglist
);
3433 lenp1
= size_binop (PLUS_EXPR
, len
, ssize_int (1));
3434 narglist
= build_tree_list (NULL_TREE
, lenp1
);
3435 narglist
= tree_cons (NULL_TREE
, src
, narglist
);
3436 narglist
= tree_cons (NULL_TREE
, dst
, narglist
);
3437 ret
= expand_builtin_mempcpy (narglist
, TREE_TYPE (exp
),
3438 target
, mode
, /*endp=*/2);
3443 if (TREE_CODE (len
) == INTEGER_CST
)
3445 rtx len_rtx
= expand_normal (len
);
3447 if (GET_CODE (len_rtx
) == CONST_INT
)
3449 ret
= expand_builtin_strcpy (get_callee_fndecl (exp
),
3450 arglist
, target
, mode
);
3456 if (mode
!= VOIDmode
)
3457 target
= gen_reg_rtx (mode
);
3459 target
= gen_reg_rtx (GET_MODE (ret
));
3461 if (GET_MODE (target
) != GET_MODE (ret
))
3462 ret
= gen_lowpart (GET_MODE (target
), ret
);
3464 ret
= plus_constant (ret
, INTVAL (len_rtx
));
3465 ret
= emit_move_insn (target
, force_operand (ret
, NULL_RTX
));
3473 return expand_movstr (TREE_VALUE (arglist
),
3474 TREE_VALUE (TREE_CHAIN (arglist
)),
3475 target
, /*endp=*/2);
3479 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
3480 bytes from constant string DATA + OFFSET and return it as target
3484 builtin_strncpy_read_str (void *data
, HOST_WIDE_INT offset
,
3485 enum machine_mode mode
)
3487 const char *str
= (const char *) data
;
3489 if ((unsigned HOST_WIDE_INT
) offset
> strlen (str
))
3492 return c_readstr (str
+ offset
, mode
);
3495 /* Expand expression EXP, which is a call to the strncpy builtin. Return 0
3496 if we failed the caller should emit a normal call. */
3499 expand_builtin_strncpy (tree exp
, rtx target
, enum machine_mode mode
)
3501 tree fndecl
= get_callee_fndecl (exp
);
3502 tree arglist
= TREE_OPERAND (exp
, 1);
3503 if (validate_arglist (arglist
,
3504 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
3506 tree slen
= c_strlen (TREE_VALUE (TREE_CHAIN (arglist
)), 1);
3507 tree len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
3508 tree result
= fold_builtin_strncpy (fndecl
, arglist
, slen
);
3512 while (TREE_CODE (result
) == COMPOUND_EXPR
)
3514 expand_expr (TREE_OPERAND (result
, 0), const0_rtx
, VOIDmode
,
3516 result
= TREE_OPERAND (result
, 1);
3518 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
3521 /* We must be passed a constant len and src parameter. */
3522 if (!host_integerp (len
, 1) || !slen
|| !host_integerp (slen
, 1))
3525 slen
= size_binop (PLUS_EXPR
, slen
, ssize_int (1));
3527 /* We're required to pad with trailing zeros if the requested
3528 len is greater than strlen(s2)+1. In that case try to
3529 use store_by_pieces, if it fails, punt. */
3530 if (tree_int_cst_lt (slen
, len
))
3532 tree dest
= TREE_VALUE (arglist
);
3533 unsigned int dest_align
3534 = get_pointer_alignment (dest
, BIGGEST_ALIGNMENT
);
3535 const char *p
= c_getstr (TREE_VALUE (TREE_CHAIN (arglist
)));
3538 if (!p
|| dest_align
== 0 || !host_integerp (len
, 1)
3539 || !can_store_by_pieces (tree_low_cst (len
, 1),
3540 builtin_strncpy_read_str
,
3541 (void *) p
, dest_align
))
3544 dest_mem
= get_memory_rtx (dest
, len
);
3545 store_by_pieces (dest_mem
, tree_low_cst (len
, 1),
3546 builtin_strncpy_read_str
,
3547 (void *) p
, dest_align
, 0);
3548 dest_mem
= force_operand (XEXP (dest_mem
, 0), NULL_RTX
);
3549 dest_mem
= convert_memory_address (ptr_mode
, dest_mem
);
3556 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
3557 bytes from constant string DATA + OFFSET and return it as target
3561 builtin_memset_read_str (void *data
, HOST_WIDE_INT offset ATTRIBUTE_UNUSED
,
3562 enum machine_mode mode
)
3564 const char *c
= (const char *) data
;
3565 char *p
= alloca (GET_MODE_SIZE (mode
));
3567 memset (p
, *c
, GET_MODE_SIZE (mode
));
3569 return c_readstr (p
, mode
);
3572 /* Callback routine for store_by_pieces. Return the RTL of a register
3573 containing GET_MODE_SIZE (MODE) consecutive copies of the unsigned
3574 char value given in the RTL register data. For example, if mode is
3575 4 bytes wide, return the RTL for 0x01010101*data. */
3578 builtin_memset_gen_str (void *data
, HOST_WIDE_INT offset ATTRIBUTE_UNUSED
,
3579 enum machine_mode mode
)
3585 size
= GET_MODE_SIZE (mode
);
3590 memset (p
, 1, size
);
3591 coeff
= c_readstr (p
, mode
);
3593 target
= convert_to_mode (mode
, (rtx
) data
, 1);
3594 target
= expand_mult (mode
, target
, coeff
, NULL_RTX
, 1);
3595 return force_reg (mode
, target
);
3598 /* Expand expression EXP, which is a call to the memset builtin. Return 0
3599 if we failed the caller should emit a normal call, otherwise try to get
3600 the result in TARGET, if convenient (and in mode MODE if that's
3604 expand_builtin_memset (tree arglist
, rtx target
, enum machine_mode mode
,
3607 if (!validate_arglist (arglist
,
3608 POINTER_TYPE
, INTEGER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
3612 tree dest
= TREE_VALUE (arglist
);
3613 tree val
= TREE_VALUE (TREE_CHAIN (arglist
));
3614 tree len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
3616 enum built_in_function fcode
;
3618 unsigned int dest_align
;
3619 rtx dest_mem
, dest_addr
, len_rtx
;
3621 dest_align
= get_pointer_alignment (dest
, BIGGEST_ALIGNMENT
);
3623 /* If DEST is not a pointer type, don't do this
3624 operation in-line. */
3625 if (dest_align
== 0)
3628 /* If the LEN parameter is zero, return DEST. */
3629 if (integer_zerop (len
))
3631 /* Evaluate and ignore VAL in case it has side-effects. */
3632 expand_expr (val
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
3633 return expand_expr (dest
, target
, mode
, EXPAND_NORMAL
);
3636 /* Stabilize the arguments in case we fail. */
3637 dest
= builtin_save_expr (dest
);
3638 val
= builtin_save_expr (val
);
3639 len
= builtin_save_expr (len
);
3641 len_rtx
= expand_normal (len
);
3642 dest_mem
= get_memory_rtx (dest
, len
);
3644 if (TREE_CODE (val
) != INTEGER_CST
)
3648 val_rtx
= expand_normal (val
);
3649 val_rtx
= convert_to_mode (TYPE_MODE (unsigned_char_type_node
),
3652 /* Assume that we can memset by pieces if we can store the
3653 * the coefficients by pieces (in the required modes).
3654 * We can't pass builtin_memset_gen_str as that emits RTL. */
3656 if (host_integerp (len
, 1)
3657 && !(optimize_size
&& tree_low_cst (len
, 1) > 1)
3658 && can_store_by_pieces (tree_low_cst (len
, 1),
3659 builtin_memset_read_str
, &c
, dest_align
))
3661 val_rtx
= force_reg (TYPE_MODE (unsigned_char_type_node
),
3663 store_by_pieces (dest_mem
, tree_low_cst (len
, 1),
3664 builtin_memset_gen_str
, val_rtx
, dest_align
, 0);
3666 else if (!set_storage_via_setmem (dest_mem
, len_rtx
, val_rtx
,
3670 dest_mem
= force_operand (XEXP (dest_mem
, 0), NULL_RTX
);
3671 dest_mem
= convert_memory_address (ptr_mode
, dest_mem
);
3675 if (target_char_cast (val
, &c
))
3680 if (host_integerp (len
, 1)
3681 && !(optimize_size
&& tree_low_cst (len
, 1) > 1)
3682 && can_store_by_pieces (tree_low_cst (len
, 1),
3683 builtin_memset_read_str
, &c
, dest_align
))
3684 store_by_pieces (dest_mem
, tree_low_cst (len
, 1),
3685 builtin_memset_read_str
, &c
, dest_align
, 0);
3686 else if (!set_storage_via_setmem (dest_mem
, len_rtx
, GEN_INT (c
),
3690 dest_mem
= force_operand (XEXP (dest_mem
, 0), NULL_RTX
);
3691 dest_mem
= convert_memory_address (ptr_mode
, dest_mem
);
3695 set_mem_align (dest_mem
, dest_align
);
3696 dest_addr
= clear_storage (dest_mem
, len_rtx
,
3697 CALL_EXPR_TAILCALL (orig_exp
)
3698 ? BLOCK_OP_TAILCALL
: BLOCK_OP_NORMAL
);
3702 dest_addr
= force_operand (XEXP (dest_mem
, 0), NULL_RTX
);
3703 dest_addr
= convert_memory_address (ptr_mode
, dest_addr
);
3709 fndecl
= get_callee_fndecl (orig_exp
);
3710 fcode
= DECL_FUNCTION_CODE (fndecl
);
3711 gcc_assert (fcode
== BUILT_IN_MEMSET
|| fcode
== BUILT_IN_BZERO
);
3712 arglist
= build_tree_list (NULL_TREE
, len
);
3713 if (fcode
== BUILT_IN_MEMSET
)
3714 arglist
= tree_cons (NULL_TREE
, val
, arglist
);
3715 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
3716 fn
= build_function_call_expr (fndecl
, arglist
);
3717 if (TREE_CODE (fn
) == CALL_EXPR
)
3718 CALL_EXPR_TAILCALL (fn
) = CALL_EXPR_TAILCALL (orig_exp
);
3719 return expand_call (fn
, target
, target
== const0_rtx
);
3723 /* Expand expression EXP, which is a call to the bzero builtin. Return 0
3724 if we failed the caller should emit a normal call. */
3727 expand_builtin_bzero (tree exp
)
3729 tree arglist
= TREE_OPERAND (exp
, 1);
3730 tree dest
, size
, newarglist
;
3732 if (!validate_arglist (arglist
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
3735 dest
= TREE_VALUE (arglist
);
3736 size
= TREE_VALUE (TREE_CHAIN (arglist
));
3738 /* New argument list transforming bzero(ptr x, int y) to
3739 memset(ptr x, int 0, size_t y). This is done this way
3740 so that if it isn't expanded inline, we fallback to
3741 calling bzero instead of memset. */
3743 newarglist
= build_tree_list (NULL_TREE
, fold_convert (sizetype
, size
));
3744 newarglist
= tree_cons (NULL_TREE
, integer_zero_node
, newarglist
);
3745 newarglist
= tree_cons (NULL_TREE
, dest
, newarglist
);
3747 return expand_builtin_memset (newarglist
, const0_rtx
, VOIDmode
, exp
);
3750 /* Expand expression EXP, which is a call to the memcmp built-in function.
3751 ARGLIST is the argument list for this call. Return 0 if we failed and the
3752 caller should emit a normal call, otherwise try to get the result in
3753 TARGET, if convenient (and in mode MODE, if that's convenient). */
3756 expand_builtin_memcmp (tree exp ATTRIBUTE_UNUSED
, tree arglist
, rtx target
,
3757 enum machine_mode mode
)
3759 if (!validate_arglist (arglist
,
3760 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
3764 tree result
= fold_builtin_memcmp (arglist
);
3766 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
3769 #if defined HAVE_cmpmemsi || defined HAVE_cmpstrnsi
3771 tree arg1
= TREE_VALUE (arglist
);
3772 tree arg2
= TREE_VALUE (TREE_CHAIN (arglist
));
3773 tree len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
3774 rtx arg1_rtx
, arg2_rtx
, arg3_rtx
;
3779 = get_pointer_alignment (arg1
, BIGGEST_ALIGNMENT
) / BITS_PER_UNIT
;
3781 = get_pointer_alignment (arg2
, BIGGEST_ALIGNMENT
) / BITS_PER_UNIT
;
3782 enum machine_mode insn_mode
;
3784 #ifdef HAVE_cmpmemsi
3786 insn_mode
= insn_data
[(int) CODE_FOR_cmpmemsi
].operand
[0].mode
;
3789 #ifdef HAVE_cmpstrnsi
3791 insn_mode
= insn_data
[(int) CODE_FOR_cmpstrnsi
].operand
[0].mode
;
3796 /* If we don't have POINTER_TYPE, call the function. */
3797 if (arg1_align
== 0 || arg2_align
== 0)
3800 /* Make a place to write the result of the instruction. */
3803 && REG_P (result
) && GET_MODE (result
) == insn_mode
3804 && REGNO (result
) >= FIRST_PSEUDO_REGISTER
))
3805 result
= gen_reg_rtx (insn_mode
);
3807 arg1_rtx
= get_memory_rtx (arg1
, len
);
3808 arg2_rtx
= get_memory_rtx (arg2
, len
);
3809 arg3_rtx
= expand_normal (len
);
3811 /* Set MEM_SIZE as appropriate. */
3812 if (GET_CODE (arg3_rtx
) == CONST_INT
)
3814 set_mem_size (arg1_rtx
, arg3_rtx
);
3815 set_mem_size (arg2_rtx
, arg3_rtx
);
3818 #ifdef HAVE_cmpmemsi
3820 insn
= gen_cmpmemsi (result
, arg1_rtx
, arg2_rtx
, arg3_rtx
,
3821 GEN_INT (MIN (arg1_align
, arg2_align
)));
3824 #ifdef HAVE_cmpstrnsi
3826 insn
= gen_cmpstrnsi (result
, arg1_rtx
, arg2_rtx
, arg3_rtx
,
3827 GEN_INT (MIN (arg1_align
, arg2_align
)));
3835 emit_library_call_value (memcmp_libfunc
, result
, LCT_PURE_MAKE_BLOCK
,
3836 TYPE_MODE (integer_type_node
), 3,
3837 XEXP (arg1_rtx
, 0), Pmode
,
3838 XEXP (arg2_rtx
, 0), Pmode
,
3839 convert_to_mode (TYPE_MODE (sizetype
), arg3_rtx
,
3840 TYPE_UNSIGNED (sizetype
)),
3841 TYPE_MODE (sizetype
));
3843 /* Return the value in the proper mode for this function. */
3844 mode
= TYPE_MODE (TREE_TYPE (exp
));
3845 if (GET_MODE (result
) == mode
)
3847 else if (target
!= 0)
3849 convert_move (target
, result
, 0);
3853 return convert_to_mode (mode
, result
, 0);
3860 /* Expand expression EXP, which is a call to the strcmp builtin. Return 0
3861 if we failed the caller should emit a normal call, otherwise try to get
3862 the result in TARGET, if convenient. */
3865 expand_builtin_strcmp (tree exp
, rtx target
, enum machine_mode mode
)
3867 tree arglist
= TREE_OPERAND (exp
, 1);
3869 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
3873 tree result
= fold_builtin_strcmp (arglist
);
3875 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
3878 #if defined HAVE_cmpstrsi || defined HAVE_cmpstrnsi
3879 if (cmpstr_optab
[SImode
] != CODE_FOR_nothing
3880 || cmpstrn_optab
[SImode
] != CODE_FOR_nothing
)
3882 rtx arg1_rtx
, arg2_rtx
;
3883 rtx result
, insn
= NULL_RTX
;
3886 tree arg1
= TREE_VALUE (arglist
);
3887 tree arg2
= TREE_VALUE (TREE_CHAIN (arglist
));
3889 = get_pointer_alignment (arg1
, BIGGEST_ALIGNMENT
) / BITS_PER_UNIT
;
3891 = get_pointer_alignment (arg2
, BIGGEST_ALIGNMENT
) / BITS_PER_UNIT
;
3893 /* If we don't have POINTER_TYPE, call the function. */
3894 if (arg1_align
== 0 || arg2_align
== 0)
3897 /* Stabilize the arguments in case gen_cmpstr(n)si fail. */
3898 arg1
= builtin_save_expr (arg1
);
3899 arg2
= builtin_save_expr (arg2
);
3901 arg1_rtx
= get_memory_rtx (arg1
, NULL
);
3902 arg2_rtx
= get_memory_rtx (arg2
, NULL
);
3904 #ifdef HAVE_cmpstrsi
3905 /* Try to call cmpstrsi. */
3908 enum machine_mode insn_mode
3909 = insn_data
[(int) CODE_FOR_cmpstrsi
].operand
[0].mode
;
3911 /* Make a place to write the result of the instruction. */
3914 && REG_P (result
) && GET_MODE (result
) == insn_mode
3915 && REGNO (result
) >= FIRST_PSEUDO_REGISTER
))
3916 result
= gen_reg_rtx (insn_mode
);
3918 insn
= gen_cmpstrsi (result
, arg1_rtx
, arg2_rtx
,
3919 GEN_INT (MIN (arg1_align
, arg2_align
)));
3922 #ifdef HAVE_cmpstrnsi
3923 /* Try to determine at least one length and call cmpstrnsi. */
3924 if (!insn
&& HAVE_cmpstrnsi
)
3929 enum machine_mode insn_mode
3930 = insn_data
[(int) CODE_FOR_cmpstrnsi
].operand
[0].mode
;
3931 tree len1
= c_strlen (arg1
, 1);
3932 tree len2
= c_strlen (arg2
, 1);
3935 len1
= size_binop (PLUS_EXPR
, ssize_int (1), len1
);
3937 len2
= size_binop (PLUS_EXPR
, ssize_int (1), len2
);
3939 /* If we don't have a constant length for the first, use the length
3940 of the second, if we know it. We don't require a constant for
3941 this case; some cost analysis could be done if both are available
3942 but neither is constant. For now, assume they're equally cheap,
3943 unless one has side effects. If both strings have constant lengths,
3950 else if (TREE_SIDE_EFFECTS (len1
))
3952 else if (TREE_SIDE_EFFECTS (len2
))
3954 else if (TREE_CODE (len1
) != INTEGER_CST
)
3956 else if (TREE_CODE (len2
) != INTEGER_CST
)
3958 else if (tree_int_cst_lt (len1
, len2
))
3963 /* If both arguments have side effects, we cannot optimize. */
3964 if (!len
|| TREE_SIDE_EFFECTS (len
))
3967 arg3_rtx
= expand_normal (len
);
3969 /* Make a place to write the result of the instruction. */
3972 && REG_P (result
) && GET_MODE (result
) == insn_mode
3973 && REGNO (result
) >= FIRST_PSEUDO_REGISTER
))
3974 result
= gen_reg_rtx (insn_mode
);
3976 insn
= gen_cmpstrnsi (result
, arg1_rtx
, arg2_rtx
, arg3_rtx
,
3977 GEN_INT (MIN (arg1_align
, arg2_align
)));
3985 /* Return the value in the proper mode for this function. */
3986 mode
= TYPE_MODE (TREE_TYPE (exp
));
3987 if (GET_MODE (result
) == mode
)
3990 return convert_to_mode (mode
, result
, 0);
3991 convert_move (target
, result
, 0);
3995 /* Expand the library call ourselves using a stabilized argument
3996 list to avoid re-evaluating the function's arguments twice. */
3997 #ifdef HAVE_cmpstrnsi
4000 arglist
= build_tree_list (NULL_TREE
, arg2
);
4001 arglist
= tree_cons (NULL_TREE
, arg1
, arglist
);
4002 fndecl
= get_callee_fndecl (exp
);
4003 fn
= build_function_call_expr (fndecl
, arglist
);
4004 if (TREE_CODE (fn
) == CALL_EXPR
)
4005 CALL_EXPR_TAILCALL (fn
) = CALL_EXPR_TAILCALL (exp
);
4006 return expand_call (fn
, target
, target
== const0_rtx
);
4012 /* Expand expression EXP, which is a call to the strncmp builtin. Return 0
4013 if we failed the caller should emit a normal call, otherwise try to get
4014 the result in TARGET, if convenient. */
4017 expand_builtin_strncmp (tree exp
, rtx target
, enum machine_mode mode
)
4019 tree arglist
= TREE_OPERAND (exp
, 1);
4021 if (!validate_arglist (arglist
,
4022 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
4026 tree result
= fold_builtin_strncmp (arglist
);
4028 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
4031 /* If c_strlen can determine an expression for one of the string
4032 lengths, and it doesn't have side effects, then emit cmpstrnsi
4033 using length MIN(strlen(string)+1, arg3). */
4034 #ifdef HAVE_cmpstrnsi
4037 tree arg1
= TREE_VALUE (arglist
);
4038 tree arg2
= TREE_VALUE (TREE_CHAIN (arglist
));
4039 tree arg3
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
4040 tree len
, len1
, len2
;
4041 rtx arg1_rtx
, arg2_rtx
, arg3_rtx
;
4046 = get_pointer_alignment (arg1
, BIGGEST_ALIGNMENT
) / BITS_PER_UNIT
;
4048 = get_pointer_alignment (arg2
, BIGGEST_ALIGNMENT
) / BITS_PER_UNIT
;
4049 enum machine_mode insn_mode
4050 = insn_data
[(int) CODE_FOR_cmpstrnsi
].operand
[0].mode
;
4052 len1
= c_strlen (arg1
, 1);
4053 len2
= c_strlen (arg2
, 1);
4056 len1
= size_binop (PLUS_EXPR
, ssize_int (1), len1
);
4058 len2
= size_binop (PLUS_EXPR
, ssize_int (1), len2
);
4060 /* If we don't have a constant length for the first, use the length
4061 of the second, if we know it. We don't require a constant for
4062 this case; some cost analysis could be done if both are available
4063 but neither is constant. For now, assume they're equally cheap,
4064 unless one has side effects. If both strings have constant lengths,
4071 else if (TREE_SIDE_EFFECTS (len1
))
4073 else if (TREE_SIDE_EFFECTS (len2
))
4075 else if (TREE_CODE (len1
) != INTEGER_CST
)
4077 else if (TREE_CODE (len2
) != INTEGER_CST
)
4079 else if (tree_int_cst_lt (len1
, len2
))
4084 /* If both arguments have side effects, we cannot optimize. */
4085 if (!len
|| TREE_SIDE_EFFECTS (len
))
4088 /* The actual new length parameter is MIN(len,arg3). */
4089 len
= fold_build2 (MIN_EXPR
, TREE_TYPE (len
), len
,
4090 fold_convert (TREE_TYPE (len
), arg3
));
4092 /* If we don't have POINTER_TYPE, call the function. */
4093 if (arg1_align
== 0 || arg2_align
== 0)
4096 /* Make a place to write the result of the instruction. */
4099 && REG_P (result
) && GET_MODE (result
) == insn_mode
4100 && REGNO (result
) >= FIRST_PSEUDO_REGISTER
))
4101 result
= gen_reg_rtx (insn_mode
);
4103 /* Stabilize the arguments in case gen_cmpstrnsi fails. */
4104 arg1
= builtin_save_expr (arg1
);
4105 arg2
= builtin_save_expr (arg2
);
4106 len
= builtin_save_expr (len
);
4108 arg1_rtx
= get_memory_rtx (arg1
, len
);
4109 arg2_rtx
= get_memory_rtx (arg2
, len
);
4110 arg3_rtx
= expand_normal (len
);
4111 insn
= gen_cmpstrnsi (result
, arg1_rtx
, arg2_rtx
, arg3_rtx
,
4112 GEN_INT (MIN (arg1_align
, arg2_align
)));
4117 /* Return the value in the proper mode for this function. */
4118 mode
= TYPE_MODE (TREE_TYPE (exp
));
4119 if (GET_MODE (result
) == mode
)
4122 return convert_to_mode (mode
, result
, 0);
4123 convert_move (target
, result
, 0);
4127 /* Expand the library call ourselves using a stabilized argument
4128 list to avoid re-evaluating the function's arguments twice. */
4129 arglist
= build_tree_list (NULL_TREE
, len
);
4130 arglist
= tree_cons (NULL_TREE
, arg2
, arglist
);
4131 arglist
= tree_cons (NULL_TREE
, arg1
, arglist
);
4132 fndecl
= get_callee_fndecl (exp
);
4133 fn
= build_function_call_expr (fndecl
, arglist
);
4134 if (TREE_CODE (fn
) == CALL_EXPR
)
4135 CALL_EXPR_TAILCALL (fn
) = CALL_EXPR_TAILCALL (exp
);
4136 return expand_call (fn
, target
, target
== const0_rtx
);
4142 /* Expand expression EXP, which is a call to the strcat builtin.
4143 Return 0 if we failed the caller should emit a normal call,
4144 otherwise try to get the result in TARGET, if convenient. */
4147 expand_builtin_strcat (tree fndecl
, tree arglist
, rtx target
, enum machine_mode mode
)
4149 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
4153 tree dst
= TREE_VALUE (arglist
),
4154 src
= TREE_VALUE (TREE_CHAIN (arglist
));
4155 const char *p
= c_getstr (src
);
4157 /* If the string length is zero, return the dst parameter. */
4158 if (p
&& *p
== '\0')
4159 return expand_expr (dst
, target
, mode
, EXPAND_NORMAL
);
4163 /* See if we can store by pieces into (dst + strlen(dst)). */
4164 tree newsrc
, newdst
,
4165 strlen_fn
= implicit_built_in_decls
[BUILT_IN_STRLEN
];
4168 /* Stabilize the argument list. */
4169 newsrc
= builtin_save_expr (src
);
4171 arglist
= build_tree_list (NULL_TREE
, newsrc
);
4173 arglist
= TREE_CHAIN (arglist
); /* Reusing arglist if safe. */
4175 dst
= builtin_save_expr (dst
);
4179 /* Create strlen (dst). */
4181 build_function_call_expr (strlen_fn
,
4182 build_tree_list (NULL_TREE
, dst
));
4183 /* Create (dst + (cast) strlen (dst)). */
4184 newdst
= fold_convert (TREE_TYPE (dst
), newdst
);
4185 newdst
= fold_build2 (PLUS_EXPR
, TREE_TYPE (dst
), dst
, newdst
);
4187 newdst
= builtin_save_expr (newdst
);
4188 arglist
= tree_cons (NULL_TREE
, newdst
, arglist
);
4190 if (!expand_builtin_strcpy (fndecl
, arglist
, target
, mode
))
4192 end_sequence (); /* Stop sequence. */
4196 /* Output the entire sequence. */
4197 insns
= get_insns ();
4201 return expand_expr (dst
, target
, mode
, EXPAND_NORMAL
);
4208 /* Expand expression EXP, which is a call to the strncat builtin.
4209 Return 0 if we failed the caller should emit a normal call,
4210 otherwise try to get the result in TARGET, if convenient. */
4213 expand_builtin_strncat (tree arglist
, rtx target
, enum machine_mode mode
)
4215 if (validate_arglist (arglist
,
4216 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
4218 tree result
= fold_builtin_strncat (arglist
);
4220 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
4225 /* Expand expression EXP, which is a call to the strspn builtin.
4226 Return 0 if we failed the caller should emit a normal call,
4227 otherwise try to get the result in TARGET, if convenient. */
4230 expand_builtin_strspn (tree arglist
, rtx target
, enum machine_mode mode
)
4232 if (validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
4234 tree result
= fold_builtin_strspn (arglist
);
4236 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
4241 /* Expand expression EXP, which is a call to the strcspn builtin.
4242 Return 0 if we failed the caller should emit a normal call,
4243 otherwise try to get the result in TARGET, if convenient. */
4246 expand_builtin_strcspn (tree arglist
, rtx target
, enum machine_mode mode
)
4248 if (validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
4250 tree result
= fold_builtin_strcspn (arglist
);
4252 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
4257 /* Expand a call to __builtin_saveregs, generating the result in TARGET,
4258 if that's convenient. */
4261 expand_builtin_saveregs (void)
4265 /* Don't do __builtin_saveregs more than once in a function.
4266 Save the result of the first call and reuse it. */
4267 if (saveregs_value
!= 0)
4268 return saveregs_value
;
4270 /* When this function is called, it means that registers must be
4271 saved on entry to this function. So we migrate the call to the
4272 first insn of this function. */
4276 /* Do whatever the machine needs done in this case. */
4277 val
= targetm
.calls
.expand_builtin_saveregs ();
4282 saveregs_value
= val
;
4284 /* Put the insns after the NOTE that starts the function. If this
4285 is inside a start_sequence, make the outer-level insn chain current, so
4286 the code is placed at the start of the function. */
4287 push_topmost_sequence ();
4288 emit_insn_after (seq
, entry_of_function ());
4289 pop_topmost_sequence ();
4294 /* __builtin_args_info (N) returns word N of the arg space info
4295 for the current function. The number and meanings of words
4296 is controlled by the definition of CUMULATIVE_ARGS. */
4299 expand_builtin_args_info (tree arglist
)
4301 int nwords
= sizeof (CUMULATIVE_ARGS
) / sizeof (int);
4302 int *word_ptr
= (int *) ¤t_function_args_info
;
4304 gcc_assert (sizeof (CUMULATIVE_ARGS
) % sizeof (int) == 0);
4308 if (!host_integerp (TREE_VALUE (arglist
), 0))
4309 error ("argument of %<__builtin_args_info%> must be constant");
4312 HOST_WIDE_INT wordnum
= tree_low_cst (TREE_VALUE (arglist
), 0);
4314 if (wordnum
< 0 || wordnum
>= nwords
)
4315 error ("argument of %<__builtin_args_info%> out of range");
4317 return GEN_INT (word_ptr
[wordnum
]);
4321 error ("missing argument in %<__builtin_args_info%>");
4326 /* Expand a call to __builtin_next_arg. */
4329 expand_builtin_next_arg (void)
4331 /* Checking arguments is already done in fold_builtin_next_arg
4332 that must be called before this function. */
4333 return expand_binop (Pmode
, add_optab
,
4334 current_function_internal_arg_pointer
,
4335 current_function_arg_offset_rtx
,
4336 NULL_RTX
, 0, OPTAB_LIB_WIDEN
);
4339 /* Make it easier for the backends by protecting the valist argument
4340 from multiple evaluations. */
4343 stabilize_va_list (tree valist
, int needs_lvalue
)
4345 if (TREE_CODE (va_list_type_node
) == ARRAY_TYPE
)
4347 if (TREE_SIDE_EFFECTS (valist
))
4348 valist
= save_expr (valist
);
4350 /* For this case, the backends will be expecting a pointer to
4351 TREE_TYPE (va_list_type_node), but it's possible we've
4352 actually been given an array (an actual va_list_type_node).
4354 if (TREE_CODE (TREE_TYPE (valist
)) == ARRAY_TYPE
)
4356 tree p1
= build_pointer_type (TREE_TYPE (va_list_type_node
));
4357 valist
= build_fold_addr_expr_with_type (valist
, p1
);
4366 if (! TREE_SIDE_EFFECTS (valist
))
4369 pt
= build_pointer_type (va_list_type_node
);
4370 valist
= fold_build1 (ADDR_EXPR
, pt
, valist
);
4371 TREE_SIDE_EFFECTS (valist
) = 1;
4374 if (TREE_SIDE_EFFECTS (valist
))
4375 valist
= save_expr (valist
);
4376 valist
= build_fold_indirect_ref (valist
);
4382 /* The "standard" definition of va_list is void*. */
4385 std_build_builtin_va_list (void)
4387 return ptr_type_node
;
4390 /* The "standard" implementation of va_start: just assign `nextarg' to
4394 std_expand_builtin_va_start (tree valist
, rtx nextarg
)
4398 t
= build2 (GIMPLE_MODIFY_STMT
, TREE_TYPE (valist
), valist
,
4399 make_tree (ptr_type_node
, nextarg
));
4400 TREE_SIDE_EFFECTS (t
) = 1;
4402 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
4405 /* Expand ARGLIST, from a call to __builtin_va_start. */
4408 expand_builtin_va_start (tree arglist
)
4413 chain
= TREE_CHAIN (arglist
);
4417 error ("too few arguments to function %<va_start%>");
4421 if (fold_builtin_next_arg (chain
))
4424 nextarg
= expand_builtin_next_arg ();
4425 valist
= stabilize_va_list (TREE_VALUE (arglist
), 1);
4427 #ifdef EXPAND_BUILTIN_VA_START
4428 EXPAND_BUILTIN_VA_START (valist
, nextarg
);
4430 std_expand_builtin_va_start (valist
, nextarg
);
4436 /* The "standard" implementation of va_arg: read the value from the
4437 current (padded) address and increment by the (padded) size. */
4440 std_gimplify_va_arg_expr (tree valist
, tree type
, tree
*pre_p
, tree
*post_p
)
4442 tree addr
, t
, type_size
, rounded_size
, valist_tmp
;
4443 unsigned HOST_WIDE_INT align
, boundary
;
4446 #ifdef ARGS_GROW_DOWNWARD
4447 /* All of the alignment and movement below is for args-grow-up machines.
4448 As of 2004, there are only 3 ARGS_GROW_DOWNWARD targets, and they all
4449 implement their own specialized gimplify_va_arg_expr routines. */
4453 indirect
= pass_by_reference (NULL
, TYPE_MODE (type
), type
, false);
4455 type
= build_pointer_type (type
);
4457 align
= PARM_BOUNDARY
/ BITS_PER_UNIT
;
4458 boundary
= FUNCTION_ARG_BOUNDARY (TYPE_MODE (type
), type
) / BITS_PER_UNIT
;
4460 /* Hoist the valist value into a temporary for the moment. */
4461 valist_tmp
= get_initialized_tmp_var (valist
, pre_p
, NULL
);
4463 /* va_list pointer is aligned to PARM_BOUNDARY. If argument actually
4464 requires greater alignment, we must perform dynamic alignment. */
4465 if (boundary
> align
4466 && !integer_zerop (TYPE_SIZE (type
)))
4468 t
= fold_convert (TREE_TYPE (valist
), size_int (boundary
- 1));
4469 t
= build2 (GIMPLE_MODIFY_STMT
, TREE_TYPE (valist
), valist_tmp
,
4470 build2 (PLUS_EXPR
, TREE_TYPE (valist
), valist_tmp
, t
));
4471 gimplify_and_add (t
, pre_p
);
4473 t
= fold_convert (TREE_TYPE (valist
), size_int (-boundary
));
4474 t
= build2 (GIMPLE_MODIFY_STMT
, TREE_TYPE (valist
), valist_tmp
,
4475 build2 (BIT_AND_EXPR
, TREE_TYPE (valist
), valist_tmp
, t
));
4476 gimplify_and_add (t
, pre_p
);
4481 /* If the actual alignment is less than the alignment of the type,
4482 adjust the type accordingly so that we don't assume strict alignment
4483 when deferencing the pointer. */
4484 boundary
*= BITS_PER_UNIT
;
4485 if (boundary
< TYPE_ALIGN (type
))
4487 type
= build_variant_type_copy (type
);
4488 TYPE_ALIGN (type
) = boundary
;
4491 /* Compute the rounded size of the type. */
4492 type_size
= size_in_bytes (type
);
4493 rounded_size
= round_up (type_size
, align
);
4495 /* Reduce rounded_size so it's sharable with the postqueue. */
4496 gimplify_expr (&rounded_size
, pre_p
, post_p
, is_gimple_val
, fb_rvalue
);
4500 if (PAD_VARARGS_DOWN
&& !integer_zerop (rounded_size
))
4502 /* Small args are padded downward. */
4503 t
= fold_build2 (GT_EXPR
, sizetype
, rounded_size
, size_int (align
));
4504 t
= fold_build3 (COND_EXPR
, sizetype
, t
, size_zero_node
,
4505 size_binop (MINUS_EXPR
, rounded_size
, type_size
));
4506 t
= fold_convert (TREE_TYPE (addr
), t
);
4507 addr
= fold_build2 (PLUS_EXPR
, TREE_TYPE (addr
), addr
, t
);
4510 /* Compute new value for AP. */
4511 t
= fold_convert (TREE_TYPE (valist
), rounded_size
);
4512 t
= build2 (PLUS_EXPR
, TREE_TYPE (valist
), valist_tmp
, t
);
4513 t
= build2 (GIMPLE_MODIFY_STMT
, TREE_TYPE (valist
), valist
, t
);
4514 gimplify_and_add (t
, pre_p
);
4516 addr
= fold_convert (build_pointer_type (type
), addr
);
4519 addr
= build_va_arg_indirect_ref (addr
);
4521 return build_va_arg_indirect_ref (addr
);
4524 /* Build an indirect-ref expression over the given TREE, which represents a
4525 piece of a va_arg() expansion. */
4527 build_va_arg_indirect_ref (tree addr
)
4529 addr
= build_fold_indirect_ref (addr
);
4531 if (flag_mudflap
) /* Don't instrument va_arg INDIRECT_REF. */
4537 /* Return a dummy expression of type TYPE in order to keep going after an
4541 dummy_object (tree type
)
4543 tree t
= build_int_cst (build_pointer_type (type
), 0);
4544 return build1 (INDIRECT_REF
, type
, t
);
4547 /* Gimplify __builtin_va_arg, aka VA_ARG_EXPR, which is not really a
4548 builtin function, but a very special sort of operator. */
4550 enum gimplify_status
4551 gimplify_va_arg_expr (tree
*expr_p
, tree
*pre_p
, tree
*post_p
)
4553 tree promoted_type
, want_va_type
, have_va_type
;
4554 tree valist
= TREE_OPERAND (*expr_p
, 0);
4555 tree type
= TREE_TYPE (*expr_p
);
4558 /* Verify that valist is of the proper type. */
4559 want_va_type
= va_list_type_node
;
4560 have_va_type
= TREE_TYPE (valist
);
4562 if (have_va_type
== error_mark_node
)
4565 if (TREE_CODE (want_va_type
) == ARRAY_TYPE
)
4567 /* If va_list is an array type, the argument may have decayed
4568 to a pointer type, e.g. by being passed to another function.
4569 In that case, unwrap both types so that we can compare the
4570 underlying records. */
4571 if (TREE_CODE (have_va_type
) == ARRAY_TYPE
4572 || POINTER_TYPE_P (have_va_type
))
4574 want_va_type
= TREE_TYPE (want_va_type
);
4575 have_va_type
= TREE_TYPE (have_va_type
);
4579 if (TYPE_MAIN_VARIANT (want_va_type
) != TYPE_MAIN_VARIANT (have_va_type
))
4581 error ("first argument to %<va_arg%> not of type %<va_list%>");
4585 /* Generate a diagnostic for requesting data of a type that cannot
4586 be passed through `...' due to type promotion at the call site. */
4587 else if ((promoted_type
= lang_hooks
.types
.type_promotes_to (type
))
4590 static bool gave_help
;
4592 /* Unfortunately, this is merely undefined, rather than a constraint
4593 violation, so we cannot make this an error. If this call is never
4594 executed, the program is still strictly conforming. */
4595 warning (0, "%qT is promoted to %qT when passed through %<...%>",
4596 type
, promoted_type
);
4600 warning (0, "(so you should pass %qT not %qT to %<va_arg%>)",
4601 promoted_type
, type
);
4604 /* We can, however, treat "undefined" any way we please.
4605 Call abort to encourage the user to fix the program. */
4606 inform ("if this code is reached, the program will abort");
4607 t
= build_function_call_expr (implicit_built_in_decls
[BUILT_IN_TRAP
],
4609 append_to_statement_list (t
, pre_p
);
4611 /* This is dead code, but go ahead and finish so that the
4612 mode of the result comes out right. */
4613 *expr_p
= dummy_object (type
);
4618 /* Make it easier for the backends by protecting the valist argument
4619 from multiple evaluations. */
4620 if (TREE_CODE (va_list_type_node
) == ARRAY_TYPE
)
4622 /* For this case, the backends will be expecting a pointer to
4623 TREE_TYPE (va_list_type_node), but it's possible we've
4624 actually been given an array (an actual va_list_type_node).
4626 if (TREE_CODE (TREE_TYPE (valist
)) == ARRAY_TYPE
)
4628 tree p1
= build_pointer_type (TREE_TYPE (va_list_type_node
));
4629 valist
= build_fold_addr_expr_with_type (valist
, p1
);
4631 gimplify_expr (&valist
, pre_p
, post_p
, is_gimple_val
, fb_rvalue
);
4634 gimplify_expr (&valist
, pre_p
, post_p
, is_gimple_min_lval
, fb_lvalue
);
4636 if (!targetm
.gimplify_va_arg_expr
)
4637 /* FIXME:Once most targets are converted we should merely
4638 assert this is non-null. */
4641 *expr_p
= targetm
.gimplify_va_arg_expr (valist
, type
, pre_p
, post_p
);
4646 /* Expand ARGLIST, from a call to __builtin_va_end. */
4649 expand_builtin_va_end (tree arglist
)
4651 tree valist
= TREE_VALUE (arglist
);
4653 /* Evaluate for side effects, if needed. I hate macros that don't
4655 if (TREE_SIDE_EFFECTS (valist
))
4656 expand_expr (valist
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
4661 /* Expand ARGLIST, from a call to __builtin_va_copy. We do this as a
4662 builtin rather than just as an assignment in stdarg.h because of the
4663 nastiness of array-type va_list types. */
4666 expand_builtin_va_copy (tree arglist
)
4670 dst
= TREE_VALUE (arglist
);
4671 src
= TREE_VALUE (TREE_CHAIN (arglist
));
4673 dst
= stabilize_va_list (dst
, 1);
4674 src
= stabilize_va_list (src
, 0);
4676 if (TREE_CODE (va_list_type_node
) != ARRAY_TYPE
)
4678 t
= build2 (GIMPLE_MODIFY_STMT
, va_list_type_node
, dst
, src
);
4679 TREE_SIDE_EFFECTS (t
) = 1;
4680 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
4684 rtx dstb
, srcb
, size
;
4686 /* Evaluate to pointers. */
4687 dstb
= expand_expr (dst
, NULL_RTX
, Pmode
, EXPAND_NORMAL
);
4688 srcb
= expand_expr (src
, NULL_RTX
, Pmode
, EXPAND_NORMAL
);
4689 size
= expand_expr (TYPE_SIZE_UNIT (va_list_type_node
), NULL_RTX
,
4690 VOIDmode
, EXPAND_NORMAL
);
4692 dstb
= convert_memory_address (Pmode
, dstb
);
4693 srcb
= convert_memory_address (Pmode
, srcb
);
4695 /* "Dereference" to BLKmode memories. */
4696 dstb
= gen_rtx_MEM (BLKmode
, dstb
);
4697 set_mem_alias_set (dstb
, get_alias_set (TREE_TYPE (TREE_TYPE (dst
))));
4698 set_mem_align (dstb
, TYPE_ALIGN (va_list_type_node
));
4699 srcb
= gen_rtx_MEM (BLKmode
, srcb
);
4700 set_mem_alias_set (srcb
, get_alias_set (TREE_TYPE (TREE_TYPE (src
))));
4701 set_mem_align (srcb
, TYPE_ALIGN (va_list_type_node
));
4704 emit_block_move (dstb
, srcb
, size
, BLOCK_OP_NORMAL
);
4710 /* Expand a call to one of the builtin functions __builtin_frame_address or
4711 __builtin_return_address. */
4714 expand_builtin_frame_address (tree fndecl
, tree arglist
)
4716 /* The argument must be a nonnegative integer constant.
4717 It counts the number of frames to scan up the stack.
4718 The value is the return address saved in that frame. */
4720 /* Warning about missing arg was already issued. */
4722 else if (! host_integerp (TREE_VALUE (arglist
), 1))
4724 if (DECL_FUNCTION_CODE (fndecl
) == BUILT_IN_FRAME_ADDRESS
)
4725 error ("invalid argument to %<__builtin_frame_address%>");
4727 error ("invalid argument to %<__builtin_return_address%>");
4733 = expand_builtin_return_addr (DECL_FUNCTION_CODE (fndecl
),
4734 tree_low_cst (TREE_VALUE (arglist
), 1));
4736 /* Some ports cannot access arbitrary stack frames. */
4739 if (DECL_FUNCTION_CODE (fndecl
) == BUILT_IN_FRAME_ADDRESS
)
4740 warning (0, "unsupported argument to %<__builtin_frame_address%>");
4742 warning (0, "unsupported argument to %<__builtin_return_address%>");
4746 /* For __builtin_frame_address, return what we've got. */
4747 if (DECL_FUNCTION_CODE (fndecl
) == BUILT_IN_FRAME_ADDRESS
)
4751 && ! CONSTANT_P (tem
))
4752 tem
= copy_to_mode_reg (Pmode
, tem
);
4757 /* Expand a call to the alloca builtin, with arguments ARGLIST. Return 0 if
4758 we failed and the caller should emit a normal call, otherwise try to get
4759 the result in TARGET, if convenient. */
4762 expand_builtin_alloca (tree arglist
, rtx target
)
4767 /* In -fmudflap-instrumented code, alloca() and __builtin_alloca()
4768 should always expand to function calls. These can be intercepted
4773 if (!validate_arglist (arglist
, INTEGER_TYPE
, VOID_TYPE
))
4776 /* Compute the argument. */
4777 op0
= expand_normal (TREE_VALUE (arglist
));
4779 /* Allocate the desired space. */
4780 result
= allocate_dynamic_stack_space (op0
, target
, BITS_PER_UNIT
);
4781 result
= convert_memory_address (ptr_mode
, result
);
4786 /* Expand a call to a bswap builtin. The arguments are in ARGLIST. MODE
4787 is the mode to expand with. */
4790 expand_builtin_bswap (tree arglist
, rtx target
, rtx subtarget
)
4792 enum machine_mode mode
;
4796 if (!validate_arglist (arglist
, INTEGER_TYPE
, VOID_TYPE
))
4799 arg
= TREE_VALUE (arglist
);
4800 mode
= TYPE_MODE (TREE_TYPE (arg
));
4801 op0
= expand_expr (arg
, subtarget
, VOIDmode
, 0);
4803 target
= expand_unop (mode
, bswap_optab
, op0
, target
, 1);
4805 gcc_assert (target
);
4807 return convert_to_mode (mode
, target
, 0);
4810 /* Expand a call to a unary builtin. The arguments are in ARGLIST.
4811 Return 0 if a normal call should be emitted rather than expanding the
4812 function in-line. If convenient, the result should be placed in TARGET.
4813 SUBTARGET may be used as the target for computing one of EXP's operands. */
4816 expand_builtin_unop (enum machine_mode target_mode
, tree arglist
, rtx target
,
4817 rtx subtarget
, optab op_optab
)
4820 if (!validate_arglist (arglist
, INTEGER_TYPE
, VOID_TYPE
))
4823 /* Compute the argument. */
4824 op0
= expand_expr (TREE_VALUE (arglist
), subtarget
, VOIDmode
, 0);
4825 /* Compute op, into TARGET if possible.
4826 Set TARGET to wherever the result comes back. */
4827 target
= expand_unop (TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist
))),
4828 op_optab
, op0
, target
, 1);
4829 gcc_assert (target
);
4831 return convert_to_mode (target_mode
, target
, 0);
4834 /* If the string passed to fputs is a constant and is one character
4835 long, we attempt to transform this call into __builtin_fputc(). */
4838 expand_builtin_fputs (tree arglist
, rtx target
, bool unlocked
)
4840 /* Verify the arguments in the original call. */
4841 if (validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
4843 tree result
= fold_builtin_fputs (arglist
, (target
== const0_rtx
),
4844 unlocked
, NULL_TREE
);
4846 return expand_expr (result
, target
, VOIDmode
, EXPAND_NORMAL
);
4851 /* Expand a call to __builtin_expect. We just return our argument
4852 as the builtin_expect semantic should've been already executed by
4853 tree branch prediction pass. */
4856 expand_builtin_expect (tree arglist
, rtx target
)
4860 if (arglist
== NULL_TREE
4861 || TREE_CHAIN (arglist
) == NULL_TREE
)
4863 exp
= TREE_VALUE (arglist
);
4864 c
= TREE_VALUE (TREE_CHAIN (arglist
));
4866 target
= expand_expr (exp
, target
, VOIDmode
, EXPAND_NORMAL
);
4867 /* When guessing was done, the hints should be already stripped away. */
4868 gcc_assert (!flag_guess_branch_prob
);
4873 expand_builtin_trap (void)
4877 emit_insn (gen_trap ());
4880 emit_library_call (abort_libfunc
, LCT_NORETURN
, VOIDmode
, 0);
4884 /* Expand a call to fabs, fabsf or fabsl with arguments ARGLIST.
4885 Return 0 if a normal call should be emitted rather than expanding
4886 the function inline. If convenient, the result should be placed
4887 in TARGET. SUBTARGET may be used as the target for computing
4891 expand_builtin_fabs (tree arglist
, rtx target
, rtx subtarget
)
4893 enum machine_mode mode
;
4897 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
4900 arg
= TREE_VALUE (arglist
);
4901 mode
= TYPE_MODE (TREE_TYPE (arg
));
4902 op0
= expand_expr (arg
, subtarget
, VOIDmode
, 0);
4903 return expand_abs (mode
, op0
, target
, 0, safe_from_p (target
, arg
, 1));
4906 /* Expand a call to copysign, copysignf, or copysignl with arguments ARGLIST.
4907 Return NULL is a normal call should be emitted rather than expanding the
4908 function inline. If convenient, the result should be placed in TARGET.
4909 SUBTARGET may be used as the target for computing the operand. */
4912 expand_builtin_copysign (tree arglist
, rtx target
, rtx subtarget
)
4917 if (!validate_arglist (arglist
, REAL_TYPE
, REAL_TYPE
, VOID_TYPE
))
4920 arg
= TREE_VALUE (arglist
);
4921 op0
= expand_expr (arg
, subtarget
, VOIDmode
, EXPAND_NORMAL
);
4923 arg
= TREE_VALUE (TREE_CHAIN (arglist
));
4924 op1
= expand_normal (arg
);
4926 return expand_copysign (op0
, op1
, target
);
4929 /* Create a new constant string literal and return a char* pointer to it.
4930 The STRING_CST value is the LEN characters at STR. */
4932 build_string_literal (int len
, const char *str
)
4934 tree t
, elem
, index
, type
;
4936 t
= build_string (len
, str
);
4937 elem
= build_type_variant (char_type_node
, 1, 0);
4938 index
= build_index_type (build_int_cst (NULL_TREE
, len
- 1));
4939 type
= build_array_type (elem
, index
);
4940 TREE_TYPE (t
) = type
;
4941 TREE_CONSTANT (t
) = 1;
4942 TREE_INVARIANT (t
) = 1;
4943 TREE_READONLY (t
) = 1;
4944 TREE_STATIC (t
) = 1;
4946 type
= build_pointer_type (type
);
4947 t
= build1 (ADDR_EXPR
, type
, t
);
4949 type
= build_pointer_type (elem
);
4950 t
= build1 (NOP_EXPR
, type
, t
);
4954 /* Expand EXP, a call to printf or printf_unlocked.
4955 Return 0 if a normal call should be emitted rather than transforming
4956 the function inline. If convenient, the result should be placed in
4957 TARGET with mode MODE. UNLOCKED indicates this is a printf_unlocked
4960 expand_builtin_printf (tree exp
, rtx target
, enum machine_mode mode
,
4963 tree arglist
= TREE_OPERAND (exp
, 1);
4964 /* If we're using an unlocked function, assume the other unlocked
4965 functions exist explicitly. */
4966 tree
const fn_putchar
= unlocked
? built_in_decls
[BUILT_IN_PUTCHAR_UNLOCKED
]
4967 : implicit_built_in_decls
[BUILT_IN_PUTCHAR
];
4968 tree
const fn_puts
= unlocked
? built_in_decls
[BUILT_IN_PUTS_UNLOCKED
]
4969 : implicit_built_in_decls
[BUILT_IN_PUTS
];
4970 const char *fmt_str
;
4973 /* If the return value is used, don't do the transformation. */
4974 if (target
!= const0_rtx
)
4977 /* Verify the required arguments in the original call. */
4980 fmt
= TREE_VALUE (arglist
);
4981 if (! POINTER_TYPE_P (TREE_TYPE (fmt
)))
4983 arglist
= TREE_CHAIN (arglist
);
4985 /* Check whether the format is a literal string constant. */
4986 fmt_str
= c_getstr (fmt
);
4987 if (fmt_str
== NULL
)
4990 if (!init_target_chars())
4993 /* If the format specifier was "%s\n", call __builtin_puts(arg). */
4994 if (strcmp (fmt_str
, target_percent_s_newline
) == 0)
4997 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist
)))
4998 || TREE_CHAIN (arglist
))
5002 /* If the format specifier was "%c", call __builtin_putchar(arg). */
5003 else if (strcmp (fmt_str
, target_percent_c
) == 0)
5006 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist
))) != INTEGER_TYPE
5007 || TREE_CHAIN (arglist
))
5013 /* We can't handle anything else with % args or %% ... yet. */
5014 if (strchr (fmt_str
, target_percent
))
5020 /* If the format specifier was "", printf does nothing. */
5021 if (fmt_str
[0] == '\0')
5023 /* If the format specifier has length of 1, call putchar. */
5024 if (fmt_str
[1] == '\0')
5026 /* Given printf("c"), (where c is any one character,)
5027 convert "c"[0] to an int and pass that to the replacement
5029 arg
= build_int_cst (NULL_TREE
, fmt_str
[0]);
5030 arglist
= build_tree_list (NULL_TREE
, arg
);
5035 /* If the format specifier was "string\n", call puts("string"). */
5036 size_t len
= strlen (fmt_str
);
5037 if ((unsigned char)fmt_str
[len
- 1] == target_newline
)
5039 /* Create a NUL-terminated string that's one char shorter
5040 than the original, stripping off the trailing '\n'. */
5041 char *newstr
= alloca (len
);
5042 memcpy (newstr
, fmt_str
, len
- 1);
5043 newstr
[len
- 1] = 0;
5045 arg
= build_string_literal (len
, newstr
);
5046 arglist
= build_tree_list (NULL_TREE
, arg
);
5050 /* We'd like to arrange to call fputs(string,stdout) here,
5051 but we need stdout and don't have a way to get it yet. */
5058 fn
= build_function_call_expr (fn
, arglist
);
5059 if (TREE_CODE (fn
) == CALL_EXPR
)
5060 CALL_EXPR_TAILCALL (fn
) = CALL_EXPR_TAILCALL (exp
);
5061 return expand_expr (fn
, target
, mode
, EXPAND_NORMAL
);
5064 /* Expand EXP, a call to fprintf or fprintf_unlocked.
5065 Return 0 if a normal call should be emitted rather than transforming
5066 the function inline. If convenient, the result should be placed in
5067 TARGET with mode MODE. UNLOCKED indicates this is a fprintf_unlocked
5070 expand_builtin_fprintf (tree exp
, rtx target
, enum machine_mode mode
,
5073 tree arglist
= TREE_OPERAND (exp
, 1);
5074 /* If we're using an unlocked function, assume the other unlocked
5075 functions exist explicitly. */
5076 tree
const fn_fputc
= unlocked
? built_in_decls
[BUILT_IN_FPUTC_UNLOCKED
]
5077 : implicit_built_in_decls
[BUILT_IN_FPUTC
];
5078 tree
const fn_fputs
= unlocked
? built_in_decls
[BUILT_IN_FPUTS_UNLOCKED
]
5079 : implicit_built_in_decls
[BUILT_IN_FPUTS
];
5080 const char *fmt_str
;
5081 tree fn
, fmt
, fp
, arg
;
5083 /* If the return value is used, don't do the transformation. */
5084 if (target
!= const0_rtx
)
5087 /* Verify the required arguments in the original call. */
5090 fp
= TREE_VALUE (arglist
);
5091 if (! POINTER_TYPE_P (TREE_TYPE (fp
)))
5093 arglist
= TREE_CHAIN (arglist
);
5096 fmt
= TREE_VALUE (arglist
);
5097 if (! POINTER_TYPE_P (TREE_TYPE (fmt
)))
5099 arglist
= TREE_CHAIN (arglist
);
5101 /* Check whether the format is a literal string constant. */
5102 fmt_str
= c_getstr (fmt
);
5103 if (fmt_str
== NULL
)
5106 if (!init_target_chars())
5109 /* If the format specifier was "%s", call __builtin_fputs(arg,fp). */
5110 if (strcmp (fmt_str
, target_percent_s
) == 0)
5113 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist
)))
5114 || TREE_CHAIN (arglist
))
5116 arg
= TREE_VALUE (arglist
);
5117 arglist
= build_tree_list (NULL_TREE
, fp
);
5118 arglist
= tree_cons (NULL_TREE
, arg
, arglist
);
5121 /* If the format specifier was "%c", call __builtin_fputc(arg,fp). */
5122 else if (strcmp (fmt_str
, target_percent_c
) == 0)
5125 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist
))) != INTEGER_TYPE
5126 || TREE_CHAIN (arglist
))
5128 arg
= TREE_VALUE (arglist
);
5129 arglist
= build_tree_list (NULL_TREE
, fp
);
5130 arglist
= tree_cons (NULL_TREE
, arg
, arglist
);
5135 /* We can't handle anything else with % args or %% ... yet. */
5136 if (strchr (fmt_str
, target_percent
))
5142 /* If the format specifier was "", fprintf does nothing. */
5143 if (fmt_str
[0] == '\0')
5145 /* Evaluate and ignore FILE* argument for side-effects. */
5146 expand_expr (fp
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
5150 /* When "string" doesn't contain %, replace all cases of
5151 fprintf(stream,string) with fputs(string,stream). The fputs
5152 builtin will take care of special cases like length == 1. */
5153 arglist
= build_tree_list (NULL_TREE
, fp
);
5154 arglist
= tree_cons (NULL_TREE
, fmt
, arglist
);
5160 fn
= build_function_call_expr (fn
, arglist
);
5161 if (TREE_CODE (fn
) == CALL_EXPR
)
5162 CALL_EXPR_TAILCALL (fn
) = CALL_EXPR_TAILCALL (exp
);
5163 return expand_expr (fn
, target
, mode
, EXPAND_NORMAL
);
5166 /* Expand a call to sprintf with argument list ARGLIST. Return 0 if
5167 a normal call should be emitted rather than expanding the function
5168 inline. If convenient, the result should be placed in TARGET with
5172 expand_builtin_sprintf (tree arglist
, rtx target
, enum machine_mode mode
)
5174 tree orig_arglist
, dest
, fmt
;
5175 const char *fmt_str
;
5177 orig_arglist
= arglist
;
5179 /* Verify the required arguments in the original call. */
5182 dest
= TREE_VALUE (arglist
);
5183 if (! POINTER_TYPE_P (TREE_TYPE (dest
)))
5185 arglist
= TREE_CHAIN (arglist
);
5188 fmt
= TREE_VALUE (arglist
);
5189 if (! POINTER_TYPE_P (TREE_TYPE (fmt
)))
5191 arglist
= TREE_CHAIN (arglist
);
5193 /* Check whether the format is a literal string constant. */
5194 fmt_str
= c_getstr (fmt
);
5195 if (fmt_str
== NULL
)
5198 if (!init_target_chars())
5201 /* If the format doesn't contain % args or %%, use strcpy. */
5202 if (strchr (fmt_str
, target_percent
) == 0)
5204 tree fn
= implicit_built_in_decls
[BUILT_IN_STRCPY
];
5207 if (arglist
|| ! fn
)
5209 expand_expr (build_function_call_expr (fn
, orig_arglist
),
5210 const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
5211 if (target
== const0_rtx
)
5213 exp
= build_int_cst (NULL_TREE
, strlen (fmt_str
));
5214 return expand_expr (exp
, target
, mode
, EXPAND_NORMAL
);
5216 /* If the format is "%s", use strcpy if the result isn't used. */
5217 else if (strcmp (fmt_str
, target_percent_s
) == 0)
5220 fn
= implicit_built_in_decls
[BUILT_IN_STRCPY
];
5225 if (! arglist
|| TREE_CHAIN (arglist
))
5227 arg
= TREE_VALUE (arglist
);
5228 if (! POINTER_TYPE_P (TREE_TYPE (arg
)))
5231 if (target
!= const0_rtx
)
5233 len
= c_strlen (arg
, 1);
5234 if (! len
|| TREE_CODE (len
) != INTEGER_CST
)
5240 arglist
= build_tree_list (NULL_TREE
, arg
);
5241 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
5242 expand_expr (build_function_call_expr (fn
, arglist
),
5243 const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
5245 if (target
== const0_rtx
)
5247 return expand_expr (len
, target
, mode
, EXPAND_NORMAL
);
5253 /* Expand a call to either the entry or exit function profiler. */
5256 expand_builtin_profile_func (bool exitp
)
5260 this = DECL_RTL (current_function_decl
);
5261 gcc_assert (MEM_P (this));
5262 this = XEXP (this, 0);
5265 which
= profile_function_exit_libfunc
;
5267 which
= profile_function_entry_libfunc
;
5269 emit_library_call (which
, LCT_NORMAL
, VOIDmode
, 2, this, Pmode
,
5270 expand_builtin_return_addr (BUILT_IN_RETURN_ADDRESS
,
5277 /* Given a trampoline address, make sure it satisfies TRAMPOLINE_ALIGNMENT. */
5280 round_trampoline_addr (rtx tramp
)
5282 rtx temp
, addend
, mask
;
5284 /* If we don't need too much alignment, we'll have been guaranteed
5285 proper alignment by get_trampoline_type. */
5286 if (TRAMPOLINE_ALIGNMENT
<= STACK_BOUNDARY
)
5289 /* Round address up to desired boundary. */
5290 temp
= gen_reg_rtx (Pmode
);
5291 addend
= GEN_INT (TRAMPOLINE_ALIGNMENT
/ BITS_PER_UNIT
- 1);
5292 mask
= GEN_INT (-TRAMPOLINE_ALIGNMENT
/ BITS_PER_UNIT
);
5294 temp
= expand_simple_binop (Pmode
, PLUS
, tramp
, addend
,
5295 temp
, 0, OPTAB_LIB_WIDEN
);
5296 tramp
= expand_simple_binop (Pmode
, AND
, temp
, mask
,
5297 temp
, 0, OPTAB_LIB_WIDEN
);
5303 expand_builtin_init_trampoline (tree arglist
)
5305 tree t_tramp
, t_func
, t_chain
;
5306 rtx r_tramp
, r_func
, r_chain
;
5307 #ifdef TRAMPOLINE_TEMPLATE
5311 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
,
5312 POINTER_TYPE
, VOID_TYPE
))
5315 t_tramp
= TREE_VALUE (arglist
);
5316 arglist
= TREE_CHAIN (arglist
);
5317 t_func
= TREE_VALUE (arglist
);
5318 arglist
= TREE_CHAIN (arglist
);
5319 t_chain
= TREE_VALUE (arglist
);
5321 r_tramp
= expand_normal (t_tramp
);
5322 r_func
= expand_normal (t_func
);
5323 r_chain
= expand_normal (t_chain
);
5325 /* Generate insns to initialize the trampoline. */
5326 r_tramp
= round_trampoline_addr (r_tramp
);
5327 #ifdef TRAMPOLINE_TEMPLATE
5328 blktramp
= gen_rtx_MEM (BLKmode
, r_tramp
);
5329 set_mem_align (blktramp
, TRAMPOLINE_ALIGNMENT
);
5330 emit_block_move (blktramp
, assemble_trampoline_template (),
5331 GEN_INT (TRAMPOLINE_SIZE
), BLOCK_OP_NORMAL
);
5333 trampolines_created
= 1;
5334 INITIALIZE_TRAMPOLINE (r_tramp
, r_func
, r_chain
);
5340 expand_builtin_adjust_trampoline (tree arglist
)
5344 if (!validate_arglist (arglist
, POINTER_TYPE
, VOID_TYPE
))
5347 tramp
= expand_normal (TREE_VALUE (arglist
));
5348 tramp
= round_trampoline_addr (tramp
);
5349 #ifdef TRAMPOLINE_ADJUST_ADDRESS
5350 TRAMPOLINE_ADJUST_ADDRESS (tramp
);
5356 /* Expand a call to the built-in signbit, signbitf or signbitl function.
5357 Return NULL_RTX if a normal call should be emitted rather than expanding
5358 the function in-line. EXP is the expression that is a call to the builtin
5359 function; if convenient, the result should be placed in TARGET. */
5362 expand_builtin_signbit (tree exp
, rtx target
)
5364 const struct real_format
*fmt
;
5365 enum machine_mode fmode
, imode
, rmode
;
5366 HOST_WIDE_INT hi
, lo
;
5371 arglist
= TREE_OPERAND (exp
, 1);
5372 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
5375 arg
= TREE_VALUE (arglist
);
5376 fmode
= TYPE_MODE (TREE_TYPE (arg
));
5377 rmode
= TYPE_MODE (TREE_TYPE (exp
));
5378 fmt
= REAL_MODE_FORMAT (fmode
);
5380 /* For floating point formats without a sign bit, implement signbit
5382 bitpos
= fmt
->signbit_ro
;
5385 /* But we can't do this if the format supports signed zero. */
5386 if (fmt
->has_signed_zero
&& HONOR_SIGNED_ZEROS (fmode
))
5389 arg
= fold_build2 (LT_EXPR
, TREE_TYPE (exp
), arg
,
5390 build_real (TREE_TYPE (arg
), dconst0
));
5391 return expand_expr (arg
, target
, VOIDmode
, EXPAND_NORMAL
);
5394 temp
= expand_normal (arg
);
5395 if (GET_MODE_SIZE (fmode
) <= UNITS_PER_WORD
)
5397 imode
= int_mode_for_mode (fmode
);
5398 if (imode
== BLKmode
)
5400 temp
= gen_lowpart (imode
, temp
);
5405 /* Handle targets with different FP word orders. */
5406 if (FLOAT_WORDS_BIG_ENDIAN
)
5407 word
= (GET_MODE_BITSIZE (fmode
) - bitpos
) / BITS_PER_WORD
;
5409 word
= bitpos
/ BITS_PER_WORD
;
5410 temp
= operand_subword_force (temp
, word
, fmode
);
5411 bitpos
= bitpos
% BITS_PER_WORD
;
5414 /* Force the intermediate word_mode (or narrower) result into a
5415 register. This avoids attempting to create paradoxical SUBREGs
5416 of floating point modes below. */
5417 temp
= force_reg (imode
, temp
);
5419 /* If the bitpos is within the "result mode" lowpart, the operation
5420 can be implement with a single bitwise AND. Otherwise, we need
5421 a right shift and an AND. */
5423 if (bitpos
< GET_MODE_BITSIZE (rmode
))
5425 if (bitpos
< HOST_BITS_PER_WIDE_INT
)
5428 lo
= (HOST_WIDE_INT
) 1 << bitpos
;
5432 hi
= (HOST_WIDE_INT
) 1 << (bitpos
- HOST_BITS_PER_WIDE_INT
);
5437 temp
= gen_lowpart (rmode
, temp
);
5438 temp
= expand_binop (rmode
, and_optab
, temp
,
5439 immed_double_const (lo
, hi
, rmode
),
5440 NULL_RTX
, 1, OPTAB_LIB_WIDEN
);
5444 /* Perform a logical right shift to place the signbit in the least
5445 significant bit, then truncate the result to the desired mode
5446 and mask just this bit. */
5447 temp
= expand_shift (RSHIFT_EXPR
, imode
, temp
,
5448 build_int_cst (NULL_TREE
, bitpos
), NULL_RTX
, 1);
5449 temp
= gen_lowpart (rmode
, temp
);
5450 temp
= expand_binop (rmode
, and_optab
, temp
, const1_rtx
,
5451 NULL_RTX
, 1, OPTAB_LIB_WIDEN
);
5457 /* Expand fork or exec calls. TARGET is the desired target of the
5458 call. ARGLIST is the list of arguments of the call. FN is the
5459 identificator of the actual function. IGNORE is nonzero if the
5460 value is to be ignored. */
5463 expand_builtin_fork_or_exec (tree fn
, tree arglist
, rtx target
, int ignore
)
5468 /* If we are not profiling, just call the function. */
5469 if (!profile_arc_flag
)
5472 /* Otherwise call the wrapper. This should be equivalent for the rest of
5473 compiler, so the code does not diverge, and the wrapper may run the
5474 code necessary for keeping the profiling sane. */
5476 switch (DECL_FUNCTION_CODE (fn
))
5479 id
= get_identifier ("__gcov_fork");
5482 case BUILT_IN_EXECL
:
5483 id
= get_identifier ("__gcov_execl");
5486 case BUILT_IN_EXECV
:
5487 id
= get_identifier ("__gcov_execv");
5490 case BUILT_IN_EXECLP
:
5491 id
= get_identifier ("__gcov_execlp");
5494 case BUILT_IN_EXECLE
:
5495 id
= get_identifier ("__gcov_execle");
5498 case BUILT_IN_EXECVP
:
5499 id
= get_identifier ("__gcov_execvp");
5502 case BUILT_IN_EXECVE
:
5503 id
= get_identifier ("__gcov_execve");
5510 decl
= build_decl (FUNCTION_DECL
, id
, TREE_TYPE (fn
));
5511 DECL_EXTERNAL (decl
) = 1;
5512 TREE_PUBLIC (decl
) = 1;
5513 DECL_ARTIFICIAL (decl
) = 1;
5514 TREE_NOTHROW (decl
) = 1;
5515 DECL_VISIBILITY (decl
) = VISIBILITY_DEFAULT
;
5516 DECL_VISIBILITY_SPECIFIED (decl
) = 1;
5517 call
= build_function_call_expr (decl
, arglist
);
5519 return expand_call (call
, target
, ignore
);
5523 /* Reconstitute a mode for a __sync intrinsic operation. Since the type of
5524 the pointer in these functions is void*, the tree optimizers may remove
5525 casts. The mode computed in expand_builtin isn't reliable either, due
5526 to __sync_bool_compare_and_swap.
5528 FCODE_DIFF should be fcode - base, where base is the FOO_1 code for the
5529 group of builtins. This gives us log2 of the mode size. */
5531 static inline enum machine_mode
5532 get_builtin_sync_mode (int fcode_diff
)
5534 /* The size is not negotiable, so ask not to get BLKmode in return
5535 if the target indicates that a smaller size would be better. */
5536 return mode_for_size (BITS_PER_UNIT
<< fcode_diff
, MODE_INT
, 0);
5539 /* Expand the memory expression LOC and return the appropriate memory operand
5540 for the builtin_sync operations. */
5543 get_builtin_sync_mem (tree loc
, enum machine_mode mode
)
5547 addr
= expand_expr (loc
, NULL
, Pmode
, EXPAND_SUM
);
5549 /* Note that we explicitly do not want any alias information for this
5550 memory, so that we kill all other live memories. Otherwise we don't
5551 satisfy the full barrier semantics of the intrinsic. */
5552 mem
= validize_mem (gen_rtx_MEM (mode
, addr
));
5554 set_mem_align (mem
, get_pointer_alignment (loc
, BIGGEST_ALIGNMENT
));
5555 set_mem_alias_set (mem
, ALIAS_SET_MEMORY_BARRIER
);
5556 MEM_VOLATILE_P (mem
) = 1;
5561 /* Expand the __sync_xxx_and_fetch and __sync_fetch_and_xxx intrinsics.
5562 ARGLIST is the operands list to the function. CODE is the rtx code
5563 that corresponds to the arithmetic or logical operation from the name;
5564 an exception here is that NOT actually means NAND. TARGET is an optional
5565 place for us to store the results; AFTER is true if this is the
5566 fetch_and_xxx form. IGNORE is true if we don't actually care about
5567 the result of the operation at all. */
5570 expand_builtin_sync_operation (enum machine_mode mode
, tree arglist
,
5571 enum rtx_code code
, bool after
,
5572 rtx target
, bool ignore
)
5576 /* Expand the operands. */
5577 mem
= get_builtin_sync_mem (TREE_VALUE (arglist
), mode
);
5579 arglist
= TREE_CHAIN (arglist
);
5580 val
= expand_expr (TREE_VALUE (arglist
), NULL
, mode
, EXPAND_NORMAL
);
5581 /* If VAL is promoted to a wider mode, convert it back to MODE. */
5582 val
= convert_to_mode (mode
, val
, 1);
5585 return expand_sync_operation (mem
, val
, code
);
5587 return expand_sync_fetch_operation (mem
, val
, code
, after
, target
);
5590 /* Expand the __sync_val_compare_and_swap and __sync_bool_compare_and_swap
5591 intrinsics. ARGLIST is the operands list to the function. IS_BOOL is
5592 true if this is the boolean form. TARGET is a place for us to store the
5593 results; this is NOT optional if IS_BOOL is true. */
5596 expand_builtin_compare_and_swap (enum machine_mode mode
, tree arglist
,
5597 bool is_bool
, rtx target
)
5599 rtx old_val
, new_val
, mem
;
5601 /* Expand the operands. */
5602 mem
= get_builtin_sync_mem (TREE_VALUE (arglist
), mode
);
5604 arglist
= TREE_CHAIN (arglist
);
5605 old_val
= expand_expr (TREE_VALUE (arglist
), NULL
, mode
, EXPAND_NORMAL
);
5606 /* If OLD_VAL is promoted to a wider mode, convert it back to MODE. */
5607 old_val
= convert_to_mode (mode
, old_val
, 1);
5609 arglist
= TREE_CHAIN (arglist
);
5610 new_val
= expand_expr (TREE_VALUE (arglist
), NULL
, mode
, EXPAND_NORMAL
);
5611 /* If NEW_VAL is promoted to a wider mode, convert it back to MODE. */
5612 new_val
= convert_to_mode (mode
, new_val
, 1);
5615 return expand_bool_compare_and_swap (mem
, old_val
, new_val
, target
);
5617 return expand_val_compare_and_swap (mem
, old_val
, new_val
, target
);
5620 /* Expand the __sync_lock_test_and_set intrinsic. Note that the most
5621 general form is actually an atomic exchange, and some targets only
5622 support a reduced form with the second argument being a constant 1.
5623 ARGLIST is the operands list to the function; TARGET is an optional
5624 place for us to store the results. */
5627 expand_builtin_lock_test_and_set (enum machine_mode mode
, tree arglist
,
5632 /* Expand the operands. */
5633 mem
= get_builtin_sync_mem (TREE_VALUE (arglist
), mode
);
5635 arglist
= TREE_CHAIN (arglist
);
5636 val
= expand_expr (TREE_VALUE (arglist
), NULL
, mode
, EXPAND_NORMAL
);
5637 /* If VAL is promoted to a wider mode, convert it back to MODE. */
5638 val
= convert_to_mode (mode
, val
, 1);
5640 return expand_sync_lock_test_and_set (mem
, val
, target
);
5643 /* Expand the __sync_synchronize intrinsic. */
5646 expand_builtin_synchronize (void)
5650 #ifdef HAVE_memory_barrier
5651 if (HAVE_memory_barrier
)
5653 emit_insn (gen_memory_barrier ());
5658 /* If no explicit memory barrier instruction is available, create an
5659 empty asm stmt with a memory clobber. */
5660 x
= build4 (ASM_EXPR
, void_type_node
, build_string (0, ""), NULL
, NULL
,
5661 tree_cons (NULL
, build_string (6, "memory"), NULL
));
5662 ASM_VOLATILE_P (x
) = 1;
5663 expand_asm_expr (x
);
5666 /* Expand the __sync_lock_release intrinsic. ARGLIST is the operands list
5670 expand_builtin_lock_release (enum machine_mode mode
, tree arglist
)
5672 enum insn_code icode
;
5674 rtx val
= const0_rtx
;
5676 /* Expand the operands. */
5677 mem
= get_builtin_sync_mem (TREE_VALUE (arglist
), mode
);
5679 /* If there is an explicit operation in the md file, use it. */
5680 icode
= sync_lock_release
[mode
];
5681 if (icode
!= CODE_FOR_nothing
)
5683 if (!insn_data
[icode
].operand
[1].predicate (val
, mode
))
5684 val
= force_reg (mode
, val
);
5686 insn
= GEN_FCN (icode
) (mem
, val
);
5694 /* Otherwise we can implement this operation by emitting a barrier
5695 followed by a store of zero. */
5696 expand_builtin_synchronize ();
5697 emit_move_insn (mem
, val
);
5700 /* Expand an expression EXP that calls a built-in function,
5701 with result going to TARGET if that's convenient
5702 (and in mode MODE if that's convenient).
5703 SUBTARGET may be used as the target for computing one of EXP's operands.
5704 IGNORE is nonzero if the value is to be ignored. */
5707 expand_builtin (tree exp
, rtx target
, rtx subtarget
, enum machine_mode mode
,
5710 tree fndecl
= get_callee_fndecl (exp
);
5711 tree arglist
= TREE_OPERAND (exp
, 1);
5712 enum built_in_function fcode
= DECL_FUNCTION_CODE (fndecl
);
5713 enum machine_mode target_mode
= TYPE_MODE (TREE_TYPE (exp
));
5715 if (DECL_BUILT_IN_CLASS (fndecl
) == BUILT_IN_MD
)
5716 return targetm
.expand_builtin (exp
, target
, subtarget
, mode
, ignore
);
5718 /* When not optimizing, generate calls to library functions for a certain
5721 && !called_as_built_in (fndecl
)
5722 && DECL_ASSEMBLER_NAME_SET_P (fndecl
)
5723 && fcode
!= BUILT_IN_ALLOCA
)
5724 return expand_call (exp
, target
, ignore
);
5726 /* The built-in function expanders test for target == const0_rtx
5727 to determine whether the function's result will be ignored. */
5729 target
= const0_rtx
;
5731 /* If the result of a pure or const built-in function is ignored, and
5732 none of its arguments are volatile, we can avoid expanding the
5733 built-in call and just evaluate the arguments for side-effects. */
5734 if (target
== const0_rtx
5735 && (DECL_IS_PURE (fndecl
) || TREE_READONLY (fndecl
)))
5737 bool volatilep
= false;
5740 for (arg
= arglist
; arg
; arg
= TREE_CHAIN (arg
))
5741 if (TREE_THIS_VOLATILE (TREE_VALUE (arg
)))
5749 for (arg
= arglist
; arg
; arg
= TREE_CHAIN (arg
))
5750 expand_expr (TREE_VALUE (arg
), const0_rtx
,
5751 VOIDmode
, EXPAND_NORMAL
);
5758 CASE_FLT_FN (BUILT_IN_FABS
):
5759 target
= expand_builtin_fabs (arglist
, target
, subtarget
);
5764 CASE_FLT_FN (BUILT_IN_COPYSIGN
):
5765 target
= expand_builtin_copysign (arglist
, target
, subtarget
);
5770 /* Just do a normal library call if we were unable to fold
5772 CASE_FLT_FN (BUILT_IN_CABS
):
5775 CASE_FLT_FN (BUILT_IN_EXP
):
5776 CASE_FLT_FN (BUILT_IN_EXP10
):
5777 CASE_FLT_FN (BUILT_IN_POW10
):
5778 CASE_FLT_FN (BUILT_IN_EXP2
):
5779 CASE_FLT_FN (BUILT_IN_EXPM1
):
5780 CASE_FLT_FN (BUILT_IN_LOGB
):
5781 CASE_FLT_FN (BUILT_IN_ILOGB
):
5782 CASE_FLT_FN (BUILT_IN_LOG
):
5783 CASE_FLT_FN (BUILT_IN_LOG10
):
5784 CASE_FLT_FN (BUILT_IN_LOG2
):
5785 CASE_FLT_FN (BUILT_IN_LOG1P
):
5786 CASE_FLT_FN (BUILT_IN_TAN
):
5787 CASE_FLT_FN (BUILT_IN_ASIN
):
5788 CASE_FLT_FN (BUILT_IN_ACOS
):
5789 CASE_FLT_FN (BUILT_IN_ATAN
):
5790 /* Treat these like sqrt only if unsafe math optimizations are allowed,
5791 because of possible accuracy problems. */
5792 if (! flag_unsafe_math_optimizations
)
5794 CASE_FLT_FN (BUILT_IN_SQRT
):
5795 CASE_FLT_FN (BUILT_IN_FLOOR
):
5796 CASE_FLT_FN (BUILT_IN_CEIL
):
5797 CASE_FLT_FN (BUILT_IN_TRUNC
):
5798 CASE_FLT_FN (BUILT_IN_ROUND
):
5799 CASE_FLT_FN (BUILT_IN_NEARBYINT
):
5800 CASE_FLT_FN (BUILT_IN_RINT
):
5801 target
= expand_builtin_mathfn (exp
, target
, subtarget
);
5806 CASE_FLT_FN (BUILT_IN_LCEIL
):
5807 CASE_FLT_FN (BUILT_IN_LLCEIL
):
5808 CASE_FLT_FN (BUILT_IN_LFLOOR
):
5809 CASE_FLT_FN (BUILT_IN_LLFLOOR
):
5810 target
= expand_builtin_int_roundingfn (exp
, target
, subtarget
);
5815 CASE_FLT_FN (BUILT_IN_LRINT
):
5816 CASE_FLT_FN (BUILT_IN_LLRINT
):
5817 CASE_FLT_FN (BUILT_IN_LROUND
):
5818 CASE_FLT_FN (BUILT_IN_LLROUND
):
5819 target
= expand_builtin_int_roundingfn_2 (exp
, target
, subtarget
);
5824 CASE_FLT_FN (BUILT_IN_POW
):
5825 target
= expand_builtin_pow (exp
, target
, subtarget
);
5830 CASE_FLT_FN (BUILT_IN_POWI
):
5831 target
= expand_builtin_powi (exp
, target
, subtarget
);
5836 CASE_FLT_FN (BUILT_IN_ATAN2
):
5837 CASE_FLT_FN (BUILT_IN_LDEXP
):
5838 if (! flag_unsafe_math_optimizations
)
5841 CASE_FLT_FN (BUILT_IN_FMOD
):
5842 CASE_FLT_FN (BUILT_IN_REMAINDER
):
5843 CASE_FLT_FN (BUILT_IN_DREM
):
5844 target
= expand_builtin_mathfn_2 (exp
, target
, subtarget
);
5849 CASE_FLT_FN (BUILT_IN_CEXPI
):
5850 target
= expand_builtin_cexpi (exp
, target
, subtarget
);
5851 gcc_assert (target
);
5854 CASE_FLT_FN (BUILT_IN_SIN
):
5855 CASE_FLT_FN (BUILT_IN_COS
):
5856 if (! flag_unsafe_math_optimizations
)
5858 target
= expand_builtin_mathfn_3 (exp
, target
, subtarget
);
5863 CASE_FLT_FN (BUILT_IN_SINCOS
):
5864 if (! flag_unsafe_math_optimizations
)
5866 target
= expand_builtin_sincos (exp
);
5871 case BUILT_IN_APPLY_ARGS
:
5872 return expand_builtin_apply_args ();
5874 /* __builtin_apply (FUNCTION, ARGUMENTS, ARGSIZE) invokes
5875 FUNCTION with a copy of the parameters described by
5876 ARGUMENTS, and ARGSIZE. It returns a block of memory
5877 allocated on the stack into which is stored all the registers
5878 that might possibly be used for returning the result of a
5879 function. ARGUMENTS is the value returned by
5880 __builtin_apply_args. ARGSIZE is the number of bytes of
5881 arguments that must be copied. ??? How should this value be
5882 computed? We'll also need a safe worst case value for varargs
5884 case BUILT_IN_APPLY
:
5885 if (!validate_arglist (arglist
, POINTER_TYPE
,
5886 POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
)
5887 && !validate_arglist (arglist
, REFERENCE_TYPE
,
5888 POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
5896 for (t
= arglist
, i
= 0; t
; t
= TREE_CHAIN (t
), i
++)
5897 ops
[i
] = expand_normal (TREE_VALUE (t
));
5899 return expand_builtin_apply (ops
[0], ops
[1], ops
[2]);
5902 /* __builtin_return (RESULT) causes the function to return the
5903 value described by RESULT. RESULT is address of the block of
5904 memory returned by __builtin_apply. */
5905 case BUILT_IN_RETURN
:
5906 if (validate_arglist (arglist
, POINTER_TYPE
, VOID_TYPE
))
5907 expand_builtin_return (expand_normal (TREE_VALUE (arglist
)));
5910 case BUILT_IN_SAVEREGS
:
5911 return expand_builtin_saveregs ();
5913 case BUILT_IN_ARGS_INFO
:
5914 return expand_builtin_args_info (arglist
);
5916 /* Return the address of the first anonymous stack arg. */
5917 case BUILT_IN_NEXT_ARG
:
5918 if (fold_builtin_next_arg (arglist
))
5920 return expand_builtin_next_arg ();
5922 case BUILT_IN_CLASSIFY_TYPE
:
5923 return expand_builtin_classify_type (arglist
);
5925 case BUILT_IN_CONSTANT_P
:
5928 case BUILT_IN_FRAME_ADDRESS
:
5929 case BUILT_IN_RETURN_ADDRESS
:
5930 return expand_builtin_frame_address (fndecl
, arglist
);
5932 /* Returns the address of the area where the structure is returned.
5934 case BUILT_IN_AGGREGATE_INCOMING_ADDRESS
:
5936 || ! AGGREGATE_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl
)))
5937 || !MEM_P (DECL_RTL (DECL_RESULT (current_function_decl
))))
5940 return XEXP (DECL_RTL (DECL_RESULT (current_function_decl
)), 0);
5942 case BUILT_IN_ALLOCA
:
5943 target
= expand_builtin_alloca (arglist
, target
);
5948 case BUILT_IN_STACK_SAVE
:
5949 return expand_stack_save ();
5951 case BUILT_IN_STACK_RESTORE
:
5952 expand_stack_restore (TREE_VALUE (arglist
));
5955 case BUILT_IN_BSWAP32
:
5956 case BUILT_IN_BSWAP64
:
5957 target
= expand_builtin_bswap (arglist
, target
, subtarget
);
5963 CASE_INT_FN (BUILT_IN_FFS
):
5964 case BUILT_IN_FFSIMAX
:
5965 target
= expand_builtin_unop (target_mode
, arglist
, target
,
5966 subtarget
, ffs_optab
);
5971 CASE_INT_FN (BUILT_IN_CLZ
):
5972 case BUILT_IN_CLZIMAX
:
5973 target
= expand_builtin_unop (target_mode
, arglist
, target
,
5974 subtarget
, clz_optab
);
5979 CASE_INT_FN (BUILT_IN_CTZ
):
5980 case BUILT_IN_CTZIMAX
:
5981 target
= expand_builtin_unop (target_mode
, arglist
, target
,
5982 subtarget
, ctz_optab
);
5987 CASE_INT_FN (BUILT_IN_POPCOUNT
):
5988 case BUILT_IN_POPCOUNTIMAX
:
5989 target
= expand_builtin_unop (target_mode
, arglist
, target
,
5990 subtarget
, popcount_optab
);
5995 CASE_INT_FN (BUILT_IN_PARITY
):
5996 case BUILT_IN_PARITYIMAX
:
5997 target
= expand_builtin_unop (target_mode
, arglist
, target
,
5998 subtarget
, parity_optab
);
6003 case BUILT_IN_STRLEN
:
6004 target
= expand_builtin_strlen (arglist
, target
, target_mode
);
6009 case BUILT_IN_STRCPY
:
6010 target
= expand_builtin_strcpy (fndecl
, arglist
, target
, mode
);
6015 case BUILT_IN_STRNCPY
:
6016 target
= expand_builtin_strncpy (exp
, target
, mode
);
6021 case BUILT_IN_STPCPY
:
6022 target
= expand_builtin_stpcpy (exp
, target
, mode
);
6027 case BUILT_IN_STRCAT
:
6028 target
= expand_builtin_strcat (fndecl
, arglist
, target
, mode
);
6033 case BUILT_IN_STRNCAT
:
6034 target
= expand_builtin_strncat (arglist
, target
, mode
);
6039 case BUILT_IN_STRSPN
:
6040 target
= expand_builtin_strspn (arglist
, target
, mode
);
6045 case BUILT_IN_STRCSPN
:
6046 target
= expand_builtin_strcspn (arglist
, target
, mode
);
6051 case BUILT_IN_STRSTR
:
6052 target
= expand_builtin_strstr (arglist
, TREE_TYPE (exp
), target
, mode
);
6057 case BUILT_IN_STRPBRK
:
6058 target
= expand_builtin_strpbrk (arglist
, TREE_TYPE (exp
), target
, mode
);
6063 case BUILT_IN_INDEX
:
6064 case BUILT_IN_STRCHR
:
6065 target
= expand_builtin_strchr (arglist
, TREE_TYPE (exp
), target
, mode
);
6070 case BUILT_IN_RINDEX
:
6071 case BUILT_IN_STRRCHR
:
6072 target
= expand_builtin_strrchr (arglist
, TREE_TYPE (exp
), target
, mode
);
6077 case BUILT_IN_MEMCPY
:
6078 target
= expand_builtin_memcpy (exp
, target
, mode
);
6083 case BUILT_IN_MEMPCPY
:
6084 target
= expand_builtin_mempcpy (arglist
, TREE_TYPE (exp
), target
, mode
, /*endp=*/ 1);
6089 case BUILT_IN_MEMMOVE
:
6090 target
= expand_builtin_memmove (arglist
, TREE_TYPE (exp
), target
,
6096 case BUILT_IN_BCOPY
:
6097 target
= expand_builtin_bcopy (exp
);
6102 case BUILT_IN_MEMSET
:
6103 target
= expand_builtin_memset (arglist
, target
, mode
, exp
);
6108 case BUILT_IN_BZERO
:
6109 target
= expand_builtin_bzero (exp
);
6114 case BUILT_IN_STRCMP
:
6115 target
= expand_builtin_strcmp (exp
, target
, mode
);
6120 case BUILT_IN_STRNCMP
:
6121 target
= expand_builtin_strncmp (exp
, target
, mode
);
6127 case BUILT_IN_MEMCMP
:
6128 target
= expand_builtin_memcmp (exp
, arglist
, target
, mode
);
6133 case BUILT_IN_SETJMP
:
6134 /* This should have been lowered to the builtins below. */
6137 case BUILT_IN_SETJMP_SETUP
:
6138 /* __builtin_setjmp_setup is passed a pointer to an array of five words
6139 and the receiver label. */
6140 if (validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
6142 rtx buf_addr
= expand_expr (TREE_VALUE (arglist
), subtarget
,
6143 VOIDmode
, EXPAND_NORMAL
);
6144 tree label
= TREE_OPERAND (TREE_VALUE (TREE_CHAIN (arglist
)), 0);
6145 rtx label_r
= label_rtx (label
);
6147 /* This is copied from the handling of non-local gotos. */
6148 expand_builtin_setjmp_setup (buf_addr
, label_r
);
6149 nonlocal_goto_handler_labels
6150 = gen_rtx_EXPR_LIST (VOIDmode
, label_r
,
6151 nonlocal_goto_handler_labels
);
6152 /* ??? Do not let expand_label treat us as such since we would
6153 not want to be both on the list of non-local labels and on
6154 the list of forced labels. */
6155 FORCED_LABEL (label
) = 0;
6160 case BUILT_IN_SETJMP_DISPATCHER
:
6161 /* __builtin_setjmp_dispatcher is passed the dispatcher label. */
6162 if (validate_arglist (arglist
, POINTER_TYPE
, VOID_TYPE
))
6164 tree label
= TREE_OPERAND (TREE_VALUE (arglist
), 0);
6165 rtx label_r
= label_rtx (label
);
6167 /* Remove the dispatcher label from the list of non-local labels
6168 since the receiver labels have been added to it above. */
6169 remove_node_from_expr_list (label_r
, &nonlocal_goto_handler_labels
);
6174 case BUILT_IN_SETJMP_RECEIVER
:
6175 /* __builtin_setjmp_receiver is passed the receiver label. */
6176 if (validate_arglist (arglist
, POINTER_TYPE
, VOID_TYPE
))
6178 tree label
= TREE_OPERAND (TREE_VALUE (arglist
), 0);
6179 rtx label_r
= label_rtx (label
);
6181 expand_builtin_setjmp_receiver (label_r
);
6186 /* __builtin_longjmp is passed a pointer to an array of five words.
6187 It's similar to the C library longjmp function but works with
6188 __builtin_setjmp above. */
6189 case BUILT_IN_LONGJMP
:
6190 if (validate_arglist (arglist
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
6192 rtx buf_addr
= expand_expr (TREE_VALUE (arglist
), subtarget
,
6193 VOIDmode
, EXPAND_NORMAL
);
6194 rtx value
= expand_normal (TREE_VALUE (TREE_CHAIN (arglist
)));
6196 if (value
!= const1_rtx
)
6198 error ("%<__builtin_longjmp%> second argument must be 1");
6202 expand_builtin_longjmp (buf_addr
, value
);
6207 case BUILT_IN_NONLOCAL_GOTO
:
6208 target
= expand_builtin_nonlocal_goto (arglist
);
6213 /* This updates the setjmp buffer that is its argument with the value
6214 of the current stack pointer. */
6215 case BUILT_IN_UPDATE_SETJMP_BUF
:
6216 if (validate_arglist (arglist
, POINTER_TYPE
, VOID_TYPE
))
6219 = expand_normal (TREE_VALUE (arglist
));
6221 expand_builtin_update_setjmp_buf (buf_addr
);
6227 expand_builtin_trap ();
6230 case BUILT_IN_PRINTF
:
6231 target
= expand_builtin_printf (exp
, target
, mode
, false);
6236 case BUILT_IN_PRINTF_UNLOCKED
:
6237 target
= expand_builtin_printf (exp
, target
, mode
, true);
6242 case BUILT_IN_FPUTS
:
6243 target
= expand_builtin_fputs (arglist
, target
, false);
6247 case BUILT_IN_FPUTS_UNLOCKED
:
6248 target
= expand_builtin_fputs (arglist
, target
, true);
6253 case BUILT_IN_FPRINTF
:
6254 target
= expand_builtin_fprintf (exp
, target
, mode
, false);
6259 case BUILT_IN_FPRINTF_UNLOCKED
:
6260 target
= expand_builtin_fprintf (exp
, target
, mode
, true);
6265 case BUILT_IN_SPRINTF
:
6266 target
= expand_builtin_sprintf (arglist
, target
, mode
);
6271 CASE_FLT_FN (BUILT_IN_SIGNBIT
):
6272 target
= expand_builtin_signbit (exp
, target
);
6277 /* Various hooks for the DWARF 2 __throw routine. */
6278 case BUILT_IN_UNWIND_INIT
:
6279 expand_builtin_unwind_init ();
6281 case BUILT_IN_DWARF_CFA
:
6282 return virtual_cfa_rtx
;
6283 #ifdef DWARF2_UNWIND_INFO
6284 case BUILT_IN_DWARF_SP_COLUMN
:
6285 return expand_builtin_dwarf_sp_column ();
6286 case BUILT_IN_INIT_DWARF_REG_SIZES
:
6287 expand_builtin_init_dwarf_reg_sizes (TREE_VALUE (arglist
));
6290 case BUILT_IN_FROB_RETURN_ADDR
:
6291 return expand_builtin_frob_return_addr (TREE_VALUE (arglist
));
6292 case BUILT_IN_EXTRACT_RETURN_ADDR
:
6293 return expand_builtin_extract_return_addr (TREE_VALUE (arglist
));
6294 case BUILT_IN_EH_RETURN
:
6295 expand_builtin_eh_return (TREE_VALUE (arglist
),
6296 TREE_VALUE (TREE_CHAIN (arglist
)));
6298 #ifdef EH_RETURN_DATA_REGNO
6299 case BUILT_IN_EH_RETURN_DATA_REGNO
:
6300 return expand_builtin_eh_return_data_regno (arglist
);
6302 case BUILT_IN_EXTEND_POINTER
:
6303 return expand_builtin_extend_pointer (TREE_VALUE (arglist
));
6305 case BUILT_IN_VA_START
:
6306 case BUILT_IN_STDARG_START
:
6307 return expand_builtin_va_start (arglist
);
6308 case BUILT_IN_VA_END
:
6309 return expand_builtin_va_end (arglist
);
6310 case BUILT_IN_VA_COPY
:
6311 return expand_builtin_va_copy (arglist
);
6312 case BUILT_IN_EXPECT
:
6313 return expand_builtin_expect (arglist
, target
);
6314 case BUILT_IN_PREFETCH
:
6315 expand_builtin_prefetch (arglist
);
6318 case BUILT_IN_PROFILE_FUNC_ENTER
:
6319 return expand_builtin_profile_func (false);
6320 case BUILT_IN_PROFILE_FUNC_EXIT
:
6321 return expand_builtin_profile_func (true);
6323 case BUILT_IN_INIT_TRAMPOLINE
:
6324 return expand_builtin_init_trampoline (arglist
);
6325 case BUILT_IN_ADJUST_TRAMPOLINE
:
6326 return expand_builtin_adjust_trampoline (arglist
);
6329 case BUILT_IN_EXECL
:
6330 case BUILT_IN_EXECV
:
6331 case BUILT_IN_EXECLP
:
6332 case BUILT_IN_EXECLE
:
6333 case BUILT_IN_EXECVP
:
6334 case BUILT_IN_EXECVE
:
6335 target
= expand_builtin_fork_or_exec (fndecl
, arglist
, target
, ignore
);
6340 case BUILT_IN_FETCH_AND_ADD_1
:
6341 case BUILT_IN_FETCH_AND_ADD_2
:
6342 case BUILT_IN_FETCH_AND_ADD_4
:
6343 case BUILT_IN_FETCH_AND_ADD_8
:
6344 case BUILT_IN_FETCH_AND_ADD_16
:
6345 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_FETCH_AND_ADD_1
);
6346 target
= expand_builtin_sync_operation (mode
, arglist
, PLUS
,
6347 false, target
, ignore
);
6352 case BUILT_IN_FETCH_AND_SUB_1
:
6353 case BUILT_IN_FETCH_AND_SUB_2
:
6354 case BUILT_IN_FETCH_AND_SUB_4
:
6355 case BUILT_IN_FETCH_AND_SUB_8
:
6356 case BUILT_IN_FETCH_AND_SUB_16
:
6357 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_FETCH_AND_SUB_1
);
6358 target
= expand_builtin_sync_operation (mode
, arglist
, MINUS
,
6359 false, target
, ignore
);
6364 case BUILT_IN_FETCH_AND_OR_1
:
6365 case BUILT_IN_FETCH_AND_OR_2
:
6366 case BUILT_IN_FETCH_AND_OR_4
:
6367 case BUILT_IN_FETCH_AND_OR_8
:
6368 case BUILT_IN_FETCH_AND_OR_16
:
6369 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_FETCH_AND_OR_1
);
6370 target
= expand_builtin_sync_operation (mode
, arglist
, IOR
,
6371 false, target
, ignore
);
6376 case BUILT_IN_FETCH_AND_AND_1
:
6377 case BUILT_IN_FETCH_AND_AND_2
:
6378 case BUILT_IN_FETCH_AND_AND_4
:
6379 case BUILT_IN_FETCH_AND_AND_8
:
6380 case BUILT_IN_FETCH_AND_AND_16
:
6381 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_FETCH_AND_AND_1
);
6382 target
= expand_builtin_sync_operation (mode
, arglist
, AND
,
6383 false, target
, ignore
);
6388 case BUILT_IN_FETCH_AND_XOR_1
:
6389 case BUILT_IN_FETCH_AND_XOR_2
:
6390 case BUILT_IN_FETCH_AND_XOR_4
:
6391 case BUILT_IN_FETCH_AND_XOR_8
:
6392 case BUILT_IN_FETCH_AND_XOR_16
:
6393 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_FETCH_AND_XOR_1
);
6394 target
= expand_builtin_sync_operation (mode
, arglist
, XOR
,
6395 false, target
, ignore
);
6400 case BUILT_IN_FETCH_AND_NAND_1
:
6401 case BUILT_IN_FETCH_AND_NAND_2
:
6402 case BUILT_IN_FETCH_AND_NAND_4
:
6403 case BUILT_IN_FETCH_AND_NAND_8
:
6404 case BUILT_IN_FETCH_AND_NAND_16
:
6405 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_FETCH_AND_NAND_1
);
6406 target
= expand_builtin_sync_operation (mode
, arglist
, NOT
,
6407 false, target
, ignore
);
6412 case BUILT_IN_ADD_AND_FETCH_1
:
6413 case BUILT_IN_ADD_AND_FETCH_2
:
6414 case BUILT_IN_ADD_AND_FETCH_4
:
6415 case BUILT_IN_ADD_AND_FETCH_8
:
6416 case BUILT_IN_ADD_AND_FETCH_16
:
6417 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_ADD_AND_FETCH_1
);
6418 target
= expand_builtin_sync_operation (mode
, arglist
, PLUS
,
6419 true, target
, ignore
);
6424 case BUILT_IN_SUB_AND_FETCH_1
:
6425 case BUILT_IN_SUB_AND_FETCH_2
:
6426 case BUILT_IN_SUB_AND_FETCH_4
:
6427 case BUILT_IN_SUB_AND_FETCH_8
:
6428 case BUILT_IN_SUB_AND_FETCH_16
:
6429 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_SUB_AND_FETCH_1
);
6430 target
= expand_builtin_sync_operation (mode
, arglist
, MINUS
,
6431 true, target
, ignore
);
6436 case BUILT_IN_OR_AND_FETCH_1
:
6437 case BUILT_IN_OR_AND_FETCH_2
:
6438 case BUILT_IN_OR_AND_FETCH_4
:
6439 case BUILT_IN_OR_AND_FETCH_8
:
6440 case BUILT_IN_OR_AND_FETCH_16
:
6441 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_OR_AND_FETCH_1
);
6442 target
= expand_builtin_sync_operation (mode
, arglist
, IOR
,
6443 true, target
, ignore
);
6448 case BUILT_IN_AND_AND_FETCH_1
:
6449 case BUILT_IN_AND_AND_FETCH_2
:
6450 case BUILT_IN_AND_AND_FETCH_4
:
6451 case BUILT_IN_AND_AND_FETCH_8
:
6452 case BUILT_IN_AND_AND_FETCH_16
:
6453 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_AND_AND_FETCH_1
);
6454 target
= expand_builtin_sync_operation (mode
, arglist
, AND
,
6455 true, target
, ignore
);
6460 case BUILT_IN_XOR_AND_FETCH_1
:
6461 case BUILT_IN_XOR_AND_FETCH_2
:
6462 case BUILT_IN_XOR_AND_FETCH_4
:
6463 case BUILT_IN_XOR_AND_FETCH_8
:
6464 case BUILT_IN_XOR_AND_FETCH_16
:
6465 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_XOR_AND_FETCH_1
);
6466 target
= expand_builtin_sync_operation (mode
, arglist
, XOR
,
6467 true, target
, ignore
);
6472 case BUILT_IN_NAND_AND_FETCH_1
:
6473 case BUILT_IN_NAND_AND_FETCH_2
:
6474 case BUILT_IN_NAND_AND_FETCH_4
:
6475 case BUILT_IN_NAND_AND_FETCH_8
:
6476 case BUILT_IN_NAND_AND_FETCH_16
:
6477 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_NAND_AND_FETCH_1
);
6478 target
= expand_builtin_sync_operation (mode
, arglist
, NOT
,
6479 true, target
, ignore
);
6484 case BUILT_IN_BOOL_COMPARE_AND_SWAP_1
:
6485 case BUILT_IN_BOOL_COMPARE_AND_SWAP_2
:
6486 case BUILT_IN_BOOL_COMPARE_AND_SWAP_4
:
6487 case BUILT_IN_BOOL_COMPARE_AND_SWAP_8
:
6488 case BUILT_IN_BOOL_COMPARE_AND_SWAP_16
:
6489 if (mode
== VOIDmode
)
6490 mode
= TYPE_MODE (boolean_type_node
);
6491 if (!target
|| !register_operand (target
, mode
))
6492 target
= gen_reg_rtx (mode
);
6494 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_BOOL_COMPARE_AND_SWAP_1
);
6495 target
= expand_builtin_compare_and_swap (mode
, arglist
, true, target
);
6500 case BUILT_IN_VAL_COMPARE_AND_SWAP_1
:
6501 case BUILT_IN_VAL_COMPARE_AND_SWAP_2
:
6502 case BUILT_IN_VAL_COMPARE_AND_SWAP_4
:
6503 case BUILT_IN_VAL_COMPARE_AND_SWAP_8
:
6504 case BUILT_IN_VAL_COMPARE_AND_SWAP_16
:
6505 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_VAL_COMPARE_AND_SWAP_1
);
6506 target
= expand_builtin_compare_and_swap (mode
, arglist
, false, target
);
6511 case BUILT_IN_LOCK_TEST_AND_SET_1
:
6512 case BUILT_IN_LOCK_TEST_AND_SET_2
:
6513 case BUILT_IN_LOCK_TEST_AND_SET_4
:
6514 case BUILT_IN_LOCK_TEST_AND_SET_8
:
6515 case BUILT_IN_LOCK_TEST_AND_SET_16
:
6516 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_LOCK_TEST_AND_SET_1
);
6517 target
= expand_builtin_lock_test_and_set (mode
, arglist
, target
);
6522 case BUILT_IN_LOCK_RELEASE_1
:
6523 case BUILT_IN_LOCK_RELEASE_2
:
6524 case BUILT_IN_LOCK_RELEASE_4
:
6525 case BUILT_IN_LOCK_RELEASE_8
:
6526 case BUILT_IN_LOCK_RELEASE_16
:
6527 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_LOCK_RELEASE_1
);
6528 expand_builtin_lock_release (mode
, arglist
);
6531 case BUILT_IN_SYNCHRONIZE
:
6532 expand_builtin_synchronize ();
6535 case BUILT_IN_OBJECT_SIZE
:
6536 return expand_builtin_object_size (exp
);
6538 case BUILT_IN_MEMCPY_CHK
:
6539 case BUILT_IN_MEMPCPY_CHK
:
6540 case BUILT_IN_MEMMOVE_CHK
:
6541 case BUILT_IN_MEMSET_CHK
:
6542 target
= expand_builtin_memory_chk (exp
, target
, mode
, fcode
);
6547 case BUILT_IN_STRCPY_CHK
:
6548 case BUILT_IN_STPCPY_CHK
:
6549 case BUILT_IN_STRNCPY_CHK
:
6550 case BUILT_IN_STRCAT_CHK
:
6551 case BUILT_IN_STRNCAT_CHK
:
6552 case BUILT_IN_SNPRINTF_CHK
:
6553 case BUILT_IN_VSNPRINTF_CHK
:
6554 maybe_emit_chk_warning (exp
, fcode
);
6557 case BUILT_IN_SPRINTF_CHK
:
6558 case BUILT_IN_VSPRINTF_CHK
:
6559 maybe_emit_sprintf_chk_warning (exp
, fcode
);
6562 default: /* just do library call, if unknown builtin */
6566 /* The switch statement above can drop through to cause the function
6567 to be called normally. */
6568 return expand_call (exp
, target
, ignore
);
6571 /* Determine whether a tree node represents a call to a built-in
6572 function. If the tree T is a call to a built-in function with
6573 the right number of arguments of the appropriate types, return
6574 the DECL_FUNCTION_CODE of the call, e.g. BUILT_IN_SQRT.
6575 Otherwise the return value is END_BUILTINS. */
6577 enum built_in_function
6578 builtin_mathfn_code (tree t
)
6580 tree fndecl
, arglist
, parmlist
;
6581 tree argtype
, parmtype
;
6583 if (TREE_CODE (t
) != CALL_EXPR
6584 || TREE_CODE (TREE_OPERAND (t
, 0)) != ADDR_EXPR
)
6585 return END_BUILTINS
;
6587 fndecl
= get_callee_fndecl (t
);
6588 if (fndecl
== NULL_TREE
6589 || TREE_CODE (fndecl
) != FUNCTION_DECL
6590 || ! DECL_BUILT_IN (fndecl
)
6591 || DECL_BUILT_IN_CLASS (fndecl
) == BUILT_IN_MD
)
6592 return END_BUILTINS
;
6594 arglist
= TREE_OPERAND (t
, 1);
6595 parmlist
= TYPE_ARG_TYPES (TREE_TYPE (fndecl
));
6596 for (; parmlist
; parmlist
= TREE_CHAIN (parmlist
))
6598 /* If a function doesn't take a variable number of arguments,
6599 the last element in the list will have type `void'. */
6600 parmtype
= TREE_VALUE (parmlist
);
6601 if (VOID_TYPE_P (parmtype
))
6604 return END_BUILTINS
;
6605 return DECL_FUNCTION_CODE (fndecl
);
6609 return END_BUILTINS
;
6611 argtype
= TREE_TYPE (TREE_VALUE (arglist
));
6613 if (SCALAR_FLOAT_TYPE_P (parmtype
))
6615 if (! SCALAR_FLOAT_TYPE_P (argtype
))
6616 return END_BUILTINS
;
6618 else if (COMPLEX_FLOAT_TYPE_P (parmtype
))
6620 if (! COMPLEX_FLOAT_TYPE_P (argtype
))
6621 return END_BUILTINS
;
6623 else if (POINTER_TYPE_P (parmtype
))
6625 if (! POINTER_TYPE_P (argtype
))
6626 return END_BUILTINS
;
6628 else if (INTEGRAL_TYPE_P (parmtype
))
6630 if (! INTEGRAL_TYPE_P (argtype
))
6631 return END_BUILTINS
;
6634 return END_BUILTINS
;
6636 arglist
= TREE_CHAIN (arglist
);
6639 /* Variable-length argument list. */
6640 return DECL_FUNCTION_CODE (fndecl
);
6643 /* Fold a call to __builtin_constant_p, if we know it will evaluate to a
6644 constant. ARGLIST is the argument list of the call. */
6647 fold_builtin_constant_p (tree arglist
)
6652 arglist
= TREE_VALUE (arglist
);
6654 /* We return 1 for a numeric type that's known to be a constant
6655 value at compile-time or for an aggregate type that's a
6656 literal constant. */
6657 STRIP_NOPS (arglist
);
6659 /* If we know this is a constant, emit the constant of one. */
6660 if (CONSTANT_CLASS_P (arglist
)
6661 || (TREE_CODE (arglist
) == CONSTRUCTOR
6662 && TREE_CONSTANT (arglist
)))
6663 return integer_one_node
;
6664 if (TREE_CODE (arglist
) == ADDR_EXPR
)
6666 tree op
= TREE_OPERAND (arglist
, 0);
6667 if (TREE_CODE (op
) == STRING_CST
6668 || (TREE_CODE (op
) == ARRAY_REF
6669 && integer_zerop (TREE_OPERAND (op
, 1))
6670 && TREE_CODE (TREE_OPERAND (op
, 0)) == STRING_CST
))
6671 return integer_one_node
;
6674 /* If this expression has side effects, show we don't know it to be a
6675 constant. Likewise if it's a pointer or aggregate type since in
6676 those case we only want literals, since those are only optimized
6677 when generating RTL, not later.
6678 And finally, if we are compiling an initializer, not code, we
6679 need to return a definite result now; there's not going to be any
6680 more optimization done. */
6681 if (TREE_SIDE_EFFECTS (arglist
)
6682 || AGGREGATE_TYPE_P (TREE_TYPE (arglist
))
6683 || POINTER_TYPE_P (TREE_TYPE (arglist
))
6685 || folding_initializer
)
6686 return integer_zero_node
;
6691 /* Fold a call to __builtin_expect, if we expect that a comparison against
6692 the argument will fold to a constant. In practice, this means a true
6693 constant or the address of a non-weak symbol. ARGLIST is the argument
6694 list of the call. */
6697 fold_builtin_expect (tree arglist
)
6704 arg
= TREE_VALUE (arglist
);
6706 /* If the argument isn't invariant, then there's nothing we can do. */
6707 if (!TREE_INVARIANT (arg
))
6710 /* If we're looking at an address of a weak decl, then do not fold. */
6713 if (TREE_CODE (inner
) == ADDR_EXPR
)
6717 inner
= TREE_OPERAND (inner
, 0);
6719 while (TREE_CODE (inner
) == COMPONENT_REF
6720 || TREE_CODE (inner
) == ARRAY_REF
);
6721 if (DECL_P (inner
) && DECL_WEAK (inner
))
6725 /* Otherwise, ARG already has the proper type for the return value. */
6729 /* Fold a call to __builtin_classify_type. */
6732 fold_builtin_classify_type (tree arglist
)
6735 return build_int_cst (NULL_TREE
, no_type_class
);
6737 return build_int_cst (NULL_TREE
,
6738 type_to_class (TREE_TYPE (TREE_VALUE (arglist
))));
6741 /* Fold a call to __builtin_strlen. */
6744 fold_builtin_strlen (tree arglist
)
6746 if (!validate_arglist (arglist
, POINTER_TYPE
, VOID_TYPE
))
6750 tree len
= c_strlen (TREE_VALUE (arglist
), 0);
6754 /* Convert from the internal "sizetype" type to "size_t". */
6756 len
= fold_convert (size_type_node
, len
);
6764 /* Fold a call to __builtin_inf or __builtin_huge_val. */
6767 fold_builtin_inf (tree type
, int warn
)
6769 REAL_VALUE_TYPE real
;
6771 /* __builtin_inff is intended to be usable to define INFINITY on all
6772 targets. If an infinity is not available, INFINITY expands "to a
6773 positive constant of type float that overflows at translation
6774 time", footnote "In this case, using INFINITY will violate the
6775 constraint in 6.4.4 and thus require a diagnostic." (C99 7.12#4).
6776 Thus we pedwarn to ensure this constraint violation is
6778 if (!MODE_HAS_INFINITIES (TYPE_MODE (type
)) && warn
)
6779 pedwarn ("target format does not support infinity");
6782 return build_real (type
, real
);
6785 /* Fold a call to __builtin_nan or __builtin_nans. */
6788 fold_builtin_nan (tree arglist
, tree type
, int quiet
)
6790 REAL_VALUE_TYPE real
;
6793 if (!validate_arglist (arglist
, POINTER_TYPE
, VOID_TYPE
))
6795 str
= c_getstr (TREE_VALUE (arglist
));
6799 if (!real_nan (&real
, str
, quiet
, TYPE_MODE (type
)))
6802 return build_real (type
, real
);
6805 /* Return true if the floating point expression T has an integer value.
6806 We also allow +Inf, -Inf and NaN to be considered integer values. */
6809 integer_valued_real_p (tree t
)
6811 switch (TREE_CODE (t
))
6818 case NON_LVALUE_EXPR
:
6819 return integer_valued_real_p (TREE_OPERAND (t
, 0));
6822 case GIMPLE_MODIFY_STMT
:
6824 return integer_valued_real_p (GENERIC_TREE_OPERAND (t
, 1));
6831 return integer_valued_real_p (TREE_OPERAND (t
, 0))
6832 && integer_valued_real_p (TREE_OPERAND (t
, 1));
6835 return integer_valued_real_p (TREE_OPERAND (t
, 1))
6836 && integer_valued_real_p (TREE_OPERAND (t
, 2));
6839 return real_isinteger (TREE_REAL_CST_PTR (t
), TYPE_MODE (TREE_TYPE (t
)));
6843 tree type
= TREE_TYPE (TREE_OPERAND (t
, 0));
6844 if (TREE_CODE (type
) == INTEGER_TYPE
)
6846 if (TREE_CODE (type
) == REAL_TYPE
)
6847 return integer_valued_real_p (TREE_OPERAND (t
, 0));
6852 switch (builtin_mathfn_code (t
))
6854 CASE_FLT_FN (BUILT_IN_CEIL
):
6855 CASE_FLT_FN (BUILT_IN_FLOOR
):
6856 CASE_FLT_FN (BUILT_IN_NEARBYINT
):
6857 CASE_FLT_FN (BUILT_IN_RINT
):
6858 CASE_FLT_FN (BUILT_IN_ROUND
):
6859 CASE_FLT_FN (BUILT_IN_TRUNC
):
6862 CASE_FLT_FN (BUILT_IN_FMIN
):
6863 CASE_FLT_FN (BUILT_IN_FMAX
):
6864 return integer_valued_real_p (TREE_VALUE (TREE_OPERAND (t
, 1)))
6865 && integer_valued_real_p (TREE_VALUE (TREE_CHAIN (TREE_OPERAND (t
, 1))));
6878 /* EXP is assumed to be builtin call where truncation can be propagated
6879 across (for instance floor((double)f) == (double)floorf (f).
6880 Do the transformation. */
6883 fold_trunc_transparent_mathfn (tree fndecl
, tree arglist
)
6885 enum built_in_function fcode
= DECL_FUNCTION_CODE (fndecl
);
6888 if (! validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
6891 arg
= TREE_VALUE (arglist
);
6892 /* Integer rounding functions are idempotent. */
6893 if (fcode
== builtin_mathfn_code (arg
))
6896 /* If argument is already integer valued, and we don't need to worry
6897 about setting errno, there's no need to perform rounding. */
6898 if (! flag_errno_math
&& integer_valued_real_p (arg
))
6903 tree arg0
= strip_float_extensions (arg
);
6904 tree ftype
= TREE_TYPE (TREE_TYPE (fndecl
));
6905 tree newtype
= TREE_TYPE (arg0
);
6908 if (TYPE_PRECISION (newtype
) < TYPE_PRECISION (ftype
)
6909 && (decl
= mathfn_built_in (newtype
, fcode
)))
6912 build_tree_list (NULL_TREE
, fold_convert (newtype
, arg0
));
6913 return fold_convert (ftype
,
6914 build_function_call_expr (decl
, arglist
));
6920 /* EXP is assumed to be builtin call which can narrow the FP type of
6921 the argument, for instance lround((double)f) -> lroundf (f). */
6924 fold_fixed_mathfn (tree fndecl
, tree arglist
)
6926 enum built_in_function fcode
= DECL_FUNCTION_CODE (fndecl
);
6929 if (! validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
6932 arg
= TREE_VALUE (arglist
);
6934 /* If argument is already integer valued, and we don't need to worry
6935 about setting errno, there's no need to perform rounding. */
6936 if (! flag_errno_math
&& integer_valued_real_p (arg
))
6937 return fold_build1 (FIX_TRUNC_EXPR
, TREE_TYPE (TREE_TYPE (fndecl
)), arg
);
6941 tree ftype
= TREE_TYPE (arg
);
6942 tree arg0
= strip_float_extensions (arg
);
6943 tree newtype
= TREE_TYPE (arg0
);
6946 if (TYPE_PRECISION (newtype
) < TYPE_PRECISION (ftype
)
6947 && (decl
= mathfn_built_in (newtype
, fcode
)))
6950 build_tree_list (NULL_TREE
, fold_convert (newtype
, arg0
));
6951 return build_function_call_expr (decl
, arglist
);
6955 /* Canonicalize llround (x) to lround (x) on LP64 targets where
6956 sizeof (long long) == sizeof (long). */
6957 if (TYPE_PRECISION (long_long_integer_type_node
)
6958 == TYPE_PRECISION (long_integer_type_node
))
6960 tree newfn
= NULL_TREE
;
6963 CASE_FLT_FN (BUILT_IN_LLCEIL
):
6964 newfn
= mathfn_built_in (TREE_TYPE (arg
), BUILT_IN_LCEIL
);
6967 CASE_FLT_FN (BUILT_IN_LLFLOOR
):
6968 newfn
= mathfn_built_in (TREE_TYPE (arg
), BUILT_IN_LFLOOR
);
6971 CASE_FLT_FN (BUILT_IN_LLROUND
):
6972 newfn
= mathfn_built_in (TREE_TYPE (arg
), BUILT_IN_LROUND
);
6975 CASE_FLT_FN (BUILT_IN_LLRINT
):
6976 newfn
= mathfn_built_in (TREE_TYPE (arg
), BUILT_IN_LRINT
);
6985 tree newcall
= build_function_call_expr (newfn
, arglist
);
6986 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl
)), newcall
);
6993 /* Fold function call to builtin cabs, cabsf or cabsl. ARGLIST
6994 is the argument list, TYPE is the return type and FNDECL is the
6995 original function DECL. Return NULL_TREE if no if no simplification
6999 fold_builtin_cabs (tree arglist
, tree type
, tree fndecl
)
7003 if (!arglist
|| TREE_CHAIN (arglist
))
7006 arg
= TREE_VALUE (arglist
);
7007 if (TREE_CODE (TREE_TYPE (arg
)) != COMPLEX_TYPE
7008 || TREE_CODE (TREE_TYPE (TREE_TYPE (arg
))) != REAL_TYPE
)
7011 /* Evaluate cabs of a constant at compile-time. */
7012 if (flag_unsafe_math_optimizations
7013 && TREE_CODE (arg
) == COMPLEX_CST
7014 && TREE_CODE (TREE_REALPART (arg
)) == REAL_CST
7015 && TREE_CODE (TREE_IMAGPART (arg
)) == REAL_CST
7016 && ! TREE_CONSTANT_OVERFLOW (TREE_REALPART (arg
))
7017 && ! TREE_CONSTANT_OVERFLOW (TREE_IMAGPART (arg
)))
7019 REAL_VALUE_TYPE r
, i
;
7021 r
= TREE_REAL_CST (TREE_REALPART (arg
));
7022 i
= TREE_REAL_CST (TREE_IMAGPART (arg
));
7024 real_arithmetic (&r
, MULT_EXPR
, &r
, &r
);
7025 real_arithmetic (&i
, MULT_EXPR
, &i
, &i
);
7026 real_arithmetic (&r
, PLUS_EXPR
, &r
, &i
);
7027 if (real_sqrt (&r
, TYPE_MODE (type
), &r
)
7028 || ! flag_trapping_math
)
7029 return build_real (type
, r
);
7032 /* If either part is zero, cabs is fabs of the other. */
7033 if (TREE_CODE (arg
) == COMPLEX_EXPR
7034 && real_zerop (TREE_OPERAND (arg
, 0)))
7035 return fold_build1 (ABS_EXPR
, type
, TREE_OPERAND (arg
, 1));
7036 if (TREE_CODE (arg
) == COMPLEX_EXPR
7037 && real_zerop (TREE_OPERAND (arg
, 1)))
7038 return fold_build1 (ABS_EXPR
, type
, TREE_OPERAND (arg
, 0));
7040 /* Optimize cabs(-z) and cabs(conj(z)) as cabs(z). */
7041 if (TREE_CODE (arg
) == NEGATE_EXPR
7042 || TREE_CODE (arg
) == CONJ_EXPR
)
7044 tree arglist
= build_tree_list (NULL_TREE
, TREE_OPERAND (arg
, 0));
7045 return build_function_call_expr (fndecl
, arglist
);
7048 /* Don't do this when optimizing for size. */
7049 if (flag_unsafe_math_optimizations
7050 && optimize
&& !optimize_size
)
7052 tree sqrtfn
= mathfn_built_in (type
, BUILT_IN_SQRT
);
7054 if (sqrtfn
!= NULL_TREE
)
7056 tree rpart
, ipart
, result
, arglist
;
7058 arg
= builtin_save_expr (arg
);
7060 rpart
= fold_build1 (REALPART_EXPR
, type
, arg
);
7061 ipart
= fold_build1 (IMAGPART_EXPR
, type
, arg
);
7063 rpart
= builtin_save_expr (rpart
);
7064 ipart
= builtin_save_expr (ipart
);
7066 result
= fold_build2 (PLUS_EXPR
, type
,
7067 fold_build2 (MULT_EXPR
, type
,
7069 fold_build2 (MULT_EXPR
, type
,
7072 arglist
= build_tree_list (NULL_TREE
, result
);
7073 return build_function_call_expr (sqrtfn
, arglist
);
7080 /* Fold a builtin function call to sqrt, sqrtf, or sqrtl. Return
7081 NULL_TREE if no simplification can be made. */
7084 fold_builtin_sqrt (tree arglist
, tree type
)
7087 enum built_in_function fcode
;
7088 tree arg
= TREE_VALUE (arglist
);
7090 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
7093 /* Optimize sqrt of constant value. */
7094 if (TREE_CODE (arg
) == REAL_CST
7095 && ! TREE_CONSTANT_OVERFLOW (arg
))
7097 REAL_VALUE_TYPE r
, x
;
7099 x
= TREE_REAL_CST (arg
);
7100 if (real_sqrt (&r
, TYPE_MODE (type
), &x
)
7101 || (!flag_trapping_math
&& !flag_errno_math
))
7102 return build_real (type
, r
);
7105 /* Optimize sqrt(expN(x)) = expN(x*0.5). */
7106 fcode
= builtin_mathfn_code (arg
);
7107 if (flag_unsafe_math_optimizations
&& BUILTIN_EXPONENT_P (fcode
))
7109 tree expfn
= TREE_OPERAND (TREE_OPERAND (arg
, 0), 0);
7110 arg
= fold_build2 (MULT_EXPR
, type
,
7111 TREE_VALUE (TREE_OPERAND (arg
, 1)),
7112 build_real (type
, dconsthalf
));
7113 arglist
= build_tree_list (NULL_TREE
, arg
);
7114 return build_function_call_expr (expfn
, arglist
);
7117 /* Optimize sqrt(Nroot(x)) -> pow(x,1/(2*N)). */
7118 if (flag_unsafe_math_optimizations
&& BUILTIN_ROOT_P (fcode
))
7120 tree powfn
= mathfn_built_in (type
, BUILT_IN_POW
);
7124 tree arg0
= TREE_VALUE (TREE_OPERAND (arg
, 1));
7126 /* The inner root was either sqrt or cbrt. */
7127 REAL_VALUE_TYPE dconstroot
=
7128 BUILTIN_SQRT_P (fcode
) ? dconsthalf
: dconstthird
;
7130 /* Adjust for the outer root. */
7131 SET_REAL_EXP (&dconstroot
, REAL_EXP (&dconstroot
) - 1);
7132 dconstroot
= real_value_truncate (TYPE_MODE (type
), dconstroot
);
7133 tree_root
= build_real (type
, dconstroot
);
7134 arglist
= tree_cons (NULL_TREE
, arg0
,
7135 build_tree_list (NULL_TREE
, tree_root
));
7136 return build_function_call_expr (powfn
, arglist
);
7140 /* Optimize sqrt(pow(x,y)) = pow(|x|,y*0.5). */
7141 if (flag_unsafe_math_optimizations
7142 && (fcode
== BUILT_IN_POW
7143 || fcode
== BUILT_IN_POWF
7144 || fcode
== BUILT_IN_POWL
))
7146 tree powfn
= TREE_OPERAND (TREE_OPERAND (arg
, 0), 0);
7147 tree arg0
= TREE_VALUE (TREE_OPERAND (arg
, 1));
7148 tree arg1
= TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg
, 1)));
7150 if (!tree_expr_nonnegative_p (arg0
))
7151 arg0
= build1 (ABS_EXPR
, type
, arg0
);
7152 narg1
= fold_build2 (MULT_EXPR
, type
, arg1
,
7153 build_real (type
, dconsthalf
));
7154 arglist
= tree_cons (NULL_TREE
, arg0
,
7155 build_tree_list (NULL_TREE
, narg1
));
7156 return build_function_call_expr (powfn
, arglist
);
7162 /* Fold a builtin function call to cbrt, cbrtf, or cbrtl. Return
7163 NULL_TREE if no simplification can be made. */
7165 fold_builtin_cbrt (tree arglist
, tree type
)
7167 tree arg
= TREE_VALUE (arglist
);
7168 const enum built_in_function fcode
= builtin_mathfn_code (arg
);
7171 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
7174 /* Calculate the result when the argument is a constant. */
7175 if ((res
= do_mpfr_arg1 (arg
, type
, mpfr_cbrt
, NULL
, NULL
, 0)))
7178 if (flag_unsafe_math_optimizations
)
7180 /* Optimize cbrt(expN(x)) -> expN(x/3). */
7181 if (BUILTIN_EXPONENT_P (fcode
))
7183 tree expfn
= TREE_OPERAND (TREE_OPERAND (arg
, 0), 0);
7184 const REAL_VALUE_TYPE third_trunc
=
7185 real_value_truncate (TYPE_MODE (type
), dconstthird
);
7186 arg
= fold_build2 (MULT_EXPR
, type
,
7187 TREE_VALUE (TREE_OPERAND (arg
, 1)),
7188 build_real (type
, third_trunc
));
7189 arglist
= build_tree_list (NULL_TREE
, arg
);
7190 return build_function_call_expr (expfn
, arglist
);
7193 /* Optimize cbrt(sqrt(x)) -> pow(x,1/6). */
7194 if (BUILTIN_SQRT_P (fcode
))
7196 tree powfn
= mathfn_built_in (type
, BUILT_IN_POW
);
7200 tree arg0
= TREE_VALUE (TREE_OPERAND (arg
, 1));
7202 REAL_VALUE_TYPE dconstroot
= dconstthird
;
7204 SET_REAL_EXP (&dconstroot
, REAL_EXP (&dconstroot
) - 1);
7205 dconstroot
= real_value_truncate (TYPE_MODE (type
), dconstroot
);
7206 tree_root
= build_real (type
, dconstroot
);
7207 arglist
= tree_cons (NULL_TREE
, arg0
,
7208 build_tree_list (NULL_TREE
, tree_root
));
7209 return build_function_call_expr (powfn
, arglist
);
7213 /* Optimize cbrt(cbrt(x)) -> pow(x,1/9) iff x is nonnegative. */
7214 if (BUILTIN_CBRT_P (fcode
))
7216 tree arg0
= TREE_VALUE (TREE_OPERAND (arg
, 1));
7217 if (tree_expr_nonnegative_p (arg0
))
7219 tree powfn
= mathfn_built_in (type
, BUILT_IN_POW
);
7224 REAL_VALUE_TYPE dconstroot
;
7226 real_arithmetic (&dconstroot
, MULT_EXPR
, &dconstthird
, &dconstthird
);
7227 dconstroot
= real_value_truncate (TYPE_MODE (type
), dconstroot
);
7228 tree_root
= build_real (type
, dconstroot
);
7229 arglist
= tree_cons (NULL_TREE
, arg0
,
7230 build_tree_list (NULL_TREE
, tree_root
));
7231 return build_function_call_expr (powfn
, arglist
);
7236 /* Optimize cbrt(pow(x,y)) -> pow(x,y/3) iff x is nonnegative. */
7237 if (fcode
== BUILT_IN_POW
|| fcode
== BUILT_IN_POWF
7238 || fcode
== BUILT_IN_POWL
)
7240 tree arg00
= TREE_VALUE (TREE_OPERAND (arg
, 1));
7241 tree arg01
= TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg
, 1)));
7242 if (tree_expr_nonnegative_p (arg00
))
7244 tree powfn
= TREE_OPERAND (TREE_OPERAND (arg
, 0), 0);
7245 const REAL_VALUE_TYPE dconstroot
7246 = real_value_truncate (TYPE_MODE (type
), dconstthird
);
7247 tree narg01
= fold_build2 (MULT_EXPR
, type
, arg01
,
7248 build_real (type
, dconstroot
));
7249 arglist
= tree_cons (NULL_TREE
, arg00
,
7250 build_tree_list (NULL_TREE
, narg01
));
7251 return build_function_call_expr (powfn
, arglist
);
7258 /* Fold function call to builtin cos, cosf, or cosl. Return
7259 NULL_TREE if no simplification can be made. */
7261 fold_builtin_cos (tree arglist
, tree type
, tree fndecl
)
7263 tree arg
= TREE_VALUE (arglist
);
7266 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
7269 /* Calculate the result when the argument is a constant. */
7270 if ((res
= do_mpfr_arg1 (arg
, type
, mpfr_cos
, NULL
, NULL
, 0)))
7273 /* Optimize cos(-x) into cos (x). */
7274 if ((narg
= fold_strip_sign_ops (arg
)))
7275 return build_function_call_expr (fndecl
,
7276 build_tree_list (NULL_TREE
, narg
));
7281 /* Fold function call to builtin cosh, coshf, or coshl. Return
7282 NULL_TREE if no simplification can be made. */
7284 fold_builtin_cosh (tree arglist
, tree type
, tree fndecl
)
7286 if (validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
7288 tree arg
= TREE_VALUE (arglist
);
7291 /* Calculate the result when the argument is a constant. */
7292 if ((res
= do_mpfr_arg1 (arg
, type
, mpfr_cosh
, NULL
, NULL
, 0)))
7295 /* Optimize cosh(-x) into cosh (x). */
7296 if ((narg
= fold_strip_sign_ops (arg
)))
7297 return build_function_call_expr (fndecl
,
7298 build_tree_list (NULL_TREE
, narg
));
7304 /* Fold function call to builtin tan, tanf, or tanl. Return
7305 NULL_TREE if no simplification can be made. */
7307 fold_builtin_tan (tree arglist
, tree type
)
7309 enum built_in_function fcode
;
7310 tree arg
= TREE_VALUE (arglist
);
7313 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
7316 /* Calculate the result when the argument is a constant. */
7317 if ((res
= do_mpfr_arg1 (arg
, type
, mpfr_tan
, NULL
, NULL
, 0)))
7320 /* Optimize tan(atan(x)) = x. */
7321 fcode
= builtin_mathfn_code (arg
);
7322 if (flag_unsafe_math_optimizations
7323 && (fcode
== BUILT_IN_ATAN
7324 || fcode
== BUILT_IN_ATANF
7325 || fcode
== BUILT_IN_ATANL
))
7326 return TREE_VALUE (TREE_OPERAND (arg
, 1));
7331 /* Fold function call to builtin sincos, sincosf, or sincosl. Return
7332 NULL_TREE if no simplification can be made. */
7335 fold_builtin_sincos (tree arglist
)
7337 tree type
, arg0
, arg1
, arg2
;
7340 if (!validate_arglist (arglist
, REAL_TYPE
, POINTER_TYPE
,
7341 POINTER_TYPE
, VOID_TYPE
))
7344 arg0
= TREE_VALUE (arglist
);
7345 type
= TREE_TYPE (arg0
);
7346 arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
7347 arg2
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
7349 /* Calculate the result when the argument is a constant. */
7350 if ((res
= do_mpfr_sincos (arg0
, arg1
, arg2
)))
7353 /* Canonicalize sincos to cexpi. */
7354 fn
= mathfn_built_in (type
, BUILT_IN_CEXPI
);
7358 call
= build_function_call_expr (fn
, build_tree_list (NULL_TREE
, arg0
));
7359 call
= builtin_save_expr (call
);
7361 return build2 (COMPOUND_EXPR
, type
,
7362 build2 (MODIFY_EXPR
, void_type_node
,
7363 build_fold_indirect_ref (arg1
),
7364 build1 (IMAGPART_EXPR
, type
, call
)),
7365 build2 (MODIFY_EXPR
, void_type_node
,
7366 build_fold_indirect_ref (arg2
),
7367 build1 (REALPART_EXPR
, type
, call
)));
7370 /* Fold function call to builtin cexp, cexpf, or cexpl. Return
7371 NULL_TREE if no simplification can be made. */
7374 fold_builtin_cexp (tree arglist
, tree type
)
7377 tree realp
, imagp
, ifn
;
7379 if (!validate_arglist (arglist
, COMPLEX_TYPE
, VOID_TYPE
))
7382 arg0
= TREE_VALUE (arglist
);
7383 rtype
= TREE_TYPE (TREE_TYPE (arg0
));
7385 /* In case we can figure out the real part of arg0 and it is constant zero
7387 ifn
= mathfn_built_in (rtype
, BUILT_IN_CEXPI
);
7391 if ((realp
= fold_unary (REALPART_EXPR
, rtype
, arg0
))
7392 && real_zerop (realp
))
7394 tree narg
= fold_build1 (IMAGPART_EXPR
, rtype
, arg0
);
7395 return build_function_call_expr (ifn
, build_tree_list (NULL_TREE
, narg
));
7398 /* In case we can easily decompose real and imaginary parts split cexp
7399 to exp (r) * cexpi (i). */
7400 if (flag_unsafe_math_optimizations
7403 tree rfn
, rcall
, icall
;
7405 rfn
= mathfn_built_in (rtype
, BUILT_IN_EXP
);
7409 imagp
= fold_unary (IMAGPART_EXPR
, rtype
, arg0
);
7413 icall
= build_function_call_expr (ifn
,
7414 build_tree_list (NULL_TREE
, imagp
));
7415 icall
= builtin_save_expr (icall
);
7416 rcall
= build_function_call_expr (rfn
,
7417 build_tree_list (NULL_TREE
, realp
));
7418 rcall
= builtin_save_expr (rcall
);
7419 return build2 (COMPLEX_EXPR
, type
,
7420 build2 (MULT_EXPR
, rtype
,
7422 build1 (REALPART_EXPR
, rtype
, icall
)),
7423 build2 (MULT_EXPR
, rtype
,
7425 build1 (IMAGPART_EXPR
, rtype
, icall
)));
7431 /* Fold function call to builtin trunc, truncf or truncl. Return
7432 NULL_TREE if no simplification can be made. */
7435 fold_builtin_trunc (tree fndecl
, tree arglist
)
7439 if (! validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
7442 /* Optimize trunc of constant value. */
7443 arg
= TREE_VALUE (arglist
);
7444 if (TREE_CODE (arg
) == REAL_CST
&& ! TREE_CONSTANT_OVERFLOW (arg
))
7446 REAL_VALUE_TYPE r
, x
;
7447 tree type
= TREE_TYPE (TREE_TYPE (fndecl
));
7449 x
= TREE_REAL_CST (arg
);
7450 real_trunc (&r
, TYPE_MODE (type
), &x
);
7451 return build_real (type
, r
);
7454 return fold_trunc_transparent_mathfn (fndecl
, arglist
);
7457 /* Fold function call to builtin floor, floorf or floorl. Return
7458 NULL_TREE if no simplification can be made. */
7461 fold_builtin_floor (tree fndecl
, tree arglist
)
7465 if (! validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
7468 /* Optimize floor of constant value. */
7469 arg
= TREE_VALUE (arglist
);
7470 if (TREE_CODE (arg
) == REAL_CST
&& ! TREE_CONSTANT_OVERFLOW (arg
))
7474 x
= TREE_REAL_CST (arg
);
7475 if (! REAL_VALUE_ISNAN (x
) || ! flag_errno_math
)
7477 tree type
= TREE_TYPE (TREE_TYPE (fndecl
));
7480 real_floor (&r
, TYPE_MODE (type
), &x
);
7481 return build_real (type
, r
);
7485 /* Fold floor (x) where x is nonnegative to trunc (x). */
7486 if (tree_expr_nonnegative_p (arg
))
7488 tree truncfn
= mathfn_built_in (TREE_TYPE (arg
), BUILT_IN_TRUNC
);
7490 return build_function_call_expr (truncfn
, arglist
);
7493 return fold_trunc_transparent_mathfn (fndecl
, arglist
);
7496 /* Fold function call to builtin ceil, ceilf or ceill. Return
7497 NULL_TREE if no simplification can be made. */
7500 fold_builtin_ceil (tree fndecl
, tree arglist
)
7504 if (! validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
7507 /* Optimize ceil of constant value. */
7508 arg
= TREE_VALUE (arglist
);
7509 if (TREE_CODE (arg
) == REAL_CST
&& ! TREE_CONSTANT_OVERFLOW (arg
))
7513 x
= TREE_REAL_CST (arg
);
7514 if (! REAL_VALUE_ISNAN (x
) || ! flag_errno_math
)
7516 tree type
= TREE_TYPE (TREE_TYPE (fndecl
));
7519 real_ceil (&r
, TYPE_MODE (type
), &x
);
7520 return build_real (type
, r
);
7524 return fold_trunc_transparent_mathfn (fndecl
, arglist
);
7527 /* Fold function call to builtin round, roundf or roundl. Return
7528 NULL_TREE if no simplification can be made. */
7531 fold_builtin_round (tree fndecl
, tree arglist
)
7535 if (! validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
7538 /* Optimize round of constant value. */
7539 arg
= TREE_VALUE (arglist
);
7540 if (TREE_CODE (arg
) == REAL_CST
&& ! TREE_CONSTANT_OVERFLOW (arg
))
7544 x
= TREE_REAL_CST (arg
);
7545 if (! REAL_VALUE_ISNAN (x
) || ! flag_errno_math
)
7547 tree type
= TREE_TYPE (TREE_TYPE (fndecl
));
7550 real_round (&r
, TYPE_MODE (type
), &x
);
7551 return build_real (type
, r
);
7555 return fold_trunc_transparent_mathfn (fndecl
, arglist
);
7558 /* Fold function call to builtin lround, lroundf or lroundl (or the
7559 corresponding long long versions) and other rounding functions.
7560 Return NULL_TREE if no simplification can be made. */
7563 fold_builtin_int_roundingfn (tree fndecl
, tree arglist
)
7567 if (! validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
7570 /* Optimize lround of constant value. */
7571 arg
= TREE_VALUE (arglist
);
7572 if (TREE_CODE (arg
) == REAL_CST
&& ! TREE_CONSTANT_OVERFLOW (arg
))
7574 const REAL_VALUE_TYPE x
= TREE_REAL_CST (arg
);
7576 if (! REAL_VALUE_ISNAN (x
) && ! REAL_VALUE_ISINF (x
))
7578 tree itype
= TREE_TYPE (TREE_TYPE (fndecl
));
7579 tree ftype
= TREE_TYPE (arg
), result
;
7580 HOST_WIDE_INT hi
, lo
;
7583 switch (DECL_FUNCTION_CODE (fndecl
))
7585 CASE_FLT_FN (BUILT_IN_LFLOOR
):
7586 CASE_FLT_FN (BUILT_IN_LLFLOOR
):
7587 real_floor (&r
, TYPE_MODE (ftype
), &x
);
7590 CASE_FLT_FN (BUILT_IN_LCEIL
):
7591 CASE_FLT_FN (BUILT_IN_LLCEIL
):
7592 real_ceil (&r
, TYPE_MODE (ftype
), &x
);
7595 CASE_FLT_FN (BUILT_IN_LROUND
):
7596 CASE_FLT_FN (BUILT_IN_LLROUND
):
7597 real_round (&r
, TYPE_MODE (ftype
), &x
);
7604 REAL_VALUE_TO_INT (&lo
, &hi
, r
);
7605 result
= build_int_cst_wide (NULL_TREE
, lo
, hi
);
7606 if (int_fits_type_p (result
, itype
))
7607 return fold_convert (itype
, result
);
7611 switch (DECL_FUNCTION_CODE (fndecl
))
7613 CASE_FLT_FN (BUILT_IN_LFLOOR
):
7614 CASE_FLT_FN (BUILT_IN_LLFLOOR
):
7615 /* Fold lfloor (x) where x is nonnegative to FIX_TRUNC (x). */
7616 if (tree_expr_nonnegative_p (arg
))
7617 return fold_build1 (FIX_TRUNC_EXPR
, TREE_TYPE (TREE_TYPE (fndecl
)),
7623 return fold_fixed_mathfn (fndecl
, arglist
);
7626 /* Fold function call to builtin ffs, clz, ctz, popcount and parity
7627 and their long and long long variants (i.e. ffsl and ffsll).
7628 Return NULL_TREE if no simplification can be made. */
7631 fold_builtin_bitop (tree fndecl
, tree arglist
)
7635 if (! validate_arglist (arglist
, INTEGER_TYPE
, VOID_TYPE
))
7638 /* Optimize for constant argument. */
7639 arg
= TREE_VALUE (arglist
);
7640 if (TREE_CODE (arg
) == INTEGER_CST
&& ! TREE_CONSTANT_OVERFLOW (arg
))
7642 HOST_WIDE_INT hi
, width
, result
;
7643 unsigned HOST_WIDE_INT lo
;
7646 type
= TREE_TYPE (arg
);
7647 width
= TYPE_PRECISION (type
);
7648 lo
= TREE_INT_CST_LOW (arg
);
7650 /* Clear all the bits that are beyond the type's precision. */
7651 if (width
> HOST_BITS_PER_WIDE_INT
)
7653 hi
= TREE_INT_CST_HIGH (arg
);
7654 if (width
< 2 * HOST_BITS_PER_WIDE_INT
)
7655 hi
&= ~((HOST_WIDE_INT
) (-1) >> (width
- HOST_BITS_PER_WIDE_INT
));
7660 if (width
< HOST_BITS_PER_WIDE_INT
)
7661 lo
&= ~((unsigned HOST_WIDE_INT
) (-1) << width
);
7664 switch (DECL_FUNCTION_CODE (fndecl
))
7666 CASE_INT_FN (BUILT_IN_FFS
):
7668 result
= exact_log2 (lo
& -lo
) + 1;
7670 result
= HOST_BITS_PER_WIDE_INT
+ exact_log2 (hi
& -hi
) + 1;
7675 CASE_INT_FN (BUILT_IN_CLZ
):
7677 result
= width
- floor_log2 (hi
) - 1 - HOST_BITS_PER_WIDE_INT
;
7679 result
= width
- floor_log2 (lo
) - 1;
7680 else if (! CLZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type
), result
))
7684 CASE_INT_FN (BUILT_IN_CTZ
):
7686 result
= exact_log2 (lo
& -lo
);
7688 result
= HOST_BITS_PER_WIDE_INT
+ exact_log2 (hi
& -hi
);
7689 else if (! CTZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type
), result
))
7693 CASE_INT_FN (BUILT_IN_POPCOUNT
):
7696 result
++, lo
&= lo
- 1;
7698 result
++, hi
&= hi
- 1;
7701 CASE_INT_FN (BUILT_IN_PARITY
):
7704 result
++, lo
&= lo
- 1;
7706 result
++, hi
&= hi
- 1;
7714 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl
)), result
);
7720 /* Fold function call to builtin_bswap and the long and long long
7721 variants. Return NULL_TREE if no simplification can be made. */
7723 fold_builtin_bswap (tree fndecl
, tree arglist
)
7727 if (! validate_arglist (arglist
, INTEGER_TYPE
, VOID_TYPE
))
7730 /* Optimize constant value. */
7731 arg
= TREE_VALUE (arglist
);
7732 if (TREE_CODE (arg
) == INTEGER_CST
&& ! TREE_CONSTANT_OVERFLOW (arg
))
7734 HOST_WIDE_INT hi
, width
, r_hi
= 0;
7735 unsigned HOST_WIDE_INT lo
, r_lo
= 0;
7738 type
= TREE_TYPE (arg
);
7739 width
= TYPE_PRECISION (type
);
7740 lo
= TREE_INT_CST_LOW (arg
);
7741 hi
= TREE_INT_CST_HIGH (arg
);
7743 switch (DECL_FUNCTION_CODE (fndecl
))
7745 case BUILT_IN_BSWAP32
:
7746 case BUILT_IN_BSWAP64
:
7750 for (s
= 0; s
< width
; s
+= 8)
7752 int d
= width
- s
- 8;
7753 unsigned HOST_WIDE_INT byte
;
7755 if (s
< HOST_BITS_PER_WIDE_INT
)
7756 byte
= (lo
>> s
) & 0xff;
7758 byte
= (hi
>> (s
- HOST_BITS_PER_WIDE_INT
)) & 0xff;
7760 if (d
< HOST_BITS_PER_WIDE_INT
)
7763 r_hi
|= byte
<< (d
- HOST_BITS_PER_WIDE_INT
);
7773 if (width
< HOST_BITS_PER_WIDE_INT
)
7774 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl
)), r_lo
);
7776 return build_int_cst_wide (TREE_TYPE (TREE_TYPE (fndecl
)), r_lo
, r_hi
);
7781 /* Return true if EXPR is the real constant contained in VALUE. */
7784 real_dconstp (tree expr
, const REAL_VALUE_TYPE
*value
)
7788 return ((TREE_CODE (expr
) == REAL_CST
7789 && ! TREE_CONSTANT_OVERFLOW (expr
)
7790 && REAL_VALUES_EQUAL (TREE_REAL_CST (expr
), *value
))
7791 || (TREE_CODE (expr
) == COMPLEX_CST
7792 && real_dconstp (TREE_REALPART (expr
), value
)
7793 && real_zerop (TREE_IMAGPART (expr
))));
7796 /* A subroutine of fold_builtin to fold the various logarithmic
7797 functions. Return NULL_TREE if no simplification can me made.
7798 FUNC is the corresponding MPFR logarithm function. */
7801 fold_builtin_logarithm (tree fndecl
, tree arglist
,
7802 int (*func
)(mpfr_ptr
, mpfr_srcptr
, mp_rnd_t
))
7804 if (validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
7806 tree type
= TREE_TYPE (TREE_TYPE (fndecl
));
7807 tree arg
= TREE_VALUE (arglist
);
7809 const enum built_in_function fcode
= builtin_mathfn_code (arg
);
7811 /* Optimize log(e) = 1.0. We're never passed an exact 'e',
7812 instead we'll look for 'e' truncated to MODE. So only do
7813 this if flag_unsafe_math_optimizations is set. */
7814 if (flag_unsafe_math_optimizations
&& func
== mpfr_log
)
7816 const REAL_VALUE_TYPE e_truncated
=
7817 real_value_truncate (TYPE_MODE (type
), dconste
);
7818 if (real_dconstp (arg
, &e_truncated
))
7819 return build_real (type
, dconst1
);
7822 /* Calculate the result when the argument is a constant. */
7823 if ((res
= do_mpfr_arg1 (arg
, type
, func
, &dconst0
, NULL
, false)))
7826 /* Special case, optimize logN(expN(x)) = x. */
7827 if (flag_unsafe_math_optimizations
7828 && ((func
== mpfr_log
7829 && (fcode
== BUILT_IN_EXP
7830 || fcode
== BUILT_IN_EXPF
7831 || fcode
== BUILT_IN_EXPL
))
7832 || (func
== mpfr_log2
7833 && (fcode
== BUILT_IN_EXP2
7834 || fcode
== BUILT_IN_EXP2F
7835 || fcode
== BUILT_IN_EXP2L
))
7836 || (func
== mpfr_log10
&& (BUILTIN_EXP10_P (fcode
)))))
7837 return fold_convert (type
, TREE_VALUE (TREE_OPERAND (arg
, 1)));
7839 /* Optimize logN(func()) for various exponential functions. We
7840 want to determine the value "x" and the power "exponent" in
7841 order to transform logN(x**exponent) into exponent*logN(x). */
7842 if (flag_unsafe_math_optimizations
)
7844 tree exponent
= 0, x
= 0;
7848 CASE_FLT_FN (BUILT_IN_EXP
):
7849 /* Prepare to do logN(exp(exponent) -> exponent*logN(e). */
7850 x
= build_real (type
,
7851 real_value_truncate (TYPE_MODE (type
), dconste
));
7852 exponent
= TREE_VALUE (TREE_OPERAND (arg
, 1));
7854 CASE_FLT_FN (BUILT_IN_EXP2
):
7855 /* Prepare to do logN(exp2(exponent) -> exponent*logN(2). */
7856 x
= build_real (type
, dconst2
);
7857 exponent
= TREE_VALUE (TREE_OPERAND (arg
, 1));
7859 CASE_FLT_FN (BUILT_IN_EXP10
):
7860 CASE_FLT_FN (BUILT_IN_POW10
):
7861 /* Prepare to do logN(exp10(exponent) -> exponent*logN(10). */
7862 x
= build_real (type
, dconst10
);
7863 exponent
= TREE_VALUE (TREE_OPERAND (arg
, 1));
7865 CASE_FLT_FN (BUILT_IN_SQRT
):
7866 /* Prepare to do logN(sqrt(x) -> 0.5*logN(x). */
7867 x
= TREE_VALUE (TREE_OPERAND (arg
, 1));
7868 exponent
= build_real (type
, dconsthalf
);
7870 CASE_FLT_FN (BUILT_IN_CBRT
):
7871 /* Prepare to do logN(cbrt(x) -> (1/3)*logN(x). */
7872 x
= TREE_VALUE (TREE_OPERAND (arg
, 1));
7873 exponent
= build_real (type
, real_value_truncate (TYPE_MODE (type
),
7876 CASE_FLT_FN (BUILT_IN_POW
):
7877 /* Prepare to do logN(pow(x,exponent) -> exponent*logN(x). */
7878 x
= TREE_VALUE (TREE_OPERAND (arg
, 1));
7879 exponent
= TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg
, 1)));
7885 /* Now perform the optimization. */
7889 arglist
= build_tree_list (NULL_TREE
, x
);
7890 logfn
= build_function_call_expr (fndecl
, arglist
);
7891 return fold_build2 (MULT_EXPR
, type
, exponent
, logfn
);
7899 /* Fold a builtin function call to hypot, hypotf, or hypotl. Return
7900 NULL_TREE if no simplification can be made. */
7903 fold_builtin_hypot (tree fndecl
, tree arglist
, tree type
)
7905 tree arg0
= TREE_VALUE (arglist
);
7906 tree arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
7907 tree res
, narg0
, narg1
;
7909 if (!validate_arglist (arglist
, REAL_TYPE
, REAL_TYPE
, VOID_TYPE
))
7912 /* Calculate the result when the argument is a constant. */
7913 if ((res
= do_mpfr_arg2 (arg0
, arg1
, type
, mpfr_hypot
)))
7916 /* If either argument to hypot has a negate or abs, strip that off.
7917 E.g. hypot(-x,fabs(y)) -> hypot(x,y). */
7918 narg0
= fold_strip_sign_ops (arg0
);
7919 narg1
= fold_strip_sign_ops (arg1
);
7922 tree narglist
= tree_cons (NULL_TREE
, narg0
? narg0
: arg0
,
7923 build_tree_list (NULL_TREE
,
7924 narg1
? narg1
: arg1
));
7925 return build_function_call_expr (fndecl
, narglist
);
7928 /* If either argument is zero, hypot is fabs of the other. */
7929 if (real_zerop (arg0
))
7930 return fold_build1 (ABS_EXPR
, type
, arg1
);
7931 else if (real_zerop (arg1
))
7932 return fold_build1 (ABS_EXPR
, type
, arg0
);
7934 /* hypot(x,x) -> fabs(x)*sqrt(2). */
7935 if (flag_unsafe_math_optimizations
7936 && operand_equal_p (arg0
, arg1
, OEP_PURE_SAME
))
7938 REAL_VALUE_TYPE sqrt2
;
7940 real_sqrt (&sqrt2
, TYPE_MODE (type
), &dconst2
);
7941 return fold_build2 (MULT_EXPR
, type
,
7942 fold_build1 (ABS_EXPR
, type
, arg0
),
7943 build_real (type
, sqrt2
));
7950 /* Fold a builtin function call to pow, powf, or powl. Return
7951 NULL_TREE if no simplification can be made. */
7953 fold_builtin_pow (tree fndecl
, tree arglist
, tree type
)
7955 tree arg0
= TREE_VALUE (arglist
);
7956 tree arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
7959 if (!validate_arglist (arglist
, REAL_TYPE
, REAL_TYPE
, VOID_TYPE
))
7962 /* Calculate the result when the argument is a constant. */
7963 if ((res
= do_mpfr_arg2 (arg0
, arg1
, type
, mpfr_pow
)))
7966 /* Optimize pow(1.0,y) = 1.0. */
7967 if (real_onep (arg0
))
7968 return omit_one_operand (type
, build_real (type
, dconst1
), arg1
);
7970 if (TREE_CODE (arg1
) == REAL_CST
7971 && ! TREE_CONSTANT_OVERFLOW (arg1
))
7973 REAL_VALUE_TYPE cint
;
7977 c
= TREE_REAL_CST (arg1
);
7979 /* Optimize pow(x,0.0) = 1.0. */
7980 if (REAL_VALUES_EQUAL (c
, dconst0
))
7981 return omit_one_operand (type
, build_real (type
, dconst1
),
7984 /* Optimize pow(x,1.0) = x. */
7985 if (REAL_VALUES_EQUAL (c
, dconst1
))
7988 /* Optimize pow(x,-1.0) = 1.0/x. */
7989 if (REAL_VALUES_EQUAL (c
, dconstm1
))
7990 return fold_build2 (RDIV_EXPR
, type
,
7991 build_real (type
, dconst1
), arg0
);
7993 /* Optimize pow(x,0.5) = sqrt(x). */
7994 if (flag_unsafe_math_optimizations
7995 && REAL_VALUES_EQUAL (c
, dconsthalf
))
7997 tree sqrtfn
= mathfn_built_in (type
, BUILT_IN_SQRT
);
7999 if (sqrtfn
!= NULL_TREE
)
8001 tree arglist
= build_tree_list (NULL_TREE
, arg0
);
8002 return build_function_call_expr (sqrtfn
, arglist
);
8006 /* Optimize pow(x,1.0/3.0) = cbrt(x). */
8007 if (flag_unsafe_math_optimizations
)
8009 const REAL_VALUE_TYPE dconstroot
8010 = real_value_truncate (TYPE_MODE (type
), dconstthird
);
8012 if (REAL_VALUES_EQUAL (c
, dconstroot
))
8014 tree cbrtfn
= mathfn_built_in (type
, BUILT_IN_CBRT
);
8015 if (cbrtfn
!= NULL_TREE
)
8017 tree arglist
= build_tree_list (NULL_TREE
, arg0
);
8018 return build_function_call_expr (cbrtfn
, arglist
);
8023 /* Check for an integer exponent. */
8024 n
= real_to_integer (&c
);
8025 real_from_integer (&cint
, VOIDmode
, n
, n
< 0 ? -1 : 0, 0);
8026 if (real_identical (&c
, &cint
))
8028 /* Attempt to evaluate pow at compile-time. */
8029 if (TREE_CODE (arg0
) == REAL_CST
8030 && ! TREE_CONSTANT_OVERFLOW (arg0
))
8035 x
= TREE_REAL_CST (arg0
);
8036 inexact
= real_powi (&x
, TYPE_MODE (type
), &x
, n
);
8037 if (flag_unsafe_math_optimizations
|| !inexact
)
8038 return build_real (type
, x
);
8041 /* Strip sign ops from even integer powers. */
8042 if ((n
& 1) == 0 && flag_unsafe_math_optimizations
)
8044 tree narg0
= fold_strip_sign_ops (arg0
);
8047 arglist
= build_tree_list (NULL_TREE
, arg1
);
8048 arglist
= tree_cons (NULL_TREE
, narg0
, arglist
);
8049 return build_function_call_expr (fndecl
, arglist
);
8055 if (flag_unsafe_math_optimizations
)
8057 const enum built_in_function fcode
= builtin_mathfn_code (arg0
);
8059 /* Optimize pow(expN(x),y) = expN(x*y). */
8060 if (BUILTIN_EXPONENT_P (fcode
))
8062 tree expfn
= TREE_OPERAND (TREE_OPERAND (arg0
, 0), 0);
8063 tree arg
= TREE_VALUE (TREE_OPERAND (arg0
, 1));
8064 arg
= fold_build2 (MULT_EXPR
, type
, arg
, arg1
);
8065 arglist
= build_tree_list (NULL_TREE
, arg
);
8066 return build_function_call_expr (expfn
, arglist
);
8069 /* Optimize pow(sqrt(x),y) = pow(x,y*0.5). */
8070 if (BUILTIN_SQRT_P (fcode
))
8072 tree narg0
= TREE_VALUE (TREE_OPERAND (arg0
, 1));
8073 tree narg1
= fold_build2 (MULT_EXPR
, type
, arg1
,
8074 build_real (type
, dconsthalf
));
8076 arglist
= tree_cons (NULL_TREE
, narg0
,
8077 build_tree_list (NULL_TREE
, narg1
));
8078 return build_function_call_expr (fndecl
, arglist
);
8081 /* Optimize pow(cbrt(x),y) = pow(x,y/3) iff x is nonnegative. */
8082 if (BUILTIN_CBRT_P (fcode
))
8084 tree arg
= TREE_VALUE (TREE_OPERAND (arg0
, 1));
8085 if (tree_expr_nonnegative_p (arg
))
8087 const REAL_VALUE_TYPE dconstroot
8088 = real_value_truncate (TYPE_MODE (type
), dconstthird
);
8089 tree narg1
= fold_build2 (MULT_EXPR
, type
, arg1
,
8090 build_real (type
, dconstroot
));
8091 arglist
= tree_cons (NULL_TREE
, arg
,
8092 build_tree_list (NULL_TREE
, narg1
));
8093 return build_function_call_expr (fndecl
, arglist
);
8097 /* Optimize pow(pow(x,y),z) = pow(x,y*z). */
8098 if (fcode
== BUILT_IN_POW
|| fcode
== BUILT_IN_POWF
8099 || fcode
== BUILT_IN_POWL
)
8101 tree arg00
= TREE_VALUE (TREE_OPERAND (arg0
, 1));
8102 tree arg01
= TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg0
, 1)));
8103 tree narg1
= fold_build2 (MULT_EXPR
, type
, arg01
, arg1
);
8104 arglist
= tree_cons (NULL_TREE
, arg00
,
8105 build_tree_list (NULL_TREE
, narg1
));
8106 return build_function_call_expr (fndecl
, arglist
);
8113 /* Fold a builtin function call to powi, powif, or powil. Return
8114 NULL_TREE if no simplification can be made. */
8116 fold_builtin_powi (tree fndecl ATTRIBUTE_UNUSED
, tree arglist
, tree type
)
8118 tree arg0
= TREE_VALUE (arglist
);
8119 tree arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
8121 if (!validate_arglist (arglist
, REAL_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
8124 /* Optimize pow(1.0,y) = 1.0. */
8125 if (real_onep (arg0
))
8126 return omit_one_operand (type
, build_real (type
, dconst1
), arg1
);
8128 if (host_integerp (arg1
, 0))
8130 HOST_WIDE_INT c
= TREE_INT_CST_LOW (arg1
);
8132 /* Evaluate powi at compile-time. */
8133 if (TREE_CODE (arg0
) == REAL_CST
8134 && ! TREE_CONSTANT_OVERFLOW (arg0
))
8137 x
= TREE_REAL_CST (arg0
);
8138 real_powi (&x
, TYPE_MODE (type
), &x
, c
);
8139 return build_real (type
, x
);
8142 /* Optimize pow(x,0) = 1.0. */
8144 return omit_one_operand (type
, build_real (type
, dconst1
),
8147 /* Optimize pow(x,1) = x. */
8151 /* Optimize pow(x,-1) = 1.0/x. */
8153 return fold_build2 (RDIV_EXPR
, type
,
8154 build_real (type
, dconst1
), arg0
);
8160 /* A subroutine of fold_builtin to fold the various exponent
8161 functions. Return NULL_TREE if no simplification can me made.
8162 FUNC is the corresponding MPFR exponent function. */
8165 fold_builtin_exponent (tree fndecl
, tree arglist
,
8166 int (*func
)(mpfr_ptr
, mpfr_srcptr
, mp_rnd_t
))
8168 if (validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
8170 tree type
= TREE_TYPE (TREE_TYPE (fndecl
));
8171 tree arg
= TREE_VALUE (arglist
);
8174 /* Calculate the result when the argument is a constant. */
8175 if ((res
= do_mpfr_arg1 (arg
, type
, func
, NULL
, NULL
, 0)))
8178 /* Optimize expN(logN(x)) = x. */
8179 if (flag_unsafe_math_optimizations
)
8181 const enum built_in_function fcode
= builtin_mathfn_code (arg
);
8183 if ((func
== mpfr_exp
8184 && (fcode
== BUILT_IN_LOG
8185 || fcode
== BUILT_IN_LOGF
8186 || fcode
== BUILT_IN_LOGL
))
8187 || (func
== mpfr_exp2
8188 && (fcode
== BUILT_IN_LOG2
8189 || fcode
== BUILT_IN_LOG2F
8190 || fcode
== BUILT_IN_LOG2L
))
8191 || (func
== mpfr_exp10
8192 && (fcode
== BUILT_IN_LOG10
8193 || fcode
== BUILT_IN_LOG10F
8194 || fcode
== BUILT_IN_LOG10L
)))
8195 return fold_convert (type
, TREE_VALUE (TREE_OPERAND (arg
, 1)));
8202 /* Return true if VAR is a VAR_DECL or a component thereof. */
8205 var_decl_component_p (tree var
)
8208 while (handled_component_p (inner
))
8209 inner
= TREE_OPERAND (inner
, 0);
8210 return SSA_VAR_P (inner
);
8213 /* Fold function call to builtin memset. Return
8214 NULL_TREE if no simplification can be made. */
8217 fold_builtin_memset (tree arglist
, tree type
, bool ignore
)
8219 tree dest
, c
, len
, var
, ret
;
8220 unsigned HOST_WIDE_INT length
, cval
;
8222 if (!validate_arglist (arglist
,
8223 POINTER_TYPE
, INTEGER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
8226 dest
= TREE_VALUE (arglist
);
8227 c
= TREE_VALUE (TREE_CHAIN (arglist
));
8228 len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
8230 if (! host_integerp (len
, 1))
8233 /* If the LEN parameter is zero, return DEST. */
8234 if (integer_zerop (len
))
8235 return omit_one_operand (type
, dest
, c
);
8237 if (! host_integerp (c
, 1) || TREE_SIDE_EFFECTS (dest
))
8242 if (TREE_CODE (var
) != ADDR_EXPR
)
8245 var
= TREE_OPERAND (var
, 0);
8246 if (TREE_THIS_VOLATILE (var
))
8249 if (!INTEGRAL_TYPE_P (TREE_TYPE (var
))
8250 && !POINTER_TYPE_P (TREE_TYPE (var
)))
8253 if (! var_decl_component_p (var
))
8256 length
= tree_low_cst (len
, 1);
8257 if (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (var
))) != length
8258 || get_pointer_alignment (dest
, BIGGEST_ALIGNMENT
) / BITS_PER_UNIT
8262 if (length
> HOST_BITS_PER_WIDE_INT
/ BITS_PER_UNIT
)
8265 if (integer_zerop (c
))
8269 if (CHAR_BIT
!= 8 || BITS_PER_UNIT
!= 8 || HOST_BITS_PER_WIDE_INT
> 64)
8272 cval
= tree_low_cst (c
, 1);
8276 cval
|= (cval
<< 31) << 1;
8279 ret
= build_int_cst_type (TREE_TYPE (var
), cval
);
8280 ret
= build2 (GIMPLE_MODIFY_STMT
, TREE_TYPE (var
), var
, ret
);
8284 return omit_one_operand (type
, dest
, ret
);
8287 /* Fold function call to builtin memset. Return
8288 NULL_TREE if no simplification can be made. */
8291 fold_builtin_bzero (tree arglist
, bool ignore
)
8293 tree dest
, size
, newarglist
;
8295 if (!validate_arglist (arglist
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
8301 dest
= TREE_VALUE (arglist
);
8302 size
= TREE_VALUE (TREE_CHAIN (arglist
));
8304 /* New argument list transforming bzero(ptr x, int y) to
8305 memset(ptr x, int 0, size_t y). This is done this way
8306 so that if it isn't expanded inline, we fallback to
8307 calling bzero instead of memset. */
8309 newarglist
= build_tree_list (NULL_TREE
, fold_convert (sizetype
, size
));
8310 newarglist
= tree_cons (NULL_TREE
, integer_zero_node
, newarglist
);
8311 newarglist
= tree_cons (NULL_TREE
, dest
, newarglist
);
8312 return fold_builtin_memset (newarglist
, void_type_node
, ignore
);
8315 /* Fold function call to builtin mem{{,p}cpy,move}. Return
8316 NULL_TREE if no simplification can be made.
8317 If ENDP is 0, return DEST (like memcpy).
8318 If ENDP is 1, return DEST+LEN (like mempcpy).
8319 If ENDP is 2, return DEST+LEN-1 (like stpcpy).
8320 If ENDP is 3, return DEST, additionally *SRC and *DEST may overlap
8324 fold_builtin_memory_op (tree arglist
, tree type
, bool ignore
, int endp
)
8326 tree dest
, src
, len
, destvar
, srcvar
, expr
;
8328 if (! validate_arglist (arglist
,
8329 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
8332 dest
= TREE_VALUE (arglist
);
8333 src
= TREE_VALUE (TREE_CHAIN (arglist
));
8334 len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
8336 /* If the LEN parameter is zero, return DEST. */
8337 if (integer_zerop (len
))
8338 return omit_one_operand (type
, dest
, src
);
8340 /* If SRC and DEST are the same (and not volatile), return
8341 DEST{,+LEN,+LEN-1}. */
8342 if (operand_equal_p (src
, dest
, 0))
8346 tree srctype
, desttype
;
8349 int src_align
= get_pointer_alignment (src
, BIGGEST_ALIGNMENT
);
8350 int dest_align
= get_pointer_alignment (dest
, BIGGEST_ALIGNMENT
);
8352 /* Both DEST and SRC must be pointer types.
8353 ??? This is what old code did. Is the testing for pointer types
8356 If either SRC is readonly or length is 1, we can use memcpy. */
8357 if (dest_align
&& src_align
8358 && (readonly_data_expr (src
)
8359 || (host_integerp (len
, 1)
8360 && (MIN (src_align
, dest_align
) / BITS_PER_UNIT
>=
8361 tree_low_cst (len
, 1)))))
8363 tree fn
= implicit_built_in_decls
[BUILT_IN_MEMCPY
];
8366 return build_function_call_expr (fn
, arglist
);
8371 if (!host_integerp (len
, 0))
8374 This logic lose for arguments like (type *)malloc (sizeof (type)),
8375 since we strip the casts of up to VOID return value from malloc.
8376 Perhaps we ought to inherit type from non-VOID argument here? */
8379 srctype
= TREE_TYPE (TREE_TYPE (src
));
8380 desttype
= TREE_TYPE (TREE_TYPE (dest
));
8381 if (!srctype
|| !desttype
8382 || !TYPE_SIZE_UNIT (srctype
)
8383 || !TYPE_SIZE_UNIT (desttype
)
8384 || TREE_CODE (TYPE_SIZE_UNIT (srctype
)) != INTEGER_CST
8385 || TREE_CODE (TYPE_SIZE_UNIT (desttype
)) != INTEGER_CST
8386 || !tree_int_cst_equal (TYPE_SIZE_UNIT (srctype
), len
)
8387 || !tree_int_cst_equal (TYPE_SIZE_UNIT (desttype
), len
))
8390 if (get_pointer_alignment (dest
, BIGGEST_ALIGNMENT
)
8391 < (int) TYPE_ALIGN (desttype
)
8392 || (get_pointer_alignment (src
, BIGGEST_ALIGNMENT
)
8393 < (int) TYPE_ALIGN (srctype
)))
8397 dest
= builtin_save_expr (dest
);
8399 srcvar
= build_fold_indirect_ref (src
);
8400 if (TREE_THIS_VOLATILE (srcvar
))
8402 if (!tree_int_cst_equal (lang_hooks
.expr_size (srcvar
), len
))
8404 /* With memcpy, it is possible to bypass aliasing rules, so without
8405 this check i. e. execute/20060930-2.c would be misoptimized, because
8406 it use conflicting alias set to hold argument for the memcpy call.
8407 This check is probably unnecesary with -fno-strict-aliasing.
8408 Similarly for destvar. See also PR29286. */
8409 if (!var_decl_component_p (srcvar
)
8410 /* Accept: memcpy (*char_var, "test", 1); that simplify
8412 || is_gimple_min_invariant (srcvar
)
8413 || readonly_data_expr (src
))
8416 destvar
= build_fold_indirect_ref (dest
);
8417 if (TREE_THIS_VOLATILE (destvar
))
8419 if (!tree_int_cst_equal (lang_hooks
.expr_size (destvar
), len
))
8421 if (!var_decl_component_p (destvar
))
8424 if (srctype
== desttype
8425 || (gimple_in_ssa_p (cfun
)
8426 && tree_ssa_useless_type_conversion_1 (desttype
, srctype
)))
8428 else if ((INTEGRAL_TYPE_P (TREE_TYPE (srcvar
))
8429 || POINTER_TYPE_P (TREE_TYPE (srcvar
)))
8430 && (INTEGRAL_TYPE_P (TREE_TYPE (destvar
))
8431 || POINTER_TYPE_P (TREE_TYPE (destvar
))))
8432 expr
= fold_convert (TREE_TYPE (destvar
), srcvar
);
8434 expr
= fold_build1 (VIEW_CONVERT_EXPR
, TREE_TYPE (destvar
), srcvar
);
8435 expr
= build2 (GIMPLE_MODIFY_STMT
, TREE_TYPE (destvar
), destvar
, expr
);
8441 if (endp
== 0 || endp
== 3)
8442 return omit_one_operand (type
, dest
, expr
);
8448 len
= fold_build2 (MINUS_EXPR
, TREE_TYPE (len
), len
,
8451 len
= fold_convert (TREE_TYPE (dest
), len
);
8452 dest
= fold_build2 (PLUS_EXPR
, TREE_TYPE (dest
), dest
, len
);
8453 dest
= fold_convert (type
, dest
);
8455 dest
= omit_one_operand (type
, dest
, expr
);
8459 /* Fold function call to builtin bcopy. Return NULL_TREE if no
8460 simplification can be made. */
8463 fold_builtin_bcopy (tree arglist
, bool ignore
)
8465 tree src
, dest
, size
, newarglist
;
8467 if (!validate_arglist (arglist
,
8468 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
8474 src
= TREE_VALUE (arglist
);
8475 dest
= TREE_VALUE (TREE_CHAIN (arglist
));
8476 size
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
8478 /* New argument list transforming bcopy(ptr x, ptr y, int z) to
8479 memmove(ptr y, ptr x, size_t z). This is done this way
8480 so that if it isn't expanded inline, we fallback to
8481 calling bcopy instead of memmove. */
8483 newarglist
= build_tree_list (NULL_TREE
, fold_convert (sizetype
, size
));
8484 newarglist
= tree_cons (NULL_TREE
, src
, newarglist
);
8485 newarglist
= tree_cons (NULL_TREE
, dest
, newarglist
);
8487 return fold_builtin_memory_op (newarglist
, void_type_node
, true, /*endp=*/3);
8490 /* Fold function call to builtin strcpy. If LEN is not NULL, it represents
8491 the length of the string to be copied. Return NULL_TREE if no
8492 simplification can be made. */
8495 fold_builtin_strcpy (tree fndecl
, tree arglist
, tree len
)
8499 if (!validate_arglist (arglist
,
8500 POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
8503 dest
= TREE_VALUE (arglist
);
8504 src
= TREE_VALUE (TREE_CHAIN (arglist
));
8506 /* If SRC and DEST are the same (and not volatile), return DEST. */
8507 if (operand_equal_p (src
, dest
, 0))
8508 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl
)), dest
);
8513 fn
= implicit_built_in_decls
[BUILT_IN_MEMCPY
];
8519 len
= c_strlen (src
, 1);
8520 if (! len
|| TREE_SIDE_EFFECTS (len
))
8524 len
= size_binop (PLUS_EXPR
, len
, ssize_int (1));
8525 arglist
= build_tree_list (NULL_TREE
, len
);
8526 arglist
= tree_cons (NULL_TREE
, src
, arglist
);
8527 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
8528 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl
)),
8529 build_function_call_expr (fn
, arglist
));
8532 /* Fold function call to builtin strncpy. If SLEN is not NULL, it represents
8533 the length of the source string. Return NULL_TREE if no simplification
8537 fold_builtin_strncpy (tree fndecl
, tree arglist
, tree slen
)
8539 tree dest
, src
, len
, fn
;
8541 if (!validate_arglist (arglist
,
8542 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
8545 dest
= TREE_VALUE (arglist
);
8546 src
= TREE_VALUE (TREE_CHAIN (arglist
));
8547 len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
8549 /* If the LEN parameter is zero, return DEST. */
8550 if (integer_zerop (len
))
8551 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl
)), dest
, src
);
8553 /* We can't compare slen with len as constants below if len is not a
8555 if (len
== 0 || TREE_CODE (len
) != INTEGER_CST
)
8559 slen
= c_strlen (src
, 1);
8561 /* Now, we must be passed a constant src ptr parameter. */
8562 if (slen
== 0 || TREE_CODE (slen
) != INTEGER_CST
)
8565 slen
= size_binop (PLUS_EXPR
, slen
, ssize_int (1));
8567 /* We do not support simplification of this case, though we do
8568 support it when expanding trees into RTL. */
8569 /* FIXME: generate a call to __builtin_memset. */
8570 if (tree_int_cst_lt (slen
, len
))
8573 /* OK transform into builtin memcpy. */
8574 fn
= implicit_built_in_decls
[BUILT_IN_MEMCPY
];
8577 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl
)),
8578 build_function_call_expr (fn
, arglist
));
8581 /* Fold function call to builtin memcmp. Return
8582 NULL_TREE if no simplification can be made. */
8585 fold_builtin_memcmp (tree arglist
)
8587 tree arg1
, arg2
, len
;
8588 const char *p1
, *p2
;
8590 if (!validate_arglist (arglist
,
8591 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
8594 arg1
= TREE_VALUE (arglist
);
8595 arg2
= TREE_VALUE (TREE_CHAIN (arglist
));
8596 len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
8598 /* If the LEN parameter is zero, return zero. */
8599 if (integer_zerop (len
))
8600 return omit_two_operands (integer_type_node
, integer_zero_node
,
8603 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
8604 if (operand_equal_p (arg1
, arg2
, 0))
8605 return omit_one_operand (integer_type_node
, integer_zero_node
, len
);
8607 p1
= c_getstr (arg1
);
8608 p2
= c_getstr (arg2
);
8610 /* If all arguments are constant, and the value of len is not greater
8611 than the lengths of arg1 and arg2, evaluate at compile-time. */
8612 if (host_integerp (len
, 1) && p1
&& p2
8613 && compare_tree_int (len
, strlen (p1
) + 1) <= 0
8614 && compare_tree_int (len
, strlen (p2
) + 1) <= 0)
8616 const int r
= memcmp (p1
, p2
, tree_low_cst (len
, 1));
8619 return integer_one_node
;
8621 return integer_minus_one_node
;
8623 return integer_zero_node
;
8626 /* If len parameter is one, return an expression corresponding to
8627 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
8628 if (host_integerp (len
, 1) && tree_low_cst (len
, 1) == 1)
8630 tree cst_uchar_node
= build_type_variant (unsigned_char_type_node
, 1, 0);
8631 tree cst_uchar_ptr_node
8632 = build_pointer_type_for_mode (cst_uchar_node
, ptr_mode
, true);
8634 tree ind1
= fold_convert (integer_type_node
,
8635 build1 (INDIRECT_REF
, cst_uchar_node
,
8636 fold_convert (cst_uchar_ptr_node
,
8638 tree ind2
= fold_convert (integer_type_node
,
8639 build1 (INDIRECT_REF
, cst_uchar_node
,
8640 fold_convert (cst_uchar_ptr_node
,
8642 return fold_build2 (MINUS_EXPR
, integer_type_node
, ind1
, ind2
);
8648 /* Fold function call to builtin strcmp. Return
8649 NULL_TREE if no simplification can be made. */
8652 fold_builtin_strcmp (tree arglist
)
8655 const char *p1
, *p2
;
8657 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
8660 arg1
= TREE_VALUE (arglist
);
8661 arg2
= TREE_VALUE (TREE_CHAIN (arglist
));
8663 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
8664 if (operand_equal_p (arg1
, arg2
, 0))
8665 return integer_zero_node
;
8667 p1
= c_getstr (arg1
);
8668 p2
= c_getstr (arg2
);
8672 const int i
= strcmp (p1
, p2
);
8674 return integer_minus_one_node
;
8676 return integer_one_node
;
8678 return integer_zero_node
;
8681 /* If the second arg is "", return *(const unsigned char*)arg1. */
8682 if (p2
&& *p2
== '\0')
8684 tree cst_uchar_node
= build_type_variant (unsigned_char_type_node
, 1, 0);
8685 tree cst_uchar_ptr_node
8686 = build_pointer_type_for_mode (cst_uchar_node
, ptr_mode
, true);
8688 return fold_convert (integer_type_node
,
8689 build1 (INDIRECT_REF
, cst_uchar_node
,
8690 fold_convert (cst_uchar_ptr_node
,
8694 /* If the first arg is "", return -*(const unsigned char*)arg2. */
8695 if (p1
&& *p1
== '\0')
8697 tree cst_uchar_node
= build_type_variant (unsigned_char_type_node
, 1, 0);
8698 tree cst_uchar_ptr_node
8699 = build_pointer_type_for_mode (cst_uchar_node
, ptr_mode
, true);
8701 tree temp
= fold_convert (integer_type_node
,
8702 build1 (INDIRECT_REF
, cst_uchar_node
,
8703 fold_convert (cst_uchar_ptr_node
,
8705 return fold_build1 (NEGATE_EXPR
, integer_type_node
, temp
);
8711 /* Fold function call to builtin strncmp. Return
8712 NULL_TREE if no simplification can be made. */
8715 fold_builtin_strncmp (tree arglist
)
8717 tree arg1
, arg2
, len
;
8718 const char *p1
, *p2
;
8720 if (!validate_arglist (arglist
,
8721 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
8724 arg1
= TREE_VALUE (arglist
);
8725 arg2
= TREE_VALUE (TREE_CHAIN (arglist
));
8726 len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
8728 /* If the LEN parameter is zero, return zero. */
8729 if (integer_zerop (len
))
8730 return omit_two_operands (integer_type_node
, integer_zero_node
,
8733 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
8734 if (operand_equal_p (arg1
, arg2
, 0))
8735 return omit_one_operand (integer_type_node
, integer_zero_node
, len
);
8737 p1
= c_getstr (arg1
);
8738 p2
= c_getstr (arg2
);
8740 if (host_integerp (len
, 1) && p1
&& p2
)
8742 const int i
= strncmp (p1
, p2
, tree_low_cst (len
, 1));
8744 return integer_one_node
;
8746 return integer_minus_one_node
;
8748 return integer_zero_node
;
8751 /* If the second arg is "", and the length is greater than zero,
8752 return *(const unsigned char*)arg1. */
8753 if (p2
&& *p2
== '\0'
8754 && TREE_CODE (len
) == INTEGER_CST
8755 && tree_int_cst_sgn (len
) == 1)
8757 tree cst_uchar_node
= build_type_variant (unsigned_char_type_node
, 1, 0);
8758 tree cst_uchar_ptr_node
8759 = build_pointer_type_for_mode (cst_uchar_node
, ptr_mode
, true);
8761 return fold_convert (integer_type_node
,
8762 build1 (INDIRECT_REF
, cst_uchar_node
,
8763 fold_convert (cst_uchar_ptr_node
,
8767 /* If the first arg is "", and the length is greater than zero,
8768 return -*(const unsigned char*)arg2. */
8769 if (p1
&& *p1
== '\0'
8770 && TREE_CODE (len
) == INTEGER_CST
8771 && tree_int_cst_sgn (len
) == 1)
8773 tree cst_uchar_node
= build_type_variant (unsigned_char_type_node
, 1, 0);
8774 tree cst_uchar_ptr_node
8775 = build_pointer_type_for_mode (cst_uchar_node
, ptr_mode
, true);
8777 tree temp
= fold_convert (integer_type_node
,
8778 build1 (INDIRECT_REF
, cst_uchar_node
,
8779 fold_convert (cst_uchar_ptr_node
,
8781 return fold_build1 (NEGATE_EXPR
, integer_type_node
, temp
);
8784 /* If len parameter is one, return an expression corresponding to
8785 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
8786 if (host_integerp (len
, 1) && tree_low_cst (len
, 1) == 1)
8788 tree cst_uchar_node
= build_type_variant (unsigned_char_type_node
, 1, 0);
8789 tree cst_uchar_ptr_node
8790 = build_pointer_type_for_mode (cst_uchar_node
, ptr_mode
, true);
8792 tree ind1
= fold_convert (integer_type_node
,
8793 build1 (INDIRECT_REF
, cst_uchar_node
,
8794 fold_convert (cst_uchar_ptr_node
,
8796 tree ind2
= fold_convert (integer_type_node
,
8797 build1 (INDIRECT_REF
, cst_uchar_node
,
8798 fold_convert (cst_uchar_ptr_node
,
8800 return fold_build2 (MINUS_EXPR
, integer_type_node
, ind1
, ind2
);
8806 /* Fold function call to builtin signbit, signbitf or signbitl. Return
8807 NULL_TREE if no simplification can be made. */
8810 fold_builtin_signbit (tree fndecl
, tree arglist
)
8812 tree type
= TREE_TYPE (TREE_TYPE (fndecl
));
8815 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
8818 arg
= TREE_VALUE (arglist
);
8820 /* If ARG is a compile-time constant, determine the result. */
8821 if (TREE_CODE (arg
) == REAL_CST
8822 && !TREE_CONSTANT_OVERFLOW (arg
))
8826 c
= TREE_REAL_CST (arg
);
8827 temp
= REAL_VALUE_NEGATIVE (c
) ? integer_one_node
: integer_zero_node
;
8828 return fold_convert (type
, temp
);
8831 /* If ARG is non-negative, the result is always zero. */
8832 if (tree_expr_nonnegative_p (arg
))
8833 return omit_one_operand (type
, integer_zero_node
, arg
);
8835 /* If ARG's format doesn't have signed zeros, return "arg < 0.0". */
8836 if (!HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg
))))
8837 return fold_build2 (LT_EXPR
, type
, arg
,
8838 build_real (TREE_TYPE (arg
), dconst0
));
8843 /* Fold function call to builtin copysign, copysignf or copysignl.
8844 Return NULL_TREE if no simplification can be made. */
8847 fold_builtin_copysign (tree fndecl
, tree arglist
, tree type
)
8849 tree arg1
, arg2
, tem
;
8851 if (!validate_arglist (arglist
, REAL_TYPE
, REAL_TYPE
, VOID_TYPE
))
8854 arg1
= TREE_VALUE (arglist
);
8855 arg2
= TREE_VALUE (TREE_CHAIN (arglist
));
8857 /* copysign(X,X) is X. */
8858 if (operand_equal_p (arg1
, arg2
, 0))
8859 return fold_convert (type
, arg1
);
8861 /* If ARG1 and ARG2 are compile-time constants, determine the result. */
8862 if (TREE_CODE (arg1
) == REAL_CST
8863 && TREE_CODE (arg2
) == REAL_CST
8864 && !TREE_CONSTANT_OVERFLOW (arg1
)
8865 && !TREE_CONSTANT_OVERFLOW (arg2
))
8867 REAL_VALUE_TYPE c1
, c2
;
8869 c1
= TREE_REAL_CST (arg1
);
8870 c2
= TREE_REAL_CST (arg2
);
8871 /* c1.sign := c2.sign. */
8872 real_copysign (&c1
, &c2
);
8873 return build_real (type
, c1
);
8876 /* copysign(X, Y) is fabs(X) when Y is always non-negative.
8877 Remember to evaluate Y for side-effects. */
8878 if (tree_expr_nonnegative_p (arg2
))
8879 return omit_one_operand (type
,
8880 fold_build1 (ABS_EXPR
, type
, arg1
),
8883 /* Strip sign changing operations for the first argument. */
8884 tem
= fold_strip_sign_ops (arg1
);
8887 arglist
= tree_cons (NULL_TREE
, tem
, TREE_CHAIN (arglist
));
8888 return build_function_call_expr (fndecl
, arglist
);
8894 /* Fold a call to builtin isascii. */
8897 fold_builtin_isascii (tree arglist
)
8899 if (! validate_arglist (arglist
, INTEGER_TYPE
, VOID_TYPE
))
8903 /* Transform isascii(c) -> ((c & ~0x7f) == 0). */
8904 tree arg
= TREE_VALUE (arglist
);
8906 arg
= build2 (BIT_AND_EXPR
, integer_type_node
, arg
,
8907 build_int_cst (NULL_TREE
,
8908 ~ (unsigned HOST_WIDE_INT
) 0x7f));
8909 return fold_build2 (EQ_EXPR
, integer_type_node
,
8910 arg
, integer_zero_node
);
8914 /* Fold a call to builtin toascii. */
8917 fold_builtin_toascii (tree arglist
)
8919 if (! validate_arglist (arglist
, INTEGER_TYPE
, VOID_TYPE
))
8923 /* Transform toascii(c) -> (c & 0x7f). */
8924 tree arg
= TREE_VALUE (arglist
);
8926 return fold_build2 (BIT_AND_EXPR
, integer_type_node
, arg
,
8927 build_int_cst (NULL_TREE
, 0x7f));
8931 /* Fold a call to builtin isdigit. */
8934 fold_builtin_isdigit (tree arglist
)
8936 if (! validate_arglist (arglist
, INTEGER_TYPE
, VOID_TYPE
))
8940 /* Transform isdigit(c) -> (unsigned)(c) - '0' <= 9. */
8941 /* According to the C standard, isdigit is unaffected by locale.
8942 However, it definitely is affected by the target character set. */
8944 unsigned HOST_WIDE_INT target_digit0
8945 = lang_hooks
.to_target_charset ('0');
8947 if (target_digit0
== 0)
8950 arg
= fold_convert (unsigned_type_node
, TREE_VALUE (arglist
));
8951 arg
= build2 (MINUS_EXPR
, unsigned_type_node
, arg
,
8952 build_int_cst (unsigned_type_node
, target_digit0
));
8953 return fold_build2 (LE_EXPR
, integer_type_node
, arg
,
8954 build_int_cst (unsigned_type_node
, 9));
8958 /* Fold a call to fabs, fabsf or fabsl. */
8961 fold_builtin_fabs (tree arglist
, tree type
)
8965 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
8968 arg
= TREE_VALUE (arglist
);
8969 arg
= fold_convert (type
, arg
);
8970 if (TREE_CODE (arg
) == REAL_CST
)
8971 return fold_abs_const (arg
, type
);
8972 return fold_build1 (ABS_EXPR
, type
, arg
);
8975 /* Fold a call to abs, labs, llabs or imaxabs. */
8978 fold_builtin_abs (tree arglist
, tree type
)
8982 if (!validate_arglist (arglist
, INTEGER_TYPE
, VOID_TYPE
))
8985 arg
= TREE_VALUE (arglist
);
8986 arg
= fold_convert (type
, arg
);
8987 if (TREE_CODE (arg
) == INTEGER_CST
)
8988 return fold_abs_const (arg
, type
);
8989 return fold_build1 (ABS_EXPR
, type
, arg
);
8992 /* Fold a call to builtin fmin or fmax. */
8995 fold_builtin_fmin_fmax (tree arglist
, tree type
, bool max
)
8997 if (validate_arglist (arglist
, REAL_TYPE
, REAL_TYPE
, VOID_TYPE
))
8999 tree arg0
= TREE_VALUE (arglist
);
9000 tree arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
9001 /* Calculate the result when the argument is a constant. */
9002 tree res
= do_mpfr_arg2 (arg0
, arg1
, type
, (max
? mpfr_max
: mpfr_min
));
9007 /* If either argument is NaN, return the other one. Avoid the
9008 transformation if we get (and honor) a signalling NaN. Using
9009 omit_one_operand() ensures we create a non-lvalue. */
9010 if (TREE_CODE (arg0
) == REAL_CST
9011 && real_isnan (&TREE_REAL_CST (arg0
))
9012 && (! HONOR_SNANS (TYPE_MODE (TREE_TYPE (arg0
)))
9013 || ! TREE_REAL_CST (arg0
).signalling
))
9014 return omit_one_operand (type
, arg1
, arg0
);
9015 if (TREE_CODE (arg1
) == REAL_CST
9016 && real_isnan (&TREE_REAL_CST (arg1
))
9017 && (! HONOR_SNANS (TYPE_MODE (TREE_TYPE (arg1
)))
9018 || ! TREE_REAL_CST (arg1
).signalling
))
9019 return omit_one_operand (type
, arg0
, arg1
);
9021 /* Transform fmin/fmax(x,x) -> x. */
9022 if (operand_equal_p (arg0
, arg1
, OEP_PURE_SAME
))
9023 return omit_one_operand (type
, arg0
, arg1
);
9025 /* Convert fmin/fmax to MIN_EXPR/MAX_EXPR. C99 requires these
9026 functions to return the numeric arg if the other one is NaN.
9027 These tree codes don't honor that, so only transform if
9028 -ffinite-math-only is set. C99 doesn't require -0.0 to be
9029 handled, so we don't have to worry about it either. */
9030 if (flag_finite_math_only
)
9031 return fold_build2 ((max
? MAX_EXPR
: MIN_EXPR
), type
,
9032 fold_convert (type
, arg0
),
9033 fold_convert (type
, arg1
));
9038 /* Fold a call to __builtin_isnan(), __builtin_isinf, __builtin_finite.
9039 EXP is the CALL_EXPR for the call. */
9042 fold_builtin_classify (tree fndecl
, tree arglist
, int builtin_index
)
9044 tree type
= TREE_TYPE (TREE_TYPE (fndecl
));
9048 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
9050 /* Check that we have exactly one argument. */
9053 error ("too few arguments to function %qs",
9054 IDENTIFIER_POINTER (DECL_NAME (fndecl
)));
9055 return error_mark_node
;
9057 else if (TREE_CHAIN (arglist
) != 0)
9059 error ("too many arguments to function %qs",
9060 IDENTIFIER_POINTER (DECL_NAME (fndecl
)));
9061 return error_mark_node
;
9065 error ("non-floating-point argument to function %qs",
9066 IDENTIFIER_POINTER (DECL_NAME (fndecl
)));
9067 return error_mark_node
;
9071 arg
= TREE_VALUE (arglist
);
9072 switch (builtin_index
)
9074 case BUILT_IN_ISINF
:
9075 if (!HONOR_INFINITIES (TYPE_MODE (TREE_TYPE (arg
))))
9076 return omit_one_operand (type
, integer_zero_node
, arg
);
9078 if (TREE_CODE (arg
) == REAL_CST
)
9080 r
= TREE_REAL_CST (arg
);
9081 if (real_isinf (&r
))
9082 return real_compare (GT_EXPR
, &r
, &dconst0
)
9083 ? integer_one_node
: integer_minus_one_node
;
9085 return integer_zero_node
;
9090 case BUILT_IN_FINITE
:
9091 if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg
)))
9092 && !HONOR_INFINITIES (TYPE_MODE (TREE_TYPE (arg
))))
9093 return omit_one_operand (type
, integer_one_node
, arg
);
9095 if (TREE_CODE (arg
) == REAL_CST
)
9097 r
= TREE_REAL_CST (arg
);
9098 return real_isinf (&r
) || real_isnan (&r
)
9099 ? integer_zero_node
: integer_one_node
;
9104 case BUILT_IN_ISNAN
:
9105 if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg
))))
9106 return omit_one_operand (type
, integer_zero_node
, arg
);
9108 if (TREE_CODE (arg
) == REAL_CST
)
9110 r
= TREE_REAL_CST (arg
);
9111 return real_isnan (&r
) ? integer_one_node
: integer_zero_node
;
9114 arg
= builtin_save_expr (arg
);
9115 return fold_build2 (UNORDERED_EXPR
, type
, arg
, arg
);
9122 /* Fold a call to an unordered comparison function such as
9123 __builtin_isgreater(). FNDECL is the FUNCTION_DECL for the function
9124 being called and ARGLIST is the argument list for the call.
9125 UNORDERED_CODE and ORDERED_CODE are comparison codes that give
9126 the opposite of the desired result. UNORDERED_CODE is used
9127 for modes that can hold NaNs and ORDERED_CODE is used for
9131 fold_builtin_unordered_cmp (tree fndecl
, tree arglist
,
9132 enum tree_code unordered_code
,
9133 enum tree_code ordered_code
)
9135 tree type
= TREE_TYPE (TREE_TYPE (fndecl
));
9136 enum tree_code code
;
9139 enum tree_code code0
, code1
;
9140 tree cmp_type
= NULL_TREE
;
9142 if (!validate_arglist (arglist
, REAL_TYPE
, REAL_TYPE
, VOID_TYPE
))
9144 /* Check that we have exactly two arguments. */
9145 if (arglist
== 0 || TREE_CHAIN (arglist
) == 0)
9147 error ("too few arguments to function %qs",
9148 IDENTIFIER_POINTER (DECL_NAME (fndecl
)));
9149 return error_mark_node
;
9151 else if (TREE_CHAIN (TREE_CHAIN (arglist
)) != 0)
9153 error ("too many arguments to function %qs",
9154 IDENTIFIER_POINTER (DECL_NAME (fndecl
)));
9155 return error_mark_node
;
9159 arg0
= TREE_VALUE (arglist
);
9160 arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
9162 type0
= TREE_TYPE (arg0
);
9163 type1
= TREE_TYPE (arg1
);
9165 code0
= TREE_CODE (type0
);
9166 code1
= TREE_CODE (type1
);
9168 if (code0
== REAL_TYPE
&& code1
== REAL_TYPE
)
9169 /* Choose the wider of two real types. */
9170 cmp_type
= TYPE_PRECISION (type0
) >= TYPE_PRECISION (type1
)
9172 else if (code0
== REAL_TYPE
&& code1
== INTEGER_TYPE
)
9174 else if (code0
== INTEGER_TYPE
&& code1
== REAL_TYPE
)
9178 error ("non-floating-point argument to function %qs",
9179 IDENTIFIER_POINTER (DECL_NAME (fndecl
)));
9180 return error_mark_node
;
9183 arg0
= fold_convert (cmp_type
, arg0
);
9184 arg1
= fold_convert (cmp_type
, arg1
);
9186 if (unordered_code
== UNORDERED_EXPR
)
9188 if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg0
))))
9189 return omit_two_operands (type
, integer_zero_node
, arg0
, arg1
);
9190 return fold_build2 (UNORDERED_EXPR
, type
, arg0
, arg1
);
9193 code
= HONOR_NANS (TYPE_MODE (TREE_TYPE (arg0
))) ? unordered_code
9195 return fold_build1 (TRUTH_NOT_EXPR
, type
,
9196 fold_build2 (code
, type
, arg0
, arg1
));
9199 /* Used by constant folding to simplify calls to builtin functions. EXP is
9200 the CALL_EXPR of a call to a builtin function. IGNORE is true if the
9201 result of the function call is ignored. This function returns NULL_TREE
9202 if no simplification was possible. */
9205 fold_builtin_1 (tree fndecl
, tree arglist
, bool ignore
)
9207 tree type
= TREE_TYPE (TREE_TYPE (fndecl
));
9208 enum built_in_function fcode
;
9210 if (DECL_BUILT_IN_CLASS (fndecl
) == BUILT_IN_MD
)
9211 return targetm
.fold_builtin (fndecl
, arglist
, ignore
);
9213 fcode
= DECL_FUNCTION_CODE (fndecl
);
9216 case BUILT_IN_FPUTS
:
9217 return fold_builtin_fputs (arglist
, ignore
, false, NULL_TREE
);
9219 case BUILT_IN_FPUTS_UNLOCKED
:
9220 return fold_builtin_fputs (arglist
, ignore
, true, NULL_TREE
);
9222 case BUILT_IN_STRSTR
:
9223 return fold_builtin_strstr (arglist
, type
);
9225 case BUILT_IN_STRCAT
:
9226 return fold_builtin_strcat (arglist
);
9228 case BUILT_IN_STRNCAT
:
9229 return fold_builtin_strncat (arglist
);
9231 case BUILT_IN_STRSPN
:
9232 return fold_builtin_strspn (arglist
);
9234 case BUILT_IN_STRCSPN
:
9235 return fold_builtin_strcspn (arglist
);
9237 case BUILT_IN_STRCHR
:
9238 case BUILT_IN_INDEX
:
9239 return fold_builtin_strchr (arglist
, type
);
9241 case BUILT_IN_STRRCHR
:
9242 case BUILT_IN_RINDEX
:
9243 return fold_builtin_strrchr (arglist
, type
);
9245 case BUILT_IN_STRCPY
:
9246 return fold_builtin_strcpy (fndecl
, arglist
, NULL_TREE
);
9248 case BUILT_IN_STRNCPY
:
9249 return fold_builtin_strncpy (fndecl
, arglist
, NULL_TREE
);
9251 case BUILT_IN_STRCMP
:
9252 return fold_builtin_strcmp (arglist
);
9254 case BUILT_IN_STRNCMP
:
9255 return fold_builtin_strncmp (arglist
);
9257 case BUILT_IN_STRPBRK
:
9258 return fold_builtin_strpbrk (arglist
, type
);
9261 case BUILT_IN_MEMCMP
:
9262 return fold_builtin_memcmp (arglist
);
9264 case BUILT_IN_SPRINTF
:
9265 return fold_builtin_sprintf (arglist
, ignore
);
9267 case BUILT_IN_CONSTANT_P
:
9271 val
= fold_builtin_constant_p (arglist
);
9272 /* Gimplification will pull the CALL_EXPR for the builtin out of
9273 an if condition. When not optimizing, we'll not CSE it back.
9274 To avoid link error types of regressions, return false now. */
9275 if (!val
&& !optimize
)
9276 val
= integer_zero_node
;
9281 case BUILT_IN_EXPECT
:
9282 return fold_builtin_expect (arglist
);
9284 case BUILT_IN_CLASSIFY_TYPE
:
9285 return fold_builtin_classify_type (arglist
);
9287 case BUILT_IN_STRLEN
:
9288 return fold_builtin_strlen (arglist
);
9290 CASE_FLT_FN (BUILT_IN_FABS
):
9291 return fold_builtin_fabs (arglist
, type
);
9295 case BUILT_IN_LLABS
:
9296 case BUILT_IN_IMAXABS
:
9297 return fold_builtin_abs (arglist
, type
);
9299 CASE_FLT_FN (BUILT_IN_CONJ
):
9300 if (validate_arglist (arglist
, COMPLEX_TYPE
, VOID_TYPE
))
9301 return fold_build1 (CONJ_EXPR
, type
, TREE_VALUE (arglist
));
9304 CASE_FLT_FN (BUILT_IN_CREAL
):
9305 if (validate_arglist (arglist
, COMPLEX_TYPE
, VOID_TYPE
))
9306 return non_lvalue (fold_build1 (REALPART_EXPR
, type
,
9307 TREE_VALUE (arglist
)));
9310 CASE_FLT_FN (BUILT_IN_CIMAG
):
9311 if (validate_arglist (arglist
, COMPLEX_TYPE
, VOID_TYPE
))
9312 return non_lvalue (fold_build1 (IMAGPART_EXPR
, type
,
9313 TREE_VALUE (arglist
)));
9316 CASE_FLT_FN (BUILT_IN_CABS
):
9317 return fold_builtin_cabs (arglist
, type
, fndecl
);
9319 CASE_FLT_FN (BUILT_IN_SQRT
):
9320 return fold_builtin_sqrt (arglist
, type
);
9322 CASE_FLT_FN (BUILT_IN_CBRT
):
9323 return fold_builtin_cbrt (arglist
, type
);
9325 CASE_FLT_FN (BUILT_IN_ASIN
):
9326 if (validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
9327 return do_mpfr_arg1 (TREE_VALUE (arglist
), type
, mpfr_asin
,
9328 &dconstm1
, &dconst1
, true);
9331 CASE_FLT_FN (BUILT_IN_ACOS
):
9332 if (validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
9333 return do_mpfr_arg1 (TREE_VALUE (arglist
), type
, mpfr_acos
,
9334 &dconstm1
, &dconst1
, true);
9337 CASE_FLT_FN (BUILT_IN_ATAN
):
9338 if (validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
9339 return do_mpfr_arg1 (TREE_VALUE (arglist
), type
, mpfr_atan
,
9343 CASE_FLT_FN (BUILT_IN_ASINH
):
9344 if (validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
9345 return do_mpfr_arg1 (TREE_VALUE (arglist
), type
, mpfr_asinh
,
9349 CASE_FLT_FN (BUILT_IN_ACOSH
):
9350 if (validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
9351 return do_mpfr_arg1 (TREE_VALUE (arglist
), type
, mpfr_acosh
,
9352 &dconst1
, NULL
, true);
9355 CASE_FLT_FN (BUILT_IN_ATANH
):
9356 if (validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
9357 return do_mpfr_arg1 (TREE_VALUE (arglist
), type
, mpfr_atanh
,
9358 &dconstm1
, &dconst1
, false);
9361 CASE_FLT_FN (BUILT_IN_SIN
):
9362 if (validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
9363 return do_mpfr_arg1 (TREE_VALUE (arglist
), type
, mpfr_sin
,
9367 CASE_FLT_FN (BUILT_IN_COS
):
9368 return fold_builtin_cos (arglist
, type
, fndecl
);
9370 CASE_FLT_FN (BUILT_IN_TAN
):
9371 return fold_builtin_tan (arglist
, type
);
9373 CASE_FLT_FN (BUILT_IN_SINCOS
):
9374 return fold_builtin_sincos (arglist
);
9376 CASE_FLT_FN (BUILT_IN_CEXP
):
9377 return fold_builtin_cexp (arglist
, type
);
9379 CASE_FLT_FN (BUILT_IN_CEXPI
):
9380 if (validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
9381 return do_mpfr_sincos (TREE_VALUE (arglist
), NULL_TREE
, NULL_TREE
);
9383 CASE_FLT_FN (BUILT_IN_SINH
):
9384 if (validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
9385 return do_mpfr_arg1 (TREE_VALUE (arglist
), type
, mpfr_sinh
,
9389 CASE_FLT_FN (BUILT_IN_COSH
):
9390 return fold_builtin_cosh (arglist
, type
, fndecl
);
9392 CASE_FLT_FN (BUILT_IN_TANH
):
9393 if (validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
9394 return do_mpfr_arg1 (TREE_VALUE (arglist
), type
, mpfr_tanh
,
9398 CASE_FLT_FN (BUILT_IN_ERF
):
9399 if (validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
9400 return do_mpfr_arg1 (TREE_VALUE (arglist
), type
, mpfr_erf
,
9404 CASE_FLT_FN (BUILT_IN_ERFC
):
9405 if (validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
9406 return do_mpfr_arg1 (TREE_VALUE (arglist
), type
, mpfr_erfc
,
9410 CASE_FLT_FN (BUILT_IN_TGAMMA
):
9411 if (validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
9412 return do_mpfr_arg1 (TREE_VALUE (arglist
), type
, mpfr_gamma
,
9416 CASE_FLT_FN (BUILT_IN_EXP
):
9417 return fold_builtin_exponent (fndecl
, arglist
, mpfr_exp
);
9419 CASE_FLT_FN (BUILT_IN_EXP2
):
9420 return fold_builtin_exponent (fndecl
, arglist
, mpfr_exp2
);
9422 CASE_FLT_FN (BUILT_IN_EXP10
):
9423 CASE_FLT_FN (BUILT_IN_POW10
):
9424 return fold_builtin_exponent (fndecl
, arglist
, mpfr_exp10
);
9426 CASE_FLT_FN (BUILT_IN_EXPM1
):
9427 if (validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
9428 return do_mpfr_arg1 (TREE_VALUE (arglist
), type
, mpfr_expm1
,
9432 CASE_FLT_FN (BUILT_IN_LOG
):
9433 return fold_builtin_logarithm (fndecl
, arglist
, mpfr_log
);
9435 CASE_FLT_FN (BUILT_IN_LOG2
):
9436 return fold_builtin_logarithm (fndecl
, arglist
, mpfr_log2
);
9438 CASE_FLT_FN (BUILT_IN_LOG10
):
9439 return fold_builtin_logarithm (fndecl
, arglist
, mpfr_log10
);
9441 CASE_FLT_FN (BUILT_IN_LOG1P
):
9442 if (validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
9443 return do_mpfr_arg1 (TREE_VALUE (arglist
), type
, mpfr_log1p
,
9444 &dconstm1
, NULL
, false);
9447 CASE_FLT_FN (BUILT_IN_ATAN2
):
9448 if (validate_arglist (arglist
, REAL_TYPE
, REAL_TYPE
, VOID_TYPE
))
9449 return do_mpfr_arg2 (TREE_VALUE (arglist
),
9450 TREE_VALUE (TREE_CHAIN (arglist
)),
9454 CASE_FLT_FN (BUILT_IN_FMA
):
9455 if (validate_arglist (arglist
, REAL_TYPE
, REAL_TYPE
, REAL_TYPE
, VOID_TYPE
))
9456 return do_mpfr_arg3 (TREE_VALUE (arglist
),
9457 TREE_VALUE (TREE_CHAIN (arglist
)),
9458 TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
))),
9462 CASE_FLT_FN (BUILT_IN_FMIN
):
9463 return fold_builtin_fmin_fmax (arglist
, type
, /*max=*/false);
9465 CASE_FLT_FN (BUILT_IN_FMAX
):
9466 return fold_builtin_fmin_fmax (arglist
, type
, /*max=*/true);
9468 CASE_FLT_FN (BUILT_IN_HYPOT
):
9469 return fold_builtin_hypot (fndecl
, arglist
, type
);
9471 CASE_FLT_FN (BUILT_IN_POW
):
9472 return fold_builtin_pow (fndecl
, arglist
, type
);
9474 CASE_FLT_FN (BUILT_IN_POWI
):
9475 return fold_builtin_powi (fndecl
, arglist
, type
);
9477 CASE_FLT_FN (BUILT_IN_INF
):
9478 case BUILT_IN_INFD32
:
9479 case BUILT_IN_INFD64
:
9480 case BUILT_IN_INFD128
:
9481 return fold_builtin_inf (type
, true);
9483 CASE_FLT_FN (BUILT_IN_HUGE_VAL
):
9484 return fold_builtin_inf (type
, false);
9486 CASE_FLT_FN (BUILT_IN_NAN
):
9487 case BUILT_IN_NAND32
:
9488 case BUILT_IN_NAND64
:
9489 case BUILT_IN_NAND128
:
9490 return fold_builtin_nan (arglist
, type
, true);
9492 CASE_FLT_FN (BUILT_IN_NANS
):
9493 return fold_builtin_nan (arglist
, type
, false);
9495 CASE_FLT_FN (BUILT_IN_FLOOR
):
9496 return fold_builtin_floor (fndecl
, arglist
);
9498 CASE_FLT_FN (BUILT_IN_CEIL
):
9499 return fold_builtin_ceil (fndecl
, arglist
);
9501 CASE_FLT_FN (BUILT_IN_TRUNC
):
9502 return fold_builtin_trunc (fndecl
, arglist
);
9504 CASE_FLT_FN (BUILT_IN_ROUND
):
9505 return fold_builtin_round (fndecl
, arglist
);
9507 CASE_FLT_FN (BUILT_IN_NEARBYINT
):
9508 CASE_FLT_FN (BUILT_IN_RINT
):
9509 return fold_trunc_transparent_mathfn (fndecl
, arglist
);
9511 CASE_FLT_FN (BUILT_IN_LCEIL
):
9512 CASE_FLT_FN (BUILT_IN_LLCEIL
):
9513 CASE_FLT_FN (BUILT_IN_LFLOOR
):
9514 CASE_FLT_FN (BUILT_IN_LLFLOOR
):
9515 CASE_FLT_FN (BUILT_IN_LROUND
):
9516 CASE_FLT_FN (BUILT_IN_LLROUND
):
9517 return fold_builtin_int_roundingfn (fndecl
, arglist
);
9519 CASE_FLT_FN (BUILT_IN_LRINT
):
9520 CASE_FLT_FN (BUILT_IN_LLRINT
):
9521 return fold_fixed_mathfn (fndecl
, arglist
);
9523 case BUILT_IN_BSWAP32
:
9524 case BUILT_IN_BSWAP64
:
9525 return fold_builtin_bswap (fndecl
, arglist
);
9527 CASE_INT_FN (BUILT_IN_FFS
):
9528 CASE_INT_FN (BUILT_IN_CLZ
):
9529 CASE_INT_FN (BUILT_IN_CTZ
):
9530 CASE_INT_FN (BUILT_IN_POPCOUNT
):
9531 CASE_INT_FN (BUILT_IN_PARITY
):
9532 return fold_builtin_bitop (fndecl
, arglist
);
9534 case BUILT_IN_MEMSET
:
9535 return fold_builtin_memset (arglist
, type
, ignore
);
9537 case BUILT_IN_MEMCPY
:
9538 return fold_builtin_memory_op (arglist
, type
, ignore
, /*endp=*/0);
9540 case BUILT_IN_MEMPCPY
:
9541 return fold_builtin_memory_op (arglist
, type
, ignore
, /*endp=*/1);
9543 case BUILT_IN_MEMMOVE
:
9544 return fold_builtin_memory_op (arglist
, type
, ignore
, /*endp=*/3);
9546 case BUILT_IN_BZERO
:
9547 return fold_builtin_bzero (arglist
, ignore
);
9549 case BUILT_IN_BCOPY
:
9550 return fold_builtin_bcopy (arglist
, ignore
);
9552 CASE_FLT_FN (BUILT_IN_SIGNBIT
):
9553 return fold_builtin_signbit (fndecl
, arglist
);
9555 case BUILT_IN_ISASCII
:
9556 return fold_builtin_isascii (arglist
);
9558 case BUILT_IN_TOASCII
:
9559 return fold_builtin_toascii (arglist
);
9561 case BUILT_IN_ISDIGIT
:
9562 return fold_builtin_isdigit (arglist
);
9564 CASE_FLT_FN (BUILT_IN_COPYSIGN
):
9565 return fold_builtin_copysign (fndecl
, arglist
, type
);
9567 CASE_FLT_FN (BUILT_IN_FINITE
):
9568 case BUILT_IN_FINITED32
:
9569 case BUILT_IN_FINITED64
:
9570 case BUILT_IN_FINITED128
:
9571 return fold_builtin_classify (fndecl
, arglist
, BUILT_IN_FINITE
);
9573 CASE_FLT_FN (BUILT_IN_ISINF
):
9574 case BUILT_IN_ISINFD32
:
9575 case BUILT_IN_ISINFD64
:
9576 case BUILT_IN_ISINFD128
:
9577 return fold_builtin_classify (fndecl
, arglist
, BUILT_IN_ISINF
);
9579 CASE_FLT_FN (BUILT_IN_ISNAN
):
9580 case BUILT_IN_ISNAND32
:
9581 case BUILT_IN_ISNAND64
:
9582 case BUILT_IN_ISNAND128
:
9583 return fold_builtin_classify (fndecl
, arglist
, BUILT_IN_ISNAN
);
9585 case BUILT_IN_ISGREATER
:
9586 return fold_builtin_unordered_cmp (fndecl
, arglist
, UNLE_EXPR
, LE_EXPR
);
9587 case BUILT_IN_ISGREATEREQUAL
:
9588 return fold_builtin_unordered_cmp (fndecl
, arglist
, UNLT_EXPR
, LT_EXPR
);
9589 case BUILT_IN_ISLESS
:
9590 return fold_builtin_unordered_cmp (fndecl
, arglist
, UNGE_EXPR
, GE_EXPR
);
9591 case BUILT_IN_ISLESSEQUAL
:
9592 return fold_builtin_unordered_cmp (fndecl
, arglist
, UNGT_EXPR
, GT_EXPR
);
9593 case BUILT_IN_ISLESSGREATER
:
9594 return fold_builtin_unordered_cmp (fndecl
, arglist
, UNEQ_EXPR
, EQ_EXPR
);
9595 case BUILT_IN_ISUNORDERED
:
9596 return fold_builtin_unordered_cmp (fndecl
, arglist
, UNORDERED_EXPR
,
9599 /* We do the folding for va_start in the expander. */
9600 case BUILT_IN_VA_START
:
9603 case BUILT_IN_OBJECT_SIZE
:
9604 return fold_builtin_object_size (arglist
);
9605 case BUILT_IN_MEMCPY_CHK
:
9606 case BUILT_IN_MEMPCPY_CHK
:
9607 case BUILT_IN_MEMMOVE_CHK
:
9608 case BUILT_IN_MEMSET_CHK
:
9609 return fold_builtin_memory_chk (fndecl
, arglist
, NULL_TREE
, ignore
,
9610 DECL_FUNCTION_CODE (fndecl
));
9611 case BUILT_IN_STRCPY_CHK
:
9612 case BUILT_IN_STPCPY_CHK
:
9613 return fold_builtin_stxcpy_chk (fndecl
, arglist
, NULL_TREE
, ignore
,
9614 DECL_FUNCTION_CODE (fndecl
));
9615 case BUILT_IN_STRNCPY_CHK
:
9616 return fold_builtin_strncpy_chk (arglist
, NULL_TREE
);
9617 case BUILT_IN_STRCAT_CHK
:
9618 return fold_builtin_strcat_chk (fndecl
, arglist
);
9619 case BUILT_IN_STRNCAT_CHK
:
9620 return fold_builtin_strncat_chk (fndecl
, arglist
);
9621 case BUILT_IN_SPRINTF_CHK
:
9622 case BUILT_IN_VSPRINTF_CHK
:
9623 return fold_builtin_sprintf_chk (arglist
, DECL_FUNCTION_CODE (fndecl
));
9624 case BUILT_IN_SNPRINTF_CHK
:
9625 case BUILT_IN_VSNPRINTF_CHK
:
9626 return fold_builtin_snprintf_chk (arglist
, NULL_TREE
,
9627 DECL_FUNCTION_CODE (fndecl
));
9629 case BUILT_IN_PRINTF
:
9630 case BUILT_IN_PRINTF_UNLOCKED
:
9631 case BUILT_IN_VPRINTF
:
9632 case BUILT_IN_PRINTF_CHK
:
9633 case BUILT_IN_VPRINTF_CHK
:
9634 return fold_builtin_printf (fndecl
, arglist
, ignore
,
9635 DECL_FUNCTION_CODE (fndecl
));
9637 case BUILT_IN_FPRINTF
:
9638 case BUILT_IN_FPRINTF_UNLOCKED
:
9639 case BUILT_IN_VFPRINTF
:
9640 case BUILT_IN_FPRINTF_CHK
:
9641 case BUILT_IN_VFPRINTF_CHK
:
9642 return fold_builtin_fprintf (fndecl
, arglist
, ignore
,
9643 DECL_FUNCTION_CODE (fndecl
));
9652 /* A wrapper function for builtin folding that prevents warnings for
9653 "statement without effect" and the like, caused by removing the
9654 call node earlier than the warning is generated. */
9657 fold_builtin (tree fndecl
, tree arglist
, bool ignore
)
9659 tree exp
= fold_builtin_1 (fndecl
, arglist
, ignore
);
9662 exp
= build1 (NOP_EXPR
, GENERIC_TREE_TYPE (exp
), exp
);
9663 TREE_NO_WARNING (exp
) = 1;
9669 /* Conveniently construct a function call expression. */
9672 build_function_call_expr (tree fn
, tree arglist
)
9676 call_expr
= build1 (ADDR_EXPR
, build_pointer_type (TREE_TYPE (fn
)), fn
);
9677 return fold_build3 (CALL_EXPR
, TREE_TYPE (TREE_TYPE (fn
)),
9678 call_expr
, arglist
, NULL_TREE
);
9681 /* This function validates the types of a function call argument list
9682 represented as a tree chain of parameters against a specified list
9683 of tree_codes. If the last specifier is a 0, that represents an
9684 ellipses, otherwise the last specifier must be a VOID_TYPE. */
9687 validate_arglist (tree arglist
, ...)
9689 enum tree_code code
;
9693 va_start (ap
, arglist
);
9697 code
= va_arg (ap
, enum tree_code
);
9701 /* This signifies an ellipses, any further arguments are all ok. */
9705 /* This signifies an endlink, if no arguments remain, return
9706 true, otherwise return false. */
9710 /* If no parameters remain or the parameter's code does not
9711 match the specified code, return false. Otherwise continue
9712 checking any remaining arguments. */
9715 if (code
== POINTER_TYPE
)
9717 if (! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist
))))
9720 else if (code
!= TREE_CODE (TREE_TYPE (TREE_VALUE (arglist
))))
9724 arglist
= TREE_CHAIN (arglist
);
9728 /* We need gotos here since we can only have one VA_CLOSE in a
9736 /* Default target-specific builtin expander that does nothing. */
9739 default_expand_builtin (tree exp ATTRIBUTE_UNUSED
,
9740 rtx target ATTRIBUTE_UNUSED
,
9741 rtx subtarget ATTRIBUTE_UNUSED
,
9742 enum machine_mode mode ATTRIBUTE_UNUSED
,
9743 int ignore ATTRIBUTE_UNUSED
)
9748 /* Returns true is EXP represents data that would potentially reside
9749 in a readonly section. */
9752 readonly_data_expr (tree exp
)
9756 if (TREE_CODE (exp
) != ADDR_EXPR
)
9759 exp
= get_base_address (TREE_OPERAND (exp
, 0));
9763 /* Make sure we call decl_readonly_section only for trees it
9764 can handle (since it returns true for everything it doesn't
9766 if (TREE_CODE (exp
) == STRING_CST
9767 || TREE_CODE (exp
) == CONSTRUCTOR
9768 || (TREE_CODE (exp
) == VAR_DECL
&& TREE_STATIC (exp
)))
9769 return decl_readonly_section (exp
, 0);
9774 /* Simplify a call to the strstr builtin.
9776 Return 0 if no simplification was possible, otherwise return the
9777 simplified form of the call as a tree.
9779 The simplified form may be a constant or other expression which
9780 computes the same value, but in a more efficient manner (including
9781 calls to other builtin functions).
9783 The call may contain arguments which need to be evaluated, but
9784 which are not useful to determine the result of the call. In
9785 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9786 COMPOUND_EXPR will be an argument which must be evaluated.
9787 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9788 COMPOUND_EXPR in the chain will contain the tree for the simplified
9789 form of the builtin function call. */
9792 fold_builtin_strstr (tree arglist
, tree type
)
9794 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
9798 tree s1
= TREE_VALUE (arglist
), s2
= TREE_VALUE (TREE_CHAIN (arglist
));
9800 const char *p1
, *p2
;
9809 const char *r
= strstr (p1
, p2
);
9813 return build_int_cst (TREE_TYPE (s1
), 0);
9815 /* Return an offset into the constant string argument. */
9816 tem
= fold_build2 (PLUS_EXPR
, TREE_TYPE (s1
),
9817 s1
, build_int_cst (TREE_TYPE (s1
), r
- p1
));
9818 return fold_convert (type
, tem
);
9821 /* The argument is const char *, and the result is char *, so we need
9822 a type conversion here to avoid a warning. */
9824 return fold_convert (type
, s1
);
9829 fn
= implicit_built_in_decls
[BUILT_IN_STRCHR
];
9833 /* New argument list transforming strstr(s1, s2) to
9834 strchr(s1, s2[0]). */
9835 arglist
= build_tree_list (NULL_TREE
,
9836 build_int_cst (NULL_TREE
, p2
[0]));
9837 arglist
= tree_cons (NULL_TREE
, s1
, arglist
);
9838 return build_function_call_expr (fn
, arglist
);
9842 /* Simplify a call to the strchr builtin.
9844 Return 0 if no simplification was possible, otherwise return the
9845 simplified form of the call as a tree.
9847 The simplified form may be a constant or other expression which
9848 computes the same value, but in a more efficient manner (including
9849 calls to other builtin functions).
9851 The call may contain arguments which need to be evaluated, but
9852 which are not useful to determine the result of the call. In
9853 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9854 COMPOUND_EXPR will be an argument which must be evaluated.
9855 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9856 COMPOUND_EXPR in the chain will contain the tree for the simplified
9857 form of the builtin function call. */
9860 fold_builtin_strchr (tree arglist
, tree type
)
9862 if (!validate_arglist (arglist
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
9866 tree s1
= TREE_VALUE (arglist
), s2
= TREE_VALUE (TREE_CHAIN (arglist
));
9869 if (TREE_CODE (s2
) != INTEGER_CST
)
9879 if (target_char_cast (s2
, &c
))
9885 return build_int_cst (TREE_TYPE (s1
), 0);
9887 /* Return an offset into the constant string argument. */
9888 tem
= fold_build2 (PLUS_EXPR
, TREE_TYPE (s1
),
9889 s1
, build_int_cst (TREE_TYPE (s1
), r
- p1
));
9890 return fold_convert (type
, tem
);
9896 /* Simplify a call to the strrchr builtin.
9898 Return 0 if no simplification was possible, otherwise return the
9899 simplified form of the call as a tree.
9901 The simplified form may be a constant or other expression which
9902 computes the same value, but in a more efficient manner (including
9903 calls to other builtin functions).
9905 The call may contain arguments which need to be evaluated, but
9906 which are not useful to determine the result of the call. In
9907 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9908 COMPOUND_EXPR will be an argument which must be evaluated.
9909 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9910 COMPOUND_EXPR in the chain will contain the tree for the simplified
9911 form of the builtin function call. */
9914 fold_builtin_strrchr (tree arglist
, tree type
)
9916 if (!validate_arglist (arglist
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
9920 tree s1
= TREE_VALUE (arglist
), s2
= TREE_VALUE (TREE_CHAIN (arglist
));
9924 if (TREE_CODE (s2
) != INTEGER_CST
)
9934 if (target_char_cast (s2
, &c
))
9937 r
= strrchr (p1
, c
);
9940 return build_int_cst (TREE_TYPE (s1
), 0);
9942 /* Return an offset into the constant string argument. */
9943 tem
= fold_build2 (PLUS_EXPR
, TREE_TYPE (s1
),
9944 s1
, build_int_cst (TREE_TYPE (s1
), r
- p1
));
9945 return fold_convert (type
, tem
);
9948 if (! integer_zerop (s2
))
9951 fn
= implicit_built_in_decls
[BUILT_IN_STRCHR
];
9955 /* Transform strrchr(s1, '\0') to strchr(s1, '\0'). */
9956 return build_function_call_expr (fn
, arglist
);
9960 /* Simplify a call to the strpbrk builtin.
9962 Return 0 if no simplification was possible, otherwise return the
9963 simplified form of the call as a tree.
9965 The simplified form may be a constant or other expression which
9966 computes the same value, but in a more efficient manner (including
9967 calls to other builtin functions).
9969 The call may contain arguments which need to be evaluated, but
9970 which are not useful to determine the result of the call. In
9971 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9972 COMPOUND_EXPR will be an argument which must be evaluated.
9973 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9974 COMPOUND_EXPR in the chain will contain the tree for the simplified
9975 form of the builtin function call. */
9978 fold_builtin_strpbrk (tree arglist
, tree type
)
9980 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
9984 tree s1
= TREE_VALUE (arglist
), s2
= TREE_VALUE (TREE_CHAIN (arglist
));
9986 const char *p1
, *p2
;
9995 const char *r
= strpbrk (p1
, p2
);
9999 return build_int_cst (TREE_TYPE (s1
), 0);
10001 /* Return an offset into the constant string argument. */
10002 tem
= fold_build2 (PLUS_EXPR
, TREE_TYPE (s1
),
10003 s1
, build_int_cst (TREE_TYPE (s1
), r
- p1
));
10004 return fold_convert (type
, tem
);
10008 /* strpbrk(x, "") == NULL.
10009 Evaluate and ignore s1 in case it had side-effects. */
10010 return omit_one_operand (TREE_TYPE (s1
), integer_zero_node
, s1
);
10013 return 0; /* Really call strpbrk. */
10015 fn
= implicit_built_in_decls
[BUILT_IN_STRCHR
];
10019 /* New argument list transforming strpbrk(s1, s2) to
10020 strchr(s1, s2[0]). */
10021 arglist
= build_tree_list (NULL_TREE
,
10022 build_int_cst (NULL_TREE
, p2
[0]));
10023 arglist
= tree_cons (NULL_TREE
, s1
, arglist
);
10024 return build_function_call_expr (fn
, arglist
);
10028 /* Simplify a call to the strcat builtin.
10030 Return 0 if no simplification was possible, otherwise return the
10031 simplified form of the call as a tree.
10033 The simplified form may be a constant or other expression which
10034 computes the same value, but in a more efficient manner (including
10035 calls to other builtin functions).
10037 The call may contain arguments which need to be evaluated, but
10038 which are not useful to determine the result of the call. In
10039 this case we return a chain of COMPOUND_EXPRs. The LHS of each
10040 COMPOUND_EXPR will be an argument which must be evaluated.
10041 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
10042 COMPOUND_EXPR in the chain will contain the tree for the simplified
10043 form of the builtin function call. */
10046 fold_builtin_strcat (tree arglist
)
10048 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
10052 tree dst
= TREE_VALUE (arglist
),
10053 src
= TREE_VALUE (TREE_CHAIN (arglist
));
10054 const char *p
= c_getstr (src
);
10056 /* If the string length is zero, return the dst parameter. */
10057 if (p
&& *p
== '\0')
10064 /* Simplify a call to the strncat builtin.
10066 Return 0 if no simplification was possible, otherwise return the
10067 simplified form of the call as a tree.
10069 The simplified form may be a constant or other expression which
10070 computes the same value, but in a more efficient manner (including
10071 calls to other builtin functions).
10073 The call may contain arguments which need to be evaluated, but
10074 which are not useful to determine the result of the call. In
10075 this case we return a chain of COMPOUND_EXPRs. The LHS of each
10076 COMPOUND_EXPR will be an argument which must be evaluated.
10077 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
10078 COMPOUND_EXPR in the chain will contain the tree for the simplified
10079 form of the builtin function call. */
10082 fold_builtin_strncat (tree arglist
)
10084 if (!validate_arglist (arglist
,
10085 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
10089 tree dst
= TREE_VALUE (arglist
);
10090 tree src
= TREE_VALUE (TREE_CHAIN (arglist
));
10091 tree len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
10092 const char *p
= c_getstr (src
);
10094 /* If the requested length is zero, or the src parameter string
10095 length is zero, return the dst parameter. */
10096 if (integer_zerop (len
) || (p
&& *p
== '\0'))
10097 return omit_two_operands (TREE_TYPE (dst
), dst
, src
, len
);
10099 /* If the requested len is greater than or equal to the string
10100 length, call strcat. */
10101 if (TREE_CODE (len
) == INTEGER_CST
&& p
10102 && compare_tree_int (len
, strlen (p
)) >= 0)
10105 = tree_cons (NULL_TREE
, dst
, build_tree_list (NULL_TREE
, src
));
10106 tree fn
= implicit_built_in_decls
[BUILT_IN_STRCAT
];
10108 /* If the replacement _DECL isn't initialized, don't do the
10113 return build_function_call_expr (fn
, newarglist
);
10119 /* Simplify a call to the strspn builtin.
10121 Return 0 if no simplification was possible, otherwise return the
10122 simplified form of the call as a tree.
10124 The simplified form may be a constant or other expression which
10125 computes the same value, but in a more efficient manner (including
10126 calls to other builtin functions).
10128 The call may contain arguments which need to be evaluated, but
10129 which are not useful to determine the result of the call. In
10130 this case we return a chain of COMPOUND_EXPRs. The LHS of each
10131 COMPOUND_EXPR will be an argument which must be evaluated.
10132 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
10133 COMPOUND_EXPR in the chain will contain the tree for the simplified
10134 form of the builtin function call. */
10137 fold_builtin_strspn (tree arglist
)
10139 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
10143 tree s1
= TREE_VALUE (arglist
), s2
= TREE_VALUE (TREE_CHAIN (arglist
));
10144 const char *p1
= c_getstr (s1
), *p2
= c_getstr (s2
);
10146 /* If both arguments are constants, evaluate at compile-time. */
10149 const size_t r
= strspn (p1
, p2
);
10150 return size_int (r
);
10153 /* If either argument is "", return 0. */
10154 if ((p1
&& *p1
== '\0') || (p2
&& *p2
== '\0'))
10155 /* Evaluate and ignore both arguments in case either one has
10157 return omit_two_operands (integer_type_node
, integer_zero_node
,
10163 /* Simplify a call to the strcspn builtin.
10165 Return 0 if no simplification was possible, otherwise return the
10166 simplified form of the call as a tree.
10168 The simplified form may be a constant or other expression which
10169 computes the same value, but in a more efficient manner (including
10170 calls to other builtin functions).
10172 The call may contain arguments which need to be evaluated, but
10173 which are not useful to determine the result of the call. In
10174 this case we return a chain of COMPOUND_EXPRs. The LHS of each
10175 COMPOUND_EXPR will be an argument which must be evaluated.
10176 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
10177 COMPOUND_EXPR in the chain will contain the tree for the simplified
10178 form of the builtin function call. */
10181 fold_builtin_strcspn (tree arglist
)
10183 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
10187 tree s1
= TREE_VALUE (arglist
), s2
= TREE_VALUE (TREE_CHAIN (arglist
));
10188 const char *p1
= c_getstr (s1
), *p2
= c_getstr (s2
);
10190 /* If both arguments are constants, evaluate at compile-time. */
10193 const size_t r
= strcspn (p1
, p2
);
10194 return size_int (r
);
10197 /* If the first argument is "", return 0. */
10198 if (p1
&& *p1
== '\0')
10200 /* Evaluate and ignore argument s2 in case it has
10202 return omit_one_operand (integer_type_node
,
10203 integer_zero_node
, s2
);
10206 /* If the second argument is "", return __builtin_strlen(s1). */
10207 if (p2
&& *p2
== '\0')
10209 tree newarglist
= build_tree_list (NULL_TREE
, s1
),
10210 fn
= implicit_built_in_decls
[BUILT_IN_STRLEN
];
10212 /* If the replacement _DECL isn't initialized, don't do the
10217 return build_function_call_expr (fn
, newarglist
);
10223 /* Fold a call to the fputs builtin. IGNORE is true if the value returned
10224 by the builtin will be ignored. UNLOCKED is true is true if this
10225 actually a call to fputs_unlocked. If LEN in non-NULL, it represents
10226 the known length of the string. Return NULL_TREE if no simplification
10230 fold_builtin_fputs (tree arglist
, bool ignore
, bool unlocked
, tree len
)
10233 /* If we're using an unlocked function, assume the other unlocked
10234 functions exist explicitly. */
10235 tree
const fn_fputc
= unlocked
? built_in_decls
[BUILT_IN_FPUTC_UNLOCKED
]
10236 : implicit_built_in_decls
[BUILT_IN_FPUTC
];
10237 tree
const fn_fwrite
= unlocked
? built_in_decls
[BUILT_IN_FWRITE_UNLOCKED
]
10238 : implicit_built_in_decls
[BUILT_IN_FWRITE
];
10240 /* If the return value is used, don't do the transformation. */
10244 /* Verify the arguments in the original call. */
10245 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
10249 len
= c_strlen (TREE_VALUE (arglist
), 0);
10251 /* Get the length of the string passed to fputs. If the length
10252 can't be determined, punt. */
10254 || TREE_CODE (len
) != INTEGER_CST
)
10257 switch (compare_tree_int (len
, 1))
10259 case -1: /* length is 0, delete the call entirely . */
10260 return omit_one_operand (integer_type_node
, integer_zero_node
,
10261 TREE_VALUE (TREE_CHAIN (arglist
)));
10263 case 0: /* length is 1, call fputc. */
10265 const char *p
= c_getstr (TREE_VALUE (arglist
));
10269 /* New argument list transforming fputs(string, stream) to
10270 fputc(string[0], stream). */
10271 arglist
= build_tree_list (NULL_TREE
,
10272 TREE_VALUE (TREE_CHAIN (arglist
)));
10273 arglist
= tree_cons (NULL_TREE
,
10274 build_int_cst (NULL_TREE
, p
[0]),
10281 case 1: /* length is greater than 1, call fwrite. */
10285 /* If optimizing for size keep fputs. */
10288 string_arg
= TREE_VALUE (arglist
);
10289 /* New argument list transforming fputs(string, stream) to
10290 fwrite(string, 1, len, stream). */
10291 arglist
= build_tree_list (NULL_TREE
,
10292 TREE_VALUE (TREE_CHAIN (arglist
)));
10293 arglist
= tree_cons (NULL_TREE
, len
, arglist
);
10294 arglist
= tree_cons (NULL_TREE
, size_one_node
, arglist
);
10295 arglist
= tree_cons (NULL_TREE
, string_arg
, arglist
);
10300 gcc_unreachable ();
10303 /* If the replacement _DECL isn't initialized, don't do the
10308 /* These optimizations are only performed when the result is ignored,
10309 hence there's no need to cast the result to integer_type_node. */
10310 return build_function_call_expr (fn
, arglist
);
10313 /* Fold the new_arg's arguments (ARGLIST). Returns true if there was an error
10314 produced. False otherwise. This is done so that we don't output the error
10315 or warning twice or three times. */
10317 fold_builtin_next_arg (tree arglist
)
10319 tree fntype
= TREE_TYPE (current_function_decl
);
10321 if (TYPE_ARG_TYPES (fntype
) == 0
10322 || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype
)))
10323 == void_type_node
))
10325 error ("%<va_start%> used in function with fixed args");
10330 /* Evidently an out of date version of <stdarg.h>; can't validate
10331 va_start's second argument, but can still work as intended. */
10332 warning (0, "%<__builtin_next_arg%> called without an argument");
10335 /* We use __builtin_va_start (ap, 0, 0) or __builtin_next_arg (0, 0)
10336 when we checked the arguments and if needed issued a warning. */
10337 else if (!TREE_CHAIN (arglist
)
10338 || !integer_zerop (TREE_VALUE (arglist
))
10339 || !integer_zerop (TREE_VALUE (TREE_CHAIN (arglist
)))
10340 || TREE_CHAIN (TREE_CHAIN (arglist
)))
10342 tree last_parm
= tree_last (DECL_ARGUMENTS (current_function_decl
));
10343 tree arg
= TREE_VALUE (arglist
);
10345 if (TREE_CHAIN (arglist
))
10347 error ("%<va_start%> used with too many arguments");
10351 /* Strip off all nops for the sake of the comparison. This
10352 is not quite the same as STRIP_NOPS. It does more.
10353 We must also strip off INDIRECT_EXPR for C++ reference
10355 while (TREE_CODE (arg
) == NOP_EXPR
10356 || TREE_CODE (arg
) == CONVERT_EXPR
10357 || TREE_CODE (arg
) == NON_LVALUE_EXPR
10358 || TREE_CODE (arg
) == INDIRECT_REF
)
10359 arg
= TREE_OPERAND (arg
, 0);
10360 if (arg
!= last_parm
)
10362 /* FIXME: Sometimes with the tree optimizers we can get the
10363 not the last argument even though the user used the last
10364 argument. We just warn and set the arg to be the last
10365 argument so that we will get wrong-code because of
10367 warning (0, "second parameter of %<va_start%> not last named argument");
10369 /* We want to verify the second parameter just once before the tree
10370 optimizers are run and then avoid keeping it in the tree,
10371 as otherwise we could warn even for correct code like:
10372 void foo (int i, ...)
10373 { va_list ap; i++; va_start (ap, i); va_end (ap); } */
10374 TREE_VALUE (arglist
) = integer_zero_node
;
10375 TREE_CHAIN (arglist
) = build_tree_list (NULL
, integer_zero_node
);
10381 /* Simplify a call to the sprintf builtin.
10383 Return 0 if no simplification was possible, otherwise return the
10384 simplified form of the call as a tree. If IGNORED is true, it means that
10385 the caller does not use the returned value of the function. */
10388 fold_builtin_sprintf (tree arglist
, int ignored
)
10390 tree call
, retval
, dest
, fmt
;
10391 const char *fmt_str
= NULL
;
10393 /* Verify the required arguments in the original call. We deal with two
10394 types of sprintf() calls: 'sprintf (str, fmt)' and
10395 'sprintf (dest, "%s", orig)'. */
10396 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
)
10397 && !validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, POINTER_TYPE
,
10401 /* Get the destination string and the format specifier. */
10402 dest
= TREE_VALUE (arglist
);
10403 fmt
= TREE_VALUE (TREE_CHAIN (arglist
));
10405 /* Check whether the format is a literal string constant. */
10406 fmt_str
= c_getstr (fmt
);
10407 if (fmt_str
== NULL
)
10411 retval
= NULL_TREE
;
10413 if (!init_target_chars())
10416 /* If the format doesn't contain % args or %%, use strcpy. */
10417 if (strchr (fmt_str
, target_percent
) == NULL
)
10419 tree fn
= implicit_built_in_decls
[BUILT_IN_STRCPY
];
10424 /* Convert sprintf (str, fmt) into strcpy (str, fmt) when
10425 'format' is known to contain no % formats. */
10426 arglist
= build_tree_list (NULL_TREE
, fmt
);
10427 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
10428 call
= build_function_call_expr (fn
, arglist
);
10430 retval
= build_int_cst (NULL_TREE
, strlen (fmt_str
));
10433 /* If the format is "%s", use strcpy if the result isn't used. */
10434 else if (fmt_str
&& strcmp (fmt_str
, target_percent_s
) == 0)
10437 fn
= implicit_built_in_decls
[BUILT_IN_STRCPY
];
10442 /* Convert sprintf (str1, "%s", str2) into strcpy (str1, str2). */
10443 orig
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
10444 arglist
= build_tree_list (NULL_TREE
, orig
);
10445 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
10448 retval
= c_strlen (orig
, 1);
10449 if (!retval
|| TREE_CODE (retval
) != INTEGER_CST
)
10452 call
= build_function_call_expr (fn
, arglist
);
10455 if (call
&& retval
)
10457 retval
= fold_convert
10458 (TREE_TYPE (TREE_TYPE (implicit_built_in_decls
[BUILT_IN_SPRINTF
])),
10460 return build2 (COMPOUND_EXPR
, TREE_TYPE (retval
), call
, retval
);
10466 /* Expand a call to __builtin_object_size. */
10469 expand_builtin_object_size (tree exp
)
10472 int object_size_type
;
10473 tree fndecl
= get_callee_fndecl (exp
);
10474 tree arglist
= TREE_OPERAND (exp
, 1);
10475 location_t locus
= EXPR_LOCATION (exp
);
10477 if (!validate_arglist (arglist
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
10479 error ("%Hfirst argument of %D must be a pointer, second integer constant",
10481 expand_builtin_trap ();
10485 ost
= TREE_VALUE (TREE_CHAIN (arglist
));
10488 if (TREE_CODE (ost
) != INTEGER_CST
10489 || tree_int_cst_sgn (ost
) < 0
10490 || compare_tree_int (ost
, 3) > 0)
10492 error ("%Hlast argument of %D is not integer constant between 0 and 3",
10494 expand_builtin_trap ();
10498 object_size_type
= tree_low_cst (ost
, 0);
10500 return object_size_type
< 2 ? constm1_rtx
: const0_rtx
;
10503 /* Expand EXP, a call to the __mem{cpy,pcpy,move,set}_chk builtin.
10504 FCODE is the BUILT_IN_* to use.
10505 Return 0 if we failed; the caller should emit a normal call,
10506 otherwise try to get the result in TARGET, if convenient (and in
10507 mode MODE if that's convenient). */
10510 expand_builtin_memory_chk (tree exp
, rtx target
, enum machine_mode mode
,
10511 enum built_in_function fcode
)
10513 tree arglist
= TREE_OPERAND (exp
, 1);
10514 tree dest
, src
, len
, size
;
10516 if (!validate_arglist (arglist
,
10518 fcode
== BUILT_IN_MEMSET_CHK
10519 ? INTEGER_TYPE
: POINTER_TYPE
,
10520 INTEGER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
10523 dest
= TREE_VALUE (arglist
);
10524 src
= TREE_VALUE (TREE_CHAIN (arglist
));
10525 len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
10526 size
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist
))));
10528 if (! host_integerp (size
, 1))
10531 if (host_integerp (len
, 1) || integer_all_onesp (size
))
10535 if (! integer_all_onesp (size
) && tree_int_cst_lt (size
, len
))
10537 location_t locus
= EXPR_LOCATION (exp
);
10538 warning (0, "%Hcall to %D will always overflow destination buffer",
10539 &locus
, get_callee_fndecl (exp
));
10543 arglist
= build_tree_list (NULL_TREE
, len
);
10544 arglist
= tree_cons (NULL_TREE
, src
, arglist
);
10545 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
10548 /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume
10549 mem{cpy,pcpy,move,set} is available. */
10552 case BUILT_IN_MEMCPY_CHK
:
10553 fn
= built_in_decls
[BUILT_IN_MEMCPY
];
10555 case BUILT_IN_MEMPCPY_CHK
:
10556 fn
= built_in_decls
[BUILT_IN_MEMPCPY
];
10558 case BUILT_IN_MEMMOVE_CHK
:
10559 fn
= built_in_decls
[BUILT_IN_MEMMOVE
];
10561 case BUILT_IN_MEMSET_CHK
:
10562 fn
= built_in_decls
[BUILT_IN_MEMSET
];
10571 fn
= build_function_call_expr (fn
, arglist
);
10572 if (TREE_CODE (fn
) == CALL_EXPR
)
10573 CALL_EXPR_TAILCALL (fn
) = CALL_EXPR_TAILCALL (exp
);
10574 return expand_expr (fn
, target
, mode
, EXPAND_NORMAL
);
10576 else if (fcode
== BUILT_IN_MEMSET_CHK
)
10580 unsigned int dest_align
10581 = get_pointer_alignment (dest
, BIGGEST_ALIGNMENT
);
10583 /* If DEST is not a pointer type, call the normal function. */
10584 if (dest_align
== 0)
10587 /* If SRC and DEST are the same (and not volatile), do nothing. */
10588 if (operand_equal_p (src
, dest
, 0))
10592 if (fcode
!= BUILT_IN_MEMPCPY_CHK
)
10594 /* Evaluate and ignore LEN in case it has side-effects. */
10595 expand_expr (len
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
10596 return expand_expr (dest
, target
, mode
, EXPAND_NORMAL
);
10599 len
= fold_convert (TREE_TYPE (dest
), len
);
10600 expr
= fold_build2 (PLUS_EXPR
, TREE_TYPE (dest
), dest
, len
);
10601 return expand_expr (expr
, target
, mode
, EXPAND_NORMAL
);
10604 /* __memmove_chk special case. */
10605 if (fcode
== BUILT_IN_MEMMOVE_CHK
)
10607 unsigned int src_align
10608 = get_pointer_alignment (src
, BIGGEST_ALIGNMENT
);
10610 if (src_align
== 0)
10613 /* If src is categorized for a readonly section we can use
10614 normal __memcpy_chk. */
10615 if (readonly_data_expr (src
))
10617 tree fn
= built_in_decls
[BUILT_IN_MEMCPY_CHK
];
10620 fn
= build_function_call_expr (fn
, arglist
);
10621 if (TREE_CODE (fn
) == CALL_EXPR
)
10622 CALL_EXPR_TAILCALL (fn
) = CALL_EXPR_TAILCALL (exp
);
10623 return expand_expr (fn
, target
, mode
, EXPAND_NORMAL
);
10630 /* Emit warning if a buffer overflow is detected at compile time. */
10633 maybe_emit_chk_warning (tree exp
, enum built_in_function fcode
)
10635 int arg_mask
, is_strlen
= 0;
10636 tree arglist
= TREE_OPERAND (exp
, 1), a
;
10642 case BUILT_IN_STRCPY_CHK
:
10643 case BUILT_IN_STPCPY_CHK
:
10644 /* For __strcat_chk the warning will be emitted only if overflowing
10645 by at least strlen (dest) + 1 bytes. */
10646 case BUILT_IN_STRCAT_CHK
:
10650 case BUILT_IN_STRNCAT_CHK
:
10651 /* For __strncat_chk the warning will be emitted only if overflowing
10652 by at least strlen (dest) + 1 bytes. */
10655 case BUILT_IN_STRNCPY_CHK
:
10658 case BUILT_IN_SNPRINTF_CHK
:
10659 case BUILT_IN_VSNPRINTF_CHK
:
10663 gcc_unreachable ();
10668 for (a
= arglist
; a
&& arg_mask
; a
= TREE_CHAIN (a
), arg_mask
>>= 1)
10680 len
= TREE_VALUE (len
);
10681 size
= TREE_VALUE (size
);
10683 if (! host_integerp (size
, 1) || integer_all_onesp (size
))
10688 len
= c_strlen (len
, 1);
10689 if (! len
|| ! host_integerp (len
, 1) || tree_int_cst_lt (len
, size
))
10692 else if (fcode
== BUILT_IN_STRNCAT_CHK
)
10694 tree src
= TREE_VALUE (TREE_CHAIN (arglist
));
10695 if (! src
|| ! host_integerp (len
, 1) || tree_int_cst_lt (len
, size
))
10697 src
= c_strlen (src
, 1);
10698 if (! src
|| ! host_integerp (src
, 1))
10700 locus
= EXPR_LOCATION (exp
);
10701 warning (0, "%Hcall to %D might overflow destination buffer",
10702 &locus
, get_callee_fndecl (exp
));
10705 else if (tree_int_cst_lt (src
, size
))
10708 else if (! host_integerp (len
, 1) || ! tree_int_cst_lt (size
, len
))
10711 locus
= EXPR_LOCATION (exp
);
10712 warning (0, "%Hcall to %D will always overflow destination buffer",
10713 &locus
, get_callee_fndecl (exp
));
10716 /* Emit warning if a buffer overflow is detected at compile time
10717 in __sprintf_chk/__vsprintf_chk calls. */
10720 maybe_emit_sprintf_chk_warning (tree exp
, enum built_in_function fcode
)
10722 tree arglist
= TREE_OPERAND (exp
, 1);
10723 tree dest
, size
, len
, fmt
, flag
;
10724 const char *fmt_str
;
10726 /* Verify the required arguments in the original call. */
10729 dest
= TREE_VALUE (arglist
);
10730 arglist
= TREE_CHAIN (arglist
);
10733 flag
= TREE_VALUE (arglist
);
10734 arglist
= TREE_CHAIN (arglist
);
10737 size
= TREE_VALUE (arglist
);
10738 arglist
= TREE_CHAIN (arglist
);
10741 fmt
= TREE_VALUE (arglist
);
10742 arglist
= TREE_CHAIN (arglist
);
10744 if (! host_integerp (size
, 1) || integer_all_onesp (size
))
10747 /* Check whether the format is a literal string constant. */
10748 fmt_str
= c_getstr (fmt
);
10749 if (fmt_str
== NULL
)
10752 if (!init_target_chars())
10755 /* If the format doesn't contain % args or %%, we know its size. */
10756 if (strchr (fmt_str
, target_percent
) == 0)
10757 len
= build_int_cstu (size_type_node
, strlen (fmt_str
));
10758 /* If the format is "%s" and first ... argument is a string literal,
10760 else if (fcode
== BUILT_IN_SPRINTF_CHK
&& strcmp (fmt_str
, target_percent_s
) == 0)
10766 arg
= TREE_VALUE (arglist
);
10767 if (! POINTER_TYPE_P (TREE_TYPE (arg
)))
10770 len
= c_strlen (arg
, 1);
10771 if (!len
|| ! host_integerp (len
, 1))
10777 if (! tree_int_cst_lt (len
, size
))
10779 location_t locus
= EXPR_LOCATION (exp
);
10780 warning (0, "%Hcall to %D will always overflow destination buffer",
10781 &locus
, get_callee_fndecl (exp
));
10785 /* Fold a call to __builtin_object_size, if possible. */
10788 fold_builtin_object_size (tree arglist
)
10790 tree ptr
, ost
, ret
= 0;
10791 int object_size_type
;
10793 if (!validate_arglist (arglist
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
10796 ptr
= TREE_VALUE (arglist
);
10797 ost
= TREE_VALUE (TREE_CHAIN (arglist
));
10800 if (TREE_CODE (ost
) != INTEGER_CST
10801 || tree_int_cst_sgn (ost
) < 0
10802 || compare_tree_int (ost
, 3) > 0)
10805 object_size_type
= tree_low_cst (ost
, 0);
10807 /* __builtin_object_size doesn't evaluate side-effects in its arguments;
10808 if there are any side-effects, it returns (size_t) -1 for types 0 and 1
10809 and (size_t) 0 for types 2 and 3. */
10810 if (TREE_SIDE_EFFECTS (ptr
))
10811 return fold_convert (size_type_node
,
10812 object_size_type
< 2
10813 ? integer_minus_one_node
: integer_zero_node
);
10815 if (TREE_CODE (ptr
) == ADDR_EXPR
)
10816 ret
= build_int_cstu (size_type_node
,
10817 compute_builtin_object_size (ptr
, object_size_type
));
10819 else if (TREE_CODE (ptr
) == SSA_NAME
)
10821 unsigned HOST_WIDE_INT bytes
;
10823 /* If object size is not known yet, delay folding until
10824 later. Maybe subsequent passes will help determining
10826 bytes
= compute_builtin_object_size (ptr
, object_size_type
);
10827 if (bytes
!= (unsigned HOST_WIDE_INT
) (object_size_type
< 2
10829 ret
= build_int_cstu (size_type_node
, bytes
);
10834 ret
= force_fit_type (ret
, -1, false, false);
10835 if (TREE_CONSTANT_OVERFLOW (ret
))
10842 /* Fold a call to the __mem{cpy,pcpy,move,set}_chk builtin.
10843 IGNORE is true, if return value can be ignored. FCODE is the BUILT_IN_*
10844 code of the builtin. If MAXLEN is not NULL, it is maximum length
10845 passed as third argument. */
10848 fold_builtin_memory_chk (tree fndecl
, tree arglist
, tree maxlen
, bool ignore
,
10849 enum built_in_function fcode
)
10851 tree dest
, src
, len
, size
, fn
;
10853 if (!validate_arglist (arglist
,
10855 fcode
== BUILT_IN_MEMSET_CHK
10856 ? INTEGER_TYPE
: POINTER_TYPE
,
10857 INTEGER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
10860 dest
= TREE_VALUE (arglist
);
10861 /* Actually val for __memset_chk, but it doesn't matter. */
10862 src
= TREE_VALUE (TREE_CHAIN (arglist
));
10863 len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
10864 size
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist
))));
10866 /* If SRC and DEST are the same (and not volatile), return DEST
10867 (resp. DEST+LEN for __mempcpy_chk). */
10868 if (fcode
!= BUILT_IN_MEMSET_CHK
&& operand_equal_p (src
, dest
, 0))
10870 if (fcode
!= BUILT_IN_MEMPCPY_CHK
)
10871 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl
)), dest
, len
);
10874 tree temp
= fold_convert (TREE_TYPE (dest
), len
);
10875 temp
= fold_build2 (PLUS_EXPR
, TREE_TYPE (dest
), dest
, temp
);
10876 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl
)), temp
);
10880 if (! host_integerp (size
, 1))
10883 if (! integer_all_onesp (size
))
10885 if (! host_integerp (len
, 1))
10887 /* If LEN is not constant, try MAXLEN too.
10888 For MAXLEN only allow optimizing into non-_ocs function
10889 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
10890 if (maxlen
== NULL_TREE
|| ! host_integerp (maxlen
, 1))
10892 if (fcode
== BUILT_IN_MEMPCPY_CHK
&& ignore
)
10894 /* (void) __mempcpy_chk () can be optimized into
10895 (void) __memcpy_chk (). */
10896 fn
= built_in_decls
[BUILT_IN_MEMCPY_CHK
];
10900 return build_function_call_expr (fn
, arglist
);
10908 if (tree_int_cst_lt (size
, maxlen
))
10912 arglist
= build_tree_list (NULL_TREE
, len
);
10913 arglist
= tree_cons (NULL_TREE
, src
, arglist
);
10914 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
10917 /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume
10918 mem{cpy,pcpy,move,set} is available. */
10921 case BUILT_IN_MEMCPY_CHK
:
10922 fn
= built_in_decls
[BUILT_IN_MEMCPY
];
10924 case BUILT_IN_MEMPCPY_CHK
:
10925 fn
= built_in_decls
[BUILT_IN_MEMPCPY
];
10927 case BUILT_IN_MEMMOVE_CHK
:
10928 fn
= built_in_decls
[BUILT_IN_MEMMOVE
];
10930 case BUILT_IN_MEMSET_CHK
:
10931 fn
= built_in_decls
[BUILT_IN_MEMSET
];
10940 return build_function_call_expr (fn
, arglist
);
10943 /* Fold a call to the __st[rp]cpy_chk builtin.
10944 IGNORE is true, if return value can be ignored. FCODE is the BUILT_IN_*
10945 code of the builtin. If MAXLEN is not NULL, it is maximum length of
10946 strings passed as second argument. */
10949 fold_builtin_stxcpy_chk (tree fndecl
, tree arglist
, tree maxlen
, bool ignore
,
10950 enum built_in_function fcode
)
10952 tree dest
, src
, size
, len
, fn
;
10954 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
,
10958 dest
= TREE_VALUE (arglist
);
10959 src
= TREE_VALUE (TREE_CHAIN (arglist
));
10960 size
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
10962 /* If SRC and DEST are the same (and not volatile), return DEST. */
10963 if (fcode
== BUILT_IN_STRCPY_CHK
&& operand_equal_p (src
, dest
, 0))
10964 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl
)), dest
);
10966 if (! host_integerp (size
, 1))
10969 if (! integer_all_onesp (size
))
10971 len
= c_strlen (src
, 1);
10972 if (! len
|| ! host_integerp (len
, 1))
10974 /* If LEN is not constant, try MAXLEN too.
10975 For MAXLEN only allow optimizing into non-_ocs function
10976 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
10977 if (maxlen
== NULL_TREE
|| ! host_integerp (maxlen
, 1))
10979 if (fcode
== BUILT_IN_STPCPY_CHK
)
10984 /* If return value of __stpcpy_chk is ignored,
10985 optimize into __strcpy_chk. */
10986 fn
= built_in_decls
[BUILT_IN_STRCPY_CHK
];
10990 return build_function_call_expr (fn
, arglist
);
10993 if (! len
|| TREE_SIDE_EFFECTS (len
))
10996 /* If c_strlen returned something, but not a constant,
10997 transform __strcpy_chk into __memcpy_chk. */
10998 fn
= built_in_decls
[BUILT_IN_MEMCPY_CHK
];
11002 len
= size_binop (PLUS_EXPR
, len
, ssize_int (1));
11003 arglist
= build_tree_list (NULL_TREE
, size
);
11004 arglist
= tree_cons (NULL_TREE
, len
, arglist
);
11005 arglist
= tree_cons (NULL_TREE
, src
, arglist
);
11006 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
11007 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl
)),
11008 build_function_call_expr (fn
, arglist
));
11014 if (! tree_int_cst_lt (maxlen
, size
))
11018 arglist
= build_tree_list (NULL_TREE
, src
);
11019 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
11021 /* If __builtin_st{r,p}cpy_chk is used, assume st{r,p}cpy is available. */
11022 fn
= built_in_decls
[fcode
== BUILT_IN_STPCPY_CHK
11023 ? BUILT_IN_STPCPY
: BUILT_IN_STRCPY
];
11027 return build_function_call_expr (fn
, arglist
);
11030 /* Fold a call to the __strncpy_chk builtin.
11031 If MAXLEN is not NULL, it is maximum length passed as third argument. */
11034 fold_builtin_strncpy_chk (tree arglist
, tree maxlen
)
11036 tree dest
, src
, size
, len
, fn
;
11038 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
,
11039 INTEGER_TYPE
, VOID_TYPE
))
11042 dest
= TREE_VALUE (arglist
);
11043 src
= TREE_VALUE (TREE_CHAIN (arglist
));
11044 len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
11045 size
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist
))));
11047 if (! host_integerp (size
, 1))
11050 if (! integer_all_onesp (size
))
11052 if (! host_integerp (len
, 1))
11054 /* If LEN is not constant, try MAXLEN too.
11055 For MAXLEN only allow optimizing into non-_ocs function
11056 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
11057 if (maxlen
== NULL_TREE
|| ! host_integerp (maxlen
, 1))
11063 if (tree_int_cst_lt (size
, maxlen
))
11067 arglist
= build_tree_list (NULL_TREE
, len
);
11068 arglist
= tree_cons (NULL_TREE
, src
, arglist
);
11069 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
11071 /* If __builtin_strncpy_chk is used, assume strncpy is available. */
11072 fn
= built_in_decls
[BUILT_IN_STRNCPY
];
11076 return build_function_call_expr (fn
, arglist
);
11079 /* Fold a call to the __strcat_chk builtin FNDECL with ARGLIST. */
11082 fold_builtin_strcat_chk (tree fndecl
, tree arglist
)
11084 tree dest
, src
, size
, fn
;
11087 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
,
11091 dest
= TREE_VALUE (arglist
);
11092 src
= TREE_VALUE (TREE_CHAIN (arglist
));
11093 size
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
11095 p
= c_getstr (src
);
11096 /* If the SRC parameter is "", return DEST. */
11097 if (p
&& *p
== '\0')
11098 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl
)), dest
, src
);
11100 if (! host_integerp (size
, 1) || ! integer_all_onesp (size
))
11103 arglist
= build_tree_list (NULL_TREE
, src
);
11104 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
11106 /* If __builtin_strcat_chk is used, assume strcat is available. */
11107 fn
= built_in_decls
[BUILT_IN_STRCAT
];
11111 return build_function_call_expr (fn
, arglist
);
11114 /* Fold a call to the __strncat_chk builtin EXP. */
11117 fold_builtin_strncat_chk (tree fndecl
, tree arglist
)
11119 tree dest
, src
, size
, len
, fn
;
11122 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
,
11123 INTEGER_TYPE
, VOID_TYPE
))
11126 dest
= TREE_VALUE (arglist
);
11127 src
= TREE_VALUE (TREE_CHAIN (arglist
));
11128 len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
11129 size
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist
))));
11131 p
= c_getstr (src
);
11132 /* If the SRC parameter is "" or if LEN is 0, return DEST. */
11133 if (p
&& *p
== '\0')
11134 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl
)), dest
, len
);
11135 else if (integer_zerop (len
))
11136 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl
)), dest
, src
);
11138 if (! host_integerp (size
, 1))
11141 if (! integer_all_onesp (size
))
11143 tree src_len
= c_strlen (src
, 1);
11145 && host_integerp (src_len
, 1)
11146 && host_integerp (len
, 1)
11147 && ! tree_int_cst_lt (len
, src_len
))
11149 /* If LEN >= strlen (SRC), optimize into __strcat_chk. */
11150 fn
= built_in_decls
[BUILT_IN_STRCAT_CHK
];
11154 arglist
= build_tree_list (NULL_TREE
, size
);
11155 arglist
= tree_cons (NULL_TREE
, src
, arglist
);
11156 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
11157 return build_function_call_expr (fn
, arglist
);
11162 arglist
= build_tree_list (NULL_TREE
, len
);
11163 arglist
= tree_cons (NULL_TREE
, src
, arglist
);
11164 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
11166 /* If __builtin_strncat_chk is used, assume strncat is available. */
11167 fn
= built_in_decls
[BUILT_IN_STRNCAT
];
11171 return build_function_call_expr (fn
, arglist
);
11174 /* Fold a call to __{,v}sprintf_chk with argument list ARGLIST. Return 0 if
11175 a normal call should be emitted rather than expanding the function
11176 inline. FCODE is either BUILT_IN_SPRINTF_CHK or BUILT_IN_VSPRINTF_CHK. */
11179 fold_builtin_sprintf_chk (tree arglist
, enum built_in_function fcode
)
11181 tree dest
, size
, len
, fn
, fmt
, flag
;
11182 const char *fmt_str
;
11184 /* Verify the required arguments in the original call. */
11187 dest
= TREE_VALUE (arglist
);
11188 if (! POINTER_TYPE_P (TREE_TYPE (dest
)))
11190 arglist
= TREE_CHAIN (arglist
);
11193 flag
= TREE_VALUE (arglist
);
11194 if (TREE_CODE (TREE_TYPE (flag
)) != INTEGER_TYPE
)
11196 arglist
= TREE_CHAIN (arglist
);
11199 size
= TREE_VALUE (arglist
);
11200 if (TREE_CODE (TREE_TYPE (size
)) != INTEGER_TYPE
)
11202 arglist
= TREE_CHAIN (arglist
);
11205 fmt
= TREE_VALUE (arglist
);
11206 if (! POINTER_TYPE_P (TREE_TYPE (fmt
)))
11208 arglist
= TREE_CHAIN (arglist
);
11210 if (! host_integerp (size
, 1))
11215 if (!init_target_chars())
11218 /* Check whether the format is a literal string constant. */
11219 fmt_str
= c_getstr (fmt
);
11220 if (fmt_str
!= NULL
)
11222 /* If the format doesn't contain % args or %%, we know the size. */
11223 if (strchr (fmt_str
, target_percent
) == 0)
11225 if (fcode
!= BUILT_IN_SPRINTF_CHK
|| arglist
== NULL_TREE
)
11226 len
= build_int_cstu (size_type_node
, strlen (fmt_str
));
11228 /* If the format is "%s" and first ... argument is a string literal,
11229 we know the size too. */
11230 else if (fcode
== BUILT_IN_SPRINTF_CHK
&& strcmp (fmt_str
, target_percent_s
) == 0)
11234 if (arglist
&& !TREE_CHAIN (arglist
))
11236 arg
= TREE_VALUE (arglist
);
11237 if (POINTER_TYPE_P (TREE_TYPE (arg
)))
11239 len
= c_strlen (arg
, 1);
11240 if (! len
|| ! host_integerp (len
, 1))
11247 if (! integer_all_onesp (size
))
11249 if (! len
|| ! tree_int_cst_lt (len
, size
))
11253 /* Only convert __{,v}sprintf_chk to {,v}sprintf if flag is 0
11254 or if format doesn't contain % chars or is "%s". */
11255 if (! integer_zerop (flag
))
11257 if (fmt_str
== NULL
)
11259 if (strchr (fmt_str
, target_percent
) != NULL
&& strcmp (fmt_str
, target_percent_s
))
11263 arglist
= tree_cons (NULL_TREE
, fmt
, arglist
);
11264 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
11266 /* If __builtin_{,v}sprintf_chk is used, assume {,v}sprintf is available. */
11267 fn
= built_in_decls
[fcode
== BUILT_IN_VSPRINTF_CHK
11268 ? BUILT_IN_VSPRINTF
: BUILT_IN_SPRINTF
];
11272 return build_function_call_expr (fn
, arglist
);
11275 /* Fold a call to {,v}snprintf with argument list ARGLIST. Return 0 if
11276 a normal call should be emitted rather than expanding the function
11277 inline. FCODE is either BUILT_IN_SNPRINTF_CHK or
11278 BUILT_IN_VSNPRINTF_CHK. If MAXLEN is not NULL, it is maximum length
11279 passed as second argument. */
11282 fold_builtin_snprintf_chk (tree arglist
, tree maxlen
,
11283 enum built_in_function fcode
)
11285 tree dest
, size
, len
, fn
, fmt
, flag
;
11286 const char *fmt_str
;
11288 /* Verify the required arguments in the original call. */
11291 dest
= TREE_VALUE (arglist
);
11292 if (! POINTER_TYPE_P (TREE_TYPE (dest
)))
11294 arglist
= TREE_CHAIN (arglist
);
11297 len
= TREE_VALUE (arglist
);
11298 if (TREE_CODE (TREE_TYPE (len
)) != INTEGER_TYPE
)
11300 arglist
= TREE_CHAIN (arglist
);
11303 flag
= TREE_VALUE (arglist
);
11304 if (TREE_CODE (TREE_TYPE (len
)) != INTEGER_TYPE
)
11306 arglist
= TREE_CHAIN (arglist
);
11309 size
= TREE_VALUE (arglist
);
11310 if (TREE_CODE (TREE_TYPE (size
)) != INTEGER_TYPE
)
11312 arglist
= TREE_CHAIN (arglist
);
11315 fmt
= TREE_VALUE (arglist
);
11316 if (! POINTER_TYPE_P (TREE_TYPE (fmt
)))
11318 arglist
= TREE_CHAIN (arglist
);
11320 if (! host_integerp (size
, 1))
11323 if (! integer_all_onesp (size
))
11325 if (! host_integerp (len
, 1))
11327 /* If LEN is not constant, try MAXLEN too.
11328 For MAXLEN only allow optimizing into non-_ocs function
11329 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
11330 if (maxlen
== NULL_TREE
|| ! host_integerp (maxlen
, 1))
11336 if (tree_int_cst_lt (size
, maxlen
))
11340 if (!init_target_chars())
11343 /* Only convert __{,v}snprintf_chk to {,v}snprintf if flag is 0
11344 or if format doesn't contain % chars or is "%s". */
11345 if (! integer_zerop (flag
))
11347 fmt_str
= c_getstr (fmt
);
11348 if (fmt_str
== NULL
)
11350 if (strchr (fmt_str
, target_percent
) != NULL
&& strcmp (fmt_str
, target_percent_s
))
11354 arglist
= tree_cons (NULL_TREE
, fmt
, arglist
);
11355 arglist
= tree_cons (NULL_TREE
, len
, arglist
);
11356 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
11358 /* If __builtin_{,v}snprintf_chk is used, assume {,v}snprintf is
11360 fn
= built_in_decls
[fcode
== BUILT_IN_VSNPRINTF_CHK
11361 ? BUILT_IN_VSNPRINTF
: BUILT_IN_SNPRINTF
];
11365 return build_function_call_expr (fn
, arglist
);
11368 /* Fold a call to the {,v}printf{,_unlocked} and __{,v}printf_chk builtins.
11370 Return 0 if no simplification was possible, otherwise return the
11371 simplified form of the call as a tree. FCODE is the BUILT_IN_*
11372 code of the function to be simplified. */
11375 fold_builtin_printf (tree fndecl
, tree arglist
, bool ignore
,
11376 enum built_in_function fcode
)
11378 tree fmt
, fn
= NULL_TREE
, fn_putchar
, fn_puts
, arg
, call
;
11379 const char *fmt_str
= NULL
;
11381 /* If the return value is used, don't do the transformation. */
11385 /* Verify the required arguments in the original call. */
11386 if (fcode
== BUILT_IN_PRINTF_CHK
|| fcode
== BUILT_IN_VPRINTF_CHK
)
11392 flag
= TREE_VALUE (arglist
);
11393 if (TREE_CODE (TREE_TYPE (flag
)) != INTEGER_TYPE
11394 || TREE_SIDE_EFFECTS (flag
))
11396 arglist
= TREE_CHAIN (arglist
);
11401 fmt
= TREE_VALUE (arglist
);
11402 if (! POINTER_TYPE_P (TREE_TYPE (fmt
)))
11404 arglist
= TREE_CHAIN (arglist
);
11406 /* Check whether the format is a literal string constant. */
11407 fmt_str
= c_getstr (fmt
);
11408 if (fmt_str
== NULL
)
11411 if (fcode
== BUILT_IN_PRINTF_UNLOCKED
)
11413 /* If we're using an unlocked function, assume the other
11414 unlocked functions exist explicitly. */
11415 fn_putchar
= built_in_decls
[BUILT_IN_PUTCHAR_UNLOCKED
];
11416 fn_puts
= built_in_decls
[BUILT_IN_PUTS_UNLOCKED
];
11420 fn_putchar
= implicit_built_in_decls
[BUILT_IN_PUTCHAR
];
11421 fn_puts
= implicit_built_in_decls
[BUILT_IN_PUTS
];
11424 if (!init_target_chars())
11427 if (strcmp (fmt_str
, target_percent_s
) == 0 || strchr (fmt_str
, target_percent
) == NULL
)
11431 if (strcmp (fmt_str
, target_percent_s
) == 0)
11433 if (fcode
== BUILT_IN_VPRINTF
|| fcode
== BUILT_IN_VPRINTF_CHK
)
11437 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist
)))
11438 || TREE_CHAIN (arglist
))
11441 str
= c_getstr (TREE_VALUE (arglist
));
11447 /* The format specifier doesn't contain any '%' characters. */
11448 if (fcode
!= BUILT_IN_VPRINTF
&& fcode
!= BUILT_IN_VPRINTF_CHK
11454 /* If the string was "", printf does nothing. */
11455 if (str
[0] == '\0')
11456 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl
)), 0);
11458 /* If the string has length of 1, call putchar. */
11459 if (str
[1] == '\0')
11461 /* Given printf("c"), (where c is any one character,)
11462 convert "c"[0] to an int and pass that to the replacement
11464 arg
= build_int_cst (NULL_TREE
, str
[0]);
11465 arglist
= build_tree_list (NULL_TREE
, arg
);
11470 /* If the string was "string\n", call puts("string"). */
11471 size_t len
= strlen (str
);
11472 if ((unsigned char)str
[len
- 1] == target_newline
)
11474 /* Create a NUL-terminated string that's one char shorter
11475 than the original, stripping off the trailing '\n'. */
11476 char *newstr
= alloca (len
);
11477 memcpy (newstr
, str
, len
- 1);
11478 newstr
[len
- 1] = 0;
11480 arg
= build_string_literal (len
, newstr
);
11481 arglist
= build_tree_list (NULL_TREE
, arg
);
11485 /* We'd like to arrange to call fputs(string,stdout) here,
11486 but we need stdout and don't have a way to get it yet. */
11491 /* The other optimizations can be done only on the non-va_list variants. */
11492 else if (fcode
== BUILT_IN_VPRINTF
|| fcode
== BUILT_IN_VPRINTF_CHK
)
11495 /* If the format specifier was "%s\n", call __builtin_puts(arg). */
11496 else if (strcmp (fmt_str
, target_percent_s_newline
) == 0)
11499 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist
)))
11500 || TREE_CHAIN (arglist
))
11505 /* If the format specifier was "%c", call __builtin_putchar(arg). */
11506 else if (strcmp (fmt_str
, target_percent_c
) == 0)
11509 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist
))) != INTEGER_TYPE
11510 || TREE_CHAIN (arglist
))
11518 call
= build_function_call_expr (fn
, arglist
);
11519 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl
)), call
);
11522 /* Fold a call to the {,v}fprintf{,_unlocked} and __{,v}printf_chk builtins.
11524 Return 0 if no simplification was possible, otherwise return the
11525 simplified form of the call as a tree. FCODE is the BUILT_IN_*
11526 code of the function to be simplified. */
11529 fold_builtin_fprintf (tree fndecl
, tree arglist
, bool ignore
,
11530 enum built_in_function fcode
)
11532 tree fp
, fmt
, fn
= NULL_TREE
, fn_fputc
, fn_fputs
, arg
, call
;
11533 const char *fmt_str
= NULL
;
11535 /* If the return value is used, don't do the transformation. */
11539 /* Verify the required arguments in the original call. */
11542 fp
= TREE_VALUE (arglist
);
11543 if (! POINTER_TYPE_P (TREE_TYPE (fp
)))
11545 arglist
= TREE_CHAIN (arglist
);
11547 if (fcode
== BUILT_IN_FPRINTF_CHK
|| fcode
== BUILT_IN_VFPRINTF_CHK
)
11553 flag
= TREE_VALUE (arglist
);
11554 if (TREE_CODE (TREE_TYPE (flag
)) != INTEGER_TYPE
11555 || TREE_SIDE_EFFECTS (flag
))
11557 arglist
= TREE_CHAIN (arglist
);
11562 fmt
= TREE_VALUE (arglist
);
11563 if (! POINTER_TYPE_P (TREE_TYPE (fmt
)))
11565 arglist
= TREE_CHAIN (arglist
);
11567 /* Check whether the format is a literal string constant. */
11568 fmt_str
= c_getstr (fmt
);
11569 if (fmt_str
== NULL
)
11572 if (fcode
== BUILT_IN_FPRINTF_UNLOCKED
)
11574 /* If we're using an unlocked function, assume the other
11575 unlocked functions exist explicitly. */
11576 fn_fputc
= built_in_decls
[BUILT_IN_FPUTC_UNLOCKED
];
11577 fn_fputs
= built_in_decls
[BUILT_IN_FPUTS_UNLOCKED
];
11581 fn_fputc
= implicit_built_in_decls
[BUILT_IN_FPUTC
];
11582 fn_fputs
= implicit_built_in_decls
[BUILT_IN_FPUTS
];
11585 if (!init_target_chars())
11588 /* If the format doesn't contain % args or %%, use strcpy. */
11589 if (strchr (fmt_str
, target_percent
) == NULL
)
11591 if (fcode
!= BUILT_IN_VFPRINTF
&& fcode
!= BUILT_IN_VFPRINTF_CHK
11595 /* If the format specifier was "", fprintf does nothing. */
11596 if (fmt_str
[0] == '\0')
11598 /* If FP has side-effects, just wait until gimplification is
11600 if (TREE_SIDE_EFFECTS (fp
))
11603 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl
)), 0);
11606 /* When "string" doesn't contain %, replace all cases of
11607 fprintf (fp, string) with fputs (string, fp). The fputs
11608 builtin will take care of special cases like length == 1. */
11609 arglist
= build_tree_list (NULL_TREE
, fp
);
11610 arglist
= tree_cons (NULL_TREE
, fmt
, arglist
);
11614 /* The other optimizations can be done only on the non-va_list variants. */
11615 else if (fcode
== BUILT_IN_VFPRINTF
|| fcode
== BUILT_IN_VFPRINTF_CHK
)
11618 /* If the format specifier was "%s", call __builtin_fputs (arg, fp). */
11619 else if (strcmp (fmt_str
, target_percent_s
) == 0)
11622 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist
)))
11623 || TREE_CHAIN (arglist
))
11625 arg
= TREE_VALUE (arglist
);
11626 arglist
= build_tree_list (NULL_TREE
, fp
);
11627 arglist
= tree_cons (NULL_TREE
, arg
, arglist
);
11631 /* If the format specifier was "%c", call __builtin_fputc (arg, fp). */
11632 else if (strcmp (fmt_str
, target_percent_c
) == 0)
11635 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist
))) != INTEGER_TYPE
11636 || TREE_CHAIN (arglist
))
11638 arg
= TREE_VALUE (arglist
);
11639 arglist
= build_tree_list (NULL_TREE
, fp
);
11640 arglist
= tree_cons (NULL_TREE
, arg
, arglist
);
11647 call
= build_function_call_expr (fn
, arglist
);
11648 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl
)), call
);
11651 /* Initialize format string characters in the target charset. */
11654 init_target_chars (void)
11659 target_newline
= lang_hooks
.to_target_charset ('\n');
11660 target_percent
= lang_hooks
.to_target_charset ('%');
11661 target_c
= lang_hooks
.to_target_charset ('c');
11662 target_s
= lang_hooks
.to_target_charset ('s');
11663 if (target_newline
== 0 || target_percent
== 0 || target_c
== 0
11667 target_percent_c
[0] = target_percent
;
11668 target_percent_c
[1] = target_c
;
11669 target_percent_c
[2] = '\0';
11671 target_percent_s
[0] = target_percent
;
11672 target_percent_s
[1] = target_s
;
11673 target_percent_s
[2] = '\0';
11675 target_percent_s_newline
[0] = target_percent
;
11676 target_percent_s_newline
[1] = target_s
;
11677 target_percent_s_newline
[2] = target_newline
;
11678 target_percent_s_newline
[3] = '\0';
11685 /* Helper function for do_mpfr_arg*(). Ensure M is a normal number
11686 and no overflow/underflow occurred. INEXACT is true if M was not
11687 exactly calculated. TYPE is the tree type for the result. This
11688 function assumes that you cleared the MPFR flags and then
11689 calculated M to see if anything subsequently set a flag prior to
11690 entering this function. Return NULL_TREE if any checks fail. */
11693 do_mpfr_ckconv(mpfr_srcptr m
, tree type
, int inexact
)
11695 /* Proceed iff we get a normal number, i.e. not NaN or Inf and no
11696 overflow/underflow occurred. If -frounding-math, proceed iff the
11697 result of calling FUNC was exact. */
11698 if (mpfr_number_p (m
) && !mpfr_overflow_p() && !mpfr_underflow_p()
11699 && (!flag_rounding_math
|| !inexact
))
11701 REAL_VALUE_TYPE rr
;
11703 real_from_mpfr (&rr
, m
);
11704 /* Proceed iff GCC's REAL_VALUE_TYPE can hold the MPFR value,
11705 check for overflow/underflow. If the REAL_VALUE_TYPE is zero
11706 but the mpft_t is not, then we underflowed in the
11708 if (!real_isnan (&rr
) && !real_isinf (&rr
)
11709 && (rr
.cl
== rvc_zero
) == (mpfr_zero_p (m
) != 0))
11711 REAL_VALUE_TYPE rmode
;
11713 real_convert (&rmode
, TYPE_MODE (type
), &rr
);
11714 /* Proceed iff the specified mode can hold the value. */
11715 if (real_identical (&rmode
, &rr
))
11716 return build_real (type
, rmode
);
11722 /* If argument ARG is a REAL_CST, call the one-argument mpfr function
11723 FUNC on it and return the resulting value as a tree with type TYPE.
11724 If MIN and/or MAX are not NULL, then the supplied ARG must be
11725 within those bounds. If INCLUSIVE is true, then MIN/MAX are
11726 acceptable values, otherwise they are not. The mpfr precision is
11727 set to the precision of TYPE. We assume that function FUNC returns
11728 zero if the result could be calculated exactly within the requested
11732 do_mpfr_arg1 (tree arg
, tree type
, int (*func
)(mpfr_ptr
, mpfr_srcptr
, mp_rnd_t
),
11733 const REAL_VALUE_TYPE
*min
, const REAL_VALUE_TYPE
*max
,
11736 tree result
= NULL_TREE
;
11740 /* To proceed, MPFR must exactly represent the target floating point
11741 format, which only happens when the target base equals two. */
11742 if (REAL_MODE_FORMAT (TYPE_MODE (type
))->b
== 2
11743 && TREE_CODE (arg
) == REAL_CST
&& ! TREE_CONSTANT_OVERFLOW (arg
))
11745 const REAL_VALUE_TYPE
*const ra
= &TREE_REAL_CST (arg
);
11747 if (!real_isnan (ra
) && !real_isinf (ra
)
11748 && (!min
|| real_compare (inclusive
? GE_EXPR
: GT_EXPR
, ra
, min
))
11749 && (!max
|| real_compare (inclusive
? LE_EXPR
: LT_EXPR
, ra
, max
)))
11751 const int prec
= REAL_MODE_FORMAT (TYPE_MODE (type
))->p
;
11755 mpfr_init2 (m
, prec
);
11756 mpfr_from_real (m
, ra
);
11757 mpfr_clear_flags();
11758 inexact
= func (m
, m
, GMP_RNDN
);
11759 result
= do_mpfr_ckconv (m
, type
, inexact
);
11767 /* If argument ARG is a REAL_CST, call the two-argument mpfr function
11768 FUNC on it and return the resulting value as a tree with type TYPE.
11769 The mpfr precision is set to the precision of TYPE. We assume that
11770 function FUNC returns zero if the result could be calculated
11771 exactly within the requested precision. */
11774 do_mpfr_arg2 (tree arg1
, tree arg2
, tree type
,
11775 int (*func
)(mpfr_ptr
, mpfr_srcptr
, mpfr_srcptr
, mp_rnd_t
))
11777 tree result
= NULL_TREE
;
11782 /* To proceed, MPFR must exactly represent the target floating point
11783 format, which only happens when the target base equals two. */
11784 if (REAL_MODE_FORMAT (TYPE_MODE (type
))->b
== 2
11785 && TREE_CODE (arg1
) == REAL_CST
&& ! TREE_CONSTANT_OVERFLOW (arg1
)
11786 && TREE_CODE (arg2
) == REAL_CST
&& ! TREE_CONSTANT_OVERFLOW (arg2
))
11788 const REAL_VALUE_TYPE
*const ra1
= &TREE_REAL_CST (arg1
);
11789 const REAL_VALUE_TYPE
*const ra2
= &TREE_REAL_CST (arg2
);
11791 if (!real_isnan (ra1
) && !real_isinf (ra1
)
11792 && !real_isnan (ra2
) && !real_isinf (ra2
))
11794 const int prec
= REAL_MODE_FORMAT (TYPE_MODE (type
))->p
;
11798 mpfr_inits2 (prec
, m1
, m2
, NULL
);
11799 mpfr_from_real (m1
, ra1
);
11800 mpfr_from_real (m2
, ra2
);
11801 mpfr_clear_flags();
11802 inexact
= func (m1
, m1
, m2
, GMP_RNDN
);
11803 result
= do_mpfr_ckconv (m1
, type
, inexact
);
11804 mpfr_clears (m1
, m2
, NULL
);
11811 /* If argument ARG is a REAL_CST, call the three-argument mpfr function
11812 FUNC on it and return the resulting value as a tree with type TYPE.
11813 The mpfr precision is set to the precision of TYPE. We assume that
11814 function FUNC returns zero if the result could be calculated
11815 exactly within the requested precision. */
11818 do_mpfr_arg3 (tree arg1
, tree arg2
, tree arg3
, tree type
,
11819 int (*func
)(mpfr_ptr
, mpfr_srcptr
, mpfr_srcptr
, mpfr_srcptr
, mp_rnd_t
))
11821 tree result
= NULL_TREE
;
11827 /* To proceed, MPFR must exactly represent the target floating point
11828 format, which only happens when the target base equals two. */
11829 if (REAL_MODE_FORMAT (TYPE_MODE (type
))->b
== 2
11830 && TREE_CODE (arg1
) == REAL_CST
&& ! TREE_CONSTANT_OVERFLOW (arg1
)
11831 && TREE_CODE (arg2
) == REAL_CST
&& ! TREE_CONSTANT_OVERFLOW (arg2
)
11832 && TREE_CODE (arg3
) == REAL_CST
&& ! TREE_CONSTANT_OVERFLOW (arg3
))
11834 const REAL_VALUE_TYPE
*const ra1
= &TREE_REAL_CST (arg1
);
11835 const REAL_VALUE_TYPE
*const ra2
= &TREE_REAL_CST (arg2
);
11836 const REAL_VALUE_TYPE
*const ra3
= &TREE_REAL_CST (arg3
);
11838 if (!real_isnan (ra1
) && !real_isinf (ra1
)
11839 && !real_isnan (ra2
) && !real_isinf (ra2
)
11840 && !real_isnan (ra3
) && !real_isinf (ra3
))
11842 const int prec
= REAL_MODE_FORMAT (TYPE_MODE (type
))->p
;
11846 mpfr_inits2 (prec
, m1
, m2
, m3
, NULL
);
11847 mpfr_from_real (m1
, ra1
);
11848 mpfr_from_real (m2
, ra2
);
11849 mpfr_from_real (m3
, ra3
);
11850 mpfr_clear_flags();
11851 inexact
= func (m1
, m1
, m2
, m3
, GMP_RNDN
);
11852 result
= do_mpfr_ckconv (m1
, type
, inexact
);
11853 mpfr_clears (m1
, m2
, m3
, NULL
);
11860 /* If argument ARG is a REAL_CST, call mpfr_sin_cos() on it and set
11861 the pointers *(ARG_SINP) and *(ARG_COSP) to the resulting values.
11862 If ARG_SINP and ARG_COSP are NULL then the result is returned
11863 as a complex value.
11864 The type is taken from the type of ARG and is used for setting the
11865 precision of the calculation and results. */
11868 do_mpfr_sincos (tree arg
, tree arg_sinp
, tree arg_cosp
)
11870 tree
const type
= TREE_TYPE (arg
);
11871 tree result
= NULL_TREE
;
11875 /* To proceed, MPFR must exactly represent the target floating point
11876 format, which only happens when the target base equals two. */
11877 if (REAL_MODE_FORMAT (TYPE_MODE (type
))->b
== 2
11878 && TREE_CODE (arg
) == REAL_CST
&& ! TREE_CONSTANT_OVERFLOW (arg
))
11880 const REAL_VALUE_TYPE
*const ra
= &TREE_REAL_CST (arg
);
11882 if (!real_isnan (ra
) && !real_isinf (ra
))
11884 const int prec
= REAL_MODE_FORMAT (TYPE_MODE (type
))->p
;
11885 tree result_s
, result_c
;
11889 mpfr_inits2 (prec
, m
, ms
, mc
, NULL
);
11890 mpfr_from_real (m
, ra
);
11891 mpfr_clear_flags();
11892 inexact
= mpfr_sin_cos (ms
, mc
, m
, GMP_RNDN
);
11893 result_s
= do_mpfr_ckconv (ms
, type
, inexact
);
11894 result_c
= do_mpfr_ckconv (mc
, type
, inexact
);
11895 mpfr_clears (m
, ms
, mc
, NULL
);
11896 if (result_s
&& result_c
)
11898 /* If we are to return in a complex value do so. */
11899 if (!arg_sinp
&& !arg_cosp
)
11900 return build_complex (build_complex_type (type
),
11901 result_c
, result_s
);
11903 /* Dereference the sin/cos pointer arguments. */
11904 arg_sinp
= build_fold_indirect_ref (arg_sinp
);
11905 arg_cosp
= build_fold_indirect_ref (arg_cosp
);
11906 /* Proceed if valid pointer type were passed in. */
11907 if (TYPE_MAIN_VARIANT (TREE_TYPE (arg_sinp
)) == TYPE_MAIN_VARIANT (type
)
11908 && TYPE_MAIN_VARIANT (TREE_TYPE (arg_cosp
)) == TYPE_MAIN_VARIANT (type
))
11910 /* Set the values. */
11911 result_s
= fold_build2 (GIMPLE_MODIFY_STMT
, type
, arg_sinp
,
11913 TREE_SIDE_EFFECTS (result_s
) = 1;
11914 result_c
= fold_build2 (GIMPLE_MODIFY_STMT
, type
, arg_cosp
,
11916 TREE_SIDE_EFFECTS (result_c
) = 1;
11917 /* Combine the assignments into a compound expr. */
11918 result
= non_lvalue (fold_build2 (COMPOUND_EXPR
, type
,
11919 result_s
, result_c
));