1 /* Expand builtin functions.
2 Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING. If not, write to the Free
19 Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
24 #include "coretypes.h"
30 #include "tree-gimple.h"
33 #include "hard-reg-set.h"
36 #include "insn-config.h"
42 #include "typeclass.h"
47 #include "langhooks.h"
48 #include "basic-block.h"
49 #include "tree-mudflap.h"
51 #ifndef PAD_VARARGS_DOWN
52 #define PAD_VARARGS_DOWN BYTES_BIG_ENDIAN
55 /* Define the names of the builtin function types and codes. */
56 const char *const built_in_class_names
[4]
57 = {"NOT_BUILT_IN", "BUILT_IN_FRONTEND", "BUILT_IN_MD", "BUILT_IN_NORMAL"};
59 #define DEF_BUILTIN(X, N, C, T, LT, B, F, NA, AT, IM, COND) #X,
60 const char * built_in_names
[(int) END_BUILTINS
] =
62 #include "builtins.def"
66 /* Setup an array of _DECL trees, make sure each element is
67 initialized to NULL_TREE. */
68 tree built_in_decls
[(int) END_BUILTINS
];
69 /* Declarations used when constructing the builtin implicitly in the compiler.
70 It may be NULL_TREE when this is invalid (for instance runtime is not
71 required to implement the function call in all cases). */
72 tree implicit_built_in_decls
[(int) END_BUILTINS
];
74 static int get_pointer_alignment (tree
, unsigned int);
75 static const char *c_getstr (tree
);
76 static rtx
c_readstr (const char *, enum machine_mode
);
77 static int target_char_cast (tree
, char *);
78 static rtx
get_memory_rtx (tree
, tree
);
79 static int apply_args_size (void);
80 static int apply_result_size (void);
81 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
82 static rtx
result_vector (int, rtx
);
84 static rtx
expand_builtin_setjmp (tree
, rtx
);
85 static void expand_builtin_update_setjmp_buf (rtx
);
86 static void expand_builtin_prefetch (tree
);
87 static rtx
expand_builtin_apply_args (void);
88 static rtx
expand_builtin_apply_args_1 (void);
89 static rtx
expand_builtin_apply (rtx
, rtx
, rtx
);
90 static void expand_builtin_return (rtx
);
91 static enum type_class
type_to_class (tree
);
92 static rtx
expand_builtin_classify_type (tree
);
93 static void expand_errno_check (tree
, rtx
);
94 static rtx
expand_builtin_mathfn (tree
, rtx
, rtx
);
95 static rtx
expand_builtin_mathfn_2 (tree
, rtx
, rtx
);
96 static rtx
expand_builtin_mathfn_3 (tree
, rtx
, rtx
);
97 static rtx
expand_builtin_sincos (tree
);
98 static rtx
expand_builtin_int_roundingfn (tree
, rtx
, rtx
);
99 static rtx
expand_builtin_args_info (tree
);
100 static rtx
expand_builtin_next_arg (void);
101 static rtx
expand_builtin_va_start (tree
);
102 static rtx
expand_builtin_va_end (tree
);
103 static rtx
expand_builtin_va_copy (tree
);
104 static rtx
expand_builtin_memcmp (tree
, tree
, rtx
, enum machine_mode
);
105 static rtx
expand_builtin_strcmp (tree
, rtx
, enum machine_mode
);
106 static rtx
expand_builtin_strncmp (tree
, rtx
, enum machine_mode
);
107 static rtx
builtin_memcpy_read_str (void *, HOST_WIDE_INT
, enum machine_mode
);
108 static rtx
expand_builtin_strcat (tree
, tree
, rtx
, enum machine_mode
);
109 static rtx
expand_builtin_strncat (tree
, rtx
, enum machine_mode
);
110 static rtx
expand_builtin_strspn (tree
, rtx
, enum machine_mode
);
111 static rtx
expand_builtin_strcspn (tree
, rtx
, enum machine_mode
);
112 static rtx
expand_builtin_memcpy (tree
, rtx
, enum machine_mode
);
113 static rtx
expand_builtin_mempcpy (tree
, tree
, rtx
, enum machine_mode
, int);
114 static rtx
expand_builtin_memmove (tree
, tree
, rtx
, enum machine_mode
, tree
);
115 static rtx
expand_builtin_bcopy (tree
);
116 static rtx
expand_builtin_strcpy (tree
, tree
, rtx
, enum machine_mode
);
117 static rtx
expand_builtin_stpcpy (tree
, rtx
, enum machine_mode
);
118 static rtx
builtin_strncpy_read_str (void *, HOST_WIDE_INT
, enum machine_mode
);
119 static rtx
expand_builtin_strncpy (tree
, rtx
, enum machine_mode
);
120 static rtx
builtin_memset_read_str (void *, HOST_WIDE_INT
, enum machine_mode
);
121 static rtx
builtin_memset_gen_str (void *, HOST_WIDE_INT
, enum machine_mode
);
122 static rtx
expand_builtin_memset (tree
, rtx
, enum machine_mode
, tree
);
123 static rtx
expand_builtin_bzero (tree
);
124 static rtx
expand_builtin_strlen (tree
, rtx
, enum machine_mode
);
125 static rtx
expand_builtin_strstr (tree
, tree
, rtx
, enum machine_mode
);
126 static rtx
expand_builtin_strpbrk (tree
, tree
, rtx
, enum machine_mode
);
127 static rtx
expand_builtin_strchr (tree
, tree
, rtx
, enum machine_mode
);
128 static rtx
expand_builtin_strrchr (tree
, tree
, rtx
, enum machine_mode
);
129 static rtx
expand_builtin_alloca (tree
, rtx
);
130 static rtx
expand_builtin_unop (enum machine_mode
, tree
, rtx
, rtx
, optab
);
131 static rtx
expand_builtin_frame_address (tree
, tree
);
132 static rtx
expand_builtin_fputs (tree
, rtx
, bool);
133 static rtx
expand_builtin_printf (tree
, rtx
, enum machine_mode
, bool);
134 static rtx
expand_builtin_fprintf (tree
, rtx
, enum machine_mode
, bool);
135 static rtx
expand_builtin_sprintf (tree
, rtx
, enum machine_mode
);
136 static tree
stabilize_va_list (tree
, int);
137 static rtx
expand_builtin_expect (tree
, rtx
);
138 static tree
fold_builtin_constant_p (tree
);
139 static tree
fold_builtin_classify_type (tree
);
140 static tree
fold_builtin_strlen (tree
);
141 static tree
fold_builtin_inf (tree
, int);
142 static tree
fold_builtin_nan (tree
, tree
, int);
143 static int validate_arglist (tree
, ...);
144 static bool integer_valued_real_p (tree
);
145 static tree
fold_trunc_transparent_mathfn (tree
, tree
);
146 static bool readonly_data_expr (tree
);
147 static rtx
expand_builtin_fabs (tree
, rtx
, rtx
);
148 static rtx
expand_builtin_signbit (tree
, rtx
);
149 static tree
fold_builtin_sqrt (tree
, tree
);
150 static tree
fold_builtin_cbrt (tree
, tree
);
151 static tree
fold_builtin_pow (tree
, tree
, tree
);
152 static tree
fold_builtin_powi (tree
, tree
, tree
);
153 static tree
fold_builtin_sin (tree
);
154 static tree
fold_builtin_cos (tree
, tree
, tree
);
155 static tree
fold_builtin_tan (tree
);
156 static tree
fold_builtin_atan (tree
, tree
);
157 static tree
fold_builtin_trunc (tree
, tree
);
158 static tree
fold_builtin_floor (tree
, tree
);
159 static tree
fold_builtin_ceil (tree
, tree
);
160 static tree
fold_builtin_round (tree
, tree
);
161 static tree
fold_builtin_int_roundingfn (tree
, tree
);
162 static tree
fold_builtin_bitop (tree
, tree
);
163 static tree
fold_builtin_memory_op (tree
, tree
, bool, int);
164 static tree
fold_builtin_strchr (tree
, tree
);
165 static tree
fold_builtin_memcmp (tree
);
166 static tree
fold_builtin_strcmp (tree
);
167 static tree
fold_builtin_strncmp (tree
);
168 static tree
fold_builtin_signbit (tree
, tree
);
169 static tree
fold_builtin_copysign (tree
, tree
, tree
);
170 static tree
fold_builtin_isascii (tree
);
171 static tree
fold_builtin_toascii (tree
);
172 static tree
fold_builtin_isdigit (tree
);
173 static tree
fold_builtin_fabs (tree
, tree
);
174 static tree
fold_builtin_abs (tree
, tree
);
175 static tree
fold_builtin_unordered_cmp (tree
, tree
, enum tree_code
,
177 static tree
fold_builtin_1 (tree
, tree
, bool);
179 static tree
fold_builtin_strpbrk (tree
, tree
);
180 static tree
fold_builtin_strstr (tree
, tree
);
181 static tree
fold_builtin_strrchr (tree
, tree
);
182 static tree
fold_builtin_strcat (tree
);
183 static tree
fold_builtin_strncat (tree
);
184 static tree
fold_builtin_strspn (tree
);
185 static tree
fold_builtin_strcspn (tree
);
186 static tree
fold_builtin_sprintf (tree
, int);
188 static rtx
expand_builtin_object_size (tree
);
189 static rtx
expand_builtin_memory_chk (tree
, rtx
, enum machine_mode
,
190 enum built_in_function
);
191 static void maybe_emit_chk_warning (tree
, enum built_in_function
);
192 static void maybe_emit_sprintf_chk_warning (tree
, enum built_in_function
);
193 static tree
fold_builtin_object_size (tree
);
194 static tree
fold_builtin_strcat_chk (tree
, tree
);
195 static tree
fold_builtin_strncat_chk (tree
, tree
);
196 static tree
fold_builtin_sprintf_chk (tree
, enum built_in_function
);
197 static tree
fold_builtin_printf (tree
, tree
, bool, enum built_in_function
);
198 static tree
fold_builtin_fprintf (tree
, tree
, bool, enum built_in_function
);
199 static bool init_target_chars (void);
201 static unsigned HOST_WIDE_INT target_newline
;
202 static unsigned HOST_WIDE_INT target_percent
;
203 static unsigned HOST_WIDE_INT target_c
;
204 static unsigned HOST_WIDE_INT target_s
;
205 static char target_percent_c
[3];
206 static char target_percent_s
[3];
207 static char target_percent_s_newline
[4];
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 if (! POINTER_TYPE_P (TREE_TYPE (exp
)))
239 align
= TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp
)));
240 align
= MIN (align
, max_align
);
244 switch (TREE_CODE (exp
))
248 case NON_LVALUE_EXPR
:
249 exp
= TREE_OPERAND (exp
, 0);
250 if (! POINTER_TYPE_P (TREE_TYPE (exp
)))
253 inner
= TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp
)));
254 align
= MIN (inner
, max_align
);
258 /* If sum of pointer + int, restrict our maximum alignment to that
259 imposed by the integer. If not, we can't do any better than
261 if (! host_integerp (TREE_OPERAND (exp
, 1), 1))
264 while (((tree_low_cst (TREE_OPERAND (exp
, 1), 1))
265 & (max_align
/ BITS_PER_UNIT
- 1))
269 exp
= TREE_OPERAND (exp
, 0);
273 /* See what we are pointing at and look at its alignment. */
274 exp
= TREE_OPERAND (exp
, 0);
276 if (handled_component_p (exp
))
278 HOST_WIDE_INT bitsize
, bitpos
;
280 enum machine_mode mode
;
281 int unsignedp
, volatilep
;
283 exp
= get_inner_reference (exp
, &bitsize
, &bitpos
, &offset
,
284 &mode
, &unsignedp
, &volatilep
, true);
286 inner
= MIN (inner
, (unsigned) (bitpos
& -bitpos
));
287 if (offset
&& TREE_CODE (offset
) == PLUS_EXPR
288 && host_integerp (TREE_OPERAND (offset
, 1), 1))
290 /* Any overflow in calculating offset_bits won't change
293 = ((unsigned) tree_low_cst (TREE_OPERAND (offset
, 1), 1)
297 inner
= MIN (inner
, (offset_bits
& -offset_bits
));
298 offset
= TREE_OPERAND (offset
, 0);
300 if (offset
&& TREE_CODE (offset
) == MULT_EXPR
301 && host_integerp (TREE_OPERAND (offset
, 1), 1))
303 /* Any overflow in calculating offset_factor won't change
305 unsigned offset_factor
306 = ((unsigned) tree_low_cst (TREE_OPERAND (offset
, 1), 1)
310 inner
= MIN (inner
, (offset_factor
& -offset_factor
));
313 inner
= MIN (inner
, BITS_PER_UNIT
);
315 if (TREE_CODE (exp
) == FUNCTION_DECL
)
316 align
= FUNCTION_BOUNDARY
;
317 else if (DECL_P (exp
))
318 align
= MIN (inner
, DECL_ALIGN (exp
));
319 #ifdef CONSTANT_ALIGNMENT
320 else if (CONSTANT_CLASS_P (exp
))
321 align
= MIN (inner
, (unsigned)CONSTANT_ALIGNMENT (exp
, align
));
323 else if (TREE_CODE (exp
) == VIEW_CONVERT_EXPR
324 || TREE_CODE (exp
) == INDIRECT_REF
)
325 align
= MIN (TYPE_ALIGN (TREE_TYPE (exp
)), inner
);
327 align
= MIN (align
, inner
);
328 return MIN (align
, max_align
);
336 /* Compute the length of a C string. TREE_STRING_LENGTH is not the right
337 way, because it could contain a zero byte in the middle.
338 TREE_STRING_LENGTH is the size of the character array, not the string.
340 ONLY_VALUE should be nonzero if the result is not going to be emitted
341 into the instruction stream and zero if it is going to be expanded.
342 E.g. with i++ ? "foo" : "bar", if ONLY_VALUE is nonzero, constant 3
343 is returned, otherwise NULL, since
344 len = c_strlen (src, 1); if (len) expand_expr (len, ...); would not
345 evaluate the side-effects.
347 The value returned is of type `ssizetype'.
349 Unfortunately, string_constant can't access the values of const char
350 arrays with initializers, so neither can we do so here. */
353 c_strlen (tree src
, int only_value
)
356 HOST_WIDE_INT offset
;
361 if (TREE_CODE (src
) == COND_EXPR
362 && (only_value
|| !TREE_SIDE_EFFECTS (TREE_OPERAND (src
, 0))))
366 len1
= c_strlen (TREE_OPERAND (src
, 1), only_value
);
367 len2
= c_strlen (TREE_OPERAND (src
, 2), only_value
);
368 if (tree_int_cst_equal (len1
, len2
))
372 if (TREE_CODE (src
) == COMPOUND_EXPR
373 && (only_value
|| !TREE_SIDE_EFFECTS (TREE_OPERAND (src
, 0))))
374 return c_strlen (TREE_OPERAND (src
, 1), only_value
);
376 src
= string_constant (src
, &offset_node
);
380 max
= TREE_STRING_LENGTH (src
) - 1;
381 ptr
= TREE_STRING_POINTER (src
);
383 if (offset_node
&& TREE_CODE (offset_node
) != INTEGER_CST
)
385 /* If the string has an internal zero byte (e.g., "foo\0bar"), we can't
386 compute the offset to the following null if we don't know where to
387 start searching for it. */
390 for (i
= 0; i
< max
; i
++)
394 /* We don't know the starting offset, but we do know that the string
395 has no internal zero bytes. We can assume that the offset falls
396 within the bounds of the string; otherwise, the programmer deserves
397 what he gets. Subtract the offset from the length of the string,
398 and return that. This would perhaps not be valid if we were dealing
399 with named arrays in addition to literal string constants. */
401 return size_diffop (size_int (max
), offset_node
);
404 /* We have a known offset into the string. Start searching there for
405 a null character if we can represent it as a single HOST_WIDE_INT. */
406 if (offset_node
== 0)
408 else if (! host_integerp (offset_node
, 0))
411 offset
= tree_low_cst (offset_node
, 0);
413 /* If the offset is known to be out of bounds, warn, and call strlen at
415 if (offset
< 0 || offset
> max
)
417 warning (0, "offset outside bounds of constant string");
421 /* Use strlen to search for the first zero byte. Since any strings
422 constructed with build_string will have nulls appended, we win even
423 if we get handed something like (char[4])"abcd".
425 Since OFFSET is our starting index into the string, no further
426 calculation is needed. */
427 return ssize_int (strlen (ptr
+ offset
));
430 /* Return a char pointer for a C string if it is a string constant
431 or sum of string constant and integer constant. */
438 src
= string_constant (src
, &offset_node
);
442 if (offset_node
== 0)
443 return TREE_STRING_POINTER (src
);
444 else if (!host_integerp (offset_node
, 1)
445 || compare_tree_int (offset_node
, TREE_STRING_LENGTH (src
) - 1) > 0)
448 return TREE_STRING_POINTER (src
) + tree_low_cst (offset_node
, 1);
451 /* Return a CONST_INT or CONST_DOUBLE corresponding to target reading
452 GET_MODE_BITSIZE (MODE) bits from string constant STR. */
455 c_readstr (const char *str
, enum machine_mode mode
)
461 gcc_assert (GET_MODE_CLASS (mode
) == MODE_INT
);
466 for (i
= 0; i
< GET_MODE_SIZE (mode
); i
++)
469 if (WORDS_BIG_ENDIAN
)
470 j
= GET_MODE_SIZE (mode
) - i
- 1;
471 if (BYTES_BIG_ENDIAN
!= WORDS_BIG_ENDIAN
472 && GET_MODE_SIZE (mode
) > UNITS_PER_WORD
)
473 j
= j
+ UNITS_PER_WORD
- 2 * (j
% UNITS_PER_WORD
) - 1;
475 gcc_assert (j
<= 2 * HOST_BITS_PER_WIDE_INT
);
478 ch
= (unsigned char) str
[i
];
479 c
[j
/ HOST_BITS_PER_WIDE_INT
] |= ch
<< (j
% HOST_BITS_PER_WIDE_INT
);
481 return immed_double_const (c
[0], c
[1], mode
);
484 /* Cast a target constant CST to target CHAR and if that value fits into
485 host char type, return zero and put that value into variable pointed to by
489 target_char_cast (tree cst
, char *p
)
491 unsigned HOST_WIDE_INT val
, hostval
;
493 if (!host_integerp (cst
, 1)
494 || CHAR_TYPE_SIZE
> HOST_BITS_PER_WIDE_INT
)
497 val
= tree_low_cst (cst
, 1);
498 if (CHAR_TYPE_SIZE
< HOST_BITS_PER_WIDE_INT
)
499 val
&= (((unsigned HOST_WIDE_INT
) 1) << CHAR_TYPE_SIZE
) - 1;
502 if (HOST_BITS_PER_CHAR
< HOST_BITS_PER_WIDE_INT
)
503 hostval
&= (((unsigned HOST_WIDE_INT
) 1) << HOST_BITS_PER_CHAR
) - 1;
512 /* Similar to save_expr, but assumes that arbitrary code is not executed
513 in between the multiple evaluations. In particular, we assume that a
514 non-addressable local variable will not be modified. */
517 builtin_save_expr (tree exp
)
519 if (TREE_ADDRESSABLE (exp
) == 0
520 && (TREE_CODE (exp
) == PARM_DECL
521 || (TREE_CODE (exp
) == VAR_DECL
&& !TREE_STATIC (exp
))))
524 return save_expr (exp
);
527 /* Given TEM, a pointer to a stack frame, follow the dynamic chain COUNT
528 times to get the address of either a higher stack frame, or a return
529 address located within it (depending on FNDECL_CODE). */
532 expand_builtin_return_addr (enum built_in_function fndecl_code
, int count
)
536 #ifdef INITIAL_FRAME_ADDRESS_RTX
537 rtx tem
= INITIAL_FRAME_ADDRESS_RTX
;
541 /* For a zero count with __builtin_return_address, we don't care what
542 frame address we return, because target-specific definitions will
543 override us. Therefore frame pointer elimination is OK, and using
544 the soft frame pointer is OK.
546 For a non-zero count, or a zero count with __builtin_frame_address,
547 we require a stable offset from the current frame pointer to the
548 previous one, so we must use the hard frame pointer, and
549 we must disable frame pointer elimination. */
550 if (count
== 0 && fndecl_code
== BUILT_IN_RETURN_ADDRESS
)
551 tem
= frame_pointer_rtx
;
554 tem
= hard_frame_pointer_rtx
;
556 /* Tell reload not to eliminate the frame pointer. */
557 current_function_accesses_prior_frames
= 1;
561 /* Some machines need special handling before we can access
562 arbitrary frames. For example, on the sparc, we must first flush
563 all register windows to the stack. */
564 #ifdef SETUP_FRAME_ADDRESSES
566 SETUP_FRAME_ADDRESSES ();
569 /* On the sparc, the return address is not in the frame, it is in a
570 register. There is no way to access it off of the current frame
571 pointer, but it can be accessed off the previous frame pointer by
572 reading the value from the register window save area. */
573 #ifdef RETURN_ADDR_IN_PREVIOUS_FRAME
574 if (fndecl_code
== BUILT_IN_RETURN_ADDRESS
)
578 /* Scan back COUNT frames to the specified frame. */
579 for (i
= 0; i
< count
; i
++)
581 /* Assume the dynamic chain pointer is in the word that the
582 frame address points to, unless otherwise specified. */
583 #ifdef DYNAMIC_CHAIN_ADDRESS
584 tem
= DYNAMIC_CHAIN_ADDRESS (tem
);
586 tem
= memory_address (Pmode
, tem
);
587 tem
= gen_frame_mem (Pmode
, tem
);
588 tem
= copy_to_reg (tem
);
591 /* For __builtin_frame_address, return what we've got. */
592 if (fndecl_code
== BUILT_IN_FRAME_ADDRESS
)
595 /* For __builtin_return_address, Get the return address from that
597 #ifdef RETURN_ADDR_RTX
598 tem
= RETURN_ADDR_RTX (count
, tem
);
600 tem
= memory_address (Pmode
,
601 plus_constant (tem
, GET_MODE_SIZE (Pmode
)));
602 tem
= gen_frame_mem (Pmode
, tem
);
607 /* Alias set used for setjmp buffer. */
608 static HOST_WIDE_INT setjmp_alias_set
= -1;
610 /* Construct the leading half of a __builtin_setjmp call. Control will
611 return to RECEIVER_LABEL. This is used directly by sjlj exception
615 expand_builtin_setjmp_setup (rtx buf_addr
, rtx receiver_label
)
617 enum machine_mode sa_mode
= STACK_SAVEAREA_MODE (SAVE_NONLOCAL
);
621 if (setjmp_alias_set
== -1)
622 setjmp_alias_set
= new_alias_set ();
624 buf_addr
= convert_memory_address (Pmode
, buf_addr
);
626 buf_addr
= force_reg (Pmode
, force_operand (buf_addr
, NULL_RTX
));
628 /* We store the frame pointer and the address of receiver_label in
629 the buffer and use the rest of it for the stack save area, which
630 is machine-dependent. */
632 mem
= gen_rtx_MEM (Pmode
, buf_addr
);
633 set_mem_alias_set (mem
, setjmp_alias_set
);
634 emit_move_insn (mem
, targetm
.builtin_setjmp_frame_value ());
636 mem
= gen_rtx_MEM (Pmode
, plus_constant (buf_addr
, GET_MODE_SIZE (Pmode
))),
637 set_mem_alias_set (mem
, setjmp_alias_set
);
639 emit_move_insn (validize_mem (mem
),
640 force_reg (Pmode
, gen_rtx_LABEL_REF (Pmode
, receiver_label
)));
642 stack_save
= gen_rtx_MEM (sa_mode
,
643 plus_constant (buf_addr
,
644 2 * GET_MODE_SIZE (Pmode
)));
645 set_mem_alias_set (stack_save
, setjmp_alias_set
);
646 emit_stack_save (SAVE_NONLOCAL
, &stack_save
, NULL_RTX
);
648 /* If there is further processing to do, do it. */
649 #ifdef HAVE_builtin_setjmp_setup
650 if (HAVE_builtin_setjmp_setup
)
651 emit_insn (gen_builtin_setjmp_setup (buf_addr
));
654 /* Tell optimize_save_area_alloca that extra work is going to
655 need to go on during alloca. */
656 current_function_calls_setjmp
= 1;
658 /* Set this so all the registers get saved in our frame; we need to be
659 able to copy the saved values for any registers from frames we unwind. */
660 current_function_has_nonlocal_label
= 1;
663 /* Construct the trailing part of a __builtin_setjmp call.
664 This is used directly by sjlj exception handling code. */
667 expand_builtin_setjmp_receiver (rtx receiver_label ATTRIBUTE_UNUSED
)
669 /* Clobber the FP when we get here, so we have to make sure it's
670 marked as used by this function. */
671 emit_insn (gen_rtx_USE (VOIDmode
, hard_frame_pointer_rtx
));
673 /* Mark the static chain as clobbered here so life information
674 doesn't get messed up for it. */
675 emit_insn (gen_rtx_CLOBBER (VOIDmode
, static_chain_rtx
));
677 /* Now put in the code to restore the frame pointer, and argument
678 pointer, if needed. */
679 #ifdef HAVE_nonlocal_goto
680 if (! HAVE_nonlocal_goto
)
683 emit_move_insn (virtual_stack_vars_rtx
, hard_frame_pointer_rtx
);
684 /* This might change the hard frame pointer in ways that aren't
685 apparent to early optimization passes, so force a clobber. */
686 emit_insn (gen_rtx_CLOBBER (VOIDmode
, hard_frame_pointer_rtx
));
689 #if ARG_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
690 if (fixed_regs
[ARG_POINTER_REGNUM
])
692 #ifdef ELIMINABLE_REGS
694 static const struct elims
{const int from
, to
;} elim_regs
[] = ELIMINABLE_REGS
;
696 for (i
= 0; i
< ARRAY_SIZE (elim_regs
); i
++)
697 if (elim_regs
[i
].from
== ARG_POINTER_REGNUM
698 && elim_regs
[i
].to
== HARD_FRAME_POINTER_REGNUM
)
701 if (i
== ARRAY_SIZE (elim_regs
))
704 /* Now restore our arg pointer from the address at which it
705 was saved in our stack frame. */
706 emit_move_insn (virtual_incoming_args_rtx
,
707 copy_to_reg (get_arg_pointer_save_area (cfun
)));
712 #ifdef HAVE_builtin_setjmp_receiver
713 if (HAVE_builtin_setjmp_receiver
)
714 emit_insn (gen_builtin_setjmp_receiver (receiver_label
));
717 #ifdef HAVE_nonlocal_goto_receiver
718 if (HAVE_nonlocal_goto_receiver
)
719 emit_insn (gen_nonlocal_goto_receiver ());
724 /* @@@ This is a kludge. Not all machine descriptions define a blockage
725 insn, but we must not allow the code we just generated to be reordered
726 by scheduling. Specifically, the update of the frame pointer must
727 happen immediately, not later. So emit an ASM_INPUT to act as blockage
729 emit_insn (gen_rtx_ASM_INPUT (VOIDmode
, ""));
732 /* __builtin_setjmp is passed a pointer to an array of five words (not
733 all will be used on all machines). It operates similarly to the C
734 library function of the same name, but is more efficient. Much of
735 the code below (and for longjmp) is copied from the handling of
738 NOTE: This is intended for use by GNAT and the exception handling
739 scheme in the compiler and will only work in the method used by
743 expand_builtin_setjmp (tree arglist
, rtx target
)
745 rtx buf_addr
, next_lab
, cont_lab
;
747 if (!validate_arglist (arglist
, POINTER_TYPE
, VOID_TYPE
))
750 if (target
== 0 || !REG_P (target
)
751 || REGNO (target
) < FIRST_PSEUDO_REGISTER
)
752 target
= gen_reg_rtx (TYPE_MODE (integer_type_node
));
754 buf_addr
= expand_normal (TREE_VALUE (arglist
));
756 next_lab
= gen_label_rtx ();
757 cont_lab
= gen_label_rtx ();
759 expand_builtin_setjmp_setup (buf_addr
, next_lab
);
761 /* Set TARGET to zero and branch to the continue label. Use emit_jump to
762 ensure that pending stack adjustments are flushed. */
763 emit_move_insn (target
, const0_rtx
);
764 emit_jump (cont_lab
);
766 emit_label (next_lab
);
768 /* Because setjmp and longjmp are not represented in the CFG, a cfgcleanup
769 may find that the basic block starting with NEXT_LAB is unreachable.
770 The whole block, along with NEXT_LAB, would be removed (see PR26983).
771 Make sure that never happens. */
772 LABEL_PRESERVE_P (next_lab
) = 1;
774 expand_builtin_setjmp_receiver (next_lab
);
776 /* Set TARGET to one. */
777 emit_move_insn (target
, const1_rtx
);
778 emit_label (cont_lab
);
780 /* Tell flow about the strange goings on. Putting `next_lab' on
781 `nonlocal_goto_handler_labels' to indicates that function
782 calls may traverse the arc back to this label. */
784 current_function_has_nonlocal_label
= 1;
785 nonlocal_goto_handler_labels
786 = gen_rtx_EXPR_LIST (VOIDmode
, next_lab
, nonlocal_goto_handler_labels
);
791 /* __builtin_longjmp is passed a pointer to an array of five words (not
792 all will be used on all machines). It operates similarly to the C
793 library function of the same name, but is more efficient. Much of
794 the code below is copied from the handling of non-local gotos.
796 NOTE: This is intended for use by GNAT and the exception handling
797 scheme in the compiler and will only work in the method used by
801 expand_builtin_longjmp (rtx buf_addr
, rtx value
)
803 rtx fp
, lab
, stack
, insn
, last
;
804 enum machine_mode sa_mode
= STACK_SAVEAREA_MODE (SAVE_NONLOCAL
);
806 if (setjmp_alias_set
== -1)
807 setjmp_alias_set
= new_alias_set ();
809 buf_addr
= convert_memory_address (Pmode
, buf_addr
);
811 buf_addr
= force_reg (Pmode
, buf_addr
);
813 /* We used to store value in static_chain_rtx, but that fails if pointers
814 are smaller than integers. We instead require that the user must pass
815 a second argument of 1, because that is what builtin_setjmp will
816 return. This also makes EH slightly more efficient, since we are no
817 longer copying around a value that we don't care about. */
818 gcc_assert (value
== const1_rtx
);
820 last
= get_last_insn ();
821 #ifdef HAVE_builtin_longjmp
822 if (HAVE_builtin_longjmp
)
823 emit_insn (gen_builtin_longjmp (buf_addr
));
827 fp
= gen_rtx_MEM (Pmode
, buf_addr
);
828 lab
= gen_rtx_MEM (Pmode
, plus_constant (buf_addr
,
829 GET_MODE_SIZE (Pmode
)));
831 stack
= gen_rtx_MEM (sa_mode
, plus_constant (buf_addr
,
832 2 * GET_MODE_SIZE (Pmode
)));
833 set_mem_alias_set (fp
, setjmp_alias_set
);
834 set_mem_alias_set (lab
, setjmp_alias_set
);
835 set_mem_alias_set (stack
, setjmp_alias_set
);
837 /* Pick up FP, label, and SP from the block and jump. This code is
838 from expand_goto in stmt.c; see there for detailed comments. */
839 #ifdef HAVE_nonlocal_goto
840 if (HAVE_nonlocal_goto
)
841 /* We have to pass a value to the nonlocal_goto pattern that will
842 get copied into the static_chain pointer, but it does not matter
843 what that value is, because builtin_setjmp does not use it. */
844 emit_insn (gen_nonlocal_goto (value
, lab
, stack
, fp
));
848 lab
= copy_to_reg (lab
);
850 emit_insn (gen_rtx_CLOBBER (VOIDmode
,
851 gen_rtx_MEM (BLKmode
,
852 gen_rtx_SCRATCH (VOIDmode
))));
853 emit_insn (gen_rtx_CLOBBER (VOIDmode
,
854 gen_rtx_MEM (BLKmode
,
855 hard_frame_pointer_rtx
)));
857 emit_move_insn (hard_frame_pointer_rtx
, fp
);
858 emit_stack_restore (SAVE_NONLOCAL
, stack
, NULL_RTX
);
860 emit_insn (gen_rtx_USE (VOIDmode
, hard_frame_pointer_rtx
));
861 emit_insn (gen_rtx_USE (VOIDmode
, stack_pointer_rtx
));
862 emit_indirect_jump (lab
);
866 /* Search backwards and mark the jump insn as a non-local goto.
867 Note that this precludes the use of __builtin_longjmp to a
868 __builtin_setjmp target in the same function. However, we've
869 already cautioned the user that these functions are for
870 internal exception handling use only. */
871 for (insn
= get_last_insn (); insn
; insn
= PREV_INSN (insn
))
873 gcc_assert (insn
!= last
);
877 REG_NOTES (insn
) = alloc_EXPR_LIST (REG_NON_LOCAL_GOTO
, const0_rtx
,
881 else if (CALL_P (insn
))
886 /* Expand a call to __builtin_nonlocal_goto. We're passed the target label
887 and the address of the save area. */
890 expand_builtin_nonlocal_goto (tree arglist
)
892 tree t_label
, t_save_area
;
893 rtx r_label
, r_save_area
, r_fp
, r_sp
, insn
;
895 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
898 t_label
= TREE_VALUE (arglist
);
899 arglist
= TREE_CHAIN (arglist
);
900 t_save_area
= TREE_VALUE (arglist
);
902 r_label
= expand_normal (t_label
);
903 r_label
= convert_memory_address (Pmode
, r_label
);
904 r_save_area
= expand_normal (t_save_area
);
905 r_save_area
= convert_memory_address (Pmode
, r_save_area
);
906 r_fp
= gen_rtx_MEM (Pmode
, r_save_area
);
907 r_sp
= gen_rtx_MEM (STACK_SAVEAREA_MODE (SAVE_NONLOCAL
),
908 plus_constant (r_save_area
, GET_MODE_SIZE (Pmode
)));
910 current_function_has_nonlocal_goto
= 1;
912 #ifdef HAVE_nonlocal_goto
913 /* ??? We no longer need to pass the static chain value, afaik. */
914 if (HAVE_nonlocal_goto
)
915 emit_insn (gen_nonlocal_goto (const0_rtx
, r_label
, r_sp
, r_fp
));
919 r_label
= copy_to_reg (r_label
);
921 emit_insn (gen_rtx_CLOBBER (VOIDmode
,
922 gen_rtx_MEM (BLKmode
,
923 gen_rtx_SCRATCH (VOIDmode
))));
925 emit_insn (gen_rtx_CLOBBER (VOIDmode
,
926 gen_rtx_MEM (BLKmode
,
927 hard_frame_pointer_rtx
)));
929 /* Restore frame pointer for containing function.
930 This sets the actual hard register used for the frame pointer
931 to the location of the function's incoming static chain info.
932 The non-local goto handler will then adjust it to contain the
933 proper value and reload the argument pointer, if needed. */
934 emit_move_insn (hard_frame_pointer_rtx
, r_fp
);
935 emit_stack_restore (SAVE_NONLOCAL
, r_sp
, NULL_RTX
);
937 /* USE of hard_frame_pointer_rtx added for consistency;
938 not clear if really needed. */
939 emit_insn (gen_rtx_USE (VOIDmode
, hard_frame_pointer_rtx
));
940 emit_insn (gen_rtx_USE (VOIDmode
, stack_pointer_rtx
));
941 emit_indirect_jump (r_label
);
944 /* Search backwards to the jump insn and mark it as a
946 for (insn
= get_last_insn (); insn
; insn
= PREV_INSN (insn
))
950 REG_NOTES (insn
) = alloc_EXPR_LIST (REG_NON_LOCAL_GOTO
,
951 const0_rtx
, REG_NOTES (insn
));
954 else if (CALL_P (insn
))
961 /* __builtin_update_setjmp_buf is passed a pointer to an array of five words
962 (not all will be used on all machines) that was passed to __builtin_setjmp.
963 It updates the stack pointer in that block to correspond to the current
967 expand_builtin_update_setjmp_buf (rtx buf_addr
)
969 enum machine_mode sa_mode
= Pmode
;
973 #ifdef HAVE_save_stack_nonlocal
974 if (HAVE_save_stack_nonlocal
)
975 sa_mode
= insn_data
[(int) CODE_FOR_save_stack_nonlocal
].operand
[0].mode
;
977 #ifdef STACK_SAVEAREA_MODE
978 sa_mode
= STACK_SAVEAREA_MODE (SAVE_NONLOCAL
);
982 = gen_rtx_MEM (sa_mode
,
985 plus_constant (buf_addr
, 2 * GET_MODE_SIZE (Pmode
))));
989 emit_insn (gen_setjmp ());
992 emit_stack_save (SAVE_NONLOCAL
, &stack_save
, NULL_RTX
);
995 /* Expand a call to __builtin_prefetch. For a target that does not support
996 data prefetch, evaluate the memory address argument in case it has side
1000 expand_builtin_prefetch (tree arglist
)
1002 tree arg0
, arg1
, arg2
;
1005 if (!validate_arglist (arglist
, POINTER_TYPE
, 0))
1008 arg0
= TREE_VALUE (arglist
);
1009 /* Arguments 1 and 2 are optional; argument 1 (read/write) defaults to
1010 zero (read) and argument 2 (locality) defaults to 3 (high degree of
1012 if (TREE_CHAIN (arglist
))
1014 arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
1015 if (TREE_CHAIN (TREE_CHAIN (arglist
)))
1016 arg2
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
1018 arg2
= build_int_cst (NULL_TREE
, 3);
1022 arg1
= integer_zero_node
;
1023 arg2
= build_int_cst (NULL_TREE
, 3);
1026 /* Argument 0 is an address. */
1027 op0
= expand_expr (arg0
, NULL_RTX
, Pmode
, EXPAND_NORMAL
);
1029 /* Argument 1 (read/write flag) must be a compile-time constant int. */
1030 if (TREE_CODE (arg1
) != INTEGER_CST
)
1032 error ("second argument to %<__builtin_prefetch%> must be a constant");
1033 arg1
= integer_zero_node
;
1035 op1
= expand_normal (arg1
);
1036 /* Argument 1 must be either zero or one. */
1037 if (INTVAL (op1
) != 0 && INTVAL (op1
) != 1)
1039 warning (0, "invalid second argument to %<__builtin_prefetch%>;"
1044 /* Argument 2 (locality) must be a compile-time constant int. */
1045 if (TREE_CODE (arg2
) != INTEGER_CST
)
1047 error ("third argument to %<__builtin_prefetch%> must be a constant");
1048 arg2
= integer_zero_node
;
1050 op2
= expand_normal (arg2
);
1051 /* Argument 2 must be 0, 1, 2, or 3. */
1052 if (INTVAL (op2
) < 0 || INTVAL (op2
) > 3)
1054 warning (0, "invalid third argument to %<__builtin_prefetch%>; using zero");
1058 #ifdef HAVE_prefetch
1061 if ((! (*insn_data
[(int) CODE_FOR_prefetch
].operand
[0].predicate
)
1063 insn_data
[(int) CODE_FOR_prefetch
].operand
[0].mode
))
1064 || (GET_MODE (op0
) != Pmode
))
1066 op0
= convert_memory_address (Pmode
, op0
);
1067 op0
= force_reg (Pmode
, op0
);
1069 emit_insn (gen_prefetch (op0
, op1
, op2
));
1073 /* Don't do anything with direct references to volatile memory, but
1074 generate code to handle other side effects. */
1075 if (!MEM_P (op0
) && side_effects_p (op0
))
1079 /* Get a MEM rtx for expression EXP which is the address of an operand
1080 to be used in a string instruction (cmpstrsi, movmemsi, ..). LEN is
1081 the maximum length of the block of memory that might be accessed or
1085 get_memory_rtx (tree exp
, tree len
)
1087 rtx addr
= expand_expr (exp
, NULL_RTX
, ptr_mode
, EXPAND_NORMAL
);
1088 rtx mem
= gen_rtx_MEM (BLKmode
, memory_address (BLKmode
, addr
));
1090 /* Get an expression we can use to find the attributes to assign to MEM.
1091 If it is an ADDR_EXPR, use the operand. Otherwise, dereference it if
1092 we can. First remove any nops. */
1093 while ((TREE_CODE (exp
) == NOP_EXPR
|| TREE_CODE (exp
) == CONVERT_EXPR
1094 || TREE_CODE (exp
) == NON_LVALUE_EXPR
)
1095 && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (exp
, 0))))
1096 exp
= TREE_OPERAND (exp
, 0);
1098 if (TREE_CODE (exp
) == ADDR_EXPR
)
1099 exp
= TREE_OPERAND (exp
, 0);
1100 else if (POINTER_TYPE_P (TREE_TYPE (exp
)))
1101 exp
= build1 (INDIRECT_REF
, TREE_TYPE (TREE_TYPE (exp
)), exp
);
1105 /* Honor attributes derived from exp, except for the alias set
1106 (as builtin stringops may alias with anything) and the size
1107 (as stringops may access multiple array elements). */
1110 set_mem_attributes (mem
, exp
, 0);
1112 /* Allow the string and memory builtins to overflow from one
1113 field into another, see http://gcc.gnu.org/PR23561.
1114 Thus avoid COMPONENT_REFs in MEM_EXPR unless we know the whole
1115 memory accessed by the string or memory builtin will fit
1116 within the field. */
1117 if (MEM_EXPR (mem
) && TREE_CODE (MEM_EXPR (mem
)) == COMPONENT_REF
)
1119 tree mem_expr
= MEM_EXPR (mem
);
1120 HOST_WIDE_INT offset
= -1, length
= -1;
1123 while (TREE_CODE (inner
) == ARRAY_REF
1124 || TREE_CODE (inner
) == NOP_EXPR
1125 || TREE_CODE (inner
) == CONVERT_EXPR
1126 || TREE_CODE (inner
) == NON_LVALUE_EXPR
1127 || TREE_CODE (inner
) == VIEW_CONVERT_EXPR
1128 || TREE_CODE (inner
) == SAVE_EXPR
)
1129 inner
= TREE_OPERAND (inner
, 0);
1131 gcc_assert (TREE_CODE (inner
) == COMPONENT_REF
);
1133 if (MEM_OFFSET (mem
)
1134 && GET_CODE (MEM_OFFSET (mem
)) == CONST_INT
)
1135 offset
= INTVAL (MEM_OFFSET (mem
));
1137 if (offset
>= 0 && len
&& host_integerp (len
, 0))
1138 length
= tree_low_cst (len
, 0);
1140 while (TREE_CODE (inner
) == COMPONENT_REF
)
1142 tree field
= TREE_OPERAND (inner
, 1);
1143 gcc_assert (! DECL_BIT_FIELD (field
));
1144 gcc_assert (TREE_CODE (mem_expr
) == COMPONENT_REF
);
1145 gcc_assert (field
== TREE_OPERAND (mem_expr
, 1));
1148 && TYPE_SIZE_UNIT (TREE_TYPE (inner
))
1149 && host_integerp (TYPE_SIZE_UNIT (TREE_TYPE (inner
)), 0))
1152 = tree_low_cst (TYPE_SIZE_UNIT (TREE_TYPE (inner
)), 0);
1153 /* If we can prove the memory starting at XEXP (mem, 0)
1154 and ending at XEXP (mem, 0) + LENGTH will fit into
1155 this field, we can keep that COMPONENT_REF in MEM_EXPR. */
1158 && offset
+ length
<= size
)
1163 && host_integerp (DECL_FIELD_OFFSET (field
), 0))
1164 offset
+= tree_low_cst (DECL_FIELD_OFFSET (field
), 0)
1165 + tree_low_cst (DECL_FIELD_BIT_OFFSET (field
), 1)
1173 mem_expr
= TREE_OPERAND (mem_expr
, 0);
1174 inner
= TREE_OPERAND (inner
, 0);
1177 if (mem_expr
== NULL
)
1179 if (mem_expr
!= MEM_EXPR (mem
))
1181 set_mem_expr (mem
, mem_expr
);
1182 set_mem_offset (mem
, offset
>= 0 ? GEN_INT (offset
) : NULL_RTX
);
1185 set_mem_alias_set (mem
, 0);
1186 set_mem_size (mem
, NULL_RTX
);
1192 /* Built-in functions to perform an untyped call and return. */
1194 /* For each register that may be used for calling a function, this
1195 gives a mode used to copy the register's value. VOIDmode indicates
1196 the register is not used for calling a function. If the machine
1197 has register windows, this gives only the outbound registers.
1198 INCOMING_REGNO gives the corresponding inbound register. */
1199 static enum machine_mode apply_args_mode
[FIRST_PSEUDO_REGISTER
];
1201 /* For each register that may be used for returning values, this gives
1202 a mode used to copy the register's value. VOIDmode indicates the
1203 register is not used for returning values. If the machine has
1204 register windows, this gives only the outbound registers.
1205 INCOMING_REGNO gives the corresponding inbound register. */
1206 static enum machine_mode apply_result_mode
[FIRST_PSEUDO_REGISTER
];
1208 /* For each register that may be used for calling a function, this
1209 gives the offset of that register into the block returned by
1210 __builtin_apply_args. 0 indicates that the register is not
1211 used for calling a function. */
1212 static int apply_args_reg_offset
[FIRST_PSEUDO_REGISTER
];
1214 /* Return the size required for the block returned by __builtin_apply_args,
1215 and initialize apply_args_mode. */
1218 apply_args_size (void)
1220 static int size
= -1;
1223 enum machine_mode mode
;
1225 /* The values computed by this function never change. */
1228 /* The first value is the incoming arg-pointer. */
1229 size
= GET_MODE_SIZE (Pmode
);
1231 /* The second value is the structure value address unless this is
1232 passed as an "invisible" first argument. */
1233 if (targetm
.calls
.struct_value_rtx (cfun
? TREE_TYPE (cfun
->decl
) : 0, 0))
1234 size
+= GET_MODE_SIZE (Pmode
);
1236 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
1237 if (FUNCTION_ARG_REGNO_P (regno
))
1239 mode
= reg_raw_mode
[regno
];
1241 gcc_assert (mode
!= VOIDmode
);
1243 align
= GET_MODE_ALIGNMENT (mode
) / BITS_PER_UNIT
;
1244 if (size
% align
!= 0)
1245 size
= CEIL (size
, align
) * align
;
1246 apply_args_reg_offset
[regno
] = size
;
1247 size
+= GET_MODE_SIZE (mode
);
1248 apply_args_mode
[regno
] = mode
;
1252 apply_args_mode
[regno
] = VOIDmode
;
1253 apply_args_reg_offset
[regno
] = 0;
1259 /* Return the size required for the block returned by __builtin_apply,
1260 and initialize apply_result_mode. */
1263 apply_result_size (void)
1265 static int size
= -1;
1267 enum machine_mode mode
;
1269 /* The values computed by this function never change. */
1274 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
1275 if (FUNCTION_VALUE_REGNO_P (regno
))
1277 mode
= reg_raw_mode
[regno
];
1279 gcc_assert (mode
!= VOIDmode
);
1281 align
= GET_MODE_ALIGNMENT (mode
) / BITS_PER_UNIT
;
1282 if (size
% align
!= 0)
1283 size
= CEIL (size
, align
) * align
;
1284 size
+= GET_MODE_SIZE (mode
);
1285 apply_result_mode
[regno
] = mode
;
1288 apply_result_mode
[regno
] = VOIDmode
;
1290 /* Allow targets that use untyped_call and untyped_return to override
1291 the size so that machine-specific information can be stored here. */
1292 #ifdef APPLY_RESULT_SIZE
1293 size
= APPLY_RESULT_SIZE
;
1299 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
1300 /* Create a vector describing the result block RESULT. If SAVEP is true,
1301 the result block is used to save the values; otherwise it is used to
1302 restore the values. */
1305 result_vector (int savep
, rtx result
)
1307 int regno
, size
, align
, nelts
;
1308 enum machine_mode mode
;
1310 rtx
*savevec
= alloca (FIRST_PSEUDO_REGISTER
* sizeof (rtx
));
1313 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
1314 if ((mode
= apply_result_mode
[regno
]) != VOIDmode
)
1316 align
= GET_MODE_ALIGNMENT (mode
) / BITS_PER_UNIT
;
1317 if (size
% align
!= 0)
1318 size
= CEIL (size
, align
) * align
;
1319 reg
= gen_rtx_REG (mode
, savep
? regno
: INCOMING_REGNO (regno
));
1320 mem
= adjust_address (result
, mode
, size
);
1321 savevec
[nelts
++] = (savep
1322 ? gen_rtx_SET (VOIDmode
, mem
, reg
)
1323 : gen_rtx_SET (VOIDmode
, reg
, mem
));
1324 size
+= GET_MODE_SIZE (mode
);
1326 return gen_rtx_PARALLEL (VOIDmode
, gen_rtvec_v (nelts
, savevec
));
1328 #endif /* HAVE_untyped_call or HAVE_untyped_return */
1330 /* Save the state required to perform an untyped call with the same
1331 arguments as were passed to the current function. */
1334 expand_builtin_apply_args_1 (void)
1337 int size
, align
, regno
;
1338 enum machine_mode mode
;
1339 rtx struct_incoming_value
= targetm
.calls
.struct_value_rtx (cfun
? TREE_TYPE (cfun
->decl
) : 0, 1);
1341 /* Create a block where the arg-pointer, structure value address,
1342 and argument registers can be saved. */
1343 registers
= assign_stack_local (BLKmode
, apply_args_size (), -1);
1345 /* Walk past the arg-pointer and structure value address. */
1346 size
= GET_MODE_SIZE (Pmode
);
1347 if (targetm
.calls
.struct_value_rtx (cfun
? TREE_TYPE (cfun
->decl
) : 0, 0))
1348 size
+= GET_MODE_SIZE (Pmode
);
1350 /* Save each register used in calling a function to the block. */
1351 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
1352 if ((mode
= apply_args_mode
[regno
]) != VOIDmode
)
1354 align
= GET_MODE_ALIGNMENT (mode
) / BITS_PER_UNIT
;
1355 if (size
% align
!= 0)
1356 size
= CEIL (size
, align
) * align
;
1358 tem
= gen_rtx_REG (mode
, INCOMING_REGNO (regno
));
1360 emit_move_insn (adjust_address (registers
, mode
, size
), tem
);
1361 size
+= GET_MODE_SIZE (mode
);
1364 /* Save the arg pointer to the block. */
1365 tem
= copy_to_reg (virtual_incoming_args_rtx
);
1366 #ifdef STACK_GROWS_DOWNWARD
1367 /* We need the pointer as the caller actually passed them to us, not
1368 as we might have pretended they were passed. Make sure it's a valid
1369 operand, as emit_move_insn isn't expected to handle a PLUS. */
1371 = force_operand (plus_constant (tem
, current_function_pretend_args_size
),
1374 emit_move_insn (adjust_address (registers
, Pmode
, 0), tem
);
1376 size
= GET_MODE_SIZE (Pmode
);
1378 /* Save the structure value address unless this is passed as an
1379 "invisible" first argument. */
1380 if (struct_incoming_value
)
1382 emit_move_insn (adjust_address (registers
, Pmode
, size
),
1383 copy_to_reg (struct_incoming_value
));
1384 size
+= GET_MODE_SIZE (Pmode
);
1387 /* Return the address of the block. */
1388 return copy_addr_to_reg (XEXP (registers
, 0));
1391 /* __builtin_apply_args returns block of memory allocated on
1392 the stack into which is stored the arg pointer, structure
1393 value address, static chain, and all the registers that might
1394 possibly be used in performing a function call. The code is
1395 moved to the start of the function so the incoming values are
1399 expand_builtin_apply_args (void)
1401 /* Don't do __builtin_apply_args more than once in a function.
1402 Save the result of the first call and reuse it. */
1403 if (apply_args_value
!= 0)
1404 return apply_args_value
;
1406 /* When this function is called, it means that registers must be
1407 saved on entry to this function. So we migrate the
1408 call to the first insn of this function. */
1413 temp
= expand_builtin_apply_args_1 ();
1417 apply_args_value
= temp
;
1419 /* Put the insns after the NOTE that starts the function.
1420 If this is inside a start_sequence, make the outer-level insn
1421 chain current, so the code is placed at the start of the
1423 push_topmost_sequence ();
1424 emit_insn_before (seq
, NEXT_INSN (entry_of_function ()));
1425 pop_topmost_sequence ();
1430 /* Perform an untyped call and save the state required to perform an
1431 untyped return of whatever value was returned by the given function. */
1434 expand_builtin_apply (rtx function
, rtx arguments
, rtx argsize
)
1436 int size
, align
, regno
;
1437 enum machine_mode mode
;
1438 rtx incoming_args
, result
, reg
, dest
, src
, call_insn
;
1439 rtx old_stack_level
= 0;
1440 rtx call_fusage
= 0;
1441 rtx struct_value
= targetm
.calls
.struct_value_rtx (cfun
? TREE_TYPE (cfun
->decl
) : 0, 0);
1443 arguments
= convert_memory_address (Pmode
, arguments
);
1445 /* Create a block where the return registers can be saved. */
1446 result
= assign_stack_local (BLKmode
, apply_result_size (), -1);
1448 /* Fetch the arg pointer from the ARGUMENTS block. */
1449 incoming_args
= gen_reg_rtx (Pmode
);
1450 emit_move_insn (incoming_args
, gen_rtx_MEM (Pmode
, arguments
));
1451 #ifndef STACK_GROWS_DOWNWARD
1452 incoming_args
= expand_simple_binop (Pmode
, MINUS
, incoming_args
, argsize
,
1453 incoming_args
, 0, OPTAB_LIB_WIDEN
);
1456 /* Push a new argument block and copy the arguments. Do not allow
1457 the (potential) memcpy call below to interfere with our stack
1459 do_pending_stack_adjust ();
1462 /* Save the stack with nonlocal if available. */
1463 #ifdef HAVE_save_stack_nonlocal
1464 if (HAVE_save_stack_nonlocal
)
1465 emit_stack_save (SAVE_NONLOCAL
, &old_stack_level
, NULL_RTX
);
1468 emit_stack_save (SAVE_BLOCK
, &old_stack_level
, NULL_RTX
);
1470 /* Allocate a block of memory onto the stack and copy the memory
1471 arguments to the outgoing arguments address. */
1472 allocate_dynamic_stack_space (argsize
, 0, BITS_PER_UNIT
);
1473 dest
= virtual_outgoing_args_rtx
;
1474 #ifndef STACK_GROWS_DOWNWARD
1475 if (GET_CODE (argsize
) == CONST_INT
)
1476 dest
= plus_constant (dest
, -INTVAL (argsize
));
1478 dest
= gen_rtx_PLUS (Pmode
, dest
, negate_rtx (Pmode
, argsize
));
1480 dest
= gen_rtx_MEM (BLKmode
, dest
);
1481 set_mem_align (dest
, PARM_BOUNDARY
);
1482 src
= gen_rtx_MEM (BLKmode
, incoming_args
);
1483 set_mem_align (src
, PARM_BOUNDARY
);
1484 emit_block_move (dest
, src
, argsize
, BLOCK_OP_NORMAL
);
1486 /* Refer to the argument block. */
1488 arguments
= gen_rtx_MEM (BLKmode
, arguments
);
1489 set_mem_align (arguments
, PARM_BOUNDARY
);
1491 /* Walk past the arg-pointer and structure value address. */
1492 size
= GET_MODE_SIZE (Pmode
);
1494 size
+= GET_MODE_SIZE (Pmode
);
1496 /* Restore each of the registers previously saved. Make USE insns
1497 for each of these registers for use in making the call. */
1498 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
1499 if ((mode
= apply_args_mode
[regno
]) != VOIDmode
)
1501 align
= GET_MODE_ALIGNMENT (mode
) / BITS_PER_UNIT
;
1502 if (size
% align
!= 0)
1503 size
= CEIL (size
, align
) * align
;
1504 reg
= gen_rtx_REG (mode
, regno
);
1505 emit_move_insn (reg
, adjust_address (arguments
, mode
, size
));
1506 use_reg (&call_fusage
, reg
);
1507 size
+= GET_MODE_SIZE (mode
);
1510 /* Restore the structure value address unless this is passed as an
1511 "invisible" first argument. */
1512 size
= GET_MODE_SIZE (Pmode
);
1515 rtx value
= gen_reg_rtx (Pmode
);
1516 emit_move_insn (value
, adjust_address (arguments
, Pmode
, size
));
1517 emit_move_insn (struct_value
, value
);
1518 if (REG_P (struct_value
))
1519 use_reg (&call_fusage
, struct_value
);
1520 size
+= GET_MODE_SIZE (Pmode
);
1523 /* All arguments and registers used for the call are set up by now! */
1524 function
= prepare_call_address (function
, NULL
, &call_fusage
, 0, 0);
1526 /* Ensure address is valid. SYMBOL_REF is already valid, so no need,
1527 and we don't want to load it into a register as an optimization,
1528 because prepare_call_address already did it if it should be done. */
1529 if (GET_CODE (function
) != SYMBOL_REF
)
1530 function
= memory_address (FUNCTION_MODE
, function
);
1532 /* Generate the actual call instruction and save the return value. */
1533 #ifdef HAVE_untyped_call
1534 if (HAVE_untyped_call
)
1535 emit_call_insn (gen_untyped_call (gen_rtx_MEM (FUNCTION_MODE
, function
),
1536 result
, result_vector (1, result
)));
1539 #ifdef HAVE_call_value
1540 if (HAVE_call_value
)
1544 /* Locate the unique return register. It is not possible to
1545 express a call that sets more than one return register using
1546 call_value; use untyped_call for that. In fact, untyped_call
1547 only needs to save the return registers in the given block. */
1548 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
1549 if ((mode
= apply_result_mode
[regno
]) != VOIDmode
)
1551 gcc_assert (!valreg
); /* HAVE_untyped_call required. */
1553 valreg
= gen_rtx_REG (mode
, regno
);
1556 emit_call_insn (GEN_CALL_VALUE (valreg
,
1557 gen_rtx_MEM (FUNCTION_MODE
, function
),
1558 const0_rtx
, NULL_RTX
, const0_rtx
));
1560 emit_move_insn (adjust_address (result
, GET_MODE (valreg
), 0), valreg
);
1566 /* Find the CALL insn we just emitted, and attach the register usage
1568 call_insn
= last_call_insn ();
1569 add_function_usage_to (call_insn
, call_fusage
);
1571 /* Restore the stack. */
1572 #ifdef HAVE_save_stack_nonlocal
1573 if (HAVE_save_stack_nonlocal
)
1574 emit_stack_restore (SAVE_NONLOCAL
, old_stack_level
, NULL_RTX
);
1577 emit_stack_restore (SAVE_BLOCK
, old_stack_level
, NULL_RTX
);
1581 /* Return the address of the result block. */
1582 result
= copy_addr_to_reg (XEXP (result
, 0));
1583 return convert_memory_address (ptr_mode
, result
);
1586 /* Perform an untyped return. */
1589 expand_builtin_return (rtx result
)
1591 int size
, align
, regno
;
1592 enum machine_mode mode
;
1594 rtx call_fusage
= 0;
1596 result
= convert_memory_address (Pmode
, result
);
1598 apply_result_size ();
1599 result
= gen_rtx_MEM (BLKmode
, result
);
1601 #ifdef HAVE_untyped_return
1602 if (HAVE_untyped_return
)
1604 emit_jump_insn (gen_untyped_return (result
, result_vector (0, result
)));
1610 /* Restore the return value and note that each value is used. */
1612 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
1613 if ((mode
= apply_result_mode
[regno
]) != VOIDmode
)
1615 align
= GET_MODE_ALIGNMENT (mode
) / BITS_PER_UNIT
;
1616 if (size
% align
!= 0)
1617 size
= CEIL (size
, align
) * align
;
1618 reg
= gen_rtx_REG (mode
, INCOMING_REGNO (regno
));
1619 emit_move_insn (reg
, adjust_address (result
, mode
, size
));
1621 push_to_sequence (call_fusage
);
1622 emit_insn (gen_rtx_USE (VOIDmode
, reg
));
1623 call_fusage
= get_insns ();
1625 size
+= GET_MODE_SIZE (mode
);
1628 /* Put the USE insns before the return. */
1629 emit_insn (call_fusage
);
1631 /* Return whatever values was restored by jumping directly to the end
1633 expand_naked_return ();
1636 /* Used by expand_builtin_classify_type and fold_builtin_classify_type. */
1638 static enum type_class
1639 type_to_class (tree type
)
1641 switch (TREE_CODE (type
))
1643 case VOID_TYPE
: return void_type_class
;
1644 case INTEGER_TYPE
: return integer_type_class
;
1645 case ENUMERAL_TYPE
: return enumeral_type_class
;
1646 case BOOLEAN_TYPE
: return boolean_type_class
;
1647 case POINTER_TYPE
: return pointer_type_class
;
1648 case REFERENCE_TYPE
: return reference_type_class
;
1649 case OFFSET_TYPE
: return offset_type_class
;
1650 case REAL_TYPE
: return real_type_class
;
1651 case COMPLEX_TYPE
: return complex_type_class
;
1652 case FUNCTION_TYPE
: return function_type_class
;
1653 case METHOD_TYPE
: return method_type_class
;
1654 case RECORD_TYPE
: return record_type_class
;
1656 case QUAL_UNION_TYPE
: return union_type_class
;
1657 case ARRAY_TYPE
: return (TYPE_STRING_FLAG (type
)
1658 ? string_type_class
: array_type_class
);
1659 case LANG_TYPE
: return lang_type_class
;
1660 default: return no_type_class
;
1664 /* Expand a call to __builtin_classify_type with arguments found in
1668 expand_builtin_classify_type (tree arglist
)
1671 return GEN_INT (type_to_class (TREE_TYPE (TREE_VALUE (arglist
))));
1672 return GEN_INT (no_type_class
);
1675 /* This helper macro, meant to be used in mathfn_built_in below,
1676 determines which among a set of three builtin math functions is
1677 appropriate for a given type mode. The `F' and `L' cases are
1678 automatically generated from the `double' case. */
1679 #define CASE_MATHFN(BUILT_IN_MATHFN) \
1680 case BUILT_IN_MATHFN: case BUILT_IN_MATHFN##F: case BUILT_IN_MATHFN##L: \
1681 fcode = BUILT_IN_MATHFN; fcodef = BUILT_IN_MATHFN##F ; \
1682 fcodel = BUILT_IN_MATHFN##L ; break;
1684 /* Return mathematic function equivalent to FN but operating directly
1685 on TYPE, if available. If we can't do the conversion, return zero. */
1687 mathfn_built_in (tree type
, enum built_in_function fn
)
1689 enum built_in_function fcode
, fcodef
, fcodel
;
1693 CASE_MATHFN (BUILT_IN_ACOS
)
1694 CASE_MATHFN (BUILT_IN_ACOSH
)
1695 CASE_MATHFN (BUILT_IN_ASIN
)
1696 CASE_MATHFN (BUILT_IN_ASINH
)
1697 CASE_MATHFN (BUILT_IN_ATAN
)
1698 CASE_MATHFN (BUILT_IN_ATAN2
)
1699 CASE_MATHFN (BUILT_IN_ATANH
)
1700 CASE_MATHFN (BUILT_IN_CBRT
)
1701 CASE_MATHFN (BUILT_IN_CEIL
)
1702 CASE_MATHFN (BUILT_IN_COPYSIGN
)
1703 CASE_MATHFN (BUILT_IN_COS
)
1704 CASE_MATHFN (BUILT_IN_COSH
)
1705 CASE_MATHFN (BUILT_IN_DREM
)
1706 CASE_MATHFN (BUILT_IN_ERF
)
1707 CASE_MATHFN (BUILT_IN_ERFC
)
1708 CASE_MATHFN (BUILT_IN_EXP
)
1709 CASE_MATHFN (BUILT_IN_EXP10
)
1710 CASE_MATHFN (BUILT_IN_EXP2
)
1711 CASE_MATHFN (BUILT_IN_EXPM1
)
1712 CASE_MATHFN (BUILT_IN_FABS
)
1713 CASE_MATHFN (BUILT_IN_FDIM
)
1714 CASE_MATHFN (BUILT_IN_FLOOR
)
1715 CASE_MATHFN (BUILT_IN_FMA
)
1716 CASE_MATHFN (BUILT_IN_FMAX
)
1717 CASE_MATHFN (BUILT_IN_FMIN
)
1718 CASE_MATHFN (BUILT_IN_FMOD
)
1719 CASE_MATHFN (BUILT_IN_FREXP
)
1720 CASE_MATHFN (BUILT_IN_GAMMA
)
1721 CASE_MATHFN (BUILT_IN_HUGE_VAL
)
1722 CASE_MATHFN (BUILT_IN_HYPOT
)
1723 CASE_MATHFN (BUILT_IN_ILOGB
)
1724 CASE_MATHFN (BUILT_IN_INF
)
1725 CASE_MATHFN (BUILT_IN_J0
)
1726 CASE_MATHFN (BUILT_IN_J1
)
1727 CASE_MATHFN (BUILT_IN_JN
)
1728 CASE_MATHFN (BUILT_IN_LCEIL
)
1729 CASE_MATHFN (BUILT_IN_LDEXP
)
1730 CASE_MATHFN (BUILT_IN_LFLOOR
)
1731 CASE_MATHFN (BUILT_IN_LGAMMA
)
1732 CASE_MATHFN (BUILT_IN_LLCEIL
)
1733 CASE_MATHFN (BUILT_IN_LLFLOOR
)
1734 CASE_MATHFN (BUILT_IN_LLRINT
)
1735 CASE_MATHFN (BUILT_IN_LLROUND
)
1736 CASE_MATHFN (BUILT_IN_LOG
)
1737 CASE_MATHFN (BUILT_IN_LOG10
)
1738 CASE_MATHFN (BUILT_IN_LOG1P
)
1739 CASE_MATHFN (BUILT_IN_LOG2
)
1740 CASE_MATHFN (BUILT_IN_LOGB
)
1741 CASE_MATHFN (BUILT_IN_LRINT
)
1742 CASE_MATHFN (BUILT_IN_LROUND
)
1743 CASE_MATHFN (BUILT_IN_MODF
)
1744 CASE_MATHFN (BUILT_IN_NAN
)
1745 CASE_MATHFN (BUILT_IN_NANS
)
1746 CASE_MATHFN (BUILT_IN_NEARBYINT
)
1747 CASE_MATHFN (BUILT_IN_NEXTAFTER
)
1748 CASE_MATHFN (BUILT_IN_NEXTTOWARD
)
1749 CASE_MATHFN (BUILT_IN_POW
)
1750 CASE_MATHFN (BUILT_IN_POWI
)
1751 CASE_MATHFN (BUILT_IN_POW10
)
1752 CASE_MATHFN (BUILT_IN_REMAINDER
)
1753 CASE_MATHFN (BUILT_IN_REMQUO
)
1754 CASE_MATHFN (BUILT_IN_RINT
)
1755 CASE_MATHFN (BUILT_IN_ROUND
)
1756 CASE_MATHFN (BUILT_IN_SCALB
)
1757 CASE_MATHFN (BUILT_IN_SCALBLN
)
1758 CASE_MATHFN (BUILT_IN_SCALBN
)
1759 CASE_MATHFN (BUILT_IN_SIGNIFICAND
)
1760 CASE_MATHFN (BUILT_IN_SIN
)
1761 CASE_MATHFN (BUILT_IN_SINCOS
)
1762 CASE_MATHFN (BUILT_IN_SINH
)
1763 CASE_MATHFN (BUILT_IN_SQRT
)
1764 CASE_MATHFN (BUILT_IN_TAN
)
1765 CASE_MATHFN (BUILT_IN_TANH
)
1766 CASE_MATHFN (BUILT_IN_TGAMMA
)
1767 CASE_MATHFN (BUILT_IN_TRUNC
)
1768 CASE_MATHFN (BUILT_IN_Y0
)
1769 CASE_MATHFN (BUILT_IN_Y1
)
1770 CASE_MATHFN (BUILT_IN_YN
)
1776 if (TYPE_MAIN_VARIANT (type
) == double_type_node
)
1777 return implicit_built_in_decls
[fcode
];
1778 else if (TYPE_MAIN_VARIANT (type
) == float_type_node
)
1779 return implicit_built_in_decls
[fcodef
];
1780 else if (TYPE_MAIN_VARIANT (type
) == long_double_type_node
)
1781 return implicit_built_in_decls
[fcodel
];
1786 /* If errno must be maintained, expand the RTL to check if the result,
1787 TARGET, of a built-in function call, EXP, is NaN, and if so set
1791 expand_errno_check (tree exp
, rtx target
)
1793 rtx lab
= gen_label_rtx ();
1795 /* Test the result; if it is NaN, set errno=EDOM because
1796 the argument was not in the domain. */
1797 emit_cmp_and_jump_insns (target
, target
, EQ
, 0, GET_MODE (target
),
1801 /* If this built-in doesn't throw an exception, set errno directly. */
1802 if (TREE_NOTHROW (TREE_OPERAND (TREE_OPERAND (exp
, 0), 0)))
1804 #ifdef GEN_ERRNO_RTX
1805 rtx errno_rtx
= GEN_ERRNO_RTX
;
1808 = gen_rtx_MEM (word_mode
, gen_rtx_SYMBOL_REF (Pmode
, "errno"));
1810 emit_move_insn (errno_rtx
, GEN_INT (TARGET_EDOM
));
1816 /* We can't set errno=EDOM directly; let the library call do it.
1817 Pop the arguments right away in case the call gets deleted. */
1819 expand_call (exp
, target
, 0);
1825 /* Expand a call to one of the builtin math functions (sqrt, exp, or log).
1826 Return 0 if a normal call should be emitted rather than expanding the
1827 function in-line. EXP is the expression that is a call to the builtin
1828 function; if convenient, the result should be placed in TARGET.
1829 SUBTARGET may be used as the target for computing one of EXP's operands. */
1832 expand_builtin_mathfn (tree exp
, rtx target
, rtx subtarget
)
1834 optab builtin_optab
;
1835 rtx op0
, insns
, before_call
;
1836 tree fndecl
= get_callee_fndecl (exp
);
1837 tree arglist
= TREE_OPERAND (exp
, 1);
1838 enum machine_mode mode
;
1839 bool errno_set
= false;
1842 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
1845 arg
= TREE_VALUE (arglist
);
1847 switch (DECL_FUNCTION_CODE (fndecl
))
1849 CASE_FLT_FN (BUILT_IN_SQRT
):
1850 errno_set
= ! tree_expr_nonnegative_p (arg
);
1851 builtin_optab
= sqrt_optab
;
1853 CASE_FLT_FN (BUILT_IN_EXP
):
1854 errno_set
= true; builtin_optab
= exp_optab
; break;
1855 CASE_FLT_FN (BUILT_IN_EXP10
):
1856 CASE_FLT_FN (BUILT_IN_POW10
):
1857 errno_set
= true; builtin_optab
= exp10_optab
; break;
1858 CASE_FLT_FN (BUILT_IN_EXP2
):
1859 errno_set
= true; builtin_optab
= exp2_optab
; break;
1860 CASE_FLT_FN (BUILT_IN_EXPM1
):
1861 errno_set
= true; builtin_optab
= expm1_optab
; break;
1862 CASE_FLT_FN (BUILT_IN_LOGB
):
1863 errno_set
= true; builtin_optab
= logb_optab
; break;
1864 CASE_FLT_FN (BUILT_IN_ILOGB
):
1865 errno_set
= true; builtin_optab
= ilogb_optab
; break;
1866 CASE_FLT_FN (BUILT_IN_LOG
):
1867 errno_set
= true; builtin_optab
= log_optab
; break;
1868 CASE_FLT_FN (BUILT_IN_LOG10
):
1869 errno_set
= true; builtin_optab
= log10_optab
; break;
1870 CASE_FLT_FN (BUILT_IN_LOG2
):
1871 errno_set
= true; builtin_optab
= log2_optab
; break;
1872 CASE_FLT_FN (BUILT_IN_LOG1P
):
1873 errno_set
= true; builtin_optab
= log1p_optab
; break;
1874 CASE_FLT_FN (BUILT_IN_ASIN
):
1875 builtin_optab
= asin_optab
; break;
1876 CASE_FLT_FN (BUILT_IN_ACOS
):
1877 builtin_optab
= acos_optab
; break;
1878 CASE_FLT_FN (BUILT_IN_TAN
):
1879 builtin_optab
= tan_optab
; break;
1880 CASE_FLT_FN (BUILT_IN_ATAN
):
1881 builtin_optab
= atan_optab
; break;
1882 CASE_FLT_FN (BUILT_IN_FLOOR
):
1883 builtin_optab
= floor_optab
; break;
1884 CASE_FLT_FN (BUILT_IN_CEIL
):
1885 builtin_optab
= ceil_optab
; break;
1886 CASE_FLT_FN (BUILT_IN_TRUNC
):
1887 builtin_optab
= btrunc_optab
; break;
1888 CASE_FLT_FN (BUILT_IN_ROUND
):
1889 builtin_optab
= round_optab
; break;
1890 CASE_FLT_FN (BUILT_IN_NEARBYINT
):
1891 builtin_optab
= nearbyint_optab
; break;
1892 CASE_FLT_FN (BUILT_IN_RINT
):
1893 builtin_optab
= rint_optab
; break;
1894 CASE_FLT_FN (BUILT_IN_LRINT
):
1895 CASE_FLT_FN (BUILT_IN_LLRINT
):
1896 builtin_optab
= lrint_optab
; break;
1901 /* Make a suitable register to place result in. */
1902 mode
= TYPE_MODE (TREE_TYPE (exp
));
1904 if (! flag_errno_math
|| ! HONOR_NANS (mode
))
1907 /* Before working hard, check whether the instruction is available. */
1908 if (builtin_optab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
)
1910 target
= gen_reg_rtx (mode
);
1912 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
1913 need to expand the argument again. This way, we will not perform
1914 side-effects more the once. */
1915 narg
= builtin_save_expr (arg
);
1919 arglist
= build_tree_list (NULL_TREE
, arg
);
1920 exp
= build_function_call_expr (fndecl
, arglist
);
1923 op0
= expand_expr (arg
, subtarget
, VOIDmode
, 0);
1927 /* Compute into TARGET.
1928 Set TARGET to wherever the result comes back. */
1929 target
= expand_unop (mode
, builtin_optab
, op0
, target
, 0);
1934 expand_errno_check (exp
, target
);
1936 /* Output the entire sequence. */
1937 insns
= get_insns ();
1943 /* If we were unable to expand via the builtin, stop the sequence
1944 (without outputting the insns) and call to the library function
1945 with the stabilized argument list. */
1949 before_call
= get_last_insn ();
1951 target
= expand_call (exp
, target
, target
== const0_rtx
);
1953 /* If this is a sqrt operation and we don't care about errno, try to
1954 attach a REG_EQUAL note with a SQRT rtx to the emitted libcall.
1955 This allows the semantics of the libcall to be visible to the RTL
1957 if (builtin_optab
== sqrt_optab
&& !errno_set
)
1959 /* Search backwards through the insns emitted by expand_call looking
1960 for the instruction with the REG_RETVAL note. */
1961 rtx last
= get_last_insn ();
1962 while (last
!= before_call
)
1964 if (find_reg_note (last
, REG_RETVAL
, NULL
))
1966 rtx note
= find_reg_note (last
, REG_EQUAL
, NULL
);
1967 /* Check that the REQ_EQUAL note is an EXPR_LIST with
1968 two elements, i.e. symbol_ref(sqrt) and the operand. */
1970 && GET_CODE (note
) == EXPR_LIST
1971 && GET_CODE (XEXP (note
, 0)) == EXPR_LIST
1972 && XEXP (XEXP (note
, 0), 1) != NULL_RTX
1973 && XEXP (XEXP (XEXP (note
, 0), 1), 1) == NULL_RTX
)
1975 rtx operand
= XEXP (XEXP (XEXP (note
, 0), 1), 0);
1976 /* Check operand is a register with expected mode. */
1979 && GET_MODE (operand
) == mode
)
1981 /* Replace the REG_EQUAL note with a SQRT rtx. */
1982 rtx equiv
= gen_rtx_SQRT (mode
, operand
);
1983 set_unique_reg_note (last
, REG_EQUAL
, equiv
);
1988 last
= PREV_INSN (last
);
1995 /* Expand a call to the builtin binary math functions (pow and atan2).
1996 Return 0 if a normal call should be emitted rather than expanding the
1997 function in-line. EXP is the expression that is a call to the builtin
1998 function; if convenient, the result should be placed in TARGET.
1999 SUBTARGET may be used as the target for computing one of EXP's
2003 expand_builtin_mathfn_2 (tree exp
, rtx target
, rtx subtarget
)
2005 optab builtin_optab
;
2006 rtx op0
, op1
, insns
;
2007 int op1_type
= REAL_TYPE
;
2008 tree fndecl
= get_callee_fndecl (exp
);
2009 tree arglist
= TREE_OPERAND (exp
, 1);
2010 tree arg0
, arg1
, temp
, narg
;
2011 enum machine_mode mode
;
2012 bool errno_set
= true;
2015 if ((DECL_FUNCTION_CODE (fndecl
) == BUILT_IN_LDEXP
)
2016 || (DECL_FUNCTION_CODE (fndecl
) == BUILT_IN_LDEXPF
)
2017 || (DECL_FUNCTION_CODE (fndecl
) == BUILT_IN_LDEXPL
))
2018 op1_type
= INTEGER_TYPE
;
2020 if (!validate_arglist (arglist
, REAL_TYPE
, op1_type
, VOID_TYPE
))
2023 arg0
= TREE_VALUE (arglist
);
2024 arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
2026 switch (DECL_FUNCTION_CODE (fndecl
))
2028 CASE_FLT_FN (BUILT_IN_POW
):
2029 builtin_optab
= pow_optab
; break;
2030 CASE_FLT_FN (BUILT_IN_ATAN2
):
2031 builtin_optab
= atan2_optab
; break;
2032 CASE_FLT_FN (BUILT_IN_LDEXP
):
2033 builtin_optab
= ldexp_optab
; break;
2034 CASE_FLT_FN (BUILT_IN_FMOD
):
2035 builtin_optab
= fmod_optab
; break;
2036 CASE_FLT_FN (BUILT_IN_DREM
):
2037 builtin_optab
= drem_optab
; break;
2042 /* Make a suitable register to place result in. */
2043 mode
= TYPE_MODE (TREE_TYPE (exp
));
2045 /* Before working hard, check whether the instruction is available. */
2046 if (builtin_optab
->handlers
[(int) mode
].insn_code
== CODE_FOR_nothing
)
2049 target
= gen_reg_rtx (mode
);
2051 if (! flag_errno_math
|| ! HONOR_NANS (mode
))
2054 /* Always stabilize the argument list. */
2055 narg
= builtin_save_expr (arg1
);
2059 temp
= build_tree_list (NULL_TREE
, narg
);
2063 temp
= TREE_CHAIN (arglist
);
2065 narg
= builtin_save_expr (arg0
);
2069 arglist
= tree_cons (NULL_TREE
, narg
, temp
);
2073 arglist
= tree_cons (NULL_TREE
, arg0
, temp
);
2076 exp
= build_function_call_expr (fndecl
, arglist
);
2078 op0
= expand_expr (arg0
, subtarget
, VOIDmode
, EXPAND_NORMAL
);
2079 op1
= expand_normal (arg1
);
2083 /* Compute into TARGET.
2084 Set TARGET to wherever the result comes back. */
2085 target
= expand_binop (mode
, builtin_optab
, op0
, op1
,
2086 target
, 0, OPTAB_DIRECT
);
2088 /* If we were unable to expand via the builtin, stop the sequence
2089 (without outputting the insns) and call to the library function
2090 with the stabilized argument list. */
2094 return expand_call (exp
, target
, target
== const0_rtx
);
2098 expand_errno_check (exp
, target
);
2100 /* Output the entire sequence. */
2101 insns
= get_insns ();
2108 /* Expand a call to the builtin sin and cos math functions.
2109 Return 0 if a normal call should be emitted rather than expanding the
2110 function in-line. EXP is the expression that is a call to the builtin
2111 function; if convenient, the result should be placed in TARGET.
2112 SUBTARGET may be used as the target for computing one of EXP's
2116 expand_builtin_mathfn_3 (tree exp
, rtx target
, rtx subtarget
)
2118 optab builtin_optab
;
2120 tree fndecl
= get_callee_fndecl (exp
);
2121 tree arglist
= TREE_OPERAND (exp
, 1);
2122 enum machine_mode mode
;
2125 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
2128 arg
= TREE_VALUE (arglist
);
2130 switch (DECL_FUNCTION_CODE (fndecl
))
2132 CASE_FLT_FN (BUILT_IN_SIN
):
2133 CASE_FLT_FN (BUILT_IN_COS
):
2134 builtin_optab
= sincos_optab
; break;
2139 /* Make a suitable register to place result in. */
2140 mode
= TYPE_MODE (TREE_TYPE (exp
));
2142 /* Check if sincos insn is available, otherwise fallback
2143 to sin or cos insn. */
2144 if (builtin_optab
->handlers
[(int) mode
].insn_code
== CODE_FOR_nothing
) {
2145 switch (DECL_FUNCTION_CODE (fndecl
))
2147 CASE_FLT_FN (BUILT_IN_SIN
):
2148 builtin_optab
= sin_optab
; break;
2149 CASE_FLT_FN (BUILT_IN_COS
):
2150 builtin_optab
= cos_optab
; break;
2156 /* Before working hard, check whether the instruction is available. */
2157 if (builtin_optab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
)
2159 target
= gen_reg_rtx (mode
);
2161 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2162 need to expand the argument again. This way, we will not perform
2163 side-effects more the once. */
2164 narg
= save_expr (arg
);
2168 arglist
= build_tree_list (NULL_TREE
, arg
);
2169 exp
= build_function_call_expr (fndecl
, arglist
);
2172 op0
= expand_expr (arg
, subtarget
, VOIDmode
, 0);
2176 /* Compute into TARGET.
2177 Set TARGET to wherever the result comes back. */
2178 if (builtin_optab
== sincos_optab
)
2182 switch (DECL_FUNCTION_CODE (fndecl
))
2184 CASE_FLT_FN (BUILT_IN_SIN
):
2185 result
= expand_twoval_unop (builtin_optab
, op0
, 0, target
, 0);
2187 CASE_FLT_FN (BUILT_IN_COS
):
2188 result
= expand_twoval_unop (builtin_optab
, op0
, target
, 0, 0);
2193 gcc_assert (result
);
2197 target
= expand_unop (mode
, builtin_optab
, op0
, target
, 0);
2202 /* Output the entire sequence. */
2203 insns
= get_insns ();
2209 /* If we were unable to expand via the builtin, stop the sequence
2210 (without outputting the insns) and call to the library function
2211 with the stabilized argument list. */
2215 target
= expand_call (exp
, target
, target
== const0_rtx
);
2220 /* Expand a call to the builtin sincos math function.
2221 Return 0 if a normal call should be emitted rather than expanding the
2222 function in-line. EXP is the expression that is a call to the builtin
2226 expand_builtin_sincos (tree exp
)
2228 rtx op0
, op1
, op2
, target1
, target2
;
2229 tree arglist
= TREE_OPERAND (exp
, 1);
2230 enum machine_mode mode
;
2231 tree arg
, sinp
, cosp
;
2234 if (!validate_arglist (arglist
, REAL_TYPE
,
2235 POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
2238 arg
= TREE_VALUE (arglist
);
2239 sinp
= TREE_VALUE (TREE_CHAIN (arglist
));
2240 cosp
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
2242 /* Make a suitable register to place result in. */
2243 mode
= TYPE_MODE (TREE_TYPE (arg
));
2245 /* Check if sincos insn is available, otherwise emit the call. */
2246 if (sincos_optab
->handlers
[(int) mode
].insn_code
== CODE_FOR_nothing
)
2249 target1
= gen_reg_rtx (mode
);
2250 target2
= gen_reg_rtx (mode
);
2252 op0
= expand_normal (arg
);
2253 op1
= expand_normal (build_fold_indirect_ref (sinp
));
2254 op2
= expand_normal (build_fold_indirect_ref (cosp
));
2256 /* Compute into target1 and target2.
2257 Set TARGET to wherever the result comes back. */
2258 result
= expand_twoval_unop (sincos_optab
, op0
, target2
, target1
, 0);
2259 gcc_assert (result
);
2261 /* Move target1 and target2 to the memory locations indicated
2263 emit_move_insn (op1
, target1
);
2264 emit_move_insn (op2
, target2
);
2269 /* Expand a call to one of the builtin rounding functions (lfloor).
2270 If expanding via optab fails, lower expression to (int)(floor(x)).
2271 EXP is the expression that is a call to the builtin function;
2272 if convenient, the result should be placed in TARGET. SUBTARGET may
2273 be used as the target for computing one of EXP's operands. */
2276 expand_builtin_int_roundingfn (tree exp
, rtx target
, rtx subtarget
)
2278 optab builtin_optab
;
2279 rtx op0
, insns
, tmp
;
2280 tree fndecl
= get_callee_fndecl (exp
);
2281 tree arglist
= TREE_OPERAND (exp
, 1);
2282 enum built_in_function fallback_fn
;
2283 tree fallback_fndecl
;
2284 enum machine_mode mode
;
2287 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
2290 arg
= TREE_VALUE (arglist
);
2292 switch (DECL_FUNCTION_CODE (fndecl
))
2294 CASE_FLT_FN (BUILT_IN_LCEIL
):
2295 CASE_FLT_FN (BUILT_IN_LLCEIL
):
2296 builtin_optab
= lceil_optab
;
2297 fallback_fn
= BUILT_IN_CEIL
;
2300 CASE_FLT_FN (BUILT_IN_LFLOOR
):
2301 CASE_FLT_FN (BUILT_IN_LLFLOOR
):
2302 builtin_optab
= lfloor_optab
;
2303 fallback_fn
= BUILT_IN_FLOOR
;
2310 /* Make a suitable register to place result in. */
2311 mode
= TYPE_MODE (TREE_TYPE (exp
));
2313 /* Before working hard, check whether the instruction is available. */
2314 if (builtin_optab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
)
2316 target
= gen_reg_rtx (mode
);
2318 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2319 need to expand the argument again. This way, we will not perform
2320 side-effects more the once. */
2321 narg
= builtin_save_expr (arg
);
2325 arglist
= build_tree_list (NULL_TREE
, arg
);
2326 exp
= build_function_call_expr (fndecl
, arglist
);
2329 op0
= expand_expr (arg
, subtarget
, VOIDmode
, 0);
2333 /* Compute into TARGET.
2334 Set TARGET to wherever the result comes back. */
2335 target
= expand_unop (mode
, builtin_optab
, op0
, target
, 0);
2339 /* Output the entire sequence. */
2340 insns
= get_insns ();
2346 /* If we were unable to expand via the builtin, stop the sequence
2347 (without outputting the insns). */
2351 /* Fall back to floating point rounding optab. */
2352 fallback_fndecl
= mathfn_built_in (TREE_TYPE (arg
), fallback_fn
);
2353 /* We shouldn't get here on targets without TARGET_C99_FUNCTIONS.
2354 ??? Perhaps convert (int)floorf(x) into (int)floor((double)x). */
2355 gcc_assert (fallback_fndecl
!= NULL_TREE
);
2356 exp
= build_function_call_expr (fallback_fndecl
, arglist
);
2358 tmp
= expand_normal (exp
);
2360 /* Truncate the result of floating point optab to integer
2361 via expand_fix (). */
2362 target
= gen_reg_rtx (mode
);
2363 expand_fix (target
, tmp
, 0);
2368 /* To evaluate powi(x,n), the floating point value x raised to the
2369 constant integer exponent n, we use a hybrid algorithm that
2370 combines the "window method" with look-up tables. For an
2371 introduction to exponentiation algorithms and "addition chains",
2372 see section 4.6.3, "Evaluation of Powers" of Donald E. Knuth,
2373 "Seminumerical Algorithms", Vol. 2, "The Art of Computer Programming",
2374 3rd Edition, 1998, and Daniel M. Gordon, "A Survey of Fast Exponentiation
2375 Methods", Journal of Algorithms, Vol. 27, pp. 129-146, 1998. */
2377 /* Provide a default value for POWI_MAX_MULTS, the maximum number of
2378 multiplications to inline before calling the system library's pow
2379 function. powi(x,n) requires at worst 2*bits(n)-2 multiplications,
2380 so this default never requires calling pow, powf or powl. */
2382 #ifndef POWI_MAX_MULTS
2383 #define POWI_MAX_MULTS (2*HOST_BITS_PER_WIDE_INT-2)
2386 /* The size of the "optimal power tree" lookup table. All
2387 exponents less than this value are simply looked up in the
2388 powi_table below. This threshold is also used to size the
2389 cache of pseudo registers that hold intermediate results. */
2390 #define POWI_TABLE_SIZE 256
2392 /* The size, in bits of the window, used in the "window method"
2393 exponentiation algorithm. This is equivalent to a radix of
2394 (1<<POWI_WINDOW_SIZE) in the corresponding "m-ary method". */
2395 #define POWI_WINDOW_SIZE 3
2397 /* The following table is an efficient representation of an
2398 "optimal power tree". For each value, i, the corresponding
2399 value, j, in the table states than an optimal evaluation
2400 sequence for calculating pow(x,i) can be found by evaluating
2401 pow(x,j)*pow(x,i-j). An optimal power tree for the first
2402 100 integers is given in Knuth's "Seminumerical algorithms". */
2404 static const unsigned char powi_table
[POWI_TABLE_SIZE
] =
2406 0, 1, 1, 2, 2, 3, 3, 4, /* 0 - 7 */
2407 4, 6, 5, 6, 6, 10, 7, 9, /* 8 - 15 */
2408 8, 16, 9, 16, 10, 12, 11, 13, /* 16 - 23 */
2409 12, 17, 13, 18, 14, 24, 15, 26, /* 24 - 31 */
2410 16, 17, 17, 19, 18, 33, 19, 26, /* 32 - 39 */
2411 20, 25, 21, 40, 22, 27, 23, 44, /* 40 - 47 */
2412 24, 32, 25, 34, 26, 29, 27, 44, /* 48 - 55 */
2413 28, 31, 29, 34, 30, 60, 31, 36, /* 56 - 63 */
2414 32, 64, 33, 34, 34, 46, 35, 37, /* 64 - 71 */
2415 36, 65, 37, 50, 38, 48, 39, 69, /* 72 - 79 */
2416 40, 49, 41, 43, 42, 51, 43, 58, /* 80 - 87 */
2417 44, 64, 45, 47, 46, 59, 47, 76, /* 88 - 95 */
2418 48, 65, 49, 66, 50, 67, 51, 66, /* 96 - 103 */
2419 52, 70, 53, 74, 54, 104, 55, 74, /* 104 - 111 */
2420 56, 64, 57, 69, 58, 78, 59, 68, /* 112 - 119 */
2421 60, 61, 61, 80, 62, 75, 63, 68, /* 120 - 127 */
2422 64, 65, 65, 128, 66, 129, 67, 90, /* 128 - 135 */
2423 68, 73, 69, 131, 70, 94, 71, 88, /* 136 - 143 */
2424 72, 128, 73, 98, 74, 132, 75, 121, /* 144 - 151 */
2425 76, 102, 77, 124, 78, 132, 79, 106, /* 152 - 159 */
2426 80, 97, 81, 160, 82, 99, 83, 134, /* 160 - 167 */
2427 84, 86, 85, 95, 86, 160, 87, 100, /* 168 - 175 */
2428 88, 113, 89, 98, 90, 107, 91, 122, /* 176 - 183 */
2429 92, 111, 93, 102, 94, 126, 95, 150, /* 184 - 191 */
2430 96, 128, 97, 130, 98, 133, 99, 195, /* 192 - 199 */
2431 100, 128, 101, 123, 102, 164, 103, 138, /* 200 - 207 */
2432 104, 145, 105, 146, 106, 109, 107, 149, /* 208 - 215 */
2433 108, 200, 109, 146, 110, 170, 111, 157, /* 216 - 223 */
2434 112, 128, 113, 130, 114, 182, 115, 132, /* 224 - 231 */
2435 116, 200, 117, 132, 118, 158, 119, 206, /* 232 - 239 */
2436 120, 240, 121, 162, 122, 147, 123, 152, /* 240 - 247 */
2437 124, 166, 125, 214, 126, 138, 127, 153, /* 248 - 255 */
2441 /* Return the number of multiplications required to calculate
2442 powi(x,n) where n is less than POWI_TABLE_SIZE. This is a
2443 subroutine of powi_cost. CACHE is an array indicating
2444 which exponents have already been calculated. */
2447 powi_lookup_cost (unsigned HOST_WIDE_INT n
, bool *cache
)
2449 /* If we've already calculated this exponent, then this evaluation
2450 doesn't require any additional multiplications. */
2455 return powi_lookup_cost (n
- powi_table
[n
], cache
)
2456 + powi_lookup_cost (powi_table
[n
], cache
) + 1;
2459 /* Return the number of multiplications required to calculate
2460 powi(x,n) for an arbitrary x, given the exponent N. This
2461 function needs to be kept in sync with expand_powi below. */
2464 powi_cost (HOST_WIDE_INT n
)
2466 bool cache
[POWI_TABLE_SIZE
];
2467 unsigned HOST_WIDE_INT digit
;
2468 unsigned HOST_WIDE_INT val
;
2474 /* Ignore the reciprocal when calculating the cost. */
2475 val
= (n
< 0) ? -n
: n
;
2477 /* Initialize the exponent cache. */
2478 memset (cache
, 0, POWI_TABLE_SIZE
* sizeof (bool));
2483 while (val
>= POWI_TABLE_SIZE
)
2487 digit
= val
& ((1 << POWI_WINDOW_SIZE
) - 1);
2488 result
+= powi_lookup_cost (digit
, cache
)
2489 + POWI_WINDOW_SIZE
+ 1;
2490 val
>>= POWI_WINDOW_SIZE
;
2499 return result
+ powi_lookup_cost (val
, cache
);
2502 /* Recursive subroutine of expand_powi. This function takes the array,
2503 CACHE, of already calculated exponents and an exponent N and returns
2504 an RTX that corresponds to CACHE[1]**N, as calculated in mode MODE. */
2507 expand_powi_1 (enum machine_mode mode
, unsigned HOST_WIDE_INT n
, rtx
*cache
)
2509 unsigned HOST_WIDE_INT digit
;
2513 if (n
< POWI_TABLE_SIZE
)
2518 target
= gen_reg_rtx (mode
);
2521 op0
= expand_powi_1 (mode
, n
- powi_table
[n
], cache
);
2522 op1
= expand_powi_1 (mode
, powi_table
[n
], cache
);
2526 target
= gen_reg_rtx (mode
);
2527 digit
= n
& ((1 << POWI_WINDOW_SIZE
) - 1);
2528 op0
= expand_powi_1 (mode
, n
- digit
, cache
);
2529 op1
= expand_powi_1 (mode
, digit
, cache
);
2533 target
= gen_reg_rtx (mode
);
2534 op0
= expand_powi_1 (mode
, n
>> 1, cache
);
2538 result
= expand_mult (mode
, op0
, op1
, target
, 0);
2539 if (result
!= target
)
2540 emit_move_insn (target
, result
);
2544 /* Expand the RTL to evaluate powi(x,n) in mode MODE. X is the
2545 floating point operand in mode MODE, and N is the exponent. This
2546 function needs to be kept in sync with powi_cost above. */
2549 expand_powi (rtx x
, enum machine_mode mode
, HOST_WIDE_INT n
)
2551 unsigned HOST_WIDE_INT val
;
2552 rtx cache
[POWI_TABLE_SIZE
];
2556 return CONST1_RTX (mode
);
2558 val
= (n
< 0) ? -n
: n
;
2560 memset (cache
, 0, sizeof (cache
));
2563 result
= expand_powi_1 (mode
, (n
< 0) ? -n
: n
, cache
);
2565 /* If the original exponent was negative, reciprocate the result. */
2567 result
= expand_binop (mode
, sdiv_optab
, CONST1_RTX (mode
),
2568 result
, NULL_RTX
, 0, OPTAB_LIB_WIDEN
);
2573 /* Expand a call to the pow built-in mathematical function. Return 0 if
2574 a normal call should be emitted rather than expanding the function
2575 in-line. EXP is the expression that is a call to the builtin
2576 function; if convenient, the result should be placed in TARGET. */
2579 expand_builtin_pow (tree exp
, rtx target
, rtx subtarget
)
2581 tree arglist
= TREE_OPERAND (exp
, 1);
2584 if (! validate_arglist (arglist
, REAL_TYPE
, REAL_TYPE
, VOID_TYPE
))
2587 arg0
= TREE_VALUE (arglist
);
2588 arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
2590 if (TREE_CODE (arg1
) == REAL_CST
2591 && ! TREE_CONSTANT_OVERFLOW (arg1
))
2593 REAL_VALUE_TYPE cint
;
2597 c
= TREE_REAL_CST (arg1
);
2598 n
= real_to_integer (&c
);
2599 real_from_integer (&cint
, VOIDmode
, n
, n
< 0 ? -1 : 0, 0);
2600 if (real_identical (&c
, &cint
))
2602 /* If the exponent is -1, 0, 1 or 2, then expand_powi is exact.
2603 Otherwise, check the number of multiplications required.
2604 Note that pow never sets errno for an integer exponent. */
2605 if ((n
>= -1 && n
<= 2)
2606 || (flag_unsafe_math_optimizations
2608 && powi_cost (n
) <= POWI_MAX_MULTS
))
2610 enum machine_mode mode
= TYPE_MODE (TREE_TYPE (exp
));
2611 rtx op
= expand_expr (arg0
, subtarget
, VOIDmode
, 0);
2612 op
= force_reg (mode
, op
);
2613 return expand_powi (op
, mode
, n
);
2618 if (! flag_unsafe_math_optimizations
)
2620 return expand_builtin_mathfn_2 (exp
, target
, subtarget
);
2623 /* Expand a call to the powi built-in mathematical function. Return 0 if
2624 a normal call should be emitted rather than expanding the function
2625 in-line. EXP is the expression that is a call to the builtin
2626 function; if convenient, the result should be placed in TARGET. */
2629 expand_builtin_powi (tree exp
, rtx target
, rtx subtarget
)
2631 tree arglist
= TREE_OPERAND (exp
, 1);
2634 enum machine_mode mode
;
2635 enum machine_mode mode2
;
2637 if (! validate_arglist (arglist
, REAL_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
2640 arg0
= TREE_VALUE (arglist
);
2641 arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
2642 mode
= TYPE_MODE (TREE_TYPE (exp
));
2644 /* Handle constant power. */
2646 if (TREE_CODE (arg1
) == INTEGER_CST
2647 && ! TREE_CONSTANT_OVERFLOW (arg1
))
2649 HOST_WIDE_INT n
= TREE_INT_CST_LOW (arg1
);
2651 /* If the exponent is -1, 0, 1 or 2, then expand_powi is exact.
2652 Otherwise, check the number of multiplications required. */
2653 if ((TREE_INT_CST_HIGH (arg1
) == 0
2654 || TREE_INT_CST_HIGH (arg1
) == -1)
2655 && ((n
>= -1 && n
<= 2)
2657 && powi_cost (n
) <= POWI_MAX_MULTS
)))
2659 op0
= expand_expr (arg0
, subtarget
, VOIDmode
, 0);
2660 op0
= force_reg (mode
, op0
);
2661 return expand_powi (op0
, mode
, n
);
2665 /* Emit a libcall to libgcc. */
2667 /* Mode of the 2nd argument must match that of an int. */
2668 mode2
= mode_for_size (INT_TYPE_SIZE
, MODE_INT
, 0);
2670 if (target
== NULL_RTX
)
2671 target
= gen_reg_rtx (mode
);
2673 op0
= expand_expr (arg0
, subtarget
, mode
, 0);
2674 if (GET_MODE (op0
) != mode
)
2675 op0
= convert_to_mode (mode
, op0
, 0);
2676 op1
= expand_expr (arg1
, 0, mode2
, 0);
2677 if (GET_MODE (op1
) != mode2
)
2678 op1
= convert_to_mode (mode2
, op1
, 0);
2680 target
= emit_library_call_value (powi_optab
->handlers
[(int) mode
].libfunc
,
2681 target
, LCT_CONST_MAKE_BLOCK
, mode
, 2,
2682 op0
, mode
, op1
, mode2
);
2687 /* Expand expression EXP which is a call to the strlen builtin. Return 0
2688 if we failed the caller should emit a normal call, otherwise
2689 try to get the result in TARGET, if convenient. */
2692 expand_builtin_strlen (tree arglist
, rtx target
,
2693 enum machine_mode target_mode
)
2695 if (!validate_arglist (arglist
, POINTER_TYPE
, VOID_TYPE
))
2700 tree len
, src
= TREE_VALUE (arglist
);
2701 rtx result
, src_reg
, char_rtx
, before_strlen
;
2702 enum machine_mode insn_mode
= target_mode
, char_mode
;
2703 enum insn_code icode
= CODE_FOR_nothing
;
2706 /* If the length can be computed at compile-time, return it. */
2707 len
= c_strlen (src
, 0);
2709 return expand_expr (len
, target
, target_mode
, EXPAND_NORMAL
);
2711 /* If the length can be computed at compile-time and is constant
2712 integer, but there are side-effects in src, evaluate
2713 src for side-effects, then return len.
2714 E.g. x = strlen (i++ ? "xfoo" + 1 : "bar");
2715 can be optimized into: i++; x = 3; */
2716 len
= c_strlen (src
, 1);
2717 if (len
&& TREE_CODE (len
) == INTEGER_CST
)
2719 expand_expr (src
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
2720 return expand_expr (len
, target
, target_mode
, EXPAND_NORMAL
);
2723 align
= get_pointer_alignment (src
, BIGGEST_ALIGNMENT
) / BITS_PER_UNIT
;
2725 /* If SRC is not a pointer type, don't do this operation inline. */
2729 /* Bail out if we can't compute strlen in the right mode. */
2730 while (insn_mode
!= VOIDmode
)
2732 icode
= strlen_optab
->handlers
[(int) insn_mode
].insn_code
;
2733 if (icode
!= CODE_FOR_nothing
)
2736 insn_mode
= GET_MODE_WIDER_MODE (insn_mode
);
2738 if (insn_mode
== VOIDmode
)
2741 /* Make a place to write the result of the instruction. */
2745 && GET_MODE (result
) == insn_mode
2746 && REGNO (result
) >= FIRST_PSEUDO_REGISTER
))
2747 result
= gen_reg_rtx (insn_mode
);
2749 /* Make a place to hold the source address. We will not expand
2750 the actual source until we are sure that the expansion will
2751 not fail -- there are trees that cannot be expanded twice. */
2752 src_reg
= gen_reg_rtx (Pmode
);
2754 /* Mark the beginning of the strlen sequence so we can emit the
2755 source operand later. */
2756 before_strlen
= get_last_insn ();
2758 char_rtx
= const0_rtx
;
2759 char_mode
= insn_data
[(int) icode
].operand
[2].mode
;
2760 if (! (*insn_data
[(int) icode
].operand
[2].predicate
) (char_rtx
,
2762 char_rtx
= copy_to_mode_reg (char_mode
, char_rtx
);
2764 pat
= GEN_FCN (icode
) (result
, gen_rtx_MEM (BLKmode
, src_reg
),
2765 char_rtx
, GEN_INT (align
));
2770 /* Now that we are assured of success, expand the source. */
2772 pat
= expand_expr (src
, src_reg
, ptr_mode
, EXPAND_NORMAL
);
2774 emit_move_insn (src_reg
, pat
);
2779 emit_insn_after (pat
, before_strlen
);
2781 emit_insn_before (pat
, get_insns ());
2783 /* Return the value in the proper mode for this function. */
2784 if (GET_MODE (result
) == target_mode
)
2786 else if (target
!= 0)
2787 convert_move (target
, result
, 0);
2789 target
= convert_to_mode (target_mode
, result
, 0);
2795 /* Expand a call to the strstr builtin. Return 0 if we failed the
2796 caller should emit a normal call, otherwise try to get the result
2797 in TARGET, if convenient (and in mode MODE if that's convenient). */
2800 expand_builtin_strstr (tree arglist
, tree type
, rtx target
, enum machine_mode mode
)
2802 if (validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
2804 tree result
= fold_builtin_strstr (arglist
, type
);
2806 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
2811 /* Expand a call to the strchr builtin. Return 0 if we failed the
2812 caller should emit a normal call, otherwise try to get the result
2813 in TARGET, if convenient (and in mode MODE if that's convenient). */
2816 expand_builtin_strchr (tree arglist
, tree type
, rtx target
, enum machine_mode mode
)
2818 if (validate_arglist (arglist
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
2820 tree result
= fold_builtin_strchr (arglist
, type
);
2822 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
2824 /* FIXME: Should use strchrM optab so that ports can optimize this. */
2829 /* Expand a call to the strrchr builtin. Return 0 if we failed the
2830 caller should emit a normal call, otherwise try to get the result
2831 in TARGET, if convenient (and in mode MODE if that's convenient). */
2834 expand_builtin_strrchr (tree arglist
, tree type
, rtx target
, enum machine_mode mode
)
2836 if (validate_arglist (arglist
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
2838 tree result
= fold_builtin_strrchr (arglist
, type
);
2840 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
2845 /* Expand a call to the strpbrk builtin. Return 0 if we failed the
2846 caller should emit a normal call, otherwise try to get the result
2847 in TARGET, if convenient (and in mode MODE if that's convenient). */
2850 expand_builtin_strpbrk (tree arglist
, tree type
, rtx target
, enum machine_mode mode
)
2852 if (validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
2854 tree result
= fold_builtin_strpbrk (arglist
, type
);
2856 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
2861 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
2862 bytes from constant string DATA + OFFSET and return it as target
2866 builtin_memcpy_read_str (void *data
, HOST_WIDE_INT offset
,
2867 enum machine_mode mode
)
2869 const char *str
= (const char *) data
;
2871 gcc_assert (offset
>= 0
2872 && ((unsigned HOST_WIDE_INT
) offset
+ GET_MODE_SIZE (mode
)
2873 <= strlen (str
) + 1));
2875 return c_readstr (str
+ offset
, mode
);
2878 /* Expand a call to the memcpy builtin, with arguments in ARGLIST.
2879 Return 0 if we failed, the caller should emit a normal call,
2880 otherwise try to get the result in TARGET, if convenient (and in
2881 mode MODE if that's convenient). */
2883 expand_builtin_memcpy (tree exp
, rtx target
, enum machine_mode mode
)
2885 tree fndecl
= get_callee_fndecl (exp
);
2886 tree arglist
= TREE_OPERAND (exp
, 1);
2887 if (!validate_arglist (arglist
,
2888 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
2892 tree dest
= TREE_VALUE (arglist
);
2893 tree src
= TREE_VALUE (TREE_CHAIN (arglist
));
2894 tree len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
2895 const char *src_str
;
2896 unsigned int src_align
= get_pointer_alignment (src
, BIGGEST_ALIGNMENT
);
2897 unsigned int dest_align
2898 = get_pointer_alignment (dest
, BIGGEST_ALIGNMENT
);
2899 rtx dest_mem
, src_mem
, dest_addr
, len_rtx
;
2900 tree result
= fold_builtin_memory_op (arglist
, TREE_TYPE (TREE_TYPE (fndecl
)),
2905 while (TREE_CODE (result
) == COMPOUND_EXPR
)
2907 expand_expr (TREE_OPERAND (result
, 0), const0_rtx
, VOIDmode
,
2909 result
= TREE_OPERAND (result
, 1);
2911 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
2914 /* If DEST is not a pointer type, call the normal function. */
2915 if (dest_align
== 0)
2918 /* If either SRC is not a pointer type, don't do this
2919 operation in-line. */
2923 dest_mem
= get_memory_rtx (dest
, len
);
2924 set_mem_align (dest_mem
, dest_align
);
2925 len_rtx
= expand_normal (len
);
2926 src_str
= c_getstr (src
);
2928 /* If SRC is a string constant and block move would be done
2929 by pieces, we can avoid loading the string from memory
2930 and only stored the computed constants. */
2932 && GET_CODE (len_rtx
) == CONST_INT
2933 && (unsigned HOST_WIDE_INT
) INTVAL (len_rtx
) <= strlen (src_str
) + 1
2934 && can_store_by_pieces (INTVAL (len_rtx
), builtin_memcpy_read_str
,
2935 (void *) src_str
, dest_align
))
2937 dest_mem
= store_by_pieces (dest_mem
, INTVAL (len_rtx
),
2938 builtin_memcpy_read_str
,
2939 (void *) src_str
, dest_align
, 0);
2940 dest_mem
= force_operand (XEXP (dest_mem
, 0), NULL_RTX
);
2941 dest_mem
= convert_memory_address (ptr_mode
, dest_mem
);
2945 src_mem
= get_memory_rtx (src
, len
);
2946 set_mem_align (src_mem
, src_align
);
2948 /* Copy word part most expediently. */
2949 dest_addr
= emit_block_move (dest_mem
, src_mem
, len_rtx
,
2950 CALL_EXPR_TAILCALL (exp
)
2951 ? BLOCK_OP_TAILCALL
: BLOCK_OP_NORMAL
);
2955 dest_addr
= force_operand (XEXP (dest_mem
, 0), NULL_RTX
);
2956 dest_addr
= convert_memory_address (ptr_mode
, dest_addr
);
2962 /* Expand a call to the mempcpy builtin, with arguments in ARGLIST.
2963 Return 0 if we failed; the caller should emit a normal call,
2964 otherwise try to get the result in TARGET, if convenient (and in
2965 mode MODE if that's convenient). If ENDP is 0 return the
2966 destination pointer, if ENDP is 1 return the end pointer ala
2967 mempcpy, and if ENDP is 2 return the end pointer minus one ala
2971 expand_builtin_mempcpy (tree arglist
, tree type
, rtx target
, enum machine_mode mode
,
2974 if (!validate_arglist (arglist
,
2975 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
2977 /* If return value is ignored, transform mempcpy into memcpy. */
2978 else if (target
== const0_rtx
)
2980 tree fn
= implicit_built_in_decls
[BUILT_IN_MEMCPY
];
2985 return expand_expr (build_function_call_expr (fn
, arglist
),
2986 target
, mode
, EXPAND_NORMAL
);
2990 tree dest
= TREE_VALUE (arglist
);
2991 tree src
= TREE_VALUE (TREE_CHAIN (arglist
));
2992 tree len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
2993 const char *src_str
;
2994 unsigned int src_align
= get_pointer_alignment (src
, BIGGEST_ALIGNMENT
);
2995 unsigned int dest_align
2996 = get_pointer_alignment (dest
, BIGGEST_ALIGNMENT
);
2997 rtx dest_mem
, src_mem
, len_rtx
;
2998 tree result
= fold_builtin_memory_op (arglist
, type
, false, endp
);
3002 while (TREE_CODE (result
) == COMPOUND_EXPR
)
3004 expand_expr (TREE_OPERAND (result
, 0), const0_rtx
, VOIDmode
,
3006 result
= TREE_OPERAND (result
, 1);
3008 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
3011 /* If either SRC or DEST is not a pointer type, don't do this
3012 operation in-line. */
3013 if (dest_align
== 0 || src_align
== 0)
3016 /* If LEN is not constant, call the normal function. */
3017 if (! host_integerp (len
, 1))
3020 len_rtx
= expand_normal (len
);
3021 src_str
= c_getstr (src
);
3023 /* If SRC is a string constant and block move would be done
3024 by pieces, we can avoid loading the string from memory
3025 and only stored the computed constants. */
3027 && GET_CODE (len_rtx
) == CONST_INT
3028 && (unsigned HOST_WIDE_INT
) INTVAL (len_rtx
) <= strlen (src_str
) + 1
3029 && can_store_by_pieces (INTVAL (len_rtx
), builtin_memcpy_read_str
,
3030 (void *) src_str
, dest_align
))
3032 dest_mem
= get_memory_rtx (dest
, len
);
3033 set_mem_align (dest_mem
, dest_align
);
3034 dest_mem
= store_by_pieces (dest_mem
, INTVAL (len_rtx
),
3035 builtin_memcpy_read_str
,
3036 (void *) src_str
, dest_align
, endp
);
3037 dest_mem
= force_operand (XEXP (dest_mem
, 0), NULL_RTX
);
3038 dest_mem
= convert_memory_address (ptr_mode
, dest_mem
);
3042 if (GET_CODE (len_rtx
) == CONST_INT
3043 && can_move_by_pieces (INTVAL (len_rtx
),
3044 MIN (dest_align
, src_align
)))
3046 dest_mem
= get_memory_rtx (dest
, len
);
3047 set_mem_align (dest_mem
, dest_align
);
3048 src_mem
= get_memory_rtx (src
, len
);
3049 set_mem_align (src_mem
, src_align
);
3050 dest_mem
= move_by_pieces (dest_mem
, src_mem
, INTVAL (len_rtx
),
3051 MIN (dest_align
, src_align
), endp
);
3052 dest_mem
= force_operand (XEXP (dest_mem
, 0), NULL_RTX
);
3053 dest_mem
= convert_memory_address (ptr_mode
, dest_mem
);
3061 /* Expand expression EXP, which is a call to the memmove builtin. Return 0
3062 if we failed; the caller should emit a normal call. */
3065 expand_builtin_memmove (tree arglist
, tree type
, rtx target
,
3066 enum machine_mode mode
, tree orig_exp
)
3068 if (!validate_arglist (arglist
,
3069 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
3073 tree dest
= TREE_VALUE (arglist
);
3074 tree src
= TREE_VALUE (TREE_CHAIN (arglist
));
3075 tree len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
3077 unsigned int src_align
= get_pointer_alignment (src
, BIGGEST_ALIGNMENT
);
3078 unsigned int dest_align
3079 = get_pointer_alignment (dest
, BIGGEST_ALIGNMENT
);
3080 tree result
= fold_builtin_memory_op (arglist
, type
, false, /*endp=*/3);
3084 while (TREE_CODE (result
) == COMPOUND_EXPR
)
3086 expand_expr (TREE_OPERAND (result
, 0), const0_rtx
, VOIDmode
,
3088 result
= TREE_OPERAND (result
, 1);
3090 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
3093 /* If DEST is not a pointer type, call the normal function. */
3094 if (dest_align
== 0)
3097 /* If either SRC is not a pointer type, don't do this
3098 operation in-line. */
3102 /* If src is categorized for a readonly section we can use
3104 if (readonly_data_expr (src
))
3106 tree fn
= implicit_built_in_decls
[BUILT_IN_MEMCPY
];
3109 fn
= build_function_call_expr (fn
, arglist
);
3110 if (TREE_CODE (fn
) == CALL_EXPR
)
3111 CALL_EXPR_TAILCALL (fn
) = CALL_EXPR_TAILCALL (orig_exp
);
3112 return expand_expr (fn
, target
, mode
, EXPAND_NORMAL
);
3115 /* If length is 1 and we can expand memcpy call inline,
3116 it is ok to use memcpy as well. */
3117 if (integer_onep (len
))
3119 rtx ret
= expand_builtin_mempcpy (arglist
, type
, target
, mode
,
3125 /* Otherwise, call the normal function. */
3130 /* Expand expression EXP, which is a call to the bcopy builtin. Return 0
3131 if we failed the caller should emit a normal call. */
3134 expand_builtin_bcopy (tree exp
)
3136 tree arglist
= TREE_OPERAND (exp
, 1);
3137 tree type
= TREE_TYPE (exp
);
3138 tree src
, dest
, size
, newarglist
;
3140 if (!validate_arglist (arglist
,
3141 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
3144 src
= TREE_VALUE (arglist
);
3145 dest
= TREE_VALUE (TREE_CHAIN (arglist
));
3146 size
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
3148 /* New argument list transforming bcopy(ptr x, ptr y, int z) to
3149 memmove(ptr y, ptr x, size_t z). This is done this way
3150 so that if it isn't expanded inline, we fallback to
3151 calling bcopy instead of memmove. */
3153 newarglist
= build_tree_list (NULL_TREE
, fold_convert (sizetype
, size
));
3154 newarglist
= tree_cons (NULL_TREE
, src
, newarglist
);
3155 newarglist
= tree_cons (NULL_TREE
, dest
, newarglist
);
3157 return expand_builtin_memmove (newarglist
, type
, const0_rtx
, VOIDmode
, exp
);
3161 # define HAVE_movstr 0
3162 # define CODE_FOR_movstr CODE_FOR_nothing
3165 /* Expand into a movstr instruction, if one is available. Return 0 if
3166 we failed, the caller should emit a normal call, otherwise try to
3167 get the result in TARGET, if convenient. If ENDP is 0 return the
3168 destination pointer, if ENDP is 1 return the end pointer ala
3169 mempcpy, and if ENDP is 2 return the end pointer minus one ala
3173 expand_movstr (tree dest
, tree src
, rtx target
, int endp
)
3179 const struct insn_data
* data
;
3184 dest_mem
= get_memory_rtx (dest
, NULL
);
3185 src_mem
= get_memory_rtx (src
, NULL
);
3188 target
= force_reg (Pmode
, XEXP (dest_mem
, 0));
3189 dest_mem
= replace_equiv_address (dest_mem
, target
);
3190 end
= gen_reg_rtx (Pmode
);
3194 if (target
== 0 || target
== const0_rtx
)
3196 end
= gen_reg_rtx (Pmode
);
3204 data
= insn_data
+ CODE_FOR_movstr
;
3206 if (data
->operand
[0].mode
!= VOIDmode
)
3207 end
= gen_lowpart (data
->operand
[0].mode
, end
);
3209 insn
= data
->genfun (end
, dest_mem
, src_mem
);
3215 /* movstr is supposed to set end to the address of the NUL
3216 terminator. If the caller requested a mempcpy-like return value,
3218 if (endp
== 1 && target
!= const0_rtx
)
3220 rtx tem
= plus_constant (gen_lowpart (GET_MODE (target
), end
), 1);
3221 emit_move_insn (target
, force_operand (tem
, NULL_RTX
));
3227 /* Expand expression EXP, which is a call to the strcpy builtin. Return 0
3228 if we failed the caller should emit a normal call, otherwise try to get
3229 the result in TARGET, if convenient (and in mode MODE if that's
3233 expand_builtin_strcpy (tree fndecl
, tree arglist
, rtx target
, enum machine_mode mode
)
3235 if (validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
3237 tree result
= fold_builtin_strcpy (fndecl
, arglist
, 0);
3240 while (TREE_CODE (result
) == COMPOUND_EXPR
)
3242 expand_expr (TREE_OPERAND (result
, 0), const0_rtx
, VOIDmode
,
3244 result
= TREE_OPERAND (result
, 1);
3246 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
3249 return expand_movstr (TREE_VALUE (arglist
),
3250 TREE_VALUE (TREE_CHAIN (arglist
)),
3251 target
, /*endp=*/0);
3256 /* Expand a call to the stpcpy builtin, with arguments in ARGLIST.
3257 Return 0 if we failed the caller should emit a normal call,
3258 otherwise try to get the result in TARGET, if convenient (and in
3259 mode MODE if that's convenient). */
3262 expand_builtin_stpcpy (tree exp
, rtx target
, enum machine_mode mode
)
3264 tree arglist
= TREE_OPERAND (exp
, 1);
3265 /* If return value is ignored, transform stpcpy into strcpy. */
3266 if (target
== const0_rtx
)
3268 tree fn
= implicit_built_in_decls
[BUILT_IN_STRCPY
];
3272 return expand_expr (build_function_call_expr (fn
, arglist
),
3273 target
, mode
, EXPAND_NORMAL
);
3276 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
3280 tree dst
, src
, len
, lenp1
;
3284 /* Ensure we get an actual string whose length can be evaluated at
3285 compile-time, not an expression containing a string. This is
3286 because the latter will potentially produce pessimized code
3287 when used to produce the return value. */
3288 src
= TREE_VALUE (TREE_CHAIN (arglist
));
3289 if (! c_getstr (src
) || ! (len
= c_strlen (src
, 0)))
3290 return expand_movstr (TREE_VALUE (arglist
),
3291 TREE_VALUE (TREE_CHAIN (arglist
)),
3292 target
, /*endp=*/2);
3294 dst
= TREE_VALUE (arglist
);
3295 lenp1
= size_binop (PLUS_EXPR
, len
, ssize_int (1));
3296 narglist
= build_tree_list (NULL_TREE
, lenp1
);
3297 narglist
= tree_cons (NULL_TREE
, src
, narglist
);
3298 narglist
= tree_cons (NULL_TREE
, dst
, narglist
);
3299 ret
= expand_builtin_mempcpy (narglist
, TREE_TYPE (exp
),
3300 target
, mode
, /*endp=*/2);
3305 if (TREE_CODE (len
) == INTEGER_CST
)
3307 rtx len_rtx
= expand_normal (len
);
3309 if (GET_CODE (len_rtx
) == CONST_INT
)
3311 ret
= expand_builtin_strcpy (get_callee_fndecl (exp
),
3312 arglist
, target
, mode
);
3318 if (mode
!= VOIDmode
)
3319 target
= gen_reg_rtx (mode
);
3321 target
= gen_reg_rtx (GET_MODE (ret
));
3323 if (GET_MODE (target
) != GET_MODE (ret
))
3324 ret
= gen_lowpart (GET_MODE (target
), ret
);
3326 ret
= plus_constant (ret
, INTVAL (len_rtx
));
3327 ret
= emit_move_insn (target
, force_operand (ret
, NULL_RTX
));
3335 return expand_movstr (TREE_VALUE (arglist
),
3336 TREE_VALUE (TREE_CHAIN (arglist
)),
3337 target
, /*endp=*/2);
3341 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
3342 bytes from constant string DATA + OFFSET and return it as target
3346 builtin_strncpy_read_str (void *data
, HOST_WIDE_INT offset
,
3347 enum machine_mode mode
)
3349 const char *str
= (const char *) data
;
3351 if ((unsigned HOST_WIDE_INT
) offset
> strlen (str
))
3354 return c_readstr (str
+ offset
, mode
);
3357 /* Expand expression EXP, which is a call to the strncpy builtin. Return 0
3358 if we failed the caller should emit a normal call. */
3361 expand_builtin_strncpy (tree exp
, rtx target
, enum machine_mode mode
)
3363 tree fndecl
= get_callee_fndecl (exp
);
3364 tree arglist
= TREE_OPERAND (exp
, 1);
3365 if (validate_arglist (arglist
,
3366 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
3368 tree slen
= c_strlen (TREE_VALUE (TREE_CHAIN (arglist
)), 1);
3369 tree len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
3370 tree result
= fold_builtin_strncpy (fndecl
, arglist
, slen
);
3374 while (TREE_CODE (result
) == COMPOUND_EXPR
)
3376 expand_expr (TREE_OPERAND (result
, 0), const0_rtx
, VOIDmode
,
3378 result
= TREE_OPERAND (result
, 1);
3380 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
3383 /* We must be passed a constant len and src parameter. */
3384 if (!host_integerp (len
, 1) || !slen
|| !host_integerp (slen
, 1))
3387 slen
= size_binop (PLUS_EXPR
, slen
, ssize_int (1));
3389 /* We're required to pad with trailing zeros if the requested
3390 len is greater than strlen(s2)+1. In that case try to
3391 use store_by_pieces, if it fails, punt. */
3392 if (tree_int_cst_lt (slen
, len
))
3394 tree dest
= TREE_VALUE (arglist
);
3395 unsigned int dest_align
3396 = get_pointer_alignment (dest
, BIGGEST_ALIGNMENT
);
3397 const char *p
= c_getstr (TREE_VALUE (TREE_CHAIN (arglist
)));
3400 if (!p
|| dest_align
== 0 || !host_integerp (len
, 1)
3401 || !can_store_by_pieces (tree_low_cst (len
, 1),
3402 builtin_strncpy_read_str
,
3403 (void *) p
, dest_align
))
3406 dest_mem
= get_memory_rtx (dest
, len
);
3407 store_by_pieces (dest_mem
, tree_low_cst (len
, 1),
3408 builtin_strncpy_read_str
,
3409 (void *) p
, dest_align
, 0);
3410 dest_mem
= force_operand (XEXP (dest_mem
, 0), NULL_RTX
);
3411 dest_mem
= convert_memory_address (ptr_mode
, dest_mem
);
3418 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
3419 bytes from constant string DATA + OFFSET and return it as target
3423 builtin_memset_read_str (void *data
, HOST_WIDE_INT offset ATTRIBUTE_UNUSED
,
3424 enum machine_mode mode
)
3426 const char *c
= (const char *) data
;
3427 char *p
= alloca (GET_MODE_SIZE (mode
));
3429 memset (p
, *c
, GET_MODE_SIZE (mode
));
3431 return c_readstr (p
, mode
);
3434 /* Callback routine for store_by_pieces. Return the RTL of a register
3435 containing GET_MODE_SIZE (MODE) consecutive copies of the unsigned
3436 char value given in the RTL register data. For example, if mode is
3437 4 bytes wide, return the RTL for 0x01010101*data. */
3440 builtin_memset_gen_str (void *data
, HOST_WIDE_INT offset ATTRIBUTE_UNUSED
,
3441 enum machine_mode mode
)
3447 size
= GET_MODE_SIZE (mode
);
3452 memset (p
, 1, size
);
3453 coeff
= c_readstr (p
, mode
);
3455 target
= convert_to_mode (mode
, (rtx
) data
, 1);
3456 target
= expand_mult (mode
, target
, coeff
, NULL_RTX
, 1);
3457 return force_reg (mode
, target
);
3460 /* Expand expression EXP, which is a call to the memset builtin. Return 0
3461 if we failed the caller should emit a normal call, otherwise try to get
3462 the result in TARGET, if convenient (and in mode MODE if that's
3466 expand_builtin_memset (tree arglist
, rtx target
, enum machine_mode mode
,
3469 if (!validate_arglist (arglist
,
3470 POINTER_TYPE
, INTEGER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
3474 tree dest
= TREE_VALUE (arglist
);
3475 tree val
= TREE_VALUE (TREE_CHAIN (arglist
));
3476 tree len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
3478 enum built_in_function fcode
;
3480 unsigned int dest_align
;
3481 rtx dest_mem
, dest_addr
, len_rtx
;
3483 dest_align
= get_pointer_alignment (dest
, BIGGEST_ALIGNMENT
);
3485 /* If DEST is not a pointer type, don't do this
3486 operation in-line. */
3487 if (dest_align
== 0)
3490 /* If the LEN parameter is zero, return DEST. */
3491 if (integer_zerop (len
))
3493 /* Evaluate and ignore VAL in case it has side-effects. */
3494 expand_expr (val
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
3495 return expand_expr (dest
, target
, mode
, EXPAND_NORMAL
);
3498 /* Stabilize the arguments in case we fail. */
3499 dest
= builtin_save_expr (dest
);
3500 val
= builtin_save_expr (val
);
3501 len
= builtin_save_expr (len
);
3503 len_rtx
= expand_normal (len
);
3504 dest_mem
= get_memory_rtx (dest
, len
);
3506 if (TREE_CODE (val
) != INTEGER_CST
)
3510 val_rtx
= expand_normal (val
);
3511 val_rtx
= convert_to_mode (TYPE_MODE (unsigned_char_type_node
),
3514 /* Assume that we can memset by pieces if we can store the
3515 * the coefficients by pieces (in the required modes).
3516 * We can't pass builtin_memset_gen_str as that emits RTL. */
3518 if (host_integerp (len
, 1)
3519 && !(optimize_size
&& tree_low_cst (len
, 1) > 1)
3520 && can_store_by_pieces (tree_low_cst (len
, 1),
3521 builtin_memset_read_str
, &c
, dest_align
))
3523 val_rtx
= force_reg (TYPE_MODE (unsigned_char_type_node
),
3525 store_by_pieces (dest_mem
, tree_low_cst (len
, 1),
3526 builtin_memset_gen_str
, val_rtx
, dest_align
, 0);
3528 else if (!set_storage_via_setmem (dest_mem
, len_rtx
, val_rtx
,
3532 dest_mem
= force_operand (XEXP (dest_mem
, 0), NULL_RTX
);
3533 dest_mem
= convert_memory_address (ptr_mode
, dest_mem
);
3537 if (target_char_cast (val
, &c
))
3542 if (host_integerp (len
, 1)
3543 && !(optimize_size
&& tree_low_cst (len
, 1) > 1)
3544 && can_store_by_pieces (tree_low_cst (len
, 1),
3545 builtin_memset_read_str
, &c
, dest_align
))
3546 store_by_pieces (dest_mem
, tree_low_cst (len
, 1),
3547 builtin_memset_read_str
, &c
, dest_align
, 0);
3548 else if (!set_storage_via_setmem (dest_mem
, len_rtx
, GEN_INT (c
),
3552 dest_mem
= force_operand (XEXP (dest_mem
, 0), NULL_RTX
);
3553 dest_mem
= convert_memory_address (ptr_mode
, dest_mem
);
3557 set_mem_align (dest_mem
, dest_align
);
3558 dest_addr
= clear_storage (dest_mem
, len_rtx
,
3559 CALL_EXPR_TAILCALL (orig_exp
)
3560 ? BLOCK_OP_TAILCALL
: BLOCK_OP_NORMAL
);
3564 dest_addr
= force_operand (XEXP (dest_mem
, 0), NULL_RTX
);
3565 dest_addr
= convert_memory_address (ptr_mode
, dest_addr
);
3571 fndecl
= get_callee_fndecl (orig_exp
);
3572 fcode
= DECL_FUNCTION_CODE (fndecl
);
3573 gcc_assert (fcode
== BUILT_IN_MEMSET
|| fcode
== BUILT_IN_BZERO
);
3574 arglist
= build_tree_list (NULL_TREE
, len
);
3575 if (fcode
== BUILT_IN_MEMSET
)
3576 arglist
= tree_cons (NULL_TREE
, val
, arglist
);
3577 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
3578 fn
= build_function_call_expr (fndecl
, arglist
);
3579 if (TREE_CODE (fn
) == CALL_EXPR
)
3580 CALL_EXPR_TAILCALL (fn
) = CALL_EXPR_TAILCALL (orig_exp
);
3581 return expand_call (fn
, target
, target
== const0_rtx
);
3585 /* Expand expression EXP, which is a call to the bzero builtin. Return 0
3586 if we failed the caller should emit a normal call. */
3589 expand_builtin_bzero (tree exp
)
3591 tree arglist
= TREE_OPERAND (exp
, 1);
3592 tree dest
, size
, newarglist
;
3594 if (!validate_arglist (arglist
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
3597 dest
= TREE_VALUE (arglist
);
3598 size
= TREE_VALUE (TREE_CHAIN (arglist
));
3600 /* New argument list transforming bzero(ptr x, int y) to
3601 memset(ptr x, int 0, size_t y). This is done this way
3602 so that if it isn't expanded inline, we fallback to
3603 calling bzero instead of memset. */
3605 newarglist
= build_tree_list (NULL_TREE
, fold_convert (sizetype
, size
));
3606 newarglist
= tree_cons (NULL_TREE
, integer_zero_node
, newarglist
);
3607 newarglist
= tree_cons (NULL_TREE
, dest
, newarglist
);
3609 return expand_builtin_memset (newarglist
, const0_rtx
, VOIDmode
, exp
);
3612 /* Expand expression EXP, which is a call to the memcmp built-in function.
3613 ARGLIST is the argument list for this call. Return 0 if we failed and the
3614 caller should emit a normal call, otherwise try to get the result in
3615 TARGET, if convenient (and in mode MODE, if that's convenient). */
3618 expand_builtin_memcmp (tree exp ATTRIBUTE_UNUSED
, tree arglist
, rtx target
,
3619 enum machine_mode mode
)
3621 if (!validate_arglist (arglist
,
3622 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
3626 tree result
= fold_builtin_memcmp (arglist
);
3628 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
3631 #if defined HAVE_cmpmemsi || defined HAVE_cmpstrnsi
3633 tree arg1
= TREE_VALUE (arglist
);
3634 tree arg2
= TREE_VALUE (TREE_CHAIN (arglist
));
3635 tree len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
3636 rtx arg1_rtx
, arg2_rtx
, arg3_rtx
;
3641 = get_pointer_alignment (arg1
, BIGGEST_ALIGNMENT
) / BITS_PER_UNIT
;
3643 = get_pointer_alignment (arg2
, BIGGEST_ALIGNMENT
) / BITS_PER_UNIT
;
3644 enum machine_mode insn_mode
;
3646 #ifdef HAVE_cmpmemsi
3648 insn_mode
= insn_data
[(int) CODE_FOR_cmpmemsi
].operand
[0].mode
;
3651 #ifdef HAVE_cmpstrnsi
3653 insn_mode
= insn_data
[(int) CODE_FOR_cmpstrnsi
].operand
[0].mode
;
3658 /* If we don't have POINTER_TYPE, call the function. */
3659 if (arg1_align
== 0 || arg2_align
== 0)
3662 /* Make a place to write the result of the instruction. */
3665 && REG_P (result
) && GET_MODE (result
) == insn_mode
3666 && REGNO (result
) >= FIRST_PSEUDO_REGISTER
))
3667 result
= gen_reg_rtx (insn_mode
);
3669 arg1_rtx
= get_memory_rtx (arg1
, len
);
3670 arg2_rtx
= get_memory_rtx (arg2
, len
);
3671 arg3_rtx
= expand_normal (len
);
3673 /* Set MEM_SIZE as appropriate. */
3674 if (GET_CODE (arg3_rtx
) == CONST_INT
)
3676 set_mem_size (arg1_rtx
, arg3_rtx
);
3677 set_mem_size (arg2_rtx
, arg3_rtx
);
3680 #ifdef HAVE_cmpmemsi
3682 insn
= gen_cmpmemsi (result
, arg1_rtx
, arg2_rtx
, arg3_rtx
,
3683 GEN_INT (MIN (arg1_align
, arg2_align
)));
3686 #ifdef HAVE_cmpstrnsi
3688 insn
= gen_cmpstrnsi (result
, arg1_rtx
, arg2_rtx
, arg3_rtx
,
3689 GEN_INT (MIN (arg1_align
, arg2_align
)));
3697 emit_library_call_value (memcmp_libfunc
, result
, LCT_PURE_MAKE_BLOCK
,
3698 TYPE_MODE (integer_type_node
), 3,
3699 XEXP (arg1_rtx
, 0), Pmode
,
3700 XEXP (arg2_rtx
, 0), Pmode
,
3701 convert_to_mode (TYPE_MODE (sizetype
), arg3_rtx
,
3702 TYPE_UNSIGNED (sizetype
)),
3703 TYPE_MODE (sizetype
));
3705 /* Return the value in the proper mode for this function. */
3706 mode
= TYPE_MODE (TREE_TYPE (exp
));
3707 if (GET_MODE (result
) == mode
)
3709 else if (target
!= 0)
3711 convert_move (target
, result
, 0);
3715 return convert_to_mode (mode
, result
, 0);
3722 /* Expand expression EXP, which is a call to the strcmp builtin. Return 0
3723 if we failed the caller should emit a normal call, otherwise try to get
3724 the result in TARGET, if convenient. */
3727 expand_builtin_strcmp (tree exp
, rtx target
, enum machine_mode mode
)
3729 tree arglist
= TREE_OPERAND (exp
, 1);
3731 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
3735 tree result
= fold_builtin_strcmp (arglist
);
3737 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
3740 #if defined HAVE_cmpstrsi || defined HAVE_cmpstrnsi
3741 if (cmpstr_optab
[SImode
] != CODE_FOR_nothing
3742 || cmpstrn_optab
[SImode
] != CODE_FOR_nothing
)
3744 rtx arg1_rtx
, arg2_rtx
;
3745 rtx result
, insn
= NULL_RTX
;
3748 tree arg1
= TREE_VALUE (arglist
);
3749 tree arg2
= TREE_VALUE (TREE_CHAIN (arglist
));
3751 = get_pointer_alignment (arg1
, BIGGEST_ALIGNMENT
) / BITS_PER_UNIT
;
3753 = get_pointer_alignment (arg2
, BIGGEST_ALIGNMENT
) / BITS_PER_UNIT
;
3755 /* If we don't have POINTER_TYPE, call the function. */
3756 if (arg1_align
== 0 || arg2_align
== 0)
3759 /* Stabilize the arguments in case gen_cmpstr(n)si fail. */
3760 arg1
= builtin_save_expr (arg1
);
3761 arg2
= builtin_save_expr (arg2
);
3763 arg1_rtx
= get_memory_rtx (arg1
, NULL
);
3764 arg2_rtx
= get_memory_rtx (arg2
, NULL
);
3766 #ifdef HAVE_cmpstrsi
3767 /* Try to call cmpstrsi. */
3770 enum machine_mode insn_mode
3771 = insn_data
[(int) CODE_FOR_cmpstrsi
].operand
[0].mode
;
3773 /* Make a place to write the result of the instruction. */
3776 && REG_P (result
) && GET_MODE (result
) == insn_mode
3777 && REGNO (result
) >= FIRST_PSEUDO_REGISTER
))
3778 result
= gen_reg_rtx (insn_mode
);
3780 insn
= gen_cmpstrsi (result
, arg1_rtx
, arg2_rtx
,
3781 GEN_INT (MIN (arg1_align
, arg2_align
)));
3784 #ifdef HAVE_cmpstrnsi
3785 /* Try to determine at least one length and call cmpstrnsi. */
3786 if (!insn
&& HAVE_cmpstrnsi
)
3791 enum machine_mode insn_mode
3792 = insn_data
[(int) CODE_FOR_cmpstrnsi
].operand
[0].mode
;
3793 tree len1
= c_strlen (arg1
, 1);
3794 tree len2
= c_strlen (arg2
, 1);
3797 len1
= size_binop (PLUS_EXPR
, ssize_int (1), len1
);
3799 len2
= size_binop (PLUS_EXPR
, ssize_int (1), len2
);
3801 /* If we don't have a constant length for the first, use the length
3802 of the second, if we know it. We don't require a constant for
3803 this case; some cost analysis could be done if both are available
3804 but neither is constant. For now, assume they're equally cheap,
3805 unless one has side effects. If both strings have constant lengths,
3812 else if (TREE_SIDE_EFFECTS (len1
))
3814 else if (TREE_SIDE_EFFECTS (len2
))
3816 else if (TREE_CODE (len1
) != INTEGER_CST
)
3818 else if (TREE_CODE (len2
) != INTEGER_CST
)
3820 else if (tree_int_cst_lt (len1
, len2
))
3825 /* If both arguments have side effects, we cannot optimize. */
3826 if (!len
|| TREE_SIDE_EFFECTS (len
))
3829 arg3_rtx
= expand_normal (len
);
3831 /* Make a place to write the result of the instruction. */
3834 && REG_P (result
) && GET_MODE (result
) == insn_mode
3835 && REGNO (result
) >= FIRST_PSEUDO_REGISTER
))
3836 result
= gen_reg_rtx (insn_mode
);
3838 insn
= gen_cmpstrnsi (result
, arg1_rtx
, arg2_rtx
, arg3_rtx
,
3839 GEN_INT (MIN (arg1_align
, arg2_align
)));
3847 /* Return the value in the proper mode for this function. */
3848 mode
= TYPE_MODE (TREE_TYPE (exp
));
3849 if (GET_MODE (result
) == mode
)
3852 return convert_to_mode (mode
, result
, 0);
3853 convert_move (target
, result
, 0);
3857 /* Expand the library call ourselves using a stabilized argument
3858 list to avoid re-evaluating the function's arguments twice. */
3859 #ifdef HAVE_cmpstrnsi
3862 arglist
= build_tree_list (NULL_TREE
, arg2
);
3863 arglist
= tree_cons (NULL_TREE
, arg1
, arglist
);
3864 fndecl
= get_callee_fndecl (exp
);
3865 fn
= build_function_call_expr (fndecl
, arglist
);
3866 if (TREE_CODE (fn
) == CALL_EXPR
)
3867 CALL_EXPR_TAILCALL (fn
) = CALL_EXPR_TAILCALL (exp
);
3868 return expand_call (fn
, target
, target
== const0_rtx
);
3874 /* Expand expression EXP, which is a call to the strncmp builtin. Return 0
3875 if we failed the caller should emit a normal call, otherwise try to get
3876 the result in TARGET, if convenient. */
3879 expand_builtin_strncmp (tree exp
, rtx target
, enum machine_mode mode
)
3881 tree arglist
= TREE_OPERAND (exp
, 1);
3883 if (!validate_arglist (arglist
,
3884 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
3888 tree result
= fold_builtin_strncmp (arglist
);
3890 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
3893 /* If c_strlen can determine an expression for one of the string
3894 lengths, and it doesn't have side effects, then emit cmpstrnsi
3895 using length MIN(strlen(string)+1, arg3). */
3896 #ifdef HAVE_cmpstrnsi
3899 tree arg1
= TREE_VALUE (arglist
);
3900 tree arg2
= TREE_VALUE (TREE_CHAIN (arglist
));
3901 tree arg3
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
3902 tree len
, len1
, len2
;
3903 rtx arg1_rtx
, arg2_rtx
, arg3_rtx
;
3908 = get_pointer_alignment (arg1
, BIGGEST_ALIGNMENT
) / BITS_PER_UNIT
;
3910 = get_pointer_alignment (arg2
, BIGGEST_ALIGNMENT
) / BITS_PER_UNIT
;
3911 enum machine_mode insn_mode
3912 = insn_data
[(int) CODE_FOR_cmpstrnsi
].operand
[0].mode
;
3914 len1
= c_strlen (arg1
, 1);
3915 len2
= c_strlen (arg2
, 1);
3918 len1
= size_binop (PLUS_EXPR
, ssize_int (1), len1
);
3920 len2
= size_binop (PLUS_EXPR
, ssize_int (1), len2
);
3922 /* If we don't have a constant length for the first, use the length
3923 of the second, if we know it. We don't require a constant for
3924 this case; some cost analysis could be done if both are available
3925 but neither is constant. For now, assume they're equally cheap,
3926 unless one has side effects. If both strings have constant lengths,
3933 else if (TREE_SIDE_EFFECTS (len1
))
3935 else if (TREE_SIDE_EFFECTS (len2
))
3937 else if (TREE_CODE (len1
) != INTEGER_CST
)
3939 else if (TREE_CODE (len2
) != INTEGER_CST
)
3941 else if (tree_int_cst_lt (len1
, len2
))
3946 /* If both arguments have side effects, we cannot optimize. */
3947 if (!len
|| TREE_SIDE_EFFECTS (len
))
3950 /* The actual new length parameter is MIN(len,arg3). */
3951 len
= fold_build2 (MIN_EXPR
, TREE_TYPE (len
), len
,
3952 fold_convert (TREE_TYPE (len
), arg3
));
3954 /* If we don't have POINTER_TYPE, call the function. */
3955 if (arg1_align
== 0 || arg2_align
== 0)
3958 /* Make a place to write the result of the instruction. */
3961 && REG_P (result
) && GET_MODE (result
) == insn_mode
3962 && REGNO (result
) >= FIRST_PSEUDO_REGISTER
))
3963 result
= gen_reg_rtx (insn_mode
);
3965 /* Stabilize the arguments in case gen_cmpstrnsi fails. */
3966 arg1
= builtin_save_expr (arg1
);
3967 arg2
= builtin_save_expr (arg2
);
3968 len
= builtin_save_expr (len
);
3970 arg1_rtx
= get_memory_rtx (arg1
, len
);
3971 arg2_rtx
= get_memory_rtx (arg2
, len
);
3972 arg3_rtx
= expand_normal (len
);
3973 insn
= gen_cmpstrnsi (result
, arg1_rtx
, arg2_rtx
, arg3_rtx
,
3974 GEN_INT (MIN (arg1_align
, arg2_align
)));
3979 /* Return the value in the proper mode for this function. */
3980 mode
= TYPE_MODE (TREE_TYPE (exp
));
3981 if (GET_MODE (result
) == mode
)
3984 return convert_to_mode (mode
, result
, 0);
3985 convert_move (target
, result
, 0);
3989 /* Expand the library call ourselves using a stabilized argument
3990 list to avoid re-evaluating the function's arguments twice. */
3991 arglist
= build_tree_list (NULL_TREE
, len
);
3992 arglist
= tree_cons (NULL_TREE
, arg2
, arglist
);
3993 arglist
= tree_cons (NULL_TREE
, arg1
, arglist
);
3994 fndecl
= get_callee_fndecl (exp
);
3995 fn
= build_function_call_expr (fndecl
, arglist
);
3996 if (TREE_CODE (fn
) == CALL_EXPR
)
3997 CALL_EXPR_TAILCALL (fn
) = CALL_EXPR_TAILCALL (exp
);
3998 return expand_call (fn
, target
, target
== const0_rtx
);
4004 /* Expand expression EXP, which is a call to the strcat builtin.
4005 Return 0 if we failed the caller should emit a normal call,
4006 otherwise try to get the result in TARGET, if convenient. */
4009 expand_builtin_strcat (tree fndecl
, tree arglist
, rtx target
, enum machine_mode mode
)
4011 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
4015 tree dst
= TREE_VALUE (arglist
),
4016 src
= TREE_VALUE (TREE_CHAIN (arglist
));
4017 const char *p
= c_getstr (src
);
4019 /* If the string length is zero, return the dst parameter. */
4020 if (p
&& *p
== '\0')
4021 return expand_expr (dst
, target
, mode
, EXPAND_NORMAL
);
4025 /* See if we can store by pieces into (dst + strlen(dst)). */
4026 tree newsrc
, newdst
,
4027 strlen_fn
= implicit_built_in_decls
[BUILT_IN_STRLEN
];
4030 /* Stabilize the argument list. */
4031 newsrc
= builtin_save_expr (src
);
4033 arglist
= build_tree_list (NULL_TREE
, newsrc
);
4035 arglist
= TREE_CHAIN (arglist
); /* Reusing arglist if safe. */
4037 dst
= builtin_save_expr (dst
);
4041 /* Create strlen (dst). */
4043 build_function_call_expr (strlen_fn
,
4044 build_tree_list (NULL_TREE
, dst
));
4045 /* Create (dst + (cast) strlen (dst)). */
4046 newdst
= fold_convert (TREE_TYPE (dst
), newdst
);
4047 newdst
= fold_build2 (PLUS_EXPR
, TREE_TYPE (dst
), dst
, newdst
);
4049 newdst
= builtin_save_expr (newdst
);
4050 arglist
= tree_cons (NULL_TREE
, newdst
, arglist
);
4052 if (!expand_builtin_strcpy (fndecl
, arglist
, target
, mode
))
4054 end_sequence (); /* Stop sequence. */
4058 /* Output the entire sequence. */
4059 insns
= get_insns ();
4063 return expand_expr (dst
, target
, mode
, EXPAND_NORMAL
);
4070 /* Expand expression EXP, which is a call to the strncat 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_strncat (tree arglist
, rtx target
, enum machine_mode mode
)
4077 if (validate_arglist (arglist
,
4078 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
4080 tree result
= fold_builtin_strncat (arglist
);
4082 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
4087 /* Expand expression EXP, which is a call to the strspn builtin.
4088 Return 0 if we failed the caller should emit a normal call,
4089 otherwise try to get the result in TARGET, if convenient. */
4092 expand_builtin_strspn (tree arglist
, rtx target
, enum machine_mode mode
)
4094 if (validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
4096 tree result
= fold_builtin_strspn (arglist
);
4098 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
4103 /* Expand expression EXP, which is a call to the strcspn builtin.
4104 Return 0 if we failed the caller should emit a normal call,
4105 otherwise try to get the result in TARGET, if convenient. */
4108 expand_builtin_strcspn (tree arglist
, rtx target
, enum machine_mode mode
)
4110 if (validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
4112 tree result
= fold_builtin_strcspn (arglist
);
4114 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
4119 /* Expand a call to __builtin_saveregs, generating the result in TARGET,
4120 if that's convenient. */
4123 expand_builtin_saveregs (void)
4127 /* Don't do __builtin_saveregs more than once in a function.
4128 Save the result of the first call and reuse it. */
4129 if (saveregs_value
!= 0)
4130 return saveregs_value
;
4132 /* When this function is called, it means that registers must be
4133 saved on entry to this function. So we migrate the call to the
4134 first insn of this function. */
4138 /* Do whatever the machine needs done in this case. */
4139 val
= targetm
.calls
.expand_builtin_saveregs ();
4144 saveregs_value
= val
;
4146 /* Put the insns after the NOTE that starts the function. If this
4147 is inside a start_sequence, make the outer-level insn chain current, so
4148 the code is placed at the start of the function. */
4149 push_topmost_sequence ();
4150 emit_insn_after (seq
, entry_of_function ());
4151 pop_topmost_sequence ();
4156 /* __builtin_args_info (N) returns word N of the arg space info
4157 for the current function. The number and meanings of words
4158 is controlled by the definition of CUMULATIVE_ARGS. */
4161 expand_builtin_args_info (tree arglist
)
4163 int nwords
= sizeof (CUMULATIVE_ARGS
) / sizeof (int);
4164 int *word_ptr
= (int *) ¤t_function_args_info
;
4166 gcc_assert (sizeof (CUMULATIVE_ARGS
) % sizeof (int) == 0);
4170 if (!host_integerp (TREE_VALUE (arglist
), 0))
4171 error ("argument of %<__builtin_args_info%> must be constant");
4174 HOST_WIDE_INT wordnum
= tree_low_cst (TREE_VALUE (arglist
), 0);
4176 if (wordnum
< 0 || wordnum
>= nwords
)
4177 error ("argument of %<__builtin_args_info%> out of range");
4179 return GEN_INT (word_ptr
[wordnum
]);
4183 error ("missing argument in %<__builtin_args_info%>");
4188 /* Expand a call to __builtin_next_arg. */
4191 expand_builtin_next_arg (void)
4193 /* Checking arguments is already done in fold_builtin_next_arg
4194 that must be called before this function. */
4195 return expand_binop (Pmode
, add_optab
,
4196 current_function_internal_arg_pointer
,
4197 current_function_arg_offset_rtx
,
4198 NULL_RTX
, 0, OPTAB_LIB_WIDEN
);
4201 /* Make it easier for the backends by protecting the valist argument
4202 from multiple evaluations. */
4205 stabilize_va_list (tree valist
, int needs_lvalue
)
4207 if (TREE_CODE (va_list_type_node
) == ARRAY_TYPE
)
4209 if (TREE_SIDE_EFFECTS (valist
))
4210 valist
= save_expr (valist
);
4212 /* For this case, the backends will be expecting a pointer to
4213 TREE_TYPE (va_list_type_node), but it's possible we've
4214 actually been given an array (an actual va_list_type_node).
4216 if (TREE_CODE (TREE_TYPE (valist
)) == ARRAY_TYPE
)
4218 tree p1
= build_pointer_type (TREE_TYPE (va_list_type_node
));
4219 valist
= build_fold_addr_expr_with_type (valist
, p1
);
4228 if (! TREE_SIDE_EFFECTS (valist
))
4231 pt
= build_pointer_type (va_list_type_node
);
4232 valist
= fold_build1 (ADDR_EXPR
, pt
, valist
);
4233 TREE_SIDE_EFFECTS (valist
) = 1;
4236 if (TREE_SIDE_EFFECTS (valist
))
4237 valist
= save_expr (valist
);
4238 valist
= build_fold_indirect_ref (valist
);
4244 /* The "standard" definition of va_list is void*. */
4247 std_build_builtin_va_list (void)
4249 return ptr_type_node
;
4252 /* The "standard" implementation of va_start: just assign `nextarg' to
4256 std_expand_builtin_va_start (tree valist
, rtx nextarg
)
4260 t
= build2 (MODIFY_EXPR
, TREE_TYPE (valist
), valist
,
4261 make_tree (ptr_type_node
, nextarg
));
4262 TREE_SIDE_EFFECTS (t
) = 1;
4264 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
4267 /* Expand ARGLIST, from a call to __builtin_va_start. */
4270 expand_builtin_va_start (tree arglist
)
4275 chain
= TREE_CHAIN (arglist
);
4279 error ("too few arguments to function %<va_start%>");
4283 if (fold_builtin_next_arg (chain
))
4286 nextarg
= expand_builtin_next_arg ();
4287 valist
= stabilize_va_list (TREE_VALUE (arglist
), 1);
4289 #ifdef EXPAND_BUILTIN_VA_START
4290 EXPAND_BUILTIN_VA_START (valist
, nextarg
);
4292 std_expand_builtin_va_start (valist
, nextarg
);
4298 /* The "standard" implementation of va_arg: read the value from the
4299 current (padded) address and increment by the (padded) size. */
4302 std_gimplify_va_arg_expr (tree valist
, tree type
, tree
*pre_p
, tree
*post_p
)
4304 tree addr
, t
, type_size
, rounded_size
, valist_tmp
;
4305 unsigned HOST_WIDE_INT align
, boundary
;
4308 #ifdef ARGS_GROW_DOWNWARD
4309 /* All of the alignment and movement below is for args-grow-up machines.
4310 As of 2004, there are only 3 ARGS_GROW_DOWNWARD targets, and they all
4311 implement their own specialized gimplify_va_arg_expr routines. */
4315 indirect
= pass_by_reference (NULL
, TYPE_MODE (type
), type
, false);
4317 type
= build_pointer_type (type
);
4319 align
= PARM_BOUNDARY
/ BITS_PER_UNIT
;
4320 boundary
= FUNCTION_ARG_BOUNDARY (TYPE_MODE (type
), type
) / BITS_PER_UNIT
;
4322 /* Hoist the valist value into a temporary for the moment. */
4323 valist_tmp
= get_initialized_tmp_var (valist
, pre_p
, NULL
);
4325 /* va_list pointer is aligned to PARM_BOUNDARY. If argument actually
4326 requires greater alignment, we must perform dynamic alignment. */
4327 if (boundary
> align
4328 && !integer_zerop (TYPE_SIZE (type
)))
4330 t
= fold_convert (TREE_TYPE (valist
), size_int (boundary
- 1));
4331 t
= build2 (MODIFY_EXPR
, TREE_TYPE (valist
), valist_tmp
,
4332 build2 (PLUS_EXPR
, TREE_TYPE (valist
), valist_tmp
, t
));
4333 gimplify_and_add (t
, pre_p
);
4335 t
= fold_convert (TREE_TYPE (valist
), size_int (-boundary
));
4336 t
= build2 (MODIFY_EXPR
, TREE_TYPE (valist
), valist_tmp
,
4337 build2 (BIT_AND_EXPR
, TREE_TYPE (valist
), valist_tmp
, t
));
4338 gimplify_and_add (t
, pre_p
);
4343 /* If the actual alignment is less than the alignment of the type,
4344 adjust the type accordingly so that we don't assume strict alignment
4345 when deferencing the pointer. */
4346 boundary
*= BITS_PER_UNIT
;
4347 if (boundary
< TYPE_ALIGN (type
))
4349 type
= build_variant_type_copy (type
);
4350 TYPE_ALIGN (type
) = boundary
;
4353 /* Compute the rounded size of the type. */
4354 type_size
= size_in_bytes (type
);
4355 rounded_size
= round_up (type_size
, align
);
4357 /* Reduce rounded_size so it's sharable with the postqueue. */
4358 gimplify_expr (&rounded_size
, pre_p
, post_p
, is_gimple_val
, fb_rvalue
);
4362 if (PAD_VARARGS_DOWN
&& !integer_zerop (rounded_size
))
4364 /* Small args are padded downward. */
4365 t
= fold_build2 (GT_EXPR
, sizetype
, rounded_size
, size_int (align
));
4366 t
= fold_build3 (COND_EXPR
, sizetype
, t
, size_zero_node
,
4367 size_binop (MINUS_EXPR
, rounded_size
, type_size
));
4368 t
= fold_convert (TREE_TYPE (addr
), t
);
4369 addr
= fold_build2 (PLUS_EXPR
, TREE_TYPE (addr
), addr
, t
);
4372 /* Compute new value for AP. */
4373 t
= fold_convert (TREE_TYPE (valist
), rounded_size
);
4374 t
= build2 (PLUS_EXPR
, TREE_TYPE (valist
), valist_tmp
, t
);
4375 t
= build2 (MODIFY_EXPR
, TREE_TYPE (valist
), valist
, t
);
4376 gimplify_and_add (t
, pre_p
);
4378 addr
= fold_convert (build_pointer_type (type
), addr
);
4381 addr
= build_va_arg_indirect_ref (addr
);
4383 return build_va_arg_indirect_ref (addr
);
4386 /* Build an indirect-ref expression over the given TREE, which represents a
4387 piece of a va_arg() expansion. */
4389 build_va_arg_indirect_ref (tree addr
)
4391 addr
= build_fold_indirect_ref (addr
);
4393 if (flag_mudflap
) /* Don't instrument va_arg INDIRECT_REF. */
4399 /* Return a dummy expression of type TYPE in order to keep going after an
4403 dummy_object (tree type
)
4405 tree t
= build_int_cst (build_pointer_type (type
), 0);
4406 return build1 (INDIRECT_REF
, type
, t
);
4409 /* Gimplify __builtin_va_arg, aka VA_ARG_EXPR, which is not really a
4410 builtin function, but a very special sort of operator. */
4412 enum gimplify_status
4413 gimplify_va_arg_expr (tree
*expr_p
, tree
*pre_p
, tree
*post_p
)
4415 tree promoted_type
, want_va_type
, have_va_type
;
4416 tree valist
= TREE_OPERAND (*expr_p
, 0);
4417 tree type
= TREE_TYPE (*expr_p
);
4420 /* Verify that valist is of the proper type. */
4421 want_va_type
= va_list_type_node
;
4422 have_va_type
= TREE_TYPE (valist
);
4424 if (have_va_type
== error_mark_node
)
4427 if (TREE_CODE (want_va_type
) == ARRAY_TYPE
)
4429 /* If va_list is an array type, the argument may have decayed
4430 to a pointer type, e.g. by being passed to another function.
4431 In that case, unwrap both types so that we can compare the
4432 underlying records. */
4433 if (TREE_CODE (have_va_type
) == ARRAY_TYPE
4434 || POINTER_TYPE_P (have_va_type
))
4436 want_va_type
= TREE_TYPE (want_va_type
);
4437 have_va_type
= TREE_TYPE (have_va_type
);
4441 if (TYPE_MAIN_VARIANT (want_va_type
) != TYPE_MAIN_VARIANT (have_va_type
))
4443 error ("first argument to %<va_arg%> not of type %<va_list%>");
4447 /* Generate a diagnostic for requesting data of a type that cannot
4448 be passed through `...' due to type promotion at the call site. */
4449 else if ((promoted_type
= lang_hooks
.types
.type_promotes_to (type
))
4452 static bool gave_help
;
4454 /* Unfortunately, this is merely undefined, rather than a constraint
4455 violation, so we cannot make this an error. If this call is never
4456 executed, the program is still strictly conforming. */
4457 warning (0, "%qT is promoted to %qT when passed through %<...%>",
4458 type
, promoted_type
);
4462 warning (0, "(so you should pass %qT not %qT to %<va_arg%>)",
4463 promoted_type
, type
);
4466 /* We can, however, treat "undefined" any way we please.
4467 Call abort to encourage the user to fix the program. */
4468 inform ("if this code is reached, the program will abort");
4469 t
= build_function_call_expr (implicit_built_in_decls
[BUILT_IN_TRAP
],
4471 append_to_statement_list (t
, pre_p
);
4473 /* This is dead code, but go ahead and finish so that the
4474 mode of the result comes out right. */
4475 *expr_p
= dummy_object (type
);
4480 /* Make it easier for the backends by protecting the valist argument
4481 from multiple evaluations. */
4482 if (TREE_CODE (va_list_type_node
) == ARRAY_TYPE
)
4484 /* For this case, the backends will be expecting a pointer to
4485 TREE_TYPE (va_list_type_node), but it's possible we've
4486 actually been given an array (an actual va_list_type_node).
4488 if (TREE_CODE (TREE_TYPE (valist
)) == ARRAY_TYPE
)
4490 tree p1
= build_pointer_type (TREE_TYPE (va_list_type_node
));
4491 valist
= build_fold_addr_expr_with_type (valist
, p1
);
4493 gimplify_expr (&valist
, pre_p
, post_p
, is_gimple_val
, fb_rvalue
);
4496 gimplify_expr (&valist
, pre_p
, post_p
, is_gimple_min_lval
, fb_lvalue
);
4498 if (!targetm
.gimplify_va_arg_expr
)
4499 /* FIXME:Once most targets are converted we should merely
4500 assert this is non-null. */
4503 *expr_p
= targetm
.gimplify_va_arg_expr (valist
, type
, pre_p
, post_p
);
4508 /* Expand ARGLIST, from a call to __builtin_va_end. */
4511 expand_builtin_va_end (tree arglist
)
4513 tree valist
= TREE_VALUE (arglist
);
4515 /* Evaluate for side effects, if needed. I hate macros that don't
4517 if (TREE_SIDE_EFFECTS (valist
))
4518 expand_expr (valist
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
4523 /* Expand ARGLIST, from a call to __builtin_va_copy. We do this as a
4524 builtin rather than just as an assignment in stdarg.h because of the
4525 nastiness of array-type va_list types. */
4528 expand_builtin_va_copy (tree arglist
)
4532 dst
= TREE_VALUE (arglist
);
4533 src
= TREE_VALUE (TREE_CHAIN (arglist
));
4535 dst
= stabilize_va_list (dst
, 1);
4536 src
= stabilize_va_list (src
, 0);
4538 if (TREE_CODE (va_list_type_node
) != ARRAY_TYPE
)
4540 t
= build2 (MODIFY_EXPR
, va_list_type_node
, dst
, src
);
4541 TREE_SIDE_EFFECTS (t
) = 1;
4542 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
4546 rtx dstb
, srcb
, size
;
4548 /* Evaluate to pointers. */
4549 dstb
= expand_expr (dst
, NULL_RTX
, Pmode
, EXPAND_NORMAL
);
4550 srcb
= expand_expr (src
, NULL_RTX
, Pmode
, EXPAND_NORMAL
);
4551 size
= expand_expr (TYPE_SIZE_UNIT (va_list_type_node
), NULL_RTX
,
4552 VOIDmode
, EXPAND_NORMAL
);
4554 dstb
= convert_memory_address (Pmode
, dstb
);
4555 srcb
= convert_memory_address (Pmode
, srcb
);
4557 /* "Dereference" to BLKmode memories. */
4558 dstb
= gen_rtx_MEM (BLKmode
, dstb
);
4559 set_mem_alias_set (dstb
, get_alias_set (TREE_TYPE (TREE_TYPE (dst
))));
4560 set_mem_align (dstb
, TYPE_ALIGN (va_list_type_node
));
4561 srcb
= gen_rtx_MEM (BLKmode
, srcb
);
4562 set_mem_alias_set (srcb
, get_alias_set (TREE_TYPE (TREE_TYPE (src
))));
4563 set_mem_align (srcb
, TYPE_ALIGN (va_list_type_node
));
4566 emit_block_move (dstb
, srcb
, size
, BLOCK_OP_NORMAL
);
4572 /* Expand a call to one of the builtin functions __builtin_frame_address or
4573 __builtin_return_address. */
4576 expand_builtin_frame_address (tree fndecl
, tree arglist
)
4578 /* The argument must be a nonnegative integer constant.
4579 It counts the number of frames to scan up the stack.
4580 The value is the return address saved in that frame. */
4582 /* Warning about missing arg was already issued. */
4584 else if (! host_integerp (TREE_VALUE (arglist
), 1))
4586 if (DECL_FUNCTION_CODE (fndecl
) == BUILT_IN_FRAME_ADDRESS
)
4587 error ("invalid argument to %<__builtin_frame_address%>");
4589 error ("invalid argument to %<__builtin_return_address%>");
4595 = expand_builtin_return_addr (DECL_FUNCTION_CODE (fndecl
),
4596 tree_low_cst (TREE_VALUE (arglist
), 1));
4598 /* Some ports cannot access arbitrary stack frames. */
4601 if (DECL_FUNCTION_CODE (fndecl
) == BUILT_IN_FRAME_ADDRESS
)
4602 warning (0, "unsupported argument to %<__builtin_frame_address%>");
4604 warning (0, "unsupported argument to %<__builtin_return_address%>");
4608 /* For __builtin_frame_address, return what we've got. */
4609 if (DECL_FUNCTION_CODE (fndecl
) == BUILT_IN_FRAME_ADDRESS
)
4613 && ! CONSTANT_P (tem
))
4614 tem
= copy_to_mode_reg (Pmode
, tem
);
4619 /* Expand a call to the alloca builtin, with arguments ARGLIST. Return 0 if
4620 we failed and the caller should emit a normal call, otherwise try to get
4621 the result in TARGET, if convenient. */
4624 expand_builtin_alloca (tree arglist
, rtx target
)
4629 /* In -fmudflap-instrumented code, alloca() and __builtin_alloca()
4630 should always expand to function calls. These can be intercepted
4635 if (!validate_arglist (arglist
, INTEGER_TYPE
, VOID_TYPE
))
4638 /* Compute the argument. */
4639 op0
= expand_normal (TREE_VALUE (arglist
));
4641 /* Allocate the desired space. */
4642 result
= allocate_dynamic_stack_space (op0
, target
, BITS_PER_UNIT
);
4643 result
= convert_memory_address (ptr_mode
, result
);
4648 /* Expand a call to a unary builtin. The arguments are in ARGLIST.
4649 Return 0 if a normal call should be emitted rather than expanding the
4650 function in-line. If convenient, the result should be placed in TARGET.
4651 SUBTARGET may be used as the target for computing one of EXP's operands. */
4654 expand_builtin_unop (enum machine_mode target_mode
, tree arglist
, rtx target
,
4655 rtx subtarget
, optab op_optab
)
4658 if (!validate_arglist (arglist
, INTEGER_TYPE
, VOID_TYPE
))
4661 /* Compute the argument. */
4662 op0
= expand_expr (TREE_VALUE (arglist
), subtarget
, VOIDmode
, 0);
4663 /* Compute op, into TARGET if possible.
4664 Set TARGET to wherever the result comes back. */
4665 target
= expand_unop (TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist
))),
4666 op_optab
, op0
, target
, 1);
4667 gcc_assert (target
);
4669 return convert_to_mode (target_mode
, target
, 0);
4672 /* If the string passed to fputs is a constant and is one character
4673 long, we attempt to transform this call into __builtin_fputc(). */
4676 expand_builtin_fputs (tree arglist
, rtx target
, bool unlocked
)
4678 /* Verify the arguments in the original call. */
4679 if (validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
4681 tree result
= fold_builtin_fputs (arglist
, (target
== const0_rtx
),
4682 unlocked
, NULL_TREE
);
4684 return expand_expr (result
, target
, VOIDmode
, EXPAND_NORMAL
);
4689 /* Expand a call to __builtin_expect. We return our argument and emit a
4690 NOTE_INSN_EXPECTED_VALUE note. This is the expansion of __builtin_expect in
4691 a non-jump context. */
4694 expand_builtin_expect (tree arglist
, rtx target
)
4699 if (arglist
== NULL_TREE
4700 || TREE_CHAIN (arglist
) == NULL_TREE
)
4702 exp
= TREE_VALUE (arglist
);
4703 c
= TREE_VALUE (TREE_CHAIN (arglist
));
4705 if (TREE_CODE (c
) != INTEGER_CST
)
4707 error ("second argument to %<__builtin_expect%> must be a constant");
4708 c
= integer_zero_node
;
4711 target
= expand_expr (exp
, target
, VOIDmode
, EXPAND_NORMAL
);
4713 /* Don't bother with expected value notes for integral constants. */
4714 if (flag_guess_branch_prob
&& GET_CODE (target
) != CONST_INT
)
4716 /* We do need to force this into a register so that we can be
4717 moderately sure to be able to correctly interpret the branch
4719 target
= force_reg (GET_MODE (target
), target
);
4721 rtx_c
= expand_expr (c
, NULL_RTX
, GET_MODE (target
), EXPAND_NORMAL
);
4723 note
= emit_note (NOTE_INSN_EXPECTED_VALUE
);
4724 NOTE_EXPECTED_VALUE (note
) = gen_rtx_EQ (VOIDmode
, target
, rtx_c
);
4730 /* Like expand_builtin_expect, except do this in a jump context. This is
4731 called from do_jump if the conditional is a __builtin_expect. Return either
4732 a list of insns to emit the jump or NULL if we cannot optimize
4733 __builtin_expect. We need to optimize this at jump time so that machines
4734 like the PowerPC don't turn the test into a SCC operation, and then jump
4735 based on the test being 0/1. */
4738 expand_builtin_expect_jump (tree exp
, rtx if_false_label
, rtx if_true_label
)
4740 tree arglist
= TREE_OPERAND (exp
, 1);
4741 tree arg0
= TREE_VALUE (arglist
);
4742 tree arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
4745 /* Only handle __builtin_expect (test, 0) and
4746 __builtin_expect (test, 1). */
4747 if (TREE_CODE (TREE_TYPE (arg1
)) == INTEGER_TYPE
4748 && (integer_zerop (arg1
) || integer_onep (arg1
)))
4750 rtx insn
, drop_through_label
, temp
;
4752 /* Expand the jump insns. */
4754 do_jump (arg0
, if_false_label
, if_true_label
);
4757 drop_through_label
= get_last_insn ();
4758 if (drop_through_label
&& NOTE_P (drop_through_label
))
4759 drop_through_label
= prev_nonnote_insn (drop_through_label
);
4760 if (drop_through_label
&& !LABEL_P (drop_through_label
))
4761 drop_through_label
= NULL_RTX
;
4764 if (! if_true_label
)
4765 if_true_label
= drop_through_label
;
4766 if (! if_false_label
)
4767 if_false_label
= drop_through_label
;
4769 /* Go through and add the expect's to each of the conditional jumps. */
4771 while (insn
!= NULL_RTX
)
4773 rtx next
= NEXT_INSN (insn
);
4775 if (JUMP_P (insn
) && any_condjump_p (insn
))
4777 rtx ifelse
= SET_SRC (pc_set (insn
));
4778 rtx then_dest
= XEXP (ifelse
, 1);
4779 rtx else_dest
= XEXP (ifelse
, 2);
4782 /* First check if we recognize any of the labels. */
4783 if (GET_CODE (then_dest
) == LABEL_REF
4784 && XEXP (then_dest
, 0) == if_true_label
)
4786 else if (GET_CODE (then_dest
) == LABEL_REF
4787 && XEXP (then_dest
, 0) == if_false_label
)
4789 else if (GET_CODE (else_dest
) == LABEL_REF
4790 && XEXP (else_dest
, 0) == if_false_label
)
4792 else if (GET_CODE (else_dest
) == LABEL_REF
4793 && XEXP (else_dest
, 0) == if_true_label
)
4795 /* Otherwise check where we drop through. */
4796 else if (else_dest
== pc_rtx
)
4798 if (next
&& NOTE_P (next
))
4799 next
= next_nonnote_insn (next
);
4801 if (next
&& JUMP_P (next
)
4802 && any_uncondjump_p (next
))
4803 temp
= XEXP (SET_SRC (pc_set (next
)), 0);
4807 /* TEMP is either a CODE_LABEL, NULL_RTX or something
4808 else that can't possibly match either target label. */
4809 if (temp
== if_false_label
)
4811 else if (temp
== if_true_label
)
4814 else if (then_dest
== pc_rtx
)
4816 if (next
&& NOTE_P (next
))
4817 next
= next_nonnote_insn (next
);
4819 if (next
&& JUMP_P (next
)
4820 && any_uncondjump_p (next
))
4821 temp
= XEXP (SET_SRC (pc_set (next
)), 0);
4825 if (temp
== if_false_label
)
4827 else if (temp
== if_true_label
)
4833 /* If the test is expected to fail, reverse the
4835 if (integer_zerop (arg1
))
4837 predict_insn_def (insn
, PRED_BUILTIN_EXPECT
, taken
);
4849 expand_builtin_trap (void)
4853 emit_insn (gen_trap ());
4856 emit_library_call (abort_libfunc
, LCT_NORETURN
, VOIDmode
, 0);
4860 /* Expand a call to fabs, fabsf or fabsl with arguments ARGLIST.
4861 Return 0 if a normal call should be emitted rather than expanding
4862 the function inline. If convenient, the result should be placed
4863 in TARGET. SUBTARGET may be used as the target for computing
4867 expand_builtin_fabs (tree arglist
, rtx target
, rtx subtarget
)
4869 enum machine_mode mode
;
4873 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
4876 arg
= TREE_VALUE (arglist
);
4877 mode
= TYPE_MODE (TREE_TYPE (arg
));
4878 op0
= expand_expr (arg
, subtarget
, VOIDmode
, 0);
4879 return expand_abs (mode
, op0
, target
, 0, safe_from_p (target
, arg
, 1));
4882 /* Expand a call to copysign, copysignf, or copysignl with arguments ARGLIST.
4883 Return NULL is a normal call should be emitted rather than expanding the
4884 function inline. If convenient, the result should be placed in TARGET.
4885 SUBTARGET may be used as the target for computing the operand. */
4888 expand_builtin_copysign (tree arglist
, rtx target
, rtx subtarget
)
4893 if (!validate_arglist (arglist
, REAL_TYPE
, REAL_TYPE
, VOID_TYPE
))
4896 arg
= TREE_VALUE (arglist
);
4897 op0
= expand_expr (arg
, subtarget
, VOIDmode
, EXPAND_NORMAL
);
4899 arg
= TREE_VALUE (TREE_CHAIN (arglist
));
4900 op1
= expand_normal (arg
);
4902 return expand_copysign (op0
, op1
, target
);
4905 /* Create a new constant string literal and return a char* pointer to it.
4906 The STRING_CST value is the LEN characters at STR. */
4908 build_string_literal (int len
, const char *str
)
4910 tree t
, elem
, index
, type
;
4912 t
= build_string (len
, str
);
4913 elem
= build_type_variant (char_type_node
, 1, 0);
4914 index
= build_index_type (build_int_cst (NULL_TREE
, len
- 1));
4915 type
= build_array_type (elem
, index
);
4916 TREE_TYPE (t
) = type
;
4917 TREE_CONSTANT (t
) = 1;
4918 TREE_INVARIANT (t
) = 1;
4919 TREE_READONLY (t
) = 1;
4920 TREE_STATIC (t
) = 1;
4922 type
= build_pointer_type (type
);
4923 t
= build1 (ADDR_EXPR
, type
, t
);
4925 type
= build_pointer_type (elem
);
4926 t
= build1 (NOP_EXPR
, type
, t
);
4930 /* Expand EXP, a call to printf or printf_unlocked.
4931 Return 0 if a normal call should be emitted rather than transforming
4932 the function inline. If convenient, the result should be placed in
4933 TARGET with mode MODE. UNLOCKED indicates this is a printf_unlocked
4936 expand_builtin_printf (tree exp
, rtx target
, enum machine_mode mode
,
4939 tree arglist
= TREE_OPERAND (exp
, 1);
4940 /* If we're using an unlocked function, assume the other unlocked
4941 functions exist explicitly. */
4942 tree
const fn_putchar
= unlocked
? built_in_decls
[BUILT_IN_PUTCHAR_UNLOCKED
]
4943 : implicit_built_in_decls
[BUILT_IN_PUTCHAR
];
4944 tree
const fn_puts
= unlocked
? built_in_decls
[BUILT_IN_PUTS_UNLOCKED
]
4945 : implicit_built_in_decls
[BUILT_IN_PUTS
];
4946 const char *fmt_str
;
4949 /* If the return value is used, don't do the transformation. */
4950 if (target
!= const0_rtx
)
4953 /* Verify the required arguments in the original call. */
4956 fmt
= TREE_VALUE (arglist
);
4957 if (! POINTER_TYPE_P (TREE_TYPE (fmt
)))
4959 arglist
= TREE_CHAIN (arglist
);
4961 /* Check whether the format is a literal string constant. */
4962 fmt_str
= c_getstr (fmt
);
4963 if (fmt_str
== NULL
)
4966 if (!init_target_chars())
4969 /* If the format specifier was "%s\n", call __builtin_puts(arg). */
4970 if (strcmp (fmt_str
, target_percent_s_newline
) == 0)
4973 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist
)))
4974 || TREE_CHAIN (arglist
))
4978 /* If the format specifier was "%c", call __builtin_putchar(arg). */
4979 else if (strcmp (fmt_str
, target_percent_c
) == 0)
4982 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist
))) != INTEGER_TYPE
4983 || TREE_CHAIN (arglist
))
4989 /* We can't handle anything else with % args or %% ... yet. */
4990 if (strchr (fmt_str
, target_percent
))
4996 /* If the format specifier was "", printf does nothing. */
4997 if (fmt_str
[0] == '\0')
4999 /* If the format specifier has length of 1, call putchar. */
5000 if (fmt_str
[1] == '\0')
5002 /* Given printf("c"), (where c is any one character,)
5003 convert "c"[0] to an int and pass that to the replacement
5005 arg
= build_int_cst (NULL_TREE
, fmt_str
[0]);
5006 arglist
= build_tree_list (NULL_TREE
, arg
);
5011 /* If the format specifier was "string\n", call puts("string"). */
5012 size_t len
= strlen (fmt_str
);
5013 if ((unsigned char)fmt_str
[len
- 1] == target_newline
)
5015 /* Create a NUL-terminated string that's one char shorter
5016 than the original, stripping off the trailing '\n'. */
5017 char *newstr
= alloca (len
);
5018 memcpy (newstr
, fmt_str
, len
- 1);
5019 newstr
[len
- 1] = 0;
5021 arg
= build_string_literal (len
, newstr
);
5022 arglist
= build_tree_list (NULL_TREE
, arg
);
5026 /* We'd like to arrange to call fputs(string,stdout) here,
5027 but we need stdout and don't have a way to get it yet. */
5034 fn
= build_function_call_expr (fn
, arglist
);
5035 if (TREE_CODE (fn
) == CALL_EXPR
)
5036 CALL_EXPR_TAILCALL (fn
) = CALL_EXPR_TAILCALL (exp
);
5037 return expand_expr (fn
, target
, mode
, EXPAND_NORMAL
);
5040 /* Expand EXP, a call to fprintf or fprintf_unlocked.
5041 Return 0 if a normal call should be emitted rather than transforming
5042 the function inline. If convenient, the result should be placed in
5043 TARGET with mode MODE. UNLOCKED indicates this is a fprintf_unlocked
5046 expand_builtin_fprintf (tree exp
, rtx target
, enum machine_mode mode
,
5049 tree arglist
= TREE_OPERAND (exp
, 1);
5050 /* If we're using an unlocked function, assume the other unlocked
5051 functions exist explicitly. */
5052 tree
const fn_fputc
= unlocked
? built_in_decls
[BUILT_IN_FPUTC_UNLOCKED
]
5053 : implicit_built_in_decls
[BUILT_IN_FPUTC
];
5054 tree
const fn_fputs
= unlocked
? built_in_decls
[BUILT_IN_FPUTS_UNLOCKED
]
5055 : implicit_built_in_decls
[BUILT_IN_FPUTS
];
5056 const char *fmt_str
;
5057 tree fn
, fmt
, fp
, arg
;
5059 /* If the return value is used, don't do the transformation. */
5060 if (target
!= const0_rtx
)
5063 /* Verify the required arguments in the original call. */
5066 fp
= TREE_VALUE (arglist
);
5067 if (! POINTER_TYPE_P (TREE_TYPE (fp
)))
5069 arglist
= TREE_CHAIN (arglist
);
5072 fmt
= TREE_VALUE (arglist
);
5073 if (! POINTER_TYPE_P (TREE_TYPE (fmt
)))
5075 arglist
= TREE_CHAIN (arglist
);
5077 /* Check whether the format is a literal string constant. */
5078 fmt_str
= c_getstr (fmt
);
5079 if (fmt_str
== NULL
)
5082 if (!init_target_chars())
5085 /* If the format specifier was "%s", call __builtin_fputs(arg,fp). */
5086 if (strcmp (fmt_str
, target_percent_s
) == 0)
5089 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist
)))
5090 || TREE_CHAIN (arglist
))
5092 arg
= TREE_VALUE (arglist
);
5093 arglist
= build_tree_list (NULL_TREE
, fp
);
5094 arglist
= tree_cons (NULL_TREE
, arg
, arglist
);
5097 /* If the format specifier was "%c", call __builtin_fputc(arg,fp). */
5098 else if (strcmp (fmt_str
, target_percent_c
) == 0)
5101 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist
))) != INTEGER_TYPE
5102 || TREE_CHAIN (arglist
))
5104 arg
= TREE_VALUE (arglist
);
5105 arglist
= build_tree_list (NULL_TREE
, fp
);
5106 arglist
= tree_cons (NULL_TREE
, arg
, arglist
);
5111 /* We can't handle anything else with % args or %% ... yet. */
5112 if (strchr (fmt_str
, target_percent
))
5118 /* If the format specifier was "", fprintf does nothing. */
5119 if (fmt_str
[0] == '\0')
5121 /* Evaluate and ignore FILE* argument for side-effects. */
5122 expand_expr (fp
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
5126 /* When "string" doesn't contain %, replace all cases of
5127 fprintf(stream,string) with fputs(string,stream). The fputs
5128 builtin will take care of special cases like length == 1. */
5129 arglist
= build_tree_list (NULL_TREE
, fp
);
5130 arglist
= tree_cons (NULL_TREE
, fmt
, arglist
);
5136 fn
= build_function_call_expr (fn
, arglist
);
5137 if (TREE_CODE (fn
) == CALL_EXPR
)
5138 CALL_EXPR_TAILCALL (fn
) = CALL_EXPR_TAILCALL (exp
);
5139 return expand_expr (fn
, target
, mode
, EXPAND_NORMAL
);
5142 /* Expand a call to sprintf with argument list ARGLIST. Return 0 if
5143 a normal call should be emitted rather than expanding the function
5144 inline. If convenient, the result should be placed in TARGET with
5148 expand_builtin_sprintf (tree arglist
, rtx target
, enum machine_mode mode
)
5150 tree orig_arglist
, dest
, fmt
;
5151 const char *fmt_str
;
5153 orig_arglist
= arglist
;
5155 /* Verify the required arguments in the original call. */
5158 dest
= TREE_VALUE (arglist
);
5159 if (! POINTER_TYPE_P (TREE_TYPE (dest
)))
5161 arglist
= TREE_CHAIN (arglist
);
5164 fmt
= TREE_VALUE (arglist
);
5165 if (! POINTER_TYPE_P (TREE_TYPE (fmt
)))
5167 arglist
= TREE_CHAIN (arglist
);
5169 /* Check whether the format is a literal string constant. */
5170 fmt_str
= c_getstr (fmt
);
5171 if (fmt_str
== NULL
)
5174 if (!init_target_chars())
5177 /* If the format doesn't contain % args or %%, use strcpy. */
5178 if (strchr (fmt_str
, target_percent
) == 0)
5180 tree fn
= implicit_built_in_decls
[BUILT_IN_STRCPY
];
5183 if (arglist
|| ! fn
)
5185 expand_expr (build_function_call_expr (fn
, orig_arglist
),
5186 const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
5187 if (target
== const0_rtx
)
5189 exp
= build_int_cst (NULL_TREE
, strlen (fmt_str
));
5190 return expand_expr (exp
, target
, mode
, EXPAND_NORMAL
);
5192 /* If the format is "%s", use strcpy if the result isn't used. */
5193 else if (strcmp (fmt_str
, target_percent_s
) == 0)
5196 fn
= implicit_built_in_decls
[BUILT_IN_STRCPY
];
5201 if (! arglist
|| TREE_CHAIN (arglist
))
5203 arg
= TREE_VALUE (arglist
);
5204 if (! POINTER_TYPE_P (TREE_TYPE (arg
)))
5207 if (target
!= const0_rtx
)
5209 len
= c_strlen (arg
, 1);
5210 if (! len
|| TREE_CODE (len
) != INTEGER_CST
)
5216 arglist
= build_tree_list (NULL_TREE
, arg
);
5217 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
5218 expand_expr (build_function_call_expr (fn
, arglist
),
5219 const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
5221 if (target
== const0_rtx
)
5223 return expand_expr (len
, target
, mode
, EXPAND_NORMAL
);
5229 /* Expand a call to either the entry or exit function profiler. */
5232 expand_builtin_profile_func (bool exitp
)
5236 this = DECL_RTL (current_function_decl
);
5237 gcc_assert (MEM_P (this));
5238 this = XEXP (this, 0);
5241 which
= profile_function_exit_libfunc
;
5243 which
= profile_function_entry_libfunc
;
5245 emit_library_call (which
, LCT_NORMAL
, VOIDmode
, 2, this, Pmode
,
5246 expand_builtin_return_addr (BUILT_IN_RETURN_ADDRESS
,
5253 /* Given a trampoline address, make sure it satisfies TRAMPOLINE_ALIGNMENT. */
5256 round_trampoline_addr (rtx tramp
)
5258 rtx temp
, addend
, mask
;
5260 /* If we don't need too much alignment, we'll have been guaranteed
5261 proper alignment by get_trampoline_type. */
5262 if (TRAMPOLINE_ALIGNMENT
<= STACK_BOUNDARY
)
5265 /* Round address up to desired boundary. */
5266 temp
= gen_reg_rtx (Pmode
);
5267 addend
= GEN_INT (TRAMPOLINE_ALIGNMENT
/ BITS_PER_UNIT
- 1);
5268 mask
= GEN_INT (-TRAMPOLINE_ALIGNMENT
/ BITS_PER_UNIT
);
5270 temp
= expand_simple_binop (Pmode
, PLUS
, tramp
, addend
,
5271 temp
, 0, OPTAB_LIB_WIDEN
);
5272 tramp
= expand_simple_binop (Pmode
, AND
, temp
, mask
,
5273 temp
, 0, OPTAB_LIB_WIDEN
);
5279 expand_builtin_init_trampoline (tree arglist
)
5281 tree t_tramp
, t_func
, t_chain
;
5282 rtx r_tramp
, r_func
, r_chain
;
5283 #ifdef TRAMPOLINE_TEMPLATE
5287 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
,
5288 POINTER_TYPE
, VOID_TYPE
))
5291 t_tramp
= TREE_VALUE (arglist
);
5292 arglist
= TREE_CHAIN (arglist
);
5293 t_func
= TREE_VALUE (arglist
);
5294 arglist
= TREE_CHAIN (arglist
);
5295 t_chain
= TREE_VALUE (arglist
);
5297 r_tramp
= expand_normal (t_tramp
);
5298 r_func
= expand_normal (t_func
);
5299 r_chain
= expand_normal (t_chain
);
5301 /* Generate insns to initialize the trampoline. */
5302 r_tramp
= round_trampoline_addr (r_tramp
);
5303 #ifdef TRAMPOLINE_TEMPLATE
5304 blktramp
= gen_rtx_MEM (BLKmode
, r_tramp
);
5305 set_mem_align (blktramp
, TRAMPOLINE_ALIGNMENT
);
5306 emit_block_move (blktramp
, assemble_trampoline_template (),
5307 GEN_INT (TRAMPOLINE_SIZE
), BLOCK_OP_NORMAL
);
5309 trampolines_created
= 1;
5310 INITIALIZE_TRAMPOLINE (r_tramp
, r_func
, r_chain
);
5316 expand_builtin_adjust_trampoline (tree arglist
)
5320 if (!validate_arglist (arglist
, POINTER_TYPE
, VOID_TYPE
))
5323 tramp
= expand_normal (TREE_VALUE (arglist
));
5324 tramp
= round_trampoline_addr (tramp
);
5325 #ifdef TRAMPOLINE_ADJUST_ADDRESS
5326 TRAMPOLINE_ADJUST_ADDRESS (tramp
);
5332 /* Expand a call to the built-in signbit, signbitf or signbitl function.
5333 Return NULL_RTX if a normal call should be emitted rather than expanding
5334 the function in-line. EXP is the expression that is a call to the builtin
5335 function; if convenient, the result should be placed in TARGET. */
5338 expand_builtin_signbit (tree exp
, rtx target
)
5340 const struct real_format
*fmt
;
5341 enum machine_mode fmode
, imode
, rmode
;
5342 HOST_WIDE_INT hi
, lo
;
5347 arglist
= TREE_OPERAND (exp
, 1);
5348 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
5351 arg
= TREE_VALUE (arglist
);
5352 fmode
= TYPE_MODE (TREE_TYPE (arg
));
5353 rmode
= TYPE_MODE (TREE_TYPE (exp
));
5354 fmt
= REAL_MODE_FORMAT (fmode
);
5356 /* For floating point formats without a sign bit, implement signbit
5358 bitpos
= fmt
->signbit_ro
;
5361 /* But we can't do this if the format supports signed zero. */
5362 if (fmt
->has_signed_zero
&& HONOR_SIGNED_ZEROS (fmode
))
5365 arg
= fold_build2 (LT_EXPR
, TREE_TYPE (exp
), arg
,
5366 build_real (TREE_TYPE (arg
), dconst0
));
5367 return expand_expr (arg
, target
, VOIDmode
, EXPAND_NORMAL
);
5370 temp
= expand_normal (arg
);
5371 if (GET_MODE_SIZE (fmode
) <= UNITS_PER_WORD
)
5373 imode
= int_mode_for_mode (fmode
);
5374 if (imode
== BLKmode
)
5376 temp
= gen_lowpart (imode
, temp
);
5381 /* Handle targets with different FP word orders. */
5382 if (FLOAT_WORDS_BIG_ENDIAN
)
5383 word
= (GET_MODE_BITSIZE (fmode
) - bitpos
) / BITS_PER_WORD
;
5385 word
= bitpos
/ BITS_PER_WORD
;
5386 temp
= operand_subword_force (temp
, word
, fmode
);
5387 bitpos
= bitpos
% BITS_PER_WORD
;
5390 /* Force the intermediate word_mode (or narrower) result into a
5391 register. This avoids attempting to create paradoxical SUBREGs
5392 of floating point modes below. */
5393 temp
= force_reg (imode
, temp
);
5395 /* If the bitpos is within the "result mode" lowpart, the operation
5396 can be implement with a single bitwise AND. Otherwise, we need
5397 a right shift and an AND. */
5399 if (bitpos
< GET_MODE_BITSIZE (rmode
))
5401 if (bitpos
< HOST_BITS_PER_WIDE_INT
)
5404 lo
= (HOST_WIDE_INT
) 1 << bitpos
;
5408 hi
= (HOST_WIDE_INT
) 1 << (bitpos
- HOST_BITS_PER_WIDE_INT
);
5413 temp
= gen_lowpart (rmode
, temp
);
5414 temp
= expand_binop (rmode
, and_optab
, temp
,
5415 immed_double_const (lo
, hi
, rmode
),
5416 NULL_RTX
, 1, OPTAB_LIB_WIDEN
);
5420 /* Perform a logical right shift to place the signbit in the least
5421 significant bit, then truncate the result to the desired mode
5422 and mask just this bit. */
5423 temp
= expand_shift (RSHIFT_EXPR
, imode
, temp
,
5424 build_int_cst (NULL_TREE
, bitpos
), NULL_RTX
, 1);
5425 temp
= gen_lowpart (rmode
, temp
);
5426 temp
= expand_binop (rmode
, and_optab
, temp
, const1_rtx
,
5427 NULL_RTX
, 1, OPTAB_LIB_WIDEN
);
5433 /* Expand fork or exec calls. TARGET is the desired target of the
5434 call. ARGLIST is the list of arguments of the call. FN is the
5435 identificator of the actual function. IGNORE is nonzero if the
5436 value is to be ignored. */
5439 expand_builtin_fork_or_exec (tree fn
, tree arglist
, rtx target
, int ignore
)
5444 /* If we are not profiling, just call the function. */
5445 if (!profile_arc_flag
)
5448 /* Otherwise call the wrapper. This should be equivalent for the rest of
5449 compiler, so the code does not diverge, and the wrapper may run the
5450 code necessary for keeping the profiling sane. */
5452 switch (DECL_FUNCTION_CODE (fn
))
5455 id
= get_identifier ("__gcov_fork");
5458 case BUILT_IN_EXECL
:
5459 id
= get_identifier ("__gcov_execl");
5462 case BUILT_IN_EXECV
:
5463 id
= get_identifier ("__gcov_execv");
5466 case BUILT_IN_EXECLP
:
5467 id
= get_identifier ("__gcov_execlp");
5470 case BUILT_IN_EXECLE
:
5471 id
= get_identifier ("__gcov_execle");
5474 case BUILT_IN_EXECVP
:
5475 id
= get_identifier ("__gcov_execvp");
5478 case BUILT_IN_EXECVE
:
5479 id
= get_identifier ("__gcov_execve");
5486 decl
= build_decl (FUNCTION_DECL
, id
, TREE_TYPE (fn
));
5487 DECL_EXTERNAL (decl
) = 1;
5488 TREE_PUBLIC (decl
) = 1;
5489 DECL_ARTIFICIAL (decl
) = 1;
5490 TREE_NOTHROW (decl
) = 1;
5491 DECL_VISIBILITY (decl
) = VISIBILITY_DEFAULT
;
5492 DECL_VISIBILITY_SPECIFIED (decl
) = 1;
5493 call
= build_function_call_expr (decl
, arglist
);
5495 return expand_call (call
, target
, ignore
);
5499 /* Reconstitute a mode for a __sync intrinsic operation. Since the type of
5500 the pointer in these functions is void*, the tree optimizers may remove
5501 casts. The mode computed in expand_builtin isn't reliable either, due
5502 to __sync_bool_compare_and_swap.
5504 FCODE_DIFF should be fcode - base, where base is the FOO_1 code for the
5505 group of builtins. This gives us log2 of the mode size. */
5507 static inline enum machine_mode
5508 get_builtin_sync_mode (int fcode_diff
)
5510 /* The size is not negotiable, so ask not to get BLKmode in return
5511 if the target indicates that a smaller size would be better. */
5512 return mode_for_size (BITS_PER_UNIT
<< fcode_diff
, MODE_INT
, 0);
5515 /* Expand the memory expression LOC and return the appropriate memory operand
5516 for the builtin_sync operations. */
5519 get_builtin_sync_mem (tree loc
, enum machine_mode mode
)
5523 addr
= expand_expr (loc
, NULL
, Pmode
, EXPAND_SUM
);
5525 /* Note that we explicitly do not want any alias information for this
5526 memory, so that we kill all other live memories. Otherwise we don't
5527 satisfy the full barrier semantics of the intrinsic. */
5528 mem
= validize_mem (gen_rtx_MEM (mode
, addr
));
5530 set_mem_align (mem
, get_pointer_alignment (loc
, BIGGEST_ALIGNMENT
));
5531 set_mem_alias_set (mem
, ALIAS_SET_MEMORY_BARRIER
);
5532 MEM_VOLATILE_P (mem
) = 1;
5537 /* Expand the __sync_xxx_and_fetch and __sync_fetch_and_xxx intrinsics.
5538 ARGLIST is the operands list to the function. CODE is the rtx code
5539 that corresponds to the arithmetic or logical operation from the name;
5540 an exception here is that NOT actually means NAND. TARGET is an optional
5541 place for us to store the results; AFTER is true if this is the
5542 fetch_and_xxx form. IGNORE is true if we don't actually care about
5543 the result of the operation at all. */
5546 expand_builtin_sync_operation (enum machine_mode mode
, tree arglist
,
5547 enum rtx_code code
, bool after
,
5548 rtx target
, bool ignore
)
5552 /* Expand the operands. */
5553 mem
= get_builtin_sync_mem (TREE_VALUE (arglist
), mode
);
5555 arglist
= TREE_CHAIN (arglist
);
5556 val
= expand_expr (TREE_VALUE (arglist
), NULL
, mode
, EXPAND_NORMAL
);
5559 return expand_sync_operation (mem
, val
, code
);
5561 return expand_sync_fetch_operation (mem
, val
, code
, after
, target
);
5564 /* Expand the __sync_val_compare_and_swap and __sync_bool_compare_and_swap
5565 intrinsics. ARGLIST is the operands list to the function. IS_BOOL is
5566 true if this is the boolean form. TARGET is a place for us to store the
5567 results; this is NOT optional if IS_BOOL is true. */
5570 expand_builtin_compare_and_swap (enum machine_mode mode
, tree arglist
,
5571 bool is_bool
, rtx target
)
5573 rtx old_val
, new_val
, mem
;
5575 /* Expand the operands. */
5576 mem
= get_builtin_sync_mem (TREE_VALUE (arglist
), mode
);
5578 arglist
= TREE_CHAIN (arglist
);
5579 old_val
= expand_expr (TREE_VALUE (arglist
), NULL
, mode
, EXPAND_NORMAL
);
5581 arglist
= TREE_CHAIN (arglist
);
5582 new_val
= expand_expr (TREE_VALUE (arglist
), NULL
, mode
, EXPAND_NORMAL
);
5585 return expand_bool_compare_and_swap (mem
, old_val
, new_val
, target
);
5587 return expand_val_compare_and_swap (mem
, old_val
, new_val
, target
);
5590 /* Expand the __sync_lock_test_and_set intrinsic. Note that the most
5591 general form is actually an atomic exchange, and some targets only
5592 support a reduced form with the second argument being a constant 1.
5593 ARGLIST is the operands list to the function; TARGET is an optional
5594 place for us to store the results. */
5597 expand_builtin_lock_test_and_set (enum machine_mode mode
, tree arglist
,
5602 /* Expand the operands. */
5603 mem
= get_builtin_sync_mem (TREE_VALUE (arglist
), mode
);
5605 arglist
= TREE_CHAIN (arglist
);
5606 val
= expand_expr (TREE_VALUE (arglist
), NULL
, mode
, EXPAND_NORMAL
);
5608 return expand_sync_lock_test_and_set (mem
, val
, target
);
5611 /* Expand the __sync_synchronize intrinsic. */
5614 expand_builtin_synchronize (void)
5618 #ifdef HAVE_memory_barrier
5619 if (HAVE_memory_barrier
)
5621 emit_insn (gen_memory_barrier ());
5626 /* If no explicit memory barrier instruction is available, create an
5627 empty asm stmt with a memory clobber. */
5628 x
= build4 (ASM_EXPR
, void_type_node
, build_string (0, ""), NULL
, NULL
,
5629 tree_cons (NULL
, build_string (6, "memory"), NULL
));
5630 ASM_VOLATILE_P (x
) = 1;
5631 expand_asm_expr (x
);
5634 /* Expand the __sync_lock_release intrinsic. ARGLIST is the operands list
5638 expand_builtin_lock_release (enum machine_mode mode
, tree arglist
)
5640 enum insn_code icode
;
5642 rtx val
= const0_rtx
;
5644 /* Expand the operands. */
5645 mem
= get_builtin_sync_mem (TREE_VALUE (arglist
), mode
);
5647 /* If there is an explicit operation in the md file, use it. */
5648 icode
= sync_lock_release
[mode
];
5649 if (icode
!= CODE_FOR_nothing
)
5651 if (!insn_data
[icode
].operand
[1].predicate (val
, mode
))
5652 val
= force_reg (mode
, val
);
5654 insn
= GEN_FCN (icode
) (mem
, val
);
5662 /* Otherwise we can implement this operation by emitting a barrier
5663 followed by a store of zero. */
5664 expand_builtin_synchronize ();
5665 emit_move_insn (mem
, val
);
5668 /* Expand an expression EXP that calls a built-in function,
5669 with result going to TARGET if that's convenient
5670 (and in mode MODE if that's convenient).
5671 SUBTARGET may be used as the target for computing one of EXP's operands.
5672 IGNORE is nonzero if the value is to be ignored. */
5675 expand_builtin (tree exp
, rtx target
, rtx subtarget
, enum machine_mode mode
,
5678 tree fndecl
= get_callee_fndecl (exp
);
5679 tree arglist
= TREE_OPERAND (exp
, 1);
5680 enum built_in_function fcode
= DECL_FUNCTION_CODE (fndecl
);
5681 enum machine_mode target_mode
= TYPE_MODE (TREE_TYPE (exp
));
5683 if (DECL_BUILT_IN_CLASS (fndecl
) == BUILT_IN_MD
)
5684 return targetm
.expand_builtin (exp
, target
, subtarget
, mode
, ignore
);
5686 /* When not optimizing, generate calls to library functions for a certain
5689 && !called_as_built_in (fndecl
)
5690 && DECL_ASSEMBLER_NAME_SET_P (fndecl
)
5691 && fcode
!= BUILT_IN_ALLOCA
)
5692 return expand_call (exp
, target
, ignore
);
5694 /* The built-in function expanders test for target == const0_rtx
5695 to determine whether the function's result will be ignored. */
5697 target
= const0_rtx
;
5699 /* If the result of a pure or const built-in function is ignored, and
5700 none of its arguments are volatile, we can avoid expanding the
5701 built-in call and just evaluate the arguments for side-effects. */
5702 if (target
== const0_rtx
5703 && (DECL_IS_PURE (fndecl
) || TREE_READONLY (fndecl
)))
5705 bool volatilep
= false;
5708 for (arg
= arglist
; arg
; arg
= TREE_CHAIN (arg
))
5709 if (TREE_THIS_VOLATILE (TREE_VALUE (arg
)))
5717 for (arg
= arglist
; arg
; arg
= TREE_CHAIN (arg
))
5718 expand_expr (TREE_VALUE (arg
), const0_rtx
,
5719 VOIDmode
, EXPAND_NORMAL
);
5726 CASE_FLT_FN (BUILT_IN_FABS
):
5727 target
= expand_builtin_fabs (arglist
, target
, subtarget
);
5732 CASE_FLT_FN (BUILT_IN_COPYSIGN
):
5733 target
= expand_builtin_copysign (arglist
, target
, subtarget
);
5738 /* Just do a normal library call if we were unable to fold
5740 CASE_FLT_FN (BUILT_IN_CABS
):
5743 CASE_FLT_FN (BUILT_IN_EXP
):
5744 CASE_FLT_FN (BUILT_IN_EXP10
):
5745 CASE_FLT_FN (BUILT_IN_POW10
):
5746 CASE_FLT_FN (BUILT_IN_EXP2
):
5747 CASE_FLT_FN (BUILT_IN_EXPM1
):
5748 CASE_FLT_FN (BUILT_IN_LOGB
):
5749 CASE_FLT_FN (BUILT_IN_ILOGB
):
5750 CASE_FLT_FN (BUILT_IN_LOG
):
5751 CASE_FLT_FN (BUILT_IN_LOG10
):
5752 CASE_FLT_FN (BUILT_IN_LOG2
):
5753 CASE_FLT_FN (BUILT_IN_LOG1P
):
5754 CASE_FLT_FN (BUILT_IN_TAN
):
5755 CASE_FLT_FN (BUILT_IN_ASIN
):
5756 CASE_FLT_FN (BUILT_IN_ACOS
):
5757 CASE_FLT_FN (BUILT_IN_ATAN
):
5758 /* Treat these like sqrt only if unsafe math optimizations are allowed,
5759 because of possible accuracy problems. */
5760 if (! flag_unsafe_math_optimizations
)
5762 CASE_FLT_FN (BUILT_IN_SQRT
):
5763 CASE_FLT_FN (BUILT_IN_FLOOR
):
5764 CASE_FLT_FN (BUILT_IN_CEIL
):
5765 CASE_FLT_FN (BUILT_IN_TRUNC
):
5766 CASE_FLT_FN (BUILT_IN_ROUND
):
5767 CASE_FLT_FN (BUILT_IN_NEARBYINT
):
5768 CASE_FLT_FN (BUILT_IN_RINT
):
5769 CASE_FLT_FN (BUILT_IN_LRINT
):
5770 CASE_FLT_FN (BUILT_IN_LLRINT
):
5771 target
= expand_builtin_mathfn (exp
, target
, subtarget
);
5776 CASE_FLT_FN (BUILT_IN_LCEIL
):
5777 CASE_FLT_FN (BUILT_IN_LLCEIL
):
5778 CASE_FLT_FN (BUILT_IN_LFLOOR
):
5779 CASE_FLT_FN (BUILT_IN_LLFLOOR
):
5780 target
= expand_builtin_int_roundingfn (exp
, target
, subtarget
);
5785 CASE_FLT_FN (BUILT_IN_POW
):
5786 target
= expand_builtin_pow (exp
, target
, subtarget
);
5791 CASE_FLT_FN (BUILT_IN_POWI
):
5792 target
= expand_builtin_powi (exp
, target
, subtarget
);
5797 CASE_FLT_FN (BUILT_IN_ATAN2
):
5798 CASE_FLT_FN (BUILT_IN_LDEXP
):
5799 CASE_FLT_FN (BUILT_IN_FMOD
):
5800 CASE_FLT_FN (BUILT_IN_DREM
):
5801 if (! flag_unsafe_math_optimizations
)
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 target
= expand_builtin_setjmp (arglist
, target
);
6085 /* __builtin_longjmp is passed a pointer to an array of five words.
6086 It's similar to the C library longjmp function but works with
6087 __builtin_setjmp above. */
6088 case BUILT_IN_LONGJMP
:
6089 if (!validate_arglist (arglist
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
6093 rtx buf_addr
= expand_expr (TREE_VALUE (arglist
), subtarget
,
6094 VOIDmode
, EXPAND_NORMAL
);
6095 rtx value
= expand_normal (TREE_VALUE (TREE_CHAIN (arglist
)));
6097 if (value
!= const1_rtx
)
6099 error ("%<__builtin_longjmp%> second argument must be 1");
6103 expand_builtin_longjmp (buf_addr
, value
);
6107 case BUILT_IN_NONLOCAL_GOTO
:
6108 target
= expand_builtin_nonlocal_goto (arglist
);
6113 /* This updates the setjmp buffer that is its argument with the value
6114 of the current stack pointer. */
6115 case BUILT_IN_UPDATE_SETJMP_BUF
:
6116 if (validate_arglist (arglist
, POINTER_TYPE
, VOID_TYPE
))
6119 = expand_normal (TREE_VALUE (arglist
));
6121 expand_builtin_update_setjmp_buf (buf_addr
);
6127 expand_builtin_trap ();
6130 case BUILT_IN_PRINTF
:
6131 target
= expand_builtin_printf (exp
, target
, mode
, false);
6136 case BUILT_IN_PRINTF_UNLOCKED
:
6137 target
= expand_builtin_printf (exp
, target
, mode
, true);
6142 case BUILT_IN_FPUTS
:
6143 target
= expand_builtin_fputs (arglist
, target
, false);
6147 case BUILT_IN_FPUTS_UNLOCKED
:
6148 target
= expand_builtin_fputs (arglist
, target
, true);
6153 case BUILT_IN_FPRINTF
:
6154 target
= expand_builtin_fprintf (exp
, target
, mode
, false);
6159 case BUILT_IN_FPRINTF_UNLOCKED
:
6160 target
= expand_builtin_fprintf (exp
, target
, mode
, true);
6165 case BUILT_IN_SPRINTF
:
6166 target
= expand_builtin_sprintf (arglist
, target
, mode
);
6171 CASE_FLT_FN (BUILT_IN_SIGNBIT
):
6172 target
= expand_builtin_signbit (exp
, target
);
6177 /* Various hooks for the DWARF 2 __throw routine. */
6178 case BUILT_IN_UNWIND_INIT
:
6179 expand_builtin_unwind_init ();
6181 case BUILT_IN_DWARF_CFA
:
6182 return virtual_cfa_rtx
;
6183 #ifdef DWARF2_UNWIND_INFO
6184 case BUILT_IN_DWARF_SP_COLUMN
:
6185 return expand_builtin_dwarf_sp_column ();
6186 case BUILT_IN_INIT_DWARF_REG_SIZES
:
6187 expand_builtin_init_dwarf_reg_sizes (TREE_VALUE (arglist
));
6190 case BUILT_IN_FROB_RETURN_ADDR
:
6191 return expand_builtin_frob_return_addr (TREE_VALUE (arglist
));
6192 case BUILT_IN_EXTRACT_RETURN_ADDR
:
6193 return expand_builtin_extract_return_addr (TREE_VALUE (arglist
));
6194 case BUILT_IN_EH_RETURN
:
6195 expand_builtin_eh_return (TREE_VALUE (arglist
),
6196 TREE_VALUE (TREE_CHAIN (arglist
)));
6198 #ifdef EH_RETURN_DATA_REGNO
6199 case BUILT_IN_EH_RETURN_DATA_REGNO
:
6200 return expand_builtin_eh_return_data_regno (arglist
);
6202 case BUILT_IN_EXTEND_POINTER
:
6203 return expand_builtin_extend_pointer (TREE_VALUE (arglist
));
6205 case BUILT_IN_VA_START
:
6206 case BUILT_IN_STDARG_START
:
6207 return expand_builtin_va_start (arglist
);
6208 case BUILT_IN_VA_END
:
6209 return expand_builtin_va_end (arglist
);
6210 case BUILT_IN_VA_COPY
:
6211 return expand_builtin_va_copy (arglist
);
6212 case BUILT_IN_EXPECT
:
6213 return expand_builtin_expect (arglist
, target
);
6214 case BUILT_IN_PREFETCH
:
6215 expand_builtin_prefetch (arglist
);
6218 case BUILT_IN_PROFILE_FUNC_ENTER
:
6219 return expand_builtin_profile_func (false);
6220 case BUILT_IN_PROFILE_FUNC_EXIT
:
6221 return expand_builtin_profile_func (true);
6223 case BUILT_IN_INIT_TRAMPOLINE
:
6224 return expand_builtin_init_trampoline (arglist
);
6225 case BUILT_IN_ADJUST_TRAMPOLINE
:
6226 return expand_builtin_adjust_trampoline (arglist
);
6229 case BUILT_IN_EXECL
:
6230 case BUILT_IN_EXECV
:
6231 case BUILT_IN_EXECLP
:
6232 case BUILT_IN_EXECLE
:
6233 case BUILT_IN_EXECVP
:
6234 case BUILT_IN_EXECVE
:
6235 target
= expand_builtin_fork_or_exec (fndecl
, arglist
, target
, ignore
);
6240 case BUILT_IN_FETCH_AND_ADD_1
:
6241 case BUILT_IN_FETCH_AND_ADD_2
:
6242 case BUILT_IN_FETCH_AND_ADD_4
:
6243 case BUILT_IN_FETCH_AND_ADD_8
:
6244 case BUILT_IN_FETCH_AND_ADD_16
:
6245 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_FETCH_AND_ADD_1
);
6246 target
= expand_builtin_sync_operation (mode
, arglist
, PLUS
,
6247 false, target
, ignore
);
6252 case BUILT_IN_FETCH_AND_SUB_1
:
6253 case BUILT_IN_FETCH_AND_SUB_2
:
6254 case BUILT_IN_FETCH_AND_SUB_4
:
6255 case BUILT_IN_FETCH_AND_SUB_8
:
6256 case BUILT_IN_FETCH_AND_SUB_16
:
6257 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_FETCH_AND_SUB_1
);
6258 target
= expand_builtin_sync_operation (mode
, arglist
, MINUS
,
6259 false, target
, ignore
);
6264 case BUILT_IN_FETCH_AND_OR_1
:
6265 case BUILT_IN_FETCH_AND_OR_2
:
6266 case BUILT_IN_FETCH_AND_OR_4
:
6267 case BUILT_IN_FETCH_AND_OR_8
:
6268 case BUILT_IN_FETCH_AND_OR_16
:
6269 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_FETCH_AND_OR_1
);
6270 target
= expand_builtin_sync_operation (mode
, arglist
, IOR
,
6271 false, target
, ignore
);
6276 case BUILT_IN_FETCH_AND_AND_1
:
6277 case BUILT_IN_FETCH_AND_AND_2
:
6278 case BUILT_IN_FETCH_AND_AND_4
:
6279 case BUILT_IN_FETCH_AND_AND_8
:
6280 case BUILT_IN_FETCH_AND_AND_16
:
6281 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_FETCH_AND_AND_1
);
6282 target
= expand_builtin_sync_operation (mode
, arglist
, AND
,
6283 false, target
, ignore
);
6288 case BUILT_IN_FETCH_AND_XOR_1
:
6289 case BUILT_IN_FETCH_AND_XOR_2
:
6290 case BUILT_IN_FETCH_AND_XOR_4
:
6291 case BUILT_IN_FETCH_AND_XOR_8
:
6292 case BUILT_IN_FETCH_AND_XOR_16
:
6293 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_FETCH_AND_XOR_1
);
6294 target
= expand_builtin_sync_operation (mode
, arglist
, XOR
,
6295 false, target
, ignore
);
6300 case BUILT_IN_FETCH_AND_NAND_1
:
6301 case BUILT_IN_FETCH_AND_NAND_2
:
6302 case BUILT_IN_FETCH_AND_NAND_4
:
6303 case BUILT_IN_FETCH_AND_NAND_8
:
6304 case BUILT_IN_FETCH_AND_NAND_16
:
6305 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_FETCH_AND_NAND_1
);
6306 target
= expand_builtin_sync_operation (mode
, arglist
, NOT
,
6307 false, target
, ignore
);
6312 case BUILT_IN_ADD_AND_FETCH_1
:
6313 case BUILT_IN_ADD_AND_FETCH_2
:
6314 case BUILT_IN_ADD_AND_FETCH_4
:
6315 case BUILT_IN_ADD_AND_FETCH_8
:
6316 case BUILT_IN_ADD_AND_FETCH_16
:
6317 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_ADD_AND_FETCH_1
);
6318 target
= expand_builtin_sync_operation (mode
, arglist
, PLUS
,
6319 true, target
, ignore
);
6324 case BUILT_IN_SUB_AND_FETCH_1
:
6325 case BUILT_IN_SUB_AND_FETCH_2
:
6326 case BUILT_IN_SUB_AND_FETCH_4
:
6327 case BUILT_IN_SUB_AND_FETCH_8
:
6328 case BUILT_IN_SUB_AND_FETCH_16
:
6329 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_SUB_AND_FETCH_1
);
6330 target
= expand_builtin_sync_operation (mode
, arglist
, MINUS
,
6331 true, target
, ignore
);
6336 case BUILT_IN_OR_AND_FETCH_1
:
6337 case BUILT_IN_OR_AND_FETCH_2
:
6338 case BUILT_IN_OR_AND_FETCH_4
:
6339 case BUILT_IN_OR_AND_FETCH_8
:
6340 case BUILT_IN_OR_AND_FETCH_16
:
6341 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_OR_AND_FETCH_1
);
6342 target
= expand_builtin_sync_operation (mode
, arglist
, IOR
,
6343 true, target
, ignore
);
6348 case BUILT_IN_AND_AND_FETCH_1
:
6349 case BUILT_IN_AND_AND_FETCH_2
:
6350 case BUILT_IN_AND_AND_FETCH_4
:
6351 case BUILT_IN_AND_AND_FETCH_8
:
6352 case BUILT_IN_AND_AND_FETCH_16
:
6353 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_AND_AND_FETCH_1
);
6354 target
= expand_builtin_sync_operation (mode
, arglist
, AND
,
6355 true, target
, ignore
);
6360 case BUILT_IN_XOR_AND_FETCH_1
:
6361 case BUILT_IN_XOR_AND_FETCH_2
:
6362 case BUILT_IN_XOR_AND_FETCH_4
:
6363 case BUILT_IN_XOR_AND_FETCH_8
:
6364 case BUILT_IN_XOR_AND_FETCH_16
:
6365 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_XOR_AND_FETCH_1
);
6366 target
= expand_builtin_sync_operation (mode
, arglist
, XOR
,
6367 true, target
, ignore
);
6372 case BUILT_IN_NAND_AND_FETCH_1
:
6373 case BUILT_IN_NAND_AND_FETCH_2
:
6374 case BUILT_IN_NAND_AND_FETCH_4
:
6375 case BUILT_IN_NAND_AND_FETCH_8
:
6376 case BUILT_IN_NAND_AND_FETCH_16
:
6377 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_NAND_AND_FETCH_1
);
6378 target
= expand_builtin_sync_operation (mode
, arglist
, NOT
,
6379 true, target
, ignore
);
6384 case BUILT_IN_BOOL_COMPARE_AND_SWAP_1
:
6385 case BUILT_IN_BOOL_COMPARE_AND_SWAP_2
:
6386 case BUILT_IN_BOOL_COMPARE_AND_SWAP_4
:
6387 case BUILT_IN_BOOL_COMPARE_AND_SWAP_8
:
6388 case BUILT_IN_BOOL_COMPARE_AND_SWAP_16
:
6389 if (mode
== VOIDmode
)
6390 mode
= TYPE_MODE (boolean_type_node
);
6391 if (!target
|| !register_operand (target
, mode
))
6392 target
= gen_reg_rtx (mode
);
6394 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_BOOL_COMPARE_AND_SWAP_1
);
6395 target
= expand_builtin_compare_and_swap (mode
, arglist
, true, target
);
6400 case BUILT_IN_VAL_COMPARE_AND_SWAP_1
:
6401 case BUILT_IN_VAL_COMPARE_AND_SWAP_2
:
6402 case BUILT_IN_VAL_COMPARE_AND_SWAP_4
:
6403 case BUILT_IN_VAL_COMPARE_AND_SWAP_8
:
6404 case BUILT_IN_VAL_COMPARE_AND_SWAP_16
:
6405 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_VAL_COMPARE_AND_SWAP_1
);
6406 target
= expand_builtin_compare_and_swap (mode
, arglist
, false, target
);
6411 case BUILT_IN_LOCK_TEST_AND_SET_1
:
6412 case BUILT_IN_LOCK_TEST_AND_SET_2
:
6413 case BUILT_IN_LOCK_TEST_AND_SET_4
:
6414 case BUILT_IN_LOCK_TEST_AND_SET_8
:
6415 case BUILT_IN_LOCK_TEST_AND_SET_16
:
6416 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_LOCK_TEST_AND_SET_1
);
6417 target
= expand_builtin_lock_test_and_set (mode
, arglist
, target
);
6422 case BUILT_IN_LOCK_RELEASE_1
:
6423 case BUILT_IN_LOCK_RELEASE_2
:
6424 case BUILT_IN_LOCK_RELEASE_4
:
6425 case BUILT_IN_LOCK_RELEASE_8
:
6426 case BUILT_IN_LOCK_RELEASE_16
:
6427 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_LOCK_RELEASE_1
);
6428 expand_builtin_lock_release (mode
, arglist
);
6431 case BUILT_IN_SYNCHRONIZE
:
6432 expand_builtin_synchronize ();
6435 case BUILT_IN_OBJECT_SIZE
:
6436 return expand_builtin_object_size (exp
);
6438 case BUILT_IN_MEMCPY_CHK
:
6439 case BUILT_IN_MEMPCPY_CHK
:
6440 case BUILT_IN_MEMMOVE_CHK
:
6441 case BUILT_IN_MEMSET_CHK
:
6442 target
= expand_builtin_memory_chk (exp
, target
, mode
, fcode
);
6447 case BUILT_IN_STRCPY_CHK
:
6448 case BUILT_IN_STPCPY_CHK
:
6449 case BUILT_IN_STRNCPY_CHK
:
6450 case BUILT_IN_STRCAT_CHK
:
6451 case BUILT_IN_SNPRINTF_CHK
:
6452 case BUILT_IN_VSNPRINTF_CHK
:
6453 maybe_emit_chk_warning (exp
, fcode
);
6456 case BUILT_IN_SPRINTF_CHK
:
6457 case BUILT_IN_VSPRINTF_CHK
:
6458 maybe_emit_sprintf_chk_warning (exp
, fcode
);
6461 default: /* just do library call, if unknown builtin */
6465 /* The switch statement above can drop through to cause the function
6466 to be called normally. */
6467 return expand_call (exp
, target
, ignore
);
6470 /* Determine whether a tree node represents a call to a built-in
6471 function. If the tree T is a call to a built-in function with
6472 the right number of arguments of the appropriate types, return
6473 the DECL_FUNCTION_CODE of the call, e.g. BUILT_IN_SQRT.
6474 Otherwise the return value is END_BUILTINS. */
6476 enum built_in_function
6477 builtin_mathfn_code (tree t
)
6479 tree fndecl
, arglist
, parmlist
;
6480 tree argtype
, parmtype
;
6482 if (TREE_CODE (t
) != CALL_EXPR
6483 || TREE_CODE (TREE_OPERAND (t
, 0)) != ADDR_EXPR
)
6484 return END_BUILTINS
;
6486 fndecl
= get_callee_fndecl (t
);
6487 if (fndecl
== NULL_TREE
6488 || TREE_CODE (fndecl
) != FUNCTION_DECL
6489 || ! DECL_BUILT_IN (fndecl
)
6490 || DECL_BUILT_IN_CLASS (fndecl
) == BUILT_IN_MD
)
6491 return END_BUILTINS
;
6493 arglist
= TREE_OPERAND (t
, 1);
6494 parmlist
= TYPE_ARG_TYPES (TREE_TYPE (fndecl
));
6495 for (; parmlist
; parmlist
= TREE_CHAIN (parmlist
))
6497 /* If a function doesn't take a variable number of arguments,
6498 the last element in the list will have type `void'. */
6499 parmtype
= TREE_VALUE (parmlist
);
6500 if (VOID_TYPE_P (parmtype
))
6503 return END_BUILTINS
;
6504 return DECL_FUNCTION_CODE (fndecl
);
6508 return END_BUILTINS
;
6510 argtype
= TREE_TYPE (TREE_VALUE (arglist
));
6512 if (SCALAR_FLOAT_TYPE_P (parmtype
))
6514 if (! SCALAR_FLOAT_TYPE_P (argtype
))
6515 return END_BUILTINS
;
6517 else if (COMPLEX_FLOAT_TYPE_P (parmtype
))
6519 if (! COMPLEX_FLOAT_TYPE_P (argtype
))
6520 return END_BUILTINS
;
6522 else if (POINTER_TYPE_P (parmtype
))
6524 if (! POINTER_TYPE_P (argtype
))
6525 return END_BUILTINS
;
6527 else if (INTEGRAL_TYPE_P (parmtype
))
6529 if (! INTEGRAL_TYPE_P (argtype
))
6530 return END_BUILTINS
;
6533 return END_BUILTINS
;
6535 arglist
= TREE_CHAIN (arglist
);
6538 /* Variable-length argument list. */
6539 return DECL_FUNCTION_CODE (fndecl
);
6542 /* Fold a call to __builtin_constant_p, if we know it will evaluate to a
6543 constant. ARGLIST is the argument list of the call. */
6546 fold_builtin_constant_p (tree arglist
)
6551 arglist
= TREE_VALUE (arglist
);
6553 /* We return 1 for a numeric type that's known to be a constant
6554 value at compile-time or for an aggregate type that's a
6555 literal constant. */
6556 STRIP_NOPS (arglist
);
6558 /* If we know this is a constant, emit the constant of one. */
6559 if (CONSTANT_CLASS_P (arglist
)
6560 || (TREE_CODE (arglist
) == CONSTRUCTOR
6561 && TREE_CONSTANT (arglist
)))
6562 return integer_one_node
;
6563 if (TREE_CODE (arglist
) == ADDR_EXPR
)
6565 tree op
= TREE_OPERAND (arglist
, 0);
6566 if (TREE_CODE (op
) == STRING_CST
6567 || (TREE_CODE (op
) == ARRAY_REF
6568 && integer_zerop (TREE_OPERAND (op
, 1))
6569 && TREE_CODE (TREE_OPERAND (op
, 0)) == STRING_CST
))
6570 return integer_one_node
;
6573 /* If this expression has side effects, show we don't know it to be a
6574 constant. Likewise if it's a pointer or aggregate type since in
6575 those case we only want literals, since those are only optimized
6576 when generating RTL, not later.
6577 And finally, if we are compiling an initializer, not code, we
6578 need to return a definite result now; there's not going to be any
6579 more optimization done. */
6580 if (TREE_SIDE_EFFECTS (arglist
)
6581 || AGGREGATE_TYPE_P (TREE_TYPE (arglist
))
6582 || POINTER_TYPE_P (TREE_TYPE (arglist
))
6584 || folding_initializer
)
6585 return integer_zero_node
;
6590 /* Fold a call to __builtin_expect, if we expect that a comparison against
6591 the argument will fold to a constant. In practice, this means a true
6592 constant or the address of a non-weak symbol. ARGLIST is the argument
6593 list of the call. */
6596 fold_builtin_expect (tree arglist
)
6603 arg
= TREE_VALUE (arglist
);
6605 /* If the argument isn't invariant, then there's nothing we can do. */
6606 if (!TREE_INVARIANT (arg
))
6609 /* If we're looking at an address of a weak decl, then do not fold. */
6612 if (TREE_CODE (inner
) == ADDR_EXPR
)
6616 inner
= TREE_OPERAND (inner
, 0);
6618 while (TREE_CODE (inner
) == COMPONENT_REF
6619 || TREE_CODE (inner
) == ARRAY_REF
);
6620 if (DECL_P (inner
) && DECL_WEAK (inner
))
6624 /* Otherwise, ARG already has the proper type for the return value. */
6628 /* Fold a call to __builtin_classify_type. */
6631 fold_builtin_classify_type (tree arglist
)
6634 return build_int_cst (NULL_TREE
, no_type_class
);
6636 return build_int_cst (NULL_TREE
,
6637 type_to_class (TREE_TYPE (TREE_VALUE (arglist
))));
6640 /* Fold a call to __builtin_strlen. */
6643 fold_builtin_strlen (tree arglist
)
6645 if (!validate_arglist (arglist
, POINTER_TYPE
, VOID_TYPE
))
6649 tree len
= c_strlen (TREE_VALUE (arglist
), 0);
6653 /* Convert from the internal "sizetype" type to "size_t". */
6655 len
= fold_convert (size_type_node
, len
);
6663 /* Fold a call to __builtin_inf or __builtin_huge_val. */
6666 fold_builtin_inf (tree type
, int warn
)
6668 REAL_VALUE_TYPE real
;
6670 /* __builtin_inff is intended to be usable to define INFINITY on all
6671 targets. If an infinity is not available, INFINITY expands "to a
6672 positive constant of type float that overflows at translation
6673 time", footnote "In this case, using INFINITY will violate the
6674 constraint in 6.4.4 and thus require a diagnostic." (C99 7.12#4).
6675 Thus we pedwarn to ensure this constraint violation is
6677 if (!MODE_HAS_INFINITIES (TYPE_MODE (type
)) && warn
)
6678 pedwarn ("target format does not support infinity");
6681 return build_real (type
, real
);
6684 /* Fold a call to __builtin_nan or __builtin_nans. */
6687 fold_builtin_nan (tree arglist
, tree type
, int quiet
)
6689 REAL_VALUE_TYPE real
;
6692 if (!validate_arglist (arglist
, POINTER_TYPE
, VOID_TYPE
))
6694 str
= c_getstr (TREE_VALUE (arglist
));
6698 if (!real_nan (&real
, str
, quiet
, TYPE_MODE (type
)))
6701 return build_real (type
, real
);
6704 /* Return true if the floating point expression T has an integer value.
6705 We also allow +Inf, -Inf and NaN to be considered integer values. */
6708 integer_valued_real_p (tree t
)
6710 switch (TREE_CODE (t
))
6717 case NON_LVALUE_EXPR
:
6718 return integer_valued_real_p (TREE_OPERAND (t
, 0));
6723 return integer_valued_real_p (TREE_OPERAND (t
, 1));
6730 return integer_valued_real_p (TREE_OPERAND (t
, 0))
6731 && integer_valued_real_p (TREE_OPERAND (t
, 1));
6734 return integer_valued_real_p (TREE_OPERAND (t
, 1))
6735 && integer_valued_real_p (TREE_OPERAND (t
, 2));
6738 if (! TREE_CONSTANT_OVERFLOW (t
))
6740 REAL_VALUE_TYPE c
, cint
;
6742 c
= TREE_REAL_CST (t
);
6743 real_trunc (&cint
, TYPE_MODE (TREE_TYPE (t
)), &c
);
6744 return real_identical (&c
, &cint
);
6750 tree type
= TREE_TYPE (TREE_OPERAND (t
, 0));
6751 if (TREE_CODE (type
) == INTEGER_TYPE
)
6753 if (TREE_CODE (type
) == REAL_TYPE
)
6754 return integer_valued_real_p (TREE_OPERAND (t
, 0));
6759 switch (builtin_mathfn_code (t
))
6761 CASE_FLT_FN (BUILT_IN_CEIL
):
6762 CASE_FLT_FN (BUILT_IN_FLOOR
):
6763 CASE_FLT_FN (BUILT_IN_NEARBYINT
):
6764 CASE_FLT_FN (BUILT_IN_RINT
):
6765 CASE_FLT_FN (BUILT_IN_ROUND
):
6766 CASE_FLT_FN (BUILT_IN_TRUNC
):
6780 /* EXP is assumed to be builtin call where truncation can be propagated
6781 across (for instance floor((double)f) == (double)floorf (f).
6782 Do the transformation. */
6785 fold_trunc_transparent_mathfn (tree fndecl
, tree arglist
)
6787 enum built_in_function fcode
= DECL_FUNCTION_CODE (fndecl
);
6790 if (! validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
6793 arg
= TREE_VALUE (arglist
);
6794 /* Integer rounding functions are idempotent. */
6795 if (fcode
== builtin_mathfn_code (arg
))
6798 /* If argument is already integer valued, and we don't need to worry
6799 about setting errno, there's no need to perform rounding. */
6800 if (! flag_errno_math
&& integer_valued_real_p (arg
))
6805 tree arg0
= strip_float_extensions (arg
);
6806 tree ftype
= TREE_TYPE (TREE_TYPE (fndecl
));
6807 tree newtype
= TREE_TYPE (arg0
);
6810 if (TYPE_PRECISION (newtype
) < TYPE_PRECISION (ftype
)
6811 && (decl
= mathfn_built_in (newtype
, fcode
)))
6814 build_tree_list (NULL_TREE
, fold_convert (newtype
, arg0
));
6815 return fold_convert (ftype
,
6816 build_function_call_expr (decl
, arglist
));
6822 /* EXP is assumed to be builtin call which can narrow the FP type of
6823 the argument, for instance lround((double)f) -> lroundf (f). */
6826 fold_fixed_mathfn (tree fndecl
, tree arglist
)
6828 enum built_in_function fcode
= DECL_FUNCTION_CODE (fndecl
);
6831 if (! validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
6834 arg
= TREE_VALUE (arglist
);
6836 /* If argument is already integer valued, and we don't need to worry
6837 about setting errno, there's no need to perform rounding. */
6838 if (! flag_errno_math
&& integer_valued_real_p (arg
))
6839 return fold_build1 (FIX_TRUNC_EXPR
, TREE_TYPE (TREE_TYPE (fndecl
)), arg
);
6843 tree ftype
= TREE_TYPE (arg
);
6844 tree arg0
= strip_float_extensions (arg
);
6845 tree newtype
= TREE_TYPE (arg0
);
6848 if (TYPE_PRECISION (newtype
) < TYPE_PRECISION (ftype
)
6849 && (decl
= mathfn_built_in (newtype
, fcode
)))
6852 build_tree_list (NULL_TREE
, fold_convert (newtype
, arg0
));
6853 return build_function_call_expr (decl
, arglist
);
6857 /* Canonicalize llround (x) to lround (x) on LP64 targets where
6858 sizeof (long long) == sizeof (long). */
6859 if (TYPE_PRECISION (long_long_integer_type_node
)
6860 == TYPE_PRECISION (long_integer_type_node
))
6862 tree newfn
= NULL_TREE
;
6865 CASE_FLT_FN (BUILT_IN_LLCEIL
):
6866 newfn
= mathfn_built_in (TREE_TYPE (arg
), BUILT_IN_LCEIL
);
6869 CASE_FLT_FN (BUILT_IN_LLFLOOR
):
6870 newfn
= mathfn_built_in (TREE_TYPE (arg
), BUILT_IN_LFLOOR
);
6873 CASE_FLT_FN (BUILT_IN_LLROUND
):
6874 newfn
= mathfn_built_in (TREE_TYPE (arg
), BUILT_IN_LROUND
);
6877 CASE_FLT_FN (BUILT_IN_LLRINT
):
6878 newfn
= mathfn_built_in (TREE_TYPE (arg
), BUILT_IN_LRINT
);
6887 tree newcall
= build_function_call_expr (newfn
, arglist
);
6888 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl
)), newcall
);
6895 /* Fold function call to builtin cabs, cabsf or cabsl. ARGLIST
6896 is the argument list, TYPE is the return type and FNDECL is the
6897 original function DECL. Return NULL_TREE if no if no simplification
6901 fold_builtin_cabs (tree arglist
, tree type
, tree fndecl
)
6905 if (!arglist
|| TREE_CHAIN (arglist
))
6908 arg
= TREE_VALUE (arglist
);
6909 if (TREE_CODE (TREE_TYPE (arg
)) != COMPLEX_TYPE
6910 || TREE_CODE (TREE_TYPE (TREE_TYPE (arg
))) != REAL_TYPE
)
6913 /* Evaluate cabs of a constant at compile-time. */
6914 if (flag_unsafe_math_optimizations
6915 && TREE_CODE (arg
) == COMPLEX_CST
6916 && TREE_CODE (TREE_REALPART (arg
)) == REAL_CST
6917 && TREE_CODE (TREE_IMAGPART (arg
)) == REAL_CST
6918 && ! TREE_CONSTANT_OVERFLOW (TREE_REALPART (arg
))
6919 && ! TREE_CONSTANT_OVERFLOW (TREE_IMAGPART (arg
)))
6921 REAL_VALUE_TYPE r
, i
;
6923 r
= TREE_REAL_CST (TREE_REALPART (arg
));
6924 i
= TREE_REAL_CST (TREE_IMAGPART (arg
));
6926 real_arithmetic (&r
, MULT_EXPR
, &r
, &r
);
6927 real_arithmetic (&i
, MULT_EXPR
, &i
, &i
);
6928 real_arithmetic (&r
, PLUS_EXPR
, &r
, &i
);
6929 if (real_sqrt (&r
, TYPE_MODE (type
), &r
)
6930 || ! flag_trapping_math
)
6931 return build_real (type
, r
);
6934 /* If either part is zero, cabs is fabs of the other. */
6935 if (TREE_CODE (arg
) == COMPLEX_EXPR
6936 && real_zerop (TREE_OPERAND (arg
, 0)))
6937 return fold_build1 (ABS_EXPR
, type
, TREE_OPERAND (arg
, 1));
6938 if (TREE_CODE (arg
) == COMPLEX_EXPR
6939 && real_zerop (TREE_OPERAND (arg
, 1)))
6940 return fold_build1 (ABS_EXPR
, type
, TREE_OPERAND (arg
, 0));
6942 /* Optimize cabs(-z) and cabs(conj(z)) as cabs(z). */
6943 if (TREE_CODE (arg
) == NEGATE_EXPR
6944 || TREE_CODE (arg
) == CONJ_EXPR
)
6946 tree arglist
= build_tree_list (NULL_TREE
, TREE_OPERAND (arg
, 0));
6947 return build_function_call_expr (fndecl
, arglist
);
6950 /* Don't do this when optimizing for size. */
6951 if (flag_unsafe_math_optimizations
6952 && optimize
&& !optimize_size
)
6954 tree sqrtfn
= mathfn_built_in (type
, BUILT_IN_SQRT
);
6956 if (sqrtfn
!= NULL_TREE
)
6958 tree rpart
, ipart
, result
, arglist
;
6960 arg
= builtin_save_expr (arg
);
6962 rpart
= fold_build1 (REALPART_EXPR
, type
, arg
);
6963 ipart
= fold_build1 (IMAGPART_EXPR
, type
, arg
);
6965 rpart
= builtin_save_expr (rpart
);
6966 ipart
= builtin_save_expr (ipart
);
6968 result
= fold_build2 (PLUS_EXPR
, type
,
6969 fold_build2 (MULT_EXPR
, type
,
6971 fold_build2 (MULT_EXPR
, type
,
6974 arglist
= build_tree_list (NULL_TREE
, result
);
6975 return build_function_call_expr (sqrtfn
, arglist
);
6982 /* Fold a builtin function call to sqrt, sqrtf, or sqrtl. Return
6983 NULL_TREE if no simplification can be made. */
6986 fold_builtin_sqrt (tree arglist
, tree type
)
6989 enum built_in_function fcode
;
6990 tree arg
= TREE_VALUE (arglist
);
6992 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
6995 /* Optimize sqrt of constant value. */
6996 if (TREE_CODE (arg
) == REAL_CST
6997 && ! TREE_CONSTANT_OVERFLOW (arg
))
6999 REAL_VALUE_TYPE r
, x
;
7001 x
= TREE_REAL_CST (arg
);
7002 if (real_sqrt (&r
, TYPE_MODE (type
), &x
)
7003 || (!flag_trapping_math
&& !flag_errno_math
))
7004 return build_real (type
, r
);
7007 /* Optimize sqrt(expN(x)) = expN(x*0.5). */
7008 fcode
= builtin_mathfn_code (arg
);
7009 if (flag_unsafe_math_optimizations
&& BUILTIN_EXPONENT_P (fcode
))
7011 tree expfn
= TREE_OPERAND (TREE_OPERAND (arg
, 0), 0);
7012 arg
= fold_build2 (MULT_EXPR
, type
,
7013 TREE_VALUE (TREE_OPERAND (arg
, 1)),
7014 build_real (type
, dconsthalf
));
7015 arglist
= build_tree_list (NULL_TREE
, arg
);
7016 return build_function_call_expr (expfn
, arglist
);
7019 /* Optimize sqrt(Nroot(x)) -> pow(x,1/(2*N)). */
7020 if (flag_unsafe_math_optimizations
&& BUILTIN_ROOT_P (fcode
))
7022 tree powfn
= mathfn_built_in (type
, BUILT_IN_POW
);
7026 tree arg0
= TREE_VALUE (TREE_OPERAND (arg
, 1));
7028 /* The inner root was either sqrt or cbrt. */
7029 REAL_VALUE_TYPE dconstroot
=
7030 BUILTIN_SQRT_P (fcode
) ? dconsthalf
: dconstthird
;
7032 /* Adjust for the outer root. */
7033 SET_REAL_EXP (&dconstroot
, REAL_EXP (&dconstroot
) - 1);
7034 dconstroot
= real_value_truncate (TYPE_MODE (type
), dconstroot
);
7035 tree_root
= build_real (type
, dconstroot
);
7036 arglist
= tree_cons (NULL_TREE
, arg0
,
7037 build_tree_list (NULL_TREE
, tree_root
));
7038 return build_function_call_expr (powfn
, arglist
);
7042 /* Optimize sqrt(pow(x,y)) = pow(|x|,y*0.5). */
7043 if (flag_unsafe_math_optimizations
7044 && (fcode
== BUILT_IN_POW
7045 || fcode
== BUILT_IN_POWF
7046 || fcode
== BUILT_IN_POWL
))
7048 tree powfn
= TREE_OPERAND (TREE_OPERAND (arg
, 0), 0);
7049 tree arg0
= TREE_VALUE (TREE_OPERAND (arg
, 1));
7050 tree arg1
= TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg
, 1)));
7052 if (!tree_expr_nonnegative_p (arg0
))
7053 arg0
= build1 (ABS_EXPR
, type
, arg0
);
7054 narg1
= fold_build2 (MULT_EXPR
, type
, arg1
,
7055 build_real (type
, dconsthalf
));
7056 arglist
= tree_cons (NULL_TREE
, arg0
,
7057 build_tree_list (NULL_TREE
, narg1
));
7058 return build_function_call_expr (powfn
, arglist
);
7064 /* Fold a builtin function call to cbrt, cbrtf, or cbrtl. Return
7065 NULL_TREE if no simplification can be made. */
7067 fold_builtin_cbrt (tree arglist
, tree type
)
7069 tree arg
= TREE_VALUE (arglist
);
7070 const enum built_in_function fcode
= builtin_mathfn_code (arg
);
7072 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
7075 /* Optimize cbrt of constant value. */
7076 if (real_zerop (arg
) || real_onep (arg
) || real_minus_onep (arg
))
7079 if (flag_unsafe_math_optimizations
)
7081 /* Optimize cbrt(expN(x)) -> expN(x/3). */
7082 if (BUILTIN_EXPONENT_P (fcode
))
7084 tree expfn
= TREE_OPERAND (TREE_OPERAND (arg
, 0), 0);
7085 const REAL_VALUE_TYPE third_trunc
=
7086 real_value_truncate (TYPE_MODE (type
), dconstthird
);
7087 arg
= fold_build2 (MULT_EXPR
, type
,
7088 TREE_VALUE (TREE_OPERAND (arg
, 1)),
7089 build_real (type
, third_trunc
));
7090 arglist
= build_tree_list (NULL_TREE
, arg
);
7091 return build_function_call_expr (expfn
, arglist
);
7094 /* Optimize cbrt(sqrt(x)) -> pow(x,1/6). */
7095 if (BUILTIN_SQRT_P (fcode
))
7097 tree powfn
= mathfn_built_in (type
, BUILT_IN_POW
);
7101 tree arg0
= TREE_VALUE (TREE_OPERAND (arg
, 1));
7103 REAL_VALUE_TYPE dconstroot
= dconstthird
;
7105 SET_REAL_EXP (&dconstroot
, REAL_EXP (&dconstroot
) - 1);
7106 dconstroot
= real_value_truncate (TYPE_MODE (type
), dconstroot
);
7107 tree_root
= build_real (type
, dconstroot
);
7108 arglist
= tree_cons (NULL_TREE
, arg0
,
7109 build_tree_list (NULL_TREE
, tree_root
));
7110 return build_function_call_expr (powfn
, arglist
);
7114 /* Optimize cbrt(cbrt(x)) -> pow(x,1/9) iff x is nonnegative. */
7115 if (BUILTIN_CBRT_P (fcode
))
7117 tree arg0
= TREE_VALUE (TREE_OPERAND (arg
, 1));
7118 if (tree_expr_nonnegative_p (arg0
))
7120 tree powfn
= mathfn_built_in (type
, BUILT_IN_POW
);
7125 REAL_VALUE_TYPE dconstroot
;
7127 real_arithmetic (&dconstroot
, MULT_EXPR
, &dconstthird
, &dconstthird
);
7128 dconstroot
= real_value_truncate (TYPE_MODE (type
), dconstroot
);
7129 tree_root
= build_real (type
, dconstroot
);
7130 arglist
= tree_cons (NULL_TREE
, arg0
,
7131 build_tree_list (NULL_TREE
, tree_root
));
7132 return build_function_call_expr (powfn
, arglist
);
7137 /* Optimize cbrt(pow(x,y)) -> pow(x,y/3) iff x is nonnegative. */
7138 if (fcode
== BUILT_IN_POW
|| fcode
== BUILT_IN_POWF
7139 || fcode
== BUILT_IN_POWL
)
7141 tree arg00
= TREE_VALUE (TREE_OPERAND (arg
, 1));
7142 tree arg01
= TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg
, 1)));
7143 if (tree_expr_nonnegative_p (arg00
))
7145 tree powfn
= TREE_OPERAND (TREE_OPERAND (arg
, 0), 0);
7146 const REAL_VALUE_TYPE dconstroot
7147 = real_value_truncate (TYPE_MODE (type
), dconstthird
);
7148 tree narg01
= fold_build2 (MULT_EXPR
, type
, arg01
,
7149 build_real (type
, dconstroot
));
7150 arglist
= tree_cons (NULL_TREE
, arg00
,
7151 build_tree_list (NULL_TREE
, narg01
));
7152 return build_function_call_expr (powfn
, arglist
);
7159 /* Fold function call to builtin sin, sinf, or sinl. Return
7160 NULL_TREE if no simplification can be made. */
7162 fold_builtin_sin (tree arglist
)
7164 tree arg
= TREE_VALUE (arglist
);
7166 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
7169 /* Optimize sin (0.0) = 0.0. */
7170 if (real_zerop (arg
))
7176 /* Fold function call to builtin cos, cosf, or cosl. Return
7177 NULL_TREE if no simplification can be made. */
7179 fold_builtin_cos (tree arglist
, tree type
, tree fndecl
)
7181 tree arg
= TREE_VALUE (arglist
);
7183 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
7186 /* Optimize cos (0.0) = 1.0. */
7187 if (real_zerop (arg
))
7188 return build_real (type
, dconst1
);
7190 /* Optimize cos(-x) into cos (x). */
7191 if (TREE_CODE (arg
) == NEGATE_EXPR
)
7193 tree args
= build_tree_list (NULL_TREE
,
7194 TREE_OPERAND (arg
, 0));
7195 return build_function_call_expr (fndecl
, args
);
7201 /* Fold function call to builtin tan, tanf, or tanl. Return
7202 NULL_TREE if no simplification can be made. */
7204 fold_builtin_tan (tree arglist
)
7206 enum built_in_function fcode
;
7207 tree arg
= TREE_VALUE (arglist
);
7209 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
7212 /* Optimize tan(0.0) = 0.0. */
7213 if (real_zerop (arg
))
7216 /* Optimize tan(atan(x)) = x. */
7217 fcode
= builtin_mathfn_code (arg
);
7218 if (flag_unsafe_math_optimizations
7219 && (fcode
== BUILT_IN_ATAN
7220 || fcode
== BUILT_IN_ATANF
7221 || fcode
== BUILT_IN_ATANL
))
7222 return TREE_VALUE (TREE_OPERAND (arg
, 1));
7227 /* Fold function call to builtin atan, atanf, or atanl. Return
7228 NULL_TREE if no simplification can be made. */
7231 fold_builtin_atan (tree arglist
, tree type
)
7234 tree arg
= TREE_VALUE (arglist
);
7236 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
7239 /* Optimize atan(0.0) = 0.0. */
7240 if (real_zerop (arg
))
7243 /* Optimize atan(1.0) = pi/4. */
7244 if (real_onep (arg
))
7246 REAL_VALUE_TYPE cst
;
7248 real_convert (&cst
, TYPE_MODE (type
), &dconstpi
);
7249 SET_REAL_EXP (&cst
, REAL_EXP (&cst
) - 2);
7250 return build_real (type
, cst
);
7256 /* Fold function call to builtin trunc, truncf or truncl. Return
7257 NULL_TREE if no simplification can be made. */
7260 fold_builtin_trunc (tree fndecl
, tree arglist
)
7264 if (! validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
7267 /* Optimize trunc of constant value. */
7268 arg
= TREE_VALUE (arglist
);
7269 if (TREE_CODE (arg
) == REAL_CST
&& ! TREE_CONSTANT_OVERFLOW (arg
))
7271 REAL_VALUE_TYPE r
, x
;
7272 tree type
= TREE_TYPE (TREE_TYPE (fndecl
));
7274 x
= TREE_REAL_CST (arg
);
7275 real_trunc (&r
, TYPE_MODE (type
), &x
);
7276 return build_real (type
, r
);
7279 return fold_trunc_transparent_mathfn (fndecl
, arglist
);
7282 /* Fold function call to builtin floor, floorf or floorl. Return
7283 NULL_TREE if no simplification can be made. */
7286 fold_builtin_floor (tree fndecl
, tree arglist
)
7290 if (! validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
7293 /* Optimize floor of constant value. */
7294 arg
= TREE_VALUE (arglist
);
7295 if (TREE_CODE (arg
) == REAL_CST
&& ! TREE_CONSTANT_OVERFLOW (arg
))
7299 x
= TREE_REAL_CST (arg
);
7300 if (! REAL_VALUE_ISNAN (x
) || ! flag_errno_math
)
7302 tree type
= TREE_TYPE (TREE_TYPE (fndecl
));
7305 real_floor (&r
, TYPE_MODE (type
), &x
);
7306 return build_real (type
, r
);
7310 return fold_trunc_transparent_mathfn (fndecl
, arglist
);
7313 /* Fold function call to builtin ceil, ceilf or ceill. Return
7314 NULL_TREE if no simplification can be made. */
7317 fold_builtin_ceil (tree fndecl
, tree arglist
)
7321 if (! validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
7324 /* Optimize ceil of constant value. */
7325 arg
= TREE_VALUE (arglist
);
7326 if (TREE_CODE (arg
) == REAL_CST
&& ! TREE_CONSTANT_OVERFLOW (arg
))
7330 x
= TREE_REAL_CST (arg
);
7331 if (! REAL_VALUE_ISNAN (x
) || ! flag_errno_math
)
7333 tree type
= TREE_TYPE (TREE_TYPE (fndecl
));
7336 real_ceil (&r
, TYPE_MODE (type
), &x
);
7337 return build_real (type
, r
);
7341 return fold_trunc_transparent_mathfn (fndecl
, arglist
);
7344 /* Fold function call to builtin round, roundf or roundl. Return
7345 NULL_TREE if no simplification can be made. */
7348 fold_builtin_round (tree fndecl
, tree arglist
)
7352 if (! validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
7355 /* Optimize round of constant value. */
7356 arg
= TREE_VALUE (arglist
);
7357 if (TREE_CODE (arg
) == REAL_CST
&& ! TREE_CONSTANT_OVERFLOW (arg
))
7361 x
= TREE_REAL_CST (arg
);
7362 if (! REAL_VALUE_ISNAN (x
) || ! flag_errno_math
)
7364 tree type
= TREE_TYPE (TREE_TYPE (fndecl
));
7367 real_round (&r
, TYPE_MODE (type
), &x
);
7368 return build_real (type
, r
);
7372 return fold_trunc_transparent_mathfn (fndecl
, arglist
);
7375 /* Fold function call to builtin lround, lroundf or lroundl (or the
7376 corresponding long long versions) and other rounding functions.
7377 Return NULL_TREE if no simplification can be made. */
7380 fold_builtin_int_roundingfn (tree fndecl
, tree arglist
)
7384 if (! validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
7387 /* Optimize lround of constant value. */
7388 arg
= TREE_VALUE (arglist
);
7389 if (TREE_CODE (arg
) == REAL_CST
&& ! TREE_CONSTANT_OVERFLOW (arg
))
7391 const REAL_VALUE_TYPE x
= TREE_REAL_CST (arg
);
7393 if (! REAL_VALUE_ISNAN (x
) && ! REAL_VALUE_ISINF (x
))
7395 tree itype
= TREE_TYPE (TREE_TYPE (fndecl
));
7396 tree ftype
= TREE_TYPE (arg
), result
;
7397 HOST_WIDE_INT hi
, lo
;
7400 switch (DECL_FUNCTION_CODE (fndecl
))
7402 CASE_FLT_FN (BUILT_IN_LFLOOR
):
7403 CASE_FLT_FN (BUILT_IN_LLFLOOR
):
7404 real_floor (&r
, TYPE_MODE (ftype
), &x
);
7407 CASE_FLT_FN (BUILT_IN_LCEIL
):
7408 CASE_FLT_FN (BUILT_IN_LLCEIL
):
7409 real_ceil (&r
, TYPE_MODE (ftype
), &x
);
7412 CASE_FLT_FN (BUILT_IN_LROUND
):
7413 CASE_FLT_FN (BUILT_IN_LLROUND
):
7414 real_round (&r
, TYPE_MODE (ftype
), &x
);
7421 REAL_VALUE_TO_INT (&lo
, &hi
, r
);
7422 result
= build_int_cst_wide (NULL_TREE
, lo
, hi
);
7423 if (int_fits_type_p (result
, itype
))
7424 return fold_convert (itype
, result
);
7428 return fold_fixed_mathfn (fndecl
, arglist
);
7431 /* Fold function call to builtin ffs, clz, ctz, popcount and parity
7432 and their long and long long variants (i.e. ffsl and ffsll).
7433 Return NULL_TREE if no simplification can be made. */
7436 fold_builtin_bitop (tree fndecl
, tree arglist
)
7440 if (! validate_arglist (arglist
, INTEGER_TYPE
, VOID_TYPE
))
7443 /* Optimize for constant argument. */
7444 arg
= TREE_VALUE (arglist
);
7445 if (TREE_CODE (arg
) == INTEGER_CST
&& ! TREE_CONSTANT_OVERFLOW (arg
))
7447 HOST_WIDE_INT hi
, width
, result
;
7448 unsigned HOST_WIDE_INT lo
;
7451 type
= TREE_TYPE (arg
);
7452 width
= TYPE_PRECISION (type
);
7453 lo
= TREE_INT_CST_LOW (arg
);
7455 /* Clear all the bits that are beyond the type's precision. */
7456 if (width
> HOST_BITS_PER_WIDE_INT
)
7458 hi
= TREE_INT_CST_HIGH (arg
);
7459 if (width
< 2 * HOST_BITS_PER_WIDE_INT
)
7460 hi
&= ~((HOST_WIDE_INT
) (-1) >> (width
- HOST_BITS_PER_WIDE_INT
));
7465 if (width
< HOST_BITS_PER_WIDE_INT
)
7466 lo
&= ~((unsigned HOST_WIDE_INT
) (-1) << width
);
7469 switch (DECL_FUNCTION_CODE (fndecl
))
7471 CASE_INT_FN (BUILT_IN_FFS
):
7473 result
= exact_log2 (lo
& -lo
) + 1;
7475 result
= HOST_BITS_PER_WIDE_INT
+ exact_log2 (hi
& -hi
) + 1;
7480 CASE_INT_FN (BUILT_IN_CLZ
):
7482 result
= width
- floor_log2 (hi
) - 1 - HOST_BITS_PER_WIDE_INT
;
7484 result
= width
- floor_log2 (lo
) - 1;
7485 else if (! CLZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type
), result
))
7489 CASE_INT_FN (BUILT_IN_CTZ
):
7491 result
= exact_log2 (lo
& -lo
);
7493 result
= HOST_BITS_PER_WIDE_INT
+ exact_log2 (hi
& -hi
);
7494 else if (! CTZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type
), result
))
7498 CASE_INT_FN (BUILT_IN_POPCOUNT
):
7501 result
++, lo
&= lo
- 1;
7503 result
++, hi
&= hi
- 1;
7506 CASE_INT_FN (BUILT_IN_PARITY
):
7509 result
++, lo
&= lo
- 1;
7511 result
++, hi
&= hi
- 1;
7519 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl
)), result
);
7525 /* Return true if EXPR is the real constant contained in VALUE. */
7528 real_dconstp (tree expr
, const REAL_VALUE_TYPE
*value
)
7532 return ((TREE_CODE (expr
) == REAL_CST
7533 && ! TREE_CONSTANT_OVERFLOW (expr
)
7534 && REAL_VALUES_EQUAL (TREE_REAL_CST (expr
), *value
))
7535 || (TREE_CODE (expr
) == COMPLEX_CST
7536 && real_dconstp (TREE_REALPART (expr
), value
)
7537 && real_zerop (TREE_IMAGPART (expr
))));
7540 /* A subroutine of fold_builtin to fold the various logarithmic
7541 functions. EXP is the CALL_EXPR of a call to a builtin logN
7542 function. VALUE is the base of the logN function. */
7545 fold_builtin_logarithm (tree fndecl
, tree arglist
,
7546 const REAL_VALUE_TYPE
*value
)
7548 if (validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
7550 tree type
= TREE_TYPE (TREE_TYPE (fndecl
));
7551 tree arg
= TREE_VALUE (arglist
);
7552 const enum built_in_function fcode
= builtin_mathfn_code (arg
);
7554 /* Optimize logN(1.0) = 0.0. */
7555 if (real_onep (arg
))
7556 return build_real (type
, dconst0
);
7558 /* Optimize logN(N) = 1.0. If N can't be truncated to MODE
7559 exactly, then only do this if flag_unsafe_math_optimizations. */
7560 if (exact_real_truncate (TYPE_MODE (type
), value
)
7561 || flag_unsafe_math_optimizations
)
7563 const REAL_VALUE_TYPE value_truncate
=
7564 real_value_truncate (TYPE_MODE (type
), *value
);
7565 if (real_dconstp (arg
, &value_truncate
))
7566 return build_real (type
, dconst1
);
7569 /* Special case, optimize logN(expN(x)) = x. */
7570 if (flag_unsafe_math_optimizations
7571 && ((value
== &dconste
7572 && (fcode
== BUILT_IN_EXP
7573 || fcode
== BUILT_IN_EXPF
7574 || fcode
== BUILT_IN_EXPL
))
7575 || (value
== &dconst2
7576 && (fcode
== BUILT_IN_EXP2
7577 || fcode
== BUILT_IN_EXP2F
7578 || fcode
== BUILT_IN_EXP2L
))
7579 || (value
== &dconst10
&& (BUILTIN_EXP10_P (fcode
)))))
7580 return fold_convert (type
, TREE_VALUE (TREE_OPERAND (arg
, 1)));
7582 /* Optimize logN(func()) for various exponential functions. We
7583 want to determine the value "x" and the power "exponent" in
7584 order to transform logN(x**exponent) into exponent*logN(x). */
7585 if (flag_unsafe_math_optimizations
)
7587 tree exponent
= 0, x
= 0;
7591 CASE_FLT_FN (BUILT_IN_EXP
):
7592 /* Prepare to do logN(exp(exponent) -> exponent*logN(e). */
7593 x
= build_real (type
,
7594 real_value_truncate (TYPE_MODE (type
), dconste
));
7595 exponent
= TREE_VALUE (TREE_OPERAND (arg
, 1));
7597 CASE_FLT_FN (BUILT_IN_EXP2
):
7598 /* Prepare to do logN(exp2(exponent) -> exponent*logN(2). */
7599 x
= build_real (type
, dconst2
);
7600 exponent
= TREE_VALUE (TREE_OPERAND (arg
, 1));
7602 CASE_FLT_FN (BUILT_IN_EXP10
):
7603 CASE_FLT_FN (BUILT_IN_POW10
):
7604 /* Prepare to do logN(exp10(exponent) -> exponent*logN(10). */
7605 x
= build_real (type
, dconst10
);
7606 exponent
= TREE_VALUE (TREE_OPERAND (arg
, 1));
7608 CASE_FLT_FN (BUILT_IN_SQRT
):
7609 /* Prepare to do logN(sqrt(x) -> 0.5*logN(x). */
7610 x
= TREE_VALUE (TREE_OPERAND (arg
, 1));
7611 exponent
= build_real (type
, dconsthalf
);
7613 CASE_FLT_FN (BUILT_IN_CBRT
):
7614 /* Prepare to do logN(cbrt(x) -> (1/3)*logN(x). */
7615 x
= TREE_VALUE (TREE_OPERAND (arg
, 1));
7616 exponent
= build_real (type
, real_value_truncate (TYPE_MODE (type
),
7619 CASE_FLT_FN (BUILT_IN_POW
):
7620 /* Prepare to do logN(pow(x,exponent) -> exponent*logN(x). */
7621 x
= TREE_VALUE (TREE_OPERAND (arg
, 1));
7622 exponent
= TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg
, 1)));
7628 /* Now perform the optimization. */
7632 arglist
= build_tree_list (NULL_TREE
, x
);
7633 logfn
= build_function_call_expr (fndecl
, arglist
);
7634 return fold_build2 (MULT_EXPR
, type
, exponent
, logfn
);
7642 /* Fold a builtin function call to pow, powf, or powl. Return
7643 NULL_TREE if no simplification can be made. */
7645 fold_builtin_pow (tree fndecl
, tree arglist
, tree type
)
7647 tree arg0
= TREE_VALUE (arglist
);
7648 tree arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
7650 if (!validate_arglist (arglist
, REAL_TYPE
, REAL_TYPE
, VOID_TYPE
))
7653 /* Optimize pow(1.0,y) = 1.0. */
7654 if (real_onep (arg0
))
7655 return omit_one_operand (type
, build_real (type
, dconst1
), arg1
);
7657 if (TREE_CODE (arg1
) == REAL_CST
7658 && ! TREE_CONSTANT_OVERFLOW (arg1
))
7660 REAL_VALUE_TYPE cint
;
7664 c
= TREE_REAL_CST (arg1
);
7666 /* Optimize pow(x,0.0) = 1.0. */
7667 if (REAL_VALUES_EQUAL (c
, dconst0
))
7668 return omit_one_operand (type
, build_real (type
, dconst1
),
7671 /* Optimize pow(x,1.0) = x. */
7672 if (REAL_VALUES_EQUAL (c
, dconst1
))
7675 /* Optimize pow(x,-1.0) = 1.0/x. */
7676 if (REAL_VALUES_EQUAL (c
, dconstm1
))
7677 return fold_build2 (RDIV_EXPR
, type
,
7678 build_real (type
, dconst1
), arg0
);
7680 /* Optimize pow(x,0.5) = sqrt(x). */
7681 if (flag_unsafe_math_optimizations
7682 && REAL_VALUES_EQUAL (c
, dconsthalf
))
7684 tree sqrtfn
= mathfn_built_in (type
, BUILT_IN_SQRT
);
7686 if (sqrtfn
!= NULL_TREE
)
7688 tree arglist
= build_tree_list (NULL_TREE
, arg0
);
7689 return build_function_call_expr (sqrtfn
, arglist
);
7693 /* Check for an integer exponent. */
7694 n
= real_to_integer (&c
);
7695 real_from_integer (&cint
, VOIDmode
, n
, n
< 0 ? -1 : 0, 0);
7696 if (real_identical (&c
, &cint
))
7698 /* Attempt to evaluate pow at compile-time. */
7699 if (TREE_CODE (arg0
) == REAL_CST
7700 && ! TREE_CONSTANT_OVERFLOW (arg0
))
7705 x
= TREE_REAL_CST (arg0
);
7706 inexact
= real_powi (&x
, TYPE_MODE (type
), &x
, n
);
7707 if (flag_unsafe_math_optimizations
|| !inexact
)
7708 return build_real (type
, x
);
7711 /* Strip sign ops from even integer powers. */
7712 if ((n
& 1) == 0 && flag_unsafe_math_optimizations
)
7714 tree narg0
= fold_strip_sign_ops (arg0
);
7717 arglist
= build_tree_list (NULL_TREE
, arg1
);
7718 arglist
= tree_cons (NULL_TREE
, narg0
, arglist
);
7719 return build_function_call_expr (fndecl
, arglist
);
7725 if (flag_unsafe_math_optimizations
)
7727 const enum built_in_function fcode
= builtin_mathfn_code (arg0
);
7729 /* Optimize pow(expN(x),y) = expN(x*y). */
7730 if (BUILTIN_EXPONENT_P (fcode
))
7732 tree expfn
= TREE_OPERAND (TREE_OPERAND (arg0
, 0), 0);
7733 tree arg
= TREE_VALUE (TREE_OPERAND (arg0
, 1));
7734 arg
= fold_build2 (MULT_EXPR
, type
, arg
, arg1
);
7735 arglist
= build_tree_list (NULL_TREE
, arg
);
7736 return build_function_call_expr (expfn
, arglist
);
7739 /* Optimize pow(sqrt(x),y) = pow(x,y*0.5). */
7740 if (BUILTIN_SQRT_P (fcode
))
7742 tree narg0
= TREE_VALUE (TREE_OPERAND (arg0
, 1));
7743 tree narg1
= fold_build2 (MULT_EXPR
, type
, arg1
,
7744 build_real (type
, dconsthalf
));
7746 arglist
= tree_cons (NULL_TREE
, narg0
,
7747 build_tree_list (NULL_TREE
, narg1
));
7748 return build_function_call_expr (fndecl
, arglist
);
7751 /* Optimize pow(cbrt(x),y) = pow(x,y/3) iff x is nonnegative. */
7752 if (BUILTIN_CBRT_P (fcode
))
7754 tree arg
= TREE_VALUE (TREE_OPERAND (arg0
, 1));
7755 if (tree_expr_nonnegative_p (arg
))
7757 const REAL_VALUE_TYPE dconstroot
7758 = real_value_truncate (TYPE_MODE (type
), dconstthird
);
7759 tree narg1
= fold_build2 (MULT_EXPR
, type
, arg1
,
7760 build_real (type
, dconstroot
));
7761 arglist
= tree_cons (NULL_TREE
, arg
,
7762 build_tree_list (NULL_TREE
, narg1
));
7763 return build_function_call_expr (fndecl
, arglist
);
7767 /* Optimize pow(pow(x,y),z) = pow(x,y*z). */
7768 if (fcode
== BUILT_IN_POW
|| fcode
== BUILT_IN_POWF
7769 || fcode
== BUILT_IN_POWL
)
7771 tree arg00
= TREE_VALUE (TREE_OPERAND (arg0
, 1));
7772 tree arg01
= TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg0
, 1)));
7773 tree narg1
= fold_build2 (MULT_EXPR
, type
, arg01
, arg1
);
7774 arglist
= tree_cons (NULL_TREE
, arg00
,
7775 build_tree_list (NULL_TREE
, narg1
));
7776 return build_function_call_expr (fndecl
, arglist
);
7783 /* Fold a builtin function call to powi, powif, or powil. Return
7784 NULL_TREE if no simplification can be made. */
7786 fold_builtin_powi (tree fndecl ATTRIBUTE_UNUSED
, tree arglist
, tree type
)
7788 tree arg0
= TREE_VALUE (arglist
);
7789 tree arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
7791 if (!validate_arglist (arglist
, REAL_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
7794 /* Optimize pow(1.0,y) = 1.0. */
7795 if (real_onep (arg0
))
7796 return omit_one_operand (type
, build_real (type
, dconst1
), arg1
);
7798 if (host_integerp (arg1
, 0))
7800 HOST_WIDE_INT c
= TREE_INT_CST_LOW (arg1
);
7802 /* Evaluate powi at compile-time. */
7803 if (TREE_CODE (arg0
) == REAL_CST
7804 && ! TREE_CONSTANT_OVERFLOW (arg0
))
7807 x
= TREE_REAL_CST (arg0
);
7808 real_powi (&x
, TYPE_MODE (type
), &x
, c
);
7809 return build_real (type
, x
);
7812 /* Optimize pow(x,0) = 1.0. */
7814 return omit_one_operand (type
, build_real (type
, dconst1
),
7817 /* Optimize pow(x,1) = x. */
7821 /* Optimize pow(x,-1) = 1.0/x. */
7823 return fold_build2 (RDIV_EXPR
, type
,
7824 build_real (type
, dconst1
), arg0
);
7830 /* A subroutine of fold_builtin to fold the various exponent
7831 functions. EXP is the CALL_EXPR of a call to a builtin function.
7832 VALUE is the value which will be raised to a power. */
7835 fold_builtin_exponent (tree fndecl
, tree arglist
,
7836 const REAL_VALUE_TYPE
*value
)
7838 if (validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
7840 tree type
= TREE_TYPE (TREE_TYPE (fndecl
));
7841 tree arg
= TREE_VALUE (arglist
);
7843 /* Optimize exp*(0.0) = 1.0. */
7844 if (real_zerop (arg
))
7845 return build_real (type
, dconst1
);
7847 /* Optimize expN(1.0) = N. */
7848 if (real_onep (arg
))
7850 REAL_VALUE_TYPE cst
;
7852 real_convert (&cst
, TYPE_MODE (type
), value
);
7853 return build_real (type
, cst
);
7856 /* Attempt to evaluate expN(integer) at compile-time. */
7857 if (flag_unsafe_math_optimizations
7858 && TREE_CODE (arg
) == REAL_CST
7859 && ! TREE_CONSTANT_OVERFLOW (arg
))
7861 REAL_VALUE_TYPE cint
;
7865 c
= TREE_REAL_CST (arg
);
7866 n
= real_to_integer (&c
);
7867 real_from_integer (&cint
, VOIDmode
, n
,
7869 if (real_identical (&c
, &cint
))
7873 real_powi (&x
, TYPE_MODE (type
), value
, n
);
7874 return build_real (type
, x
);
7878 /* Optimize expN(logN(x)) = x. */
7879 if (flag_unsafe_math_optimizations
)
7881 const enum built_in_function fcode
= builtin_mathfn_code (arg
);
7883 if ((value
== &dconste
7884 && (fcode
== BUILT_IN_LOG
7885 || fcode
== BUILT_IN_LOGF
7886 || fcode
== BUILT_IN_LOGL
))
7887 || (value
== &dconst2
7888 && (fcode
== BUILT_IN_LOG2
7889 || fcode
== BUILT_IN_LOG2F
7890 || fcode
== BUILT_IN_LOG2L
))
7891 || (value
== &dconst10
7892 && (fcode
== BUILT_IN_LOG10
7893 || fcode
== BUILT_IN_LOG10F
7894 || fcode
== BUILT_IN_LOG10L
)))
7895 return fold_convert (type
, TREE_VALUE (TREE_OPERAND (arg
, 1)));
7902 /* Fold function call to builtin memset. Return
7903 NULL_TREE if no simplification can be made. */
7906 fold_builtin_memset (tree arglist
, tree type
, bool ignore
)
7908 tree dest
, c
, len
, var
, ret
;
7909 unsigned HOST_WIDE_INT length
, cval
;
7911 if (!validate_arglist (arglist
,
7912 POINTER_TYPE
, INTEGER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
7915 dest
= TREE_VALUE (arglist
);
7916 c
= TREE_VALUE (TREE_CHAIN (arglist
));
7917 len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
7919 if (! host_integerp (len
, 1))
7922 /* If the LEN parameter is zero, return DEST. */
7923 if (integer_zerop (len
))
7924 return omit_one_operand (type
, dest
, c
);
7926 if (! host_integerp (c
, 1) || TREE_SIDE_EFFECTS (dest
))
7931 if (TREE_CODE (var
) != ADDR_EXPR
)
7934 var
= TREE_OPERAND (var
, 0);
7935 if (TREE_THIS_VOLATILE (var
))
7938 if (!INTEGRAL_TYPE_P (TREE_TYPE (var
))
7939 && !POINTER_TYPE_P (TREE_TYPE (var
)))
7942 length
= tree_low_cst (len
, 1);
7943 if (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (var
))) != length
7944 || get_pointer_alignment (dest
, BIGGEST_ALIGNMENT
) / BITS_PER_UNIT
7948 if (length
> HOST_BITS_PER_WIDE_INT
/ BITS_PER_UNIT
)
7951 if (integer_zerop (c
))
7955 if (CHAR_BIT
!= 8 || BITS_PER_UNIT
!= 8 || HOST_BITS_PER_WIDE_INT
> 64)
7958 cval
= tree_low_cst (c
, 1);
7962 cval
|= (cval
<< 31) << 1;
7965 ret
= build_int_cst_type (TREE_TYPE (var
), cval
);
7966 ret
= build2 (MODIFY_EXPR
, TREE_TYPE (var
), var
, ret
);
7970 return omit_one_operand (type
, dest
, ret
);
7973 /* Fold function call to builtin memset. Return
7974 NULL_TREE if no simplification can be made. */
7977 fold_builtin_bzero (tree arglist
, bool ignore
)
7979 tree dest
, size
, newarglist
;
7981 if (!validate_arglist (arglist
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
7987 dest
= TREE_VALUE (arglist
);
7988 size
= TREE_VALUE (TREE_CHAIN (arglist
));
7990 /* New argument list transforming bzero(ptr x, int y) to
7991 memset(ptr x, int 0, size_t y). This is done this way
7992 so that if it isn't expanded inline, we fallback to
7993 calling bzero instead of memset. */
7995 newarglist
= build_tree_list (NULL_TREE
, fold_convert (sizetype
, size
));
7996 newarglist
= tree_cons (NULL_TREE
, integer_zero_node
, newarglist
);
7997 newarglist
= tree_cons (NULL_TREE
, dest
, newarglist
);
7998 return fold_builtin_memset (newarglist
, void_type_node
, ignore
);
8001 /* Fold function call to builtin mem{{,p}cpy,move}. Return
8002 NULL_TREE if no simplification can be made.
8003 If ENDP is 0, return DEST (like memcpy).
8004 If ENDP is 1, return DEST+LEN (like mempcpy).
8005 If ENDP is 2, return DEST+LEN-1 (like stpcpy).
8006 If ENDP is 3, return DEST, additionally *SRC and *DEST may overlap
8010 fold_builtin_memory_op (tree arglist
, tree type
, bool ignore
, int endp
)
8012 tree dest
, src
, len
, destvar
, srcvar
, expr
;
8013 unsigned HOST_WIDE_INT length
;
8015 if (! validate_arglist (arglist
,
8016 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
8019 dest
= TREE_VALUE (arglist
);
8020 src
= TREE_VALUE (TREE_CHAIN (arglist
));
8021 len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
8023 /* If the LEN parameter is zero, return DEST. */
8024 if (integer_zerop (len
))
8025 return omit_one_operand (type
, dest
, src
);
8027 /* If SRC and DEST are the same (and not volatile), return
8028 DEST{,+LEN,+LEN-1}. */
8029 if (operand_equal_p (src
, dest
, 0))
8033 if (! host_integerp (len
, 1))
8036 if (TREE_SIDE_EFFECTS (dest
) || TREE_SIDE_EFFECTS (src
))
8040 STRIP_NOPS (destvar
);
8041 if (TREE_CODE (destvar
) != ADDR_EXPR
)
8044 destvar
= TREE_OPERAND (destvar
, 0);
8045 if (TREE_THIS_VOLATILE (destvar
))
8048 if (!INTEGRAL_TYPE_P (TREE_TYPE (destvar
))
8049 && !POINTER_TYPE_P (TREE_TYPE (destvar
))
8050 && !SCALAR_FLOAT_TYPE_P (TREE_TYPE (destvar
)))
8054 STRIP_NOPS (srcvar
);
8055 if (TREE_CODE (srcvar
) != ADDR_EXPR
)
8058 srcvar
= TREE_OPERAND (srcvar
, 0);
8059 if (TREE_THIS_VOLATILE (srcvar
))
8062 if (!INTEGRAL_TYPE_P (TREE_TYPE (srcvar
))
8063 && !POINTER_TYPE_P (TREE_TYPE (srcvar
))
8064 && !SCALAR_FLOAT_TYPE_P (TREE_TYPE (srcvar
)))
8067 length
= tree_low_cst (len
, 1);
8068 if (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (destvar
))) != length
8069 || get_pointer_alignment (dest
, BIGGEST_ALIGNMENT
) / BITS_PER_UNIT
8071 || GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (srcvar
))) != length
8072 || get_pointer_alignment (src
, BIGGEST_ALIGNMENT
) / BITS_PER_UNIT
8076 if ((INTEGRAL_TYPE_P (TREE_TYPE (srcvar
))
8077 || POINTER_TYPE_P (TREE_TYPE (srcvar
)))
8078 && (INTEGRAL_TYPE_P (TREE_TYPE (destvar
))
8079 || POINTER_TYPE_P (TREE_TYPE (destvar
))))
8080 expr
= fold_convert (TREE_TYPE (destvar
), srcvar
);
8082 expr
= fold_build1 (VIEW_CONVERT_EXPR
, TREE_TYPE (destvar
), srcvar
);
8083 expr
= build2 (MODIFY_EXPR
, TREE_TYPE (destvar
), destvar
, expr
);
8089 if (endp
== 0 || endp
== 3)
8090 return omit_one_operand (type
, dest
, expr
);
8096 len
= fold_build2 (MINUS_EXPR
, TREE_TYPE (len
), len
,
8099 len
= fold_convert (TREE_TYPE (dest
), len
);
8100 dest
= fold_build2 (PLUS_EXPR
, TREE_TYPE (dest
), dest
, len
);
8101 dest
= fold_convert (type
, dest
);
8103 dest
= omit_one_operand (type
, dest
, expr
);
8107 /* Fold function call to builtin bcopy. Return NULL_TREE if no
8108 simplification can be made. */
8111 fold_builtin_bcopy (tree arglist
, bool ignore
)
8113 tree src
, dest
, size
, newarglist
;
8115 if (!validate_arglist (arglist
,
8116 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
8122 src
= TREE_VALUE (arglist
);
8123 dest
= TREE_VALUE (TREE_CHAIN (arglist
));
8124 size
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
8126 /* New argument list transforming bcopy(ptr x, ptr y, int z) to
8127 memmove(ptr y, ptr x, size_t z). This is done this way
8128 so that if it isn't expanded inline, we fallback to
8129 calling bcopy instead of memmove. */
8131 newarglist
= build_tree_list (NULL_TREE
, fold_convert (sizetype
, size
));
8132 newarglist
= tree_cons (NULL_TREE
, src
, newarglist
);
8133 newarglist
= tree_cons (NULL_TREE
, dest
, newarglist
);
8135 return fold_builtin_memory_op (newarglist
, void_type_node
, true, /*endp=*/3);
8138 /* Fold function call to builtin strcpy. If LEN is not NULL, it represents
8139 the length of the string to be copied. Return NULL_TREE if no
8140 simplification can be made. */
8143 fold_builtin_strcpy (tree fndecl
, tree arglist
, tree len
)
8147 if (!validate_arglist (arglist
,
8148 POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
8151 dest
= TREE_VALUE (arglist
);
8152 src
= TREE_VALUE (TREE_CHAIN (arglist
));
8154 /* If SRC and DEST are the same (and not volatile), return DEST. */
8155 if (operand_equal_p (src
, dest
, 0))
8156 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl
)), dest
);
8161 fn
= implicit_built_in_decls
[BUILT_IN_MEMCPY
];
8167 len
= c_strlen (src
, 1);
8168 if (! len
|| TREE_SIDE_EFFECTS (len
))
8172 len
= size_binop (PLUS_EXPR
, len
, ssize_int (1));
8173 arglist
= build_tree_list (NULL_TREE
, len
);
8174 arglist
= tree_cons (NULL_TREE
, src
, arglist
);
8175 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
8176 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl
)),
8177 build_function_call_expr (fn
, arglist
));
8180 /* Fold function call to builtin strncpy. If SLEN is not NULL, it represents
8181 the length of the source string. Return NULL_TREE if no simplification
8185 fold_builtin_strncpy (tree fndecl
, tree arglist
, tree slen
)
8187 tree dest
, src
, len
, fn
;
8189 if (!validate_arglist (arglist
,
8190 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
8193 dest
= TREE_VALUE (arglist
);
8194 src
= TREE_VALUE (TREE_CHAIN (arglist
));
8195 len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
8197 /* If the LEN parameter is zero, return DEST. */
8198 if (integer_zerop (len
))
8199 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl
)), dest
, src
);
8201 /* We can't compare slen with len as constants below if len is not a
8203 if (len
== 0 || TREE_CODE (len
) != INTEGER_CST
)
8207 slen
= c_strlen (src
, 1);
8209 /* Now, we must be passed a constant src ptr parameter. */
8210 if (slen
== 0 || TREE_CODE (slen
) != INTEGER_CST
)
8213 slen
= size_binop (PLUS_EXPR
, slen
, ssize_int (1));
8215 /* We do not support simplification of this case, though we do
8216 support it when expanding trees into RTL. */
8217 /* FIXME: generate a call to __builtin_memset. */
8218 if (tree_int_cst_lt (slen
, len
))
8221 /* OK transform into builtin memcpy. */
8222 fn
= implicit_built_in_decls
[BUILT_IN_MEMCPY
];
8225 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl
)),
8226 build_function_call_expr (fn
, arglist
));
8229 /* Fold function call to builtin memcmp. Return
8230 NULL_TREE if no simplification can be made. */
8233 fold_builtin_memcmp (tree arglist
)
8235 tree arg1
, arg2
, len
;
8236 const char *p1
, *p2
;
8238 if (!validate_arglist (arglist
,
8239 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
8242 arg1
= TREE_VALUE (arglist
);
8243 arg2
= TREE_VALUE (TREE_CHAIN (arglist
));
8244 len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
8246 /* If the LEN parameter is zero, return zero. */
8247 if (integer_zerop (len
))
8248 return omit_two_operands (integer_type_node
, integer_zero_node
,
8251 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
8252 if (operand_equal_p (arg1
, arg2
, 0))
8253 return omit_one_operand (integer_type_node
, integer_zero_node
, len
);
8255 p1
= c_getstr (arg1
);
8256 p2
= c_getstr (arg2
);
8258 /* If all arguments are constant, and the value of len is not greater
8259 than the lengths of arg1 and arg2, evaluate at compile-time. */
8260 if (host_integerp (len
, 1) && p1
&& p2
8261 && compare_tree_int (len
, strlen (p1
) + 1) <= 0
8262 && compare_tree_int (len
, strlen (p2
) + 1) <= 0)
8264 const int r
= memcmp (p1
, p2
, tree_low_cst (len
, 1));
8267 return integer_one_node
;
8269 return integer_minus_one_node
;
8271 return integer_zero_node
;
8274 /* If len parameter is one, return an expression corresponding to
8275 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
8276 if (host_integerp (len
, 1) && tree_low_cst (len
, 1) == 1)
8278 tree cst_uchar_node
= build_type_variant (unsigned_char_type_node
, 1, 0);
8279 tree cst_uchar_ptr_node
8280 = build_pointer_type_for_mode (cst_uchar_node
, ptr_mode
, true);
8282 tree ind1
= fold_convert (integer_type_node
,
8283 build1 (INDIRECT_REF
, cst_uchar_node
,
8284 fold_convert (cst_uchar_ptr_node
,
8286 tree ind2
= fold_convert (integer_type_node
,
8287 build1 (INDIRECT_REF
, cst_uchar_node
,
8288 fold_convert (cst_uchar_ptr_node
,
8290 return fold_build2 (MINUS_EXPR
, integer_type_node
, ind1
, ind2
);
8296 /* Fold function call to builtin strcmp. Return
8297 NULL_TREE if no simplification can be made. */
8300 fold_builtin_strcmp (tree arglist
)
8303 const char *p1
, *p2
;
8305 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
8308 arg1
= TREE_VALUE (arglist
);
8309 arg2
= TREE_VALUE (TREE_CHAIN (arglist
));
8311 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
8312 if (operand_equal_p (arg1
, arg2
, 0))
8313 return integer_zero_node
;
8315 p1
= c_getstr (arg1
);
8316 p2
= c_getstr (arg2
);
8320 const int i
= strcmp (p1
, p2
);
8322 return integer_minus_one_node
;
8324 return integer_one_node
;
8326 return integer_zero_node
;
8329 /* If the second arg is "", return *(const unsigned char*)arg1. */
8330 if (p2
&& *p2
== '\0')
8332 tree cst_uchar_node
= build_type_variant (unsigned_char_type_node
, 1, 0);
8333 tree cst_uchar_ptr_node
8334 = build_pointer_type_for_mode (cst_uchar_node
, ptr_mode
, true);
8336 return fold_convert (integer_type_node
,
8337 build1 (INDIRECT_REF
, cst_uchar_node
,
8338 fold_convert (cst_uchar_ptr_node
,
8342 /* If the first arg is "", return -*(const unsigned char*)arg2. */
8343 if (p1
&& *p1
== '\0')
8345 tree cst_uchar_node
= build_type_variant (unsigned_char_type_node
, 1, 0);
8346 tree cst_uchar_ptr_node
8347 = build_pointer_type_for_mode (cst_uchar_node
, ptr_mode
, true);
8349 tree temp
= fold_convert (integer_type_node
,
8350 build1 (INDIRECT_REF
, cst_uchar_node
,
8351 fold_convert (cst_uchar_ptr_node
,
8353 return fold_build1 (NEGATE_EXPR
, integer_type_node
, temp
);
8359 /* Fold function call to builtin strncmp. Return
8360 NULL_TREE if no simplification can be made. */
8363 fold_builtin_strncmp (tree arglist
)
8365 tree arg1
, arg2
, len
;
8366 const char *p1
, *p2
;
8368 if (!validate_arglist (arglist
,
8369 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
8372 arg1
= TREE_VALUE (arglist
);
8373 arg2
= TREE_VALUE (TREE_CHAIN (arglist
));
8374 len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
8376 /* If the LEN parameter is zero, return zero. */
8377 if (integer_zerop (len
))
8378 return omit_two_operands (integer_type_node
, integer_zero_node
,
8381 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
8382 if (operand_equal_p (arg1
, arg2
, 0))
8383 return omit_one_operand (integer_type_node
, integer_zero_node
, len
);
8385 p1
= c_getstr (arg1
);
8386 p2
= c_getstr (arg2
);
8388 if (host_integerp (len
, 1) && p1
&& p2
)
8390 const int i
= strncmp (p1
, p2
, tree_low_cst (len
, 1));
8392 return integer_one_node
;
8394 return integer_minus_one_node
;
8396 return integer_zero_node
;
8399 /* If the second arg is "", and the length is greater than zero,
8400 return *(const unsigned char*)arg1. */
8401 if (p2
&& *p2
== '\0'
8402 && TREE_CODE (len
) == INTEGER_CST
8403 && tree_int_cst_sgn (len
) == 1)
8405 tree cst_uchar_node
= build_type_variant (unsigned_char_type_node
, 1, 0);
8406 tree cst_uchar_ptr_node
8407 = build_pointer_type_for_mode (cst_uchar_node
, ptr_mode
, true);
8409 return fold_convert (integer_type_node
,
8410 build1 (INDIRECT_REF
, cst_uchar_node
,
8411 fold_convert (cst_uchar_ptr_node
,
8415 /* If the first arg is "", and the length is greater than zero,
8416 return -*(const unsigned char*)arg2. */
8417 if (p1
&& *p1
== '\0'
8418 && TREE_CODE (len
) == INTEGER_CST
8419 && tree_int_cst_sgn (len
) == 1)
8421 tree cst_uchar_node
= build_type_variant (unsigned_char_type_node
, 1, 0);
8422 tree cst_uchar_ptr_node
8423 = build_pointer_type_for_mode (cst_uchar_node
, ptr_mode
, true);
8425 tree temp
= fold_convert (integer_type_node
,
8426 build1 (INDIRECT_REF
, cst_uchar_node
,
8427 fold_convert (cst_uchar_ptr_node
,
8429 return fold_build1 (NEGATE_EXPR
, integer_type_node
, temp
);
8432 /* If len parameter is one, return an expression corresponding to
8433 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
8434 if (host_integerp (len
, 1) && tree_low_cst (len
, 1) == 1)
8436 tree cst_uchar_node
= build_type_variant (unsigned_char_type_node
, 1, 0);
8437 tree cst_uchar_ptr_node
8438 = build_pointer_type_for_mode (cst_uchar_node
, ptr_mode
, true);
8440 tree ind1
= fold_convert (integer_type_node
,
8441 build1 (INDIRECT_REF
, cst_uchar_node
,
8442 fold_convert (cst_uchar_ptr_node
,
8444 tree ind2
= fold_convert (integer_type_node
,
8445 build1 (INDIRECT_REF
, cst_uchar_node
,
8446 fold_convert (cst_uchar_ptr_node
,
8448 return fold_build2 (MINUS_EXPR
, integer_type_node
, ind1
, ind2
);
8454 /* Fold function call to builtin signbit, signbitf or signbitl. Return
8455 NULL_TREE if no simplification can be made. */
8458 fold_builtin_signbit (tree fndecl
, tree arglist
)
8460 tree type
= TREE_TYPE (TREE_TYPE (fndecl
));
8463 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
8466 arg
= TREE_VALUE (arglist
);
8468 /* If ARG is a compile-time constant, determine the result. */
8469 if (TREE_CODE (arg
) == REAL_CST
8470 && !TREE_CONSTANT_OVERFLOW (arg
))
8474 c
= TREE_REAL_CST (arg
);
8475 temp
= REAL_VALUE_NEGATIVE (c
) ? integer_one_node
: integer_zero_node
;
8476 return fold_convert (type
, temp
);
8479 /* If ARG is non-negative, the result is always zero. */
8480 if (tree_expr_nonnegative_p (arg
))
8481 return omit_one_operand (type
, integer_zero_node
, arg
);
8483 /* If ARG's format doesn't have signed zeros, return "arg < 0.0". */
8484 if (!HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg
))))
8485 return fold_build2 (LT_EXPR
, type
, arg
,
8486 build_real (TREE_TYPE (arg
), dconst0
));
8491 /* Fold function call to builtin copysign, copysignf or copysignl.
8492 Return NULL_TREE if no simplification can be made. */
8495 fold_builtin_copysign (tree fndecl
, tree arglist
, tree type
)
8497 tree arg1
, arg2
, tem
;
8499 if (!validate_arglist (arglist
, REAL_TYPE
, REAL_TYPE
, VOID_TYPE
))
8502 arg1
= TREE_VALUE (arglist
);
8503 arg2
= TREE_VALUE (TREE_CHAIN (arglist
));
8505 /* copysign(X,X) is X. */
8506 if (operand_equal_p (arg1
, arg2
, 0))
8507 return fold_convert (type
, arg1
);
8509 /* If ARG1 and ARG2 are compile-time constants, determine the result. */
8510 if (TREE_CODE (arg1
) == REAL_CST
8511 && TREE_CODE (arg2
) == REAL_CST
8512 && !TREE_CONSTANT_OVERFLOW (arg1
)
8513 && !TREE_CONSTANT_OVERFLOW (arg2
))
8515 REAL_VALUE_TYPE c1
, c2
;
8517 c1
= TREE_REAL_CST (arg1
);
8518 c2
= TREE_REAL_CST (arg2
);
8519 /* c1.sign := c2.sign. */
8520 real_copysign (&c1
, &c2
);
8521 return build_real (type
, c1
);
8524 /* copysign(X, Y) is fabs(X) when Y is always non-negative.
8525 Remember to evaluate Y for side-effects. */
8526 if (tree_expr_nonnegative_p (arg2
))
8527 return omit_one_operand (type
,
8528 fold_build1 (ABS_EXPR
, type
, arg1
),
8531 /* Strip sign changing operations for the first argument. */
8532 tem
= fold_strip_sign_ops (arg1
);
8535 arglist
= tree_cons (NULL_TREE
, tem
, TREE_CHAIN (arglist
));
8536 return build_function_call_expr (fndecl
, arglist
);
8542 /* Fold a call to builtin isascii. */
8545 fold_builtin_isascii (tree arglist
)
8547 if (! validate_arglist (arglist
, INTEGER_TYPE
, VOID_TYPE
))
8551 /* Transform isascii(c) -> ((c & ~0x7f) == 0). */
8552 tree arg
= TREE_VALUE (arglist
);
8554 arg
= build2 (BIT_AND_EXPR
, integer_type_node
, arg
,
8555 build_int_cst (NULL_TREE
,
8556 ~ (unsigned HOST_WIDE_INT
) 0x7f));
8557 arg
= fold_build2 (EQ_EXPR
, integer_type_node
,
8558 arg
, integer_zero_node
);
8560 if (in_gimple_form
&& !TREE_CONSTANT (arg
))
8567 /* Fold a call to builtin toascii. */
8570 fold_builtin_toascii (tree arglist
)
8572 if (! validate_arglist (arglist
, INTEGER_TYPE
, VOID_TYPE
))
8576 /* Transform toascii(c) -> (c & 0x7f). */
8577 tree arg
= TREE_VALUE (arglist
);
8579 return fold_build2 (BIT_AND_EXPR
, integer_type_node
, arg
,
8580 build_int_cst (NULL_TREE
, 0x7f));
8584 /* Fold a call to builtin isdigit. */
8587 fold_builtin_isdigit (tree arglist
)
8589 if (! validate_arglist (arglist
, INTEGER_TYPE
, VOID_TYPE
))
8593 /* Transform isdigit(c) -> (unsigned)(c) - '0' <= 9. */
8594 /* According to the C standard, isdigit is unaffected by locale.
8595 However, it definitely is affected by the target character set. */
8597 unsigned HOST_WIDE_INT target_digit0
8598 = lang_hooks
.to_target_charset ('0');
8600 if (target_digit0
== 0)
8603 arg
= fold_convert (unsigned_type_node
, TREE_VALUE (arglist
));
8604 arg
= build2 (MINUS_EXPR
, unsigned_type_node
, arg
,
8605 build_int_cst (unsigned_type_node
, target_digit0
));
8606 arg
= fold_build2 (LE_EXPR
, integer_type_node
, arg
,
8607 build_int_cst (unsigned_type_node
, 9));
8608 if (in_gimple_form
&& !TREE_CONSTANT (arg
))
8615 /* Fold a call to fabs, fabsf or fabsl. */
8618 fold_builtin_fabs (tree arglist
, tree type
)
8622 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
8625 arg
= TREE_VALUE (arglist
);
8626 arg
= fold_convert (type
, arg
);
8627 if (TREE_CODE (arg
) == REAL_CST
)
8628 return fold_abs_const (arg
, type
);
8629 return fold_build1 (ABS_EXPR
, type
, arg
);
8632 /* Fold a call to abs, labs, llabs or imaxabs. */
8635 fold_builtin_abs (tree arglist
, tree type
)
8639 if (!validate_arglist (arglist
, INTEGER_TYPE
, VOID_TYPE
))
8642 arg
= TREE_VALUE (arglist
);
8643 arg
= fold_convert (type
, arg
);
8644 if (TREE_CODE (arg
) == INTEGER_CST
)
8645 return fold_abs_const (arg
, type
);
8646 return fold_build1 (ABS_EXPR
, type
, arg
);
8649 /* Fold a call to __builtin_isnan(), __builtin_isinf, __builtin_finite.
8650 EXP is the CALL_EXPR for the call. */
8653 fold_builtin_classify (tree fndecl
, tree arglist
, int builtin_index
)
8655 tree type
= TREE_TYPE (TREE_TYPE (fndecl
));
8659 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
8661 /* Check that we have exactly one argument. */
8664 error ("too few arguments to function %qs",
8665 IDENTIFIER_POINTER (DECL_NAME (fndecl
)));
8666 return error_mark_node
;
8668 else if (TREE_CHAIN (arglist
) != 0)
8670 error ("too many arguments to function %qs",
8671 IDENTIFIER_POINTER (DECL_NAME (fndecl
)));
8672 return error_mark_node
;
8676 error ("non-floating-point argument to function %qs",
8677 IDENTIFIER_POINTER (DECL_NAME (fndecl
)));
8678 return error_mark_node
;
8682 arg
= TREE_VALUE (arglist
);
8683 switch (builtin_index
)
8685 case BUILT_IN_ISINF
:
8686 if (!MODE_HAS_INFINITIES (TYPE_MODE (TREE_TYPE (arg
))))
8687 return omit_one_operand (type
, integer_zero_node
, arg
);
8689 if (TREE_CODE (arg
) == REAL_CST
)
8691 r
= TREE_REAL_CST (arg
);
8692 if (real_isinf (&r
))
8693 return real_compare (GT_EXPR
, &r
, &dconst0
)
8694 ? integer_one_node
: integer_minus_one_node
;
8696 return integer_zero_node
;
8701 case BUILT_IN_FINITE
:
8702 if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg
)))
8703 && !MODE_HAS_INFINITIES (TYPE_MODE (TREE_TYPE (arg
))))
8704 return omit_one_operand (type
, integer_zero_node
, arg
);
8706 if (TREE_CODE (arg
) == REAL_CST
)
8708 r
= TREE_REAL_CST (arg
);
8709 return real_isinf (&r
) || real_isnan (&r
)
8710 ? integer_zero_node
: integer_one_node
;
8715 case BUILT_IN_ISNAN
:
8716 if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg
))))
8717 return omit_one_operand (type
, integer_zero_node
, arg
);
8719 if (TREE_CODE (arg
) == REAL_CST
)
8721 r
= TREE_REAL_CST (arg
);
8722 return real_isnan (&r
) ? integer_one_node
: integer_zero_node
;
8725 arg
= builtin_save_expr (arg
);
8726 return fold_build2 (UNORDERED_EXPR
, type
, arg
, arg
);
8733 /* Fold a call to an unordered comparison function such as
8734 __builtin_isgreater(). FNDECL is the FUNCTION_DECL for the function
8735 being called and ARGLIST is the argument list for the call.
8736 UNORDERED_CODE and ORDERED_CODE are comparison codes that give
8737 the opposite of the desired result. UNORDERED_CODE is used
8738 for modes that can hold NaNs and ORDERED_CODE is used for
8742 fold_builtin_unordered_cmp (tree fndecl
, tree arglist
,
8743 enum tree_code unordered_code
,
8744 enum tree_code ordered_code
)
8746 tree type
= TREE_TYPE (TREE_TYPE (fndecl
));
8747 enum tree_code code
;
8750 enum tree_code code0
, code1
;
8751 tree cmp_type
= NULL_TREE
;
8753 if (!validate_arglist (arglist
, REAL_TYPE
, REAL_TYPE
, VOID_TYPE
))
8755 /* Check that we have exactly two arguments. */
8756 if (arglist
== 0 || TREE_CHAIN (arglist
) == 0)
8758 error ("too few arguments to function %qs",
8759 IDENTIFIER_POINTER (DECL_NAME (fndecl
)));
8760 return error_mark_node
;
8762 else if (TREE_CHAIN (TREE_CHAIN (arglist
)) != 0)
8764 error ("too many arguments to function %qs",
8765 IDENTIFIER_POINTER (DECL_NAME (fndecl
)));
8766 return error_mark_node
;
8770 arg0
= TREE_VALUE (arglist
);
8771 arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
8773 type0
= TREE_TYPE (arg0
);
8774 type1
= TREE_TYPE (arg1
);
8776 code0
= TREE_CODE (type0
);
8777 code1
= TREE_CODE (type1
);
8779 if (code0
== REAL_TYPE
&& code1
== REAL_TYPE
)
8780 /* Choose the wider of two real types. */
8781 cmp_type
= TYPE_PRECISION (type0
) >= TYPE_PRECISION (type1
)
8783 else if (code0
== REAL_TYPE
&& code1
== INTEGER_TYPE
)
8785 else if (code0
== INTEGER_TYPE
&& code1
== REAL_TYPE
)
8789 error ("non-floating-point argument to function %qs",
8790 IDENTIFIER_POINTER (DECL_NAME (fndecl
)));
8791 return error_mark_node
;
8794 arg0
= fold_convert (cmp_type
, arg0
);
8795 arg1
= fold_convert (cmp_type
, arg1
);
8797 if (unordered_code
== UNORDERED_EXPR
)
8799 if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg0
))))
8800 return omit_two_operands (type
, integer_zero_node
, arg0
, arg1
);
8801 return fold_build2 (UNORDERED_EXPR
, type
, arg0
, arg1
);
8804 code
= MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg0
))) ? unordered_code
8806 return fold_build1 (TRUTH_NOT_EXPR
, type
,
8807 fold_build2 (code
, type
, arg0
, arg1
));
8810 /* Used by constant folding to simplify calls to builtin functions. EXP is
8811 the CALL_EXPR of a call to a builtin function. IGNORE is true if the
8812 result of the function call is ignored. This function returns NULL_TREE
8813 if no simplification was possible. */
8816 fold_builtin_1 (tree fndecl
, tree arglist
, bool ignore
)
8818 tree type
= TREE_TYPE (TREE_TYPE (fndecl
));
8819 enum built_in_function fcode
;
8821 if (DECL_BUILT_IN_CLASS (fndecl
) == BUILT_IN_MD
)
8822 return targetm
.fold_builtin (fndecl
, arglist
, ignore
);
8824 fcode
= DECL_FUNCTION_CODE (fndecl
);
8827 case BUILT_IN_FPUTS
:
8828 return fold_builtin_fputs (arglist
, ignore
, false, NULL_TREE
);
8830 case BUILT_IN_FPUTS_UNLOCKED
:
8831 return fold_builtin_fputs (arglist
, ignore
, true, NULL_TREE
);
8833 case BUILT_IN_STRSTR
:
8834 return fold_builtin_strstr (arglist
, type
);
8836 case BUILT_IN_STRCAT
:
8837 return fold_builtin_strcat (arglist
);
8839 case BUILT_IN_STRNCAT
:
8840 return fold_builtin_strncat (arglist
);
8842 case BUILT_IN_STRSPN
:
8843 return fold_builtin_strspn (arglist
);
8845 case BUILT_IN_STRCSPN
:
8846 return fold_builtin_strcspn (arglist
);
8848 case BUILT_IN_STRCHR
:
8849 case BUILT_IN_INDEX
:
8850 return fold_builtin_strchr (arglist
, type
);
8852 case BUILT_IN_STRRCHR
:
8853 case BUILT_IN_RINDEX
:
8854 return fold_builtin_strrchr (arglist
, type
);
8856 case BUILT_IN_STRCPY
:
8857 return fold_builtin_strcpy (fndecl
, arglist
, NULL_TREE
);
8859 case BUILT_IN_STRNCPY
:
8860 return fold_builtin_strncpy (fndecl
, arglist
, NULL_TREE
);
8862 case BUILT_IN_STRCMP
:
8863 return fold_builtin_strcmp (arglist
);
8865 case BUILT_IN_STRNCMP
:
8866 return fold_builtin_strncmp (arglist
);
8868 case BUILT_IN_STRPBRK
:
8869 return fold_builtin_strpbrk (arglist
, type
);
8872 case BUILT_IN_MEMCMP
:
8873 return fold_builtin_memcmp (arglist
);
8875 case BUILT_IN_SPRINTF
:
8876 return fold_builtin_sprintf (arglist
, ignore
);
8878 case BUILT_IN_CONSTANT_P
:
8882 val
= fold_builtin_constant_p (arglist
);
8883 /* Gimplification will pull the CALL_EXPR for the builtin out of
8884 an if condition. When not optimizing, we'll not CSE it back.
8885 To avoid link error types of regressions, return false now. */
8886 if (!val
&& !optimize
)
8887 val
= integer_zero_node
;
8892 case BUILT_IN_EXPECT
:
8893 return fold_builtin_expect (arglist
);
8895 case BUILT_IN_CLASSIFY_TYPE
:
8896 return fold_builtin_classify_type (arglist
);
8898 case BUILT_IN_STRLEN
:
8899 return fold_builtin_strlen (arglist
);
8901 CASE_FLT_FN (BUILT_IN_FABS
):
8902 return fold_builtin_fabs (arglist
, type
);
8906 case BUILT_IN_LLABS
:
8907 case BUILT_IN_IMAXABS
:
8908 return fold_builtin_abs (arglist
, type
);
8910 CASE_FLT_FN (BUILT_IN_CONJ
):
8911 if (validate_arglist (arglist
, COMPLEX_TYPE
, VOID_TYPE
))
8912 return fold_build1 (CONJ_EXPR
, type
, TREE_VALUE (arglist
));
8915 CASE_FLT_FN (BUILT_IN_CREAL
):
8916 if (validate_arglist (arglist
, COMPLEX_TYPE
, VOID_TYPE
))
8917 return non_lvalue (fold_build1 (REALPART_EXPR
, type
,
8918 TREE_VALUE (arglist
)));
8921 CASE_FLT_FN (BUILT_IN_CIMAG
):
8922 if (validate_arglist (arglist
, COMPLEX_TYPE
, VOID_TYPE
))
8923 return non_lvalue (fold_build1 (IMAGPART_EXPR
, type
,
8924 TREE_VALUE (arglist
)));
8927 CASE_FLT_FN (BUILT_IN_CABS
):
8928 return fold_builtin_cabs (arglist
, type
, fndecl
);
8930 CASE_FLT_FN (BUILT_IN_SQRT
):
8931 return fold_builtin_sqrt (arglist
, type
);
8933 CASE_FLT_FN (BUILT_IN_CBRT
):
8934 return fold_builtin_cbrt (arglist
, type
);
8936 CASE_FLT_FN (BUILT_IN_SIN
):
8937 return fold_builtin_sin (arglist
);
8939 CASE_FLT_FN (BUILT_IN_COS
):
8940 return fold_builtin_cos (arglist
, type
, fndecl
);
8942 CASE_FLT_FN (BUILT_IN_EXP
):
8943 return fold_builtin_exponent (fndecl
, arglist
, &dconste
);
8945 CASE_FLT_FN (BUILT_IN_EXP2
):
8946 return fold_builtin_exponent (fndecl
, arglist
, &dconst2
);
8948 CASE_FLT_FN (BUILT_IN_EXP10
):
8949 CASE_FLT_FN (BUILT_IN_POW10
):
8950 return fold_builtin_exponent (fndecl
, arglist
, &dconst10
);
8952 CASE_FLT_FN (BUILT_IN_LOG
):
8953 return fold_builtin_logarithm (fndecl
, arglist
, &dconste
);
8955 CASE_FLT_FN (BUILT_IN_LOG2
):
8956 return fold_builtin_logarithm (fndecl
, arglist
, &dconst2
);
8958 CASE_FLT_FN (BUILT_IN_LOG10
):
8959 return fold_builtin_logarithm (fndecl
, arglist
, &dconst10
);
8961 CASE_FLT_FN (BUILT_IN_TAN
):
8962 return fold_builtin_tan (arglist
);
8964 CASE_FLT_FN (BUILT_IN_ATAN
):
8965 return fold_builtin_atan (arglist
, type
);
8967 CASE_FLT_FN (BUILT_IN_POW
):
8968 return fold_builtin_pow (fndecl
, arglist
, type
);
8970 CASE_FLT_FN (BUILT_IN_POWI
):
8971 return fold_builtin_powi (fndecl
, arglist
, type
);
8973 CASE_FLT_FN (BUILT_IN_INF
):
8974 case BUILT_IN_INFD32
:
8975 case BUILT_IN_INFD64
:
8976 case BUILT_IN_INFD128
:
8977 return fold_builtin_inf (type
, true);
8979 CASE_FLT_FN (BUILT_IN_HUGE_VAL
):
8980 return fold_builtin_inf (type
, false);
8982 CASE_FLT_FN (BUILT_IN_NAN
):
8983 case BUILT_IN_NAND32
:
8984 case BUILT_IN_NAND64
:
8985 case BUILT_IN_NAND128
:
8986 return fold_builtin_nan (arglist
, type
, true);
8988 CASE_FLT_FN (BUILT_IN_NANS
):
8989 return fold_builtin_nan (arglist
, type
, false);
8991 CASE_FLT_FN (BUILT_IN_FLOOR
):
8992 return fold_builtin_floor (fndecl
, arglist
);
8994 CASE_FLT_FN (BUILT_IN_CEIL
):
8995 return fold_builtin_ceil (fndecl
, arglist
);
8997 CASE_FLT_FN (BUILT_IN_TRUNC
):
8998 return fold_builtin_trunc (fndecl
, arglist
);
9000 CASE_FLT_FN (BUILT_IN_ROUND
):
9001 return fold_builtin_round (fndecl
, arglist
);
9003 CASE_FLT_FN (BUILT_IN_NEARBYINT
):
9004 CASE_FLT_FN (BUILT_IN_RINT
):
9005 return fold_trunc_transparent_mathfn (fndecl
, arglist
);
9007 CASE_FLT_FN (BUILT_IN_LCEIL
):
9008 CASE_FLT_FN (BUILT_IN_LLCEIL
):
9009 CASE_FLT_FN (BUILT_IN_LFLOOR
):
9010 CASE_FLT_FN (BUILT_IN_LLFLOOR
):
9011 CASE_FLT_FN (BUILT_IN_LROUND
):
9012 CASE_FLT_FN (BUILT_IN_LLROUND
):
9013 return fold_builtin_int_roundingfn (fndecl
, arglist
);
9015 CASE_FLT_FN (BUILT_IN_LRINT
):
9016 CASE_FLT_FN (BUILT_IN_LLRINT
):
9017 return fold_fixed_mathfn (fndecl
, arglist
);
9019 CASE_INT_FN (BUILT_IN_FFS
):
9020 CASE_INT_FN (BUILT_IN_CLZ
):
9021 CASE_INT_FN (BUILT_IN_CTZ
):
9022 CASE_INT_FN (BUILT_IN_POPCOUNT
):
9023 CASE_INT_FN (BUILT_IN_PARITY
):
9024 return fold_builtin_bitop (fndecl
, arglist
);
9026 case BUILT_IN_MEMSET
:
9027 return fold_builtin_memset (arglist
, type
, ignore
);
9029 case BUILT_IN_MEMCPY
:
9030 return fold_builtin_memory_op (arglist
, type
, ignore
, /*endp=*/0);
9032 case BUILT_IN_MEMPCPY
:
9033 return fold_builtin_memory_op (arglist
, type
, ignore
, /*endp=*/1);
9035 case BUILT_IN_MEMMOVE
:
9036 return fold_builtin_memory_op (arglist
, type
, ignore
, /*endp=*/3);
9038 case BUILT_IN_BZERO
:
9039 return fold_builtin_bzero (arglist
, ignore
);
9041 case BUILT_IN_BCOPY
:
9042 return fold_builtin_bcopy (arglist
, ignore
);
9044 CASE_FLT_FN (BUILT_IN_SIGNBIT
):
9045 return fold_builtin_signbit (fndecl
, arglist
);
9047 case BUILT_IN_ISASCII
:
9048 return fold_builtin_isascii (arglist
);
9050 case BUILT_IN_TOASCII
:
9051 return fold_builtin_toascii (arglist
);
9053 case BUILT_IN_ISDIGIT
:
9054 return fold_builtin_isdigit (arglist
);
9056 CASE_FLT_FN (BUILT_IN_COPYSIGN
):
9057 return fold_builtin_copysign (fndecl
, arglist
, type
);
9059 CASE_FLT_FN (BUILT_IN_FINITE
):
9060 case BUILT_IN_FINITED32
:
9061 case BUILT_IN_FINITED64
:
9062 case BUILT_IN_FINITED128
:
9063 return fold_builtin_classify (fndecl
, arglist
, BUILT_IN_FINITE
);
9065 CASE_FLT_FN (BUILT_IN_ISINF
):
9066 case BUILT_IN_ISINFD32
:
9067 case BUILT_IN_ISINFD64
:
9068 case BUILT_IN_ISINFD128
:
9069 return fold_builtin_classify (fndecl
, arglist
, BUILT_IN_ISINF
);
9071 CASE_FLT_FN (BUILT_IN_ISNAN
):
9072 case BUILT_IN_ISNAND32
:
9073 case BUILT_IN_ISNAND64
:
9074 case BUILT_IN_ISNAND128
:
9075 return fold_builtin_classify (fndecl
, arglist
, BUILT_IN_ISNAN
);
9077 case BUILT_IN_ISGREATER
:
9078 return fold_builtin_unordered_cmp (fndecl
, arglist
, UNLE_EXPR
, LE_EXPR
);
9079 case BUILT_IN_ISGREATEREQUAL
:
9080 return fold_builtin_unordered_cmp (fndecl
, arglist
, UNLT_EXPR
, LT_EXPR
);
9081 case BUILT_IN_ISLESS
:
9082 return fold_builtin_unordered_cmp (fndecl
, arglist
, UNGE_EXPR
, GE_EXPR
);
9083 case BUILT_IN_ISLESSEQUAL
:
9084 return fold_builtin_unordered_cmp (fndecl
, arglist
, UNGT_EXPR
, GT_EXPR
);
9085 case BUILT_IN_ISLESSGREATER
:
9086 return fold_builtin_unordered_cmp (fndecl
, arglist
, UNEQ_EXPR
, EQ_EXPR
);
9087 case BUILT_IN_ISUNORDERED
:
9088 return fold_builtin_unordered_cmp (fndecl
, arglist
, UNORDERED_EXPR
,
9091 /* We do the folding for va_start in the expander. */
9092 case BUILT_IN_VA_START
:
9095 case BUILT_IN_OBJECT_SIZE
:
9096 return fold_builtin_object_size (arglist
);
9097 case BUILT_IN_MEMCPY_CHK
:
9098 case BUILT_IN_MEMPCPY_CHK
:
9099 case BUILT_IN_MEMMOVE_CHK
:
9100 case BUILT_IN_MEMSET_CHK
:
9101 return fold_builtin_memory_chk (fndecl
, arglist
, NULL_TREE
, ignore
,
9102 DECL_FUNCTION_CODE (fndecl
));
9103 case BUILT_IN_STRCPY_CHK
:
9104 case BUILT_IN_STPCPY_CHK
:
9105 return fold_builtin_stxcpy_chk (fndecl
, arglist
, NULL_TREE
, ignore
,
9106 DECL_FUNCTION_CODE (fndecl
));
9107 case BUILT_IN_STRNCPY_CHK
:
9108 return fold_builtin_strncpy_chk (arglist
, NULL_TREE
);
9109 case BUILT_IN_STRCAT_CHK
:
9110 return fold_builtin_strcat_chk (fndecl
, arglist
);
9111 case BUILT_IN_STRNCAT_CHK
:
9112 return fold_builtin_strncat_chk (fndecl
, arglist
);
9113 case BUILT_IN_SPRINTF_CHK
:
9114 case BUILT_IN_VSPRINTF_CHK
:
9115 return fold_builtin_sprintf_chk (arglist
, DECL_FUNCTION_CODE (fndecl
));
9116 case BUILT_IN_SNPRINTF_CHK
:
9117 case BUILT_IN_VSNPRINTF_CHK
:
9118 return fold_builtin_snprintf_chk (arglist
, NULL_TREE
,
9119 DECL_FUNCTION_CODE (fndecl
));
9121 case BUILT_IN_PRINTF
:
9122 case BUILT_IN_PRINTF_UNLOCKED
:
9123 case BUILT_IN_VPRINTF
:
9124 case BUILT_IN_PRINTF_CHK
:
9125 case BUILT_IN_VPRINTF_CHK
:
9126 return fold_builtin_printf (fndecl
, arglist
, ignore
,
9127 DECL_FUNCTION_CODE (fndecl
));
9129 case BUILT_IN_FPRINTF
:
9130 case BUILT_IN_FPRINTF_UNLOCKED
:
9131 case BUILT_IN_VFPRINTF
:
9132 case BUILT_IN_FPRINTF_CHK
:
9133 case BUILT_IN_VFPRINTF_CHK
:
9134 return fold_builtin_fprintf (fndecl
, arglist
, ignore
,
9135 DECL_FUNCTION_CODE (fndecl
));
9144 /* A wrapper function for builtin folding that prevents warnings for
9145 "statement without effect" and the like, caused by removing the
9146 call node earlier than the warning is generated. */
9149 fold_builtin (tree fndecl
, tree arglist
, bool ignore
)
9151 tree exp
= fold_builtin_1 (fndecl
, arglist
, ignore
);
9154 exp
= build1 (NOP_EXPR
, TREE_TYPE (exp
), exp
);
9155 TREE_NO_WARNING (exp
) = 1;
9161 /* Conveniently construct a function call expression. */
9164 build_function_call_expr (tree fn
, tree arglist
)
9168 call_expr
= build1 (ADDR_EXPR
, build_pointer_type (TREE_TYPE (fn
)), fn
);
9169 return fold_build3 (CALL_EXPR
, TREE_TYPE (TREE_TYPE (fn
)),
9170 call_expr
, arglist
, NULL_TREE
);
9173 /* This function validates the types of a function call argument list
9174 represented as a tree chain of parameters against a specified list
9175 of tree_codes. If the last specifier is a 0, that represents an
9176 ellipses, otherwise the last specifier must be a VOID_TYPE. */
9179 validate_arglist (tree arglist
, ...)
9181 enum tree_code code
;
9185 va_start (ap
, arglist
);
9189 code
= va_arg (ap
, enum tree_code
);
9193 /* This signifies an ellipses, any further arguments are all ok. */
9197 /* This signifies an endlink, if no arguments remain, return
9198 true, otherwise return false. */
9202 /* If no parameters remain or the parameter's code does not
9203 match the specified code, return false. Otherwise continue
9204 checking any remaining arguments. */
9207 if (code
== POINTER_TYPE
)
9209 if (! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist
))))
9212 else if (code
!= TREE_CODE (TREE_TYPE (TREE_VALUE (arglist
))))
9216 arglist
= TREE_CHAIN (arglist
);
9220 /* We need gotos here since we can only have one VA_CLOSE in a
9228 /* Default target-specific builtin expander that does nothing. */
9231 default_expand_builtin (tree exp ATTRIBUTE_UNUSED
,
9232 rtx target ATTRIBUTE_UNUSED
,
9233 rtx subtarget ATTRIBUTE_UNUSED
,
9234 enum machine_mode mode ATTRIBUTE_UNUSED
,
9235 int ignore ATTRIBUTE_UNUSED
)
9240 /* Returns true is EXP represents data that would potentially reside
9241 in a readonly section. */
9244 readonly_data_expr (tree exp
)
9248 if (TREE_CODE (exp
) != ADDR_EXPR
)
9251 exp
= get_base_address (TREE_OPERAND (exp
, 0));
9255 /* Make sure we call decl_readonly_section only for trees it
9256 can handle (since it returns true for everything it doesn't
9258 if (TREE_CODE (exp
) == STRING_CST
9259 || TREE_CODE (exp
) == CONSTRUCTOR
9260 || (TREE_CODE (exp
) == VAR_DECL
&& TREE_STATIC (exp
)))
9261 return decl_readonly_section (exp
, 0);
9266 /* Simplify a call to the strstr builtin.
9268 Return 0 if no simplification was possible, otherwise return the
9269 simplified form of the call as a tree.
9271 The simplified form may be a constant or other expression which
9272 computes the same value, but in a more efficient manner (including
9273 calls to other builtin functions).
9275 The call may contain arguments which need to be evaluated, but
9276 which are not useful to determine the result of the call. In
9277 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9278 COMPOUND_EXPR will be an argument which must be evaluated.
9279 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9280 COMPOUND_EXPR in the chain will contain the tree for the simplified
9281 form of the builtin function call. */
9284 fold_builtin_strstr (tree arglist
, tree type
)
9286 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
9290 tree s1
= TREE_VALUE (arglist
), s2
= TREE_VALUE (TREE_CHAIN (arglist
));
9292 const char *p1
, *p2
;
9301 const char *r
= strstr (p1
, p2
);
9305 return build_int_cst (TREE_TYPE (s1
), 0);
9307 /* Return an offset into the constant string argument. */
9308 tem
= fold_build2 (PLUS_EXPR
, TREE_TYPE (s1
),
9309 s1
, build_int_cst (TREE_TYPE (s1
), r
- p1
));
9310 return fold_convert (type
, tem
);
9313 /* The argument is const char *, and the result is char *, so we need
9314 a type conversion here to avoid a warning. */
9316 return fold_convert (type
, s1
);
9321 fn
= implicit_built_in_decls
[BUILT_IN_STRCHR
];
9325 /* New argument list transforming strstr(s1, s2) to
9326 strchr(s1, s2[0]). */
9327 arglist
= build_tree_list (NULL_TREE
,
9328 build_int_cst (NULL_TREE
, p2
[0]));
9329 arglist
= tree_cons (NULL_TREE
, s1
, arglist
);
9330 return build_function_call_expr (fn
, arglist
);
9334 /* Simplify a call to the strchr builtin.
9336 Return 0 if no simplification was possible, otherwise return the
9337 simplified form of the call as a tree.
9339 The simplified form may be a constant or other expression which
9340 computes the same value, but in a more efficient manner (including
9341 calls to other builtin functions).
9343 The call may contain arguments which need to be evaluated, but
9344 which are not useful to determine the result of the call. In
9345 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9346 COMPOUND_EXPR will be an argument which must be evaluated.
9347 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9348 COMPOUND_EXPR in the chain will contain the tree for the simplified
9349 form of the builtin function call. */
9352 fold_builtin_strchr (tree arglist
, tree type
)
9354 if (!validate_arglist (arglist
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
9358 tree s1
= TREE_VALUE (arglist
), s2
= TREE_VALUE (TREE_CHAIN (arglist
));
9361 if (TREE_CODE (s2
) != INTEGER_CST
)
9371 if (target_char_cast (s2
, &c
))
9377 return build_int_cst (TREE_TYPE (s1
), 0);
9379 /* Return an offset into the constant string argument. */
9380 tem
= fold_build2 (PLUS_EXPR
, TREE_TYPE (s1
),
9381 s1
, build_int_cst (TREE_TYPE (s1
), r
- p1
));
9382 return fold_convert (type
, tem
);
9388 /* Simplify a call to the strrchr builtin.
9390 Return 0 if no simplification was possible, otherwise return the
9391 simplified form of the call as a tree.
9393 The simplified form may be a constant or other expression which
9394 computes the same value, but in a more efficient manner (including
9395 calls to other builtin functions).
9397 The call may contain arguments which need to be evaluated, but
9398 which are not useful to determine the result of the call. In
9399 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9400 COMPOUND_EXPR will be an argument which must be evaluated.
9401 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9402 COMPOUND_EXPR in the chain will contain the tree for the simplified
9403 form of the builtin function call. */
9406 fold_builtin_strrchr (tree arglist
, tree type
)
9408 if (!validate_arglist (arglist
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
9412 tree s1
= TREE_VALUE (arglist
), s2
= TREE_VALUE (TREE_CHAIN (arglist
));
9416 if (TREE_CODE (s2
) != INTEGER_CST
)
9426 if (target_char_cast (s2
, &c
))
9429 r
= strrchr (p1
, c
);
9432 return build_int_cst (TREE_TYPE (s1
), 0);
9434 /* Return an offset into the constant string argument. */
9435 tem
= fold_build2 (PLUS_EXPR
, TREE_TYPE (s1
),
9436 s1
, build_int_cst (TREE_TYPE (s1
), r
- p1
));
9437 return fold_convert (type
, tem
);
9440 if (! integer_zerop (s2
))
9443 fn
= implicit_built_in_decls
[BUILT_IN_STRCHR
];
9447 /* Transform strrchr(s1, '\0') to strchr(s1, '\0'). */
9448 return build_function_call_expr (fn
, arglist
);
9452 /* Simplify a call to the strpbrk builtin.
9454 Return 0 if no simplification was possible, otherwise return the
9455 simplified form of the call as a tree.
9457 The simplified form may be a constant or other expression which
9458 computes the same value, but in a more efficient manner (including
9459 calls to other builtin functions).
9461 The call may contain arguments which need to be evaluated, but
9462 which are not useful to determine the result of the call. In
9463 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9464 COMPOUND_EXPR will be an argument which must be evaluated.
9465 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9466 COMPOUND_EXPR in the chain will contain the tree for the simplified
9467 form of the builtin function call. */
9470 fold_builtin_strpbrk (tree arglist
, tree type
)
9472 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
9476 tree s1
= TREE_VALUE (arglist
), s2
= TREE_VALUE (TREE_CHAIN (arglist
));
9478 const char *p1
, *p2
;
9487 const char *r
= strpbrk (p1
, p2
);
9491 return build_int_cst (TREE_TYPE (s1
), 0);
9493 /* Return an offset into the constant string argument. */
9494 tem
= fold_build2 (PLUS_EXPR
, TREE_TYPE (s1
),
9495 s1
, build_int_cst (TREE_TYPE (s1
), r
- p1
));
9496 return fold_convert (type
, tem
);
9500 /* strpbrk(x, "") == NULL.
9501 Evaluate and ignore s1 in case it had side-effects. */
9502 return omit_one_operand (TREE_TYPE (s1
), integer_zero_node
, s1
);
9505 return 0; /* Really call strpbrk. */
9507 fn
= implicit_built_in_decls
[BUILT_IN_STRCHR
];
9511 /* New argument list transforming strpbrk(s1, s2) to
9512 strchr(s1, s2[0]). */
9513 arglist
= build_tree_list (NULL_TREE
,
9514 build_int_cst (NULL_TREE
, p2
[0]));
9515 arglist
= tree_cons (NULL_TREE
, s1
, arglist
);
9516 return build_function_call_expr (fn
, arglist
);
9520 /* Simplify a call to the strcat builtin.
9522 Return 0 if no simplification was possible, otherwise return the
9523 simplified form of the call as a tree.
9525 The simplified form may be a constant or other expression which
9526 computes the same value, but in a more efficient manner (including
9527 calls to other builtin functions).
9529 The call may contain arguments which need to be evaluated, but
9530 which are not useful to determine the result of the call. In
9531 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9532 COMPOUND_EXPR will be an argument which must be evaluated.
9533 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9534 COMPOUND_EXPR in the chain will contain the tree for the simplified
9535 form of the builtin function call. */
9538 fold_builtin_strcat (tree arglist
)
9540 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
9544 tree dst
= TREE_VALUE (arglist
),
9545 src
= TREE_VALUE (TREE_CHAIN (arglist
));
9546 const char *p
= c_getstr (src
);
9548 /* If the string length is zero, return the dst parameter. */
9549 if (p
&& *p
== '\0')
9556 /* Simplify a call to the strncat builtin.
9558 Return 0 if no simplification was possible, otherwise return the
9559 simplified form of the call as a tree.
9561 The simplified form may be a constant or other expression which
9562 computes the same value, but in a more efficient manner (including
9563 calls to other builtin functions).
9565 The call may contain arguments which need to be evaluated, but
9566 which are not useful to determine the result of the call. In
9567 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9568 COMPOUND_EXPR will be an argument which must be evaluated.
9569 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9570 COMPOUND_EXPR in the chain will contain the tree for the simplified
9571 form of the builtin function call. */
9574 fold_builtin_strncat (tree arglist
)
9576 if (!validate_arglist (arglist
,
9577 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
9581 tree dst
= TREE_VALUE (arglist
);
9582 tree src
= TREE_VALUE (TREE_CHAIN (arglist
));
9583 tree len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
9584 const char *p
= c_getstr (src
);
9586 /* If the requested length is zero, or the src parameter string
9587 length is zero, return the dst parameter. */
9588 if (integer_zerop (len
) || (p
&& *p
== '\0'))
9589 return omit_two_operands (TREE_TYPE (dst
), dst
, src
, len
);
9591 /* If the requested len is greater than or equal to the string
9592 length, call strcat. */
9593 if (TREE_CODE (len
) == INTEGER_CST
&& p
9594 && compare_tree_int (len
, strlen (p
)) >= 0)
9597 = tree_cons (NULL_TREE
, dst
, build_tree_list (NULL_TREE
, src
));
9598 tree fn
= implicit_built_in_decls
[BUILT_IN_STRCAT
];
9600 /* If the replacement _DECL isn't initialized, don't do the
9605 return build_function_call_expr (fn
, newarglist
);
9611 /* Simplify a call to the strspn builtin.
9613 Return 0 if no simplification was possible, otherwise return the
9614 simplified form of the call as a tree.
9616 The simplified form may be a constant or other expression which
9617 computes the same value, but in a more efficient manner (including
9618 calls to other builtin functions).
9620 The call may contain arguments which need to be evaluated, but
9621 which are not useful to determine the result of the call. In
9622 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9623 COMPOUND_EXPR will be an argument which must be evaluated.
9624 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9625 COMPOUND_EXPR in the chain will contain the tree for the simplified
9626 form of the builtin function call. */
9629 fold_builtin_strspn (tree arglist
)
9631 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
9635 tree s1
= TREE_VALUE (arglist
), s2
= TREE_VALUE (TREE_CHAIN (arglist
));
9636 const char *p1
= c_getstr (s1
), *p2
= c_getstr (s2
);
9638 /* If both arguments are constants, evaluate at compile-time. */
9641 const size_t r
= strspn (p1
, p2
);
9642 return size_int (r
);
9645 /* If either argument is "", return 0. */
9646 if ((p1
&& *p1
== '\0') || (p2
&& *p2
== '\0'))
9647 /* Evaluate and ignore both arguments in case either one has
9649 return omit_two_operands (integer_type_node
, integer_zero_node
,
9655 /* Simplify a call to the strcspn builtin.
9657 Return 0 if no simplification was possible, otherwise return the
9658 simplified form of the call as a tree.
9660 The simplified form may be a constant or other expression which
9661 computes the same value, but in a more efficient manner (including
9662 calls to other builtin functions).
9664 The call may contain arguments which need to be evaluated, but
9665 which are not useful to determine the result of the call. In
9666 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9667 COMPOUND_EXPR will be an argument which must be evaluated.
9668 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9669 COMPOUND_EXPR in the chain will contain the tree for the simplified
9670 form of the builtin function call. */
9673 fold_builtin_strcspn (tree arglist
)
9675 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
9679 tree s1
= TREE_VALUE (arglist
), s2
= TREE_VALUE (TREE_CHAIN (arglist
));
9680 const char *p1
= c_getstr (s1
), *p2
= c_getstr (s2
);
9682 /* If both arguments are constants, evaluate at compile-time. */
9685 const size_t r
= strcspn (p1
, p2
);
9686 return size_int (r
);
9689 /* If the first argument is "", return 0. */
9690 if (p1
&& *p1
== '\0')
9692 /* Evaluate and ignore argument s2 in case it has
9694 return omit_one_operand (integer_type_node
,
9695 integer_zero_node
, s2
);
9698 /* If the second argument is "", return __builtin_strlen(s1). */
9699 if (p2
&& *p2
== '\0')
9701 tree newarglist
= build_tree_list (NULL_TREE
, s1
),
9702 fn
= implicit_built_in_decls
[BUILT_IN_STRLEN
];
9704 /* If the replacement _DECL isn't initialized, don't do the
9709 return build_function_call_expr (fn
, newarglist
);
9715 /* Fold a call to the fputs builtin. IGNORE is true if the value returned
9716 by the builtin will be ignored. UNLOCKED is true is true if this
9717 actually a call to fputs_unlocked. If LEN in non-NULL, it represents
9718 the known length of the string. Return NULL_TREE if no simplification
9722 fold_builtin_fputs (tree arglist
, bool ignore
, bool unlocked
, tree len
)
9725 /* If we're using an unlocked function, assume the other unlocked
9726 functions exist explicitly. */
9727 tree
const fn_fputc
= unlocked
? built_in_decls
[BUILT_IN_FPUTC_UNLOCKED
]
9728 : implicit_built_in_decls
[BUILT_IN_FPUTC
];
9729 tree
const fn_fwrite
= unlocked
? built_in_decls
[BUILT_IN_FWRITE_UNLOCKED
]
9730 : implicit_built_in_decls
[BUILT_IN_FWRITE
];
9732 /* If the return value is used, don't do the transformation. */
9736 /* Verify the arguments in the original call. */
9737 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
9741 len
= c_strlen (TREE_VALUE (arglist
), 0);
9743 /* Get the length of the string passed to fputs. If the length
9744 can't be determined, punt. */
9746 || TREE_CODE (len
) != INTEGER_CST
)
9749 switch (compare_tree_int (len
, 1))
9751 case -1: /* length is 0, delete the call entirely . */
9752 return omit_one_operand (integer_type_node
, integer_zero_node
,
9753 TREE_VALUE (TREE_CHAIN (arglist
)));
9755 case 0: /* length is 1, call fputc. */
9757 const char *p
= c_getstr (TREE_VALUE (arglist
));
9761 /* New argument list transforming fputs(string, stream) to
9762 fputc(string[0], stream). */
9763 arglist
= build_tree_list (NULL_TREE
,
9764 TREE_VALUE (TREE_CHAIN (arglist
)));
9765 arglist
= tree_cons (NULL_TREE
,
9766 build_int_cst (NULL_TREE
, p
[0]),
9773 case 1: /* length is greater than 1, call fwrite. */
9777 /* If optimizing for size keep fputs. */
9780 string_arg
= TREE_VALUE (arglist
);
9781 /* New argument list transforming fputs(string, stream) to
9782 fwrite(string, 1, len, stream). */
9783 arglist
= build_tree_list (NULL_TREE
,
9784 TREE_VALUE (TREE_CHAIN (arglist
)));
9785 arglist
= tree_cons (NULL_TREE
, len
, arglist
);
9786 arglist
= tree_cons (NULL_TREE
, size_one_node
, arglist
);
9787 arglist
= tree_cons (NULL_TREE
, string_arg
, arglist
);
9795 /* If the replacement _DECL isn't initialized, don't do the
9800 /* These optimizations are only performed when the result is ignored,
9801 hence there's no need to cast the result to integer_type_node. */
9802 return build_function_call_expr (fn
, arglist
);
9805 /* Fold the new_arg's arguments (ARGLIST). Returns true if there was an error
9806 produced. False otherwise. This is done so that we don't output the error
9807 or warning twice or three times. */
9809 fold_builtin_next_arg (tree arglist
)
9811 tree fntype
= TREE_TYPE (current_function_decl
);
9813 if (TYPE_ARG_TYPES (fntype
) == 0
9814 || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype
)))
9817 error ("%<va_start%> used in function with fixed args");
9822 /* Evidently an out of date version of <stdarg.h>; can't validate
9823 va_start's second argument, but can still work as intended. */
9824 warning (0, "%<__builtin_next_arg%> called without an argument");
9827 /* We use __builtin_va_start (ap, 0, 0) or __builtin_next_arg (0, 0)
9828 when we checked the arguments and if needed issued a warning. */
9829 else if (!TREE_CHAIN (arglist
)
9830 || !integer_zerop (TREE_VALUE (arglist
))
9831 || !integer_zerop (TREE_VALUE (TREE_CHAIN (arglist
)))
9832 || TREE_CHAIN (TREE_CHAIN (arglist
)))
9834 tree last_parm
= tree_last (DECL_ARGUMENTS (current_function_decl
));
9835 tree arg
= TREE_VALUE (arglist
);
9837 if (TREE_CHAIN (arglist
))
9839 error ("%<va_start%> used with too many arguments");
9843 /* Strip off all nops for the sake of the comparison. This
9844 is not quite the same as STRIP_NOPS. It does more.
9845 We must also strip off INDIRECT_EXPR for C++ reference
9847 while (TREE_CODE (arg
) == NOP_EXPR
9848 || TREE_CODE (arg
) == CONVERT_EXPR
9849 || TREE_CODE (arg
) == NON_LVALUE_EXPR
9850 || TREE_CODE (arg
) == INDIRECT_REF
)
9851 arg
= TREE_OPERAND (arg
, 0);
9852 if (arg
!= last_parm
)
9854 /* FIXME: Sometimes with the tree optimizers we can get the
9855 not the last argument even though the user used the last
9856 argument. We just warn and set the arg to be the last
9857 argument so that we will get wrong-code because of
9859 warning (0, "second parameter of %<va_start%> not last named argument");
9861 /* We want to verify the second parameter just once before the tree
9862 optimizers are run and then avoid keeping it in the tree,
9863 as otherwise we could warn even for correct code like:
9864 void foo (int i, ...)
9865 { va_list ap; i++; va_start (ap, i); va_end (ap); } */
9866 TREE_VALUE (arglist
) = integer_zero_node
;
9867 TREE_CHAIN (arglist
) = build_tree_list (NULL
, integer_zero_node
);
9873 /* Simplify a call to the sprintf builtin.
9875 Return 0 if no simplification was possible, otherwise return the
9876 simplified form of the call as a tree. If IGNORED is true, it means that
9877 the caller does not use the returned value of the function. */
9880 fold_builtin_sprintf (tree arglist
, int ignored
)
9882 tree call
, retval
, dest
, fmt
;
9883 const char *fmt_str
= NULL
;
9885 /* Verify the required arguments in the original call. We deal with two
9886 types of sprintf() calls: 'sprintf (str, fmt)' and
9887 'sprintf (dest, "%s", orig)'. */
9888 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
)
9889 && !validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, POINTER_TYPE
,
9893 /* Get the destination string and the format specifier. */
9894 dest
= TREE_VALUE (arglist
);
9895 fmt
= TREE_VALUE (TREE_CHAIN (arglist
));
9897 /* Check whether the format is a literal string constant. */
9898 fmt_str
= c_getstr (fmt
);
9899 if (fmt_str
== NULL
)
9905 if (!init_target_chars())
9908 /* If the format doesn't contain % args or %%, use strcpy. */
9909 if (strchr (fmt_str
, target_percent
) == NULL
)
9911 tree fn
= implicit_built_in_decls
[BUILT_IN_STRCPY
];
9916 /* Convert sprintf (str, fmt) into strcpy (str, fmt) when
9917 'format' is known to contain no % formats. */
9918 arglist
= build_tree_list (NULL_TREE
, fmt
);
9919 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
9920 call
= build_function_call_expr (fn
, arglist
);
9922 retval
= build_int_cst (NULL_TREE
, strlen (fmt_str
));
9925 /* If the format is "%s", use strcpy if the result isn't used. */
9926 else if (fmt_str
&& strcmp (fmt_str
, target_percent_s
) == 0)
9929 fn
= implicit_built_in_decls
[BUILT_IN_STRCPY
];
9934 /* Convert sprintf (str1, "%s", str2) into strcpy (str1, str2). */
9935 orig
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
9936 arglist
= build_tree_list (NULL_TREE
, orig
);
9937 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
9940 retval
= c_strlen (orig
, 1);
9941 if (!retval
|| TREE_CODE (retval
) != INTEGER_CST
)
9944 call
= build_function_call_expr (fn
, arglist
);
9949 retval
= fold_convert
9950 (TREE_TYPE (TREE_TYPE (implicit_built_in_decls
[BUILT_IN_SPRINTF
])),
9952 return build2 (COMPOUND_EXPR
, TREE_TYPE (retval
), call
, retval
);
9958 /* Expand a call to __builtin_object_size. */
9961 expand_builtin_object_size (tree exp
)
9964 int object_size_type
;
9965 tree fndecl
= get_callee_fndecl (exp
);
9966 tree arglist
= TREE_OPERAND (exp
, 1);
9967 location_t locus
= EXPR_LOCATION (exp
);
9969 if (!validate_arglist (arglist
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
9971 error ("%Hfirst argument of %D must be a pointer, second integer constant",
9973 expand_builtin_trap ();
9977 ost
= TREE_VALUE (TREE_CHAIN (arglist
));
9980 if (TREE_CODE (ost
) != INTEGER_CST
9981 || tree_int_cst_sgn (ost
) < 0
9982 || compare_tree_int (ost
, 3) > 0)
9984 error ("%Hlast argument of %D is not integer constant between 0 and 3",
9986 expand_builtin_trap ();
9990 object_size_type
= tree_low_cst (ost
, 0);
9992 return object_size_type
< 2 ? constm1_rtx
: const0_rtx
;
9995 /* Expand EXP, a call to the __mem{cpy,pcpy,move,set}_chk builtin.
9996 FCODE is the BUILT_IN_* to use.
9997 Return 0 if we failed; the caller should emit a normal call,
9998 otherwise try to get the result in TARGET, if convenient (and in
9999 mode MODE if that's convenient). */
10002 expand_builtin_memory_chk (tree exp
, rtx target
, enum machine_mode mode
,
10003 enum built_in_function fcode
)
10005 tree arglist
= TREE_OPERAND (exp
, 1);
10006 tree dest
, src
, len
, size
;
10008 if (!validate_arglist (arglist
,
10010 fcode
== BUILT_IN_MEMSET_CHK
10011 ? INTEGER_TYPE
: POINTER_TYPE
,
10012 INTEGER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
10015 dest
= TREE_VALUE (arglist
);
10016 src
= TREE_VALUE (TREE_CHAIN (arglist
));
10017 len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
10018 size
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist
))));
10020 if (! host_integerp (size
, 1))
10023 if (host_integerp (len
, 1) || integer_all_onesp (size
))
10027 if (! integer_all_onesp (size
) && tree_int_cst_lt (size
, len
))
10029 location_t locus
= EXPR_LOCATION (exp
);
10030 warning (0, "%Hcall to %D will always overflow destination buffer",
10031 &locus
, get_callee_fndecl (exp
));
10035 arglist
= build_tree_list (NULL_TREE
, len
);
10036 arglist
= tree_cons (NULL_TREE
, src
, arglist
);
10037 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
10040 /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume
10041 mem{cpy,pcpy,move,set} is available. */
10044 case BUILT_IN_MEMCPY_CHK
:
10045 fn
= built_in_decls
[BUILT_IN_MEMCPY
];
10047 case BUILT_IN_MEMPCPY_CHK
:
10048 fn
= built_in_decls
[BUILT_IN_MEMPCPY
];
10050 case BUILT_IN_MEMMOVE_CHK
:
10051 fn
= built_in_decls
[BUILT_IN_MEMMOVE
];
10053 case BUILT_IN_MEMSET_CHK
:
10054 fn
= built_in_decls
[BUILT_IN_MEMSET
];
10063 fn
= build_function_call_expr (fn
, arglist
);
10064 if (TREE_CODE (fn
) == CALL_EXPR
)
10065 CALL_EXPR_TAILCALL (fn
) = CALL_EXPR_TAILCALL (exp
);
10066 return expand_expr (fn
, target
, mode
, EXPAND_NORMAL
);
10068 else if (fcode
== BUILT_IN_MEMSET_CHK
)
10072 unsigned int dest_align
10073 = get_pointer_alignment (dest
, BIGGEST_ALIGNMENT
);
10075 /* If DEST is not a pointer type, call the normal function. */
10076 if (dest_align
== 0)
10079 /* If SRC and DEST are the same (and not volatile), do nothing. */
10080 if (operand_equal_p (src
, dest
, 0))
10084 if (fcode
!= BUILT_IN_MEMPCPY_CHK
)
10086 /* Evaluate and ignore LEN in case it has side-effects. */
10087 expand_expr (len
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
10088 return expand_expr (dest
, target
, mode
, EXPAND_NORMAL
);
10091 len
= fold_convert (TREE_TYPE (dest
), len
);
10092 expr
= fold_build2 (PLUS_EXPR
, TREE_TYPE (dest
), dest
, len
);
10093 return expand_expr (expr
, target
, mode
, EXPAND_NORMAL
);
10096 /* __memmove_chk special case. */
10097 if (fcode
== BUILT_IN_MEMMOVE_CHK
)
10099 unsigned int src_align
10100 = get_pointer_alignment (src
, BIGGEST_ALIGNMENT
);
10102 if (src_align
== 0)
10105 /* If src is categorized for a readonly section we can use
10106 normal __memcpy_chk. */
10107 if (readonly_data_expr (src
))
10109 tree fn
= built_in_decls
[BUILT_IN_MEMCPY_CHK
];
10112 fn
= build_function_call_expr (fn
, arglist
);
10113 if (TREE_CODE (fn
) == CALL_EXPR
)
10114 CALL_EXPR_TAILCALL (fn
) = CALL_EXPR_TAILCALL (exp
);
10115 return expand_expr (fn
, target
, mode
, EXPAND_NORMAL
);
10122 /* Emit warning if a buffer overflow is detected at compile time. */
10125 maybe_emit_chk_warning (tree exp
, enum built_in_function fcode
)
10127 int arg_mask
, is_strlen
= 0;
10128 tree arglist
= TREE_OPERAND (exp
, 1), a
;
10134 case BUILT_IN_STRCPY_CHK
:
10135 case BUILT_IN_STPCPY_CHK
:
10136 /* For __strcat_chk the warning will be emitted only if overflowing
10137 by at least strlen (dest) + 1 bytes. */
10138 case BUILT_IN_STRCAT_CHK
:
10142 case BUILT_IN_STRNCPY_CHK
:
10145 case BUILT_IN_SNPRINTF_CHK
:
10146 case BUILT_IN_VSNPRINTF_CHK
:
10150 gcc_unreachable ();
10155 for (a
= arglist
; a
&& arg_mask
; a
= TREE_CHAIN (a
), arg_mask
>>= 1)
10167 len
= TREE_VALUE (len
);
10168 size
= TREE_VALUE (size
);
10170 if (! host_integerp (size
, 1) || integer_all_onesp (size
))
10175 len
= c_strlen (len
, 1);
10176 if (! len
|| ! host_integerp (len
, 1) || tree_int_cst_lt (len
, size
))
10179 else if (! host_integerp (len
, 1) || ! tree_int_cst_lt (size
, len
))
10182 locus
= EXPR_LOCATION (exp
);
10183 warning (0, "%Hcall to %D will always overflow destination buffer",
10184 &locus
, get_callee_fndecl (exp
));
10187 /* Emit warning if a buffer overflow is detected at compile time
10188 in __sprintf_chk/__vsprintf_chk calls. */
10191 maybe_emit_sprintf_chk_warning (tree exp
, enum built_in_function fcode
)
10193 tree arglist
= TREE_OPERAND (exp
, 1);
10194 tree dest
, size
, len
, fmt
, flag
;
10195 const char *fmt_str
;
10197 /* Verify the required arguments in the original call. */
10200 dest
= TREE_VALUE (arglist
);
10201 arglist
= TREE_CHAIN (arglist
);
10204 flag
= TREE_VALUE (arglist
);
10205 arglist
= TREE_CHAIN (arglist
);
10208 size
= TREE_VALUE (arglist
);
10209 arglist
= TREE_CHAIN (arglist
);
10212 fmt
= TREE_VALUE (arglist
);
10213 arglist
= TREE_CHAIN (arglist
);
10215 if (! host_integerp (size
, 1) || integer_all_onesp (size
))
10218 /* Check whether the format is a literal string constant. */
10219 fmt_str
= c_getstr (fmt
);
10220 if (fmt_str
== NULL
)
10223 if (!init_target_chars())
10226 /* If the format doesn't contain % args or %%, we know its size. */
10227 if (strchr (fmt_str
, target_percent
) == 0)
10228 len
= build_int_cstu (size_type_node
, strlen (fmt_str
));
10229 /* If the format is "%s" and first ... argument is a string literal,
10231 else if (fcode
== BUILT_IN_SPRINTF_CHK
&& strcmp (fmt_str
, target_percent_s
) == 0)
10237 arg
= TREE_VALUE (arglist
);
10238 if (! POINTER_TYPE_P (TREE_TYPE (arg
)))
10241 len
= c_strlen (arg
, 1);
10242 if (!len
|| ! host_integerp (len
, 1))
10248 if (! tree_int_cst_lt (len
, size
))
10250 location_t locus
= EXPR_LOCATION (exp
);
10251 warning (0, "%Hcall to %D will always overflow destination buffer",
10252 &locus
, get_callee_fndecl (exp
));
10256 /* Fold a call to __builtin_object_size, if possible. */
10259 fold_builtin_object_size (tree arglist
)
10261 tree ptr
, ost
, ret
= 0;
10262 int object_size_type
;
10264 if (!validate_arglist (arglist
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
10267 ptr
= TREE_VALUE (arglist
);
10268 ost
= TREE_VALUE (TREE_CHAIN (arglist
));
10271 if (TREE_CODE (ost
) != INTEGER_CST
10272 || tree_int_cst_sgn (ost
) < 0
10273 || compare_tree_int (ost
, 3) > 0)
10276 object_size_type
= tree_low_cst (ost
, 0);
10278 /* __builtin_object_size doesn't evaluate side-effects in its arguments;
10279 if there are any side-effects, it returns (size_t) -1 for types 0 and 1
10280 and (size_t) 0 for types 2 and 3. */
10281 if (TREE_SIDE_EFFECTS (ptr
))
10282 return fold_convert (size_type_node
,
10283 object_size_type
< 2
10284 ? integer_minus_one_node
: integer_zero_node
);
10286 if (TREE_CODE (ptr
) == ADDR_EXPR
)
10287 ret
= build_int_cstu (size_type_node
,
10288 compute_builtin_object_size (ptr
, object_size_type
));
10290 else if (TREE_CODE (ptr
) == SSA_NAME
)
10292 unsigned HOST_WIDE_INT bytes
;
10294 /* If object size is not known yet, delay folding until
10295 later. Maybe subsequent passes will help determining
10297 bytes
= compute_builtin_object_size (ptr
, object_size_type
);
10298 if (bytes
!= (unsigned HOST_WIDE_INT
) (object_size_type
< 2
10300 ret
= build_int_cstu (size_type_node
, bytes
);
10305 ret
= force_fit_type (ret
, -1, false, false);
10306 if (TREE_CONSTANT_OVERFLOW (ret
))
10313 /* Fold a call to the __mem{cpy,pcpy,move,set}_chk builtin.
10314 IGNORE is true, if return value can be ignored. FCODE is the BUILT_IN_*
10315 code of the builtin. If MAXLEN is not NULL, it is maximum length
10316 passed as third argument. */
10319 fold_builtin_memory_chk (tree fndecl
, tree arglist
, tree maxlen
, bool ignore
,
10320 enum built_in_function fcode
)
10322 tree dest
, src
, len
, size
, fn
;
10324 if (!validate_arglist (arglist
,
10326 fcode
== BUILT_IN_MEMSET_CHK
10327 ? INTEGER_TYPE
: POINTER_TYPE
,
10328 INTEGER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
10331 dest
= TREE_VALUE (arglist
);
10332 /* Actually val for __memset_chk, but it doesn't matter. */
10333 src
= TREE_VALUE (TREE_CHAIN (arglist
));
10334 len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
10335 size
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist
))));
10337 /* If SRC and DEST are the same (and not volatile), return DEST
10338 (resp. DEST+LEN for __mempcpy_chk). */
10339 if (fcode
!= BUILT_IN_MEMSET_CHK
&& operand_equal_p (src
, dest
, 0))
10341 if (fcode
!= BUILT_IN_MEMPCPY_CHK
)
10342 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl
)), dest
, len
);
10345 tree temp
= fold_convert (TREE_TYPE (dest
), len
);
10346 temp
= fold_build2 (PLUS_EXPR
, TREE_TYPE (dest
), dest
, temp
);
10347 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl
)), temp
);
10351 if (! host_integerp (size
, 1))
10354 if (! integer_all_onesp (size
))
10356 if (! host_integerp (len
, 1))
10358 /* If LEN is not constant, try MAXLEN too.
10359 For MAXLEN only allow optimizing into non-_ocs function
10360 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
10361 if (maxlen
== NULL_TREE
|| ! host_integerp (maxlen
, 1))
10363 if (fcode
== BUILT_IN_MEMPCPY_CHK
&& ignore
)
10365 /* (void) __mempcpy_chk () can be optimized into
10366 (void) __memcpy_chk (). */
10367 fn
= built_in_decls
[BUILT_IN_MEMCPY_CHK
];
10371 return build_function_call_expr (fn
, arglist
);
10379 if (tree_int_cst_lt (size
, maxlen
))
10383 arglist
= build_tree_list (NULL_TREE
, len
);
10384 arglist
= tree_cons (NULL_TREE
, src
, arglist
);
10385 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
10388 /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume
10389 mem{cpy,pcpy,move,set} is available. */
10392 case BUILT_IN_MEMCPY_CHK
:
10393 fn
= built_in_decls
[BUILT_IN_MEMCPY
];
10395 case BUILT_IN_MEMPCPY_CHK
:
10396 fn
= built_in_decls
[BUILT_IN_MEMPCPY
];
10398 case BUILT_IN_MEMMOVE_CHK
:
10399 fn
= built_in_decls
[BUILT_IN_MEMMOVE
];
10401 case BUILT_IN_MEMSET_CHK
:
10402 fn
= built_in_decls
[BUILT_IN_MEMSET
];
10411 return build_function_call_expr (fn
, arglist
);
10414 /* Fold a call to the __st[rp]cpy_chk builtin.
10415 IGNORE is true, if return value can be ignored. FCODE is the BUILT_IN_*
10416 code of the builtin. If MAXLEN is not NULL, it is maximum length of
10417 strings passed as second argument. */
10420 fold_builtin_stxcpy_chk (tree fndecl
, tree arglist
, tree maxlen
, bool ignore
,
10421 enum built_in_function fcode
)
10423 tree dest
, src
, size
, len
, fn
;
10425 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
,
10429 dest
= TREE_VALUE (arglist
);
10430 src
= TREE_VALUE (TREE_CHAIN (arglist
));
10431 size
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
10433 /* If SRC and DEST are the same (and not volatile), return DEST. */
10434 if (fcode
== BUILT_IN_STRCPY_CHK
&& operand_equal_p (src
, dest
, 0))
10435 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl
)), dest
);
10437 if (! host_integerp (size
, 1))
10440 if (! integer_all_onesp (size
))
10442 len
= c_strlen (src
, 1);
10443 if (! len
|| ! host_integerp (len
, 1))
10445 /* If LEN is not constant, try MAXLEN too.
10446 For MAXLEN only allow optimizing into non-_ocs function
10447 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
10448 if (maxlen
== NULL_TREE
|| ! host_integerp (maxlen
, 1))
10450 if (fcode
== BUILT_IN_STPCPY_CHK
)
10455 /* If return value of __stpcpy_chk is ignored,
10456 optimize into __strcpy_chk. */
10457 fn
= built_in_decls
[BUILT_IN_STRCPY_CHK
];
10461 return build_function_call_expr (fn
, arglist
);
10464 if (! len
|| TREE_SIDE_EFFECTS (len
))
10467 /* If c_strlen returned something, but not a constant,
10468 transform __strcpy_chk into __memcpy_chk. */
10469 fn
= built_in_decls
[BUILT_IN_MEMCPY_CHK
];
10473 len
= size_binop (PLUS_EXPR
, len
, ssize_int (1));
10474 arglist
= build_tree_list (NULL_TREE
, size
);
10475 arglist
= tree_cons (NULL_TREE
, len
, arglist
);
10476 arglist
= tree_cons (NULL_TREE
, src
, arglist
);
10477 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
10478 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl
)),
10479 build_function_call_expr (fn
, arglist
));
10485 if (! tree_int_cst_lt (maxlen
, size
))
10489 arglist
= build_tree_list (NULL_TREE
, src
);
10490 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
10492 /* If __builtin_st{r,p}cpy_chk is used, assume st{r,p}cpy is available. */
10493 fn
= built_in_decls
[fcode
== BUILT_IN_STPCPY_CHK
10494 ? BUILT_IN_STPCPY
: BUILT_IN_STRCPY
];
10498 return build_function_call_expr (fn
, arglist
);
10501 /* Fold a call to the __strncpy_chk builtin.
10502 If MAXLEN is not NULL, it is maximum length passed as third argument. */
10505 fold_builtin_strncpy_chk (tree arglist
, tree maxlen
)
10507 tree dest
, src
, size
, len
, fn
;
10509 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
,
10510 INTEGER_TYPE
, VOID_TYPE
))
10513 dest
= TREE_VALUE (arglist
);
10514 src
= TREE_VALUE (TREE_CHAIN (arglist
));
10515 len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
10516 size
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist
))));
10518 if (! host_integerp (size
, 1))
10521 if (! integer_all_onesp (size
))
10523 if (! host_integerp (len
, 1))
10525 /* If LEN is not constant, try MAXLEN too.
10526 For MAXLEN only allow optimizing into non-_ocs function
10527 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
10528 if (maxlen
== NULL_TREE
|| ! host_integerp (maxlen
, 1))
10534 if (tree_int_cst_lt (size
, maxlen
))
10538 arglist
= build_tree_list (NULL_TREE
, len
);
10539 arglist
= tree_cons (NULL_TREE
, src
, arglist
);
10540 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
10542 /* If __builtin_strncpy_chk is used, assume strncpy is available. */
10543 fn
= built_in_decls
[BUILT_IN_STRNCPY
];
10547 return build_function_call_expr (fn
, arglist
);
10550 /* Fold a call to the __strcat_chk builtin FNDECL with ARGLIST. */
10553 fold_builtin_strcat_chk (tree fndecl
, tree arglist
)
10555 tree dest
, src
, size
, fn
;
10558 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
,
10562 dest
= TREE_VALUE (arglist
);
10563 src
= TREE_VALUE (TREE_CHAIN (arglist
));
10564 size
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
10566 p
= c_getstr (src
);
10567 /* If the SRC parameter is "", return DEST. */
10568 if (p
&& *p
== '\0')
10569 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl
)), dest
, src
);
10571 if (! host_integerp (size
, 1) || ! integer_all_onesp (size
))
10574 arglist
= build_tree_list (NULL_TREE
, src
);
10575 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
10577 /* If __builtin_strcat_chk is used, assume strcat is available. */
10578 fn
= built_in_decls
[BUILT_IN_STRCAT
];
10582 return build_function_call_expr (fn
, arglist
);
10585 /* Fold a call to the __strncat_chk builtin EXP. */
10588 fold_builtin_strncat_chk (tree fndecl
, tree arglist
)
10590 tree dest
, src
, size
, len
, fn
;
10593 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
,
10594 INTEGER_TYPE
, VOID_TYPE
))
10597 dest
= TREE_VALUE (arglist
);
10598 src
= TREE_VALUE (TREE_CHAIN (arglist
));
10599 len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
10600 size
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist
))));
10602 p
= c_getstr (src
);
10603 /* If the SRC parameter is "" or if LEN is 0, return DEST. */
10604 if (p
&& *p
== '\0')
10605 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl
)), dest
, len
);
10606 else if (integer_zerop (len
))
10607 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl
)), dest
, src
);
10609 if (! host_integerp (size
, 1))
10612 if (! integer_all_onesp (size
))
10614 tree src_len
= c_strlen (src
, 1);
10616 && host_integerp (src_len
, 1)
10617 && host_integerp (len
, 1)
10618 && ! tree_int_cst_lt (len
, src_len
))
10620 /* If LEN >= strlen (SRC), optimize into __strcat_chk. */
10621 fn
= built_in_decls
[BUILT_IN_STRCAT_CHK
];
10625 arglist
= build_tree_list (NULL_TREE
, size
);
10626 arglist
= tree_cons (NULL_TREE
, src
, arglist
);
10627 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
10628 return build_function_call_expr (fn
, arglist
);
10633 arglist
= build_tree_list (NULL_TREE
, len
);
10634 arglist
= tree_cons (NULL_TREE
, src
, arglist
);
10635 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
10637 /* If __builtin_strncat_chk is used, assume strncat is available. */
10638 fn
= built_in_decls
[BUILT_IN_STRNCAT
];
10642 return build_function_call_expr (fn
, arglist
);
10645 /* Fold a call to __{,v}sprintf_chk with argument list ARGLIST. Return 0 if
10646 a normal call should be emitted rather than expanding the function
10647 inline. FCODE is either BUILT_IN_SPRINTF_CHK or BUILT_IN_VSPRINTF_CHK. */
10650 fold_builtin_sprintf_chk (tree arglist
, enum built_in_function fcode
)
10652 tree dest
, size
, len
, fn
, fmt
, flag
;
10653 const char *fmt_str
;
10655 /* Verify the required arguments in the original call. */
10658 dest
= TREE_VALUE (arglist
);
10659 if (! POINTER_TYPE_P (TREE_TYPE (dest
)))
10661 arglist
= TREE_CHAIN (arglist
);
10664 flag
= TREE_VALUE (arglist
);
10665 if (TREE_CODE (TREE_TYPE (flag
)) != INTEGER_TYPE
)
10667 arglist
= TREE_CHAIN (arglist
);
10670 size
= TREE_VALUE (arglist
);
10671 if (TREE_CODE (TREE_TYPE (size
)) != INTEGER_TYPE
)
10673 arglist
= TREE_CHAIN (arglist
);
10676 fmt
= TREE_VALUE (arglist
);
10677 if (! POINTER_TYPE_P (TREE_TYPE (fmt
)))
10679 arglist
= TREE_CHAIN (arglist
);
10681 if (! host_integerp (size
, 1))
10686 if (!init_target_chars())
10689 /* Check whether the format is a literal string constant. */
10690 fmt_str
= c_getstr (fmt
);
10691 if (fmt_str
!= NULL
)
10693 /* If the format doesn't contain % args or %%, we know the size. */
10694 if (strchr (fmt_str
, target_percent
) == 0)
10696 if (fcode
!= BUILT_IN_SPRINTF_CHK
|| arglist
== NULL_TREE
)
10697 len
= build_int_cstu (size_type_node
, strlen (fmt_str
));
10699 /* If the format is "%s" and first ... argument is a string literal,
10700 we know the size too. */
10701 else if (fcode
== BUILT_IN_SPRINTF_CHK
&& strcmp (fmt_str
, target_percent_s
) == 0)
10705 if (arglist
&& !TREE_CHAIN (arglist
))
10707 arg
= TREE_VALUE (arglist
);
10708 if (POINTER_TYPE_P (TREE_TYPE (arg
)))
10710 len
= c_strlen (arg
, 1);
10711 if (! len
|| ! host_integerp (len
, 1))
10718 if (! integer_all_onesp (size
))
10720 if (! len
|| ! tree_int_cst_lt (len
, size
))
10724 /* Only convert __{,v}sprintf_chk to {,v}sprintf if flag is 0
10725 or if format doesn't contain % chars or is "%s". */
10726 if (! integer_zerop (flag
))
10728 if (fmt_str
== NULL
)
10730 if (strchr (fmt_str
, target_percent
) != NULL
&& strcmp (fmt_str
, target_percent_s
))
10734 arglist
= tree_cons (NULL_TREE
, fmt
, arglist
);
10735 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
10737 /* If __builtin_{,v}sprintf_chk is used, assume {,v}sprintf is available. */
10738 fn
= built_in_decls
[fcode
== BUILT_IN_VSPRINTF_CHK
10739 ? BUILT_IN_VSPRINTF
: BUILT_IN_SPRINTF
];
10743 return build_function_call_expr (fn
, arglist
);
10746 /* Fold a call to {,v}snprintf with argument list ARGLIST. Return 0 if
10747 a normal call should be emitted rather than expanding the function
10748 inline. FCODE is either BUILT_IN_SNPRINTF_CHK or
10749 BUILT_IN_VSNPRINTF_CHK. If MAXLEN is not NULL, it is maximum length
10750 passed as second argument. */
10753 fold_builtin_snprintf_chk (tree arglist
, tree maxlen
,
10754 enum built_in_function fcode
)
10756 tree dest
, size
, len
, fn
, fmt
, flag
;
10757 const char *fmt_str
;
10759 /* Verify the required arguments in the original call. */
10762 dest
= TREE_VALUE (arglist
);
10763 if (! POINTER_TYPE_P (TREE_TYPE (dest
)))
10765 arglist
= TREE_CHAIN (arglist
);
10768 len
= TREE_VALUE (arglist
);
10769 if (TREE_CODE (TREE_TYPE (len
)) != INTEGER_TYPE
)
10771 arglist
= TREE_CHAIN (arglist
);
10774 flag
= TREE_VALUE (arglist
);
10775 if (TREE_CODE (TREE_TYPE (len
)) != INTEGER_TYPE
)
10777 arglist
= TREE_CHAIN (arglist
);
10780 size
= TREE_VALUE (arglist
);
10781 if (TREE_CODE (TREE_TYPE (size
)) != INTEGER_TYPE
)
10783 arglist
= TREE_CHAIN (arglist
);
10786 fmt
= TREE_VALUE (arglist
);
10787 if (! POINTER_TYPE_P (TREE_TYPE (fmt
)))
10789 arglist
= TREE_CHAIN (arglist
);
10791 if (! host_integerp (size
, 1))
10794 if (! integer_all_onesp (size
))
10796 if (! host_integerp (len
, 1))
10798 /* If LEN is not constant, try MAXLEN too.
10799 For MAXLEN only allow optimizing into non-_ocs function
10800 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
10801 if (maxlen
== NULL_TREE
|| ! host_integerp (maxlen
, 1))
10807 if (tree_int_cst_lt (size
, maxlen
))
10811 if (!init_target_chars())
10814 /* Only convert __{,v}snprintf_chk to {,v}snprintf if flag is 0
10815 or if format doesn't contain % chars or is "%s". */
10816 if (! integer_zerop (flag
))
10818 fmt_str
= c_getstr (fmt
);
10819 if (fmt_str
== NULL
)
10821 if (strchr (fmt_str
, target_percent
) != NULL
&& strcmp (fmt_str
, target_percent_s
))
10825 arglist
= tree_cons (NULL_TREE
, fmt
, arglist
);
10826 arglist
= tree_cons (NULL_TREE
, len
, arglist
);
10827 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
10829 /* If __builtin_{,v}snprintf_chk is used, assume {,v}snprintf is
10831 fn
= built_in_decls
[fcode
== BUILT_IN_VSNPRINTF_CHK
10832 ? BUILT_IN_VSNPRINTF
: BUILT_IN_SNPRINTF
];
10836 return build_function_call_expr (fn
, arglist
);
10839 /* Fold a call to the {,v}printf{,_unlocked} and __{,v}printf_chk builtins.
10841 Return 0 if no simplification was possible, otherwise return the
10842 simplified form of the call as a tree. FCODE is the BUILT_IN_*
10843 code of the function to be simplified. */
10846 fold_builtin_printf (tree fndecl
, tree arglist
, bool ignore
,
10847 enum built_in_function fcode
)
10849 tree fmt
, fn
= NULL_TREE
, fn_putchar
, fn_puts
, arg
, call
;
10850 const char *fmt_str
= NULL
;
10852 /* If the return value is used, don't do the transformation. */
10856 /* Verify the required arguments in the original call. */
10857 if (fcode
== BUILT_IN_PRINTF_CHK
|| fcode
== BUILT_IN_VPRINTF_CHK
)
10863 flag
= TREE_VALUE (arglist
);
10864 if (TREE_CODE (TREE_TYPE (flag
)) != INTEGER_TYPE
10865 || TREE_SIDE_EFFECTS (flag
))
10867 arglist
= TREE_CHAIN (arglist
);
10872 fmt
= TREE_VALUE (arglist
);
10873 if (! POINTER_TYPE_P (TREE_TYPE (fmt
)))
10875 arglist
= TREE_CHAIN (arglist
);
10877 /* Check whether the format is a literal string constant. */
10878 fmt_str
= c_getstr (fmt
);
10879 if (fmt_str
== NULL
)
10882 if (fcode
== BUILT_IN_PRINTF_UNLOCKED
)
10884 /* If we're using an unlocked function, assume the other
10885 unlocked functions exist explicitly. */
10886 fn_putchar
= built_in_decls
[BUILT_IN_PUTCHAR_UNLOCKED
];
10887 fn_puts
= built_in_decls
[BUILT_IN_PUTS_UNLOCKED
];
10891 fn_putchar
= implicit_built_in_decls
[BUILT_IN_PUTCHAR
];
10892 fn_puts
= implicit_built_in_decls
[BUILT_IN_PUTS
];
10895 if (!init_target_chars())
10898 if (strcmp (fmt_str
, target_percent_s
) == 0 || strchr (fmt_str
, target_percent
) == NULL
)
10902 if (strcmp (fmt_str
, target_percent_s
) == 0)
10904 if (fcode
== BUILT_IN_VPRINTF
|| fcode
== BUILT_IN_VPRINTF_CHK
)
10908 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist
)))
10909 || TREE_CHAIN (arglist
))
10912 str
= c_getstr (TREE_VALUE (arglist
));
10918 /* The format specifier doesn't contain any '%' characters. */
10919 if (fcode
!= BUILT_IN_VPRINTF
&& fcode
!= BUILT_IN_VPRINTF_CHK
10925 /* If the string was "", printf does nothing. */
10926 if (str
[0] == '\0')
10927 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl
)), 0);
10929 /* If the string has length of 1, call putchar. */
10930 if (str
[1] == '\0')
10932 /* Given printf("c"), (where c is any one character,)
10933 convert "c"[0] to an int and pass that to the replacement
10935 arg
= build_int_cst (NULL_TREE
, str
[0]);
10936 arglist
= build_tree_list (NULL_TREE
, arg
);
10941 /* If the string was "string\n", call puts("string"). */
10942 size_t len
= strlen (str
);
10943 if ((unsigned char)str
[len
- 1] == target_newline
)
10945 /* Create a NUL-terminated string that's one char shorter
10946 than the original, stripping off the trailing '\n'. */
10947 char *newstr
= alloca (len
);
10948 memcpy (newstr
, str
, len
- 1);
10949 newstr
[len
- 1] = 0;
10951 arg
= build_string_literal (len
, newstr
);
10952 arglist
= build_tree_list (NULL_TREE
, arg
);
10956 /* We'd like to arrange to call fputs(string,stdout) here,
10957 but we need stdout and don't have a way to get it yet. */
10962 /* The other optimizations can be done only on the non-va_list variants. */
10963 else if (fcode
== BUILT_IN_VPRINTF
|| fcode
== BUILT_IN_VPRINTF_CHK
)
10966 /* If the format specifier was "%s\n", call __builtin_puts(arg). */
10967 else if (strcmp (fmt_str
, target_percent_s_newline
) == 0)
10970 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist
)))
10971 || TREE_CHAIN (arglist
))
10976 /* If the format specifier was "%c", call __builtin_putchar(arg). */
10977 else if (strcmp (fmt_str
, target_percent_c
) == 0)
10980 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist
))) != INTEGER_TYPE
10981 || TREE_CHAIN (arglist
))
10989 call
= build_function_call_expr (fn
, arglist
);
10990 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl
)), call
);
10993 /* Fold a call to the {,v}fprintf{,_unlocked} and __{,v}printf_chk builtins.
10995 Return 0 if no simplification was possible, otherwise return the
10996 simplified form of the call as a tree. FCODE is the BUILT_IN_*
10997 code of the function to be simplified. */
11000 fold_builtin_fprintf (tree fndecl
, tree arglist
, bool ignore
,
11001 enum built_in_function fcode
)
11003 tree fp
, fmt
, fn
= NULL_TREE
, fn_fputc
, fn_fputs
, arg
, call
;
11004 const char *fmt_str
= NULL
;
11006 /* If the return value is used, don't do the transformation. */
11010 /* Verify the required arguments in the original call. */
11013 fp
= TREE_VALUE (arglist
);
11014 if (! POINTER_TYPE_P (TREE_TYPE (fp
)))
11016 arglist
= TREE_CHAIN (arglist
);
11018 if (fcode
== BUILT_IN_FPRINTF_CHK
|| fcode
== BUILT_IN_VFPRINTF_CHK
)
11024 flag
= TREE_VALUE (arglist
);
11025 if (TREE_CODE (TREE_TYPE (flag
)) != INTEGER_TYPE
11026 || TREE_SIDE_EFFECTS (flag
))
11028 arglist
= TREE_CHAIN (arglist
);
11033 fmt
= TREE_VALUE (arglist
);
11034 if (! POINTER_TYPE_P (TREE_TYPE (fmt
)))
11036 arglist
= TREE_CHAIN (arglist
);
11038 /* Check whether the format is a literal string constant. */
11039 fmt_str
= c_getstr (fmt
);
11040 if (fmt_str
== NULL
)
11043 if (fcode
== BUILT_IN_FPRINTF_UNLOCKED
)
11045 /* If we're using an unlocked function, assume the other
11046 unlocked functions exist explicitly. */
11047 fn_fputc
= built_in_decls
[BUILT_IN_FPUTC_UNLOCKED
];
11048 fn_fputs
= built_in_decls
[BUILT_IN_FPUTS_UNLOCKED
];
11052 fn_fputc
= implicit_built_in_decls
[BUILT_IN_FPUTC
];
11053 fn_fputs
= implicit_built_in_decls
[BUILT_IN_FPUTS
];
11056 if (!init_target_chars())
11059 /* If the format doesn't contain % args or %%, use strcpy. */
11060 if (strchr (fmt_str
, target_percent
) == NULL
)
11062 if (fcode
!= BUILT_IN_VFPRINTF
&& fcode
!= BUILT_IN_VFPRINTF_CHK
11066 /* If the format specifier was "", fprintf does nothing. */
11067 if (fmt_str
[0] == '\0')
11069 /* If FP has side-effects, just wait until gimplification is
11071 if (TREE_SIDE_EFFECTS (fp
))
11074 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl
)), 0);
11077 /* When "string" doesn't contain %, replace all cases of
11078 fprintf (fp, string) with fputs (string, fp). The fputs
11079 builtin will take care of special cases like length == 1. */
11080 arglist
= build_tree_list (NULL_TREE
, fp
);
11081 arglist
= tree_cons (NULL_TREE
, fmt
, arglist
);
11085 /* The other optimizations can be done only on the non-va_list variants. */
11086 else if (fcode
== BUILT_IN_VFPRINTF
|| fcode
== BUILT_IN_VFPRINTF_CHK
)
11089 /* If the format specifier was "%s", call __builtin_fputs (arg, fp). */
11090 else if (strcmp (fmt_str
, target_percent_s
) == 0)
11093 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist
)))
11094 || TREE_CHAIN (arglist
))
11096 arg
= TREE_VALUE (arglist
);
11097 arglist
= build_tree_list (NULL_TREE
, fp
);
11098 arglist
= tree_cons (NULL_TREE
, arg
, arglist
);
11102 /* If the format specifier was "%c", call __builtin_fputc (arg, fp). */
11103 else if (strcmp (fmt_str
, target_percent_c
) == 0)
11106 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist
))) != INTEGER_TYPE
11107 || TREE_CHAIN (arglist
))
11109 arg
= TREE_VALUE (arglist
);
11110 arglist
= build_tree_list (NULL_TREE
, fp
);
11111 arglist
= tree_cons (NULL_TREE
, arg
, arglist
);
11118 call
= build_function_call_expr (fn
, arglist
);
11119 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl
)), call
);
11122 /* Initialize format string characters in the target charset. */
11125 init_target_chars (void)
11130 target_newline
= lang_hooks
.to_target_charset ('\n');
11131 target_percent
= lang_hooks
.to_target_charset ('%');
11132 target_c
= lang_hooks
.to_target_charset ('c');
11133 target_s
= lang_hooks
.to_target_charset ('s');
11134 if (target_newline
== 0 || target_percent
== 0 || target_c
== 0
11138 target_percent_c
[0] = target_percent
;
11139 target_percent_c
[1] = target_c
;
11140 target_percent_c
[2] = '\0';
11142 target_percent_s
[0] = target_percent
;
11143 target_percent_s
[1] = target_s
;
11144 target_percent_s
[2] = '\0';
11146 target_percent_s_newline
[0] = target_percent
;
11147 target_percent_s_newline
[1] = target_s
;
11148 target_percent_s_newline
[2] = target_newline
;
11149 target_percent_s_newline
[3] = '\0';