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_cabs (tree
, tree
);
150 static tree
fold_builtin_sqrt (tree
, tree
);
151 static tree
fold_builtin_cbrt (tree
, tree
);
152 static tree
fold_builtin_pow (tree
, tree
, tree
);
153 static tree
fold_builtin_powi (tree
, tree
, tree
);
154 static tree
fold_builtin_sin (tree
);
155 static tree
fold_builtin_cos (tree
, tree
, tree
);
156 static tree
fold_builtin_tan (tree
);
157 static tree
fold_builtin_atan (tree
, tree
);
158 static tree
fold_builtin_trunc (tree
, tree
);
159 static tree
fold_builtin_floor (tree
, tree
);
160 static tree
fold_builtin_ceil (tree
, tree
);
161 static tree
fold_builtin_round (tree
, tree
);
162 static tree
fold_builtin_int_roundingfn (tree
, tree
);
163 static tree
fold_builtin_bitop (tree
, tree
);
164 static tree
fold_builtin_memcpy (tree
, tree
);
165 static tree
fold_builtin_mempcpy (tree
, tree
, int);
166 static tree
fold_builtin_memmove (tree
, tree
);
167 static tree
fold_builtin_strchr (tree
, tree
);
168 static tree
fold_builtin_memcmp (tree
);
169 static tree
fold_builtin_strcmp (tree
);
170 static tree
fold_builtin_strncmp (tree
);
171 static tree
fold_builtin_signbit (tree
, tree
);
172 static tree
fold_builtin_copysign (tree
, tree
, tree
);
173 static tree
fold_builtin_isascii (tree
);
174 static tree
fold_builtin_toascii (tree
);
175 static tree
fold_builtin_isdigit (tree
);
176 static tree
fold_builtin_fabs (tree
, tree
);
177 static tree
fold_builtin_abs (tree
, tree
);
178 static tree
fold_builtin_unordered_cmp (tree
, tree
, enum tree_code
,
180 static tree
fold_builtin_1 (tree
, tree
, bool);
182 static tree
fold_builtin_strpbrk (tree
, tree
);
183 static tree
fold_builtin_strstr (tree
, tree
);
184 static tree
fold_builtin_strrchr (tree
, tree
);
185 static tree
fold_builtin_strcat (tree
);
186 static tree
fold_builtin_strncat (tree
);
187 static tree
fold_builtin_strspn (tree
);
188 static tree
fold_builtin_strcspn (tree
);
189 static tree
fold_builtin_sprintf (tree
, int);
191 static rtx
expand_builtin_object_size (tree
);
192 static rtx
expand_builtin_memory_chk (tree
, rtx
, enum machine_mode
,
193 enum built_in_function
);
194 static void maybe_emit_chk_warning (tree
, enum built_in_function
);
195 static void maybe_emit_sprintf_chk_warning (tree
, enum built_in_function
);
196 static tree
fold_builtin_object_size (tree
);
197 static tree
fold_builtin_strcat_chk (tree
, tree
);
198 static tree
fold_builtin_strncat_chk (tree
, tree
);
199 static tree
fold_builtin_sprintf_chk (tree
, enum built_in_function
);
200 static tree
fold_builtin_printf (tree
, tree
, bool, enum built_in_function
);
201 static tree
fold_builtin_fprintf (tree
, tree
, bool, enum built_in_function
);
202 static bool init_target_chars (void);
204 static unsigned HOST_WIDE_INT target_newline
;
205 static unsigned HOST_WIDE_INT target_percent
;
206 static unsigned HOST_WIDE_INT target_c
;
207 static unsigned HOST_WIDE_INT target_s
;
208 static char target_percent_c
[3];
209 static char target_percent_s
[3];
210 static char target_percent_s_newline
[4];
212 /* Return true if NODE should be considered for inline expansion regardless
213 of the optimization level. This means whenever a function is invoked with
214 its "internal" name, which normally contains the prefix "__builtin". */
216 static bool called_as_built_in (tree node
)
218 const char *name
= IDENTIFIER_POINTER (DECL_NAME (node
));
219 if (strncmp (name
, "__builtin_", 10) == 0)
221 if (strncmp (name
, "__sync_", 7) == 0)
226 /* Return the alignment in bits of EXP, a pointer valued expression.
227 But don't return more than MAX_ALIGN no matter what.
228 The alignment returned is, by default, the alignment of the thing that
229 EXP points to. If it is not a POINTER_TYPE, 0 is returned.
231 Otherwise, look at the expression to see if we can do better, i.e., if the
232 expression is actually pointing at an object whose alignment is tighter. */
235 get_pointer_alignment (tree exp
, unsigned int max_align
)
237 unsigned int align
, inner
;
239 if (! POINTER_TYPE_P (TREE_TYPE (exp
)))
242 align
= TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp
)));
243 align
= MIN (align
, max_align
);
247 switch (TREE_CODE (exp
))
251 case NON_LVALUE_EXPR
:
252 exp
= TREE_OPERAND (exp
, 0);
253 if (! POINTER_TYPE_P (TREE_TYPE (exp
)))
256 inner
= TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp
)));
257 align
= MIN (inner
, max_align
);
261 /* If sum of pointer + int, restrict our maximum alignment to that
262 imposed by the integer. If not, we can't do any better than
264 if (! host_integerp (TREE_OPERAND (exp
, 1), 1))
267 while (((tree_low_cst (TREE_OPERAND (exp
, 1), 1))
268 & (max_align
/ BITS_PER_UNIT
- 1))
272 exp
= TREE_OPERAND (exp
, 0);
276 /* See what we are pointing at and look at its alignment. */
277 exp
= TREE_OPERAND (exp
, 0);
278 if (TREE_CODE (exp
) == FUNCTION_DECL
)
279 align
= FUNCTION_BOUNDARY
;
280 else if (DECL_P (exp
))
281 align
= DECL_ALIGN (exp
);
282 #ifdef CONSTANT_ALIGNMENT
283 else if (CONSTANT_CLASS_P (exp
))
284 align
= CONSTANT_ALIGNMENT (exp
, align
);
286 return MIN (align
, max_align
);
294 /* Compute the length of a C string. TREE_STRING_LENGTH is not the right
295 way, because it could contain a zero byte in the middle.
296 TREE_STRING_LENGTH is the size of the character array, not the string.
298 ONLY_VALUE should be nonzero if the result is not going to be emitted
299 into the instruction stream and zero if it is going to be expanded.
300 E.g. with i++ ? "foo" : "bar", if ONLY_VALUE is nonzero, constant 3
301 is returned, otherwise NULL, since
302 len = c_strlen (src, 1); if (len) expand_expr (len, ...); would not
303 evaluate the side-effects.
305 The value returned is of type `ssizetype'.
307 Unfortunately, string_constant can't access the values of const char
308 arrays with initializers, so neither can we do so here. */
311 c_strlen (tree src
, int only_value
)
314 HOST_WIDE_INT offset
;
319 if (TREE_CODE (src
) == COND_EXPR
320 && (only_value
|| !TREE_SIDE_EFFECTS (TREE_OPERAND (src
, 0))))
324 len1
= c_strlen (TREE_OPERAND (src
, 1), only_value
);
325 len2
= c_strlen (TREE_OPERAND (src
, 2), only_value
);
326 if (tree_int_cst_equal (len1
, len2
))
330 if (TREE_CODE (src
) == COMPOUND_EXPR
331 && (only_value
|| !TREE_SIDE_EFFECTS (TREE_OPERAND (src
, 0))))
332 return c_strlen (TREE_OPERAND (src
, 1), only_value
);
334 src
= string_constant (src
, &offset_node
);
338 max
= TREE_STRING_LENGTH (src
) - 1;
339 ptr
= TREE_STRING_POINTER (src
);
341 if (offset_node
&& TREE_CODE (offset_node
) != INTEGER_CST
)
343 /* If the string has an internal zero byte (e.g., "foo\0bar"), we can't
344 compute the offset to the following null if we don't know where to
345 start searching for it. */
348 for (i
= 0; i
< max
; i
++)
352 /* We don't know the starting offset, but we do know that the string
353 has no internal zero bytes. We can assume that the offset falls
354 within the bounds of the string; otherwise, the programmer deserves
355 what he gets. Subtract the offset from the length of the string,
356 and return that. This would perhaps not be valid if we were dealing
357 with named arrays in addition to literal string constants. */
359 return size_diffop (size_int (max
), offset_node
);
362 /* We have a known offset into the string. Start searching there for
363 a null character if we can represent it as a single HOST_WIDE_INT. */
364 if (offset_node
== 0)
366 else if (! host_integerp (offset_node
, 0))
369 offset
= tree_low_cst (offset_node
, 0);
371 /* If the offset is known to be out of bounds, warn, and call strlen at
373 if (offset
< 0 || offset
> max
)
375 warning (0, "offset outside bounds of constant string");
379 /* Use strlen to search for the first zero byte. Since any strings
380 constructed with build_string will have nulls appended, we win even
381 if we get handed something like (char[4])"abcd".
383 Since OFFSET is our starting index into the string, no further
384 calculation is needed. */
385 return ssize_int (strlen (ptr
+ offset
));
388 /* Return a char pointer for a C string if it is a string constant
389 or sum of string constant and integer constant. */
396 src
= string_constant (src
, &offset_node
);
400 if (offset_node
== 0)
401 return TREE_STRING_POINTER (src
);
402 else if (!host_integerp (offset_node
, 1)
403 || compare_tree_int (offset_node
, TREE_STRING_LENGTH (src
) - 1) > 0)
406 return TREE_STRING_POINTER (src
) + tree_low_cst (offset_node
, 1);
409 /* Return a CONST_INT or CONST_DOUBLE corresponding to target reading
410 GET_MODE_BITSIZE (MODE) bits from string constant STR. */
413 c_readstr (const char *str
, enum machine_mode mode
)
419 gcc_assert (GET_MODE_CLASS (mode
) == MODE_INT
);
424 for (i
= 0; i
< GET_MODE_SIZE (mode
); i
++)
427 if (WORDS_BIG_ENDIAN
)
428 j
= GET_MODE_SIZE (mode
) - i
- 1;
429 if (BYTES_BIG_ENDIAN
!= WORDS_BIG_ENDIAN
430 && GET_MODE_SIZE (mode
) > UNITS_PER_WORD
)
431 j
= j
+ UNITS_PER_WORD
- 2 * (j
% UNITS_PER_WORD
) - 1;
433 gcc_assert (j
<= 2 * HOST_BITS_PER_WIDE_INT
);
436 ch
= (unsigned char) str
[i
];
437 c
[j
/ HOST_BITS_PER_WIDE_INT
] |= ch
<< (j
% HOST_BITS_PER_WIDE_INT
);
439 return immed_double_const (c
[0], c
[1], mode
);
442 /* Cast a target constant CST to target CHAR and if that value fits into
443 host char type, return zero and put that value into variable pointed to by
447 target_char_cast (tree cst
, char *p
)
449 unsigned HOST_WIDE_INT val
, hostval
;
451 if (!host_integerp (cst
, 1)
452 || CHAR_TYPE_SIZE
> HOST_BITS_PER_WIDE_INT
)
455 val
= tree_low_cst (cst
, 1);
456 if (CHAR_TYPE_SIZE
< HOST_BITS_PER_WIDE_INT
)
457 val
&= (((unsigned HOST_WIDE_INT
) 1) << CHAR_TYPE_SIZE
) - 1;
460 if (HOST_BITS_PER_CHAR
< HOST_BITS_PER_WIDE_INT
)
461 hostval
&= (((unsigned HOST_WIDE_INT
) 1) << HOST_BITS_PER_CHAR
) - 1;
470 /* Similar to save_expr, but assumes that arbitrary code is not executed
471 in between the multiple evaluations. In particular, we assume that a
472 non-addressable local variable will not be modified. */
475 builtin_save_expr (tree exp
)
477 if (TREE_ADDRESSABLE (exp
) == 0
478 && (TREE_CODE (exp
) == PARM_DECL
479 || (TREE_CODE (exp
) == VAR_DECL
&& !TREE_STATIC (exp
))))
482 return save_expr (exp
);
485 /* Given TEM, a pointer to a stack frame, follow the dynamic chain COUNT
486 times to get the address of either a higher stack frame, or a return
487 address located within it (depending on FNDECL_CODE). */
490 expand_builtin_return_addr (enum built_in_function fndecl_code
, int count
)
494 #ifdef INITIAL_FRAME_ADDRESS_RTX
495 rtx tem
= INITIAL_FRAME_ADDRESS_RTX
;
499 /* For a zero count, we don't care what frame address we return, so frame
500 pointer elimination is OK, and using the soft frame pointer is OK.
501 For a non-zero count, we require a stable offset from the current frame
502 pointer to the previous one, so we must use the hard frame pointer, and
503 we must disable frame pointer elimination. */
505 tem
= frame_pointer_rtx
;
508 tem
= hard_frame_pointer_rtx
;
510 /* Tell reload not to eliminate the frame pointer. */
511 current_function_accesses_prior_frames
= 1;
515 /* Some machines need special handling before we can access
516 arbitrary frames. For example, on the sparc, we must first flush
517 all register windows to the stack. */
518 #ifdef SETUP_FRAME_ADDRESSES
520 SETUP_FRAME_ADDRESSES ();
523 /* On the sparc, the return address is not in the frame, it is in a
524 register. There is no way to access it off of the current frame
525 pointer, but it can be accessed off the previous frame pointer by
526 reading the value from the register window save area. */
527 #ifdef RETURN_ADDR_IN_PREVIOUS_FRAME
528 if (fndecl_code
== BUILT_IN_RETURN_ADDRESS
)
532 /* Scan back COUNT frames to the specified frame. */
533 for (i
= 0; i
< count
; i
++)
535 /* Assume the dynamic chain pointer is in the word that the
536 frame address points to, unless otherwise specified. */
537 #ifdef DYNAMIC_CHAIN_ADDRESS
538 tem
= DYNAMIC_CHAIN_ADDRESS (tem
);
540 tem
= memory_address (Pmode
, tem
);
541 tem
= gen_frame_mem (Pmode
, tem
);
542 tem
= copy_to_reg (tem
);
545 /* For __builtin_frame_address, return what we've got. */
546 if (fndecl_code
== BUILT_IN_FRAME_ADDRESS
)
549 /* For __builtin_return_address, Get the return address from that
551 #ifdef RETURN_ADDR_RTX
552 tem
= RETURN_ADDR_RTX (count
, tem
);
554 tem
= memory_address (Pmode
,
555 plus_constant (tem
, GET_MODE_SIZE (Pmode
)));
556 tem
= gen_frame_mem (Pmode
, tem
);
561 /* Alias set used for setjmp buffer. */
562 static HOST_WIDE_INT setjmp_alias_set
= -1;
564 /* Construct the leading half of a __builtin_setjmp call. Control will
565 return to RECEIVER_LABEL. This is used directly by sjlj exception
569 expand_builtin_setjmp_setup (rtx buf_addr
, rtx receiver_label
)
571 enum machine_mode sa_mode
= STACK_SAVEAREA_MODE (SAVE_NONLOCAL
);
575 if (setjmp_alias_set
== -1)
576 setjmp_alias_set
= new_alias_set ();
578 buf_addr
= convert_memory_address (Pmode
, buf_addr
);
580 buf_addr
= force_reg (Pmode
, force_operand (buf_addr
, NULL_RTX
));
582 /* We store the frame pointer and the address of receiver_label in
583 the buffer and use the rest of it for the stack save area, which
584 is machine-dependent. */
586 mem
= gen_rtx_MEM (Pmode
, buf_addr
);
587 set_mem_alias_set (mem
, setjmp_alias_set
);
588 emit_move_insn (mem
, targetm
.builtin_setjmp_frame_value ());
590 mem
= gen_rtx_MEM (Pmode
, plus_constant (buf_addr
, GET_MODE_SIZE (Pmode
))),
591 set_mem_alias_set (mem
, setjmp_alias_set
);
593 emit_move_insn (validize_mem (mem
),
594 force_reg (Pmode
, gen_rtx_LABEL_REF (Pmode
, receiver_label
)));
596 stack_save
= gen_rtx_MEM (sa_mode
,
597 plus_constant (buf_addr
,
598 2 * GET_MODE_SIZE (Pmode
)));
599 set_mem_alias_set (stack_save
, setjmp_alias_set
);
600 emit_stack_save (SAVE_NONLOCAL
, &stack_save
, NULL_RTX
);
602 /* If there is further processing to do, do it. */
603 #ifdef HAVE_builtin_setjmp_setup
604 if (HAVE_builtin_setjmp_setup
)
605 emit_insn (gen_builtin_setjmp_setup (buf_addr
));
608 /* Tell optimize_save_area_alloca that extra work is going to
609 need to go on during alloca. */
610 current_function_calls_setjmp
= 1;
612 /* Set this so all the registers get saved in our frame; we need to be
613 able to copy the saved values for any registers from frames we unwind. */
614 current_function_has_nonlocal_label
= 1;
617 /* Construct the trailing part of a __builtin_setjmp call.
618 This is used directly by sjlj exception handling code. */
621 expand_builtin_setjmp_receiver (rtx receiver_label ATTRIBUTE_UNUSED
)
623 /* Clobber the FP when we get here, so we have to make sure it's
624 marked as used by this function. */
625 emit_insn (gen_rtx_USE (VOIDmode
, hard_frame_pointer_rtx
));
627 /* Mark the static chain as clobbered here so life information
628 doesn't get messed up for it. */
629 emit_insn (gen_rtx_CLOBBER (VOIDmode
, static_chain_rtx
));
631 /* Now put in the code to restore the frame pointer, and argument
632 pointer, if needed. */
633 #ifdef HAVE_nonlocal_goto
634 if (! HAVE_nonlocal_goto
)
636 emit_move_insn (virtual_stack_vars_rtx
, hard_frame_pointer_rtx
);
638 #if ARG_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
639 if (fixed_regs
[ARG_POINTER_REGNUM
])
641 #ifdef ELIMINABLE_REGS
643 static const struct elims
{const int from
, to
;} elim_regs
[] = ELIMINABLE_REGS
;
645 for (i
= 0; i
< ARRAY_SIZE (elim_regs
); i
++)
646 if (elim_regs
[i
].from
== ARG_POINTER_REGNUM
647 && elim_regs
[i
].to
== HARD_FRAME_POINTER_REGNUM
)
650 if (i
== ARRAY_SIZE (elim_regs
))
653 /* Now restore our arg pointer from the address at which it
654 was saved in our stack frame. */
655 emit_move_insn (virtual_incoming_args_rtx
,
656 copy_to_reg (get_arg_pointer_save_area (cfun
)));
661 #ifdef HAVE_builtin_setjmp_receiver
662 if (HAVE_builtin_setjmp_receiver
)
663 emit_insn (gen_builtin_setjmp_receiver (receiver_label
));
666 #ifdef HAVE_nonlocal_goto_receiver
667 if (HAVE_nonlocal_goto_receiver
)
668 emit_insn (gen_nonlocal_goto_receiver ());
673 /* @@@ This is a kludge. Not all machine descriptions define a blockage
674 insn, but we must not allow the code we just generated to be reordered
675 by scheduling. Specifically, the update of the frame pointer must
676 happen immediately, not later. So emit an ASM_INPUT to act as blockage
678 emit_insn (gen_rtx_ASM_INPUT (VOIDmode
, ""));
681 /* __builtin_setjmp is passed a pointer to an array of five words (not
682 all will be used on all machines). It operates similarly to the C
683 library function of the same name, but is more efficient. Much of
684 the code below (and for longjmp) is copied from the handling of
687 NOTE: This is intended for use by GNAT and the exception handling
688 scheme in the compiler and will only work in the method used by
692 expand_builtin_setjmp (tree arglist
, rtx target
)
694 rtx buf_addr
, next_lab
, cont_lab
;
696 if (!validate_arglist (arglist
, POINTER_TYPE
, VOID_TYPE
))
699 if (target
== 0 || !REG_P (target
)
700 || REGNO (target
) < FIRST_PSEUDO_REGISTER
)
701 target
= gen_reg_rtx (TYPE_MODE (integer_type_node
));
703 buf_addr
= expand_normal (TREE_VALUE (arglist
));
705 next_lab
= gen_label_rtx ();
706 cont_lab
= gen_label_rtx ();
708 expand_builtin_setjmp_setup (buf_addr
, next_lab
);
710 /* Set TARGET to zero and branch to the continue label. Use emit_jump to
711 ensure that pending stack adjustments are flushed. */
712 emit_move_insn (target
, const0_rtx
);
713 emit_jump (cont_lab
);
715 emit_label (next_lab
);
717 expand_builtin_setjmp_receiver (next_lab
);
719 /* Set TARGET to one. */
720 emit_move_insn (target
, const1_rtx
);
721 emit_label (cont_lab
);
723 /* Tell flow about the strange goings on. Putting `next_lab' on
724 `nonlocal_goto_handler_labels' to indicates that function
725 calls may traverse the arc back to this label. */
727 current_function_has_nonlocal_label
= 1;
728 nonlocal_goto_handler_labels
729 = gen_rtx_EXPR_LIST (VOIDmode
, next_lab
, nonlocal_goto_handler_labels
);
734 /* __builtin_longjmp is passed a pointer to an array of five words (not
735 all will be used on all machines). It operates similarly to the C
736 library function of the same name, but is more efficient. Much of
737 the code below is copied from the handling of non-local gotos.
739 NOTE: This is intended for use by GNAT and the exception handling
740 scheme in the compiler and will only work in the method used by
744 expand_builtin_longjmp (rtx buf_addr
, rtx value
)
746 rtx fp
, lab
, stack
, insn
, last
;
747 enum machine_mode sa_mode
= STACK_SAVEAREA_MODE (SAVE_NONLOCAL
);
749 if (setjmp_alias_set
== -1)
750 setjmp_alias_set
= new_alias_set ();
752 buf_addr
= convert_memory_address (Pmode
, buf_addr
);
754 buf_addr
= force_reg (Pmode
, buf_addr
);
756 /* We used to store value in static_chain_rtx, but that fails if pointers
757 are smaller than integers. We instead require that the user must pass
758 a second argument of 1, because that is what builtin_setjmp will
759 return. This also makes EH slightly more efficient, since we are no
760 longer copying around a value that we don't care about. */
761 gcc_assert (value
== const1_rtx
);
763 last
= get_last_insn ();
764 #ifdef HAVE_builtin_longjmp
765 if (HAVE_builtin_longjmp
)
766 emit_insn (gen_builtin_longjmp (buf_addr
));
770 fp
= gen_rtx_MEM (Pmode
, buf_addr
);
771 lab
= gen_rtx_MEM (Pmode
, plus_constant (buf_addr
,
772 GET_MODE_SIZE (Pmode
)));
774 stack
= gen_rtx_MEM (sa_mode
, plus_constant (buf_addr
,
775 2 * GET_MODE_SIZE (Pmode
)));
776 set_mem_alias_set (fp
, setjmp_alias_set
);
777 set_mem_alias_set (lab
, setjmp_alias_set
);
778 set_mem_alias_set (stack
, setjmp_alias_set
);
780 /* Pick up FP, label, and SP from the block and jump. This code is
781 from expand_goto in stmt.c; see there for detailed comments. */
782 #if HAVE_nonlocal_goto
783 if (HAVE_nonlocal_goto
)
784 /* We have to pass a value to the nonlocal_goto pattern that will
785 get copied into the static_chain pointer, but it does not matter
786 what that value is, because builtin_setjmp does not use it. */
787 emit_insn (gen_nonlocal_goto (value
, lab
, stack
, fp
));
791 lab
= copy_to_reg (lab
);
793 emit_insn (gen_rtx_CLOBBER (VOIDmode
,
794 gen_rtx_MEM (BLKmode
,
795 gen_rtx_SCRATCH (VOIDmode
))));
796 emit_insn (gen_rtx_CLOBBER (VOIDmode
,
797 gen_rtx_MEM (BLKmode
,
798 hard_frame_pointer_rtx
)));
800 emit_move_insn (hard_frame_pointer_rtx
, fp
);
801 emit_stack_restore (SAVE_NONLOCAL
, stack
, NULL_RTX
);
803 emit_insn (gen_rtx_USE (VOIDmode
, hard_frame_pointer_rtx
));
804 emit_insn (gen_rtx_USE (VOIDmode
, stack_pointer_rtx
));
805 emit_indirect_jump (lab
);
809 /* Search backwards and mark the jump insn as a non-local goto.
810 Note that this precludes the use of __builtin_longjmp to a
811 __builtin_setjmp target in the same function. However, we've
812 already cautioned the user that these functions are for
813 internal exception handling use only. */
814 for (insn
= get_last_insn (); insn
; insn
= PREV_INSN (insn
))
816 gcc_assert (insn
!= last
);
820 REG_NOTES (insn
) = alloc_EXPR_LIST (REG_NON_LOCAL_GOTO
, const0_rtx
,
824 else if (CALL_P (insn
))
829 /* Expand a call to __builtin_nonlocal_goto. We're passed the target label
830 and the address of the save area. */
833 expand_builtin_nonlocal_goto (tree arglist
)
835 tree t_label
, t_save_area
;
836 rtx r_label
, r_save_area
, r_fp
, r_sp
, insn
;
838 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
841 t_label
= TREE_VALUE (arglist
);
842 arglist
= TREE_CHAIN (arglist
);
843 t_save_area
= TREE_VALUE (arglist
);
845 r_label
= expand_normal (t_label
);
846 r_label
= convert_memory_address (Pmode
, r_label
);
847 r_save_area
= expand_normal (t_save_area
);
848 r_save_area
= convert_memory_address (Pmode
, r_save_area
);
849 r_fp
= gen_rtx_MEM (Pmode
, r_save_area
);
850 r_sp
= gen_rtx_MEM (STACK_SAVEAREA_MODE (SAVE_NONLOCAL
),
851 plus_constant (r_save_area
, GET_MODE_SIZE (Pmode
)));
853 current_function_has_nonlocal_goto
= 1;
855 #if HAVE_nonlocal_goto
856 /* ??? We no longer need to pass the static chain value, afaik. */
857 if (HAVE_nonlocal_goto
)
858 emit_insn (gen_nonlocal_goto (const0_rtx
, r_label
, r_sp
, r_fp
));
862 r_label
= copy_to_reg (r_label
);
864 emit_insn (gen_rtx_CLOBBER (VOIDmode
,
865 gen_rtx_MEM (BLKmode
,
866 gen_rtx_SCRATCH (VOIDmode
))));
868 emit_insn (gen_rtx_CLOBBER (VOIDmode
,
869 gen_rtx_MEM (BLKmode
,
870 hard_frame_pointer_rtx
)));
872 /* Restore frame pointer for containing function.
873 This sets the actual hard register used for the frame pointer
874 to the location of the function's incoming static chain info.
875 The non-local goto handler will then adjust it to contain the
876 proper value and reload the argument pointer, if needed. */
877 emit_move_insn (hard_frame_pointer_rtx
, r_fp
);
878 emit_stack_restore (SAVE_NONLOCAL
, r_sp
, NULL_RTX
);
880 /* USE of hard_frame_pointer_rtx added for consistency;
881 not clear if really needed. */
882 emit_insn (gen_rtx_USE (VOIDmode
, hard_frame_pointer_rtx
));
883 emit_insn (gen_rtx_USE (VOIDmode
, stack_pointer_rtx
));
884 emit_indirect_jump (r_label
);
887 /* Search backwards to the jump insn and mark it as a
889 for (insn
= get_last_insn (); insn
; insn
= PREV_INSN (insn
))
893 REG_NOTES (insn
) = alloc_EXPR_LIST (REG_NON_LOCAL_GOTO
,
894 const0_rtx
, REG_NOTES (insn
));
897 else if (CALL_P (insn
))
904 /* __builtin_update_setjmp_buf is passed a pointer to an array of five words
905 (not all will be used on all machines) that was passed to __builtin_setjmp.
906 It updates the stack pointer in that block to correspond to the current
910 expand_builtin_update_setjmp_buf (rtx buf_addr
)
912 enum machine_mode sa_mode
= Pmode
;
916 #ifdef HAVE_save_stack_nonlocal
917 if (HAVE_save_stack_nonlocal
)
918 sa_mode
= insn_data
[(int) CODE_FOR_save_stack_nonlocal
].operand
[0].mode
;
920 #ifdef STACK_SAVEAREA_MODE
921 sa_mode
= STACK_SAVEAREA_MODE (SAVE_NONLOCAL
);
925 = gen_rtx_MEM (sa_mode
,
928 plus_constant (buf_addr
, 2 * GET_MODE_SIZE (Pmode
))));
932 emit_insn (gen_setjmp ());
935 emit_stack_save (SAVE_NONLOCAL
, &stack_save
, NULL_RTX
);
938 /* Expand a call to __builtin_prefetch. For a target that does not support
939 data prefetch, evaluate the memory address argument in case it has side
943 expand_builtin_prefetch (tree arglist
)
945 tree arg0
, arg1
, arg2
;
948 if (!validate_arglist (arglist
, POINTER_TYPE
, 0))
951 arg0
= TREE_VALUE (arglist
);
952 /* Arguments 1 and 2 are optional; argument 1 (read/write) defaults to
953 zero (read) and argument 2 (locality) defaults to 3 (high degree of
955 if (TREE_CHAIN (arglist
))
957 arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
958 if (TREE_CHAIN (TREE_CHAIN (arglist
)))
959 arg2
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
961 arg2
= build_int_cst (NULL_TREE
, 3);
965 arg1
= integer_zero_node
;
966 arg2
= build_int_cst (NULL_TREE
, 3);
969 /* Argument 0 is an address. */
970 op0
= expand_expr (arg0
, NULL_RTX
, Pmode
, EXPAND_NORMAL
);
972 /* Argument 1 (read/write flag) must be a compile-time constant int. */
973 if (TREE_CODE (arg1
) != INTEGER_CST
)
975 error ("second argument to %<__builtin_prefetch%> must be a constant");
976 arg1
= integer_zero_node
;
978 op1
= expand_normal (arg1
);
979 /* Argument 1 must be either zero or one. */
980 if (INTVAL (op1
) != 0 && INTVAL (op1
) != 1)
982 warning (0, "invalid second argument to %<__builtin_prefetch%>;"
987 /* Argument 2 (locality) must be a compile-time constant int. */
988 if (TREE_CODE (arg2
) != INTEGER_CST
)
990 error ("third argument to %<__builtin_prefetch%> must be a constant");
991 arg2
= integer_zero_node
;
993 op2
= expand_normal (arg2
);
994 /* Argument 2 must be 0, 1, 2, or 3. */
995 if (INTVAL (op2
) < 0 || INTVAL (op2
) > 3)
997 warning (0, "invalid third argument to %<__builtin_prefetch%>; using zero");
1001 #ifdef HAVE_prefetch
1004 if ((! (*insn_data
[(int) CODE_FOR_prefetch
].operand
[0].predicate
)
1006 insn_data
[(int) CODE_FOR_prefetch
].operand
[0].mode
))
1007 || (GET_MODE (op0
) != Pmode
))
1009 op0
= convert_memory_address (Pmode
, op0
);
1010 op0
= force_reg (Pmode
, op0
);
1012 emit_insn (gen_prefetch (op0
, op1
, op2
));
1016 /* Don't do anything with direct references to volatile memory, but
1017 generate code to handle other side effects. */
1018 if (!MEM_P (op0
) && side_effects_p (op0
))
1022 /* Get a MEM rtx for expression EXP which is the address of an operand
1023 to be used in a string instruction (cmpstrsi, movmemsi, ..). LEN is
1024 the maximum length of the block of memory that might be accessed or
1028 get_memory_rtx (tree exp
, tree len
)
1030 rtx addr
= expand_expr (exp
, NULL_RTX
, ptr_mode
, EXPAND_NORMAL
);
1031 rtx mem
= gen_rtx_MEM (BLKmode
, memory_address (BLKmode
, addr
));
1033 /* Get an expression we can use to find the attributes to assign to MEM.
1034 If it is an ADDR_EXPR, use the operand. Otherwise, dereference it if
1035 we can. First remove any nops. */
1036 while ((TREE_CODE (exp
) == NOP_EXPR
|| TREE_CODE (exp
) == CONVERT_EXPR
1037 || TREE_CODE (exp
) == NON_LVALUE_EXPR
)
1038 && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (exp
, 0))))
1039 exp
= TREE_OPERAND (exp
, 0);
1041 if (TREE_CODE (exp
) == ADDR_EXPR
)
1042 exp
= TREE_OPERAND (exp
, 0);
1043 else if (POINTER_TYPE_P (TREE_TYPE (exp
)))
1044 exp
= build1 (INDIRECT_REF
, TREE_TYPE (TREE_TYPE (exp
)), exp
);
1048 /* Honor attributes derived from exp, except for the alias set
1049 (as builtin stringops may alias with anything) and the size
1050 (as stringops may access multiple array elements). */
1053 set_mem_attributes (mem
, exp
, 0);
1055 /* Allow the string and memory builtins to overflow from one
1056 field into another, see http://gcc.gnu.org/PR23561.
1057 Thus avoid COMPONENT_REFs in MEM_EXPR unless we know the whole
1058 memory accessed by the string or memory builtin will fit
1059 within the field. */
1060 if (MEM_EXPR (mem
) && TREE_CODE (MEM_EXPR (mem
)) == COMPONENT_REF
)
1062 tree mem_expr
= MEM_EXPR (mem
);
1063 HOST_WIDE_INT offset
= -1, length
= -1;
1066 while (TREE_CODE (inner
) == ARRAY_REF
1067 || TREE_CODE (inner
) == NOP_EXPR
1068 || TREE_CODE (inner
) == CONVERT_EXPR
1069 || TREE_CODE (inner
) == NON_LVALUE_EXPR
1070 || TREE_CODE (inner
) == VIEW_CONVERT_EXPR
1071 || TREE_CODE (inner
) == SAVE_EXPR
)
1072 inner
= TREE_OPERAND (inner
, 0);
1074 gcc_assert (TREE_CODE (inner
) == COMPONENT_REF
);
1076 if (MEM_OFFSET (mem
)
1077 && GET_CODE (MEM_OFFSET (mem
)) == CONST_INT
)
1078 offset
= INTVAL (MEM_OFFSET (mem
));
1080 if (offset
>= 0 && len
&& host_integerp (len
, 0))
1081 length
= tree_low_cst (len
, 0);
1083 while (TREE_CODE (inner
) == COMPONENT_REF
)
1085 tree field
= TREE_OPERAND (inner
, 1);
1086 gcc_assert (! DECL_BIT_FIELD (field
));
1087 gcc_assert (TREE_CODE (mem_expr
) == COMPONENT_REF
);
1088 gcc_assert (field
== TREE_OPERAND (mem_expr
, 1));
1091 && TYPE_SIZE_UNIT (TREE_TYPE (inner
))
1092 && host_integerp (TYPE_SIZE_UNIT (TREE_TYPE (inner
)), 0))
1095 = tree_low_cst (TYPE_SIZE_UNIT (TREE_TYPE (inner
)), 0);
1096 /* If we can prove the memory starting at XEXP (mem, 0)
1097 and ending at XEXP (mem, 0) + LENGTH will fit into
1098 this field, we can keep that COMPONENT_REF in MEM_EXPR. */
1101 && offset
+ length
<= size
)
1106 && host_integerp (DECL_FIELD_OFFSET (field
), 0))
1107 offset
+= tree_low_cst (DECL_FIELD_OFFSET (field
), 0)
1108 + tree_low_cst (DECL_FIELD_BIT_OFFSET (field
), 1)
1116 mem_expr
= TREE_OPERAND (mem_expr
, 0);
1117 inner
= TREE_OPERAND (inner
, 0);
1120 if (mem_expr
== NULL
)
1122 if (mem_expr
!= MEM_EXPR (mem
))
1124 set_mem_expr (mem
, mem_expr
);
1125 set_mem_offset (mem
, offset
>= 0 ? GEN_INT (offset
) : NULL_RTX
);
1128 set_mem_alias_set (mem
, 0);
1129 set_mem_size (mem
, NULL_RTX
);
1135 /* Built-in functions to perform an untyped call and return. */
1137 /* For each register that may be used for calling a function, this
1138 gives a mode used to copy the register's value. VOIDmode indicates
1139 the register is not used for calling a function. If the machine
1140 has register windows, this gives only the outbound registers.
1141 INCOMING_REGNO gives the corresponding inbound register. */
1142 static enum machine_mode apply_args_mode
[FIRST_PSEUDO_REGISTER
];
1144 /* For each register that may be used for returning values, this gives
1145 a mode used to copy the register's value. VOIDmode indicates the
1146 register is not used for returning values. If the machine has
1147 register windows, this gives only the outbound registers.
1148 INCOMING_REGNO gives the corresponding inbound register. */
1149 static enum machine_mode apply_result_mode
[FIRST_PSEUDO_REGISTER
];
1151 /* For each register that may be used for calling a function, this
1152 gives the offset of that register into the block returned by
1153 __builtin_apply_args. 0 indicates that the register is not
1154 used for calling a function. */
1155 static int apply_args_reg_offset
[FIRST_PSEUDO_REGISTER
];
1157 /* Return the size required for the block returned by __builtin_apply_args,
1158 and initialize apply_args_mode. */
1161 apply_args_size (void)
1163 static int size
= -1;
1166 enum machine_mode mode
;
1168 /* The values computed by this function never change. */
1171 /* The first value is the incoming arg-pointer. */
1172 size
= GET_MODE_SIZE (Pmode
);
1174 /* The second value is the structure value address unless this is
1175 passed as an "invisible" first argument. */
1176 if (targetm
.calls
.struct_value_rtx (cfun
? TREE_TYPE (cfun
->decl
) : 0, 0))
1177 size
+= GET_MODE_SIZE (Pmode
);
1179 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
1180 if (FUNCTION_ARG_REGNO_P (regno
))
1182 mode
= reg_raw_mode
[regno
];
1184 gcc_assert (mode
!= VOIDmode
);
1186 align
= GET_MODE_ALIGNMENT (mode
) / BITS_PER_UNIT
;
1187 if (size
% align
!= 0)
1188 size
= CEIL (size
, align
) * align
;
1189 apply_args_reg_offset
[regno
] = size
;
1190 size
+= GET_MODE_SIZE (mode
);
1191 apply_args_mode
[regno
] = mode
;
1195 apply_args_mode
[regno
] = VOIDmode
;
1196 apply_args_reg_offset
[regno
] = 0;
1202 /* Return the size required for the block returned by __builtin_apply,
1203 and initialize apply_result_mode. */
1206 apply_result_size (void)
1208 static int size
= -1;
1210 enum machine_mode mode
;
1212 /* The values computed by this function never change. */
1217 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
1218 if (FUNCTION_VALUE_REGNO_P (regno
))
1220 mode
= reg_raw_mode
[regno
];
1222 gcc_assert (mode
!= VOIDmode
);
1224 align
= GET_MODE_ALIGNMENT (mode
) / BITS_PER_UNIT
;
1225 if (size
% align
!= 0)
1226 size
= CEIL (size
, align
) * align
;
1227 size
+= GET_MODE_SIZE (mode
);
1228 apply_result_mode
[regno
] = mode
;
1231 apply_result_mode
[regno
] = VOIDmode
;
1233 /* Allow targets that use untyped_call and untyped_return to override
1234 the size so that machine-specific information can be stored here. */
1235 #ifdef APPLY_RESULT_SIZE
1236 size
= APPLY_RESULT_SIZE
;
1242 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
1243 /* Create a vector describing the result block RESULT. If SAVEP is true,
1244 the result block is used to save the values; otherwise it is used to
1245 restore the values. */
1248 result_vector (int savep
, rtx result
)
1250 int regno
, size
, align
, nelts
;
1251 enum machine_mode mode
;
1253 rtx
*savevec
= alloca (FIRST_PSEUDO_REGISTER
* sizeof (rtx
));
1256 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
1257 if ((mode
= apply_result_mode
[regno
]) != VOIDmode
)
1259 align
= GET_MODE_ALIGNMENT (mode
) / BITS_PER_UNIT
;
1260 if (size
% align
!= 0)
1261 size
= CEIL (size
, align
) * align
;
1262 reg
= gen_rtx_REG (mode
, savep
? regno
: INCOMING_REGNO (regno
));
1263 mem
= adjust_address (result
, mode
, size
);
1264 savevec
[nelts
++] = (savep
1265 ? gen_rtx_SET (VOIDmode
, mem
, reg
)
1266 : gen_rtx_SET (VOIDmode
, reg
, mem
));
1267 size
+= GET_MODE_SIZE (mode
);
1269 return gen_rtx_PARALLEL (VOIDmode
, gen_rtvec_v (nelts
, savevec
));
1271 #endif /* HAVE_untyped_call or HAVE_untyped_return */
1273 /* Save the state required to perform an untyped call with the same
1274 arguments as were passed to the current function. */
1277 expand_builtin_apply_args_1 (void)
1280 int size
, align
, regno
;
1281 enum machine_mode mode
;
1282 rtx struct_incoming_value
= targetm
.calls
.struct_value_rtx (cfun
? TREE_TYPE (cfun
->decl
) : 0, 1);
1284 /* Create a block where the arg-pointer, structure value address,
1285 and argument registers can be saved. */
1286 registers
= assign_stack_local (BLKmode
, apply_args_size (), -1);
1288 /* Walk past the arg-pointer and structure value address. */
1289 size
= GET_MODE_SIZE (Pmode
);
1290 if (targetm
.calls
.struct_value_rtx (cfun
? TREE_TYPE (cfun
->decl
) : 0, 0))
1291 size
+= GET_MODE_SIZE (Pmode
);
1293 /* Save each register used in calling a function to the block. */
1294 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
1295 if ((mode
= apply_args_mode
[regno
]) != VOIDmode
)
1297 align
= GET_MODE_ALIGNMENT (mode
) / BITS_PER_UNIT
;
1298 if (size
% align
!= 0)
1299 size
= CEIL (size
, align
) * align
;
1301 tem
= gen_rtx_REG (mode
, INCOMING_REGNO (regno
));
1303 emit_move_insn (adjust_address (registers
, mode
, size
), tem
);
1304 size
+= GET_MODE_SIZE (mode
);
1307 /* Save the arg pointer to the block. */
1308 tem
= copy_to_reg (virtual_incoming_args_rtx
);
1309 #ifdef STACK_GROWS_DOWNWARD
1310 /* We need the pointer as the caller actually passed them to us, not
1311 as we might have pretended they were passed. Make sure it's a valid
1312 operand, as emit_move_insn isn't expected to handle a PLUS. */
1314 = force_operand (plus_constant (tem
, current_function_pretend_args_size
),
1317 emit_move_insn (adjust_address (registers
, Pmode
, 0), tem
);
1319 size
= GET_MODE_SIZE (Pmode
);
1321 /* Save the structure value address unless this is passed as an
1322 "invisible" first argument. */
1323 if (struct_incoming_value
)
1325 emit_move_insn (adjust_address (registers
, Pmode
, size
),
1326 copy_to_reg (struct_incoming_value
));
1327 size
+= GET_MODE_SIZE (Pmode
);
1330 /* Return the address of the block. */
1331 return copy_addr_to_reg (XEXP (registers
, 0));
1334 /* __builtin_apply_args returns block of memory allocated on
1335 the stack into which is stored the arg pointer, structure
1336 value address, static chain, and all the registers that might
1337 possibly be used in performing a function call. The code is
1338 moved to the start of the function so the incoming values are
1342 expand_builtin_apply_args (void)
1344 /* Don't do __builtin_apply_args more than once in a function.
1345 Save the result of the first call and reuse it. */
1346 if (apply_args_value
!= 0)
1347 return apply_args_value
;
1349 /* When this function is called, it means that registers must be
1350 saved on entry to this function. So we migrate the
1351 call to the first insn of this function. */
1356 temp
= expand_builtin_apply_args_1 ();
1360 apply_args_value
= temp
;
1362 /* Put the insns after the NOTE that starts the function.
1363 If this is inside a start_sequence, make the outer-level insn
1364 chain current, so the code is placed at the start of the
1366 push_topmost_sequence ();
1367 emit_insn_before (seq
, NEXT_INSN (entry_of_function ()));
1368 pop_topmost_sequence ();
1373 /* Perform an untyped call and save the state required to perform an
1374 untyped return of whatever value was returned by the given function. */
1377 expand_builtin_apply (rtx function
, rtx arguments
, rtx argsize
)
1379 int size
, align
, regno
;
1380 enum machine_mode mode
;
1381 rtx incoming_args
, result
, reg
, dest
, src
, call_insn
;
1382 rtx old_stack_level
= 0;
1383 rtx call_fusage
= 0;
1384 rtx struct_value
= targetm
.calls
.struct_value_rtx (cfun
? TREE_TYPE (cfun
->decl
) : 0, 0);
1386 arguments
= convert_memory_address (Pmode
, arguments
);
1388 /* Create a block where the return registers can be saved. */
1389 result
= assign_stack_local (BLKmode
, apply_result_size (), -1);
1391 /* Fetch the arg pointer from the ARGUMENTS block. */
1392 incoming_args
= gen_reg_rtx (Pmode
);
1393 emit_move_insn (incoming_args
, gen_rtx_MEM (Pmode
, arguments
));
1394 #ifndef STACK_GROWS_DOWNWARD
1395 incoming_args
= expand_simple_binop (Pmode
, MINUS
, incoming_args
, argsize
,
1396 incoming_args
, 0, OPTAB_LIB_WIDEN
);
1399 /* Push a new argument block and copy the arguments. Do not allow
1400 the (potential) memcpy call below to interfere with our stack
1402 do_pending_stack_adjust ();
1405 /* Save the stack with nonlocal if available. */
1406 #ifdef HAVE_save_stack_nonlocal
1407 if (HAVE_save_stack_nonlocal
)
1408 emit_stack_save (SAVE_NONLOCAL
, &old_stack_level
, NULL_RTX
);
1411 emit_stack_save (SAVE_BLOCK
, &old_stack_level
, NULL_RTX
);
1413 /* Allocate a block of memory onto the stack and copy the memory
1414 arguments to the outgoing arguments address. */
1415 allocate_dynamic_stack_space (argsize
, 0, BITS_PER_UNIT
);
1416 dest
= virtual_outgoing_args_rtx
;
1417 #ifndef STACK_GROWS_DOWNWARD
1418 if (GET_CODE (argsize
) == CONST_INT
)
1419 dest
= plus_constant (dest
, -INTVAL (argsize
));
1421 dest
= gen_rtx_PLUS (Pmode
, dest
, negate_rtx (Pmode
, argsize
));
1423 dest
= gen_rtx_MEM (BLKmode
, dest
);
1424 set_mem_align (dest
, PARM_BOUNDARY
);
1425 src
= gen_rtx_MEM (BLKmode
, incoming_args
);
1426 set_mem_align (src
, PARM_BOUNDARY
);
1427 emit_block_move (dest
, src
, argsize
, BLOCK_OP_NORMAL
);
1429 /* Refer to the argument block. */
1431 arguments
= gen_rtx_MEM (BLKmode
, arguments
);
1432 set_mem_align (arguments
, PARM_BOUNDARY
);
1434 /* Walk past the arg-pointer and structure value address. */
1435 size
= GET_MODE_SIZE (Pmode
);
1437 size
+= GET_MODE_SIZE (Pmode
);
1439 /* Restore each of the registers previously saved. Make USE insns
1440 for each of these registers for use in making the call. */
1441 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
1442 if ((mode
= apply_args_mode
[regno
]) != VOIDmode
)
1444 align
= GET_MODE_ALIGNMENT (mode
) / BITS_PER_UNIT
;
1445 if (size
% align
!= 0)
1446 size
= CEIL (size
, align
) * align
;
1447 reg
= gen_rtx_REG (mode
, regno
);
1448 emit_move_insn (reg
, adjust_address (arguments
, mode
, size
));
1449 use_reg (&call_fusage
, reg
);
1450 size
+= GET_MODE_SIZE (mode
);
1453 /* Restore the structure value address unless this is passed as an
1454 "invisible" first argument. */
1455 size
= GET_MODE_SIZE (Pmode
);
1458 rtx value
= gen_reg_rtx (Pmode
);
1459 emit_move_insn (value
, adjust_address (arguments
, Pmode
, size
));
1460 emit_move_insn (struct_value
, value
);
1461 if (REG_P (struct_value
))
1462 use_reg (&call_fusage
, struct_value
);
1463 size
+= GET_MODE_SIZE (Pmode
);
1466 /* All arguments and registers used for the call are set up by now! */
1467 function
= prepare_call_address (function
, NULL
, &call_fusage
, 0, 0);
1469 /* Ensure address is valid. SYMBOL_REF is already valid, so no need,
1470 and we don't want to load it into a register as an optimization,
1471 because prepare_call_address already did it if it should be done. */
1472 if (GET_CODE (function
) != SYMBOL_REF
)
1473 function
= memory_address (FUNCTION_MODE
, function
);
1475 /* Generate the actual call instruction and save the return value. */
1476 #ifdef HAVE_untyped_call
1477 if (HAVE_untyped_call
)
1478 emit_call_insn (gen_untyped_call (gen_rtx_MEM (FUNCTION_MODE
, function
),
1479 result
, result_vector (1, result
)));
1482 #ifdef HAVE_call_value
1483 if (HAVE_call_value
)
1487 /* Locate the unique return register. It is not possible to
1488 express a call that sets more than one return register using
1489 call_value; use untyped_call for that. In fact, untyped_call
1490 only needs to save the return registers in the given block. */
1491 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
1492 if ((mode
= apply_result_mode
[regno
]) != VOIDmode
)
1494 gcc_assert (!valreg
); /* HAVE_untyped_call required. */
1496 valreg
= gen_rtx_REG (mode
, regno
);
1499 emit_call_insn (GEN_CALL_VALUE (valreg
,
1500 gen_rtx_MEM (FUNCTION_MODE
, function
),
1501 const0_rtx
, NULL_RTX
, const0_rtx
));
1503 emit_move_insn (adjust_address (result
, GET_MODE (valreg
), 0), valreg
);
1509 /* Find the CALL insn we just emitted, and attach the register usage
1511 call_insn
= last_call_insn ();
1512 add_function_usage_to (call_insn
, call_fusage
);
1514 /* Restore the stack. */
1515 #ifdef HAVE_save_stack_nonlocal
1516 if (HAVE_save_stack_nonlocal
)
1517 emit_stack_restore (SAVE_NONLOCAL
, old_stack_level
, NULL_RTX
);
1520 emit_stack_restore (SAVE_BLOCK
, old_stack_level
, NULL_RTX
);
1524 /* Return the address of the result block. */
1525 result
= copy_addr_to_reg (XEXP (result
, 0));
1526 return convert_memory_address (ptr_mode
, result
);
1529 /* Perform an untyped return. */
1532 expand_builtin_return (rtx result
)
1534 int size
, align
, regno
;
1535 enum machine_mode mode
;
1537 rtx call_fusage
= 0;
1539 result
= convert_memory_address (Pmode
, result
);
1541 apply_result_size ();
1542 result
= gen_rtx_MEM (BLKmode
, result
);
1544 #ifdef HAVE_untyped_return
1545 if (HAVE_untyped_return
)
1547 emit_jump_insn (gen_untyped_return (result
, result_vector (0, result
)));
1553 /* Restore the return value and note that each value is used. */
1555 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
1556 if ((mode
= apply_result_mode
[regno
]) != VOIDmode
)
1558 align
= GET_MODE_ALIGNMENT (mode
) / BITS_PER_UNIT
;
1559 if (size
% align
!= 0)
1560 size
= CEIL (size
, align
) * align
;
1561 reg
= gen_rtx_REG (mode
, INCOMING_REGNO (regno
));
1562 emit_move_insn (reg
, adjust_address (result
, mode
, size
));
1564 push_to_sequence (call_fusage
);
1565 emit_insn (gen_rtx_USE (VOIDmode
, reg
));
1566 call_fusage
= get_insns ();
1568 size
+= GET_MODE_SIZE (mode
);
1571 /* Put the USE insns before the return. */
1572 emit_insn (call_fusage
);
1574 /* Return whatever values was restored by jumping directly to the end
1576 expand_naked_return ();
1579 /* Used by expand_builtin_classify_type and fold_builtin_classify_type. */
1581 static enum type_class
1582 type_to_class (tree type
)
1584 switch (TREE_CODE (type
))
1586 case VOID_TYPE
: return void_type_class
;
1587 case INTEGER_TYPE
: return integer_type_class
;
1588 case CHAR_TYPE
: return char_type_class
;
1589 case ENUMERAL_TYPE
: return enumeral_type_class
;
1590 case BOOLEAN_TYPE
: return boolean_type_class
;
1591 case POINTER_TYPE
: return pointer_type_class
;
1592 case REFERENCE_TYPE
: return reference_type_class
;
1593 case OFFSET_TYPE
: return offset_type_class
;
1594 case REAL_TYPE
: return real_type_class
;
1595 case COMPLEX_TYPE
: return complex_type_class
;
1596 case FUNCTION_TYPE
: return function_type_class
;
1597 case METHOD_TYPE
: return method_type_class
;
1598 case RECORD_TYPE
: return record_type_class
;
1600 case QUAL_UNION_TYPE
: return union_type_class
;
1601 case ARRAY_TYPE
: return (TYPE_STRING_FLAG (type
)
1602 ? string_type_class
: array_type_class
);
1603 case LANG_TYPE
: return lang_type_class
;
1604 default: return no_type_class
;
1608 /* Expand a call to __builtin_classify_type with arguments found in
1612 expand_builtin_classify_type (tree arglist
)
1615 return GEN_INT (type_to_class (TREE_TYPE (TREE_VALUE (arglist
))));
1616 return GEN_INT (no_type_class
);
1619 /* This helper macro, meant to be used in mathfn_built_in below,
1620 determines which among a set of three builtin math functions is
1621 appropriate for a given type mode. The `F' and `L' cases are
1622 automatically generated from the `double' case. */
1623 #define CASE_MATHFN(BUILT_IN_MATHFN) \
1624 case BUILT_IN_MATHFN: case BUILT_IN_MATHFN##F: case BUILT_IN_MATHFN##L: \
1625 fcode = BUILT_IN_MATHFN; fcodef = BUILT_IN_MATHFN##F ; \
1626 fcodel = BUILT_IN_MATHFN##L ; break;
1628 /* Return mathematic function equivalent to FN but operating directly
1629 on TYPE, if available. If we can't do the conversion, return zero. */
1631 mathfn_built_in (tree type
, enum built_in_function fn
)
1633 enum built_in_function fcode
, fcodef
, fcodel
;
1637 CASE_MATHFN (BUILT_IN_ACOS
)
1638 CASE_MATHFN (BUILT_IN_ACOSH
)
1639 CASE_MATHFN (BUILT_IN_ASIN
)
1640 CASE_MATHFN (BUILT_IN_ASINH
)
1641 CASE_MATHFN (BUILT_IN_ATAN
)
1642 CASE_MATHFN (BUILT_IN_ATAN2
)
1643 CASE_MATHFN (BUILT_IN_ATANH
)
1644 CASE_MATHFN (BUILT_IN_CBRT
)
1645 CASE_MATHFN (BUILT_IN_CEIL
)
1646 CASE_MATHFN (BUILT_IN_COPYSIGN
)
1647 CASE_MATHFN (BUILT_IN_COS
)
1648 CASE_MATHFN (BUILT_IN_COSH
)
1649 CASE_MATHFN (BUILT_IN_DREM
)
1650 CASE_MATHFN (BUILT_IN_ERF
)
1651 CASE_MATHFN (BUILT_IN_ERFC
)
1652 CASE_MATHFN (BUILT_IN_EXP
)
1653 CASE_MATHFN (BUILT_IN_EXP10
)
1654 CASE_MATHFN (BUILT_IN_EXP2
)
1655 CASE_MATHFN (BUILT_IN_EXPM1
)
1656 CASE_MATHFN (BUILT_IN_FABS
)
1657 CASE_MATHFN (BUILT_IN_FDIM
)
1658 CASE_MATHFN (BUILT_IN_FLOOR
)
1659 CASE_MATHFN (BUILT_IN_FMA
)
1660 CASE_MATHFN (BUILT_IN_FMAX
)
1661 CASE_MATHFN (BUILT_IN_FMIN
)
1662 CASE_MATHFN (BUILT_IN_FMOD
)
1663 CASE_MATHFN (BUILT_IN_FREXP
)
1664 CASE_MATHFN (BUILT_IN_GAMMA
)
1665 CASE_MATHFN (BUILT_IN_HUGE_VAL
)
1666 CASE_MATHFN (BUILT_IN_HYPOT
)
1667 CASE_MATHFN (BUILT_IN_ILOGB
)
1668 CASE_MATHFN (BUILT_IN_INF
)
1669 CASE_MATHFN (BUILT_IN_J0
)
1670 CASE_MATHFN (BUILT_IN_J1
)
1671 CASE_MATHFN (BUILT_IN_JN
)
1672 CASE_MATHFN (BUILT_IN_LCEIL
)
1673 CASE_MATHFN (BUILT_IN_LDEXP
)
1674 CASE_MATHFN (BUILT_IN_LFLOOR
)
1675 CASE_MATHFN (BUILT_IN_LGAMMA
)
1676 CASE_MATHFN (BUILT_IN_LLCEIL
)
1677 CASE_MATHFN (BUILT_IN_LLFLOOR
)
1678 CASE_MATHFN (BUILT_IN_LLRINT
)
1679 CASE_MATHFN (BUILT_IN_LLROUND
)
1680 CASE_MATHFN (BUILT_IN_LOG
)
1681 CASE_MATHFN (BUILT_IN_LOG10
)
1682 CASE_MATHFN (BUILT_IN_LOG1P
)
1683 CASE_MATHFN (BUILT_IN_LOG2
)
1684 CASE_MATHFN (BUILT_IN_LOGB
)
1685 CASE_MATHFN (BUILT_IN_LRINT
)
1686 CASE_MATHFN (BUILT_IN_LROUND
)
1687 CASE_MATHFN (BUILT_IN_MODF
)
1688 CASE_MATHFN (BUILT_IN_NAN
)
1689 CASE_MATHFN (BUILT_IN_NANS
)
1690 CASE_MATHFN (BUILT_IN_NEARBYINT
)
1691 CASE_MATHFN (BUILT_IN_NEXTAFTER
)
1692 CASE_MATHFN (BUILT_IN_NEXTTOWARD
)
1693 CASE_MATHFN (BUILT_IN_POW
)
1694 CASE_MATHFN (BUILT_IN_POWI
)
1695 CASE_MATHFN (BUILT_IN_POW10
)
1696 CASE_MATHFN (BUILT_IN_REMAINDER
)
1697 CASE_MATHFN (BUILT_IN_REMQUO
)
1698 CASE_MATHFN (BUILT_IN_RINT
)
1699 CASE_MATHFN (BUILT_IN_ROUND
)
1700 CASE_MATHFN (BUILT_IN_SCALB
)
1701 CASE_MATHFN (BUILT_IN_SCALBLN
)
1702 CASE_MATHFN (BUILT_IN_SCALBN
)
1703 CASE_MATHFN (BUILT_IN_SIGNIFICAND
)
1704 CASE_MATHFN (BUILT_IN_SIN
)
1705 CASE_MATHFN (BUILT_IN_SINCOS
)
1706 CASE_MATHFN (BUILT_IN_SINH
)
1707 CASE_MATHFN (BUILT_IN_SQRT
)
1708 CASE_MATHFN (BUILT_IN_TAN
)
1709 CASE_MATHFN (BUILT_IN_TANH
)
1710 CASE_MATHFN (BUILT_IN_TGAMMA
)
1711 CASE_MATHFN (BUILT_IN_TRUNC
)
1712 CASE_MATHFN (BUILT_IN_Y0
)
1713 CASE_MATHFN (BUILT_IN_Y1
)
1714 CASE_MATHFN (BUILT_IN_YN
)
1720 if (TYPE_MAIN_VARIANT (type
) == double_type_node
)
1721 return implicit_built_in_decls
[fcode
];
1722 else if (TYPE_MAIN_VARIANT (type
) == float_type_node
)
1723 return implicit_built_in_decls
[fcodef
];
1724 else if (TYPE_MAIN_VARIANT (type
) == long_double_type_node
)
1725 return implicit_built_in_decls
[fcodel
];
1730 /* If errno must be maintained, expand the RTL to check if the result,
1731 TARGET, of a built-in function call, EXP, is NaN, and if so set
1735 expand_errno_check (tree exp
, rtx target
)
1737 rtx lab
= gen_label_rtx ();
1739 /* Test the result; if it is NaN, set errno=EDOM because
1740 the argument was not in the domain. */
1741 emit_cmp_and_jump_insns (target
, target
, EQ
, 0, GET_MODE (target
),
1745 /* If this built-in doesn't throw an exception, set errno directly. */
1746 if (TREE_NOTHROW (TREE_OPERAND (TREE_OPERAND (exp
, 0), 0)))
1748 #ifdef GEN_ERRNO_RTX
1749 rtx errno_rtx
= GEN_ERRNO_RTX
;
1752 = gen_rtx_MEM (word_mode
, gen_rtx_SYMBOL_REF (Pmode
, "errno"));
1754 emit_move_insn (errno_rtx
, GEN_INT (TARGET_EDOM
));
1760 /* We can't set errno=EDOM directly; let the library call do it.
1761 Pop the arguments right away in case the call gets deleted. */
1763 expand_call (exp
, target
, 0);
1769 /* Expand a call to one of the builtin math functions (sqrt, exp, or log).
1770 Return 0 if a normal call should be emitted rather than expanding the
1771 function in-line. EXP is the expression that is a call to the builtin
1772 function; if convenient, the result should be placed in TARGET.
1773 SUBTARGET may be used as the target for computing one of EXP's operands. */
1776 expand_builtin_mathfn (tree exp
, rtx target
, rtx subtarget
)
1778 optab builtin_optab
;
1779 rtx op0
, insns
, before_call
;
1780 tree fndecl
= get_callee_fndecl (exp
);
1781 tree arglist
= TREE_OPERAND (exp
, 1);
1782 enum machine_mode mode
;
1783 bool errno_set
= false;
1786 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
1789 arg
= TREE_VALUE (arglist
);
1791 switch (DECL_FUNCTION_CODE (fndecl
))
1793 CASE_FLT_FN (BUILT_IN_SQRT
):
1794 errno_set
= ! tree_expr_nonnegative_p (arg
);
1795 builtin_optab
= sqrt_optab
;
1797 CASE_FLT_FN (BUILT_IN_EXP
):
1798 errno_set
= true; builtin_optab
= exp_optab
; break;
1799 CASE_FLT_FN (BUILT_IN_EXP10
):
1800 CASE_FLT_FN (BUILT_IN_POW10
):
1801 errno_set
= true; builtin_optab
= exp10_optab
; break;
1802 CASE_FLT_FN (BUILT_IN_EXP2
):
1803 errno_set
= true; builtin_optab
= exp2_optab
; break;
1804 CASE_FLT_FN (BUILT_IN_EXPM1
):
1805 errno_set
= true; builtin_optab
= expm1_optab
; break;
1806 CASE_FLT_FN (BUILT_IN_LOGB
):
1807 errno_set
= true; builtin_optab
= logb_optab
; break;
1808 CASE_FLT_FN (BUILT_IN_ILOGB
):
1809 errno_set
= true; builtin_optab
= ilogb_optab
; break;
1810 CASE_FLT_FN (BUILT_IN_LOG
):
1811 errno_set
= true; builtin_optab
= log_optab
; break;
1812 CASE_FLT_FN (BUILT_IN_LOG10
):
1813 errno_set
= true; builtin_optab
= log10_optab
; break;
1814 CASE_FLT_FN (BUILT_IN_LOG2
):
1815 errno_set
= true; builtin_optab
= log2_optab
; break;
1816 CASE_FLT_FN (BUILT_IN_LOG1P
):
1817 errno_set
= true; builtin_optab
= log1p_optab
; break;
1818 CASE_FLT_FN (BUILT_IN_ASIN
):
1819 builtin_optab
= asin_optab
; break;
1820 CASE_FLT_FN (BUILT_IN_ACOS
):
1821 builtin_optab
= acos_optab
; break;
1822 CASE_FLT_FN (BUILT_IN_TAN
):
1823 builtin_optab
= tan_optab
; break;
1824 CASE_FLT_FN (BUILT_IN_ATAN
):
1825 builtin_optab
= atan_optab
; break;
1826 CASE_FLT_FN (BUILT_IN_FLOOR
):
1827 builtin_optab
= floor_optab
; break;
1828 CASE_FLT_FN (BUILT_IN_CEIL
):
1829 builtin_optab
= ceil_optab
; break;
1830 CASE_FLT_FN (BUILT_IN_TRUNC
):
1831 builtin_optab
= btrunc_optab
; break;
1832 CASE_FLT_FN (BUILT_IN_ROUND
):
1833 builtin_optab
= round_optab
; break;
1834 CASE_FLT_FN (BUILT_IN_NEARBYINT
):
1835 builtin_optab
= nearbyint_optab
; break;
1836 CASE_FLT_FN (BUILT_IN_RINT
):
1837 builtin_optab
= rint_optab
; break;
1838 CASE_FLT_FN (BUILT_IN_LRINT
):
1839 CASE_FLT_FN (BUILT_IN_LLRINT
):
1840 builtin_optab
= lrint_optab
; break;
1845 /* Make a suitable register to place result in. */
1846 mode
= TYPE_MODE (TREE_TYPE (exp
));
1848 if (! flag_errno_math
|| ! HONOR_NANS (mode
))
1851 /* Before working hard, check whether the instruction is available. */
1852 if (builtin_optab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
)
1854 target
= gen_reg_rtx (mode
);
1856 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
1857 need to expand the argument again. This way, we will not perform
1858 side-effects more the once. */
1859 narg
= builtin_save_expr (arg
);
1863 arglist
= build_tree_list (NULL_TREE
, arg
);
1864 exp
= build_function_call_expr (fndecl
, arglist
);
1867 op0
= expand_expr (arg
, subtarget
, VOIDmode
, 0);
1871 /* Compute into TARGET.
1872 Set TARGET to wherever the result comes back. */
1873 target
= expand_unop (mode
, builtin_optab
, op0
, target
, 0);
1878 expand_errno_check (exp
, target
);
1880 /* Output the entire sequence. */
1881 insns
= get_insns ();
1887 /* If we were unable to expand via the builtin, stop the sequence
1888 (without outputting the insns) and call to the library function
1889 with the stabilized argument list. */
1893 before_call
= get_last_insn ();
1895 target
= expand_call (exp
, target
, target
== const0_rtx
);
1897 /* If this is a sqrt operation and we don't care about errno, try to
1898 attach a REG_EQUAL note with a SQRT rtx to the emitted libcall.
1899 This allows the semantics of the libcall to be visible to the RTL
1901 if (builtin_optab
== sqrt_optab
&& !errno_set
)
1903 /* Search backwards through the insns emitted by expand_call looking
1904 for the instruction with the REG_RETVAL note. */
1905 rtx last
= get_last_insn ();
1906 while (last
!= before_call
)
1908 if (find_reg_note (last
, REG_RETVAL
, NULL
))
1910 rtx note
= find_reg_note (last
, REG_EQUAL
, NULL
);
1911 /* Check that the REQ_EQUAL note is an EXPR_LIST with
1912 two elements, i.e. symbol_ref(sqrt) and the operand. */
1914 && GET_CODE (note
) == EXPR_LIST
1915 && GET_CODE (XEXP (note
, 0)) == EXPR_LIST
1916 && XEXP (XEXP (note
, 0), 1) != NULL_RTX
1917 && XEXP (XEXP (XEXP (note
, 0), 1), 1) == NULL_RTX
)
1919 rtx operand
= XEXP (XEXP (XEXP (note
, 0), 1), 0);
1920 /* Check operand is a register with expected mode. */
1923 && GET_MODE (operand
) == mode
)
1925 /* Replace the REG_EQUAL note with a SQRT rtx. */
1926 rtx equiv
= gen_rtx_SQRT (mode
, operand
);
1927 set_unique_reg_note (last
, REG_EQUAL
, equiv
);
1932 last
= PREV_INSN (last
);
1939 /* Expand a call to the builtin binary math functions (pow and atan2).
1940 Return 0 if a normal call should be emitted rather than expanding the
1941 function in-line. EXP is the expression that is a call to the builtin
1942 function; if convenient, the result should be placed in TARGET.
1943 SUBTARGET may be used as the target for computing one of EXP's
1947 expand_builtin_mathfn_2 (tree exp
, rtx target
, rtx subtarget
)
1949 optab builtin_optab
;
1950 rtx op0
, op1
, insns
;
1951 int op1_type
= REAL_TYPE
;
1952 tree fndecl
= get_callee_fndecl (exp
);
1953 tree arglist
= TREE_OPERAND (exp
, 1);
1954 tree arg0
, arg1
, temp
, narg
;
1955 enum machine_mode mode
;
1956 bool errno_set
= true;
1959 if ((DECL_FUNCTION_CODE (fndecl
) == BUILT_IN_LDEXP
)
1960 || (DECL_FUNCTION_CODE (fndecl
) == BUILT_IN_LDEXPF
)
1961 || (DECL_FUNCTION_CODE (fndecl
) == BUILT_IN_LDEXPL
))
1962 op1_type
= INTEGER_TYPE
;
1964 if (!validate_arglist (arglist
, REAL_TYPE
, op1_type
, VOID_TYPE
))
1967 arg0
= TREE_VALUE (arglist
);
1968 arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
1970 switch (DECL_FUNCTION_CODE (fndecl
))
1972 CASE_FLT_FN (BUILT_IN_POW
):
1973 builtin_optab
= pow_optab
; break;
1974 CASE_FLT_FN (BUILT_IN_ATAN2
):
1975 builtin_optab
= atan2_optab
; break;
1976 CASE_FLT_FN (BUILT_IN_LDEXP
):
1977 builtin_optab
= ldexp_optab
; break;
1978 CASE_FLT_FN (BUILT_IN_FMOD
):
1979 builtin_optab
= fmod_optab
; break;
1980 CASE_FLT_FN (BUILT_IN_DREM
):
1981 builtin_optab
= drem_optab
; break;
1986 /* Make a suitable register to place result in. */
1987 mode
= TYPE_MODE (TREE_TYPE (exp
));
1989 /* Before working hard, check whether the instruction is available. */
1990 if (builtin_optab
->handlers
[(int) mode
].insn_code
== CODE_FOR_nothing
)
1993 target
= gen_reg_rtx (mode
);
1995 if (! flag_errno_math
|| ! HONOR_NANS (mode
))
1998 /* Always stabilize the argument list. */
1999 narg
= builtin_save_expr (arg1
);
2003 temp
= build_tree_list (NULL_TREE
, narg
);
2007 temp
= TREE_CHAIN (arglist
);
2009 narg
= builtin_save_expr (arg0
);
2013 arglist
= tree_cons (NULL_TREE
, narg
, temp
);
2017 arglist
= tree_cons (NULL_TREE
, arg0
, temp
);
2020 exp
= build_function_call_expr (fndecl
, arglist
);
2022 op0
= expand_expr (arg0
, subtarget
, VOIDmode
, EXPAND_NORMAL
);
2023 op1
= expand_normal (arg1
);
2027 /* Compute into TARGET.
2028 Set TARGET to wherever the result comes back. */
2029 target
= expand_binop (mode
, builtin_optab
, op0
, op1
,
2030 target
, 0, OPTAB_DIRECT
);
2032 /* If we were unable to expand via the builtin, stop the sequence
2033 (without outputting the insns) and call to the library function
2034 with the stabilized argument list. */
2038 return expand_call (exp
, target
, target
== const0_rtx
);
2042 expand_errno_check (exp
, target
);
2044 /* Output the entire sequence. */
2045 insns
= get_insns ();
2052 /* Expand a call to the builtin sin and cos math functions.
2053 Return 0 if a normal call should be emitted rather than expanding the
2054 function in-line. EXP is the expression that is a call to the builtin
2055 function; if convenient, the result should be placed in TARGET.
2056 SUBTARGET may be used as the target for computing one of EXP's
2060 expand_builtin_mathfn_3 (tree exp
, rtx target
, rtx subtarget
)
2062 optab builtin_optab
;
2064 tree fndecl
= get_callee_fndecl (exp
);
2065 tree arglist
= TREE_OPERAND (exp
, 1);
2066 enum machine_mode mode
;
2069 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
2072 arg
= TREE_VALUE (arglist
);
2074 switch (DECL_FUNCTION_CODE (fndecl
))
2076 CASE_FLT_FN (BUILT_IN_SIN
):
2077 CASE_FLT_FN (BUILT_IN_COS
):
2078 builtin_optab
= sincos_optab
; break;
2083 /* Make a suitable register to place result in. */
2084 mode
= TYPE_MODE (TREE_TYPE (exp
));
2086 /* Check if sincos insn is available, otherwise fallback
2087 to sin or cos insn. */
2088 if (builtin_optab
->handlers
[(int) mode
].insn_code
== CODE_FOR_nothing
) {
2089 switch (DECL_FUNCTION_CODE (fndecl
))
2091 CASE_FLT_FN (BUILT_IN_SIN
):
2092 builtin_optab
= sin_optab
; break;
2093 CASE_FLT_FN (BUILT_IN_COS
):
2094 builtin_optab
= cos_optab
; break;
2100 /* Before working hard, check whether the instruction is available. */
2101 if (builtin_optab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
)
2103 target
= gen_reg_rtx (mode
);
2105 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2106 need to expand the argument again. This way, we will not perform
2107 side-effects more the once. */
2108 narg
= save_expr (arg
);
2112 arglist
= build_tree_list (NULL_TREE
, arg
);
2113 exp
= build_function_call_expr (fndecl
, arglist
);
2116 op0
= expand_expr (arg
, subtarget
, VOIDmode
, 0);
2120 /* Compute into TARGET.
2121 Set TARGET to wherever the result comes back. */
2122 if (builtin_optab
== sincos_optab
)
2126 switch (DECL_FUNCTION_CODE (fndecl
))
2128 CASE_FLT_FN (BUILT_IN_SIN
):
2129 result
= expand_twoval_unop (builtin_optab
, op0
, 0, target
, 0);
2131 CASE_FLT_FN (BUILT_IN_COS
):
2132 result
= expand_twoval_unop (builtin_optab
, op0
, target
, 0, 0);
2137 gcc_assert (result
);
2141 target
= expand_unop (mode
, builtin_optab
, op0
, target
, 0);
2146 /* Output the entire sequence. */
2147 insns
= get_insns ();
2153 /* If we were unable to expand via the builtin, stop the sequence
2154 (without outputting the insns) and call to the library function
2155 with the stabilized argument list. */
2159 target
= expand_call (exp
, target
, target
== const0_rtx
);
2164 /* Expand a call to the builtin sincos math function.
2165 Return 0 if a normal call should be emitted rather than expanding the
2166 function in-line. EXP is the expression that is a call to the builtin
2170 expand_builtin_sincos (tree exp
)
2172 rtx op0
, op1
, op2
, target1
, target2
;
2173 tree arglist
= TREE_OPERAND (exp
, 1);
2174 enum machine_mode mode
;
2175 tree arg
, sinp
, cosp
;
2178 if (!validate_arglist (arglist
, REAL_TYPE
,
2179 POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
2182 arg
= TREE_VALUE (arglist
);
2183 sinp
= TREE_VALUE (TREE_CHAIN (arglist
));
2184 cosp
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
2186 /* Make a suitable register to place result in. */
2187 mode
= TYPE_MODE (TREE_TYPE (arg
));
2189 /* Check if sincos insn is available, otherwise emit the call. */
2190 if (sincos_optab
->handlers
[(int) mode
].insn_code
== CODE_FOR_nothing
)
2193 target1
= gen_reg_rtx (mode
);
2194 target2
= gen_reg_rtx (mode
);
2196 op0
= expand_normal (arg
);
2197 op1
= expand_normal (build_fold_indirect_ref (sinp
));
2198 op2
= expand_normal (build_fold_indirect_ref (cosp
));
2200 /* Compute into target1 and target2.
2201 Set TARGET to wherever the result comes back. */
2202 result
= expand_twoval_unop (sincos_optab
, op0
, target2
, target1
, 0);
2203 gcc_assert (result
);
2205 /* Move target1 and target2 to the memory locations indicated
2207 emit_move_insn (op1
, target1
);
2208 emit_move_insn (op2
, target2
);
2213 /* Expand a call to one of the builtin rounding functions (lfloor).
2214 If expanding via optab fails, lower expression to (int)(floor(x)).
2215 EXP is the expression that is a call to the builtin function;
2216 if convenient, the result should be placed in TARGET. SUBTARGET may
2217 be used as the target for computing one of EXP's operands. */
2220 expand_builtin_int_roundingfn (tree exp
, rtx target
, rtx subtarget
)
2222 optab builtin_optab
;
2223 rtx op0
, insns
, tmp
;
2224 tree fndecl
= get_callee_fndecl (exp
);
2225 tree arglist
= TREE_OPERAND (exp
, 1);
2226 enum built_in_function fallback_fn
;
2227 tree fallback_fndecl
;
2228 enum machine_mode mode
;
2231 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
2234 arg
= TREE_VALUE (arglist
);
2236 switch (DECL_FUNCTION_CODE (fndecl
))
2238 CASE_FLT_FN (BUILT_IN_LCEIL
):
2239 CASE_FLT_FN (BUILT_IN_LLCEIL
):
2240 builtin_optab
= lceil_optab
;
2241 fallback_fn
= BUILT_IN_CEIL
;
2244 CASE_FLT_FN (BUILT_IN_LFLOOR
):
2245 CASE_FLT_FN (BUILT_IN_LLFLOOR
):
2246 builtin_optab
= lfloor_optab
;
2247 fallback_fn
= BUILT_IN_FLOOR
;
2254 /* Make a suitable register to place result in. */
2255 mode
= TYPE_MODE (TREE_TYPE (exp
));
2257 /* Before working hard, check whether the instruction is available. */
2258 if (builtin_optab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
)
2260 target
= gen_reg_rtx (mode
);
2262 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2263 need to expand the argument again. This way, we will not perform
2264 side-effects more the once. */
2265 narg
= builtin_save_expr (arg
);
2269 arglist
= build_tree_list (NULL_TREE
, arg
);
2270 exp
= build_function_call_expr (fndecl
, arglist
);
2273 op0
= expand_expr (arg
, subtarget
, VOIDmode
, 0);
2277 /* Compute into TARGET.
2278 Set TARGET to wherever the result comes back. */
2279 target
= expand_unop (mode
, builtin_optab
, op0
, target
, 0);
2283 /* Output the entire sequence. */
2284 insns
= get_insns ();
2290 /* If we were unable to expand via the builtin, stop the sequence
2291 (without outputting the insns). */
2295 /* Fall back to floating point rounding optab. */
2296 fallback_fndecl
= mathfn_built_in (TREE_TYPE (arg
), fallback_fn
);
2297 /* We shouldn't get here on targets without TARGET_C99_FUNCTIONS.
2298 ??? Perhaps convert (int)floorf(x) into (int)floor((double)x). */
2299 gcc_assert (fallback_fndecl
!= NULL_TREE
);
2300 exp
= build_function_call_expr (fallback_fndecl
, arglist
);
2302 tmp
= expand_builtin_mathfn (exp
, NULL_RTX
, NULL_RTX
);
2304 /* Truncate the result of floating point optab to integer
2305 via expand_fix (). */
2306 target
= gen_reg_rtx (mode
);
2307 expand_fix (target
, tmp
, 0);
2312 /* To evaluate powi(x,n), the floating point value x raised to the
2313 constant integer exponent n, we use a hybrid algorithm that
2314 combines the "window method" with look-up tables. For an
2315 introduction to exponentiation algorithms and "addition chains",
2316 see section 4.6.3, "Evaluation of Powers" of Donald E. Knuth,
2317 "Seminumerical Algorithms", Vol. 2, "The Art of Computer Programming",
2318 3rd Edition, 1998, and Daniel M. Gordon, "A Survey of Fast Exponentiation
2319 Methods", Journal of Algorithms, Vol. 27, pp. 129-146, 1998. */
2321 /* Provide a default value for POWI_MAX_MULTS, the maximum number of
2322 multiplications to inline before calling the system library's pow
2323 function. powi(x,n) requires at worst 2*bits(n)-2 multiplications,
2324 so this default never requires calling pow, powf or powl. */
2326 #ifndef POWI_MAX_MULTS
2327 #define POWI_MAX_MULTS (2*HOST_BITS_PER_WIDE_INT-2)
2330 /* The size of the "optimal power tree" lookup table. All
2331 exponents less than this value are simply looked up in the
2332 powi_table below. This threshold is also used to size the
2333 cache of pseudo registers that hold intermediate results. */
2334 #define POWI_TABLE_SIZE 256
2336 /* The size, in bits of the window, used in the "window method"
2337 exponentiation algorithm. This is equivalent to a radix of
2338 (1<<POWI_WINDOW_SIZE) in the corresponding "m-ary method". */
2339 #define POWI_WINDOW_SIZE 3
2341 /* The following table is an efficient representation of an
2342 "optimal power tree". For each value, i, the corresponding
2343 value, j, in the table states than an optimal evaluation
2344 sequence for calculating pow(x,i) can be found by evaluating
2345 pow(x,j)*pow(x,i-j). An optimal power tree for the first
2346 100 integers is given in Knuth's "Seminumerical algorithms". */
2348 static const unsigned char powi_table
[POWI_TABLE_SIZE
] =
2350 0, 1, 1, 2, 2, 3, 3, 4, /* 0 - 7 */
2351 4, 6, 5, 6, 6, 10, 7, 9, /* 8 - 15 */
2352 8, 16, 9, 16, 10, 12, 11, 13, /* 16 - 23 */
2353 12, 17, 13, 18, 14, 24, 15, 26, /* 24 - 31 */
2354 16, 17, 17, 19, 18, 33, 19, 26, /* 32 - 39 */
2355 20, 25, 21, 40, 22, 27, 23, 44, /* 40 - 47 */
2356 24, 32, 25, 34, 26, 29, 27, 44, /* 48 - 55 */
2357 28, 31, 29, 34, 30, 60, 31, 36, /* 56 - 63 */
2358 32, 64, 33, 34, 34, 46, 35, 37, /* 64 - 71 */
2359 36, 65, 37, 50, 38, 48, 39, 69, /* 72 - 79 */
2360 40, 49, 41, 43, 42, 51, 43, 58, /* 80 - 87 */
2361 44, 64, 45, 47, 46, 59, 47, 76, /* 88 - 95 */
2362 48, 65, 49, 66, 50, 67, 51, 66, /* 96 - 103 */
2363 52, 70, 53, 74, 54, 104, 55, 74, /* 104 - 111 */
2364 56, 64, 57, 69, 58, 78, 59, 68, /* 112 - 119 */
2365 60, 61, 61, 80, 62, 75, 63, 68, /* 120 - 127 */
2366 64, 65, 65, 128, 66, 129, 67, 90, /* 128 - 135 */
2367 68, 73, 69, 131, 70, 94, 71, 88, /* 136 - 143 */
2368 72, 128, 73, 98, 74, 132, 75, 121, /* 144 - 151 */
2369 76, 102, 77, 124, 78, 132, 79, 106, /* 152 - 159 */
2370 80, 97, 81, 160, 82, 99, 83, 134, /* 160 - 167 */
2371 84, 86, 85, 95, 86, 160, 87, 100, /* 168 - 175 */
2372 88, 113, 89, 98, 90, 107, 91, 122, /* 176 - 183 */
2373 92, 111, 93, 102, 94, 126, 95, 150, /* 184 - 191 */
2374 96, 128, 97, 130, 98, 133, 99, 195, /* 192 - 199 */
2375 100, 128, 101, 123, 102, 164, 103, 138, /* 200 - 207 */
2376 104, 145, 105, 146, 106, 109, 107, 149, /* 208 - 215 */
2377 108, 200, 109, 146, 110, 170, 111, 157, /* 216 - 223 */
2378 112, 128, 113, 130, 114, 182, 115, 132, /* 224 - 231 */
2379 116, 200, 117, 132, 118, 158, 119, 206, /* 232 - 239 */
2380 120, 240, 121, 162, 122, 147, 123, 152, /* 240 - 247 */
2381 124, 166, 125, 214, 126, 138, 127, 153, /* 248 - 255 */
2385 /* Return the number of multiplications required to calculate
2386 powi(x,n) where n is less than POWI_TABLE_SIZE. This is a
2387 subroutine of powi_cost. CACHE is an array indicating
2388 which exponents have already been calculated. */
2391 powi_lookup_cost (unsigned HOST_WIDE_INT n
, bool *cache
)
2393 /* If we've already calculated this exponent, then this evaluation
2394 doesn't require any additional multiplications. */
2399 return powi_lookup_cost (n
- powi_table
[n
], cache
)
2400 + powi_lookup_cost (powi_table
[n
], cache
) + 1;
2403 /* Return the number of multiplications required to calculate
2404 powi(x,n) for an arbitrary x, given the exponent N. This
2405 function needs to be kept in sync with expand_powi below. */
2408 powi_cost (HOST_WIDE_INT n
)
2410 bool cache
[POWI_TABLE_SIZE
];
2411 unsigned HOST_WIDE_INT digit
;
2412 unsigned HOST_WIDE_INT val
;
2418 /* Ignore the reciprocal when calculating the cost. */
2419 val
= (n
< 0) ? -n
: n
;
2421 /* Initialize the exponent cache. */
2422 memset (cache
, 0, POWI_TABLE_SIZE
* sizeof (bool));
2427 while (val
>= POWI_TABLE_SIZE
)
2431 digit
= val
& ((1 << POWI_WINDOW_SIZE
) - 1);
2432 result
+= powi_lookup_cost (digit
, cache
)
2433 + POWI_WINDOW_SIZE
+ 1;
2434 val
>>= POWI_WINDOW_SIZE
;
2443 return result
+ powi_lookup_cost (val
, cache
);
2446 /* Recursive subroutine of expand_powi. This function takes the array,
2447 CACHE, of already calculated exponents and an exponent N and returns
2448 an RTX that corresponds to CACHE[1]**N, as calculated in mode MODE. */
2451 expand_powi_1 (enum machine_mode mode
, unsigned HOST_WIDE_INT n
, rtx
*cache
)
2453 unsigned HOST_WIDE_INT digit
;
2457 if (n
< POWI_TABLE_SIZE
)
2462 target
= gen_reg_rtx (mode
);
2465 op0
= expand_powi_1 (mode
, n
- powi_table
[n
], cache
);
2466 op1
= expand_powi_1 (mode
, powi_table
[n
], cache
);
2470 target
= gen_reg_rtx (mode
);
2471 digit
= n
& ((1 << POWI_WINDOW_SIZE
) - 1);
2472 op0
= expand_powi_1 (mode
, n
- digit
, cache
);
2473 op1
= expand_powi_1 (mode
, digit
, cache
);
2477 target
= gen_reg_rtx (mode
);
2478 op0
= expand_powi_1 (mode
, n
>> 1, cache
);
2482 result
= expand_mult (mode
, op0
, op1
, target
, 0);
2483 if (result
!= target
)
2484 emit_move_insn (target
, result
);
2488 /* Expand the RTL to evaluate powi(x,n) in mode MODE. X is the
2489 floating point operand in mode MODE, and N is the exponent. This
2490 function needs to be kept in sync with powi_cost above. */
2493 expand_powi (rtx x
, enum machine_mode mode
, HOST_WIDE_INT n
)
2495 unsigned HOST_WIDE_INT val
;
2496 rtx cache
[POWI_TABLE_SIZE
];
2500 return CONST1_RTX (mode
);
2502 val
= (n
< 0) ? -n
: n
;
2504 memset (cache
, 0, sizeof (cache
));
2507 result
= expand_powi_1 (mode
, (n
< 0) ? -n
: n
, cache
);
2509 /* If the original exponent was negative, reciprocate the result. */
2511 result
= expand_binop (mode
, sdiv_optab
, CONST1_RTX (mode
),
2512 result
, NULL_RTX
, 0, OPTAB_LIB_WIDEN
);
2517 /* Expand a call to the pow built-in mathematical function. Return 0 if
2518 a normal call should be emitted rather than expanding the function
2519 in-line. EXP is the expression that is a call to the builtin
2520 function; if convenient, the result should be placed in TARGET. */
2523 expand_builtin_pow (tree exp
, rtx target
, rtx subtarget
)
2525 tree arglist
= TREE_OPERAND (exp
, 1);
2528 if (! validate_arglist (arglist
, REAL_TYPE
, REAL_TYPE
, VOID_TYPE
))
2531 arg0
= TREE_VALUE (arglist
);
2532 arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
2534 if (TREE_CODE (arg1
) == REAL_CST
2535 && ! TREE_CONSTANT_OVERFLOW (arg1
))
2537 REAL_VALUE_TYPE cint
;
2541 c
= TREE_REAL_CST (arg1
);
2542 n
= real_to_integer (&c
);
2543 real_from_integer (&cint
, VOIDmode
, n
, n
< 0 ? -1 : 0, 0);
2544 if (real_identical (&c
, &cint
))
2546 /* If the exponent is -1, 0, 1 or 2, then expand_powi is exact.
2547 Otherwise, check the number of multiplications required.
2548 Note that pow never sets errno for an integer exponent. */
2549 if ((n
>= -1 && n
<= 2)
2550 || (flag_unsafe_math_optimizations
2552 && powi_cost (n
) <= POWI_MAX_MULTS
))
2554 enum machine_mode mode
= TYPE_MODE (TREE_TYPE (exp
));
2555 rtx op
= expand_expr (arg0
, subtarget
, VOIDmode
, 0);
2556 op
= force_reg (mode
, op
);
2557 return expand_powi (op
, mode
, n
);
2562 if (! flag_unsafe_math_optimizations
)
2564 return expand_builtin_mathfn_2 (exp
, target
, subtarget
);
2567 /* Expand a call to the powi built-in mathematical function. Return 0 if
2568 a normal call should be emitted rather than expanding the function
2569 in-line. EXP is the expression that is a call to the builtin
2570 function; if convenient, the result should be placed in TARGET. */
2573 expand_builtin_powi (tree exp
, rtx target
, rtx subtarget
)
2575 tree arglist
= TREE_OPERAND (exp
, 1);
2578 enum machine_mode mode
;
2579 enum machine_mode mode2
;
2581 if (! validate_arglist (arglist
, REAL_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
2584 arg0
= TREE_VALUE (arglist
);
2585 arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
2586 mode
= TYPE_MODE (TREE_TYPE (exp
));
2588 /* Handle constant power. */
2590 if (TREE_CODE (arg1
) == INTEGER_CST
2591 && ! TREE_CONSTANT_OVERFLOW (arg1
))
2593 HOST_WIDE_INT n
= TREE_INT_CST_LOW (arg1
);
2595 /* If the exponent is -1, 0, 1 or 2, then expand_powi is exact.
2596 Otherwise, check the number of multiplications required. */
2597 if ((TREE_INT_CST_HIGH (arg1
) == 0
2598 || TREE_INT_CST_HIGH (arg1
) == -1)
2599 && ((n
>= -1 && n
<= 2)
2601 && powi_cost (n
) <= POWI_MAX_MULTS
)))
2603 op0
= expand_expr (arg0
, subtarget
, VOIDmode
, 0);
2604 op0
= force_reg (mode
, op0
);
2605 return expand_powi (op0
, mode
, n
);
2609 /* Emit a libcall to libgcc. */
2611 /* Mode of the 2nd argument must match that of an int. */
2612 mode2
= mode_for_size (INT_TYPE_SIZE
, MODE_INT
, 0);
2614 if (target
== NULL_RTX
)
2615 target
= gen_reg_rtx (mode
);
2617 op0
= expand_expr (arg0
, subtarget
, mode
, 0);
2618 if (GET_MODE (op0
) != mode
)
2619 op0
= convert_to_mode (mode
, op0
, 0);
2620 op1
= expand_expr (arg1
, 0, mode2
, 0);
2621 if (GET_MODE (op1
) != mode2
)
2622 op1
= convert_to_mode (mode2
, op1
, 0);
2624 target
= emit_library_call_value (powi_optab
->handlers
[(int) mode
].libfunc
,
2625 target
, LCT_CONST_MAKE_BLOCK
, mode
, 2,
2626 op0
, mode
, op1
, mode2
);
2631 /* Expand expression EXP which is a call to the strlen builtin. Return 0
2632 if we failed the caller should emit a normal call, otherwise
2633 try to get the result in TARGET, if convenient. */
2636 expand_builtin_strlen (tree arglist
, rtx target
,
2637 enum machine_mode target_mode
)
2639 if (!validate_arglist (arglist
, POINTER_TYPE
, VOID_TYPE
))
2644 tree len
, src
= TREE_VALUE (arglist
);
2645 rtx result
, src_reg
, char_rtx
, before_strlen
;
2646 enum machine_mode insn_mode
= target_mode
, char_mode
;
2647 enum insn_code icode
= CODE_FOR_nothing
;
2650 /* If the length can be computed at compile-time, return it. */
2651 len
= c_strlen (src
, 0);
2653 return expand_expr (len
, target
, target_mode
, EXPAND_NORMAL
);
2655 /* If the length can be computed at compile-time and is constant
2656 integer, but there are side-effects in src, evaluate
2657 src for side-effects, then return len.
2658 E.g. x = strlen (i++ ? "xfoo" + 1 : "bar");
2659 can be optimized into: i++; x = 3; */
2660 len
= c_strlen (src
, 1);
2661 if (len
&& TREE_CODE (len
) == INTEGER_CST
)
2663 expand_expr (src
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
2664 return expand_expr (len
, target
, target_mode
, EXPAND_NORMAL
);
2667 align
= get_pointer_alignment (src
, BIGGEST_ALIGNMENT
) / BITS_PER_UNIT
;
2669 /* If SRC is not a pointer type, don't do this operation inline. */
2673 /* Bail out if we can't compute strlen in the right mode. */
2674 while (insn_mode
!= VOIDmode
)
2676 icode
= strlen_optab
->handlers
[(int) insn_mode
].insn_code
;
2677 if (icode
!= CODE_FOR_nothing
)
2680 insn_mode
= GET_MODE_WIDER_MODE (insn_mode
);
2682 if (insn_mode
== VOIDmode
)
2685 /* Make a place to write the result of the instruction. */
2689 && GET_MODE (result
) == insn_mode
2690 && REGNO (result
) >= FIRST_PSEUDO_REGISTER
))
2691 result
= gen_reg_rtx (insn_mode
);
2693 /* Make a place to hold the source address. We will not expand
2694 the actual source until we are sure that the expansion will
2695 not fail -- there are trees that cannot be expanded twice. */
2696 src_reg
= gen_reg_rtx (Pmode
);
2698 /* Mark the beginning of the strlen sequence so we can emit the
2699 source operand later. */
2700 before_strlen
= get_last_insn ();
2702 char_rtx
= const0_rtx
;
2703 char_mode
= insn_data
[(int) icode
].operand
[2].mode
;
2704 if (! (*insn_data
[(int) icode
].operand
[2].predicate
) (char_rtx
,
2706 char_rtx
= copy_to_mode_reg (char_mode
, char_rtx
);
2708 pat
= GEN_FCN (icode
) (result
, gen_rtx_MEM (BLKmode
, src_reg
),
2709 char_rtx
, GEN_INT (align
));
2714 /* Now that we are assured of success, expand the source. */
2716 pat
= expand_expr (src
, src_reg
, ptr_mode
, EXPAND_NORMAL
);
2718 emit_move_insn (src_reg
, pat
);
2723 emit_insn_after (pat
, before_strlen
);
2725 emit_insn_before (pat
, get_insns ());
2727 /* Return the value in the proper mode for this function. */
2728 if (GET_MODE (result
) == target_mode
)
2730 else if (target
!= 0)
2731 convert_move (target
, result
, 0);
2733 target
= convert_to_mode (target_mode
, result
, 0);
2739 /* Expand a call to the strstr builtin. Return 0 if we failed the
2740 caller should emit a normal call, otherwise try to get the result
2741 in TARGET, if convenient (and in mode MODE if that's convenient). */
2744 expand_builtin_strstr (tree arglist
, tree type
, rtx target
, enum machine_mode mode
)
2746 if (validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
2748 tree result
= fold_builtin_strstr (arglist
, type
);
2750 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
2755 /* Expand a call to the strchr builtin. Return 0 if we failed the
2756 caller should emit a normal call, otherwise try to get the result
2757 in TARGET, if convenient (and in mode MODE if that's convenient). */
2760 expand_builtin_strchr (tree arglist
, tree type
, rtx target
, enum machine_mode mode
)
2762 if (validate_arglist (arglist
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
2764 tree result
= fold_builtin_strchr (arglist
, type
);
2766 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
2768 /* FIXME: Should use strchrM optab so that ports can optimize this. */
2773 /* Expand a call to the strrchr builtin. Return 0 if we failed the
2774 caller should emit a normal call, otherwise try to get the result
2775 in TARGET, if convenient (and in mode MODE if that's convenient). */
2778 expand_builtin_strrchr (tree arglist
, tree type
, rtx target
, enum machine_mode mode
)
2780 if (validate_arglist (arglist
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
2782 tree result
= fold_builtin_strrchr (arglist
, type
);
2784 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
2789 /* Expand a call to the strpbrk builtin. Return 0 if we failed the
2790 caller should emit a normal call, otherwise try to get the result
2791 in TARGET, if convenient (and in mode MODE if that's convenient). */
2794 expand_builtin_strpbrk (tree arglist
, tree type
, rtx target
, enum machine_mode mode
)
2796 if (validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
2798 tree result
= fold_builtin_strpbrk (arglist
, type
);
2800 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
2805 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
2806 bytes from constant string DATA + OFFSET and return it as target
2810 builtin_memcpy_read_str (void *data
, HOST_WIDE_INT offset
,
2811 enum machine_mode mode
)
2813 const char *str
= (const char *) data
;
2815 gcc_assert (offset
>= 0
2816 && ((unsigned HOST_WIDE_INT
) offset
+ GET_MODE_SIZE (mode
)
2817 <= strlen (str
) + 1));
2819 return c_readstr (str
+ offset
, mode
);
2822 /* Expand a call to the memcpy builtin, with arguments in ARGLIST.
2823 Return 0 if we failed, the caller should emit a normal call,
2824 otherwise try to get the result in TARGET, if convenient (and in
2825 mode MODE if that's convenient). */
2827 expand_builtin_memcpy (tree exp
, rtx target
, enum machine_mode mode
)
2829 tree fndecl
= get_callee_fndecl (exp
);
2830 tree arglist
= TREE_OPERAND (exp
, 1);
2831 if (!validate_arglist (arglist
,
2832 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
2836 tree dest
= TREE_VALUE (arglist
);
2837 tree src
= TREE_VALUE (TREE_CHAIN (arglist
));
2838 tree len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
2839 const char *src_str
;
2840 unsigned int src_align
= get_pointer_alignment (src
, BIGGEST_ALIGNMENT
);
2841 unsigned int dest_align
2842 = get_pointer_alignment (dest
, BIGGEST_ALIGNMENT
);
2843 rtx dest_mem
, src_mem
, dest_addr
, len_rtx
;
2844 tree result
= fold_builtin_memcpy (fndecl
, arglist
);
2847 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
2849 /* If DEST is not a pointer type, call the normal function. */
2850 if (dest_align
== 0)
2853 /* If either SRC is not a pointer type, don't do this
2854 operation in-line. */
2858 dest_mem
= get_memory_rtx (dest
, len
);
2859 set_mem_align (dest_mem
, dest_align
);
2860 len_rtx
= expand_normal (len
);
2861 src_str
= c_getstr (src
);
2863 /* If SRC is a string constant and block move would be done
2864 by pieces, we can avoid loading the string from memory
2865 and only stored the computed constants. */
2867 && GET_CODE (len_rtx
) == CONST_INT
2868 && (unsigned HOST_WIDE_INT
) INTVAL (len_rtx
) <= strlen (src_str
) + 1
2869 && can_store_by_pieces (INTVAL (len_rtx
), builtin_memcpy_read_str
,
2870 (void *) src_str
, dest_align
))
2872 dest_mem
= store_by_pieces (dest_mem
, INTVAL (len_rtx
),
2873 builtin_memcpy_read_str
,
2874 (void *) src_str
, dest_align
, 0);
2875 dest_mem
= force_operand (XEXP (dest_mem
, 0), NULL_RTX
);
2876 dest_mem
= convert_memory_address (ptr_mode
, dest_mem
);
2880 src_mem
= get_memory_rtx (src
, len
);
2881 set_mem_align (src_mem
, src_align
);
2883 /* Copy word part most expediently. */
2884 dest_addr
= emit_block_move (dest_mem
, src_mem
, len_rtx
,
2885 CALL_EXPR_TAILCALL (exp
)
2886 ? BLOCK_OP_TAILCALL
: BLOCK_OP_NORMAL
);
2890 dest_addr
= force_operand (XEXP (dest_mem
, 0), NULL_RTX
);
2891 dest_addr
= convert_memory_address (ptr_mode
, dest_addr
);
2897 /* Expand a call to the mempcpy builtin, with arguments in ARGLIST.
2898 Return 0 if we failed; the caller should emit a normal call,
2899 otherwise try to get the result in TARGET, if convenient (and in
2900 mode MODE if that's convenient). If ENDP is 0 return the
2901 destination pointer, if ENDP is 1 return the end pointer ala
2902 mempcpy, and if ENDP is 2 return the end pointer minus one ala
2906 expand_builtin_mempcpy (tree arglist
, tree type
, rtx target
, enum machine_mode mode
,
2909 if (!validate_arglist (arglist
,
2910 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
2912 /* If return value is ignored, transform mempcpy into memcpy. */
2913 else if (target
== const0_rtx
)
2915 tree fn
= implicit_built_in_decls
[BUILT_IN_MEMCPY
];
2920 return expand_expr (build_function_call_expr (fn
, arglist
),
2921 target
, mode
, EXPAND_NORMAL
);
2925 tree dest
= TREE_VALUE (arglist
);
2926 tree src
= TREE_VALUE (TREE_CHAIN (arglist
));
2927 tree len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
2928 const char *src_str
;
2929 unsigned int src_align
= get_pointer_alignment (src
, BIGGEST_ALIGNMENT
);
2930 unsigned int dest_align
2931 = get_pointer_alignment (dest
, BIGGEST_ALIGNMENT
);
2932 rtx dest_mem
, src_mem
, len_rtx
;
2933 tree result
= fold_builtin_mempcpy (arglist
, type
, endp
);
2936 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
2938 /* If either SRC or DEST is not a pointer type, don't do this
2939 operation in-line. */
2940 if (dest_align
== 0 || src_align
== 0)
2943 /* If LEN is not constant, call the normal function. */
2944 if (! host_integerp (len
, 1))
2947 len_rtx
= expand_normal (len
);
2948 src_str
= c_getstr (src
);
2950 /* If SRC is a string constant and block move would be done
2951 by pieces, we can avoid loading the string from memory
2952 and only stored the computed constants. */
2954 && GET_CODE (len_rtx
) == CONST_INT
2955 && (unsigned HOST_WIDE_INT
) INTVAL (len_rtx
) <= strlen (src_str
) + 1
2956 && can_store_by_pieces (INTVAL (len_rtx
), builtin_memcpy_read_str
,
2957 (void *) src_str
, dest_align
))
2959 dest_mem
= get_memory_rtx (dest
, len
);
2960 set_mem_align (dest_mem
, dest_align
);
2961 dest_mem
= store_by_pieces (dest_mem
, INTVAL (len_rtx
),
2962 builtin_memcpy_read_str
,
2963 (void *) src_str
, dest_align
, endp
);
2964 dest_mem
= force_operand (XEXP (dest_mem
, 0), NULL_RTX
);
2965 dest_mem
= convert_memory_address (ptr_mode
, dest_mem
);
2969 if (GET_CODE (len_rtx
) == CONST_INT
2970 && can_move_by_pieces (INTVAL (len_rtx
),
2971 MIN (dest_align
, src_align
)))
2973 dest_mem
= get_memory_rtx (dest
, len
);
2974 set_mem_align (dest_mem
, dest_align
);
2975 src_mem
= get_memory_rtx (src
, len
);
2976 set_mem_align (src_mem
, src_align
);
2977 dest_mem
= move_by_pieces (dest_mem
, src_mem
, INTVAL (len_rtx
),
2978 MIN (dest_align
, src_align
), endp
);
2979 dest_mem
= force_operand (XEXP (dest_mem
, 0), NULL_RTX
);
2980 dest_mem
= convert_memory_address (ptr_mode
, dest_mem
);
2988 /* Expand expression EXP, which is a call to the memmove builtin. Return 0
2989 if we failed; the caller should emit a normal call. */
2992 expand_builtin_memmove (tree arglist
, tree type
, rtx target
,
2993 enum machine_mode mode
, tree orig_exp
)
2995 if (!validate_arglist (arglist
,
2996 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
3000 tree dest
= TREE_VALUE (arglist
);
3001 tree src
= TREE_VALUE (TREE_CHAIN (arglist
));
3002 tree len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
3004 unsigned int src_align
= get_pointer_alignment (src
, BIGGEST_ALIGNMENT
);
3005 unsigned int dest_align
3006 = get_pointer_alignment (dest
, BIGGEST_ALIGNMENT
);
3007 tree result
= fold_builtin_memmove (arglist
, type
);
3010 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
3012 /* If DEST is not a pointer type, call the normal function. */
3013 if (dest_align
== 0)
3016 /* If either SRC is not a pointer type, don't do this
3017 operation in-line. */
3021 /* If src is categorized for a readonly section we can use
3023 if (readonly_data_expr (src
))
3025 tree fn
= implicit_built_in_decls
[BUILT_IN_MEMCPY
];
3028 fn
= build_function_call_expr (fn
, arglist
);
3029 if (TREE_CODE (fn
) == CALL_EXPR
)
3030 CALL_EXPR_TAILCALL (fn
) = CALL_EXPR_TAILCALL (orig_exp
);
3031 return expand_expr (fn
, target
, mode
, EXPAND_NORMAL
);
3034 /* If length is 1 and we can expand memcpy call inline,
3035 it is ok to use memcpy as well. */
3036 if (integer_onep (len
))
3038 rtx ret
= expand_builtin_mempcpy (arglist
, type
, target
, mode
,
3044 /* Otherwise, call the normal function. */
3049 /* Expand expression EXP, which is a call to the bcopy builtin. Return 0
3050 if we failed the caller should emit a normal call. */
3053 expand_builtin_bcopy (tree exp
)
3055 tree arglist
= TREE_OPERAND (exp
, 1);
3056 tree type
= TREE_TYPE (exp
);
3057 tree src
, dest
, size
, newarglist
;
3059 if (!validate_arglist (arglist
,
3060 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
3063 src
= TREE_VALUE (arglist
);
3064 dest
= TREE_VALUE (TREE_CHAIN (arglist
));
3065 size
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
3067 /* New argument list transforming bcopy(ptr x, ptr y, int z) to
3068 memmove(ptr y, ptr x, size_t z). This is done this way
3069 so that if it isn't expanded inline, we fallback to
3070 calling bcopy instead of memmove. */
3072 newarglist
= build_tree_list (NULL_TREE
, fold_convert (sizetype
, size
));
3073 newarglist
= tree_cons (NULL_TREE
, src
, newarglist
);
3074 newarglist
= tree_cons (NULL_TREE
, dest
, newarglist
);
3076 return expand_builtin_memmove (newarglist
, type
, const0_rtx
, VOIDmode
, exp
);
3080 # define HAVE_movstr 0
3081 # define CODE_FOR_movstr CODE_FOR_nothing
3084 /* Expand into a movstr instruction, if one is available. Return 0 if
3085 we failed, the caller should emit a normal call, otherwise try to
3086 get the result in TARGET, if convenient. If ENDP is 0 return the
3087 destination pointer, if ENDP is 1 return the end pointer ala
3088 mempcpy, and if ENDP is 2 return the end pointer minus one ala
3092 expand_movstr (tree dest
, tree src
, rtx target
, int endp
)
3098 const struct insn_data
* data
;
3103 dest_mem
= get_memory_rtx (dest
, NULL
);
3104 src_mem
= get_memory_rtx (src
, NULL
);
3107 target
= force_reg (Pmode
, XEXP (dest_mem
, 0));
3108 dest_mem
= replace_equiv_address (dest_mem
, target
);
3109 end
= gen_reg_rtx (Pmode
);
3113 if (target
== 0 || target
== const0_rtx
)
3115 end
= gen_reg_rtx (Pmode
);
3123 data
= insn_data
+ CODE_FOR_movstr
;
3125 if (data
->operand
[0].mode
!= VOIDmode
)
3126 end
= gen_lowpart (data
->operand
[0].mode
, end
);
3128 insn
= data
->genfun (end
, dest_mem
, src_mem
);
3134 /* movstr is supposed to set end to the address of the NUL
3135 terminator. If the caller requested a mempcpy-like return value,
3137 if (endp
== 1 && target
!= const0_rtx
)
3139 rtx tem
= plus_constant (gen_lowpart (GET_MODE (target
), end
), 1);
3140 emit_move_insn (target
, force_operand (tem
, NULL_RTX
));
3146 /* Expand expression EXP, which is a call to the strcpy builtin. Return 0
3147 if we failed the caller should emit a normal call, otherwise try to get
3148 the result in TARGET, if convenient (and in mode MODE if that's
3152 expand_builtin_strcpy (tree fndecl
, tree arglist
, rtx target
, enum machine_mode mode
)
3154 if (validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
3156 tree result
= fold_builtin_strcpy (fndecl
, arglist
, 0);
3158 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
3160 return expand_movstr (TREE_VALUE (arglist
),
3161 TREE_VALUE (TREE_CHAIN (arglist
)),
3162 target
, /*endp=*/0);
3167 /* Expand a call to the stpcpy builtin, with arguments in ARGLIST.
3168 Return 0 if we failed the caller should emit a normal call,
3169 otherwise try to get the result in TARGET, if convenient (and in
3170 mode MODE if that's convenient). */
3173 expand_builtin_stpcpy (tree exp
, rtx target
, enum machine_mode mode
)
3175 tree arglist
= TREE_OPERAND (exp
, 1);
3176 /* If return value is ignored, transform stpcpy into strcpy. */
3177 if (target
== const0_rtx
)
3179 tree fn
= implicit_built_in_decls
[BUILT_IN_STRCPY
];
3183 return expand_expr (build_function_call_expr (fn
, arglist
),
3184 target
, mode
, EXPAND_NORMAL
);
3187 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
3191 tree dst
, src
, len
, lenp1
;
3195 /* Ensure we get an actual string whose length can be evaluated at
3196 compile-time, not an expression containing a string. This is
3197 because the latter will potentially produce pessimized code
3198 when used to produce the return value. */
3199 src
= TREE_VALUE (TREE_CHAIN (arglist
));
3200 if (! c_getstr (src
) || ! (len
= c_strlen (src
, 0)))
3201 return expand_movstr (TREE_VALUE (arglist
),
3202 TREE_VALUE (TREE_CHAIN (arglist
)),
3203 target
, /*endp=*/2);
3205 dst
= TREE_VALUE (arglist
);
3206 lenp1
= size_binop (PLUS_EXPR
, len
, ssize_int (1));
3207 narglist
= build_tree_list (NULL_TREE
, lenp1
);
3208 narglist
= tree_cons (NULL_TREE
, src
, narglist
);
3209 narglist
= tree_cons (NULL_TREE
, dst
, narglist
);
3210 ret
= expand_builtin_mempcpy (narglist
, TREE_TYPE (exp
),
3211 target
, mode
, /*endp=*/2);
3216 if (TREE_CODE (len
) == INTEGER_CST
)
3218 rtx len_rtx
= expand_normal (len
);
3220 if (GET_CODE (len_rtx
) == CONST_INT
)
3222 ret
= expand_builtin_strcpy (get_callee_fndecl (exp
),
3223 arglist
, target
, mode
);
3229 if (mode
!= VOIDmode
)
3230 target
= gen_reg_rtx (mode
);
3232 target
= gen_reg_rtx (GET_MODE (ret
));
3234 if (GET_MODE (target
) != GET_MODE (ret
))
3235 ret
= gen_lowpart (GET_MODE (target
), ret
);
3237 ret
= plus_constant (ret
, INTVAL (len_rtx
));
3238 ret
= emit_move_insn (target
, force_operand (ret
, NULL_RTX
));
3246 return expand_movstr (TREE_VALUE (arglist
),
3247 TREE_VALUE (TREE_CHAIN (arglist
)),
3248 target
, /*endp=*/2);
3252 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
3253 bytes from constant string DATA + OFFSET and return it as target
3257 builtin_strncpy_read_str (void *data
, HOST_WIDE_INT offset
,
3258 enum machine_mode mode
)
3260 const char *str
= (const char *) data
;
3262 if ((unsigned HOST_WIDE_INT
) offset
> strlen (str
))
3265 return c_readstr (str
+ offset
, mode
);
3268 /* Expand expression EXP, which is a call to the strncpy builtin. Return 0
3269 if we failed the caller should emit a normal call. */
3272 expand_builtin_strncpy (tree exp
, rtx target
, enum machine_mode mode
)
3274 tree fndecl
= get_callee_fndecl (exp
);
3275 tree arglist
= TREE_OPERAND (exp
, 1);
3276 if (validate_arglist (arglist
,
3277 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
3279 tree slen
= c_strlen (TREE_VALUE (TREE_CHAIN (arglist
)), 1);
3280 tree len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
3281 tree result
= fold_builtin_strncpy (fndecl
, arglist
, slen
);
3284 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
3286 /* We must be passed a constant len and src parameter. */
3287 if (!host_integerp (len
, 1) || !slen
|| !host_integerp (slen
, 1))
3290 slen
= size_binop (PLUS_EXPR
, slen
, ssize_int (1));
3292 /* We're required to pad with trailing zeros if the requested
3293 len is greater than strlen(s2)+1. In that case try to
3294 use store_by_pieces, if it fails, punt. */
3295 if (tree_int_cst_lt (slen
, len
))
3297 tree dest
= TREE_VALUE (arglist
);
3298 unsigned int dest_align
3299 = get_pointer_alignment (dest
, BIGGEST_ALIGNMENT
);
3300 const char *p
= c_getstr (TREE_VALUE (TREE_CHAIN (arglist
)));
3303 if (!p
|| dest_align
== 0 || !host_integerp (len
, 1)
3304 || !can_store_by_pieces (tree_low_cst (len
, 1),
3305 builtin_strncpy_read_str
,
3306 (void *) p
, dest_align
))
3309 dest_mem
= get_memory_rtx (dest
, len
);
3310 store_by_pieces (dest_mem
, tree_low_cst (len
, 1),
3311 builtin_strncpy_read_str
,
3312 (void *) p
, dest_align
, 0);
3313 dest_mem
= force_operand (XEXP (dest_mem
, 0), NULL_RTX
);
3314 dest_mem
= convert_memory_address (ptr_mode
, dest_mem
);
3321 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
3322 bytes from constant string DATA + OFFSET and return it as target
3326 builtin_memset_read_str (void *data
, HOST_WIDE_INT offset ATTRIBUTE_UNUSED
,
3327 enum machine_mode mode
)
3329 const char *c
= (const char *) data
;
3330 char *p
= alloca (GET_MODE_SIZE (mode
));
3332 memset (p
, *c
, GET_MODE_SIZE (mode
));
3334 return c_readstr (p
, mode
);
3337 /* Callback routine for store_by_pieces. Return the RTL of a register
3338 containing GET_MODE_SIZE (MODE) consecutive copies of the unsigned
3339 char value given in the RTL register data. For example, if mode is
3340 4 bytes wide, return the RTL for 0x01010101*data. */
3343 builtin_memset_gen_str (void *data
, HOST_WIDE_INT offset ATTRIBUTE_UNUSED
,
3344 enum machine_mode mode
)
3350 size
= GET_MODE_SIZE (mode
);
3355 memset (p
, 1, size
);
3356 coeff
= c_readstr (p
, mode
);
3358 target
= convert_to_mode (mode
, (rtx
) data
, 1);
3359 target
= expand_mult (mode
, target
, coeff
, NULL_RTX
, 1);
3360 return force_reg (mode
, target
);
3363 /* Expand expression EXP, which is a call to the memset builtin. Return 0
3364 if we failed the caller should emit a normal call, otherwise try to get
3365 the result in TARGET, if convenient (and in mode MODE if that's
3369 expand_builtin_memset (tree arglist
, rtx target
, enum machine_mode mode
,
3372 if (!validate_arglist (arglist
,
3373 POINTER_TYPE
, INTEGER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
3377 tree dest
= TREE_VALUE (arglist
);
3378 tree val
= TREE_VALUE (TREE_CHAIN (arglist
));
3379 tree len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
3382 unsigned int dest_align
3383 = get_pointer_alignment (dest
, BIGGEST_ALIGNMENT
);
3384 rtx dest_mem
, dest_addr
, len_rtx
;
3386 /* If DEST is not a pointer type, don't do this
3387 operation in-line. */
3388 if (dest_align
== 0)
3391 /* If the LEN parameter is zero, return DEST. */
3392 if (integer_zerop (len
))
3394 /* Evaluate and ignore VAL in case it has side-effects. */
3395 expand_expr (val
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
3396 return expand_expr (dest
, target
, mode
, EXPAND_NORMAL
);
3399 len_rtx
= expand_normal (len
);
3400 dest_mem
= get_memory_rtx (dest
, len
);
3402 if (TREE_CODE (val
) != INTEGER_CST
)
3406 val
= fold_build1 (CONVERT_EXPR
, unsigned_char_type_node
, val
);
3407 val_rtx
= expand_normal (val
);
3409 /* Assume that we can memset by pieces if we can store the
3410 * the coefficients by pieces (in the required modes).
3411 * We can't pass builtin_memset_gen_str as that emits RTL. */
3413 if (host_integerp (len
, 1)
3414 && !(optimize_size
&& tree_low_cst (len
, 1) > 1)
3415 && can_store_by_pieces (tree_low_cst (len
, 1),
3416 builtin_memset_read_str
, &c
, dest_align
))
3418 val_rtx
= force_reg (TYPE_MODE (unsigned_char_type_node
),
3420 store_by_pieces (dest_mem
, tree_low_cst (len
, 1),
3421 builtin_memset_gen_str
, val_rtx
, dest_align
, 0);
3423 else if (!set_storage_via_setmem(dest_mem
, len_rtx
, val_rtx
,
3427 dest_mem
= force_operand (XEXP (dest_mem
, 0), NULL_RTX
);
3428 dest_mem
= convert_memory_address (ptr_mode
, dest_mem
);
3432 if (target_char_cast (val
, &c
))
3437 if (host_integerp (len
, 1)
3438 && !(optimize_size
&& tree_low_cst (len
, 1) > 1)
3439 && can_store_by_pieces (tree_low_cst (len
, 1),
3440 builtin_memset_read_str
, &c
, dest_align
))
3441 store_by_pieces (dest_mem
, tree_low_cst (len
, 1),
3442 builtin_memset_read_str
, &c
, dest_align
, 0);
3443 else if (!set_storage_via_setmem (dest_mem
, len_rtx
, GEN_INT (c
),
3447 dest_mem
= force_operand (XEXP (dest_mem
, 0), NULL_RTX
);
3448 dest_mem
= convert_memory_address (ptr_mode
, dest_mem
);
3452 set_mem_align (dest_mem
, dest_align
);
3453 dest_addr
= clear_storage (dest_mem
, len_rtx
,
3454 CALL_EXPR_TAILCALL (orig_exp
)
3455 ? BLOCK_OP_TAILCALL
: BLOCK_OP_NORMAL
);
3459 dest_addr
= force_operand (XEXP (dest_mem
, 0), NULL_RTX
);
3460 dest_addr
= convert_memory_address (ptr_mode
, dest_addr
);
3467 /* Expand expression EXP, which is a call to the bzero builtin. Return 0
3468 if we failed the caller should emit a normal call. */
3471 expand_builtin_bzero (tree exp
)
3473 tree arglist
= TREE_OPERAND (exp
, 1);
3474 tree dest
, size
, newarglist
;
3476 if (!validate_arglist (arglist
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
3479 dest
= TREE_VALUE (arglist
);
3480 size
= TREE_VALUE (TREE_CHAIN (arglist
));
3482 /* New argument list transforming bzero(ptr x, int y) to
3483 memset(ptr x, int 0, size_t y). This is done this way
3484 so that if it isn't expanded inline, we fallback to
3485 calling bzero instead of memset. */
3487 newarglist
= build_tree_list (NULL_TREE
, fold_convert (sizetype
, size
));
3488 newarglist
= tree_cons (NULL_TREE
, integer_zero_node
, newarglist
);
3489 newarglist
= tree_cons (NULL_TREE
, dest
, newarglist
);
3491 return expand_builtin_memset (newarglist
, const0_rtx
, VOIDmode
, exp
);
3494 /* Expand expression EXP, which is a call to the memcmp built-in function.
3495 ARGLIST is the argument list for this call. Return 0 if we failed and the
3496 caller should emit a normal call, otherwise try to get the result in
3497 TARGET, if convenient (and in mode MODE, if that's convenient). */
3500 expand_builtin_memcmp (tree exp ATTRIBUTE_UNUSED
, tree arglist
, rtx target
,
3501 enum machine_mode mode
)
3503 if (!validate_arglist (arglist
,
3504 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
3508 tree result
= fold_builtin_memcmp (arglist
);
3510 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
3513 #if defined HAVE_cmpmemsi || defined HAVE_cmpstrnsi
3515 tree arg1
= TREE_VALUE (arglist
);
3516 tree arg2
= TREE_VALUE (TREE_CHAIN (arglist
));
3517 tree len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
3518 rtx arg1_rtx
, arg2_rtx
, arg3_rtx
;
3523 = get_pointer_alignment (arg1
, BIGGEST_ALIGNMENT
) / BITS_PER_UNIT
;
3525 = get_pointer_alignment (arg2
, BIGGEST_ALIGNMENT
) / BITS_PER_UNIT
;
3526 enum machine_mode insn_mode
;
3528 #ifdef HAVE_cmpmemsi
3530 insn_mode
= insn_data
[(int) CODE_FOR_cmpmemsi
].operand
[0].mode
;
3533 #ifdef HAVE_cmpstrnsi
3535 insn_mode
= insn_data
[(int) CODE_FOR_cmpstrnsi
].operand
[0].mode
;
3540 /* If we don't have POINTER_TYPE, call the function. */
3541 if (arg1_align
== 0 || arg2_align
== 0)
3544 /* Make a place to write the result of the instruction. */
3547 && REG_P (result
) && GET_MODE (result
) == insn_mode
3548 && REGNO (result
) >= FIRST_PSEUDO_REGISTER
))
3549 result
= gen_reg_rtx (insn_mode
);
3551 arg1_rtx
= get_memory_rtx (arg1
, len
);
3552 arg2_rtx
= get_memory_rtx (arg2
, len
);
3553 arg3_rtx
= expand_normal (len
);
3555 /* Set MEM_SIZE as appropriate. */
3556 if (GET_CODE (arg3_rtx
) == CONST_INT
)
3558 set_mem_size (arg1_rtx
, arg3_rtx
);
3559 set_mem_size (arg2_rtx
, arg3_rtx
);
3562 #ifdef HAVE_cmpmemsi
3564 insn
= gen_cmpmemsi (result
, arg1_rtx
, arg2_rtx
, arg3_rtx
,
3565 GEN_INT (MIN (arg1_align
, arg2_align
)));
3568 #ifdef HAVE_cmpstrnsi
3570 insn
= gen_cmpstrnsi (result
, arg1_rtx
, arg2_rtx
, arg3_rtx
,
3571 GEN_INT (MIN (arg1_align
, arg2_align
)));
3579 emit_library_call_value (memcmp_libfunc
, result
, LCT_PURE_MAKE_BLOCK
,
3580 TYPE_MODE (integer_type_node
), 3,
3581 XEXP (arg1_rtx
, 0), Pmode
,
3582 XEXP (arg2_rtx
, 0), Pmode
,
3583 convert_to_mode (TYPE_MODE (sizetype
), arg3_rtx
,
3584 TYPE_UNSIGNED (sizetype
)),
3585 TYPE_MODE (sizetype
));
3587 /* Return the value in the proper mode for this function. */
3588 mode
= TYPE_MODE (TREE_TYPE (exp
));
3589 if (GET_MODE (result
) == mode
)
3591 else if (target
!= 0)
3593 convert_move (target
, result
, 0);
3597 return convert_to_mode (mode
, result
, 0);
3604 /* Expand expression EXP, which is a call to the strcmp builtin. Return 0
3605 if we failed the caller should emit a normal call, otherwise try to get
3606 the result in TARGET, if convenient. */
3609 expand_builtin_strcmp (tree exp
, rtx target
, enum machine_mode mode
)
3611 tree arglist
= TREE_OPERAND (exp
, 1);
3613 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
3617 tree result
= fold_builtin_strcmp (arglist
);
3619 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
3622 #if defined HAVE_cmpstrsi || defined HAVE_cmpstrnsi
3623 if (cmpstr_optab
[SImode
] != CODE_FOR_nothing
3624 || cmpstrn_optab
[SImode
] != CODE_FOR_nothing
)
3626 rtx arg1_rtx
, arg2_rtx
;
3627 rtx result
, insn
= NULL_RTX
;
3630 tree arg1
= TREE_VALUE (arglist
);
3631 tree arg2
= TREE_VALUE (TREE_CHAIN (arglist
));
3633 = get_pointer_alignment (arg1
, BIGGEST_ALIGNMENT
) / BITS_PER_UNIT
;
3635 = get_pointer_alignment (arg2
, BIGGEST_ALIGNMENT
) / BITS_PER_UNIT
;
3637 /* If we don't have POINTER_TYPE, call the function. */
3638 if (arg1_align
== 0 || arg2_align
== 0)
3641 /* Stabilize the arguments in case gen_cmpstr(n)si fail. */
3642 arg1
= builtin_save_expr (arg1
);
3643 arg2
= builtin_save_expr (arg2
);
3645 arg1_rtx
= get_memory_rtx (arg1
, NULL
);
3646 arg2_rtx
= get_memory_rtx (arg2
, NULL
);
3648 #ifdef HAVE_cmpstrsi
3649 /* Try to call cmpstrsi. */
3652 enum machine_mode insn_mode
3653 = insn_data
[(int) CODE_FOR_cmpstrsi
].operand
[0].mode
;
3655 /* Make a place to write the result of the instruction. */
3658 && REG_P (result
) && GET_MODE (result
) == insn_mode
3659 && REGNO (result
) >= FIRST_PSEUDO_REGISTER
))
3660 result
= gen_reg_rtx (insn_mode
);
3662 insn
= gen_cmpstrsi (result
, arg1_rtx
, arg2_rtx
,
3663 GEN_INT (MIN (arg1_align
, arg2_align
)));
3667 /* Try to determine at least one length and call cmpstrnsi. */
3668 if (!insn
&& HAVE_cmpstrnsi
)
3673 enum machine_mode insn_mode
3674 = insn_data
[(int) CODE_FOR_cmpstrnsi
].operand
[0].mode
;
3675 tree len1
= c_strlen (arg1
, 1);
3676 tree len2
= c_strlen (arg2
, 1);
3679 len1
= size_binop (PLUS_EXPR
, ssize_int (1), len1
);
3681 len2
= size_binop (PLUS_EXPR
, ssize_int (1), len2
);
3683 /* If we don't have a constant length for the first, use the length
3684 of the second, if we know it. We don't require a constant for
3685 this case; some cost analysis could be done if both are available
3686 but neither is constant. For now, assume they're equally cheap,
3687 unless one has side effects. If both strings have constant lengths,
3694 else if (TREE_SIDE_EFFECTS (len1
))
3696 else if (TREE_SIDE_EFFECTS (len2
))
3698 else if (TREE_CODE (len1
) != INTEGER_CST
)
3700 else if (TREE_CODE (len2
) != INTEGER_CST
)
3702 else if (tree_int_cst_lt (len1
, len2
))
3707 /* If both arguments have side effects, we cannot optimize. */
3708 if (!len
|| TREE_SIDE_EFFECTS (len
))
3711 /* Stabilize the arguments in case gen_cmpstrnsi fails. */
3712 arg3_rtx
= expand_normal (len
);
3714 /* Make a place to write the result of the instruction. */
3717 && REG_P (result
) && GET_MODE (result
) == insn_mode
3718 && REGNO (result
) >= FIRST_PSEUDO_REGISTER
))
3719 result
= gen_reg_rtx (insn_mode
);
3721 insn
= gen_cmpstrnsi (result
, arg1_rtx
, arg2_rtx
, arg3_rtx
,
3722 GEN_INT (MIN (arg1_align
, arg2_align
)));
3730 /* Return the value in the proper mode for this function. */
3731 mode
= TYPE_MODE (TREE_TYPE (exp
));
3732 if (GET_MODE (result
) == mode
)
3735 return convert_to_mode (mode
, result
, 0);
3736 convert_move (target
, result
, 0);
3740 /* Expand the library call ourselves using a stabilized argument
3741 list to avoid re-evaluating the function's arguments twice. */
3742 arglist
= build_tree_list (NULL_TREE
, arg2
);
3743 arglist
= tree_cons (NULL_TREE
, arg1
, arglist
);
3744 fndecl
= get_callee_fndecl (exp
);
3745 fn
= build_function_call_expr (fndecl
, arglist
);
3746 if (TREE_CODE (fn
) == CALL_EXPR
)
3747 CALL_EXPR_TAILCALL (fn
) = CALL_EXPR_TAILCALL (exp
);
3748 return expand_call (fn
, target
, target
== const0_rtx
);
3754 /* Expand expression EXP, which is a call to the strncmp builtin. Return 0
3755 if we failed the caller should emit a normal call, otherwise try to get
3756 the result in TARGET, if convenient. */
3759 expand_builtin_strncmp (tree exp
, rtx target
, enum machine_mode mode
)
3761 tree arglist
= TREE_OPERAND (exp
, 1);
3763 if (!validate_arglist (arglist
,
3764 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
3768 tree result
= fold_builtin_strncmp (arglist
);
3770 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
3773 /* If c_strlen can determine an expression for one of the string
3774 lengths, and it doesn't have side effects, then emit cmpstrnsi
3775 using length MIN(strlen(string)+1, arg3). */
3776 #ifdef HAVE_cmpstrnsi
3779 tree arg1
= TREE_VALUE (arglist
);
3780 tree arg2
= TREE_VALUE (TREE_CHAIN (arglist
));
3781 tree arg3
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
3782 tree len
, len1
, len2
;
3783 rtx arg1_rtx
, arg2_rtx
, arg3_rtx
;
3788 = get_pointer_alignment (arg1
, BIGGEST_ALIGNMENT
) / BITS_PER_UNIT
;
3790 = get_pointer_alignment (arg2
, BIGGEST_ALIGNMENT
) / BITS_PER_UNIT
;
3791 enum machine_mode insn_mode
3792 = insn_data
[(int) CODE_FOR_cmpstrnsi
].operand
[0].mode
;
3794 len1
= c_strlen (arg1
, 1);
3795 len2
= c_strlen (arg2
, 1);
3798 len1
= size_binop (PLUS_EXPR
, ssize_int (1), len1
);
3800 len2
= size_binop (PLUS_EXPR
, ssize_int (1), len2
);
3802 /* If we don't have a constant length for the first, use the length
3803 of the second, if we know it. We don't require a constant for
3804 this case; some cost analysis could be done if both are available
3805 but neither is constant. For now, assume they're equally cheap,
3806 unless one has side effects. If both strings have constant lengths,
3813 else if (TREE_SIDE_EFFECTS (len1
))
3815 else if (TREE_SIDE_EFFECTS (len2
))
3817 else if (TREE_CODE (len1
) != INTEGER_CST
)
3819 else if (TREE_CODE (len2
) != INTEGER_CST
)
3821 else if (tree_int_cst_lt (len1
, len2
))
3826 /* If both arguments have side effects, we cannot optimize. */
3827 if (!len
|| TREE_SIDE_EFFECTS (len
))
3830 /* The actual new length parameter is MIN(len,arg3). */
3831 len
= fold_build2 (MIN_EXPR
, TREE_TYPE (len
), len
,
3832 fold_convert (TREE_TYPE (len
), arg3
));
3834 /* If we don't have POINTER_TYPE, call the function. */
3835 if (arg1_align
== 0 || arg2_align
== 0)
3838 /* Make a place to write the result of the instruction. */
3841 && REG_P (result
) && GET_MODE (result
) == insn_mode
3842 && REGNO (result
) >= FIRST_PSEUDO_REGISTER
))
3843 result
= gen_reg_rtx (insn_mode
);
3845 /* Stabilize the arguments in case gen_cmpstrnsi fails. */
3846 arg1
= builtin_save_expr (arg1
);
3847 arg2
= builtin_save_expr (arg2
);
3848 len
= builtin_save_expr (len
);
3850 arg1_rtx
= get_memory_rtx (arg1
, len
);
3851 arg2_rtx
= get_memory_rtx (arg2
, len
);
3852 arg3_rtx
= expand_normal (len
);
3853 insn
= gen_cmpstrnsi (result
, arg1_rtx
, arg2_rtx
, arg3_rtx
,
3854 GEN_INT (MIN (arg1_align
, arg2_align
)));
3859 /* Return the value in the proper mode for this function. */
3860 mode
= TYPE_MODE (TREE_TYPE (exp
));
3861 if (GET_MODE (result
) == mode
)
3864 return convert_to_mode (mode
, result
, 0);
3865 convert_move (target
, result
, 0);
3869 /* Expand the library call ourselves using a stabilized argument
3870 list to avoid re-evaluating the function's arguments twice. */
3871 arglist
= build_tree_list (NULL_TREE
, len
);
3872 arglist
= tree_cons (NULL_TREE
, arg2
, arglist
);
3873 arglist
= tree_cons (NULL_TREE
, arg1
, arglist
);
3874 fndecl
= get_callee_fndecl (exp
);
3875 fn
= build_function_call_expr (fndecl
, arglist
);
3876 if (TREE_CODE (fn
) == CALL_EXPR
)
3877 CALL_EXPR_TAILCALL (fn
) = CALL_EXPR_TAILCALL (exp
);
3878 return expand_call (fn
, target
, target
== const0_rtx
);
3884 /* Expand expression EXP, which is a call to the strcat builtin.
3885 Return 0 if we failed the caller should emit a normal call,
3886 otherwise try to get the result in TARGET, if convenient. */
3889 expand_builtin_strcat (tree fndecl
, tree arglist
, rtx target
, enum machine_mode mode
)
3891 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
3895 tree dst
= TREE_VALUE (arglist
),
3896 src
= TREE_VALUE (TREE_CHAIN (arglist
));
3897 const char *p
= c_getstr (src
);
3899 /* If the string length is zero, return the dst parameter. */
3900 if (p
&& *p
== '\0')
3901 return expand_expr (dst
, target
, mode
, EXPAND_NORMAL
);
3905 /* See if we can store by pieces into (dst + strlen(dst)). */
3906 tree newsrc
, newdst
,
3907 strlen_fn
= implicit_built_in_decls
[BUILT_IN_STRLEN
];
3910 /* Stabilize the argument list. */
3911 newsrc
= builtin_save_expr (src
);
3913 arglist
= build_tree_list (NULL_TREE
, newsrc
);
3915 arglist
= TREE_CHAIN (arglist
); /* Reusing arglist if safe. */
3917 dst
= builtin_save_expr (dst
);
3921 /* Create strlen (dst). */
3923 build_function_call_expr (strlen_fn
,
3924 build_tree_list (NULL_TREE
, dst
));
3925 /* Create (dst + (cast) strlen (dst)). */
3926 newdst
= fold_convert (TREE_TYPE (dst
), newdst
);
3927 newdst
= fold_build2 (PLUS_EXPR
, TREE_TYPE (dst
), dst
, newdst
);
3929 newdst
= builtin_save_expr (newdst
);
3930 arglist
= tree_cons (NULL_TREE
, newdst
, arglist
);
3932 if (!expand_builtin_strcpy (fndecl
, arglist
, target
, mode
))
3934 end_sequence (); /* Stop sequence. */
3938 /* Output the entire sequence. */
3939 insns
= get_insns ();
3943 return expand_expr (dst
, target
, mode
, EXPAND_NORMAL
);
3950 /* Expand expression EXP, which is a call to the strncat builtin.
3951 Return 0 if we failed the caller should emit a normal call,
3952 otherwise try to get the result in TARGET, if convenient. */
3955 expand_builtin_strncat (tree arglist
, rtx target
, enum machine_mode mode
)
3957 if (validate_arglist (arglist
,
3958 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
3960 tree result
= fold_builtin_strncat (arglist
);
3962 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
3967 /* Expand expression EXP, which is a call to the strspn builtin.
3968 Return 0 if we failed the caller should emit a normal call,
3969 otherwise try to get the result in TARGET, if convenient. */
3972 expand_builtin_strspn (tree arglist
, rtx target
, enum machine_mode mode
)
3974 if (validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
3976 tree result
= fold_builtin_strspn (arglist
);
3978 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
3983 /* Expand expression EXP, which is a call to the strcspn builtin.
3984 Return 0 if we failed the caller should emit a normal call,
3985 otherwise try to get the result in TARGET, if convenient. */
3988 expand_builtin_strcspn (tree arglist
, rtx target
, enum machine_mode mode
)
3990 if (validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
3992 tree result
= fold_builtin_strcspn (arglist
);
3994 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
3999 /* Expand a call to __builtin_saveregs, generating the result in TARGET,
4000 if that's convenient. */
4003 expand_builtin_saveregs (void)
4007 /* Don't do __builtin_saveregs more than once in a function.
4008 Save the result of the first call and reuse it. */
4009 if (saveregs_value
!= 0)
4010 return saveregs_value
;
4012 /* When this function is called, it means that registers must be
4013 saved on entry to this function. So we migrate the call to the
4014 first insn of this function. */
4018 /* Do whatever the machine needs done in this case. */
4019 val
= targetm
.calls
.expand_builtin_saveregs ();
4024 saveregs_value
= val
;
4026 /* Put the insns after the NOTE that starts the function. If this
4027 is inside a start_sequence, make the outer-level insn chain current, so
4028 the code is placed at the start of the function. */
4029 push_topmost_sequence ();
4030 emit_insn_after (seq
, entry_of_function ());
4031 pop_topmost_sequence ();
4036 /* __builtin_args_info (N) returns word N of the arg space info
4037 for the current function. The number and meanings of words
4038 is controlled by the definition of CUMULATIVE_ARGS. */
4041 expand_builtin_args_info (tree arglist
)
4043 int nwords
= sizeof (CUMULATIVE_ARGS
) / sizeof (int);
4044 int *word_ptr
= (int *) ¤t_function_args_info
;
4046 gcc_assert (sizeof (CUMULATIVE_ARGS
) % sizeof (int) == 0);
4050 if (!host_integerp (TREE_VALUE (arglist
), 0))
4051 error ("argument of %<__builtin_args_info%> must be constant");
4054 HOST_WIDE_INT wordnum
= tree_low_cst (TREE_VALUE (arglist
), 0);
4056 if (wordnum
< 0 || wordnum
>= nwords
)
4057 error ("argument of %<__builtin_args_info%> out of range");
4059 return GEN_INT (word_ptr
[wordnum
]);
4063 error ("missing argument in %<__builtin_args_info%>");
4068 /* Expand a call to __builtin_next_arg. */
4071 expand_builtin_next_arg (void)
4073 /* Checking arguments is already done in fold_builtin_next_arg
4074 that must be called before this function. */
4075 return expand_binop (Pmode
, add_optab
,
4076 current_function_internal_arg_pointer
,
4077 current_function_arg_offset_rtx
,
4078 NULL_RTX
, 0, OPTAB_LIB_WIDEN
);
4081 /* Make it easier for the backends by protecting the valist argument
4082 from multiple evaluations. */
4085 stabilize_va_list (tree valist
, int needs_lvalue
)
4087 if (TREE_CODE (va_list_type_node
) == ARRAY_TYPE
)
4089 if (TREE_SIDE_EFFECTS (valist
))
4090 valist
= save_expr (valist
);
4092 /* For this case, the backends will be expecting a pointer to
4093 TREE_TYPE (va_list_type_node), but it's possible we've
4094 actually been given an array (an actual va_list_type_node).
4096 if (TREE_CODE (TREE_TYPE (valist
)) == ARRAY_TYPE
)
4098 tree p1
= build_pointer_type (TREE_TYPE (va_list_type_node
));
4099 valist
= build_fold_addr_expr_with_type (valist
, p1
);
4108 if (! TREE_SIDE_EFFECTS (valist
))
4111 pt
= build_pointer_type (va_list_type_node
);
4112 valist
= fold_build1 (ADDR_EXPR
, pt
, valist
);
4113 TREE_SIDE_EFFECTS (valist
) = 1;
4116 if (TREE_SIDE_EFFECTS (valist
))
4117 valist
= save_expr (valist
);
4118 valist
= build_fold_indirect_ref (valist
);
4124 /* The "standard" definition of va_list is void*. */
4127 std_build_builtin_va_list (void)
4129 return ptr_type_node
;
4132 /* The "standard" implementation of va_start: just assign `nextarg' to
4136 std_expand_builtin_va_start (tree valist
, rtx nextarg
)
4140 t
= build2 (MODIFY_EXPR
, TREE_TYPE (valist
), valist
,
4141 make_tree (ptr_type_node
, nextarg
));
4142 TREE_SIDE_EFFECTS (t
) = 1;
4144 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
4147 /* Expand ARGLIST, from a call to __builtin_va_start. */
4150 expand_builtin_va_start (tree arglist
)
4155 chain
= TREE_CHAIN (arglist
);
4159 error ("too few arguments to function %<va_start%>");
4163 if (fold_builtin_next_arg (chain
))
4166 nextarg
= expand_builtin_next_arg ();
4167 valist
= stabilize_va_list (TREE_VALUE (arglist
), 1);
4169 #ifdef EXPAND_BUILTIN_VA_START
4170 EXPAND_BUILTIN_VA_START (valist
, nextarg
);
4172 std_expand_builtin_va_start (valist
, nextarg
);
4178 /* The "standard" implementation of va_arg: read the value from the
4179 current (padded) address and increment by the (padded) size. */
4182 std_gimplify_va_arg_expr (tree valist
, tree type
, tree
*pre_p
, tree
*post_p
)
4184 tree addr
, t
, type_size
, rounded_size
, valist_tmp
;
4185 unsigned HOST_WIDE_INT align
, boundary
;
4188 #ifdef ARGS_GROW_DOWNWARD
4189 /* All of the alignment and movement below is for args-grow-up machines.
4190 As of 2004, there are only 3 ARGS_GROW_DOWNWARD targets, and they all
4191 implement their own specialized gimplify_va_arg_expr routines. */
4195 indirect
= pass_by_reference (NULL
, TYPE_MODE (type
), type
, false);
4197 type
= build_pointer_type (type
);
4199 align
= PARM_BOUNDARY
/ BITS_PER_UNIT
;
4200 boundary
= FUNCTION_ARG_BOUNDARY (TYPE_MODE (type
), type
) / BITS_PER_UNIT
;
4202 /* Hoist the valist value into a temporary for the moment. */
4203 valist_tmp
= get_initialized_tmp_var (valist
, pre_p
, NULL
);
4205 /* va_list pointer is aligned to PARM_BOUNDARY. If argument actually
4206 requires greater alignment, we must perform dynamic alignment. */
4207 if (boundary
> align
4208 && !integer_zerop (TYPE_SIZE (type
)))
4210 t
= fold_convert (TREE_TYPE (valist
), size_int (boundary
- 1));
4211 t
= build2 (MODIFY_EXPR
, TREE_TYPE (valist
), valist_tmp
,
4212 build2 (PLUS_EXPR
, TREE_TYPE (valist
), valist_tmp
, t
));
4213 gimplify_and_add (t
, pre_p
);
4215 t
= fold_convert (TREE_TYPE (valist
), size_int (-boundary
));
4216 t
= build2 (MODIFY_EXPR
, TREE_TYPE (valist
), valist_tmp
,
4217 build2 (BIT_AND_EXPR
, TREE_TYPE (valist
), valist_tmp
, t
));
4218 gimplify_and_add (t
, pre_p
);
4223 /* If the actual alignment is less than the alignment of the type,
4224 adjust the type accordingly so that we don't assume strict alignment
4225 when deferencing the pointer. */
4226 boundary
*= BITS_PER_UNIT
;
4227 if (boundary
< TYPE_ALIGN (type
))
4229 type
= build_variant_type_copy (type
);
4230 TYPE_ALIGN (type
) = boundary
;
4233 /* Compute the rounded size of the type. */
4234 type_size
= size_in_bytes (type
);
4235 rounded_size
= round_up (type_size
, align
);
4237 /* Reduce rounded_size so it's sharable with the postqueue. */
4238 gimplify_expr (&rounded_size
, pre_p
, post_p
, is_gimple_val
, fb_rvalue
);
4242 if (PAD_VARARGS_DOWN
&& !integer_zerop (rounded_size
))
4244 /* Small args are padded downward. */
4245 t
= fold_build2 (GT_EXPR
, sizetype
, rounded_size
, size_int (align
));
4246 t
= fold_build3 (COND_EXPR
, sizetype
, t
, size_zero_node
,
4247 size_binop (MINUS_EXPR
, rounded_size
, type_size
));
4248 t
= fold_convert (TREE_TYPE (addr
), t
);
4249 addr
= fold_build2 (PLUS_EXPR
, TREE_TYPE (addr
), addr
, t
);
4252 /* Compute new value for AP. */
4253 t
= fold_convert (TREE_TYPE (valist
), rounded_size
);
4254 t
= build2 (PLUS_EXPR
, TREE_TYPE (valist
), valist_tmp
, t
);
4255 t
= build2 (MODIFY_EXPR
, TREE_TYPE (valist
), valist
, t
);
4256 gimplify_and_add (t
, pre_p
);
4258 addr
= fold_convert (build_pointer_type (type
), addr
);
4261 addr
= build_va_arg_indirect_ref (addr
);
4263 return build_va_arg_indirect_ref (addr
);
4266 /* Build an indirect-ref expression over the given TREE, which represents a
4267 piece of a va_arg() expansion. */
4269 build_va_arg_indirect_ref (tree addr
)
4271 addr
= build_fold_indirect_ref (addr
);
4273 if (flag_mudflap
) /* Don't instrument va_arg INDIRECT_REF. */
4279 /* Return a dummy expression of type TYPE in order to keep going after an
4283 dummy_object (tree type
)
4285 tree t
= convert (build_pointer_type (type
), null_pointer_node
);
4286 return build1 (INDIRECT_REF
, type
, t
);
4289 /* Gimplify __builtin_va_arg, aka VA_ARG_EXPR, which is not really a
4290 builtin function, but a very special sort of operator. */
4292 enum gimplify_status
4293 gimplify_va_arg_expr (tree
*expr_p
, tree
*pre_p
, tree
*post_p
)
4295 tree promoted_type
, want_va_type
, have_va_type
;
4296 tree valist
= TREE_OPERAND (*expr_p
, 0);
4297 tree type
= TREE_TYPE (*expr_p
);
4300 /* Verify that valist is of the proper type. */
4301 want_va_type
= va_list_type_node
;
4302 have_va_type
= TREE_TYPE (valist
);
4304 if (have_va_type
== error_mark_node
)
4307 if (TREE_CODE (want_va_type
) == ARRAY_TYPE
)
4309 /* If va_list is an array type, the argument may have decayed
4310 to a pointer type, e.g. by being passed to another function.
4311 In that case, unwrap both types so that we can compare the
4312 underlying records. */
4313 if (TREE_CODE (have_va_type
) == ARRAY_TYPE
4314 || POINTER_TYPE_P (have_va_type
))
4316 want_va_type
= TREE_TYPE (want_va_type
);
4317 have_va_type
= TREE_TYPE (have_va_type
);
4321 if (TYPE_MAIN_VARIANT (want_va_type
) != TYPE_MAIN_VARIANT (have_va_type
))
4323 error ("first argument to %<va_arg%> not of type %<va_list%>");
4327 /* Generate a diagnostic for requesting data of a type that cannot
4328 be passed through `...' due to type promotion at the call site. */
4329 else if ((promoted_type
= lang_hooks
.types
.type_promotes_to (type
))
4332 static bool gave_help
;
4334 /* Unfortunately, this is merely undefined, rather than a constraint
4335 violation, so we cannot make this an error. If this call is never
4336 executed, the program is still strictly conforming. */
4337 warning (0, "%qT is promoted to %qT when passed through %<...%>",
4338 type
, promoted_type
);
4342 warning (0, "(so you should pass %qT not %qT to %<va_arg%>)",
4343 promoted_type
, type
);
4346 /* We can, however, treat "undefined" any way we please.
4347 Call abort to encourage the user to fix the program. */
4348 inform ("if this code is reached, the program will abort");
4349 t
= build_function_call_expr (implicit_built_in_decls
[BUILT_IN_TRAP
],
4351 append_to_statement_list (t
, pre_p
);
4353 /* This is dead code, but go ahead and finish so that the
4354 mode of the result comes out right. */
4355 *expr_p
= dummy_object (type
);
4360 /* Make it easier for the backends by protecting the valist argument
4361 from multiple evaluations. */
4362 if (TREE_CODE (va_list_type_node
) == ARRAY_TYPE
)
4364 /* For this case, the backends will be expecting a pointer to
4365 TREE_TYPE (va_list_type_node), but it's possible we've
4366 actually been given an array (an actual va_list_type_node).
4368 if (TREE_CODE (TREE_TYPE (valist
)) == ARRAY_TYPE
)
4370 tree p1
= build_pointer_type (TREE_TYPE (va_list_type_node
));
4371 valist
= build_fold_addr_expr_with_type (valist
, p1
);
4373 gimplify_expr (&valist
, pre_p
, post_p
, is_gimple_val
, fb_rvalue
);
4376 gimplify_expr (&valist
, pre_p
, post_p
, is_gimple_min_lval
, fb_lvalue
);
4378 if (!targetm
.gimplify_va_arg_expr
)
4379 /* FIXME:Once most targets are converted we should merely
4380 assert this is non-null. */
4383 *expr_p
= targetm
.gimplify_va_arg_expr (valist
, type
, pre_p
, post_p
);
4388 /* Expand ARGLIST, from a call to __builtin_va_end. */
4391 expand_builtin_va_end (tree arglist
)
4393 tree valist
= TREE_VALUE (arglist
);
4395 /* Evaluate for side effects, if needed. I hate macros that don't
4397 if (TREE_SIDE_EFFECTS (valist
))
4398 expand_expr (valist
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
4403 /* Expand ARGLIST, from a call to __builtin_va_copy. We do this as a
4404 builtin rather than just as an assignment in stdarg.h because of the
4405 nastiness of array-type va_list types. */
4408 expand_builtin_va_copy (tree arglist
)
4412 dst
= TREE_VALUE (arglist
);
4413 src
= TREE_VALUE (TREE_CHAIN (arglist
));
4415 dst
= stabilize_va_list (dst
, 1);
4416 src
= stabilize_va_list (src
, 0);
4418 if (TREE_CODE (va_list_type_node
) != ARRAY_TYPE
)
4420 t
= build2 (MODIFY_EXPR
, va_list_type_node
, dst
, src
);
4421 TREE_SIDE_EFFECTS (t
) = 1;
4422 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
4426 rtx dstb
, srcb
, size
;
4428 /* Evaluate to pointers. */
4429 dstb
= expand_expr (dst
, NULL_RTX
, Pmode
, EXPAND_NORMAL
);
4430 srcb
= expand_expr (src
, NULL_RTX
, Pmode
, EXPAND_NORMAL
);
4431 size
= expand_expr (TYPE_SIZE_UNIT (va_list_type_node
), NULL_RTX
,
4432 VOIDmode
, EXPAND_NORMAL
);
4434 dstb
= convert_memory_address (Pmode
, dstb
);
4435 srcb
= convert_memory_address (Pmode
, srcb
);
4437 /* "Dereference" to BLKmode memories. */
4438 dstb
= gen_rtx_MEM (BLKmode
, dstb
);
4439 set_mem_alias_set (dstb
, get_alias_set (TREE_TYPE (TREE_TYPE (dst
))));
4440 set_mem_align (dstb
, TYPE_ALIGN (va_list_type_node
));
4441 srcb
= gen_rtx_MEM (BLKmode
, srcb
);
4442 set_mem_alias_set (srcb
, get_alias_set (TREE_TYPE (TREE_TYPE (src
))));
4443 set_mem_align (srcb
, TYPE_ALIGN (va_list_type_node
));
4446 emit_block_move (dstb
, srcb
, size
, BLOCK_OP_NORMAL
);
4452 /* Expand a call to one of the builtin functions __builtin_frame_address or
4453 __builtin_return_address. */
4456 expand_builtin_frame_address (tree fndecl
, tree arglist
)
4458 /* The argument must be a nonnegative integer constant.
4459 It counts the number of frames to scan up the stack.
4460 The value is the return address saved in that frame. */
4462 /* Warning about missing arg was already issued. */
4464 else if (! host_integerp (TREE_VALUE (arglist
), 1))
4466 if (DECL_FUNCTION_CODE (fndecl
) == BUILT_IN_FRAME_ADDRESS
)
4467 error ("invalid argument to %<__builtin_frame_address%>");
4469 error ("invalid argument to %<__builtin_return_address%>");
4475 = expand_builtin_return_addr (DECL_FUNCTION_CODE (fndecl
),
4476 tree_low_cst (TREE_VALUE (arglist
), 1));
4478 /* Some ports cannot access arbitrary stack frames. */
4481 if (DECL_FUNCTION_CODE (fndecl
) == BUILT_IN_FRAME_ADDRESS
)
4482 warning (0, "unsupported argument to %<__builtin_frame_address%>");
4484 warning (0, "unsupported argument to %<__builtin_return_address%>");
4488 /* For __builtin_frame_address, return what we've got. */
4489 if (DECL_FUNCTION_CODE (fndecl
) == BUILT_IN_FRAME_ADDRESS
)
4493 && ! CONSTANT_P (tem
))
4494 tem
= copy_to_mode_reg (Pmode
, tem
);
4499 /* Expand a call to the alloca builtin, with arguments ARGLIST. Return 0 if
4500 we failed and the caller should emit a normal call, otherwise try to get
4501 the result in TARGET, if convenient. */
4504 expand_builtin_alloca (tree arglist
, rtx target
)
4509 /* In -fmudflap-instrumented code, alloca() and __builtin_alloca()
4510 should always expand to function calls. These can be intercepted
4515 if (!validate_arglist (arglist
, INTEGER_TYPE
, VOID_TYPE
))
4518 /* Compute the argument. */
4519 op0
= expand_normal (TREE_VALUE (arglist
));
4521 /* Allocate the desired space. */
4522 result
= allocate_dynamic_stack_space (op0
, target
, BITS_PER_UNIT
);
4523 result
= convert_memory_address (ptr_mode
, result
);
4528 /* Expand a call to a unary builtin. The arguments are in ARGLIST.
4529 Return 0 if a normal call should be emitted rather than expanding the
4530 function in-line. If convenient, the result should be placed in TARGET.
4531 SUBTARGET may be used as the target for computing one of EXP's operands. */
4534 expand_builtin_unop (enum machine_mode target_mode
, tree arglist
, rtx target
,
4535 rtx subtarget
, optab op_optab
)
4538 if (!validate_arglist (arglist
, INTEGER_TYPE
, VOID_TYPE
))
4541 /* Compute the argument. */
4542 op0
= expand_expr (TREE_VALUE (arglist
), subtarget
, VOIDmode
, 0);
4543 /* Compute op, into TARGET if possible.
4544 Set TARGET to wherever the result comes back. */
4545 target
= expand_unop (TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist
))),
4546 op_optab
, op0
, target
, 1);
4547 gcc_assert (target
);
4549 return convert_to_mode (target_mode
, target
, 0);
4552 /* If the string passed to fputs is a constant and is one character
4553 long, we attempt to transform this call into __builtin_fputc(). */
4556 expand_builtin_fputs (tree arglist
, rtx target
, bool unlocked
)
4558 /* Verify the arguments in the original call. */
4559 if (validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
4561 tree result
= fold_builtin_fputs (arglist
, (target
== const0_rtx
),
4562 unlocked
, NULL_TREE
);
4564 return expand_expr (result
, target
, VOIDmode
, EXPAND_NORMAL
);
4569 /* Expand a call to __builtin_expect. We return our argument and emit a
4570 NOTE_INSN_EXPECTED_VALUE note. This is the expansion of __builtin_expect in
4571 a non-jump context. */
4574 expand_builtin_expect (tree arglist
, rtx target
)
4579 if (arglist
== NULL_TREE
4580 || TREE_CHAIN (arglist
) == NULL_TREE
)
4582 exp
= TREE_VALUE (arglist
);
4583 c
= TREE_VALUE (TREE_CHAIN (arglist
));
4585 if (TREE_CODE (c
) != INTEGER_CST
)
4587 error ("second argument to %<__builtin_expect%> must be a constant");
4588 c
= integer_zero_node
;
4591 target
= expand_expr (exp
, target
, VOIDmode
, EXPAND_NORMAL
);
4593 /* Don't bother with expected value notes for integral constants. */
4594 if (flag_guess_branch_prob
&& GET_CODE (target
) != CONST_INT
)
4596 /* We do need to force this into a register so that we can be
4597 moderately sure to be able to correctly interpret the branch
4599 target
= force_reg (GET_MODE (target
), target
);
4601 rtx_c
= expand_expr (c
, NULL_RTX
, GET_MODE (target
), EXPAND_NORMAL
);
4603 note
= emit_note (NOTE_INSN_EXPECTED_VALUE
);
4604 NOTE_EXPECTED_VALUE (note
) = gen_rtx_EQ (VOIDmode
, target
, rtx_c
);
4610 /* Like expand_builtin_expect, except do this in a jump context. This is
4611 called from do_jump if the conditional is a __builtin_expect. Return either
4612 a list of insns to emit the jump or NULL if we cannot optimize
4613 __builtin_expect. We need to optimize this at jump time so that machines
4614 like the PowerPC don't turn the test into a SCC operation, and then jump
4615 based on the test being 0/1. */
4618 expand_builtin_expect_jump (tree exp
, rtx if_false_label
, rtx if_true_label
)
4620 tree arglist
= TREE_OPERAND (exp
, 1);
4621 tree arg0
= TREE_VALUE (arglist
);
4622 tree arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
4625 /* Only handle __builtin_expect (test, 0) and
4626 __builtin_expect (test, 1). */
4627 if (TREE_CODE (TREE_TYPE (arg1
)) == INTEGER_TYPE
4628 && (integer_zerop (arg1
) || integer_onep (arg1
)))
4630 rtx insn
, drop_through_label
, temp
;
4632 /* Expand the jump insns. */
4634 do_jump (arg0
, if_false_label
, if_true_label
);
4637 drop_through_label
= get_last_insn ();
4638 if (drop_through_label
&& NOTE_P (drop_through_label
))
4639 drop_through_label
= prev_nonnote_insn (drop_through_label
);
4640 if (drop_through_label
&& !LABEL_P (drop_through_label
))
4641 drop_through_label
= NULL_RTX
;
4644 if (! if_true_label
)
4645 if_true_label
= drop_through_label
;
4646 if (! if_false_label
)
4647 if_false_label
= drop_through_label
;
4649 /* Go through and add the expect's to each of the conditional jumps. */
4651 while (insn
!= NULL_RTX
)
4653 rtx next
= NEXT_INSN (insn
);
4655 if (JUMP_P (insn
) && any_condjump_p (insn
))
4657 rtx ifelse
= SET_SRC (pc_set (insn
));
4658 rtx then_dest
= XEXP (ifelse
, 1);
4659 rtx else_dest
= XEXP (ifelse
, 2);
4662 /* First check if we recognize any of the labels. */
4663 if (GET_CODE (then_dest
) == LABEL_REF
4664 && XEXP (then_dest
, 0) == if_true_label
)
4666 else if (GET_CODE (then_dest
) == LABEL_REF
4667 && XEXP (then_dest
, 0) == if_false_label
)
4669 else if (GET_CODE (else_dest
) == LABEL_REF
4670 && XEXP (else_dest
, 0) == if_false_label
)
4672 else if (GET_CODE (else_dest
) == LABEL_REF
4673 && XEXP (else_dest
, 0) == if_true_label
)
4675 /* Otherwise check where we drop through. */
4676 else if (else_dest
== pc_rtx
)
4678 if (next
&& NOTE_P (next
))
4679 next
= next_nonnote_insn (next
);
4681 if (next
&& JUMP_P (next
)
4682 && any_uncondjump_p (next
))
4683 temp
= XEXP (SET_SRC (pc_set (next
)), 0);
4687 /* TEMP is either a CODE_LABEL, NULL_RTX or something
4688 else that can't possibly match either target label. */
4689 if (temp
== if_false_label
)
4691 else if (temp
== if_true_label
)
4694 else if (then_dest
== pc_rtx
)
4696 if (next
&& NOTE_P (next
))
4697 next
= next_nonnote_insn (next
);
4699 if (next
&& JUMP_P (next
)
4700 && any_uncondjump_p (next
))
4701 temp
= XEXP (SET_SRC (pc_set (next
)), 0);
4705 if (temp
== if_false_label
)
4707 else if (temp
== if_true_label
)
4713 /* If the test is expected to fail, reverse the
4715 if (integer_zerop (arg1
))
4717 predict_insn_def (insn
, PRED_BUILTIN_EXPECT
, taken
);
4729 expand_builtin_trap (void)
4733 emit_insn (gen_trap ());
4736 emit_library_call (abort_libfunc
, LCT_NORETURN
, VOIDmode
, 0);
4740 /* Expand a call to fabs, fabsf or fabsl with arguments ARGLIST.
4741 Return 0 if a normal call should be emitted rather than expanding
4742 the function inline. If convenient, the result should be placed
4743 in TARGET. SUBTARGET may be used as the target for computing
4747 expand_builtin_fabs (tree arglist
, rtx target
, rtx subtarget
)
4749 enum machine_mode mode
;
4753 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
4756 arg
= TREE_VALUE (arglist
);
4757 mode
= TYPE_MODE (TREE_TYPE (arg
));
4758 op0
= expand_expr (arg
, subtarget
, VOIDmode
, 0);
4759 return expand_abs (mode
, op0
, target
, 0, safe_from_p (target
, arg
, 1));
4762 /* Expand a call to copysign, copysignf, or copysignl with arguments ARGLIST.
4763 Return NULL is a normal call should be emitted rather than expanding the
4764 function inline. If convenient, the result should be placed in TARGET.
4765 SUBTARGET may be used as the target for computing the operand. */
4768 expand_builtin_copysign (tree arglist
, rtx target
, rtx subtarget
)
4773 if (!validate_arglist (arglist
, REAL_TYPE
, REAL_TYPE
, VOID_TYPE
))
4776 arg
= TREE_VALUE (arglist
);
4777 op0
= expand_expr (arg
, subtarget
, VOIDmode
, EXPAND_NORMAL
);
4779 arg
= TREE_VALUE (TREE_CHAIN (arglist
));
4780 op1
= expand_normal (arg
);
4782 return expand_copysign (op0
, op1
, target
);
4785 /* Create a new constant string literal and return a char* pointer to it.
4786 The STRING_CST value is the LEN characters at STR. */
4788 build_string_literal (int len
, const char *str
)
4790 tree t
, elem
, index
, type
;
4792 t
= build_string (len
, str
);
4793 elem
= build_type_variant (char_type_node
, 1, 0);
4794 index
= build_index_type (build_int_cst (NULL_TREE
, len
- 1));
4795 type
= build_array_type (elem
, index
);
4796 TREE_TYPE (t
) = type
;
4797 TREE_CONSTANT (t
) = 1;
4798 TREE_INVARIANT (t
) = 1;
4799 TREE_READONLY (t
) = 1;
4800 TREE_STATIC (t
) = 1;
4802 type
= build_pointer_type (type
);
4803 t
= build1 (ADDR_EXPR
, type
, t
);
4805 type
= build_pointer_type (elem
);
4806 t
= build1 (NOP_EXPR
, type
, t
);
4810 /* Expand EXP, a call to printf or printf_unlocked.
4811 Return 0 if a normal call should be emitted rather than transforming
4812 the function inline. If convenient, the result should be placed in
4813 TARGET with mode MODE. UNLOCKED indicates this is a printf_unlocked
4816 expand_builtin_printf (tree exp
, rtx target
, enum machine_mode mode
,
4819 tree arglist
= TREE_OPERAND (exp
, 1);
4820 /* If we're using an unlocked function, assume the other unlocked
4821 functions exist explicitly. */
4822 tree
const fn_putchar
= unlocked
? built_in_decls
[BUILT_IN_PUTCHAR_UNLOCKED
]
4823 : implicit_built_in_decls
[BUILT_IN_PUTCHAR
];
4824 tree
const fn_puts
= unlocked
? built_in_decls
[BUILT_IN_PUTS_UNLOCKED
]
4825 : implicit_built_in_decls
[BUILT_IN_PUTS
];
4826 const char *fmt_str
;
4829 /* If the return value is used, don't do the transformation. */
4830 if (target
!= const0_rtx
)
4833 /* Verify the required arguments in the original call. */
4836 fmt
= TREE_VALUE (arglist
);
4837 if (! POINTER_TYPE_P (TREE_TYPE (fmt
)))
4839 arglist
= TREE_CHAIN (arglist
);
4841 /* Check whether the format is a literal string constant. */
4842 fmt_str
= c_getstr (fmt
);
4843 if (fmt_str
== NULL
)
4846 if (!init_target_chars())
4849 /* If the format specifier was "%s\n", call __builtin_puts(arg). */
4850 if (strcmp (fmt_str
, target_percent_s_newline
) == 0)
4853 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist
)))
4854 || TREE_CHAIN (arglist
))
4858 /* If the format specifier was "%c", call __builtin_putchar(arg). */
4859 else if (strcmp (fmt_str
, target_percent_c
) == 0)
4862 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist
))) != INTEGER_TYPE
4863 || TREE_CHAIN (arglist
))
4869 /* We can't handle anything else with % args or %% ... yet. */
4870 if (strchr (fmt_str
, target_percent
))
4876 /* If the format specifier was "", printf does nothing. */
4877 if (fmt_str
[0] == '\0')
4879 /* If the format specifier has length of 1, call putchar. */
4880 if (fmt_str
[1] == '\0')
4882 /* Given printf("c"), (where c is any one character,)
4883 convert "c"[0] to an int and pass that to the replacement
4885 arg
= build_int_cst (NULL_TREE
, fmt_str
[0]);
4886 arglist
= build_tree_list (NULL_TREE
, arg
);
4891 /* If the format specifier was "string\n", call puts("string"). */
4892 size_t len
= strlen (fmt_str
);
4893 if ((unsigned char)fmt_str
[len
- 1] == target_newline
)
4895 /* Create a NUL-terminated string that's one char shorter
4896 than the original, stripping off the trailing '\n'. */
4897 char *newstr
= alloca (len
);
4898 memcpy (newstr
, fmt_str
, len
- 1);
4899 newstr
[len
- 1] = 0;
4901 arg
= build_string_literal (len
, newstr
);
4902 arglist
= build_tree_list (NULL_TREE
, arg
);
4906 /* We'd like to arrange to call fputs(string,stdout) here,
4907 but we need stdout and don't have a way to get it yet. */
4914 fn
= build_function_call_expr (fn
, arglist
);
4915 if (TREE_CODE (fn
) == CALL_EXPR
)
4916 CALL_EXPR_TAILCALL (fn
) = CALL_EXPR_TAILCALL (exp
);
4917 return expand_expr (fn
, target
, mode
, EXPAND_NORMAL
);
4920 /* Expand EXP, a call to fprintf or fprintf_unlocked.
4921 Return 0 if a normal call should be emitted rather than transforming
4922 the function inline. If convenient, the result should be placed in
4923 TARGET with mode MODE. UNLOCKED indicates this is a fprintf_unlocked
4926 expand_builtin_fprintf (tree exp
, rtx target
, enum machine_mode mode
,
4929 tree arglist
= TREE_OPERAND (exp
, 1);
4930 /* If we're using an unlocked function, assume the other unlocked
4931 functions exist explicitly. */
4932 tree
const fn_fputc
= unlocked
? built_in_decls
[BUILT_IN_FPUTC_UNLOCKED
]
4933 : implicit_built_in_decls
[BUILT_IN_FPUTC
];
4934 tree
const fn_fputs
= unlocked
? built_in_decls
[BUILT_IN_FPUTS_UNLOCKED
]
4935 : implicit_built_in_decls
[BUILT_IN_FPUTS
];
4936 const char *fmt_str
;
4937 tree fn
, fmt
, fp
, arg
;
4939 /* If the return value is used, don't do the transformation. */
4940 if (target
!= const0_rtx
)
4943 /* Verify the required arguments in the original call. */
4946 fp
= TREE_VALUE (arglist
);
4947 if (! POINTER_TYPE_P (TREE_TYPE (fp
)))
4949 arglist
= TREE_CHAIN (arglist
);
4952 fmt
= TREE_VALUE (arglist
);
4953 if (! POINTER_TYPE_P (TREE_TYPE (fmt
)))
4955 arglist
= TREE_CHAIN (arglist
);
4957 /* Check whether the format is a literal string constant. */
4958 fmt_str
= c_getstr (fmt
);
4959 if (fmt_str
== NULL
)
4962 if (!init_target_chars())
4965 /* If the format specifier was "%s", call __builtin_fputs(arg,fp). */
4966 if (strcmp (fmt_str
, target_percent_s
) == 0)
4969 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist
)))
4970 || TREE_CHAIN (arglist
))
4972 arg
= TREE_VALUE (arglist
);
4973 arglist
= build_tree_list (NULL_TREE
, fp
);
4974 arglist
= tree_cons (NULL_TREE
, arg
, arglist
);
4977 /* If the format specifier was "%c", call __builtin_fputc(arg,fp). */
4978 else if (strcmp (fmt_str
, target_percent_c
) == 0)
4981 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist
))) != INTEGER_TYPE
4982 || TREE_CHAIN (arglist
))
4984 arg
= TREE_VALUE (arglist
);
4985 arglist
= build_tree_list (NULL_TREE
, fp
);
4986 arglist
= tree_cons (NULL_TREE
, arg
, arglist
);
4991 /* We can't handle anything else with % args or %% ... yet. */
4992 if (strchr (fmt_str
, target_percent
))
4998 /* If the format specifier was "", fprintf does nothing. */
4999 if (fmt_str
[0] == '\0')
5001 /* Evaluate and ignore FILE* argument for side-effects. */
5002 expand_expr (fp
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
5006 /* When "string" doesn't contain %, replace all cases of
5007 fprintf(stream,string) with fputs(string,stream). The fputs
5008 builtin will take care of special cases like length == 1. */
5009 arglist
= build_tree_list (NULL_TREE
, fp
);
5010 arglist
= tree_cons (NULL_TREE
, fmt
, arglist
);
5016 fn
= build_function_call_expr (fn
, arglist
);
5017 if (TREE_CODE (fn
) == CALL_EXPR
)
5018 CALL_EXPR_TAILCALL (fn
) = CALL_EXPR_TAILCALL (exp
);
5019 return expand_expr (fn
, target
, mode
, EXPAND_NORMAL
);
5022 /* Expand a call to sprintf with argument list ARGLIST. Return 0 if
5023 a normal call should be emitted rather than expanding the function
5024 inline. If convenient, the result should be placed in TARGET with
5028 expand_builtin_sprintf (tree arglist
, rtx target
, enum machine_mode mode
)
5030 tree orig_arglist
, dest
, fmt
;
5031 const char *fmt_str
;
5033 orig_arglist
= arglist
;
5035 /* Verify the required arguments in the original call. */
5038 dest
= TREE_VALUE (arglist
);
5039 if (! POINTER_TYPE_P (TREE_TYPE (dest
)))
5041 arglist
= TREE_CHAIN (arglist
);
5044 fmt
= TREE_VALUE (arglist
);
5045 if (! POINTER_TYPE_P (TREE_TYPE (fmt
)))
5047 arglist
= TREE_CHAIN (arglist
);
5049 /* Check whether the format is a literal string constant. */
5050 fmt_str
= c_getstr (fmt
);
5051 if (fmt_str
== NULL
)
5054 if (!init_target_chars())
5057 /* If the format doesn't contain % args or %%, use strcpy. */
5058 if (strchr (fmt_str
, target_percent
) == 0)
5060 tree fn
= implicit_built_in_decls
[BUILT_IN_STRCPY
];
5063 if (arglist
|| ! fn
)
5065 expand_expr (build_function_call_expr (fn
, orig_arglist
),
5066 const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
5067 if (target
== const0_rtx
)
5069 exp
= build_int_cst (NULL_TREE
, strlen (fmt_str
));
5070 return expand_expr (exp
, target
, mode
, EXPAND_NORMAL
);
5072 /* If the format is "%s", use strcpy if the result isn't used. */
5073 else if (strcmp (fmt_str
, target_percent_s
) == 0)
5076 fn
= implicit_built_in_decls
[BUILT_IN_STRCPY
];
5081 if (! arglist
|| TREE_CHAIN (arglist
))
5083 arg
= TREE_VALUE (arglist
);
5084 if (! POINTER_TYPE_P (TREE_TYPE (arg
)))
5087 if (target
!= const0_rtx
)
5089 len
= c_strlen (arg
, 1);
5090 if (! len
|| TREE_CODE (len
) != INTEGER_CST
)
5096 arglist
= build_tree_list (NULL_TREE
, arg
);
5097 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
5098 expand_expr (build_function_call_expr (fn
, arglist
),
5099 const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
5101 if (target
== const0_rtx
)
5103 return expand_expr (len
, target
, mode
, EXPAND_NORMAL
);
5109 /* Expand a call to either the entry or exit function profiler. */
5112 expand_builtin_profile_func (bool exitp
)
5116 this = DECL_RTL (current_function_decl
);
5117 gcc_assert (MEM_P (this));
5118 this = XEXP (this, 0);
5121 which
= profile_function_exit_libfunc
;
5123 which
= profile_function_entry_libfunc
;
5125 emit_library_call (which
, LCT_NORMAL
, VOIDmode
, 2, this, Pmode
,
5126 expand_builtin_return_addr (BUILT_IN_RETURN_ADDRESS
,
5133 /* Given a trampoline address, make sure it satisfies TRAMPOLINE_ALIGNMENT. */
5136 round_trampoline_addr (rtx tramp
)
5138 rtx temp
, addend
, mask
;
5140 /* If we don't need too much alignment, we'll have been guaranteed
5141 proper alignment by get_trampoline_type. */
5142 if (TRAMPOLINE_ALIGNMENT
<= STACK_BOUNDARY
)
5145 /* Round address up to desired boundary. */
5146 temp
= gen_reg_rtx (Pmode
);
5147 addend
= GEN_INT (TRAMPOLINE_ALIGNMENT
/ BITS_PER_UNIT
- 1);
5148 mask
= GEN_INT (-TRAMPOLINE_ALIGNMENT
/ BITS_PER_UNIT
);
5150 temp
= expand_simple_binop (Pmode
, PLUS
, tramp
, addend
,
5151 temp
, 0, OPTAB_LIB_WIDEN
);
5152 tramp
= expand_simple_binop (Pmode
, AND
, temp
, mask
,
5153 temp
, 0, OPTAB_LIB_WIDEN
);
5159 expand_builtin_init_trampoline (tree arglist
)
5161 tree t_tramp
, t_func
, t_chain
;
5162 rtx r_tramp
, r_func
, r_chain
;
5163 #ifdef TRAMPOLINE_TEMPLATE
5167 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
,
5168 POINTER_TYPE
, VOID_TYPE
))
5171 t_tramp
= TREE_VALUE (arglist
);
5172 arglist
= TREE_CHAIN (arglist
);
5173 t_func
= TREE_VALUE (arglist
);
5174 arglist
= TREE_CHAIN (arglist
);
5175 t_chain
= TREE_VALUE (arglist
);
5177 r_tramp
= expand_normal (t_tramp
);
5178 r_func
= expand_normal (t_func
);
5179 r_chain
= expand_normal (t_chain
);
5181 /* Generate insns to initialize the trampoline. */
5182 r_tramp
= round_trampoline_addr (r_tramp
);
5183 #ifdef TRAMPOLINE_TEMPLATE
5184 blktramp
= gen_rtx_MEM (BLKmode
, r_tramp
);
5185 set_mem_align (blktramp
, TRAMPOLINE_ALIGNMENT
);
5186 emit_block_move (blktramp
, assemble_trampoline_template (),
5187 GEN_INT (TRAMPOLINE_SIZE
), BLOCK_OP_NORMAL
);
5189 trampolines_created
= 1;
5190 INITIALIZE_TRAMPOLINE (r_tramp
, r_func
, r_chain
);
5196 expand_builtin_adjust_trampoline (tree arglist
)
5200 if (!validate_arglist (arglist
, POINTER_TYPE
, VOID_TYPE
))
5203 tramp
= expand_normal (TREE_VALUE (arglist
));
5204 tramp
= round_trampoline_addr (tramp
);
5205 #ifdef TRAMPOLINE_ADJUST_ADDRESS
5206 TRAMPOLINE_ADJUST_ADDRESS (tramp
);
5212 /* Expand a call to the built-in signbit, signbitf or signbitl function.
5213 Return NULL_RTX if a normal call should be emitted rather than expanding
5214 the function in-line. EXP is the expression that is a call to the builtin
5215 function; if convenient, the result should be placed in TARGET. */
5218 expand_builtin_signbit (tree exp
, rtx target
)
5220 const struct real_format
*fmt
;
5221 enum machine_mode fmode
, imode
, rmode
;
5222 HOST_WIDE_INT hi
, lo
;
5227 arglist
= TREE_OPERAND (exp
, 1);
5228 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
5231 arg
= TREE_VALUE (arglist
);
5232 fmode
= TYPE_MODE (TREE_TYPE (arg
));
5233 rmode
= TYPE_MODE (TREE_TYPE (exp
));
5234 fmt
= REAL_MODE_FORMAT (fmode
);
5236 /* For floating point formats without a sign bit, implement signbit
5238 bitpos
= fmt
->signbit_ro
;
5241 /* But we can't do this if the format supports signed zero. */
5242 if (fmt
->has_signed_zero
&& HONOR_SIGNED_ZEROS (fmode
))
5245 arg
= fold_build2 (LT_EXPR
, TREE_TYPE (exp
), arg
,
5246 build_real (TREE_TYPE (arg
), dconst0
));
5247 return expand_expr (arg
, target
, VOIDmode
, EXPAND_NORMAL
);
5250 temp
= expand_normal (arg
);
5251 if (GET_MODE_SIZE (fmode
) <= UNITS_PER_WORD
)
5253 imode
= int_mode_for_mode (fmode
);
5254 if (imode
== BLKmode
)
5256 temp
= gen_lowpart (imode
, temp
);
5261 /* Handle targets with different FP word orders. */
5262 if (FLOAT_WORDS_BIG_ENDIAN
)
5263 word
= (GET_MODE_BITSIZE (fmode
) - bitpos
) / BITS_PER_WORD
;
5265 word
= bitpos
/ BITS_PER_WORD
;
5266 temp
= operand_subword_force (temp
, word
, fmode
);
5267 bitpos
= bitpos
% BITS_PER_WORD
;
5270 /* Force the intermediate word_mode (or narrower) result into a
5271 register. This avoids attempting to create paradoxical SUBREGs
5272 of floating point modes below. */
5273 temp
= force_reg (imode
, temp
);
5275 /* If the bitpos is within the "result mode" lowpart, the operation
5276 can be implement with a single bitwise AND. Otherwise, we need
5277 a right shift and an AND. */
5279 if (bitpos
< GET_MODE_BITSIZE (rmode
))
5281 if (bitpos
< HOST_BITS_PER_WIDE_INT
)
5284 lo
= (HOST_WIDE_INT
) 1 << bitpos
;
5288 hi
= (HOST_WIDE_INT
) 1 << (bitpos
- HOST_BITS_PER_WIDE_INT
);
5293 temp
= gen_lowpart (rmode
, temp
);
5294 temp
= expand_binop (rmode
, and_optab
, temp
,
5295 immed_double_const (lo
, hi
, rmode
),
5296 NULL_RTX
, 1, OPTAB_LIB_WIDEN
);
5300 /* Perform a logical right shift to place the signbit in the least
5301 significant bit, then truncate the result to the desired mode
5302 and mask just this bit. */
5303 temp
= expand_shift (RSHIFT_EXPR
, imode
, temp
,
5304 build_int_cst (NULL_TREE
, bitpos
), NULL_RTX
, 1);
5305 temp
= gen_lowpart (rmode
, temp
);
5306 temp
= expand_binop (rmode
, and_optab
, temp
, const1_rtx
,
5307 NULL_RTX
, 1, OPTAB_LIB_WIDEN
);
5313 /* Expand fork or exec calls. TARGET is the desired target of the
5314 call. ARGLIST is the list of arguments of the call. FN is the
5315 identificator of the actual function. IGNORE is nonzero if the
5316 value is to be ignored. */
5319 expand_builtin_fork_or_exec (tree fn
, tree arglist
, rtx target
, int ignore
)
5324 /* If we are not profiling, just call the function. */
5325 if (!profile_arc_flag
)
5328 /* Otherwise call the wrapper. This should be equivalent for the rest of
5329 compiler, so the code does not diverge, and the wrapper may run the
5330 code necessary for keeping the profiling sane. */
5332 switch (DECL_FUNCTION_CODE (fn
))
5335 id
= get_identifier ("__gcov_fork");
5338 case BUILT_IN_EXECL
:
5339 id
= get_identifier ("__gcov_execl");
5342 case BUILT_IN_EXECV
:
5343 id
= get_identifier ("__gcov_execv");
5346 case BUILT_IN_EXECLP
:
5347 id
= get_identifier ("__gcov_execlp");
5350 case BUILT_IN_EXECLE
:
5351 id
= get_identifier ("__gcov_execle");
5354 case BUILT_IN_EXECVP
:
5355 id
= get_identifier ("__gcov_execvp");
5358 case BUILT_IN_EXECVE
:
5359 id
= get_identifier ("__gcov_execve");
5366 decl
= build_decl (FUNCTION_DECL
, id
, TREE_TYPE (fn
));
5367 DECL_EXTERNAL (decl
) = 1;
5368 TREE_PUBLIC (decl
) = 1;
5369 DECL_ARTIFICIAL (decl
) = 1;
5370 TREE_NOTHROW (decl
) = 1;
5371 call
= build_function_call_expr (decl
, arglist
);
5373 return expand_call (call
, target
, ignore
);
5377 /* Reconstitute a mode for a __sync intrinsic operation. Since the type of
5378 the pointer in these functions is void*, the tree optimizers may remove
5379 casts. The mode computed in expand_builtin isn't reliable either, due
5380 to __sync_bool_compare_and_swap.
5382 FCODE_DIFF should be fcode - base, where base is the FOO_1 code for the
5383 group of builtins. This gives us log2 of the mode size. */
5385 static inline enum machine_mode
5386 get_builtin_sync_mode (int fcode_diff
)
5388 /* The size is not negotiable, so ask not to get BLKmode in return
5389 if the target indicates that a smaller size would be better. */
5390 return mode_for_size (BITS_PER_UNIT
<< fcode_diff
, MODE_INT
, 0);
5393 /* Expand the memory expression LOC and return the appropriate memory operand
5394 for the builtin_sync operations. */
5397 get_builtin_sync_mem (tree loc
, enum machine_mode mode
)
5401 addr
= expand_expr (loc
, NULL
, Pmode
, EXPAND_SUM
);
5403 /* Note that we explicitly do not want any alias information for this
5404 memory, so that we kill all other live memories. Otherwise we don't
5405 satisfy the full barrier semantics of the intrinsic. */
5406 mem
= validize_mem (gen_rtx_MEM (mode
, addr
));
5408 set_mem_align (mem
, get_pointer_alignment (loc
, BIGGEST_ALIGNMENT
));
5409 set_mem_alias_set (mem
, ALIAS_SET_MEMORY_BARRIER
);
5410 MEM_VOLATILE_P (mem
) = 1;
5415 /* Expand the __sync_xxx_and_fetch and __sync_fetch_and_xxx intrinsics.
5416 ARGLIST is the operands list to the function. CODE is the rtx code
5417 that corresponds to the arithmetic or logical operation from the name;
5418 an exception here is that NOT actually means NAND. TARGET is an optional
5419 place for us to store the results; AFTER is true if this is the
5420 fetch_and_xxx form. IGNORE is true if we don't actually care about
5421 the result of the operation at all. */
5424 expand_builtin_sync_operation (enum machine_mode mode
, tree arglist
,
5425 enum rtx_code code
, bool after
,
5426 rtx target
, bool ignore
)
5430 /* Expand the operands. */
5431 mem
= get_builtin_sync_mem (TREE_VALUE (arglist
), mode
);
5433 arglist
= TREE_CHAIN (arglist
);
5434 val
= expand_expr (TREE_VALUE (arglist
), NULL
, mode
, EXPAND_NORMAL
);
5437 return expand_sync_operation (mem
, val
, code
);
5439 return expand_sync_fetch_operation (mem
, val
, code
, after
, target
);
5442 /* Expand the __sync_val_compare_and_swap and __sync_bool_compare_and_swap
5443 intrinsics. ARGLIST is the operands list to the function. IS_BOOL is
5444 true if this is the boolean form. TARGET is a place for us to store the
5445 results; this is NOT optional if IS_BOOL is true. */
5448 expand_builtin_compare_and_swap (enum machine_mode mode
, tree arglist
,
5449 bool is_bool
, rtx target
)
5451 rtx old_val
, new_val
, mem
;
5453 /* Expand the operands. */
5454 mem
= get_builtin_sync_mem (TREE_VALUE (arglist
), mode
);
5456 arglist
= TREE_CHAIN (arglist
);
5457 old_val
= expand_expr (TREE_VALUE (arglist
), NULL
, mode
, EXPAND_NORMAL
);
5459 arglist
= TREE_CHAIN (arglist
);
5460 new_val
= expand_expr (TREE_VALUE (arglist
), NULL
, mode
, EXPAND_NORMAL
);
5463 return expand_bool_compare_and_swap (mem
, old_val
, new_val
, target
);
5465 return expand_val_compare_and_swap (mem
, old_val
, new_val
, target
);
5468 /* Expand the __sync_lock_test_and_set intrinsic. Note that the most
5469 general form is actually an atomic exchange, and some targets only
5470 support a reduced form with the second argument being a constant 1.
5471 ARGLIST is the operands list to the function; TARGET is an optional
5472 place for us to store the results. */
5475 expand_builtin_lock_test_and_set (enum machine_mode mode
, tree arglist
,
5480 /* Expand the operands. */
5481 mem
= get_builtin_sync_mem (TREE_VALUE (arglist
), mode
);
5483 arglist
= TREE_CHAIN (arglist
);
5484 val
= expand_expr (TREE_VALUE (arglist
), NULL
, mode
, EXPAND_NORMAL
);
5486 return expand_sync_lock_test_and_set (mem
, val
, target
);
5489 /* Expand the __sync_synchronize intrinsic. */
5492 expand_builtin_synchronize (void)
5496 #ifdef HAVE_memory_barrier
5497 if (HAVE_memory_barrier
)
5499 emit_insn (gen_memory_barrier ());
5504 /* If no explicit memory barrier instruction is available, create an
5505 empty asm stmt with a memory clobber. */
5506 x
= build4 (ASM_EXPR
, void_type_node
, build_string (0, ""), NULL
, NULL
,
5507 tree_cons (NULL
, build_string (6, "memory"), NULL
));
5508 ASM_VOLATILE_P (x
) = 1;
5509 expand_asm_expr (x
);
5512 /* Expand the __sync_lock_release intrinsic. ARGLIST is the operands list
5516 expand_builtin_lock_release (enum machine_mode mode
, tree arglist
)
5518 enum insn_code icode
;
5520 rtx val
= const0_rtx
;
5522 /* Expand the operands. */
5523 mem
= get_builtin_sync_mem (TREE_VALUE (arglist
), mode
);
5525 /* If there is an explicit operation in the md file, use it. */
5526 icode
= sync_lock_release
[mode
];
5527 if (icode
!= CODE_FOR_nothing
)
5529 if (!insn_data
[icode
].operand
[1].predicate (val
, mode
))
5530 val
= force_reg (mode
, val
);
5532 insn
= GEN_FCN (icode
) (mem
, val
);
5540 /* Otherwise we can implement this operation by emitting a barrier
5541 followed by a store of zero. */
5542 expand_builtin_synchronize ();
5543 emit_move_insn (mem
, val
);
5546 /* Expand an expression EXP that calls a built-in function,
5547 with result going to TARGET if that's convenient
5548 (and in mode MODE if that's convenient).
5549 SUBTARGET may be used as the target for computing one of EXP's operands.
5550 IGNORE is nonzero if the value is to be ignored. */
5553 expand_builtin (tree exp
, rtx target
, rtx subtarget
, enum machine_mode mode
,
5556 tree fndecl
= get_callee_fndecl (exp
);
5557 tree arglist
= TREE_OPERAND (exp
, 1);
5558 enum built_in_function fcode
= DECL_FUNCTION_CODE (fndecl
);
5559 enum machine_mode target_mode
= TYPE_MODE (TREE_TYPE (exp
));
5561 if (DECL_BUILT_IN_CLASS (fndecl
) == BUILT_IN_MD
)
5562 return targetm
.expand_builtin (exp
, target
, subtarget
, mode
, ignore
);
5565 /* Try expanding the builtin via the generic target hook. */
5566 rtx tmp
= targetm
.expand_library_builtin (exp
, target
, subtarget
,
5568 if (tmp
!= NULL_RTX
)
5572 /* When not optimizing, generate calls to library functions for a certain
5575 && !called_as_built_in (fndecl
)
5576 && DECL_ASSEMBLER_NAME_SET_P (fndecl
)
5577 && fcode
!= BUILT_IN_ALLOCA
)
5578 return expand_call (exp
, target
, ignore
);
5580 /* The built-in function expanders test for target == const0_rtx
5581 to determine whether the function's result will be ignored. */
5583 target
= const0_rtx
;
5585 /* If the result of a pure or const built-in function is ignored, and
5586 none of its arguments are volatile, we can avoid expanding the
5587 built-in call and just evaluate the arguments for side-effects. */
5588 if (target
== const0_rtx
5589 && (DECL_IS_PURE (fndecl
) || TREE_READONLY (fndecl
)))
5591 bool volatilep
= false;
5594 for (arg
= arglist
; arg
; arg
= TREE_CHAIN (arg
))
5595 if (TREE_THIS_VOLATILE (TREE_VALUE (arg
)))
5603 for (arg
= arglist
; arg
; arg
= TREE_CHAIN (arg
))
5604 expand_expr (TREE_VALUE (arg
), const0_rtx
,
5605 VOIDmode
, EXPAND_NORMAL
);
5612 CASE_FLT_FN (BUILT_IN_FABS
):
5613 target
= expand_builtin_fabs (arglist
, target
, subtarget
);
5618 CASE_FLT_FN (BUILT_IN_COPYSIGN
):
5619 target
= expand_builtin_copysign (arglist
, target
, subtarget
);
5624 /* Just do a normal library call if we were unable to fold
5626 CASE_FLT_FN (BUILT_IN_CABS
):
5629 CASE_FLT_FN (BUILT_IN_EXP
):
5630 CASE_FLT_FN (BUILT_IN_EXP10
):
5631 CASE_FLT_FN (BUILT_IN_POW10
):
5632 CASE_FLT_FN (BUILT_IN_EXP2
):
5633 CASE_FLT_FN (BUILT_IN_EXPM1
):
5634 CASE_FLT_FN (BUILT_IN_LOGB
):
5635 CASE_FLT_FN (BUILT_IN_ILOGB
):
5636 CASE_FLT_FN (BUILT_IN_LOG
):
5637 CASE_FLT_FN (BUILT_IN_LOG10
):
5638 CASE_FLT_FN (BUILT_IN_LOG2
):
5639 CASE_FLT_FN (BUILT_IN_LOG1P
):
5640 CASE_FLT_FN (BUILT_IN_TAN
):
5641 CASE_FLT_FN (BUILT_IN_ASIN
):
5642 CASE_FLT_FN (BUILT_IN_ACOS
):
5643 CASE_FLT_FN (BUILT_IN_ATAN
):
5644 /* Treat these like sqrt only if unsafe math optimizations are allowed,
5645 because of possible accuracy problems. */
5646 if (! flag_unsafe_math_optimizations
)
5648 CASE_FLT_FN (BUILT_IN_SQRT
):
5649 CASE_FLT_FN (BUILT_IN_FLOOR
):
5650 CASE_FLT_FN (BUILT_IN_CEIL
):
5651 CASE_FLT_FN (BUILT_IN_TRUNC
):
5652 CASE_FLT_FN (BUILT_IN_ROUND
):
5653 CASE_FLT_FN (BUILT_IN_NEARBYINT
):
5654 CASE_FLT_FN (BUILT_IN_RINT
):
5655 CASE_FLT_FN (BUILT_IN_LRINT
):
5656 CASE_FLT_FN (BUILT_IN_LLRINT
):
5657 target
= expand_builtin_mathfn (exp
, target
, subtarget
);
5662 CASE_FLT_FN (BUILT_IN_LCEIL
):
5663 CASE_FLT_FN (BUILT_IN_LLCEIL
):
5664 CASE_FLT_FN (BUILT_IN_LFLOOR
):
5665 CASE_FLT_FN (BUILT_IN_LLFLOOR
):
5666 target
= expand_builtin_int_roundingfn (exp
, target
, subtarget
);
5671 CASE_FLT_FN (BUILT_IN_POW
):
5672 target
= expand_builtin_pow (exp
, target
, subtarget
);
5677 CASE_FLT_FN (BUILT_IN_POWI
):
5678 target
= expand_builtin_powi (exp
, target
, subtarget
);
5683 CASE_FLT_FN (BUILT_IN_ATAN2
):
5684 CASE_FLT_FN (BUILT_IN_LDEXP
):
5685 CASE_FLT_FN (BUILT_IN_FMOD
):
5686 CASE_FLT_FN (BUILT_IN_DREM
):
5687 if (! flag_unsafe_math_optimizations
)
5689 target
= expand_builtin_mathfn_2 (exp
, target
, subtarget
);
5694 CASE_FLT_FN (BUILT_IN_SIN
):
5695 CASE_FLT_FN (BUILT_IN_COS
):
5696 if (! flag_unsafe_math_optimizations
)
5698 target
= expand_builtin_mathfn_3 (exp
, target
, subtarget
);
5703 CASE_FLT_FN (BUILT_IN_SINCOS
):
5704 if (! flag_unsafe_math_optimizations
)
5706 target
= expand_builtin_sincos (exp
);
5711 case BUILT_IN_APPLY_ARGS
:
5712 return expand_builtin_apply_args ();
5714 /* __builtin_apply (FUNCTION, ARGUMENTS, ARGSIZE) invokes
5715 FUNCTION with a copy of the parameters described by
5716 ARGUMENTS, and ARGSIZE. It returns a block of memory
5717 allocated on the stack into which is stored all the registers
5718 that might possibly be used for returning the result of a
5719 function. ARGUMENTS is the value returned by
5720 __builtin_apply_args. ARGSIZE is the number of bytes of
5721 arguments that must be copied. ??? How should this value be
5722 computed? We'll also need a safe worst case value for varargs
5724 case BUILT_IN_APPLY
:
5725 if (!validate_arglist (arglist
, POINTER_TYPE
,
5726 POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
)
5727 && !validate_arglist (arglist
, REFERENCE_TYPE
,
5728 POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
5736 for (t
= arglist
, i
= 0; t
; t
= TREE_CHAIN (t
), i
++)
5737 ops
[i
] = expand_normal (TREE_VALUE (t
));
5739 return expand_builtin_apply (ops
[0], ops
[1], ops
[2]);
5742 /* __builtin_return (RESULT) causes the function to return the
5743 value described by RESULT. RESULT is address of the block of
5744 memory returned by __builtin_apply. */
5745 case BUILT_IN_RETURN
:
5746 if (validate_arglist (arglist
, POINTER_TYPE
, VOID_TYPE
))
5747 expand_builtin_return (expand_normal (TREE_VALUE (arglist
)));
5750 case BUILT_IN_SAVEREGS
:
5751 return expand_builtin_saveregs ();
5753 case BUILT_IN_ARGS_INFO
:
5754 return expand_builtin_args_info (arglist
);
5756 /* Return the address of the first anonymous stack arg. */
5757 case BUILT_IN_NEXT_ARG
:
5758 if (fold_builtin_next_arg (arglist
))
5760 return expand_builtin_next_arg ();
5762 case BUILT_IN_CLASSIFY_TYPE
:
5763 return expand_builtin_classify_type (arglist
);
5765 case BUILT_IN_CONSTANT_P
:
5768 case BUILT_IN_FRAME_ADDRESS
:
5769 case BUILT_IN_RETURN_ADDRESS
:
5770 return expand_builtin_frame_address (fndecl
, arglist
);
5772 /* Returns the address of the area where the structure is returned.
5774 case BUILT_IN_AGGREGATE_INCOMING_ADDRESS
:
5776 || ! AGGREGATE_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl
)))
5777 || !MEM_P (DECL_RTL (DECL_RESULT (current_function_decl
))))
5780 return XEXP (DECL_RTL (DECL_RESULT (current_function_decl
)), 0);
5782 case BUILT_IN_ALLOCA
:
5783 target
= expand_builtin_alloca (arglist
, target
);
5788 case BUILT_IN_STACK_SAVE
:
5789 return expand_stack_save ();
5791 case BUILT_IN_STACK_RESTORE
:
5792 expand_stack_restore (TREE_VALUE (arglist
));
5795 CASE_INT_FN (BUILT_IN_FFS
):
5796 case BUILT_IN_FFSIMAX
:
5797 target
= expand_builtin_unop (target_mode
, arglist
, target
,
5798 subtarget
, ffs_optab
);
5803 CASE_INT_FN (BUILT_IN_CLZ
):
5804 case BUILT_IN_CLZIMAX
:
5805 target
= expand_builtin_unop (target_mode
, arglist
, target
,
5806 subtarget
, clz_optab
);
5811 CASE_INT_FN (BUILT_IN_CTZ
):
5812 case BUILT_IN_CTZIMAX
:
5813 target
= expand_builtin_unop (target_mode
, arglist
, target
,
5814 subtarget
, ctz_optab
);
5819 CASE_INT_FN (BUILT_IN_POPCOUNT
):
5820 case BUILT_IN_POPCOUNTIMAX
:
5821 target
= expand_builtin_unop (target_mode
, arglist
, target
,
5822 subtarget
, popcount_optab
);
5827 CASE_INT_FN (BUILT_IN_PARITY
):
5828 case BUILT_IN_PARITYIMAX
:
5829 target
= expand_builtin_unop (target_mode
, arglist
, target
,
5830 subtarget
, parity_optab
);
5835 case BUILT_IN_STRLEN
:
5836 target
= expand_builtin_strlen (arglist
, target
, target_mode
);
5841 case BUILT_IN_STRCPY
:
5842 target
= expand_builtin_strcpy (fndecl
, arglist
, target
, mode
);
5847 case BUILT_IN_STRNCPY
:
5848 target
= expand_builtin_strncpy (exp
, target
, mode
);
5853 case BUILT_IN_STPCPY
:
5854 target
= expand_builtin_stpcpy (exp
, target
, mode
);
5859 case BUILT_IN_STRCAT
:
5860 target
= expand_builtin_strcat (fndecl
, arglist
, target
, mode
);
5865 case BUILT_IN_STRNCAT
:
5866 target
= expand_builtin_strncat (arglist
, target
, mode
);
5871 case BUILT_IN_STRSPN
:
5872 target
= expand_builtin_strspn (arglist
, target
, mode
);
5877 case BUILT_IN_STRCSPN
:
5878 target
= expand_builtin_strcspn (arglist
, target
, mode
);
5883 case BUILT_IN_STRSTR
:
5884 target
= expand_builtin_strstr (arglist
, TREE_TYPE (exp
), target
, mode
);
5889 case BUILT_IN_STRPBRK
:
5890 target
= expand_builtin_strpbrk (arglist
, TREE_TYPE (exp
), target
, mode
);
5895 case BUILT_IN_INDEX
:
5896 case BUILT_IN_STRCHR
:
5897 target
= expand_builtin_strchr (arglist
, TREE_TYPE (exp
), target
, mode
);
5902 case BUILT_IN_RINDEX
:
5903 case BUILT_IN_STRRCHR
:
5904 target
= expand_builtin_strrchr (arglist
, TREE_TYPE (exp
), target
, mode
);
5909 case BUILT_IN_MEMCPY
:
5910 target
= expand_builtin_memcpy (exp
, target
, mode
);
5915 case BUILT_IN_MEMPCPY
:
5916 target
= expand_builtin_mempcpy (arglist
, TREE_TYPE (exp
), target
, mode
, /*endp=*/ 1);
5921 case BUILT_IN_MEMMOVE
:
5922 target
= expand_builtin_memmove (arglist
, TREE_TYPE (exp
), target
,
5928 case BUILT_IN_BCOPY
:
5929 target
= expand_builtin_bcopy (exp
);
5934 case BUILT_IN_MEMSET
:
5935 target
= expand_builtin_memset (arglist
, target
, mode
, exp
);
5940 case BUILT_IN_BZERO
:
5941 target
= expand_builtin_bzero (exp
);
5946 case BUILT_IN_STRCMP
:
5947 target
= expand_builtin_strcmp (exp
, target
, mode
);
5952 case BUILT_IN_STRNCMP
:
5953 target
= expand_builtin_strncmp (exp
, target
, mode
);
5959 case BUILT_IN_MEMCMP
:
5960 target
= expand_builtin_memcmp (exp
, arglist
, target
, mode
);
5965 case BUILT_IN_SETJMP
:
5966 target
= expand_builtin_setjmp (arglist
, target
);
5971 /* __builtin_longjmp is passed a pointer to an array of five words.
5972 It's similar to the C library longjmp function but works with
5973 __builtin_setjmp above. */
5974 case BUILT_IN_LONGJMP
:
5975 if (!validate_arglist (arglist
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
5979 rtx buf_addr
= expand_expr (TREE_VALUE (arglist
), subtarget
,
5980 VOIDmode
, EXPAND_NORMAL
);
5981 rtx value
= expand_normal (TREE_VALUE (TREE_CHAIN (arglist
)));
5983 if (value
!= const1_rtx
)
5985 error ("%<__builtin_longjmp%> second argument must be 1");
5989 expand_builtin_longjmp (buf_addr
, value
);
5993 case BUILT_IN_NONLOCAL_GOTO
:
5994 target
= expand_builtin_nonlocal_goto (arglist
);
5999 /* This updates the setjmp buffer that is its argument with the value
6000 of the current stack pointer. */
6001 case BUILT_IN_UPDATE_SETJMP_BUF
:
6002 if (validate_arglist (arglist
, POINTER_TYPE
, VOID_TYPE
))
6005 = expand_normal (TREE_VALUE (arglist
));
6007 expand_builtin_update_setjmp_buf (buf_addr
);
6013 expand_builtin_trap ();
6016 case BUILT_IN_PRINTF
:
6017 target
= expand_builtin_printf (exp
, target
, mode
, false);
6022 case BUILT_IN_PRINTF_UNLOCKED
:
6023 target
= expand_builtin_printf (exp
, target
, mode
, true);
6028 case BUILT_IN_FPUTS
:
6029 target
= expand_builtin_fputs (arglist
, target
, false);
6033 case BUILT_IN_FPUTS_UNLOCKED
:
6034 target
= expand_builtin_fputs (arglist
, target
, true);
6039 case BUILT_IN_FPRINTF
:
6040 target
= expand_builtin_fprintf (exp
, target
, mode
, false);
6045 case BUILT_IN_FPRINTF_UNLOCKED
:
6046 target
= expand_builtin_fprintf (exp
, target
, mode
, true);
6051 case BUILT_IN_SPRINTF
:
6052 target
= expand_builtin_sprintf (arglist
, target
, mode
);
6057 CASE_FLT_FN (BUILT_IN_SIGNBIT
):
6058 target
= expand_builtin_signbit (exp
, target
);
6063 /* Various hooks for the DWARF 2 __throw routine. */
6064 case BUILT_IN_UNWIND_INIT
:
6065 expand_builtin_unwind_init ();
6067 case BUILT_IN_DWARF_CFA
:
6068 return virtual_cfa_rtx
;
6069 #ifdef DWARF2_UNWIND_INFO
6070 case BUILT_IN_DWARF_SP_COLUMN
:
6071 return expand_builtin_dwarf_sp_column ();
6072 case BUILT_IN_INIT_DWARF_REG_SIZES
:
6073 expand_builtin_init_dwarf_reg_sizes (TREE_VALUE (arglist
));
6076 case BUILT_IN_FROB_RETURN_ADDR
:
6077 return expand_builtin_frob_return_addr (TREE_VALUE (arglist
));
6078 case BUILT_IN_EXTRACT_RETURN_ADDR
:
6079 return expand_builtin_extract_return_addr (TREE_VALUE (arglist
));
6080 case BUILT_IN_EH_RETURN
:
6081 expand_builtin_eh_return (TREE_VALUE (arglist
),
6082 TREE_VALUE (TREE_CHAIN (arglist
)));
6084 #ifdef EH_RETURN_DATA_REGNO
6085 case BUILT_IN_EH_RETURN_DATA_REGNO
:
6086 return expand_builtin_eh_return_data_regno (arglist
);
6088 case BUILT_IN_EXTEND_POINTER
:
6089 return expand_builtin_extend_pointer (TREE_VALUE (arglist
));
6091 case BUILT_IN_VA_START
:
6092 case BUILT_IN_STDARG_START
:
6093 return expand_builtin_va_start (arglist
);
6094 case BUILT_IN_VA_END
:
6095 return expand_builtin_va_end (arglist
);
6096 case BUILT_IN_VA_COPY
:
6097 return expand_builtin_va_copy (arglist
);
6098 case BUILT_IN_EXPECT
:
6099 return expand_builtin_expect (arglist
, target
);
6100 case BUILT_IN_PREFETCH
:
6101 expand_builtin_prefetch (arglist
);
6104 case BUILT_IN_PROFILE_FUNC_ENTER
:
6105 return expand_builtin_profile_func (false);
6106 case BUILT_IN_PROFILE_FUNC_EXIT
:
6107 return expand_builtin_profile_func (true);
6109 case BUILT_IN_INIT_TRAMPOLINE
:
6110 return expand_builtin_init_trampoline (arglist
);
6111 case BUILT_IN_ADJUST_TRAMPOLINE
:
6112 return expand_builtin_adjust_trampoline (arglist
);
6115 case BUILT_IN_EXECL
:
6116 case BUILT_IN_EXECV
:
6117 case BUILT_IN_EXECLP
:
6118 case BUILT_IN_EXECLE
:
6119 case BUILT_IN_EXECVP
:
6120 case BUILT_IN_EXECVE
:
6121 target
= expand_builtin_fork_or_exec (fndecl
, arglist
, target
, ignore
);
6126 case BUILT_IN_FETCH_AND_ADD_1
:
6127 case BUILT_IN_FETCH_AND_ADD_2
:
6128 case BUILT_IN_FETCH_AND_ADD_4
:
6129 case BUILT_IN_FETCH_AND_ADD_8
:
6130 case BUILT_IN_FETCH_AND_ADD_16
:
6131 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_FETCH_AND_ADD_1
);
6132 target
= expand_builtin_sync_operation (mode
, arglist
, PLUS
,
6133 false, target
, ignore
);
6138 case BUILT_IN_FETCH_AND_SUB_1
:
6139 case BUILT_IN_FETCH_AND_SUB_2
:
6140 case BUILT_IN_FETCH_AND_SUB_4
:
6141 case BUILT_IN_FETCH_AND_SUB_8
:
6142 case BUILT_IN_FETCH_AND_SUB_16
:
6143 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_FETCH_AND_SUB_1
);
6144 target
= expand_builtin_sync_operation (mode
, arglist
, MINUS
,
6145 false, target
, ignore
);
6150 case BUILT_IN_FETCH_AND_OR_1
:
6151 case BUILT_IN_FETCH_AND_OR_2
:
6152 case BUILT_IN_FETCH_AND_OR_4
:
6153 case BUILT_IN_FETCH_AND_OR_8
:
6154 case BUILT_IN_FETCH_AND_OR_16
:
6155 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_FETCH_AND_OR_1
);
6156 target
= expand_builtin_sync_operation (mode
, arglist
, IOR
,
6157 false, target
, ignore
);
6162 case BUILT_IN_FETCH_AND_AND_1
:
6163 case BUILT_IN_FETCH_AND_AND_2
:
6164 case BUILT_IN_FETCH_AND_AND_4
:
6165 case BUILT_IN_FETCH_AND_AND_8
:
6166 case BUILT_IN_FETCH_AND_AND_16
:
6167 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_FETCH_AND_AND_1
);
6168 target
= expand_builtin_sync_operation (mode
, arglist
, AND
,
6169 false, target
, ignore
);
6174 case BUILT_IN_FETCH_AND_XOR_1
:
6175 case BUILT_IN_FETCH_AND_XOR_2
:
6176 case BUILT_IN_FETCH_AND_XOR_4
:
6177 case BUILT_IN_FETCH_AND_XOR_8
:
6178 case BUILT_IN_FETCH_AND_XOR_16
:
6179 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_FETCH_AND_XOR_1
);
6180 target
= expand_builtin_sync_operation (mode
, arglist
, XOR
,
6181 false, target
, ignore
);
6186 case BUILT_IN_FETCH_AND_NAND_1
:
6187 case BUILT_IN_FETCH_AND_NAND_2
:
6188 case BUILT_IN_FETCH_AND_NAND_4
:
6189 case BUILT_IN_FETCH_AND_NAND_8
:
6190 case BUILT_IN_FETCH_AND_NAND_16
:
6191 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_FETCH_AND_NAND_1
);
6192 target
= expand_builtin_sync_operation (mode
, arglist
, NOT
,
6193 false, target
, ignore
);
6198 case BUILT_IN_ADD_AND_FETCH_1
:
6199 case BUILT_IN_ADD_AND_FETCH_2
:
6200 case BUILT_IN_ADD_AND_FETCH_4
:
6201 case BUILT_IN_ADD_AND_FETCH_8
:
6202 case BUILT_IN_ADD_AND_FETCH_16
:
6203 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_ADD_AND_FETCH_1
);
6204 target
= expand_builtin_sync_operation (mode
, arglist
, PLUS
,
6205 true, target
, ignore
);
6210 case BUILT_IN_SUB_AND_FETCH_1
:
6211 case BUILT_IN_SUB_AND_FETCH_2
:
6212 case BUILT_IN_SUB_AND_FETCH_4
:
6213 case BUILT_IN_SUB_AND_FETCH_8
:
6214 case BUILT_IN_SUB_AND_FETCH_16
:
6215 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_SUB_AND_FETCH_1
);
6216 target
= expand_builtin_sync_operation (mode
, arglist
, MINUS
,
6217 true, target
, ignore
);
6222 case BUILT_IN_OR_AND_FETCH_1
:
6223 case BUILT_IN_OR_AND_FETCH_2
:
6224 case BUILT_IN_OR_AND_FETCH_4
:
6225 case BUILT_IN_OR_AND_FETCH_8
:
6226 case BUILT_IN_OR_AND_FETCH_16
:
6227 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_OR_AND_FETCH_1
);
6228 target
= expand_builtin_sync_operation (mode
, arglist
, IOR
,
6229 true, target
, ignore
);
6234 case BUILT_IN_AND_AND_FETCH_1
:
6235 case BUILT_IN_AND_AND_FETCH_2
:
6236 case BUILT_IN_AND_AND_FETCH_4
:
6237 case BUILT_IN_AND_AND_FETCH_8
:
6238 case BUILT_IN_AND_AND_FETCH_16
:
6239 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_AND_AND_FETCH_1
);
6240 target
= expand_builtin_sync_operation (mode
, arglist
, AND
,
6241 true, target
, ignore
);
6246 case BUILT_IN_XOR_AND_FETCH_1
:
6247 case BUILT_IN_XOR_AND_FETCH_2
:
6248 case BUILT_IN_XOR_AND_FETCH_4
:
6249 case BUILT_IN_XOR_AND_FETCH_8
:
6250 case BUILT_IN_XOR_AND_FETCH_16
:
6251 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_XOR_AND_FETCH_1
);
6252 target
= expand_builtin_sync_operation (mode
, arglist
, XOR
,
6253 true, target
, ignore
);
6258 case BUILT_IN_NAND_AND_FETCH_1
:
6259 case BUILT_IN_NAND_AND_FETCH_2
:
6260 case BUILT_IN_NAND_AND_FETCH_4
:
6261 case BUILT_IN_NAND_AND_FETCH_8
:
6262 case BUILT_IN_NAND_AND_FETCH_16
:
6263 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_NAND_AND_FETCH_1
);
6264 target
= expand_builtin_sync_operation (mode
, arglist
, NOT
,
6265 true, target
, ignore
);
6270 case BUILT_IN_BOOL_COMPARE_AND_SWAP_1
:
6271 case BUILT_IN_BOOL_COMPARE_AND_SWAP_2
:
6272 case BUILT_IN_BOOL_COMPARE_AND_SWAP_4
:
6273 case BUILT_IN_BOOL_COMPARE_AND_SWAP_8
:
6274 case BUILT_IN_BOOL_COMPARE_AND_SWAP_16
:
6275 if (mode
== VOIDmode
)
6276 mode
= TYPE_MODE (boolean_type_node
);
6277 if (!target
|| !register_operand (target
, mode
))
6278 target
= gen_reg_rtx (mode
);
6280 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_BOOL_COMPARE_AND_SWAP_1
);
6281 target
= expand_builtin_compare_and_swap (mode
, arglist
, true, target
);
6286 case BUILT_IN_VAL_COMPARE_AND_SWAP_1
:
6287 case BUILT_IN_VAL_COMPARE_AND_SWAP_2
:
6288 case BUILT_IN_VAL_COMPARE_AND_SWAP_4
:
6289 case BUILT_IN_VAL_COMPARE_AND_SWAP_8
:
6290 case BUILT_IN_VAL_COMPARE_AND_SWAP_16
:
6291 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_VAL_COMPARE_AND_SWAP_1
);
6292 target
= expand_builtin_compare_and_swap (mode
, arglist
, false, target
);
6297 case BUILT_IN_LOCK_TEST_AND_SET_1
:
6298 case BUILT_IN_LOCK_TEST_AND_SET_2
:
6299 case BUILT_IN_LOCK_TEST_AND_SET_4
:
6300 case BUILT_IN_LOCK_TEST_AND_SET_8
:
6301 case BUILT_IN_LOCK_TEST_AND_SET_16
:
6302 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_LOCK_TEST_AND_SET_1
);
6303 target
= expand_builtin_lock_test_and_set (mode
, arglist
, target
);
6308 case BUILT_IN_LOCK_RELEASE_1
:
6309 case BUILT_IN_LOCK_RELEASE_2
:
6310 case BUILT_IN_LOCK_RELEASE_4
:
6311 case BUILT_IN_LOCK_RELEASE_8
:
6312 case BUILT_IN_LOCK_RELEASE_16
:
6313 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_LOCK_RELEASE_1
);
6314 expand_builtin_lock_release (mode
, arglist
);
6317 case BUILT_IN_SYNCHRONIZE
:
6318 expand_builtin_synchronize ();
6321 case BUILT_IN_OBJECT_SIZE
:
6322 return expand_builtin_object_size (exp
);
6324 case BUILT_IN_MEMCPY_CHK
:
6325 case BUILT_IN_MEMPCPY_CHK
:
6326 case BUILT_IN_MEMMOVE_CHK
:
6327 case BUILT_IN_MEMSET_CHK
:
6328 target
= expand_builtin_memory_chk (exp
, target
, mode
, fcode
);
6333 case BUILT_IN_STRCPY_CHK
:
6334 case BUILT_IN_STPCPY_CHK
:
6335 case BUILT_IN_STRNCPY_CHK
:
6336 case BUILT_IN_STRCAT_CHK
:
6337 case BUILT_IN_SNPRINTF_CHK
:
6338 case BUILT_IN_VSNPRINTF_CHK
:
6339 maybe_emit_chk_warning (exp
, fcode
);
6342 case BUILT_IN_SPRINTF_CHK
:
6343 case BUILT_IN_VSPRINTF_CHK
:
6344 maybe_emit_sprintf_chk_warning (exp
, fcode
);
6347 default: /* just do library call, if unknown builtin */
6351 /* The switch statement above can drop through to cause the function
6352 to be called normally. */
6353 return expand_call (exp
, target
, ignore
);
6356 /* Determine whether a tree node represents a call to a built-in
6357 function. If the tree T is a call to a built-in function with
6358 the right number of arguments of the appropriate types, return
6359 the DECL_FUNCTION_CODE of the call, e.g. BUILT_IN_SQRT.
6360 Otherwise the return value is END_BUILTINS. */
6362 enum built_in_function
6363 builtin_mathfn_code (tree t
)
6365 tree fndecl
, arglist
, parmlist
;
6366 tree argtype
, parmtype
;
6368 if (TREE_CODE (t
) != CALL_EXPR
6369 || TREE_CODE (TREE_OPERAND (t
, 0)) != ADDR_EXPR
)
6370 return END_BUILTINS
;
6372 fndecl
= get_callee_fndecl (t
);
6373 if (fndecl
== NULL_TREE
6374 || TREE_CODE (fndecl
) != FUNCTION_DECL
6375 || ! DECL_BUILT_IN (fndecl
)
6376 || DECL_BUILT_IN_CLASS (fndecl
) == BUILT_IN_MD
)
6377 return END_BUILTINS
;
6379 arglist
= TREE_OPERAND (t
, 1);
6380 parmlist
= TYPE_ARG_TYPES (TREE_TYPE (fndecl
));
6381 for (; parmlist
; parmlist
= TREE_CHAIN (parmlist
))
6383 /* If a function doesn't take a variable number of arguments,
6384 the last element in the list will have type `void'. */
6385 parmtype
= TREE_VALUE (parmlist
);
6386 if (VOID_TYPE_P (parmtype
))
6389 return END_BUILTINS
;
6390 return DECL_FUNCTION_CODE (fndecl
);
6394 return END_BUILTINS
;
6396 argtype
= TREE_TYPE (TREE_VALUE (arglist
));
6398 if (SCALAR_FLOAT_TYPE_P (parmtype
))
6400 if (! SCALAR_FLOAT_TYPE_P (argtype
))
6401 return END_BUILTINS
;
6403 else if (COMPLEX_FLOAT_TYPE_P (parmtype
))
6405 if (! COMPLEX_FLOAT_TYPE_P (argtype
))
6406 return END_BUILTINS
;
6408 else if (POINTER_TYPE_P (parmtype
))
6410 if (! POINTER_TYPE_P (argtype
))
6411 return END_BUILTINS
;
6413 else if (INTEGRAL_TYPE_P (parmtype
))
6415 if (! INTEGRAL_TYPE_P (argtype
))
6416 return END_BUILTINS
;
6419 return END_BUILTINS
;
6421 arglist
= TREE_CHAIN (arglist
);
6424 /* Variable-length argument list. */
6425 return DECL_FUNCTION_CODE (fndecl
);
6428 /* Fold a call to __builtin_constant_p, if we know it will evaluate to a
6429 constant. ARGLIST is the argument list of the call. */
6432 fold_builtin_constant_p (tree arglist
)
6437 arglist
= TREE_VALUE (arglist
);
6439 /* We return 1 for a numeric type that's known to be a constant
6440 value at compile-time or for an aggregate type that's a
6441 literal constant. */
6442 STRIP_NOPS (arglist
);
6444 /* If we know this is a constant, emit the constant of one. */
6445 if (CONSTANT_CLASS_P (arglist
)
6446 || (TREE_CODE (arglist
) == CONSTRUCTOR
6447 && TREE_CONSTANT (arglist
)))
6448 return integer_one_node
;
6449 if (TREE_CODE (arglist
) == ADDR_EXPR
)
6451 tree op
= TREE_OPERAND (arglist
, 0);
6452 if (TREE_CODE (op
) == STRING_CST
6453 || (TREE_CODE (op
) == ARRAY_REF
6454 && integer_zerop (TREE_OPERAND (op
, 1))
6455 && TREE_CODE (TREE_OPERAND (op
, 0)) == STRING_CST
))
6456 return integer_one_node
;
6459 /* If this expression has side effects, show we don't know it to be a
6460 constant. Likewise if it's a pointer or aggregate type since in
6461 those case we only want literals, since those are only optimized
6462 when generating RTL, not later.
6463 And finally, if we are compiling an initializer, not code, we
6464 need to return a definite result now; there's not going to be any
6465 more optimization done. */
6466 if (TREE_SIDE_EFFECTS (arglist
)
6467 || AGGREGATE_TYPE_P (TREE_TYPE (arglist
))
6468 || POINTER_TYPE_P (TREE_TYPE (arglist
))
6470 return integer_zero_node
;
6475 /* Fold a call to __builtin_expect, if we expect that a comparison against
6476 the argument will fold to a constant. In practice, this means a true
6477 constant or the address of a non-weak symbol. ARGLIST is the argument
6478 list of the call. */
6481 fold_builtin_expect (tree arglist
)
6488 arg
= TREE_VALUE (arglist
);
6490 /* If the argument isn't invariant, then there's nothing we can do. */
6491 if (!TREE_INVARIANT (arg
))
6494 /* If we're looking at an address of a weak decl, then do not fold. */
6497 if (TREE_CODE (inner
) == ADDR_EXPR
)
6501 inner
= TREE_OPERAND (inner
, 0);
6503 while (TREE_CODE (inner
) == COMPONENT_REF
6504 || TREE_CODE (inner
) == ARRAY_REF
);
6505 if (DECL_P (inner
) && DECL_WEAK (inner
))
6509 /* Otherwise, ARG already has the proper type for the return value. */
6513 /* Fold a call to __builtin_classify_type. */
6516 fold_builtin_classify_type (tree arglist
)
6519 return build_int_cst (NULL_TREE
, no_type_class
);
6521 return build_int_cst (NULL_TREE
,
6522 type_to_class (TREE_TYPE (TREE_VALUE (arglist
))));
6525 /* Fold a call to __builtin_strlen. */
6528 fold_builtin_strlen (tree arglist
)
6530 if (!validate_arglist (arglist
, POINTER_TYPE
, VOID_TYPE
))
6534 tree len
= c_strlen (TREE_VALUE (arglist
), 0);
6538 /* Convert from the internal "sizetype" type to "size_t". */
6540 len
= fold_convert (size_type_node
, len
);
6548 /* Fold a call to __builtin_inf or __builtin_huge_val. */
6551 fold_builtin_inf (tree type
, int warn
)
6553 REAL_VALUE_TYPE real
;
6555 /* __builtin_inff is intended to be usable to define INFINITY on all
6556 targets. If an infinity is not available, INFINITY expands "to a
6557 positive constant of type float that overflows at translation
6558 time", footnote "In this case, using INFINITY will violate the
6559 constraint in 6.4.4 and thus require a diagnostic." (C99 7.12#4).
6560 Thus we pedwarn to ensure this constraint violation is
6562 if (!MODE_HAS_INFINITIES (TYPE_MODE (type
)) && warn
)
6563 pedwarn ("target format does not support infinity");
6566 return build_real (type
, real
);
6569 /* Fold a call to __builtin_nan or __builtin_nans. */
6572 fold_builtin_nan (tree arglist
, tree type
, int quiet
)
6574 REAL_VALUE_TYPE real
;
6577 if (!validate_arglist (arglist
, POINTER_TYPE
, VOID_TYPE
))
6579 str
= c_getstr (TREE_VALUE (arglist
));
6583 if (!real_nan (&real
, str
, quiet
, TYPE_MODE (type
)))
6586 return build_real (type
, real
);
6589 /* Return true if the floating point expression T has an integer value.
6590 We also allow +Inf, -Inf and NaN to be considered integer values. */
6593 integer_valued_real_p (tree t
)
6595 switch (TREE_CODE (t
))
6602 case NON_LVALUE_EXPR
:
6603 return integer_valued_real_p (TREE_OPERAND (t
, 0));
6608 return integer_valued_real_p (TREE_OPERAND (t
, 1));
6615 return integer_valued_real_p (TREE_OPERAND (t
, 0))
6616 && integer_valued_real_p (TREE_OPERAND (t
, 1));
6619 return integer_valued_real_p (TREE_OPERAND (t
, 1))
6620 && integer_valued_real_p (TREE_OPERAND (t
, 2));
6623 if (! TREE_CONSTANT_OVERFLOW (t
))
6625 REAL_VALUE_TYPE c
, cint
;
6627 c
= TREE_REAL_CST (t
);
6628 real_trunc (&cint
, TYPE_MODE (TREE_TYPE (t
)), &c
);
6629 return real_identical (&c
, &cint
);
6635 tree type
= TREE_TYPE (TREE_OPERAND (t
, 0));
6636 if (TREE_CODE (type
) == INTEGER_TYPE
)
6638 if (TREE_CODE (type
) == REAL_TYPE
)
6639 return integer_valued_real_p (TREE_OPERAND (t
, 0));
6644 switch (builtin_mathfn_code (t
))
6646 CASE_FLT_FN (BUILT_IN_CEIL
):
6647 CASE_FLT_FN (BUILT_IN_FLOOR
):
6648 CASE_FLT_FN (BUILT_IN_NEARBYINT
):
6649 CASE_FLT_FN (BUILT_IN_RINT
):
6650 CASE_FLT_FN (BUILT_IN_ROUND
):
6651 CASE_FLT_FN (BUILT_IN_TRUNC
):
6665 /* EXP is assumed to be builtin call where truncation can be propagated
6666 across (for instance floor((double)f) == (double)floorf (f).
6667 Do the transformation. */
6670 fold_trunc_transparent_mathfn (tree fndecl
, tree arglist
)
6672 enum built_in_function fcode
= DECL_FUNCTION_CODE (fndecl
);
6675 if (! validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
6678 arg
= TREE_VALUE (arglist
);
6679 /* Integer rounding functions are idempotent. */
6680 if (fcode
== builtin_mathfn_code (arg
))
6683 /* If argument is already integer valued, and we don't need to worry
6684 about setting errno, there's no need to perform rounding. */
6685 if (! flag_errno_math
&& integer_valued_real_p (arg
))
6690 tree arg0
= strip_float_extensions (arg
);
6691 tree ftype
= TREE_TYPE (TREE_TYPE (fndecl
));
6692 tree newtype
= TREE_TYPE (arg0
);
6695 if (TYPE_PRECISION (newtype
) < TYPE_PRECISION (ftype
)
6696 && (decl
= mathfn_built_in (newtype
, fcode
)))
6699 build_tree_list (NULL_TREE
, fold_convert (newtype
, arg0
));
6700 return fold_convert (ftype
,
6701 build_function_call_expr (decl
, arglist
));
6707 /* EXP is assumed to be builtin call which can narrow the FP type of
6708 the argument, for instance lround((double)f) -> lroundf (f). */
6711 fold_fixed_mathfn (tree fndecl
, tree arglist
)
6713 enum built_in_function fcode
= DECL_FUNCTION_CODE (fndecl
);
6716 if (! validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
6719 arg
= TREE_VALUE (arglist
);
6721 /* If argument is already integer valued, and we don't need to worry
6722 about setting errno, there's no need to perform rounding. */
6723 if (! flag_errno_math
&& integer_valued_real_p (arg
))
6724 return fold_build1 (FIX_TRUNC_EXPR
, TREE_TYPE (TREE_TYPE (fndecl
)), arg
);
6728 tree ftype
= TREE_TYPE (arg
);
6729 tree arg0
= strip_float_extensions (arg
);
6730 tree newtype
= TREE_TYPE (arg0
);
6733 if (TYPE_PRECISION (newtype
) < TYPE_PRECISION (ftype
)
6734 && (decl
= mathfn_built_in (newtype
, fcode
)))
6737 build_tree_list (NULL_TREE
, fold_convert (newtype
, arg0
));
6738 return build_function_call_expr (decl
, arglist
);
6744 /* Fold function call to builtin cabs, cabsf or cabsl. ARGLIST
6745 is the argument list and TYPE is the return type. Return
6746 NULL_TREE if no if no simplification can be made. */
6749 fold_builtin_cabs (tree arglist
, tree type
)
6753 if (!arglist
|| TREE_CHAIN (arglist
))
6756 arg
= TREE_VALUE (arglist
);
6757 if (TREE_CODE (TREE_TYPE (arg
)) != COMPLEX_TYPE
6758 || TREE_CODE (TREE_TYPE (TREE_TYPE (arg
))) != REAL_TYPE
)
6761 /* Evaluate cabs of a constant at compile-time. */
6762 if (flag_unsafe_math_optimizations
6763 && TREE_CODE (arg
) == COMPLEX_CST
6764 && TREE_CODE (TREE_REALPART (arg
)) == REAL_CST
6765 && TREE_CODE (TREE_IMAGPART (arg
)) == REAL_CST
6766 && ! TREE_CONSTANT_OVERFLOW (TREE_REALPART (arg
))
6767 && ! TREE_CONSTANT_OVERFLOW (TREE_IMAGPART (arg
)))
6769 REAL_VALUE_TYPE r
, i
;
6771 r
= TREE_REAL_CST (TREE_REALPART (arg
));
6772 i
= TREE_REAL_CST (TREE_IMAGPART (arg
));
6774 real_arithmetic (&r
, MULT_EXPR
, &r
, &r
);
6775 real_arithmetic (&i
, MULT_EXPR
, &i
, &i
);
6776 real_arithmetic (&r
, PLUS_EXPR
, &r
, &i
);
6777 if (real_sqrt (&r
, TYPE_MODE (type
), &r
)
6778 || ! flag_trapping_math
)
6779 return build_real (type
, r
);
6782 /* If either part is zero, cabs is fabs of the other. */
6783 if (TREE_CODE (arg
) == COMPLEX_EXPR
6784 && real_zerop (TREE_OPERAND (arg
, 0)))
6785 return fold_build1 (ABS_EXPR
, type
, TREE_OPERAND (arg
, 1));
6786 if (TREE_CODE (arg
) == COMPLEX_EXPR
6787 && real_zerop (TREE_OPERAND (arg
, 1)))
6788 return fold_build1 (ABS_EXPR
, type
, TREE_OPERAND (arg
, 0));
6790 /* Don't do this when optimizing for size. */
6791 if (flag_unsafe_math_optimizations
6792 && optimize
&& !optimize_size
)
6794 tree sqrtfn
= mathfn_built_in (type
, BUILT_IN_SQRT
);
6796 if (sqrtfn
!= NULL_TREE
)
6798 tree rpart
, ipart
, result
, arglist
;
6800 arg
= builtin_save_expr (arg
);
6802 rpart
= fold_build1 (REALPART_EXPR
, type
, arg
);
6803 ipart
= fold_build1 (IMAGPART_EXPR
, type
, arg
);
6805 rpart
= builtin_save_expr (rpart
);
6806 ipart
= builtin_save_expr (ipart
);
6808 result
= fold_build2 (PLUS_EXPR
, type
,
6809 fold_build2 (MULT_EXPR
, type
,
6811 fold_build2 (MULT_EXPR
, type
,
6814 arglist
= build_tree_list (NULL_TREE
, result
);
6815 return build_function_call_expr (sqrtfn
, arglist
);
6822 /* Fold a builtin function call to sqrt, sqrtf, or sqrtl. Return
6823 NULL_TREE if no simplification can be made. */
6826 fold_builtin_sqrt (tree arglist
, tree type
)
6829 enum built_in_function fcode
;
6830 tree arg
= TREE_VALUE (arglist
);
6832 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
6835 /* Optimize sqrt of constant value. */
6836 if (TREE_CODE (arg
) == REAL_CST
6837 && ! TREE_CONSTANT_OVERFLOW (arg
))
6839 REAL_VALUE_TYPE r
, x
;
6841 x
= TREE_REAL_CST (arg
);
6842 if (real_sqrt (&r
, TYPE_MODE (type
), &x
)
6843 || (!flag_trapping_math
&& !flag_errno_math
))
6844 return build_real (type
, r
);
6847 /* Optimize sqrt(expN(x)) = expN(x*0.5). */
6848 fcode
= builtin_mathfn_code (arg
);
6849 if (flag_unsafe_math_optimizations
&& BUILTIN_EXPONENT_P (fcode
))
6851 tree expfn
= TREE_OPERAND (TREE_OPERAND (arg
, 0), 0);
6852 arg
= fold_build2 (MULT_EXPR
, type
,
6853 TREE_VALUE (TREE_OPERAND (arg
, 1)),
6854 build_real (type
, dconsthalf
));
6855 arglist
= build_tree_list (NULL_TREE
, arg
);
6856 return build_function_call_expr (expfn
, arglist
);
6859 /* Optimize sqrt(Nroot(x)) -> pow(x,1/(2*N)). */
6860 if (flag_unsafe_math_optimizations
&& BUILTIN_ROOT_P (fcode
))
6862 tree powfn
= mathfn_built_in (type
, BUILT_IN_POW
);
6866 tree arg0
= TREE_VALUE (TREE_OPERAND (arg
, 1));
6868 /* The inner root was either sqrt or cbrt. */
6869 REAL_VALUE_TYPE dconstroot
=
6870 BUILTIN_SQRT_P (fcode
) ? dconsthalf
: dconstthird
;
6872 /* Adjust for the outer root. */
6873 SET_REAL_EXP (&dconstroot
, REAL_EXP (&dconstroot
) - 1);
6874 dconstroot
= real_value_truncate (TYPE_MODE (type
), dconstroot
);
6875 tree_root
= build_real (type
, dconstroot
);
6876 arglist
= tree_cons (NULL_TREE
, arg0
,
6877 build_tree_list (NULL_TREE
, tree_root
));
6878 return build_function_call_expr (powfn
, arglist
);
6882 /* Optimize sqrt(pow(x,y)) = pow(|x|,y*0.5). */
6883 if (flag_unsafe_math_optimizations
6884 && (fcode
== BUILT_IN_POW
6885 || fcode
== BUILT_IN_POWF
6886 || fcode
== BUILT_IN_POWL
))
6888 tree powfn
= TREE_OPERAND (TREE_OPERAND (arg
, 0), 0);
6889 tree arg0
= TREE_VALUE (TREE_OPERAND (arg
, 1));
6890 tree arg1
= TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg
, 1)));
6892 if (!tree_expr_nonnegative_p (arg0
))
6893 arg0
= build1 (ABS_EXPR
, type
, arg0
);
6894 narg1
= fold_build2 (MULT_EXPR
, type
, arg1
,
6895 build_real (type
, dconsthalf
));
6896 arglist
= tree_cons (NULL_TREE
, arg0
,
6897 build_tree_list (NULL_TREE
, narg1
));
6898 return build_function_call_expr (powfn
, arglist
);
6904 /* Fold a builtin function call to cbrt, cbrtf, or cbrtl. Return
6905 NULL_TREE if no simplification can be made. */
6907 fold_builtin_cbrt (tree arglist
, tree type
)
6909 tree arg
= TREE_VALUE (arglist
);
6910 const enum built_in_function fcode
= builtin_mathfn_code (arg
);
6912 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
6915 /* Optimize cbrt of constant value. */
6916 if (real_zerop (arg
) || real_onep (arg
) || real_minus_onep (arg
))
6919 if (flag_unsafe_math_optimizations
)
6921 /* Optimize cbrt(expN(x)) -> expN(x/3). */
6922 if (BUILTIN_EXPONENT_P (fcode
))
6924 tree expfn
= TREE_OPERAND (TREE_OPERAND (arg
, 0), 0);
6925 const REAL_VALUE_TYPE third_trunc
=
6926 real_value_truncate (TYPE_MODE (type
), dconstthird
);
6927 arg
= fold_build2 (MULT_EXPR
, type
,
6928 TREE_VALUE (TREE_OPERAND (arg
, 1)),
6929 build_real (type
, third_trunc
));
6930 arglist
= build_tree_list (NULL_TREE
, arg
);
6931 return build_function_call_expr (expfn
, arglist
);
6934 /* Optimize cbrt(sqrt(x)) -> pow(x,1/6). */
6935 if (BUILTIN_SQRT_P (fcode
))
6937 tree powfn
= mathfn_built_in (type
, BUILT_IN_POW
);
6941 tree arg0
= TREE_VALUE (TREE_OPERAND (arg
, 1));
6943 REAL_VALUE_TYPE dconstroot
= dconstthird
;
6945 SET_REAL_EXP (&dconstroot
, REAL_EXP (&dconstroot
) - 1);
6946 dconstroot
= real_value_truncate (TYPE_MODE (type
), dconstroot
);
6947 tree_root
= build_real (type
, dconstroot
);
6948 arglist
= tree_cons (NULL_TREE
, arg0
,
6949 build_tree_list (NULL_TREE
, tree_root
));
6950 return build_function_call_expr (powfn
, arglist
);
6954 /* Optimize cbrt(cbrt(x)) -> pow(x,1/9) iff x is nonnegative. */
6955 if (BUILTIN_CBRT_P (fcode
))
6957 tree arg0
= TREE_VALUE (TREE_OPERAND (arg
, 1));
6958 if (tree_expr_nonnegative_p (arg0
))
6960 tree powfn
= mathfn_built_in (type
, BUILT_IN_POW
);
6965 REAL_VALUE_TYPE dconstroot
;
6967 real_arithmetic (&dconstroot
, MULT_EXPR
, &dconstthird
, &dconstthird
);
6968 dconstroot
= real_value_truncate (TYPE_MODE (type
), dconstroot
);
6969 tree_root
= build_real (type
, dconstroot
);
6970 arglist
= tree_cons (NULL_TREE
, arg0
,
6971 build_tree_list (NULL_TREE
, tree_root
));
6972 return build_function_call_expr (powfn
, arglist
);
6977 /* Optimize cbrt(pow(x,y)) -> pow(x,y/3) iff x is nonnegative. */
6978 if (fcode
== BUILT_IN_POW
|| fcode
== BUILT_IN_POWF
6979 || fcode
== BUILT_IN_POWL
)
6981 tree arg00
= TREE_VALUE (TREE_OPERAND (arg
, 1));
6982 tree arg01
= TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg
, 1)));
6983 if (tree_expr_nonnegative_p (arg00
))
6985 tree powfn
= TREE_OPERAND (TREE_OPERAND (arg
, 0), 0);
6986 const REAL_VALUE_TYPE dconstroot
6987 = real_value_truncate (TYPE_MODE (type
), dconstthird
);
6988 tree narg01
= fold_build2 (MULT_EXPR
, type
, arg01
,
6989 build_real (type
, dconstroot
));
6990 arglist
= tree_cons (NULL_TREE
, arg00
,
6991 build_tree_list (NULL_TREE
, narg01
));
6992 return build_function_call_expr (powfn
, arglist
);
6999 /* Fold function call to builtin sin, sinf, or sinl. Return
7000 NULL_TREE if no simplification can be made. */
7002 fold_builtin_sin (tree arglist
)
7004 tree arg
= TREE_VALUE (arglist
);
7006 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
7009 /* Optimize sin (0.0) = 0.0. */
7010 if (real_zerop (arg
))
7016 /* Fold function call to builtin cos, cosf, or cosl. Return
7017 NULL_TREE if no simplification can be made. */
7019 fold_builtin_cos (tree arglist
, tree type
, tree fndecl
)
7021 tree arg
= TREE_VALUE (arglist
);
7023 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
7026 /* Optimize cos (0.0) = 1.0. */
7027 if (real_zerop (arg
))
7028 return build_real (type
, dconst1
);
7030 /* Optimize cos(-x) into cos (x). */
7031 if (TREE_CODE (arg
) == NEGATE_EXPR
)
7033 tree args
= build_tree_list (NULL_TREE
,
7034 TREE_OPERAND (arg
, 0));
7035 return build_function_call_expr (fndecl
, args
);
7041 /* Fold function call to builtin tan, tanf, or tanl. Return
7042 NULL_TREE if no simplification can be made. */
7044 fold_builtin_tan (tree arglist
)
7046 enum built_in_function fcode
;
7047 tree arg
= TREE_VALUE (arglist
);
7049 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
7052 /* Optimize tan(0.0) = 0.0. */
7053 if (real_zerop (arg
))
7056 /* Optimize tan(atan(x)) = x. */
7057 fcode
= builtin_mathfn_code (arg
);
7058 if (flag_unsafe_math_optimizations
7059 && (fcode
== BUILT_IN_ATAN
7060 || fcode
== BUILT_IN_ATANF
7061 || fcode
== BUILT_IN_ATANL
))
7062 return TREE_VALUE (TREE_OPERAND (arg
, 1));
7067 /* Fold function call to builtin atan, atanf, or atanl. Return
7068 NULL_TREE if no simplification can be made. */
7071 fold_builtin_atan (tree arglist
, tree type
)
7074 tree arg
= TREE_VALUE (arglist
);
7076 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
7079 /* Optimize atan(0.0) = 0.0. */
7080 if (real_zerop (arg
))
7083 /* Optimize atan(1.0) = pi/4. */
7084 if (real_onep (arg
))
7086 REAL_VALUE_TYPE cst
;
7088 real_convert (&cst
, TYPE_MODE (type
), &dconstpi
);
7089 SET_REAL_EXP (&cst
, REAL_EXP (&cst
) - 2);
7090 return build_real (type
, cst
);
7096 /* Fold function call to builtin trunc, truncf or truncl. Return
7097 NULL_TREE if no simplification can be made. */
7100 fold_builtin_trunc (tree fndecl
, tree arglist
)
7104 if (! validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
7107 /* Optimize trunc of constant value. */
7108 arg
= TREE_VALUE (arglist
);
7109 if (TREE_CODE (arg
) == REAL_CST
&& ! TREE_CONSTANT_OVERFLOW (arg
))
7111 REAL_VALUE_TYPE r
, x
;
7112 tree type
= TREE_TYPE (TREE_TYPE (fndecl
));
7114 x
= TREE_REAL_CST (arg
);
7115 real_trunc (&r
, TYPE_MODE (type
), &x
);
7116 return build_real (type
, r
);
7119 return fold_trunc_transparent_mathfn (fndecl
, arglist
);
7122 /* Fold function call to builtin floor, floorf or floorl. Return
7123 NULL_TREE if no simplification can be made. */
7126 fold_builtin_floor (tree fndecl
, tree arglist
)
7130 if (! validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
7133 /* Optimize floor of constant value. */
7134 arg
= TREE_VALUE (arglist
);
7135 if (TREE_CODE (arg
) == REAL_CST
&& ! TREE_CONSTANT_OVERFLOW (arg
))
7139 x
= TREE_REAL_CST (arg
);
7140 if (! REAL_VALUE_ISNAN (x
) || ! flag_errno_math
)
7142 tree type
= TREE_TYPE (TREE_TYPE (fndecl
));
7145 real_floor (&r
, TYPE_MODE (type
), &x
);
7146 return build_real (type
, r
);
7150 return fold_trunc_transparent_mathfn (fndecl
, arglist
);
7153 /* Fold function call to builtin ceil, ceilf or ceill. Return
7154 NULL_TREE if no simplification can be made. */
7157 fold_builtin_ceil (tree fndecl
, tree arglist
)
7161 if (! validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
7164 /* Optimize ceil of constant value. */
7165 arg
= TREE_VALUE (arglist
);
7166 if (TREE_CODE (arg
) == REAL_CST
&& ! TREE_CONSTANT_OVERFLOW (arg
))
7170 x
= TREE_REAL_CST (arg
);
7171 if (! REAL_VALUE_ISNAN (x
) || ! flag_errno_math
)
7173 tree type
= TREE_TYPE (TREE_TYPE (fndecl
));
7176 real_ceil (&r
, TYPE_MODE (type
), &x
);
7177 return build_real (type
, r
);
7181 return fold_trunc_transparent_mathfn (fndecl
, arglist
);
7184 /* Fold function call to builtin round, roundf or roundl. Return
7185 NULL_TREE if no simplification can be made. */
7188 fold_builtin_round (tree fndecl
, tree arglist
)
7192 if (! validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
7195 /* Optimize round of constant value. */
7196 arg
= TREE_VALUE (arglist
);
7197 if (TREE_CODE (arg
) == REAL_CST
&& ! TREE_CONSTANT_OVERFLOW (arg
))
7201 x
= TREE_REAL_CST (arg
);
7202 if (! REAL_VALUE_ISNAN (x
) || ! flag_errno_math
)
7204 tree type
= TREE_TYPE (TREE_TYPE (fndecl
));
7207 real_round (&r
, TYPE_MODE (type
), &x
);
7208 return build_real (type
, r
);
7212 return fold_trunc_transparent_mathfn (fndecl
, arglist
);
7215 /* Fold function call to builtin lround, lroundf or lroundl (or the
7216 corresponding long long versions) and other rounding functions.
7217 Return NULL_TREE if no simplification can be made. */
7220 fold_builtin_int_roundingfn (tree fndecl
, tree arglist
)
7224 if (! validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
7227 /* Optimize lround of constant value. */
7228 arg
= TREE_VALUE (arglist
);
7229 if (TREE_CODE (arg
) == REAL_CST
&& ! TREE_CONSTANT_OVERFLOW (arg
))
7231 const REAL_VALUE_TYPE x
= TREE_REAL_CST (arg
);
7233 if (! REAL_VALUE_ISNAN (x
) && ! REAL_VALUE_ISINF (x
))
7235 tree itype
= TREE_TYPE (TREE_TYPE (fndecl
));
7236 tree ftype
= TREE_TYPE (arg
), result
;
7237 HOST_WIDE_INT hi
, lo
;
7240 switch (DECL_FUNCTION_CODE (fndecl
))
7242 CASE_FLT_FN (BUILT_IN_LFLOOR
):
7243 CASE_FLT_FN (BUILT_IN_LLFLOOR
):
7244 real_floor (&r
, TYPE_MODE (ftype
), &x
);
7247 CASE_FLT_FN (BUILT_IN_LCEIL
):
7248 CASE_FLT_FN (BUILT_IN_LLCEIL
):
7249 real_ceil (&r
, TYPE_MODE (ftype
), &x
);
7252 CASE_FLT_FN (BUILT_IN_LROUND
):
7253 CASE_FLT_FN (BUILT_IN_LLROUND
):
7254 real_round (&r
, TYPE_MODE (ftype
), &x
);
7261 REAL_VALUE_TO_INT (&lo
, &hi
, r
);
7262 result
= build_int_cst_wide (NULL_TREE
, lo
, hi
);
7263 if (int_fits_type_p (result
, itype
))
7264 return fold_convert (itype
, result
);
7268 return fold_fixed_mathfn (fndecl
, arglist
);
7271 /* Fold function call to builtin ffs, clz, ctz, popcount and parity
7272 and their long and long long variants (i.e. ffsl and ffsll).
7273 Return NULL_TREE if no simplification can be made. */
7276 fold_builtin_bitop (tree fndecl
, tree arglist
)
7280 if (! validate_arglist (arglist
, INTEGER_TYPE
, VOID_TYPE
))
7283 /* Optimize for constant argument. */
7284 arg
= TREE_VALUE (arglist
);
7285 if (TREE_CODE (arg
) == INTEGER_CST
&& ! TREE_CONSTANT_OVERFLOW (arg
))
7287 HOST_WIDE_INT hi
, width
, result
;
7288 unsigned HOST_WIDE_INT lo
;
7291 type
= TREE_TYPE (arg
);
7292 width
= TYPE_PRECISION (type
);
7293 lo
= TREE_INT_CST_LOW (arg
);
7295 /* Clear all the bits that are beyond the type's precision. */
7296 if (width
> HOST_BITS_PER_WIDE_INT
)
7298 hi
= TREE_INT_CST_HIGH (arg
);
7299 if (width
< 2 * HOST_BITS_PER_WIDE_INT
)
7300 hi
&= ~((HOST_WIDE_INT
) (-1) >> (width
- HOST_BITS_PER_WIDE_INT
));
7305 if (width
< HOST_BITS_PER_WIDE_INT
)
7306 lo
&= ~((unsigned HOST_WIDE_INT
) (-1) << width
);
7309 switch (DECL_FUNCTION_CODE (fndecl
))
7311 CASE_INT_FN (BUILT_IN_FFS
):
7313 result
= exact_log2 (lo
& -lo
) + 1;
7315 result
= HOST_BITS_PER_WIDE_INT
+ exact_log2 (hi
& -hi
) + 1;
7320 CASE_INT_FN (BUILT_IN_CLZ
):
7322 result
= width
- floor_log2 (hi
) - 1 - HOST_BITS_PER_WIDE_INT
;
7324 result
= width
- floor_log2 (lo
) - 1;
7325 else if (! CLZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type
), result
))
7329 CASE_INT_FN (BUILT_IN_CTZ
):
7331 result
= exact_log2 (lo
& -lo
);
7333 result
= HOST_BITS_PER_WIDE_INT
+ exact_log2 (hi
& -hi
);
7334 else if (! CTZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type
), result
))
7338 CASE_INT_FN (BUILT_IN_POPCOUNT
):
7341 result
++, lo
&= lo
- 1;
7343 result
++, hi
&= hi
- 1;
7346 CASE_INT_FN (BUILT_IN_PARITY
):
7349 result
++, lo
&= lo
- 1;
7351 result
++, hi
&= hi
- 1;
7359 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl
)), result
);
7365 /* Return true if EXPR is the real constant contained in VALUE. */
7368 real_dconstp (tree expr
, const REAL_VALUE_TYPE
*value
)
7372 return ((TREE_CODE (expr
) == REAL_CST
7373 && ! TREE_CONSTANT_OVERFLOW (expr
)
7374 && REAL_VALUES_EQUAL (TREE_REAL_CST (expr
), *value
))
7375 || (TREE_CODE (expr
) == COMPLEX_CST
7376 && real_dconstp (TREE_REALPART (expr
), value
)
7377 && real_zerop (TREE_IMAGPART (expr
))));
7380 /* A subroutine of fold_builtin to fold the various logarithmic
7381 functions. EXP is the CALL_EXPR of a call to a builtin logN
7382 function. VALUE is the base of the logN function. */
7385 fold_builtin_logarithm (tree fndecl
, tree arglist
,
7386 const REAL_VALUE_TYPE
*value
)
7388 if (validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
7390 tree type
= TREE_TYPE (TREE_TYPE (fndecl
));
7391 tree arg
= TREE_VALUE (arglist
);
7392 const enum built_in_function fcode
= builtin_mathfn_code (arg
);
7394 /* Optimize logN(1.0) = 0.0. */
7395 if (real_onep (arg
))
7396 return build_real (type
, dconst0
);
7398 /* Optimize logN(N) = 1.0. If N can't be truncated to MODE
7399 exactly, then only do this if flag_unsafe_math_optimizations. */
7400 if (exact_real_truncate (TYPE_MODE (type
), value
)
7401 || flag_unsafe_math_optimizations
)
7403 const REAL_VALUE_TYPE value_truncate
=
7404 real_value_truncate (TYPE_MODE (type
), *value
);
7405 if (real_dconstp (arg
, &value_truncate
))
7406 return build_real (type
, dconst1
);
7409 /* Special case, optimize logN(expN(x)) = x. */
7410 if (flag_unsafe_math_optimizations
7411 && ((value
== &dconste
7412 && (fcode
== BUILT_IN_EXP
7413 || fcode
== BUILT_IN_EXPF
7414 || fcode
== BUILT_IN_EXPL
))
7415 || (value
== &dconst2
7416 && (fcode
== BUILT_IN_EXP2
7417 || fcode
== BUILT_IN_EXP2F
7418 || fcode
== BUILT_IN_EXP2L
))
7419 || (value
== &dconst10
&& (BUILTIN_EXP10_P (fcode
)))))
7420 return fold_convert (type
, TREE_VALUE (TREE_OPERAND (arg
, 1)));
7422 /* Optimize logN(func()) for various exponential functions. We
7423 want to determine the value "x" and the power "exponent" in
7424 order to transform logN(x**exponent) into exponent*logN(x). */
7425 if (flag_unsafe_math_optimizations
)
7427 tree exponent
= 0, x
= 0;
7431 CASE_FLT_FN (BUILT_IN_EXP
):
7432 /* Prepare to do logN(exp(exponent) -> exponent*logN(e). */
7433 x
= build_real (type
,
7434 real_value_truncate (TYPE_MODE (type
), dconste
));
7435 exponent
= TREE_VALUE (TREE_OPERAND (arg
, 1));
7437 CASE_FLT_FN (BUILT_IN_EXP2
):
7438 /* Prepare to do logN(exp2(exponent) -> exponent*logN(2). */
7439 x
= build_real (type
, dconst2
);
7440 exponent
= TREE_VALUE (TREE_OPERAND (arg
, 1));
7442 CASE_FLT_FN (BUILT_IN_EXP10
):
7443 CASE_FLT_FN (BUILT_IN_POW10
):
7444 /* Prepare to do logN(exp10(exponent) -> exponent*logN(10). */
7445 x
= build_real (type
, dconst10
);
7446 exponent
= TREE_VALUE (TREE_OPERAND (arg
, 1));
7448 CASE_FLT_FN (BUILT_IN_SQRT
):
7449 /* Prepare to do logN(sqrt(x) -> 0.5*logN(x). */
7450 x
= TREE_VALUE (TREE_OPERAND (arg
, 1));
7451 exponent
= build_real (type
, dconsthalf
);
7453 CASE_FLT_FN (BUILT_IN_CBRT
):
7454 /* Prepare to do logN(cbrt(x) -> (1/3)*logN(x). */
7455 x
= TREE_VALUE (TREE_OPERAND (arg
, 1));
7456 exponent
= build_real (type
, real_value_truncate (TYPE_MODE (type
),
7459 CASE_FLT_FN (BUILT_IN_POW
):
7460 /* Prepare to do logN(pow(x,exponent) -> exponent*logN(x). */
7461 x
= TREE_VALUE (TREE_OPERAND (arg
, 1));
7462 exponent
= TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg
, 1)));
7468 /* Now perform the optimization. */
7472 arglist
= build_tree_list (NULL_TREE
, x
);
7473 logfn
= build_function_call_expr (fndecl
, arglist
);
7474 return fold_build2 (MULT_EXPR
, type
, exponent
, logfn
);
7482 /* Fold a builtin function call to pow, powf, or powl. Return
7483 NULL_TREE if no simplification can be made. */
7485 fold_builtin_pow (tree fndecl
, tree arglist
, tree type
)
7487 tree arg0
= TREE_VALUE (arglist
);
7488 tree arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
7490 if (!validate_arglist (arglist
, REAL_TYPE
, REAL_TYPE
, VOID_TYPE
))
7493 /* Optimize pow(1.0,y) = 1.0. */
7494 if (real_onep (arg0
))
7495 return omit_one_operand (type
, build_real (type
, dconst1
), arg1
);
7497 if (TREE_CODE (arg1
) == REAL_CST
7498 && ! TREE_CONSTANT_OVERFLOW (arg1
))
7500 REAL_VALUE_TYPE cint
;
7504 c
= TREE_REAL_CST (arg1
);
7506 /* Optimize pow(x,0.0) = 1.0. */
7507 if (REAL_VALUES_EQUAL (c
, dconst0
))
7508 return omit_one_operand (type
, build_real (type
, dconst1
),
7511 /* Optimize pow(x,1.0) = x. */
7512 if (REAL_VALUES_EQUAL (c
, dconst1
))
7515 /* Optimize pow(x,-1.0) = 1.0/x. */
7516 if (REAL_VALUES_EQUAL (c
, dconstm1
))
7517 return fold_build2 (RDIV_EXPR
, type
,
7518 build_real (type
, dconst1
), arg0
);
7520 /* Optimize pow(x,0.5) = sqrt(x). */
7521 if (flag_unsafe_math_optimizations
7522 && REAL_VALUES_EQUAL (c
, dconsthalf
))
7524 tree sqrtfn
= mathfn_built_in (type
, BUILT_IN_SQRT
);
7526 if (sqrtfn
!= NULL_TREE
)
7528 tree arglist
= build_tree_list (NULL_TREE
, arg0
);
7529 return build_function_call_expr (sqrtfn
, arglist
);
7533 /* Check for an integer exponent. */
7534 n
= real_to_integer (&c
);
7535 real_from_integer (&cint
, VOIDmode
, n
, n
< 0 ? -1 : 0, 0);
7536 if (real_identical (&c
, &cint
))
7538 /* Attempt to evaluate pow at compile-time. */
7539 if (TREE_CODE (arg0
) == REAL_CST
7540 && ! TREE_CONSTANT_OVERFLOW (arg0
))
7545 x
= TREE_REAL_CST (arg0
);
7546 inexact
= real_powi (&x
, TYPE_MODE (type
), &x
, n
);
7547 if (flag_unsafe_math_optimizations
|| !inexact
)
7548 return build_real (type
, x
);
7551 /* Strip sign ops from even integer powers. */
7552 if ((n
& 1) == 0 && flag_unsafe_math_optimizations
)
7554 tree narg0
= fold_strip_sign_ops (arg0
);
7557 arglist
= build_tree_list (NULL_TREE
, arg1
);
7558 arglist
= tree_cons (NULL_TREE
, narg0
, arglist
);
7559 return build_function_call_expr (fndecl
, arglist
);
7565 if (flag_unsafe_math_optimizations
)
7567 const enum built_in_function fcode
= builtin_mathfn_code (arg0
);
7569 /* Optimize pow(expN(x),y) = expN(x*y). */
7570 if (BUILTIN_EXPONENT_P (fcode
))
7572 tree expfn
= TREE_OPERAND (TREE_OPERAND (arg0
, 0), 0);
7573 tree arg
= TREE_VALUE (TREE_OPERAND (arg0
, 1));
7574 arg
= fold_build2 (MULT_EXPR
, type
, arg
, arg1
);
7575 arglist
= build_tree_list (NULL_TREE
, arg
);
7576 return build_function_call_expr (expfn
, arglist
);
7579 /* Optimize pow(sqrt(x),y) = pow(x,y*0.5). */
7580 if (BUILTIN_SQRT_P (fcode
))
7582 tree narg0
= TREE_VALUE (TREE_OPERAND (arg0
, 1));
7583 tree narg1
= fold_build2 (MULT_EXPR
, type
, arg1
,
7584 build_real (type
, dconsthalf
));
7586 arglist
= tree_cons (NULL_TREE
, narg0
,
7587 build_tree_list (NULL_TREE
, narg1
));
7588 return build_function_call_expr (fndecl
, arglist
);
7591 /* Optimize pow(cbrt(x),y) = pow(x,y/3) iff x is nonnegative. */
7592 if (BUILTIN_CBRT_P (fcode
))
7594 tree arg
= TREE_VALUE (TREE_OPERAND (arg0
, 1));
7595 if (tree_expr_nonnegative_p (arg
))
7597 const REAL_VALUE_TYPE dconstroot
7598 = real_value_truncate (TYPE_MODE (type
), dconstthird
);
7599 tree narg1
= fold_build2 (MULT_EXPR
, type
, arg1
,
7600 build_real (type
, dconstroot
));
7601 arglist
= tree_cons (NULL_TREE
, arg
,
7602 build_tree_list (NULL_TREE
, narg1
));
7603 return build_function_call_expr (fndecl
, arglist
);
7607 /* Optimize pow(pow(x,y),z) = pow(x,y*z). */
7608 if (fcode
== BUILT_IN_POW
|| fcode
== BUILT_IN_POWF
7609 || fcode
== BUILT_IN_POWL
)
7611 tree arg00
= TREE_VALUE (TREE_OPERAND (arg0
, 1));
7612 tree arg01
= TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg0
, 1)));
7613 tree narg1
= fold_build2 (MULT_EXPR
, type
, arg01
, arg1
);
7614 arglist
= tree_cons (NULL_TREE
, arg00
,
7615 build_tree_list (NULL_TREE
, narg1
));
7616 return build_function_call_expr (fndecl
, arglist
);
7623 /* Fold a builtin function call to powi, powif, or powil. Return
7624 NULL_TREE if no simplification can be made. */
7626 fold_builtin_powi (tree fndecl ATTRIBUTE_UNUSED
, tree arglist
, tree type
)
7628 tree arg0
= TREE_VALUE (arglist
);
7629 tree arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
7631 if (!validate_arglist (arglist
, REAL_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
7634 /* Optimize pow(1.0,y) = 1.0. */
7635 if (real_onep (arg0
))
7636 return omit_one_operand (type
, build_real (type
, dconst1
), arg1
);
7638 if (host_integerp (arg1
, 0))
7640 HOST_WIDE_INT c
= TREE_INT_CST_LOW (arg1
);
7642 /* Evaluate powi at compile-time. */
7643 if (TREE_CODE (arg0
) == REAL_CST
7644 && ! TREE_CONSTANT_OVERFLOW (arg0
))
7647 x
= TREE_REAL_CST (arg0
);
7648 real_powi (&x
, TYPE_MODE (type
), &x
, c
);
7649 return build_real (type
, x
);
7652 /* Optimize pow(x,0) = 1.0. */
7654 return omit_one_operand (type
, build_real (type
, dconst1
),
7657 /* Optimize pow(x,1) = x. */
7661 /* Optimize pow(x,-1) = 1.0/x. */
7663 return fold_build2 (RDIV_EXPR
, type
,
7664 build_real (type
, dconst1
), arg0
);
7670 /* A subroutine of fold_builtin to fold the various exponent
7671 functions. EXP is the CALL_EXPR of a call to a builtin function.
7672 VALUE is the value which will be raised to a power. */
7675 fold_builtin_exponent (tree fndecl
, tree arglist
,
7676 const REAL_VALUE_TYPE
*value
)
7678 if (validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
7680 tree type
= TREE_TYPE (TREE_TYPE (fndecl
));
7681 tree arg
= TREE_VALUE (arglist
);
7683 /* Optimize exp*(0.0) = 1.0. */
7684 if (real_zerop (arg
))
7685 return build_real (type
, dconst1
);
7687 /* Optimize expN(1.0) = N. */
7688 if (real_onep (arg
))
7690 REAL_VALUE_TYPE cst
;
7692 real_convert (&cst
, TYPE_MODE (type
), value
);
7693 return build_real (type
, cst
);
7696 /* Attempt to evaluate expN(integer) at compile-time. */
7697 if (flag_unsafe_math_optimizations
7698 && TREE_CODE (arg
) == REAL_CST
7699 && ! TREE_CONSTANT_OVERFLOW (arg
))
7701 REAL_VALUE_TYPE cint
;
7705 c
= TREE_REAL_CST (arg
);
7706 n
= real_to_integer (&c
);
7707 real_from_integer (&cint
, VOIDmode
, n
,
7709 if (real_identical (&c
, &cint
))
7713 real_powi (&x
, TYPE_MODE (type
), value
, n
);
7714 return build_real (type
, x
);
7718 /* Optimize expN(logN(x)) = x. */
7719 if (flag_unsafe_math_optimizations
)
7721 const enum built_in_function fcode
= builtin_mathfn_code (arg
);
7723 if ((value
== &dconste
7724 && (fcode
== BUILT_IN_LOG
7725 || fcode
== BUILT_IN_LOGF
7726 || fcode
== BUILT_IN_LOGL
))
7727 || (value
== &dconst2
7728 && (fcode
== BUILT_IN_LOG2
7729 || fcode
== BUILT_IN_LOG2F
7730 || fcode
== BUILT_IN_LOG2L
))
7731 || (value
== &dconst10
7732 && (fcode
== BUILT_IN_LOG10
7733 || fcode
== BUILT_IN_LOG10F
7734 || fcode
== BUILT_IN_LOG10L
)))
7735 return fold_convert (type
, TREE_VALUE (TREE_OPERAND (arg
, 1)));
7742 /* Fold function call to builtin memcpy. Return
7743 NULL_TREE if no simplification can be made. */
7746 fold_builtin_memcpy (tree fndecl
, tree arglist
)
7748 tree dest
, src
, len
;
7750 if (!validate_arglist (arglist
,
7751 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
7754 dest
= TREE_VALUE (arglist
);
7755 src
= TREE_VALUE (TREE_CHAIN (arglist
));
7756 len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
7758 /* If the LEN parameter is zero, return DEST. */
7759 if (integer_zerop (len
))
7760 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl
)), dest
, src
);
7762 /* If SRC and DEST are the same (and not volatile), return DEST. */
7763 if (operand_equal_p (src
, dest
, 0))
7764 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl
)), dest
, len
);
7769 /* Fold function call to builtin mempcpy. Return
7770 NULL_TREE if no simplification can be made. */
7773 fold_builtin_mempcpy (tree arglist
, tree type
, int endp
)
7775 if (validate_arglist (arglist
,
7776 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
7778 tree dest
= TREE_VALUE (arglist
);
7779 tree src
= TREE_VALUE (TREE_CHAIN (arglist
));
7780 tree len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
7782 /* If the LEN parameter is zero, return DEST. */
7783 if (integer_zerop (len
))
7784 return omit_one_operand (type
, dest
, src
);
7786 /* If SRC and DEST are the same (and not volatile), return DEST+LEN. */
7787 if (operand_equal_p (src
, dest
, 0))
7790 return omit_one_operand (type
, dest
, len
);
7793 len
= fold_build2 (MINUS_EXPR
, TREE_TYPE (len
), len
,
7796 len
= fold_convert (TREE_TYPE (dest
), len
);
7797 len
= fold_build2 (PLUS_EXPR
, TREE_TYPE (dest
), dest
, len
);
7798 return fold_convert (type
, len
);
7804 /* Fold function call to builtin memmove. Return
7805 NULL_TREE if no simplification can be made. */
7808 fold_builtin_memmove (tree arglist
, tree type
)
7810 tree dest
, src
, len
;
7812 if (!validate_arglist (arglist
,
7813 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
7816 dest
= TREE_VALUE (arglist
);
7817 src
= TREE_VALUE (TREE_CHAIN (arglist
));
7818 len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
7820 /* If the LEN parameter is zero, return DEST. */
7821 if (integer_zerop (len
))
7822 return omit_one_operand (type
, dest
, src
);
7824 /* If SRC and DEST are the same (and not volatile), return DEST. */
7825 if (operand_equal_p (src
, dest
, 0))
7826 return omit_one_operand (type
, dest
, len
);
7831 /* Fold function call to builtin strcpy. If LEN is not NULL, it represents
7832 the length of the string to be copied. Return NULL_TREE if no
7833 simplification can be made. */
7836 fold_builtin_strcpy (tree fndecl
, tree arglist
, tree len
)
7840 if (!validate_arglist (arglist
,
7841 POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
7844 dest
= TREE_VALUE (arglist
);
7845 src
= TREE_VALUE (TREE_CHAIN (arglist
));
7847 /* If SRC and DEST are the same (and not volatile), return DEST. */
7848 if (operand_equal_p (src
, dest
, 0))
7849 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl
)), dest
);
7854 fn
= implicit_built_in_decls
[BUILT_IN_MEMCPY
];
7860 len
= c_strlen (src
, 1);
7861 if (! len
|| TREE_SIDE_EFFECTS (len
))
7865 len
= size_binop (PLUS_EXPR
, len
, ssize_int (1));
7866 arglist
= build_tree_list (NULL_TREE
, len
);
7867 arglist
= tree_cons (NULL_TREE
, src
, arglist
);
7868 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
7869 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl
)),
7870 build_function_call_expr (fn
, arglist
));
7873 /* Fold function call to builtin strncpy. If SLEN is not NULL, it represents
7874 the length of the source string. Return NULL_TREE if no simplification
7878 fold_builtin_strncpy (tree fndecl
, tree arglist
, tree slen
)
7880 tree dest
, src
, len
, fn
;
7882 if (!validate_arglist (arglist
,
7883 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
7886 dest
= TREE_VALUE (arglist
);
7887 src
= TREE_VALUE (TREE_CHAIN (arglist
));
7888 len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
7890 /* If the LEN parameter is zero, return DEST. */
7891 if (integer_zerop (len
))
7892 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl
)), dest
, src
);
7894 /* We can't compare slen with len as constants below if len is not a
7896 if (len
== 0 || TREE_CODE (len
) != INTEGER_CST
)
7900 slen
= c_strlen (src
, 1);
7902 /* Now, we must be passed a constant src ptr parameter. */
7903 if (slen
== 0 || TREE_CODE (slen
) != INTEGER_CST
)
7906 slen
= size_binop (PLUS_EXPR
, slen
, ssize_int (1));
7908 /* We do not support simplification of this case, though we do
7909 support it when expanding trees into RTL. */
7910 /* FIXME: generate a call to __builtin_memset. */
7911 if (tree_int_cst_lt (slen
, len
))
7914 /* OK transform into builtin memcpy. */
7915 fn
= implicit_built_in_decls
[BUILT_IN_MEMCPY
];
7918 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl
)),
7919 build_function_call_expr (fn
, arglist
));
7922 /* Fold function call to builtin memcmp. Return
7923 NULL_TREE if no simplification can be made. */
7926 fold_builtin_memcmp (tree arglist
)
7928 tree arg1
, arg2
, len
;
7929 const char *p1
, *p2
;
7931 if (!validate_arglist (arglist
,
7932 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
7935 arg1
= TREE_VALUE (arglist
);
7936 arg2
= TREE_VALUE (TREE_CHAIN (arglist
));
7937 len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
7939 /* If the LEN parameter is zero, return zero. */
7940 if (integer_zerop (len
))
7941 return omit_two_operands (integer_type_node
, integer_zero_node
,
7944 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
7945 if (operand_equal_p (arg1
, arg2
, 0))
7946 return omit_one_operand (integer_type_node
, integer_zero_node
, len
);
7948 p1
= c_getstr (arg1
);
7949 p2
= c_getstr (arg2
);
7951 /* If all arguments are constant, and the value of len is not greater
7952 than the lengths of arg1 and arg2, evaluate at compile-time. */
7953 if (host_integerp (len
, 1) && p1
&& p2
7954 && compare_tree_int (len
, strlen (p1
) + 1) <= 0
7955 && compare_tree_int (len
, strlen (p2
) + 1) <= 0)
7957 const int r
= memcmp (p1
, p2
, tree_low_cst (len
, 1));
7960 return integer_one_node
;
7962 return integer_minus_one_node
;
7964 return integer_zero_node
;
7967 /* If len parameter is one, return an expression corresponding to
7968 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
7969 if (host_integerp (len
, 1) && tree_low_cst (len
, 1) == 1)
7971 tree cst_uchar_node
= build_type_variant (unsigned_char_type_node
, 1, 0);
7972 tree cst_uchar_ptr_node
7973 = build_pointer_type_for_mode (cst_uchar_node
, ptr_mode
, true);
7975 tree ind1
= fold_convert (integer_type_node
,
7976 build1 (INDIRECT_REF
, cst_uchar_node
,
7977 fold_convert (cst_uchar_ptr_node
,
7979 tree ind2
= fold_convert (integer_type_node
,
7980 build1 (INDIRECT_REF
, cst_uchar_node
,
7981 fold_convert (cst_uchar_ptr_node
,
7983 return fold_build2 (MINUS_EXPR
, integer_type_node
, ind1
, ind2
);
7989 /* Fold function call to builtin strcmp. Return
7990 NULL_TREE if no simplification can be made. */
7993 fold_builtin_strcmp (tree arglist
)
7996 const char *p1
, *p2
;
7998 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
8001 arg1
= TREE_VALUE (arglist
);
8002 arg2
= TREE_VALUE (TREE_CHAIN (arglist
));
8004 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
8005 if (operand_equal_p (arg1
, arg2
, 0))
8006 return integer_zero_node
;
8008 p1
= c_getstr (arg1
);
8009 p2
= c_getstr (arg2
);
8013 const int i
= strcmp (p1
, p2
);
8015 return integer_minus_one_node
;
8017 return integer_one_node
;
8019 return integer_zero_node
;
8022 /* If the second arg is "", return *(const unsigned char*)arg1. */
8023 if (p2
&& *p2
== '\0')
8025 tree cst_uchar_node
= build_type_variant (unsigned_char_type_node
, 1, 0);
8026 tree cst_uchar_ptr_node
8027 = build_pointer_type_for_mode (cst_uchar_node
, ptr_mode
, true);
8029 return fold_convert (integer_type_node
,
8030 build1 (INDIRECT_REF
, cst_uchar_node
,
8031 fold_convert (cst_uchar_ptr_node
,
8035 /* If the first arg is "", return -*(const unsigned char*)arg2. */
8036 if (p1
&& *p1
== '\0')
8038 tree cst_uchar_node
= build_type_variant (unsigned_char_type_node
, 1, 0);
8039 tree cst_uchar_ptr_node
8040 = build_pointer_type_for_mode (cst_uchar_node
, ptr_mode
, true);
8042 tree temp
= fold_convert (integer_type_node
,
8043 build1 (INDIRECT_REF
, cst_uchar_node
,
8044 fold_convert (cst_uchar_ptr_node
,
8046 return fold_build1 (NEGATE_EXPR
, integer_type_node
, temp
);
8052 /* Fold function call to builtin strncmp. Return
8053 NULL_TREE if no simplification can be made. */
8056 fold_builtin_strncmp (tree arglist
)
8058 tree arg1
, arg2
, len
;
8059 const char *p1
, *p2
;
8061 if (!validate_arglist (arglist
,
8062 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
8065 arg1
= TREE_VALUE (arglist
);
8066 arg2
= TREE_VALUE (TREE_CHAIN (arglist
));
8067 len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
8069 /* If the LEN parameter is zero, return zero. */
8070 if (integer_zerop (len
))
8071 return omit_two_operands (integer_type_node
, integer_zero_node
,
8074 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
8075 if (operand_equal_p (arg1
, arg2
, 0))
8076 return omit_one_operand (integer_type_node
, integer_zero_node
, len
);
8078 p1
= c_getstr (arg1
);
8079 p2
= c_getstr (arg2
);
8081 if (host_integerp (len
, 1) && p1
&& p2
)
8083 const int i
= strncmp (p1
, p2
, tree_low_cst (len
, 1));
8085 return integer_one_node
;
8087 return integer_minus_one_node
;
8089 return integer_zero_node
;
8092 /* If the second arg is "", and the length is greater than zero,
8093 return *(const unsigned char*)arg1. */
8094 if (p2
&& *p2
== '\0'
8095 && TREE_CODE (len
) == INTEGER_CST
8096 && tree_int_cst_sgn (len
) == 1)
8098 tree cst_uchar_node
= build_type_variant (unsigned_char_type_node
, 1, 0);
8099 tree cst_uchar_ptr_node
8100 = build_pointer_type_for_mode (cst_uchar_node
, ptr_mode
, true);
8102 return fold_convert (integer_type_node
,
8103 build1 (INDIRECT_REF
, cst_uchar_node
,
8104 fold_convert (cst_uchar_ptr_node
,
8108 /* If the first arg is "", and the length is greater than zero,
8109 return -*(const unsigned char*)arg2. */
8110 if (p1
&& *p1
== '\0'
8111 && TREE_CODE (len
) == INTEGER_CST
8112 && tree_int_cst_sgn (len
) == 1)
8114 tree cst_uchar_node
= build_type_variant (unsigned_char_type_node
, 1, 0);
8115 tree cst_uchar_ptr_node
8116 = build_pointer_type_for_mode (cst_uchar_node
, ptr_mode
, true);
8118 tree temp
= fold_convert (integer_type_node
,
8119 build1 (INDIRECT_REF
, cst_uchar_node
,
8120 fold_convert (cst_uchar_ptr_node
,
8122 return fold_build1 (NEGATE_EXPR
, integer_type_node
, temp
);
8125 /* If len parameter is one, return an expression corresponding to
8126 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
8127 if (host_integerp (len
, 1) && tree_low_cst (len
, 1) == 1)
8129 tree cst_uchar_node
= build_type_variant (unsigned_char_type_node
, 1, 0);
8130 tree cst_uchar_ptr_node
8131 = build_pointer_type_for_mode (cst_uchar_node
, ptr_mode
, true);
8133 tree ind1
= fold_convert (integer_type_node
,
8134 build1 (INDIRECT_REF
, cst_uchar_node
,
8135 fold_convert (cst_uchar_ptr_node
,
8137 tree ind2
= fold_convert (integer_type_node
,
8138 build1 (INDIRECT_REF
, cst_uchar_node
,
8139 fold_convert (cst_uchar_ptr_node
,
8141 return fold_build2 (MINUS_EXPR
, integer_type_node
, ind1
, ind2
);
8147 /* Fold function call to builtin signbit, signbitf or signbitl. Return
8148 NULL_TREE if no simplification can be made. */
8151 fold_builtin_signbit (tree fndecl
, tree arglist
)
8153 tree type
= TREE_TYPE (TREE_TYPE (fndecl
));
8156 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
8159 arg
= TREE_VALUE (arglist
);
8161 /* If ARG is a compile-time constant, determine the result. */
8162 if (TREE_CODE (arg
) == REAL_CST
8163 && !TREE_CONSTANT_OVERFLOW (arg
))
8167 c
= TREE_REAL_CST (arg
);
8168 temp
= REAL_VALUE_NEGATIVE (c
) ? integer_one_node
: integer_zero_node
;
8169 return fold_convert (type
, temp
);
8172 /* If ARG is non-negative, the result is always zero. */
8173 if (tree_expr_nonnegative_p (arg
))
8174 return omit_one_operand (type
, integer_zero_node
, arg
);
8176 /* If ARG's format doesn't have signed zeros, return "arg < 0.0". */
8177 if (!HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg
))))
8178 return fold_build2 (LT_EXPR
, type
, arg
,
8179 build_real (TREE_TYPE (arg
), dconst0
));
8184 /* Fold function call to builtin copysign, copysignf or copysignl.
8185 Return NULL_TREE if no simplification can be made. */
8188 fold_builtin_copysign (tree fndecl
, tree arglist
, tree type
)
8190 tree arg1
, arg2
, tem
;
8192 if (!validate_arglist (arglist
, REAL_TYPE
, REAL_TYPE
, VOID_TYPE
))
8195 arg1
= TREE_VALUE (arglist
);
8196 arg2
= TREE_VALUE (TREE_CHAIN (arglist
));
8198 /* copysign(X,X) is X. */
8199 if (operand_equal_p (arg1
, arg2
, 0))
8200 return fold_convert (type
, arg1
);
8202 /* If ARG1 and ARG2 are compile-time constants, determine the result. */
8203 if (TREE_CODE (arg1
) == REAL_CST
8204 && TREE_CODE (arg2
) == REAL_CST
8205 && !TREE_CONSTANT_OVERFLOW (arg1
)
8206 && !TREE_CONSTANT_OVERFLOW (arg2
))
8208 REAL_VALUE_TYPE c1
, c2
;
8210 c1
= TREE_REAL_CST (arg1
);
8211 c2
= TREE_REAL_CST (arg2
);
8212 real_copysign (&c1
, &c2
);
8213 return build_real (type
, c1
);
8217 /* copysign(X, Y) is fabs(X) when Y is always non-negative.
8218 Remember to evaluate Y for side-effects. */
8219 if (tree_expr_nonnegative_p (arg2
))
8220 return omit_one_operand (type
,
8221 fold_build1 (ABS_EXPR
, type
, arg1
),
8224 /* Strip sign changing operations for the first argument. */
8225 tem
= fold_strip_sign_ops (arg1
);
8228 arglist
= tree_cons (NULL_TREE
, tem
, TREE_CHAIN (arglist
));
8229 return build_function_call_expr (fndecl
, arglist
);
8235 /* Fold a call to builtin isascii. */
8238 fold_builtin_isascii (tree arglist
)
8240 if (! validate_arglist (arglist
, INTEGER_TYPE
, VOID_TYPE
))
8244 /* Transform isascii(c) -> ((c & ~0x7f) == 0). */
8245 tree arg
= TREE_VALUE (arglist
);
8247 arg
= build2 (BIT_AND_EXPR
, integer_type_node
, arg
,
8248 build_int_cst (NULL_TREE
,
8249 ~ (unsigned HOST_WIDE_INT
) 0x7f));
8250 arg
= fold_build2 (EQ_EXPR
, integer_type_node
,
8251 arg
, integer_zero_node
);
8253 if (in_gimple_form
&& !TREE_CONSTANT (arg
))
8260 /* Fold a call to builtin toascii. */
8263 fold_builtin_toascii (tree arglist
)
8265 if (! validate_arglist (arglist
, INTEGER_TYPE
, VOID_TYPE
))
8269 /* Transform toascii(c) -> (c & 0x7f). */
8270 tree arg
= TREE_VALUE (arglist
);
8272 return fold_build2 (BIT_AND_EXPR
, integer_type_node
, arg
,
8273 build_int_cst (NULL_TREE
, 0x7f));
8277 /* Fold a call to builtin isdigit. */
8280 fold_builtin_isdigit (tree arglist
)
8282 if (! validate_arglist (arglist
, INTEGER_TYPE
, VOID_TYPE
))
8286 /* Transform isdigit(c) -> (unsigned)(c) - '0' <= 9. */
8287 /* According to the C standard, isdigit is unaffected by locale.
8288 However, it definitely is affected by the target character set. */
8290 unsigned HOST_WIDE_INT target_digit0
8291 = lang_hooks
.to_target_charset ('0');
8293 if (target_digit0
== 0)
8296 arg
= fold_convert (unsigned_type_node
, TREE_VALUE (arglist
));
8297 arg
= build2 (MINUS_EXPR
, unsigned_type_node
, arg
,
8298 build_int_cst (unsigned_type_node
, target_digit0
));
8299 arg
= fold_build2 (LE_EXPR
, integer_type_node
, arg
,
8300 build_int_cst (unsigned_type_node
, 9));
8301 if (in_gimple_form
&& !TREE_CONSTANT (arg
))
8308 /* Fold a call to fabs, fabsf or fabsl. */
8311 fold_builtin_fabs (tree arglist
, tree type
)
8315 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
8318 arg
= TREE_VALUE (arglist
);
8319 arg
= fold_convert (type
, arg
);
8320 if (TREE_CODE (arg
) == REAL_CST
)
8321 return fold_abs_const (arg
, type
);
8322 return fold_build1 (ABS_EXPR
, type
, arg
);
8325 /* Fold a call to abs, labs, llabs or imaxabs. */
8328 fold_builtin_abs (tree arglist
, tree type
)
8332 if (!validate_arglist (arglist
, INTEGER_TYPE
, VOID_TYPE
))
8335 arg
= TREE_VALUE (arglist
);
8336 arg
= fold_convert (type
, arg
);
8337 if (TREE_CODE (arg
) == INTEGER_CST
)
8338 return fold_abs_const (arg
, type
);
8339 return fold_build1 (ABS_EXPR
, type
, arg
);
8342 /* Fold a call to __builtin_isnan(), __builtin_isinf, __builtin_finite.
8343 EXP is the CALL_EXPR for the call. */
8346 fold_builtin_classify (tree fndecl
, tree arglist
, int builtin_index
)
8348 tree type
= TREE_TYPE (TREE_TYPE (fndecl
));
8352 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
8354 /* Check that we have exactly one argument. */
8357 error ("too few arguments to function %qs",
8358 IDENTIFIER_POINTER (DECL_NAME (fndecl
)));
8359 return error_mark_node
;
8361 else if (TREE_CHAIN (arglist
) != 0)
8363 error ("too many arguments to function %qs",
8364 IDENTIFIER_POINTER (DECL_NAME (fndecl
)));
8365 return error_mark_node
;
8369 error ("non-floating-point argument to function %qs",
8370 IDENTIFIER_POINTER (DECL_NAME (fndecl
)));
8371 return error_mark_node
;
8375 arg
= TREE_VALUE (arglist
);
8376 switch (builtin_index
)
8378 case BUILT_IN_ISINF
:
8379 if (!MODE_HAS_INFINITIES (TYPE_MODE (TREE_TYPE (arg
))))
8380 return omit_one_operand (type
, integer_zero_node
, arg
);
8382 if (TREE_CODE (arg
) == REAL_CST
)
8384 r
= TREE_REAL_CST (arg
);
8385 if (real_isinf (&r
))
8386 return real_compare (GT_EXPR
, &r
, &dconst0
)
8387 ? integer_one_node
: integer_minus_one_node
;
8389 return integer_zero_node
;
8394 case BUILT_IN_FINITE
:
8395 if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg
)))
8396 && !MODE_HAS_INFINITIES (TYPE_MODE (TREE_TYPE (arg
))))
8397 return omit_one_operand (type
, integer_zero_node
, arg
);
8399 if (TREE_CODE (arg
) == REAL_CST
)
8401 r
= TREE_REAL_CST (arg
);
8402 return real_isinf (&r
) || real_isnan (&r
)
8403 ? integer_zero_node
: integer_one_node
;
8408 case BUILT_IN_ISNAN
:
8409 if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg
))))
8410 return omit_one_operand (type
, integer_zero_node
, arg
);
8412 if (TREE_CODE (arg
) == REAL_CST
)
8414 r
= TREE_REAL_CST (arg
);
8415 return real_isnan (&r
) ? integer_one_node
: integer_zero_node
;
8418 arg
= builtin_save_expr (arg
);
8419 return fold_build2 (UNORDERED_EXPR
, type
, arg
, arg
);
8426 /* Fold a call to an unordered comparison function such as
8427 __builtin_isgreater(). FNDECL is the FUNCTION_DECL for the function
8428 being called and ARGLIST is the argument list for the call.
8429 UNORDERED_CODE and ORDERED_CODE are comparison codes that give
8430 the opposite of the desired result. UNORDERED_CODE is used
8431 for modes that can hold NaNs and ORDERED_CODE is used for
8435 fold_builtin_unordered_cmp (tree fndecl
, tree arglist
,
8436 enum tree_code unordered_code
,
8437 enum tree_code ordered_code
)
8439 tree type
= TREE_TYPE (TREE_TYPE (fndecl
));
8440 enum tree_code code
;
8443 enum tree_code code0
, code1
;
8444 tree cmp_type
= NULL_TREE
;
8446 if (!validate_arglist (arglist
, REAL_TYPE
, REAL_TYPE
, VOID_TYPE
))
8448 /* Check that we have exactly two arguments. */
8449 if (arglist
== 0 || TREE_CHAIN (arglist
) == 0)
8451 error ("too few arguments to function %qs",
8452 IDENTIFIER_POINTER (DECL_NAME (fndecl
)));
8453 return error_mark_node
;
8455 else if (TREE_CHAIN (TREE_CHAIN (arglist
)) != 0)
8457 error ("too many arguments to function %qs",
8458 IDENTIFIER_POINTER (DECL_NAME (fndecl
)));
8459 return error_mark_node
;
8463 arg0
= TREE_VALUE (arglist
);
8464 arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
8466 type0
= TREE_TYPE (arg0
);
8467 type1
= TREE_TYPE (arg1
);
8469 code0
= TREE_CODE (type0
);
8470 code1
= TREE_CODE (type1
);
8472 if (code0
== REAL_TYPE
&& code1
== REAL_TYPE
)
8473 /* Choose the wider of two real types. */
8474 cmp_type
= TYPE_PRECISION (type0
) >= TYPE_PRECISION (type1
)
8476 else if (code0
== REAL_TYPE
&& code1
== INTEGER_TYPE
)
8478 else if (code0
== INTEGER_TYPE
&& code1
== REAL_TYPE
)
8482 error ("non-floating-point argument to function %qs",
8483 IDENTIFIER_POINTER (DECL_NAME (fndecl
)));
8484 return error_mark_node
;
8487 arg0
= fold_convert (cmp_type
, arg0
);
8488 arg1
= fold_convert (cmp_type
, arg1
);
8490 if (unordered_code
== UNORDERED_EXPR
)
8492 if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg0
))))
8493 return omit_two_operands (type
, integer_zero_node
, arg0
, arg1
);
8494 return fold_build2 (UNORDERED_EXPR
, type
, arg0
, arg1
);
8497 code
= MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg0
))) ? unordered_code
8499 return fold_build1 (TRUTH_NOT_EXPR
, type
,
8500 fold_build2 (code
, type
, arg0
, arg1
));
8503 /* Used by constant folding to simplify calls to builtin functions. EXP is
8504 the CALL_EXPR of a call to a builtin function. IGNORE is true if the
8505 result of the function call is ignored. This function returns NULL_TREE
8506 if no simplification was possible. */
8509 fold_builtin_1 (tree fndecl
, tree arglist
, bool ignore
)
8511 tree type
= TREE_TYPE (TREE_TYPE (fndecl
));
8512 enum built_in_function fcode
;
8514 if (DECL_BUILT_IN_CLASS (fndecl
) == BUILT_IN_MD
)
8515 return targetm
.fold_builtin (fndecl
, arglist
, ignore
);
8517 fcode
= DECL_FUNCTION_CODE (fndecl
);
8520 case BUILT_IN_FPUTS
:
8521 return fold_builtin_fputs (arglist
, ignore
, false, NULL_TREE
);
8523 case BUILT_IN_FPUTS_UNLOCKED
:
8524 return fold_builtin_fputs (arglist
, ignore
, true, NULL_TREE
);
8526 case BUILT_IN_STRSTR
:
8527 return fold_builtin_strstr (arglist
, type
);
8529 case BUILT_IN_STRCAT
:
8530 return fold_builtin_strcat (arglist
);
8532 case BUILT_IN_STRNCAT
:
8533 return fold_builtin_strncat (arglist
);
8535 case BUILT_IN_STRSPN
:
8536 return fold_builtin_strspn (arglist
);
8538 case BUILT_IN_STRCSPN
:
8539 return fold_builtin_strcspn (arglist
);
8541 case BUILT_IN_STRCHR
:
8542 case BUILT_IN_INDEX
:
8543 return fold_builtin_strchr (arglist
, type
);
8545 case BUILT_IN_STRRCHR
:
8546 case BUILT_IN_RINDEX
:
8547 return fold_builtin_strrchr (arglist
, type
);
8549 case BUILT_IN_STRCPY
:
8550 return fold_builtin_strcpy (fndecl
, arglist
, NULL_TREE
);
8552 case BUILT_IN_STRNCPY
:
8553 return fold_builtin_strncpy (fndecl
, arglist
, NULL_TREE
);
8555 case BUILT_IN_STRCMP
:
8556 return fold_builtin_strcmp (arglist
);
8558 case BUILT_IN_STRNCMP
:
8559 return fold_builtin_strncmp (arglist
);
8561 case BUILT_IN_STRPBRK
:
8562 return fold_builtin_strpbrk (arglist
, type
);
8565 case BUILT_IN_MEMCMP
:
8566 return fold_builtin_memcmp (arglist
);
8568 case BUILT_IN_SPRINTF
:
8569 return fold_builtin_sprintf (arglist
, ignore
);
8571 case BUILT_IN_CONSTANT_P
:
8575 val
= fold_builtin_constant_p (arglist
);
8576 /* Gimplification will pull the CALL_EXPR for the builtin out of
8577 an if condition. When not optimizing, we'll not CSE it back.
8578 To avoid link error types of regressions, return false now. */
8579 if (!val
&& !optimize
)
8580 val
= integer_zero_node
;
8585 case BUILT_IN_EXPECT
:
8586 return fold_builtin_expect (arglist
);
8588 case BUILT_IN_CLASSIFY_TYPE
:
8589 return fold_builtin_classify_type (arglist
);
8591 case BUILT_IN_STRLEN
:
8592 return fold_builtin_strlen (arglist
);
8594 CASE_FLT_FN (BUILT_IN_FABS
):
8595 return fold_builtin_fabs (arglist
, type
);
8599 case BUILT_IN_LLABS
:
8600 case BUILT_IN_IMAXABS
:
8601 return fold_builtin_abs (arglist
, type
);
8603 CASE_FLT_FN (BUILT_IN_CONJ
):
8604 if (validate_arglist (arglist
, COMPLEX_TYPE
, VOID_TYPE
))
8605 return fold_build1 (CONJ_EXPR
, type
, TREE_VALUE (arglist
));
8608 CASE_FLT_FN (BUILT_IN_CREAL
):
8609 if (validate_arglist (arglist
, COMPLEX_TYPE
, VOID_TYPE
))
8610 return non_lvalue (fold_build1 (REALPART_EXPR
, type
,
8611 TREE_VALUE (arglist
)));
8614 CASE_FLT_FN (BUILT_IN_CIMAG
):
8615 if (validate_arglist (arglist
, COMPLEX_TYPE
, VOID_TYPE
))
8616 return non_lvalue (fold_build1 (IMAGPART_EXPR
, type
,
8617 TREE_VALUE (arglist
)));
8620 CASE_FLT_FN (BUILT_IN_CABS
):
8621 return fold_builtin_cabs (arglist
, type
);
8623 CASE_FLT_FN (BUILT_IN_SQRT
):
8624 return fold_builtin_sqrt (arglist
, type
);
8626 CASE_FLT_FN (BUILT_IN_CBRT
):
8627 return fold_builtin_cbrt (arglist
, type
);
8629 CASE_FLT_FN (BUILT_IN_SIN
):
8630 return fold_builtin_sin (arglist
);
8632 CASE_FLT_FN (BUILT_IN_COS
):
8633 return fold_builtin_cos (arglist
, type
, fndecl
);
8635 CASE_FLT_FN (BUILT_IN_EXP
):
8636 return fold_builtin_exponent (fndecl
, arglist
, &dconste
);
8638 CASE_FLT_FN (BUILT_IN_EXP2
):
8639 return fold_builtin_exponent (fndecl
, arglist
, &dconst2
);
8641 CASE_FLT_FN (BUILT_IN_EXP10
):
8642 CASE_FLT_FN (BUILT_IN_POW10
):
8643 return fold_builtin_exponent (fndecl
, arglist
, &dconst10
);
8645 CASE_FLT_FN (BUILT_IN_LOG
):
8646 return fold_builtin_logarithm (fndecl
, arglist
, &dconste
);
8648 CASE_FLT_FN (BUILT_IN_LOG2
):
8649 return fold_builtin_logarithm (fndecl
, arglist
, &dconst2
);
8651 CASE_FLT_FN (BUILT_IN_LOG10
):
8652 return fold_builtin_logarithm (fndecl
, arglist
, &dconst10
);
8654 CASE_FLT_FN (BUILT_IN_TAN
):
8655 return fold_builtin_tan (arglist
);
8657 CASE_FLT_FN (BUILT_IN_ATAN
):
8658 return fold_builtin_atan (arglist
, type
);
8660 CASE_FLT_FN (BUILT_IN_POW
):
8661 return fold_builtin_pow (fndecl
, arglist
, type
);
8663 CASE_FLT_FN (BUILT_IN_POWI
):
8664 return fold_builtin_powi (fndecl
, arglist
, type
);
8666 CASE_FLT_FN (BUILT_IN_INF
):
8667 case BUILT_IN_INFD32
:
8668 case BUILT_IN_INFD64
:
8669 case BUILT_IN_INFD128
:
8670 return fold_builtin_inf (type
, true);
8672 CASE_FLT_FN (BUILT_IN_HUGE_VAL
):
8673 return fold_builtin_inf (type
, false);
8675 CASE_FLT_FN (BUILT_IN_NAN
):
8676 case BUILT_IN_NAND32
:
8677 case BUILT_IN_NAND64
:
8678 case BUILT_IN_NAND128
:
8679 return fold_builtin_nan (arglist
, type
, true);
8681 CASE_FLT_FN (BUILT_IN_NANS
):
8682 return fold_builtin_nan (arglist
, type
, false);
8684 CASE_FLT_FN (BUILT_IN_FLOOR
):
8685 return fold_builtin_floor (fndecl
, arglist
);
8687 CASE_FLT_FN (BUILT_IN_CEIL
):
8688 return fold_builtin_ceil (fndecl
, arglist
);
8690 CASE_FLT_FN (BUILT_IN_TRUNC
):
8691 return fold_builtin_trunc (fndecl
, arglist
);
8693 CASE_FLT_FN (BUILT_IN_ROUND
):
8694 return fold_builtin_round (fndecl
, arglist
);
8696 CASE_FLT_FN (BUILT_IN_NEARBYINT
):
8697 CASE_FLT_FN (BUILT_IN_RINT
):
8698 return fold_trunc_transparent_mathfn (fndecl
, arglist
);
8700 CASE_FLT_FN (BUILT_IN_LCEIL
):
8701 CASE_FLT_FN (BUILT_IN_LLCEIL
):
8702 CASE_FLT_FN (BUILT_IN_LFLOOR
):
8703 CASE_FLT_FN (BUILT_IN_LLFLOOR
):
8704 CASE_FLT_FN (BUILT_IN_LROUND
):
8705 CASE_FLT_FN (BUILT_IN_LLROUND
):
8706 return fold_builtin_int_roundingfn (fndecl
, arglist
);
8708 CASE_FLT_FN (BUILT_IN_LRINT
):
8709 CASE_FLT_FN (BUILT_IN_LLRINT
):
8710 return fold_fixed_mathfn (fndecl
, arglist
);
8712 CASE_INT_FN (BUILT_IN_FFS
):
8713 CASE_INT_FN (BUILT_IN_CLZ
):
8714 CASE_INT_FN (BUILT_IN_CTZ
):
8715 CASE_INT_FN (BUILT_IN_POPCOUNT
):
8716 CASE_INT_FN (BUILT_IN_PARITY
):
8717 return fold_builtin_bitop (fndecl
, arglist
);
8719 case BUILT_IN_MEMCPY
:
8720 return fold_builtin_memcpy (fndecl
, arglist
);
8722 case BUILT_IN_MEMPCPY
:
8723 return fold_builtin_mempcpy (arglist
, type
, /*endp=*/1);
8725 case BUILT_IN_MEMMOVE
:
8726 return fold_builtin_memmove (arglist
, type
);
8728 CASE_FLT_FN (BUILT_IN_SIGNBIT
):
8729 return fold_builtin_signbit (fndecl
, arglist
);
8731 case BUILT_IN_ISASCII
:
8732 return fold_builtin_isascii (arglist
);
8734 case BUILT_IN_TOASCII
:
8735 return fold_builtin_toascii (arglist
);
8737 case BUILT_IN_ISDIGIT
:
8738 return fold_builtin_isdigit (arglist
);
8740 CASE_FLT_FN (BUILT_IN_COPYSIGN
):
8741 return fold_builtin_copysign (fndecl
, arglist
, type
);
8743 CASE_FLT_FN (BUILT_IN_FINITE
):
8744 case BUILT_IN_FINITED32
:
8745 case BUILT_IN_FINITED64
:
8746 case BUILT_IN_FINITED128
:
8747 return fold_builtin_classify (fndecl
, arglist
, BUILT_IN_FINITE
);
8749 CASE_FLT_FN (BUILT_IN_ISINF
):
8750 case BUILT_IN_ISINFD32
:
8751 case BUILT_IN_ISINFD64
:
8752 case BUILT_IN_ISINFD128
:
8753 return fold_builtin_classify (fndecl
, arglist
, BUILT_IN_ISINF
);
8755 CASE_FLT_FN (BUILT_IN_ISNAN
):
8756 case BUILT_IN_ISNAND32
:
8757 case BUILT_IN_ISNAND64
:
8758 case BUILT_IN_ISNAND128
:
8759 return fold_builtin_classify (fndecl
, arglist
, BUILT_IN_ISNAN
);
8761 case BUILT_IN_ISGREATER
:
8762 return fold_builtin_unordered_cmp (fndecl
, arglist
, UNLE_EXPR
, LE_EXPR
);
8763 case BUILT_IN_ISGREATEREQUAL
:
8764 return fold_builtin_unordered_cmp (fndecl
, arglist
, UNLT_EXPR
, LT_EXPR
);
8765 case BUILT_IN_ISLESS
:
8766 return fold_builtin_unordered_cmp (fndecl
, arglist
, UNGE_EXPR
, GE_EXPR
);
8767 case BUILT_IN_ISLESSEQUAL
:
8768 return fold_builtin_unordered_cmp (fndecl
, arglist
, UNGT_EXPR
, GT_EXPR
);
8769 case BUILT_IN_ISLESSGREATER
:
8770 return fold_builtin_unordered_cmp (fndecl
, arglist
, UNEQ_EXPR
, EQ_EXPR
);
8771 case BUILT_IN_ISUNORDERED
:
8772 return fold_builtin_unordered_cmp (fndecl
, arglist
, UNORDERED_EXPR
,
8775 /* We do the folding for va_start in the expander. */
8776 case BUILT_IN_VA_START
:
8779 case BUILT_IN_OBJECT_SIZE
:
8780 return fold_builtin_object_size (arglist
);
8781 case BUILT_IN_MEMCPY_CHK
:
8782 case BUILT_IN_MEMPCPY_CHK
:
8783 case BUILT_IN_MEMMOVE_CHK
:
8784 case BUILT_IN_MEMSET_CHK
:
8785 return fold_builtin_memory_chk (fndecl
, arglist
, NULL_TREE
, ignore
,
8786 DECL_FUNCTION_CODE (fndecl
));
8787 case BUILT_IN_STRCPY_CHK
:
8788 case BUILT_IN_STPCPY_CHK
:
8789 return fold_builtin_stxcpy_chk (fndecl
, arglist
, NULL_TREE
, ignore
,
8790 DECL_FUNCTION_CODE (fndecl
));
8791 case BUILT_IN_STRNCPY_CHK
:
8792 return fold_builtin_strncpy_chk (arglist
, NULL_TREE
);
8793 case BUILT_IN_STRCAT_CHK
:
8794 return fold_builtin_strcat_chk (fndecl
, arglist
);
8795 case BUILT_IN_STRNCAT_CHK
:
8796 return fold_builtin_strncat_chk (fndecl
, arglist
);
8797 case BUILT_IN_SPRINTF_CHK
:
8798 case BUILT_IN_VSPRINTF_CHK
:
8799 return fold_builtin_sprintf_chk (arglist
, DECL_FUNCTION_CODE (fndecl
));
8800 case BUILT_IN_SNPRINTF_CHK
:
8801 case BUILT_IN_VSNPRINTF_CHK
:
8802 return fold_builtin_snprintf_chk (arglist
, NULL_TREE
,
8803 DECL_FUNCTION_CODE (fndecl
));
8805 case BUILT_IN_PRINTF
:
8806 case BUILT_IN_PRINTF_UNLOCKED
:
8807 case BUILT_IN_VPRINTF
:
8808 case BUILT_IN_PRINTF_CHK
:
8809 case BUILT_IN_VPRINTF_CHK
:
8810 return fold_builtin_printf (fndecl
, arglist
, ignore
,
8811 DECL_FUNCTION_CODE (fndecl
));
8813 case BUILT_IN_FPRINTF
:
8814 case BUILT_IN_FPRINTF_UNLOCKED
:
8815 case BUILT_IN_VFPRINTF
:
8816 case BUILT_IN_FPRINTF_CHK
:
8817 case BUILT_IN_VFPRINTF_CHK
:
8818 return fold_builtin_fprintf (fndecl
, arglist
, ignore
,
8819 DECL_FUNCTION_CODE (fndecl
));
8828 /* A wrapper function for builtin folding that prevents warnings for
8829 "statement without effect" and the like, caused by removing the
8830 call node earlier than the warning is generated. */
8833 fold_builtin (tree fndecl
, tree arglist
, bool ignore
)
8835 tree exp
= fold_builtin_1 (fndecl
, arglist
, ignore
);
8838 exp
= build1 (NOP_EXPR
, TREE_TYPE (exp
), exp
);
8839 TREE_NO_WARNING (exp
) = 1;
8845 /* Conveniently construct a function call expression. */
8848 build_function_call_expr (tree fn
, tree arglist
)
8852 call_expr
= build1 (ADDR_EXPR
, build_pointer_type (TREE_TYPE (fn
)), fn
);
8853 return fold_build3 (CALL_EXPR
, TREE_TYPE (TREE_TYPE (fn
)),
8854 call_expr
, arglist
, NULL_TREE
);
8857 /* This function validates the types of a function call argument list
8858 represented as a tree chain of parameters against a specified list
8859 of tree_codes. If the last specifier is a 0, that represents an
8860 ellipses, otherwise the last specifier must be a VOID_TYPE. */
8863 validate_arglist (tree arglist
, ...)
8865 enum tree_code code
;
8869 va_start (ap
, arglist
);
8873 code
= va_arg (ap
, enum tree_code
);
8877 /* This signifies an ellipses, any further arguments are all ok. */
8881 /* This signifies an endlink, if no arguments remain, return
8882 true, otherwise return false. */
8886 /* If no parameters remain or the parameter's code does not
8887 match the specified code, return false. Otherwise continue
8888 checking any remaining arguments. */
8891 if (code
== POINTER_TYPE
)
8893 if (! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist
))))
8896 else if (code
!= TREE_CODE (TREE_TYPE (TREE_VALUE (arglist
))))
8900 arglist
= TREE_CHAIN (arglist
);
8904 /* We need gotos here since we can only have one VA_CLOSE in a
8912 /* Default target-specific builtin expander that does nothing. */
8915 default_expand_builtin (tree exp ATTRIBUTE_UNUSED
,
8916 rtx target ATTRIBUTE_UNUSED
,
8917 rtx subtarget ATTRIBUTE_UNUSED
,
8918 enum machine_mode mode ATTRIBUTE_UNUSED
,
8919 int ignore ATTRIBUTE_UNUSED
)
8924 /* Default target-specific library builtin expander that does nothing. */
8927 default_expand_library_builtin (tree exp ATTRIBUTE_UNUSED
,
8928 rtx target ATTRIBUTE_UNUSED
,
8929 rtx subtarget ATTRIBUTE_UNUSED
,
8930 enum machine_mode mode ATTRIBUTE_UNUSED
,
8931 int ignore ATTRIBUTE_UNUSED
)
8936 /* Returns true is EXP represents data that would potentially reside
8937 in a readonly section. */
8940 readonly_data_expr (tree exp
)
8944 if (TREE_CODE (exp
) != ADDR_EXPR
)
8947 exp
= get_base_address (TREE_OPERAND (exp
, 0));
8951 /* Make sure we call decl_readonly_section only for trees it
8952 can handle (since it returns true for everything it doesn't
8954 if (TREE_CODE (exp
) == STRING_CST
8955 || TREE_CODE (exp
) == CONSTRUCTOR
8956 || (TREE_CODE (exp
) == VAR_DECL
&& TREE_STATIC (exp
)))
8957 return decl_readonly_section (exp
, 0);
8962 /* Simplify a call to the strstr builtin.
8964 Return 0 if no simplification was possible, otherwise return the
8965 simplified form of the call as a tree.
8967 The simplified form may be a constant or other expression which
8968 computes the same value, but in a more efficient manner (including
8969 calls to other builtin functions).
8971 The call may contain arguments which need to be evaluated, but
8972 which are not useful to determine the result of the call. In
8973 this case we return a chain of COMPOUND_EXPRs. The LHS of each
8974 COMPOUND_EXPR will be an argument which must be evaluated.
8975 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
8976 COMPOUND_EXPR in the chain will contain the tree for the simplified
8977 form of the builtin function call. */
8980 fold_builtin_strstr (tree arglist
, tree type
)
8982 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
8986 tree s1
= TREE_VALUE (arglist
), s2
= TREE_VALUE (TREE_CHAIN (arglist
));
8988 const char *p1
, *p2
;
8997 const char *r
= strstr (p1
, p2
);
9001 return build_int_cst (TREE_TYPE (s1
), 0);
9003 /* Return an offset into the constant string argument. */
9004 tem
= fold_build2 (PLUS_EXPR
, TREE_TYPE (s1
),
9005 s1
, build_int_cst (TREE_TYPE (s1
), r
- p1
));
9006 return fold_convert (type
, tem
);
9009 /* The argument is const char *, and the result is char *, so we need
9010 a type conversion here to avoid a warning. */
9012 return fold_convert (type
, s1
);
9017 fn
= implicit_built_in_decls
[BUILT_IN_STRCHR
];
9021 /* New argument list transforming strstr(s1, s2) to
9022 strchr(s1, s2[0]). */
9023 arglist
= build_tree_list (NULL_TREE
,
9024 build_int_cst (NULL_TREE
, p2
[0]));
9025 arglist
= tree_cons (NULL_TREE
, s1
, arglist
);
9026 return build_function_call_expr (fn
, arglist
);
9030 /* Simplify a call to the strchr builtin.
9032 Return 0 if no simplification was possible, otherwise return the
9033 simplified form of the call as a tree.
9035 The simplified form may be a constant or other expression which
9036 computes the same value, but in a more efficient manner (including
9037 calls to other builtin functions).
9039 The call may contain arguments which need to be evaluated, but
9040 which are not useful to determine the result of the call. In
9041 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9042 COMPOUND_EXPR will be an argument which must be evaluated.
9043 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9044 COMPOUND_EXPR in the chain will contain the tree for the simplified
9045 form of the builtin function call. */
9048 fold_builtin_strchr (tree arglist
, tree type
)
9050 if (!validate_arglist (arglist
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
9054 tree s1
= TREE_VALUE (arglist
), s2
= TREE_VALUE (TREE_CHAIN (arglist
));
9057 if (TREE_CODE (s2
) != INTEGER_CST
)
9067 if (target_char_cast (s2
, &c
))
9073 return build_int_cst (TREE_TYPE (s1
), 0);
9075 /* Return an offset into the constant string argument. */
9076 tem
= fold_build2 (PLUS_EXPR
, TREE_TYPE (s1
),
9077 s1
, build_int_cst (TREE_TYPE (s1
), r
- p1
));
9078 return fold_convert (type
, tem
);
9084 /* Simplify a call to the strrchr builtin.
9086 Return 0 if no simplification was possible, otherwise return the
9087 simplified form of the call as a tree.
9089 The simplified form may be a constant or other expression which
9090 computes the same value, but in a more efficient manner (including
9091 calls to other builtin functions).
9093 The call may contain arguments which need to be evaluated, but
9094 which are not useful to determine the result of the call. In
9095 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9096 COMPOUND_EXPR will be an argument which must be evaluated.
9097 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9098 COMPOUND_EXPR in the chain will contain the tree for the simplified
9099 form of the builtin function call. */
9102 fold_builtin_strrchr (tree arglist
, tree type
)
9104 if (!validate_arglist (arglist
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
9108 tree s1
= TREE_VALUE (arglist
), s2
= TREE_VALUE (TREE_CHAIN (arglist
));
9112 if (TREE_CODE (s2
) != INTEGER_CST
)
9122 if (target_char_cast (s2
, &c
))
9125 r
= strrchr (p1
, c
);
9128 return build_int_cst (TREE_TYPE (s1
), 0);
9130 /* Return an offset into the constant string argument. */
9131 tem
= fold_build2 (PLUS_EXPR
, TREE_TYPE (s1
),
9132 s1
, build_int_cst (TREE_TYPE (s1
), r
- p1
));
9133 return fold_convert (type
, tem
);
9136 if (! integer_zerop (s2
))
9139 fn
= implicit_built_in_decls
[BUILT_IN_STRCHR
];
9143 /* Transform strrchr(s1, '\0') to strchr(s1, '\0'). */
9144 return build_function_call_expr (fn
, arglist
);
9148 /* Simplify a call to the strpbrk builtin.
9150 Return 0 if no simplification was possible, otherwise return the
9151 simplified form of the call as a tree.
9153 The simplified form may be a constant or other expression which
9154 computes the same value, but in a more efficient manner (including
9155 calls to other builtin functions).
9157 The call may contain arguments which need to be evaluated, but
9158 which are not useful to determine the result of the call. In
9159 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9160 COMPOUND_EXPR will be an argument which must be evaluated.
9161 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9162 COMPOUND_EXPR in the chain will contain the tree for the simplified
9163 form of the builtin function call. */
9166 fold_builtin_strpbrk (tree arglist
, tree type
)
9168 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
9172 tree s1
= TREE_VALUE (arglist
), s2
= TREE_VALUE (TREE_CHAIN (arglist
));
9174 const char *p1
, *p2
;
9183 const char *r
= strpbrk (p1
, p2
);
9187 return build_int_cst (TREE_TYPE (s1
), 0);
9189 /* Return an offset into the constant string argument. */
9190 tem
= fold_build2 (PLUS_EXPR
, TREE_TYPE (s1
),
9191 s1
, build_int_cst (TREE_TYPE (s1
), r
- p1
));
9192 return fold_convert (type
, tem
);
9196 /* strpbrk(x, "") == NULL.
9197 Evaluate and ignore s1 in case it had side-effects. */
9198 return omit_one_operand (TREE_TYPE (s1
), integer_zero_node
, s1
);
9201 return 0; /* Really call strpbrk. */
9203 fn
= implicit_built_in_decls
[BUILT_IN_STRCHR
];
9207 /* New argument list transforming strpbrk(s1, s2) to
9208 strchr(s1, s2[0]). */
9209 arglist
= build_tree_list (NULL_TREE
,
9210 build_int_cst (NULL_TREE
, p2
[0]));
9211 arglist
= tree_cons (NULL_TREE
, s1
, arglist
);
9212 return build_function_call_expr (fn
, arglist
);
9216 /* Simplify a call to the strcat builtin.
9218 Return 0 if no simplification was possible, otherwise return the
9219 simplified form of the call as a tree.
9221 The simplified form may be a constant or other expression which
9222 computes the same value, but in a more efficient manner (including
9223 calls to other builtin functions).
9225 The call may contain arguments which need to be evaluated, but
9226 which are not useful to determine the result of the call. In
9227 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9228 COMPOUND_EXPR will be an argument which must be evaluated.
9229 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9230 COMPOUND_EXPR in the chain will contain the tree for the simplified
9231 form of the builtin function call. */
9234 fold_builtin_strcat (tree arglist
)
9236 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
9240 tree dst
= TREE_VALUE (arglist
),
9241 src
= TREE_VALUE (TREE_CHAIN (arglist
));
9242 const char *p
= c_getstr (src
);
9244 /* If the string length is zero, return the dst parameter. */
9245 if (p
&& *p
== '\0')
9252 /* Simplify a call to the strncat builtin.
9254 Return 0 if no simplification was possible, otherwise return the
9255 simplified form of the call as a tree.
9257 The simplified form may be a constant or other expression which
9258 computes the same value, but in a more efficient manner (including
9259 calls to other builtin functions).
9261 The call may contain arguments which need to be evaluated, but
9262 which are not useful to determine the result of the call. In
9263 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9264 COMPOUND_EXPR will be an argument which must be evaluated.
9265 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9266 COMPOUND_EXPR in the chain will contain the tree for the simplified
9267 form of the builtin function call. */
9270 fold_builtin_strncat (tree arglist
)
9272 if (!validate_arglist (arglist
,
9273 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
9277 tree dst
= TREE_VALUE (arglist
);
9278 tree src
= TREE_VALUE (TREE_CHAIN (arglist
));
9279 tree len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
9280 const char *p
= c_getstr (src
);
9282 /* If the requested length is zero, or the src parameter string
9283 length is zero, return the dst parameter. */
9284 if (integer_zerop (len
) || (p
&& *p
== '\0'))
9285 return omit_two_operands (TREE_TYPE (dst
), dst
, src
, len
);
9287 /* If the requested len is greater than or equal to the string
9288 length, call strcat. */
9289 if (TREE_CODE (len
) == INTEGER_CST
&& p
9290 && compare_tree_int (len
, strlen (p
)) >= 0)
9293 = tree_cons (NULL_TREE
, dst
, build_tree_list (NULL_TREE
, src
));
9294 tree fn
= implicit_built_in_decls
[BUILT_IN_STRCAT
];
9296 /* If the replacement _DECL isn't initialized, don't do the
9301 return build_function_call_expr (fn
, newarglist
);
9307 /* Simplify a call to the strspn builtin.
9309 Return 0 if no simplification was possible, otherwise return the
9310 simplified form of the call as a tree.
9312 The simplified form may be a constant or other expression which
9313 computes the same value, but in a more efficient manner (including
9314 calls to other builtin functions).
9316 The call may contain arguments which need to be evaluated, but
9317 which are not useful to determine the result of the call. In
9318 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9319 COMPOUND_EXPR will be an argument which must be evaluated.
9320 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9321 COMPOUND_EXPR in the chain will contain the tree for the simplified
9322 form of the builtin function call. */
9325 fold_builtin_strspn (tree arglist
)
9327 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
9331 tree s1
= TREE_VALUE (arglist
), s2
= TREE_VALUE (TREE_CHAIN (arglist
));
9332 const char *p1
= c_getstr (s1
), *p2
= c_getstr (s2
);
9334 /* If both arguments are constants, evaluate at compile-time. */
9337 const size_t r
= strspn (p1
, p2
);
9338 return size_int (r
);
9341 /* If either argument is "", return 0. */
9342 if ((p1
&& *p1
== '\0') || (p2
&& *p2
== '\0'))
9343 /* Evaluate and ignore both arguments in case either one has
9345 return omit_two_operands (integer_type_node
, integer_zero_node
,
9351 /* Simplify a call to the strcspn builtin.
9353 Return 0 if no simplification was possible, otherwise return the
9354 simplified form of the call as a tree.
9356 The simplified form may be a constant or other expression which
9357 computes the same value, but in a more efficient manner (including
9358 calls to other builtin functions).
9360 The call may contain arguments which need to be evaluated, but
9361 which are not useful to determine the result of the call. In
9362 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9363 COMPOUND_EXPR will be an argument which must be evaluated.
9364 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9365 COMPOUND_EXPR in the chain will contain the tree for the simplified
9366 form of the builtin function call. */
9369 fold_builtin_strcspn (tree arglist
)
9371 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
9375 tree s1
= TREE_VALUE (arglist
), s2
= TREE_VALUE (TREE_CHAIN (arglist
));
9376 const char *p1
= c_getstr (s1
), *p2
= c_getstr (s2
);
9378 /* If both arguments are constants, evaluate at compile-time. */
9381 const size_t r
= strcspn (p1
, p2
);
9382 return size_int (r
);
9385 /* If the first argument is "", return 0. */
9386 if (p1
&& *p1
== '\0')
9388 /* Evaluate and ignore argument s2 in case it has
9390 return omit_one_operand (integer_type_node
,
9391 integer_zero_node
, s2
);
9394 /* If the second argument is "", return __builtin_strlen(s1). */
9395 if (p2
&& *p2
== '\0')
9397 tree newarglist
= build_tree_list (NULL_TREE
, s1
),
9398 fn
= implicit_built_in_decls
[BUILT_IN_STRLEN
];
9400 /* If the replacement _DECL isn't initialized, don't do the
9405 return build_function_call_expr (fn
, newarglist
);
9411 /* Fold a call to the fputs builtin. IGNORE is true if the value returned
9412 by the builtin will be ignored. UNLOCKED is true is true if this
9413 actually a call to fputs_unlocked. If LEN in non-NULL, it represents
9414 the known length of the string. Return NULL_TREE if no simplification
9418 fold_builtin_fputs (tree arglist
, bool ignore
, bool unlocked
, tree len
)
9421 /* If we're using an unlocked function, assume the other unlocked
9422 functions exist explicitly. */
9423 tree
const fn_fputc
= unlocked
? built_in_decls
[BUILT_IN_FPUTC_UNLOCKED
]
9424 : implicit_built_in_decls
[BUILT_IN_FPUTC
];
9425 tree
const fn_fwrite
= unlocked
? built_in_decls
[BUILT_IN_FWRITE_UNLOCKED
]
9426 : implicit_built_in_decls
[BUILT_IN_FWRITE
];
9428 /* If the return value is used, don't do the transformation. */
9432 /* Verify the arguments in the original call. */
9433 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
9437 len
= c_strlen (TREE_VALUE (arglist
), 0);
9439 /* Get the length of the string passed to fputs. If the length
9440 can't be determined, punt. */
9442 || TREE_CODE (len
) != INTEGER_CST
)
9445 switch (compare_tree_int (len
, 1))
9447 case -1: /* length is 0, delete the call entirely . */
9448 return omit_one_operand (integer_type_node
, integer_zero_node
,
9449 TREE_VALUE (TREE_CHAIN (arglist
)));
9451 case 0: /* length is 1, call fputc. */
9453 const char *p
= c_getstr (TREE_VALUE (arglist
));
9457 /* New argument list transforming fputs(string, stream) to
9458 fputc(string[0], stream). */
9459 arglist
= build_tree_list (NULL_TREE
,
9460 TREE_VALUE (TREE_CHAIN (arglist
)));
9461 arglist
= tree_cons (NULL_TREE
,
9462 build_int_cst (NULL_TREE
, p
[0]),
9469 case 1: /* length is greater than 1, call fwrite. */
9473 /* If optimizing for size keep fputs. */
9476 string_arg
= TREE_VALUE (arglist
);
9477 /* New argument list transforming fputs(string, stream) to
9478 fwrite(string, 1, len, stream). */
9479 arglist
= build_tree_list (NULL_TREE
,
9480 TREE_VALUE (TREE_CHAIN (arglist
)));
9481 arglist
= tree_cons (NULL_TREE
, len
, arglist
);
9482 arglist
= tree_cons (NULL_TREE
, size_one_node
, arglist
);
9483 arglist
= tree_cons (NULL_TREE
, string_arg
, arglist
);
9491 /* If the replacement _DECL isn't initialized, don't do the
9496 /* These optimizations are only performed when the result is ignored,
9497 hence there's no need to cast the result to integer_type_node. */
9498 return build_function_call_expr (fn
, arglist
);
9501 /* Fold the new_arg's arguments (ARGLIST). Returns true if there was an error
9502 produced. False otherwise. This is done so that we don't output the error
9503 or warning twice or three times. */
9505 fold_builtin_next_arg (tree arglist
)
9507 tree fntype
= TREE_TYPE (current_function_decl
);
9509 if (TYPE_ARG_TYPES (fntype
) == 0
9510 || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype
)))
9513 error ("%<va_start%> used in function with fixed args");
9518 /* Evidently an out of date version of <stdarg.h>; can't validate
9519 va_start's second argument, but can still work as intended. */
9520 warning (0, "%<__builtin_next_arg%> called without an argument");
9523 /* We use __builtin_va_start (ap, 0, 0) or __builtin_next_arg (0, 0)
9524 when we checked the arguments and if needed issued a warning. */
9525 else if (!TREE_CHAIN (arglist
)
9526 || !integer_zerop (TREE_VALUE (arglist
))
9527 || !integer_zerop (TREE_VALUE (TREE_CHAIN (arglist
)))
9528 || TREE_CHAIN (TREE_CHAIN (arglist
)))
9530 tree last_parm
= tree_last (DECL_ARGUMENTS (current_function_decl
));
9531 tree arg
= TREE_VALUE (arglist
);
9533 if (TREE_CHAIN (arglist
))
9535 error ("%<va_start%> used with too many arguments");
9539 /* Strip off all nops for the sake of the comparison. This
9540 is not quite the same as STRIP_NOPS. It does more.
9541 We must also strip off INDIRECT_EXPR for C++ reference
9543 while (TREE_CODE (arg
) == NOP_EXPR
9544 || TREE_CODE (arg
) == CONVERT_EXPR
9545 || TREE_CODE (arg
) == NON_LVALUE_EXPR
9546 || TREE_CODE (arg
) == INDIRECT_REF
)
9547 arg
= TREE_OPERAND (arg
, 0);
9548 if (arg
!= last_parm
)
9550 /* FIXME: Sometimes with the tree optimizers we can get the
9551 not the last argument even though the user used the last
9552 argument. We just warn and set the arg to be the last
9553 argument so that we will get wrong-code because of
9555 warning (0, "second parameter of %<va_start%> not last named argument");
9557 /* We want to verify the second parameter just once before the tree
9558 optimizers are run and then avoid keeping it in the tree,
9559 as otherwise we could warn even for correct code like:
9560 void foo (int i, ...)
9561 { va_list ap; i++; va_start (ap, i); va_end (ap); } */
9562 TREE_VALUE (arglist
) = integer_zero_node
;
9563 TREE_CHAIN (arglist
) = build_tree_list (NULL
, integer_zero_node
);
9569 /* Simplify a call to the sprintf builtin.
9571 Return 0 if no simplification was possible, otherwise return the
9572 simplified form of the call as a tree. If IGNORED is true, it means that
9573 the caller does not use the returned value of the function. */
9576 fold_builtin_sprintf (tree arglist
, int ignored
)
9578 tree call
, retval
, dest
, fmt
;
9579 const char *fmt_str
= NULL
;
9581 /* Verify the required arguments in the original call. We deal with two
9582 types of sprintf() calls: 'sprintf (str, fmt)' and
9583 'sprintf (dest, "%s", orig)'. */
9584 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
)
9585 && !validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, POINTER_TYPE
,
9589 /* Get the destination string and the format specifier. */
9590 dest
= TREE_VALUE (arglist
);
9591 fmt
= TREE_VALUE (TREE_CHAIN (arglist
));
9593 /* Check whether the format is a literal string constant. */
9594 fmt_str
= c_getstr (fmt
);
9595 if (fmt_str
== NULL
)
9601 if (!init_target_chars())
9604 /* If the format doesn't contain % args or %%, use strcpy. */
9605 if (strchr (fmt_str
, target_percent
) == NULL
)
9607 tree fn
= implicit_built_in_decls
[BUILT_IN_STRCPY
];
9612 /* Convert sprintf (str, fmt) into strcpy (str, fmt) when
9613 'format' is known to contain no % formats. */
9614 arglist
= build_tree_list (NULL_TREE
, fmt
);
9615 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
9616 call
= build_function_call_expr (fn
, arglist
);
9618 retval
= build_int_cst (NULL_TREE
, strlen (fmt_str
));
9621 /* If the format is "%s", use strcpy if the result isn't used. */
9622 else if (fmt_str
&& strcmp (fmt_str
, target_percent_s
) == 0)
9625 fn
= implicit_built_in_decls
[BUILT_IN_STRCPY
];
9630 /* Convert sprintf (str1, "%s", str2) into strcpy (str1, str2). */
9631 orig
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
9632 arglist
= build_tree_list (NULL_TREE
, orig
);
9633 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
9636 retval
= c_strlen (orig
, 1);
9637 if (!retval
|| TREE_CODE (retval
) != INTEGER_CST
)
9640 call
= build_function_call_expr (fn
, arglist
);
9646 (TREE_TYPE (TREE_TYPE (implicit_built_in_decls
[BUILT_IN_SPRINTF
])),
9648 return build2 (COMPOUND_EXPR
, TREE_TYPE (retval
), call
, retval
);
9654 /* Expand a call to __builtin_object_size. */
9657 expand_builtin_object_size (tree exp
)
9660 int object_size_type
;
9661 tree fndecl
= get_callee_fndecl (exp
);
9662 tree arglist
= TREE_OPERAND (exp
, 1);
9663 location_t locus
= EXPR_LOCATION (exp
);
9665 if (!validate_arglist (arglist
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
9667 error ("%Hfirst argument of %D must be a pointer, second integer constant",
9669 expand_builtin_trap ();
9673 ost
= TREE_VALUE (TREE_CHAIN (arglist
));
9676 if (TREE_CODE (ost
) != INTEGER_CST
9677 || tree_int_cst_sgn (ost
) < 0
9678 || compare_tree_int (ost
, 3) > 0)
9680 error ("%Hlast argument of %D is not integer constant between 0 and 3",
9682 expand_builtin_trap ();
9686 object_size_type
= tree_low_cst (ost
, 0);
9688 return object_size_type
< 2 ? constm1_rtx
: const0_rtx
;
9691 /* Expand EXP, a call to the __mem{cpy,pcpy,move,set}_chk builtin.
9692 FCODE is the BUILT_IN_* to use.
9693 Return 0 if we failed; the caller should emit a normal call,
9694 otherwise try to get the result in TARGET, if convenient (and in
9695 mode MODE if that's convenient). */
9698 expand_builtin_memory_chk (tree exp
, rtx target
, enum machine_mode mode
,
9699 enum built_in_function fcode
)
9701 tree arglist
= TREE_OPERAND (exp
, 1);
9702 tree dest
, src
, len
, size
;
9704 if (!validate_arglist (arglist
,
9706 fcode
== BUILT_IN_MEMSET_CHK
9707 ? INTEGER_TYPE
: POINTER_TYPE
,
9708 INTEGER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
9711 dest
= TREE_VALUE (arglist
);
9712 src
= TREE_VALUE (TREE_CHAIN (arglist
));
9713 len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
9714 size
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist
))));
9716 if (! host_integerp (size
, 1))
9719 if (host_integerp (len
, 1) || integer_all_onesp (size
))
9723 if (! integer_all_onesp (size
) && tree_int_cst_lt (size
, len
))
9725 location_t locus
= EXPR_LOCATION (exp
);
9726 warning (0, "%Hcall to %D will always overflow destination buffer",
9727 &locus
, get_callee_fndecl (exp
));
9731 arglist
= build_tree_list (NULL_TREE
, len
);
9732 arglist
= tree_cons (NULL_TREE
, src
, arglist
);
9733 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
9736 /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume
9737 mem{cpy,pcpy,move,set} is available. */
9740 case BUILT_IN_MEMCPY_CHK
:
9741 fn
= built_in_decls
[BUILT_IN_MEMCPY
];
9743 case BUILT_IN_MEMPCPY_CHK
:
9744 fn
= built_in_decls
[BUILT_IN_MEMPCPY
];
9746 case BUILT_IN_MEMMOVE_CHK
:
9747 fn
= built_in_decls
[BUILT_IN_MEMMOVE
];
9749 case BUILT_IN_MEMSET_CHK
:
9750 fn
= built_in_decls
[BUILT_IN_MEMSET
];
9759 fn
= build_function_call_expr (fn
, arglist
);
9760 if (TREE_CODE (fn
) == CALL_EXPR
)
9761 CALL_EXPR_TAILCALL (fn
) = CALL_EXPR_TAILCALL (exp
);
9762 return expand_expr (fn
, target
, mode
, EXPAND_NORMAL
);
9764 else if (fcode
== BUILT_IN_MEMSET_CHK
)
9768 unsigned int dest_align
9769 = get_pointer_alignment (dest
, BIGGEST_ALIGNMENT
);
9771 /* If DEST is not a pointer type, call the normal function. */
9772 if (dest_align
== 0)
9775 /* If SRC and DEST are the same (and not volatile), do nothing. */
9776 if (operand_equal_p (src
, dest
, 0))
9780 if (fcode
!= BUILT_IN_MEMPCPY_CHK
)
9782 /* Evaluate and ignore LEN in case it has side-effects. */
9783 expand_expr (len
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
9784 return expand_expr (dest
, target
, mode
, EXPAND_NORMAL
);
9787 len
= fold_convert (TREE_TYPE (dest
), len
);
9788 expr
= fold_build2 (PLUS_EXPR
, TREE_TYPE (dest
), dest
, len
);
9789 return expand_expr (expr
, target
, mode
, EXPAND_NORMAL
);
9792 /* __memmove_chk special case. */
9793 if (fcode
== BUILT_IN_MEMMOVE_CHK
)
9795 unsigned int src_align
9796 = get_pointer_alignment (src
, BIGGEST_ALIGNMENT
);
9801 /* If src is categorized for a readonly section we can use
9802 normal __memcpy_chk. */
9803 if (readonly_data_expr (src
))
9805 tree fn
= built_in_decls
[BUILT_IN_MEMCPY_CHK
];
9808 fn
= build_function_call_expr (fn
, arglist
);
9809 if (TREE_CODE (fn
) == CALL_EXPR
)
9810 CALL_EXPR_TAILCALL (fn
) = CALL_EXPR_TAILCALL (exp
);
9811 return expand_expr (fn
, target
, mode
, EXPAND_NORMAL
);
9818 /* Emit warning if a buffer overflow is detected at compile time. */
9821 maybe_emit_chk_warning (tree exp
, enum built_in_function fcode
)
9823 int arg_mask
, is_strlen
= 0;
9824 tree arglist
= TREE_OPERAND (exp
, 1), a
;
9830 case BUILT_IN_STRCPY_CHK
:
9831 case BUILT_IN_STPCPY_CHK
:
9832 /* For __strcat_chk the warning will be emitted only if overflowing
9833 by at least strlen (dest) + 1 bytes. */
9834 case BUILT_IN_STRCAT_CHK
:
9838 case BUILT_IN_STRNCPY_CHK
:
9841 case BUILT_IN_SNPRINTF_CHK
:
9842 case BUILT_IN_VSNPRINTF_CHK
:
9851 for (a
= arglist
; a
&& arg_mask
; a
= TREE_CHAIN (a
), arg_mask
>>= 1)
9863 len
= TREE_VALUE (len
);
9864 size
= TREE_VALUE (size
);
9866 if (! host_integerp (size
, 1) || integer_all_onesp (size
))
9871 len
= c_strlen (len
, 1);
9872 if (! len
|| ! host_integerp (len
, 1) || tree_int_cst_lt (len
, size
))
9875 else if (! host_integerp (len
, 1) || ! tree_int_cst_lt (size
, len
))
9878 locus
= EXPR_LOCATION (exp
);
9879 warning (0, "%Hcall to %D will always overflow destination buffer",
9880 &locus
, get_callee_fndecl (exp
));
9883 /* Emit warning if a buffer overflow is detected at compile time
9884 in __sprintf_chk/__vsprintf_chk calls. */
9887 maybe_emit_sprintf_chk_warning (tree exp
, enum built_in_function fcode
)
9889 tree arglist
= TREE_OPERAND (exp
, 1);
9890 tree dest
, size
, len
, fmt
, flag
;
9891 const char *fmt_str
;
9893 /* Verify the required arguments in the original call. */
9896 dest
= TREE_VALUE (arglist
);
9897 arglist
= TREE_CHAIN (arglist
);
9900 flag
= TREE_VALUE (arglist
);
9901 arglist
= TREE_CHAIN (arglist
);
9904 size
= TREE_VALUE (arglist
);
9905 arglist
= TREE_CHAIN (arglist
);
9908 fmt
= TREE_VALUE (arglist
);
9909 arglist
= TREE_CHAIN (arglist
);
9911 if (! host_integerp (size
, 1) || integer_all_onesp (size
))
9914 /* Check whether the format is a literal string constant. */
9915 fmt_str
= c_getstr (fmt
);
9916 if (fmt_str
== NULL
)
9919 if (!init_target_chars())
9922 /* If the format doesn't contain % args or %%, we know its size. */
9923 if (strchr (fmt_str
, target_percent
) == 0)
9924 len
= build_int_cstu (size_type_node
, strlen (fmt_str
));
9925 /* If the format is "%s" and first ... argument is a string literal,
9927 else if (fcode
== BUILT_IN_SPRINTF_CHK
&& strcmp (fmt_str
, target_percent_s
) == 0)
9933 arg
= TREE_VALUE (arglist
);
9934 if (! POINTER_TYPE_P (TREE_TYPE (arg
)))
9937 len
= c_strlen (arg
, 1);
9938 if (!len
|| ! host_integerp (len
, 1))
9944 if (! tree_int_cst_lt (len
, size
))
9946 location_t locus
= EXPR_LOCATION (exp
);
9947 warning (0, "%Hcall to %D will always overflow destination buffer",
9948 &locus
, get_callee_fndecl (exp
));
9952 /* Fold a call to __builtin_object_size, if possible. */
9955 fold_builtin_object_size (tree arglist
)
9957 tree ptr
, ost
, ret
= 0;
9958 int object_size_type
;
9960 if (!validate_arglist (arglist
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
9963 ptr
= TREE_VALUE (arglist
);
9964 ost
= TREE_VALUE (TREE_CHAIN (arglist
));
9967 if (TREE_CODE (ost
) != INTEGER_CST
9968 || tree_int_cst_sgn (ost
) < 0
9969 || compare_tree_int (ost
, 3) > 0)
9972 object_size_type
= tree_low_cst (ost
, 0);
9974 /* __builtin_object_size doesn't evaluate side-effects in its arguments;
9975 if there are any side-effects, it returns (size_t) -1 for types 0 and 1
9976 and (size_t) 0 for types 2 and 3. */
9977 if (TREE_SIDE_EFFECTS (ptr
))
9978 return fold_convert (size_type_node
,
9979 object_size_type
< 2
9980 ? integer_minus_one_node
: integer_zero_node
);
9982 if (TREE_CODE (ptr
) == ADDR_EXPR
)
9983 ret
= build_int_cstu (size_type_node
,
9984 compute_builtin_object_size (ptr
, object_size_type
));
9986 else if (TREE_CODE (ptr
) == SSA_NAME
)
9988 unsigned HOST_WIDE_INT bytes
;
9990 /* If object size is not known yet, delay folding until
9991 later. Maybe subsequent passes will help determining
9993 bytes
= compute_builtin_object_size (ptr
, object_size_type
);
9994 if (bytes
!= (unsigned HOST_WIDE_INT
) (object_size_type
< 2
9996 ret
= build_int_cstu (size_type_node
, bytes
);
10001 ret
= force_fit_type (ret
, -1, false, false);
10002 if (TREE_CONSTANT_OVERFLOW (ret
))
10009 /* Fold a call to the __mem{cpy,pcpy,move,set}_chk builtin.
10010 IGNORE is true, if return value can be ignored. FCODE is the BUILT_IN_*
10011 code of the builtin. If MAXLEN is not NULL, it is maximum length
10012 passed as third argument. */
10015 fold_builtin_memory_chk (tree fndecl
, tree arglist
, tree maxlen
, bool ignore
,
10016 enum built_in_function fcode
)
10018 tree dest
, src
, len
, size
, fn
;
10020 if (!validate_arglist (arglist
,
10022 fcode
== BUILT_IN_MEMSET_CHK
10023 ? INTEGER_TYPE
: POINTER_TYPE
,
10024 INTEGER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
10027 dest
= TREE_VALUE (arglist
);
10028 /* Actually val for __memset_chk, but it doesn't matter. */
10029 src
= TREE_VALUE (TREE_CHAIN (arglist
));
10030 len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
10031 size
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist
))));
10033 /* If SRC and DEST are the same (and not volatile), return DEST
10034 (resp. DEST+LEN for __mempcpy_chk). */
10035 if (fcode
!= BUILT_IN_MEMSET_CHK
&& operand_equal_p (src
, dest
, 0))
10037 if (fcode
!= BUILT_IN_MEMPCPY_CHK
)
10038 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl
)), dest
, len
);
10041 tree temp
= fold_convert (TREE_TYPE (dest
), len
);
10042 temp
= fold_build2 (PLUS_EXPR
, TREE_TYPE (dest
), dest
, temp
);
10043 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl
)), temp
);
10047 if (! host_integerp (size
, 1))
10050 if (! integer_all_onesp (size
))
10052 if (! host_integerp (len
, 1))
10054 /* If LEN is not constant, try MAXLEN too.
10055 For MAXLEN only allow optimizing into non-_ocs function
10056 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
10057 if (maxlen
== NULL_TREE
|| ! host_integerp (maxlen
, 1))
10059 if (fcode
== BUILT_IN_MEMPCPY_CHK
&& ignore
)
10061 /* (void) __mempcpy_chk () can be optimized into
10062 (void) __memcpy_chk (). */
10063 fn
= built_in_decls
[BUILT_IN_MEMCPY_CHK
];
10067 return build_function_call_expr (fn
, arglist
);
10075 if (tree_int_cst_lt (size
, maxlen
))
10079 arglist
= build_tree_list (NULL_TREE
, len
);
10080 arglist
= tree_cons (NULL_TREE
, src
, arglist
);
10081 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
10084 /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume
10085 mem{cpy,pcpy,move,set} is available. */
10088 case BUILT_IN_MEMCPY_CHK
:
10089 fn
= built_in_decls
[BUILT_IN_MEMCPY
];
10091 case BUILT_IN_MEMPCPY_CHK
:
10092 fn
= built_in_decls
[BUILT_IN_MEMPCPY
];
10094 case BUILT_IN_MEMMOVE_CHK
:
10095 fn
= built_in_decls
[BUILT_IN_MEMMOVE
];
10097 case BUILT_IN_MEMSET_CHK
:
10098 fn
= built_in_decls
[BUILT_IN_MEMSET
];
10107 return build_function_call_expr (fn
, arglist
);
10110 /* Fold a call to the __st[rp]cpy_chk builtin.
10111 IGNORE is true, if return value can be ignored. FCODE is the BUILT_IN_*
10112 code of the builtin. If MAXLEN is not NULL, it is maximum length of
10113 strings passed as second argument. */
10116 fold_builtin_stxcpy_chk (tree fndecl
, tree arglist
, tree maxlen
, bool ignore
,
10117 enum built_in_function fcode
)
10119 tree dest
, src
, size
, len
, fn
;
10121 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
,
10125 dest
= TREE_VALUE (arglist
);
10126 src
= TREE_VALUE (TREE_CHAIN (arglist
));
10127 size
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
10129 /* If SRC and DEST are the same (and not volatile), return DEST. */
10130 if (fcode
== BUILT_IN_STRCPY_CHK
&& operand_equal_p (src
, dest
, 0))
10131 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl
)), dest
);
10133 if (! host_integerp (size
, 1))
10136 if (! integer_all_onesp (size
))
10138 len
= c_strlen (src
, 1);
10139 if (! len
|| ! host_integerp (len
, 1))
10141 /* If LEN is not constant, try MAXLEN too.
10142 For MAXLEN only allow optimizing into non-_ocs function
10143 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
10144 if (maxlen
== NULL_TREE
|| ! host_integerp (maxlen
, 1))
10146 if (fcode
== BUILT_IN_STPCPY_CHK
)
10151 /* If return value of __stpcpy_chk is ignored,
10152 optimize into __strcpy_chk. */
10153 fn
= built_in_decls
[BUILT_IN_STRCPY_CHK
];
10157 return build_function_call_expr (fn
, arglist
);
10160 if (! len
|| TREE_SIDE_EFFECTS (len
))
10163 /* If c_strlen returned something, but not a constant,
10164 transform __strcpy_chk into __memcpy_chk. */
10165 fn
= built_in_decls
[BUILT_IN_MEMCPY_CHK
];
10169 len
= size_binop (PLUS_EXPR
, len
, ssize_int (1));
10170 arglist
= build_tree_list (NULL_TREE
, size
);
10171 arglist
= tree_cons (NULL_TREE
, len
, arglist
);
10172 arglist
= tree_cons (NULL_TREE
, src
, arglist
);
10173 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
10174 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl
)),
10175 build_function_call_expr (fn
, arglist
));
10181 if (! tree_int_cst_lt (maxlen
, size
))
10185 arglist
= build_tree_list (NULL_TREE
, src
);
10186 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
10188 /* If __builtin_st{r,p}cpy_chk is used, assume st{r,p}cpy is available. */
10189 fn
= built_in_decls
[fcode
== BUILT_IN_STPCPY_CHK
10190 ? BUILT_IN_STPCPY
: BUILT_IN_STRCPY
];
10194 return build_function_call_expr (fn
, arglist
);
10197 /* Fold a call to the __strncpy_chk builtin.
10198 If MAXLEN is not NULL, it is maximum length passed as third argument. */
10201 fold_builtin_strncpy_chk (tree arglist
, tree maxlen
)
10203 tree dest
, src
, size
, len
, fn
;
10205 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
,
10206 INTEGER_TYPE
, VOID_TYPE
))
10209 dest
= TREE_VALUE (arglist
);
10210 src
= TREE_VALUE (TREE_CHAIN (arglist
));
10211 len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
10212 size
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist
))));
10214 if (! host_integerp (size
, 1))
10217 if (! integer_all_onesp (size
))
10219 if (! host_integerp (len
, 1))
10221 /* If LEN is not constant, try MAXLEN too.
10222 For MAXLEN only allow optimizing into non-_ocs function
10223 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
10224 if (maxlen
== NULL_TREE
|| ! host_integerp (maxlen
, 1))
10230 if (tree_int_cst_lt (size
, maxlen
))
10234 arglist
= build_tree_list (NULL_TREE
, len
);
10235 arglist
= tree_cons (NULL_TREE
, src
, arglist
);
10236 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
10238 /* If __builtin_strncpy_chk is used, assume strncpy is available. */
10239 fn
= built_in_decls
[BUILT_IN_STRNCPY
];
10243 return build_function_call_expr (fn
, arglist
);
10246 /* Fold a call to the __strcat_chk builtin FNDECL with ARGLIST. */
10249 fold_builtin_strcat_chk (tree fndecl
, tree arglist
)
10251 tree dest
, src
, size
, fn
;
10254 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
,
10258 dest
= TREE_VALUE (arglist
);
10259 src
= TREE_VALUE (TREE_CHAIN (arglist
));
10260 size
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
10262 p
= c_getstr (src
);
10263 /* If the SRC parameter is "", return DEST. */
10264 if (p
&& *p
== '\0')
10265 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl
)), dest
, src
);
10267 if (! host_integerp (size
, 1) || ! integer_all_onesp (size
))
10270 arglist
= build_tree_list (NULL_TREE
, src
);
10271 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
10273 /* If __builtin_strcat_chk is used, assume strcat is available. */
10274 fn
= built_in_decls
[BUILT_IN_STRCAT
];
10278 return build_function_call_expr (fn
, arglist
);
10281 /* Fold a call to the __strncat_chk builtin EXP. */
10284 fold_builtin_strncat_chk (tree fndecl
, tree arglist
)
10286 tree dest
, src
, size
, len
, fn
;
10289 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
,
10290 INTEGER_TYPE
, VOID_TYPE
))
10293 dest
= TREE_VALUE (arglist
);
10294 src
= TREE_VALUE (TREE_CHAIN (arglist
));
10295 len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
10296 size
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist
))));
10298 p
= c_getstr (src
);
10299 /* If the SRC parameter is "" or if LEN is 0, return DEST. */
10300 if (p
&& *p
== '\0')
10301 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl
)), dest
, len
);
10302 else if (integer_zerop (len
))
10303 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl
)), dest
, src
);
10305 if (! host_integerp (size
, 1))
10308 if (! integer_all_onesp (size
))
10310 tree src_len
= c_strlen (src
, 1);
10312 && host_integerp (src_len
, 1)
10313 && host_integerp (len
, 1)
10314 && ! tree_int_cst_lt (len
, src_len
))
10316 /* If LEN >= strlen (SRC), optimize into __strcat_chk. */
10317 fn
= built_in_decls
[BUILT_IN_STRCAT_CHK
];
10321 arglist
= build_tree_list (NULL_TREE
, size
);
10322 arglist
= tree_cons (NULL_TREE
, src
, arglist
);
10323 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
10324 return build_function_call_expr (fn
, arglist
);
10329 arglist
= build_tree_list (NULL_TREE
, len
);
10330 arglist
= tree_cons (NULL_TREE
, src
, arglist
);
10331 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
10333 /* If __builtin_strncat_chk is used, assume strncat is available. */
10334 fn
= built_in_decls
[BUILT_IN_STRNCAT
];
10338 return build_function_call_expr (fn
, arglist
);
10341 /* Fold a call to __{,v}sprintf_chk with argument list ARGLIST. Return 0 if
10342 a normal call should be emitted rather than expanding the function
10343 inline. FCODE is either BUILT_IN_SPRINTF_CHK or BUILT_IN_VSPRINTF_CHK. */
10346 fold_builtin_sprintf_chk (tree arglist
, enum built_in_function fcode
)
10348 tree dest
, size
, len
, fn
, fmt
, flag
;
10349 const char *fmt_str
;
10351 /* Verify the required arguments in the original call. */
10354 dest
= TREE_VALUE (arglist
);
10355 if (! POINTER_TYPE_P (TREE_TYPE (dest
)))
10357 arglist
= TREE_CHAIN (arglist
);
10360 flag
= TREE_VALUE (arglist
);
10361 if (TREE_CODE (TREE_TYPE (flag
)) != INTEGER_TYPE
)
10363 arglist
= TREE_CHAIN (arglist
);
10366 size
= TREE_VALUE (arglist
);
10367 if (TREE_CODE (TREE_TYPE (size
)) != INTEGER_TYPE
)
10369 arglist
= TREE_CHAIN (arglist
);
10372 fmt
= TREE_VALUE (arglist
);
10373 if (! POINTER_TYPE_P (TREE_TYPE (fmt
)))
10375 arglist
= TREE_CHAIN (arglist
);
10377 if (! host_integerp (size
, 1))
10382 if (!init_target_chars())
10385 /* Check whether the format is a literal string constant. */
10386 fmt_str
= c_getstr (fmt
);
10387 if (fmt_str
!= NULL
)
10389 /* If the format doesn't contain % args or %%, we know the size. */
10390 if (strchr (fmt_str
, target_percent
) == 0)
10392 if (fcode
!= BUILT_IN_SPRINTF_CHK
|| arglist
== NULL_TREE
)
10393 len
= build_int_cstu (size_type_node
, strlen (fmt_str
));
10395 /* If the format is "%s" and first ... argument is a string literal,
10396 we know the size too. */
10397 else if (fcode
== BUILT_IN_SPRINTF_CHK
&& strcmp (fmt_str
, target_percent_s
) == 0)
10401 if (arglist
&& !TREE_CHAIN (arglist
))
10403 arg
= TREE_VALUE (arglist
);
10404 if (POINTER_TYPE_P (TREE_TYPE (arg
)))
10406 len
= c_strlen (arg
, 1);
10407 if (! len
|| ! host_integerp (len
, 1))
10414 if (! integer_all_onesp (size
))
10416 if (! len
|| ! tree_int_cst_lt (len
, size
))
10420 /* Only convert __{,v}sprintf_chk to {,v}sprintf if flag is 0
10421 or if format doesn't contain % chars or is "%s". */
10422 if (! integer_zerop (flag
))
10424 if (fmt_str
== NULL
)
10426 if (strchr (fmt_str
, target_percent
) != NULL
&& strcmp (fmt_str
, target_percent_s
))
10430 arglist
= tree_cons (NULL_TREE
, fmt
, arglist
);
10431 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
10433 /* If __builtin_{,v}sprintf_chk is used, assume {,v}sprintf is available. */
10434 fn
= built_in_decls
[fcode
== BUILT_IN_VSPRINTF_CHK
10435 ? BUILT_IN_VSPRINTF
: BUILT_IN_SPRINTF
];
10439 return build_function_call_expr (fn
, arglist
);
10442 /* Fold a call to {,v}snprintf with argument list ARGLIST. Return 0 if
10443 a normal call should be emitted rather than expanding the function
10444 inline. FCODE is either BUILT_IN_SNPRINTF_CHK or
10445 BUILT_IN_VSNPRINTF_CHK. If MAXLEN is not NULL, it is maximum length
10446 passed as second argument. */
10449 fold_builtin_snprintf_chk (tree arglist
, tree maxlen
,
10450 enum built_in_function fcode
)
10452 tree dest
, size
, len
, fn
, fmt
, flag
;
10453 const char *fmt_str
;
10455 /* Verify the required arguments in the original call. */
10458 dest
= TREE_VALUE (arglist
);
10459 if (! POINTER_TYPE_P (TREE_TYPE (dest
)))
10461 arglist
= TREE_CHAIN (arglist
);
10464 len
= TREE_VALUE (arglist
);
10465 if (TREE_CODE (TREE_TYPE (len
)) != INTEGER_TYPE
)
10467 arglist
= TREE_CHAIN (arglist
);
10470 flag
= TREE_VALUE (arglist
);
10471 if (TREE_CODE (TREE_TYPE (len
)) != INTEGER_TYPE
)
10473 arglist
= TREE_CHAIN (arglist
);
10476 size
= TREE_VALUE (arglist
);
10477 if (TREE_CODE (TREE_TYPE (size
)) != INTEGER_TYPE
)
10479 arglist
= TREE_CHAIN (arglist
);
10482 fmt
= TREE_VALUE (arglist
);
10483 if (! POINTER_TYPE_P (TREE_TYPE (fmt
)))
10485 arglist
= TREE_CHAIN (arglist
);
10487 if (! host_integerp (size
, 1))
10490 if (! integer_all_onesp (size
))
10492 if (! host_integerp (len
, 1))
10494 /* If LEN is not constant, try MAXLEN too.
10495 For MAXLEN only allow optimizing into non-_ocs function
10496 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
10497 if (maxlen
== NULL_TREE
|| ! host_integerp (maxlen
, 1))
10503 if (tree_int_cst_lt (size
, maxlen
))
10507 if (!init_target_chars())
10510 /* Only convert __{,v}snprintf_chk to {,v}snprintf if flag is 0
10511 or if format doesn't contain % chars or is "%s". */
10512 if (! integer_zerop (flag
))
10514 fmt_str
= c_getstr (fmt
);
10515 if (fmt_str
== NULL
)
10517 if (strchr (fmt_str
, target_percent
) != NULL
&& strcmp (fmt_str
, target_percent_s
))
10521 arglist
= tree_cons (NULL_TREE
, fmt
, arglist
);
10522 arglist
= tree_cons (NULL_TREE
, len
, arglist
);
10523 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
10525 /* If __builtin_{,v}snprintf_chk is used, assume {,v}snprintf is
10527 fn
= built_in_decls
[fcode
== BUILT_IN_VSNPRINTF_CHK
10528 ? BUILT_IN_VSNPRINTF
: BUILT_IN_SNPRINTF
];
10532 return build_function_call_expr (fn
, arglist
);
10535 /* Fold a call to the {,v}printf{,_unlocked} and __{,v}printf_chk builtins.
10537 Return 0 if no simplification was possible, otherwise return the
10538 simplified form of the call as a tree. FCODE is the BUILT_IN_*
10539 code of the function to be simplified. */
10542 fold_builtin_printf (tree fndecl
, tree arglist
, bool ignore
,
10543 enum built_in_function fcode
)
10545 tree fmt
, fn
= NULL_TREE
, fn_putchar
, fn_puts
, arg
, call
;
10546 const char *fmt_str
= NULL
;
10548 /* If the return value is used, don't do the transformation. */
10552 /* Verify the required arguments in the original call. */
10553 if (fcode
== BUILT_IN_PRINTF_CHK
|| fcode
== BUILT_IN_VPRINTF_CHK
)
10559 flag
= TREE_VALUE (arglist
);
10560 if (TREE_CODE (TREE_TYPE (flag
)) != INTEGER_TYPE
10561 || TREE_SIDE_EFFECTS (flag
))
10563 arglist
= TREE_CHAIN (arglist
);
10568 fmt
= TREE_VALUE (arglist
);
10569 if (! POINTER_TYPE_P (TREE_TYPE (fmt
)))
10571 arglist
= TREE_CHAIN (arglist
);
10573 /* Check whether the format is a literal string constant. */
10574 fmt_str
= c_getstr (fmt
);
10575 if (fmt_str
== NULL
)
10578 if (fcode
== BUILT_IN_PRINTF_UNLOCKED
)
10580 /* If we're using an unlocked function, assume the other
10581 unlocked functions exist explicitly. */
10582 fn_putchar
= built_in_decls
[BUILT_IN_PUTCHAR_UNLOCKED
];
10583 fn_puts
= built_in_decls
[BUILT_IN_PUTS_UNLOCKED
];
10587 fn_putchar
= implicit_built_in_decls
[BUILT_IN_PUTCHAR
];
10588 fn_puts
= implicit_built_in_decls
[BUILT_IN_PUTS
];
10591 if (!init_target_chars())
10594 if (strcmp (fmt_str
, target_percent_s
) == 0 || strchr (fmt_str
, target_percent
) == NULL
)
10598 if (strcmp (fmt_str
, target_percent_s
) == 0)
10600 if (fcode
== BUILT_IN_VPRINTF
|| fcode
== BUILT_IN_VPRINTF_CHK
)
10604 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist
)))
10605 || TREE_CHAIN (arglist
))
10608 str
= c_getstr (TREE_VALUE (arglist
));
10614 /* The format specifier doesn't contain any '%' characters. */
10615 if (fcode
!= BUILT_IN_VPRINTF
&& fcode
!= BUILT_IN_VPRINTF_CHK
10621 /* If the string was "", printf does nothing. */
10622 if (str
[0] == '\0')
10623 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl
)), 0);
10625 /* If the string has length of 1, call putchar. */
10626 if (str
[1] == '\0')
10628 /* Given printf("c"), (where c is any one character,)
10629 convert "c"[0] to an int and pass that to the replacement
10631 arg
= build_int_cst (NULL_TREE
, str
[0]);
10632 arglist
= build_tree_list (NULL_TREE
, arg
);
10637 /* If the string was "string\n", call puts("string"). */
10638 size_t len
= strlen (str
);
10639 if ((unsigned char)str
[len
- 1] == target_newline
)
10641 /* Create a NUL-terminated string that's one char shorter
10642 than the original, stripping off the trailing '\n'. */
10643 char *newstr
= alloca (len
);
10644 memcpy (newstr
, str
, len
- 1);
10645 newstr
[len
- 1] = 0;
10647 arg
= build_string_literal (len
, newstr
);
10648 arglist
= build_tree_list (NULL_TREE
, arg
);
10652 /* We'd like to arrange to call fputs(string,stdout) here,
10653 but we need stdout and don't have a way to get it yet. */
10658 /* The other optimizations can be done only on the non-va_list variants. */
10659 else if (fcode
== BUILT_IN_VPRINTF
|| fcode
== BUILT_IN_VPRINTF_CHK
)
10662 /* If the format specifier was "%s\n", call __builtin_puts(arg). */
10663 else if (strcmp (fmt_str
, target_percent_s_newline
) == 0)
10666 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist
)))
10667 || TREE_CHAIN (arglist
))
10672 /* If the format specifier was "%c", call __builtin_putchar(arg). */
10673 else if (strcmp (fmt_str
, target_percent_c
) == 0)
10676 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist
))) != INTEGER_TYPE
10677 || TREE_CHAIN (arglist
))
10685 call
= build_function_call_expr (fn
, arglist
);
10686 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl
)), call
);
10689 /* Fold a call to the {,v}fprintf{,_unlocked} and __{,v}printf_chk builtins.
10691 Return 0 if no simplification was possible, otherwise return the
10692 simplified form of the call as a tree. FCODE is the BUILT_IN_*
10693 code of the function to be simplified. */
10696 fold_builtin_fprintf (tree fndecl
, tree arglist
, bool ignore
,
10697 enum built_in_function fcode
)
10699 tree fp
, fmt
, fn
= NULL_TREE
, fn_fputc
, fn_fputs
, arg
, call
;
10700 const char *fmt_str
= NULL
;
10702 /* If the return value is used, don't do the transformation. */
10706 /* Verify the required arguments in the original call. */
10709 fp
= TREE_VALUE (arglist
);
10710 if (! POINTER_TYPE_P (TREE_TYPE (fp
)))
10712 arglist
= TREE_CHAIN (arglist
);
10714 if (fcode
== BUILT_IN_FPRINTF_CHK
|| fcode
== BUILT_IN_VFPRINTF_CHK
)
10720 flag
= TREE_VALUE (arglist
);
10721 if (TREE_CODE (TREE_TYPE (flag
)) != INTEGER_TYPE
10722 || TREE_SIDE_EFFECTS (flag
))
10724 arglist
= TREE_CHAIN (arglist
);
10729 fmt
= TREE_VALUE (arglist
);
10730 if (! POINTER_TYPE_P (TREE_TYPE (fmt
)))
10732 arglist
= TREE_CHAIN (arglist
);
10734 /* Check whether the format is a literal string constant. */
10735 fmt_str
= c_getstr (fmt
);
10736 if (fmt_str
== NULL
)
10739 if (fcode
== BUILT_IN_FPRINTF_UNLOCKED
)
10741 /* If we're using an unlocked function, assume the other
10742 unlocked functions exist explicitly. */
10743 fn_fputc
= built_in_decls
[BUILT_IN_FPUTC_UNLOCKED
];
10744 fn_fputs
= built_in_decls
[BUILT_IN_FPUTS_UNLOCKED
];
10748 fn_fputc
= implicit_built_in_decls
[BUILT_IN_FPUTC
];
10749 fn_fputs
= implicit_built_in_decls
[BUILT_IN_FPUTS
];
10752 if (!init_target_chars())
10755 /* If the format doesn't contain % args or %%, use strcpy. */
10756 if (strchr (fmt_str
, target_percent
) == NULL
)
10758 if (fcode
!= BUILT_IN_VFPRINTF
&& fcode
!= BUILT_IN_VFPRINTF_CHK
10762 /* If the format specifier was "", fprintf does nothing. */
10763 if (fmt_str
[0] == '\0')
10765 /* If FP has side-effects, just wait until gimplification is
10767 if (TREE_SIDE_EFFECTS (fp
))
10770 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl
)), 0);
10773 /* When "string" doesn't contain %, replace all cases of
10774 fprintf (fp, string) with fputs (string, fp). The fputs
10775 builtin will take care of special cases like length == 1. */
10776 arglist
= build_tree_list (NULL_TREE
, fp
);
10777 arglist
= tree_cons (NULL_TREE
, fmt
, arglist
);
10781 /* The other optimizations can be done only on the non-va_list variants. */
10782 else if (fcode
== BUILT_IN_VFPRINTF
|| fcode
== BUILT_IN_VFPRINTF_CHK
)
10785 /* If the format specifier was "%s", call __builtin_fputs (arg, fp). */
10786 else if (strcmp (fmt_str
, target_percent_s
) == 0)
10789 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist
)))
10790 || TREE_CHAIN (arglist
))
10792 arg
= TREE_VALUE (arglist
);
10793 arglist
= build_tree_list (NULL_TREE
, fp
);
10794 arglist
= tree_cons (NULL_TREE
, arg
, arglist
);
10798 /* If the format specifier was "%c", call __builtin_fputc (arg, fp). */
10799 else if (strcmp (fmt_str
, target_percent_c
) == 0)
10802 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist
))) != INTEGER_TYPE
10803 || TREE_CHAIN (arglist
))
10805 arg
= TREE_VALUE (arglist
);
10806 arglist
= build_tree_list (NULL_TREE
, fp
);
10807 arglist
= tree_cons (NULL_TREE
, arg
, arglist
);
10814 call
= build_function_call_expr (fn
, arglist
);
10815 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl
)), call
);
10818 /* Initialize format string characters in the target charset. */
10821 init_target_chars (void)
10826 target_newline
= lang_hooks
.to_target_charset ('\n');
10827 target_percent
= lang_hooks
.to_target_charset ('%');
10828 target_c
= lang_hooks
.to_target_charset ('c');
10829 target_s
= lang_hooks
.to_target_charset ('s');
10830 if (target_newline
== 0 || target_percent
== 0 || target_c
== 0
10834 target_percent_c
[0] = target_percent
;
10835 target_percent_c
[1] = target_c
;
10836 target_percent_c
[2] = '\0';
10838 target_percent_s
[0] = target_percent
;
10839 target_percent_s
[1] = target_s
;
10840 target_percent_s
[2] = '\0';
10842 target_percent_s_newline
[0] = target_percent
;
10843 target_percent_s_newline
[1] = target_s
;
10844 target_percent_s_newline
[2] = target_newline
;
10845 target_percent_s_newline
[3] = '\0';