1 /* Expand builtin functions.
2 Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING. If not, write to the Free
19 Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
24 #include "coretypes.h"
30 #include "tree-gimple.h"
33 #include "hard-reg-set.h"
36 #include "insn-config.h"
42 #include "typeclass.h"
47 #include "langhooks.h"
48 #include "basic-block.h"
49 #include "tree-mudflap.h"
51 #ifndef PAD_VARARGS_DOWN
52 #define PAD_VARARGS_DOWN BYTES_BIG_ENDIAN
55 /* Define the names of the builtin function types and codes. */
56 const char *const built_in_class_names
[4]
57 = {"NOT_BUILT_IN", "BUILT_IN_FRONTEND", "BUILT_IN_MD", "BUILT_IN_NORMAL"};
59 #define DEF_BUILTIN(X, N, C, T, LT, B, F, NA, AT, IM, COND) #X,
60 const char * built_in_names
[(int) END_BUILTINS
] =
62 #include "builtins.def"
66 /* Setup an array of _DECL trees, make sure each element is
67 initialized to NULL_TREE. */
68 tree built_in_decls
[(int) END_BUILTINS
];
69 /* Declarations used when constructing the builtin implicitly in the compiler.
70 It may be NULL_TREE when this is invalid (for instance runtime is not
71 required to implement the function call in all cases). */
72 tree implicit_built_in_decls
[(int) END_BUILTINS
];
74 static int get_pointer_alignment (tree
, unsigned int);
75 static const char *c_getstr (tree
);
76 static rtx
c_readstr (const char *, enum machine_mode
);
77 static int target_char_cast (tree
, char *);
78 static rtx
get_memory_rtx (tree
, tree
);
79 static int apply_args_size (void);
80 static int apply_result_size (void);
81 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
82 static rtx
result_vector (int, rtx
);
84 static 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_int_roundingfn (tree
, rtx
, rtx
);
98 static rtx
expand_builtin_int_roundingfn_2 (tree
, rtx
, rtx
);
99 static rtx
expand_builtin_args_info (tree
);
100 static rtx
expand_builtin_next_arg (void);
101 static rtx
expand_builtin_va_start (tree
);
102 static rtx
expand_builtin_va_end (tree
);
103 static rtx
expand_builtin_va_copy (tree
);
104 static rtx
expand_builtin_memcmp (tree
, tree
, rtx
, enum machine_mode
);
105 static rtx
expand_builtin_strcmp (tree
, rtx
, enum machine_mode
);
106 static rtx
expand_builtin_strncmp (tree
, rtx
, enum machine_mode
);
107 static rtx
builtin_memcpy_read_str (void *, HOST_WIDE_INT
, enum machine_mode
);
108 static rtx
expand_builtin_strcat (tree
, tree
, rtx
, enum machine_mode
);
109 static rtx
expand_builtin_strncat (tree
, rtx
, enum machine_mode
);
110 static rtx
expand_builtin_strspn (tree
, rtx
, enum machine_mode
);
111 static rtx
expand_builtin_strcspn (tree
, rtx
, enum machine_mode
);
112 static rtx
expand_builtin_memcpy (tree
, rtx
, enum machine_mode
);
113 static rtx
expand_builtin_mempcpy (tree
, tree
, rtx
, enum machine_mode
, int);
114 static rtx
expand_builtin_memmove (tree
, tree
, rtx
, enum machine_mode
);
115 static rtx
expand_builtin_bcopy (tree
);
116 static rtx
expand_builtin_strcpy (tree
, tree
, rtx
, enum machine_mode
);
117 static rtx
expand_builtin_stpcpy (tree
, rtx
, enum machine_mode
);
118 static rtx
builtin_strncpy_read_str (void *, HOST_WIDE_INT
, enum machine_mode
);
119 static rtx
expand_builtin_strncpy (tree
, rtx
, enum machine_mode
);
120 static rtx
builtin_memset_read_str (void *, HOST_WIDE_INT
, enum machine_mode
);
121 static rtx
builtin_memset_gen_str (void *, HOST_WIDE_INT
, enum machine_mode
);
122 static rtx
expand_builtin_memset (tree
, rtx
, enum machine_mode
, tree
);
123 static rtx
expand_builtin_bzero (tree
);
124 static rtx
expand_builtin_strlen (tree
, rtx
, enum machine_mode
);
125 static rtx
expand_builtin_strstr (tree
, tree
, rtx
, enum machine_mode
);
126 static rtx
expand_builtin_strpbrk (tree
, tree
, rtx
, enum machine_mode
);
127 static rtx
expand_builtin_strchr (tree
, tree
, rtx
, enum machine_mode
);
128 static rtx
expand_builtin_strrchr (tree
, tree
, rtx
, enum machine_mode
);
129 static rtx
expand_builtin_alloca (tree
, rtx
);
130 static rtx
expand_builtin_unop (enum machine_mode
, tree
, rtx
, rtx
, optab
);
131 static rtx
expand_builtin_frame_address (tree
, tree
);
132 static rtx
expand_builtin_fputs (tree
, rtx
, bool);
133 static rtx
expand_builtin_printf (tree
, rtx
, enum machine_mode
, bool);
134 static rtx
expand_builtin_fprintf (tree
, rtx
, enum machine_mode
, bool);
135 static rtx
expand_builtin_sprintf (tree
, rtx
, enum machine_mode
);
136 static tree
stabilize_va_list (tree
, int);
137 static rtx
expand_builtin_expect (tree
, rtx
);
138 static tree
fold_builtin_constant_p (tree
);
139 static tree
fold_builtin_classify_type (tree
);
140 static tree
fold_builtin_strlen (tree
);
141 static tree
fold_builtin_inf (tree
, int);
142 static tree
fold_builtin_nan (tree
, tree
, int);
143 static int validate_arglist (tree
, ...);
144 static bool integer_valued_real_p (tree
);
145 static tree
fold_trunc_transparent_mathfn (tree
, tree
);
146 static bool readonly_data_expr (tree
);
147 static rtx
expand_builtin_fabs (tree
, rtx
, rtx
);
148 static rtx
expand_builtin_signbit (tree
, rtx
);
149 static tree
fold_builtin_sqrt (tree
, tree
);
150 static tree
fold_builtin_cbrt (tree
, tree
);
151 static tree
fold_builtin_pow (tree
, tree
, tree
);
152 static tree
fold_builtin_powi (tree
, tree
, tree
);
153 static tree
fold_builtin_cos (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);
209 /* Return true if NODE should be considered for inline expansion regardless
210 of the optimization level. This means whenever a function is invoked with
211 its "internal" name, which normally contains the prefix "__builtin". */
213 static bool called_as_built_in (tree node
)
215 const char *name
= IDENTIFIER_POINTER (DECL_NAME (node
));
216 if (strncmp (name
, "__builtin_", 10) == 0)
218 if (strncmp (name
, "__sync_", 7) == 0)
223 /* Return the alignment in bits of EXP, a pointer valued expression.
224 But don't return more than MAX_ALIGN no matter what.
225 The alignment returned is, by default, the alignment of the thing that
226 EXP points to. If it is not a POINTER_TYPE, 0 is returned.
228 Otherwise, look at the expression to see if we can do better, i.e., if the
229 expression is actually pointing at an object whose alignment is tighter. */
232 get_pointer_alignment (tree exp
, unsigned int max_align
)
234 unsigned int align
, inner
;
236 /* We rely on TER to compute accurate alignment information. */
237 if (!(optimize
&& flag_tree_ter
))
240 if (!POINTER_TYPE_P (TREE_TYPE (exp
)))
243 align
= TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp
)));
244 align
= MIN (align
, max_align
);
248 switch (TREE_CODE (exp
))
252 case NON_LVALUE_EXPR
:
253 exp
= TREE_OPERAND (exp
, 0);
254 if (! POINTER_TYPE_P (TREE_TYPE (exp
)))
257 inner
= TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp
)));
258 align
= MIN (inner
, max_align
);
262 /* If sum of pointer + int, restrict our maximum alignment to that
263 imposed by the integer. If not, we can't do any better than
265 if (! host_integerp (TREE_OPERAND (exp
, 1), 1))
268 while (((tree_low_cst (TREE_OPERAND (exp
, 1), 1))
269 & (max_align
/ BITS_PER_UNIT
- 1))
273 exp
= TREE_OPERAND (exp
, 0);
277 /* See what we are pointing at and look at its alignment. */
278 exp
= TREE_OPERAND (exp
, 0);
280 if (handled_component_p (exp
))
282 HOST_WIDE_INT bitsize
, bitpos
;
284 enum machine_mode mode
;
285 int unsignedp
, volatilep
;
287 exp
= get_inner_reference (exp
, &bitsize
, &bitpos
, &offset
,
288 &mode
, &unsignedp
, &volatilep
, true);
290 inner
= MIN (inner
, (unsigned) (bitpos
& -bitpos
));
291 if (offset
&& TREE_CODE (offset
) == PLUS_EXPR
292 && host_integerp (TREE_OPERAND (offset
, 1), 1))
294 /* Any overflow in calculating offset_bits won't change
297 = ((unsigned) tree_low_cst (TREE_OPERAND (offset
, 1), 1)
301 inner
= MIN (inner
, (offset_bits
& -offset_bits
));
302 offset
= TREE_OPERAND (offset
, 0);
304 if (offset
&& TREE_CODE (offset
) == MULT_EXPR
305 && host_integerp (TREE_OPERAND (offset
, 1), 1))
307 /* Any overflow in calculating offset_factor won't change
309 unsigned offset_factor
310 = ((unsigned) tree_low_cst (TREE_OPERAND (offset
, 1), 1)
314 inner
= MIN (inner
, (offset_factor
& -offset_factor
));
317 inner
= MIN (inner
, BITS_PER_UNIT
);
319 if (TREE_CODE (exp
) == FUNCTION_DECL
)
320 align
= FUNCTION_BOUNDARY
;
321 else if (DECL_P (exp
))
322 align
= MIN (inner
, DECL_ALIGN (exp
));
323 #ifdef CONSTANT_ALIGNMENT
324 else if (CONSTANT_CLASS_P (exp
))
325 align
= MIN (inner
, (unsigned)CONSTANT_ALIGNMENT (exp
, align
));
327 else if (TREE_CODE (exp
) == VIEW_CONVERT_EXPR
328 || TREE_CODE (exp
) == INDIRECT_REF
)
329 align
= MIN (TYPE_ALIGN (TREE_TYPE (exp
)), inner
);
331 align
= MIN (align
, inner
);
332 return MIN (align
, max_align
);
340 /* Compute the length of a C string. TREE_STRING_LENGTH is not the right
341 way, because it could contain a zero byte in the middle.
342 TREE_STRING_LENGTH is the size of the character array, not the string.
344 ONLY_VALUE should be nonzero if the result is not going to be emitted
345 into the instruction stream and zero if it is going to be expanded.
346 E.g. with i++ ? "foo" : "bar", if ONLY_VALUE is nonzero, constant 3
347 is returned, otherwise NULL, since
348 len = c_strlen (src, 1); if (len) expand_expr (len, ...); would not
349 evaluate the side-effects.
351 The value returned is of type `ssizetype'.
353 Unfortunately, string_constant can't access the values of const char
354 arrays with initializers, so neither can we do so here. */
357 c_strlen (tree src
, int only_value
)
360 HOST_WIDE_INT offset
;
365 if (TREE_CODE (src
) == COND_EXPR
366 && (only_value
|| !TREE_SIDE_EFFECTS (TREE_OPERAND (src
, 0))))
370 len1
= c_strlen (TREE_OPERAND (src
, 1), only_value
);
371 len2
= c_strlen (TREE_OPERAND (src
, 2), only_value
);
372 if (tree_int_cst_equal (len1
, len2
))
376 if (TREE_CODE (src
) == COMPOUND_EXPR
377 && (only_value
|| !TREE_SIDE_EFFECTS (TREE_OPERAND (src
, 0))))
378 return c_strlen (TREE_OPERAND (src
, 1), only_value
);
380 src
= string_constant (src
, &offset_node
);
384 max
= TREE_STRING_LENGTH (src
) - 1;
385 ptr
= TREE_STRING_POINTER (src
);
387 if (offset_node
&& TREE_CODE (offset_node
) != INTEGER_CST
)
389 /* If the string has an internal zero byte (e.g., "foo\0bar"), we can't
390 compute the offset to the following null if we don't know where to
391 start searching for it. */
394 for (i
= 0; i
< max
; i
++)
398 /* We don't know the starting offset, but we do know that the string
399 has no internal zero bytes. We can assume that the offset falls
400 within the bounds of the string; otherwise, the programmer deserves
401 what he gets. Subtract the offset from the length of the string,
402 and return that. This would perhaps not be valid if we were dealing
403 with named arrays in addition to literal string constants. */
405 return size_diffop (size_int (max
), offset_node
);
408 /* We have a known offset into the string. Start searching there for
409 a null character if we can represent it as a single HOST_WIDE_INT. */
410 if (offset_node
== 0)
412 else if (! host_integerp (offset_node
, 0))
415 offset
= tree_low_cst (offset_node
, 0);
417 /* If the offset is known to be out of bounds, warn, and call strlen at
419 if (offset
< 0 || offset
> max
)
421 warning (0, "offset outside bounds of constant string");
425 /* Use strlen to search for the first zero byte. Since any strings
426 constructed with build_string will have nulls appended, we win even
427 if we get handed something like (char[4])"abcd".
429 Since OFFSET is our starting index into the string, no further
430 calculation is needed. */
431 return ssize_int (strlen (ptr
+ offset
));
434 /* Return a char pointer for a C string if it is a string constant
435 or sum of string constant and integer constant. */
442 src
= string_constant (src
, &offset_node
);
446 if (offset_node
== 0)
447 return TREE_STRING_POINTER (src
);
448 else if (!host_integerp (offset_node
, 1)
449 || compare_tree_int (offset_node
, TREE_STRING_LENGTH (src
) - 1) > 0)
452 return TREE_STRING_POINTER (src
) + tree_low_cst (offset_node
, 1);
455 /* Return a CONST_INT or CONST_DOUBLE corresponding to target reading
456 GET_MODE_BITSIZE (MODE) bits from string constant STR. */
459 c_readstr (const char *str
, enum machine_mode mode
)
465 gcc_assert (GET_MODE_CLASS (mode
) == MODE_INT
);
470 for (i
= 0; i
< GET_MODE_SIZE (mode
); i
++)
473 if (WORDS_BIG_ENDIAN
)
474 j
= GET_MODE_SIZE (mode
) - i
- 1;
475 if (BYTES_BIG_ENDIAN
!= WORDS_BIG_ENDIAN
476 && GET_MODE_SIZE (mode
) > UNITS_PER_WORD
)
477 j
= j
+ UNITS_PER_WORD
- 2 * (j
% UNITS_PER_WORD
) - 1;
479 gcc_assert (j
<= 2 * HOST_BITS_PER_WIDE_INT
);
482 ch
= (unsigned char) str
[i
];
483 c
[j
/ HOST_BITS_PER_WIDE_INT
] |= ch
<< (j
% HOST_BITS_PER_WIDE_INT
);
485 return immed_double_const (c
[0], c
[1], mode
);
488 /* Cast a target constant CST to target CHAR and if that value fits into
489 host char type, return zero and put that value into variable pointed to by
493 target_char_cast (tree cst
, char *p
)
495 unsigned HOST_WIDE_INT val
, hostval
;
497 if (!host_integerp (cst
, 1)
498 || CHAR_TYPE_SIZE
> HOST_BITS_PER_WIDE_INT
)
501 val
= tree_low_cst (cst
, 1);
502 if (CHAR_TYPE_SIZE
< HOST_BITS_PER_WIDE_INT
)
503 val
&= (((unsigned HOST_WIDE_INT
) 1) << CHAR_TYPE_SIZE
) - 1;
506 if (HOST_BITS_PER_CHAR
< HOST_BITS_PER_WIDE_INT
)
507 hostval
&= (((unsigned HOST_WIDE_INT
) 1) << HOST_BITS_PER_CHAR
) - 1;
516 /* Similar to save_expr, but assumes that arbitrary code is not executed
517 in between the multiple evaluations. In particular, we assume that a
518 non-addressable local variable will not be modified. */
521 builtin_save_expr (tree exp
)
523 if (TREE_ADDRESSABLE (exp
) == 0
524 && (TREE_CODE (exp
) == PARM_DECL
525 || (TREE_CODE (exp
) == VAR_DECL
&& !TREE_STATIC (exp
))))
528 return save_expr (exp
);
531 /* Given TEM, a pointer to a stack frame, follow the dynamic chain COUNT
532 times to get the address of either a higher stack frame, or a return
533 address located within it (depending on FNDECL_CODE). */
536 expand_builtin_return_addr (enum built_in_function fndecl_code
, int count
)
540 #ifdef INITIAL_FRAME_ADDRESS_RTX
541 rtx tem
= INITIAL_FRAME_ADDRESS_RTX
;
545 /* For a zero count with __builtin_return_address, we don't care what
546 frame address we return, because target-specific definitions will
547 override us. Therefore frame pointer elimination is OK, and using
548 the soft frame pointer is OK.
550 For a non-zero count, or a zero count with __builtin_frame_address,
551 we require a stable offset from the current frame pointer to the
552 previous one, so we must use the hard frame pointer, and
553 we must disable frame pointer elimination. */
554 if (count
== 0 && fndecl_code
== BUILT_IN_RETURN_ADDRESS
)
555 tem
= frame_pointer_rtx
;
558 tem
= hard_frame_pointer_rtx
;
560 /* Tell reload not to eliminate the frame pointer. */
561 current_function_accesses_prior_frames
= 1;
565 /* Some machines need special handling before we can access
566 arbitrary frames. For example, on the SPARC, we must first flush
567 all register windows to the stack. */
568 #ifdef SETUP_FRAME_ADDRESSES
570 SETUP_FRAME_ADDRESSES ();
573 /* On the SPARC, the return address is not in the frame, it is in a
574 register. There is no way to access it off of the current frame
575 pointer, but it can be accessed off the previous frame pointer by
576 reading the value from the register window save area. */
577 #ifdef RETURN_ADDR_IN_PREVIOUS_FRAME
578 if (fndecl_code
== BUILT_IN_RETURN_ADDRESS
)
582 /* Scan back COUNT frames to the specified frame. */
583 for (i
= 0; i
< count
; i
++)
585 /* Assume the dynamic chain pointer is in the word that the
586 frame address points to, unless otherwise specified. */
587 #ifdef DYNAMIC_CHAIN_ADDRESS
588 tem
= DYNAMIC_CHAIN_ADDRESS (tem
);
590 tem
= memory_address (Pmode
, tem
);
591 tem
= gen_frame_mem (Pmode
, tem
);
592 tem
= copy_to_reg (tem
);
595 /* For __builtin_frame_address, return what we've got. But, on
596 the SPARC for example, we may have to add a bias. */
597 if (fndecl_code
== BUILT_IN_FRAME_ADDRESS
)
598 #ifdef FRAME_ADDR_RTX
599 return FRAME_ADDR_RTX (tem
);
604 /* For __builtin_return_address, get the return address from that frame. */
605 #ifdef RETURN_ADDR_RTX
606 tem
= RETURN_ADDR_RTX (count
, tem
);
608 tem
= memory_address (Pmode
,
609 plus_constant (tem
, GET_MODE_SIZE (Pmode
)));
610 tem
= gen_frame_mem (Pmode
, tem
);
615 /* Alias set used for setjmp buffer. */
616 static HOST_WIDE_INT setjmp_alias_set
= -1;
618 /* Construct the leading half of a __builtin_setjmp call. Control will
619 return to RECEIVER_LABEL. This is also called directly by the SJLJ
620 exception handling code. */
623 expand_builtin_setjmp_setup (rtx buf_addr
, rtx receiver_label
)
625 enum machine_mode sa_mode
= STACK_SAVEAREA_MODE (SAVE_NONLOCAL
);
629 if (setjmp_alias_set
== -1)
630 setjmp_alias_set
= new_alias_set ();
632 buf_addr
= convert_memory_address (Pmode
, buf_addr
);
634 buf_addr
= force_reg (Pmode
, force_operand (buf_addr
, NULL_RTX
));
636 /* We store the frame pointer and the address of receiver_label in
637 the buffer and use the rest of it for the stack save area, which
638 is machine-dependent. */
640 mem
= gen_rtx_MEM (Pmode
, buf_addr
);
641 set_mem_alias_set (mem
, setjmp_alias_set
);
642 emit_move_insn (mem
, targetm
.builtin_setjmp_frame_value ());
644 mem
= gen_rtx_MEM (Pmode
, plus_constant (buf_addr
, GET_MODE_SIZE (Pmode
))),
645 set_mem_alias_set (mem
, setjmp_alias_set
);
647 emit_move_insn (validize_mem (mem
),
648 force_reg (Pmode
, gen_rtx_LABEL_REF (Pmode
, receiver_label
)));
650 stack_save
= gen_rtx_MEM (sa_mode
,
651 plus_constant (buf_addr
,
652 2 * GET_MODE_SIZE (Pmode
)));
653 set_mem_alias_set (stack_save
, setjmp_alias_set
);
654 emit_stack_save (SAVE_NONLOCAL
, &stack_save
, NULL_RTX
);
656 /* If there is further processing to do, do it. */
657 #ifdef HAVE_builtin_setjmp_setup
658 if (HAVE_builtin_setjmp_setup
)
659 emit_insn (gen_builtin_setjmp_setup (buf_addr
));
662 /* Tell optimize_save_area_alloca that extra work is going to
663 need to go on during alloca. */
664 current_function_calls_setjmp
= 1;
666 /* Set this so all the registers get saved in our frame; we need to be
667 able to copy the saved values for any registers from frames we unwind. */
668 current_function_has_nonlocal_label
= 1;
671 /* Construct the trailing part of a __builtin_setjmp call. This is
672 also called directly by the SJLJ exception handling code. */
675 expand_builtin_setjmp_receiver (rtx receiver_label ATTRIBUTE_UNUSED
)
677 /* Clobber the FP when we get here, so we have to make sure it's
678 marked as used by this function. */
679 emit_insn (gen_rtx_USE (VOIDmode
, hard_frame_pointer_rtx
));
681 /* Mark the static chain as clobbered here so life information
682 doesn't get messed up for it. */
683 emit_insn (gen_rtx_CLOBBER (VOIDmode
, static_chain_rtx
));
685 /* Now put in the code to restore the frame pointer, and argument
686 pointer, if needed. */
687 #ifdef HAVE_nonlocal_goto
688 if (! HAVE_nonlocal_goto
)
691 emit_move_insn (virtual_stack_vars_rtx
, hard_frame_pointer_rtx
);
692 /* This might change the hard frame pointer in ways that aren't
693 apparent to early optimization passes, so force a clobber. */
694 emit_insn (gen_rtx_CLOBBER (VOIDmode
, hard_frame_pointer_rtx
));
697 #if ARG_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
698 if (fixed_regs
[ARG_POINTER_REGNUM
])
700 #ifdef ELIMINABLE_REGS
702 static const struct elims
{const int from
, to
;} elim_regs
[] = ELIMINABLE_REGS
;
704 for (i
= 0; i
< ARRAY_SIZE (elim_regs
); i
++)
705 if (elim_regs
[i
].from
== ARG_POINTER_REGNUM
706 && elim_regs
[i
].to
== HARD_FRAME_POINTER_REGNUM
)
709 if (i
== ARRAY_SIZE (elim_regs
))
712 /* Now restore our arg pointer from the address at which it
713 was saved in our stack frame. */
714 emit_move_insn (virtual_incoming_args_rtx
,
715 copy_to_reg (get_arg_pointer_save_area (cfun
)));
720 #ifdef HAVE_builtin_setjmp_receiver
721 if (HAVE_builtin_setjmp_receiver
)
722 emit_insn (gen_builtin_setjmp_receiver (receiver_label
));
725 #ifdef HAVE_nonlocal_goto_receiver
726 if (HAVE_nonlocal_goto_receiver
)
727 emit_insn (gen_nonlocal_goto_receiver ());
732 /* @@@ This is a kludge. Not all machine descriptions define a blockage
733 insn, but we must not allow the code we just generated to be reordered
734 by scheduling. Specifically, the update of the frame pointer must
735 happen immediately, not later. So emit an ASM_INPUT to act as blockage
737 emit_insn (gen_rtx_ASM_INPUT (VOIDmode
, ""));
740 /* __builtin_longjmp is passed a pointer to an array of five words (not
741 all will be used on all machines). It operates similarly to the C
742 library function of the same name, but is more efficient. Much of
743 the code below is copied from the handling of non-local gotos. */
746 expand_builtin_longjmp (rtx buf_addr
, rtx value
)
748 rtx fp
, lab
, stack
, insn
, last
;
749 enum machine_mode sa_mode
= STACK_SAVEAREA_MODE (SAVE_NONLOCAL
);
751 if (setjmp_alias_set
== -1)
752 setjmp_alias_set
= new_alias_set ();
754 buf_addr
= convert_memory_address (Pmode
, buf_addr
);
756 buf_addr
= force_reg (Pmode
, buf_addr
);
758 /* We used to store value in static_chain_rtx, but that fails if pointers
759 are smaller than integers. We instead require that the user must pass
760 a second argument of 1, because that is what builtin_setjmp will
761 return. This also makes EH slightly more efficient, since we are no
762 longer copying around a value that we don't care about. */
763 gcc_assert (value
== const1_rtx
);
765 last
= get_last_insn ();
766 #ifdef HAVE_builtin_longjmp
767 if (HAVE_builtin_longjmp
)
768 emit_insn (gen_builtin_longjmp (buf_addr
));
772 fp
= gen_rtx_MEM (Pmode
, buf_addr
);
773 lab
= gen_rtx_MEM (Pmode
, plus_constant (buf_addr
,
774 GET_MODE_SIZE (Pmode
)));
776 stack
= gen_rtx_MEM (sa_mode
, plus_constant (buf_addr
,
777 2 * GET_MODE_SIZE (Pmode
)));
778 set_mem_alias_set (fp
, setjmp_alias_set
);
779 set_mem_alias_set (lab
, setjmp_alias_set
);
780 set_mem_alias_set (stack
, setjmp_alias_set
);
782 /* Pick up FP, label, and SP from the block and jump. This code is
783 from expand_goto in stmt.c; see there for detailed comments. */
784 #ifdef HAVE_nonlocal_goto
785 if (HAVE_nonlocal_goto
)
786 /* We have to pass a value to the nonlocal_goto pattern that will
787 get copied into the static_chain pointer, but it does not matter
788 what that value is, because builtin_setjmp does not use it. */
789 emit_insn (gen_nonlocal_goto (value
, lab
, stack
, fp
));
793 lab
= copy_to_reg (lab
);
795 emit_insn (gen_rtx_CLOBBER (VOIDmode
,
796 gen_rtx_MEM (BLKmode
,
797 gen_rtx_SCRATCH (VOIDmode
))));
798 emit_insn (gen_rtx_CLOBBER (VOIDmode
,
799 gen_rtx_MEM (BLKmode
,
800 hard_frame_pointer_rtx
)));
802 emit_move_insn (hard_frame_pointer_rtx
, fp
);
803 emit_stack_restore (SAVE_NONLOCAL
, stack
, NULL_RTX
);
805 emit_insn (gen_rtx_USE (VOIDmode
, hard_frame_pointer_rtx
));
806 emit_insn (gen_rtx_USE (VOIDmode
, stack_pointer_rtx
));
807 emit_indirect_jump (lab
);
811 /* Search backwards and mark the jump insn as a non-local goto.
812 Note that this precludes the use of __builtin_longjmp to a
813 __builtin_setjmp target in the same function. However, we've
814 already cautioned the user that these functions are for
815 internal exception handling use only. */
816 for (insn
= get_last_insn (); insn
; insn
= PREV_INSN (insn
))
818 gcc_assert (insn
!= last
);
822 REG_NOTES (insn
) = alloc_EXPR_LIST (REG_NON_LOCAL_GOTO
, const0_rtx
,
826 else if (CALL_P (insn
))
831 /* Expand a call to __builtin_nonlocal_goto. We're passed the target label
832 and the address of the save area. */
835 expand_builtin_nonlocal_goto (tree arglist
)
837 tree t_label
, t_save_area
;
838 rtx r_label
, r_save_area
, r_fp
, r_sp
, insn
;
840 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
843 t_label
= TREE_VALUE (arglist
);
844 arglist
= TREE_CHAIN (arglist
);
845 t_save_area
= TREE_VALUE (arglist
);
847 r_label
= expand_normal (t_label
);
848 r_label
= convert_memory_address (Pmode
, r_label
);
849 r_save_area
= expand_normal (t_save_area
);
850 r_save_area
= convert_memory_address (Pmode
, r_save_area
);
851 r_fp
= gen_rtx_MEM (Pmode
, r_save_area
);
852 r_sp
= gen_rtx_MEM (STACK_SAVEAREA_MODE (SAVE_NONLOCAL
),
853 plus_constant (r_save_area
, GET_MODE_SIZE (Pmode
)));
855 current_function_has_nonlocal_goto
= 1;
857 #ifdef HAVE_nonlocal_goto
858 /* ??? We no longer need to pass the static chain value, afaik. */
859 if (HAVE_nonlocal_goto
)
860 emit_insn (gen_nonlocal_goto (const0_rtx
, r_label
, r_sp
, r_fp
));
864 r_label
= copy_to_reg (r_label
);
866 emit_insn (gen_rtx_CLOBBER (VOIDmode
,
867 gen_rtx_MEM (BLKmode
,
868 gen_rtx_SCRATCH (VOIDmode
))));
870 emit_insn (gen_rtx_CLOBBER (VOIDmode
,
871 gen_rtx_MEM (BLKmode
,
872 hard_frame_pointer_rtx
)));
874 /* Restore frame pointer for containing function.
875 This sets the actual hard register used for the frame pointer
876 to the location of the function's incoming static chain info.
877 The non-local goto handler will then adjust it to contain the
878 proper value and reload the argument pointer, if needed. */
879 emit_move_insn (hard_frame_pointer_rtx
, r_fp
);
880 emit_stack_restore (SAVE_NONLOCAL
, r_sp
, NULL_RTX
);
882 /* USE of hard_frame_pointer_rtx added for consistency;
883 not clear if really needed. */
884 emit_insn (gen_rtx_USE (VOIDmode
, hard_frame_pointer_rtx
));
885 emit_insn (gen_rtx_USE (VOIDmode
, stack_pointer_rtx
));
886 emit_indirect_jump (r_label
);
889 /* Search backwards to the jump insn and mark it as a
891 for (insn
= get_last_insn (); insn
; insn
= PREV_INSN (insn
))
895 REG_NOTES (insn
) = alloc_EXPR_LIST (REG_NON_LOCAL_GOTO
,
896 const0_rtx
, REG_NOTES (insn
));
899 else if (CALL_P (insn
))
906 /* __builtin_update_setjmp_buf is passed a pointer to an array of five words
907 (not all will be used on all machines) that was passed to __builtin_setjmp.
908 It updates the stack pointer in that block to correspond to the current
912 expand_builtin_update_setjmp_buf (rtx buf_addr
)
914 enum machine_mode sa_mode
= Pmode
;
918 #ifdef HAVE_save_stack_nonlocal
919 if (HAVE_save_stack_nonlocal
)
920 sa_mode
= insn_data
[(int) CODE_FOR_save_stack_nonlocal
].operand
[0].mode
;
922 #ifdef STACK_SAVEAREA_MODE
923 sa_mode
= STACK_SAVEAREA_MODE (SAVE_NONLOCAL
);
927 = gen_rtx_MEM (sa_mode
,
930 plus_constant (buf_addr
, 2 * GET_MODE_SIZE (Pmode
))));
934 emit_insn (gen_setjmp ());
937 emit_stack_save (SAVE_NONLOCAL
, &stack_save
, NULL_RTX
);
940 /* Expand a call to __builtin_prefetch. For a target that does not support
941 data prefetch, evaluate the memory address argument in case it has side
945 expand_builtin_prefetch (tree arglist
)
947 tree arg0
, arg1
, arg2
;
950 if (!validate_arglist (arglist
, POINTER_TYPE
, 0))
953 arg0
= TREE_VALUE (arglist
);
954 /* Arguments 1 and 2 are optional; argument 1 (read/write) defaults to
955 zero (read) and argument 2 (locality) defaults to 3 (high degree of
957 if (TREE_CHAIN (arglist
))
959 arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
960 if (TREE_CHAIN (TREE_CHAIN (arglist
)))
961 arg2
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
963 arg2
= build_int_cst (NULL_TREE
, 3);
967 arg1
= integer_zero_node
;
968 arg2
= build_int_cst (NULL_TREE
, 3);
971 /* Argument 0 is an address. */
972 op0
= expand_expr (arg0
, NULL_RTX
, Pmode
, EXPAND_NORMAL
);
974 /* Argument 1 (read/write flag) must be a compile-time constant int. */
975 if (TREE_CODE (arg1
) != INTEGER_CST
)
977 error ("second argument to %<__builtin_prefetch%> must be a constant");
978 arg1
= integer_zero_node
;
980 op1
= expand_normal (arg1
);
981 /* Argument 1 must be either zero or one. */
982 if (INTVAL (op1
) != 0 && INTVAL (op1
) != 1)
984 warning (0, "invalid second argument to %<__builtin_prefetch%>;"
989 /* Argument 2 (locality) must be a compile-time constant int. */
990 if (TREE_CODE (arg2
) != INTEGER_CST
)
992 error ("third argument to %<__builtin_prefetch%> must be a constant");
993 arg2
= integer_zero_node
;
995 op2
= expand_normal (arg2
);
996 /* Argument 2 must be 0, 1, 2, or 3. */
997 if (INTVAL (op2
) < 0 || INTVAL (op2
) > 3)
999 warning (0, "invalid third argument to %<__builtin_prefetch%>; using zero");
1003 #ifdef HAVE_prefetch
1006 if ((! (*insn_data
[(int) CODE_FOR_prefetch
].operand
[0].predicate
)
1008 insn_data
[(int) CODE_FOR_prefetch
].operand
[0].mode
))
1009 || (GET_MODE (op0
) != Pmode
))
1011 op0
= convert_memory_address (Pmode
, op0
);
1012 op0
= force_reg (Pmode
, op0
);
1014 emit_insn (gen_prefetch (op0
, op1
, op2
));
1018 /* Don't do anything with direct references to volatile memory, but
1019 generate code to handle other side effects. */
1020 if (!MEM_P (op0
) && side_effects_p (op0
))
1024 /* Get a MEM rtx for expression EXP which is the address of an operand
1025 to be used in a string instruction (cmpstrsi, movmemsi, ..). LEN is
1026 the maximum length of the block of memory that might be accessed or
1030 get_memory_rtx (tree exp
, tree len
)
1032 rtx addr
= expand_expr (exp
, NULL_RTX
, ptr_mode
, EXPAND_NORMAL
);
1033 rtx mem
= gen_rtx_MEM (BLKmode
, memory_address (BLKmode
, addr
));
1035 /* Get an expression we can use to find the attributes to assign to MEM.
1036 If it is an ADDR_EXPR, use the operand. Otherwise, dereference it if
1037 we can. First remove any nops. */
1038 while ((TREE_CODE (exp
) == NOP_EXPR
|| TREE_CODE (exp
) == CONVERT_EXPR
1039 || TREE_CODE (exp
) == NON_LVALUE_EXPR
)
1040 && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (exp
, 0))))
1041 exp
= TREE_OPERAND (exp
, 0);
1043 if (TREE_CODE (exp
) == ADDR_EXPR
)
1044 exp
= TREE_OPERAND (exp
, 0);
1045 else if (POINTER_TYPE_P (TREE_TYPE (exp
)))
1046 exp
= build1 (INDIRECT_REF
, TREE_TYPE (TREE_TYPE (exp
)), exp
);
1050 /* Honor attributes derived from exp, except for the alias set
1051 (as builtin stringops may alias with anything) and the size
1052 (as stringops may access multiple array elements). */
1055 set_mem_attributes (mem
, exp
, 0);
1057 /* Allow the string and memory builtins to overflow from one
1058 field into another, see http://gcc.gnu.org/PR23561.
1059 Thus avoid COMPONENT_REFs in MEM_EXPR unless we know the whole
1060 memory accessed by the string or memory builtin will fit
1061 within the field. */
1062 if (MEM_EXPR (mem
) && TREE_CODE (MEM_EXPR (mem
)) == COMPONENT_REF
)
1064 tree mem_expr
= MEM_EXPR (mem
);
1065 HOST_WIDE_INT offset
= -1, length
= -1;
1068 while (TREE_CODE (inner
) == ARRAY_REF
1069 || TREE_CODE (inner
) == NOP_EXPR
1070 || TREE_CODE (inner
) == CONVERT_EXPR
1071 || TREE_CODE (inner
) == NON_LVALUE_EXPR
1072 || TREE_CODE (inner
) == VIEW_CONVERT_EXPR
1073 || TREE_CODE (inner
) == SAVE_EXPR
)
1074 inner
= TREE_OPERAND (inner
, 0);
1076 gcc_assert (TREE_CODE (inner
) == COMPONENT_REF
);
1078 if (MEM_OFFSET (mem
)
1079 && GET_CODE (MEM_OFFSET (mem
)) == CONST_INT
)
1080 offset
= INTVAL (MEM_OFFSET (mem
));
1082 if (offset
>= 0 && len
&& host_integerp (len
, 0))
1083 length
= tree_low_cst (len
, 0);
1085 while (TREE_CODE (inner
) == COMPONENT_REF
)
1087 tree field
= TREE_OPERAND (inner
, 1);
1088 gcc_assert (! DECL_BIT_FIELD (field
));
1089 gcc_assert (TREE_CODE (mem_expr
) == COMPONENT_REF
);
1090 gcc_assert (field
== TREE_OPERAND (mem_expr
, 1));
1093 && TYPE_SIZE_UNIT (TREE_TYPE (inner
))
1094 && host_integerp (TYPE_SIZE_UNIT (TREE_TYPE (inner
)), 0))
1097 = tree_low_cst (TYPE_SIZE_UNIT (TREE_TYPE (inner
)), 0);
1098 /* If we can prove the memory starting at XEXP (mem, 0)
1099 and ending at XEXP (mem, 0) + LENGTH will fit into
1100 this field, we can keep that COMPONENT_REF in MEM_EXPR. */
1103 && offset
+ length
<= size
)
1108 && host_integerp (DECL_FIELD_OFFSET (field
), 0))
1109 offset
+= tree_low_cst (DECL_FIELD_OFFSET (field
), 0)
1110 + tree_low_cst (DECL_FIELD_BIT_OFFSET (field
), 1)
1118 mem_expr
= TREE_OPERAND (mem_expr
, 0);
1119 inner
= TREE_OPERAND (inner
, 0);
1122 if (mem_expr
== NULL
)
1124 if (mem_expr
!= MEM_EXPR (mem
))
1126 set_mem_expr (mem
, mem_expr
);
1127 set_mem_offset (mem
, offset
>= 0 ? GEN_INT (offset
) : NULL_RTX
);
1130 set_mem_alias_set (mem
, 0);
1131 set_mem_size (mem
, NULL_RTX
);
1137 /* Built-in functions to perform an untyped call and return. */
1139 /* For each register that may be used for calling a function, this
1140 gives a mode used to copy the register's value. VOIDmode indicates
1141 the register is not used for calling a function. If the machine
1142 has register windows, this gives only the outbound registers.
1143 INCOMING_REGNO gives the corresponding inbound register. */
1144 static enum machine_mode apply_args_mode
[FIRST_PSEUDO_REGISTER
];
1146 /* For each register that may be used for returning values, this gives
1147 a mode used to copy the register's value. VOIDmode indicates the
1148 register is not used for returning values. If the machine has
1149 register windows, this gives only the outbound registers.
1150 INCOMING_REGNO gives the corresponding inbound register. */
1151 static enum machine_mode apply_result_mode
[FIRST_PSEUDO_REGISTER
];
1153 /* For each register that may be used for calling a function, this
1154 gives the offset of that register into the block returned by
1155 __builtin_apply_args. 0 indicates that the register is not
1156 used for calling a function. */
1157 static int apply_args_reg_offset
[FIRST_PSEUDO_REGISTER
];
1159 /* Return the size required for the block returned by __builtin_apply_args,
1160 and initialize apply_args_mode. */
1163 apply_args_size (void)
1165 static int size
= -1;
1168 enum machine_mode mode
;
1170 /* The values computed by this function never change. */
1173 /* The first value is the incoming arg-pointer. */
1174 size
= GET_MODE_SIZE (Pmode
);
1176 /* The second value is the structure value address unless this is
1177 passed as an "invisible" first argument. */
1178 if (targetm
.calls
.struct_value_rtx (cfun
? TREE_TYPE (cfun
->decl
) : 0, 0))
1179 size
+= GET_MODE_SIZE (Pmode
);
1181 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
1182 if (FUNCTION_ARG_REGNO_P (regno
))
1184 mode
= reg_raw_mode
[regno
];
1186 gcc_assert (mode
!= VOIDmode
);
1188 align
= GET_MODE_ALIGNMENT (mode
) / BITS_PER_UNIT
;
1189 if (size
% align
!= 0)
1190 size
= CEIL (size
, align
) * align
;
1191 apply_args_reg_offset
[regno
] = size
;
1192 size
+= GET_MODE_SIZE (mode
);
1193 apply_args_mode
[regno
] = mode
;
1197 apply_args_mode
[regno
] = VOIDmode
;
1198 apply_args_reg_offset
[regno
] = 0;
1204 /* Return the size required for the block returned by __builtin_apply,
1205 and initialize apply_result_mode. */
1208 apply_result_size (void)
1210 static int size
= -1;
1212 enum machine_mode mode
;
1214 /* The values computed by this function never change. */
1219 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
1220 if (FUNCTION_VALUE_REGNO_P (regno
))
1222 mode
= reg_raw_mode
[regno
];
1224 gcc_assert (mode
!= VOIDmode
);
1226 align
= GET_MODE_ALIGNMENT (mode
) / BITS_PER_UNIT
;
1227 if (size
% align
!= 0)
1228 size
= CEIL (size
, align
) * align
;
1229 size
+= GET_MODE_SIZE (mode
);
1230 apply_result_mode
[regno
] = mode
;
1233 apply_result_mode
[regno
] = VOIDmode
;
1235 /* Allow targets that use untyped_call and untyped_return to override
1236 the size so that machine-specific information can be stored here. */
1237 #ifdef APPLY_RESULT_SIZE
1238 size
= APPLY_RESULT_SIZE
;
1244 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
1245 /* Create a vector describing the result block RESULT. If SAVEP is true,
1246 the result block is used to save the values; otherwise it is used to
1247 restore the values. */
1250 result_vector (int savep
, rtx result
)
1252 int regno
, size
, align
, nelts
;
1253 enum machine_mode mode
;
1255 rtx
*savevec
= alloca (FIRST_PSEUDO_REGISTER
* sizeof (rtx
));
1258 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
1259 if ((mode
= apply_result_mode
[regno
]) != VOIDmode
)
1261 align
= GET_MODE_ALIGNMENT (mode
) / BITS_PER_UNIT
;
1262 if (size
% align
!= 0)
1263 size
= CEIL (size
, align
) * align
;
1264 reg
= gen_rtx_REG (mode
, savep
? regno
: INCOMING_REGNO (regno
));
1265 mem
= adjust_address (result
, mode
, size
);
1266 savevec
[nelts
++] = (savep
1267 ? gen_rtx_SET (VOIDmode
, mem
, reg
)
1268 : gen_rtx_SET (VOIDmode
, reg
, mem
));
1269 size
+= GET_MODE_SIZE (mode
);
1271 return gen_rtx_PARALLEL (VOIDmode
, gen_rtvec_v (nelts
, savevec
));
1273 #endif /* HAVE_untyped_call or HAVE_untyped_return */
1275 /* Save the state required to perform an untyped call with the same
1276 arguments as were passed to the current function. */
1279 expand_builtin_apply_args_1 (void)
1282 int size
, align
, regno
;
1283 enum machine_mode mode
;
1284 rtx struct_incoming_value
= targetm
.calls
.struct_value_rtx (cfun
? TREE_TYPE (cfun
->decl
) : 0, 1);
1286 /* Create a block where the arg-pointer, structure value address,
1287 and argument registers can be saved. */
1288 registers
= assign_stack_local (BLKmode
, apply_args_size (), -1);
1290 /* Walk past the arg-pointer and structure value address. */
1291 size
= GET_MODE_SIZE (Pmode
);
1292 if (targetm
.calls
.struct_value_rtx (cfun
? TREE_TYPE (cfun
->decl
) : 0, 0))
1293 size
+= GET_MODE_SIZE (Pmode
);
1295 /* Save each register used in calling a function to the block. */
1296 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
1297 if ((mode
= apply_args_mode
[regno
]) != VOIDmode
)
1299 align
= GET_MODE_ALIGNMENT (mode
) / BITS_PER_UNIT
;
1300 if (size
% align
!= 0)
1301 size
= CEIL (size
, align
) * align
;
1303 tem
= gen_rtx_REG (mode
, INCOMING_REGNO (regno
));
1305 emit_move_insn (adjust_address (registers
, mode
, size
), tem
);
1306 size
+= GET_MODE_SIZE (mode
);
1309 /* Save the arg pointer to the block. */
1310 tem
= copy_to_reg (virtual_incoming_args_rtx
);
1311 #ifdef STACK_GROWS_DOWNWARD
1312 /* We need the pointer as the caller actually passed them to us, not
1313 as we might have pretended they were passed. Make sure it's a valid
1314 operand, as emit_move_insn isn't expected to handle a PLUS. */
1316 = force_operand (plus_constant (tem
, current_function_pretend_args_size
),
1319 emit_move_insn (adjust_address (registers
, Pmode
, 0), tem
);
1321 size
= GET_MODE_SIZE (Pmode
);
1323 /* Save the structure value address unless this is passed as an
1324 "invisible" first argument. */
1325 if (struct_incoming_value
)
1327 emit_move_insn (adjust_address (registers
, Pmode
, size
),
1328 copy_to_reg (struct_incoming_value
));
1329 size
+= GET_MODE_SIZE (Pmode
);
1332 /* Return the address of the block. */
1333 return copy_addr_to_reg (XEXP (registers
, 0));
1336 /* __builtin_apply_args returns block of memory allocated on
1337 the stack into which is stored the arg pointer, structure
1338 value address, static chain, and all the registers that might
1339 possibly be used in performing a function call. The code is
1340 moved to the start of the function so the incoming values are
1344 expand_builtin_apply_args (void)
1346 /* Don't do __builtin_apply_args more than once in a function.
1347 Save the result of the first call and reuse it. */
1348 if (apply_args_value
!= 0)
1349 return apply_args_value
;
1351 /* When this function is called, it means that registers must be
1352 saved on entry to this function. So we migrate the
1353 call to the first insn of this function. */
1358 temp
= expand_builtin_apply_args_1 ();
1362 apply_args_value
= temp
;
1364 /* Put the insns after the NOTE that starts the function.
1365 If this is inside a start_sequence, make the outer-level insn
1366 chain current, so the code is placed at the start of the
1368 push_topmost_sequence ();
1369 emit_insn_before (seq
, NEXT_INSN (entry_of_function ()));
1370 pop_topmost_sequence ();
1375 /* Perform an untyped call and save the state required to perform an
1376 untyped return of whatever value was returned by the given function. */
1379 expand_builtin_apply (rtx function
, rtx arguments
, rtx argsize
)
1381 int size
, align
, regno
;
1382 enum machine_mode mode
;
1383 rtx incoming_args
, result
, reg
, dest
, src
, call_insn
;
1384 rtx old_stack_level
= 0;
1385 rtx call_fusage
= 0;
1386 rtx struct_value
= targetm
.calls
.struct_value_rtx (cfun
? TREE_TYPE (cfun
->decl
) : 0, 0);
1388 arguments
= convert_memory_address (Pmode
, arguments
);
1390 /* Create a block where the return registers can be saved. */
1391 result
= assign_stack_local (BLKmode
, apply_result_size (), -1);
1393 /* Fetch the arg pointer from the ARGUMENTS block. */
1394 incoming_args
= gen_reg_rtx (Pmode
);
1395 emit_move_insn (incoming_args
, gen_rtx_MEM (Pmode
, arguments
));
1396 #ifndef STACK_GROWS_DOWNWARD
1397 incoming_args
= expand_simple_binop (Pmode
, MINUS
, incoming_args
, argsize
,
1398 incoming_args
, 0, OPTAB_LIB_WIDEN
);
1401 /* Push a new argument block and copy the arguments. Do not allow
1402 the (potential) memcpy call below to interfere with our stack
1404 do_pending_stack_adjust ();
1407 /* Save the stack with nonlocal if available. */
1408 #ifdef HAVE_save_stack_nonlocal
1409 if (HAVE_save_stack_nonlocal
)
1410 emit_stack_save (SAVE_NONLOCAL
, &old_stack_level
, NULL_RTX
);
1413 emit_stack_save (SAVE_BLOCK
, &old_stack_level
, NULL_RTX
);
1415 /* Allocate a block of memory onto the stack and copy the memory
1416 arguments to the outgoing arguments address. */
1417 allocate_dynamic_stack_space (argsize
, 0, BITS_PER_UNIT
);
1418 dest
= virtual_outgoing_args_rtx
;
1419 #ifndef STACK_GROWS_DOWNWARD
1420 if (GET_CODE (argsize
) == CONST_INT
)
1421 dest
= plus_constant (dest
, -INTVAL (argsize
));
1423 dest
= gen_rtx_PLUS (Pmode
, dest
, negate_rtx (Pmode
, argsize
));
1425 dest
= gen_rtx_MEM (BLKmode
, dest
);
1426 set_mem_align (dest
, PARM_BOUNDARY
);
1427 src
= gen_rtx_MEM (BLKmode
, incoming_args
);
1428 set_mem_align (src
, PARM_BOUNDARY
);
1429 emit_block_move (dest
, src
, argsize
, BLOCK_OP_NORMAL
);
1431 /* Refer to the argument block. */
1433 arguments
= gen_rtx_MEM (BLKmode
, arguments
);
1434 set_mem_align (arguments
, PARM_BOUNDARY
);
1436 /* Walk past the arg-pointer and structure value address. */
1437 size
= GET_MODE_SIZE (Pmode
);
1439 size
+= GET_MODE_SIZE (Pmode
);
1441 /* Restore each of the registers previously saved. Make USE insns
1442 for each of these registers for use in making the call. */
1443 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
1444 if ((mode
= apply_args_mode
[regno
]) != VOIDmode
)
1446 align
= GET_MODE_ALIGNMENT (mode
) / BITS_PER_UNIT
;
1447 if (size
% align
!= 0)
1448 size
= CEIL (size
, align
) * align
;
1449 reg
= gen_rtx_REG (mode
, regno
);
1450 emit_move_insn (reg
, adjust_address (arguments
, mode
, size
));
1451 use_reg (&call_fusage
, reg
);
1452 size
+= GET_MODE_SIZE (mode
);
1455 /* Restore the structure value address unless this is passed as an
1456 "invisible" first argument. */
1457 size
= GET_MODE_SIZE (Pmode
);
1460 rtx value
= gen_reg_rtx (Pmode
);
1461 emit_move_insn (value
, adjust_address (arguments
, Pmode
, size
));
1462 emit_move_insn (struct_value
, value
);
1463 if (REG_P (struct_value
))
1464 use_reg (&call_fusage
, struct_value
);
1465 size
+= GET_MODE_SIZE (Pmode
);
1468 /* All arguments and registers used for the call are set up by now! */
1469 function
= prepare_call_address (function
, NULL
, &call_fusage
, 0, 0);
1471 /* Ensure address is valid. SYMBOL_REF is already valid, so no need,
1472 and we don't want to load it into a register as an optimization,
1473 because prepare_call_address already did it if it should be done. */
1474 if (GET_CODE (function
) != SYMBOL_REF
)
1475 function
= memory_address (FUNCTION_MODE
, function
);
1477 /* Generate the actual call instruction and save the return value. */
1478 #ifdef HAVE_untyped_call
1479 if (HAVE_untyped_call
)
1480 emit_call_insn (gen_untyped_call (gen_rtx_MEM (FUNCTION_MODE
, function
),
1481 result
, result_vector (1, result
)));
1484 #ifdef HAVE_call_value
1485 if (HAVE_call_value
)
1489 /* Locate the unique return register. It is not possible to
1490 express a call that sets more than one return register using
1491 call_value; use untyped_call for that. In fact, untyped_call
1492 only needs to save the return registers in the given block. */
1493 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
1494 if ((mode
= apply_result_mode
[regno
]) != VOIDmode
)
1496 gcc_assert (!valreg
); /* HAVE_untyped_call required. */
1498 valreg
= gen_rtx_REG (mode
, regno
);
1501 emit_call_insn (GEN_CALL_VALUE (valreg
,
1502 gen_rtx_MEM (FUNCTION_MODE
, function
),
1503 const0_rtx
, NULL_RTX
, const0_rtx
));
1505 emit_move_insn (adjust_address (result
, GET_MODE (valreg
), 0), valreg
);
1511 /* Find the CALL insn we just emitted, and attach the register usage
1513 call_insn
= last_call_insn ();
1514 add_function_usage_to (call_insn
, call_fusage
);
1516 /* Restore the stack. */
1517 #ifdef HAVE_save_stack_nonlocal
1518 if (HAVE_save_stack_nonlocal
)
1519 emit_stack_restore (SAVE_NONLOCAL
, old_stack_level
, NULL_RTX
);
1522 emit_stack_restore (SAVE_BLOCK
, old_stack_level
, NULL_RTX
);
1526 /* Return the address of the result block. */
1527 result
= copy_addr_to_reg (XEXP (result
, 0));
1528 return convert_memory_address (ptr_mode
, result
);
1531 /* Perform an untyped return. */
1534 expand_builtin_return (rtx result
)
1536 int size
, align
, regno
;
1537 enum machine_mode mode
;
1539 rtx call_fusage
= 0;
1541 result
= convert_memory_address (Pmode
, result
);
1543 apply_result_size ();
1544 result
= gen_rtx_MEM (BLKmode
, result
);
1546 #ifdef HAVE_untyped_return
1547 if (HAVE_untyped_return
)
1549 emit_jump_insn (gen_untyped_return (result
, result_vector (0, result
)));
1555 /* Restore the return value and note that each value is used. */
1557 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
1558 if ((mode
= apply_result_mode
[regno
]) != VOIDmode
)
1560 align
= GET_MODE_ALIGNMENT (mode
) / BITS_PER_UNIT
;
1561 if (size
% align
!= 0)
1562 size
= CEIL (size
, align
) * align
;
1563 reg
= gen_rtx_REG (mode
, INCOMING_REGNO (regno
));
1564 emit_move_insn (reg
, adjust_address (result
, mode
, size
));
1566 push_to_sequence (call_fusage
);
1567 emit_insn (gen_rtx_USE (VOIDmode
, reg
));
1568 call_fusage
= get_insns ();
1570 size
+= GET_MODE_SIZE (mode
);
1573 /* Put the USE insns before the return. */
1574 emit_insn (call_fusage
);
1576 /* Return whatever values was restored by jumping directly to the end
1578 expand_naked_return ();
1581 /* Used by expand_builtin_classify_type and fold_builtin_classify_type. */
1583 static enum type_class
1584 type_to_class (tree type
)
1586 switch (TREE_CODE (type
))
1588 case VOID_TYPE
: return void_type_class
;
1589 case INTEGER_TYPE
: return integer_type_class
;
1590 case ENUMERAL_TYPE
: return enumeral_type_class
;
1591 case BOOLEAN_TYPE
: return boolean_type_class
;
1592 case POINTER_TYPE
: return pointer_type_class
;
1593 case REFERENCE_TYPE
: return reference_type_class
;
1594 case OFFSET_TYPE
: return offset_type_class
;
1595 case REAL_TYPE
: return real_type_class
;
1596 case COMPLEX_TYPE
: return complex_type_class
;
1597 case FUNCTION_TYPE
: return function_type_class
;
1598 case METHOD_TYPE
: return method_type_class
;
1599 case RECORD_TYPE
: return record_type_class
;
1601 case QUAL_UNION_TYPE
: return union_type_class
;
1602 case ARRAY_TYPE
: return (TYPE_STRING_FLAG (type
)
1603 ? string_type_class
: array_type_class
);
1604 case LANG_TYPE
: return lang_type_class
;
1605 default: return no_type_class
;
1609 /* Expand a call to __builtin_classify_type with arguments found in
1613 expand_builtin_classify_type (tree arglist
)
1616 return GEN_INT (type_to_class (TREE_TYPE (TREE_VALUE (arglist
))));
1617 return GEN_INT (no_type_class
);
1620 /* This helper macro, meant to be used in mathfn_built_in below,
1621 determines which among a set of three builtin math functions is
1622 appropriate for a given type mode. The `F' and `L' cases are
1623 automatically generated from the `double' case. */
1624 #define CASE_MATHFN(BUILT_IN_MATHFN) \
1625 case BUILT_IN_MATHFN: case BUILT_IN_MATHFN##F: case BUILT_IN_MATHFN##L: \
1626 fcode = BUILT_IN_MATHFN; fcodef = BUILT_IN_MATHFN##F ; \
1627 fcodel = BUILT_IN_MATHFN##L ; break;
1629 /* Return mathematic function equivalent to FN but operating directly
1630 on TYPE, if available. If we can't do the conversion, return zero. */
1632 mathfn_built_in (tree type
, enum built_in_function fn
)
1634 enum built_in_function fcode
, fcodef
, fcodel
;
1638 CASE_MATHFN (BUILT_IN_ACOS
)
1639 CASE_MATHFN (BUILT_IN_ACOSH
)
1640 CASE_MATHFN (BUILT_IN_ASIN
)
1641 CASE_MATHFN (BUILT_IN_ASINH
)
1642 CASE_MATHFN (BUILT_IN_ATAN
)
1643 CASE_MATHFN (BUILT_IN_ATAN2
)
1644 CASE_MATHFN (BUILT_IN_ATANH
)
1645 CASE_MATHFN (BUILT_IN_CBRT
)
1646 CASE_MATHFN (BUILT_IN_CEIL
)
1647 CASE_MATHFN (BUILT_IN_COPYSIGN
)
1648 CASE_MATHFN (BUILT_IN_COS
)
1649 CASE_MATHFN (BUILT_IN_COSH
)
1650 CASE_MATHFN (BUILT_IN_DREM
)
1651 CASE_MATHFN (BUILT_IN_ERF
)
1652 CASE_MATHFN (BUILT_IN_ERFC
)
1653 CASE_MATHFN (BUILT_IN_EXP
)
1654 CASE_MATHFN (BUILT_IN_EXP10
)
1655 CASE_MATHFN (BUILT_IN_EXP2
)
1656 CASE_MATHFN (BUILT_IN_EXPM1
)
1657 CASE_MATHFN (BUILT_IN_FABS
)
1658 CASE_MATHFN (BUILT_IN_FDIM
)
1659 CASE_MATHFN (BUILT_IN_FLOOR
)
1660 CASE_MATHFN (BUILT_IN_FMA
)
1661 CASE_MATHFN (BUILT_IN_FMAX
)
1662 CASE_MATHFN (BUILT_IN_FMIN
)
1663 CASE_MATHFN (BUILT_IN_FMOD
)
1664 CASE_MATHFN (BUILT_IN_FREXP
)
1665 CASE_MATHFN (BUILT_IN_GAMMA
)
1666 CASE_MATHFN (BUILT_IN_HUGE_VAL
)
1667 CASE_MATHFN (BUILT_IN_HYPOT
)
1668 CASE_MATHFN (BUILT_IN_ILOGB
)
1669 CASE_MATHFN (BUILT_IN_INF
)
1670 CASE_MATHFN (BUILT_IN_J0
)
1671 CASE_MATHFN (BUILT_IN_J1
)
1672 CASE_MATHFN (BUILT_IN_JN
)
1673 CASE_MATHFN (BUILT_IN_LCEIL
)
1674 CASE_MATHFN (BUILT_IN_LDEXP
)
1675 CASE_MATHFN (BUILT_IN_LFLOOR
)
1676 CASE_MATHFN (BUILT_IN_LGAMMA
)
1677 CASE_MATHFN (BUILT_IN_LLCEIL
)
1678 CASE_MATHFN (BUILT_IN_LLFLOOR
)
1679 CASE_MATHFN (BUILT_IN_LLRINT
)
1680 CASE_MATHFN (BUILT_IN_LLROUND
)
1681 CASE_MATHFN (BUILT_IN_LOG
)
1682 CASE_MATHFN (BUILT_IN_LOG10
)
1683 CASE_MATHFN (BUILT_IN_LOG1P
)
1684 CASE_MATHFN (BUILT_IN_LOG2
)
1685 CASE_MATHFN (BUILT_IN_LOGB
)
1686 CASE_MATHFN (BUILT_IN_LRINT
)
1687 CASE_MATHFN (BUILT_IN_LROUND
)
1688 CASE_MATHFN (BUILT_IN_MODF
)
1689 CASE_MATHFN (BUILT_IN_NAN
)
1690 CASE_MATHFN (BUILT_IN_NANS
)
1691 CASE_MATHFN (BUILT_IN_NEARBYINT
)
1692 CASE_MATHFN (BUILT_IN_NEXTAFTER
)
1693 CASE_MATHFN (BUILT_IN_NEXTTOWARD
)
1694 CASE_MATHFN (BUILT_IN_POW
)
1695 CASE_MATHFN (BUILT_IN_POWI
)
1696 CASE_MATHFN (BUILT_IN_POW10
)
1697 CASE_MATHFN (BUILT_IN_REMAINDER
)
1698 CASE_MATHFN (BUILT_IN_REMQUO
)
1699 CASE_MATHFN (BUILT_IN_RINT
)
1700 CASE_MATHFN (BUILT_IN_ROUND
)
1701 CASE_MATHFN (BUILT_IN_SCALB
)
1702 CASE_MATHFN (BUILT_IN_SCALBLN
)
1703 CASE_MATHFN (BUILT_IN_SCALBN
)
1704 CASE_MATHFN (BUILT_IN_SIGNIFICAND
)
1705 CASE_MATHFN (BUILT_IN_SIN
)
1706 CASE_MATHFN (BUILT_IN_SINCOS
)
1707 CASE_MATHFN (BUILT_IN_SINH
)
1708 CASE_MATHFN (BUILT_IN_SQRT
)
1709 CASE_MATHFN (BUILT_IN_TAN
)
1710 CASE_MATHFN (BUILT_IN_TANH
)
1711 CASE_MATHFN (BUILT_IN_TGAMMA
)
1712 CASE_MATHFN (BUILT_IN_TRUNC
)
1713 CASE_MATHFN (BUILT_IN_Y0
)
1714 CASE_MATHFN (BUILT_IN_Y1
)
1715 CASE_MATHFN (BUILT_IN_YN
)
1721 if (TYPE_MAIN_VARIANT (type
) == double_type_node
)
1722 return implicit_built_in_decls
[fcode
];
1723 else if (TYPE_MAIN_VARIANT (type
) == float_type_node
)
1724 return implicit_built_in_decls
[fcodef
];
1725 else if (TYPE_MAIN_VARIANT (type
) == long_double_type_node
)
1726 return implicit_built_in_decls
[fcodel
];
1731 /* If errno must be maintained, expand the RTL to check if the result,
1732 TARGET, of a built-in function call, EXP, is NaN, and if so set
1736 expand_errno_check (tree exp
, rtx target
)
1738 rtx lab
= gen_label_rtx ();
1740 /* Test the result; if it is NaN, set errno=EDOM because
1741 the argument was not in the domain. */
1742 emit_cmp_and_jump_insns (target
, target
, EQ
, 0, GET_MODE (target
),
1746 /* If this built-in doesn't throw an exception, set errno directly. */
1747 if (TREE_NOTHROW (TREE_OPERAND (TREE_OPERAND (exp
, 0), 0)))
1749 #ifdef GEN_ERRNO_RTX
1750 rtx errno_rtx
= GEN_ERRNO_RTX
;
1753 = gen_rtx_MEM (word_mode
, gen_rtx_SYMBOL_REF (Pmode
, "errno"));
1755 emit_move_insn (errno_rtx
, GEN_INT (TARGET_EDOM
));
1761 /* We can't set errno=EDOM directly; let the library call do it.
1762 Pop the arguments right away in case the call gets deleted. */
1764 expand_call (exp
, target
, 0);
1770 /* Expand a call to one of the builtin math functions (sqrt, exp, or log).
1771 Return 0 if a normal call should be emitted rather than expanding the
1772 function in-line. EXP is the expression that is a call to the builtin
1773 function; if convenient, the result should be placed in TARGET.
1774 SUBTARGET may be used as the target for computing one of EXP's operands. */
1777 expand_builtin_mathfn (tree exp
, rtx target
, rtx subtarget
)
1779 optab builtin_optab
;
1780 rtx op0
, insns
, before_call
;
1781 tree fndecl
= get_callee_fndecl (exp
);
1782 tree arglist
= TREE_OPERAND (exp
, 1);
1783 enum machine_mode mode
;
1784 bool errno_set
= false;
1787 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
1790 arg
= TREE_VALUE (arglist
);
1792 switch (DECL_FUNCTION_CODE (fndecl
))
1794 CASE_FLT_FN (BUILT_IN_SQRT
):
1795 errno_set
= ! tree_expr_nonnegative_p (arg
);
1796 builtin_optab
= sqrt_optab
;
1798 CASE_FLT_FN (BUILT_IN_EXP
):
1799 errno_set
= true; builtin_optab
= exp_optab
; break;
1800 CASE_FLT_FN (BUILT_IN_EXP10
):
1801 CASE_FLT_FN (BUILT_IN_POW10
):
1802 errno_set
= true; builtin_optab
= exp10_optab
; break;
1803 CASE_FLT_FN (BUILT_IN_EXP2
):
1804 errno_set
= true; builtin_optab
= exp2_optab
; break;
1805 CASE_FLT_FN (BUILT_IN_EXPM1
):
1806 errno_set
= true; builtin_optab
= expm1_optab
; break;
1807 CASE_FLT_FN (BUILT_IN_LOGB
):
1808 errno_set
= true; builtin_optab
= logb_optab
; break;
1809 CASE_FLT_FN (BUILT_IN_ILOGB
):
1810 errno_set
= true; builtin_optab
= ilogb_optab
; break;
1811 CASE_FLT_FN (BUILT_IN_LOG
):
1812 errno_set
= true; builtin_optab
= log_optab
; break;
1813 CASE_FLT_FN (BUILT_IN_LOG10
):
1814 errno_set
= true; builtin_optab
= log10_optab
; break;
1815 CASE_FLT_FN (BUILT_IN_LOG2
):
1816 errno_set
= true; builtin_optab
= log2_optab
; break;
1817 CASE_FLT_FN (BUILT_IN_LOG1P
):
1818 errno_set
= true; builtin_optab
= log1p_optab
; break;
1819 CASE_FLT_FN (BUILT_IN_ASIN
):
1820 builtin_optab
= asin_optab
; break;
1821 CASE_FLT_FN (BUILT_IN_ACOS
):
1822 builtin_optab
= acos_optab
; break;
1823 CASE_FLT_FN (BUILT_IN_TAN
):
1824 builtin_optab
= tan_optab
; break;
1825 CASE_FLT_FN (BUILT_IN_ATAN
):
1826 builtin_optab
= atan_optab
; break;
1827 CASE_FLT_FN (BUILT_IN_FLOOR
):
1828 builtin_optab
= floor_optab
; break;
1829 CASE_FLT_FN (BUILT_IN_CEIL
):
1830 builtin_optab
= ceil_optab
; break;
1831 CASE_FLT_FN (BUILT_IN_TRUNC
):
1832 builtin_optab
= btrunc_optab
; break;
1833 CASE_FLT_FN (BUILT_IN_ROUND
):
1834 builtin_optab
= round_optab
; break;
1835 CASE_FLT_FN (BUILT_IN_NEARBYINT
):
1836 builtin_optab
= nearbyint_optab
; break;
1837 CASE_FLT_FN (BUILT_IN_RINT
):
1838 builtin_optab
= rint_optab
; break;
1843 /* Make a suitable register to place result in. */
1844 mode
= TYPE_MODE (TREE_TYPE (exp
));
1846 if (! flag_errno_math
|| ! HONOR_NANS (mode
))
1849 /* Before working hard, check whether the instruction is available. */
1850 if (builtin_optab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
)
1852 target
= gen_reg_rtx (mode
);
1854 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
1855 need to expand the argument again. This way, we will not perform
1856 side-effects more the once. */
1857 narg
= builtin_save_expr (arg
);
1861 arglist
= build_tree_list (NULL_TREE
, arg
);
1862 exp
= build_function_call_expr (fndecl
, arglist
);
1865 op0
= expand_expr (arg
, subtarget
, VOIDmode
, 0);
1869 /* Compute into TARGET.
1870 Set TARGET to wherever the result comes back. */
1871 target
= expand_unop (mode
, builtin_optab
, op0
, target
, 0);
1876 expand_errno_check (exp
, target
);
1878 /* Output the entire sequence. */
1879 insns
= get_insns ();
1885 /* If we were unable to expand via the builtin, stop the sequence
1886 (without outputting the insns) and call to the library function
1887 with the stabilized argument list. */
1891 before_call
= get_last_insn ();
1893 target
= expand_call (exp
, target
, target
== const0_rtx
);
1895 /* If this is a sqrt operation and we don't care about errno, try to
1896 attach a REG_EQUAL note with a SQRT rtx to the emitted libcall.
1897 This allows the semantics of the libcall to be visible to the RTL
1899 if (builtin_optab
== sqrt_optab
&& !errno_set
)
1901 /* Search backwards through the insns emitted by expand_call looking
1902 for the instruction with the REG_RETVAL note. */
1903 rtx last
= get_last_insn ();
1904 while (last
!= before_call
)
1906 if (find_reg_note (last
, REG_RETVAL
, NULL
))
1908 rtx note
= find_reg_note (last
, REG_EQUAL
, NULL
);
1909 /* Check that the REQ_EQUAL note is an EXPR_LIST with
1910 two elements, i.e. symbol_ref(sqrt) and the operand. */
1912 && GET_CODE (note
) == EXPR_LIST
1913 && GET_CODE (XEXP (note
, 0)) == EXPR_LIST
1914 && XEXP (XEXP (note
, 0), 1) != NULL_RTX
1915 && XEXP (XEXP (XEXP (note
, 0), 1), 1) == NULL_RTX
)
1917 rtx operand
= XEXP (XEXP (XEXP (note
, 0), 1), 0);
1918 /* Check operand is a register with expected mode. */
1921 && GET_MODE (operand
) == mode
)
1923 /* Replace the REG_EQUAL note with a SQRT rtx. */
1924 rtx equiv
= gen_rtx_SQRT (mode
, operand
);
1925 set_unique_reg_note (last
, REG_EQUAL
, equiv
);
1930 last
= PREV_INSN (last
);
1937 /* Expand a call to the builtin binary math functions (pow and atan2).
1938 Return 0 if a normal call should be emitted rather than expanding the
1939 function in-line. EXP is the expression that is a call to the builtin
1940 function; if convenient, the result should be placed in TARGET.
1941 SUBTARGET may be used as the target for computing one of EXP's
1945 expand_builtin_mathfn_2 (tree exp
, rtx target
, rtx subtarget
)
1947 optab builtin_optab
;
1948 rtx op0
, op1
, insns
;
1949 int op1_type
= REAL_TYPE
;
1950 tree fndecl
= get_callee_fndecl (exp
);
1951 tree arglist
= TREE_OPERAND (exp
, 1);
1952 tree arg0
, arg1
, temp
, narg
;
1953 enum machine_mode mode
;
1954 bool errno_set
= true;
1957 if ((DECL_FUNCTION_CODE (fndecl
) == BUILT_IN_LDEXP
)
1958 || (DECL_FUNCTION_CODE (fndecl
) == BUILT_IN_LDEXPF
)
1959 || (DECL_FUNCTION_CODE (fndecl
) == BUILT_IN_LDEXPL
))
1960 op1_type
= INTEGER_TYPE
;
1962 if (!validate_arglist (arglist
, REAL_TYPE
, op1_type
, VOID_TYPE
))
1965 arg0
= TREE_VALUE (arglist
);
1966 arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
1968 switch (DECL_FUNCTION_CODE (fndecl
))
1970 CASE_FLT_FN (BUILT_IN_POW
):
1971 builtin_optab
= pow_optab
; break;
1972 CASE_FLT_FN (BUILT_IN_ATAN2
):
1973 builtin_optab
= atan2_optab
; break;
1974 CASE_FLT_FN (BUILT_IN_LDEXP
):
1975 builtin_optab
= ldexp_optab
; break;
1976 CASE_FLT_FN (BUILT_IN_FMOD
):
1977 builtin_optab
= fmod_optab
; break;
1978 CASE_FLT_FN (BUILT_IN_REMAINDER
):
1979 CASE_FLT_FN (BUILT_IN_DREM
):
1980 builtin_optab
= remainder_optab
; break;
1985 /* Make a suitable register to place result in. */
1986 mode
= TYPE_MODE (TREE_TYPE (exp
));
1988 /* Before working hard, check whether the instruction is available. */
1989 if (builtin_optab
->handlers
[(int) mode
].insn_code
== CODE_FOR_nothing
)
1992 target
= gen_reg_rtx (mode
);
1994 if (! flag_errno_math
|| ! HONOR_NANS (mode
))
1997 /* Always stabilize the argument list. */
1998 narg
= builtin_save_expr (arg1
);
2002 temp
= build_tree_list (NULL_TREE
, narg
);
2006 temp
= TREE_CHAIN (arglist
);
2008 narg
= builtin_save_expr (arg0
);
2012 arglist
= tree_cons (NULL_TREE
, narg
, temp
);
2016 arglist
= tree_cons (NULL_TREE
, arg0
, temp
);
2019 exp
= build_function_call_expr (fndecl
, arglist
);
2021 op0
= expand_expr (arg0
, subtarget
, VOIDmode
, EXPAND_NORMAL
);
2022 op1
= expand_normal (arg1
);
2026 /* Compute into TARGET.
2027 Set TARGET to wherever the result comes back. */
2028 target
= expand_binop (mode
, builtin_optab
, op0
, op1
,
2029 target
, 0, OPTAB_DIRECT
);
2031 /* If we were unable to expand via the builtin, stop the sequence
2032 (without outputting the insns) and call to the library function
2033 with the stabilized argument list. */
2037 return expand_call (exp
, target
, target
== const0_rtx
);
2041 expand_errno_check (exp
, target
);
2043 /* Output the entire sequence. */
2044 insns
= get_insns ();
2051 /* Expand a call to the builtin sin and cos math functions.
2052 Return 0 if a normal call should be emitted rather than expanding the
2053 function in-line. EXP is the expression that is a call to the builtin
2054 function; if convenient, the result should be placed in TARGET.
2055 SUBTARGET may be used as the target for computing one of EXP's
2059 expand_builtin_mathfn_3 (tree exp
, rtx target
, rtx subtarget
)
2061 optab builtin_optab
;
2063 tree fndecl
= get_callee_fndecl (exp
);
2064 tree arglist
= TREE_OPERAND (exp
, 1);
2065 enum machine_mode mode
;
2068 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
2071 arg
= TREE_VALUE (arglist
);
2073 switch (DECL_FUNCTION_CODE (fndecl
))
2075 CASE_FLT_FN (BUILT_IN_SIN
):
2076 CASE_FLT_FN (BUILT_IN_COS
):
2077 builtin_optab
= sincos_optab
; break;
2082 /* Make a suitable register to place result in. */
2083 mode
= TYPE_MODE (TREE_TYPE (exp
));
2085 /* Check if sincos insn is available, otherwise fallback
2086 to sin or cos insn. */
2087 if (builtin_optab
->handlers
[(int) mode
].insn_code
== CODE_FOR_nothing
) {
2088 switch (DECL_FUNCTION_CODE (fndecl
))
2090 CASE_FLT_FN (BUILT_IN_SIN
):
2091 builtin_optab
= sin_optab
; break;
2092 CASE_FLT_FN (BUILT_IN_COS
):
2093 builtin_optab
= cos_optab
; break;
2099 /* Before working hard, check whether the instruction is available. */
2100 if (builtin_optab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
)
2102 target
= gen_reg_rtx (mode
);
2104 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2105 need to expand the argument again. This way, we will not perform
2106 side-effects more the once. */
2107 narg
= save_expr (arg
);
2111 arglist
= build_tree_list (NULL_TREE
, arg
);
2112 exp
= build_function_call_expr (fndecl
, arglist
);
2115 op0
= expand_expr (arg
, subtarget
, VOIDmode
, 0);
2119 /* Compute into TARGET.
2120 Set TARGET to wherever the result comes back. */
2121 if (builtin_optab
== sincos_optab
)
2125 switch (DECL_FUNCTION_CODE (fndecl
))
2127 CASE_FLT_FN (BUILT_IN_SIN
):
2128 result
= expand_twoval_unop (builtin_optab
, op0
, 0, target
, 0);
2130 CASE_FLT_FN (BUILT_IN_COS
):
2131 result
= expand_twoval_unop (builtin_optab
, op0
, target
, 0, 0);
2136 gcc_assert (result
);
2140 target
= expand_unop (mode
, builtin_optab
, op0
, target
, 0);
2145 /* Output the entire sequence. */
2146 insns
= get_insns ();
2152 /* If we were unable to expand via the builtin, stop the sequence
2153 (without outputting the insns) and call to the library function
2154 with the stabilized argument list. */
2158 target
= expand_call (exp
, target
, target
== const0_rtx
);
2163 /* Expand a call to the builtin sincos math function.
2164 Return 0 if a normal call should be emitted rather than expanding the
2165 function in-line. EXP is the expression that is a call to the builtin
2169 expand_builtin_sincos (tree exp
)
2171 rtx op0
, op1
, op2
, target1
, target2
;
2172 tree arglist
= TREE_OPERAND (exp
, 1);
2173 enum machine_mode mode
;
2174 tree arg
, sinp
, cosp
;
2177 if (!validate_arglist (arglist
, REAL_TYPE
,
2178 POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
2181 arg
= TREE_VALUE (arglist
);
2182 sinp
= TREE_VALUE (TREE_CHAIN (arglist
));
2183 cosp
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
2185 /* Make a suitable register to place result in. */
2186 mode
= TYPE_MODE (TREE_TYPE (arg
));
2188 /* Check if sincos insn is available, otherwise emit the call. */
2189 if (sincos_optab
->handlers
[(int) mode
].insn_code
== CODE_FOR_nothing
)
2192 target1
= gen_reg_rtx (mode
);
2193 target2
= gen_reg_rtx (mode
);
2195 op0
= expand_normal (arg
);
2196 op1
= expand_normal (build_fold_indirect_ref (sinp
));
2197 op2
= expand_normal (build_fold_indirect_ref (cosp
));
2199 /* Compute into target1 and target2.
2200 Set TARGET to wherever the result comes back. */
2201 result
= expand_twoval_unop (sincos_optab
, op0
, target2
, target1
, 0);
2202 gcc_assert (result
);
2204 /* Move target1 and target2 to the memory locations indicated
2206 emit_move_insn (op1
, target1
);
2207 emit_move_insn (op2
, target2
);
2212 /* Expand a call to one of the builtin rounding functions gcc defines
2213 as an extension (lfloor and lceil). As these are gcc extensions we
2214 do not need to worry about setting errno to EDOM.
2215 If expanding via optab fails, lower expression to (int)(floor(x)).
2216 EXP is the expression that is a call to the builtin function;
2217 if convenient, the result should be placed in TARGET. SUBTARGET may
2218 be used as the target for computing one of EXP's operands. */
2221 expand_builtin_int_roundingfn (tree exp
, rtx target
, rtx subtarget
)
2223 optab builtin_optab
;
2224 rtx op0
, insns
, tmp
;
2225 tree fndecl
= get_callee_fndecl (exp
);
2226 tree arglist
= TREE_OPERAND (exp
, 1);
2227 enum built_in_function fallback_fn
;
2228 tree fallback_fndecl
;
2229 enum machine_mode mode
;
2232 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
2235 arg
= TREE_VALUE (arglist
);
2237 switch (DECL_FUNCTION_CODE (fndecl
))
2239 CASE_FLT_FN (BUILT_IN_LCEIL
):
2240 CASE_FLT_FN (BUILT_IN_LLCEIL
):
2241 builtin_optab
= lceil_optab
;
2242 fallback_fn
= BUILT_IN_CEIL
;
2245 CASE_FLT_FN (BUILT_IN_LFLOOR
):
2246 CASE_FLT_FN (BUILT_IN_LLFLOOR
):
2247 builtin_optab
= lfloor_optab
;
2248 fallback_fn
= BUILT_IN_FLOOR
;
2255 /* Make a suitable register to place result in. */
2256 mode
= TYPE_MODE (TREE_TYPE (exp
));
2258 /* Before working hard, check whether the instruction is available. */
2259 if (builtin_optab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
)
2261 target
= gen_reg_rtx (mode
);
2263 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2264 need to expand the argument again. This way, we will not perform
2265 side-effects more the once. */
2266 narg
= builtin_save_expr (arg
);
2270 arglist
= build_tree_list (NULL_TREE
, arg
);
2271 exp
= build_function_call_expr (fndecl
, arglist
);
2274 op0
= expand_expr (arg
, subtarget
, VOIDmode
, 0);
2278 /* Compute into TARGET.
2279 Set TARGET to wherever the result comes back. */
2280 target
= expand_unop (mode
, builtin_optab
, op0
, target
, 0);
2284 /* Output the entire sequence. */
2285 insns
= get_insns ();
2291 /* If we were unable to expand via the builtin, stop the sequence
2292 (without outputting the insns). */
2296 /* Fall back to floating point rounding optab. */
2297 fallback_fndecl
= mathfn_built_in (TREE_TYPE (arg
), fallback_fn
);
2298 /* We shouldn't get here on targets without TARGET_C99_FUNCTIONS.
2299 ??? Perhaps convert (int)floorf(x) into (int)floor((double)x). */
2300 gcc_assert (fallback_fndecl
!= NULL_TREE
);
2301 exp
= build_function_call_expr (fallback_fndecl
, arglist
);
2303 tmp
= expand_normal (exp
);
2305 /* Truncate the result of floating point optab to integer
2306 via expand_fix (). */
2307 target
= gen_reg_rtx (mode
);
2308 expand_fix (target
, tmp
, 0);
2313 /* Expand a call to one of the builtin math functions doing integer
2315 Return 0 if a normal call should be emitted rather than expanding the
2316 function in-line. EXP is the expression that is a call to the builtin
2317 function; if convenient, the result should be placed in TARGET.
2318 SUBTARGET may be used as the target for computing one of EXP's operands. */
2321 expand_builtin_int_roundingfn_2 (tree exp
, rtx target
, rtx subtarget
)
2323 convert_optab builtin_optab
;
2325 tree fndecl
= get_callee_fndecl (exp
);
2326 tree arglist
= TREE_OPERAND (exp
, 1);
2327 enum machine_mode mode
;
2330 /* There's no easy way to detect the case we need to set EDOM. */
2331 if (flag_errno_math
)
2334 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
2337 arg
= TREE_VALUE (arglist
);
2339 switch (DECL_FUNCTION_CODE (fndecl
))
2341 CASE_FLT_FN (BUILT_IN_LRINT
):
2342 CASE_FLT_FN (BUILT_IN_LLRINT
):
2343 builtin_optab
= lrint_optab
; break;
2344 CASE_FLT_FN (BUILT_IN_LROUND
):
2345 CASE_FLT_FN (BUILT_IN_LLROUND
):
2346 builtin_optab
= lround_optab
; break;
2351 /* Make a suitable register to place result in. */
2352 mode
= TYPE_MODE (TREE_TYPE (exp
));
2354 target
= gen_reg_rtx (mode
);
2356 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2357 need to expand the argument again. This way, we will not perform
2358 side-effects more the once. */
2359 narg
= builtin_save_expr (arg
);
2363 arglist
= build_tree_list (NULL_TREE
, arg
);
2364 exp
= build_function_call_expr (fndecl
, arglist
);
2367 op0
= expand_expr (arg
, subtarget
, VOIDmode
, 0);
2371 if (expand_sfix_optab (target
, op0
, builtin_optab
))
2373 /* Output the entire sequence. */
2374 insns
= get_insns ();
2380 /* If we were unable to expand via the builtin, stop the sequence
2381 (without outputting the insns) and call to the library function
2382 with the stabilized argument list. */
2385 target
= expand_call (exp
, target
, target
== const0_rtx
);
2390 /* To evaluate powi(x,n), the floating point value x raised to the
2391 constant integer exponent n, we use a hybrid algorithm that
2392 combines the "window method" with look-up tables. For an
2393 introduction to exponentiation algorithms and "addition chains",
2394 see section 4.6.3, "Evaluation of Powers" of Donald E. Knuth,
2395 "Seminumerical Algorithms", Vol. 2, "The Art of Computer Programming",
2396 3rd Edition, 1998, and Daniel M. Gordon, "A Survey of Fast Exponentiation
2397 Methods", Journal of Algorithms, Vol. 27, pp. 129-146, 1998. */
2399 /* Provide a default value for POWI_MAX_MULTS, the maximum number of
2400 multiplications to inline before calling the system library's pow
2401 function. powi(x,n) requires at worst 2*bits(n)-2 multiplications,
2402 so this default never requires calling pow, powf or powl. */
2404 #ifndef POWI_MAX_MULTS
2405 #define POWI_MAX_MULTS (2*HOST_BITS_PER_WIDE_INT-2)
2408 /* The size of the "optimal power tree" lookup table. All
2409 exponents less than this value are simply looked up in the
2410 powi_table below. This threshold is also used to size the
2411 cache of pseudo registers that hold intermediate results. */
2412 #define POWI_TABLE_SIZE 256
2414 /* The size, in bits of the window, used in the "window method"
2415 exponentiation algorithm. This is equivalent to a radix of
2416 (1<<POWI_WINDOW_SIZE) in the corresponding "m-ary method". */
2417 #define POWI_WINDOW_SIZE 3
2419 /* The following table is an efficient representation of an
2420 "optimal power tree". For each value, i, the corresponding
2421 value, j, in the table states than an optimal evaluation
2422 sequence for calculating pow(x,i) can be found by evaluating
2423 pow(x,j)*pow(x,i-j). An optimal power tree for the first
2424 100 integers is given in Knuth's "Seminumerical algorithms". */
2426 static const unsigned char powi_table
[POWI_TABLE_SIZE
] =
2428 0, 1, 1, 2, 2, 3, 3, 4, /* 0 - 7 */
2429 4, 6, 5, 6, 6, 10, 7, 9, /* 8 - 15 */
2430 8, 16, 9, 16, 10, 12, 11, 13, /* 16 - 23 */
2431 12, 17, 13, 18, 14, 24, 15, 26, /* 24 - 31 */
2432 16, 17, 17, 19, 18, 33, 19, 26, /* 32 - 39 */
2433 20, 25, 21, 40, 22, 27, 23, 44, /* 40 - 47 */
2434 24, 32, 25, 34, 26, 29, 27, 44, /* 48 - 55 */
2435 28, 31, 29, 34, 30, 60, 31, 36, /* 56 - 63 */
2436 32, 64, 33, 34, 34, 46, 35, 37, /* 64 - 71 */
2437 36, 65, 37, 50, 38, 48, 39, 69, /* 72 - 79 */
2438 40, 49, 41, 43, 42, 51, 43, 58, /* 80 - 87 */
2439 44, 64, 45, 47, 46, 59, 47, 76, /* 88 - 95 */
2440 48, 65, 49, 66, 50, 67, 51, 66, /* 96 - 103 */
2441 52, 70, 53, 74, 54, 104, 55, 74, /* 104 - 111 */
2442 56, 64, 57, 69, 58, 78, 59, 68, /* 112 - 119 */
2443 60, 61, 61, 80, 62, 75, 63, 68, /* 120 - 127 */
2444 64, 65, 65, 128, 66, 129, 67, 90, /* 128 - 135 */
2445 68, 73, 69, 131, 70, 94, 71, 88, /* 136 - 143 */
2446 72, 128, 73, 98, 74, 132, 75, 121, /* 144 - 151 */
2447 76, 102, 77, 124, 78, 132, 79, 106, /* 152 - 159 */
2448 80, 97, 81, 160, 82, 99, 83, 134, /* 160 - 167 */
2449 84, 86, 85, 95, 86, 160, 87, 100, /* 168 - 175 */
2450 88, 113, 89, 98, 90, 107, 91, 122, /* 176 - 183 */
2451 92, 111, 93, 102, 94, 126, 95, 150, /* 184 - 191 */
2452 96, 128, 97, 130, 98, 133, 99, 195, /* 192 - 199 */
2453 100, 128, 101, 123, 102, 164, 103, 138, /* 200 - 207 */
2454 104, 145, 105, 146, 106, 109, 107, 149, /* 208 - 215 */
2455 108, 200, 109, 146, 110, 170, 111, 157, /* 216 - 223 */
2456 112, 128, 113, 130, 114, 182, 115, 132, /* 224 - 231 */
2457 116, 200, 117, 132, 118, 158, 119, 206, /* 232 - 239 */
2458 120, 240, 121, 162, 122, 147, 123, 152, /* 240 - 247 */
2459 124, 166, 125, 214, 126, 138, 127, 153, /* 248 - 255 */
2463 /* Return the number of multiplications required to calculate
2464 powi(x,n) where n is less than POWI_TABLE_SIZE. This is a
2465 subroutine of powi_cost. CACHE is an array indicating
2466 which exponents have already been calculated. */
2469 powi_lookup_cost (unsigned HOST_WIDE_INT n
, bool *cache
)
2471 /* If we've already calculated this exponent, then this evaluation
2472 doesn't require any additional multiplications. */
2477 return powi_lookup_cost (n
- powi_table
[n
], cache
)
2478 + powi_lookup_cost (powi_table
[n
], cache
) + 1;
2481 /* Return the number of multiplications required to calculate
2482 powi(x,n) for an arbitrary x, given the exponent N. This
2483 function needs to be kept in sync with expand_powi below. */
2486 powi_cost (HOST_WIDE_INT n
)
2488 bool cache
[POWI_TABLE_SIZE
];
2489 unsigned HOST_WIDE_INT digit
;
2490 unsigned HOST_WIDE_INT val
;
2496 /* Ignore the reciprocal when calculating the cost. */
2497 val
= (n
< 0) ? -n
: n
;
2499 /* Initialize the exponent cache. */
2500 memset (cache
, 0, POWI_TABLE_SIZE
* sizeof (bool));
2505 while (val
>= POWI_TABLE_SIZE
)
2509 digit
= val
& ((1 << POWI_WINDOW_SIZE
) - 1);
2510 result
+= powi_lookup_cost (digit
, cache
)
2511 + POWI_WINDOW_SIZE
+ 1;
2512 val
>>= POWI_WINDOW_SIZE
;
2521 return result
+ powi_lookup_cost (val
, cache
);
2524 /* Recursive subroutine of expand_powi. This function takes the array,
2525 CACHE, of already calculated exponents and an exponent N and returns
2526 an RTX that corresponds to CACHE[1]**N, as calculated in mode MODE. */
2529 expand_powi_1 (enum machine_mode mode
, unsigned HOST_WIDE_INT n
, rtx
*cache
)
2531 unsigned HOST_WIDE_INT digit
;
2535 if (n
< POWI_TABLE_SIZE
)
2540 target
= gen_reg_rtx (mode
);
2543 op0
= expand_powi_1 (mode
, n
- powi_table
[n
], cache
);
2544 op1
= expand_powi_1 (mode
, powi_table
[n
], cache
);
2548 target
= gen_reg_rtx (mode
);
2549 digit
= n
& ((1 << POWI_WINDOW_SIZE
) - 1);
2550 op0
= expand_powi_1 (mode
, n
- digit
, cache
);
2551 op1
= expand_powi_1 (mode
, digit
, cache
);
2555 target
= gen_reg_rtx (mode
);
2556 op0
= expand_powi_1 (mode
, n
>> 1, cache
);
2560 result
= expand_mult (mode
, op0
, op1
, target
, 0);
2561 if (result
!= target
)
2562 emit_move_insn (target
, result
);
2566 /* Expand the RTL to evaluate powi(x,n) in mode MODE. X is the
2567 floating point operand in mode MODE, and N is the exponent. This
2568 function needs to be kept in sync with powi_cost above. */
2571 expand_powi (rtx x
, enum machine_mode mode
, HOST_WIDE_INT n
)
2573 unsigned HOST_WIDE_INT val
;
2574 rtx cache
[POWI_TABLE_SIZE
];
2578 return CONST1_RTX (mode
);
2580 val
= (n
< 0) ? -n
: n
;
2582 memset (cache
, 0, sizeof (cache
));
2585 result
= expand_powi_1 (mode
, (n
< 0) ? -n
: n
, cache
);
2587 /* If the original exponent was negative, reciprocate the result. */
2589 result
= expand_binop (mode
, sdiv_optab
, CONST1_RTX (mode
),
2590 result
, NULL_RTX
, 0, OPTAB_LIB_WIDEN
);
2595 /* Expand a call to the pow built-in mathematical function. Return 0 if
2596 a normal call should be emitted rather than expanding the function
2597 in-line. EXP is the expression that is a call to the builtin
2598 function; if convenient, the result should be placed in TARGET. */
2601 expand_builtin_pow (tree exp
, rtx target
, rtx subtarget
)
2603 tree arglist
= TREE_OPERAND (exp
, 1);
2606 if (! validate_arglist (arglist
, REAL_TYPE
, REAL_TYPE
, VOID_TYPE
))
2609 arg0
= TREE_VALUE (arglist
);
2610 arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
2612 if (TREE_CODE (arg1
) == REAL_CST
2613 && ! TREE_CONSTANT_OVERFLOW (arg1
))
2615 REAL_VALUE_TYPE cint
;
2619 c
= TREE_REAL_CST (arg1
);
2620 n
= real_to_integer (&c
);
2621 real_from_integer (&cint
, VOIDmode
, n
, n
< 0 ? -1 : 0, 0);
2622 if (real_identical (&c
, &cint
))
2624 /* If the exponent is -1, 0, 1 or 2, then expand_powi is exact.
2625 Otherwise, check the number of multiplications required.
2626 Note that pow never sets errno for an integer exponent. */
2627 if ((n
>= -1 && n
<= 2)
2628 || (flag_unsafe_math_optimizations
2630 && powi_cost (n
) <= POWI_MAX_MULTS
))
2632 enum machine_mode mode
= TYPE_MODE (TREE_TYPE (exp
));
2633 rtx op
= expand_expr (arg0
, subtarget
, VOIDmode
, 0);
2634 op
= force_reg (mode
, op
);
2635 return expand_powi (op
, mode
, n
);
2640 if (! flag_unsafe_math_optimizations
)
2642 return expand_builtin_mathfn_2 (exp
, target
, subtarget
);
2645 /* Expand a call to the powi built-in mathematical function. Return 0 if
2646 a normal call should be emitted rather than expanding the function
2647 in-line. EXP is the expression that is a call to the builtin
2648 function; if convenient, the result should be placed in TARGET. */
2651 expand_builtin_powi (tree exp
, rtx target
, rtx subtarget
)
2653 tree arglist
= TREE_OPERAND (exp
, 1);
2656 enum machine_mode mode
;
2657 enum machine_mode mode2
;
2659 if (! validate_arglist (arglist
, REAL_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
2662 arg0
= TREE_VALUE (arglist
);
2663 arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
2664 mode
= TYPE_MODE (TREE_TYPE (exp
));
2666 /* Handle constant power. */
2668 if (TREE_CODE (arg1
) == INTEGER_CST
2669 && ! TREE_CONSTANT_OVERFLOW (arg1
))
2671 HOST_WIDE_INT n
= TREE_INT_CST_LOW (arg1
);
2673 /* If the exponent is -1, 0, 1 or 2, then expand_powi is exact.
2674 Otherwise, check the number of multiplications required. */
2675 if ((TREE_INT_CST_HIGH (arg1
) == 0
2676 || TREE_INT_CST_HIGH (arg1
) == -1)
2677 && ((n
>= -1 && n
<= 2)
2679 && powi_cost (n
) <= POWI_MAX_MULTS
)))
2681 op0
= expand_expr (arg0
, subtarget
, VOIDmode
, 0);
2682 op0
= force_reg (mode
, op0
);
2683 return expand_powi (op0
, mode
, n
);
2687 /* Emit a libcall to libgcc. */
2689 /* Mode of the 2nd argument must match that of an int. */
2690 mode2
= mode_for_size (INT_TYPE_SIZE
, MODE_INT
, 0);
2692 if (target
== NULL_RTX
)
2693 target
= gen_reg_rtx (mode
);
2695 op0
= expand_expr (arg0
, subtarget
, mode
, 0);
2696 if (GET_MODE (op0
) != mode
)
2697 op0
= convert_to_mode (mode
, op0
, 0);
2698 op1
= expand_expr (arg1
, 0, mode2
, 0);
2699 if (GET_MODE (op1
) != mode2
)
2700 op1
= convert_to_mode (mode2
, op1
, 0);
2702 target
= emit_library_call_value (powi_optab
->handlers
[(int) mode
].libfunc
,
2703 target
, LCT_CONST_MAKE_BLOCK
, mode
, 2,
2704 op0
, mode
, op1
, mode2
);
2709 /* Expand expression EXP which is a call to the strlen builtin. Return 0
2710 if we failed the caller should emit a normal call, otherwise
2711 try to get the result in TARGET, if convenient. */
2714 expand_builtin_strlen (tree arglist
, rtx target
,
2715 enum machine_mode target_mode
)
2717 if (!validate_arglist (arglist
, POINTER_TYPE
, VOID_TYPE
))
2722 tree len
, src
= TREE_VALUE (arglist
);
2723 rtx result
, src_reg
, char_rtx
, before_strlen
;
2724 enum machine_mode insn_mode
= target_mode
, char_mode
;
2725 enum insn_code icode
= CODE_FOR_nothing
;
2728 /* If the length can be computed at compile-time, return it. */
2729 len
= c_strlen (src
, 0);
2731 return expand_expr (len
, target
, target_mode
, EXPAND_NORMAL
);
2733 /* If the length can be computed at compile-time and is constant
2734 integer, but there are side-effects in src, evaluate
2735 src for side-effects, then return len.
2736 E.g. x = strlen (i++ ? "xfoo" + 1 : "bar");
2737 can be optimized into: i++; x = 3; */
2738 len
= c_strlen (src
, 1);
2739 if (len
&& TREE_CODE (len
) == INTEGER_CST
)
2741 expand_expr (src
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
2742 return expand_expr (len
, target
, target_mode
, EXPAND_NORMAL
);
2745 align
= get_pointer_alignment (src
, BIGGEST_ALIGNMENT
) / BITS_PER_UNIT
;
2747 /* If SRC is not a pointer type, don't do this operation inline. */
2751 /* Bail out if we can't compute strlen in the right mode. */
2752 while (insn_mode
!= VOIDmode
)
2754 icode
= strlen_optab
->handlers
[(int) insn_mode
].insn_code
;
2755 if (icode
!= CODE_FOR_nothing
)
2758 insn_mode
= GET_MODE_WIDER_MODE (insn_mode
);
2760 if (insn_mode
== VOIDmode
)
2763 /* Make a place to write the result of the instruction. */
2767 && GET_MODE (result
) == insn_mode
2768 && REGNO (result
) >= FIRST_PSEUDO_REGISTER
))
2769 result
= gen_reg_rtx (insn_mode
);
2771 /* Make a place to hold the source address. We will not expand
2772 the actual source until we are sure that the expansion will
2773 not fail -- there are trees that cannot be expanded twice. */
2774 src_reg
= gen_reg_rtx (Pmode
);
2776 /* Mark the beginning of the strlen sequence so we can emit the
2777 source operand later. */
2778 before_strlen
= get_last_insn ();
2780 char_rtx
= const0_rtx
;
2781 char_mode
= insn_data
[(int) icode
].operand
[2].mode
;
2782 if (! (*insn_data
[(int) icode
].operand
[2].predicate
) (char_rtx
,
2784 char_rtx
= copy_to_mode_reg (char_mode
, char_rtx
);
2786 pat
= GEN_FCN (icode
) (result
, gen_rtx_MEM (BLKmode
, src_reg
),
2787 char_rtx
, GEN_INT (align
));
2792 /* Now that we are assured of success, expand the source. */
2794 pat
= expand_expr (src
, src_reg
, ptr_mode
, EXPAND_NORMAL
);
2796 emit_move_insn (src_reg
, pat
);
2801 emit_insn_after (pat
, before_strlen
);
2803 emit_insn_before (pat
, get_insns ());
2805 /* Return the value in the proper mode for this function. */
2806 if (GET_MODE (result
) == target_mode
)
2808 else if (target
!= 0)
2809 convert_move (target
, result
, 0);
2811 target
= convert_to_mode (target_mode
, result
, 0);
2817 /* Expand a call to the strstr builtin. Return 0 if we failed the
2818 caller should emit a normal call, otherwise try to get the result
2819 in TARGET, if convenient (and in mode MODE if that's convenient). */
2822 expand_builtin_strstr (tree arglist
, tree type
, rtx target
, enum machine_mode mode
)
2824 if (validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
2826 tree result
= fold_builtin_strstr (arglist
, type
);
2828 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
2833 /* Expand a call to the strchr builtin. Return 0 if we failed the
2834 caller should emit a normal call, otherwise try to get the result
2835 in TARGET, if convenient (and in mode MODE if that's convenient). */
2838 expand_builtin_strchr (tree arglist
, tree type
, rtx target
, enum machine_mode mode
)
2840 if (validate_arglist (arglist
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
2842 tree result
= fold_builtin_strchr (arglist
, type
);
2844 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
2846 /* FIXME: Should use strchrM optab so that ports can optimize this. */
2851 /* Expand a call to the strrchr builtin. Return 0 if we failed the
2852 caller should emit a normal call, otherwise try to get the result
2853 in TARGET, if convenient (and in mode MODE if that's convenient). */
2856 expand_builtin_strrchr (tree arglist
, tree type
, rtx target
, enum machine_mode mode
)
2858 if (validate_arglist (arglist
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
2860 tree result
= fold_builtin_strrchr (arglist
, type
);
2862 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
2867 /* Expand a call to the strpbrk builtin. Return 0 if we failed the
2868 caller should emit a normal call, otherwise try to get the result
2869 in TARGET, if convenient (and in mode MODE if that's convenient). */
2872 expand_builtin_strpbrk (tree arglist
, tree type
, rtx target
, enum machine_mode mode
)
2874 if (validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
2876 tree result
= fold_builtin_strpbrk (arglist
, type
);
2878 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
2883 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
2884 bytes from constant string DATA + OFFSET and return it as target
2888 builtin_memcpy_read_str (void *data
, HOST_WIDE_INT offset
,
2889 enum machine_mode mode
)
2891 const char *str
= (const char *) data
;
2893 gcc_assert (offset
>= 0
2894 && ((unsigned HOST_WIDE_INT
) offset
+ GET_MODE_SIZE (mode
)
2895 <= strlen (str
) + 1));
2897 return c_readstr (str
+ offset
, mode
);
2900 /* Expand a call to the memcpy builtin, with arguments in ARGLIST.
2901 Return 0 if we failed, the caller should emit a normal call,
2902 otherwise try to get the result in TARGET, if convenient (and in
2903 mode MODE if that's convenient). */
2905 expand_builtin_memcpy (tree exp
, rtx target
, enum machine_mode mode
)
2907 tree fndecl
= get_callee_fndecl (exp
);
2908 tree arglist
= TREE_OPERAND (exp
, 1);
2909 if (!validate_arglist (arglist
,
2910 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
2914 tree dest
= TREE_VALUE (arglist
);
2915 tree src
= TREE_VALUE (TREE_CHAIN (arglist
));
2916 tree len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
2917 const char *src_str
;
2918 unsigned int src_align
= get_pointer_alignment (src
, BIGGEST_ALIGNMENT
);
2919 unsigned int dest_align
2920 = get_pointer_alignment (dest
, BIGGEST_ALIGNMENT
);
2921 rtx dest_mem
, src_mem
, dest_addr
, len_rtx
;
2922 tree result
= fold_builtin_memory_op (arglist
, TREE_TYPE (TREE_TYPE (fndecl
)),
2927 while (TREE_CODE (result
) == COMPOUND_EXPR
)
2929 expand_expr (TREE_OPERAND (result
, 0), const0_rtx
, VOIDmode
,
2931 result
= TREE_OPERAND (result
, 1);
2933 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
2936 /* If DEST is not a pointer type, call the normal function. */
2937 if (dest_align
== 0)
2940 /* If either SRC is not a pointer type, don't do this
2941 operation in-line. */
2945 dest_mem
= get_memory_rtx (dest
, len
);
2946 set_mem_align (dest_mem
, dest_align
);
2947 len_rtx
= expand_normal (len
);
2948 src_str
= c_getstr (src
);
2950 /* If SRC is a string constant and block move would be done
2951 by pieces, we can avoid loading the string from memory
2952 and only stored the computed constants. */
2954 && GET_CODE (len_rtx
) == CONST_INT
2955 && (unsigned HOST_WIDE_INT
) INTVAL (len_rtx
) <= strlen (src_str
) + 1
2956 && can_store_by_pieces (INTVAL (len_rtx
), builtin_memcpy_read_str
,
2957 (void *) src_str
, dest_align
))
2959 dest_mem
= store_by_pieces (dest_mem
, INTVAL (len_rtx
),
2960 builtin_memcpy_read_str
,
2961 (void *) src_str
, dest_align
, 0);
2962 dest_mem
= force_operand (XEXP (dest_mem
, 0), NULL_RTX
);
2963 dest_mem
= convert_memory_address (ptr_mode
, dest_mem
);
2967 src_mem
= get_memory_rtx (src
, len
);
2968 set_mem_align (src_mem
, src_align
);
2970 /* Copy word part most expediently. */
2971 dest_addr
= emit_block_move (dest_mem
, src_mem
, len_rtx
,
2972 CALL_EXPR_TAILCALL (exp
)
2973 ? BLOCK_OP_TAILCALL
: BLOCK_OP_NORMAL
);
2977 dest_addr
= force_operand (XEXP (dest_mem
, 0), NULL_RTX
);
2978 dest_addr
= convert_memory_address (ptr_mode
, dest_addr
);
2984 /* Expand a call to the mempcpy builtin, with arguments in ARGLIST.
2985 Return 0 if we failed; the caller should emit a normal call,
2986 otherwise try to get the result in TARGET, if convenient (and in
2987 mode MODE if that's convenient). If ENDP is 0 return the
2988 destination pointer, if ENDP is 1 return the end pointer ala
2989 mempcpy, and if ENDP is 2 return the end pointer minus one ala
2993 expand_builtin_mempcpy (tree arglist
, tree type
, rtx target
, enum machine_mode mode
,
2996 if (!validate_arglist (arglist
,
2997 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
2999 /* If return value is ignored, transform mempcpy into memcpy. */
3000 else if (target
== const0_rtx
)
3002 tree fn
= implicit_built_in_decls
[BUILT_IN_MEMCPY
];
3007 return expand_expr (build_function_call_expr (fn
, arglist
),
3008 target
, mode
, EXPAND_NORMAL
);
3012 tree dest
= TREE_VALUE (arglist
);
3013 tree src
= TREE_VALUE (TREE_CHAIN (arglist
));
3014 tree len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
3015 const char *src_str
;
3016 unsigned int src_align
= get_pointer_alignment (src
, BIGGEST_ALIGNMENT
);
3017 unsigned int dest_align
3018 = get_pointer_alignment (dest
, BIGGEST_ALIGNMENT
);
3019 rtx dest_mem
, src_mem
, len_rtx
;
3020 tree result
= fold_builtin_memory_op (arglist
, type
, false, endp
);
3024 while (TREE_CODE (result
) == COMPOUND_EXPR
)
3026 expand_expr (TREE_OPERAND (result
, 0), const0_rtx
, VOIDmode
,
3028 result
= TREE_OPERAND (result
, 1);
3030 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
3033 /* If either SRC or DEST is not a pointer type, don't do this
3034 operation in-line. */
3035 if (dest_align
== 0 || src_align
== 0)
3038 /* If LEN is not constant, call the normal function. */
3039 if (! host_integerp (len
, 1))
3042 len_rtx
= expand_normal (len
);
3043 src_str
= c_getstr (src
);
3045 /* If SRC is a string constant and block move would be done
3046 by pieces, we can avoid loading the string from memory
3047 and only stored the computed constants. */
3049 && GET_CODE (len_rtx
) == CONST_INT
3050 && (unsigned HOST_WIDE_INT
) INTVAL (len_rtx
) <= strlen (src_str
) + 1
3051 && can_store_by_pieces (INTVAL (len_rtx
), builtin_memcpy_read_str
,
3052 (void *) src_str
, dest_align
))
3054 dest_mem
= get_memory_rtx (dest
, len
);
3055 set_mem_align (dest_mem
, dest_align
);
3056 dest_mem
= store_by_pieces (dest_mem
, INTVAL (len_rtx
),
3057 builtin_memcpy_read_str
,
3058 (void *) src_str
, dest_align
, endp
);
3059 dest_mem
= force_operand (XEXP (dest_mem
, 0), NULL_RTX
);
3060 dest_mem
= convert_memory_address (ptr_mode
, dest_mem
);
3064 if (GET_CODE (len_rtx
) == CONST_INT
3065 && can_move_by_pieces (INTVAL (len_rtx
),
3066 MIN (dest_align
, src_align
)))
3068 dest_mem
= get_memory_rtx (dest
, len
);
3069 set_mem_align (dest_mem
, dest_align
);
3070 src_mem
= get_memory_rtx (src
, len
);
3071 set_mem_align (src_mem
, src_align
);
3072 dest_mem
= move_by_pieces (dest_mem
, src_mem
, INTVAL (len_rtx
),
3073 MIN (dest_align
, src_align
), endp
);
3074 dest_mem
= force_operand (XEXP (dest_mem
, 0), NULL_RTX
);
3075 dest_mem
= convert_memory_address (ptr_mode
, dest_mem
);
3083 /* Expand expression EXP, which is a call to the memmove builtin. Return 0
3084 if we failed; the caller should emit a normal call. */
3087 expand_builtin_memmove (tree arglist
, tree type
, rtx target
,
3088 enum machine_mode mode
)
3090 if (!validate_arglist (arglist
,
3091 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
3095 tree result
= fold_builtin_memory_op (arglist
, type
, false, /*endp=*/3);
3099 while (TREE_CODE (result
) == COMPOUND_EXPR
)
3101 expand_expr (TREE_OPERAND (result
, 0), const0_rtx
, VOIDmode
,
3103 result
= TREE_OPERAND (result
, 1);
3105 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
3108 /* Otherwise, call the normal function. */
3113 /* Expand expression EXP, which is a call to the bcopy builtin. Return 0
3114 if we failed the caller should emit a normal call. */
3117 expand_builtin_bcopy (tree exp
)
3119 tree arglist
= TREE_OPERAND (exp
, 1);
3120 tree type
= TREE_TYPE (exp
);
3121 tree src
, dest
, size
, newarglist
;
3123 if (!validate_arglist (arglist
,
3124 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
3127 src
= TREE_VALUE (arglist
);
3128 dest
= TREE_VALUE (TREE_CHAIN (arglist
));
3129 size
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
3131 /* New argument list transforming bcopy(ptr x, ptr y, int z) to
3132 memmove(ptr y, ptr x, size_t z). This is done this way
3133 so that if it isn't expanded inline, we fallback to
3134 calling bcopy instead of memmove. */
3136 newarglist
= build_tree_list (NULL_TREE
, fold_convert (sizetype
, size
));
3137 newarglist
= tree_cons (NULL_TREE
, src
, newarglist
);
3138 newarglist
= tree_cons (NULL_TREE
, dest
, newarglist
);
3140 return expand_builtin_memmove (newarglist
, type
, const0_rtx
, VOIDmode
);
3144 # define HAVE_movstr 0
3145 # define CODE_FOR_movstr CODE_FOR_nothing
3148 /* Expand into a movstr instruction, if one is available. Return 0 if
3149 we failed, the caller should emit a normal call, otherwise try to
3150 get the result in TARGET, if convenient. If ENDP is 0 return the
3151 destination pointer, if ENDP is 1 return the end pointer ala
3152 mempcpy, and if ENDP is 2 return the end pointer minus one ala
3156 expand_movstr (tree dest
, tree src
, rtx target
, int endp
)
3162 const struct insn_data
* data
;
3167 dest_mem
= get_memory_rtx (dest
, NULL
);
3168 src_mem
= get_memory_rtx (src
, NULL
);
3171 target
= force_reg (Pmode
, XEXP (dest_mem
, 0));
3172 dest_mem
= replace_equiv_address (dest_mem
, target
);
3173 end
= gen_reg_rtx (Pmode
);
3177 if (target
== 0 || target
== const0_rtx
)
3179 end
= gen_reg_rtx (Pmode
);
3187 data
= insn_data
+ CODE_FOR_movstr
;
3189 if (data
->operand
[0].mode
!= VOIDmode
)
3190 end
= gen_lowpart (data
->operand
[0].mode
, end
);
3192 insn
= data
->genfun (end
, dest_mem
, src_mem
);
3198 /* movstr is supposed to set end to the address of the NUL
3199 terminator. If the caller requested a mempcpy-like return value,
3201 if (endp
== 1 && target
!= const0_rtx
)
3203 rtx tem
= plus_constant (gen_lowpart (GET_MODE (target
), end
), 1);
3204 emit_move_insn (target
, force_operand (tem
, NULL_RTX
));
3210 /* Expand expression EXP, which is a call to the strcpy builtin. Return 0
3211 if we failed the caller should emit a normal call, otherwise try to get
3212 the result in TARGET, if convenient (and in mode MODE if that's
3216 expand_builtin_strcpy (tree fndecl
, tree arglist
, rtx target
, enum machine_mode mode
)
3218 if (validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
3220 tree result
= fold_builtin_strcpy (fndecl
, arglist
, 0);
3223 while (TREE_CODE (result
) == COMPOUND_EXPR
)
3225 expand_expr (TREE_OPERAND (result
, 0), const0_rtx
, VOIDmode
,
3227 result
= TREE_OPERAND (result
, 1);
3229 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
3232 return expand_movstr (TREE_VALUE (arglist
),
3233 TREE_VALUE (TREE_CHAIN (arglist
)),
3234 target
, /*endp=*/0);
3239 /* Expand a call to the stpcpy builtin, with arguments in ARGLIST.
3240 Return 0 if we failed the caller should emit a normal call,
3241 otherwise try to get the result in TARGET, if convenient (and in
3242 mode MODE if that's convenient). */
3245 expand_builtin_stpcpy (tree exp
, rtx target
, enum machine_mode mode
)
3247 tree arglist
= TREE_OPERAND (exp
, 1);
3248 /* If return value is ignored, transform stpcpy into strcpy. */
3249 if (target
== const0_rtx
)
3251 tree fn
= implicit_built_in_decls
[BUILT_IN_STRCPY
];
3255 return expand_expr (build_function_call_expr (fn
, arglist
),
3256 target
, mode
, EXPAND_NORMAL
);
3259 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
3263 tree dst
, src
, len
, lenp1
;
3267 /* Ensure we get an actual string whose length can be evaluated at
3268 compile-time, not an expression containing a string. This is
3269 because the latter will potentially produce pessimized code
3270 when used to produce the return value. */
3271 src
= TREE_VALUE (TREE_CHAIN (arglist
));
3272 if (! c_getstr (src
) || ! (len
= c_strlen (src
, 0)))
3273 return expand_movstr (TREE_VALUE (arglist
),
3274 TREE_VALUE (TREE_CHAIN (arglist
)),
3275 target
, /*endp=*/2);
3277 dst
= TREE_VALUE (arglist
);
3278 lenp1
= size_binop (PLUS_EXPR
, len
, ssize_int (1));
3279 narglist
= build_tree_list (NULL_TREE
, lenp1
);
3280 narglist
= tree_cons (NULL_TREE
, src
, narglist
);
3281 narglist
= tree_cons (NULL_TREE
, dst
, narglist
);
3282 ret
= expand_builtin_mempcpy (narglist
, TREE_TYPE (exp
),
3283 target
, mode
, /*endp=*/2);
3288 if (TREE_CODE (len
) == INTEGER_CST
)
3290 rtx len_rtx
= expand_normal (len
);
3292 if (GET_CODE (len_rtx
) == CONST_INT
)
3294 ret
= expand_builtin_strcpy (get_callee_fndecl (exp
),
3295 arglist
, target
, mode
);
3301 if (mode
!= VOIDmode
)
3302 target
= gen_reg_rtx (mode
);
3304 target
= gen_reg_rtx (GET_MODE (ret
));
3306 if (GET_MODE (target
) != GET_MODE (ret
))
3307 ret
= gen_lowpart (GET_MODE (target
), ret
);
3309 ret
= plus_constant (ret
, INTVAL (len_rtx
));
3310 ret
= emit_move_insn (target
, force_operand (ret
, NULL_RTX
));
3318 return expand_movstr (TREE_VALUE (arglist
),
3319 TREE_VALUE (TREE_CHAIN (arglist
)),
3320 target
, /*endp=*/2);
3324 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
3325 bytes from constant string DATA + OFFSET and return it as target
3329 builtin_strncpy_read_str (void *data
, HOST_WIDE_INT offset
,
3330 enum machine_mode mode
)
3332 const char *str
= (const char *) data
;
3334 if ((unsigned HOST_WIDE_INT
) offset
> strlen (str
))
3337 return c_readstr (str
+ offset
, mode
);
3340 /* Expand expression EXP, which is a call to the strncpy builtin. Return 0
3341 if we failed the caller should emit a normal call. */
3344 expand_builtin_strncpy (tree exp
, rtx target
, enum machine_mode mode
)
3346 tree fndecl
= get_callee_fndecl (exp
);
3347 tree arglist
= TREE_OPERAND (exp
, 1);
3348 if (validate_arglist (arglist
,
3349 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
3351 tree slen
= c_strlen (TREE_VALUE (TREE_CHAIN (arglist
)), 1);
3352 tree len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
3353 tree result
= fold_builtin_strncpy (fndecl
, arglist
, slen
);
3357 while (TREE_CODE (result
) == COMPOUND_EXPR
)
3359 expand_expr (TREE_OPERAND (result
, 0), const0_rtx
, VOIDmode
,
3361 result
= TREE_OPERAND (result
, 1);
3363 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
3366 /* We must be passed a constant len and src parameter. */
3367 if (!host_integerp (len
, 1) || !slen
|| !host_integerp (slen
, 1))
3370 slen
= size_binop (PLUS_EXPR
, slen
, ssize_int (1));
3372 /* We're required to pad with trailing zeros if the requested
3373 len is greater than strlen(s2)+1. In that case try to
3374 use store_by_pieces, if it fails, punt. */
3375 if (tree_int_cst_lt (slen
, len
))
3377 tree dest
= TREE_VALUE (arglist
);
3378 unsigned int dest_align
3379 = get_pointer_alignment (dest
, BIGGEST_ALIGNMENT
);
3380 const char *p
= c_getstr (TREE_VALUE (TREE_CHAIN (arglist
)));
3383 if (!p
|| dest_align
== 0 || !host_integerp (len
, 1)
3384 || !can_store_by_pieces (tree_low_cst (len
, 1),
3385 builtin_strncpy_read_str
,
3386 (void *) p
, dest_align
))
3389 dest_mem
= get_memory_rtx (dest
, len
);
3390 store_by_pieces (dest_mem
, tree_low_cst (len
, 1),
3391 builtin_strncpy_read_str
,
3392 (void *) p
, dest_align
, 0);
3393 dest_mem
= force_operand (XEXP (dest_mem
, 0), NULL_RTX
);
3394 dest_mem
= convert_memory_address (ptr_mode
, dest_mem
);
3401 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
3402 bytes from constant string DATA + OFFSET and return it as target
3406 builtin_memset_read_str (void *data
, HOST_WIDE_INT offset ATTRIBUTE_UNUSED
,
3407 enum machine_mode mode
)
3409 const char *c
= (const char *) data
;
3410 char *p
= alloca (GET_MODE_SIZE (mode
));
3412 memset (p
, *c
, GET_MODE_SIZE (mode
));
3414 return c_readstr (p
, mode
);
3417 /* Callback routine for store_by_pieces. Return the RTL of a register
3418 containing GET_MODE_SIZE (MODE) consecutive copies of the unsigned
3419 char value given in the RTL register data. For example, if mode is
3420 4 bytes wide, return the RTL for 0x01010101*data. */
3423 builtin_memset_gen_str (void *data
, HOST_WIDE_INT offset ATTRIBUTE_UNUSED
,
3424 enum machine_mode mode
)
3430 size
= GET_MODE_SIZE (mode
);
3435 memset (p
, 1, size
);
3436 coeff
= c_readstr (p
, mode
);
3438 target
= convert_to_mode (mode
, (rtx
) data
, 1);
3439 target
= expand_mult (mode
, target
, coeff
, NULL_RTX
, 1);
3440 return force_reg (mode
, target
);
3443 /* Expand expression EXP, which is a call to the memset builtin. Return 0
3444 if we failed the caller should emit a normal call, otherwise try to get
3445 the result in TARGET, if convenient (and in mode MODE if that's
3449 expand_builtin_memset (tree arglist
, rtx target
, enum machine_mode mode
,
3452 if (!validate_arglist (arglist
,
3453 POINTER_TYPE
, INTEGER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
3457 tree dest
= TREE_VALUE (arglist
);
3458 tree val
= TREE_VALUE (TREE_CHAIN (arglist
));
3459 tree len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
3461 enum built_in_function fcode
;
3463 unsigned int dest_align
;
3464 rtx dest_mem
, dest_addr
, len_rtx
;
3466 dest_align
= get_pointer_alignment (dest
, BIGGEST_ALIGNMENT
);
3468 /* If DEST is not a pointer type, don't do this
3469 operation in-line. */
3470 if (dest_align
== 0)
3473 /* If the LEN parameter is zero, return DEST. */
3474 if (integer_zerop (len
))
3476 /* Evaluate and ignore VAL in case it has side-effects. */
3477 expand_expr (val
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
3478 return expand_expr (dest
, target
, mode
, EXPAND_NORMAL
);
3481 /* Stabilize the arguments in case we fail. */
3482 dest
= builtin_save_expr (dest
);
3483 val
= builtin_save_expr (val
);
3484 len
= builtin_save_expr (len
);
3486 len_rtx
= expand_normal (len
);
3487 dest_mem
= get_memory_rtx (dest
, len
);
3489 if (TREE_CODE (val
) != INTEGER_CST
)
3493 val_rtx
= expand_normal (val
);
3494 val_rtx
= convert_to_mode (TYPE_MODE (unsigned_char_type_node
),
3497 /* Assume that we can memset by pieces if we can store the
3498 * the coefficients by pieces (in the required modes).
3499 * We can't pass builtin_memset_gen_str as that emits RTL. */
3501 if (host_integerp (len
, 1)
3502 && !(optimize_size
&& tree_low_cst (len
, 1) > 1)
3503 && can_store_by_pieces (tree_low_cst (len
, 1),
3504 builtin_memset_read_str
, &c
, dest_align
))
3506 val_rtx
= force_reg (TYPE_MODE (unsigned_char_type_node
),
3508 store_by_pieces (dest_mem
, tree_low_cst (len
, 1),
3509 builtin_memset_gen_str
, val_rtx
, dest_align
, 0);
3511 else if (!set_storage_via_setmem (dest_mem
, len_rtx
, val_rtx
,
3515 dest_mem
= force_operand (XEXP (dest_mem
, 0), NULL_RTX
);
3516 dest_mem
= convert_memory_address (ptr_mode
, dest_mem
);
3520 if (target_char_cast (val
, &c
))
3525 if (host_integerp (len
, 1)
3526 && !(optimize_size
&& tree_low_cst (len
, 1) > 1)
3527 && can_store_by_pieces (tree_low_cst (len
, 1),
3528 builtin_memset_read_str
, &c
, dest_align
))
3529 store_by_pieces (dest_mem
, tree_low_cst (len
, 1),
3530 builtin_memset_read_str
, &c
, dest_align
, 0);
3531 else if (!set_storage_via_setmem (dest_mem
, len_rtx
, GEN_INT (c
),
3535 dest_mem
= force_operand (XEXP (dest_mem
, 0), NULL_RTX
);
3536 dest_mem
= convert_memory_address (ptr_mode
, dest_mem
);
3540 set_mem_align (dest_mem
, dest_align
);
3541 dest_addr
= clear_storage (dest_mem
, len_rtx
,
3542 CALL_EXPR_TAILCALL (orig_exp
)
3543 ? BLOCK_OP_TAILCALL
: BLOCK_OP_NORMAL
);
3547 dest_addr
= force_operand (XEXP (dest_mem
, 0), NULL_RTX
);
3548 dest_addr
= convert_memory_address (ptr_mode
, dest_addr
);
3554 fndecl
= get_callee_fndecl (orig_exp
);
3555 fcode
= DECL_FUNCTION_CODE (fndecl
);
3556 gcc_assert (fcode
== BUILT_IN_MEMSET
|| fcode
== BUILT_IN_BZERO
);
3557 arglist
= build_tree_list (NULL_TREE
, len
);
3558 if (fcode
== BUILT_IN_MEMSET
)
3559 arglist
= tree_cons (NULL_TREE
, val
, arglist
);
3560 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
3561 fn
= build_function_call_expr (fndecl
, arglist
);
3562 if (TREE_CODE (fn
) == CALL_EXPR
)
3563 CALL_EXPR_TAILCALL (fn
) = CALL_EXPR_TAILCALL (orig_exp
);
3564 return expand_call (fn
, target
, target
== const0_rtx
);
3568 /* Expand expression EXP, which is a call to the bzero builtin. Return 0
3569 if we failed the caller should emit a normal call. */
3572 expand_builtin_bzero (tree exp
)
3574 tree arglist
= TREE_OPERAND (exp
, 1);
3575 tree dest
, size
, newarglist
;
3577 if (!validate_arglist (arglist
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
3580 dest
= TREE_VALUE (arglist
);
3581 size
= TREE_VALUE (TREE_CHAIN (arglist
));
3583 /* New argument list transforming bzero(ptr x, int y) to
3584 memset(ptr x, int 0, size_t y). This is done this way
3585 so that if it isn't expanded inline, we fallback to
3586 calling bzero instead of memset. */
3588 newarglist
= build_tree_list (NULL_TREE
, fold_convert (sizetype
, size
));
3589 newarglist
= tree_cons (NULL_TREE
, integer_zero_node
, newarglist
);
3590 newarglist
= tree_cons (NULL_TREE
, dest
, newarglist
);
3592 return expand_builtin_memset (newarglist
, const0_rtx
, VOIDmode
, exp
);
3595 /* Expand expression EXP, which is a call to the memcmp built-in function.
3596 ARGLIST is the argument list for this call. Return 0 if we failed and the
3597 caller should emit a normal call, otherwise try to get the result in
3598 TARGET, if convenient (and in mode MODE, if that's convenient). */
3601 expand_builtin_memcmp (tree exp ATTRIBUTE_UNUSED
, tree arglist
, rtx target
,
3602 enum machine_mode mode
)
3604 if (!validate_arglist (arglist
,
3605 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
3609 tree result
= fold_builtin_memcmp (arglist
);
3611 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
3614 #if defined HAVE_cmpmemsi || defined HAVE_cmpstrnsi
3616 tree arg1
= TREE_VALUE (arglist
);
3617 tree arg2
= TREE_VALUE (TREE_CHAIN (arglist
));
3618 tree len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
3619 rtx arg1_rtx
, arg2_rtx
, arg3_rtx
;
3624 = get_pointer_alignment (arg1
, BIGGEST_ALIGNMENT
) / BITS_PER_UNIT
;
3626 = get_pointer_alignment (arg2
, BIGGEST_ALIGNMENT
) / BITS_PER_UNIT
;
3627 enum machine_mode insn_mode
;
3629 #ifdef HAVE_cmpmemsi
3631 insn_mode
= insn_data
[(int) CODE_FOR_cmpmemsi
].operand
[0].mode
;
3634 #ifdef HAVE_cmpstrnsi
3636 insn_mode
= insn_data
[(int) CODE_FOR_cmpstrnsi
].operand
[0].mode
;
3641 /* If we don't have POINTER_TYPE, call the function. */
3642 if (arg1_align
== 0 || arg2_align
== 0)
3645 /* Make a place to write the result of the instruction. */
3648 && REG_P (result
) && GET_MODE (result
) == insn_mode
3649 && REGNO (result
) >= FIRST_PSEUDO_REGISTER
))
3650 result
= gen_reg_rtx (insn_mode
);
3652 arg1_rtx
= get_memory_rtx (arg1
, len
);
3653 arg2_rtx
= get_memory_rtx (arg2
, len
);
3654 arg3_rtx
= expand_normal (len
);
3656 /* Set MEM_SIZE as appropriate. */
3657 if (GET_CODE (arg3_rtx
) == CONST_INT
)
3659 set_mem_size (arg1_rtx
, arg3_rtx
);
3660 set_mem_size (arg2_rtx
, arg3_rtx
);
3663 #ifdef HAVE_cmpmemsi
3665 insn
= gen_cmpmemsi (result
, arg1_rtx
, arg2_rtx
, arg3_rtx
,
3666 GEN_INT (MIN (arg1_align
, arg2_align
)));
3669 #ifdef HAVE_cmpstrnsi
3671 insn
= gen_cmpstrnsi (result
, arg1_rtx
, arg2_rtx
, arg3_rtx
,
3672 GEN_INT (MIN (arg1_align
, arg2_align
)));
3680 emit_library_call_value (memcmp_libfunc
, result
, LCT_PURE_MAKE_BLOCK
,
3681 TYPE_MODE (integer_type_node
), 3,
3682 XEXP (arg1_rtx
, 0), Pmode
,
3683 XEXP (arg2_rtx
, 0), Pmode
,
3684 convert_to_mode (TYPE_MODE (sizetype
), arg3_rtx
,
3685 TYPE_UNSIGNED (sizetype
)),
3686 TYPE_MODE (sizetype
));
3688 /* Return the value in the proper mode for this function. */
3689 mode
= TYPE_MODE (TREE_TYPE (exp
));
3690 if (GET_MODE (result
) == mode
)
3692 else if (target
!= 0)
3694 convert_move (target
, result
, 0);
3698 return convert_to_mode (mode
, result
, 0);
3705 /* Expand expression EXP, which is a call to the strcmp builtin. Return 0
3706 if we failed the caller should emit a normal call, otherwise try to get
3707 the result in TARGET, if convenient. */
3710 expand_builtin_strcmp (tree exp
, rtx target
, enum machine_mode mode
)
3712 tree arglist
= TREE_OPERAND (exp
, 1);
3714 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
3718 tree result
= fold_builtin_strcmp (arglist
);
3720 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
3723 #if defined HAVE_cmpstrsi || defined HAVE_cmpstrnsi
3724 if (cmpstr_optab
[SImode
] != CODE_FOR_nothing
3725 || cmpstrn_optab
[SImode
] != CODE_FOR_nothing
)
3727 rtx arg1_rtx
, arg2_rtx
;
3728 rtx result
, insn
= NULL_RTX
;
3731 tree arg1
= TREE_VALUE (arglist
);
3732 tree arg2
= TREE_VALUE (TREE_CHAIN (arglist
));
3734 = get_pointer_alignment (arg1
, BIGGEST_ALIGNMENT
) / BITS_PER_UNIT
;
3736 = get_pointer_alignment (arg2
, BIGGEST_ALIGNMENT
) / BITS_PER_UNIT
;
3738 /* If we don't have POINTER_TYPE, call the function. */
3739 if (arg1_align
== 0 || arg2_align
== 0)
3742 /* Stabilize the arguments in case gen_cmpstr(n)si fail. */
3743 arg1
= builtin_save_expr (arg1
);
3744 arg2
= builtin_save_expr (arg2
);
3746 arg1_rtx
= get_memory_rtx (arg1
, NULL
);
3747 arg2_rtx
= get_memory_rtx (arg2
, NULL
);
3749 #ifdef HAVE_cmpstrsi
3750 /* Try to call cmpstrsi. */
3753 enum machine_mode insn_mode
3754 = insn_data
[(int) CODE_FOR_cmpstrsi
].operand
[0].mode
;
3756 /* Make a place to write the result of the instruction. */
3759 && REG_P (result
) && GET_MODE (result
) == insn_mode
3760 && REGNO (result
) >= FIRST_PSEUDO_REGISTER
))
3761 result
= gen_reg_rtx (insn_mode
);
3763 insn
= gen_cmpstrsi (result
, arg1_rtx
, arg2_rtx
,
3764 GEN_INT (MIN (arg1_align
, arg2_align
)));
3767 #ifdef HAVE_cmpstrnsi
3768 /* Try to determine at least one length and call cmpstrnsi. */
3769 if (!insn
&& HAVE_cmpstrnsi
)
3774 enum machine_mode insn_mode
3775 = insn_data
[(int) CODE_FOR_cmpstrnsi
].operand
[0].mode
;
3776 tree len1
= c_strlen (arg1
, 1);
3777 tree len2
= c_strlen (arg2
, 1);
3780 len1
= size_binop (PLUS_EXPR
, ssize_int (1), len1
);
3782 len2
= size_binop (PLUS_EXPR
, ssize_int (1), len2
);
3784 /* If we don't have a constant length for the first, use the length
3785 of the second, if we know it. We don't require a constant for
3786 this case; some cost analysis could be done if both are available
3787 but neither is constant. For now, assume they're equally cheap,
3788 unless one has side effects. If both strings have constant lengths,
3795 else if (TREE_SIDE_EFFECTS (len1
))
3797 else if (TREE_SIDE_EFFECTS (len2
))
3799 else if (TREE_CODE (len1
) != INTEGER_CST
)
3801 else if (TREE_CODE (len2
) != INTEGER_CST
)
3803 else if (tree_int_cst_lt (len1
, len2
))
3808 /* If both arguments have side effects, we cannot optimize. */
3809 if (!len
|| TREE_SIDE_EFFECTS (len
))
3812 arg3_rtx
= expand_normal (len
);
3814 /* Make a place to write the result of the instruction. */
3817 && REG_P (result
) && GET_MODE (result
) == insn_mode
3818 && REGNO (result
) >= FIRST_PSEUDO_REGISTER
))
3819 result
= gen_reg_rtx (insn_mode
);
3821 insn
= gen_cmpstrnsi (result
, arg1_rtx
, arg2_rtx
, arg3_rtx
,
3822 GEN_INT (MIN (arg1_align
, arg2_align
)));
3830 /* Return the value in the proper mode for this function. */
3831 mode
= TYPE_MODE (TREE_TYPE (exp
));
3832 if (GET_MODE (result
) == mode
)
3835 return convert_to_mode (mode
, result
, 0);
3836 convert_move (target
, result
, 0);
3840 /* Expand the library call ourselves using a stabilized argument
3841 list to avoid re-evaluating the function's arguments twice. */
3842 #ifdef HAVE_cmpstrnsi
3845 arglist
= build_tree_list (NULL_TREE
, arg2
);
3846 arglist
= tree_cons (NULL_TREE
, arg1
, arglist
);
3847 fndecl
= get_callee_fndecl (exp
);
3848 fn
= build_function_call_expr (fndecl
, arglist
);
3849 if (TREE_CODE (fn
) == CALL_EXPR
)
3850 CALL_EXPR_TAILCALL (fn
) = CALL_EXPR_TAILCALL (exp
);
3851 return expand_call (fn
, target
, target
== const0_rtx
);
3857 /* Expand expression EXP, which is a call to the strncmp builtin. Return 0
3858 if we failed the caller should emit a normal call, otherwise try to get
3859 the result in TARGET, if convenient. */
3862 expand_builtin_strncmp (tree exp
, rtx target
, enum machine_mode mode
)
3864 tree arglist
= TREE_OPERAND (exp
, 1);
3866 if (!validate_arglist (arglist
,
3867 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
3871 tree result
= fold_builtin_strncmp (arglist
);
3873 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
3876 /* If c_strlen can determine an expression for one of the string
3877 lengths, and it doesn't have side effects, then emit cmpstrnsi
3878 using length MIN(strlen(string)+1, arg3). */
3879 #ifdef HAVE_cmpstrnsi
3882 tree arg1
= TREE_VALUE (arglist
);
3883 tree arg2
= TREE_VALUE (TREE_CHAIN (arglist
));
3884 tree arg3
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
3885 tree len
, len1
, len2
;
3886 rtx arg1_rtx
, arg2_rtx
, arg3_rtx
;
3891 = get_pointer_alignment (arg1
, BIGGEST_ALIGNMENT
) / BITS_PER_UNIT
;
3893 = get_pointer_alignment (arg2
, BIGGEST_ALIGNMENT
) / BITS_PER_UNIT
;
3894 enum machine_mode insn_mode
3895 = insn_data
[(int) CODE_FOR_cmpstrnsi
].operand
[0].mode
;
3897 len1
= c_strlen (arg1
, 1);
3898 len2
= c_strlen (arg2
, 1);
3901 len1
= size_binop (PLUS_EXPR
, ssize_int (1), len1
);
3903 len2
= size_binop (PLUS_EXPR
, ssize_int (1), len2
);
3905 /* If we don't have a constant length for the first, use the length
3906 of the second, if we know it. We don't require a constant for
3907 this case; some cost analysis could be done if both are available
3908 but neither is constant. For now, assume they're equally cheap,
3909 unless one has side effects. If both strings have constant lengths,
3916 else if (TREE_SIDE_EFFECTS (len1
))
3918 else if (TREE_SIDE_EFFECTS (len2
))
3920 else if (TREE_CODE (len1
) != INTEGER_CST
)
3922 else if (TREE_CODE (len2
) != INTEGER_CST
)
3924 else if (tree_int_cst_lt (len1
, len2
))
3929 /* If both arguments have side effects, we cannot optimize. */
3930 if (!len
|| TREE_SIDE_EFFECTS (len
))
3933 /* The actual new length parameter is MIN(len,arg3). */
3934 len
= fold_build2 (MIN_EXPR
, TREE_TYPE (len
), len
,
3935 fold_convert (TREE_TYPE (len
), arg3
));
3937 /* If we don't have POINTER_TYPE, call the function. */
3938 if (arg1_align
== 0 || arg2_align
== 0)
3941 /* Make a place to write the result of the instruction. */
3944 && REG_P (result
) && GET_MODE (result
) == insn_mode
3945 && REGNO (result
) >= FIRST_PSEUDO_REGISTER
))
3946 result
= gen_reg_rtx (insn_mode
);
3948 /* Stabilize the arguments in case gen_cmpstrnsi fails. */
3949 arg1
= builtin_save_expr (arg1
);
3950 arg2
= builtin_save_expr (arg2
);
3951 len
= builtin_save_expr (len
);
3953 arg1_rtx
= get_memory_rtx (arg1
, len
);
3954 arg2_rtx
= get_memory_rtx (arg2
, len
);
3955 arg3_rtx
= expand_normal (len
);
3956 insn
= gen_cmpstrnsi (result
, arg1_rtx
, arg2_rtx
, arg3_rtx
,
3957 GEN_INT (MIN (arg1_align
, arg2_align
)));
3962 /* Return the value in the proper mode for this function. */
3963 mode
= TYPE_MODE (TREE_TYPE (exp
));
3964 if (GET_MODE (result
) == mode
)
3967 return convert_to_mode (mode
, result
, 0);
3968 convert_move (target
, result
, 0);
3972 /* Expand the library call ourselves using a stabilized argument
3973 list to avoid re-evaluating the function's arguments twice. */
3974 arglist
= build_tree_list (NULL_TREE
, len
);
3975 arglist
= tree_cons (NULL_TREE
, arg2
, arglist
);
3976 arglist
= tree_cons (NULL_TREE
, arg1
, arglist
);
3977 fndecl
= get_callee_fndecl (exp
);
3978 fn
= build_function_call_expr (fndecl
, arglist
);
3979 if (TREE_CODE (fn
) == CALL_EXPR
)
3980 CALL_EXPR_TAILCALL (fn
) = CALL_EXPR_TAILCALL (exp
);
3981 return expand_call (fn
, target
, target
== const0_rtx
);
3987 /* Expand expression EXP, which is a call to the strcat builtin.
3988 Return 0 if we failed the caller should emit a normal call,
3989 otherwise try to get the result in TARGET, if convenient. */
3992 expand_builtin_strcat (tree fndecl
, tree arglist
, rtx target
, enum machine_mode mode
)
3994 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
3998 tree dst
= TREE_VALUE (arglist
),
3999 src
= TREE_VALUE (TREE_CHAIN (arglist
));
4000 const char *p
= c_getstr (src
);
4002 /* If the string length is zero, return the dst parameter. */
4003 if (p
&& *p
== '\0')
4004 return expand_expr (dst
, target
, mode
, EXPAND_NORMAL
);
4008 /* See if we can store by pieces into (dst + strlen(dst)). */
4009 tree newsrc
, newdst
,
4010 strlen_fn
= implicit_built_in_decls
[BUILT_IN_STRLEN
];
4013 /* Stabilize the argument list. */
4014 newsrc
= builtin_save_expr (src
);
4016 arglist
= build_tree_list (NULL_TREE
, newsrc
);
4018 arglist
= TREE_CHAIN (arglist
); /* Reusing arglist if safe. */
4020 dst
= builtin_save_expr (dst
);
4024 /* Create strlen (dst). */
4026 build_function_call_expr (strlen_fn
,
4027 build_tree_list (NULL_TREE
, dst
));
4028 /* Create (dst + (cast) strlen (dst)). */
4029 newdst
= fold_convert (TREE_TYPE (dst
), newdst
);
4030 newdst
= fold_build2 (PLUS_EXPR
, TREE_TYPE (dst
), dst
, newdst
);
4032 newdst
= builtin_save_expr (newdst
);
4033 arglist
= tree_cons (NULL_TREE
, newdst
, arglist
);
4035 if (!expand_builtin_strcpy (fndecl
, arglist
, target
, mode
))
4037 end_sequence (); /* Stop sequence. */
4041 /* Output the entire sequence. */
4042 insns
= get_insns ();
4046 return expand_expr (dst
, target
, mode
, EXPAND_NORMAL
);
4053 /* Expand expression EXP, which is a call to the strncat builtin.
4054 Return 0 if we failed the caller should emit a normal call,
4055 otherwise try to get the result in TARGET, if convenient. */
4058 expand_builtin_strncat (tree arglist
, rtx target
, enum machine_mode mode
)
4060 if (validate_arglist (arglist
,
4061 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
4063 tree result
= fold_builtin_strncat (arglist
);
4065 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
4070 /* Expand expression EXP, which is a call to the strspn builtin.
4071 Return 0 if we failed the caller should emit a normal call,
4072 otherwise try to get the result in TARGET, if convenient. */
4075 expand_builtin_strspn (tree arglist
, rtx target
, enum machine_mode mode
)
4077 if (validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
4079 tree result
= fold_builtin_strspn (arglist
);
4081 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
4086 /* Expand expression EXP, which is a call to the strcspn builtin.
4087 Return 0 if we failed the caller should emit a normal call,
4088 otherwise try to get the result in TARGET, if convenient. */
4091 expand_builtin_strcspn (tree arglist
, rtx target
, enum machine_mode mode
)
4093 if (validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
4095 tree result
= fold_builtin_strcspn (arglist
);
4097 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
4102 /* Expand a call to __builtin_saveregs, generating the result in TARGET,
4103 if that's convenient. */
4106 expand_builtin_saveregs (void)
4110 /* Don't do __builtin_saveregs more than once in a function.
4111 Save the result of the first call and reuse it. */
4112 if (saveregs_value
!= 0)
4113 return saveregs_value
;
4115 /* When this function is called, it means that registers must be
4116 saved on entry to this function. So we migrate the call to the
4117 first insn of this function. */
4121 /* Do whatever the machine needs done in this case. */
4122 val
= targetm
.calls
.expand_builtin_saveregs ();
4127 saveregs_value
= val
;
4129 /* Put the insns after the NOTE that starts the function. If this
4130 is inside a start_sequence, make the outer-level insn chain current, so
4131 the code is placed at the start of the function. */
4132 push_topmost_sequence ();
4133 emit_insn_after (seq
, entry_of_function ());
4134 pop_topmost_sequence ();
4139 /* __builtin_args_info (N) returns word N of the arg space info
4140 for the current function. The number and meanings of words
4141 is controlled by the definition of CUMULATIVE_ARGS. */
4144 expand_builtin_args_info (tree arglist
)
4146 int nwords
= sizeof (CUMULATIVE_ARGS
) / sizeof (int);
4147 int *word_ptr
= (int *) ¤t_function_args_info
;
4149 gcc_assert (sizeof (CUMULATIVE_ARGS
) % sizeof (int) == 0);
4153 if (!host_integerp (TREE_VALUE (arglist
), 0))
4154 error ("argument of %<__builtin_args_info%> must be constant");
4157 HOST_WIDE_INT wordnum
= tree_low_cst (TREE_VALUE (arglist
), 0);
4159 if (wordnum
< 0 || wordnum
>= nwords
)
4160 error ("argument of %<__builtin_args_info%> out of range");
4162 return GEN_INT (word_ptr
[wordnum
]);
4166 error ("missing argument in %<__builtin_args_info%>");
4171 /* Expand a call to __builtin_next_arg. */
4174 expand_builtin_next_arg (void)
4176 /* Checking arguments is already done in fold_builtin_next_arg
4177 that must be called before this function. */
4178 return expand_binop (Pmode
, add_optab
,
4179 current_function_internal_arg_pointer
,
4180 current_function_arg_offset_rtx
,
4181 NULL_RTX
, 0, OPTAB_LIB_WIDEN
);
4184 /* Make it easier for the backends by protecting the valist argument
4185 from multiple evaluations. */
4188 stabilize_va_list (tree valist
, int needs_lvalue
)
4190 if (TREE_CODE (va_list_type_node
) == ARRAY_TYPE
)
4192 if (TREE_SIDE_EFFECTS (valist
))
4193 valist
= save_expr (valist
);
4195 /* For this case, the backends will be expecting a pointer to
4196 TREE_TYPE (va_list_type_node), but it's possible we've
4197 actually been given an array (an actual va_list_type_node).
4199 if (TREE_CODE (TREE_TYPE (valist
)) == ARRAY_TYPE
)
4201 tree p1
= build_pointer_type (TREE_TYPE (va_list_type_node
));
4202 valist
= build_fold_addr_expr_with_type (valist
, p1
);
4211 if (! TREE_SIDE_EFFECTS (valist
))
4214 pt
= build_pointer_type (va_list_type_node
);
4215 valist
= fold_build1 (ADDR_EXPR
, pt
, valist
);
4216 TREE_SIDE_EFFECTS (valist
) = 1;
4219 if (TREE_SIDE_EFFECTS (valist
))
4220 valist
= save_expr (valist
);
4221 valist
= build_fold_indirect_ref (valist
);
4227 /* The "standard" definition of va_list is void*. */
4230 std_build_builtin_va_list (void)
4232 return ptr_type_node
;
4235 /* The "standard" implementation of va_start: just assign `nextarg' to
4239 std_expand_builtin_va_start (tree valist
, rtx nextarg
)
4243 t
= build2 (MODIFY_EXPR
, TREE_TYPE (valist
), valist
,
4244 make_tree (ptr_type_node
, nextarg
));
4245 TREE_SIDE_EFFECTS (t
) = 1;
4247 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
4250 /* Expand ARGLIST, from a call to __builtin_va_start. */
4253 expand_builtin_va_start (tree arglist
)
4258 chain
= TREE_CHAIN (arglist
);
4262 error ("too few arguments to function %<va_start%>");
4266 if (fold_builtin_next_arg (chain
))
4269 nextarg
= expand_builtin_next_arg ();
4270 valist
= stabilize_va_list (TREE_VALUE (arglist
), 1);
4272 #ifdef EXPAND_BUILTIN_VA_START
4273 EXPAND_BUILTIN_VA_START (valist
, nextarg
);
4275 std_expand_builtin_va_start (valist
, nextarg
);
4281 /* The "standard" implementation of va_arg: read the value from the
4282 current (padded) address and increment by the (padded) size. */
4285 std_gimplify_va_arg_expr (tree valist
, tree type
, tree
*pre_p
, tree
*post_p
)
4287 tree addr
, t
, type_size
, rounded_size
, valist_tmp
;
4288 unsigned HOST_WIDE_INT align
, boundary
;
4291 #ifdef ARGS_GROW_DOWNWARD
4292 /* All of the alignment and movement below is for args-grow-up machines.
4293 As of 2004, there are only 3 ARGS_GROW_DOWNWARD targets, and they all
4294 implement their own specialized gimplify_va_arg_expr routines. */
4298 indirect
= pass_by_reference (NULL
, TYPE_MODE (type
), type
, false);
4300 type
= build_pointer_type (type
);
4302 align
= PARM_BOUNDARY
/ BITS_PER_UNIT
;
4303 boundary
= FUNCTION_ARG_BOUNDARY (TYPE_MODE (type
), type
) / BITS_PER_UNIT
;
4305 /* Hoist the valist value into a temporary for the moment. */
4306 valist_tmp
= get_initialized_tmp_var (valist
, pre_p
, NULL
);
4308 /* va_list pointer is aligned to PARM_BOUNDARY. If argument actually
4309 requires greater alignment, we must perform dynamic alignment. */
4310 if (boundary
> align
4311 && !integer_zerop (TYPE_SIZE (type
)))
4313 t
= fold_convert (TREE_TYPE (valist
), size_int (boundary
- 1));
4314 t
= build2 (MODIFY_EXPR
, TREE_TYPE (valist
), valist_tmp
,
4315 build2 (PLUS_EXPR
, TREE_TYPE (valist
), valist_tmp
, t
));
4316 gimplify_and_add (t
, pre_p
);
4318 t
= fold_convert (TREE_TYPE (valist
), size_int (-boundary
));
4319 t
= build2 (MODIFY_EXPR
, TREE_TYPE (valist
), valist_tmp
,
4320 build2 (BIT_AND_EXPR
, TREE_TYPE (valist
), valist_tmp
, t
));
4321 gimplify_and_add (t
, pre_p
);
4326 /* If the actual alignment is less than the alignment of the type,
4327 adjust the type accordingly so that we don't assume strict alignment
4328 when deferencing the pointer. */
4329 boundary
*= BITS_PER_UNIT
;
4330 if (boundary
< TYPE_ALIGN (type
))
4332 type
= build_variant_type_copy (type
);
4333 TYPE_ALIGN (type
) = boundary
;
4336 /* Compute the rounded size of the type. */
4337 type_size
= size_in_bytes (type
);
4338 rounded_size
= round_up (type_size
, align
);
4340 /* Reduce rounded_size so it's sharable with the postqueue. */
4341 gimplify_expr (&rounded_size
, pre_p
, post_p
, is_gimple_val
, fb_rvalue
);
4345 if (PAD_VARARGS_DOWN
&& !integer_zerop (rounded_size
))
4347 /* Small args are padded downward. */
4348 t
= fold_build2 (GT_EXPR
, sizetype
, rounded_size
, size_int (align
));
4349 t
= fold_build3 (COND_EXPR
, sizetype
, t
, size_zero_node
,
4350 size_binop (MINUS_EXPR
, rounded_size
, type_size
));
4351 t
= fold_convert (TREE_TYPE (addr
), t
);
4352 addr
= fold_build2 (PLUS_EXPR
, TREE_TYPE (addr
), addr
, t
);
4355 /* Compute new value for AP. */
4356 t
= fold_convert (TREE_TYPE (valist
), rounded_size
);
4357 t
= build2 (PLUS_EXPR
, TREE_TYPE (valist
), valist_tmp
, t
);
4358 t
= build2 (MODIFY_EXPR
, TREE_TYPE (valist
), valist
, t
);
4359 gimplify_and_add (t
, pre_p
);
4361 addr
= fold_convert (build_pointer_type (type
), addr
);
4364 addr
= build_va_arg_indirect_ref (addr
);
4366 return build_va_arg_indirect_ref (addr
);
4369 /* Build an indirect-ref expression over the given TREE, which represents a
4370 piece of a va_arg() expansion. */
4372 build_va_arg_indirect_ref (tree addr
)
4374 addr
= build_fold_indirect_ref (addr
);
4376 if (flag_mudflap
) /* Don't instrument va_arg INDIRECT_REF. */
4382 /* Return a dummy expression of type TYPE in order to keep going after an
4386 dummy_object (tree type
)
4388 tree t
= build_int_cst (build_pointer_type (type
), 0);
4389 return build1 (INDIRECT_REF
, type
, t
);
4392 /* Gimplify __builtin_va_arg, aka VA_ARG_EXPR, which is not really a
4393 builtin function, but a very special sort of operator. */
4395 enum gimplify_status
4396 gimplify_va_arg_expr (tree
*expr_p
, tree
*pre_p
, tree
*post_p
)
4398 tree promoted_type
, want_va_type
, have_va_type
;
4399 tree valist
= TREE_OPERAND (*expr_p
, 0);
4400 tree type
= TREE_TYPE (*expr_p
);
4403 /* Verify that valist is of the proper type. */
4404 want_va_type
= va_list_type_node
;
4405 have_va_type
= TREE_TYPE (valist
);
4407 if (have_va_type
== error_mark_node
)
4410 if (TREE_CODE (want_va_type
) == ARRAY_TYPE
)
4412 /* If va_list is an array type, the argument may have decayed
4413 to a pointer type, e.g. by being passed to another function.
4414 In that case, unwrap both types so that we can compare the
4415 underlying records. */
4416 if (TREE_CODE (have_va_type
) == ARRAY_TYPE
4417 || POINTER_TYPE_P (have_va_type
))
4419 want_va_type
= TREE_TYPE (want_va_type
);
4420 have_va_type
= TREE_TYPE (have_va_type
);
4424 if (TYPE_MAIN_VARIANT (want_va_type
) != TYPE_MAIN_VARIANT (have_va_type
))
4426 error ("first argument to %<va_arg%> not of type %<va_list%>");
4430 /* Generate a diagnostic for requesting data of a type that cannot
4431 be passed through `...' due to type promotion at the call site. */
4432 else if ((promoted_type
= lang_hooks
.types
.type_promotes_to (type
))
4435 static bool gave_help
;
4437 /* Unfortunately, this is merely undefined, rather than a constraint
4438 violation, so we cannot make this an error. If this call is never
4439 executed, the program is still strictly conforming. */
4440 warning (0, "%qT is promoted to %qT when passed through %<...%>",
4441 type
, promoted_type
);
4445 warning (0, "(so you should pass %qT not %qT to %<va_arg%>)",
4446 promoted_type
, type
);
4449 /* We can, however, treat "undefined" any way we please.
4450 Call abort to encourage the user to fix the program. */
4451 inform ("if this code is reached, the program will abort");
4452 t
= build_function_call_expr (implicit_built_in_decls
[BUILT_IN_TRAP
],
4454 append_to_statement_list (t
, pre_p
);
4456 /* This is dead code, but go ahead and finish so that the
4457 mode of the result comes out right. */
4458 *expr_p
= dummy_object (type
);
4463 /* Make it easier for the backends by protecting the valist argument
4464 from multiple evaluations. */
4465 if (TREE_CODE (va_list_type_node
) == ARRAY_TYPE
)
4467 /* For this case, the backends will be expecting a pointer to
4468 TREE_TYPE (va_list_type_node), but it's possible we've
4469 actually been given an array (an actual va_list_type_node).
4471 if (TREE_CODE (TREE_TYPE (valist
)) == ARRAY_TYPE
)
4473 tree p1
= build_pointer_type (TREE_TYPE (va_list_type_node
));
4474 valist
= build_fold_addr_expr_with_type (valist
, p1
);
4476 gimplify_expr (&valist
, pre_p
, post_p
, is_gimple_val
, fb_rvalue
);
4479 gimplify_expr (&valist
, pre_p
, post_p
, is_gimple_min_lval
, fb_lvalue
);
4481 if (!targetm
.gimplify_va_arg_expr
)
4482 /* FIXME:Once most targets are converted we should merely
4483 assert this is non-null. */
4486 *expr_p
= targetm
.gimplify_va_arg_expr (valist
, type
, pre_p
, post_p
);
4491 /* Expand ARGLIST, from a call to __builtin_va_end. */
4494 expand_builtin_va_end (tree arglist
)
4496 tree valist
= TREE_VALUE (arglist
);
4498 /* Evaluate for side effects, if needed. I hate macros that don't
4500 if (TREE_SIDE_EFFECTS (valist
))
4501 expand_expr (valist
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
4506 /* Expand ARGLIST, from a call to __builtin_va_copy. We do this as a
4507 builtin rather than just as an assignment in stdarg.h because of the
4508 nastiness of array-type va_list types. */
4511 expand_builtin_va_copy (tree arglist
)
4515 dst
= TREE_VALUE (arglist
);
4516 src
= TREE_VALUE (TREE_CHAIN (arglist
));
4518 dst
= stabilize_va_list (dst
, 1);
4519 src
= stabilize_va_list (src
, 0);
4521 if (TREE_CODE (va_list_type_node
) != ARRAY_TYPE
)
4523 t
= build2 (MODIFY_EXPR
, va_list_type_node
, dst
, src
);
4524 TREE_SIDE_EFFECTS (t
) = 1;
4525 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
4529 rtx dstb
, srcb
, size
;
4531 /* Evaluate to pointers. */
4532 dstb
= expand_expr (dst
, NULL_RTX
, Pmode
, EXPAND_NORMAL
);
4533 srcb
= expand_expr (src
, NULL_RTX
, Pmode
, EXPAND_NORMAL
);
4534 size
= expand_expr (TYPE_SIZE_UNIT (va_list_type_node
), NULL_RTX
,
4535 VOIDmode
, EXPAND_NORMAL
);
4537 dstb
= convert_memory_address (Pmode
, dstb
);
4538 srcb
= convert_memory_address (Pmode
, srcb
);
4540 /* "Dereference" to BLKmode memories. */
4541 dstb
= gen_rtx_MEM (BLKmode
, dstb
);
4542 set_mem_alias_set (dstb
, get_alias_set (TREE_TYPE (TREE_TYPE (dst
))));
4543 set_mem_align (dstb
, TYPE_ALIGN (va_list_type_node
));
4544 srcb
= gen_rtx_MEM (BLKmode
, srcb
);
4545 set_mem_alias_set (srcb
, get_alias_set (TREE_TYPE (TREE_TYPE (src
))));
4546 set_mem_align (srcb
, TYPE_ALIGN (va_list_type_node
));
4549 emit_block_move (dstb
, srcb
, size
, BLOCK_OP_NORMAL
);
4555 /* Expand a call to one of the builtin functions __builtin_frame_address or
4556 __builtin_return_address. */
4559 expand_builtin_frame_address (tree fndecl
, tree arglist
)
4561 /* The argument must be a nonnegative integer constant.
4562 It counts the number of frames to scan up the stack.
4563 The value is the return address saved in that frame. */
4565 /* Warning about missing arg was already issued. */
4567 else if (! host_integerp (TREE_VALUE (arglist
), 1))
4569 if (DECL_FUNCTION_CODE (fndecl
) == BUILT_IN_FRAME_ADDRESS
)
4570 error ("invalid argument to %<__builtin_frame_address%>");
4572 error ("invalid argument to %<__builtin_return_address%>");
4578 = expand_builtin_return_addr (DECL_FUNCTION_CODE (fndecl
),
4579 tree_low_cst (TREE_VALUE (arglist
), 1));
4581 /* Some ports cannot access arbitrary stack frames. */
4584 if (DECL_FUNCTION_CODE (fndecl
) == BUILT_IN_FRAME_ADDRESS
)
4585 warning (0, "unsupported argument to %<__builtin_frame_address%>");
4587 warning (0, "unsupported argument to %<__builtin_return_address%>");
4591 /* For __builtin_frame_address, return what we've got. */
4592 if (DECL_FUNCTION_CODE (fndecl
) == BUILT_IN_FRAME_ADDRESS
)
4596 && ! CONSTANT_P (tem
))
4597 tem
= copy_to_mode_reg (Pmode
, tem
);
4602 /* Expand a call to the alloca builtin, with arguments ARGLIST. Return 0 if
4603 we failed and the caller should emit a normal call, otherwise try to get
4604 the result in TARGET, if convenient. */
4607 expand_builtin_alloca (tree arglist
, rtx target
)
4612 /* In -fmudflap-instrumented code, alloca() and __builtin_alloca()
4613 should always expand to function calls. These can be intercepted
4618 if (!validate_arglist (arglist
, INTEGER_TYPE
, VOID_TYPE
))
4621 /* Compute the argument. */
4622 op0
= expand_normal (TREE_VALUE (arglist
));
4624 /* Allocate the desired space. */
4625 result
= allocate_dynamic_stack_space (op0
, target
, BITS_PER_UNIT
);
4626 result
= convert_memory_address (ptr_mode
, result
);
4631 /* Expand a call to a unary builtin. The arguments are in ARGLIST.
4632 Return 0 if a normal call should be emitted rather than expanding the
4633 function in-line. If convenient, the result should be placed in TARGET.
4634 SUBTARGET may be used as the target for computing one of EXP's operands. */
4637 expand_builtin_unop (enum machine_mode target_mode
, tree arglist
, rtx target
,
4638 rtx subtarget
, optab op_optab
)
4641 if (!validate_arglist (arglist
, INTEGER_TYPE
, VOID_TYPE
))
4644 /* Compute the argument. */
4645 op0
= expand_expr (TREE_VALUE (arglist
), subtarget
, VOIDmode
, 0);
4646 /* Compute op, into TARGET if possible.
4647 Set TARGET to wherever the result comes back. */
4648 target
= expand_unop (TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist
))),
4649 op_optab
, op0
, target
, 1);
4650 gcc_assert (target
);
4652 return convert_to_mode (target_mode
, target
, 0);
4655 /* If the string passed to fputs is a constant and is one character
4656 long, we attempt to transform this call into __builtin_fputc(). */
4659 expand_builtin_fputs (tree arglist
, rtx target
, bool unlocked
)
4661 /* Verify the arguments in the original call. */
4662 if (validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
4664 tree result
= fold_builtin_fputs (arglist
, (target
== const0_rtx
),
4665 unlocked
, NULL_TREE
);
4667 return expand_expr (result
, target
, VOIDmode
, EXPAND_NORMAL
);
4672 /* Expand a call to __builtin_expect. We return our argument and emit a
4673 NOTE_INSN_EXPECTED_VALUE note. This is the expansion of __builtin_expect in
4674 a non-jump context. */
4677 expand_builtin_expect (tree arglist
, rtx target
)
4682 if (arglist
== NULL_TREE
4683 || TREE_CHAIN (arglist
) == NULL_TREE
)
4685 exp
= TREE_VALUE (arglist
);
4686 c
= TREE_VALUE (TREE_CHAIN (arglist
));
4688 if (TREE_CODE (c
) != INTEGER_CST
)
4690 error ("second argument to %<__builtin_expect%> must be a constant");
4691 c
= integer_zero_node
;
4694 target
= expand_expr (exp
, target
, VOIDmode
, EXPAND_NORMAL
);
4696 /* Don't bother with expected value notes for integral constants. */
4697 if (flag_guess_branch_prob
&& GET_CODE (target
) != CONST_INT
)
4699 /* We do need to force this into a register so that we can be
4700 moderately sure to be able to correctly interpret the branch
4702 target
= force_reg (GET_MODE (target
), target
);
4704 rtx_c
= expand_expr (c
, NULL_RTX
, GET_MODE (target
), EXPAND_NORMAL
);
4706 note
= emit_note (NOTE_INSN_EXPECTED_VALUE
);
4707 NOTE_EXPECTED_VALUE (note
) = gen_rtx_EQ (VOIDmode
, target
, rtx_c
);
4713 /* Like expand_builtin_expect, except do this in a jump context. This is
4714 called from do_jump if the conditional is a __builtin_expect. Return either
4715 a list of insns to emit the jump or NULL if we cannot optimize
4716 __builtin_expect. We need to optimize this at jump time so that machines
4717 like the PowerPC don't turn the test into a SCC operation, and then jump
4718 based on the test being 0/1. */
4721 expand_builtin_expect_jump (tree exp
, rtx if_false_label
, rtx if_true_label
)
4723 tree arglist
= TREE_OPERAND (exp
, 1);
4724 tree arg0
= TREE_VALUE (arglist
);
4725 tree arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
4728 /* Only handle __builtin_expect (test, 0) and
4729 __builtin_expect (test, 1). */
4730 if (TREE_CODE (TREE_TYPE (arg1
)) == INTEGER_TYPE
4731 && (integer_zerop (arg1
) || integer_onep (arg1
)))
4733 rtx insn
, drop_through_label
, temp
;
4735 /* Expand the jump insns. */
4737 do_jump (arg0
, if_false_label
, if_true_label
);
4740 drop_through_label
= get_last_insn ();
4741 if (drop_through_label
&& NOTE_P (drop_through_label
))
4742 drop_through_label
= prev_nonnote_insn (drop_through_label
);
4743 if (drop_through_label
&& !LABEL_P (drop_through_label
))
4744 drop_through_label
= NULL_RTX
;
4747 if (! if_true_label
)
4748 if_true_label
= drop_through_label
;
4749 if (! if_false_label
)
4750 if_false_label
= drop_through_label
;
4752 /* Go through and add the expect's to each of the conditional jumps. */
4754 while (insn
!= NULL_RTX
)
4756 rtx next
= NEXT_INSN (insn
);
4758 if (JUMP_P (insn
) && any_condjump_p (insn
))
4760 rtx ifelse
= SET_SRC (pc_set (insn
));
4761 rtx then_dest
= XEXP (ifelse
, 1);
4762 rtx else_dest
= XEXP (ifelse
, 2);
4765 /* First check if we recognize any of the labels. */
4766 if (GET_CODE (then_dest
) == LABEL_REF
4767 && XEXP (then_dest
, 0) == if_true_label
)
4769 else if (GET_CODE (then_dest
) == LABEL_REF
4770 && XEXP (then_dest
, 0) == if_false_label
)
4772 else if (GET_CODE (else_dest
) == LABEL_REF
4773 && XEXP (else_dest
, 0) == if_false_label
)
4775 else if (GET_CODE (else_dest
) == LABEL_REF
4776 && XEXP (else_dest
, 0) == if_true_label
)
4778 /* Otherwise check where we drop through. */
4779 else if (else_dest
== pc_rtx
)
4781 if (next
&& NOTE_P (next
))
4782 next
= next_nonnote_insn (next
);
4784 if (next
&& JUMP_P (next
)
4785 && any_uncondjump_p (next
))
4786 temp
= XEXP (SET_SRC (pc_set (next
)), 0);
4790 /* TEMP is either a CODE_LABEL, NULL_RTX or something
4791 else that can't possibly match either target label. */
4792 if (temp
== if_false_label
)
4794 else if (temp
== if_true_label
)
4797 else if (then_dest
== pc_rtx
)
4799 if (next
&& NOTE_P (next
))
4800 next
= next_nonnote_insn (next
);
4802 if (next
&& JUMP_P (next
)
4803 && any_uncondjump_p (next
))
4804 temp
= XEXP (SET_SRC (pc_set (next
)), 0);
4808 if (temp
== if_false_label
)
4810 else if (temp
== if_true_label
)
4816 /* If the test is expected to fail, reverse the
4818 if (integer_zerop (arg1
))
4820 predict_insn_def (insn
, PRED_BUILTIN_EXPECT
, taken
);
4832 expand_builtin_trap (void)
4836 emit_insn (gen_trap ());
4839 emit_library_call (abort_libfunc
, LCT_NORETURN
, VOIDmode
, 0);
4843 /* Expand a call to fabs, fabsf or fabsl with arguments ARGLIST.
4844 Return 0 if a normal call should be emitted rather than expanding
4845 the function inline. If convenient, the result should be placed
4846 in TARGET. SUBTARGET may be used as the target for computing
4850 expand_builtin_fabs (tree arglist
, rtx target
, rtx subtarget
)
4852 enum machine_mode mode
;
4856 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
4859 arg
= TREE_VALUE (arglist
);
4860 mode
= TYPE_MODE (TREE_TYPE (arg
));
4861 op0
= expand_expr (arg
, subtarget
, VOIDmode
, 0);
4862 return expand_abs (mode
, op0
, target
, 0, safe_from_p (target
, arg
, 1));
4865 /* Expand a call to copysign, copysignf, or copysignl with arguments ARGLIST.
4866 Return NULL is a normal call should be emitted rather than expanding the
4867 function inline. If convenient, the result should be placed in TARGET.
4868 SUBTARGET may be used as the target for computing the operand. */
4871 expand_builtin_copysign (tree arglist
, rtx target
, rtx subtarget
)
4876 if (!validate_arglist (arglist
, REAL_TYPE
, REAL_TYPE
, VOID_TYPE
))
4879 arg
= TREE_VALUE (arglist
);
4880 op0
= expand_expr (arg
, subtarget
, VOIDmode
, EXPAND_NORMAL
);
4882 arg
= TREE_VALUE (TREE_CHAIN (arglist
));
4883 op1
= expand_normal (arg
);
4885 return expand_copysign (op0
, op1
, target
);
4888 /* Create a new constant string literal and return a char* pointer to it.
4889 The STRING_CST value is the LEN characters at STR. */
4891 build_string_literal (int len
, const char *str
)
4893 tree t
, elem
, index
, type
;
4895 t
= build_string (len
, str
);
4896 elem
= build_type_variant (char_type_node
, 1, 0);
4897 index
= build_index_type (build_int_cst (NULL_TREE
, len
- 1));
4898 type
= build_array_type (elem
, index
);
4899 TREE_TYPE (t
) = type
;
4900 TREE_CONSTANT (t
) = 1;
4901 TREE_INVARIANT (t
) = 1;
4902 TREE_READONLY (t
) = 1;
4903 TREE_STATIC (t
) = 1;
4905 type
= build_pointer_type (type
);
4906 t
= build1 (ADDR_EXPR
, type
, t
);
4908 type
= build_pointer_type (elem
);
4909 t
= build1 (NOP_EXPR
, type
, t
);
4913 /* Expand EXP, a call to printf or printf_unlocked.
4914 Return 0 if a normal call should be emitted rather than transforming
4915 the function inline. If convenient, the result should be placed in
4916 TARGET with mode MODE. UNLOCKED indicates this is a printf_unlocked
4919 expand_builtin_printf (tree exp
, rtx target
, enum machine_mode mode
,
4922 tree arglist
= TREE_OPERAND (exp
, 1);
4923 /* If we're using an unlocked function, assume the other unlocked
4924 functions exist explicitly. */
4925 tree
const fn_putchar
= unlocked
? built_in_decls
[BUILT_IN_PUTCHAR_UNLOCKED
]
4926 : implicit_built_in_decls
[BUILT_IN_PUTCHAR
];
4927 tree
const fn_puts
= unlocked
? built_in_decls
[BUILT_IN_PUTS_UNLOCKED
]
4928 : implicit_built_in_decls
[BUILT_IN_PUTS
];
4929 const char *fmt_str
;
4932 /* If the return value is used, don't do the transformation. */
4933 if (target
!= const0_rtx
)
4936 /* Verify the required arguments in the original call. */
4939 fmt
= TREE_VALUE (arglist
);
4940 if (! POINTER_TYPE_P (TREE_TYPE (fmt
)))
4942 arglist
= TREE_CHAIN (arglist
);
4944 /* Check whether the format is a literal string constant. */
4945 fmt_str
= c_getstr (fmt
);
4946 if (fmt_str
== NULL
)
4949 if (!init_target_chars())
4952 /* If the format specifier was "%s\n", call __builtin_puts(arg). */
4953 if (strcmp (fmt_str
, target_percent_s_newline
) == 0)
4956 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist
)))
4957 || TREE_CHAIN (arglist
))
4961 /* If the format specifier was "%c", call __builtin_putchar(arg). */
4962 else if (strcmp (fmt_str
, target_percent_c
) == 0)
4965 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist
))) != INTEGER_TYPE
4966 || TREE_CHAIN (arglist
))
4972 /* We can't handle anything else with % args or %% ... yet. */
4973 if (strchr (fmt_str
, target_percent
))
4979 /* If the format specifier was "", printf does nothing. */
4980 if (fmt_str
[0] == '\0')
4982 /* If the format specifier has length of 1, call putchar. */
4983 if (fmt_str
[1] == '\0')
4985 /* Given printf("c"), (where c is any one character,)
4986 convert "c"[0] to an int and pass that to the replacement
4988 arg
= build_int_cst (NULL_TREE
, fmt_str
[0]);
4989 arglist
= build_tree_list (NULL_TREE
, arg
);
4994 /* If the format specifier was "string\n", call puts("string"). */
4995 size_t len
= strlen (fmt_str
);
4996 if ((unsigned char)fmt_str
[len
- 1] == target_newline
)
4998 /* Create a NUL-terminated string that's one char shorter
4999 than the original, stripping off the trailing '\n'. */
5000 char *newstr
= alloca (len
);
5001 memcpy (newstr
, fmt_str
, len
- 1);
5002 newstr
[len
- 1] = 0;
5004 arg
= build_string_literal (len
, newstr
);
5005 arglist
= build_tree_list (NULL_TREE
, arg
);
5009 /* We'd like to arrange to call fputs(string,stdout) here,
5010 but we need stdout and don't have a way to get it yet. */
5017 fn
= build_function_call_expr (fn
, arglist
);
5018 if (TREE_CODE (fn
) == CALL_EXPR
)
5019 CALL_EXPR_TAILCALL (fn
) = CALL_EXPR_TAILCALL (exp
);
5020 return expand_expr (fn
, target
, mode
, EXPAND_NORMAL
);
5023 /* Expand EXP, a call to fprintf or fprintf_unlocked.
5024 Return 0 if a normal call should be emitted rather than transforming
5025 the function inline. If convenient, the result should be placed in
5026 TARGET with mode MODE. UNLOCKED indicates this is a fprintf_unlocked
5029 expand_builtin_fprintf (tree exp
, rtx target
, enum machine_mode mode
,
5032 tree arglist
= TREE_OPERAND (exp
, 1);
5033 /* If we're using an unlocked function, assume the other unlocked
5034 functions exist explicitly. */
5035 tree
const fn_fputc
= unlocked
? built_in_decls
[BUILT_IN_FPUTC_UNLOCKED
]
5036 : implicit_built_in_decls
[BUILT_IN_FPUTC
];
5037 tree
const fn_fputs
= unlocked
? built_in_decls
[BUILT_IN_FPUTS_UNLOCKED
]
5038 : implicit_built_in_decls
[BUILT_IN_FPUTS
];
5039 const char *fmt_str
;
5040 tree fn
, fmt
, fp
, arg
;
5042 /* If the return value is used, don't do the transformation. */
5043 if (target
!= const0_rtx
)
5046 /* Verify the required arguments in the original call. */
5049 fp
= TREE_VALUE (arglist
);
5050 if (! POINTER_TYPE_P (TREE_TYPE (fp
)))
5052 arglist
= TREE_CHAIN (arglist
);
5055 fmt
= TREE_VALUE (arglist
);
5056 if (! POINTER_TYPE_P (TREE_TYPE (fmt
)))
5058 arglist
= TREE_CHAIN (arglist
);
5060 /* Check whether the format is a literal string constant. */
5061 fmt_str
= c_getstr (fmt
);
5062 if (fmt_str
== NULL
)
5065 if (!init_target_chars())
5068 /* If the format specifier was "%s", call __builtin_fputs(arg,fp). */
5069 if (strcmp (fmt_str
, target_percent_s
) == 0)
5072 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist
)))
5073 || TREE_CHAIN (arglist
))
5075 arg
= TREE_VALUE (arglist
);
5076 arglist
= build_tree_list (NULL_TREE
, fp
);
5077 arglist
= tree_cons (NULL_TREE
, arg
, arglist
);
5080 /* If the format specifier was "%c", call __builtin_fputc(arg,fp). */
5081 else if (strcmp (fmt_str
, target_percent_c
) == 0)
5084 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist
))) != INTEGER_TYPE
5085 || TREE_CHAIN (arglist
))
5087 arg
= TREE_VALUE (arglist
);
5088 arglist
= build_tree_list (NULL_TREE
, fp
);
5089 arglist
= tree_cons (NULL_TREE
, arg
, arglist
);
5094 /* We can't handle anything else with % args or %% ... yet. */
5095 if (strchr (fmt_str
, target_percent
))
5101 /* If the format specifier was "", fprintf does nothing. */
5102 if (fmt_str
[0] == '\0')
5104 /* Evaluate and ignore FILE* argument for side-effects. */
5105 expand_expr (fp
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
5109 /* When "string" doesn't contain %, replace all cases of
5110 fprintf(stream,string) with fputs(string,stream). The fputs
5111 builtin will take care of special cases like length == 1. */
5112 arglist
= build_tree_list (NULL_TREE
, fp
);
5113 arglist
= tree_cons (NULL_TREE
, fmt
, arglist
);
5119 fn
= build_function_call_expr (fn
, arglist
);
5120 if (TREE_CODE (fn
) == CALL_EXPR
)
5121 CALL_EXPR_TAILCALL (fn
) = CALL_EXPR_TAILCALL (exp
);
5122 return expand_expr (fn
, target
, mode
, EXPAND_NORMAL
);
5125 /* Expand a call to sprintf with argument list ARGLIST. Return 0 if
5126 a normal call should be emitted rather than expanding the function
5127 inline. If convenient, the result should be placed in TARGET with
5131 expand_builtin_sprintf (tree arglist
, rtx target
, enum machine_mode mode
)
5133 tree orig_arglist
, dest
, fmt
;
5134 const char *fmt_str
;
5136 orig_arglist
= arglist
;
5138 /* Verify the required arguments in the original call. */
5141 dest
= TREE_VALUE (arglist
);
5142 if (! POINTER_TYPE_P (TREE_TYPE (dest
)))
5144 arglist
= TREE_CHAIN (arglist
);
5147 fmt
= TREE_VALUE (arglist
);
5148 if (! POINTER_TYPE_P (TREE_TYPE (fmt
)))
5150 arglist
= TREE_CHAIN (arglist
);
5152 /* Check whether the format is a literal string constant. */
5153 fmt_str
= c_getstr (fmt
);
5154 if (fmt_str
== NULL
)
5157 if (!init_target_chars())
5160 /* If the format doesn't contain % args or %%, use strcpy. */
5161 if (strchr (fmt_str
, target_percent
) == 0)
5163 tree fn
= implicit_built_in_decls
[BUILT_IN_STRCPY
];
5166 if (arglist
|| ! fn
)
5168 expand_expr (build_function_call_expr (fn
, orig_arglist
),
5169 const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
5170 if (target
== const0_rtx
)
5172 exp
= build_int_cst (NULL_TREE
, strlen (fmt_str
));
5173 return expand_expr (exp
, target
, mode
, EXPAND_NORMAL
);
5175 /* If the format is "%s", use strcpy if the result isn't used. */
5176 else if (strcmp (fmt_str
, target_percent_s
) == 0)
5179 fn
= implicit_built_in_decls
[BUILT_IN_STRCPY
];
5184 if (! arglist
|| TREE_CHAIN (arglist
))
5186 arg
= TREE_VALUE (arglist
);
5187 if (! POINTER_TYPE_P (TREE_TYPE (arg
)))
5190 if (target
!= const0_rtx
)
5192 len
= c_strlen (arg
, 1);
5193 if (! len
|| TREE_CODE (len
) != INTEGER_CST
)
5199 arglist
= build_tree_list (NULL_TREE
, arg
);
5200 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
5201 expand_expr (build_function_call_expr (fn
, arglist
),
5202 const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
5204 if (target
== const0_rtx
)
5206 return expand_expr (len
, target
, mode
, EXPAND_NORMAL
);
5212 /* Expand a call to either the entry or exit function profiler. */
5215 expand_builtin_profile_func (bool exitp
)
5219 this = DECL_RTL (current_function_decl
);
5220 gcc_assert (MEM_P (this));
5221 this = XEXP (this, 0);
5224 which
= profile_function_exit_libfunc
;
5226 which
= profile_function_entry_libfunc
;
5228 emit_library_call (which
, LCT_NORMAL
, VOIDmode
, 2, this, Pmode
,
5229 expand_builtin_return_addr (BUILT_IN_RETURN_ADDRESS
,
5236 /* Given a trampoline address, make sure it satisfies TRAMPOLINE_ALIGNMENT. */
5239 round_trampoline_addr (rtx tramp
)
5241 rtx temp
, addend
, mask
;
5243 /* If we don't need too much alignment, we'll have been guaranteed
5244 proper alignment by get_trampoline_type. */
5245 if (TRAMPOLINE_ALIGNMENT
<= STACK_BOUNDARY
)
5248 /* Round address up to desired boundary. */
5249 temp
= gen_reg_rtx (Pmode
);
5250 addend
= GEN_INT (TRAMPOLINE_ALIGNMENT
/ BITS_PER_UNIT
- 1);
5251 mask
= GEN_INT (-TRAMPOLINE_ALIGNMENT
/ BITS_PER_UNIT
);
5253 temp
= expand_simple_binop (Pmode
, PLUS
, tramp
, addend
,
5254 temp
, 0, OPTAB_LIB_WIDEN
);
5255 tramp
= expand_simple_binop (Pmode
, AND
, temp
, mask
,
5256 temp
, 0, OPTAB_LIB_WIDEN
);
5262 expand_builtin_init_trampoline (tree arglist
)
5264 tree t_tramp
, t_func
, t_chain
;
5265 rtx r_tramp
, r_func
, r_chain
;
5266 #ifdef TRAMPOLINE_TEMPLATE
5270 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
,
5271 POINTER_TYPE
, VOID_TYPE
))
5274 t_tramp
= TREE_VALUE (arglist
);
5275 arglist
= TREE_CHAIN (arglist
);
5276 t_func
= TREE_VALUE (arglist
);
5277 arglist
= TREE_CHAIN (arglist
);
5278 t_chain
= TREE_VALUE (arglist
);
5280 r_tramp
= expand_normal (t_tramp
);
5281 r_func
= expand_normal (t_func
);
5282 r_chain
= expand_normal (t_chain
);
5284 /* Generate insns to initialize the trampoline. */
5285 r_tramp
= round_trampoline_addr (r_tramp
);
5286 #ifdef TRAMPOLINE_TEMPLATE
5287 blktramp
= gen_rtx_MEM (BLKmode
, r_tramp
);
5288 set_mem_align (blktramp
, TRAMPOLINE_ALIGNMENT
);
5289 emit_block_move (blktramp
, assemble_trampoline_template (),
5290 GEN_INT (TRAMPOLINE_SIZE
), BLOCK_OP_NORMAL
);
5292 trampolines_created
= 1;
5293 INITIALIZE_TRAMPOLINE (r_tramp
, r_func
, r_chain
);
5299 expand_builtin_adjust_trampoline (tree arglist
)
5303 if (!validate_arglist (arglist
, POINTER_TYPE
, VOID_TYPE
))
5306 tramp
= expand_normal (TREE_VALUE (arglist
));
5307 tramp
= round_trampoline_addr (tramp
);
5308 #ifdef TRAMPOLINE_ADJUST_ADDRESS
5309 TRAMPOLINE_ADJUST_ADDRESS (tramp
);
5315 /* Expand a call to the built-in signbit, signbitf or signbitl function.
5316 Return NULL_RTX if a normal call should be emitted rather than expanding
5317 the function in-line. EXP is the expression that is a call to the builtin
5318 function; if convenient, the result should be placed in TARGET. */
5321 expand_builtin_signbit (tree exp
, rtx target
)
5323 const struct real_format
*fmt
;
5324 enum machine_mode fmode
, imode
, rmode
;
5325 HOST_WIDE_INT hi
, lo
;
5330 arglist
= TREE_OPERAND (exp
, 1);
5331 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
5334 arg
= TREE_VALUE (arglist
);
5335 fmode
= TYPE_MODE (TREE_TYPE (arg
));
5336 rmode
= TYPE_MODE (TREE_TYPE (exp
));
5337 fmt
= REAL_MODE_FORMAT (fmode
);
5339 /* For floating point formats without a sign bit, implement signbit
5341 bitpos
= fmt
->signbit_ro
;
5344 /* But we can't do this if the format supports signed zero. */
5345 if (fmt
->has_signed_zero
&& HONOR_SIGNED_ZEROS (fmode
))
5348 arg
= fold_build2 (LT_EXPR
, TREE_TYPE (exp
), arg
,
5349 build_real (TREE_TYPE (arg
), dconst0
));
5350 return expand_expr (arg
, target
, VOIDmode
, EXPAND_NORMAL
);
5353 temp
= expand_normal (arg
);
5354 if (GET_MODE_SIZE (fmode
) <= UNITS_PER_WORD
)
5356 imode
= int_mode_for_mode (fmode
);
5357 if (imode
== BLKmode
)
5359 temp
= gen_lowpart (imode
, temp
);
5364 /* Handle targets with different FP word orders. */
5365 if (FLOAT_WORDS_BIG_ENDIAN
)
5366 word
= (GET_MODE_BITSIZE (fmode
) - bitpos
) / BITS_PER_WORD
;
5368 word
= bitpos
/ BITS_PER_WORD
;
5369 temp
= operand_subword_force (temp
, word
, fmode
);
5370 bitpos
= bitpos
% BITS_PER_WORD
;
5373 /* Force the intermediate word_mode (or narrower) result into a
5374 register. This avoids attempting to create paradoxical SUBREGs
5375 of floating point modes below. */
5376 temp
= force_reg (imode
, temp
);
5378 /* If the bitpos is within the "result mode" lowpart, the operation
5379 can be implement with a single bitwise AND. Otherwise, we need
5380 a right shift and an AND. */
5382 if (bitpos
< GET_MODE_BITSIZE (rmode
))
5384 if (bitpos
< HOST_BITS_PER_WIDE_INT
)
5387 lo
= (HOST_WIDE_INT
) 1 << bitpos
;
5391 hi
= (HOST_WIDE_INT
) 1 << (bitpos
- HOST_BITS_PER_WIDE_INT
);
5396 temp
= gen_lowpart (rmode
, temp
);
5397 temp
= expand_binop (rmode
, and_optab
, temp
,
5398 immed_double_const (lo
, hi
, rmode
),
5399 NULL_RTX
, 1, OPTAB_LIB_WIDEN
);
5403 /* Perform a logical right shift to place the signbit in the least
5404 significant bit, then truncate the result to the desired mode
5405 and mask just this bit. */
5406 temp
= expand_shift (RSHIFT_EXPR
, imode
, temp
,
5407 build_int_cst (NULL_TREE
, bitpos
), NULL_RTX
, 1);
5408 temp
= gen_lowpart (rmode
, temp
);
5409 temp
= expand_binop (rmode
, and_optab
, temp
, const1_rtx
,
5410 NULL_RTX
, 1, OPTAB_LIB_WIDEN
);
5416 /* Expand fork or exec calls. TARGET is the desired target of the
5417 call. ARGLIST is the list of arguments of the call. FN is the
5418 identificator of the actual function. IGNORE is nonzero if the
5419 value is to be ignored. */
5422 expand_builtin_fork_or_exec (tree fn
, tree arglist
, rtx target
, int ignore
)
5427 /* If we are not profiling, just call the function. */
5428 if (!profile_arc_flag
)
5431 /* Otherwise call the wrapper. This should be equivalent for the rest of
5432 compiler, so the code does not diverge, and the wrapper may run the
5433 code necessary for keeping the profiling sane. */
5435 switch (DECL_FUNCTION_CODE (fn
))
5438 id
= get_identifier ("__gcov_fork");
5441 case BUILT_IN_EXECL
:
5442 id
= get_identifier ("__gcov_execl");
5445 case BUILT_IN_EXECV
:
5446 id
= get_identifier ("__gcov_execv");
5449 case BUILT_IN_EXECLP
:
5450 id
= get_identifier ("__gcov_execlp");
5453 case BUILT_IN_EXECLE
:
5454 id
= get_identifier ("__gcov_execle");
5457 case BUILT_IN_EXECVP
:
5458 id
= get_identifier ("__gcov_execvp");
5461 case BUILT_IN_EXECVE
:
5462 id
= get_identifier ("__gcov_execve");
5469 decl
= build_decl (FUNCTION_DECL
, id
, TREE_TYPE (fn
));
5470 DECL_EXTERNAL (decl
) = 1;
5471 TREE_PUBLIC (decl
) = 1;
5472 DECL_ARTIFICIAL (decl
) = 1;
5473 TREE_NOTHROW (decl
) = 1;
5474 DECL_VISIBILITY (decl
) = VISIBILITY_DEFAULT
;
5475 DECL_VISIBILITY_SPECIFIED (decl
) = 1;
5476 call
= build_function_call_expr (decl
, arglist
);
5478 return expand_call (call
, target
, ignore
);
5482 /* Reconstitute a mode for a __sync intrinsic operation. Since the type of
5483 the pointer in these functions is void*, the tree optimizers may remove
5484 casts. The mode computed in expand_builtin isn't reliable either, due
5485 to __sync_bool_compare_and_swap.
5487 FCODE_DIFF should be fcode - base, where base is the FOO_1 code for the
5488 group of builtins. This gives us log2 of the mode size. */
5490 static inline enum machine_mode
5491 get_builtin_sync_mode (int fcode_diff
)
5493 /* The size is not negotiable, so ask not to get BLKmode in return
5494 if the target indicates that a smaller size would be better. */
5495 return mode_for_size (BITS_PER_UNIT
<< fcode_diff
, MODE_INT
, 0);
5498 /* Expand the memory expression LOC and return the appropriate memory operand
5499 for the builtin_sync operations. */
5502 get_builtin_sync_mem (tree loc
, enum machine_mode mode
)
5506 addr
= expand_expr (loc
, NULL
, Pmode
, EXPAND_SUM
);
5508 /* Note that we explicitly do not want any alias information for this
5509 memory, so that we kill all other live memories. Otherwise we don't
5510 satisfy the full barrier semantics of the intrinsic. */
5511 mem
= validize_mem (gen_rtx_MEM (mode
, addr
));
5513 set_mem_align (mem
, get_pointer_alignment (loc
, BIGGEST_ALIGNMENT
));
5514 set_mem_alias_set (mem
, ALIAS_SET_MEMORY_BARRIER
);
5515 MEM_VOLATILE_P (mem
) = 1;
5520 /* Expand the __sync_xxx_and_fetch and __sync_fetch_and_xxx intrinsics.
5521 ARGLIST is the operands list to the function. CODE is the rtx code
5522 that corresponds to the arithmetic or logical operation from the name;
5523 an exception here is that NOT actually means NAND. TARGET is an optional
5524 place for us to store the results; AFTER is true if this is the
5525 fetch_and_xxx form. IGNORE is true if we don't actually care about
5526 the result of the operation at all. */
5529 expand_builtin_sync_operation (enum machine_mode mode
, tree arglist
,
5530 enum rtx_code code
, bool after
,
5531 rtx target
, bool ignore
)
5535 /* Expand the operands. */
5536 mem
= get_builtin_sync_mem (TREE_VALUE (arglist
), mode
);
5538 arglist
= TREE_CHAIN (arglist
);
5539 val
= expand_expr (TREE_VALUE (arglist
), NULL
, mode
, EXPAND_NORMAL
);
5540 /* If VAL is promoted to a wider mode, convert it back to MODE. */
5541 val
= convert_to_mode (mode
, val
, 1);
5544 return expand_sync_operation (mem
, val
, code
);
5546 return expand_sync_fetch_operation (mem
, val
, code
, after
, target
);
5549 /* Expand the __sync_val_compare_and_swap and __sync_bool_compare_and_swap
5550 intrinsics. ARGLIST is the operands list to the function. IS_BOOL is
5551 true if this is the boolean form. TARGET is a place for us to store the
5552 results; this is NOT optional if IS_BOOL is true. */
5555 expand_builtin_compare_and_swap (enum machine_mode mode
, tree arglist
,
5556 bool is_bool
, rtx target
)
5558 rtx old_val
, new_val
, mem
;
5560 /* Expand the operands. */
5561 mem
= get_builtin_sync_mem (TREE_VALUE (arglist
), mode
);
5563 arglist
= TREE_CHAIN (arglist
);
5564 old_val
= expand_expr (TREE_VALUE (arglist
), NULL
, mode
, EXPAND_NORMAL
);
5565 /* If OLD_VAL is promoted to a wider mode, convert it back to MODE. */
5566 old_val
= convert_to_mode (mode
, old_val
, 1);
5568 arglist
= TREE_CHAIN (arglist
);
5569 new_val
= expand_expr (TREE_VALUE (arglist
), NULL
, mode
, EXPAND_NORMAL
);
5570 /* If NEW_VAL is promoted to a wider mode, convert it back to MODE. */
5571 new_val
= convert_to_mode (mode
, new_val
, 1);
5574 return expand_bool_compare_and_swap (mem
, old_val
, new_val
, target
);
5576 return expand_val_compare_and_swap (mem
, old_val
, new_val
, target
);
5579 /* Expand the __sync_lock_test_and_set intrinsic. Note that the most
5580 general form is actually an atomic exchange, and some targets only
5581 support a reduced form with the second argument being a constant 1.
5582 ARGLIST is the operands list to the function; TARGET is an optional
5583 place for us to store the results. */
5586 expand_builtin_lock_test_and_set (enum machine_mode mode
, tree arglist
,
5591 /* Expand the operands. */
5592 mem
= get_builtin_sync_mem (TREE_VALUE (arglist
), mode
);
5594 arglist
= TREE_CHAIN (arglist
);
5595 val
= expand_expr (TREE_VALUE (arglist
), NULL
, mode
, EXPAND_NORMAL
);
5596 /* If VAL is promoted to a wider mode, convert it back to MODE. */
5597 val
= convert_to_mode (mode
, val
, 1);
5599 return expand_sync_lock_test_and_set (mem
, val
, target
);
5602 /* Expand the __sync_synchronize intrinsic. */
5605 expand_builtin_synchronize (void)
5609 #ifdef HAVE_memory_barrier
5610 if (HAVE_memory_barrier
)
5612 emit_insn (gen_memory_barrier ());
5617 /* If no explicit memory barrier instruction is available, create an
5618 empty asm stmt with a memory clobber. */
5619 x
= build4 (ASM_EXPR
, void_type_node
, build_string (0, ""), NULL
, NULL
,
5620 tree_cons (NULL
, build_string (6, "memory"), NULL
));
5621 ASM_VOLATILE_P (x
) = 1;
5622 expand_asm_expr (x
);
5625 /* Expand the __sync_lock_release intrinsic. ARGLIST is the operands list
5629 expand_builtin_lock_release (enum machine_mode mode
, tree arglist
)
5631 enum insn_code icode
;
5633 rtx val
= const0_rtx
;
5635 /* Expand the operands. */
5636 mem
= get_builtin_sync_mem (TREE_VALUE (arglist
), mode
);
5638 /* If there is an explicit operation in the md file, use it. */
5639 icode
= sync_lock_release
[mode
];
5640 if (icode
!= CODE_FOR_nothing
)
5642 if (!insn_data
[icode
].operand
[1].predicate (val
, mode
))
5643 val
= force_reg (mode
, val
);
5645 insn
= GEN_FCN (icode
) (mem
, val
);
5653 /* Otherwise we can implement this operation by emitting a barrier
5654 followed by a store of zero. */
5655 expand_builtin_synchronize ();
5656 emit_move_insn (mem
, val
);
5659 /* Expand an expression EXP that calls a built-in function,
5660 with result going to TARGET if that's convenient
5661 (and in mode MODE if that's convenient).
5662 SUBTARGET may be used as the target for computing one of EXP's operands.
5663 IGNORE is nonzero if the value is to be ignored. */
5666 expand_builtin (tree exp
, rtx target
, rtx subtarget
, enum machine_mode mode
,
5669 tree fndecl
= get_callee_fndecl (exp
);
5670 tree arglist
= TREE_OPERAND (exp
, 1);
5671 enum built_in_function fcode
= DECL_FUNCTION_CODE (fndecl
);
5672 enum machine_mode target_mode
= TYPE_MODE (TREE_TYPE (exp
));
5674 if (DECL_BUILT_IN_CLASS (fndecl
) == BUILT_IN_MD
)
5675 return targetm
.expand_builtin (exp
, target
, subtarget
, mode
, ignore
);
5677 /* When not optimizing, generate calls to library functions for a certain
5680 && !called_as_built_in (fndecl
)
5681 && DECL_ASSEMBLER_NAME_SET_P (fndecl
)
5682 && fcode
!= BUILT_IN_ALLOCA
)
5683 return expand_call (exp
, target
, ignore
);
5685 /* The built-in function expanders test for target == const0_rtx
5686 to determine whether the function's result will be ignored. */
5688 target
= const0_rtx
;
5690 /* If the result of a pure or const built-in function is ignored, and
5691 none of its arguments are volatile, we can avoid expanding the
5692 built-in call and just evaluate the arguments for side-effects. */
5693 if (target
== const0_rtx
5694 && (DECL_IS_PURE (fndecl
) || TREE_READONLY (fndecl
)))
5696 bool volatilep
= false;
5699 for (arg
= arglist
; arg
; arg
= TREE_CHAIN (arg
))
5700 if (TREE_THIS_VOLATILE (TREE_VALUE (arg
)))
5708 for (arg
= arglist
; arg
; arg
= TREE_CHAIN (arg
))
5709 expand_expr (TREE_VALUE (arg
), const0_rtx
,
5710 VOIDmode
, EXPAND_NORMAL
);
5717 CASE_FLT_FN (BUILT_IN_FABS
):
5718 target
= expand_builtin_fabs (arglist
, target
, subtarget
);
5723 CASE_FLT_FN (BUILT_IN_COPYSIGN
):
5724 target
= expand_builtin_copysign (arglist
, target
, subtarget
);
5729 /* Just do a normal library call if we were unable to fold
5731 CASE_FLT_FN (BUILT_IN_CABS
):
5734 CASE_FLT_FN (BUILT_IN_EXP
):
5735 CASE_FLT_FN (BUILT_IN_EXP10
):
5736 CASE_FLT_FN (BUILT_IN_POW10
):
5737 CASE_FLT_FN (BUILT_IN_EXP2
):
5738 CASE_FLT_FN (BUILT_IN_EXPM1
):
5739 CASE_FLT_FN (BUILT_IN_LOGB
):
5740 CASE_FLT_FN (BUILT_IN_ILOGB
):
5741 CASE_FLT_FN (BUILT_IN_LOG
):
5742 CASE_FLT_FN (BUILT_IN_LOG10
):
5743 CASE_FLT_FN (BUILT_IN_LOG2
):
5744 CASE_FLT_FN (BUILT_IN_LOG1P
):
5745 CASE_FLT_FN (BUILT_IN_TAN
):
5746 CASE_FLT_FN (BUILT_IN_ASIN
):
5747 CASE_FLT_FN (BUILT_IN_ACOS
):
5748 CASE_FLT_FN (BUILT_IN_ATAN
):
5749 /* Treat these like sqrt only if unsafe math optimizations are allowed,
5750 because of possible accuracy problems. */
5751 if (! flag_unsafe_math_optimizations
)
5753 CASE_FLT_FN (BUILT_IN_SQRT
):
5754 CASE_FLT_FN (BUILT_IN_FLOOR
):
5755 CASE_FLT_FN (BUILT_IN_CEIL
):
5756 CASE_FLT_FN (BUILT_IN_TRUNC
):
5757 CASE_FLT_FN (BUILT_IN_ROUND
):
5758 CASE_FLT_FN (BUILT_IN_NEARBYINT
):
5759 CASE_FLT_FN (BUILT_IN_RINT
):
5760 target
= expand_builtin_mathfn (exp
, target
, subtarget
);
5765 CASE_FLT_FN (BUILT_IN_LCEIL
):
5766 CASE_FLT_FN (BUILT_IN_LLCEIL
):
5767 CASE_FLT_FN (BUILT_IN_LFLOOR
):
5768 CASE_FLT_FN (BUILT_IN_LLFLOOR
):
5769 target
= expand_builtin_int_roundingfn (exp
, target
, subtarget
);
5774 CASE_FLT_FN (BUILT_IN_LRINT
):
5775 CASE_FLT_FN (BUILT_IN_LLRINT
):
5776 CASE_FLT_FN (BUILT_IN_LROUND
):
5777 CASE_FLT_FN (BUILT_IN_LLROUND
):
5778 target
= expand_builtin_int_roundingfn_2 (exp
, target
, subtarget
);
5783 CASE_FLT_FN (BUILT_IN_POW
):
5784 target
= expand_builtin_pow (exp
, target
, subtarget
);
5789 CASE_FLT_FN (BUILT_IN_POWI
):
5790 target
= expand_builtin_powi (exp
, target
, subtarget
);
5795 CASE_FLT_FN (BUILT_IN_ATAN2
):
5796 CASE_FLT_FN (BUILT_IN_LDEXP
):
5797 if (! flag_unsafe_math_optimizations
)
5800 CASE_FLT_FN (BUILT_IN_FMOD
):
5801 CASE_FLT_FN (BUILT_IN_REMAINDER
):
5802 CASE_FLT_FN (BUILT_IN_DREM
):
5803 target
= expand_builtin_mathfn_2 (exp
, target
, subtarget
);
5808 CASE_FLT_FN (BUILT_IN_SIN
):
5809 CASE_FLT_FN (BUILT_IN_COS
):
5810 if (! flag_unsafe_math_optimizations
)
5812 target
= expand_builtin_mathfn_3 (exp
, target
, subtarget
);
5817 CASE_FLT_FN (BUILT_IN_SINCOS
):
5818 if (! flag_unsafe_math_optimizations
)
5820 target
= expand_builtin_sincos (exp
);
5825 case BUILT_IN_APPLY_ARGS
:
5826 return expand_builtin_apply_args ();
5828 /* __builtin_apply (FUNCTION, ARGUMENTS, ARGSIZE) invokes
5829 FUNCTION with a copy of the parameters described by
5830 ARGUMENTS, and ARGSIZE. It returns a block of memory
5831 allocated on the stack into which is stored all the registers
5832 that might possibly be used for returning the result of a
5833 function. ARGUMENTS is the value returned by
5834 __builtin_apply_args. ARGSIZE is the number of bytes of
5835 arguments that must be copied. ??? How should this value be
5836 computed? We'll also need a safe worst case value for varargs
5838 case BUILT_IN_APPLY
:
5839 if (!validate_arglist (arglist
, POINTER_TYPE
,
5840 POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
)
5841 && !validate_arglist (arglist
, REFERENCE_TYPE
,
5842 POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
5850 for (t
= arglist
, i
= 0; t
; t
= TREE_CHAIN (t
), i
++)
5851 ops
[i
] = expand_normal (TREE_VALUE (t
));
5853 return expand_builtin_apply (ops
[0], ops
[1], ops
[2]);
5856 /* __builtin_return (RESULT) causes the function to return the
5857 value described by RESULT. RESULT is address of the block of
5858 memory returned by __builtin_apply. */
5859 case BUILT_IN_RETURN
:
5860 if (validate_arglist (arglist
, POINTER_TYPE
, VOID_TYPE
))
5861 expand_builtin_return (expand_normal (TREE_VALUE (arglist
)));
5864 case BUILT_IN_SAVEREGS
:
5865 return expand_builtin_saveregs ();
5867 case BUILT_IN_ARGS_INFO
:
5868 return expand_builtin_args_info (arglist
);
5870 /* Return the address of the first anonymous stack arg. */
5871 case BUILT_IN_NEXT_ARG
:
5872 if (fold_builtin_next_arg (arglist
))
5874 return expand_builtin_next_arg ();
5876 case BUILT_IN_CLASSIFY_TYPE
:
5877 return expand_builtin_classify_type (arglist
);
5879 case BUILT_IN_CONSTANT_P
:
5882 case BUILT_IN_FRAME_ADDRESS
:
5883 case BUILT_IN_RETURN_ADDRESS
:
5884 return expand_builtin_frame_address (fndecl
, arglist
);
5886 /* Returns the address of the area where the structure is returned.
5888 case BUILT_IN_AGGREGATE_INCOMING_ADDRESS
:
5890 || ! AGGREGATE_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl
)))
5891 || !MEM_P (DECL_RTL (DECL_RESULT (current_function_decl
))))
5894 return XEXP (DECL_RTL (DECL_RESULT (current_function_decl
)), 0);
5896 case BUILT_IN_ALLOCA
:
5897 target
= expand_builtin_alloca (arglist
, target
);
5902 case BUILT_IN_STACK_SAVE
:
5903 return expand_stack_save ();
5905 case BUILT_IN_STACK_RESTORE
:
5906 expand_stack_restore (TREE_VALUE (arglist
));
5909 CASE_INT_FN (BUILT_IN_FFS
):
5910 case BUILT_IN_FFSIMAX
:
5911 target
= expand_builtin_unop (target_mode
, arglist
, target
,
5912 subtarget
, ffs_optab
);
5917 CASE_INT_FN (BUILT_IN_CLZ
):
5918 case BUILT_IN_CLZIMAX
:
5919 target
= expand_builtin_unop (target_mode
, arglist
, target
,
5920 subtarget
, clz_optab
);
5925 CASE_INT_FN (BUILT_IN_CTZ
):
5926 case BUILT_IN_CTZIMAX
:
5927 target
= expand_builtin_unop (target_mode
, arglist
, target
,
5928 subtarget
, ctz_optab
);
5933 CASE_INT_FN (BUILT_IN_POPCOUNT
):
5934 case BUILT_IN_POPCOUNTIMAX
:
5935 target
= expand_builtin_unop (target_mode
, arglist
, target
,
5936 subtarget
, popcount_optab
);
5941 CASE_INT_FN (BUILT_IN_PARITY
):
5942 case BUILT_IN_PARITYIMAX
:
5943 target
= expand_builtin_unop (target_mode
, arglist
, target
,
5944 subtarget
, parity_optab
);
5949 case BUILT_IN_STRLEN
:
5950 target
= expand_builtin_strlen (arglist
, target
, target_mode
);
5955 case BUILT_IN_STRCPY
:
5956 target
= expand_builtin_strcpy (fndecl
, arglist
, target
, mode
);
5961 case BUILT_IN_STRNCPY
:
5962 target
= expand_builtin_strncpy (exp
, target
, mode
);
5967 case BUILT_IN_STPCPY
:
5968 target
= expand_builtin_stpcpy (exp
, target
, mode
);
5973 case BUILT_IN_STRCAT
:
5974 target
= expand_builtin_strcat (fndecl
, arglist
, target
, mode
);
5979 case BUILT_IN_STRNCAT
:
5980 target
= expand_builtin_strncat (arglist
, target
, mode
);
5985 case BUILT_IN_STRSPN
:
5986 target
= expand_builtin_strspn (arglist
, target
, mode
);
5991 case BUILT_IN_STRCSPN
:
5992 target
= expand_builtin_strcspn (arglist
, target
, mode
);
5997 case BUILT_IN_STRSTR
:
5998 target
= expand_builtin_strstr (arglist
, TREE_TYPE (exp
), target
, mode
);
6003 case BUILT_IN_STRPBRK
:
6004 target
= expand_builtin_strpbrk (arglist
, TREE_TYPE (exp
), target
, mode
);
6009 case BUILT_IN_INDEX
:
6010 case BUILT_IN_STRCHR
:
6011 target
= expand_builtin_strchr (arglist
, TREE_TYPE (exp
), target
, mode
);
6016 case BUILT_IN_RINDEX
:
6017 case BUILT_IN_STRRCHR
:
6018 target
= expand_builtin_strrchr (arglist
, TREE_TYPE (exp
), target
, mode
);
6023 case BUILT_IN_MEMCPY
:
6024 target
= expand_builtin_memcpy (exp
, target
, mode
);
6029 case BUILT_IN_MEMPCPY
:
6030 target
= expand_builtin_mempcpy (arglist
, TREE_TYPE (exp
), target
, mode
, /*endp=*/ 1);
6035 case BUILT_IN_MEMMOVE
:
6036 target
= expand_builtin_memmove (arglist
, TREE_TYPE (exp
), target
,
6042 case BUILT_IN_BCOPY
:
6043 target
= expand_builtin_bcopy (exp
);
6048 case BUILT_IN_MEMSET
:
6049 target
= expand_builtin_memset (arglist
, target
, mode
, exp
);
6054 case BUILT_IN_BZERO
:
6055 target
= expand_builtin_bzero (exp
);
6060 case BUILT_IN_STRCMP
:
6061 target
= expand_builtin_strcmp (exp
, target
, mode
);
6066 case BUILT_IN_STRNCMP
:
6067 target
= expand_builtin_strncmp (exp
, target
, mode
);
6073 case BUILT_IN_MEMCMP
:
6074 target
= expand_builtin_memcmp (exp
, arglist
, target
, mode
);
6079 case BUILT_IN_SETJMP
:
6080 /* This should have been lowered to the builtins below. */
6083 case BUILT_IN_SETJMP_SETUP
:
6084 /* __builtin_setjmp_setup is passed a pointer to an array of five words
6085 and the receiver label. */
6086 if (validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
6088 rtx buf_addr
= expand_expr (TREE_VALUE (arglist
), subtarget
,
6089 VOIDmode
, EXPAND_NORMAL
);
6090 tree label
= TREE_OPERAND (TREE_VALUE (TREE_CHAIN (arglist
)), 0);
6091 rtx label_r
= label_rtx (label
);
6093 /* This is copied from the handling of non-local gotos. */
6094 expand_builtin_setjmp_setup (buf_addr
, label_r
);
6095 nonlocal_goto_handler_labels
6096 = gen_rtx_EXPR_LIST (VOIDmode
, label_r
,
6097 nonlocal_goto_handler_labels
);
6098 /* ??? Do not let expand_label treat us as such since we would
6099 not want to be both on the list of non-local labels and on
6100 the list of forced labels. */
6101 FORCED_LABEL (label
) = 0;
6106 case BUILT_IN_SETJMP_DISPATCHER
:
6107 /* __builtin_setjmp_dispatcher is passed the dispatcher label. */
6108 if (validate_arglist (arglist
, POINTER_TYPE
, VOID_TYPE
))
6110 tree label
= TREE_OPERAND (TREE_VALUE (arglist
), 0);
6111 rtx label_r
= label_rtx (label
);
6113 /* Remove the dispatcher label from the list of non-local labels
6114 since the receiver labels have been added to it above. */
6115 remove_node_from_expr_list (label_r
, &nonlocal_goto_handler_labels
);
6120 case BUILT_IN_SETJMP_RECEIVER
:
6121 /* __builtin_setjmp_receiver is passed the receiver label. */
6122 if (validate_arglist (arglist
, POINTER_TYPE
, VOID_TYPE
))
6124 tree label
= TREE_OPERAND (TREE_VALUE (arglist
), 0);
6125 rtx label_r
= label_rtx (label
);
6127 expand_builtin_setjmp_receiver (label_r
);
6132 /* __builtin_longjmp is passed a pointer to an array of five words.
6133 It's similar to the C library longjmp function but works with
6134 __builtin_setjmp above. */
6135 case BUILT_IN_LONGJMP
:
6136 if (validate_arglist (arglist
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
6138 rtx buf_addr
= expand_expr (TREE_VALUE (arglist
), subtarget
,
6139 VOIDmode
, EXPAND_NORMAL
);
6140 rtx value
= expand_normal (TREE_VALUE (TREE_CHAIN (arglist
)));
6142 if (value
!= const1_rtx
)
6144 error ("%<__builtin_longjmp%> second argument must be 1");
6148 expand_builtin_longjmp (buf_addr
, value
);
6153 case BUILT_IN_NONLOCAL_GOTO
:
6154 target
= expand_builtin_nonlocal_goto (arglist
);
6159 /* This updates the setjmp buffer that is its argument with the value
6160 of the current stack pointer. */
6161 case BUILT_IN_UPDATE_SETJMP_BUF
:
6162 if (validate_arglist (arglist
, POINTER_TYPE
, VOID_TYPE
))
6165 = expand_normal (TREE_VALUE (arglist
));
6167 expand_builtin_update_setjmp_buf (buf_addr
);
6173 expand_builtin_trap ();
6176 case BUILT_IN_PRINTF
:
6177 target
= expand_builtin_printf (exp
, target
, mode
, false);
6182 case BUILT_IN_PRINTF_UNLOCKED
:
6183 target
= expand_builtin_printf (exp
, target
, mode
, true);
6188 case BUILT_IN_FPUTS
:
6189 target
= expand_builtin_fputs (arglist
, target
, false);
6193 case BUILT_IN_FPUTS_UNLOCKED
:
6194 target
= expand_builtin_fputs (arglist
, target
, true);
6199 case BUILT_IN_FPRINTF
:
6200 target
= expand_builtin_fprintf (exp
, target
, mode
, false);
6205 case BUILT_IN_FPRINTF_UNLOCKED
:
6206 target
= expand_builtin_fprintf (exp
, target
, mode
, true);
6211 case BUILT_IN_SPRINTF
:
6212 target
= expand_builtin_sprintf (arglist
, target
, mode
);
6217 CASE_FLT_FN (BUILT_IN_SIGNBIT
):
6218 target
= expand_builtin_signbit (exp
, target
);
6223 /* Various hooks for the DWARF 2 __throw routine. */
6224 case BUILT_IN_UNWIND_INIT
:
6225 expand_builtin_unwind_init ();
6227 case BUILT_IN_DWARF_CFA
:
6228 return virtual_cfa_rtx
;
6229 #ifdef DWARF2_UNWIND_INFO
6230 case BUILT_IN_DWARF_SP_COLUMN
:
6231 return expand_builtin_dwarf_sp_column ();
6232 case BUILT_IN_INIT_DWARF_REG_SIZES
:
6233 expand_builtin_init_dwarf_reg_sizes (TREE_VALUE (arglist
));
6236 case BUILT_IN_FROB_RETURN_ADDR
:
6237 return expand_builtin_frob_return_addr (TREE_VALUE (arglist
));
6238 case BUILT_IN_EXTRACT_RETURN_ADDR
:
6239 return expand_builtin_extract_return_addr (TREE_VALUE (arglist
));
6240 case BUILT_IN_EH_RETURN
:
6241 expand_builtin_eh_return (TREE_VALUE (arglist
),
6242 TREE_VALUE (TREE_CHAIN (arglist
)));
6244 #ifdef EH_RETURN_DATA_REGNO
6245 case BUILT_IN_EH_RETURN_DATA_REGNO
:
6246 return expand_builtin_eh_return_data_regno (arglist
);
6248 case BUILT_IN_EXTEND_POINTER
:
6249 return expand_builtin_extend_pointer (TREE_VALUE (arglist
));
6251 case BUILT_IN_VA_START
:
6252 case BUILT_IN_STDARG_START
:
6253 return expand_builtin_va_start (arglist
);
6254 case BUILT_IN_VA_END
:
6255 return expand_builtin_va_end (arglist
);
6256 case BUILT_IN_VA_COPY
:
6257 return expand_builtin_va_copy (arglist
);
6258 case BUILT_IN_EXPECT
:
6259 return expand_builtin_expect (arglist
, target
);
6260 case BUILT_IN_PREFETCH
:
6261 expand_builtin_prefetch (arglist
);
6264 case BUILT_IN_PROFILE_FUNC_ENTER
:
6265 return expand_builtin_profile_func (false);
6266 case BUILT_IN_PROFILE_FUNC_EXIT
:
6267 return expand_builtin_profile_func (true);
6269 case BUILT_IN_INIT_TRAMPOLINE
:
6270 return expand_builtin_init_trampoline (arglist
);
6271 case BUILT_IN_ADJUST_TRAMPOLINE
:
6272 return expand_builtin_adjust_trampoline (arglist
);
6275 case BUILT_IN_EXECL
:
6276 case BUILT_IN_EXECV
:
6277 case BUILT_IN_EXECLP
:
6278 case BUILT_IN_EXECLE
:
6279 case BUILT_IN_EXECVP
:
6280 case BUILT_IN_EXECVE
:
6281 target
= expand_builtin_fork_or_exec (fndecl
, arglist
, target
, ignore
);
6286 case BUILT_IN_FETCH_AND_ADD_1
:
6287 case BUILT_IN_FETCH_AND_ADD_2
:
6288 case BUILT_IN_FETCH_AND_ADD_4
:
6289 case BUILT_IN_FETCH_AND_ADD_8
:
6290 case BUILT_IN_FETCH_AND_ADD_16
:
6291 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_FETCH_AND_ADD_1
);
6292 target
= expand_builtin_sync_operation (mode
, arglist
, PLUS
,
6293 false, target
, ignore
);
6298 case BUILT_IN_FETCH_AND_SUB_1
:
6299 case BUILT_IN_FETCH_AND_SUB_2
:
6300 case BUILT_IN_FETCH_AND_SUB_4
:
6301 case BUILT_IN_FETCH_AND_SUB_8
:
6302 case BUILT_IN_FETCH_AND_SUB_16
:
6303 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_FETCH_AND_SUB_1
);
6304 target
= expand_builtin_sync_operation (mode
, arglist
, MINUS
,
6305 false, target
, ignore
);
6310 case BUILT_IN_FETCH_AND_OR_1
:
6311 case BUILT_IN_FETCH_AND_OR_2
:
6312 case BUILT_IN_FETCH_AND_OR_4
:
6313 case BUILT_IN_FETCH_AND_OR_8
:
6314 case BUILT_IN_FETCH_AND_OR_16
:
6315 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_FETCH_AND_OR_1
);
6316 target
= expand_builtin_sync_operation (mode
, arglist
, IOR
,
6317 false, target
, ignore
);
6322 case BUILT_IN_FETCH_AND_AND_1
:
6323 case BUILT_IN_FETCH_AND_AND_2
:
6324 case BUILT_IN_FETCH_AND_AND_4
:
6325 case BUILT_IN_FETCH_AND_AND_8
:
6326 case BUILT_IN_FETCH_AND_AND_16
:
6327 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_FETCH_AND_AND_1
);
6328 target
= expand_builtin_sync_operation (mode
, arglist
, AND
,
6329 false, target
, ignore
);
6334 case BUILT_IN_FETCH_AND_XOR_1
:
6335 case BUILT_IN_FETCH_AND_XOR_2
:
6336 case BUILT_IN_FETCH_AND_XOR_4
:
6337 case BUILT_IN_FETCH_AND_XOR_8
:
6338 case BUILT_IN_FETCH_AND_XOR_16
:
6339 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_FETCH_AND_XOR_1
);
6340 target
= expand_builtin_sync_operation (mode
, arglist
, XOR
,
6341 false, target
, ignore
);
6346 case BUILT_IN_FETCH_AND_NAND_1
:
6347 case BUILT_IN_FETCH_AND_NAND_2
:
6348 case BUILT_IN_FETCH_AND_NAND_4
:
6349 case BUILT_IN_FETCH_AND_NAND_8
:
6350 case BUILT_IN_FETCH_AND_NAND_16
:
6351 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_FETCH_AND_NAND_1
);
6352 target
= expand_builtin_sync_operation (mode
, arglist
, NOT
,
6353 false, target
, ignore
);
6358 case BUILT_IN_ADD_AND_FETCH_1
:
6359 case BUILT_IN_ADD_AND_FETCH_2
:
6360 case BUILT_IN_ADD_AND_FETCH_4
:
6361 case BUILT_IN_ADD_AND_FETCH_8
:
6362 case BUILT_IN_ADD_AND_FETCH_16
:
6363 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_ADD_AND_FETCH_1
);
6364 target
= expand_builtin_sync_operation (mode
, arglist
, PLUS
,
6365 true, target
, ignore
);
6370 case BUILT_IN_SUB_AND_FETCH_1
:
6371 case BUILT_IN_SUB_AND_FETCH_2
:
6372 case BUILT_IN_SUB_AND_FETCH_4
:
6373 case BUILT_IN_SUB_AND_FETCH_8
:
6374 case BUILT_IN_SUB_AND_FETCH_16
:
6375 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_SUB_AND_FETCH_1
);
6376 target
= expand_builtin_sync_operation (mode
, arglist
, MINUS
,
6377 true, target
, ignore
);
6382 case BUILT_IN_OR_AND_FETCH_1
:
6383 case BUILT_IN_OR_AND_FETCH_2
:
6384 case BUILT_IN_OR_AND_FETCH_4
:
6385 case BUILT_IN_OR_AND_FETCH_8
:
6386 case BUILT_IN_OR_AND_FETCH_16
:
6387 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_OR_AND_FETCH_1
);
6388 target
= expand_builtin_sync_operation (mode
, arglist
, IOR
,
6389 true, target
, ignore
);
6394 case BUILT_IN_AND_AND_FETCH_1
:
6395 case BUILT_IN_AND_AND_FETCH_2
:
6396 case BUILT_IN_AND_AND_FETCH_4
:
6397 case BUILT_IN_AND_AND_FETCH_8
:
6398 case BUILT_IN_AND_AND_FETCH_16
:
6399 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_AND_AND_FETCH_1
);
6400 target
= expand_builtin_sync_operation (mode
, arglist
, AND
,
6401 true, target
, ignore
);
6406 case BUILT_IN_XOR_AND_FETCH_1
:
6407 case BUILT_IN_XOR_AND_FETCH_2
:
6408 case BUILT_IN_XOR_AND_FETCH_4
:
6409 case BUILT_IN_XOR_AND_FETCH_8
:
6410 case BUILT_IN_XOR_AND_FETCH_16
:
6411 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_XOR_AND_FETCH_1
);
6412 target
= expand_builtin_sync_operation (mode
, arglist
, XOR
,
6413 true, target
, ignore
);
6418 case BUILT_IN_NAND_AND_FETCH_1
:
6419 case BUILT_IN_NAND_AND_FETCH_2
:
6420 case BUILT_IN_NAND_AND_FETCH_4
:
6421 case BUILT_IN_NAND_AND_FETCH_8
:
6422 case BUILT_IN_NAND_AND_FETCH_16
:
6423 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_NAND_AND_FETCH_1
);
6424 target
= expand_builtin_sync_operation (mode
, arglist
, NOT
,
6425 true, target
, ignore
);
6430 case BUILT_IN_BOOL_COMPARE_AND_SWAP_1
:
6431 case BUILT_IN_BOOL_COMPARE_AND_SWAP_2
:
6432 case BUILT_IN_BOOL_COMPARE_AND_SWAP_4
:
6433 case BUILT_IN_BOOL_COMPARE_AND_SWAP_8
:
6434 case BUILT_IN_BOOL_COMPARE_AND_SWAP_16
:
6435 if (mode
== VOIDmode
)
6436 mode
= TYPE_MODE (boolean_type_node
);
6437 if (!target
|| !register_operand (target
, mode
))
6438 target
= gen_reg_rtx (mode
);
6440 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_BOOL_COMPARE_AND_SWAP_1
);
6441 target
= expand_builtin_compare_and_swap (mode
, arglist
, true, target
);
6446 case BUILT_IN_VAL_COMPARE_AND_SWAP_1
:
6447 case BUILT_IN_VAL_COMPARE_AND_SWAP_2
:
6448 case BUILT_IN_VAL_COMPARE_AND_SWAP_4
:
6449 case BUILT_IN_VAL_COMPARE_AND_SWAP_8
:
6450 case BUILT_IN_VAL_COMPARE_AND_SWAP_16
:
6451 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_VAL_COMPARE_AND_SWAP_1
);
6452 target
= expand_builtin_compare_and_swap (mode
, arglist
, false, target
);
6457 case BUILT_IN_LOCK_TEST_AND_SET_1
:
6458 case BUILT_IN_LOCK_TEST_AND_SET_2
:
6459 case BUILT_IN_LOCK_TEST_AND_SET_4
:
6460 case BUILT_IN_LOCK_TEST_AND_SET_8
:
6461 case BUILT_IN_LOCK_TEST_AND_SET_16
:
6462 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_LOCK_TEST_AND_SET_1
);
6463 target
= expand_builtin_lock_test_and_set (mode
, arglist
, target
);
6468 case BUILT_IN_LOCK_RELEASE_1
:
6469 case BUILT_IN_LOCK_RELEASE_2
:
6470 case BUILT_IN_LOCK_RELEASE_4
:
6471 case BUILT_IN_LOCK_RELEASE_8
:
6472 case BUILT_IN_LOCK_RELEASE_16
:
6473 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_LOCK_RELEASE_1
);
6474 expand_builtin_lock_release (mode
, arglist
);
6477 case BUILT_IN_SYNCHRONIZE
:
6478 expand_builtin_synchronize ();
6481 case BUILT_IN_OBJECT_SIZE
:
6482 return expand_builtin_object_size (exp
);
6484 case BUILT_IN_MEMCPY_CHK
:
6485 case BUILT_IN_MEMPCPY_CHK
:
6486 case BUILT_IN_MEMMOVE_CHK
:
6487 case BUILT_IN_MEMSET_CHK
:
6488 target
= expand_builtin_memory_chk (exp
, target
, mode
, fcode
);
6493 case BUILT_IN_STRCPY_CHK
:
6494 case BUILT_IN_STPCPY_CHK
:
6495 case BUILT_IN_STRNCPY_CHK
:
6496 case BUILT_IN_STRCAT_CHK
:
6497 case BUILT_IN_STRNCAT_CHK
:
6498 case BUILT_IN_SNPRINTF_CHK
:
6499 case BUILT_IN_VSNPRINTF_CHK
:
6500 maybe_emit_chk_warning (exp
, fcode
);
6503 case BUILT_IN_SPRINTF_CHK
:
6504 case BUILT_IN_VSPRINTF_CHK
:
6505 maybe_emit_sprintf_chk_warning (exp
, fcode
);
6508 default: /* just do library call, if unknown builtin */
6512 /* The switch statement above can drop through to cause the function
6513 to be called normally. */
6514 return expand_call (exp
, target
, ignore
);
6517 /* Determine whether a tree node represents a call to a built-in
6518 function. If the tree T is a call to a built-in function with
6519 the right number of arguments of the appropriate types, return
6520 the DECL_FUNCTION_CODE of the call, e.g. BUILT_IN_SQRT.
6521 Otherwise the return value is END_BUILTINS. */
6523 enum built_in_function
6524 builtin_mathfn_code (tree t
)
6526 tree fndecl
, arglist
, parmlist
;
6527 tree argtype
, parmtype
;
6529 if (TREE_CODE (t
) != CALL_EXPR
6530 || TREE_CODE (TREE_OPERAND (t
, 0)) != ADDR_EXPR
)
6531 return END_BUILTINS
;
6533 fndecl
= get_callee_fndecl (t
);
6534 if (fndecl
== NULL_TREE
6535 || TREE_CODE (fndecl
) != FUNCTION_DECL
6536 || ! DECL_BUILT_IN (fndecl
)
6537 || DECL_BUILT_IN_CLASS (fndecl
) == BUILT_IN_MD
)
6538 return END_BUILTINS
;
6540 arglist
= TREE_OPERAND (t
, 1);
6541 parmlist
= TYPE_ARG_TYPES (TREE_TYPE (fndecl
));
6542 for (; parmlist
; parmlist
= TREE_CHAIN (parmlist
))
6544 /* If a function doesn't take a variable number of arguments,
6545 the last element in the list will have type `void'. */
6546 parmtype
= TREE_VALUE (parmlist
);
6547 if (VOID_TYPE_P (parmtype
))
6550 return END_BUILTINS
;
6551 return DECL_FUNCTION_CODE (fndecl
);
6555 return END_BUILTINS
;
6557 argtype
= TREE_TYPE (TREE_VALUE (arglist
));
6559 if (SCALAR_FLOAT_TYPE_P (parmtype
))
6561 if (! SCALAR_FLOAT_TYPE_P (argtype
))
6562 return END_BUILTINS
;
6564 else if (COMPLEX_FLOAT_TYPE_P (parmtype
))
6566 if (! COMPLEX_FLOAT_TYPE_P (argtype
))
6567 return END_BUILTINS
;
6569 else if (POINTER_TYPE_P (parmtype
))
6571 if (! POINTER_TYPE_P (argtype
))
6572 return END_BUILTINS
;
6574 else if (INTEGRAL_TYPE_P (parmtype
))
6576 if (! INTEGRAL_TYPE_P (argtype
))
6577 return END_BUILTINS
;
6580 return END_BUILTINS
;
6582 arglist
= TREE_CHAIN (arglist
);
6585 /* Variable-length argument list. */
6586 return DECL_FUNCTION_CODE (fndecl
);
6589 /* Fold a call to __builtin_constant_p, if we know it will evaluate to a
6590 constant. ARGLIST is the argument list of the call. */
6593 fold_builtin_constant_p (tree arglist
)
6598 arglist
= TREE_VALUE (arglist
);
6600 /* We return 1 for a numeric type that's known to be a constant
6601 value at compile-time or for an aggregate type that's a
6602 literal constant. */
6603 STRIP_NOPS (arglist
);
6605 /* If we know this is a constant, emit the constant of one. */
6606 if (CONSTANT_CLASS_P (arglist
)
6607 || (TREE_CODE (arglist
) == CONSTRUCTOR
6608 && TREE_CONSTANT (arglist
)))
6609 return integer_one_node
;
6610 if (TREE_CODE (arglist
) == ADDR_EXPR
)
6612 tree op
= TREE_OPERAND (arglist
, 0);
6613 if (TREE_CODE (op
) == STRING_CST
6614 || (TREE_CODE (op
) == ARRAY_REF
6615 && integer_zerop (TREE_OPERAND (op
, 1))
6616 && TREE_CODE (TREE_OPERAND (op
, 0)) == STRING_CST
))
6617 return integer_one_node
;
6620 /* If this expression has side effects, show we don't know it to be a
6621 constant. Likewise if it's a pointer or aggregate type since in
6622 those case we only want literals, since those are only optimized
6623 when generating RTL, not later.
6624 And finally, if we are compiling an initializer, not code, we
6625 need to return a definite result now; there's not going to be any
6626 more optimization done. */
6627 if (TREE_SIDE_EFFECTS (arglist
)
6628 || AGGREGATE_TYPE_P (TREE_TYPE (arglist
))
6629 || POINTER_TYPE_P (TREE_TYPE (arglist
))
6631 || folding_initializer
)
6632 return integer_zero_node
;
6637 /* Fold a call to __builtin_expect, if we expect that a comparison against
6638 the argument will fold to a constant. In practice, this means a true
6639 constant or the address of a non-weak symbol. ARGLIST is the argument
6640 list of the call. */
6643 fold_builtin_expect (tree arglist
)
6650 arg
= TREE_VALUE (arglist
);
6652 /* If the argument isn't invariant, then there's nothing we can do. */
6653 if (!TREE_INVARIANT (arg
))
6656 /* If we're looking at an address of a weak decl, then do not fold. */
6659 if (TREE_CODE (inner
) == ADDR_EXPR
)
6663 inner
= TREE_OPERAND (inner
, 0);
6665 while (TREE_CODE (inner
) == COMPONENT_REF
6666 || TREE_CODE (inner
) == ARRAY_REF
);
6667 if (DECL_P (inner
) && DECL_WEAK (inner
))
6671 /* Otherwise, ARG already has the proper type for the return value. */
6675 /* Fold a call to __builtin_classify_type. */
6678 fold_builtin_classify_type (tree arglist
)
6681 return build_int_cst (NULL_TREE
, no_type_class
);
6683 return build_int_cst (NULL_TREE
,
6684 type_to_class (TREE_TYPE (TREE_VALUE (arglist
))));
6687 /* Fold a call to __builtin_strlen. */
6690 fold_builtin_strlen (tree arglist
)
6692 if (!validate_arglist (arglist
, POINTER_TYPE
, VOID_TYPE
))
6696 tree len
= c_strlen (TREE_VALUE (arglist
), 0);
6700 /* Convert from the internal "sizetype" type to "size_t". */
6702 len
= fold_convert (size_type_node
, len
);
6710 /* Fold a call to __builtin_inf or __builtin_huge_val. */
6713 fold_builtin_inf (tree type
, int warn
)
6715 REAL_VALUE_TYPE real
;
6717 /* __builtin_inff is intended to be usable to define INFINITY on all
6718 targets. If an infinity is not available, INFINITY expands "to a
6719 positive constant of type float that overflows at translation
6720 time", footnote "In this case, using INFINITY will violate the
6721 constraint in 6.4.4 and thus require a diagnostic." (C99 7.12#4).
6722 Thus we pedwarn to ensure this constraint violation is
6724 if (!MODE_HAS_INFINITIES (TYPE_MODE (type
)) && warn
)
6725 pedwarn ("target format does not support infinity");
6728 return build_real (type
, real
);
6731 /* Fold a call to __builtin_nan or __builtin_nans. */
6734 fold_builtin_nan (tree arglist
, tree type
, int quiet
)
6736 REAL_VALUE_TYPE real
;
6739 if (!validate_arglist (arglist
, POINTER_TYPE
, VOID_TYPE
))
6741 str
= c_getstr (TREE_VALUE (arglist
));
6745 if (!real_nan (&real
, str
, quiet
, TYPE_MODE (type
)))
6748 return build_real (type
, real
);
6751 /* Return true if the floating point expression T has an integer value.
6752 We also allow +Inf, -Inf and NaN to be considered integer values. */
6755 integer_valued_real_p (tree t
)
6757 switch (TREE_CODE (t
))
6764 case NON_LVALUE_EXPR
:
6765 return integer_valued_real_p (TREE_OPERAND (t
, 0));
6770 return integer_valued_real_p (TREE_OPERAND (t
, 1));
6777 return integer_valued_real_p (TREE_OPERAND (t
, 0))
6778 && integer_valued_real_p (TREE_OPERAND (t
, 1));
6781 return integer_valued_real_p (TREE_OPERAND (t
, 1))
6782 && integer_valued_real_p (TREE_OPERAND (t
, 2));
6785 if (! TREE_CONSTANT_OVERFLOW (t
))
6787 REAL_VALUE_TYPE c
, cint
;
6789 c
= TREE_REAL_CST (t
);
6790 real_trunc (&cint
, TYPE_MODE (TREE_TYPE (t
)), &c
);
6791 return real_identical (&c
, &cint
);
6797 tree type
= TREE_TYPE (TREE_OPERAND (t
, 0));
6798 if (TREE_CODE (type
) == INTEGER_TYPE
)
6800 if (TREE_CODE (type
) == REAL_TYPE
)
6801 return integer_valued_real_p (TREE_OPERAND (t
, 0));
6806 switch (builtin_mathfn_code (t
))
6808 CASE_FLT_FN (BUILT_IN_CEIL
):
6809 CASE_FLT_FN (BUILT_IN_FLOOR
):
6810 CASE_FLT_FN (BUILT_IN_NEARBYINT
):
6811 CASE_FLT_FN (BUILT_IN_RINT
):
6812 CASE_FLT_FN (BUILT_IN_ROUND
):
6813 CASE_FLT_FN (BUILT_IN_TRUNC
):
6827 /* EXP is assumed to be builtin call where truncation can be propagated
6828 across (for instance floor((double)f) == (double)floorf (f).
6829 Do the transformation. */
6832 fold_trunc_transparent_mathfn (tree fndecl
, tree arglist
)
6834 enum built_in_function fcode
= DECL_FUNCTION_CODE (fndecl
);
6837 if (! validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
6840 arg
= TREE_VALUE (arglist
);
6841 /* Integer rounding functions are idempotent. */
6842 if (fcode
== builtin_mathfn_code (arg
))
6845 /* If argument is already integer valued, and we don't need to worry
6846 about setting errno, there's no need to perform rounding. */
6847 if (! flag_errno_math
&& integer_valued_real_p (arg
))
6852 tree arg0
= strip_float_extensions (arg
);
6853 tree ftype
= TREE_TYPE (TREE_TYPE (fndecl
));
6854 tree newtype
= TREE_TYPE (arg0
);
6857 if (TYPE_PRECISION (newtype
) < TYPE_PRECISION (ftype
)
6858 && (decl
= mathfn_built_in (newtype
, fcode
)))
6861 build_tree_list (NULL_TREE
, fold_convert (newtype
, arg0
));
6862 return fold_convert (ftype
,
6863 build_function_call_expr (decl
, arglist
));
6869 /* EXP is assumed to be builtin call which can narrow the FP type of
6870 the argument, for instance lround((double)f) -> lroundf (f). */
6873 fold_fixed_mathfn (tree fndecl
, tree arglist
)
6875 enum built_in_function fcode
= DECL_FUNCTION_CODE (fndecl
);
6878 if (! validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
6881 arg
= TREE_VALUE (arglist
);
6883 /* If argument is already integer valued, and we don't need to worry
6884 about setting errno, there's no need to perform rounding. */
6885 if (! flag_errno_math
&& integer_valued_real_p (arg
))
6886 return fold_build1 (FIX_TRUNC_EXPR
, TREE_TYPE (TREE_TYPE (fndecl
)), arg
);
6890 tree ftype
= TREE_TYPE (arg
);
6891 tree arg0
= strip_float_extensions (arg
);
6892 tree newtype
= TREE_TYPE (arg0
);
6895 if (TYPE_PRECISION (newtype
) < TYPE_PRECISION (ftype
)
6896 && (decl
= mathfn_built_in (newtype
, fcode
)))
6899 build_tree_list (NULL_TREE
, fold_convert (newtype
, arg0
));
6900 return build_function_call_expr (decl
, arglist
);
6904 /* Canonicalize llround (x) to lround (x) on LP64 targets where
6905 sizeof (long long) == sizeof (long). */
6906 if (TYPE_PRECISION (long_long_integer_type_node
)
6907 == TYPE_PRECISION (long_integer_type_node
))
6909 tree newfn
= NULL_TREE
;
6912 CASE_FLT_FN (BUILT_IN_LLCEIL
):
6913 newfn
= mathfn_built_in (TREE_TYPE (arg
), BUILT_IN_LCEIL
);
6916 CASE_FLT_FN (BUILT_IN_LLFLOOR
):
6917 newfn
= mathfn_built_in (TREE_TYPE (arg
), BUILT_IN_LFLOOR
);
6920 CASE_FLT_FN (BUILT_IN_LLROUND
):
6921 newfn
= mathfn_built_in (TREE_TYPE (arg
), BUILT_IN_LROUND
);
6924 CASE_FLT_FN (BUILT_IN_LLRINT
):
6925 newfn
= mathfn_built_in (TREE_TYPE (arg
), BUILT_IN_LRINT
);
6934 tree newcall
= build_function_call_expr (newfn
, arglist
);
6935 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl
)), newcall
);
6942 /* Fold function call to builtin cabs, cabsf or cabsl. ARGLIST
6943 is the argument list, TYPE is the return type and FNDECL is the
6944 original function DECL. Return NULL_TREE if no if no simplification
6948 fold_builtin_cabs (tree arglist
, tree type
, tree fndecl
)
6952 if (!arglist
|| TREE_CHAIN (arglist
))
6955 arg
= TREE_VALUE (arglist
);
6956 if (TREE_CODE (TREE_TYPE (arg
)) != COMPLEX_TYPE
6957 || TREE_CODE (TREE_TYPE (TREE_TYPE (arg
))) != REAL_TYPE
)
6960 /* Evaluate cabs of a constant at compile-time. */
6961 if (flag_unsafe_math_optimizations
6962 && TREE_CODE (arg
) == COMPLEX_CST
6963 && TREE_CODE (TREE_REALPART (arg
)) == REAL_CST
6964 && TREE_CODE (TREE_IMAGPART (arg
)) == REAL_CST
6965 && ! TREE_CONSTANT_OVERFLOW (TREE_REALPART (arg
))
6966 && ! TREE_CONSTANT_OVERFLOW (TREE_IMAGPART (arg
)))
6968 REAL_VALUE_TYPE r
, i
;
6970 r
= TREE_REAL_CST (TREE_REALPART (arg
));
6971 i
= TREE_REAL_CST (TREE_IMAGPART (arg
));
6973 real_arithmetic (&r
, MULT_EXPR
, &r
, &r
);
6974 real_arithmetic (&i
, MULT_EXPR
, &i
, &i
);
6975 real_arithmetic (&r
, PLUS_EXPR
, &r
, &i
);
6976 if (real_sqrt (&r
, TYPE_MODE (type
), &r
)
6977 || ! flag_trapping_math
)
6978 return build_real (type
, r
);
6981 /* If either part is zero, cabs is fabs of the other. */
6982 if (TREE_CODE (arg
) == COMPLEX_EXPR
6983 && real_zerop (TREE_OPERAND (arg
, 0)))
6984 return fold_build1 (ABS_EXPR
, type
, TREE_OPERAND (arg
, 1));
6985 if (TREE_CODE (arg
) == COMPLEX_EXPR
6986 && real_zerop (TREE_OPERAND (arg
, 1)))
6987 return fold_build1 (ABS_EXPR
, type
, TREE_OPERAND (arg
, 0));
6989 /* Optimize cabs(-z) and cabs(conj(z)) as cabs(z). */
6990 if (TREE_CODE (arg
) == NEGATE_EXPR
6991 || TREE_CODE (arg
) == CONJ_EXPR
)
6993 tree arglist
= build_tree_list (NULL_TREE
, TREE_OPERAND (arg
, 0));
6994 return build_function_call_expr (fndecl
, arglist
);
6997 /* Don't do this when optimizing for size. */
6998 if (flag_unsafe_math_optimizations
6999 && optimize
&& !optimize_size
)
7001 tree sqrtfn
= mathfn_built_in (type
, BUILT_IN_SQRT
);
7003 if (sqrtfn
!= NULL_TREE
)
7005 tree rpart
, ipart
, result
, arglist
;
7007 arg
= builtin_save_expr (arg
);
7009 rpart
= fold_build1 (REALPART_EXPR
, type
, arg
);
7010 ipart
= fold_build1 (IMAGPART_EXPR
, type
, arg
);
7012 rpart
= builtin_save_expr (rpart
);
7013 ipart
= builtin_save_expr (ipart
);
7015 result
= fold_build2 (PLUS_EXPR
, type
,
7016 fold_build2 (MULT_EXPR
, type
,
7018 fold_build2 (MULT_EXPR
, type
,
7021 arglist
= build_tree_list (NULL_TREE
, result
);
7022 return build_function_call_expr (sqrtfn
, arglist
);
7029 /* Fold a builtin function call to sqrt, sqrtf, or sqrtl. Return
7030 NULL_TREE if no simplification can be made. */
7033 fold_builtin_sqrt (tree arglist
, tree type
)
7036 enum built_in_function fcode
;
7037 tree arg
= TREE_VALUE (arglist
);
7039 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
7042 /* Optimize sqrt of constant value. */
7043 if (TREE_CODE (arg
) == REAL_CST
7044 && ! TREE_CONSTANT_OVERFLOW (arg
))
7046 REAL_VALUE_TYPE r
, x
;
7048 x
= TREE_REAL_CST (arg
);
7049 if (real_sqrt (&r
, TYPE_MODE (type
), &x
)
7050 || (!flag_trapping_math
&& !flag_errno_math
))
7051 return build_real (type
, r
);
7054 /* Optimize sqrt(expN(x)) = expN(x*0.5). */
7055 fcode
= builtin_mathfn_code (arg
);
7056 if (flag_unsafe_math_optimizations
&& BUILTIN_EXPONENT_P (fcode
))
7058 tree expfn
= TREE_OPERAND (TREE_OPERAND (arg
, 0), 0);
7059 arg
= fold_build2 (MULT_EXPR
, type
,
7060 TREE_VALUE (TREE_OPERAND (arg
, 1)),
7061 build_real (type
, dconsthalf
));
7062 arglist
= build_tree_list (NULL_TREE
, arg
);
7063 return build_function_call_expr (expfn
, arglist
);
7066 /* Optimize sqrt(Nroot(x)) -> pow(x,1/(2*N)). */
7067 if (flag_unsafe_math_optimizations
&& BUILTIN_ROOT_P (fcode
))
7069 tree powfn
= mathfn_built_in (type
, BUILT_IN_POW
);
7073 tree arg0
= TREE_VALUE (TREE_OPERAND (arg
, 1));
7075 /* The inner root was either sqrt or cbrt. */
7076 REAL_VALUE_TYPE dconstroot
=
7077 BUILTIN_SQRT_P (fcode
) ? dconsthalf
: dconstthird
;
7079 /* Adjust for the outer root. */
7080 SET_REAL_EXP (&dconstroot
, REAL_EXP (&dconstroot
) - 1);
7081 dconstroot
= real_value_truncate (TYPE_MODE (type
), dconstroot
);
7082 tree_root
= build_real (type
, dconstroot
);
7083 arglist
= tree_cons (NULL_TREE
, arg0
,
7084 build_tree_list (NULL_TREE
, tree_root
));
7085 return build_function_call_expr (powfn
, arglist
);
7089 /* Optimize sqrt(pow(x,y)) = pow(|x|,y*0.5). */
7090 if (flag_unsafe_math_optimizations
7091 && (fcode
== BUILT_IN_POW
7092 || fcode
== BUILT_IN_POWF
7093 || fcode
== BUILT_IN_POWL
))
7095 tree powfn
= TREE_OPERAND (TREE_OPERAND (arg
, 0), 0);
7096 tree arg0
= TREE_VALUE (TREE_OPERAND (arg
, 1));
7097 tree arg1
= TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg
, 1)));
7099 if (!tree_expr_nonnegative_p (arg0
))
7100 arg0
= build1 (ABS_EXPR
, type
, arg0
);
7101 narg1
= fold_build2 (MULT_EXPR
, type
, arg1
,
7102 build_real (type
, dconsthalf
));
7103 arglist
= tree_cons (NULL_TREE
, arg0
,
7104 build_tree_list (NULL_TREE
, narg1
));
7105 return build_function_call_expr (powfn
, arglist
);
7111 /* Fold a builtin function call to cbrt, cbrtf, or cbrtl. Return
7112 NULL_TREE if no simplification can be made. */
7114 fold_builtin_cbrt (tree arglist
, tree type
)
7116 tree arg
= TREE_VALUE (arglist
);
7117 const enum built_in_function fcode
= builtin_mathfn_code (arg
);
7120 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
7123 /* Calculate the result when the argument is a constant. */
7124 if ((res
= do_mpfr_arg1 (arg
, type
, mpfr_cbrt
, NULL
, NULL
, 0)))
7127 if (flag_unsafe_math_optimizations
)
7129 /* Optimize cbrt(expN(x)) -> expN(x/3). */
7130 if (BUILTIN_EXPONENT_P (fcode
))
7132 tree expfn
= TREE_OPERAND (TREE_OPERAND (arg
, 0), 0);
7133 const REAL_VALUE_TYPE third_trunc
=
7134 real_value_truncate (TYPE_MODE (type
), dconstthird
);
7135 arg
= fold_build2 (MULT_EXPR
, type
,
7136 TREE_VALUE (TREE_OPERAND (arg
, 1)),
7137 build_real (type
, third_trunc
));
7138 arglist
= build_tree_list (NULL_TREE
, arg
);
7139 return build_function_call_expr (expfn
, arglist
);
7142 /* Optimize cbrt(sqrt(x)) -> pow(x,1/6). */
7143 if (BUILTIN_SQRT_P (fcode
))
7145 tree powfn
= mathfn_built_in (type
, BUILT_IN_POW
);
7149 tree arg0
= TREE_VALUE (TREE_OPERAND (arg
, 1));
7151 REAL_VALUE_TYPE dconstroot
= dconstthird
;
7153 SET_REAL_EXP (&dconstroot
, REAL_EXP (&dconstroot
) - 1);
7154 dconstroot
= real_value_truncate (TYPE_MODE (type
), dconstroot
);
7155 tree_root
= build_real (type
, dconstroot
);
7156 arglist
= tree_cons (NULL_TREE
, arg0
,
7157 build_tree_list (NULL_TREE
, tree_root
));
7158 return build_function_call_expr (powfn
, arglist
);
7162 /* Optimize cbrt(cbrt(x)) -> pow(x,1/9) iff x is nonnegative. */
7163 if (BUILTIN_CBRT_P (fcode
))
7165 tree arg0
= TREE_VALUE (TREE_OPERAND (arg
, 1));
7166 if (tree_expr_nonnegative_p (arg0
))
7168 tree powfn
= mathfn_built_in (type
, BUILT_IN_POW
);
7173 REAL_VALUE_TYPE dconstroot
;
7175 real_arithmetic (&dconstroot
, MULT_EXPR
, &dconstthird
, &dconstthird
);
7176 dconstroot
= real_value_truncate (TYPE_MODE (type
), dconstroot
);
7177 tree_root
= build_real (type
, dconstroot
);
7178 arglist
= tree_cons (NULL_TREE
, arg0
,
7179 build_tree_list (NULL_TREE
, tree_root
));
7180 return build_function_call_expr (powfn
, arglist
);
7185 /* Optimize cbrt(pow(x,y)) -> pow(x,y/3) iff x is nonnegative. */
7186 if (fcode
== BUILT_IN_POW
|| fcode
== BUILT_IN_POWF
7187 || fcode
== BUILT_IN_POWL
)
7189 tree arg00
= TREE_VALUE (TREE_OPERAND (arg
, 1));
7190 tree arg01
= TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg
, 1)));
7191 if (tree_expr_nonnegative_p (arg00
))
7193 tree powfn
= TREE_OPERAND (TREE_OPERAND (arg
, 0), 0);
7194 const REAL_VALUE_TYPE dconstroot
7195 = real_value_truncate (TYPE_MODE (type
), dconstthird
);
7196 tree narg01
= fold_build2 (MULT_EXPR
, type
, arg01
,
7197 build_real (type
, dconstroot
));
7198 arglist
= tree_cons (NULL_TREE
, arg00
,
7199 build_tree_list (NULL_TREE
, narg01
));
7200 return build_function_call_expr (powfn
, arglist
);
7207 /* Fold function call to builtin cos, cosf, or cosl. Return
7208 NULL_TREE if no simplification can be made. */
7210 fold_builtin_cos (tree arglist
, tree type
, tree fndecl
)
7212 tree arg
= TREE_VALUE (arglist
);
7215 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
7218 /* Calculate the result when the argument is a constant. */
7219 if ((res
= do_mpfr_arg1 (arg
, type
, mpfr_cos
, NULL
, NULL
, 0)))
7222 /* Optimize cos(-x) into cos (x). */
7223 if (TREE_CODE (arg
) == NEGATE_EXPR
)
7225 tree args
= build_tree_list (NULL_TREE
,
7226 TREE_OPERAND (arg
, 0));
7227 return build_function_call_expr (fndecl
, args
);
7233 /* Fold function call to builtin tan, tanf, or tanl. Return
7234 NULL_TREE if no simplification can be made. */
7236 fold_builtin_tan (tree arglist
, tree type
)
7238 enum built_in_function fcode
;
7239 tree arg
= TREE_VALUE (arglist
);
7242 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
7245 /* Calculate the result when the argument is a constant. */
7246 if ((res
= do_mpfr_arg1 (arg
, type
, mpfr_tan
, NULL
, NULL
, 0)))
7249 /* Optimize tan(atan(x)) = x. */
7250 fcode
= builtin_mathfn_code (arg
);
7251 if (flag_unsafe_math_optimizations
7252 && (fcode
== BUILT_IN_ATAN
7253 || fcode
== BUILT_IN_ATANF
7254 || fcode
== BUILT_IN_ATANL
))
7255 return TREE_VALUE (TREE_OPERAND (arg
, 1));
7260 /* Fold function call to builtin trunc, truncf or truncl. Return
7261 NULL_TREE if no simplification can be made. */
7264 fold_builtin_trunc (tree fndecl
, tree arglist
)
7268 if (! validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
7271 /* Optimize trunc of constant value. */
7272 arg
= TREE_VALUE (arglist
);
7273 if (TREE_CODE (arg
) == REAL_CST
&& ! TREE_CONSTANT_OVERFLOW (arg
))
7275 REAL_VALUE_TYPE r
, x
;
7276 tree type
= TREE_TYPE (TREE_TYPE (fndecl
));
7278 x
= TREE_REAL_CST (arg
);
7279 real_trunc (&r
, TYPE_MODE (type
), &x
);
7280 return build_real (type
, r
);
7283 return fold_trunc_transparent_mathfn (fndecl
, arglist
);
7286 /* Fold function call to builtin floor, floorf or floorl. Return
7287 NULL_TREE if no simplification can be made. */
7290 fold_builtin_floor (tree fndecl
, tree arglist
)
7294 if (! validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
7297 /* Optimize floor of constant value. */
7298 arg
= TREE_VALUE (arglist
);
7299 if (TREE_CODE (arg
) == REAL_CST
&& ! TREE_CONSTANT_OVERFLOW (arg
))
7303 x
= TREE_REAL_CST (arg
);
7304 if (! REAL_VALUE_ISNAN (x
) || ! flag_errno_math
)
7306 tree type
= TREE_TYPE (TREE_TYPE (fndecl
));
7309 real_floor (&r
, TYPE_MODE (type
), &x
);
7310 return build_real (type
, r
);
7314 /* Fold floor (x) where x is nonnegative to trunc (x). */
7315 if (tree_expr_nonnegative_p (arg
))
7316 return build_function_call_expr (mathfn_built_in (TREE_TYPE (arg
),
7320 return fold_trunc_transparent_mathfn (fndecl
, arglist
);
7323 /* Fold function call to builtin ceil, ceilf or ceill. Return
7324 NULL_TREE if no simplification can be made. */
7327 fold_builtin_ceil (tree fndecl
, tree arglist
)
7331 if (! validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
7334 /* Optimize ceil of constant value. */
7335 arg
= TREE_VALUE (arglist
);
7336 if (TREE_CODE (arg
) == REAL_CST
&& ! TREE_CONSTANT_OVERFLOW (arg
))
7340 x
= TREE_REAL_CST (arg
);
7341 if (! REAL_VALUE_ISNAN (x
) || ! flag_errno_math
)
7343 tree type
= TREE_TYPE (TREE_TYPE (fndecl
));
7346 real_ceil (&r
, TYPE_MODE (type
), &x
);
7347 return build_real (type
, r
);
7351 return fold_trunc_transparent_mathfn (fndecl
, arglist
);
7354 /* Fold function call to builtin round, roundf or roundl. Return
7355 NULL_TREE if no simplification can be made. */
7358 fold_builtin_round (tree fndecl
, tree arglist
)
7362 if (! validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
7365 /* Optimize round of constant value. */
7366 arg
= TREE_VALUE (arglist
);
7367 if (TREE_CODE (arg
) == REAL_CST
&& ! TREE_CONSTANT_OVERFLOW (arg
))
7371 x
= TREE_REAL_CST (arg
);
7372 if (! REAL_VALUE_ISNAN (x
) || ! flag_errno_math
)
7374 tree type
= TREE_TYPE (TREE_TYPE (fndecl
));
7377 real_round (&r
, TYPE_MODE (type
), &x
);
7378 return build_real (type
, r
);
7382 return fold_trunc_transparent_mathfn (fndecl
, arglist
);
7385 /* Fold function call to builtin lround, lroundf or lroundl (or the
7386 corresponding long long versions) and other rounding functions.
7387 Return NULL_TREE if no simplification can be made. */
7390 fold_builtin_int_roundingfn (tree fndecl
, tree arglist
)
7394 if (! validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
7397 /* Optimize lround of constant value. */
7398 arg
= TREE_VALUE (arglist
);
7399 if (TREE_CODE (arg
) == REAL_CST
&& ! TREE_CONSTANT_OVERFLOW (arg
))
7401 const REAL_VALUE_TYPE x
= TREE_REAL_CST (arg
);
7403 if (! REAL_VALUE_ISNAN (x
) && ! REAL_VALUE_ISINF (x
))
7405 tree itype
= TREE_TYPE (TREE_TYPE (fndecl
));
7406 tree ftype
= TREE_TYPE (arg
), result
;
7407 HOST_WIDE_INT hi
, lo
;
7410 switch (DECL_FUNCTION_CODE (fndecl
))
7412 CASE_FLT_FN (BUILT_IN_LFLOOR
):
7413 CASE_FLT_FN (BUILT_IN_LLFLOOR
):
7414 real_floor (&r
, TYPE_MODE (ftype
), &x
);
7417 CASE_FLT_FN (BUILT_IN_LCEIL
):
7418 CASE_FLT_FN (BUILT_IN_LLCEIL
):
7419 real_ceil (&r
, TYPE_MODE (ftype
), &x
);
7422 CASE_FLT_FN (BUILT_IN_LROUND
):
7423 CASE_FLT_FN (BUILT_IN_LLROUND
):
7424 real_round (&r
, TYPE_MODE (ftype
), &x
);
7431 REAL_VALUE_TO_INT (&lo
, &hi
, r
);
7432 result
= build_int_cst_wide (NULL_TREE
, lo
, hi
);
7433 if (int_fits_type_p (result
, itype
))
7434 return fold_convert (itype
, result
);
7438 switch (DECL_FUNCTION_CODE (fndecl
))
7440 CASE_FLT_FN (BUILT_IN_LFLOOR
):
7441 CASE_FLT_FN (BUILT_IN_LLFLOOR
):
7442 /* Fold lfloor (x) where x is nonnegative to FIX_TRUNC (x). */
7443 if (tree_expr_nonnegative_p (arg
))
7444 return fold_build1 (FIX_TRUNC_EXPR
, TREE_TYPE (TREE_TYPE (fndecl
)),
7450 return fold_fixed_mathfn (fndecl
, arglist
);
7453 /* Fold function call to builtin ffs, clz, ctz, popcount and parity
7454 and their long and long long variants (i.e. ffsl and ffsll).
7455 Return NULL_TREE if no simplification can be made. */
7458 fold_builtin_bitop (tree fndecl
, tree arglist
)
7462 if (! validate_arglist (arglist
, INTEGER_TYPE
, VOID_TYPE
))
7465 /* Optimize for constant argument. */
7466 arg
= TREE_VALUE (arglist
);
7467 if (TREE_CODE (arg
) == INTEGER_CST
&& ! TREE_CONSTANT_OVERFLOW (arg
))
7469 HOST_WIDE_INT hi
, width
, result
;
7470 unsigned HOST_WIDE_INT lo
;
7473 type
= TREE_TYPE (arg
);
7474 width
= TYPE_PRECISION (type
);
7475 lo
= TREE_INT_CST_LOW (arg
);
7477 /* Clear all the bits that are beyond the type's precision. */
7478 if (width
> HOST_BITS_PER_WIDE_INT
)
7480 hi
= TREE_INT_CST_HIGH (arg
);
7481 if (width
< 2 * HOST_BITS_PER_WIDE_INT
)
7482 hi
&= ~((HOST_WIDE_INT
) (-1) >> (width
- HOST_BITS_PER_WIDE_INT
));
7487 if (width
< HOST_BITS_PER_WIDE_INT
)
7488 lo
&= ~((unsigned HOST_WIDE_INT
) (-1) << width
);
7491 switch (DECL_FUNCTION_CODE (fndecl
))
7493 CASE_INT_FN (BUILT_IN_FFS
):
7495 result
= exact_log2 (lo
& -lo
) + 1;
7497 result
= HOST_BITS_PER_WIDE_INT
+ exact_log2 (hi
& -hi
) + 1;
7502 CASE_INT_FN (BUILT_IN_CLZ
):
7504 result
= width
- floor_log2 (hi
) - 1 - HOST_BITS_PER_WIDE_INT
;
7506 result
= width
- floor_log2 (lo
) - 1;
7507 else if (! CLZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type
), result
))
7511 CASE_INT_FN (BUILT_IN_CTZ
):
7513 result
= exact_log2 (lo
& -lo
);
7515 result
= HOST_BITS_PER_WIDE_INT
+ exact_log2 (hi
& -hi
);
7516 else if (! CTZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type
), result
))
7520 CASE_INT_FN (BUILT_IN_POPCOUNT
):
7523 result
++, lo
&= lo
- 1;
7525 result
++, hi
&= hi
- 1;
7528 CASE_INT_FN (BUILT_IN_PARITY
):
7531 result
++, lo
&= lo
- 1;
7533 result
++, hi
&= hi
- 1;
7541 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl
)), result
);
7547 /* Return true if EXPR is the real constant contained in VALUE. */
7550 real_dconstp (tree expr
, const REAL_VALUE_TYPE
*value
)
7554 return ((TREE_CODE (expr
) == REAL_CST
7555 && ! TREE_CONSTANT_OVERFLOW (expr
)
7556 && REAL_VALUES_EQUAL (TREE_REAL_CST (expr
), *value
))
7557 || (TREE_CODE (expr
) == COMPLEX_CST
7558 && real_dconstp (TREE_REALPART (expr
), value
)
7559 && real_zerop (TREE_IMAGPART (expr
))));
7562 /* A subroutine of fold_builtin to fold the various logarithmic
7563 functions. Return NULL_TREE if no simplification can me made.
7564 FUNC is the corresponding MPFR logarithm function. */
7567 fold_builtin_logarithm (tree fndecl
, tree arglist
,
7568 int (*func
)(mpfr_ptr
, mpfr_srcptr
, mp_rnd_t
))
7570 if (validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
7572 tree type
= TREE_TYPE (TREE_TYPE (fndecl
));
7573 tree arg
= TREE_VALUE (arglist
);
7575 const enum built_in_function fcode
= builtin_mathfn_code (arg
);
7577 /* Optimize log(e) = 1.0. We're never passed an exact 'e',
7578 instead we'll look for 'e' truncated to MODE. So only do
7579 this if flag_unsafe_math_optimizations is set. */
7580 if (flag_unsafe_math_optimizations
&& func
== mpfr_log
)
7582 const REAL_VALUE_TYPE e_truncated
=
7583 real_value_truncate (TYPE_MODE (type
), dconste
);
7584 if (real_dconstp (arg
, &e_truncated
))
7585 return build_real (type
, dconst1
);
7588 /* Calculate the result when the argument is a constant. */
7589 if ((res
= do_mpfr_arg1 (arg
, type
, func
, &dconst0
, NULL
, false)))
7592 /* Special case, optimize logN(expN(x)) = x. */
7593 if (flag_unsafe_math_optimizations
7594 && ((func
== mpfr_log
7595 && (fcode
== BUILT_IN_EXP
7596 || fcode
== BUILT_IN_EXPF
7597 || fcode
== BUILT_IN_EXPL
))
7598 || (func
== mpfr_log2
7599 && (fcode
== BUILT_IN_EXP2
7600 || fcode
== BUILT_IN_EXP2F
7601 || fcode
== BUILT_IN_EXP2L
))
7602 || (func
== mpfr_log10
&& (BUILTIN_EXP10_P (fcode
)))))
7603 return fold_convert (type
, TREE_VALUE (TREE_OPERAND (arg
, 1)));
7605 /* Optimize logN(func()) for various exponential functions. We
7606 want to determine the value "x" and the power "exponent" in
7607 order to transform logN(x**exponent) into exponent*logN(x). */
7608 if (flag_unsafe_math_optimizations
)
7610 tree exponent
= 0, x
= 0;
7614 CASE_FLT_FN (BUILT_IN_EXP
):
7615 /* Prepare to do logN(exp(exponent) -> exponent*logN(e). */
7616 x
= build_real (type
,
7617 real_value_truncate (TYPE_MODE (type
), dconste
));
7618 exponent
= TREE_VALUE (TREE_OPERAND (arg
, 1));
7620 CASE_FLT_FN (BUILT_IN_EXP2
):
7621 /* Prepare to do logN(exp2(exponent) -> exponent*logN(2). */
7622 x
= build_real (type
, dconst2
);
7623 exponent
= TREE_VALUE (TREE_OPERAND (arg
, 1));
7625 CASE_FLT_FN (BUILT_IN_EXP10
):
7626 CASE_FLT_FN (BUILT_IN_POW10
):
7627 /* Prepare to do logN(exp10(exponent) -> exponent*logN(10). */
7628 x
= build_real (type
, dconst10
);
7629 exponent
= TREE_VALUE (TREE_OPERAND (arg
, 1));
7631 CASE_FLT_FN (BUILT_IN_SQRT
):
7632 /* Prepare to do logN(sqrt(x) -> 0.5*logN(x). */
7633 x
= TREE_VALUE (TREE_OPERAND (arg
, 1));
7634 exponent
= build_real (type
, dconsthalf
);
7636 CASE_FLT_FN (BUILT_IN_CBRT
):
7637 /* Prepare to do logN(cbrt(x) -> (1/3)*logN(x). */
7638 x
= TREE_VALUE (TREE_OPERAND (arg
, 1));
7639 exponent
= build_real (type
, real_value_truncate (TYPE_MODE (type
),
7642 CASE_FLT_FN (BUILT_IN_POW
):
7643 /* Prepare to do logN(pow(x,exponent) -> exponent*logN(x). */
7644 x
= TREE_VALUE (TREE_OPERAND (arg
, 1));
7645 exponent
= TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg
, 1)));
7651 /* Now perform the optimization. */
7655 arglist
= build_tree_list (NULL_TREE
, x
);
7656 logfn
= build_function_call_expr (fndecl
, arglist
);
7657 return fold_build2 (MULT_EXPR
, type
, exponent
, logfn
);
7665 /* Fold a builtin function call to pow, powf, or powl. Return
7666 NULL_TREE if no simplification can be made. */
7668 fold_builtin_pow (tree fndecl
, tree arglist
, tree type
)
7670 tree arg0
= TREE_VALUE (arglist
);
7671 tree arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
7673 if (!validate_arglist (arglist
, REAL_TYPE
, REAL_TYPE
, VOID_TYPE
))
7676 /* Optimize pow(1.0,y) = 1.0. */
7677 if (real_onep (arg0
))
7678 return omit_one_operand (type
, build_real (type
, dconst1
), arg1
);
7680 if (TREE_CODE (arg1
) == REAL_CST
7681 && ! TREE_CONSTANT_OVERFLOW (arg1
))
7683 REAL_VALUE_TYPE cint
;
7687 c
= TREE_REAL_CST (arg1
);
7689 /* Optimize pow(x,0.0) = 1.0. */
7690 if (REAL_VALUES_EQUAL (c
, dconst0
))
7691 return omit_one_operand (type
, build_real (type
, dconst1
),
7694 /* Optimize pow(x,1.0) = x. */
7695 if (REAL_VALUES_EQUAL (c
, dconst1
))
7698 /* Optimize pow(x,-1.0) = 1.0/x. */
7699 if (REAL_VALUES_EQUAL (c
, dconstm1
))
7700 return fold_build2 (RDIV_EXPR
, type
,
7701 build_real (type
, dconst1
), arg0
);
7703 /* Optimize pow(x,0.5) = sqrt(x). */
7704 if (flag_unsafe_math_optimizations
7705 && REAL_VALUES_EQUAL (c
, dconsthalf
))
7707 tree sqrtfn
= mathfn_built_in (type
, BUILT_IN_SQRT
);
7709 if (sqrtfn
!= NULL_TREE
)
7711 tree arglist
= build_tree_list (NULL_TREE
, arg0
);
7712 return build_function_call_expr (sqrtfn
, arglist
);
7716 /* Optimize pow(x,1.0/3.0) = cbrt(x). */
7717 if (flag_unsafe_math_optimizations
)
7719 const REAL_VALUE_TYPE dconstroot
7720 = real_value_truncate (TYPE_MODE (type
), dconstthird
);
7722 if (REAL_VALUES_EQUAL (c
, dconstroot
))
7724 tree cbrtfn
= mathfn_built_in (type
, BUILT_IN_CBRT
);
7725 if (cbrtfn
!= NULL_TREE
)
7727 tree arglist
= build_tree_list (NULL_TREE
, arg0
);
7728 return build_function_call_expr (cbrtfn
, arglist
);
7733 /* Check for an integer exponent. */
7734 n
= real_to_integer (&c
);
7735 real_from_integer (&cint
, VOIDmode
, n
, n
< 0 ? -1 : 0, 0);
7736 if (real_identical (&c
, &cint
))
7738 /* Attempt to evaluate pow at compile-time. */
7739 if (TREE_CODE (arg0
) == REAL_CST
7740 && ! TREE_CONSTANT_OVERFLOW (arg0
))
7745 x
= TREE_REAL_CST (arg0
);
7746 inexact
= real_powi (&x
, TYPE_MODE (type
), &x
, n
);
7747 if (flag_unsafe_math_optimizations
|| !inexact
)
7748 return build_real (type
, x
);
7751 /* Strip sign ops from even integer powers. */
7752 if ((n
& 1) == 0 && flag_unsafe_math_optimizations
)
7754 tree narg0
= fold_strip_sign_ops (arg0
);
7757 arglist
= build_tree_list (NULL_TREE
, arg1
);
7758 arglist
= tree_cons (NULL_TREE
, narg0
, arglist
);
7759 return build_function_call_expr (fndecl
, arglist
);
7765 if (flag_unsafe_math_optimizations
)
7767 const enum built_in_function fcode
= builtin_mathfn_code (arg0
);
7769 /* Optimize pow(expN(x),y) = expN(x*y). */
7770 if (BUILTIN_EXPONENT_P (fcode
))
7772 tree expfn
= TREE_OPERAND (TREE_OPERAND (arg0
, 0), 0);
7773 tree arg
= TREE_VALUE (TREE_OPERAND (arg0
, 1));
7774 arg
= fold_build2 (MULT_EXPR
, type
, arg
, arg1
);
7775 arglist
= build_tree_list (NULL_TREE
, arg
);
7776 return build_function_call_expr (expfn
, arglist
);
7779 /* Optimize pow(sqrt(x),y) = pow(x,y*0.5). */
7780 if (BUILTIN_SQRT_P (fcode
))
7782 tree narg0
= TREE_VALUE (TREE_OPERAND (arg0
, 1));
7783 tree narg1
= fold_build2 (MULT_EXPR
, type
, arg1
,
7784 build_real (type
, dconsthalf
));
7786 arglist
= tree_cons (NULL_TREE
, narg0
,
7787 build_tree_list (NULL_TREE
, narg1
));
7788 return build_function_call_expr (fndecl
, arglist
);
7791 /* Optimize pow(cbrt(x),y) = pow(x,y/3) iff x is nonnegative. */
7792 if (BUILTIN_CBRT_P (fcode
))
7794 tree arg
= TREE_VALUE (TREE_OPERAND (arg0
, 1));
7795 if (tree_expr_nonnegative_p (arg
))
7797 const REAL_VALUE_TYPE dconstroot
7798 = real_value_truncate (TYPE_MODE (type
), dconstthird
);
7799 tree narg1
= fold_build2 (MULT_EXPR
, type
, arg1
,
7800 build_real (type
, dconstroot
));
7801 arglist
= tree_cons (NULL_TREE
, arg
,
7802 build_tree_list (NULL_TREE
, narg1
));
7803 return build_function_call_expr (fndecl
, arglist
);
7807 /* Optimize pow(pow(x,y),z) = pow(x,y*z). */
7808 if (fcode
== BUILT_IN_POW
|| fcode
== BUILT_IN_POWF
7809 || fcode
== BUILT_IN_POWL
)
7811 tree arg00
= TREE_VALUE (TREE_OPERAND (arg0
, 1));
7812 tree arg01
= TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg0
, 1)));
7813 tree narg1
= fold_build2 (MULT_EXPR
, type
, arg01
, arg1
);
7814 arglist
= tree_cons (NULL_TREE
, arg00
,
7815 build_tree_list (NULL_TREE
, narg1
));
7816 return build_function_call_expr (fndecl
, arglist
);
7823 /* Fold a builtin function call to powi, powif, or powil. Return
7824 NULL_TREE if no simplification can be made. */
7826 fold_builtin_powi (tree fndecl ATTRIBUTE_UNUSED
, tree arglist
, tree type
)
7828 tree arg0
= TREE_VALUE (arglist
);
7829 tree arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
7831 if (!validate_arglist (arglist
, REAL_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
7834 /* Optimize pow(1.0,y) = 1.0. */
7835 if (real_onep (arg0
))
7836 return omit_one_operand (type
, build_real (type
, dconst1
), arg1
);
7838 if (host_integerp (arg1
, 0))
7840 HOST_WIDE_INT c
= TREE_INT_CST_LOW (arg1
);
7842 /* Evaluate powi at compile-time. */
7843 if (TREE_CODE (arg0
) == REAL_CST
7844 && ! TREE_CONSTANT_OVERFLOW (arg0
))
7847 x
= TREE_REAL_CST (arg0
);
7848 real_powi (&x
, TYPE_MODE (type
), &x
, c
);
7849 return build_real (type
, x
);
7852 /* Optimize pow(x,0) = 1.0. */
7854 return omit_one_operand (type
, build_real (type
, dconst1
),
7857 /* Optimize pow(x,1) = x. */
7861 /* Optimize pow(x,-1) = 1.0/x. */
7863 return fold_build2 (RDIV_EXPR
, type
,
7864 build_real (type
, dconst1
), arg0
);
7870 /* A subroutine of fold_builtin to fold the various exponent
7871 functions. Return NULL_TREE if no simplification can me made.
7872 FUNC is the corresponding MPFR exponent function. */
7875 fold_builtin_exponent (tree fndecl
, tree arglist
,
7876 int (*func
)(mpfr_ptr
, mpfr_srcptr
, mp_rnd_t
))
7878 if (validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
7880 tree type
= TREE_TYPE (TREE_TYPE (fndecl
));
7881 tree arg
= TREE_VALUE (arglist
);
7884 /* Calculate the result when the argument is a constant. */
7885 if ((res
= do_mpfr_arg1 (arg
, type
, func
, NULL
, NULL
, 0)))
7888 /* Optimize expN(logN(x)) = x. */
7889 if (flag_unsafe_math_optimizations
)
7891 const enum built_in_function fcode
= builtin_mathfn_code (arg
);
7893 if ((func
== mpfr_exp
7894 && (fcode
== BUILT_IN_LOG
7895 || fcode
== BUILT_IN_LOGF
7896 || fcode
== BUILT_IN_LOGL
))
7897 || (func
== mpfr_exp2
7898 && (fcode
== BUILT_IN_LOG2
7899 || fcode
== BUILT_IN_LOG2F
7900 || fcode
== BUILT_IN_LOG2L
))
7901 || (func
== mpfr_exp10
7902 && (fcode
== BUILT_IN_LOG10
7903 || fcode
== BUILT_IN_LOG10F
7904 || fcode
== BUILT_IN_LOG10L
)))
7905 return fold_convert (type
, TREE_VALUE (TREE_OPERAND (arg
, 1)));
7912 /* Return true if VAR is a VAR_DECL or a component thereof. */
7915 var_decl_component_p (tree var
)
7918 while (handled_component_p (inner
))
7919 inner
= TREE_OPERAND (inner
, 0);
7920 return SSA_VAR_P (inner
);
7923 /* Fold function call to builtin memset. Return
7924 NULL_TREE if no simplification can be made. */
7927 fold_builtin_memset (tree arglist
, tree type
, bool ignore
)
7929 tree dest
, c
, len
, var
, ret
;
7930 unsigned HOST_WIDE_INT length
, cval
;
7932 if (!validate_arglist (arglist
,
7933 POINTER_TYPE
, INTEGER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
7936 dest
= TREE_VALUE (arglist
);
7937 c
= TREE_VALUE (TREE_CHAIN (arglist
));
7938 len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
7940 if (! host_integerp (len
, 1))
7943 /* If the LEN parameter is zero, return DEST. */
7944 if (integer_zerop (len
))
7945 return omit_one_operand (type
, dest
, c
);
7947 if (! host_integerp (c
, 1) || TREE_SIDE_EFFECTS (dest
))
7952 if (TREE_CODE (var
) != ADDR_EXPR
)
7955 var
= TREE_OPERAND (var
, 0);
7956 if (TREE_THIS_VOLATILE (var
))
7959 if (!INTEGRAL_TYPE_P (TREE_TYPE (var
))
7960 && !POINTER_TYPE_P (TREE_TYPE (var
)))
7963 if (! var_decl_component_p (var
))
7966 length
= tree_low_cst (len
, 1);
7967 if (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (var
))) != length
7968 || get_pointer_alignment (dest
, BIGGEST_ALIGNMENT
) / BITS_PER_UNIT
7972 if (length
> HOST_BITS_PER_WIDE_INT
/ BITS_PER_UNIT
)
7975 if (integer_zerop (c
))
7979 if (CHAR_BIT
!= 8 || BITS_PER_UNIT
!= 8 || HOST_BITS_PER_WIDE_INT
> 64)
7982 cval
= tree_low_cst (c
, 1);
7986 cval
|= (cval
<< 31) << 1;
7989 ret
= build_int_cst_type (TREE_TYPE (var
), cval
);
7990 ret
= build2 (MODIFY_EXPR
, TREE_TYPE (var
), var
, ret
);
7994 return omit_one_operand (type
, dest
, ret
);
7997 /* Fold function call to builtin memset. Return
7998 NULL_TREE if no simplification can be made. */
8001 fold_builtin_bzero (tree arglist
, bool ignore
)
8003 tree dest
, size
, newarglist
;
8005 if (!validate_arglist (arglist
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
8011 dest
= TREE_VALUE (arglist
);
8012 size
= TREE_VALUE (TREE_CHAIN (arglist
));
8014 /* New argument list transforming bzero(ptr x, int y) to
8015 memset(ptr x, int 0, size_t y). This is done this way
8016 so that if it isn't expanded inline, we fallback to
8017 calling bzero instead of memset. */
8019 newarglist
= build_tree_list (NULL_TREE
, fold_convert (sizetype
, size
));
8020 newarglist
= tree_cons (NULL_TREE
, integer_zero_node
, newarglist
);
8021 newarglist
= tree_cons (NULL_TREE
, dest
, newarglist
);
8022 return fold_builtin_memset (newarglist
, void_type_node
, ignore
);
8025 /* Fold function call to builtin mem{{,p}cpy,move}. Return
8026 NULL_TREE if no simplification can be made.
8027 If ENDP is 0, return DEST (like memcpy).
8028 If ENDP is 1, return DEST+LEN (like mempcpy).
8029 If ENDP is 2, return DEST+LEN-1 (like stpcpy).
8030 If ENDP is 3, return DEST, additionally *SRC and *DEST may overlap
8034 fold_builtin_memory_op (tree arglist
, tree type
, bool ignore
, int endp
)
8036 tree dest
, src
, len
, destvar
, srcvar
, expr
;
8037 unsigned HOST_WIDE_INT length
;
8039 if (! validate_arglist (arglist
,
8040 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
8043 dest
= TREE_VALUE (arglist
);
8044 src
= TREE_VALUE (TREE_CHAIN (arglist
));
8045 len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
8047 /* If the LEN parameter is zero, return DEST. */
8048 if (integer_zerop (len
))
8049 return omit_one_operand (type
, dest
, src
);
8051 /* If SRC and DEST are the same (and not volatile), return
8052 DEST{,+LEN,+LEN-1}. */
8053 if (operand_equal_p (src
, dest
, 0))
8059 unsigned int src_align
8060 = get_pointer_alignment (src
, BIGGEST_ALIGNMENT
);
8061 unsigned int dest_align
8062 = get_pointer_alignment (dest
, BIGGEST_ALIGNMENT
);
8063 /* Both DEST and SRC must be pointer types.
8064 ??? This is what old code did. Is the testing for pointer types
8067 If either SRC is readonly or length is 1, we can use memcpy. */
8068 if (dest_align
&& src_align
8069 && (readonly_data_expr (src
)
8070 || integer_onep (len
)))
8072 tree fn
= implicit_built_in_decls
[BUILT_IN_MEMCPY
];
8075 return build_function_call_expr (fn
, arglist
);
8078 if (! host_integerp (len
, 1))
8081 if (TREE_SIDE_EFFECTS (dest
) || TREE_SIDE_EFFECTS (src
))
8085 STRIP_NOPS (destvar
);
8086 if (TREE_CODE (destvar
) != ADDR_EXPR
)
8089 destvar
= TREE_OPERAND (destvar
, 0);
8090 if (TREE_THIS_VOLATILE (destvar
))
8093 if (!INTEGRAL_TYPE_P (TREE_TYPE (destvar
))
8094 && !POINTER_TYPE_P (TREE_TYPE (destvar
))
8095 && !SCALAR_FLOAT_TYPE_P (TREE_TYPE (destvar
)))
8098 if (! var_decl_component_p (destvar
))
8102 STRIP_NOPS (srcvar
);
8103 if (TREE_CODE (srcvar
) != ADDR_EXPR
)
8106 srcvar
= TREE_OPERAND (srcvar
, 0);
8107 if (TREE_THIS_VOLATILE (srcvar
))
8110 if (!INTEGRAL_TYPE_P (TREE_TYPE (srcvar
))
8111 && !POINTER_TYPE_P (TREE_TYPE (srcvar
))
8112 && !SCALAR_FLOAT_TYPE_P (TREE_TYPE (srcvar
)))
8115 if (! var_decl_component_p (srcvar
))
8118 length
= tree_low_cst (len
, 1);
8119 if (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (destvar
))) != length
8120 || get_pointer_alignment (dest
, BIGGEST_ALIGNMENT
) / BITS_PER_UNIT
8122 || GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (srcvar
))) != length
8123 || get_pointer_alignment (src
, BIGGEST_ALIGNMENT
) / BITS_PER_UNIT
8127 if ((INTEGRAL_TYPE_P (TREE_TYPE (srcvar
))
8128 || POINTER_TYPE_P (TREE_TYPE (srcvar
)))
8129 && (INTEGRAL_TYPE_P (TREE_TYPE (destvar
))
8130 || POINTER_TYPE_P (TREE_TYPE (destvar
))))
8131 expr
= fold_convert (TREE_TYPE (destvar
), srcvar
);
8133 expr
= fold_build1 (VIEW_CONVERT_EXPR
, TREE_TYPE (destvar
), srcvar
);
8134 expr
= build2 (MODIFY_EXPR
, TREE_TYPE (destvar
), destvar
, expr
);
8140 if (endp
== 0 || endp
== 3)
8141 return omit_one_operand (type
, dest
, expr
);
8147 len
= fold_build2 (MINUS_EXPR
, TREE_TYPE (len
), len
,
8150 len
= fold_convert (TREE_TYPE (dest
), len
);
8151 dest
= fold_build2 (PLUS_EXPR
, TREE_TYPE (dest
), dest
, len
);
8152 dest
= fold_convert (type
, dest
);
8154 dest
= omit_one_operand (type
, dest
, expr
);
8158 /* Fold function call to builtin bcopy. Return NULL_TREE if no
8159 simplification can be made. */
8162 fold_builtin_bcopy (tree arglist
, bool ignore
)
8164 tree src
, dest
, size
, newarglist
;
8166 if (!validate_arglist (arglist
,
8167 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
8173 src
= TREE_VALUE (arglist
);
8174 dest
= TREE_VALUE (TREE_CHAIN (arglist
));
8175 size
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
8177 /* New argument list transforming bcopy(ptr x, ptr y, int z) to
8178 memmove(ptr y, ptr x, size_t z). This is done this way
8179 so that if it isn't expanded inline, we fallback to
8180 calling bcopy instead of memmove. */
8182 newarglist
= build_tree_list (NULL_TREE
, fold_convert (sizetype
, size
));
8183 newarglist
= tree_cons (NULL_TREE
, src
, newarglist
);
8184 newarglist
= tree_cons (NULL_TREE
, dest
, newarglist
);
8186 return fold_builtin_memory_op (newarglist
, void_type_node
, true, /*endp=*/3);
8189 /* Fold function call to builtin strcpy. If LEN is not NULL, it represents
8190 the length of the string to be copied. Return NULL_TREE if no
8191 simplification can be made. */
8194 fold_builtin_strcpy (tree fndecl
, tree arglist
, tree len
)
8198 if (!validate_arglist (arglist
,
8199 POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
8202 dest
= TREE_VALUE (arglist
);
8203 src
= TREE_VALUE (TREE_CHAIN (arglist
));
8205 /* If SRC and DEST are the same (and not volatile), return DEST. */
8206 if (operand_equal_p (src
, dest
, 0))
8207 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl
)), dest
);
8212 fn
= implicit_built_in_decls
[BUILT_IN_MEMCPY
];
8218 len
= c_strlen (src
, 1);
8219 if (! len
|| TREE_SIDE_EFFECTS (len
))
8223 len
= size_binop (PLUS_EXPR
, len
, ssize_int (1));
8224 arglist
= build_tree_list (NULL_TREE
, len
);
8225 arglist
= tree_cons (NULL_TREE
, src
, arglist
);
8226 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
8227 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl
)),
8228 build_function_call_expr (fn
, arglist
));
8231 /* Fold function call to builtin strncpy. If SLEN is not NULL, it represents
8232 the length of the source string. Return NULL_TREE if no simplification
8236 fold_builtin_strncpy (tree fndecl
, tree arglist
, tree slen
)
8238 tree dest
, src
, len
, fn
;
8240 if (!validate_arglist (arglist
,
8241 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
8244 dest
= TREE_VALUE (arglist
);
8245 src
= TREE_VALUE (TREE_CHAIN (arglist
));
8246 len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
8248 /* If the LEN parameter is zero, return DEST. */
8249 if (integer_zerop (len
))
8250 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl
)), dest
, src
);
8252 /* We can't compare slen with len as constants below if len is not a
8254 if (len
== 0 || TREE_CODE (len
) != INTEGER_CST
)
8258 slen
= c_strlen (src
, 1);
8260 /* Now, we must be passed a constant src ptr parameter. */
8261 if (slen
== 0 || TREE_CODE (slen
) != INTEGER_CST
)
8264 slen
= size_binop (PLUS_EXPR
, slen
, ssize_int (1));
8266 /* We do not support simplification of this case, though we do
8267 support it when expanding trees into RTL. */
8268 /* FIXME: generate a call to __builtin_memset. */
8269 if (tree_int_cst_lt (slen
, len
))
8272 /* OK transform into builtin memcpy. */
8273 fn
= implicit_built_in_decls
[BUILT_IN_MEMCPY
];
8276 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl
)),
8277 build_function_call_expr (fn
, arglist
));
8280 /* Fold function call to builtin memcmp. Return
8281 NULL_TREE if no simplification can be made. */
8284 fold_builtin_memcmp (tree arglist
)
8286 tree arg1
, arg2
, len
;
8287 const char *p1
, *p2
;
8289 if (!validate_arglist (arglist
,
8290 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
8293 arg1
= TREE_VALUE (arglist
);
8294 arg2
= TREE_VALUE (TREE_CHAIN (arglist
));
8295 len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
8297 /* If the LEN parameter is zero, return zero. */
8298 if (integer_zerop (len
))
8299 return omit_two_operands (integer_type_node
, integer_zero_node
,
8302 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
8303 if (operand_equal_p (arg1
, arg2
, 0))
8304 return omit_one_operand (integer_type_node
, integer_zero_node
, len
);
8306 p1
= c_getstr (arg1
);
8307 p2
= c_getstr (arg2
);
8309 /* If all arguments are constant, and the value of len is not greater
8310 than the lengths of arg1 and arg2, evaluate at compile-time. */
8311 if (host_integerp (len
, 1) && p1
&& p2
8312 && compare_tree_int (len
, strlen (p1
) + 1) <= 0
8313 && compare_tree_int (len
, strlen (p2
) + 1) <= 0)
8315 const int r
= memcmp (p1
, p2
, tree_low_cst (len
, 1));
8318 return integer_one_node
;
8320 return integer_minus_one_node
;
8322 return integer_zero_node
;
8325 /* If len parameter is one, return an expression corresponding to
8326 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
8327 if (host_integerp (len
, 1) && tree_low_cst (len
, 1) == 1)
8329 tree cst_uchar_node
= build_type_variant (unsigned_char_type_node
, 1, 0);
8330 tree cst_uchar_ptr_node
8331 = build_pointer_type_for_mode (cst_uchar_node
, ptr_mode
, true);
8333 tree ind1
= fold_convert (integer_type_node
,
8334 build1 (INDIRECT_REF
, cst_uchar_node
,
8335 fold_convert (cst_uchar_ptr_node
,
8337 tree ind2
= fold_convert (integer_type_node
,
8338 build1 (INDIRECT_REF
, cst_uchar_node
,
8339 fold_convert (cst_uchar_ptr_node
,
8341 return fold_build2 (MINUS_EXPR
, integer_type_node
, ind1
, ind2
);
8347 /* Fold function call to builtin strcmp. Return
8348 NULL_TREE if no simplification can be made. */
8351 fold_builtin_strcmp (tree arglist
)
8354 const char *p1
, *p2
;
8356 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
8359 arg1
= TREE_VALUE (arglist
);
8360 arg2
= TREE_VALUE (TREE_CHAIN (arglist
));
8362 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
8363 if (operand_equal_p (arg1
, arg2
, 0))
8364 return integer_zero_node
;
8366 p1
= c_getstr (arg1
);
8367 p2
= c_getstr (arg2
);
8371 const int i
= strcmp (p1
, p2
);
8373 return integer_minus_one_node
;
8375 return integer_one_node
;
8377 return integer_zero_node
;
8380 /* If the second arg is "", return *(const unsigned char*)arg1. */
8381 if (p2
&& *p2
== '\0')
8383 tree cst_uchar_node
= build_type_variant (unsigned_char_type_node
, 1, 0);
8384 tree cst_uchar_ptr_node
8385 = build_pointer_type_for_mode (cst_uchar_node
, ptr_mode
, true);
8387 return fold_convert (integer_type_node
,
8388 build1 (INDIRECT_REF
, cst_uchar_node
,
8389 fold_convert (cst_uchar_ptr_node
,
8393 /* If the first arg is "", return -*(const unsigned char*)arg2. */
8394 if (p1
&& *p1
== '\0')
8396 tree cst_uchar_node
= build_type_variant (unsigned_char_type_node
, 1, 0);
8397 tree cst_uchar_ptr_node
8398 = build_pointer_type_for_mode (cst_uchar_node
, ptr_mode
, true);
8400 tree temp
= fold_convert (integer_type_node
,
8401 build1 (INDIRECT_REF
, cst_uchar_node
,
8402 fold_convert (cst_uchar_ptr_node
,
8404 return fold_build1 (NEGATE_EXPR
, integer_type_node
, temp
);
8410 /* Fold function call to builtin strncmp. Return
8411 NULL_TREE if no simplification can be made. */
8414 fold_builtin_strncmp (tree arglist
)
8416 tree arg1
, arg2
, len
;
8417 const char *p1
, *p2
;
8419 if (!validate_arglist (arglist
,
8420 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
8423 arg1
= TREE_VALUE (arglist
);
8424 arg2
= TREE_VALUE (TREE_CHAIN (arglist
));
8425 len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
8427 /* If the LEN parameter is zero, return zero. */
8428 if (integer_zerop (len
))
8429 return omit_two_operands (integer_type_node
, integer_zero_node
,
8432 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
8433 if (operand_equal_p (arg1
, arg2
, 0))
8434 return omit_one_operand (integer_type_node
, integer_zero_node
, len
);
8436 p1
= c_getstr (arg1
);
8437 p2
= c_getstr (arg2
);
8439 if (host_integerp (len
, 1) && p1
&& p2
)
8441 const int i
= strncmp (p1
, p2
, tree_low_cst (len
, 1));
8443 return integer_one_node
;
8445 return integer_minus_one_node
;
8447 return integer_zero_node
;
8450 /* If the second arg is "", and the length is greater than zero,
8451 return *(const unsigned char*)arg1. */
8452 if (p2
&& *p2
== '\0'
8453 && TREE_CODE (len
) == INTEGER_CST
8454 && tree_int_cst_sgn (len
) == 1)
8456 tree cst_uchar_node
= build_type_variant (unsigned_char_type_node
, 1, 0);
8457 tree cst_uchar_ptr_node
8458 = build_pointer_type_for_mode (cst_uchar_node
, ptr_mode
, true);
8460 return fold_convert (integer_type_node
,
8461 build1 (INDIRECT_REF
, cst_uchar_node
,
8462 fold_convert (cst_uchar_ptr_node
,
8466 /* If the first arg is "", and the length is greater than zero,
8467 return -*(const unsigned char*)arg2. */
8468 if (p1
&& *p1
== '\0'
8469 && TREE_CODE (len
) == INTEGER_CST
8470 && tree_int_cst_sgn (len
) == 1)
8472 tree cst_uchar_node
= build_type_variant (unsigned_char_type_node
, 1, 0);
8473 tree cst_uchar_ptr_node
8474 = build_pointer_type_for_mode (cst_uchar_node
, ptr_mode
, true);
8476 tree temp
= fold_convert (integer_type_node
,
8477 build1 (INDIRECT_REF
, cst_uchar_node
,
8478 fold_convert (cst_uchar_ptr_node
,
8480 return fold_build1 (NEGATE_EXPR
, integer_type_node
, temp
);
8483 /* If len parameter is one, return an expression corresponding to
8484 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
8485 if (host_integerp (len
, 1) && tree_low_cst (len
, 1) == 1)
8487 tree cst_uchar_node
= build_type_variant (unsigned_char_type_node
, 1, 0);
8488 tree cst_uchar_ptr_node
8489 = build_pointer_type_for_mode (cst_uchar_node
, ptr_mode
, true);
8491 tree ind1
= fold_convert (integer_type_node
,
8492 build1 (INDIRECT_REF
, cst_uchar_node
,
8493 fold_convert (cst_uchar_ptr_node
,
8495 tree ind2
= fold_convert (integer_type_node
,
8496 build1 (INDIRECT_REF
, cst_uchar_node
,
8497 fold_convert (cst_uchar_ptr_node
,
8499 return fold_build2 (MINUS_EXPR
, integer_type_node
, ind1
, ind2
);
8505 /* Fold function call to builtin signbit, signbitf or signbitl. Return
8506 NULL_TREE if no simplification can be made. */
8509 fold_builtin_signbit (tree fndecl
, tree arglist
)
8511 tree type
= TREE_TYPE (TREE_TYPE (fndecl
));
8514 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
8517 arg
= TREE_VALUE (arglist
);
8519 /* If ARG is a compile-time constant, determine the result. */
8520 if (TREE_CODE (arg
) == REAL_CST
8521 && !TREE_CONSTANT_OVERFLOW (arg
))
8525 c
= TREE_REAL_CST (arg
);
8526 temp
= REAL_VALUE_NEGATIVE (c
) ? integer_one_node
: integer_zero_node
;
8527 return fold_convert (type
, temp
);
8530 /* If ARG is non-negative, the result is always zero. */
8531 if (tree_expr_nonnegative_p (arg
))
8532 return omit_one_operand (type
, integer_zero_node
, arg
);
8534 /* If ARG's format doesn't have signed zeros, return "arg < 0.0". */
8535 if (!HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg
))))
8536 return fold_build2 (LT_EXPR
, type
, arg
,
8537 build_real (TREE_TYPE (arg
), dconst0
));
8542 /* Fold function call to builtin copysign, copysignf or copysignl.
8543 Return NULL_TREE if no simplification can be made. */
8546 fold_builtin_copysign (tree fndecl
, tree arglist
, tree type
)
8548 tree arg1
, arg2
, tem
;
8550 if (!validate_arglist (arglist
, REAL_TYPE
, REAL_TYPE
, VOID_TYPE
))
8553 arg1
= TREE_VALUE (arglist
);
8554 arg2
= TREE_VALUE (TREE_CHAIN (arglist
));
8556 /* copysign(X,X) is X. */
8557 if (operand_equal_p (arg1
, arg2
, 0))
8558 return fold_convert (type
, arg1
);
8560 /* If ARG1 and ARG2 are compile-time constants, determine the result. */
8561 if (TREE_CODE (arg1
) == REAL_CST
8562 && TREE_CODE (arg2
) == REAL_CST
8563 && !TREE_CONSTANT_OVERFLOW (arg1
)
8564 && !TREE_CONSTANT_OVERFLOW (arg2
))
8566 REAL_VALUE_TYPE c1
, c2
;
8568 c1
= TREE_REAL_CST (arg1
);
8569 c2
= TREE_REAL_CST (arg2
);
8570 /* c1.sign := c2.sign. */
8571 real_copysign (&c1
, &c2
);
8572 return build_real (type
, c1
);
8575 /* copysign(X, Y) is fabs(X) when Y is always non-negative.
8576 Remember to evaluate Y for side-effects. */
8577 if (tree_expr_nonnegative_p (arg2
))
8578 return omit_one_operand (type
,
8579 fold_build1 (ABS_EXPR
, type
, arg1
),
8582 /* Strip sign changing operations for the first argument. */
8583 tem
= fold_strip_sign_ops (arg1
);
8586 arglist
= tree_cons (NULL_TREE
, tem
, TREE_CHAIN (arglist
));
8587 return build_function_call_expr (fndecl
, arglist
);
8593 /* Fold a call to builtin isascii. */
8596 fold_builtin_isascii (tree arglist
)
8598 if (! validate_arglist (arglist
, INTEGER_TYPE
, VOID_TYPE
))
8602 /* Transform isascii(c) -> ((c & ~0x7f) == 0). */
8603 tree arg
= TREE_VALUE (arglist
);
8605 arg
= build2 (BIT_AND_EXPR
, integer_type_node
, arg
,
8606 build_int_cst (NULL_TREE
,
8607 ~ (unsigned HOST_WIDE_INT
) 0x7f));
8608 arg
= fold_build2 (EQ_EXPR
, integer_type_node
,
8609 arg
, integer_zero_node
);
8611 if (in_gimple_form
&& !TREE_CONSTANT (arg
))
8618 /* Fold a call to builtin toascii. */
8621 fold_builtin_toascii (tree arglist
)
8623 if (! validate_arglist (arglist
, INTEGER_TYPE
, VOID_TYPE
))
8627 /* Transform toascii(c) -> (c & 0x7f). */
8628 tree arg
= TREE_VALUE (arglist
);
8630 return fold_build2 (BIT_AND_EXPR
, integer_type_node
, arg
,
8631 build_int_cst (NULL_TREE
, 0x7f));
8635 /* Fold a call to builtin isdigit. */
8638 fold_builtin_isdigit (tree arglist
)
8640 if (! validate_arglist (arglist
, INTEGER_TYPE
, VOID_TYPE
))
8644 /* Transform isdigit(c) -> (unsigned)(c) - '0' <= 9. */
8645 /* According to the C standard, isdigit is unaffected by locale.
8646 However, it definitely is affected by the target character set. */
8648 unsigned HOST_WIDE_INT target_digit0
8649 = lang_hooks
.to_target_charset ('0');
8651 if (target_digit0
== 0)
8654 arg
= fold_convert (unsigned_type_node
, TREE_VALUE (arglist
));
8655 arg
= build2 (MINUS_EXPR
, unsigned_type_node
, arg
,
8656 build_int_cst (unsigned_type_node
, target_digit0
));
8657 arg
= fold_build2 (LE_EXPR
, integer_type_node
, arg
,
8658 build_int_cst (unsigned_type_node
, 9));
8659 if (in_gimple_form
&& !TREE_CONSTANT (arg
))
8666 /* Fold a call to fabs, fabsf or fabsl. */
8669 fold_builtin_fabs (tree arglist
, tree type
)
8673 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
8676 arg
= TREE_VALUE (arglist
);
8677 arg
= fold_convert (type
, arg
);
8678 if (TREE_CODE (arg
) == REAL_CST
)
8679 return fold_abs_const (arg
, type
);
8680 return fold_build1 (ABS_EXPR
, type
, arg
);
8683 /* Fold a call to abs, labs, llabs or imaxabs. */
8686 fold_builtin_abs (tree arglist
, tree type
)
8690 if (!validate_arglist (arglist
, INTEGER_TYPE
, VOID_TYPE
))
8693 arg
= TREE_VALUE (arglist
);
8694 arg
= fold_convert (type
, arg
);
8695 if (TREE_CODE (arg
) == INTEGER_CST
)
8696 return fold_abs_const (arg
, type
);
8697 return fold_build1 (ABS_EXPR
, type
, arg
);
8700 /* Fold a call to __builtin_isnan(), __builtin_isinf, __builtin_finite.
8701 EXP is the CALL_EXPR for the call. */
8704 fold_builtin_classify (tree fndecl
, tree arglist
, int builtin_index
)
8706 tree type
= TREE_TYPE (TREE_TYPE (fndecl
));
8710 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
8712 /* Check that we have exactly one argument. */
8715 error ("too few arguments to function %qs",
8716 IDENTIFIER_POINTER (DECL_NAME (fndecl
)));
8717 return error_mark_node
;
8719 else if (TREE_CHAIN (arglist
) != 0)
8721 error ("too many arguments to function %qs",
8722 IDENTIFIER_POINTER (DECL_NAME (fndecl
)));
8723 return error_mark_node
;
8727 error ("non-floating-point argument to function %qs",
8728 IDENTIFIER_POINTER (DECL_NAME (fndecl
)));
8729 return error_mark_node
;
8733 arg
= TREE_VALUE (arglist
);
8734 switch (builtin_index
)
8736 case BUILT_IN_ISINF
:
8737 if (!HONOR_INFINITIES (TYPE_MODE (TREE_TYPE (arg
))))
8738 return omit_one_operand (type
, integer_zero_node
, arg
);
8740 if (TREE_CODE (arg
) == REAL_CST
)
8742 r
= TREE_REAL_CST (arg
);
8743 if (real_isinf (&r
))
8744 return real_compare (GT_EXPR
, &r
, &dconst0
)
8745 ? integer_one_node
: integer_minus_one_node
;
8747 return integer_zero_node
;
8752 case BUILT_IN_FINITE
:
8753 if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg
)))
8754 && !HONOR_INFINITIES (TYPE_MODE (TREE_TYPE (arg
))))
8755 return omit_one_operand (type
, integer_one_node
, arg
);
8757 if (TREE_CODE (arg
) == REAL_CST
)
8759 r
= TREE_REAL_CST (arg
);
8760 return real_isinf (&r
) || real_isnan (&r
)
8761 ? integer_zero_node
: integer_one_node
;
8766 case BUILT_IN_ISNAN
:
8767 if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg
))))
8768 return omit_one_operand (type
, integer_zero_node
, arg
);
8770 if (TREE_CODE (arg
) == REAL_CST
)
8772 r
= TREE_REAL_CST (arg
);
8773 return real_isnan (&r
) ? integer_one_node
: integer_zero_node
;
8776 arg
= builtin_save_expr (arg
);
8777 return fold_build2 (UNORDERED_EXPR
, type
, arg
, arg
);
8784 /* Fold a call to an unordered comparison function such as
8785 __builtin_isgreater(). FNDECL is the FUNCTION_DECL for the function
8786 being called and ARGLIST is the argument list for the call.
8787 UNORDERED_CODE and ORDERED_CODE are comparison codes that give
8788 the opposite of the desired result. UNORDERED_CODE is used
8789 for modes that can hold NaNs and ORDERED_CODE is used for
8793 fold_builtin_unordered_cmp (tree fndecl
, tree arglist
,
8794 enum tree_code unordered_code
,
8795 enum tree_code ordered_code
)
8797 tree type
= TREE_TYPE (TREE_TYPE (fndecl
));
8798 enum tree_code code
;
8801 enum tree_code code0
, code1
;
8802 tree cmp_type
= NULL_TREE
;
8804 if (!validate_arglist (arglist
, REAL_TYPE
, REAL_TYPE
, VOID_TYPE
))
8806 /* Check that we have exactly two arguments. */
8807 if (arglist
== 0 || TREE_CHAIN (arglist
) == 0)
8809 error ("too few arguments to function %qs",
8810 IDENTIFIER_POINTER (DECL_NAME (fndecl
)));
8811 return error_mark_node
;
8813 else if (TREE_CHAIN (TREE_CHAIN (arglist
)) != 0)
8815 error ("too many arguments to function %qs",
8816 IDENTIFIER_POINTER (DECL_NAME (fndecl
)));
8817 return error_mark_node
;
8821 arg0
= TREE_VALUE (arglist
);
8822 arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
8824 type0
= TREE_TYPE (arg0
);
8825 type1
= TREE_TYPE (arg1
);
8827 code0
= TREE_CODE (type0
);
8828 code1
= TREE_CODE (type1
);
8830 if (code0
== REAL_TYPE
&& code1
== REAL_TYPE
)
8831 /* Choose the wider of two real types. */
8832 cmp_type
= TYPE_PRECISION (type0
) >= TYPE_PRECISION (type1
)
8834 else if (code0
== REAL_TYPE
&& code1
== INTEGER_TYPE
)
8836 else if (code0
== INTEGER_TYPE
&& code1
== REAL_TYPE
)
8840 error ("non-floating-point argument to function %qs",
8841 IDENTIFIER_POINTER (DECL_NAME (fndecl
)));
8842 return error_mark_node
;
8845 arg0
= fold_convert (cmp_type
, arg0
);
8846 arg1
= fold_convert (cmp_type
, arg1
);
8848 if (unordered_code
== UNORDERED_EXPR
)
8850 if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg0
))))
8851 return omit_two_operands (type
, integer_zero_node
, arg0
, arg1
);
8852 return fold_build2 (UNORDERED_EXPR
, type
, arg0
, arg1
);
8855 code
= HONOR_NANS (TYPE_MODE (TREE_TYPE (arg0
))) ? unordered_code
8857 return fold_build1 (TRUTH_NOT_EXPR
, type
,
8858 fold_build2 (code
, type
, arg0
, arg1
));
8861 /* Used by constant folding to simplify calls to builtin functions. EXP is
8862 the CALL_EXPR of a call to a builtin function. IGNORE is true if the
8863 result of the function call is ignored. This function returns NULL_TREE
8864 if no simplification was possible. */
8867 fold_builtin_1 (tree fndecl
, tree arglist
, bool ignore
)
8869 tree type
= TREE_TYPE (TREE_TYPE (fndecl
));
8870 enum built_in_function fcode
;
8872 if (DECL_BUILT_IN_CLASS (fndecl
) == BUILT_IN_MD
)
8873 return targetm
.fold_builtin (fndecl
, arglist
, ignore
);
8875 fcode
= DECL_FUNCTION_CODE (fndecl
);
8878 case BUILT_IN_FPUTS
:
8879 return fold_builtin_fputs (arglist
, ignore
, false, NULL_TREE
);
8881 case BUILT_IN_FPUTS_UNLOCKED
:
8882 return fold_builtin_fputs (arglist
, ignore
, true, NULL_TREE
);
8884 case BUILT_IN_STRSTR
:
8885 return fold_builtin_strstr (arglist
, type
);
8887 case BUILT_IN_STRCAT
:
8888 return fold_builtin_strcat (arglist
);
8890 case BUILT_IN_STRNCAT
:
8891 return fold_builtin_strncat (arglist
);
8893 case BUILT_IN_STRSPN
:
8894 return fold_builtin_strspn (arglist
);
8896 case BUILT_IN_STRCSPN
:
8897 return fold_builtin_strcspn (arglist
);
8899 case BUILT_IN_STRCHR
:
8900 case BUILT_IN_INDEX
:
8901 return fold_builtin_strchr (arglist
, type
);
8903 case BUILT_IN_STRRCHR
:
8904 case BUILT_IN_RINDEX
:
8905 return fold_builtin_strrchr (arglist
, type
);
8907 case BUILT_IN_STRCPY
:
8908 return fold_builtin_strcpy (fndecl
, arglist
, NULL_TREE
);
8910 case BUILT_IN_STRNCPY
:
8911 return fold_builtin_strncpy (fndecl
, arglist
, NULL_TREE
);
8913 case BUILT_IN_STRCMP
:
8914 return fold_builtin_strcmp (arglist
);
8916 case BUILT_IN_STRNCMP
:
8917 return fold_builtin_strncmp (arglist
);
8919 case BUILT_IN_STRPBRK
:
8920 return fold_builtin_strpbrk (arglist
, type
);
8923 case BUILT_IN_MEMCMP
:
8924 return fold_builtin_memcmp (arglist
);
8926 case BUILT_IN_SPRINTF
:
8927 return fold_builtin_sprintf (arglist
, ignore
);
8929 case BUILT_IN_CONSTANT_P
:
8933 val
= fold_builtin_constant_p (arglist
);
8934 /* Gimplification will pull the CALL_EXPR for the builtin out of
8935 an if condition. When not optimizing, we'll not CSE it back.
8936 To avoid link error types of regressions, return false now. */
8937 if (!val
&& !optimize
)
8938 val
= integer_zero_node
;
8943 case BUILT_IN_EXPECT
:
8944 return fold_builtin_expect (arglist
);
8946 case BUILT_IN_CLASSIFY_TYPE
:
8947 return fold_builtin_classify_type (arglist
);
8949 case BUILT_IN_STRLEN
:
8950 return fold_builtin_strlen (arglist
);
8952 CASE_FLT_FN (BUILT_IN_FABS
):
8953 return fold_builtin_fabs (arglist
, type
);
8957 case BUILT_IN_LLABS
:
8958 case BUILT_IN_IMAXABS
:
8959 return fold_builtin_abs (arglist
, type
);
8961 CASE_FLT_FN (BUILT_IN_CONJ
):
8962 if (validate_arglist (arglist
, COMPLEX_TYPE
, VOID_TYPE
))
8963 return fold_build1 (CONJ_EXPR
, type
, TREE_VALUE (arglist
));
8966 CASE_FLT_FN (BUILT_IN_CREAL
):
8967 if (validate_arglist (arglist
, COMPLEX_TYPE
, VOID_TYPE
))
8968 return non_lvalue (fold_build1 (REALPART_EXPR
, type
,
8969 TREE_VALUE (arglist
)));
8972 CASE_FLT_FN (BUILT_IN_CIMAG
):
8973 if (validate_arglist (arglist
, COMPLEX_TYPE
, VOID_TYPE
))
8974 return non_lvalue (fold_build1 (IMAGPART_EXPR
, type
,
8975 TREE_VALUE (arglist
)));
8978 CASE_FLT_FN (BUILT_IN_CABS
):
8979 return fold_builtin_cabs (arglist
, type
, fndecl
);
8981 CASE_FLT_FN (BUILT_IN_SQRT
):
8982 return fold_builtin_sqrt (arglist
, type
);
8984 CASE_FLT_FN (BUILT_IN_CBRT
):
8985 return fold_builtin_cbrt (arglist
, type
);
8987 CASE_FLT_FN (BUILT_IN_ASIN
):
8988 if (validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
8989 return do_mpfr_arg1 (TREE_VALUE (arglist
), type
, mpfr_asin
,
8990 &dconstm1
, &dconst1
, true);
8993 CASE_FLT_FN (BUILT_IN_ACOS
):
8994 if (validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
8995 return do_mpfr_arg1 (TREE_VALUE (arglist
), type
, mpfr_acos
,
8996 &dconstm1
, &dconst1
, true);
8999 CASE_FLT_FN (BUILT_IN_ATAN
):
9000 if (validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
9001 return do_mpfr_arg1 (TREE_VALUE (arglist
), type
, mpfr_atan
,
9005 CASE_FLT_FN (BUILT_IN_ASINH
):
9006 if (validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
9007 return do_mpfr_arg1 (TREE_VALUE (arglist
), type
, mpfr_asinh
,
9011 CASE_FLT_FN (BUILT_IN_ACOSH
):
9012 if (validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
9013 return do_mpfr_arg1 (TREE_VALUE (arglist
), type
, mpfr_acosh
,
9014 &dconst1
, NULL
, true);
9017 CASE_FLT_FN (BUILT_IN_ATANH
):
9018 if (validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
9019 return do_mpfr_arg1 (TREE_VALUE (arglist
), type
, mpfr_atanh
,
9020 &dconstm1
, &dconst1
, false);
9023 CASE_FLT_FN (BUILT_IN_SIN
):
9024 if (validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
9025 return do_mpfr_arg1 (TREE_VALUE (arglist
), type
, mpfr_sin
,
9029 CASE_FLT_FN (BUILT_IN_COS
):
9030 return fold_builtin_cos (arglist
, type
, fndecl
);
9032 CASE_FLT_FN (BUILT_IN_TAN
):
9033 return fold_builtin_tan (arglist
, type
);
9035 CASE_FLT_FN (BUILT_IN_SINH
):
9036 if (validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
9037 return do_mpfr_arg1 (TREE_VALUE (arglist
), type
, mpfr_sinh
,
9041 CASE_FLT_FN (BUILT_IN_COSH
):
9042 if (validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
9043 return do_mpfr_arg1 (TREE_VALUE (arglist
), type
, mpfr_cosh
,
9047 CASE_FLT_FN (BUILT_IN_TANH
):
9048 if (validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
9049 return do_mpfr_arg1 (TREE_VALUE (arglist
), type
, mpfr_tanh
,
9053 CASE_FLT_FN (BUILT_IN_ERF
):
9054 if (validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
9055 return do_mpfr_arg1 (TREE_VALUE (arglist
), type
, mpfr_erf
,
9059 CASE_FLT_FN (BUILT_IN_ERFC
):
9060 if (validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
9061 return do_mpfr_arg1 (TREE_VALUE (arglist
), type
, mpfr_erfc
,
9065 CASE_FLT_FN (BUILT_IN_EXP
):
9066 return fold_builtin_exponent (fndecl
, arglist
, mpfr_exp
);
9068 CASE_FLT_FN (BUILT_IN_EXP2
):
9069 return fold_builtin_exponent (fndecl
, arglist
, mpfr_exp2
);
9071 CASE_FLT_FN (BUILT_IN_EXP10
):
9072 CASE_FLT_FN (BUILT_IN_POW10
):
9073 return fold_builtin_exponent (fndecl
, arglist
, mpfr_exp10
);
9075 CASE_FLT_FN (BUILT_IN_EXPM1
):
9076 if (validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
9077 return do_mpfr_arg1 (TREE_VALUE (arglist
), type
, mpfr_expm1
,
9081 CASE_FLT_FN (BUILT_IN_LOG
):
9082 return fold_builtin_logarithm (fndecl
, arglist
, mpfr_log
);
9084 CASE_FLT_FN (BUILT_IN_LOG2
):
9085 return fold_builtin_logarithm (fndecl
, arglist
, mpfr_log2
);
9087 CASE_FLT_FN (BUILT_IN_LOG10
):
9088 return fold_builtin_logarithm (fndecl
, arglist
, mpfr_log10
);
9090 CASE_FLT_FN (BUILT_IN_LOG1P
):
9091 if (validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
9092 return do_mpfr_arg1 (TREE_VALUE (arglist
), type
, mpfr_log1p
,
9093 &dconstm1
, NULL
, false);
9096 CASE_FLT_FN (BUILT_IN_POW
):
9097 return fold_builtin_pow (fndecl
, arglist
, type
);
9099 CASE_FLT_FN (BUILT_IN_POWI
):
9100 return fold_builtin_powi (fndecl
, arglist
, type
);
9102 CASE_FLT_FN (BUILT_IN_INF
):
9103 case BUILT_IN_INFD32
:
9104 case BUILT_IN_INFD64
:
9105 case BUILT_IN_INFD128
:
9106 return fold_builtin_inf (type
, true);
9108 CASE_FLT_FN (BUILT_IN_HUGE_VAL
):
9109 return fold_builtin_inf (type
, false);
9111 CASE_FLT_FN (BUILT_IN_NAN
):
9112 case BUILT_IN_NAND32
:
9113 case BUILT_IN_NAND64
:
9114 case BUILT_IN_NAND128
:
9115 return fold_builtin_nan (arglist
, type
, true);
9117 CASE_FLT_FN (BUILT_IN_NANS
):
9118 return fold_builtin_nan (arglist
, type
, false);
9120 CASE_FLT_FN (BUILT_IN_FLOOR
):
9121 return fold_builtin_floor (fndecl
, arglist
);
9123 CASE_FLT_FN (BUILT_IN_CEIL
):
9124 return fold_builtin_ceil (fndecl
, arglist
);
9126 CASE_FLT_FN (BUILT_IN_TRUNC
):
9127 return fold_builtin_trunc (fndecl
, arglist
);
9129 CASE_FLT_FN (BUILT_IN_ROUND
):
9130 return fold_builtin_round (fndecl
, arglist
);
9132 CASE_FLT_FN (BUILT_IN_NEARBYINT
):
9133 CASE_FLT_FN (BUILT_IN_RINT
):
9134 return fold_trunc_transparent_mathfn (fndecl
, arglist
);
9136 CASE_FLT_FN (BUILT_IN_LCEIL
):
9137 CASE_FLT_FN (BUILT_IN_LLCEIL
):
9138 CASE_FLT_FN (BUILT_IN_LFLOOR
):
9139 CASE_FLT_FN (BUILT_IN_LLFLOOR
):
9140 CASE_FLT_FN (BUILT_IN_LROUND
):
9141 CASE_FLT_FN (BUILT_IN_LLROUND
):
9142 return fold_builtin_int_roundingfn (fndecl
, arglist
);
9144 CASE_FLT_FN (BUILT_IN_LRINT
):
9145 CASE_FLT_FN (BUILT_IN_LLRINT
):
9146 return fold_fixed_mathfn (fndecl
, arglist
);
9148 CASE_INT_FN (BUILT_IN_FFS
):
9149 CASE_INT_FN (BUILT_IN_CLZ
):
9150 CASE_INT_FN (BUILT_IN_CTZ
):
9151 CASE_INT_FN (BUILT_IN_POPCOUNT
):
9152 CASE_INT_FN (BUILT_IN_PARITY
):
9153 return fold_builtin_bitop (fndecl
, arglist
);
9155 case BUILT_IN_MEMSET
:
9156 return fold_builtin_memset (arglist
, type
, ignore
);
9158 case BUILT_IN_MEMCPY
:
9159 return fold_builtin_memory_op (arglist
, type
, ignore
, /*endp=*/0);
9161 case BUILT_IN_MEMPCPY
:
9162 return fold_builtin_memory_op (arglist
, type
, ignore
, /*endp=*/1);
9164 case BUILT_IN_MEMMOVE
:
9165 return fold_builtin_memory_op (arglist
, type
, ignore
, /*endp=*/3);
9167 case BUILT_IN_BZERO
:
9168 return fold_builtin_bzero (arglist
, ignore
);
9170 case BUILT_IN_BCOPY
:
9171 return fold_builtin_bcopy (arglist
, ignore
);
9173 CASE_FLT_FN (BUILT_IN_SIGNBIT
):
9174 return fold_builtin_signbit (fndecl
, arglist
);
9176 case BUILT_IN_ISASCII
:
9177 return fold_builtin_isascii (arglist
);
9179 case BUILT_IN_TOASCII
:
9180 return fold_builtin_toascii (arglist
);
9182 case BUILT_IN_ISDIGIT
:
9183 return fold_builtin_isdigit (arglist
);
9185 CASE_FLT_FN (BUILT_IN_COPYSIGN
):
9186 return fold_builtin_copysign (fndecl
, arglist
, type
);
9188 CASE_FLT_FN (BUILT_IN_FINITE
):
9189 case BUILT_IN_FINITED32
:
9190 case BUILT_IN_FINITED64
:
9191 case BUILT_IN_FINITED128
:
9192 return fold_builtin_classify (fndecl
, arglist
, BUILT_IN_FINITE
);
9194 CASE_FLT_FN (BUILT_IN_ISINF
):
9195 case BUILT_IN_ISINFD32
:
9196 case BUILT_IN_ISINFD64
:
9197 case BUILT_IN_ISINFD128
:
9198 return fold_builtin_classify (fndecl
, arglist
, BUILT_IN_ISINF
);
9200 CASE_FLT_FN (BUILT_IN_ISNAN
):
9201 case BUILT_IN_ISNAND32
:
9202 case BUILT_IN_ISNAND64
:
9203 case BUILT_IN_ISNAND128
:
9204 return fold_builtin_classify (fndecl
, arglist
, BUILT_IN_ISNAN
);
9206 case BUILT_IN_ISGREATER
:
9207 return fold_builtin_unordered_cmp (fndecl
, arglist
, UNLE_EXPR
, LE_EXPR
);
9208 case BUILT_IN_ISGREATEREQUAL
:
9209 return fold_builtin_unordered_cmp (fndecl
, arglist
, UNLT_EXPR
, LT_EXPR
);
9210 case BUILT_IN_ISLESS
:
9211 return fold_builtin_unordered_cmp (fndecl
, arglist
, UNGE_EXPR
, GE_EXPR
);
9212 case BUILT_IN_ISLESSEQUAL
:
9213 return fold_builtin_unordered_cmp (fndecl
, arglist
, UNGT_EXPR
, GT_EXPR
);
9214 case BUILT_IN_ISLESSGREATER
:
9215 return fold_builtin_unordered_cmp (fndecl
, arglist
, UNEQ_EXPR
, EQ_EXPR
);
9216 case BUILT_IN_ISUNORDERED
:
9217 return fold_builtin_unordered_cmp (fndecl
, arglist
, UNORDERED_EXPR
,
9220 /* We do the folding for va_start in the expander. */
9221 case BUILT_IN_VA_START
:
9224 case BUILT_IN_OBJECT_SIZE
:
9225 return fold_builtin_object_size (arglist
);
9226 case BUILT_IN_MEMCPY_CHK
:
9227 case BUILT_IN_MEMPCPY_CHK
:
9228 case BUILT_IN_MEMMOVE_CHK
:
9229 case BUILT_IN_MEMSET_CHK
:
9230 return fold_builtin_memory_chk (fndecl
, arglist
, NULL_TREE
, ignore
,
9231 DECL_FUNCTION_CODE (fndecl
));
9232 case BUILT_IN_STRCPY_CHK
:
9233 case BUILT_IN_STPCPY_CHK
:
9234 return fold_builtin_stxcpy_chk (fndecl
, arglist
, NULL_TREE
, ignore
,
9235 DECL_FUNCTION_CODE (fndecl
));
9236 case BUILT_IN_STRNCPY_CHK
:
9237 return fold_builtin_strncpy_chk (arglist
, NULL_TREE
);
9238 case BUILT_IN_STRCAT_CHK
:
9239 return fold_builtin_strcat_chk (fndecl
, arglist
);
9240 case BUILT_IN_STRNCAT_CHK
:
9241 return fold_builtin_strncat_chk (fndecl
, arglist
);
9242 case BUILT_IN_SPRINTF_CHK
:
9243 case BUILT_IN_VSPRINTF_CHK
:
9244 return fold_builtin_sprintf_chk (arglist
, DECL_FUNCTION_CODE (fndecl
));
9245 case BUILT_IN_SNPRINTF_CHK
:
9246 case BUILT_IN_VSNPRINTF_CHK
:
9247 return fold_builtin_snprintf_chk (arglist
, NULL_TREE
,
9248 DECL_FUNCTION_CODE (fndecl
));
9250 case BUILT_IN_PRINTF
:
9251 case BUILT_IN_PRINTF_UNLOCKED
:
9252 case BUILT_IN_VPRINTF
:
9253 case BUILT_IN_PRINTF_CHK
:
9254 case BUILT_IN_VPRINTF_CHK
:
9255 return fold_builtin_printf (fndecl
, arglist
, ignore
,
9256 DECL_FUNCTION_CODE (fndecl
));
9258 case BUILT_IN_FPRINTF
:
9259 case BUILT_IN_FPRINTF_UNLOCKED
:
9260 case BUILT_IN_VFPRINTF
:
9261 case BUILT_IN_FPRINTF_CHK
:
9262 case BUILT_IN_VFPRINTF_CHK
:
9263 return fold_builtin_fprintf (fndecl
, arglist
, ignore
,
9264 DECL_FUNCTION_CODE (fndecl
));
9273 /* A wrapper function for builtin folding that prevents warnings for
9274 "statement without effect" and the like, caused by removing the
9275 call node earlier than the warning is generated. */
9278 fold_builtin (tree fndecl
, tree arglist
, bool ignore
)
9280 tree exp
= fold_builtin_1 (fndecl
, arglist
, ignore
);
9283 exp
= build1 (NOP_EXPR
, TREE_TYPE (exp
), exp
);
9284 TREE_NO_WARNING (exp
) = 1;
9290 /* Conveniently construct a function call expression. */
9293 build_function_call_expr (tree fn
, tree arglist
)
9297 call_expr
= build1 (ADDR_EXPR
, build_pointer_type (TREE_TYPE (fn
)), fn
);
9298 return fold_build3 (CALL_EXPR
, TREE_TYPE (TREE_TYPE (fn
)),
9299 call_expr
, arglist
, NULL_TREE
);
9302 /* This function validates the types of a function call argument list
9303 represented as a tree chain of parameters against a specified list
9304 of tree_codes. If the last specifier is a 0, that represents an
9305 ellipses, otherwise the last specifier must be a VOID_TYPE. */
9308 validate_arglist (tree arglist
, ...)
9310 enum tree_code code
;
9314 va_start (ap
, arglist
);
9318 code
= va_arg (ap
, enum tree_code
);
9322 /* This signifies an ellipses, any further arguments are all ok. */
9326 /* This signifies an endlink, if no arguments remain, return
9327 true, otherwise return false. */
9331 /* If no parameters remain or the parameter's code does not
9332 match the specified code, return false. Otherwise continue
9333 checking any remaining arguments. */
9336 if (code
== POINTER_TYPE
)
9338 if (! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist
))))
9341 else if (code
!= TREE_CODE (TREE_TYPE (TREE_VALUE (arglist
))))
9345 arglist
= TREE_CHAIN (arglist
);
9349 /* We need gotos here since we can only have one VA_CLOSE in a
9357 /* Default target-specific builtin expander that does nothing. */
9360 default_expand_builtin (tree exp ATTRIBUTE_UNUSED
,
9361 rtx target ATTRIBUTE_UNUSED
,
9362 rtx subtarget ATTRIBUTE_UNUSED
,
9363 enum machine_mode mode ATTRIBUTE_UNUSED
,
9364 int ignore ATTRIBUTE_UNUSED
)
9369 /* Returns true is EXP represents data that would potentially reside
9370 in a readonly section. */
9373 readonly_data_expr (tree exp
)
9377 if (TREE_CODE (exp
) != ADDR_EXPR
)
9380 exp
= get_base_address (TREE_OPERAND (exp
, 0));
9384 /* Make sure we call decl_readonly_section only for trees it
9385 can handle (since it returns true for everything it doesn't
9387 if (TREE_CODE (exp
) == STRING_CST
9388 || TREE_CODE (exp
) == CONSTRUCTOR
9389 || (TREE_CODE (exp
) == VAR_DECL
&& TREE_STATIC (exp
)))
9390 return decl_readonly_section (exp
, 0);
9395 /* Simplify a call to the strstr builtin.
9397 Return 0 if no simplification was possible, otherwise return the
9398 simplified form of the call as a tree.
9400 The simplified form may be a constant or other expression which
9401 computes the same value, but in a more efficient manner (including
9402 calls to other builtin functions).
9404 The call may contain arguments which need to be evaluated, but
9405 which are not useful to determine the result of the call. In
9406 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9407 COMPOUND_EXPR will be an argument which must be evaluated.
9408 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9409 COMPOUND_EXPR in the chain will contain the tree for the simplified
9410 form of the builtin function call. */
9413 fold_builtin_strstr (tree arglist
, tree type
)
9415 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
9419 tree s1
= TREE_VALUE (arglist
), s2
= TREE_VALUE (TREE_CHAIN (arglist
));
9421 const char *p1
, *p2
;
9430 const char *r
= strstr (p1
, p2
);
9434 return build_int_cst (TREE_TYPE (s1
), 0);
9436 /* Return an offset into the constant string argument. */
9437 tem
= fold_build2 (PLUS_EXPR
, TREE_TYPE (s1
),
9438 s1
, build_int_cst (TREE_TYPE (s1
), r
- p1
));
9439 return fold_convert (type
, tem
);
9442 /* The argument is const char *, and the result is char *, so we need
9443 a type conversion here to avoid a warning. */
9445 return fold_convert (type
, s1
);
9450 fn
= implicit_built_in_decls
[BUILT_IN_STRCHR
];
9454 /* New argument list transforming strstr(s1, s2) to
9455 strchr(s1, s2[0]). */
9456 arglist
= build_tree_list (NULL_TREE
,
9457 build_int_cst (NULL_TREE
, p2
[0]));
9458 arglist
= tree_cons (NULL_TREE
, s1
, arglist
);
9459 return build_function_call_expr (fn
, arglist
);
9463 /* Simplify a call to the strchr builtin.
9465 Return 0 if no simplification was possible, otherwise return the
9466 simplified form of the call as a tree.
9468 The simplified form may be a constant or other expression which
9469 computes the same value, but in a more efficient manner (including
9470 calls to other builtin functions).
9472 The call may contain arguments which need to be evaluated, but
9473 which are not useful to determine the result of the call. In
9474 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9475 COMPOUND_EXPR will be an argument which must be evaluated.
9476 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9477 COMPOUND_EXPR in the chain will contain the tree for the simplified
9478 form of the builtin function call. */
9481 fold_builtin_strchr (tree arglist
, tree type
)
9483 if (!validate_arglist (arglist
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
9487 tree s1
= TREE_VALUE (arglist
), s2
= TREE_VALUE (TREE_CHAIN (arglist
));
9490 if (TREE_CODE (s2
) != INTEGER_CST
)
9500 if (target_char_cast (s2
, &c
))
9506 return build_int_cst (TREE_TYPE (s1
), 0);
9508 /* Return an offset into the constant string argument. */
9509 tem
= fold_build2 (PLUS_EXPR
, TREE_TYPE (s1
),
9510 s1
, build_int_cst (TREE_TYPE (s1
), r
- p1
));
9511 return fold_convert (type
, tem
);
9517 /* Simplify a call to the strrchr builtin.
9519 Return 0 if no simplification was possible, otherwise return the
9520 simplified form of the call as a tree.
9522 The simplified form may be a constant or other expression which
9523 computes the same value, but in a more efficient manner (including
9524 calls to other builtin functions).
9526 The call may contain arguments which need to be evaluated, but
9527 which are not useful to determine the result of the call. In
9528 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9529 COMPOUND_EXPR will be an argument which must be evaluated.
9530 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9531 COMPOUND_EXPR in the chain will contain the tree for the simplified
9532 form of the builtin function call. */
9535 fold_builtin_strrchr (tree arglist
, tree type
)
9537 if (!validate_arglist (arglist
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
9541 tree s1
= TREE_VALUE (arglist
), s2
= TREE_VALUE (TREE_CHAIN (arglist
));
9545 if (TREE_CODE (s2
) != INTEGER_CST
)
9555 if (target_char_cast (s2
, &c
))
9558 r
= strrchr (p1
, c
);
9561 return build_int_cst (TREE_TYPE (s1
), 0);
9563 /* Return an offset into the constant string argument. */
9564 tem
= fold_build2 (PLUS_EXPR
, TREE_TYPE (s1
),
9565 s1
, build_int_cst (TREE_TYPE (s1
), r
- p1
));
9566 return fold_convert (type
, tem
);
9569 if (! integer_zerop (s2
))
9572 fn
= implicit_built_in_decls
[BUILT_IN_STRCHR
];
9576 /* Transform strrchr(s1, '\0') to strchr(s1, '\0'). */
9577 return build_function_call_expr (fn
, arglist
);
9581 /* Simplify a call to the strpbrk builtin.
9583 Return 0 if no simplification was possible, otherwise return the
9584 simplified form of the call as a tree.
9586 The simplified form may be a constant or other expression which
9587 computes the same value, but in a more efficient manner (including
9588 calls to other builtin functions).
9590 The call may contain arguments which need to be evaluated, but
9591 which are not useful to determine the result of the call. In
9592 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9593 COMPOUND_EXPR will be an argument which must be evaluated.
9594 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9595 COMPOUND_EXPR in the chain will contain the tree for the simplified
9596 form of the builtin function call. */
9599 fold_builtin_strpbrk (tree arglist
, tree type
)
9601 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
9605 tree s1
= TREE_VALUE (arglist
), s2
= TREE_VALUE (TREE_CHAIN (arglist
));
9607 const char *p1
, *p2
;
9616 const char *r
= strpbrk (p1
, p2
);
9620 return build_int_cst (TREE_TYPE (s1
), 0);
9622 /* Return an offset into the constant string argument. */
9623 tem
= fold_build2 (PLUS_EXPR
, TREE_TYPE (s1
),
9624 s1
, build_int_cst (TREE_TYPE (s1
), r
- p1
));
9625 return fold_convert (type
, tem
);
9629 /* strpbrk(x, "") == NULL.
9630 Evaluate and ignore s1 in case it had side-effects. */
9631 return omit_one_operand (TREE_TYPE (s1
), integer_zero_node
, s1
);
9634 return 0; /* Really call strpbrk. */
9636 fn
= implicit_built_in_decls
[BUILT_IN_STRCHR
];
9640 /* New argument list transforming strpbrk(s1, s2) to
9641 strchr(s1, s2[0]). */
9642 arglist
= build_tree_list (NULL_TREE
,
9643 build_int_cst (NULL_TREE
, p2
[0]));
9644 arglist
= tree_cons (NULL_TREE
, s1
, arglist
);
9645 return build_function_call_expr (fn
, arglist
);
9649 /* Simplify a call to the strcat builtin.
9651 Return 0 if no simplification was possible, otherwise return the
9652 simplified form of the call as a tree.
9654 The simplified form may be a constant or other expression which
9655 computes the same value, but in a more efficient manner (including
9656 calls to other builtin functions).
9658 The call may contain arguments which need to be evaluated, but
9659 which are not useful to determine the result of the call. In
9660 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9661 COMPOUND_EXPR will be an argument which must be evaluated.
9662 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9663 COMPOUND_EXPR in the chain will contain the tree for the simplified
9664 form of the builtin function call. */
9667 fold_builtin_strcat (tree arglist
)
9669 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
9673 tree dst
= TREE_VALUE (arglist
),
9674 src
= TREE_VALUE (TREE_CHAIN (arglist
));
9675 const char *p
= c_getstr (src
);
9677 /* If the string length is zero, return the dst parameter. */
9678 if (p
&& *p
== '\0')
9685 /* Simplify a call to the strncat builtin.
9687 Return 0 if no simplification was possible, otherwise return the
9688 simplified form of the call as a tree.
9690 The simplified form may be a constant or other expression which
9691 computes the same value, but in a more efficient manner (including
9692 calls to other builtin functions).
9694 The call may contain arguments which need to be evaluated, but
9695 which are not useful to determine the result of the call. In
9696 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9697 COMPOUND_EXPR will be an argument which must be evaluated.
9698 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9699 COMPOUND_EXPR in the chain will contain the tree for the simplified
9700 form of the builtin function call. */
9703 fold_builtin_strncat (tree arglist
)
9705 if (!validate_arglist (arglist
,
9706 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
9710 tree dst
= TREE_VALUE (arglist
);
9711 tree src
= TREE_VALUE (TREE_CHAIN (arglist
));
9712 tree len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
9713 const char *p
= c_getstr (src
);
9715 /* If the requested length is zero, or the src parameter string
9716 length is zero, return the dst parameter. */
9717 if (integer_zerop (len
) || (p
&& *p
== '\0'))
9718 return omit_two_operands (TREE_TYPE (dst
), dst
, src
, len
);
9720 /* If the requested len is greater than or equal to the string
9721 length, call strcat. */
9722 if (TREE_CODE (len
) == INTEGER_CST
&& p
9723 && compare_tree_int (len
, strlen (p
)) >= 0)
9726 = tree_cons (NULL_TREE
, dst
, build_tree_list (NULL_TREE
, src
));
9727 tree fn
= implicit_built_in_decls
[BUILT_IN_STRCAT
];
9729 /* If the replacement _DECL isn't initialized, don't do the
9734 return build_function_call_expr (fn
, newarglist
);
9740 /* Simplify a call to the strspn builtin.
9742 Return 0 if no simplification was possible, otherwise return the
9743 simplified form of the call as a tree.
9745 The simplified form may be a constant or other expression which
9746 computes the same value, but in a more efficient manner (including
9747 calls to other builtin functions).
9749 The call may contain arguments which need to be evaluated, but
9750 which are not useful to determine the result of the call. In
9751 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9752 COMPOUND_EXPR will be an argument which must be evaluated.
9753 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9754 COMPOUND_EXPR in the chain will contain the tree for the simplified
9755 form of the builtin function call. */
9758 fold_builtin_strspn (tree arglist
)
9760 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
9764 tree s1
= TREE_VALUE (arglist
), s2
= TREE_VALUE (TREE_CHAIN (arglist
));
9765 const char *p1
= c_getstr (s1
), *p2
= c_getstr (s2
);
9767 /* If both arguments are constants, evaluate at compile-time. */
9770 const size_t r
= strspn (p1
, p2
);
9771 return size_int (r
);
9774 /* If either argument is "", return 0. */
9775 if ((p1
&& *p1
== '\0') || (p2
&& *p2
== '\0'))
9776 /* Evaluate and ignore both arguments in case either one has
9778 return omit_two_operands (integer_type_node
, integer_zero_node
,
9784 /* Simplify a call to the strcspn builtin.
9786 Return 0 if no simplification was possible, otherwise return the
9787 simplified form of the call as a tree.
9789 The simplified form may be a constant or other expression which
9790 computes the same value, but in a more efficient manner (including
9791 calls to other builtin functions).
9793 The call may contain arguments which need to be evaluated, but
9794 which are not useful to determine the result of the call. In
9795 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9796 COMPOUND_EXPR will be an argument which must be evaluated.
9797 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9798 COMPOUND_EXPR in the chain will contain the tree for the simplified
9799 form of the builtin function call. */
9802 fold_builtin_strcspn (tree arglist
)
9804 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
9808 tree s1
= TREE_VALUE (arglist
), s2
= TREE_VALUE (TREE_CHAIN (arglist
));
9809 const char *p1
= c_getstr (s1
), *p2
= c_getstr (s2
);
9811 /* If both arguments are constants, evaluate at compile-time. */
9814 const size_t r
= strcspn (p1
, p2
);
9815 return size_int (r
);
9818 /* If the first argument is "", return 0. */
9819 if (p1
&& *p1
== '\0')
9821 /* Evaluate and ignore argument s2 in case it has
9823 return omit_one_operand (integer_type_node
,
9824 integer_zero_node
, s2
);
9827 /* If the second argument is "", return __builtin_strlen(s1). */
9828 if (p2
&& *p2
== '\0')
9830 tree newarglist
= build_tree_list (NULL_TREE
, s1
),
9831 fn
= implicit_built_in_decls
[BUILT_IN_STRLEN
];
9833 /* If the replacement _DECL isn't initialized, don't do the
9838 return build_function_call_expr (fn
, newarglist
);
9844 /* Fold a call to the fputs builtin. IGNORE is true if the value returned
9845 by the builtin will be ignored. UNLOCKED is true is true if this
9846 actually a call to fputs_unlocked. If LEN in non-NULL, it represents
9847 the known length of the string. Return NULL_TREE if no simplification
9851 fold_builtin_fputs (tree arglist
, bool ignore
, bool unlocked
, tree len
)
9854 /* If we're using an unlocked function, assume the other unlocked
9855 functions exist explicitly. */
9856 tree
const fn_fputc
= unlocked
? built_in_decls
[BUILT_IN_FPUTC_UNLOCKED
]
9857 : implicit_built_in_decls
[BUILT_IN_FPUTC
];
9858 tree
const fn_fwrite
= unlocked
? built_in_decls
[BUILT_IN_FWRITE_UNLOCKED
]
9859 : implicit_built_in_decls
[BUILT_IN_FWRITE
];
9861 /* If the return value is used, don't do the transformation. */
9865 /* Verify the arguments in the original call. */
9866 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
9870 len
= c_strlen (TREE_VALUE (arglist
), 0);
9872 /* Get the length of the string passed to fputs. If the length
9873 can't be determined, punt. */
9875 || TREE_CODE (len
) != INTEGER_CST
)
9878 switch (compare_tree_int (len
, 1))
9880 case -1: /* length is 0, delete the call entirely . */
9881 return omit_one_operand (integer_type_node
, integer_zero_node
,
9882 TREE_VALUE (TREE_CHAIN (arglist
)));
9884 case 0: /* length is 1, call fputc. */
9886 const char *p
= c_getstr (TREE_VALUE (arglist
));
9890 /* New argument list transforming fputs(string, stream) to
9891 fputc(string[0], stream). */
9892 arglist
= build_tree_list (NULL_TREE
,
9893 TREE_VALUE (TREE_CHAIN (arglist
)));
9894 arglist
= tree_cons (NULL_TREE
,
9895 build_int_cst (NULL_TREE
, p
[0]),
9902 case 1: /* length is greater than 1, call fwrite. */
9906 /* If optimizing for size keep fputs. */
9909 string_arg
= TREE_VALUE (arglist
);
9910 /* New argument list transforming fputs(string, stream) to
9911 fwrite(string, 1, len, stream). */
9912 arglist
= build_tree_list (NULL_TREE
,
9913 TREE_VALUE (TREE_CHAIN (arglist
)));
9914 arglist
= tree_cons (NULL_TREE
, len
, arglist
);
9915 arglist
= tree_cons (NULL_TREE
, size_one_node
, arglist
);
9916 arglist
= tree_cons (NULL_TREE
, string_arg
, arglist
);
9924 /* If the replacement _DECL isn't initialized, don't do the
9929 /* These optimizations are only performed when the result is ignored,
9930 hence there's no need to cast the result to integer_type_node. */
9931 return build_function_call_expr (fn
, arglist
);
9934 /* Fold the new_arg's arguments (ARGLIST). Returns true if there was an error
9935 produced. False otherwise. This is done so that we don't output the error
9936 or warning twice or three times. */
9938 fold_builtin_next_arg (tree arglist
)
9940 tree fntype
= TREE_TYPE (current_function_decl
);
9942 if (TYPE_ARG_TYPES (fntype
) == 0
9943 || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype
)))
9946 error ("%<va_start%> used in function with fixed args");
9951 /* Evidently an out of date version of <stdarg.h>; can't validate
9952 va_start's second argument, but can still work as intended. */
9953 warning (0, "%<__builtin_next_arg%> called without an argument");
9956 /* We use __builtin_va_start (ap, 0, 0) or __builtin_next_arg (0, 0)
9957 when we checked the arguments and if needed issued a warning. */
9958 else if (!TREE_CHAIN (arglist
)
9959 || !integer_zerop (TREE_VALUE (arglist
))
9960 || !integer_zerop (TREE_VALUE (TREE_CHAIN (arglist
)))
9961 || TREE_CHAIN (TREE_CHAIN (arglist
)))
9963 tree last_parm
= tree_last (DECL_ARGUMENTS (current_function_decl
));
9964 tree arg
= TREE_VALUE (arglist
);
9966 if (TREE_CHAIN (arglist
))
9968 error ("%<va_start%> used with too many arguments");
9972 /* Strip off all nops for the sake of the comparison. This
9973 is not quite the same as STRIP_NOPS. It does more.
9974 We must also strip off INDIRECT_EXPR for C++ reference
9976 while (TREE_CODE (arg
) == NOP_EXPR
9977 || TREE_CODE (arg
) == CONVERT_EXPR
9978 || TREE_CODE (arg
) == NON_LVALUE_EXPR
9979 || TREE_CODE (arg
) == INDIRECT_REF
)
9980 arg
= TREE_OPERAND (arg
, 0);
9981 if (arg
!= last_parm
)
9983 /* FIXME: Sometimes with the tree optimizers we can get the
9984 not the last argument even though the user used the last
9985 argument. We just warn and set the arg to be the last
9986 argument so that we will get wrong-code because of
9988 warning (0, "second parameter of %<va_start%> not last named argument");
9990 /* We want to verify the second parameter just once before the tree
9991 optimizers are run and then avoid keeping it in the tree,
9992 as otherwise we could warn even for correct code like:
9993 void foo (int i, ...)
9994 { va_list ap; i++; va_start (ap, i); va_end (ap); } */
9995 TREE_VALUE (arglist
) = integer_zero_node
;
9996 TREE_CHAIN (arglist
) = build_tree_list (NULL
, integer_zero_node
);
10002 /* Simplify a call to the sprintf builtin.
10004 Return 0 if no simplification was possible, otherwise return the
10005 simplified form of the call as a tree. If IGNORED is true, it means that
10006 the caller does not use the returned value of the function. */
10009 fold_builtin_sprintf (tree arglist
, int ignored
)
10011 tree call
, retval
, dest
, fmt
;
10012 const char *fmt_str
= NULL
;
10014 /* Verify the required arguments in the original call. We deal with two
10015 types of sprintf() calls: 'sprintf (str, fmt)' and
10016 'sprintf (dest, "%s", orig)'. */
10017 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
)
10018 && !validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, POINTER_TYPE
,
10022 /* Get the destination string and the format specifier. */
10023 dest
= TREE_VALUE (arglist
);
10024 fmt
= TREE_VALUE (TREE_CHAIN (arglist
));
10026 /* Check whether the format is a literal string constant. */
10027 fmt_str
= c_getstr (fmt
);
10028 if (fmt_str
== NULL
)
10032 retval
= NULL_TREE
;
10034 if (!init_target_chars())
10037 /* If the format doesn't contain % args or %%, use strcpy. */
10038 if (strchr (fmt_str
, target_percent
) == NULL
)
10040 tree fn
= implicit_built_in_decls
[BUILT_IN_STRCPY
];
10045 /* Convert sprintf (str, fmt) into strcpy (str, fmt) when
10046 'format' is known to contain no % formats. */
10047 arglist
= build_tree_list (NULL_TREE
, fmt
);
10048 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
10049 call
= build_function_call_expr (fn
, arglist
);
10051 retval
= build_int_cst (NULL_TREE
, strlen (fmt_str
));
10054 /* If the format is "%s", use strcpy if the result isn't used. */
10055 else if (fmt_str
&& strcmp (fmt_str
, target_percent_s
) == 0)
10058 fn
= implicit_built_in_decls
[BUILT_IN_STRCPY
];
10063 /* Convert sprintf (str1, "%s", str2) into strcpy (str1, str2). */
10064 orig
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
10065 arglist
= build_tree_list (NULL_TREE
, orig
);
10066 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
10069 retval
= c_strlen (orig
, 1);
10070 if (!retval
|| TREE_CODE (retval
) != INTEGER_CST
)
10073 call
= build_function_call_expr (fn
, arglist
);
10076 if (call
&& retval
)
10078 retval
= fold_convert
10079 (TREE_TYPE (TREE_TYPE (implicit_built_in_decls
[BUILT_IN_SPRINTF
])),
10081 return build2 (COMPOUND_EXPR
, TREE_TYPE (retval
), call
, retval
);
10087 /* Expand a call to __builtin_object_size. */
10090 expand_builtin_object_size (tree exp
)
10093 int object_size_type
;
10094 tree fndecl
= get_callee_fndecl (exp
);
10095 tree arglist
= TREE_OPERAND (exp
, 1);
10096 location_t locus
= EXPR_LOCATION (exp
);
10098 if (!validate_arglist (arglist
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
10100 error ("%Hfirst argument of %D must be a pointer, second integer constant",
10102 expand_builtin_trap ();
10106 ost
= TREE_VALUE (TREE_CHAIN (arglist
));
10109 if (TREE_CODE (ost
) != INTEGER_CST
10110 || tree_int_cst_sgn (ost
) < 0
10111 || compare_tree_int (ost
, 3) > 0)
10113 error ("%Hlast argument of %D is not integer constant between 0 and 3",
10115 expand_builtin_trap ();
10119 object_size_type
= tree_low_cst (ost
, 0);
10121 return object_size_type
< 2 ? constm1_rtx
: const0_rtx
;
10124 /* Expand EXP, a call to the __mem{cpy,pcpy,move,set}_chk builtin.
10125 FCODE is the BUILT_IN_* to use.
10126 Return 0 if we failed; the caller should emit a normal call,
10127 otherwise try to get the result in TARGET, if convenient (and in
10128 mode MODE if that's convenient). */
10131 expand_builtin_memory_chk (tree exp
, rtx target
, enum machine_mode mode
,
10132 enum built_in_function fcode
)
10134 tree arglist
= TREE_OPERAND (exp
, 1);
10135 tree dest
, src
, len
, size
;
10137 if (!validate_arglist (arglist
,
10139 fcode
== BUILT_IN_MEMSET_CHK
10140 ? INTEGER_TYPE
: POINTER_TYPE
,
10141 INTEGER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
10144 dest
= TREE_VALUE (arglist
);
10145 src
= TREE_VALUE (TREE_CHAIN (arglist
));
10146 len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
10147 size
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist
))));
10149 if (! host_integerp (size
, 1))
10152 if (host_integerp (len
, 1) || integer_all_onesp (size
))
10156 if (! integer_all_onesp (size
) && tree_int_cst_lt (size
, len
))
10158 location_t locus
= EXPR_LOCATION (exp
);
10159 warning (0, "%Hcall to %D will always overflow destination buffer",
10160 &locus
, get_callee_fndecl (exp
));
10164 arglist
= build_tree_list (NULL_TREE
, len
);
10165 arglist
= tree_cons (NULL_TREE
, src
, arglist
);
10166 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
10169 /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume
10170 mem{cpy,pcpy,move,set} is available. */
10173 case BUILT_IN_MEMCPY_CHK
:
10174 fn
= built_in_decls
[BUILT_IN_MEMCPY
];
10176 case BUILT_IN_MEMPCPY_CHK
:
10177 fn
= built_in_decls
[BUILT_IN_MEMPCPY
];
10179 case BUILT_IN_MEMMOVE_CHK
:
10180 fn
= built_in_decls
[BUILT_IN_MEMMOVE
];
10182 case BUILT_IN_MEMSET_CHK
:
10183 fn
= built_in_decls
[BUILT_IN_MEMSET
];
10192 fn
= build_function_call_expr (fn
, arglist
);
10193 if (TREE_CODE (fn
) == CALL_EXPR
)
10194 CALL_EXPR_TAILCALL (fn
) = CALL_EXPR_TAILCALL (exp
);
10195 return expand_expr (fn
, target
, mode
, EXPAND_NORMAL
);
10197 else if (fcode
== BUILT_IN_MEMSET_CHK
)
10201 unsigned int dest_align
10202 = get_pointer_alignment (dest
, BIGGEST_ALIGNMENT
);
10204 /* If DEST is not a pointer type, call the normal function. */
10205 if (dest_align
== 0)
10208 /* If SRC and DEST are the same (and not volatile), do nothing. */
10209 if (operand_equal_p (src
, dest
, 0))
10213 if (fcode
!= BUILT_IN_MEMPCPY_CHK
)
10215 /* Evaluate and ignore LEN in case it has side-effects. */
10216 expand_expr (len
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
10217 return expand_expr (dest
, target
, mode
, EXPAND_NORMAL
);
10220 len
= fold_convert (TREE_TYPE (dest
), len
);
10221 expr
= fold_build2 (PLUS_EXPR
, TREE_TYPE (dest
), dest
, len
);
10222 return expand_expr (expr
, target
, mode
, EXPAND_NORMAL
);
10225 /* __memmove_chk special case. */
10226 if (fcode
== BUILT_IN_MEMMOVE_CHK
)
10228 unsigned int src_align
10229 = get_pointer_alignment (src
, BIGGEST_ALIGNMENT
);
10231 if (src_align
== 0)
10234 /* If src is categorized for a readonly section we can use
10235 normal __memcpy_chk. */
10236 if (readonly_data_expr (src
))
10238 tree fn
= built_in_decls
[BUILT_IN_MEMCPY_CHK
];
10241 fn
= build_function_call_expr (fn
, arglist
);
10242 if (TREE_CODE (fn
) == CALL_EXPR
)
10243 CALL_EXPR_TAILCALL (fn
) = CALL_EXPR_TAILCALL (exp
);
10244 return expand_expr (fn
, target
, mode
, EXPAND_NORMAL
);
10251 /* Emit warning if a buffer overflow is detected at compile time. */
10254 maybe_emit_chk_warning (tree exp
, enum built_in_function fcode
)
10256 int arg_mask
, is_strlen
= 0;
10257 tree arglist
= TREE_OPERAND (exp
, 1), a
;
10263 case BUILT_IN_STRCPY_CHK
:
10264 case BUILT_IN_STPCPY_CHK
:
10265 /* For __strcat_chk the warning will be emitted only if overflowing
10266 by at least strlen (dest) + 1 bytes. */
10267 case BUILT_IN_STRCAT_CHK
:
10271 case BUILT_IN_STRNCAT_CHK
:
10272 /* For __strncat_chk the warning will be emitted only if overflowing
10273 by at least strlen (dest) + 1 bytes. */
10276 case BUILT_IN_STRNCPY_CHK
:
10279 case BUILT_IN_SNPRINTF_CHK
:
10280 case BUILT_IN_VSNPRINTF_CHK
:
10284 gcc_unreachable ();
10289 for (a
= arglist
; a
&& arg_mask
; a
= TREE_CHAIN (a
), arg_mask
>>= 1)
10301 len
= TREE_VALUE (len
);
10302 size
= TREE_VALUE (size
);
10304 if (! host_integerp (size
, 1) || integer_all_onesp (size
))
10309 len
= c_strlen (len
, 1);
10310 if (! len
|| ! host_integerp (len
, 1) || tree_int_cst_lt (len
, size
))
10313 else if (fcode
== BUILT_IN_STRNCAT_CHK
)
10315 tree src
= TREE_VALUE (TREE_CHAIN (arglist
));
10316 if (! src
|| ! host_integerp (len
, 1) || tree_int_cst_lt (len
, size
))
10318 src
= c_strlen (src
, 1);
10319 if (! src
|| ! host_integerp (src
, 1))
10321 locus
= EXPR_LOCATION (exp
);
10322 warning (0, "%Hcall to %D might overflow destination buffer",
10323 &locus
, get_callee_fndecl (exp
));
10326 else if (tree_int_cst_lt (src
, size
))
10329 else if (! host_integerp (len
, 1) || ! tree_int_cst_lt (size
, len
))
10332 locus
= EXPR_LOCATION (exp
);
10333 warning (0, "%Hcall to %D will always overflow destination buffer",
10334 &locus
, get_callee_fndecl (exp
));
10337 /* Emit warning if a buffer overflow is detected at compile time
10338 in __sprintf_chk/__vsprintf_chk calls. */
10341 maybe_emit_sprintf_chk_warning (tree exp
, enum built_in_function fcode
)
10343 tree arglist
= TREE_OPERAND (exp
, 1);
10344 tree dest
, size
, len
, fmt
, flag
;
10345 const char *fmt_str
;
10347 /* Verify the required arguments in the original call. */
10350 dest
= TREE_VALUE (arglist
);
10351 arglist
= TREE_CHAIN (arglist
);
10354 flag
= TREE_VALUE (arglist
);
10355 arglist
= TREE_CHAIN (arglist
);
10358 size
= TREE_VALUE (arglist
);
10359 arglist
= TREE_CHAIN (arglist
);
10362 fmt
= TREE_VALUE (arglist
);
10363 arglist
= TREE_CHAIN (arglist
);
10365 if (! host_integerp (size
, 1) || integer_all_onesp (size
))
10368 /* Check whether the format is a literal string constant. */
10369 fmt_str
= c_getstr (fmt
);
10370 if (fmt_str
== NULL
)
10373 if (!init_target_chars())
10376 /* If the format doesn't contain % args or %%, we know its size. */
10377 if (strchr (fmt_str
, target_percent
) == 0)
10378 len
= build_int_cstu (size_type_node
, strlen (fmt_str
));
10379 /* If the format is "%s" and first ... argument is a string literal,
10381 else if (fcode
== BUILT_IN_SPRINTF_CHK
&& strcmp (fmt_str
, target_percent_s
) == 0)
10387 arg
= TREE_VALUE (arglist
);
10388 if (! POINTER_TYPE_P (TREE_TYPE (arg
)))
10391 len
= c_strlen (arg
, 1);
10392 if (!len
|| ! host_integerp (len
, 1))
10398 if (! tree_int_cst_lt (len
, size
))
10400 location_t locus
= EXPR_LOCATION (exp
);
10401 warning (0, "%Hcall to %D will always overflow destination buffer",
10402 &locus
, get_callee_fndecl (exp
));
10406 /* Fold a call to __builtin_object_size, if possible. */
10409 fold_builtin_object_size (tree arglist
)
10411 tree ptr
, ost
, ret
= 0;
10412 int object_size_type
;
10414 if (!validate_arglist (arglist
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
10417 ptr
= TREE_VALUE (arglist
);
10418 ost
= TREE_VALUE (TREE_CHAIN (arglist
));
10421 if (TREE_CODE (ost
) != INTEGER_CST
10422 || tree_int_cst_sgn (ost
) < 0
10423 || compare_tree_int (ost
, 3) > 0)
10426 object_size_type
= tree_low_cst (ost
, 0);
10428 /* __builtin_object_size doesn't evaluate side-effects in its arguments;
10429 if there are any side-effects, it returns (size_t) -1 for types 0 and 1
10430 and (size_t) 0 for types 2 and 3. */
10431 if (TREE_SIDE_EFFECTS (ptr
))
10432 return fold_convert (size_type_node
,
10433 object_size_type
< 2
10434 ? integer_minus_one_node
: integer_zero_node
);
10436 if (TREE_CODE (ptr
) == ADDR_EXPR
)
10437 ret
= build_int_cstu (size_type_node
,
10438 compute_builtin_object_size (ptr
, object_size_type
));
10440 else if (TREE_CODE (ptr
) == SSA_NAME
)
10442 unsigned HOST_WIDE_INT bytes
;
10444 /* If object size is not known yet, delay folding until
10445 later. Maybe subsequent passes will help determining
10447 bytes
= compute_builtin_object_size (ptr
, object_size_type
);
10448 if (bytes
!= (unsigned HOST_WIDE_INT
) (object_size_type
< 2
10450 ret
= build_int_cstu (size_type_node
, bytes
);
10455 ret
= force_fit_type (ret
, -1, false, false);
10456 if (TREE_CONSTANT_OVERFLOW (ret
))
10463 /* Fold a call to the __mem{cpy,pcpy,move,set}_chk builtin.
10464 IGNORE is true, if return value can be ignored. FCODE is the BUILT_IN_*
10465 code of the builtin. If MAXLEN is not NULL, it is maximum length
10466 passed as third argument. */
10469 fold_builtin_memory_chk (tree fndecl
, tree arglist
, tree maxlen
, bool ignore
,
10470 enum built_in_function fcode
)
10472 tree dest
, src
, len
, size
, fn
;
10474 if (!validate_arglist (arglist
,
10476 fcode
== BUILT_IN_MEMSET_CHK
10477 ? INTEGER_TYPE
: POINTER_TYPE
,
10478 INTEGER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
10481 dest
= TREE_VALUE (arglist
);
10482 /* Actually val for __memset_chk, but it doesn't matter. */
10483 src
= TREE_VALUE (TREE_CHAIN (arglist
));
10484 len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
10485 size
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist
))));
10487 /* If SRC and DEST are the same (and not volatile), return DEST
10488 (resp. DEST+LEN for __mempcpy_chk). */
10489 if (fcode
!= BUILT_IN_MEMSET_CHK
&& operand_equal_p (src
, dest
, 0))
10491 if (fcode
!= BUILT_IN_MEMPCPY_CHK
)
10492 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl
)), dest
, len
);
10495 tree temp
= fold_convert (TREE_TYPE (dest
), len
);
10496 temp
= fold_build2 (PLUS_EXPR
, TREE_TYPE (dest
), dest
, temp
);
10497 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl
)), temp
);
10501 if (! host_integerp (size
, 1))
10504 if (! integer_all_onesp (size
))
10506 if (! host_integerp (len
, 1))
10508 /* If LEN is not constant, try MAXLEN too.
10509 For MAXLEN only allow optimizing into non-_ocs function
10510 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
10511 if (maxlen
== NULL_TREE
|| ! host_integerp (maxlen
, 1))
10513 if (fcode
== BUILT_IN_MEMPCPY_CHK
&& ignore
)
10515 /* (void) __mempcpy_chk () can be optimized into
10516 (void) __memcpy_chk (). */
10517 fn
= built_in_decls
[BUILT_IN_MEMCPY_CHK
];
10521 return build_function_call_expr (fn
, arglist
);
10529 if (tree_int_cst_lt (size
, maxlen
))
10533 arglist
= build_tree_list (NULL_TREE
, len
);
10534 arglist
= tree_cons (NULL_TREE
, src
, arglist
);
10535 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
10538 /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume
10539 mem{cpy,pcpy,move,set} is available. */
10542 case BUILT_IN_MEMCPY_CHK
:
10543 fn
= built_in_decls
[BUILT_IN_MEMCPY
];
10545 case BUILT_IN_MEMPCPY_CHK
:
10546 fn
= built_in_decls
[BUILT_IN_MEMPCPY
];
10548 case BUILT_IN_MEMMOVE_CHK
:
10549 fn
= built_in_decls
[BUILT_IN_MEMMOVE
];
10551 case BUILT_IN_MEMSET_CHK
:
10552 fn
= built_in_decls
[BUILT_IN_MEMSET
];
10561 return build_function_call_expr (fn
, arglist
);
10564 /* Fold a call to the __st[rp]cpy_chk builtin.
10565 IGNORE is true, if return value can be ignored. FCODE is the BUILT_IN_*
10566 code of the builtin. If MAXLEN is not NULL, it is maximum length of
10567 strings passed as second argument. */
10570 fold_builtin_stxcpy_chk (tree fndecl
, tree arglist
, tree maxlen
, bool ignore
,
10571 enum built_in_function fcode
)
10573 tree dest
, src
, size
, len
, fn
;
10575 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
,
10579 dest
= TREE_VALUE (arglist
);
10580 src
= TREE_VALUE (TREE_CHAIN (arglist
));
10581 size
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
10583 /* If SRC and DEST are the same (and not volatile), return DEST. */
10584 if (fcode
== BUILT_IN_STRCPY_CHK
&& operand_equal_p (src
, dest
, 0))
10585 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl
)), dest
);
10587 if (! host_integerp (size
, 1))
10590 if (! integer_all_onesp (size
))
10592 len
= c_strlen (src
, 1);
10593 if (! len
|| ! host_integerp (len
, 1))
10595 /* If LEN is not constant, try MAXLEN too.
10596 For MAXLEN only allow optimizing into non-_ocs function
10597 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
10598 if (maxlen
== NULL_TREE
|| ! host_integerp (maxlen
, 1))
10600 if (fcode
== BUILT_IN_STPCPY_CHK
)
10605 /* If return value of __stpcpy_chk is ignored,
10606 optimize into __strcpy_chk. */
10607 fn
= built_in_decls
[BUILT_IN_STRCPY_CHK
];
10611 return build_function_call_expr (fn
, arglist
);
10614 if (! len
|| TREE_SIDE_EFFECTS (len
))
10617 /* If c_strlen returned something, but not a constant,
10618 transform __strcpy_chk into __memcpy_chk. */
10619 fn
= built_in_decls
[BUILT_IN_MEMCPY_CHK
];
10623 len
= size_binop (PLUS_EXPR
, len
, ssize_int (1));
10624 arglist
= build_tree_list (NULL_TREE
, size
);
10625 arglist
= tree_cons (NULL_TREE
, len
, arglist
);
10626 arglist
= tree_cons (NULL_TREE
, src
, arglist
);
10627 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
10628 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl
)),
10629 build_function_call_expr (fn
, arglist
));
10635 if (! tree_int_cst_lt (maxlen
, size
))
10639 arglist
= build_tree_list (NULL_TREE
, src
);
10640 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
10642 /* If __builtin_st{r,p}cpy_chk is used, assume st{r,p}cpy is available. */
10643 fn
= built_in_decls
[fcode
== BUILT_IN_STPCPY_CHK
10644 ? BUILT_IN_STPCPY
: BUILT_IN_STRCPY
];
10648 return build_function_call_expr (fn
, arglist
);
10651 /* Fold a call to the __strncpy_chk builtin.
10652 If MAXLEN is not NULL, it is maximum length passed as third argument. */
10655 fold_builtin_strncpy_chk (tree arglist
, tree maxlen
)
10657 tree dest
, src
, size
, len
, fn
;
10659 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
,
10660 INTEGER_TYPE
, VOID_TYPE
))
10663 dest
= TREE_VALUE (arglist
);
10664 src
= TREE_VALUE (TREE_CHAIN (arglist
));
10665 len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
10666 size
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist
))));
10668 if (! host_integerp (size
, 1))
10671 if (! integer_all_onesp (size
))
10673 if (! host_integerp (len
, 1))
10675 /* If LEN is not constant, try MAXLEN too.
10676 For MAXLEN only allow optimizing into non-_ocs function
10677 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
10678 if (maxlen
== NULL_TREE
|| ! host_integerp (maxlen
, 1))
10684 if (tree_int_cst_lt (size
, maxlen
))
10688 arglist
= build_tree_list (NULL_TREE
, len
);
10689 arglist
= tree_cons (NULL_TREE
, src
, arglist
);
10690 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
10692 /* If __builtin_strncpy_chk is used, assume strncpy is available. */
10693 fn
= built_in_decls
[BUILT_IN_STRNCPY
];
10697 return build_function_call_expr (fn
, arglist
);
10700 /* Fold a call to the __strcat_chk builtin FNDECL with ARGLIST. */
10703 fold_builtin_strcat_chk (tree fndecl
, tree arglist
)
10705 tree dest
, src
, size
, fn
;
10708 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
,
10712 dest
= TREE_VALUE (arglist
);
10713 src
= TREE_VALUE (TREE_CHAIN (arglist
));
10714 size
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
10716 p
= c_getstr (src
);
10717 /* If the SRC parameter is "", return DEST. */
10718 if (p
&& *p
== '\0')
10719 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl
)), dest
, src
);
10721 if (! host_integerp (size
, 1) || ! integer_all_onesp (size
))
10724 arglist
= build_tree_list (NULL_TREE
, src
);
10725 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
10727 /* If __builtin_strcat_chk is used, assume strcat is available. */
10728 fn
= built_in_decls
[BUILT_IN_STRCAT
];
10732 return build_function_call_expr (fn
, arglist
);
10735 /* Fold a call to the __strncat_chk builtin EXP. */
10738 fold_builtin_strncat_chk (tree fndecl
, tree arglist
)
10740 tree dest
, src
, size
, len
, fn
;
10743 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
,
10744 INTEGER_TYPE
, VOID_TYPE
))
10747 dest
= TREE_VALUE (arglist
);
10748 src
= TREE_VALUE (TREE_CHAIN (arglist
));
10749 len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
10750 size
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist
))));
10752 p
= c_getstr (src
);
10753 /* If the SRC parameter is "" or if LEN is 0, return DEST. */
10754 if (p
&& *p
== '\0')
10755 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl
)), dest
, len
);
10756 else if (integer_zerop (len
))
10757 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl
)), dest
, src
);
10759 if (! host_integerp (size
, 1))
10762 if (! integer_all_onesp (size
))
10764 tree src_len
= c_strlen (src
, 1);
10766 && host_integerp (src_len
, 1)
10767 && host_integerp (len
, 1)
10768 && ! tree_int_cst_lt (len
, src_len
))
10770 /* If LEN >= strlen (SRC), optimize into __strcat_chk. */
10771 fn
= built_in_decls
[BUILT_IN_STRCAT_CHK
];
10775 arglist
= build_tree_list (NULL_TREE
, size
);
10776 arglist
= tree_cons (NULL_TREE
, src
, arglist
);
10777 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
10778 return build_function_call_expr (fn
, arglist
);
10783 arglist
= build_tree_list (NULL_TREE
, len
);
10784 arglist
= tree_cons (NULL_TREE
, src
, arglist
);
10785 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
10787 /* If __builtin_strncat_chk is used, assume strncat is available. */
10788 fn
= built_in_decls
[BUILT_IN_STRNCAT
];
10792 return build_function_call_expr (fn
, arglist
);
10795 /* Fold a call to __{,v}sprintf_chk with argument list ARGLIST. Return 0 if
10796 a normal call should be emitted rather than expanding the function
10797 inline. FCODE is either BUILT_IN_SPRINTF_CHK or BUILT_IN_VSPRINTF_CHK. */
10800 fold_builtin_sprintf_chk (tree arglist
, enum built_in_function fcode
)
10802 tree dest
, size
, len
, fn
, fmt
, flag
;
10803 const char *fmt_str
;
10805 /* Verify the required arguments in the original call. */
10808 dest
= TREE_VALUE (arglist
);
10809 if (! POINTER_TYPE_P (TREE_TYPE (dest
)))
10811 arglist
= TREE_CHAIN (arglist
);
10814 flag
= TREE_VALUE (arglist
);
10815 if (TREE_CODE (TREE_TYPE (flag
)) != INTEGER_TYPE
)
10817 arglist
= TREE_CHAIN (arglist
);
10820 size
= TREE_VALUE (arglist
);
10821 if (TREE_CODE (TREE_TYPE (size
)) != INTEGER_TYPE
)
10823 arglist
= TREE_CHAIN (arglist
);
10826 fmt
= TREE_VALUE (arglist
);
10827 if (! POINTER_TYPE_P (TREE_TYPE (fmt
)))
10829 arglist
= TREE_CHAIN (arglist
);
10831 if (! host_integerp (size
, 1))
10836 if (!init_target_chars())
10839 /* Check whether the format is a literal string constant. */
10840 fmt_str
= c_getstr (fmt
);
10841 if (fmt_str
!= NULL
)
10843 /* If the format doesn't contain % args or %%, we know the size. */
10844 if (strchr (fmt_str
, target_percent
) == 0)
10846 if (fcode
!= BUILT_IN_SPRINTF_CHK
|| arglist
== NULL_TREE
)
10847 len
= build_int_cstu (size_type_node
, strlen (fmt_str
));
10849 /* If the format is "%s" and first ... argument is a string literal,
10850 we know the size too. */
10851 else if (fcode
== BUILT_IN_SPRINTF_CHK
&& strcmp (fmt_str
, target_percent_s
) == 0)
10855 if (arglist
&& !TREE_CHAIN (arglist
))
10857 arg
= TREE_VALUE (arglist
);
10858 if (POINTER_TYPE_P (TREE_TYPE (arg
)))
10860 len
= c_strlen (arg
, 1);
10861 if (! len
|| ! host_integerp (len
, 1))
10868 if (! integer_all_onesp (size
))
10870 if (! len
|| ! tree_int_cst_lt (len
, size
))
10874 /* Only convert __{,v}sprintf_chk to {,v}sprintf if flag is 0
10875 or if format doesn't contain % chars or is "%s". */
10876 if (! integer_zerop (flag
))
10878 if (fmt_str
== NULL
)
10880 if (strchr (fmt_str
, target_percent
) != NULL
&& strcmp (fmt_str
, target_percent_s
))
10884 arglist
= tree_cons (NULL_TREE
, fmt
, arglist
);
10885 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
10887 /* If __builtin_{,v}sprintf_chk is used, assume {,v}sprintf is available. */
10888 fn
= built_in_decls
[fcode
== BUILT_IN_VSPRINTF_CHK
10889 ? BUILT_IN_VSPRINTF
: BUILT_IN_SPRINTF
];
10893 return build_function_call_expr (fn
, arglist
);
10896 /* Fold a call to {,v}snprintf with argument list ARGLIST. Return 0 if
10897 a normal call should be emitted rather than expanding the function
10898 inline. FCODE is either BUILT_IN_SNPRINTF_CHK or
10899 BUILT_IN_VSNPRINTF_CHK. If MAXLEN is not NULL, it is maximum length
10900 passed as second argument. */
10903 fold_builtin_snprintf_chk (tree arglist
, tree maxlen
,
10904 enum built_in_function fcode
)
10906 tree dest
, size
, len
, fn
, fmt
, flag
;
10907 const char *fmt_str
;
10909 /* Verify the required arguments in the original call. */
10912 dest
= TREE_VALUE (arglist
);
10913 if (! POINTER_TYPE_P (TREE_TYPE (dest
)))
10915 arglist
= TREE_CHAIN (arglist
);
10918 len
= TREE_VALUE (arglist
);
10919 if (TREE_CODE (TREE_TYPE (len
)) != INTEGER_TYPE
)
10921 arglist
= TREE_CHAIN (arglist
);
10924 flag
= TREE_VALUE (arglist
);
10925 if (TREE_CODE (TREE_TYPE (len
)) != INTEGER_TYPE
)
10927 arglist
= TREE_CHAIN (arglist
);
10930 size
= TREE_VALUE (arglist
);
10931 if (TREE_CODE (TREE_TYPE (size
)) != INTEGER_TYPE
)
10933 arglist
= TREE_CHAIN (arglist
);
10936 fmt
= TREE_VALUE (arglist
);
10937 if (! POINTER_TYPE_P (TREE_TYPE (fmt
)))
10939 arglist
= TREE_CHAIN (arglist
);
10941 if (! host_integerp (size
, 1))
10944 if (! integer_all_onesp (size
))
10946 if (! host_integerp (len
, 1))
10948 /* If LEN is not constant, try MAXLEN too.
10949 For MAXLEN only allow optimizing into non-_ocs function
10950 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
10951 if (maxlen
== NULL_TREE
|| ! host_integerp (maxlen
, 1))
10957 if (tree_int_cst_lt (size
, maxlen
))
10961 if (!init_target_chars())
10964 /* Only convert __{,v}snprintf_chk to {,v}snprintf if flag is 0
10965 or if format doesn't contain % chars or is "%s". */
10966 if (! integer_zerop (flag
))
10968 fmt_str
= c_getstr (fmt
);
10969 if (fmt_str
== NULL
)
10971 if (strchr (fmt_str
, target_percent
) != NULL
&& strcmp (fmt_str
, target_percent_s
))
10975 arglist
= tree_cons (NULL_TREE
, fmt
, arglist
);
10976 arglist
= tree_cons (NULL_TREE
, len
, arglist
);
10977 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
10979 /* If __builtin_{,v}snprintf_chk is used, assume {,v}snprintf is
10981 fn
= built_in_decls
[fcode
== BUILT_IN_VSNPRINTF_CHK
10982 ? BUILT_IN_VSNPRINTF
: BUILT_IN_SNPRINTF
];
10986 return build_function_call_expr (fn
, arglist
);
10989 /* Fold a call to the {,v}printf{,_unlocked} and __{,v}printf_chk builtins.
10991 Return 0 if no simplification was possible, otherwise return the
10992 simplified form of the call as a tree. FCODE is the BUILT_IN_*
10993 code of the function to be simplified. */
10996 fold_builtin_printf (tree fndecl
, tree arglist
, bool ignore
,
10997 enum built_in_function fcode
)
10999 tree fmt
, fn
= NULL_TREE
, fn_putchar
, fn_puts
, arg
, call
;
11000 const char *fmt_str
= NULL
;
11002 /* If the return value is used, don't do the transformation. */
11006 /* Verify the required arguments in the original call. */
11007 if (fcode
== BUILT_IN_PRINTF_CHK
|| fcode
== BUILT_IN_VPRINTF_CHK
)
11013 flag
= TREE_VALUE (arglist
);
11014 if (TREE_CODE (TREE_TYPE (flag
)) != INTEGER_TYPE
11015 || TREE_SIDE_EFFECTS (flag
))
11017 arglist
= TREE_CHAIN (arglist
);
11022 fmt
= TREE_VALUE (arglist
);
11023 if (! POINTER_TYPE_P (TREE_TYPE (fmt
)))
11025 arglist
= TREE_CHAIN (arglist
);
11027 /* Check whether the format is a literal string constant. */
11028 fmt_str
= c_getstr (fmt
);
11029 if (fmt_str
== NULL
)
11032 if (fcode
== BUILT_IN_PRINTF_UNLOCKED
)
11034 /* If we're using an unlocked function, assume the other
11035 unlocked functions exist explicitly. */
11036 fn_putchar
= built_in_decls
[BUILT_IN_PUTCHAR_UNLOCKED
];
11037 fn_puts
= built_in_decls
[BUILT_IN_PUTS_UNLOCKED
];
11041 fn_putchar
= implicit_built_in_decls
[BUILT_IN_PUTCHAR
];
11042 fn_puts
= implicit_built_in_decls
[BUILT_IN_PUTS
];
11045 if (!init_target_chars())
11048 if (strcmp (fmt_str
, target_percent_s
) == 0 || strchr (fmt_str
, target_percent
) == NULL
)
11052 if (strcmp (fmt_str
, target_percent_s
) == 0)
11054 if (fcode
== BUILT_IN_VPRINTF
|| fcode
== BUILT_IN_VPRINTF_CHK
)
11058 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist
)))
11059 || TREE_CHAIN (arglist
))
11062 str
= c_getstr (TREE_VALUE (arglist
));
11068 /* The format specifier doesn't contain any '%' characters. */
11069 if (fcode
!= BUILT_IN_VPRINTF
&& fcode
!= BUILT_IN_VPRINTF_CHK
11075 /* If the string was "", printf does nothing. */
11076 if (str
[0] == '\0')
11077 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl
)), 0);
11079 /* If the string has length of 1, call putchar. */
11080 if (str
[1] == '\0')
11082 /* Given printf("c"), (where c is any one character,)
11083 convert "c"[0] to an int and pass that to the replacement
11085 arg
= build_int_cst (NULL_TREE
, str
[0]);
11086 arglist
= build_tree_list (NULL_TREE
, arg
);
11091 /* If the string was "string\n", call puts("string"). */
11092 size_t len
= strlen (str
);
11093 if ((unsigned char)str
[len
- 1] == target_newline
)
11095 /* Create a NUL-terminated string that's one char shorter
11096 than the original, stripping off the trailing '\n'. */
11097 char *newstr
= alloca (len
);
11098 memcpy (newstr
, str
, len
- 1);
11099 newstr
[len
- 1] = 0;
11101 arg
= build_string_literal (len
, newstr
);
11102 arglist
= build_tree_list (NULL_TREE
, arg
);
11106 /* We'd like to arrange to call fputs(string,stdout) here,
11107 but we need stdout and don't have a way to get it yet. */
11112 /* The other optimizations can be done only on the non-va_list variants. */
11113 else if (fcode
== BUILT_IN_VPRINTF
|| fcode
== BUILT_IN_VPRINTF_CHK
)
11116 /* If the format specifier was "%s\n", call __builtin_puts(arg). */
11117 else if (strcmp (fmt_str
, target_percent_s_newline
) == 0)
11120 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist
)))
11121 || TREE_CHAIN (arglist
))
11126 /* If the format specifier was "%c", call __builtin_putchar(arg). */
11127 else if (strcmp (fmt_str
, target_percent_c
) == 0)
11130 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist
))) != INTEGER_TYPE
11131 || TREE_CHAIN (arglist
))
11139 call
= build_function_call_expr (fn
, arglist
);
11140 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl
)), call
);
11143 /* Fold a call to the {,v}fprintf{,_unlocked} and __{,v}printf_chk builtins.
11145 Return 0 if no simplification was possible, otherwise return the
11146 simplified form of the call as a tree. FCODE is the BUILT_IN_*
11147 code of the function to be simplified. */
11150 fold_builtin_fprintf (tree fndecl
, tree arglist
, bool ignore
,
11151 enum built_in_function fcode
)
11153 tree fp
, fmt
, fn
= NULL_TREE
, fn_fputc
, fn_fputs
, arg
, call
;
11154 const char *fmt_str
= NULL
;
11156 /* If the return value is used, don't do the transformation. */
11160 /* Verify the required arguments in the original call. */
11163 fp
= TREE_VALUE (arglist
);
11164 if (! POINTER_TYPE_P (TREE_TYPE (fp
)))
11166 arglist
= TREE_CHAIN (arglist
);
11168 if (fcode
== BUILT_IN_FPRINTF_CHK
|| fcode
== BUILT_IN_VFPRINTF_CHK
)
11174 flag
= TREE_VALUE (arglist
);
11175 if (TREE_CODE (TREE_TYPE (flag
)) != INTEGER_TYPE
11176 || TREE_SIDE_EFFECTS (flag
))
11178 arglist
= TREE_CHAIN (arglist
);
11183 fmt
= TREE_VALUE (arglist
);
11184 if (! POINTER_TYPE_P (TREE_TYPE (fmt
)))
11186 arglist
= TREE_CHAIN (arglist
);
11188 /* Check whether the format is a literal string constant. */
11189 fmt_str
= c_getstr (fmt
);
11190 if (fmt_str
== NULL
)
11193 if (fcode
== BUILT_IN_FPRINTF_UNLOCKED
)
11195 /* If we're using an unlocked function, assume the other
11196 unlocked functions exist explicitly. */
11197 fn_fputc
= built_in_decls
[BUILT_IN_FPUTC_UNLOCKED
];
11198 fn_fputs
= built_in_decls
[BUILT_IN_FPUTS_UNLOCKED
];
11202 fn_fputc
= implicit_built_in_decls
[BUILT_IN_FPUTC
];
11203 fn_fputs
= implicit_built_in_decls
[BUILT_IN_FPUTS
];
11206 if (!init_target_chars())
11209 /* If the format doesn't contain % args or %%, use strcpy. */
11210 if (strchr (fmt_str
, target_percent
) == NULL
)
11212 if (fcode
!= BUILT_IN_VFPRINTF
&& fcode
!= BUILT_IN_VFPRINTF_CHK
11216 /* If the format specifier was "", fprintf does nothing. */
11217 if (fmt_str
[0] == '\0')
11219 /* If FP has side-effects, just wait until gimplification is
11221 if (TREE_SIDE_EFFECTS (fp
))
11224 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl
)), 0);
11227 /* When "string" doesn't contain %, replace all cases of
11228 fprintf (fp, string) with fputs (string, fp). The fputs
11229 builtin will take care of special cases like length == 1. */
11230 arglist
= build_tree_list (NULL_TREE
, fp
);
11231 arglist
= tree_cons (NULL_TREE
, fmt
, arglist
);
11235 /* The other optimizations can be done only on the non-va_list variants. */
11236 else if (fcode
== BUILT_IN_VFPRINTF
|| fcode
== BUILT_IN_VFPRINTF_CHK
)
11239 /* If the format specifier was "%s", call __builtin_fputs (arg, fp). */
11240 else if (strcmp (fmt_str
, target_percent_s
) == 0)
11243 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist
)))
11244 || TREE_CHAIN (arglist
))
11246 arg
= TREE_VALUE (arglist
);
11247 arglist
= build_tree_list (NULL_TREE
, fp
);
11248 arglist
= tree_cons (NULL_TREE
, arg
, arglist
);
11252 /* If the format specifier was "%c", call __builtin_fputc (arg, fp). */
11253 else if (strcmp (fmt_str
, target_percent_c
) == 0)
11256 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist
))) != INTEGER_TYPE
11257 || TREE_CHAIN (arglist
))
11259 arg
= TREE_VALUE (arglist
);
11260 arglist
= build_tree_list (NULL_TREE
, fp
);
11261 arglist
= tree_cons (NULL_TREE
, arg
, arglist
);
11268 call
= build_function_call_expr (fn
, arglist
);
11269 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl
)), call
);
11272 /* Initialize format string characters in the target charset. */
11275 init_target_chars (void)
11280 target_newline
= lang_hooks
.to_target_charset ('\n');
11281 target_percent
= lang_hooks
.to_target_charset ('%');
11282 target_c
= lang_hooks
.to_target_charset ('c');
11283 target_s
= lang_hooks
.to_target_charset ('s');
11284 if (target_newline
== 0 || target_percent
== 0 || target_c
== 0
11288 target_percent_c
[0] = target_percent
;
11289 target_percent_c
[1] = target_c
;
11290 target_percent_c
[2] = '\0';
11292 target_percent_s
[0] = target_percent
;
11293 target_percent_s
[1] = target_s
;
11294 target_percent_s
[2] = '\0';
11296 target_percent_s_newline
[0] = target_percent
;
11297 target_percent_s_newline
[1] = target_s
;
11298 target_percent_s_newline
[2] = target_newline
;
11299 target_percent_s_newline
[3] = '\0';
11306 /* If argument ARG is a REAL_CST, call the one-argument mpfr function
11307 FUNC on it and return the resulting value as a tree with type TYPE.
11308 If MIN and/or MAX are not NULL, then the supplied ARG must be
11309 within those bounds. If INCLUSIVE is true, then MIN/MAX are
11310 acceptable values, otherwise they are not. The mpfr precision is
11311 set to the precision of TYPE. We assume that function FUNC returns
11312 zero if the result could be calculated exactly within the requested
11316 do_mpfr_arg1 (tree arg
, tree type
, int (*func
)(mpfr_ptr
, mpfr_srcptr
, mp_rnd_t
),
11317 const REAL_VALUE_TYPE
*min
, const REAL_VALUE_TYPE
*max
,
11320 tree result
= NULL_TREE
;
11324 if (TREE_CODE (arg
) == REAL_CST
&& ! TREE_CONSTANT_OVERFLOW (arg
))
11326 REAL_VALUE_TYPE r
= TREE_REAL_CST (arg
);
11328 if (!real_isnan (&r
) && !real_isinf (&r
)
11329 && (!min
|| real_compare (inclusive
? GE_EXPR
: GT_EXPR
, &r
, min
))
11330 && (!max
|| real_compare (inclusive
? LE_EXPR
: LT_EXPR
, &r
, max
)))
11332 const enum machine_mode mode
= TYPE_MODE (type
);
11333 const int prec
= REAL_MODE_FORMAT (mode
)->p
;
11337 mpfr_init2 (m
, prec
);
11338 mpfr_from_real (m
, &r
);
11339 mpfr_clear_flags();
11340 inexact
= func (m
, m
, GMP_RNDN
);
11342 /* Proceed iff we get a normal number, i.e. not NaN or Inf
11343 and no overflow/underflow occurred. If -frounding-math,
11344 proceed iff the result of calling FUNC was exact. */
11345 if (mpfr_number_p (m
) && !mpfr_overflow_p() && !mpfr_underflow_p()
11346 && (!flag_rounding_math
|| !inexact
))
11348 real_from_mpfr (&r
, m
);
11349 /* Proceed iff GCC's REAL_VALUE_TYPE can hold the MPFR
11350 value, check for overflow/underflow. If the
11351 REAL_VALUE_TYPE is zero but the mpft_t is not, then
11352 we underflowed in the conversion. */
11353 if (!real_isnan (&r
) && !real_isinf (&r
)
11354 && (r
.cl
== rvc_zero
) == (mpfr_zero_p (m
) != 0))
11356 REAL_VALUE_TYPE rmode
;
11357 real_convert (&rmode
, mode
, &r
);
11358 /* Proceed iff the specified mode can hold the value. */
11359 if (real_identical (&rmode
, &r
))
11360 result
= build_real (type
, rmode
);