1 /* Expand builtin functions.
2 Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING. If not, write to the Free
19 Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
24 #include "coretypes.h"
30 #include "tree-gimple.h"
33 #include "hard-reg-set.h"
36 #include "insn-config.h"
42 #include "typeclass.h"
47 #include "langhooks.h"
48 #include "basic-block.h"
49 #include "tree-mudflap.h"
51 #ifndef PAD_VARARGS_DOWN
52 #define PAD_VARARGS_DOWN BYTES_BIG_ENDIAN
55 /* Define the names of the builtin function types and codes. */
56 const char *const built_in_class_names
[4]
57 = {"NOT_BUILT_IN", "BUILT_IN_FRONTEND", "BUILT_IN_MD", "BUILT_IN_NORMAL"};
59 #define DEF_BUILTIN(X, N, C, T, LT, B, F, NA, AT, IM, COND) #X,
60 const char * built_in_names
[(int) END_BUILTINS
] =
62 #include "builtins.def"
66 /* Setup an array of _DECL trees, make sure each element is
67 initialized to NULL_TREE. */
68 tree built_in_decls
[(int) END_BUILTINS
];
69 /* Declarations used when constructing the builtin implicitly in the compiler.
70 It may be NULL_TREE when this is invalid (for instance runtime is not
71 required to implement the function call in all cases). */
72 tree implicit_built_in_decls
[(int) END_BUILTINS
];
74 static int get_pointer_alignment (tree
, unsigned int);
75 static const char *c_getstr (tree
);
76 static rtx
c_readstr (const char *, enum machine_mode
);
77 static int target_char_cast (tree
, char *);
78 static rtx
get_memory_rtx (tree
, tree
);
79 static tree
build_string_literal (int, const char *);
80 static int apply_args_size (void);
81 static int apply_result_size (void);
82 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
83 static rtx
result_vector (int, rtx
);
85 static rtx
expand_builtin_setjmp (tree
, rtx
);
86 static void expand_builtin_update_setjmp_buf (rtx
);
87 static void expand_builtin_prefetch (tree
);
88 static rtx
expand_builtin_apply_args (void);
89 static rtx
expand_builtin_apply_args_1 (void);
90 static rtx
expand_builtin_apply (rtx
, rtx
, rtx
);
91 static void expand_builtin_return (rtx
);
92 static enum type_class
type_to_class (tree
);
93 static rtx
expand_builtin_classify_type (tree
);
94 static void expand_errno_check (tree
, rtx
);
95 static rtx
expand_builtin_mathfn (tree
, rtx
, rtx
);
96 static rtx
expand_builtin_mathfn_2 (tree
, rtx
, rtx
);
97 static rtx
expand_builtin_mathfn_3 (tree
, rtx
, rtx
);
98 static rtx
expand_builtin_int_roundingfn (tree
, rtx
, rtx
);
99 static rtx
expand_builtin_args_info (tree
);
100 static rtx
expand_builtin_next_arg (void);
101 static rtx
expand_builtin_va_start (tree
);
102 static rtx
expand_builtin_va_end (tree
);
103 static rtx
expand_builtin_va_copy (tree
);
104 static rtx
expand_builtin_memcmp (tree
, tree
, rtx
, enum machine_mode
);
105 static rtx
expand_builtin_strcmp (tree
, rtx
, enum machine_mode
);
106 static rtx
expand_builtin_strncmp (tree
, rtx
, enum machine_mode
);
107 static rtx
builtin_memcpy_read_str (void *, HOST_WIDE_INT
, enum machine_mode
);
108 static rtx
expand_builtin_strcat (tree
, tree
, rtx
, enum machine_mode
);
109 static rtx
expand_builtin_strncat (tree
, rtx
, enum machine_mode
);
110 static rtx
expand_builtin_strspn (tree
, rtx
, enum machine_mode
);
111 static rtx
expand_builtin_strcspn (tree
, rtx
, enum machine_mode
);
112 static rtx
expand_builtin_memcpy (tree
, rtx
, enum machine_mode
);
113 static rtx
expand_builtin_mempcpy (tree
, tree
, rtx
, enum machine_mode
, int);
114 static rtx
expand_builtin_memmove (tree
, tree
, rtx
, enum machine_mode
, tree
);
115 static rtx
expand_builtin_bcopy (tree
);
116 static rtx
expand_builtin_strcpy (tree
, tree
, rtx
, enum machine_mode
);
117 static rtx
expand_builtin_stpcpy (tree
, rtx
, enum machine_mode
);
118 static rtx
builtin_strncpy_read_str (void *, HOST_WIDE_INT
, enum machine_mode
);
119 static rtx
expand_builtin_strncpy (tree
, rtx
, enum machine_mode
);
120 static rtx
builtin_memset_read_str (void *, HOST_WIDE_INT
, enum machine_mode
);
121 static rtx
builtin_memset_gen_str (void *, HOST_WIDE_INT
, enum machine_mode
);
122 static rtx
expand_builtin_memset (tree
, rtx
, enum machine_mode
, tree
);
123 static rtx
expand_builtin_bzero (tree
);
124 static rtx
expand_builtin_strlen (tree
, rtx
, enum machine_mode
);
125 static rtx
expand_builtin_strstr (tree
, tree
, rtx
, enum machine_mode
);
126 static rtx
expand_builtin_strpbrk (tree
, tree
, rtx
, enum machine_mode
);
127 static rtx
expand_builtin_strchr (tree
, tree
, rtx
, enum machine_mode
);
128 static rtx
expand_builtin_strrchr (tree
, tree
, rtx
, enum machine_mode
);
129 static rtx
expand_builtin_alloca (tree
, rtx
);
130 static rtx
expand_builtin_unop (enum machine_mode
, tree
, rtx
, rtx
, optab
);
131 static rtx
expand_builtin_frame_address (tree
, tree
);
132 static rtx
expand_builtin_fputs (tree
, rtx
, bool);
133 static rtx
expand_builtin_printf (tree
, rtx
, enum machine_mode
, bool);
134 static rtx
expand_builtin_fprintf (tree
, rtx
, enum machine_mode
, bool);
135 static rtx
expand_builtin_sprintf (tree
, rtx
, enum machine_mode
);
136 static tree
stabilize_va_list (tree
, int);
137 static rtx
expand_builtin_expect (tree
, rtx
);
138 static tree
fold_builtin_constant_p (tree
);
139 static tree
fold_builtin_classify_type (tree
);
140 static tree
fold_builtin_strlen (tree
);
141 static tree
fold_builtin_inf (tree
, int);
142 static tree
fold_builtin_nan (tree
, tree
, int);
143 static int validate_arglist (tree
, ...);
144 static bool integer_valued_real_p (tree
);
145 static tree
fold_trunc_transparent_mathfn (tree
, tree
);
146 static bool readonly_data_expr (tree
);
147 static rtx
expand_builtin_fabs (tree
, rtx
, rtx
);
148 static rtx
expand_builtin_signbit (tree
, rtx
);
149 static tree
fold_builtin_cabs (tree
, tree
);
150 static tree
fold_builtin_sqrt (tree
, tree
);
151 static tree
fold_builtin_cbrt (tree
, tree
);
152 static tree
fold_builtin_pow (tree
, tree
, tree
);
153 static tree
fold_builtin_powi (tree
, tree
, tree
);
154 static tree
fold_builtin_sin (tree
);
155 static tree
fold_builtin_cos (tree
, tree
, tree
);
156 static tree
fold_builtin_tan (tree
);
157 static tree
fold_builtin_atan (tree
, tree
);
158 static tree
fold_builtin_trunc (tree
, tree
);
159 static tree
fold_builtin_floor (tree
, tree
);
160 static tree
fold_builtin_ceil (tree
, tree
);
161 static tree
fold_builtin_round (tree
, tree
);
162 static tree
fold_builtin_int_roundingfn (tree
, tree
);
163 static tree
fold_builtin_bitop (tree
, tree
);
164 static tree
fold_builtin_memcpy (tree
, tree
);
165 static tree
fold_builtin_mempcpy (tree
, tree
, int);
166 static tree
fold_builtin_memmove (tree
, tree
);
167 static tree
fold_builtin_strchr (tree
, tree
);
168 static tree
fold_builtin_memcmp (tree
);
169 static tree
fold_builtin_strcmp (tree
);
170 static tree
fold_builtin_strncmp (tree
);
171 static tree
fold_builtin_signbit (tree
, tree
);
172 static tree
fold_builtin_copysign (tree
, tree
, tree
);
173 static tree
fold_builtin_isascii (tree
);
174 static tree
fold_builtin_toascii (tree
);
175 static tree
fold_builtin_isdigit (tree
);
176 static tree
fold_builtin_fabs (tree
, tree
);
177 static tree
fold_builtin_abs (tree
, tree
);
178 static tree
fold_builtin_unordered_cmp (tree
, tree
, enum tree_code
,
180 static tree
fold_builtin_1 (tree
, tree
, bool);
182 static tree
fold_builtin_strpbrk (tree
, tree
);
183 static tree
fold_builtin_strstr (tree
, tree
);
184 static tree
fold_builtin_strrchr (tree
, tree
);
185 static tree
fold_builtin_strcat (tree
);
186 static tree
fold_builtin_strncat (tree
);
187 static tree
fold_builtin_strspn (tree
);
188 static tree
fold_builtin_strcspn (tree
);
189 static tree
fold_builtin_sprintf (tree
, int);
191 static rtx
expand_builtin_object_size (tree
);
192 static rtx
expand_builtin_memory_chk (tree
, rtx
, enum machine_mode
,
193 enum built_in_function
);
194 static void maybe_emit_chk_warning (tree
, enum built_in_function
);
195 static void maybe_emit_sprintf_chk_warning (tree
, enum built_in_function
);
196 static tree
fold_builtin_object_size (tree
);
197 static tree
fold_builtin_strcat_chk (tree
, tree
);
198 static tree
fold_builtin_strncat_chk (tree
, tree
);
199 static tree
fold_builtin_sprintf_chk (tree
, enum built_in_function
);
200 static tree
fold_builtin_printf (tree
, tree
, bool, enum built_in_function
);
201 static tree
fold_builtin_fprintf (tree
, tree
, bool, enum built_in_function
);
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_expr (TREE_VALUE (arglist
), NULL_RTX
, VOIDmode
, 0);
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_expr (t_label
, NULL_RTX
, VOIDmode
, 0);
846 r_label
= convert_memory_address (Pmode
, r_label
);
847 r_save_area
= expand_expr (t_save_area
, NULL_RTX
, VOIDmode
, 0);
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_expr (arg1
, NULL_RTX
, VOIDmode
, 0);
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_expr (arg2
, NULL_RTX
, VOIDmode
, 0);
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
, 0);
2023 op1
= expand_expr (arg1
, 0, VOIDmode
, 0);
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
;
2067 bool errno_set
= false;
2070 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
2073 arg
= TREE_VALUE (arglist
);
2075 switch (DECL_FUNCTION_CODE (fndecl
))
2077 CASE_FLT_FN (BUILT_IN_SIN
):
2078 CASE_FLT_FN (BUILT_IN_COS
):
2079 builtin_optab
= sincos_optab
; break;
2084 /* Make a suitable register to place result in. */
2085 mode
= TYPE_MODE (TREE_TYPE (exp
));
2087 if (! flag_errno_math
|| ! HONOR_NANS (mode
))
2090 /* Check if sincos insn is available, otherwise fallback
2091 to sin or cos insn. */
2092 if (builtin_optab
->handlers
[(int) mode
].insn_code
== CODE_FOR_nothing
) {
2093 switch (DECL_FUNCTION_CODE (fndecl
))
2095 CASE_FLT_FN (BUILT_IN_SIN
):
2096 builtin_optab
= sin_optab
; break;
2097 CASE_FLT_FN (BUILT_IN_COS
):
2098 builtin_optab
= cos_optab
; break;
2104 /* Before working hard, check whether the instruction is available. */
2105 if (builtin_optab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
)
2107 target
= gen_reg_rtx (mode
);
2109 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2110 need to expand the argument again. This way, we will not perform
2111 side-effects more the once. */
2112 narg
= save_expr (arg
);
2116 arglist
= build_tree_list (NULL_TREE
, arg
);
2117 exp
= build_function_call_expr (fndecl
, arglist
);
2120 op0
= expand_expr (arg
, subtarget
, VOIDmode
, 0);
2124 /* Compute into TARGET.
2125 Set TARGET to wherever the result comes back. */
2126 if (builtin_optab
== sincos_optab
)
2130 switch (DECL_FUNCTION_CODE (fndecl
))
2132 CASE_FLT_FN (BUILT_IN_SIN
):
2133 result
= expand_twoval_unop (builtin_optab
, op0
, 0, target
, 0);
2135 CASE_FLT_FN (BUILT_IN_COS
):
2136 result
= expand_twoval_unop (builtin_optab
, op0
, target
, 0, 0);
2141 gcc_assert (result
);
2145 target
= expand_unop (mode
, builtin_optab
, op0
, target
, 0);
2151 expand_errno_check (exp
, target
);
2153 /* Output the entire sequence. */
2154 insns
= get_insns ();
2160 /* If we were unable to expand via the builtin, stop the sequence
2161 (without outputting the insns) and call to the library function
2162 with the stabilized argument list. */
2166 target
= expand_call (exp
, target
, target
== const0_rtx
);
2171 /* Expand a call to one of the builtin rounding functions (lfloor).
2172 If expanding via optab fails, lower expression to (int)(floor(x)).
2173 EXP is the expression that is a call to the builtin function;
2174 if convenient, the result should be placed in TARGET. SUBTARGET may
2175 be used as the target for computing one of EXP's operands. */
2178 expand_builtin_int_roundingfn (tree exp
, rtx target
, rtx subtarget
)
2180 optab builtin_optab
;
2181 rtx op0
, insns
, tmp
;
2182 tree fndecl
= get_callee_fndecl (exp
);
2183 tree arglist
= TREE_OPERAND (exp
, 1);
2184 enum built_in_function fallback_fn
;
2185 tree fallback_fndecl
;
2186 enum machine_mode mode
;
2189 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
2192 arg
= TREE_VALUE (arglist
);
2194 switch (DECL_FUNCTION_CODE (fndecl
))
2196 CASE_FLT_FN (BUILT_IN_LCEIL
):
2197 CASE_FLT_FN (BUILT_IN_LLCEIL
):
2198 builtin_optab
= lceil_optab
;
2199 fallback_fn
= BUILT_IN_CEIL
;
2202 CASE_FLT_FN (BUILT_IN_LFLOOR
):
2203 CASE_FLT_FN (BUILT_IN_LLFLOOR
):
2204 builtin_optab
= lfloor_optab
;
2205 fallback_fn
= BUILT_IN_FLOOR
;
2212 /* Make a suitable register to place result in. */
2213 mode
= TYPE_MODE (TREE_TYPE (exp
));
2215 /* Before working hard, check whether the instruction is available. */
2216 if (builtin_optab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
)
2218 target
= gen_reg_rtx (mode
);
2220 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2221 need to expand the argument again. This way, we will not perform
2222 side-effects more the once. */
2223 narg
= builtin_save_expr (arg
);
2227 arglist
= build_tree_list (NULL_TREE
, arg
);
2228 exp
= build_function_call_expr (fndecl
, arglist
);
2231 op0
= expand_expr (arg
, subtarget
, VOIDmode
, 0);
2235 /* Compute into TARGET.
2236 Set TARGET to wherever the result comes back. */
2237 target
= expand_unop (mode
, builtin_optab
, op0
, target
, 0);
2241 /* Output the entire sequence. */
2242 insns
= get_insns ();
2248 /* If we were unable to expand via the builtin, stop the sequence
2249 (without outputting the insns). */
2253 /* Fall back to floating point rounding optab. */
2254 fallback_fndecl
= mathfn_built_in (TREE_TYPE (arg
), fallback_fn
);
2255 /* We shouldn't get here on targets without TARGET_C99_FUNCTIONS.
2256 ??? Perhaps convert (int)floorf(x) into (int)floor((double)x). */
2257 gcc_assert (fallback_fndecl
!= NULL_TREE
);
2258 exp
= build_function_call_expr (fallback_fndecl
, arglist
);
2260 tmp
= expand_builtin_mathfn (exp
, NULL_RTX
, NULL_RTX
);
2262 /* Truncate the result of floating point optab to integer
2263 via expand_fix (). */
2264 target
= gen_reg_rtx (mode
);
2265 expand_fix (target
, tmp
, 0);
2270 /* To evaluate powi(x,n), the floating point value x raised to the
2271 constant integer exponent n, we use a hybrid algorithm that
2272 combines the "window method" with look-up tables. For an
2273 introduction to exponentiation algorithms and "addition chains",
2274 see section 4.6.3, "Evaluation of Powers" of Donald E. Knuth,
2275 "Seminumerical Algorithms", Vol. 2, "The Art of Computer Programming",
2276 3rd Edition, 1998, and Daniel M. Gordon, "A Survey of Fast Exponentiation
2277 Methods", Journal of Algorithms, Vol. 27, pp. 129-146, 1998. */
2279 /* Provide a default value for POWI_MAX_MULTS, the maximum number of
2280 multiplications to inline before calling the system library's pow
2281 function. powi(x,n) requires at worst 2*bits(n)-2 multiplications,
2282 so this default never requires calling pow, powf or powl. */
2284 #ifndef POWI_MAX_MULTS
2285 #define POWI_MAX_MULTS (2*HOST_BITS_PER_WIDE_INT-2)
2288 /* The size of the "optimal power tree" lookup table. All
2289 exponents less than this value are simply looked up in the
2290 powi_table below. This threshold is also used to size the
2291 cache of pseudo registers that hold intermediate results. */
2292 #define POWI_TABLE_SIZE 256
2294 /* The size, in bits of the window, used in the "window method"
2295 exponentiation algorithm. This is equivalent to a radix of
2296 (1<<POWI_WINDOW_SIZE) in the corresponding "m-ary method". */
2297 #define POWI_WINDOW_SIZE 3
2299 /* The following table is an efficient representation of an
2300 "optimal power tree". For each value, i, the corresponding
2301 value, j, in the table states than an optimal evaluation
2302 sequence for calculating pow(x,i) can be found by evaluating
2303 pow(x,j)*pow(x,i-j). An optimal power tree for the first
2304 100 integers is given in Knuth's "Seminumerical algorithms". */
2306 static const unsigned char powi_table
[POWI_TABLE_SIZE
] =
2308 0, 1, 1, 2, 2, 3, 3, 4, /* 0 - 7 */
2309 4, 6, 5, 6, 6, 10, 7, 9, /* 8 - 15 */
2310 8, 16, 9, 16, 10, 12, 11, 13, /* 16 - 23 */
2311 12, 17, 13, 18, 14, 24, 15, 26, /* 24 - 31 */
2312 16, 17, 17, 19, 18, 33, 19, 26, /* 32 - 39 */
2313 20, 25, 21, 40, 22, 27, 23, 44, /* 40 - 47 */
2314 24, 32, 25, 34, 26, 29, 27, 44, /* 48 - 55 */
2315 28, 31, 29, 34, 30, 60, 31, 36, /* 56 - 63 */
2316 32, 64, 33, 34, 34, 46, 35, 37, /* 64 - 71 */
2317 36, 65, 37, 50, 38, 48, 39, 69, /* 72 - 79 */
2318 40, 49, 41, 43, 42, 51, 43, 58, /* 80 - 87 */
2319 44, 64, 45, 47, 46, 59, 47, 76, /* 88 - 95 */
2320 48, 65, 49, 66, 50, 67, 51, 66, /* 96 - 103 */
2321 52, 70, 53, 74, 54, 104, 55, 74, /* 104 - 111 */
2322 56, 64, 57, 69, 58, 78, 59, 68, /* 112 - 119 */
2323 60, 61, 61, 80, 62, 75, 63, 68, /* 120 - 127 */
2324 64, 65, 65, 128, 66, 129, 67, 90, /* 128 - 135 */
2325 68, 73, 69, 131, 70, 94, 71, 88, /* 136 - 143 */
2326 72, 128, 73, 98, 74, 132, 75, 121, /* 144 - 151 */
2327 76, 102, 77, 124, 78, 132, 79, 106, /* 152 - 159 */
2328 80, 97, 81, 160, 82, 99, 83, 134, /* 160 - 167 */
2329 84, 86, 85, 95, 86, 160, 87, 100, /* 168 - 175 */
2330 88, 113, 89, 98, 90, 107, 91, 122, /* 176 - 183 */
2331 92, 111, 93, 102, 94, 126, 95, 150, /* 184 - 191 */
2332 96, 128, 97, 130, 98, 133, 99, 195, /* 192 - 199 */
2333 100, 128, 101, 123, 102, 164, 103, 138, /* 200 - 207 */
2334 104, 145, 105, 146, 106, 109, 107, 149, /* 208 - 215 */
2335 108, 200, 109, 146, 110, 170, 111, 157, /* 216 - 223 */
2336 112, 128, 113, 130, 114, 182, 115, 132, /* 224 - 231 */
2337 116, 200, 117, 132, 118, 158, 119, 206, /* 232 - 239 */
2338 120, 240, 121, 162, 122, 147, 123, 152, /* 240 - 247 */
2339 124, 166, 125, 214, 126, 138, 127, 153, /* 248 - 255 */
2343 /* Return the number of multiplications required to calculate
2344 powi(x,n) where n is less than POWI_TABLE_SIZE. This is a
2345 subroutine of powi_cost. CACHE is an array indicating
2346 which exponents have already been calculated. */
2349 powi_lookup_cost (unsigned HOST_WIDE_INT n
, bool *cache
)
2351 /* If we've already calculated this exponent, then this evaluation
2352 doesn't require any additional multiplications. */
2357 return powi_lookup_cost (n
- powi_table
[n
], cache
)
2358 + powi_lookup_cost (powi_table
[n
], cache
) + 1;
2361 /* Return the number of multiplications required to calculate
2362 powi(x,n) for an arbitrary x, given the exponent N. This
2363 function needs to be kept in sync with expand_powi below. */
2366 powi_cost (HOST_WIDE_INT n
)
2368 bool cache
[POWI_TABLE_SIZE
];
2369 unsigned HOST_WIDE_INT digit
;
2370 unsigned HOST_WIDE_INT val
;
2376 /* Ignore the reciprocal when calculating the cost. */
2377 val
= (n
< 0) ? -n
: n
;
2379 /* Initialize the exponent cache. */
2380 memset (cache
, 0, POWI_TABLE_SIZE
* sizeof (bool));
2385 while (val
>= POWI_TABLE_SIZE
)
2389 digit
= val
& ((1 << POWI_WINDOW_SIZE
) - 1);
2390 result
+= powi_lookup_cost (digit
, cache
)
2391 + POWI_WINDOW_SIZE
+ 1;
2392 val
>>= POWI_WINDOW_SIZE
;
2401 return result
+ powi_lookup_cost (val
, cache
);
2404 /* Recursive subroutine of expand_powi. This function takes the array,
2405 CACHE, of already calculated exponents and an exponent N and returns
2406 an RTX that corresponds to CACHE[1]**N, as calculated in mode MODE. */
2409 expand_powi_1 (enum machine_mode mode
, unsigned HOST_WIDE_INT n
, rtx
*cache
)
2411 unsigned HOST_WIDE_INT digit
;
2415 if (n
< POWI_TABLE_SIZE
)
2420 target
= gen_reg_rtx (mode
);
2423 op0
= expand_powi_1 (mode
, n
- powi_table
[n
], cache
);
2424 op1
= expand_powi_1 (mode
, powi_table
[n
], cache
);
2428 target
= gen_reg_rtx (mode
);
2429 digit
= n
& ((1 << POWI_WINDOW_SIZE
) - 1);
2430 op0
= expand_powi_1 (mode
, n
- digit
, cache
);
2431 op1
= expand_powi_1 (mode
, digit
, cache
);
2435 target
= gen_reg_rtx (mode
);
2436 op0
= expand_powi_1 (mode
, n
>> 1, cache
);
2440 result
= expand_mult (mode
, op0
, op1
, target
, 0);
2441 if (result
!= target
)
2442 emit_move_insn (target
, result
);
2446 /* Expand the RTL to evaluate powi(x,n) in mode MODE. X is the
2447 floating point operand in mode MODE, and N is the exponent. This
2448 function needs to be kept in sync with powi_cost above. */
2451 expand_powi (rtx x
, enum machine_mode mode
, HOST_WIDE_INT n
)
2453 unsigned HOST_WIDE_INT val
;
2454 rtx cache
[POWI_TABLE_SIZE
];
2458 return CONST1_RTX (mode
);
2460 val
= (n
< 0) ? -n
: n
;
2462 memset (cache
, 0, sizeof (cache
));
2465 result
= expand_powi_1 (mode
, (n
< 0) ? -n
: n
, cache
);
2467 /* If the original exponent was negative, reciprocate the result. */
2469 result
= expand_binop (mode
, sdiv_optab
, CONST1_RTX (mode
),
2470 result
, NULL_RTX
, 0, OPTAB_LIB_WIDEN
);
2475 /* Expand a call to the pow built-in mathematical function. Return 0 if
2476 a normal call should be emitted rather than expanding the function
2477 in-line. EXP is the expression that is a call to the builtin
2478 function; if convenient, the result should be placed in TARGET. */
2481 expand_builtin_pow (tree exp
, rtx target
, rtx subtarget
)
2483 tree arglist
= TREE_OPERAND (exp
, 1);
2486 if (! validate_arglist (arglist
, REAL_TYPE
, REAL_TYPE
, VOID_TYPE
))
2489 arg0
= TREE_VALUE (arglist
);
2490 arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
2492 if (TREE_CODE (arg1
) == REAL_CST
2493 && ! TREE_CONSTANT_OVERFLOW (arg1
))
2495 REAL_VALUE_TYPE cint
;
2499 c
= TREE_REAL_CST (arg1
);
2500 n
= real_to_integer (&c
);
2501 real_from_integer (&cint
, VOIDmode
, n
, n
< 0 ? -1 : 0, 0);
2502 if (real_identical (&c
, &cint
))
2504 /* If the exponent is -1, 0, 1 or 2, then expand_powi is exact.
2505 Otherwise, check the number of multiplications required.
2506 Note that pow never sets errno for an integer exponent. */
2507 if ((n
>= -1 && n
<= 2)
2508 || (flag_unsafe_math_optimizations
2510 && powi_cost (n
) <= POWI_MAX_MULTS
))
2512 enum machine_mode mode
= TYPE_MODE (TREE_TYPE (exp
));
2513 rtx op
= expand_expr (arg0
, subtarget
, VOIDmode
, 0);
2514 op
= force_reg (mode
, op
);
2515 return expand_powi (op
, mode
, n
);
2520 if (! flag_unsafe_math_optimizations
)
2522 return expand_builtin_mathfn_2 (exp
, target
, subtarget
);
2525 /* Expand a call to the powi built-in mathematical function. Return 0 if
2526 a normal call should be emitted rather than expanding the function
2527 in-line. EXP is the expression that is a call to the builtin
2528 function; if convenient, the result should be placed in TARGET. */
2531 expand_builtin_powi (tree exp
, rtx target
, rtx subtarget
)
2533 tree arglist
= TREE_OPERAND (exp
, 1);
2536 enum machine_mode mode
;
2537 enum machine_mode mode2
;
2539 if (! validate_arglist (arglist
, REAL_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
2542 arg0
= TREE_VALUE (arglist
);
2543 arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
2544 mode
= TYPE_MODE (TREE_TYPE (exp
));
2546 /* Handle constant power. */
2548 if (TREE_CODE (arg1
) == INTEGER_CST
2549 && ! TREE_CONSTANT_OVERFLOW (arg1
))
2551 HOST_WIDE_INT n
= TREE_INT_CST_LOW (arg1
);
2553 /* If the exponent is -1, 0, 1 or 2, then expand_powi is exact.
2554 Otherwise, check the number of multiplications required. */
2555 if ((TREE_INT_CST_HIGH (arg1
) == 0
2556 || TREE_INT_CST_HIGH (arg1
) == -1)
2557 && ((n
>= -1 && n
<= 2)
2559 && powi_cost (n
) <= POWI_MAX_MULTS
)))
2561 op0
= expand_expr (arg0
, subtarget
, VOIDmode
, 0);
2562 op0
= force_reg (mode
, op0
);
2563 return expand_powi (op0
, mode
, n
);
2567 /* Emit a libcall to libgcc. */
2569 /* Mode of the 2nd argument must match that of an int. */
2570 mode2
= mode_for_size (INT_TYPE_SIZE
, MODE_INT
, 0);
2572 if (target
== NULL_RTX
)
2573 target
= gen_reg_rtx (mode
);
2575 op0
= expand_expr (arg0
, subtarget
, mode
, 0);
2576 if (GET_MODE (op0
) != mode
)
2577 op0
= convert_to_mode (mode
, op0
, 0);
2578 op1
= expand_expr (arg1
, 0, mode2
, 0);
2579 if (GET_MODE (op1
) != mode2
)
2580 op1
= convert_to_mode (mode2
, op1
, 0);
2582 target
= emit_library_call_value (powi_optab
->handlers
[(int) mode
].libfunc
,
2583 target
, LCT_CONST_MAKE_BLOCK
, mode
, 2,
2584 op0
, mode
, op1
, mode2
);
2589 /* Expand expression EXP which is a call to the strlen builtin. Return 0
2590 if we failed the caller should emit a normal call, otherwise
2591 try to get the result in TARGET, if convenient. */
2594 expand_builtin_strlen (tree arglist
, rtx target
,
2595 enum machine_mode target_mode
)
2597 if (!validate_arglist (arglist
, POINTER_TYPE
, VOID_TYPE
))
2602 tree len
, src
= TREE_VALUE (arglist
);
2603 rtx result
, src_reg
, char_rtx
, before_strlen
;
2604 enum machine_mode insn_mode
= target_mode
, char_mode
;
2605 enum insn_code icode
= CODE_FOR_nothing
;
2608 /* If the length can be computed at compile-time, return it. */
2609 len
= c_strlen (src
, 0);
2611 return expand_expr (len
, target
, target_mode
, EXPAND_NORMAL
);
2613 /* If the length can be computed at compile-time and is constant
2614 integer, but there are side-effects in src, evaluate
2615 src for side-effects, then return len.
2616 E.g. x = strlen (i++ ? "xfoo" + 1 : "bar");
2617 can be optimized into: i++; x = 3; */
2618 len
= c_strlen (src
, 1);
2619 if (len
&& TREE_CODE (len
) == INTEGER_CST
)
2621 expand_expr (src
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
2622 return expand_expr (len
, target
, target_mode
, EXPAND_NORMAL
);
2625 align
= get_pointer_alignment (src
, BIGGEST_ALIGNMENT
) / BITS_PER_UNIT
;
2627 /* If SRC is not a pointer type, don't do this operation inline. */
2631 /* Bail out if we can't compute strlen in the right mode. */
2632 while (insn_mode
!= VOIDmode
)
2634 icode
= strlen_optab
->handlers
[(int) insn_mode
].insn_code
;
2635 if (icode
!= CODE_FOR_nothing
)
2638 insn_mode
= GET_MODE_WIDER_MODE (insn_mode
);
2640 if (insn_mode
== VOIDmode
)
2643 /* Make a place to write the result of the instruction. */
2647 && GET_MODE (result
) == insn_mode
2648 && REGNO (result
) >= FIRST_PSEUDO_REGISTER
))
2649 result
= gen_reg_rtx (insn_mode
);
2651 /* Make a place to hold the source address. We will not expand
2652 the actual source until we are sure that the expansion will
2653 not fail -- there are trees that cannot be expanded twice. */
2654 src_reg
= gen_reg_rtx (Pmode
);
2656 /* Mark the beginning of the strlen sequence so we can emit the
2657 source operand later. */
2658 before_strlen
= get_last_insn ();
2660 char_rtx
= const0_rtx
;
2661 char_mode
= insn_data
[(int) icode
].operand
[2].mode
;
2662 if (! (*insn_data
[(int) icode
].operand
[2].predicate
) (char_rtx
,
2664 char_rtx
= copy_to_mode_reg (char_mode
, char_rtx
);
2666 pat
= GEN_FCN (icode
) (result
, gen_rtx_MEM (BLKmode
, src_reg
),
2667 char_rtx
, GEN_INT (align
));
2672 /* Now that we are assured of success, expand the source. */
2674 pat
= expand_expr (src
, src_reg
, ptr_mode
, EXPAND_NORMAL
);
2676 emit_move_insn (src_reg
, pat
);
2681 emit_insn_after (pat
, before_strlen
);
2683 emit_insn_before (pat
, get_insns ());
2685 /* Return the value in the proper mode for this function. */
2686 if (GET_MODE (result
) == target_mode
)
2688 else if (target
!= 0)
2689 convert_move (target
, result
, 0);
2691 target
= convert_to_mode (target_mode
, result
, 0);
2697 /* Expand a call to the strstr builtin. Return 0 if we failed the
2698 caller should emit a normal call, otherwise try to get the result
2699 in TARGET, if convenient (and in mode MODE if that's convenient). */
2702 expand_builtin_strstr (tree arglist
, tree type
, rtx target
, enum machine_mode mode
)
2704 if (validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
2706 tree result
= fold_builtin_strstr (arglist
, type
);
2708 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
2713 /* Expand a call to the strchr builtin. Return 0 if we failed the
2714 caller should emit a normal call, otherwise try to get the result
2715 in TARGET, if convenient (and in mode MODE if that's convenient). */
2718 expand_builtin_strchr (tree arglist
, tree type
, rtx target
, enum machine_mode mode
)
2720 if (validate_arglist (arglist
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
2722 tree result
= fold_builtin_strchr (arglist
, type
);
2724 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
2726 /* FIXME: Should use strchrM optab so that ports can optimize this. */
2731 /* Expand a call to the strrchr builtin. Return 0 if we failed the
2732 caller should emit a normal call, otherwise try to get the result
2733 in TARGET, if convenient (and in mode MODE if that's convenient). */
2736 expand_builtin_strrchr (tree arglist
, tree type
, rtx target
, enum machine_mode mode
)
2738 if (validate_arglist (arglist
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
2740 tree result
= fold_builtin_strrchr (arglist
, type
);
2742 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
2747 /* Expand a call to the strpbrk builtin. Return 0 if we failed the
2748 caller should emit a normal call, otherwise try to get the result
2749 in TARGET, if convenient (and in mode MODE if that's convenient). */
2752 expand_builtin_strpbrk (tree arglist
, tree type
, rtx target
, enum machine_mode mode
)
2754 if (validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
2756 tree result
= fold_builtin_strpbrk (arglist
, type
);
2758 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
2763 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
2764 bytes from constant string DATA + OFFSET and return it as target
2768 builtin_memcpy_read_str (void *data
, HOST_WIDE_INT offset
,
2769 enum machine_mode mode
)
2771 const char *str
= (const char *) data
;
2773 gcc_assert (offset
>= 0
2774 && ((unsigned HOST_WIDE_INT
) offset
+ GET_MODE_SIZE (mode
)
2775 <= strlen (str
) + 1));
2777 return c_readstr (str
+ offset
, mode
);
2780 /* Expand a call to the memcpy builtin, with arguments in ARGLIST.
2781 Return 0 if we failed, the caller should emit a normal call,
2782 otherwise try to get the result in TARGET, if convenient (and in
2783 mode MODE if that's convenient). */
2785 expand_builtin_memcpy (tree exp
, rtx target
, enum machine_mode mode
)
2787 tree fndecl
= get_callee_fndecl (exp
);
2788 tree arglist
= TREE_OPERAND (exp
, 1);
2789 if (!validate_arglist (arglist
,
2790 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
2794 tree dest
= TREE_VALUE (arglist
);
2795 tree src
= TREE_VALUE (TREE_CHAIN (arglist
));
2796 tree len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
2797 const char *src_str
;
2798 unsigned int src_align
= get_pointer_alignment (src
, BIGGEST_ALIGNMENT
);
2799 unsigned int dest_align
2800 = get_pointer_alignment (dest
, BIGGEST_ALIGNMENT
);
2801 rtx dest_mem
, src_mem
, dest_addr
, len_rtx
;
2802 tree result
= fold_builtin_memcpy (fndecl
, arglist
);
2805 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
2807 /* If DEST is not a pointer type, call the normal function. */
2808 if (dest_align
== 0)
2811 /* If either SRC is not a pointer type, don't do this
2812 operation in-line. */
2816 dest_mem
= get_memory_rtx (dest
, len
);
2817 set_mem_align (dest_mem
, dest_align
);
2818 len_rtx
= expand_expr (len
, NULL_RTX
, VOIDmode
, 0);
2819 src_str
= c_getstr (src
);
2821 /* If SRC is a string constant and block move would be done
2822 by pieces, we can avoid loading the string from memory
2823 and only stored the computed constants. */
2825 && GET_CODE (len_rtx
) == CONST_INT
2826 && (unsigned HOST_WIDE_INT
) INTVAL (len_rtx
) <= strlen (src_str
) + 1
2827 && can_store_by_pieces (INTVAL (len_rtx
), builtin_memcpy_read_str
,
2828 (void *) src_str
, dest_align
))
2830 dest_mem
= store_by_pieces (dest_mem
, INTVAL (len_rtx
),
2831 builtin_memcpy_read_str
,
2832 (void *) src_str
, dest_align
, 0);
2833 dest_mem
= force_operand (XEXP (dest_mem
, 0), NULL_RTX
);
2834 dest_mem
= convert_memory_address (ptr_mode
, dest_mem
);
2838 src_mem
= get_memory_rtx (src
, len
);
2839 set_mem_align (src_mem
, src_align
);
2841 /* Copy word part most expediently. */
2842 dest_addr
= emit_block_move (dest_mem
, src_mem
, len_rtx
,
2843 CALL_EXPR_TAILCALL (exp
)
2844 ? BLOCK_OP_TAILCALL
: BLOCK_OP_NORMAL
);
2848 dest_addr
= force_operand (XEXP (dest_mem
, 0), NULL_RTX
);
2849 dest_addr
= convert_memory_address (ptr_mode
, dest_addr
);
2855 /* Expand a call to the mempcpy builtin, with arguments in ARGLIST.
2856 Return 0 if we failed; the caller should emit a normal call,
2857 otherwise try to get the result in TARGET, if convenient (and in
2858 mode MODE if that's convenient). If ENDP is 0 return the
2859 destination pointer, if ENDP is 1 return the end pointer ala
2860 mempcpy, and if ENDP is 2 return the end pointer minus one ala
2864 expand_builtin_mempcpy (tree arglist
, tree type
, rtx target
, enum machine_mode mode
,
2867 if (!validate_arglist (arglist
,
2868 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
2870 /* If return value is ignored, transform mempcpy into memcpy. */
2871 else if (target
== const0_rtx
)
2873 tree fn
= implicit_built_in_decls
[BUILT_IN_MEMCPY
];
2878 return expand_expr (build_function_call_expr (fn
, arglist
),
2879 target
, mode
, EXPAND_NORMAL
);
2883 tree dest
= TREE_VALUE (arglist
);
2884 tree src
= TREE_VALUE (TREE_CHAIN (arglist
));
2885 tree len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
2886 const char *src_str
;
2887 unsigned int src_align
= get_pointer_alignment (src
, BIGGEST_ALIGNMENT
);
2888 unsigned int dest_align
2889 = get_pointer_alignment (dest
, BIGGEST_ALIGNMENT
);
2890 rtx dest_mem
, src_mem
, len_rtx
;
2891 tree result
= fold_builtin_mempcpy (arglist
, type
, endp
);
2894 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
2896 /* If either SRC or DEST is not a pointer type, don't do this
2897 operation in-line. */
2898 if (dest_align
== 0 || src_align
== 0)
2901 /* If LEN is not constant, call the normal function. */
2902 if (! host_integerp (len
, 1))
2905 len_rtx
= expand_expr (len
, NULL_RTX
, VOIDmode
, 0);
2906 src_str
= c_getstr (src
);
2908 /* If SRC is a string constant and block move would be done
2909 by pieces, we can avoid loading the string from memory
2910 and only stored the computed constants. */
2912 && GET_CODE (len_rtx
) == CONST_INT
2913 && (unsigned HOST_WIDE_INT
) INTVAL (len_rtx
) <= strlen (src_str
) + 1
2914 && can_store_by_pieces (INTVAL (len_rtx
), builtin_memcpy_read_str
,
2915 (void *) src_str
, dest_align
))
2917 dest_mem
= get_memory_rtx (dest
, len
);
2918 set_mem_align (dest_mem
, dest_align
);
2919 dest_mem
= store_by_pieces (dest_mem
, INTVAL (len_rtx
),
2920 builtin_memcpy_read_str
,
2921 (void *) src_str
, dest_align
, endp
);
2922 dest_mem
= force_operand (XEXP (dest_mem
, 0), NULL_RTX
);
2923 dest_mem
= convert_memory_address (ptr_mode
, dest_mem
);
2927 if (GET_CODE (len_rtx
) == CONST_INT
2928 && can_move_by_pieces (INTVAL (len_rtx
),
2929 MIN (dest_align
, src_align
)))
2931 dest_mem
= get_memory_rtx (dest
, len
);
2932 set_mem_align (dest_mem
, dest_align
);
2933 src_mem
= get_memory_rtx (src
, len
);
2934 set_mem_align (src_mem
, src_align
);
2935 dest_mem
= move_by_pieces (dest_mem
, src_mem
, INTVAL (len_rtx
),
2936 MIN (dest_align
, src_align
), endp
);
2937 dest_mem
= force_operand (XEXP (dest_mem
, 0), NULL_RTX
);
2938 dest_mem
= convert_memory_address (ptr_mode
, dest_mem
);
2946 /* Expand expression EXP, which is a call to the memmove builtin. Return 0
2947 if we failed; the caller should emit a normal call. */
2950 expand_builtin_memmove (tree arglist
, tree type
, rtx target
,
2951 enum machine_mode mode
, tree orig_exp
)
2953 if (!validate_arglist (arglist
,
2954 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
2958 tree dest
= TREE_VALUE (arglist
);
2959 tree src
= TREE_VALUE (TREE_CHAIN (arglist
));
2960 tree len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
2962 unsigned int src_align
= get_pointer_alignment (src
, BIGGEST_ALIGNMENT
);
2963 unsigned int dest_align
2964 = get_pointer_alignment (dest
, BIGGEST_ALIGNMENT
);
2965 tree result
= fold_builtin_memmove (arglist
, type
);
2968 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
2970 /* If DEST is not a pointer type, call the normal function. */
2971 if (dest_align
== 0)
2974 /* If either SRC is not a pointer type, don't do this
2975 operation in-line. */
2979 /* If src is categorized for a readonly section we can use
2981 if (readonly_data_expr (src
))
2983 tree fn
= implicit_built_in_decls
[BUILT_IN_MEMCPY
];
2986 fn
= build_function_call_expr (fn
, arglist
);
2987 if (TREE_CODE (fn
) == CALL_EXPR
)
2988 CALL_EXPR_TAILCALL (fn
) = CALL_EXPR_TAILCALL (orig_exp
);
2989 return expand_expr (fn
, target
, mode
, EXPAND_NORMAL
);
2992 /* If length is 1 and we can expand memcpy call inline,
2993 it is ok to use memcpy as well. */
2994 if (integer_onep (len
))
2996 rtx ret
= expand_builtin_mempcpy (arglist
, type
, target
, mode
,
3002 /* Otherwise, call the normal function. */
3007 /* Expand expression EXP, which is a call to the bcopy builtin. Return 0
3008 if we failed the caller should emit a normal call. */
3011 expand_builtin_bcopy (tree exp
)
3013 tree arglist
= TREE_OPERAND (exp
, 1);
3014 tree type
= TREE_TYPE (exp
);
3015 tree src
, dest
, size
, newarglist
;
3017 if (!validate_arglist (arglist
,
3018 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
3021 src
= TREE_VALUE (arglist
);
3022 dest
= TREE_VALUE (TREE_CHAIN (arglist
));
3023 size
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
3025 /* New argument list transforming bcopy(ptr x, ptr y, int z) to
3026 memmove(ptr y, ptr x, size_t z). This is done this way
3027 so that if it isn't expanded inline, we fallback to
3028 calling bcopy instead of memmove. */
3030 newarglist
= build_tree_list (NULL_TREE
, fold_convert (sizetype
, size
));
3031 newarglist
= tree_cons (NULL_TREE
, src
, newarglist
);
3032 newarglist
= tree_cons (NULL_TREE
, dest
, newarglist
);
3034 return expand_builtin_memmove (newarglist
, type
, const0_rtx
, VOIDmode
, exp
);
3038 # define HAVE_movstr 0
3039 # define CODE_FOR_movstr CODE_FOR_nothing
3042 /* Expand into a movstr instruction, if one is available. Return 0 if
3043 we failed, the caller should emit a normal call, otherwise try to
3044 get the result in TARGET, if convenient. If ENDP is 0 return the
3045 destination pointer, if ENDP is 1 return the end pointer ala
3046 mempcpy, and if ENDP is 2 return the end pointer minus one ala
3050 expand_movstr (tree dest
, tree src
, rtx target
, int endp
)
3056 const struct insn_data
* data
;
3061 dest_mem
= get_memory_rtx (dest
, NULL
);
3062 src_mem
= get_memory_rtx (src
, NULL
);
3065 target
= force_reg (Pmode
, XEXP (dest_mem
, 0));
3066 dest_mem
= replace_equiv_address (dest_mem
, target
);
3067 end
= gen_reg_rtx (Pmode
);
3071 if (target
== 0 || target
== const0_rtx
)
3073 end
= gen_reg_rtx (Pmode
);
3081 data
= insn_data
+ CODE_FOR_movstr
;
3083 if (data
->operand
[0].mode
!= VOIDmode
)
3084 end
= gen_lowpart (data
->operand
[0].mode
, end
);
3086 insn
= data
->genfun (end
, dest_mem
, src_mem
);
3092 /* movstr is supposed to set end to the address of the NUL
3093 terminator. If the caller requested a mempcpy-like return value,
3095 if (endp
== 1 && target
!= const0_rtx
)
3097 rtx tem
= plus_constant (gen_lowpart (GET_MODE (target
), end
), 1);
3098 emit_move_insn (target
, force_operand (tem
, NULL_RTX
));
3104 /* Expand expression EXP, which is a call to the strcpy builtin. Return 0
3105 if we failed the caller should emit a normal call, otherwise try to get
3106 the result in TARGET, if convenient (and in mode MODE if that's
3110 expand_builtin_strcpy (tree fndecl
, tree arglist
, rtx target
, enum machine_mode mode
)
3112 if (validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
3114 tree result
= fold_builtin_strcpy (fndecl
, arglist
, 0);
3116 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
3118 return expand_movstr (TREE_VALUE (arglist
),
3119 TREE_VALUE (TREE_CHAIN (arglist
)),
3120 target
, /*endp=*/0);
3125 /* Expand a call to the stpcpy builtin, with arguments in ARGLIST.
3126 Return 0 if we failed the caller should emit a normal call,
3127 otherwise try to get the result in TARGET, if convenient (and in
3128 mode MODE if that's convenient). */
3131 expand_builtin_stpcpy (tree exp
, rtx target
, enum machine_mode mode
)
3133 tree arglist
= TREE_OPERAND (exp
, 1);
3134 /* If return value is ignored, transform stpcpy into strcpy. */
3135 if (target
== const0_rtx
)
3137 tree fn
= implicit_built_in_decls
[BUILT_IN_STRCPY
];
3141 return expand_expr (build_function_call_expr (fn
, arglist
),
3142 target
, mode
, EXPAND_NORMAL
);
3145 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
3149 tree dst
, src
, len
, lenp1
;
3153 /* Ensure we get an actual string whose length can be evaluated at
3154 compile-time, not an expression containing a string. This is
3155 because the latter will potentially produce pessimized code
3156 when used to produce the return value. */
3157 src
= TREE_VALUE (TREE_CHAIN (arglist
));
3158 if (! c_getstr (src
) || ! (len
= c_strlen (src
, 0)))
3159 return expand_movstr (TREE_VALUE (arglist
),
3160 TREE_VALUE (TREE_CHAIN (arglist
)),
3161 target
, /*endp=*/2);
3163 dst
= TREE_VALUE (arglist
);
3164 lenp1
= size_binop (PLUS_EXPR
, len
, ssize_int (1));
3165 narglist
= build_tree_list (NULL_TREE
, lenp1
);
3166 narglist
= tree_cons (NULL_TREE
, src
, narglist
);
3167 narglist
= tree_cons (NULL_TREE
, dst
, narglist
);
3168 ret
= expand_builtin_mempcpy (narglist
, TREE_TYPE (exp
),
3169 target
, mode
, /*endp=*/2);
3174 if (TREE_CODE (len
) == INTEGER_CST
)
3176 rtx len_rtx
= expand_expr (len
, NULL_RTX
, VOIDmode
, 0);
3178 if (GET_CODE (len_rtx
) == CONST_INT
)
3180 ret
= expand_builtin_strcpy (get_callee_fndecl (exp
),
3181 arglist
, target
, mode
);
3187 if (mode
!= VOIDmode
)
3188 target
= gen_reg_rtx (mode
);
3190 target
= gen_reg_rtx (GET_MODE (ret
));
3192 if (GET_MODE (target
) != GET_MODE (ret
))
3193 ret
= gen_lowpart (GET_MODE (target
), ret
);
3195 ret
= plus_constant (ret
, INTVAL (len_rtx
));
3196 ret
= emit_move_insn (target
, force_operand (ret
, NULL_RTX
));
3204 return expand_movstr (TREE_VALUE (arglist
),
3205 TREE_VALUE (TREE_CHAIN (arglist
)),
3206 target
, /*endp=*/2);
3210 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
3211 bytes from constant string DATA + OFFSET and return it as target
3215 builtin_strncpy_read_str (void *data
, HOST_WIDE_INT offset
,
3216 enum machine_mode mode
)
3218 const char *str
= (const char *) data
;
3220 if ((unsigned HOST_WIDE_INT
) offset
> strlen (str
))
3223 return c_readstr (str
+ offset
, mode
);
3226 /* Expand expression EXP, which is a call to the strncpy builtin. Return 0
3227 if we failed the caller should emit a normal call. */
3230 expand_builtin_strncpy (tree exp
, rtx target
, enum machine_mode mode
)
3232 tree fndecl
= get_callee_fndecl (exp
);
3233 tree arglist
= TREE_OPERAND (exp
, 1);
3234 if (validate_arglist (arglist
,
3235 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
3237 tree slen
= c_strlen (TREE_VALUE (TREE_CHAIN (arglist
)), 1);
3238 tree len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
3239 tree result
= fold_builtin_strncpy (fndecl
, arglist
, slen
);
3242 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
3244 /* We must be passed a constant len and src parameter. */
3245 if (!host_integerp (len
, 1) || !slen
|| !host_integerp (slen
, 1))
3248 slen
= size_binop (PLUS_EXPR
, slen
, ssize_int (1));
3250 /* We're required to pad with trailing zeros if the requested
3251 len is greater than strlen(s2)+1. In that case try to
3252 use store_by_pieces, if it fails, punt. */
3253 if (tree_int_cst_lt (slen
, len
))
3255 tree dest
= TREE_VALUE (arglist
);
3256 unsigned int dest_align
3257 = get_pointer_alignment (dest
, BIGGEST_ALIGNMENT
);
3258 const char *p
= c_getstr (TREE_VALUE (TREE_CHAIN (arglist
)));
3261 if (!p
|| dest_align
== 0 || !host_integerp (len
, 1)
3262 || !can_store_by_pieces (tree_low_cst (len
, 1),
3263 builtin_strncpy_read_str
,
3264 (void *) p
, dest_align
))
3267 dest_mem
= get_memory_rtx (dest
, len
);
3268 store_by_pieces (dest_mem
, tree_low_cst (len
, 1),
3269 builtin_strncpy_read_str
,
3270 (void *) p
, dest_align
, 0);
3271 dest_mem
= force_operand (XEXP (dest_mem
, 0), NULL_RTX
);
3272 dest_mem
= convert_memory_address (ptr_mode
, dest_mem
);
3279 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
3280 bytes from constant string DATA + OFFSET and return it as target
3284 builtin_memset_read_str (void *data
, HOST_WIDE_INT offset ATTRIBUTE_UNUSED
,
3285 enum machine_mode mode
)
3287 const char *c
= (const char *) data
;
3288 char *p
= alloca (GET_MODE_SIZE (mode
));
3290 memset (p
, *c
, GET_MODE_SIZE (mode
));
3292 return c_readstr (p
, mode
);
3295 /* Callback routine for store_by_pieces. Return the RTL of a register
3296 containing GET_MODE_SIZE (MODE) consecutive copies of the unsigned
3297 char value given in the RTL register data. For example, if mode is
3298 4 bytes wide, return the RTL for 0x01010101*data. */
3301 builtin_memset_gen_str (void *data
, HOST_WIDE_INT offset ATTRIBUTE_UNUSED
,
3302 enum machine_mode mode
)
3308 size
= GET_MODE_SIZE (mode
);
3313 memset (p
, 1, size
);
3314 coeff
= c_readstr (p
, mode
);
3316 target
= convert_to_mode (mode
, (rtx
) data
, 1);
3317 target
= expand_mult (mode
, target
, coeff
, NULL_RTX
, 1);
3318 return force_reg (mode
, target
);
3321 /* Expand expression EXP, which is a call to the memset builtin. Return 0
3322 if we failed the caller should emit a normal call, otherwise try to get
3323 the result in TARGET, if convenient (and in mode MODE if that's
3327 expand_builtin_memset (tree arglist
, rtx target
, enum machine_mode mode
,
3330 if (!validate_arglist (arglist
,
3331 POINTER_TYPE
, INTEGER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
3335 tree dest
= TREE_VALUE (arglist
);
3336 tree val
= TREE_VALUE (TREE_CHAIN (arglist
));
3337 tree len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
3340 unsigned int dest_align
3341 = get_pointer_alignment (dest
, BIGGEST_ALIGNMENT
);
3342 rtx dest_mem
, dest_addr
, len_rtx
;
3344 /* If DEST is not a pointer type, don't do this
3345 operation in-line. */
3346 if (dest_align
== 0)
3349 /* If the LEN parameter is zero, return DEST. */
3350 if (integer_zerop (len
))
3352 /* Evaluate and ignore VAL in case it has side-effects. */
3353 expand_expr (val
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
3354 return expand_expr (dest
, target
, mode
, EXPAND_NORMAL
);
3357 len_rtx
= expand_expr (len
, NULL_RTX
, VOIDmode
, 0);
3358 dest_mem
= get_memory_rtx (dest
, len
);
3360 if (TREE_CODE (val
) != INTEGER_CST
)
3364 val
= fold_build1 (CONVERT_EXPR
, unsigned_char_type_node
, val
);
3365 val_rtx
= expand_expr (val
, NULL_RTX
, VOIDmode
, 0);
3367 /* Assume that we can memset by pieces if we can store the
3368 * the coefficients by pieces (in the required modes).
3369 * We can't pass builtin_memset_gen_str as that emits RTL. */
3371 if (host_integerp (len
, 1)
3372 && !(optimize_size
&& tree_low_cst (len
, 1) > 1)
3373 && can_store_by_pieces (tree_low_cst (len
, 1),
3374 builtin_memset_read_str
, &c
, dest_align
))
3376 val_rtx
= force_reg (TYPE_MODE (unsigned_char_type_node
),
3378 store_by_pieces (dest_mem
, tree_low_cst (len
, 1),
3379 builtin_memset_gen_str
, val_rtx
, dest_align
, 0);
3381 else if (!set_storage_via_setmem(dest_mem
, len_rtx
, val_rtx
,
3385 dest_mem
= force_operand (XEXP (dest_mem
, 0), NULL_RTX
);
3386 dest_mem
= convert_memory_address (ptr_mode
, dest_mem
);
3390 if (target_char_cast (val
, &c
))
3395 if (host_integerp (len
, 1)
3396 && !(optimize_size
&& tree_low_cst (len
, 1) > 1)
3397 && can_store_by_pieces (tree_low_cst (len
, 1),
3398 builtin_memset_read_str
, &c
, dest_align
))
3399 store_by_pieces (dest_mem
, tree_low_cst (len
, 1),
3400 builtin_memset_read_str
, &c
, dest_align
, 0);
3401 else if (!set_storage_via_setmem (dest_mem
, len_rtx
, GEN_INT (c
),
3405 dest_mem
= force_operand (XEXP (dest_mem
, 0), NULL_RTX
);
3406 dest_mem
= convert_memory_address (ptr_mode
, dest_mem
);
3410 set_mem_align (dest_mem
, dest_align
);
3411 dest_addr
= clear_storage (dest_mem
, len_rtx
,
3412 CALL_EXPR_TAILCALL (orig_exp
)
3413 ? BLOCK_OP_TAILCALL
: BLOCK_OP_NORMAL
);
3417 dest_addr
= force_operand (XEXP (dest_mem
, 0), NULL_RTX
);
3418 dest_addr
= convert_memory_address (ptr_mode
, dest_addr
);
3425 /* Expand expression EXP, which is a call to the bzero builtin. Return 0
3426 if we failed the caller should emit a normal call. */
3429 expand_builtin_bzero (tree exp
)
3431 tree arglist
= TREE_OPERAND (exp
, 1);
3432 tree dest
, size
, newarglist
;
3434 if (!validate_arglist (arglist
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
3437 dest
= TREE_VALUE (arglist
);
3438 size
= TREE_VALUE (TREE_CHAIN (arglist
));
3440 /* New argument list transforming bzero(ptr x, int y) to
3441 memset(ptr x, int 0, size_t y). This is done this way
3442 so that if it isn't expanded inline, we fallback to
3443 calling bzero instead of memset. */
3445 newarglist
= build_tree_list (NULL_TREE
, fold_convert (sizetype
, size
));
3446 newarglist
= tree_cons (NULL_TREE
, integer_zero_node
, newarglist
);
3447 newarglist
= tree_cons (NULL_TREE
, dest
, newarglist
);
3449 return expand_builtin_memset (newarglist
, const0_rtx
, VOIDmode
, exp
);
3452 /* Expand expression EXP, which is a call to the memcmp built-in function.
3453 ARGLIST is the argument list for this call. Return 0 if we failed and the
3454 caller should emit a normal call, otherwise try to get the result in
3455 TARGET, if convenient (and in mode MODE, if that's convenient). */
3458 expand_builtin_memcmp (tree exp ATTRIBUTE_UNUSED
, tree arglist
, rtx target
,
3459 enum machine_mode mode
)
3461 if (!validate_arglist (arglist
,
3462 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
3466 tree result
= fold_builtin_memcmp (arglist
);
3468 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
3471 #if defined HAVE_cmpmemsi || defined HAVE_cmpstrnsi
3473 tree arg1
= TREE_VALUE (arglist
);
3474 tree arg2
= TREE_VALUE (TREE_CHAIN (arglist
));
3475 tree len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
3476 rtx arg1_rtx
, arg2_rtx
, arg3_rtx
;
3481 = get_pointer_alignment (arg1
, BIGGEST_ALIGNMENT
) / BITS_PER_UNIT
;
3483 = get_pointer_alignment (arg2
, BIGGEST_ALIGNMENT
) / BITS_PER_UNIT
;
3484 enum machine_mode insn_mode
;
3486 #ifdef HAVE_cmpmemsi
3488 insn_mode
= insn_data
[(int) CODE_FOR_cmpmemsi
].operand
[0].mode
;
3491 #ifdef HAVE_cmpstrnsi
3493 insn_mode
= insn_data
[(int) CODE_FOR_cmpstrnsi
].operand
[0].mode
;
3498 /* If we don't have POINTER_TYPE, call the function. */
3499 if (arg1_align
== 0 || arg2_align
== 0)
3502 /* Make a place to write the result of the instruction. */
3505 && REG_P (result
) && GET_MODE (result
) == insn_mode
3506 && REGNO (result
) >= FIRST_PSEUDO_REGISTER
))
3507 result
= gen_reg_rtx (insn_mode
);
3509 arg1_rtx
= get_memory_rtx (arg1
, len
);
3510 arg2_rtx
= get_memory_rtx (arg2
, len
);
3511 arg3_rtx
= expand_expr (len
, NULL_RTX
, VOIDmode
, 0);
3513 /* Set MEM_SIZE as appropriate. */
3514 if (GET_CODE (arg3_rtx
) == CONST_INT
)
3516 set_mem_size (arg1_rtx
, arg3_rtx
);
3517 set_mem_size (arg2_rtx
, arg3_rtx
);
3520 #ifdef HAVE_cmpmemsi
3522 insn
= gen_cmpmemsi (result
, arg1_rtx
, arg2_rtx
, arg3_rtx
,
3523 GEN_INT (MIN (arg1_align
, arg2_align
)));
3526 #ifdef HAVE_cmpstrnsi
3528 insn
= gen_cmpstrnsi (result
, arg1_rtx
, arg2_rtx
, arg3_rtx
,
3529 GEN_INT (MIN (arg1_align
, arg2_align
)));
3537 emit_library_call_value (memcmp_libfunc
, result
, LCT_PURE_MAKE_BLOCK
,
3538 TYPE_MODE (integer_type_node
), 3,
3539 XEXP (arg1_rtx
, 0), Pmode
,
3540 XEXP (arg2_rtx
, 0), Pmode
,
3541 convert_to_mode (TYPE_MODE (sizetype
), arg3_rtx
,
3542 TYPE_UNSIGNED (sizetype
)),
3543 TYPE_MODE (sizetype
));
3545 /* Return the value in the proper mode for this function. */
3546 mode
= TYPE_MODE (TREE_TYPE (exp
));
3547 if (GET_MODE (result
) == mode
)
3549 else if (target
!= 0)
3551 convert_move (target
, result
, 0);
3555 return convert_to_mode (mode
, result
, 0);
3562 /* Expand expression EXP, which is a call to the strcmp builtin. Return 0
3563 if we failed the caller should emit a normal call, otherwise try to get
3564 the result in TARGET, if convenient. */
3567 expand_builtin_strcmp (tree exp
, rtx target
, enum machine_mode mode
)
3569 tree arglist
= TREE_OPERAND (exp
, 1);
3571 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
3575 tree result
= fold_builtin_strcmp (arglist
);
3577 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
3580 #if defined HAVE_cmpstrsi || defined HAVE_cmpstrnsi
3581 if (cmpstr_optab
[SImode
] != CODE_FOR_nothing
3582 || cmpstrn_optab
[SImode
] != CODE_FOR_nothing
)
3584 rtx arg1_rtx
, arg2_rtx
;
3585 rtx result
, insn
= NULL_RTX
;
3588 tree arg1
= TREE_VALUE (arglist
);
3589 tree arg2
= TREE_VALUE (TREE_CHAIN (arglist
));
3591 = get_pointer_alignment (arg1
, BIGGEST_ALIGNMENT
) / BITS_PER_UNIT
;
3593 = get_pointer_alignment (arg2
, BIGGEST_ALIGNMENT
) / BITS_PER_UNIT
;
3595 /* If we don't have POINTER_TYPE, call the function. */
3596 if (arg1_align
== 0 || arg2_align
== 0)
3599 /* Stabilize the arguments in case gen_cmpstr(n)si fail. */
3600 arg1
= builtin_save_expr (arg1
);
3601 arg2
= builtin_save_expr (arg2
);
3603 arg1_rtx
= get_memory_rtx (arg1
, NULL
);
3604 arg2_rtx
= get_memory_rtx (arg2
, NULL
);
3606 #ifdef HAVE_cmpstrsi
3607 /* Try to call cmpstrsi. */
3610 enum machine_mode insn_mode
3611 = insn_data
[(int) CODE_FOR_cmpstrsi
].operand
[0].mode
;
3613 /* Make a place to write the result of the instruction. */
3616 && REG_P (result
) && GET_MODE (result
) == insn_mode
3617 && REGNO (result
) >= FIRST_PSEUDO_REGISTER
))
3618 result
= gen_reg_rtx (insn_mode
);
3620 insn
= gen_cmpstrsi (result
, arg1_rtx
, arg2_rtx
,
3621 GEN_INT (MIN (arg1_align
, arg2_align
)));
3625 /* Try to determine at least one length and call cmpstrnsi. */
3626 if (!insn
&& HAVE_cmpstrnsi
)
3631 enum machine_mode insn_mode
3632 = insn_data
[(int) CODE_FOR_cmpstrnsi
].operand
[0].mode
;
3633 tree len1
= c_strlen (arg1
, 1);
3634 tree len2
= c_strlen (arg2
, 1);
3637 len1
= size_binop (PLUS_EXPR
, ssize_int (1), len1
);
3639 len2
= size_binop (PLUS_EXPR
, ssize_int (1), len2
);
3641 /* If we don't have a constant length for the first, use the length
3642 of the second, if we know it. We don't require a constant for
3643 this case; some cost analysis could be done if both are available
3644 but neither is constant. For now, assume they're equally cheap,
3645 unless one has side effects. If both strings have constant lengths,
3652 else if (TREE_SIDE_EFFECTS (len1
))
3654 else if (TREE_SIDE_EFFECTS (len2
))
3656 else if (TREE_CODE (len1
) != INTEGER_CST
)
3658 else if (TREE_CODE (len2
) != INTEGER_CST
)
3660 else if (tree_int_cst_lt (len1
, len2
))
3665 /* If both arguments have side effects, we cannot optimize. */
3666 if (!len
|| TREE_SIDE_EFFECTS (len
))
3669 /* Stabilize the arguments in case gen_cmpstrnsi fails. */
3670 arg3_rtx
= expand_expr (len
, NULL_RTX
, VOIDmode
, 0);
3672 /* Make a place to write the result of the instruction. */
3675 && REG_P (result
) && GET_MODE (result
) == insn_mode
3676 && REGNO (result
) >= FIRST_PSEUDO_REGISTER
))
3677 result
= gen_reg_rtx (insn_mode
);
3679 insn
= gen_cmpstrnsi (result
, arg1_rtx
, arg2_rtx
, arg3_rtx
,
3680 GEN_INT (MIN (arg1_align
, arg2_align
)));
3688 /* Return the value in the proper mode for this function. */
3689 mode
= TYPE_MODE (TREE_TYPE (exp
));
3690 if (GET_MODE (result
) == mode
)
3693 return convert_to_mode (mode
, result
, 0);
3694 convert_move (target
, result
, 0);
3698 /* Expand the library call ourselves using a stabilized argument
3699 list to avoid re-evaluating the function's arguments twice. */
3700 arglist
= build_tree_list (NULL_TREE
, arg2
);
3701 arglist
= tree_cons (NULL_TREE
, arg1
, arglist
);
3702 fndecl
= get_callee_fndecl (exp
);
3703 fn
= build_function_call_expr (fndecl
, arglist
);
3704 if (TREE_CODE (fn
) == CALL_EXPR
)
3705 CALL_EXPR_TAILCALL (fn
) = CALL_EXPR_TAILCALL (exp
);
3706 return expand_call (fn
, target
, target
== const0_rtx
);
3712 /* Expand expression EXP, which is a call to the strncmp builtin. Return 0
3713 if we failed the caller should emit a normal call, otherwise try to get
3714 the result in TARGET, if convenient. */
3717 expand_builtin_strncmp (tree exp
, rtx target
, enum machine_mode mode
)
3719 tree arglist
= TREE_OPERAND (exp
, 1);
3721 if (!validate_arglist (arglist
,
3722 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
3726 tree result
= fold_builtin_strncmp (arglist
);
3728 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
3731 /* If c_strlen can determine an expression for one of the string
3732 lengths, and it doesn't have side effects, then emit cmpstrnsi
3733 using length MIN(strlen(string)+1, arg3). */
3734 #ifdef HAVE_cmpstrnsi
3737 tree arg1
= TREE_VALUE (arglist
);
3738 tree arg2
= TREE_VALUE (TREE_CHAIN (arglist
));
3739 tree arg3
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
3740 tree len
, len1
, len2
;
3741 rtx arg1_rtx
, arg2_rtx
, arg3_rtx
;
3746 = get_pointer_alignment (arg1
, BIGGEST_ALIGNMENT
) / BITS_PER_UNIT
;
3748 = get_pointer_alignment (arg2
, BIGGEST_ALIGNMENT
) / BITS_PER_UNIT
;
3749 enum machine_mode insn_mode
3750 = insn_data
[(int) CODE_FOR_cmpstrnsi
].operand
[0].mode
;
3752 len1
= c_strlen (arg1
, 1);
3753 len2
= c_strlen (arg2
, 1);
3756 len1
= size_binop (PLUS_EXPR
, ssize_int (1), len1
);
3758 len2
= size_binop (PLUS_EXPR
, ssize_int (1), len2
);
3760 /* If we don't have a constant length for the first, use the length
3761 of the second, if we know it. We don't require a constant for
3762 this case; some cost analysis could be done if both are available
3763 but neither is constant. For now, assume they're equally cheap,
3764 unless one has side effects. If both strings have constant lengths,
3771 else if (TREE_SIDE_EFFECTS (len1
))
3773 else if (TREE_SIDE_EFFECTS (len2
))
3775 else if (TREE_CODE (len1
) != INTEGER_CST
)
3777 else if (TREE_CODE (len2
) != INTEGER_CST
)
3779 else if (tree_int_cst_lt (len1
, len2
))
3784 /* If both arguments have side effects, we cannot optimize. */
3785 if (!len
|| TREE_SIDE_EFFECTS (len
))
3788 /* The actual new length parameter is MIN(len,arg3). */
3789 len
= fold_build2 (MIN_EXPR
, TREE_TYPE (len
), len
,
3790 fold_convert (TREE_TYPE (len
), arg3
));
3792 /* If we don't have POINTER_TYPE, call the function. */
3793 if (arg1_align
== 0 || arg2_align
== 0)
3796 /* Make a place to write the result of the instruction. */
3799 && REG_P (result
) && GET_MODE (result
) == insn_mode
3800 && REGNO (result
) >= FIRST_PSEUDO_REGISTER
))
3801 result
= gen_reg_rtx (insn_mode
);
3803 /* Stabilize the arguments in case gen_cmpstrnsi fails. */
3804 arg1
= builtin_save_expr (arg1
);
3805 arg2
= builtin_save_expr (arg2
);
3806 len
= builtin_save_expr (len
);
3808 arg1_rtx
= get_memory_rtx (arg1
, len
);
3809 arg2_rtx
= get_memory_rtx (arg2
, len
);
3810 arg3_rtx
= expand_expr (len
, NULL_RTX
, VOIDmode
, 0);
3811 insn
= gen_cmpstrnsi (result
, arg1_rtx
, arg2_rtx
, arg3_rtx
,
3812 GEN_INT (MIN (arg1_align
, arg2_align
)));
3817 /* Return the value in the proper mode for this function. */
3818 mode
= TYPE_MODE (TREE_TYPE (exp
));
3819 if (GET_MODE (result
) == mode
)
3822 return convert_to_mode (mode
, result
, 0);
3823 convert_move (target
, result
, 0);
3827 /* Expand the library call ourselves using a stabilized argument
3828 list to avoid re-evaluating the function's arguments twice. */
3829 arglist
= build_tree_list (NULL_TREE
, len
);
3830 arglist
= tree_cons (NULL_TREE
, arg2
, arglist
);
3831 arglist
= tree_cons (NULL_TREE
, arg1
, arglist
);
3832 fndecl
= get_callee_fndecl (exp
);
3833 fn
= build_function_call_expr (fndecl
, arglist
);
3834 if (TREE_CODE (fn
) == CALL_EXPR
)
3835 CALL_EXPR_TAILCALL (fn
) = CALL_EXPR_TAILCALL (exp
);
3836 return expand_call (fn
, target
, target
== const0_rtx
);
3842 /* Expand expression EXP, which is a call to the strcat builtin.
3843 Return 0 if we failed the caller should emit a normal call,
3844 otherwise try to get the result in TARGET, if convenient. */
3847 expand_builtin_strcat (tree fndecl
, tree arglist
, rtx target
, enum machine_mode mode
)
3849 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
3853 tree dst
= TREE_VALUE (arglist
),
3854 src
= TREE_VALUE (TREE_CHAIN (arglist
));
3855 const char *p
= c_getstr (src
);
3857 /* If the string length is zero, return the dst parameter. */
3858 if (p
&& *p
== '\0')
3859 return expand_expr (dst
, target
, mode
, EXPAND_NORMAL
);
3863 /* See if we can store by pieces into (dst + strlen(dst)). */
3864 tree newsrc
, newdst
,
3865 strlen_fn
= implicit_built_in_decls
[BUILT_IN_STRLEN
];
3868 /* Stabilize the argument list. */
3869 newsrc
= builtin_save_expr (src
);
3871 arglist
= build_tree_list (NULL_TREE
, newsrc
);
3873 arglist
= TREE_CHAIN (arglist
); /* Reusing arglist if safe. */
3875 dst
= builtin_save_expr (dst
);
3879 /* Create strlen (dst). */
3881 build_function_call_expr (strlen_fn
,
3882 build_tree_list (NULL_TREE
, dst
));
3883 /* Create (dst + (cast) strlen (dst)). */
3884 newdst
= fold_convert (TREE_TYPE (dst
), newdst
);
3885 newdst
= fold_build2 (PLUS_EXPR
, TREE_TYPE (dst
), dst
, newdst
);
3887 newdst
= builtin_save_expr (newdst
);
3888 arglist
= tree_cons (NULL_TREE
, newdst
, arglist
);
3890 if (!expand_builtin_strcpy (fndecl
, arglist
, target
, mode
))
3892 end_sequence (); /* Stop sequence. */
3896 /* Output the entire sequence. */
3897 insns
= get_insns ();
3901 return expand_expr (dst
, target
, mode
, EXPAND_NORMAL
);
3908 /* Expand expression EXP, which is a call to the strncat builtin.
3909 Return 0 if we failed the caller should emit a normal call,
3910 otherwise try to get the result in TARGET, if convenient. */
3913 expand_builtin_strncat (tree arglist
, rtx target
, enum machine_mode mode
)
3915 if (validate_arglist (arglist
,
3916 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
3918 tree result
= fold_builtin_strncat (arglist
);
3920 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
3925 /* Expand expression EXP, which is a call to the strspn builtin.
3926 Return 0 if we failed the caller should emit a normal call,
3927 otherwise try to get the result in TARGET, if convenient. */
3930 expand_builtin_strspn (tree arglist
, rtx target
, enum machine_mode mode
)
3932 if (validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
3934 tree result
= fold_builtin_strspn (arglist
);
3936 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
3941 /* Expand expression EXP, which is a call to the strcspn builtin.
3942 Return 0 if we failed the caller should emit a normal call,
3943 otherwise try to get the result in TARGET, if convenient. */
3946 expand_builtin_strcspn (tree arglist
, rtx target
, enum machine_mode mode
)
3948 if (validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
3950 tree result
= fold_builtin_strcspn (arglist
);
3952 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
3957 /* Expand a call to __builtin_saveregs, generating the result in TARGET,
3958 if that's convenient. */
3961 expand_builtin_saveregs (void)
3965 /* Don't do __builtin_saveregs more than once in a function.
3966 Save the result of the first call and reuse it. */
3967 if (saveregs_value
!= 0)
3968 return saveregs_value
;
3970 /* When this function is called, it means that registers must be
3971 saved on entry to this function. So we migrate the call to the
3972 first insn of this function. */
3976 /* Do whatever the machine needs done in this case. */
3977 val
= targetm
.calls
.expand_builtin_saveregs ();
3982 saveregs_value
= val
;
3984 /* Put the insns after the NOTE that starts the function. If this
3985 is inside a start_sequence, make the outer-level insn chain current, so
3986 the code is placed at the start of the function. */
3987 push_topmost_sequence ();
3988 emit_insn_after (seq
, entry_of_function ());
3989 pop_topmost_sequence ();
3994 /* __builtin_args_info (N) returns word N of the arg space info
3995 for the current function. The number and meanings of words
3996 is controlled by the definition of CUMULATIVE_ARGS. */
3999 expand_builtin_args_info (tree arglist
)
4001 int nwords
= sizeof (CUMULATIVE_ARGS
) / sizeof (int);
4002 int *word_ptr
= (int *) ¤t_function_args_info
;
4004 gcc_assert (sizeof (CUMULATIVE_ARGS
) % sizeof (int) == 0);
4008 if (!host_integerp (TREE_VALUE (arglist
), 0))
4009 error ("argument of %<__builtin_args_info%> must be constant");
4012 HOST_WIDE_INT wordnum
= tree_low_cst (TREE_VALUE (arglist
), 0);
4014 if (wordnum
< 0 || wordnum
>= nwords
)
4015 error ("argument of %<__builtin_args_info%> out of range");
4017 return GEN_INT (word_ptr
[wordnum
]);
4021 error ("missing argument in %<__builtin_args_info%>");
4026 /* Expand a call to __builtin_next_arg. */
4029 expand_builtin_next_arg (void)
4031 /* Checking arguments is already done in fold_builtin_next_arg
4032 that must be called before this function. */
4033 return expand_binop (Pmode
, add_optab
,
4034 current_function_internal_arg_pointer
,
4035 current_function_arg_offset_rtx
,
4036 NULL_RTX
, 0, OPTAB_LIB_WIDEN
);
4039 /* Make it easier for the backends by protecting the valist argument
4040 from multiple evaluations. */
4043 stabilize_va_list (tree valist
, int needs_lvalue
)
4045 if (TREE_CODE (va_list_type_node
) == ARRAY_TYPE
)
4047 if (TREE_SIDE_EFFECTS (valist
))
4048 valist
= save_expr (valist
);
4050 /* For this case, the backends will be expecting a pointer to
4051 TREE_TYPE (va_list_type_node), but it's possible we've
4052 actually been given an array (an actual va_list_type_node).
4054 if (TREE_CODE (TREE_TYPE (valist
)) == ARRAY_TYPE
)
4056 tree p1
= build_pointer_type (TREE_TYPE (va_list_type_node
));
4057 valist
= build_fold_addr_expr_with_type (valist
, p1
);
4066 if (! TREE_SIDE_EFFECTS (valist
))
4069 pt
= build_pointer_type (va_list_type_node
);
4070 valist
= fold_build1 (ADDR_EXPR
, pt
, valist
);
4071 TREE_SIDE_EFFECTS (valist
) = 1;
4074 if (TREE_SIDE_EFFECTS (valist
))
4075 valist
= save_expr (valist
);
4076 valist
= build_fold_indirect_ref (valist
);
4082 /* The "standard" definition of va_list is void*. */
4085 std_build_builtin_va_list (void)
4087 return ptr_type_node
;
4090 /* The "standard" implementation of va_start: just assign `nextarg' to
4094 std_expand_builtin_va_start (tree valist
, rtx nextarg
)
4098 t
= build2 (MODIFY_EXPR
, TREE_TYPE (valist
), valist
,
4099 make_tree (ptr_type_node
, nextarg
));
4100 TREE_SIDE_EFFECTS (t
) = 1;
4102 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
4105 /* Expand ARGLIST, from a call to __builtin_va_start. */
4108 expand_builtin_va_start (tree arglist
)
4113 chain
= TREE_CHAIN (arglist
);
4117 error ("too few arguments to function %<va_start%>");
4121 if (fold_builtin_next_arg (chain
))
4124 nextarg
= expand_builtin_next_arg ();
4125 valist
= stabilize_va_list (TREE_VALUE (arglist
), 1);
4127 #ifdef EXPAND_BUILTIN_VA_START
4128 EXPAND_BUILTIN_VA_START (valist
, nextarg
);
4130 std_expand_builtin_va_start (valist
, nextarg
);
4136 /* The "standard" implementation of va_arg: read the value from the
4137 current (padded) address and increment by the (padded) size. */
4140 std_gimplify_va_arg_expr (tree valist
, tree type
, tree
*pre_p
, tree
*post_p
)
4142 tree addr
, t
, type_size
, rounded_size
, valist_tmp
;
4143 unsigned HOST_WIDE_INT align
, boundary
;
4146 #ifdef ARGS_GROW_DOWNWARD
4147 /* All of the alignment and movement below is for args-grow-up machines.
4148 As of 2004, there are only 3 ARGS_GROW_DOWNWARD targets, and they all
4149 implement their own specialized gimplify_va_arg_expr routines. */
4153 indirect
= pass_by_reference (NULL
, TYPE_MODE (type
), type
, false);
4155 type
= build_pointer_type (type
);
4157 align
= PARM_BOUNDARY
/ BITS_PER_UNIT
;
4158 boundary
= FUNCTION_ARG_BOUNDARY (TYPE_MODE (type
), type
) / BITS_PER_UNIT
;
4160 /* Hoist the valist value into a temporary for the moment. */
4161 valist_tmp
= get_initialized_tmp_var (valist
, pre_p
, NULL
);
4163 /* va_list pointer is aligned to PARM_BOUNDARY. If argument actually
4164 requires greater alignment, we must perform dynamic alignment. */
4165 if (boundary
> align
)
4167 t
= fold_convert (TREE_TYPE (valist
), size_int (boundary
- 1));
4168 t
= build2 (MODIFY_EXPR
, TREE_TYPE (valist
), valist_tmp
,
4169 build2 (PLUS_EXPR
, TREE_TYPE (valist
), valist_tmp
, t
));
4170 gimplify_and_add (t
, pre_p
);
4172 t
= fold_convert (TREE_TYPE (valist
), size_int (-boundary
));
4173 t
= build2 (MODIFY_EXPR
, TREE_TYPE (valist
), valist_tmp
,
4174 build2 (BIT_AND_EXPR
, TREE_TYPE (valist
), valist_tmp
, t
));
4175 gimplify_and_add (t
, pre_p
);
4180 /* If the actual alignment is less than the alignment of the type,
4181 adjust the type accordingly so that we don't assume strict alignment
4182 when deferencing the pointer. */
4183 boundary
*= BITS_PER_UNIT
;
4184 if (boundary
< TYPE_ALIGN (type
))
4186 type
= build_variant_type_copy (type
);
4187 TYPE_ALIGN (type
) = boundary
;
4190 /* Compute the rounded size of the type. */
4191 type_size
= size_in_bytes (type
);
4192 rounded_size
= round_up (type_size
, align
);
4194 /* Reduce rounded_size so it's sharable with the postqueue. */
4195 gimplify_expr (&rounded_size
, pre_p
, post_p
, is_gimple_val
, fb_rvalue
);
4199 if (PAD_VARARGS_DOWN
&& !integer_zerop (rounded_size
))
4201 /* Small args are padded downward. */
4202 t
= fold_build2 (GT_EXPR
, sizetype
, rounded_size
, size_int (align
));
4203 t
= fold_build3 (COND_EXPR
, sizetype
, t
, size_zero_node
,
4204 size_binop (MINUS_EXPR
, rounded_size
, type_size
));
4205 t
= fold_convert (TREE_TYPE (addr
), t
);
4206 addr
= fold_build2 (PLUS_EXPR
, TREE_TYPE (addr
), addr
, t
);
4209 /* Compute new value for AP. */
4210 t
= fold_convert (TREE_TYPE (valist
), rounded_size
);
4211 t
= build2 (PLUS_EXPR
, TREE_TYPE (valist
), valist_tmp
, t
);
4212 t
= build2 (MODIFY_EXPR
, TREE_TYPE (valist
), valist
, t
);
4213 gimplify_and_add (t
, pre_p
);
4215 addr
= fold_convert (build_pointer_type (type
), addr
);
4218 addr
= build_va_arg_indirect_ref (addr
);
4220 return build_va_arg_indirect_ref (addr
);
4223 /* Build an indirect-ref expression over the given TREE, which represents a
4224 piece of a va_arg() expansion. */
4226 build_va_arg_indirect_ref (tree addr
)
4228 addr
= build_fold_indirect_ref (addr
);
4230 if (flag_mudflap
) /* Don't instrument va_arg INDIRECT_REF. */
4236 /* Return a dummy expression of type TYPE in order to keep going after an
4240 dummy_object (tree type
)
4242 tree t
= convert (build_pointer_type (type
), null_pointer_node
);
4243 return build1 (INDIRECT_REF
, type
, t
);
4246 /* Gimplify __builtin_va_arg, aka VA_ARG_EXPR, which is not really a
4247 builtin function, but a very special sort of operator. */
4249 enum gimplify_status
4250 gimplify_va_arg_expr (tree
*expr_p
, tree
*pre_p
, tree
*post_p
)
4252 tree promoted_type
, want_va_type
, have_va_type
;
4253 tree valist
= TREE_OPERAND (*expr_p
, 0);
4254 tree type
= TREE_TYPE (*expr_p
);
4257 /* Verify that valist is of the proper type. */
4258 want_va_type
= va_list_type_node
;
4259 have_va_type
= TREE_TYPE (valist
);
4261 if (have_va_type
== error_mark_node
)
4264 if (TREE_CODE (want_va_type
) == ARRAY_TYPE
)
4266 /* If va_list is an array type, the argument may have decayed
4267 to a pointer type, e.g. by being passed to another function.
4268 In that case, unwrap both types so that we can compare the
4269 underlying records. */
4270 if (TREE_CODE (have_va_type
) == ARRAY_TYPE
4271 || POINTER_TYPE_P (have_va_type
))
4273 want_va_type
= TREE_TYPE (want_va_type
);
4274 have_va_type
= TREE_TYPE (have_va_type
);
4278 if (TYPE_MAIN_VARIANT (want_va_type
) != TYPE_MAIN_VARIANT (have_va_type
))
4280 error ("first argument to %<va_arg%> not of type %<va_list%>");
4284 /* Generate a diagnostic for requesting data of a type that cannot
4285 be passed through `...' due to type promotion at the call site. */
4286 else if ((promoted_type
= lang_hooks
.types
.type_promotes_to (type
))
4289 static bool gave_help
;
4291 /* Unfortunately, this is merely undefined, rather than a constraint
4292 violation, so we cannot make this an error. If this call is never
4293 executed, the program is still strictly conforming. */
4294 warning (0, "%qT is promoted to %qT when passed through %<...%>",
4295 type
, promoted_type
);
4299 warning (0, "(so you should pass %qT not %qT to %<va_arg%>)",
4300 promoted_type
, type
);
4303 /* We can, however, treat "undefined" any way we please.
4304 Call abort to encourage the user to fix the program. */
4305 inform ("if this code is reached, the program will abort");
4306 t
= build_function_call_expr (implicit_built_in_decls
[BUILT_IN_TRAP
],
4308 append_to_statement_list (t
, pre_p
);
4310 /* This is dead code, but go ahead and finish so that the
4311 mode of the result comes out right. */
4312 *expr_p
= dummy_object (type
);
4317 /* Make it easier for the backends by protecting the valist argument
4318 from multiple evaluations. */
4319 if (TREE_CODE (va_list_type_node
) == ARRAY_TYPE
)
4321 /* For this case, the backends will be expecting a pointer to
4322 TREE_TYPE (va_list_type_node), but it's possible we've
4323 actually been given an array (an actual va_list_type_node).
4325 if (TREE_CODE (TREE_TYPE (valist
)) == ARRAY_TYPE
)
4327 tree p1
= build_pointer_type (TREE_TYPE (va_list_type_node
));
4328 valist
= build_fold_addr_expr_with_type (valist
, p1
);
4330 gimplify_expr (&valist
, pre_p
, post_p
, is_gimple_val
, fb_rvalue
);
4333 gimplify_expr (&valist
, pre_p
, post_p
, is_gimple_min_lval
, fb_lvalue
);
4335 if (!targetm
.gimplify_va_arg_expr
)
4336 /* FIXME:Once most targets are converted we should merely
4337 assert this is non-null. */
4340 *expr_p
= targetm
.gimplify_va_arg_expr (valist
, type
, pre_p
, post_p
);
4345 /* Expand ARGLIST, from a call to __builtin_va_end. */
4348 expand_builtin_va_end (tree arglist
)
4350 tree valist
= TREE_VALUE (arglist
);
4352 /* Evaluate for side effects, if needed. I hate macros that don't
4354 if (TREE_SIDE_EFFECTS (valist
))
4355 expand_expr (valist
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
4360 /* Expand ARGLIST, from a call to __builtin_va_copy. We do this as a
4361 builtin rather than just as an assignment in stdarg.h because of the
4362 nastiness of array-type va_list types. */
4365 expand_builtin_va_copy (tree arglist
)
4369 dst
= TREE_VALUE (arglist
);
4370 src
= TREE_VALUE (TREE_CHAIN (arglist
));
4372 dst
= stabilize_va_list (dst
, 1);
4373 src
= stabilize_va_list (src
, 0);
4375 if (TREE_CODE (va_list_type_node
) != ARRAY_TYPE
)
4377 t
= build2 (MODIFY_EXPR
, va_list_type_node
, dst
, src
);
4378 TREE_SIDE_EFFECTS (t
) = 1;
4379 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
4383 rtx dstb
, srcb
, size
;
4385 /* Evaluate to pointers. */
4386 dstb
= expand_expr (dst
, NULL_RTX
, Pmode
, EXPAND_NORMAL
);
4387 srcb
= expand_expr (src
, NULL_RTX
, Pmode
, EXPAND_NORMAL
);
4388 size
= expand_expr (TYPE_SIZE_UNIT (va_list_type_node
), NULL_RTX
,
4389 VOIDmode
, EXPAND_NORMAL
);
4391 dstb
= convert_memory_address (Pmode
, dstb
);
4392 srcb
= convert_memory_address (Pmode
, srcb
);
4394 /* "Dereference" to BLKmode memories. */
4395 dstb
= gen_rtx_MEM (BLKmode
, dstb
);
4396 set_mem_alias_set (dstb
, get_alias_set (TREE_TYPE (TREE_TYPE (dst
))));
4397 set_mem_align (dstb
, TYPE_ALIGN (va_list_type_node
));
4398 srcb
= gen_rtx_MEM (BLKmode
, srcb
);
4399 set_mem_alias_set (srcb
, get_alias_set (TREE_TYPE (TREE_TYPE (src
))));
4400 set_mem_align (srcb
, TYPE_ALIGN (va_list_type_node
));
4403 emit_block_move (dstb
, srcb
, size
, BLOCK_OP_NORMAL
);
4409 /* Expand a call to one of the builtin functions __builtin_frame_address or
4410 __builtin_return_address. */
4413 expand_builtin_frame_address (tree fndecl
, tree arglist
)
4415 /* The argument must be a nonnegative integer constant.
4416 It counts the number of frames to scan up the stack.
4417 The value is the return address saved in that frame. */
4419 /* Warning about missing arg was already issued. */
4421 else if (! host_integerp (TREE_VALUE (arglist
), 1))
4423 if (DECL_FUNCTION_CODE (fndecl
) == BUILT_IN_FRAME_ADDRESS
)
4424 error ("invalid argument to %<__builtin_frame_address%>");
4426 error ("invalid argument to %<__builtin_return_address%>");
4432 = expand_builtin_return_addr (DECL_FUNCTION_CODE (fndecl
),
4433 tree_low_cst (TREE_VALUE (arglist
), 1));
4435 /* Some ports cannot access arbitrary stack frames. */
4438 if (DECL_FUNCTION_CODE (fndecl
) == BUILT_IN_FRAME_ADDRESS
)
4439 warning (0, "unsupported argument to %<__builtin_frame_address%>");
4441 warning (0, "unsupported argument to %<__builtin_return_address%>");
4445 /* For __builtin_frame_address, return what we've got. */
4446 if (DECL_FUNCTION_CODE (fndecl
) == BUILT_IN_FRAME_ADDRESS
)
4450 && ! CONSTANT_P (tem
))
4451 tem
= copy_to_mode_reg (Pmode
, tem
);
4456 /* Expand a call to the alloca builtin, with arguments ARGLIST. Return 0 if
4457 we failed and the caller should emit a normal call, otherwise try to get
4458 the result in TARGET, if convenient. */
4461 expand_builtin_alloca (tree arglist
, rtx target
)
4466 /* In -fmudflap-instrumented code, alloca() and __builtin_alloca()
4467 should always expand to function calls. These can be intercepted
4472 if (!validate_arglist (arglist
, INTEGER_TYPE
, VOID_TYPE
))
4475 /* Compute the argument. */
4476 op0
= expand_expr (TREE_VALUE (arglist
), NULL_RTX
, VOIDmode
, 0);
4478 /* Allocate the desired space. */
4479 result
= allocate_dynamic_stack_space (op0
, target
, BITS_PER_UNIT
);
4480 result
= convert_memory_address (ptr_mode
, result
);
4485 /* Expand a call to a unary builtin. The arguments are in ARGLIST.
4486 Return 0 if a normal call should be emitted rather than expanding the
4487 function in-line. If convenient, the result should be placed in TARGET.
4488 SUBTARGET may be used as the target for computing one of EXP's operands. */
4491 expand_builtin_unop (enum machine_mode target_mode
, tree arglist
, rtx target
,
4492 rtx subtarget
, optab op_optab
)
4495 if (!validate_arglist (arglist
, INTEGER_TYPE
, VOID_TYPE
))
4498 /* Compute the argument. */
4499 op0
= expand_expr (TREE_VALUE (arglist
), subtarget
, VOIDmode
, 0);
4500 /* Compute op, into TARGET if possible.
4501 Set TARGET to wherever the result comes back. */
4502 target
= expand_unop (TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist
))),
4503 op_optab
, op0
, target
, 1);
4504 gcc_assert (target
);
4506 return convert_to_mode (target_mode
, target
, 0);
4509 /* If the string passed to fputs is a constant and is one character
4510 long, we attempt to transform this call into __builtin_fputc(). */
4513 expand_builtin_fputs (tree arglist
, rtx target
, bool unlocked
)
4515 /* Verify the arguments in the original call. */
4516 if (validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
4518 tree result
= fold_builtin_fputs (arglist
, (target
== const0_rtx
),
4519 unlocked
, NULL_TREE
);
4521 return expand_expr (result
, target
, VOIDmode
, EXPAND_NORMAL
);
4526 /* Expand a call to __builtin_expect. We return our argument and emit a
4527 NOTE_INSN_EXPECTED_VALUE note. This is the expansion of __builtin_expect in
4528 a non-jump context. */
4531 expand_builtin_expect (tree arglist
, rtx target
)
4536 if (arglist
== NULL_TREE
4537 || TREE_CHAIN (arglist
) == NULL_TREE
)
4539 exp
= TREE_VALUE (arglist
);
4540 c
= TREE_VALUE (TREE_CHAIN (arglist
));
4542 if (TREE_CODE (c
) != INTEGER_CST
)
4544 error ("second argument to %<__builtin_expect%> must be a constant");
4545 c
= integer_zero_node
;
4548 target
= expand_expr (exp
, target
, VOIDmode
, EXPAND_NORMAL
);
4550 /* Don't bother with expected value notes for integral constants. */
4551 if (flag_guess_branch_prob
&& GET_CODE (target
) != CONST_INT
)
4553 /* We do need to force this into a register so that we can be
4554 moderately sure to be able to correctly interpret the branch
4556 target
= force_reg (GET_MODE (target
), target
);
4558 rtx_c
= expand_expr (c
, NULL_RTX
, GET_MODE (target
), EXPAND_NORMAL
);
4560 note
= emit_note (NOTE_INSN_EXPECTED_VALUE
);
4561 NOTE_EXPECTED_VALUE (note
) = gen_rtx_EQ (VOIDmode
, target
, rtx_c
);
4567 /* Like expand_builtin_expect, except do this in a jump context. This is
4568 called from do_jump if the conditional is a __builtin_expect. Return either
4569 a list of insns to emit the jump or NULL if we cannot optimize
4570 __builtin_expect. We need to optimize this at jump time so that machines
4571 like the PowerPC don't turn the test into a SCC operation, and then jump
4572 based on the test being 0/1. */
4575 expand_builtin_expect_jump (tree exp
, rtx if_false_label
, rtx if_true_label
)
4577 tree arglist
= TREE_OPERAND (exp
, 1);
4578 tree arg0
= TREE_VALUE (arglist
);
4579 tree arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
4582 /* Only handle __builtin_expect (test, 0) and
4583 __builtin_expect (test, 1). */
4584 if (TREE_CODE (TREE_TYPE (arg1
)) == INTEGER_TYPE
4585 && (integer_zerop (arg1
) || integer_onep (arg1
)))
4587 rtx insn
, drop_through_label
, temp
;
4589 /* Expand the jump insns. */
4591 do_jump (arg0
, if_false_label
, if_true_label
);
4594 drop_through_label
= get_last_insn ();
4595 if (drop_through_label
&& NOTE_P (drop_through_label
))
4596 drop_through_label
= prev_nonnote_insn (drop_through_label
);
4597 if (drop_through_label
&& !LABEL_P (drop_through_label
))
4598 drop_through_label
= NULL_RTX
;
4601 if (! if_true_label
)
4602 if_true_label
= drop_through_label
;
4603 if (! if_false_label
)
4604 if_false_label
= drop_through_label
;
4606 /* Go through and add the expect's to each of the conditional jumps. */
4608 while (insn
!= NULL_RTX
)
4610 rtx next
= NEXT_INSN (insn
);
4612 if (JUMP_P (insn
) && any_condjump_p (insn
))
4614 rtx ifelse
= SET_SRC (pc_set (insn
));
4615 rtx then_dest
= XEXP (ifelse
, 1);
4616 rtx else_dest
= XEXP (ifelse
, 2);
4619 /* First check if we recognize any of the labels. */
4620 if (GET_CODE (then_dest
) == LABEL_REF
4621 && XEXP (then_dest
, 0) == if_true_label
)
4623 else if (GET_CODE (then_dest
) == LABEL_REF
4624 && XEXP (then_dest
, 0) == if_false_label
)
4626 else if (GET_CODE (else_dest
) == LABEL_REF
4627 && XEXP (else_dest
, 0) == if_false_label
)
4629 else if (GET_CODE (else_dest
) == LABEL_REF
4630 && XEXP (else_dest
, 0) == if_true_label
)
4632 /* Otherwise check where we drop through. */
4633 else if (else_dest
== pc_rtx
)
4635 if (next
&& NOTE_P (next
))
4636 next
= next_nonnote_insn (next
);
4638 if (next
&& JUMP_P (next
)
4639 && any_uncondjump_p (next
))
4640 temp
= XEXP (SET_SRC (pc_set (next
)), 0);
4644 /* TEMP is either a CODE_LABEL, NULL_RTX or something
4645 else that can't possibly match either target label. */
4646 if (temp
== if_false_label
)
4648 else if (temp
== if_true_label
)
4651 else if (then_dest
== pc_rtx
)
4653 if (next
&& NOTE_P (next
))
4654 next
= next_nonnote_insn (next
);
4656 if (next
&& JUMP_P (next
)
4657 && any_uncondjump_p (next
))
4658 temp
= XEXP (SET_SRC (pc_set (next
)), 0);
4662 if (temp
== if_false_label
)
4664 else if (temp
== if_true_label
)
4670 /* If the test is expected to fail, reverse the
4672 if (integer_zerop (arg1
))
4674 predict_insn_def (insn
, PRED_BUILTIN_EXPECT
, taken
);
4686 expand_builtin_trap (void)
4690 emit_insn (gen_trap ());
4693 emit_library_call (abort_libfunc
, LCT_NORETURN
, VOIDmode
, 0);
4697 /* Expand a call to fabs, fabsf or fabsl with arguments ARGLIST.
4698 Return 0 if a normal call should be emitted rather than expanding
4699 the function inline. If convenient, the result should be placed
4700 in TARGET. SUBTARGET may be used as the target for computing
4704 expand_builtin_fabs (tree arglist
, rtx target
, rtx subtarget
)
4706 enum machine_mode mode
;
4710 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
4713 arg
= TREE_VALUE (arglist
);
4714 mode
= TYPE_MODE (TREE_TYPE (arg
));
4715 op0
= expand_expr (arg
, subtarget
, VOIDmode
, 0);
4716 return expand_abs (mode
, op0
, target
, 0, safe_from_p (target
, arg
, 1));
4719 /* Expand a call to copysign, copysignf, or copysignl with arguments ARGLIST.
4720 Return NULL is a normal call should be emitted rather than expanding the
4721 function inline. If convenient, the result should be placed in TARGET.
4722 SUBTARGET may be used as the target for computing the operand. */
4725 expand_builtin_copysign (tree arglist
, rtx target
, rtx subtarget
)
4730 if (!validate_arglist (arglist
, REAL_TYPE
, REAL_TYPE
, VOID_TYPE
))
4733 arg
= TREE_VALUE (arglist
);
4734 op0
= expand_expr (arg
, subtarget
, VOIDmode
, 0);
4736 arg
= TREE_VALUE (TREE_CHAIN (arglist
));
4737 op1
= expand_expr (arg
, NULL
, VOIDmode
, 0);
4739 return expand_copysign (op0
, op1
, target
);
4742 /* Create a new constant string literal and return a char* pointer to it.
4743 The STRING_CST value is the LEN characters at STR. */
4745 build_string_literal (int len
, const char *str
)
4747 tree t
, elem
, index
, type
;
4749 t
= build_string (len
, str
);
4750 elem
= build_type_variant (char_type_node
, 1, 0);
4751 index
= build_index_type (build_int_cst (NULL_TREE
, len
- 1));
4752 type
= build_array_type (elem
, index
);
4753 TREE_TYPE (t
) = type
;
4754 TREE_CONSTANT (t
) = 1;
4755 TREE_INVARIANT (t
) = 1;
4756 TREE_READONLY (t
) = 1;
4757 TREE_STATIC (t
) = 1;
4759 type
= build_pointer_type (type
);
4760 t
= build1 (ADDR_EXPR
, type
, t
);
4762 type
= build_pointer_type (elem
);
4763 t
= build1 (NOP_EXPR
, type
, t
);
4767 /* Expand EXP, a call to printf or printf_unlocked.
4768 Return 0 if a normal call should be emitted rather than transforming
4769 the function inline. If convenient, the result should be placed in
4770 TARGET with mode MODE. UNLOCKED indicates this is a printf_unlocked
4773 expand_builtin_printf (tree exp
, rtx target
, enum machine_mode mode
,
4776 tree arglist
= TREE_OPERAND (exp
, 1);
4777 /* If we're using an unlocked function, assume the other unlocked
4778 functions exist explicitly. */
4779 tree
const fn_putchar
= unlocked
? built_in_decls
[BUILT_IN_PUTCHAR_UNLOCKED
]
4780 : implicit_built_in_decls
[BUILT_IN_PUTCHAR
];
4781 tree
const fn_puts
= unlocked
? built_in_decls
[BUILT_IN_PUTS_UNLOCKED
]
4782 : implicit_built_in_decls
[BUILT_IN_PUTS
];
4783 const char *fmt_str
;
4786 /* If the return value is used, don't do the transformation. */
4787 if (target
!= const0_rtx
)
4790 /* Verify the required arguments in the original call. */
4793 fmt
= TREE_VALUE (arglist
);
4794 if (! POINTER_TYPE_P (TREE_TYPE (fmt
)))
4796 arglist
= TREE_CHAIN (arglist
);
4798 /* Check whether the format is a literal string constant. */
4799 fmt_str
= c_getstr (fmt
);
4800 if (fmt_str
== NULL
)
4803 if (!init_target_chars())
4806 /* If the format specifier was "%s\n", call __builtin_puts(arg). */
4807 if (strcmp (fmt_str
, target_percent_s_newline
) == 0)
4810 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist
)))
4811 || TREE_CHAIN (arglist
))
4815 /* If the format specifier was "%c", call __builtin_putchar(arg). */
4816 else if (strcmp (fmt_str
, target_percent_c
) == 0)
4819 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist
))) != INTEGER_TYPE
4820 || TREE_CHAIN (arglist
))
4826 /* We can't handle anything else with % args or %% ... yet. */
4827 if (strchr (fmt_str
, target_percent
))
4833 /* If the format specifier was "", printf does nothing. */
4834 if (fmt_str
[0] == '\0')
4836 /* If the format specifier has length of 1, call putchar. */
4837 if (fmt_str
[1] == '\0')
4839 /* Given printf("c"), (where c is any one character,)
4840 convert "c"[0] to an int and pass that to the replacement
4842 arg
= build_int_cst (NULL_TREE
, fmt_str
[0]);
4843 arglist
= build_tree_list (NULL_TREE
, arg
);
4848 /* If the format specifier was "string\n", call puts("string"). */
4849 size_t len
= strlen (fmt_str
);
4850 if ((unsigned char)fmt_str
[len
- 1] == target_newline
)
4852 /* Create a NUL-terminated string that's one char shorter
4853 than the original, stripping off the trailing '\n'. */
4854 char *newstr
= alloca (len
);
4855 memcpy (newstr
, fmt_str
, len
- 1);
4856 newstr
[len
- 1] = 0;
4858 arg
= build_string_literal (len
, newstr
);
4859 arglist
= build_tree_list (NULL_TREE
, arg
);
4863 /* We'd like to arrange to call fputs(string,stdout) here,
4864 but we need stdout and don't have a way to get it yet. */
4871 fn
= build_function_call_expr (fn
, arglist
);
4872 if (TREE_CODE (fn
) == CALL_EXPR
)
4873 CALL_EXPR_TAILCALL (fn
) = CALL_EXPR_TAILCALL (exp
);
4874 return expand_expr (fn
, target
, mode
, EXPAND_NORMAL
);
4877 /* Expand EXP, a call to fprintf or fprintf_unlocked.
4878 Return 0 if a normal call should be emitted rather than transforming
4879 the function inline. If convenient, the result should be placed in
4880 TARGET with mode MODE. UNLOCKED indicates this is a fprintf_unlocked
4883 expand_builtin_fprintf (tree exp
, rtx target
, enum machine_mode mode
,
4886 tree arglist
= TREE_OPERAND (exp
, 1);
4887 /* If we're using an unlocked function, assume the other unlocked
4888 functions exist explicitly. */
4889 tree
const fn_fputc
= unlocked
? built_in_decls
[BUILT_IN_FPUTC_UNLOCKED
]
4890 : implicit_built_in_decls
[BUILT_IN_FPUTC
];
4891 tree
const fn_fputs
= unlocked
? built_in_decls
[BUILT_IN_FPUTS_UNLOCKED
]
4892 : implicit_built_in_decls
[BUILT_IN_FPUTS
];
4893 const char *fmt_str
;
4894 tree fn
, fmt
, fp
, arg
;
4896 /* If the return value is used, don't do the transformation. */
4897 if (target
!= const0_rtx
)
4900 /* Verify the required arguments in the original call. */
4903 fp
= TREE_VALUE (arglist
);
4904 if (! POINTER_TYPE_P (TREE_TYPE (fp
)))
4906 arglist
= TREE_CHAIN (arglist
);
4909 fmt
= TREE_VALUE (arglist
);
4910 if (! POINTER_TYPE_P (TREE_TYPE (fmt
)))
4912 arglist
= TREE_CHAIN (arglist
);
4914 /* Check whether the format is a literal string constant. */
4915 fmt_str
= c_getstr (fmt
);
4916 if (fmt_str
== NULL
)
4919 if (!init_target_chars())
4922 /* If the format specifier was "%s", call __builtin_fputs(arg,fp). */
4923 if (strcmp (fmt_str
, target_percent_s
) == 0)
4926 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist
)))
4927 || TREE_CHAIN (arglist
))
4929 arg
= TREE_VALUE (arglist
);
4930 arglist
= build_tree_list (NULL_TREE
, fp
);
4931 arglist
= tree_cons (NULL_TREE
, arg
, arglist
);
4934 /* If the format specifier was "%c", call __builtin_fputc(arg,fp). */
4935 else if (strcmp (fmt_str
, target_percent_c
) == 0)
4938 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist
))) != INTEGER_TYPE
4939 || TREE_CHAIN (arglist
))
4941 arg
= TREE_VALUE (arglist
);
4942 arglist
= build_tree_list (NULL_TREE
, fp
);
4943 arglist
= tree_cons (NULL_TREE
, arg
, arglist
);
4948 /* We can't handle anything else with % args or %% ... yet. */
4949 if (strchr (fmt_str
, target_percent
))
4955 /* If the format specifier was "", fprintf does nothing. */
4956 if (fmt_str
[0] == '\0')
4958 /* Evaluate and ignore FILE* argument for side-effects. */
4959 expand_expr (fp
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
4963 /* When "string" doesn't contain %, replace all cases of
4964 fprintf(stream,string) with fputs(string,stream). The fputs
4965 builtin will take care of special cases like length == 1. */
4966 arglist
= build_tree_list (NULL_TREE
, fp
);
4967 arglist
= tree_cons (NULL_TREE
, fmt
, arglist
);
4973 fn
= build_function_call_expr (fn
, arglist
);
4974 if (TREE_CODE (fn
) == CALL_EXPR
)
4975 CALL_EXPR_TAILCALL (fn
) = CALL_EXPR_TAILCALL (exp
);
4976 return expand_expr (fn
, target
, mode
, EXPAND_NORMAL
);
4979 /* Expand a call to sprintf with argument list ARGLIST. Return 0 if
4980 a normal call should be emitted rather than expanding the function
4981 inline. If convenient, the result should be placed in TARGET with
4985 expand_builtin_sprintf (tree arglist
, rtx target
, enum machine_mode mode
)
4987 tree orig_arglist
, dest
, fmt
;
4988 const char *fmt_str
;
4990 orig_arglist
= arglist
;
4992 /* Verify the required arguments in the original call. */
4995 dest
= TREE_VALUE (arglist
);
4996 if (! POINTER_TYPE_P (TREE_TYPE (dest
)))
4998 arglist
= TREE_CHAIN (arglist
);
5001 fmt
= TREE_VALUE (arglist
);
5002 if (! POINTER_TYPE_P (TREE_TYPE (fmt
)))
5004 arglist
= TREE_CHAIN (arglist
);
5006 /* Check whether the format is a literal string constant. */
5007 fmt_str
= c_getstr (fmt
);
5008 if (fmt_str
== NULL
)
5011 if (!init_target_chars())
5014 /* If the format doesn't contain % args or %%, use strcpy. */
5015 if (strchr (fmt_str
, target_percent
) == 0)
5017 tree fn
= implicit_built_in_decls
[BUILT_IN_STRCPY
];
5020 if (arglist
|| ! fn
)
5022 expand_expr (build_function_call_expr (fn
, orig_arglist
),
5023 const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
5024 if (target
== const0_rtx
)
5026 exp
= build_int_cst (NULL_TREE
, strlen (fmt_str
));
5027 return expand_expr (exp
, target
, mode
, EXPAND_NORMAL
);
5029 /* If the format is "%s", use strcpy if the result isn't used. */
5030 else if (strcmp (fmt_str
, target_percent_s
) == 0)
5033 fn
= implicit_built_in_decls
[BUILT_IN_STRCPY
];
5038 if (! arglist
|| TREE_CHAIN (arglist
))
5040 arg
= TREE_VALUE (arglist
);
5041 if (! POINTER_TYPE_P (TREE_TYPE (arg
)))
5044 if (target
!= const0_rtx
)
5046 len
= c_strlen (arg
, 1);
5047 if (! len
|| TREE_CODE (len
) != INTEGER_CST
)
5053 arglist
= build_tree_list (NULL_TREE
, arg
);
5054 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
5055 expand_expr (build_function_call_expr (fn
, arglist
),
5056 const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
5058 if (target
== const0_rtx
)
5060 return expand_expr (len
, target
, mode
, EXPAND_NORMAL
);
5066 /* Expand a call to either the entry or exit function profiler. */
5069 expand_builtin_profile_func (bool exitp
)
5073 this = DECL_RTL (current_function_decl
);
5074 gcc_assert (MEM_P (this));
5075 this = XEXP (this, 0);
5078 which
= profile_function_exit_libfunc
;
5080 which
= profile_function_entry_libfunc
;
5082 emit_library_call (which
, LCT_NORMAL
, VOIDmode
, 2, this, Pmode
,
5083 expand_builtin_return_addr (BUILT_IN_RETURN_ADDRESS
,
5090 /* Given a trampoline address, make sure it satisfies TRAMPOLINE_ALIGNMENT. */
5093 round_trampoline_addr (rtx tramp
)
5095 rtx temp
, addend
, mask
;
5097 /* If we don't need too much alignment, we'll have been guaranteed
5098 proper alignment by get_trampoline_type. */
5099 if (TRAMPOLINE_ALIGNMENT
<= STACK_BOUNDARY
)
5102 /* Round address up to desired boundary. */
5103 temp
= gen_reg_rtx (Pmode
);
5104 addend
= GEN_INT (TRAMPOLINE_ALIGNMENT
/ BITS_PER_UNIT
- 1);
5105 mask
= GEN_INT (-TRAMPOLINE_ALIGNMENT
/ BITS_PER_UNIT
);
5107 temp
= expand_simple_binop (Pmode
, PLUS
, tramp
, addend
,
5108 temp
, 0, OPTAB_LIB_WIDEN
);
5109 tramp
= expand_simple_binop (Pmode
, AND
, temp
, mask
,
5110 temp
, 0, OPTAB_LIB_WIDEN
);
5116 expand_builtin_init_trampoline (tree arglist
)
5118 tree t_tramp
, t_func
, t_chain
;
5119 rtx r_tramp
, r_func
, r_chain
;
5120 #ifdef TRAMPOLINE_TEMPLATE
5124 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
,
5125 POINTER_TYPE
, VOID_TYPE
))
5128 t_tramp
= TREE_VALUE (arglist
);
5129 arglist
= TREE_CHAIN (arglist
);
5130 t_func
= TREE_VALUE (arglist
);
5131 arglist
= TREE_CHAIN (arglist
);
5132 t_chain
= TREE_VALUE (arglist
);
5134 r_tramp
= expand_expr (t_tramp
, NULL_RTX
, VOIDmode
, 0);
5135 r_func
= expand_expr (t_func
, NULL_RTX
, VOIDmode
, 0);
5136 r_chain
= expand_expr (t_chain
, NULL_RTX
, VOIDmode
, 0);
5138 /* Generate insns to initialize the trampoline. */
5139 r_tramp
= round_trampoline_addr (r_tramp
);
5140 #ifdef TRAMPOLINE_TEMPLATE
5141 blktramp
= gen_rtx_MEM (BLKmode
, r_tramp
);
5142 set_mem_align (blktramp
, TRAMPOLINE_ALIGNMENT
);
5143 emit_block_move (blktramp
, assemble_trampoline_template (),
5144 GEN_INT (TRAMPOLINE_SIZE
), BLOCK_OP_NORMAL
);
5146 trampolines_created
= 1;
5147 INITIALIZE_TRAMPOLINE (r_tramp
, r_func
, r_chain
);
5153 expand_builtin_adjust_trampoline (tree arglist
)
5157 if (!validate_arglist (arglist
, POINTER_TYPE
, VOID_TYPE
))
5160 tramp
= expand_expr (TREE_VALUE (arglist
), NULL_RTX
, VOIDmode
, 0);
5161 tramp
= round_trampoline_addr (tramp
);
5162 #ifdef TRAMPOLINE_ADJUST_ADDRESS
5163 TRAMPOLINE_ADJUST_ADDRESS (tramp
);
5169 /* Expand a call to the built-in signbit, signbitf or signbitl function.
5170 Return NULL_RTX if a normal call should be emitted rather than expanding
5171 the function in-line. EXP is the expression that is a call to the builtin
5172 function; if convenient, the result should be placed in TARGET. */
5175 expand_builtin_signbit (tree exp
, rtx target
)
5177 const struct real_format
*fmt
;
5178 enum machine_mode fmode
, imode
, rmode
;
5179 HOST_WIDE_INT hi
, lo
;
5184 arglist
= TREE_OPERAND (exp
, 1);
5185 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
5188 arg
= TREE_VALUE (arglist
);
5189 fmode
= TYPE_MODE (TREE_TYPE (arg
));
5190 rmode
= TYPE_MODE (TREE_TYPE (exp
));
5191 fmt
= REAL_MODE_FORMAT (fmode
);
5193 /* For floating point formats without a sign bit, implement signbit
5195 bitpos
= fmt
->signbit_ro
;
5198 /* But we can't do this if the format supports signed zero. */
5199 if (fmt
->has_signed_zero
&& HONOR_SIGNED_ZEROS (fmode
))
5202 arg
= fold_build2 (LT_EXPR
, TREE_TYPE (exp
), arg
,
5203 build_real (TREE_TYPE (arg
), dconst0
));
5204 return expand_expr (arg
, target
, VOIDmode
, EXPAND_NORMAL
);
5207 temp
= expand_expr (arg
, NULL_RTX
, VOIDmode
, 0);
5208 if (GET_MODE_SIZE (fmode
) <= UNITS_PER_WORD
)
5210 imode
= int_mode_for_mode (fmode
);
5211 if (imode
== BLKmode
)
5213 temp
= gen_lowpart (imode
, temp
);
5218 /* Handle targets with different FP word orders. */
5219 if (FLOAT_WORDS_BIG_ENDIAN
)
5220 word
= (GET_MODE_BITSIZE (fmode
) - bitpos
) / BITS_PER_WORD
;
5222 word
= bitpos
/ BITS_PER_WORD
;
5223 temp
= operand_subword_force (temp
, word
, fmode
);
5224 bitpos
= bitpos
% BITS_PER_WORD
;
5227 /* Force the intermediate word_mode (or narrower) result into a
5228 register. This avoids attempting to create paradoxical SUBREGs
5229 of floating point modes below. */
5230 temp
= force_reg (imode
, temp
);
5232 /* If the bitpos is within the "result mode" lowpart, the operation
5233 can be implement with a single bitwise AND. Otherwise, we need
5234 a right shift and an AND. */
5236 if (bitpos
< GET_MODE_BITSIZE (rmode
))
5238 if (bitpos
< HOST_BITS_PER_WIDE_INT
)
5241 lo
= (HOST_WIDE_INT
) 1 << bitpos
;
5245 hi
= (HOST_WIDE_INT
) 1 << (bitpos
- HOST_BITS_PER_WIDE_INT
);
5250 temp
= gen_lowpart (rmode
, temp
);
5251 temp
= expand_binop (rmode
, and_optab
, temp
,
5252 immed_double_const (lo
, hi
, rmode
),
5253 NULL_RTX
, 1, OPTAB_LIB_WIDEN
);
5257 /* Perform a logical right shift to place the signbit in the least
5258 significant bit, then truncate the result to the desired mode
5259 and mask just this bit. */
5260 temp
= expand_shift (RSHIFT_EXPR
, imode
, temp
,
5261 build_int_cst (NULL_TREE
, bitpos
), NULL_RTX
, 1);
5262 temp
= gen_lowpart (rmode
, temp
);
5263 temp
= expand_binop (rmode
, and_optab
, temp
, const1_rtx
,
5264 NULL_RTX
, 1, OPTAB_LIB_WIDEN
);
5270 /* Expand fork or exec calls. TARGET is the desired target of the
5271 call. ARGLIST is the list of arguments of the call. FN is the
5272 identificator of the actual function. IGNORE is nonzero if the
5273 value is to be ignored. */
5276 expand_builtin_fork_or_exec (tree fn
, tree arglist
, rtx target
, int ignore
)
5281 /* If we are not profiling, just call the function. */
5282 if (!profile_arc_flag
)
5285 /* Otherwise call the wrapper. This should be equivalent for the rest of
5286 compiler, so the code does not diverge, and the wrapper may run the
5287 code necessary for keeping the profiling sane. */
5289 switch (DECL_FUNCTION_CODE (fn
))
5292 id
= get_identifier ("__gcov_fork");
5295 case BUILT_IN_EXECL
:
5296 id
= get_identifier ("__gcov_execl");
5299 case BUILT_IN_EXECV
:
5300 id
= get_identifier ("__gcov_execv");
5303 case BUILT_IN_EXECLP
:
5304 id
= get_identifier ("__gcov_execlp");
5307 case BUILT_IN_EXECLE
:
5308 id
= get_identifier ("__gcov_execle");
5311 case BUILT_IN_EXECVP
:
5312 id
= get_identifier ("__gcov_execvp");
5315 case BUILT_IN_EXECVE
:
5316 id
= get_identifier ("__gcov_execve");
5323 decl
= build_decl (FUNCTION_DECL
, id
, TREE_TYPE (fn
));
5324 DECL_EXTERNAL (decl
) = 1;
5325 TREE_PUBLIC (decl
) = 1;
5326 DECL_ARTIFICIAL (decl
) = 1;
5327 TREE_NOTHROW (decl
) = 1;
5328 call
= build_function_call_expr (decl
, arglist
);
5330 return expand_call (call
, target
, ignore
);
5334 /* Reconstitute a mode for a __sync intrinsic operation. Since the type of
5335 the pointer in these functions is void*, the tree optimizers may remove
5336 casts. The mode computed in expand_builtin isn't reliable either, due
5337 to __sync_bool_compare_and_swap.
5339 FCODE_DIFF should be fcode - base, where base is the FOO_1 code for the
5340 group of builtins. This gives us log2 of the mode size. */
5342 static inline enum machine_mode
5343 get_builtin_sync_mode (int fcode_diff
)
5345 /* The size is not negotiable, so ask not to get BLKmode in return
5346 if the target indicates that a smaller size would be better. */
5347 return mode_for_size (BITS_PER_UNIT
<< fcode_diff
, MODE_INT
, 0);
5350 /* Expand the __sync_xxx_and_fetch and __sync_fetch_and_xxx intrinsics.
5351 ARGLIST is the operands list to the function. CODE is the rtx code
5352 that corresponds to the arithmetic or logical operation from the name;
5353 an exception here is that NOT actually means NAND. TARGET is an optional
5354 place for us to store the results; AFTER is true if this is the
5355 fetch_and_xxx form. IGNORE is true if we don't actually care about
5356 the result of the operation at all. */
5359 expand_builtin_sync_operation (enum machine_mode mode
, tree arglist
,
5360 enum rtx_code code
, bool after
,
5361 rtx target
, bool ignore
)
5365 /* Expand the operands. */
5366 addr
= expand_expr (TREE_VALUE (arglist
), NULL
, Pmode
, EXPAND_SUM
);
5368 arglist
= TREE_CHAIN (arglist
);
5369 val
= expand_expr (TREE_VALUE (arglist
), NULL
, mode
, EXPAND_NORMAL
);
5371 /* Note that we explicitly do not want any alias information for this
5372 memory, so that we kill all other live memories. Otherwise we don't
5373 satisfy the full barrier semantics of the intrinsic. */
5374 mem
= validize_mem (gen_rtx_MEM (mode
, addr
));
5375 MEM_VOLATILE_P (mem
) = 1;
5378 return expand_sync_operation (mem
, val
, code
);
5380 return expand_sync_fetch_operation (mem
, val
, code
, after
, target
);
5383 /* Expand the __sync_val_compare_and_swap and __sync_bool_compare_and_swap
5384 intrinsics. ARGLIST is the operands list to the function. IS_BOOL is
5385 true if this is the boolean form. TARGET is a place for us to store the
5386 results; this is NOT optional if IS_BOOL is true. */
5389 expand_builtin_compare_and_swap (enum machine_mode mode
, tree arglist
,
5390 bool is_bool
, rtx target
)
5392 rtx addr
, old_val
, new_val
, mem
;
5394 /* Expand the operands. */
5395 addr
= expand_expr (TREE_VALUE (arglist
), NULL
, Pmode
, EXPAND_SUM
);
5397 arglist
= TREE_CHAIN (arglist
);
5398 old_val
= expand_expr (TREE_VALUE (arglist
), NULL
, mode
, EXPAND_NORMAL
);
5400 arglist
= TREE_CHAIN (arglist
);
5401 new_val
= expand_expr (TREE_VALUE (arglist
), NULL
, mode
, EXPAND_NORMAL
);
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
));
5407 MEM_VOLATILE_P (mem
) = 1;
5410 return expand_bool_compare_and_swap (mem
, old_val
, new_val
, target
);
5412 return expand_val_compare_and_swap (mem
, old_val
, new_val
, target
);
5415 /* Expand the __sync_lock_test_and_set intrinsic. Note that the most
5416 general form is actually an atomic exchange, and some targets only
5417 support a reduced form with the second argument being a constant 1.
5418 ARGLIST is the operands list to the function; TARGET is an optional
5419 place for us to store the results. */
5422 expand_builtin_lock_test_and_set (enum machine_mode mode
, tree arglist
,
5427 /* Expand the operands. */
5428 addr
= expand_expr (TREE_VALUE (arglist
), NULL
, Pmode
, EXPAND_NORMAL
);
5430 arglist
= TREE_CHAIN (arglist
);
5431 val
= expand_expr (TREE_VALUE (arglist
), NULL
, mode
, EXPAND_NORMAL
);
5433 /* Note that we explicitly do not want any alias information for this
5434 memory, so that we kill all other live memories. Otherwise we don't
5435 satisfy the barrier semantics of the intrinsic. */
5436 mem
= validize_mem (gen_rtx_MEM (mode
, addr
));
5437 MEM_VOLATILE_P (mem
) = 1;
5439 return expand_sync_lock_test_and_set (mem
, val
, target
);
5442 /* Expand the __sync_synchronize intrinsic. */
5445 expand_builtin_synchronize (void)
5449 #ifdef HAVE_memory_barrier
5450 if (HAVE_memory_barrier
)
5452 emit_insn (gen_memory_barrier ());
5457 /* If no explicit memory barrier instruction is available, create an
5458 empty asm stmt with a memory clobber. */
5459 x
= build4 (ASM_EXPR
, void_type_node
, build_string (0, ""), NULL
, NULL
,
5460 tree_cons (NULL
, build_string (6, "memory"), NULL
));
5461 ASM_VOLATILE_P (x
) = 1;
5462 expand_asm_expr (x
);
5465 /* Expand the __sync_lock_release intrinsic. ARGLIST is the operands list
5469 expand_builtin_lock_release (enum machine_mode mode
, tree arglist
)
5471 enum insn_code icode
;
5472 rtx addr
, mem
, insn
;
5473 rtx val
= const0_rtx
;
5475 /* Expand the operands. */
5476 addr
= expand_expr (TREE_VALUE (arglist
), NULL
, Pmode
, EXPAND_NORMAL
);
5478 /* Note that we explicitly do not want any alias information for this
5479 memory, so that we kill all other live memories. Otherwise we don't
5480 satisfy the barrier semantics of the intrinsic. */
5481 mem
= validize_mem (gen_rtx_MEM (mode
, addr
));
5482 MEM_VOLATILE_P (mem
) = 1;
5484 /* If there is an explicit operation in the md file, use it. */
5485 icode
= sync_lock_release
[mode
];
5486 if (icode
!= CODE_FOR_nothing
)
5488 if (!insn_data
[icode
].operand
[1].predicate (val
, mode
))
5489 val
= force_reg (mode
, val
);
5491 insn
= GEN_FCN (icode
) (mem
, val
);
5499 /* Otherwise we can implement this operation by emitting a barrier
5500 followed by a store of zero. */
5501 expand_builtin_synchronize ();
5502 emit_move_insn (mem
, val
);
5505 /* Expand an expression EXP that calls a built-in function,
5506 with result going to TARGET if that's convenient
5507 (and in mode MODE if that's convenient).
5508 SUBTARGET may be used as the target for computing one of EXP's operands.
5509 IGNORE is nonzero if the value is to be ignored. */
5512 expand_builtin (tree exp
, rtx target
, rtx subtarget
, enum machine_mode mode
,
5515 tree fndecl
= get_callee_fndecl (exp
);
5516 tree arglist
= TREE_OPERAND (exp
, 1);
5517 enum built_in_function fcode
= DECL_FUNCTION_CODE (fndecl
);
5518 enum machine_mode target_mode
= TYPE_MODE (TREE_TYPE (exp
));
5520 if (DECL_BUILT_IN_CLASS (fndecl
) == BUILT_IN_MD
)
5521 return targetm
.expand_builtin (exp
, target
, subtarget
, mode
, ignore
);
5523 /* When not optimizing, generate calls to library functions for a certain
5526 && !called_as_built_in (fndecl
)
5527 && DECL_ASSEMBLER_NAME_SET_P (fndecl
)
5528 && fcode
!= BUILT_IN_ALLOCA
)
5529 return expand_call (exp
, target
, ignore
);
5531 /* The built-in function expanders test for target == const0_rtx
5532 to determine whether the function's result will be ignored. */
5534 target
= const0_rtx
;
5536 /* If the result of a pure or const built-in function is ignored, and
5537 none of its arguments are volatile, we can avoid expanding the
5538 built-in call and just evaluate the arguments for side-effects. */
5539 if (target
== const0_rtx
5540 && (DECL_IS_PURE (fndecl
) || TREE_READONLY (fndecl
)))
5542 bool volatilep
= false;
5545 for (arg
= arglist
; arg
; arg
= TREE_CHAIN (arg
))
5546 if (TREE_THIS_VOLATILE (TREE_VALUE (arg
)))
5554 for (arg
= arglist
; arg
; arg
= TREE_CHAIN (arg
))
5555 expand_expr (TREE_VALUE (arg
), const0_rtx
,
5556 VOIDmode
, EXPAND_NORMAL
);
5563 CASE_FLT_FN (BUILT_IN_FABS
):
5564 target
= expand_builtin_fabs (arglist
, target
, subtarget
);
5569 CASE_FLT_FN (BUILT_IN_COPYSIGN
):
5570 target
= expand_builtin_copysign (arglist
, target
, subtarget
);
5575 /* Just do a normal library call if we were unable to fold
5577 CASE_FLT_FN (BUILT_IN_CABS
):
5580 CASE_FLT_FN (BUILT_IN_EXP
):
5581 CASE_FLT_FN (BUILT_IN_EXP10
):
5582 CASE_FLT_FN (BUILT_IN_POW10
):
5583 CASE_FLT_FN (BUILT_IN_EXP2
):
5584 CASE_FLT_FN (BUILT_IN_EXPM1
):
5585 CASE_FLT_FN (BUILT_IN_LOGB
):
5586 CASE_FLT_FN (BUILT_IN_ILOGB
):
5587 CASE_FLT_FN (BUILT_IN_LOG
):
5588 CASE_FLT_FN (BUILT_IN_LOG10
):
5589 CASE_FLT_FN (BUILT_IN_LOG2
):
5590 CASE_FLT_FN (BUILT_IN_LOG1P
):
5591 CASE_FLT_FN (BUILT_IN_TAN
):
5592 CASE_FLT_FN (BUILT_IN_ASIN
):
5593 CASE_FLT_FN (BUILT_IN_ACOS
):
5594 CASE_FLT_FN (BUILT_IN_ATAN
):
5595 /* Treat these like sqrt only if unsafe math optimizations are allowed,
5596 because of possible accuracy problems. */
5597 if (! flag_unsafe_math_optimizations
)
5599 CASE_FLT_FN (BUILT_IN_SQRT
):
5600 CASE_FLT_FN (BUILT_IN_FLOOR
):
5601 CASE_FLT_FN (BUILT_IN_CEIL
):
5602 CASE_FLT_FN (BUILT_IN_TRUNC
):
5603 CASE_FLT_FN (BUILT_IN_ROUND
):
5604 CASE_FLT_FN (BUILT_IN_NEARBYINT
):
5605 CASE_FLT_FN (BUILT_IN_RINT
):
5606 CASE_FLT_FN (BUILT_IN_LRINT
):
5607 CASE_FLT_FN (BUILT_IN_LLRINT
):
5608 target
= expand_builtin_mathfn (exp
, target
, subtarget
);
5613 CASE_FLT_FN (BUILT_IN_LCEIL
):
5614 CASE_FLT_FN (BUILT_IN_LLCEIL
):
5615 CASE_FLT_FN (BUILT_IN_LFLOOR
):
5616 CASE_FLT_FN (BUILT_IN_LLFLOOR
):
5617 target
= expand_builtin_int_roundingfn (exp
, target
, subtarget
);
5622 CASE_FLT_FN (BUILT_IN_POW
):
5623 target
= expand_builtin_pow (exp
, target
, subtarget
);
5628 CASE_FLT_FN (BUILT_IN_POWI
):
5629 target
= expand_builtin_powi (exp
, target
, subtarget
);
5634 CASE_FLT_FN (BUILT_IN_ATAN2
):
5635 CASE_FLT_FN (BUILT_IN_LDEXP
):
5636 CASE_FLT_FN (BUILT_IN_FMOD
):
5637 CASE_FLT_FN (BUILT_IN_DREM
):
5638 if (! flag_unsafe_math_optimizations
)
5640 target
= expand_builtin_mathfn_2 (exp
, target
, subtarget
);
5645 CASE_FLT_FN (BUILT_IN_SIN
):
5646 CASE_FLT_FN (BUILT_IN_COS
):
5647 if (! flag_unsafe_math_optimizations
)
5649 target
= expand_builtin_mathfn_3 (exp
, target
, subtarget
);
5654 case BUILT_IN_APPLY_ARGS
:
5655 return expand_builtin_apply_args ();
5657 /* __builtin_apply (FUNCTION, ARGUMENTS, ARGSIZE) invokes
5658 FUNCTION with a copy of the parameters described by
5659 ARGUMENTS, and ARGSIZE. It returns a block of memory
5660 allocated on the stack into which is stored all the registers
5661 that might possibly be used for returning the result of a
5662 function. ARGUMENTS is the value returned by
5663 __builtin_apply_args. ARGSIZE is the number of bytes of
5664 arguments that must be copied. ??? How should this value be
5665 computed? We'll also need a safe worst case value for varargs
5667 case BUILT_IN_APPLY
:
5668 if (!validate_arglist (arglist
, POINTER_TYPE
,
5669 POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
)
5670 && !validate_arglist (arglist
, REFERENCE_TYPE
,
5671 POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
5679 for (t
= arglist
, i
= 0; t
; t
= TREE_CHAIN (t
), i
++)
5680 ops
[i
] = expand_expr (TREE_VALUE (t
), NULL_RTX
, VOIDmode
, 0);
5682 return expand_builtin_apply (ops
[0], ops
[1], ops
[2]);
5685 /* __builtin_return (RESULT) causes the function to return the
5686 value described by RESULT. RESULT is address of the block of
5687 memory returned by __builtin_apply. */
5688 case BUILT_IN_RETURN
:
5689 if (validate_arglist (arglist
, POINTER_TYPE
, VOID_TYPE
))
5690 expand_builtin_return (expand_expr (TREE_VALUE (arglist
),
5691 NULL_RTX
, VOIDmode
, 0));
5694 case BUILT_IN_SAVEREGS
:
5695 return expand_builtin_saveregs ();
5697 case BUILT_IN_ARGS_INFO
:
5698 return expand_builtin_args_info (arglist
);
5700 /* Return the address of the first anonymous stack arg. */
5701 case BUILT_IN_NEXT_ARG
:
5702 if (fold_builtin_next_arg (arglist
))
5704 return expand_builtin_next_arg ();
5706 case BUILT_IN_CLASSIFY_TYPE
:
5707 return expand_builtin_classify_type (arglist
);
5709 case BUILT_IN_CONSTANT_P
:
5712 case BUILT_IN_FRAME_ADDRESS
:
5713 case BUILT_IN_RETURN_ADDRESS
:
5714 return expand_builtin_frame_address (fndecl
, arglist
);
5716 /* Returns the address of the area where the structure is returned.
5718 case BUILT_IN_AGGREGATE_INCOMING_ADDRESS
:
5720 || ! AGGREGATE_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl
)))
5721 || !MEM_P (DECL_RTL (DECL_RESULT (current_function_decl
))))
5724 return XEXP (DECL_RTL (DECL_RESULT (current_function_decl
)), 0);
5726 case BUILT_IN_ALLOCA
:
5727 target
= expand_builtin_alloca (arglist
, target
);
5732 case BUILT_IN_STACK_SAVE
:
5733 return expand_stack_save ();
5735 case BUILT_IN_STACK_RESTORE
:
5736 expand_stack_restore (TREE_VALUE (arglist
));
5739 CASE_INT_FN (BUILT_IN_FFS
):
5740 case BUILT_IN_FFSIMAX
:
5741 target
= expand_builtin_unop (target_mode
, arglist
, target
,
5742 subtarget
, ffs_optab
);
5747 CASE_INT_FN (BUILT_IN_CLZ
):
5748 case BUILT_IN_CLZIMAX
:
5749 target
= expand_builtin_unop (target_mode
, arglist
, target
,
5750 subtarget
, clz_optab
);
5755 CASE_INT_FN (BUILT_IN_CTZ
):
5756 case BUILT_IN_CTZIMAX
:
5757 target
= expand_builtin_unop (target_mode
, arglist
, target
,
5758 subtarget
, ctz_optab
);
5763 CASE_INT_FN (BUILT_IN_POPCOUNT
):
5764 case BUILT_IN_POPCOUNTIMAX
:
5765 target
= expand_builtin_unop (target_mode
, arglist
, target
,
5766 subtarget
, popcount_optab
);
5771 CASE_INT_FN (BUILT_IN_PARITY
):
5772 case BUILT_IN_PARITYIMAX
:
5773 target
= expand_builtin_unop (target_mode
, arglist
, target
,
5774 subtarget
, parity_optab
);
5779 case BUILT_IN_STRLEN
:
5780 target
= expand_builtin_strlen (arglist
, target
, target_mode
);
5785 case BUILT_IN_STRCPY
:
5786 target
= expand_builtin_strcpy (fndecl
, arglist
, target
, mode
);
5791 case BUILT_IN_STRNCPY
:
5792 target
= expand_builtin_strncpy (exp
, target
, mode
);
5797 case BUILT_IN_STPCPY
:
5798 target
= expand_builtin_stpcpy (exp
, target
, mode
);
5803 case BUILT_IN_STRCAT
:
5804 target
= expand_builtin_strcat (fndecl
, arglist
, target
, mode
);
5809 case BUILT_IN_STRNCAT
:
5810 target
= expand_builtin_strncat (arglist
, target
, mode
);
5815 case BUILT_IN_STRSPN
:
5816 target
= expand_builtin_strspn (arglist
, target
, mode
);
5821 case BUILT_IN_STRCSPN
:
5822 target
= expand_builtin_strcspn (arglist
, target
, mode
);
5827 case BUILT_IN_STRSTR
:
5828 target
= expand_builtin_strstr (arglist
, TREE_TYPE (exp
), target
, mode
);
5833 case BUILT_IN_STRPBRK
:
5834 target
= expand_builtin_strpbrk (arglist
, TREE_TYPE (exp
), target
, mode
);
5839 case BUILT_IN_INDEX
:
5840 case BUILT_IN_STRCHR
:
5841 target
= expand_builtin_strchr (arglist
, TREE_TYPE (exp
), target
, mode
);
5846 case BUILT_IN_RINDEX
:
5847 case BUILT_IN_STRRCHR
:
5848 target
= expand_builtin_strrchr (arglist
, TREE_TYPE (exp
), target
, mode
);
5853 case BUILT_IN_MEMCPY
:
5854 target
= expand_builtin_memcpy (exp
, target
, mode
);
5859 case BUILT_IN_MEMPCPY
:
5860 target
= expand_builtin_mempcpy (arglist
, TREE_TYPE (exp
), target
, mode
, /*endp=*/ 1);
5865 case BUILT_IN_MEMMOVE
:
5866 target
= expand_builtin_memmove (arglist
, TREE_TYPE (exp
), target
,
5872 case BUILT_IN_BCOPY
:
5873 target
= expand_builtin_bcopy (exp
);
5878 case BUILT_IN_MEMSET
:
5879 target
= expand_builtin_memset (arglist
, target
, mode
, exp
);
5884 case BUILT_IN_BZERO
:
5885 target
= expand_builtin_bzero (exp
);
5890 case BUILT_IN_STRCMP
:
5891 target
= expand_builtin_strcmp (exp
, target
, mode
);
5896 case BUILT_IN_STRNCMP
:
5897 target
= expand_builtin_strncmp (exp
, target
, mode
);
5903 case BUILT_IN_MEMCMP
:
5904 target
= expand_builtin_memcmp (exp
, arglist
, target
, mode
);
5909 case BUILT_IN_SETJMP
:
5910 target
= expand_builtin_setjmp (arglist
, target
);
5915 /* __builtin_longjmp is passed a pointer to an array of five words.
5916 It's similar to the C library longjmp function but works with
5917 __builtin_setjmp above. */
5918 case BUILT_IN_LONGJMP
:
5919 if (!validate_arglist (arglist
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
5923 rtx buf_addr
= expand_expr (TREE_VALUE (arglist
), subtarget
,
5925 rtx value
= expand_expr (TREE_VALUE (TREE_CHAIN (arglist
)),
5926 NULL_RTX
, VOIDmode
, 0);
5928 if (value
!= const1_rtx
)
5930 error ("%<__builtin_longjmp%> second argument must be 1");
5934 expand_builtin_longjmp (buf_addr
, value
);
5938 case BUILT_IN_NONLOCAL_GOTO
:
5939 target
= expand_builtin_nonlocal_goto (arglist
);
5944 /* This updates the setjmp buffer that is its argument with the value
5945 of the current stack pointer. */
5946 case BUILT_IN_UPDATE_SETJMP_BUF
:
5947 if (validate_arglist (arglist
, POINTER_TYPE
, VOID_TYPE
))
5950 = expand_expr (TREE_VALUE (arglist
), NULL_RTX
, VOIDmode
, 0);
5952 expand_builtin_update_setjmp_buf (buf_addr
);
5958 expand_builtin_trap ();
5961 case BUILT_IN_PRINTF
:
5962 target
= expand_builtin_printf (exp
, target
, mode
, false);
5967 case BUILT_IN_PRINTF_UNLOCKED
:
5968 target
= expand_builtin_printf (exp
, target
, mode
, true);
5973 case BUILT_IN_FPUTS
:
5974 target
= expand_builtin_fputs (arglist
, target
, false);
5978 case BUILT_IN_FPUTS_UNLOCKED
:
5979 target
= expand_builtin_fputs (arglist
, target
, true);
5984 case BUILT_IN_FPRINTF
:
5985 target
= expand_builtin_fprintf (exp
, target
, mode
, false);
5990 case BUILT_IN_FPRINTF_UNLOCKED
:
5991 target
= expand_builtin_fprintf (exp
, target
, mode
, true);
5996 case BUILT_IN_SPRINTF
:
5997 target
= expand_builtin_sprintf (arglist
, target
, mode
);
6002 CASE_FLT_FN (BUILT_IN_SIGNBIT
):
6003 target
= expand_builtin_signbit (exp
, target
);
6008 /* Various hooks for the DWARF 2 __throw routine. */
6009 case BUILT_IN_UNWIND_INIT
:
6010 expand_builtin_unwind_init ();
6012 case BUILT_IN_DWARF_CFA
:
6013 return virtual_cfa_rtx
;
6014 #ifdef DWARF2_UNWIND_INFO
6015 case BUILT_IN_DWARF_SP_COLUMN
:
6016 return expand_builtin_dwarf_sp_column ();
6017 case BUILT_IN_INIT_DWARF_REG_SIZES
:
6018 expand_builtin_init_dwarf_reg_sizes (TREE_VALUE (arglist
));
6021 case BUILT_IN_FROB_RETURN_ADDR
:
6022 return expand_builtin_frob_return_addr (TREE_VALUE (arglist
));
6023 case BUILT_IN_EXTRACT_RETURN_ADDR
:
6024 return expand_builtin_extract_return_addr (TREE_VALUE (arglist
));
6025 case BUILT_IN_EH_RETURN
:
6026 expand_builtin_eh_return (TREE_VALUE (arglist
),
6027 TREE_VALUE (TREE_CHAIN (arglist
)));
6029 #ifdef EH_RETURN_DATA_REGNO
6030 case BUILT_IN_EH_RETURN_DATA_REGNO
:
6031 return expand_builtin_eh_return_data_regno (arglist
);
6033 case BUILT_IN_EXTEND_POINTER
:
6034 return expand_builtin_extend_pointer (TREE_VALUE (arglist
));
6036 case BUILT_IN_VA_START
:
6037 case BUILT_IN_STDARG_START
:
6038 return expand_builtin_va_start (arglist
);
6039 case BUILT_IN_VA_END
:
6040 return expand_builtin_va_end (arglist
);
6041 case BUILT_IN_VA_COPY
:
6042 return expand_builtin_va_copy (arglist
);
6043 case BUILT_IN_EXPECT
:
6044 return expand_builtin_expect (arglist
, target
);
6045 case BUILT_IN_PREFETCH
:
6046 expand_builtin_prefetch (arglist
);
6049 case BUILT_IN_PROFILE_FUNC_ENTER
:
6050 return expand_builtin_profile_func (false);
6051 case BUILT_IN_PROFILE_FUNC_EXIT
:
6052 return expand_builtin_profile_func (true);
6054 case BUILT_IN_INIT_TRAMPOLINE
:
6055 return expand_builtin_init_trampoline (arglist
);
6056 case BUILT_IN_ADJUST_TRAMPOLINE
:
6057 return expand_builtin_adjust_trampoline (arglist
);
6060 case BUILT_IN_EXECL
:
6061 case BUILT_IN_EXECV
:
6062 case BUILT_IN_EXECLP
:
6063 case BUILT_IN_EXECLE
:
6064 case BUILT_IN_EXECVP
:
6065 case BUILT_IN_EXECVE
:
6066 target
= expand_builtin_fork_or_exec (fndecl
, arglist
, target
, ignore
);
6071 case BUILT_IN_FETCH_AND_ADD_1
:
6072 case BUILT_IN_FETCH_AND_ADD_2
:
6073 case BUILT_IN_FETCH_AND_ADD_4
:
6074 case BUILT_IN_FETCH_AND_ADD_8
:
6075 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_FETCH_AND_ADD_1
);
6076 target
= expand_builtin_sync_operation (mode
, arglist
, PLUS
,
6077 false, target
, ignore
);
6082 case BUILT_IN_FETCH_AND_SUB_1
:
6083 case BUILT_IN_FETCH_AND_SUB_2
:
6084 case BUILT_IN_FETCH_AND_SUB_4
:
6085 case BUILT_IN_FETCH_AND_SUB_8
:
6086 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_FETCH_AND_SUB_1
);
6087 target
= expand_builtin_sync_operation (mode
, arglist
, MINUS
,
6088 false, target
, ignore
);
6093 case BUILT_IN_FETCH_AND_OR_1
:
6094 case BUILT_IN_FETCH_AND_OR_2
:
6095 case BUILT_IN_FETCH_AND_OR_4
:
6096 case BUILT_IN_FETCH_AND_OR_8
:
6097 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_FETCH_AND_OR_1
);
6098 target
= expand_builtin_sync_operation (mode
, arglist
, IOR
,
6099 false, target
, ignore
);
6104 case BUILT_IN_FETCH_AND_AND_1
:
6105 case BUILT_IN_FETCH_AND_AND_2
:
6106 case BUILT_IN_FETCH_AND_AND_4
:
6107 case BUILT_IN_FETCH_AND_AND_8
:
6108 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_FETCH_AND_AND_1
);
6109 target
= expand_builtin_sync_operation (mode
, arglist
, AND
,
6110 false, target
, ignore
);
6115 case BUILT_IN_FETCH_AND_XOR_1
:
6116 case BUILT_IN_FETCH_AND_XOR_2
:
6117 case BUILT_IN_FETCH_AND_XOR_4
:
6118 case BUILT_IN_FETCH_AND_XOR_8
:
6119 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_FETCH_AND_XOR_1
);
6120 target
= expand_builtin_sync_operation (mode
, arglist
, XOR
,
6121 false, target
, ignore
);
6126 case BUILT_IN_FETCH_AND_NAND_1
:
6127 case BUILT_IN_FETCH_AND_NAND_2
:
6128 case BUILT_IN_FETCH_AND_NAND_4
:
6129 case BUILT_IN_FETCH_AND_NAND_8
:
6130 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_FETCH_AND_NAND_1
);
6131 target
= expand_builtin_sync_operation (mode
, arglist
, NOT
,
6132 false, target
, ignore
);
6137 case BUILT_IN_ADD_AND_FETCH_1
:
6138 case BUILT_IN_ADD_AND_FETCH_2
:
6139 case BUILT_IN_ADD_AND_FETCH_4
:
6140 case BUILT_IN_ADD_AND_FETCH_8
:
6141 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_ADD_AND_FETCH_1
);
6142 target
= expand_builtin_sync_operation (mode
, arglist
, PLUS
,
6143 true, target
, ignore
);
6148 case BUILT_IN_SUB_AND_FETCH_1
:
6149 case BUILT_IN_SUB_AND_FETCH_2
:
6150 case BUILT_IN_SUB_AND_FETCH_4
:
6151 case BUILT_IN_SUB_AND_FETCH_8
:
6152 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_SUB_AND_FETCH_1
);
6153 target
= expand_builtin_sync_operation (mode
, arglist
, MINUS
,
6154 true, target
, ignore
);
6159 case BUILT_IN_OR_AND_FETCH_1
:
6160 case BUILT_IN_OR_AND_FETCH_2
:
6161 case BUILT_IN_OR_AND_FETCH_4
:
6162 case BUILT_IN_OR_AND_FETCH_8
:
6163 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_OR_AND_FETCH_1
);
6164 target
= expand_builtin_sync_operation (mode
, arglist
, IOR
,
6165 true, target
, ignore
);
6170 case BUILT_IN_AND_AND_FETCH_1
:
6171 case BUILT_IN_AND_AND_FETCH_2
:
6172 case BUILT_IN_AND_AND_FETCH_4
:
6173 case BUILT_IN_AND_AND_FETCH_8
:
6174 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_AND_AND_FETCH_1
);
6175 target
= expand_builtin_sync_operation (mode
, arglist
, AND
,
6176 true, target
, ignore
);
6181 case BUILT_IN_XOR_AND_FETCH_1
:
6182 case BUILT_IN_XOR_AND_FETCH_2
:
6183 case BUILT_IN_XOR_AND_FETCH_4
:
6184 case BUILT_IN_XOR_AND_FETCH_8
:
6185 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_XOR_AND_FETCH_1
);
6186 target
= expand_builtin_sync_operation (mode
, arglist
, XOR
,
6187 true, target
, ignore
);
6192 case BUILT_IN_NAND_AND_FETCH_1
:
6193 case BUILT_IN_NAND_AND_FETCH_2
:
6194 case BUILT_IN_NAND_AND_FETCH_4
:
6195 case BUILT_IN_NAND_AND_FETCH_8
:
6196 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_NAND_AND_FETCH_1
);
6197 target
= expand_builtin_sync_operation (mode
, arglist
, NOT
,
6198 true, target
, ignore
);
6203 case BUILT_IN_BOOL_COMPARE_AND_SWAP_1
:
6204 case BUILT_IN_BOOL_COMPARE_AND_SWAP_2
:
6205 case BUILT_IN_BOOL_COMPARE_AND_SWAP_4
:
6206 case BUILT_IN_BOOL_COMPARE_AND_SWAP_8
:
6207 if (mode
== VOIDmode
)
6208 mode
= TYPE_MODE (boolean_type_node
);
6209 if (!target
|| !register_operand (target
, mode
))
6210 target
= gen_reg_rtx (mode
);
6212 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_BOOL_COMPARE_AND_SWAP_1
);
6213 target
= expand_builtin_compare_and_swap (mode
, arglist
, true, target
);
6218 case BUILT_IN_VAL_COMPARE_AND_SWAP_1
:
6219 case BUILT_IN_VAL_COMPARE_AND_SWAP_2
:
6220 case BUILT_IN_VAL_COMPARE_AND_SWAP_4
:
6221 case BUILT_IN_VAL_COMPARE_AND_SWAP_8
:
6222 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_VAL_COMPARE_AND_SWAP_1
);
6223 target
= expand_builtin_compare_and_swap (mode
, arglist
, false, target
);
6228 case BUILT_IN_LOCK_TEST_AND_SET_1
:
6229 case BUILT_IN_LOCK_TEST_AND_SET_2
:
6230 case BUILT_IN_LOCK_TEST_AND_SET_4
:
6231 case BUILT_IN_LOCK_TEST_AND_SET_8
:
6232 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_LOCK_TEST_AND_SET_1
);
6233 target
= expand_builtin_lock_test_and_set (mode
, arglist
, target
);
6238 case BUILT_IN_LOCK_RELEASE_1
:
6239 case BUILT_IN_LOCK_RELEASE_2
:
6240 case BUILT_IN_LOCK_RELEASE_4
:
6241 case BUILT_IN_LOCK_RELEASE_8
:
6242 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_LOCK_RELEASE_1
);
6243 expand_builtin_lock_release (mode
, arglist
);
6246 case BUILT_IN_SYNCHRONIZE
:
6247 expand_builtin_synchronize ();
6250 case BUILT_IN_OBJECT_SIZE
:
6251 return expand_builtin_object_size (exp
);
6253 case BUILT_IN_MEMCPY_CHK
:
6254 case BUILT_IN_MEMPCPY_CHK
:
6255 case BUILT_IN_MEMMOVE_CHK
:
6256 case BUILT_IN_MEMSET_CHK
:
6257 target
= expand_builtin_memory_chk (exp
, target
, mode
, fcode
);
6262 case BUILT_IN_STRCPY_CHK
:
6263 case BUILT_IN_STPCPY_CHK
:
6264 case BUILT_IN_STRNCPY_CHK
:
6265 case BUILT_IN_STRCAT_CHK
:
6266 case BUILT_IN_SNPRINTF_CHK
:
6267 case BUILT_IN_VSNPRINTF_CHK
:
6268 maybe_emit_chk_warning (exp
, fcode
);
6271 case BUILT_IN_SPRINTF_CHK
:
6272 case BUILT_IN_VSPRINTF_CHK
:
6273 maybe_emit_sprintf_chk_warning (exp
, fcode
);
6276 default: /* just do library call, if unknown builtin */
6280 /* The switch statement above can drop through to cause the function
6281 to be called normally. */
6282 return expand_call (exp
, target
, ignore
);
6285 /* Determine whether a tree node represents a call to a built-in
6286 function. If the tree T is a call to a built-in function with
6287 the right number of arguments of the appropriate types, return
6288 the DECL_FUNCTION_CODE of the call, e.g. BUILT_IN_SQRT.
6289 Otherwise the return value is END_BUILTINS. */
6291 enum built_in_function
6292 builtin_mathfn_code (tree t
)
6294 tree fndecl
, arglist
, parmlist
;
6295 tree argtype
, parmtype
;
6297 if (TREE_CODE (t
) != CALL_EXPR
6298 || TREE_CODE (TREE_OPERAND (t
, 0)) != ADDR_EXPR
)
6299 return END_BUILTINS
;
6301 fndecl
= get_callee_fndecl (t
);
6302 if (fndecl
== NULL_TREE
6303 || TREE_CODE (fndecl
) != FUNCTION_DECL
6304 || ! DECL_BUILT_IN (fndecl
)
6305 || DECL_BUILT_IN_CLASS (fndecl
) == BUILT_IN_MD
)
6306 return END_BUILTINS
;
6308 arglist
= TREE_OPERAND (t
, 1);
6309 parmlist
= TYPE_ARG_TYPES (TREE_TYPE (fndecl
));
6310 for (; parmlist
; parmlist
= TREE_CHAIN (parmlist
))
6312 /* If a function doesn't take a variable number of arguments,
6313 the last element in the list will have type `void'. */
6314 parmtype
= TREE_VALUE (parmlist
);
6315 if (VOID_TYPE_P (parmtype
))
6318 return END_BUILTINS
;
6319 return DECL_FUNCTION_CODE (fndecl
);
6323 return END_BUILTINS
;
6325 argtype
= TREE_TYPE (TREE_VALUE (arglist
));
6327 if (SCALAR_FLOAT_TYPE_P (parmtype
))
6329 if (! SCALAR_FLOAT_TYPE_P (argtype
))
6330 return END_BUILTINS
;
6332 else if (COMPLEX_FLOAT_TYPE_P (parmtype
))
6334 if (! COMPLEX_FLOAT_TYPE_P (argtype
))
6335 return END_BUILTINS
;
6337 else if (POINTER_TYPE_P (parmtype
))
6339 if (! POINTER_TYPE_P (argtype
))
6340 return END_BUILTINS
;
6342 else if (INTEGRAL_TYPE_P (parmtype
))
6344 if (! INTEGRAL_TYPE_P (argtype
))
6345 return END_BUILTINS
;
6348 return END_BUILTINS
;
6350 arglist
= TREE_CHAIN (arglist
);
6353 /* Variable-length argument list. */
6354 return DECL_FUNCTION_CODE (fndecl
);
6357 /* Fold a call to __builtin_constant_p, if we know it will evaluate to a
6358 constant. ARGLIST is the argument list of the call. */
6361 fold_builtin_constant_p (tree arglist
)
6366 arglist
= TREE_VALUE (arglist
);
6368 /* We return 1 for a numeric type that's known to be a constant
6369 value at compile-time or for an aggregate type that's a
6370 literal constant. */
6371 STRIP_NOPS (arglist
);
6373 /* If we know this is a constant, emit the constant of one. */
6374 if (CONSTANT_CLASS_P (arglist
)
6375 || (TREE_CODE (arglist
) == CONSTRUCTOR
6376 && TREE_CONSTANT (arglist
)))
6377 return integer_one_node
;
6378 if (TREE_CODE (arglist
) == ADDR_EXPR
)
6380 tree op
= TREE_OPERAND (arglist
, 0);
6381 if (TREE_CODE (op
) == STRING_CST
6382 || (TREE_CODE (op
) == ARRAY_REF
6383 && integer_zerop (TREE_OPERAND (op
, 1))
6384 && TREE_CODE (TREE_OPERAND (op
, 0)) == STRING_CST
))
6385 return integer_one_node
;
6388 /* If this expression has side effects, show we don't know it to be a
6389 constant. Likewise if it's a pointer or aggregate type since in
6390 those case we only want literals, since those are only optimized
6391 when generating RTL, not later.
6392 And finally, if we are compiling an initializer, not code, we
6393 need to return a definite result now; there's not going to be any
6394 more optimization done. */
6395 if (TREE_SIDE_EFFECTS (arglist
)
6396 || AGGREGATE_TYPE_P (TREE_TYPE (arglist
))
6397 || POINTER_TYPE_P (TREE_TYPE (arglist
))
6399 return integer_zero_node
;
6404 /* Fold a call to __builtin_expect, if we expect that a comparison against
6405 the argument will fold to a constant. In practice, this means a true
6406 constant or the address of a non-weak symbol. ARGLIST is the argument
6407 list of the call. */
6410 fold_builtin_expect (tree arglist
)
6417 arg
= TREE_VALUE (arglist
);
6419 /* If the argument isn't invariant, then there's nothing we can do. */
6420 if (!TREE_INVARIANT (arg
))
6423 /* If we're looking at an address of a weak decl, then do not fold. */
6426 if (TREE_CODE (inner
) == ADDR_EXPR
)
6430 inner
= TREE_OPERAND (inner
, 0);
6432 while (TREE_CODE (inner
) == COMPONENT_REF
6433 || TREE_CODE (inner
) == ARRAY_REF
);
6434 if (DECL_P (inner
) && DECL_WEAK (inner
))
6438 /* Otherwise, ARG already has the proper type for the return value. */
6442 /* Fold a call to __builtin_classify_type. */
6445 fold_builtin_classify_type (tree arglist
)
6448 return build_int_cst (NULL_TREE
, no_type_class
);
6450 return build_int_cst (NULL_TREE
,
6451 type_to_class (TREE_TYPE (TREE_VALUE (arglist
))));
6454 /* Fold a call to __builtin_strlen. */
6457 fold_builtin_strlen (tree arglist
)
6459 if (!validate_arglist (arglist
, POINTER_TYPE
, VOID_TYPE
))
6463 tree len
= c_strlen (TREE_VALUE (arglist
), 0);
6467 /* Convert from the internal "sizetype" type to "size_t". */
6469 len
= fold_convert (size_type_node
, len
);
6477 /* Fold a call to __builtin_inf or __builtin_huge_val. */
6480 fold_builtin_inf (tree type
, int warn
)
6482 REAL_VALUE_TYPE real
;
6484 /* __builtin_inff is intended to be usable to define INFINITY on all
6485 targets. If an infinity is not available, INFINITY expands "to a
6486 positive constant of type float that overflows at translation
6487 time", footnote "In this case, using INFINITY will violate the
6488 constraint in 6.4.4 and thus require a diagnostic." (C99 7.12#4).
6489 Thus we pedwarn to ensure this constraint violation is
6491 if (!MODE_HAS_INFINITIES (TYPE_MODE (type
)) && warn
)
6492 pedwarn ("target format does not support infinity");
6495 return build_real (type
, real
);
6498 /* Fold a call to __builtin_nan or __builtin_nans. */
6501 fold_builtin_nan (tree arglist
, tree type
, int quiet
)
6503 REAL_VALUE_TYPE real
;
6506 if (!validate_arglist (arglist
, POINTER_TYPE
, VOID_TYPE
))
6508 str
= c_getstr (TREE_VALUE (arglist
));
6512 if (!real_nan (&real
, str
, quiet
, TYPE_MODE (type
)))
6515 return build_real (type
, real
);
6518 /* Return true if the floating point expression T has an integer value.
6519 We also allow +Inf, -Inf and NaN to be considered integer values. */
6522 integer_valued_real_p (tree t
)
6524 switch (TREE_CODE (t
))
6531 case NON_LVALUE_EXPR
:
6532 return integer_valued_real_p (TREE_OPERAND (t
, 0));
6537 return integer_valued_real_p (TREE_OPERAND (t
, 1));
6544 return integer_valued_real_p (TREE_OPERAND (t
, 0))
6545 && integer_valued_real_p (TREE_OPERAND (t
, 1));
6548 return integer_valued_real_p (TREE_OPERAND (t
, 1))
6549 && integer_valued_real_p (TREE_OPERAND (t
, 2));
6552 if (! TREE_CONSTANT_OVERFLOW (t
))
6554 REAL_VALUE_TYPE c
, cint
;
6556 c
= TREE_REAL_CST (t
);
6557 real_trunc (&cint
, TYPE_MODE (TREE_TYPE (t
)), &c
);
6558 return real_identical (&c
, &cint
);
6564 tree type
= TREE_TYPE (TREE_OPERAND (t
, 0));
6565 if (TREE_CODE (type
) == INTEGER_TYPE
)
6567 if (TREE_CODE (type
) == REAL_TYPE
)
6568 return integer_valued_real_p (TREE_OPERAND (t
, 0));
6573 switch (builtin_mathfn_code (t
))
6575 CASE_FLT_FN (BUILT_IN_CEIL
):
6576 CASE_FLT_FN (BUILT_IN_FLOOR
):
6577 CASE_FLT_FN (BUILT_IN_NEARBYINT
):
6578 CASE_FLT_FN (BUILT_IN_RINT
):
6579 CASE_FLT_FN (BUILT_IN_ROUND
):
6580 CASE_FLT_FN (BUILT_IN_TRUNC
):
6594 /* EXP is assumed to be builtin call where truncation can be propagated
6595 across (for instance floor((double)f) == (double)floorf (f).
6596 Do the transformation. */
6599 fold_trunc_transparent_mathfn (tree fndecl
, tree arglist
)
6601 enum built_in_function fcode
= DECL_FUNCTION_CODE (fndecl
);
6604 if (! validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
6607 arg
= TREE_VALUE (arglist
);
6608 /* Integer rounding functions are idempotent. */
6609 if (fcode
== builtin_mathfn_code (arg
))
6612 /* If argument is already integer valued, and we don't need to worry
6613 about setting errno, there's no need to perform rounding. */
6614 if (! flag_errno_math
&& integer_valued_real_p (arg
))
6619 tree arg0
= strip_float_extensions (arg
);
6620 tree ftype
= TREE_TYPE (TREE_TYPE (fndecl
));
6621 tree newtype
= TREE_TYPE (arg0
);
6624 if (TYPE_PRECISION (newtype
) < TYPE_PRECISION (ftype
)
6625 && (decl
= mathfn_built_in (newtype
, fcode
)))
6628 build_tree_list (NULL_TREE
, fold_convert (newtype
, arg0
));
6629 return fold_convert (ftype
,
6630 build_function_call_expr (decl
, arglist
));
6636 /* EXP is assumed to be builtin call which can narrow the FP type of
6637 the argument, for instance lround((double)f) -> lroundf (f). */
6640 fold_fixed_mathfn (tree fndecl
, tree arglist
)
6642 enum built_in_function fcode
= DECL_FUNCTION_CODE (fndecl
);
6645 if (! validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
6648 arg
= TREE_VALUE (arglist
);
6650 /* If argument is already integer valued, and we don't need to worry
6651 about setting errno, there's no need to perform rounding. */
6652 if (! flag_errno_math
&& integer_valued_real_p (arg
))
6653 return fold_build1 (FIX_TRUNC_EXPR
, TREE_TYPE (TREE_TYPE (fndecl
)), arg
);
6657 tree ftype
= TREE_TYPE (arg
);
6658 tree arg0
= strip_float_extensions (arg
);
6659 tree newtype
= TREE_TYPE (arg0
);
6662 if (TYPE_PRECISION (newtype
) < TYPE_PRECISION (ftype
)
6663 && (decl
= mathfn_built_in (newtype
, fcode
)))
6666 build_tree_list (NULL_TREE
, fold_convert (newtype
, arg0
));
6667 return build_function_call_expr (decl
, arglist
);
6673 /* Fold function call to builtin cabs, cabsf or cabsl. ARGLIST
6674 is the argument list and TYPE is the return type. Return
6675 NULL_TREE if no if no simplification can be made. */
6678 fold_builtin_cabs (tree arglist
, tree type
)
6682 if (!arglist
|| TREE_CHAIN (arglist
))
6685 arg
= TREE_VALUE (arglist
);
6686 if (TREE_CODE (TREE_TYPE (arg
)) != COMPLEX_TYPE
6687 || TREE_CODE (TREE_TYPE (TREE_TYPE (arg
))) != REAL_TYPE
)
6690 /* Evaluate cabs of a constant at compile-time. */
6691 if (flag_unsafe_math_optimizations
6692 && TREE_CODE (arg
) == COMPLEX_CST
6693 && TREE_CODE (TREE_REALPART (arg
)) == REAL_CST
6694 && TREE_CODE (TREE_IMAGPART (arg
)) == REAL_CST
6695 && ! TREE_CONSTANT_OVERFLOW (TREE_REALPART (arg
))
6696 && ! TREE_CONSTANT_OVERFLOW (TREE_IMAGPART (arg
)))
6698 REAL_VALUE_TYPE r
, i
;
6700 r
= TREE_REAL_CST (TREE_REALPART (arg
));
6701 i
= TREE_REAL_CST (TREE_IMAGPART (arg
));
6703 real_arithmetic (&r
, MULT_EXPR
, &r
, &r
);
6704 real_arithmetic (&i
, MULT_EXPR
, &i
, &i
);
6705 real_arithmetic (&r
, PLUS_EXPR
, &r
, &i
);
6706 if (real_sqrt (&r
, TYPE_MODE (type
), &r
)
6707 || ! flag_trapping_math
)
6708 return build_real (type
, r
);
6711 /* If either part is zero, cabs is fabs of the other. */
6712 if (TREE_CODE (arg
) == COMPLEX_EXPR
6713 && real_zerop (TREE_OPERAND (arg
, 0)))
6714 return fold_build1 (ABS_EXPR
, type
, TREE_OPERAND (arg
, 1));
6715 if (TREE_CODE (arg
) == COMPLEX_EXPR
6716 && real_zerop (TREE_OPERAND (arg
, 1)))
6717 return fold_build1 (ABS_EXPR
, type
, TREE_OPERAND (arg
, 0));
6719 /* Don't do this when optimizing for size. */
6720 if (flag_unsafe_math_optimizations
6721 && optimize
&& !optimize_size
)
6723 tree sqrtfn
= mathfn_built_in (type
, BUILT_IN_SQRT
);
6725 if (sqrtfn
!= NULL_TREE
)
6727 tree rpart
, ipart
, result
, arglist
;
6729 arg
= builtin_save_expr (arg
);
6731 rpart
= fold_build1 (REALPART_EXPR
, type
, arg
);
6732 ipart
= fold_build1 (IMAGPART_EXPR
, type
, arg
);
6734 rpart
= builtin_save_expr (rpart
);
6735 ipart
= builtin_save_expr (ipart
);
6737 result
= fold_build2 (PLUS_EXPR
, type
,
6738 fold_build2 (MULT_EXPR
, type
,
6740 fold_build2 (MULT_EXPR
, type
,
6743 arglist
= build_tree_list (NULL_TREE
, result
);
6744 return build_function_call_expr (sqrtfn
, arglist
);
6751 /* Fold a builtin function call to sqrt, sqrtf, or sqrtl. Return
6752 NULL_TREE if no simplification can be made. */
6755 fold_builtin_sqrt (tree arglist
, tree type
)
6758 enum built_in_function fcode
;
6759 tree arg
= TREE_VALUE (arglist
);
6761 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
6764 /* Optimize sqrt of constant value. */
6765 if (TREE_CODE (arg
) == REAL_CST
6766 && ! TREE_CONSTANT_OVERFLOW (arg
))
6768 REAL_VALUE_TYPE r
, x
;
6770 x
= TREE_REAL_CST (arg
);
6771 if (real_sqrt (&r
, TYPE_MODE (type
), &x
)
6772 || (!flag_trapping_math
&& !flag_errno_math
))
6773 return build_real (type
, r
);
6776 /* Optimize sqrt(expN(x)) = expN(x*0.5). */
6777 fcode
= builtin_mathfn_code (arg
);
6778 if (flag_unsafe_math_optimizations
&& BUILTIN_EXPONENT_P (fcode
))
6780 tree expfn
= TREE_OPERAND (TREE_OPERAND (arg
, 0), 0);
6781 arg
= fold_build2 (MULT_EXPR
, type
,
6782 TREE_VALUE (TREE_OPERAND (arg
, 1)),
6783 build_real (type
, dconsthalf
));
6784 arglist
= build_tree_list (NULL_TREE
, arg
);
6785 return build_function_call_expr (expfn
, arglist
);
6788 /* Optimize sqrt(Nroot(x)) -> pow(x,1/(2*N)). */
6789 if (flag_unsafe_math_optimizations
&& BUILTIN_ROOT_P (fcode
))
6791 tree powfn
= mathfn_built_in (type
, BUILT_IN_POW
);
6795 tree arg0
= TREE_VALUE (TREE_OPERAND (arg
, 1));
6797 /* The inner root was either sqrt or cbrt. */
6798 REAL_VALUE_TYPE dconstroot
=
6799 BUILTIN_SQRT_P (fcode
) ? dconsthalf
: dconstthird
;
6801 /* Adjust for the outer root. */
6802 SET_REAL_EXP (&dconstroot
, REAL_EXP (&dconstroot
) - 1);
6803 dconstroot
= real_value_truncate (TYPE_MODE (type
), dconstroot
);
6804 tree_root
= build_real (type
, dconstroot
);
6805 arglist
= tree_cons (NULL_TREE
, arg0
,
6806 build_tree_list (NULL_TREE
, tree_root
));
6807 return build_function_call_expr (powfn
, arglist
);
6811 /* Optimize sqrt(pow(x,y)) = pow(|x|,y*0.5). */
6812 if (flag_unsafe_math_optimizations
6813 && (fcode
== BUILT_IN_POW
6814 || fcode
== BUILT_IN_POWF
6815 || fcode
== BUILT_IN_POWL
))
6817 tree powfn
= TREE_OPERAND (TREE_OPERAND (arg
, 0), 0);
6818 tree arg0
= TREE_VALUE (TREE_OPERAND (arg
, 1));
6819 tree arg1
= TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg
, 1)));
6821 if (!tree_expr_nonnegative_p (arg0
))
6822 arg0
= build1 (ABS_EXPR
, type
, arg0
);
6823 narg1
= fold_build2 (MULT_EXPR
, type
, arg1
,
6824 build_real (type
, dconsthalf
));
6825 arglist
= tree_cons (NULL_TREE
, arg0
,
6826 build_tree_list (NULL_TREE
, narg1
));
6827 return build_function_call_expr (powfn
, arglist
);
6833 /* Fold a builtin function call to cbrt, cbrtf, or cbrtl. Return
6834 NULL_TREE if no simplification can be made. */
6836 fold_builtin_cbrt (tree arglist
, tree type
)
6838 tree arg
= TREE_VALUE (arglist
);
6839 const enum built_in_function fcode
= builtin_mathfn_code (arg
);
6841 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
6844 /* Optimize cbrt of constant value. */
6845 if (real_zerop (arg
) || real_onep (arg
) || real_minus_onep (arg
))
6848 if (flag_unsafe_math_optimizations
)
6850 /* Optimize cbrt(expN(x)) -> expN(x/3). */
6851 if (BUILTIN_EXPONENT_P (fcode
))
6853 tree expfn
= TREE_OPERAND (TREE_OPERAND (arg
, 0), 0);
6854 const REAL_VALUE_TYPE third_trunc
=
6855 real_value_truncate (TYPE_MODE (type
), dconstthird
);
6856 arg
= fold_build2 (MULT_EXPR
, type
,
6857 TREE_VALUE (TREE_OPERAND (arg
, 1)),
6858 build_real (type
, third_trunc
));
6859 arglist
= build_tree_list (NULL_TREE
, arg
);
6860 return build_function_call_expr (expfn
, arglist
);
6863 /* Optimize cbrt(sqrt(x)) -> pow(x,1/6). */
6864 if (BUILTIN_SQRT_P (fcode
))
6866 tree powfn
= mathfn_built_in (type
, BUILT_IN_POW
);
6870 tree arg0
= TREE_VALUE (TREE_OPERAND (arg
, 1));
6872 REAL_VALUE_TYPE dconstroot
= dconstthird
;
6874 SET_REAL_EXP (&dconstroot
, REAL_EXP (&dconstroot
) - 1);
6875 dconstroot
= real_value_truncate (TYPE_MODE (type
), dconstroot
);
6876 tree_root
= build_real (type
, dconstroot
);
6877 arglist
= tree_cons (NULL_TREE
, arg0
,
6878 build_tree_list (NULL_TREE
, tree_root
));
6879 return build_function_call_expr (powfn
, arglist
);
6883 /* Optimize cbrt(cbrt(x)) -> pow(x,1/9) iff x is nonnegative. */
6884 if (BUILTIN_CBRT_P (fcode
))
6886 tree arg0
= TREE_VALUE (TREE_OPERAND (arg
, 1));
6887 if (tree_expr_nonnegative_p (arg0
))
6889 tree powfn
= mathfn_built_in (type
, BUILT_IN_POW
);
6894 REAL_VALUE_TYPE dconstroot
;
6896 real_arithmetic (&dconstroot
, MULT_EXPR
, &dconstthird
, &dconstthird
);
6897 dconstroot
= real_value_truncate (TYPE_MODE (type
), dconstroot
);
6898 tree_root
= build_real (type
, dconstroot
);
6899 arglist
= tree_cons (NULL_TREE
, arg0
,
6900 build_tree_list (NULL_TREE
, tree_root
));
6901 return build_function_call_expr (powfn
, arglist
);
6906 /* Optimize cbrt(pow(x,y)) -> pow(x,y/3) iff x is nonnegative. */
6907 if (fcode
== BUILT_IN_POW
|| fcode
== BUILT_IN_POWF
6908 || fcode
== BUILT_IN_POWL
)
6910 tree arg00
= TREE_VALUE (TREE_OPERAND (arg
, 1));
6911 tree arg01
= TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg
, 1)));
6912 if (tree_expr_nonnegative_p (arg00
))
6914 tree powfn
= TREE_OPERAND (TREE_OPERAND (arg
, 0), 0);
6915 const REAL_VALUE_TYPE dconstroot
6916 = real_value_truncate (TYPE_MODE (type
), dconstthird
);
6917 tree narg01
= fold_build2 (MULT_EXPR
, type
, arg01
,
6918 build_real (type
, dconstroot
));
6919 arglist
= tree_cons (NULL_TREE
, arg00
,
6920 build_tree_list (NULL_TREE
, narg01
));
6921 return build_function_call_expr (powfn
, arglist
);
6928 /* Fold function call to builtin sin, sinf, or sinl. Return
6929 NULL_TREE if no simplification can be made. */
6931 fold_builtin_sin (tree arglist
)
6933 tree arg
= TREE_VALUE (arglist
);
6935 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
6938 /* Optimize sin (0.0) = 0.0. */
6939 if (real_zerop (arg
))
6945 /* Fold function call to builtin cos, cosf, or cosl. Return
6946 NULL_TREE if no simplification can be made. */
6948 fold_builtin_cos (tree arglist
, tree type
, tree fndecl
)
6950 tree arg
= TREE_VALUE (arglist
);
6952 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
6955 /* Optimize cos (0.0) = 1.0. */
6956 if (real_zerop (arg
))
6957 return build_real (type
, dconst1
);
6959 /* Optimize cos(-x) into cos (x). */
6960 if (TREE_CODE (arg
) == NEGATE_EXPR
)
6962 tree args
= build_tree_list (NULL_TREE
,
6963 TREE_OPERAND (arg
, 0));
6964 return build_function_call_expr (fndecl
, args
);
6970 /* Fold function call to builtin tan, tanf, or tanl. Return
6971 NULL_TREE if no simplification can be made. */
6973 fold_builtin_tan (tree arglist
)
6975 enum built_in_function fcode
;
6976 tree arg
= TREE_VALUE (arglist
);
6978 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
6981 /* Optimize tan(0.0) = 0.0. */
6982 if (real_zerop (arg
))
6985 /* Optimize tan(atan(x)) = x. */
6986 fcode
= builtin_mathfn_code (arg
);
6987 if (flag_unsafe_math_optimizations
6988 && (fcode
== BUILT_IN_ATAN
6989 || fcode
== BUILT_IN_ATANF
6990 || fcode
== BUILT_IN_ATANL
))
6991 return TREE_VALUE (TREE_OPERAND (arg
, 1));
6996 /* Fold function call to builtin atan, atanf, or atanl. Return
6997 NULL_TREE if no simplification can be made. */
7000 fold_builtin_atan (tree arglist
, tree type
)
7003 tree arg
= TREE_VALUE (arglist
);
7005 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
7008 /* Optimize atan(0.0) = 0.0. */
7009 if (real_zerop (arg
))
7012 /* Optimize atan(1.0) = pi/4. */
7013 if (real_onep (arg
))
7015 REAL_VALUE_TYPE cst
;
7017 real_convert (&cst
, TYPE_MODE (type
), &dconstpi
);
7018 SET_REAL_EXP (&cst
, REAL_EXP (&cst
) - 2);
7019 return build_real (type
, cst
);
7025 /* Fold function call to builtin trunc, truncf or truncl. Return
7026 NULL_TREE if no simplification can be made. */
7029 fold_builtin_trunc (tree fndecl
, tree arglist
)
7033 if (! validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
7036 /* Optimize trunc of constant value. */
7037 arg
= TREE_VALUE (arglist
);
7038 if (TREE_CODE (arg
) == REAL_CST
&& ! TREE_CONSTANT_OVERFLOW (arg
))
7040 REAL_VALUE_TYPE r
, x
;
7041 tree type
= TREE_TYPE (TREE_TYPE (fndecl
));
7043 x
= TREE_REAL_CST (arg
);
7044 real_trunc (&r
, TYPE_MODE (type
), &x
);
7045 return build_real (type
, r
);
7048 return fold_trunc_transparent_mathfn (fndecl
, arglist
);
7051 /* Fold function call to builtin floor, floorf or floorl. Return
7052 NULL_TREE if no simplification can be made. */
7055 fold_builtin_floor (tree fndecl
, tree arglist
)
7059 if (! validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
7062 /* Optimize floor of constant value. */
7063 arg
= TREE_VALUE (arglist
);
7064 if (TREE_CODE (arg
) == REAL_CST
&& ! TREE_CONSTANT_OVERFLOW (arg
))
7068 x
= TREE_REAL_CST (arg
);
7069 if (! REAL_VALUE_ISNAN (x
) || ! flag_errno_math
)
7071 tree type
= TREE_TYPE (TREE_TYPE (fndecl
));
7074 real_floor (&r
, TYPE_MODE (type
), &x
);
7075 return build_real (type
, r
);
7079 return fold_trunc_transparent_mathfn (fndecl
, arglist
);
7082 /* Fold function call to builtin ceil, ceilf or ceill. Return
7083 NULL_TREE if no simplification can be made. */
7086 fold_builtin_ceil (tree fndecl
, tree arglist
)
7090 if (! validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
7093 /* Optimize ceil of constant value. */
7094 arg
= TREE_VALUE (arglist
);
7095 if (TREE_CODE (arg
) == REAL_CST
&& ! TREE_CONSTANT_OVERFLOW (arg
))
7099 x
= TREE_REAL_CST (arg
);
7100 if (! REAL_VALUE_ISNAN (x
) || ! flag_errno_math
)
7102 tree type
= TREE_TYPE (TREE_TYPE (fndecl
));
7105 real_ceil (&r
, TYPE_MODE (type
), &x
);
7106 return build_real (type
, r
);
7110 return fold_trunc_transparent_mathfn (fndecl
, arglist
);
7113 /* Fold function call to builtin round, roundf or roundl. Return
7114 NULL_TREE if no simplification can be made. */
7117 fold_builtin_round (tree fndecl
, tree arglist
)
7121 if (! validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
7124 /* Optimize round of constant value. */
7125 arg
= TREE_VALUE (arglist
);
7126 if (TREE_CODE (arg
) == REAL_CST
&& ! TREE_CONSTANT_OVERFLOW (arg
))
7130 x
= TREE_REAL_CST (arg
);
7131 if (! REAL_VALUE_ISNAN (x
) || ! flag_errno_math
)
7133 tree type
= TREE_TYPE (TREE_TYPE (fndecl
));
7136 real_round (&r
, TYPE_MODE (type
), &x
);
7137 return build_real (type
, r
);
7141 return fold_trunc_transparent_mathfn (fndecl
, arglist
);
7144 /* Fold function call to builtin lround, lroundf or lroundl (or the
7145 corresponding long long versions) and other rounding functions.
7146 Return NULL_TREE if no simplification can be made. */
7149 fold_builtin_int_roundingfn (tree fndecl
, tree arglist
)
7153 if (! validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
7156 /* Optimize lround of constant value. */
7157 arg
= TREE_VALUE (arglist
);
7158 if (TREE_CODE (arg
) == REAL_CST
&& ! TREE_CONSTANT_OVERFLOW (arg
))
7160 const REAL_VALUE_TYPE x
= TREE_REAL_CST (arg
);
7162 if (! REAL_VALUE_ISNAN (x
) && ! REAL_VALUE_ISINF (x
))
7164 tree itype
= TREE_TYPE (TREE_TYPE (fndecl
));
7165 tree ftype
= TREE_TYPE (arg
), result
;
7166 HOST_WIDE_INT hi
, lo
;
7169 switch (DECL_FUNCTION_CODE (fndecl
))
7171 CASE_FLT_FN (BUILT_IN_LFLOOR
):
7172 CASE_FLT_FN (BUILT_IN_LLFLOOR
):
7173 real_floor (&r
, TYPE_MODE (ftype
), &x
);
7176 CASE_FLT_FN (BUILT_IN_LCEIL
):
7177 CASE_FLT_FN (BUILT_IN_LLCEIL
):
7178 real_ceil (&r
, TYPE_MODE (ftype
), &x
);
7181 CASE_FLT_FN (BUILT_IN_LROUND
):
7182 CASE_FLT_FN (BUILT_IN_LLROUND
):
7183 real_round (&r
, TYPE_MODE (ftype
), &x
);
7190 REAL_VALUE_TO_INT (&lo
, &hi
, r
);
7191 result
= build_int_cst_wide (NULL_TREE
, lo
, hi
);
7192 if (int_fits_type_p (result
, itype
))
7193 return fold_convert (itype
, result
);
7197 return fold_fixed_mathfn (fndecl
, arglist
);
7200 /* Fold function call to builtin ffs, clz, ctz, popcount and parity
7201 and their long and long long variants (i.e. ffsl and ffsll).
7202 Return NULL_TREE if no simplification can be made. */
7205 fold_builtin_bitop (tree fndecl
, tree arglist
)
7209 if (! validate_arglist (arglist
, INTEGER_TYPE
, VOID_TYPE
))
7212 /* Optimize for constant argument. */
7213 arg
= TREE_VALUE (arglist
);
7214 if (TREE_CODE (arg
) == INTEGER_CST
&& ! TREE_CONSTANT_OVERFLOW (arg
))
7216 HOST_WIDE_INT hi
, width
, result
;
7217 unsigned HOST_WIDE_INT lo
;
7220 type
= TREE_TYPE (arg
);
7221 width
= TYPE_PRECISION (type
);
7222 lo
= TREE_INT_CST_LOW (arg
);
7224 /* Clear all the bits that are beyond the type's precision. */
7225 if (width
> HOST_BITS_PER_WIDE_INT
)
7227 hi
= TREE_INT_CST_HIGH (arg
);
7228 if (width
< 2 * HOST_BITS_PER_WIDE_INT
)
7229 hi
&= ~((HOST_WIDE_INT
) (-1) >> (width
- HOST_BITS_PER_WIDE_INT
));
7234 if (width
< HOST_BITS_PER_WIDE_INT
)
7235 lo
&= ~((unsigned HOST_WIDE_INT
) (-1) << width
);
7238 switch (DECL_FUNCTION_CODE (fndecl
))
7240 CASE_INT_FN (BUILT_IN_FFS
):
7242 result
= exact_log2 (lo
& -lo
) + 1;
7244 result
= HOST_BITS_PER_WIDE_INT
+ exact_log2 (hi
& -hi
) + 1;
7249 CASE_INT_FN (BUILT_IN_CLZ
):
7251 result
= width
- floor_log2 (hi
) - 1 - HOST_BITS_PER_WIDE_INT
;
7253 result
= width
- floor_log2 (lo
) - 1;
7254 else if (! CLZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type
), result
))
7258 CASE_INT_FN (BUILT_IN_CTZ
):
7260 result
= exact_log2 (lo
& -lo
);
7262 result
= HOST_BITS_PER_WIDE_INT
+ exact_log2 (hi
& -hi
);
7263 else if (! CTZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type
), result
))
7267 CASE_INT_FN (BUILT_IN_POPCOUNT
):
7270 result
++, lo
&= lo
- 1;
7272 result
++, hi
&= hi
- 1;
7275 CASE_INT_FN (BUILT_IN_PARITY
):
7278 result
++, lo
&= lo
- 1;
7280 result
++, hi
&= hi
- 1;
7288 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl
)), result
);
7294 /* Return true if EXPR is the real constant contained in VALUE. */
7297 real_dconstp (tree expr
, const REAL_VALUE_TYPE
*value
)
7301 return ((TREE_CODE (expr
) == REAL_CST
7302 && ! TREE_CONSTANT_OVERFLOW (expr
)
7303 && REAL_VALUES_EQUAL (TREE_REAL_CST (expr
), *value
))
7304 || (TREE_CODE (expr
) == COMPLEX_CST
7305 && real_dconstp (TREE_REALPART (expr
), value
)
7306 && real_zerop (TREE_IMAGPART (expr
))));
7309 /* A subroutine of fold_builtin to fold the various logarithmic
7310 functions. EXP is the CALL_EXPR of a call to a builtin logN
7311 function. VALUE is the base of the logN function. */
7314 fold_builtin_logarithm (tree fndecl
, tree arglist
,
7315 const REAL_VALUE_TYPE
*value
)
7317 if (validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
7319 tree type
= TREE_TYPE (TREE_TYPE (fndecl
));
7320 tree arg
= TREE_VALUE (arglist
);
7321 const enum built_in_function fcode
= builtin_mathfn_code (arg
);
7323 /* Optimize logN(1.0) = 0.0. */
7324 if (real_onep (arg
))
7325 return build_real (type
, dconst0
);
7327 /* Optimize logN(N) = 1.0. If N can't be truncated to MODE
7328 exactly, then only do this if flag_unsafe_math_optimizations. */
7329 if (exact_real_truncate (TYPE_MODE (type
), value
)
7330 || flag_unsafe_math_optimizations
)
7332 const REAL_VALUE_TYPE value_truncate
=
7333 real_value_truncate (TYPE_MODE (type
), *value
);
7334 if (real_dconstp (arg
, &value_truncate
))
7335 return build_real (type
, dconst1
);
7338 /* Special case, optimize logN(expN(x)) = x. */
7339 if (flag_unsafe_math_optimizations
7340 && ((value
== &dconste
7341 && (fcode
== BUILT_IN_EXP
7342 || fcode
== BUILT_IN_EXPF
7343 || fcode
== BUILT_IN_EXPL
))
7344 || (value
== &dconst2
7345 && (fcode
== BUILT_IN_EXP2
7346 || fcode
== BUILT_IN_EXP2F
7347 || fcode
== BUILT_IN_EXP2L
))
7348 || (value
== &dconst10
&& (BUILTIN_EXP10_P (fcode
)))))
7349 return fold_convert (type
, TREE_VALUE (TREE_OPERAND (arg
, 1)));
7351 /* Optimize logN(func()) for various exponential functions. We
7352 want to determine the value "x" and the power "exponent" in
7353 order to transform logN(x**exponent) into exponent*logN(x). */
7354 if (flag_unsafe_math_optimizations
)
7356 tree exponent
= 0, x
= 0;
7360 CASE_FLT_FN (BUILT_IN_EXP
):
7361 /* Prepare to do logN(exp(exponent) -> exponent*logN(e). */
7362 x
= build_real (type
,
7363 real_value_truncate (TYPE_MODE (type
), dconste
));
7364 exponent
= TREE_VALUE (TREE_OPERAND (arg
, 1));
7366 CASE_FLT_FN (BUILT_IN_EXP2
):
7367 /* Prepare to do logN(exp2(exponent) -> exponent*logN(2). */
7368 x
= build_real (type
, dconst2
);
7369 exponent
= TREE_VALUE (TREE_OPERAND (arg
, 1));
7371 CASE_FLT_FN (BUILT_IN_EXP10
):
7372 CASE_FLT_FN (BUILT_IN_POW10
):
7373 /* Prepare to do logN(exp10(exponent) -> exponent*logN(10). */
7374 x
= build_real (type
, dconst10
);
7375 exponent
= TREE_VALUE (TREE_OPERAND (arg
, 1));
7377 CASE_FLT_FN (BUILT_IN_SQRT
):
7378 /* Prepare to do logN(sqrt(x) -> 0.5*logN(x). */
7379 x
= TREE_VALUE (TREE_OPERAND (arg
, 1));
7380 exponent
= build_real (type
, dconsthalf
);
7382 CASE_FLT_FN (BUILT_IN_CBRT
):
7383 /* Prepare to do logN(cbrt(x) -> (1/3)*logN(x). */
7384 x
= TREE_VALUE (TREE_OPERAND (arg
, 1));
7385 exponent
= build_real (type
, real_value_truncate (TYPE_MODE (type
),
7388 CASE_FLT_FN (BUILT_IN_POW
):
7389 /* Prepare to do logN(pow(x,exponent) -> exponent*logN(x). */
7390 x
= TREE_VALUE (TREE_OPERAND (arg
, 1));
7391 exponent
= TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg
, 1)));
7397 /* Now perform the optimization. */
7401 arglist
= build_tree_list (NULL_TREE
, x
);
7402 logfn
= build_function_call_expr (fndecl
, arglist
);
7403 return fold_build2 (MULT_EXPR
, type
, exponent
, logfn
);
7411 /* Fold a builtin function call to pow, powf, or powl. Return
7412 NULL_TREE if no simplification can be made. */
7414 fold_builtin_pow (tree fndecl
, tree arglist
, tree type
)
7416 tree arg0
= TREE_VALUE (arglist
);
7417 tree arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
7419 if (!validate_arglist (arglist
, REAL_TYPE
, REAL_TYPE
, VOID_TYPE
))
7422 /* Optimize pow(1.0,y) = 1.0. */
7423 if (real_onep (arg0
))
7424 return omit_one_operand (type
, build_real (type
, dconst1
), arg1
);
7426 if (TREE_CODE (arg1
) == REAL_CST
7427 && ! TREE_CONSTANT_OVERFLOW (arg1
))
7429 REAL_VALUE_TYPE cint
;
7433 c
= TREE_REAL_CST (arg1
);
7435 /* Optimize pow(x,0.0) = 1.0. */
7436 if (REAL_VALUES_EQUAL (c
, dconst0
))
7437 return omit_one_operand (type
, build_real (type
, dconst1
),
7440 /* Optimize pow(x,1.0) = x. */
7441 if (REAL_VALUES_EQUAL (c
, dconst1
))
7444 /* Optimize pow(x,-1.0) = 1.0/x. */
7445 if (REAL_VALUES_EQUAL (c
, dconstm1
))
7446 return fold_build2 (RDIV_EXPR
, type
,
7447 build_real (type
, dconst1
), arg0
);
7449 /* Optimize pow(x,0.5) = sqrt(x). */
7450 if (flag_unsafe_math_optimizations
7451 && REAL_VALUES_EQUAL (c
, dconsthalf
))
7453 tree sqrtfn
= mathfn_built_in (type
, BUILT_IN_SQRT
);
7455 if (sqrtfn
!= NULL_TREE
)
7457 tree arglist
= build_tree_list (NULL_TREE
, arg0
);
7458 return build_function_call_expr (sqrtfn
, arglist
);
7462 /* Check for an integer exponent. */
7463 n
= real_to_integer (&c
);
7464 real_from_integer (&cint
, VOIDmode
, n
, n
< 0 ? -1 : 0, 0);
7465 if (real_identical (&c
, &cint
))
7467 /* Attempt to evaluate pow at compile-time. */
7468 if (TREE_CODE (arg0
) == REAL_CST
7469 && ! TREE_CONSTANT_OVERFLOW (arg0
))
7474 x
= TREE_REAL_CST (arg0
);
7475 inexact
= real_powi (&x
, TYPE_MODE (type
), &x
, n
);
7476 if (flag_unsafe_math_optimizations
|| !inexact
)
7477 return build_real (type
, x
);
7480 /* Strip sign ops from even integer powers. */
7481 if ((n
& 1) == 0 && flag_unsafe_math_optimizations
)
7483 tree narg0
= fold_strip_sign_ops (arg0
);
7486 arglist
= build_tree_list (NULL_TREE
, arg1
);
7487 arglist
= tree_cons (NULL_TREE
, narg0
, arglist
);
7488 return build_function_call_expr (fndecl
, arglist
);
7494 if (flag_unsafe_math_optimizations
)
7496 const enum built_in_function fcode
= builtin_mathfn_code (arg0
);
7498 /* Optimize pow(expN(x),y) = expN(x*y). */
7499 if (BUILTIN_EXPONENT_P (fcode
))
7501 tree expfn
= TREE_OPERAND (TREE_OPERAND (arg0
, 0), 0);
7502 tree arg
= TREE_VALUE (TREE_OPERAND (arg0
, 1));
7503 arg
= fold_build2 (MULT_EXPR
, type
, arg
, arg1
);
7504 arglist
= build_tree_list (NULL_TREE
, arg
);
7505 return build_function_call_expr (expfn
, arglist
);
7508 /* Optimize pow(sqrt(x),y) = pow(x,y*0.5). */
7509 if (BUILTIN_SQRT_P (fcode
))
7511 tree narg0
= TREE_VALUE (TREE_OPERAND (arg0
, 1));
7512 tree narg1
= fold_build2 (MULT_EXPR
, type
, arg1
,
7513 build_real (type
, dconsthalf
));
7515 arglist
= tree_cons (NULL_TREE
, narg0
,
7516 build_tree_list (NULL_TREE
, narg1
));
7517 return build_function_call_expr (fndecl
, arglist
);
7520 /* Optimize pow(cbrt(x),y) = pow(x,y/3) iff x is nonnegative. */
7521 if (BUILTIN_CBRT_P (fcode
))
7523 tree arg
= TREE_VALUE (TREE_OPERAND (arg0
, 1));
7524 if (tree_expr_nonnegative_p (arg
))
7526 const REAL_VALUE_TYPE dconstroot
7527 = real_value_truncate (TYPE_MODE (type
), dconstthird
);
7528 tree narg1
= fold_build2 (MULT_EXPR
, type
, arg1
,
7529 build_real (type
, dconstroot
));
7530 arglist
= tree_cons (NULL_TREE
, arg
,
7531 build_tree_list (NULL_TREE
, narg1
));
7532 return build_function_call_expr (fndecl
, arglist
);
7536 /* Optimize pow(pow(x,y),z) = pow(x,y*z). */
7537 if (fcode
== BUILT_IN_POW
|| fcode
== BUILT_IN_POWF
7538 || fcode
== BUILT_IN_POWL
)
7540 tree arg00
= TREE_VALUE (TREE_OPERAND (arg0
, 1));
7541 tree arg01
= TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg0
, 1)));
7542 tree narg1
= fold_build2 (MULT_EXPR
, type
, arg01
, arg1
);
7543 arglist
= tree_cons (NULL_TREE
, arg00
,
7544 build_tree_list (NULL_TREE
, narg1
));
7545 return build_function_call_expr (fndecl
, arglist
);
7552 /* Fold a builtin function call to powi, powif, or powil. Return
7553 NULL_TREE if no simplification can be made. */
7555 fold_builtin_powi (tree fndecl ATTRIBUTE_UNUSED
, tree arglist
, tree type
)
7557 tree arg0
= TREE_VALUE (arglist
);
7558 tree arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
7560 if (!validate_arglist (arglist
, REAL_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
7563 /* Optimize pow(1.0,y) = 1.0. */
7564 if (real_onep (arg0
))
7565 return omit_one_operand (type
, build_real (type
, dconst1
), arg1
);
7567 if (host_integerp (arg1
, 0))
7569 HOST_WIDE_INT c
= TREE_INT_CST_LOW (arg1
);
7571 /* Evaluate powi at compile-time. */
7572 if (TREE_CODE (arg0
) == REAL_CST
7573 && ! TREE_CONSTANT_OVERFLOW (arg0
))
7576 x
= TREE_REAL_CST (arg0
);
7577 real_powi (&x
, TYPE_MODE (type
), &x
, c
);
7578 return build_real (type
, x
);
7581 /* Optimize pow(x,0) = 1.0. */
7583 return omit_one_operand (type
, build_real (type
, dconst1
),
7586 /* Optimize pow(x,1) = x. */
7590 /* Optimize pow(x,-1) = 1.0/x. */
7592 return fold_build2 (RDIV_EXPR
, type
,
7593 build_real (type
, dconst1
), arg0
);
7599 /* A subroutine of fold_builtin to fold the various exponent
7600 functions. EXP is the CALL_EXPR of a call to a builtin function.
7601 VALUE is the value which will be raised to a power. */
7604 fold_builtin_exponent (tree fndecl
, tree arglist
,
7605 const REAL_VALUE_TYPE
*value
)
7607 if (validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
7609 tree type
= TREE_TYPE (TREE_TYPE (fndecl
));
7610 tree arg
= TREE_VALUE (arglist
);
7612 /* Optimize exp*(0.0) = 1.0. */
7613 if (real_zerop (arg
))
7614 return build_real (type
, dconst1
);
7616 /* Optimize expN(1.0) = N. */
7617 if (real_onep (arg
))
7619 REAL_VALUE_TYPE cst
;
7621 real_convert (&cst
, TYPE_MODE (type
), value
);
7622 return build_real (type
, cst
);
7625 /* Attempt to evaluate expN(integer) at compile-time. */
7626 if (flag_unsafe_math_optimizations
7627 && TREE_CODE (arg
) == REAL_CST
7628 && ! TREE_CONSTANT_OVERFLOW (arg
))
7630 REAL_VALUE_TYPE cint
;
7634 c
= TREE_REAL_CST (arg
);
7635 n
= real_to_integer (&c
);
7636 real_from_integer (&cint
, VOIDmode
, n
,
7638 if (real_identical (&c
, &cint
))
7642 real_powi (&x
, TYPE_MODE (type
), value
, n
);
7643 return build_real (type
, x
);
7647 /* Optimize expN(logN(x)) = x. */
7648 if (flag_unsafe_math_optimizations
)
7650 const enum built_in_function fcode
= builtin_mathfn_code (arg
);
7652 if ((value
== &dconste
7653 && (fcode
== BUILT_IN_LOG
7654 || fcode
== BUILT_IN_LOGF
7655 || fcode
== BUILT_IN_LOGL
))
7656 || (value
== &dconst2
7657 && (fcode
== BUILT_IN_LOG2
7658 || fcode
== BUILT_IN_LOG2F
7659 || fcode
== BUILT_IN_LOG2L
))
7660 || (value
== &dconst10
7661 && (fcode
== BUILT_IN_LOG10
7662 || fcode
== BUILT_IN_LOG10F
7663 || fcode
== BUILT_IN_LOG10L
)))
7664 return fold_convert (type
, TREE_VALUE (TREE_OPERAND (arg
, 1)));
7671 /* Fold function call to builtin memcpy. Return
7672 NULL_TREE if no simplification can be made. */
7675 fold_builtin_memcpy (tree fndecl
, tree arglist
)
7677 tree dest
, src
, len
;
7679 if (!validate_arglist (arglist
,
7680 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
7683 dest
= TREE_VALUE (arglist
);
7684 src
= TREE_VALUE (TREE_CHAIN (arglist
));
7685 len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
7687 /* If the LEN parameter is zero, return DEST. */
7688 if (integer_zerop (len
))
7689 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl
)), dest
, src
);
7691 /* If SRC and DEST are the same (and not volatile), return DEST. */
7692 if (operand_equal_p (src
, dest
, 0))
7693 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl
)), dest
, len
);
7698 /* Fold function call to builtin mempcpy. Return
7699 NULL_TREE if no simplification can be made. */
7702 fold_builtin_mempcpy (tree arglist
, tree type
, int endp
)
7704 if (validate_arglist (arglist
,
7705 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
7707 tree dest
= TREE_VALUE (arglist
);
7708 tree src
= TREE_VALUE (TREE_CHAIN (arglist
));
7709 tree len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
7711 /* If the LEN parameter is zero, return DEST. */
7712 if (integer_zerop (len
))
7713 return omit_one_operand (type
, dest
, src
);
7715 /* If SRC and DEST are the same (and not volatile), return DEST+LEN. */
7716 if (operand_equal_p (src
, dest
, 0))
7719 return omit_one_operand (type
, dest
, len
);
7722 len
= fold_build2 (MINUS_EXPR
, TREE_TYPE (len
), len
,
7725 len
= fold_convert (TREE_TYPE (dest
), len
);
7726 len
= fold_build2 (PLUS_EXPR
, TREE_TYPE (dest
), dest
, len
);
7727 return fold_convert (type
, len
);
7733 /* Fold function call to builtin memmove. Return
7734 NULL_TREE if no simplification can be made. */
7737 fold_builtin_memmove (tree arglist
, tree type
)
7739 tree dest
, src
, len
;
7741 if (!validate_arglist (arglist
,
7742 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
7745 dest
= TREE_VALUE (arglist
);
7746 src
= TREE_VALUE (TREE_CHAIN (arglist
));
7747 len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
7749 /* If the LEN parameter is zero, return DEST. */
7750 if (integer_zerop (len
))
7751 return omit_one_operand (type
, dest
, src
);
7753 /* If SRC and DEST are the same (and not volatile), return DEST. */
7754 if (operand_equal_p (src
, dest
, 0))
7755 return omit_one_operand (type
, dest
, len
);
7760 /* Fold function call to builtin strcpy. If LEN is not NULL, it represents
7761 the length of the string to be copied. Return NULL_TREE if no
7762 simplification can be made. */
7765 fold_builtin_strcpy (tree fndecl
, tree arglist
, tree len
)
7769 if (!validate_arglist (arglist
,
7770 POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
7773 dest
= TREE_VALUE (arglist
);
7774 src
= TREE_VALUE (TREE_CHAIN (arglist
));
7776 /* If SRC and DEST are the same (and not volatile), return DEST. */
7777 if (operand_equal_p (src
, dest
, 0))
7778 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl
)), dest
);
7783 fn
= implicit_built_in_decls
[BUILT_IN_MEMCPY
];
7789 len
= c_strlen (src
, 1);
7790 if (! len
|| TREE_SIDE_EFFECTS (len
))
7794 len
= size_binop (PLUS_EXPR
, len
, ssize_int (1));
7795 arglist
= build_tree_list (NULL_TREE
, len
);
7796 arglist
= tree_cons (NULL_TREE
, src
, arglist
);
7797 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
7798 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl
)),
7799 build_function_call_expr (fn
, arglist
));
7802 /* Fold function call to builtin strncpy. If SLEN is not NULL, it represents
7803 the length of the source string. Return NULL_TREE if no simplification
7807 fold_builtin_strncpy (tree fndecl
, tree arglist
, tree slen
)
7809 tree dest
, src
, len
, fn
;
7811 if (!validate_arglist (arglist
,
7812 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
7815 dest
= TREE_VALUE (arglist
);
7816 src
= TREE_VALUE (TREE_CHAIN (arglist
));
7817 len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
7819 /* If the LEN parameter is zero, return DEST. */
7820 if (integer_zerop (len
))
7821 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl
)), dest
, src
);
7823 /* We can't compare slen with len as constants below if len is not a
7825 if (len
== 0 || TREE_CODE (len
) != INTEGER_CST
)
7829 slen
= c_strlen (src
, 1);
7831 /* Now, we must be passed a constant src ptr parameter. */
7832 if (slen
== 0 || TREE_CODE (slen
) != INTEGER_CST
)
7835 slen
= size_binop (PLUS_EXPR
, slen
, ssize_int (1));
7837 /* We do not support simplification of this case, though we do
7838 support it when expanding trees into RTL. */
7839 /* FIXME: generate a call to __builtin_memset. */
7840 if (tree_int_cst_lt (slen
, len
))
7843 /* OK transform into builtin memcpy. */
7844 fn
= implicit_built_in_decls
[BUILT_IN_MEMCPY
];
7847 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl
)),
7848 build_function_call_expr (fn
, arglist
));
7851 /* Fold function call to builtin memcmp. Return
7852 NULL_TREE if no simplification can be made. */
7855 fold_builtin_memcmp (tree arglist
)
7857 tree arg1
, arg2
, len
;
7858 const char *p1
, *p2
;
7860 if (!validate_arglist (arglist
,
7861 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
7864 arg1
= TREE_VALUE (arglist
);
7865 arg2
= TREE_VALUE (TREE_CHAIN (arglist
));
7866 len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
7868 /* If the LEN parameter is zero, return zero. */
7869 if (integer_zerop (len
))
7870 return omit_two_operands (integer_type_node
, integer_zero_node
,
7873 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
7874 if (operand_equal_p (arg1
, arg2
, 0))
7875 return omit_one_operand (integer_type_node
, integer_zero_node
, len
);
7877 p1
= c_getstr (arg1
);
7878 p2
= c_getstr (arg2
);
7880 /* If all arguments are constant, and the value of len is not greater
7881 than the lengths of arg1 and arg2, evaluate at compile-time. */
7882 if (host_integerp (len
, 1) && p1
&& p2
7883 && compare_tree_int (len
, strlen (p1
) + 1) <= 0
7884 && compare_tree_int (len
, strlen (p2
) + 1) <= 0)
7886 const int r
= memcmp (p1
, p2
, tree_low_cst (len
, 1));
7889 return integer_one_node
;
7891 return integer_minus_one_node
;
7893 return integer_zero_node
;
7896 /* If len parameter is one, return an expression corresponding to
7897 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
7898 if (host_integerp (len
, 1) && tree_low_cst (len
, 1) == 1)
7900 tree cst_uchar_node
= build_type_variant (unsigned_char_type_node
, 1, 0);
7901 tree cst_uchar_ptr_node
7902 = build_pointer_type_for_mode (cst_uchar_node
, ptr_mode
, true);
7904 tree ind1
= fold_convert (integer_type_node
,
7905 build1 (INDIRECT_REF
, cst_uchar_node
,
7906 fold_convert (cst_uchar_ptr_node
,
7908 tree ind2
= fold_convert (integer_type_node
,
7909 build1 (INDIRECT_REF
, cst_uchar_node
,
7910 fold_convert (cst_uchar_ptr_node
,
7912 return fold_build2 (MINUS_EXPR
, integer_type_node
, ind1
, ind2
);
7918 /* Fold function call to builtin strcmp. Return
7919 NULL_TREE if no simplification can be made. */
7922 fold_builtin_strcmp (tree arglist
)
7925 const char *p1
, *p2
;
7927 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
7930 arg1
= TREE_VALUE (arglist
);
7931 arg2
= TREE_VALUE (TREE_CHAIN (arglist
));
7933 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
7934 if (operand_equal_p (arg1
, arg2
, 0))
7935 return integer_zero_node
;
7937 p1
= c_getstr (arg1
);
7938 p2
= c_getstr (arg2
);
7942 const int i
= strcmp (p1
, p2
);
7944 return integer_minus_one_node
;
7946 return integer_one_node
;
7948 return integer_zero_node
;
7951 /* If the second arg is "", return *(const unsigned char*)arg1. */
7952 if (p2
&& *p2
== '\0')
7954 tree cst_uchar_node
= build_type_variant (unsigned_char_type_node
, 1, 0);
7955 tree cst_uchar_ptr_node
7956 = build_pointer_type_for_mode (cst_uchar_node
, ptr_mode
, true);
7958 return fold_convert (integer_type_node
,
7959 build1 (INDIRECT_REF
, cst_uchar_node
,
7960 fold_convert (cst_uchar_ptr_node
,
7964 /* If the first arg is "", return -*(const unsigned char*)arg2. */
7965 if (p1
&& *p1
== '\0')
7967 tree cst_uchar_node
= build_type_variant (unsigned_char_type_node
, 1, 0);
7968 tree cst_uchar_ptr_node
7969 = build_pointer_type_for_mode (cst_uchar_node
, ptr_mode
, true);
7971 tree temp
= fold_convert (integer_type_node
,
7972 build1 (INDIRECT_REF
, cst_uchar_node
,
7973 fold_convert (cst_uchar_ptr_node
,
7975 return fold_build1 (NEGATE_EXPR
, integer_type_node
, temp
);
7981 /* Fold function call to builtin strncmp. Return
7982 NULL_TREE if no simplification can be made. */
7985 fold_builtin_strncmp (tree arglist
)
7987 tree arg1
, arg2
, len
;
7988 const char *p1
, *p2
;
7990 if (!validate_arglist (arglist
,
7991 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
7994 arg1
= TREE_VALUE (arglist
);
7995 arg2
= TREE_VALUE (TREE_CHAIN (arglist
));
7996 len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
7998 /* If the LEN parameter is zero, return zero. */
7999 if (integer_zerop (len
))
8000 return omit_two_operands (integer_type_node
, integer_zero_node
,
8003 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
8004 if (operand_equal_p (arg1
, arg2
, 0))
8005 return omit_one_operand (integer_type_node
, integer_zero_node
, len
);
8007 p1
= c_getstr (arg1
);
8008 p2
= c_getstr (arg2
);
8010 if (host_integerp (len
, 1) && p1
&& p2
)
8012 const int i
= strncmp (p1
, p2
, tree_low_cst (len
, 1));
8014 return integer_one_node
;
8016 return integer_minus_one_node
;
8018 return integer_zero_node
;
8021 /* If the second arg is "", and the length is greater than zero,
8022 return *(const unsigned char*)arg1. */
8023 if (p2
&& *p2
== '\0'
8024 && TREE_CODE (len
) == INTEGER_CST
8025 && tree_int_cst_sgn (len
) == 1)
8027 tree cst_uchar_node
= build_type_variant (unsigned_char_type_node
, 1, 0);
8028 tree cst_uchar_ptr_node
8029 = build_pointer_type_for_mode (cst_uchar_node
, ptr_mode
, true);
8031 return fold_convert (integer_type_node
,
8032 build1 (INDIRECT_REF
, cst_uchar_node
,
8033 fold_convert (cst_uchar_ptr_node
,
8037 /* If the first arg is "", and the length is greater than zero,
8038 return -*(const unsigned char*)arg2. */
8039 if (p1
&& *p1
== '\0'
8040 && TREE_CODE (len
) == INTEGER_CST
8041 && tree_int_cst_sgn (len
) == 1)
8043 tree cst_uchar_node
= build_type_variant (unsigned_char_type_node
, 1, 0);
8044 tree cst_uchar_ptr_node
8045 = build_pointer_type_for_mode (cst_uchar_node
, ptr_mode
, true);
8047 tree temp
= fold_convert (integer_type_node
,
8048 build1 (INDIRECT_REF
, cst_uchar_node
,
8049 fold_convert (cst_uchar_ptr_node
,
8051 return fold_build1 (NEGATE_EXPR
, integer_type_node
, temp
);
8054 /* If len parameter is one, return an expression corresponding to
8055 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
8056 if (host_integerp (len
, 1) && tree_low_cst (len
, 1) == 1)
8058 tree cst_uchar_node
= build_type_variant (unsigned_char_type_node
, 1, 0);
8059 tree cst_uchar_ptr_node
8060 = build_pointer_type_for_mode (cst_uchar_node
, ptr_mode
, true);
8062 tree ind1
= fold_convert (integer_type_node
,
8063 build1 (INDIRECT_REF
, cst_uchar_node
,
8064 fold_convert (cst_uchar_ptr_node
,
8066 tree ind2
= fold_convert (integer_type_node
,
8067 build1 (INDIRECT_REF
, cst_uchar_node
,
8068 fold_convert (cst_uchar_ptr_node
,
8070 return fold_build2 (MINUS_EXPR
, integer_type_node
, ind1
, ind2
);
8076 /* Fold function call to builtin signbit, signbitf or signbitl. Return
8077 NULL_TREE if no simplification can be made. */
8080 fold_builtin_signbit (tree fndecl
, tree arglist
)
8082 tree type
= TREE_TYPE (TREE_TYPE (fndecl
));
8085 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
8088 arg
= TREE_VALUE (arglist
);
8090 /* If ARG is a compile-time constant, determine the result. */
8091 if (TREE_CODE (arg
) == REAL_CST
8092 && !TREE_CONSTANT_OVERFLOW (arg
))
8096 c
= TREE_REAL_CST (arg
);
8097 temp
= REAL_VALUE_NEGATIVE (c
) ? integer_one_node
: integer_zero_node
;
8098 return fold_convert (type
, temp
);
8101 /* If ARG is non-negative, the result is always zero. */
8102 if (tree_expr_nonnegative_p (arg
))
8103 return omit_one_operand (type
, integer_zero_node
, arg
);
8105 /* If ARG's format doesn't have signed zeros, return "arg < 0.0". */
8106 if (!HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg
))))
8107 return fold_build2 (LT_EXPR
, type
, arg
,
8108 build_real (TREE_TYPE (arg
), dconst0
));
8113 /* Fold function call to builtin copysign, copysignf or copysignl.
8114 Return NULL_TREE if no simplification can be made. */
8117 fold_builtin_copysign (tree fndecl
, tree arglist
, tree type
)
8119 tree arg1
, arg2
, tem
;
8121 if (!validate_arglist (arglist
, REAL_TYPE
, REAL_TYPE
, VOID_TYPE
))
8124 arg1
= TREE_VALUE (arglist
);
8125 arg2
= TREE_VALUE (TREE_CHAIN (arglist
));
8127 /* copysign(X,X) is X. */
8128 if (operand_equal_p (arg1
, arg2
, 0))
8129 return fold_convert (type
, arg1
);
8131 /* If ARG1 and ARG2 are compile-time constants, determine the result. */
8132 if (TREE_CODE (arg1
) == REAL_CST
8133 && TREE_CODE (arg2
) == REAL_CST
8134 && !TREE_CONSTANT_OVERFLOW (arg1
)
8135 && !TREE_CONSTANT_OVERFLOW (arg2
))
8137 REAL_VALUE_TYPE c1
, c2
;
8139 c1
= TREE_REAL_CST (arg1
);
8140 c2
= TREE_REAL_CST (arg2
);
8141 real_copysign (&c1
, &c2
);
8142 return build_real (type
, c1
);
8146 /* copysign(X, Y) is fabs(X) when Y is always non-negative.
8147 Remember to evaluate Y for side-effects. */
8148 if (tree_expr_nonnegative_p (arg2
))
8149 return omit_one_operand (type
,
8150 fold_build1 (ABS_EXPR
, type
, arg1
),
8153 /* Strip sign changing operations for the first argument. */
8154 tem
= fold_strip_sign_ops (arg1
);
8157 arglist
= tree_cons (NULL_TREE
, tem
, TREE_CHAIN (arglist
));
8158 return build_function_call_expr (fndecl
, arglist
);
8164 /* Fold a call to builtin isascii. */
8167 fold_builtin_isascii (tree arglist
)
8169 if (! validate_arglist (arglist
, INTEGER_TYPE
, VOID_TYPE
))
8173 /* Transform isascii(c) -> ((c & ~0x7f) == 0). */
8174 tree arg
= TREE_VALUE (arglist
);
8176 arg
= build2 (BIT_AND_EXPR
, integer_type_node
, arg
,
8177 build_int_cst (NULL_TREE
,
8178 ~ (unsigned HOST_WIDE_INT
) 0x7f));
8179 arg
= fold_build2 (EQ_EXPR
, integer_type_node
,
8180 arg
, integer_zero_node
);
8182 if (in_gimple_form
&& !TREE_CONSTANT (arg
))
8189 /* Fold a call to builtin toascii. */
8192 fold_builtin_toascii (tree arglist
)
8194 if (! validate_arglist (arglist
, INTEGER_TYPE
, VOID_TYPE
))
8198 /* Transform toascii(c) -> (c & 0x7f). */
8199 tree arg
= TREE_VALUE (arglist
);
8201 return fold_build2 (BIT_AND_EXPR
, integer_type_node
, arg
,
8202 build_int_cst (NULL_TREE
, 0x7f));
8206 /* Fold a call to builtin isdigit. */
8209 fold_builtin_isdigit (tree arglist
)
8211 if (! validate_arglist (arglist
, INTEGER_TYPE
, VOID_TYPE
))
8215 /* Transform isdigit(c) -> (unsigned)(c) - '0' <= 9. */
8216 /* According to the C standard, isdigit is unaffected by locale.
8217 However, it definitely is affected by the target character set. */
8219 unsigned HOST_WIDE_INT target_digit0
8220 = lang_hooks
.to_target_charset ('0');
8222 if (target_digit0
== 0)
8225 arg
= fold_convert (unsigned_type_node
, TREE_VALUE (arglist
));
8226 arg
= build2 (MINUS_EXPR
, unsigned_type_node
, arg
,
8227 build_int_cst (unsigned_type_node
, target_digit0
));
8228 arg
= fold_build2 (LE_EXPR
, integer_type_node
, arg
,
8229 build_int_cst (unsigned_type_node
, 9));
8230 if (in_gimple_form
&& !TREE_CONSTANT (arg
))
8237 /* Fold a call to fabs, fabsf or fabsl. */
8240 fold_builtin_fabs (tree arglist
, tree type
)
8244 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
8247 arg
= TREE_VALUE (arglist
);
8248 arg
= fold_convert (type
, arg
);
8249 if (TREE_CODE (arg
) == REAL_CST
)
8250 return fold_abs_const (arg
, type
);
8251 return fold_build1 (ABS_EXPR
, type
, arg
);
8254 /* Fold a call to abs, labs, llabs or imaxabs. */
8257 fold_builtin_abs (tree arglist
, tree type
)
8261 if (!validate_arglist (arglist
, INTEGER_TYPE
, VOID_TYPE
))
8264 arg
= TREE_VALUE (arglist
);
8265 arg
= fold_convert (type
, arg
);
8266 if (TREE_CODE (arg
) == INTEGER_CST
)
8267 return fold_abs_const (arg
, type
);
8268 return fold_build1 (ABS_EXPR
, type
, arg
);
8271 /* Fold a call to __builtin_isnan(), __builtin_isinf, __builtin_finite.
8272 EXP is the CALL_EXPR for the call. */
8275 fold_builtin_classify (tree fndecl
, tree arglist
, int builtin_index
)
8277 tree type
= TREE_TYPE (TREE_TYPE (fndecl
));
8281 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
8283 /* Check that we have exactly one argument. */
8286 error ("too few arguments to function %qs",
8287 IDENTIFIER_POINTER (DECL_NAME (fndecl
)));
8288 return error_mark_node
;
8290 else if (TREE_CHAIN (arglist
) != 0)
8292 error ("too many arguments to function %qs",
8293 IDENTIFIER_POINTER (DECL_NAME (fndecl
)));
8294 return error_mark_node
;
8298 error ("non-floating-point argument to function %qs",
8299 IDENTIFIER_POINTER (DECL_NAME (fndecl
)));
8300 return error_mark_node
;
8304 arg
= TREE_VALUE (arglist
);
8305 switch (builtin_index
)
8307 case BUILT_IN_ISINF
:
8308 if (!MODE_HAS_INFINITIES (TYPE_MODE (TREE_TYPE (arg
))))
8309 return omit_one_operand (type
, integer_zero_node
, arg
);
8311 if (TREE_CODE (arg
) == REAL_CST
)
8313 r
= TREE_REAL_CST (arg
);
8314 if (real_isinf (&r
))
8315 return real_compare (GT_EXPR
, &r
, &dconst0
)
8316 ? integer_one_node
: integer_minus_one_node
;
8318 return integer_zero_node
;
8323 case BUILT_IN_FINITE
:
8324 if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg
)))
8325 && !MODE_HAS_INFINITIES (TYPE_MODE (TREE_TYPE (arg
))))
8326 return omit_one_operand (type
, integer_zero_node
, arg
);
8328 if (TREE_CODE (arg
) == REAL_CST
)
8330 r
= TREE_REAL_CST (arg
);
8331 return real_isinf (&r
) || real_isnan (&r
)
8332 ? integer_zero_node
: integer_one_node
;
8337 case BUILT_IN_ISNAN
:
8338 if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg
))))
8339 return omit_one_operand (type
, integer_zero_node
, arg
);
8341 if (TREE_CODE (arg
) == REAL_CST
)
8343 r
= TREE_REAL_CST (arg
);
8344 return real_isnan (&r
) ? integer_one_node
: integer_zero_node
;
8347 arg
= builtin_save_expr (arg
);
8348 return fold_build2 (UNORDERED_EXPR
, type
, arg
, arg
);
8355 /* Fold a call to an unordered comparison function such as
8356 __builtin_isgreater(). FNDECL is the FUNCTION_DECL for the function
8357 being called and ARGLIST is the argument list for the call.
8358 UNORDERED_CODE and ORDERED_CODE are comparison codes that give
8359 the opposite of the desired result. UNORDERED_CODE is used
8360 for modes that can hold NaNs and ORDERED_CODE is used for
8364 fold_builtin_unordered_cmp (tree fndecl
, tree arglist
,
8365 enum tree_code unordered_code
,
8366 enum tree_code ordered_code
)
8368 tree type
= TREE_TYPE (TREE_TYPE (fndecl
));
8369 enum tree_code code
;
8372 enum tree_code code0
, code1
;
8373 tree cmp_type
= NULL_TREE
;
8375 if (!validate_arglist (arglist
, REAL_TYPE
, REAL_TYPE
, VOID_TYPE
))
8377 /* Check that we have exactly two arguments. */
8378 if (arglist
== 0 || TREE_CHAIN (arglist
) == 0)
8380 error ("too few arguments to function %qs",
8381 IDENTIFIER_POINTER (DECL_NAME (fndecl
)));
8382 return error_mark_node
;
8384 else if (TREE_CHAIN (TREE_CHAIN (arglist
)) != 0)
8386 error ("too many arguments to function %qs",
8387 IDENTIFIER_POINTER (DECL_NAME (fndecl
)));
8388 return error_mark_node
;
8392 arg0
= TREE_VALUE (arglist
);
8393 arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
8395 type0
= TREE_TYPE (arg0
);
8396 type1
= TREE_TYPE (arg1
);
8398 code0
= TREE_CODE (type0
);
8399 code1
= TREE_CODE (type1
);
8401 if (code0
== REAL_TYPE
&& code1
== REAL_TYPE
)
8402 /* Choose the wider of two real types. */
8403 cmp_type
= TYPE_PRECISION (type0
) >= TYPE_PRECISION (type1
)
8405 else if (code0
== REAL_TYPE
&& code1
== INTEGER_TYPE
)
8407 else if (code0
== INTEGER_TYPE
&& code1
== REAL_TYPE
)
8411 error ("non-floating-point argument to function %qs",
8412 IDENTIFIER_POINTER (DECL_NAME (fndecl
)));
8413 return error_mark_node
;
8416 arg0
= fold_convert (cmp_type
, arg0
);
8417 arg1
= fold_convert (cmp_type
, arg1
);
8419 if (unordered_code
== UNORDERED_EXPR
)
8421 if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg0
))))
8422 return omit_two_operands (type
, integer_zero_node
, arg0
, arg1
);
8423 return fold_build2 (UNORDERED_EXPR
, type
, arg0
, arg1
);
8426 code
= MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg0
))) ? unordered_code
8428 return fold_build1 (TRUTH_NOT_EXPR
, type
,
8429 fold_build2 (code
, type
, arg0
, arg1
));
8432 /* Used by constant folding to simplify calls to builtin functions. EXP is
8433 the CALL_EXPR of a call to a builtin function. IGNORE is true if the
8434 result of the function call is ignored. This function returns NULL_TREE
8435 if no simplification was possible. */
8438 fold_builtin_1 (tree fndecl
, tree arglist
, bool ignore
)
8440 tree type
= TREE_TYPE (TREE_TYPE (fndecl
));
8441 enum built_in_function fcode
;
8443 if (DECL_BUILT_IN_CLASS (fndecl
) == BUILT_IN_MD
)
8444 return targetm
.fold_builtin (fndecl
, arglist
, ignore
);
8446 fcode
= DECL_FUNCTION_CODE (fndecl
);
8449 case BUILT_IN_FPUTS
:
8450 return fold_builtin_fputs (arglist
, ignore
, false, NULL_TREE
);
8452 case BUILT_IN_FPUTS_UNLOCKED
:
8453 return fold_builtin_fputs (arglist
, ignore
, true, NULL_TREE
);
8455 case BUILT_IN_STRSTR
:
8456 return fold_builtin_strstr (arglist
, type
);
8458 case BUILT_IN_STRCAT
:
8459 return fold_builtin_strcat (arglist
);
8461 case BUILT_IN_STRNCAT
:
8462 return fold_builtin_strncat (arglist
);
8464 case BUILT_IN_STRSPN
:
8465 return fold_builtin_strspn (arglist
);
8467 case BUILT_IN_STRCSPN
:
8468 return fold_builtin_strcspn (arglist
);
8470 case BUILT_IN_STRCHR
:
8471 case BUILT_IN_INDEX
:
8472 return fold_builtin_strchr (arglist
, type
);
8474 case BUILT_IN_STRRCHR
:
8475 case BUILT_IN_RINDEX
:
8476 return fold_builtin_strrchr (arglist
, type
);
8478 case BUILT_IN_STRCPY
:
8479 return fold_builtin_strcpy (fndecl
, arglist
, NULL_TREE
);
8481 case BUILT_IN_STRNCPY
:
8482 return fold_builtin_strncpy (fndecl
, arglist
, NULL_TREE
);
8484 case BUILT_IN_STRCMP
:
8485 return fold_builtin_strcmp (arglist
);
8487 case BUILT_IN_STRNCMP
:
8488 return fold_builtin_strncmp (arglist
);
8490 case BUILT_IN_STRPBRK
:
8491 return fold_builtin_strpbrk (arglist
, type
);
8494 case BUILT_IN_MEMCMP
:
8495 return fold_builtin_memcmp (arglist
);
8497 case BUILT_IN_SPRINTF
:
8498 return fold_builtin_sprintf (arglist
, ignore
);
8500 case BUILT_IN_CONSTANT_P
:
8504 val
= fold_builtin_constant_p (arglist
);
8505 /* Gimplification will pull the CALL_EXPR for the builtin out of
8506 an if condition. When not optimizing, we'll not CSE it back.
8507 To avoid link error types of regressions, return false now. */
8508 if (!val
&& !optimize
)
8509 val
= integer_zero_node
;
8514 case BUILT_IN_EXPECT
:
8515 return fold_builtin_expect (arglist
);
8517 case BUILT_IN_CLASSIFY_TYPE
:
8518 return fold_builtin_classify_type (arglist
);
8520 case BUILT_IN_STRLEN
:
8521 return fold_builtin_strlen (arglist
);
8523 CASE_FLT_FN (BUILT_IN_FABS
):
8524 return fold_builtin_fabs (arglist
, type
);
8528 case BUILT_IN_LLABS
:
8529 case BUILT_IN_IMAXABS
:
8530 return fold_builtin_abs (arglist
, type
);
8532 CASE_FLT_FN (BUILT_IN_CONJ
):
8533 if (validate_arglist (arglist
, COMPLEX_TYPE
, VOID_TYPE
))
8534 return fold_build1 (CONJ_EXPR
, type
, TREE_VALUE (arglist
));
8537 CASE_FLT_FN (BUILT_IN_CREAL
):
8538 if (validate_arglist (arglist
, COMPLEX_TYPE
, VOID_TYPE
))
8539 return non_lvalue (fold_build1 (REALPART_EXPR
, type
,
8540 TREE_VALUE (arglist
)));
8543 CASE_FLT_FN (BUILT_IN_CIMAG
):
8544 if (validate_arglist (arglist
, COMPLEX_TYPE
, VOID_TYPE
))
8545 return non_lvalue (fold_build1 (IMAGPART_EXPR
, type
,
8546 TREE_VALUE (arglist
)));
8549 CASE_FLT_FN (BUILT_IN_CABS
):
8550 return fold_builtin_cabs (arglist
, type
);
8552 CASE_FLT_FN (BUILT_IN_SQRT
):
8553 return fold_builtin_sqrt (arglist
, type
);
8555 CASE_FLT_FN (BUILT_IN_CBRT
):
8556 return fold_builtin_cbrt (arglist
, type
);
8558 CASE_FLT_FN (BUILT_IN_SIN
):
8559 return fold_builtin_sin (arglist
);
8561 CASE_FLT_FN (BUILT_IN_COS
):
8562 return fold_builtin_cos (arglist
, type
, fndecl
);
8564 CASE_FLT_FN (BUILT_IN_EXP
):
8565 return fold_builtin_exponent (fndecl
, arglist
, &dconste
);
8567 CASE_FLT_FN (BUILT_IN_EXP2
):
8568 return fold_builtin_exponent (fndecl
, arglist
, &dconst2
);
8570 CASE_FLT_FN (BUILT_IN_EXP10
):
8571 CASE_FLT_FN (BUILT_IN_POW10
):
8572 return fold_builtin_exponent (fndecl
, arglist
, &dconst10
);
8574 CASE_FLT_FN (BUILT_IN_LOG
):
8575 return fold_builtin_logarithm (fndecl
, arglist
, &dconste
);
8577 CASE_FLT_FN (BUILT_IN_LOG2
):
8578 return fold_builtin_logarithm (fndecl
, arglist
, &dconst2
);
8580 CASE_FLT_FN (BUILT_IN_LOG10
):
8581 return fold_builtin_logarithm (fndecl
, arglist
, &dconst10
);
8583 CASE_FLT_FN (BUILT_IN_TAN
):
8584 return fold_builtin_tan (arglist
);
8586 CASE_FLT_FN (BUILT_IN_ATAN
):
8587 return fold_builtin_atan (arglist
, type
);
8589 CASE_FLT_FN (BUILT_IN_POW
):
8590 return fold_builtin_pow (fndecl
, arglist
, type
);
8592 CASE_FLT_FN (BUILT_IN_POWI
):
8593 return fold_builtin_powi (fndecl
, arglist
, type
);
8595 CASE_FLT_FN (BUILT_IN_INF
):
8596 return fold_builtin_inf (type
, true);
8598 CASE_FLT_FN (BUILT_IN_HUGE_VAL
):
8599 return fold_builtin_inf (type
, false);
8601 CASE_FLT_FN (BUILT_IN_NAN
):
8602 return fold_builtin_nan (arglist
, type
, true);
8604 CASE_FLT_FN (BUILT_IN_NANS
):
8605 return fold_builtin_nan (arglist
, type
, false);
8607 CASE_FLT_FN (BUILT_IN_FLOOR
):
8608 return fold_builtin_floor (fndecl
, arglist
);
8610 CASE_FLT_FN (BUILT_IN_CEIL
):
8611 return fold_builtin_ceil (fndecl
, arglist
);
8613 CASE_FLT_FN (BUILT_IN_TRUNC
):
8614 return fold_builtin_trunc (fndecl
, arglist
);
8616 CASE_FLT_FN (BUILT_IN_ROUND
):
8617 return fold_builtin_round (fndecl
, arglist
);
8619 CASE_FLT_FN (BUILT_IN_NEARBYINT
):
8620 CASE_FLT_FN (BUILT_IN_RINT
):
8621 return fold_trunc_transparent_mathfn (fndecl
, arglist
);
8623 CASE_FLT_FN (BUILT_IN_LCEIL
):
8624 CASE_FLT_FN (BUILT_IN_LLCEIL
):
8625 CASE_FLT_FN (BUILT_IN_LFLOOR
):
8626 CASE_FLT_FN (BUILT_IN_LLFLOOR
):
8627 CASE_FLT_FN (BUILT_IN_LROUND
):
8628 CASE_FLT_FN (BUILT_IN_LLROUND
):
8629 return fold_builtin_int_roundingfn (fndecl
, arglist
);
8631 CASE_FLT_FN (BUILT_IN_LRINT
):
8632 CASE_FLT_FN (BUILT_IN_LLRINT
):
8633 return fold_fixed_mathfn (fndecl
, arglist
);
8635 CASE_INT_FN (BUILT_IN_FFS
):
8636 CASE_INT_FN (BUILT_IN_CLZ
):
8637 CASE_INT_FN (BUILT_IN_CTZ
):
8638 CASE_INT_FN (BUILT_IN_POPCOUNT
):
8639 CASE_INT_FN (BUILT_IN_PARITY
):
8640 return fold_builtin_bitop (fndecl
, arglist
);
8642 case BUILT_IN_MEMCPY
:
8643 return fold_builtin_memcpy (fndecl
, arglist
);
8645 case BUILT_IN_MEMPCPY
:
8646 return fold_builtin_mempcpy (arglist
, type
, /*endp=*/1);
8648 case BUILT_IN_MEMMOVE
:
8649 return fold_builtin_memmove (arglist
, type
);
8651 CASE_FLT_FN (BUILT_IN_SIGNBIT
):
8652 return fold_builtin_signbit (fndecl
, arglist
);
8654 case BUILT_IN_ISASCII
:
8655 return fold_builtin_isascii (arglist
);
8657 case BUILT_IN_TOASCII
:
8658 return fold_builtin_toascii (arglist
);
8660 case BUILT_IN_ISDIGIT
:
8661 return fold_builtin_isdigit (arglist
);
8663 CASE_FLT_FN (BUILT_IN_COPYSIGN
):
8664 return fold_builtin_copysign (fndecl
, arglist
, type
);
8666 CASE_FLT_FN (BUILT_IN_FINITE
):
8667 return fold_builtin_classify (fndecl
, arglist
, BUILT_IN_FINITE
);
8669 CASE_FLT_FN (BUILT_IN_ISINF
):
8670 return fold_builtin_classify (fndecl
, arglist
, BUILT_IN_ISINF
);
8672 CASE_FLT_FN (BUILT_IN_ISNAN
):
8673 return fold_builtin_classify (fndecl
, arglist
, BUILT_IN_ISNAN
);
8675 case BUILT_IN_ISGREATER
:
8676 return fold_builtin_unordered_cmp (fndecl
, arglist
, UNLE_EXPR
, LE_EXPR
);
8677 case BUILT_IN_ISGREATEREQUAL
:
8678 return fold_builtin_unordered_cmp (fndecl
, arglist
, UNLT_EXPR
, LT_EXPR
);
8679 case BUILT_IN_ISLESS
:
8680 return fold_builtin_unordered_cmp (fndecl
, arglist
, UNGE_EXPR
, GE_EXPR
);
8681 case BUILT_IN_ISLESSEQUAL
:
8682 return fold_builtin_unordered_cmp (fndecl
, arglist
, UNGT_EXPR
, GT_EXPR
);
8683 case BUILT_IN_ISLESSGREATER
:
8684 return fold_builtin_unordered_cmp (fndecl
, arglist
, UNEQ_EXPR
, EQ_EXPR
);
8685 case BUILT_IN_ISUNORDERED
:
8686 return fold_builtin_unordered_cmp (fndecl
, arglist
, UNORDERED_EXPR
,
8689 /* We do the folding for va_start in the expander. */
8690 case BUILT_IN_VA_START
:
8693 case BUILT_IN_OBJECT_SIZE
:
8694 return fold_builtin_object_size (arglist
);
8695 case BUILT_IN_MEMCPY_CHK
:
8696 case BUILT_IN_MEMPCPY_CHK
:
8697 case BUILT_IN_MEMMOVE_CHK
:
8698 case BUILT_IN_MEMSET_CHK
:
8699 return fold_builtin_memory_chk (fndecl
, arglist
, NULL_TREE
, ignore
,
8700 DECL_FUNCTION_CODE (fndecl
));
8701 case BUILT_IN_STRCPY_CHK
:
8702 case BUILT_IN_STPCPY_CHK
:
8703 return fold_builtin_stxcpy_chk (fndecl
, arglist
, NULL_TREE
, ignore
,
8704 DECL_FUNCTION_CODE (fndecl
));
8705 case BUILT_IN_STRNCPY_CHK
:
8706 return fold_builtin_strncpy_chk (arglist
, NULL_TREE
);
8707 case BUILT_IN_STRCAT_CHK
:
8708 return fold_builtin_strcat_chk (fndecl
, arglist
);
8709 case BUILT_IN_STRNCAT_CHK
:
8710 return fold_builtin_strncat_chk (fndecl
, arglist
);
8711 case BUILT_IN_SPRINTF_CHK
:
8712 case BUILT_IN_VSPRINTF_CHK
:
8713 return fold_builtin_sprintf_chk (arglist
, DECL_FUNCTION_CODE (fndecl
));
8714 case BUILT_IN_SNPRINTF_CHK
:
8715 case BUILT_IN_VSNPRINTF_CHK
:
8716 return fold_builtin_snprintf_chk (arglist
, NULL_TREE
,
8717 DECL_FUNCTION_CODE (fndecl
));
8719 case BUILT_IN_PRINTF
:
8720 case BUILT_IN_PRINTF_UNLOCKED
:
8721 case BUILT_IN_VPRINTF
:
8722 case BUILT_IN_PRINTF_CHK
:
8723 case BUILT_IN_VPRINTF_CHK
:
8724 return fold_builtin_printf (fndecl
, arglist
, ignore
,
8725 DECL_FUNCTION_CODE (fndecl
));
8727 case BUILT_IN_FPRINTF
:
8728 case BUILT_IN_FPRINTF_UNLOCKED
:
8729 case BUILT_IN_VFPRINTF
:
8730 case BUILT_IN_FPRINTF_CHK
:
8731 case BUILT_IN_VFPRINTF_CHK
:
8732 return fold_builtin_fprintf (fndecl
, arglist
, ignore
,
8733 DECL_FUNCTION_CODE (fndecl
));
8742 /* A wrapper function for builtin folding that prevents warnings for
8743 "statement without effect" and the like, caused by removing the
8744 call node earlier than the warning is generated. */
8747 fold_builtin (tree fndecl
, tree arglist
, bool ignore
)
8749 tree exp
= fold_builtin_1 (fndecl
, arglist
, ignore
);
8752 exp
= build1 (NOP_EXPR
, TREE_TYPE (exp
), exp
);
8753 TREE_NO_WARNING (exp
) = 1;
8759 /* Conveniently construct a function call expression. */
8762 build_function_call_expr (tree fn
, tree arglist
)
8766 call_expr
= build1 (ADDR_EXPR
, build_pointer_type (TREE_TYPE (fn
)), fn
);
8767 return fold_build3 (CALL_EXPR
, TREE_TYPE (TREE_TYPE (fn
)),
8768 call_expr
, arglist
, NULL_TREE
);
8771 /* This function validates the types of a function call argument list
8772 represented as a tree chain of parameters against a specified list
8773 of tree_codes. If the last specifier is a 0, that represents an
8774 ellipses, otherwise the last specifier must be a VOID_TYPE. */
8777 validate_arglist (tree arglist
, ...)
8779 enum tree_code code
;
8783 va_start (ap
, arglist
);
8787 code
= va_arg (ap
, enum tree_code
);
8791 /* This signifies an ellipses, any further arguments are all ok. */
8795 /* This signifies an endlink, if no arguments remain, return
8796 true, otherwise return false. */
8800 /* If no parameters remain or the parameter's code does not
8801 match the specified code, return false. Otherwise continue
8802 checking any remaining arguments. */
8805 if (code
== POINTER_TYPE
)
8807 if (! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist
))))
8810 else if (code
!= TREE_CODE (TREE_TYPE (TREE_VALUE (arglist
))))
8814 arglist
= TREE_CHAIN (arglist
);
8818 /* We need gotos here since we can only have one VA_CLOSE in a
8826 /* Default target-specific builtin expander that does nothing. */
8829 default_expand_builtin (tree exp ATTRIBUTE_UNUSED
,
8830 rtx target ATTRIBUTE_UNUSED
,
8831 rtx subtarget ATTRIBUTE_UNUSED
,
8832 enum machine_mode mode ATTRIBUTE_UNUSED
,
8833 int ignore ATTRIBUTE_UNUSED
)
8838 /* Returns true is EXP represents data that would potentially reside
8839 in a readonly section. */
8842 readonly_data_expr (tree exp
)
8846 if (TREE_CODE (exp
) != ADDR_EXPR
)
8849 exp
= get_base_address (TREE_OPERAND (exp
, 0));
8853 /* Make sure we call decl_readonly_section only for trees it
8854 can handle (since it returns true for everything it doesn't
8856 if (TREE_CODE (exp
) == STRING_CST
8857 || TREE_CODE (exp
) == CONSTRUCTOR
8858 || (TREE_CODE (exp
) == VAR_DECL
&& TREE_STATIC (exp
)))
8859 return decl_readonly_section (exp
, 0);
8864 /* Simplify a call to the strstr builtin.
8866 Return 0 if no simplification was possible, otherwise return the
8867 simplified form of the call as a tree.
8869 The simplified form may be a constant or other expression which
8870 computes the same value, but in a more efficient manner (including
8871 calls to other builtin functions).
8873 The call may contain arguments which need to be evaluated, but
8874 which are not useful to determine the result of the call. In
8875 this case we return a chain of COMPOUND_EXPRs. The LHS of each
8876 COMPOUND_EXPR will be an argument which must be evaluated.
8877 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
8878 COMPOUND_EXPR in the chain will contain the tree for the simplified
8879 form of the builtin function call. */
8882 fold_builtin_strstr (tree arglist
, tree type
)
8884 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
8888 tree s1
= TREE_VALUE (arglist
), s2
= TREE_VALUE (TREE_CHAIN (arglist
));
8890 const char *p1
, *p2
;
8899 const char *r
= strstr (p1
, p2
);
8903 return build_int_cst (TREE_TYPE (s1
), 0);
8905 /* Return an offset into the constant string argument. */
8906 tem
= fold_build2 (PLUS_EXPR
, TREE_TYPE (s1
),
8907 s1
, build_int_cst (TREE_TYPE (s1
), r
- p1
));
8908 return fold_convert (type
, tem
);
8911 /* The argument is const char *, and the result is char *, so we need
8912 a type conversion here to avoid a warning. */
8914 return fold_convert (type
, s1
);
8919 fn
= implicit_built_in_decls
[BUILT_IN_STRCHR
];
8923 /* New argument list transforming strstr(s1, s2) to
8924 strchr(s1, s2[0]). */
8925 arglist
= build_tree_list (NULL_TREE
,
8926 build_int_cst (NULL_TREE
, p2
[0]));
8927 arglist
= tree_cons (NULL_TREE
, s1
, arglist
);
8928 return build_function_call_expr (fn
, arglist
);
8932 /* Simplify a call to the strchr builtin.
8934 Return 0 if no simplification was possible, otherwise return the
8935 simplified form of the call as a tree.
8937 The simplified form may be a constant or other expression which
8938 computes the same value, but in a more efficient manner (including
8939 calls to other builtin functions).
8941 The call may contain arguments which need to be evaluated, but
8942 which are not useful to determine the result of the call. In
8943 this case we return a chain of COMPOUND_EXPRs. The LHS of each
8944 COMPOUND_EXPR will be an argument which must be evaluated.
8945 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
8946 COMPOUND_EXPR in the chain will contain the tree for the simplified
8947 form of the builtin function call. */
8950 fold_builtin_strchr (tree arglist
, tree type
)
8952 if (!validate_arglist (arglist
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
8956 tree s1
= TREE_VALUE (arglist
), s2
= TREE_VALUE (TREE_CHAIN (arglist
));
8959 if (TREE_CODE (s2
) != INTEGER_CST
)
8969 if (target_char_cast (s2
, &c
))
8975 return build_int_cst (TREE_TYPE (s1
), 0);
8977 /* Return an offset into the constant string argument. */
8978 tem
= fold_build2 (PLUS_EXPR
, TREE_TYPE (s1
),
8979 s1
, build_int_cst (TREE_TYPE (s1
), r
- p1
));
8980 return fold_convert (type
, tem
);
8986 /* Simplify a call to the strrchr builtin.
8988 Return 0 if no simplification was possible, otherwise return the
8989 simplified form of the call as a tree.
8991 The simplified form may be a constant or other expression which
8992 computes the same value, but in a more efficient manner (including
8993 calls to other builtin functions).
8995 The call may contain arguments which need to be evaluated, but
8996 which are not useful to determine the result of the call. In
8997 this case we return a chain of COMPOUND_EXPRs. The LHS of each
8998 COMPOUND_EXPR will be an argument which must be evaluated.
8999 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9000 COMPOUND_EXPR in the chain will contain the tree for the simplified
9001 form of the builtin function call. */
9004 fold_builtin_strrchr (tree arglist
, tree type
)
9006 if (!validate_arglist (arglist
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
9010 tree s1
= TREE_VALUE (arglist
), s2
= TREE_VALUE (TREE_CHAIN (arglist
));
9014 if (TREE_CODE (s2
) != INTEGER_CST
)
9024 if (target_char_cast (s2
, &c
))
9027 r
= strrchr (p1
, c
);
9030 return build_int_cst (TREE_TYPE (s1
), 0);
9032 /* Return an offset into the constant string argument. */
9033 tem
= fold_build2 (PLUS_EXPR
, TREE_TYPE (s1
),
9034 s1
, build_int_cst (TREE_TYPE (s1
), r
- p1
));
9035 return fold_convert (type
, tem
);
9038 if (! integer_zerop (s2
))
9041 fn
= implicit_built_in_decls
[BUILT_IN_STRCHR
];
9045 /* Transform strrchr(s1, '\0') to strchr(s1, '\0'). */
9046 return build_function_call_expr (fn
, arglist
);
9050 /* Simplify a call to the strpbrk builtin.
9052 Return 0 if no simplification was possible, otherwise return the
9053 simplified form of the call as a tree.
9055 The simplified form may be a constant or other expression which
9056 computes the same value, but in a more efficient manner (including
9057 calls to other builtin functions).
9059 The call may contain arguments which need to be evaluated, but
9060 which are not useful to determine the result of the call. In
9061 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9062 COMPOUND_EXPR will be an argument which must be evaluated.
9063 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9064 COMPOUND_EXPR in the chain will contain the tree for the simplified
9065 form of the builtin function call. */
9068 fold_builtin_strpbrk (tree arglist
, tree type
)
9070 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
9074 tree s1
= TREE_VALUE (arglist
), s2
= TREE_VALUE (TREE_CHAIN (arglist
));
9076 const char *p1
, *p2
;
9085 const char *r
= strpbrk (p1
, p2
);
9089 return build_int_cst (TREE_TYPE (s1
), 0);
9091 /* Return an offset into the constant string argument. */
9092 tem
= fold_build2 (PLUS_EXPR
, TREE_TYPE (s1
),
9093 s1
, build_int_cst (TREE_TYPE (s1
), r
- p1
));
9094 return fold_convert (type
, tem
);
9098 /* strpbrk(x, "") == NULL.
9099 Evaluate and ignore s1 in case it had side-effects. */
9100 return omit_one_operand (TREE_TYPE (s1
), integer_zero_node
, s1
);
9103 return 0; /* Really call strpbrk. */
9105 fn
= implicit_built_in_decls
[BUILT_IN_STRCHR
];
9109 /* New argument list transforming strpbrk(s1, s2) to
9110 strchr(s1, s2[0]). */
9111 arglist
= build_tree_list (NULL_TREE
,
9112 build_int_cst (NULL_TREE
, p2
[0]));
9113 arglist
= tree_cons (NULL_TREE
, s1
, arglist
);
9114 return build_function_call_expr (fn
, arglist
);
9118 /* Simplify a call to the strcat builtin.
9120 Return 0 if no simplification was possible, otherwise return the
9121 simplified form of the call as a tree.
9123 The simplified form may be a constant or other expression which
9124 computes the same value, but in a more efficient manner (including
9125 calls to other builtin functions).
9127 The call may contain arguments which need to be evaluated, but
9128 which are not useful to determine the result of the call. In
9129 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9130 COMPOUND_EXPR will be an argument which must be evaluated.
9131 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9132 COMPOUND_EXPR in the chain will contain the tree for the simplified
9133 form of the builtin function call. */
9136 fold_builtin_strcat (tree arglist
)
9138 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
9142 tree dst
= TREE_VALUE (arglist
),
9143 src
= TREE_VALUE (TREE_CHAIN (arglist
));
9144 const char *p
= c_getstr (src
);
9146 /* If the string length is zero, return the dst parameter. */
9147 if (p
&& *p
== '\0')
9154 /* Simplify a call to the strncat builtin.
9156 Return 0 if no simplification was possible, otherwise return the
9157 simplified form of the call as a tree.
9159 The simplified form may be a constant or other expression which
9160 computes the same value, but in a more efficient manner (including
9161 calls to other builtin functions).
9163 The call may contain arguments which need to be evaluated, but
9164 which are not useful to determine the result of the call. In
9165 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9166 COMPOUND_EXPR will be an argument which must be evaluated.
9167 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9168 COMPOUND_EXPR in the chain will contain the tree for the simplified
9169 form of the builtin function call. */
9172 fold_builtin_strncat (tree arglist
)
9174 if (!validate_arglist (arglist
,
9175 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
9179 tree dst
= TREE_VALUE (arglist
);
9180 tree src
= TREE_VALUE (TREE_CHAIN (arglist
));
9181 tree len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
9182 const char *p
= c_getstr (src
);
9184 /* If the requested length is zero, or the src parameter string
9185 length is zero, return the dst parameter. */
9186 if (integer_zerop (len
) || (p
&& *p
== '\0'))
9187 return omit_two_operands (TREE_TYPE (dst
), dst
, src
, len
);
9189 /* If the requested len is greater than or equal to the string
9190 length, call strcat. */
9191 if (TREE_CODE (len
) == INTEGER_CST
&& p
9192 && compare_tree_int (len
, strlen (p
)) >= 0)
9195 = tree_cons (NULL_TREE
, dst
, build_tree_list (NULL_TREE
, src
));
9196 tree fn
= implicit_built_in_decls
[BUILT_IN_STRCAT
];
9198 /* If the replacement _DECL isn't initialized, don't do the
9203 return build_function_call_expr (fn
, newarglist
);
9209 /* Simplify a call to the strspn builtin.
9211 Return 0 if no simplification was possible, otherwise return the
9212 simplified form of the call as a tree.
9214 The simplified form may be a constant or other expression which
9215 computes the same value, but in a more efficient manner (including
9216 calls to other builtin functions).
9218 The call may contain arguments which need to be evaluated, but
9219 which are not useful to determine the result of the call. In
9220 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9221 COMPOUND_EXPR will be an argument which must be evaluated.
9222 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9223 COMPOUND_EXPR in the chain will contain the tree for the simplified
9224 form of the builtin function call. */
9227 fold_builtin_strspn (tree arglist
)
9229 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
9233 tree s1
= TREE_VALUE (arglist
), s2
= TREE_VALUE (TREE_CHAIN (arglist
));
9234 const char *p1
= c_getstr (s1
), *p2
= c_getstr (s2
);
9236 /* If both arguments are constants, evaluate at compile-time. */
9239 const size_t r
= strspn (p1
, p2
);
9240 return size_int (r
);
9243 /* If either argument is "", return 0. */
9244 if ((p1
&& *p1
== '\0') || (p2
&& *p2
== '\0'))
9245 /* Evaluate and ignore both arguments in case either one has
9247 return omit_two_operands (integer_type_node
, integer_zero_node
,
9253 /* Simplify a call to the strcspn builtin.
9255 Return 0 if no simplification was possible, otherwise return the
9256 simplified form of the call as a tree.
9258 The simplified form may be a constant or other expression which
9259 computes the same value, but in a more efficient manner (including
9260 calls to other builtin functions).
9262 The call may contain arguments which need to be evaluated, but
9263 which are not useful to determine the result of the call. In
9264 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9265 COMPOUND_EXPR will be an argument which must be evaluated.
9266 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9267 COMPOUND_EXPR in the chain will contain the tree for the simplified
9268 form of the builtin function call. */
9271 fold_builtin_strcspn (tree arglist
)
9273 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
9277 tree s1
= TREE_VALUE (arglist
), s2
= TREE_VALUE (TREE_CHAIN (arglist
));
9278 const char *p1
= c_getstr (s1
), *p2
= c_getstr (s2
);
9280 /* If both arguments are constants, evaluate at compile-time. */
9283 const size_t r
= strcspn (p1
, p2
);
9284 return size_int (r
);
9287 /* If the first argument is "", return 0. */
9288 if (p1
&& *p1
== '\0')
9290 /* Evaluate and ignore argument s2 in case it has
9292 return omit_one_operand (integer_type_node
,
9293 integer_zero_node
, s2
);
9296 /* If the second argument is "", return __builtin_strlen(s1). */
9297 if (p2
&& *p2
== '\0')
9299 tree newarglist
= build_tree_list (NULL_TREE
, s1
),
9300 fn
= implicit_built_in_decls
[BUILT_IN_STRLEN
];
9302 /* If the replacement _DECL isn't initialized, don't do the
9307 return build_function_call_expr (fn
, newarglist
);
9313 /* Fold a call to the fputs builtin. IGNORE is true if the value returned
9314 by the builtin will be ignored. UNLOCKED is true is true if this
9315 actually a call to fputs_unlocked. If LEN in non-NULL, it represents
9316 the known length of the string. Return NULL_TREE if no simplification
9320 fold_builtin_fputs (tree arglist
, bool ignore
, bool unlocked
, tree len
)
9323 /* If we're using an unlocked function, assume the other unlocked
9324 functions exist explicitly. */
9325 tree
const fn_fputc
= unlocked
? built_in_decls
[BUILT_IN_FPUTC_UNLOCKED
]
9326 : implicit_built_in_decls
[BUILT_IN_FPUTC
];
9327 tree
const fn_fwrite
= unlocked
? built_in_decls
[BUILT_IN_FWRITE_UNLOCKED
]
9328 : implicit_built_in_decls
[BUILT_IN_FWRITE
];
9330 /* If the return value is used, don't do the transformation. */
9334 /* Verify the arguments in the original call. */
9335 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
9339 len
= c_strlen (TREE_VALUE (arglist
), 0);
9341 /* Get the length of the string passed to fputs. If the length
9342 can't be determined, punt. */
9344 || TREE_CODE (len
) != INTEGER_CST
)
9347 switch (compare_tree_int (len
, 1))
9349 case -1: /* length is 0, delete the call entirely . */
9350 return omit_one_operand (integer_type_node
, integer_zero_node
,
9351 TREE_VALUE (TREE_CHAIN (arglist
)));
9353 case 0: /* length is 1, call fputc. */
9355 const char *p
= c_getstr (TREE_VALUE (arglist
));
9359 /* New argument list transforming fputs(string, stream) to
9360 fputc(string[0], stream). */
9361 arglist
= build_tree_list (NULL_TREE
,
9362 TREE_VALUE (TREE_CHAIN (arglist
)));
9363 arglist
= tree_cons (NULL_TREE
,
9364 build_int_cst (NULL_TREE
, p
[0]),
9371 case 1: /* length is greater than 1, call fwrite. */
9375 /* If optimizing for size keep fputs. */
9378 string_arg
= TREE_VALUE (arglist
);
9379 /* New argument list transforming fputs(string, stream) to
9380 fwrite(string, 1, len, stream). */
9381 arglist
= build_tree_list (NULL_TREE
,
9382 TREE_VALUE (TREE_CHAIN (arglist
)));
9383 arglist
= tree_cons (NULL_TREE
, len
, arglist
);
9384 arglist
= tree_cons (NULL_TREE
, size_one_node
, arglist
);
9385 arglist
= tree_cons (NULL_TREE
, string_arg
, arglist
);
9393 /* If the replacement _DECL isn't initialized, don't do the
9398 /* These optimizations are only performed when the result is ignored,
9399 hence there's no need to cast the result to integer_type_node. */
9400 return build_function_call_expr (fn
, arglist
);
9403 /* Fold the new_arg's arguments (ARGLIST). Returns true if there was an error
9404 produced. False otherwise. This is done so that we don't output the error
9405 or warning twice or three times. */
9407 fold_builtin_next_arg (tree arglist
)
9409 tree fntype
= TREE_TYPE (current_function_decl
);
9411 if (TYPE_ARG_TYPES (fntype
) == 0
9412 || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype
)))
9415 error ("%<va_start%> used in function with fixed args");
9420 /* Evidently an out of date version of <stdarg.h>; can't validate
9421 va_start's second argument, but can still work as intended. */
9422 warning (0, "%<__builtin_next_arg%> called without an argument");
9425 /* We use __builtin_va_start (ap, 0, 0) or __builtin_next_arg (0, 0)
9426 when we checked the arguments and if needed issued a warning. */
9427 else if (!TREE_CHAIN (arglist
)
9428 || !integer_zerop (TREE_VALUE (arglist
))
9429 || !integer_zerop (TREE_VALUE (TREE_CHAIN (arglist
)))
9430 || TREE_CHAIN (TREE_CHAIN (arglist
)))
9432 tree last_parm
= tree_last (DECL_ARGUMENTS (current_function_decl
));
9433 tree arg
= TREE_VALUE (arglist
);
9435 if (TREE_CHAIN (arglist
))
9437 error ("%<va_start%> used with too many arguments");
9441 /* Strip off all nops for the sake of the comparison. This
9442 is not quite the same as STRIP_NOPS. It does more.
9443 We must also strip off INDIRECT_EXPR for C++ reference
9445 while (TREE_CODE (arg
) == NOP_EXPR
9446 || TREE_CODE (arg
) == CONVERT_EXPR
9447 || TREE_CODE (arg
) == NON_LVALUE_EXPR
9448 || TREE_CODE (arg
) == INDIRECT_REF
)
9449 arg
= TREE_OPERAND (arg
, 0);
9450 if (arg
!= last_parm
)
9452 /* FIXME: Sometimes with the tree optimizers we can get the
9453 not the last argument even though the user used the last
9454 argument. We just warn and set the arg to be the last
9455 argument so that we will get wrong-code because of
9457 warning (0, "second parameter of %<va_start%> not last named argument");
9459 /* We want to verify the second parameter just once before the tree
9460 optimizers are run and then avoid keeping it in the tree,
9461 as otherwise we could warn even for correct code like:
9462 void foo (int i, ...)
9463 { va_list ap; i++; va_start (ap, i); va_end (ap); } */
9464 TREE_VALUE (arglist
) = integer_zero_node
;
9465 TREE_CHAIN (arglist
) = build_tree_list (NULL
, integer_zero_node
);
9471 /* Simplify a call to the sprintf builtin.
9473 Return 0 if no simplification was possible, otherwise return the
9474 simplified form of the call as a tree. If IGNORED is true, it means that
9475 the caller does not use the returned value of the function. */
9478 fold_builtin_sprintf (tree arglist
, int ignored
)
9480 tree call
, retval
, dest
, fmt
;
9481 const char *fmt_str
= NULL
;
9483 /* Verify the required arguments in the original call. We deal with two
9484 types of sprintf() calls: 'sprintf (str, fmt)' and
9485 'sprintf (dest, "%s", orig)'. */
9486 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
)
9487 && !validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, POINTER_TYPE
,
9491 /* Get the destination string and the format specifier. */
9492 dest
= TREE_VALUE (arglist
);
9493 fmt
= TREE_VALUE (TREE_CHAIN (arglist
));
9495 /* Check whether the format is a literal string constant. */
9496 fmt_str
= c_getstr (fmt
);
9497 if (fmt_str
== NULL
)
9503 if (!init_target_chars())
9506 /* If the format doesn't contain % args or %%, use strcpy. */
9507 if (strchr (fmt_str
, target_percent
) == NULL
)
9509 tree fn
= implicit_built_in_decls
[BUILT_IN_STRCPY
];
9514 /* Convert sprintf (str, fmt) into strcpy (str, fmt) when
9515 'format' is known to contain no % formats. */
9516 arglist
= build_tree_list (NULL_TREE
, fmt
);
9517 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
9518 call
= build_function_call_expr (fn
, arglist
);
9520 retval
= build_int_cst (NULL_TREE
, strlen (fmt_str
));
9523 /* If the format is "%s", use strcpy if the result isn't used. */
9524 else if (fmt_str
&& strcmp (fmt_str
, target_percent_s
) == 0)
9527 fn
= implicit_built_in_decls
[BUILT_IN_STRCPY
];
9532 /* Convert sprintf (str1, "%s", str2) into strcpy (str1, str2). */
9533 orig
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
9534 arglist
= build_tree_list (NULL_TREE
, orig
);
9535 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
9538 retval
= c_strlen (orig
, 1);
9539 if (!retval
|| TREE_CODE (retval
) != INTEGER_CST
)
9542 call
= build_function_call_expr (fn
, arglist
);
9548 (TREE_TYPE (TREE_TYPE (implicit_built_in_decls
[BUILT_IN_SPRINTF
])),
9550 return build2 (COMPOUND_EXPR
, TREE_TYPE (retval
), call
, retval
);
9556 /* Expand a call to __builtin_object_size. */
9559 expand_builtin_object_size (tree exp
)
9562 int object_size_type
;
9563 tree fndecl
= get_callee_fndecl (exp
);
9564 tree arglist
= TREE_OPERAND (exp
, 1);
9565 location_t locus
= EXPR_LOCATION (exp
);
9567 if (!validate_arglist (arglist
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
9569 error ("%Hfirst argument of %D must be a pointer, second integer constant",
9571 expand_builtin_trap ();
9575 ost
= TREE_VALUE (TREE_CHAIN (arglist
));
9578 if (TREE_CODE (ost
) != INTEGER_CST
9579 || tree_int_cst_sgn (ost
) < 0
9580 || compare_tree_int (ost
, 3) > 0)
9582 error ("%Hlast argument of %D is not integer constant between 0 and 3",
9584 expand_builtin_trap ();
9588 object_size_type
= tree_low_cst (ost
, 0);
9590 return object_size_type
< 2 ? constm1_rtx
: const0_rtx
;
9593 /* Expand EXP, a call to the __mem{cpy,pcpy,move,set}_chk builtin.
9594 FCODE is the BUILT_IN_* to use.
9595 Return 0 if we failed; the caller should emit a normal call,
9596 otherwise try to get the result in TARGET, if convenient (and in
9597 mode MODE if that's convenient). */
9600 expand_builtin_memory_chk (tree exp
, rtx target
, enum machine_mode mode
,
9601 enum built_in_function fcode
)
9603 tree arglist
= TREE_OPERAND (exp
, 1);
9604 tree dest
, src
, len
, size
;
9606 if (!validate_arglist (arglist
,
9608 fcode
== BUILT_IN_MEMSET_CHK
9609 ? INTEGER_TYPE
: POINTER_TYPE
,
9610 INTEGER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
9613 dest
= TREE_VALUE (arglist
);
9614 src
= TREE_VALUE (TREE_CHAIN (arglist
));
9615 len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
9616 size
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist
))));
9618 if (! host_integerp (size
, 1))
9621 if (host_integerp (len
, 1) || integer_all_onesp (size
))
9625 if (! integer_all_onesp (size
) && tree_int_cst_lt (size
, len
))
9627 location_t locus
= EXPR_LOCATION (exp
);
9628 warning (0, "%Hcall to %D will always overflow destination buffer",
9629 &locus
, get_callee_fndecl (exp
));
9633 arglist
= build_tree_list (NULL_TREE
, len
);
9634 arglist
= tree_cons (NULL_TREE
, src
, arglist
);
9635 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
9638 /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume
9639 mem{cpy,pcpy,move,set} is available. */
9642 case BUILT_IN_MEMCPY_CHK
:
9643 fn
= built_in_decls
[BUILT_IN_MEMCPY
];
9645 case BUILT_IN_MEMPCPY_CHK
:
9646 fn
= built_in_decls
[BUILT_IN_MEMPCPY
];
9648 case BUILT_IN_MEMMOVE_CHK
:
9649 fn
= built_in_decls
[BUILT_IN_MEMMOVE
];
9651 case BUILT_IN_MEMSET_CHK
:
9652 fn
= built_in_decls
[BUILT_IN_MEMSET
];
9661 fn
= build_function_call_expr (fn
, arglist
);
9662 if (TREE_CODE (fn
) == CALL_EXPR
)
9663 CALL_EXPR_TAILCALL (fn
) = CALL_EXPR_TAILCALL (exp
);
9664 return expand_expr (fn
, target
, mode
, EXPAND_NORMAL
);
9666 else if (fcode
== BUILT_IN_MEMSET_CHK
)
9670 unsigned int dest_align
9671 = get_pointer_alignment (dest
, BIGGEST_ALIGNMENT
);
9673 /* If DEST is not a pointer type, call the normal function. */
9674 if (dest_align
== 0)
9677 /* If SRC and DEST are the same (and not volatile), do nothing. */
9678 if (operand_equal_p (src
, dest
, 0))
9682 if (fcode
!= BUILT_IN_MEMPCPY_CHK
)
9684 /* Evaluate and ignore LEN in case it has side-effects. */
9685 expand_expr (len
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
9686 return expand_expr (dest
, target
, mode
, EXPAND_NORMAL
);
9689 len
= fold_convert (TREE_TYPE (dest
), len
);
9690 expr
= fold_build2 (PLUS_EXPR
, TREE_TYPE (dest
), dest
, len
);
9691 return expand_expr (expr
, target
, mode
, EXPAND_NORMAL
);
9694 /* __memmove_chk special case. */
9695 if (fcode
== BUILT_IN_MEMMOVE_CHK
)
9697 unsigned int src_align
9698 = get_pointer_alignment (src
, BIGGEST_ALIGNMENT
);
9703 /* If src is categorized for a readonly section we can use
9704 normal __memcpy_chk. */
9705 if (readonly_data_expr (src
))
9707 tree fn
= built_in_decls
[BUILT_IN_MEMCPY_CHK
];
9710 fn
= build_function_call_expr (fn
, arglist
);
9711 if (TREE_CODE (fn
) == CALL_EXPR
)
9712 CALL_EXPR_TAILCALL (fn
) = CALL_EXPR_TAILCALL (exp
);
9713 return expand_expr (fn
, target
, mode
, EXPAND_NORMAL
);
9720 /* Emit warning if a buffer overflow is detected at compile time. */
9723 maybe_emit_chk_warning (tree exp
, enum built_in_function fcode
)
9725 int arg_mask
, is_strlen
= 0;
9726 tree arglist
= TREE_OPERAND (exp
, 1), a
;
9732 case BUILT_IN_STRCPY_CHK
:
9733 case BUILT_IN_STPCPY_CHK
:
9734 /* For __strcat_chk the warning will be emitted only if overflowing
9735 by at least strlen (dest) + 1 bytes. */
9736 case BUILT_IN_STRCAT_CHK
:
9740 case BUILT_IN_STRNCPY_CHK
:
9743 case BUILT_IN_SNPRINTF_CHK
:
9744 case BUILT_IN_VSNPRINTF_CHK
:
9753 for (a
= arglist
; a
&& arg_mask
; a
= TREE_CHAIN (a
), arg_mask
>>= 1)
9765 len
= TREE_VALUE (len
);
9766 size
= TREE_VALUE (size
);
9768 if (! host_integerp (size
, 1) || integer_all_onesp (size
))
9773 len
= c_strlen (len
, 1);
9774 if (! len
|| ! host_integerp (len
, 1) || tree_int_cst_lt (len
, size
))
9777 else if (! host_integerp (len
, 1) || ! tree_int_cst_lt (size
, len
))
9780 locus
= EXPR_LOCATION (exp
);
9781 warning (0, "%Hcall to %D will always overflow destination buffer",
9782 &locus
, get_callee_fndecl (exp
));
9785 /* Emit warning if a buffer overflow is detected at compile time
9786 in __sprintf_chk/__vsprintf_chk calls. */
9789 maybe_emit_sprintf_chk_warning (tree exp
, enum built_in_function fcode
)
9791 tree arglist
= TREE_OPERAND (exp
, 1);
9792 tree dest
, size
, len
, fmt
, flag
;
9793 const char *fmt_str
;
9795 /* Verify the required arguments in the original call. */
9798 dest
= TREE_VALUE (arglist
);
9799 arglist
= TREE_CHAIN (arglist
);
9802 flag
= TREE_VALUE (arglist
);
9803 arglist
= TREE_CHAIN (arglist
);
9806 size
= TREE_VALUE (arglist
);
9807 arglist
= TREE_CHAIN (arglist
);
9810 fmt
= TREE_VALUE (arglist
);
9811 arglist
= TREE_CHAIN (arglist
);
9813 if (! host_integerp (size
, 1) || integer_all_onesp (size
))
9816 /* Check whether the format is a literal string constant. */
9817 fmt_str
= c_getstr (fmt
);
9818 if (fmt_str
== NULL
)
9821 if (!init_target_chars())
9824 /* If the format doesn't contain % args or %%, we know its size. */
9825 if (strchr (fmt_str
, target_percent
) == 0)
9826 len
= build_int_cstu (size_type_node
, strlen (fmt_str
));
9827 /* If the format is "%s" and first ... argument is a string literal,
9829 else if (fcode
== BUILT_IN_SPRINTF_CHK
&& strcmp (fmt_str
, target_percent_s
) == 0)
9835 arg
= TREE_VALUE (arglist
);
9836 if (! POINTER_TYPE_P (TREE_TYPE (arg
)))
9839 len
= c_strlen (arg
, 1);
9840 if (!len
|| ! host_integerp (len
, 1))
9846 if (! tree_int_cst_lt (len
, size
))
9848 location_t locus
= EXPR_LOCATION (exp
);
9849 warning (0, "%Hcall to %D will always overflow destination buffer",
9850 &locus
, get_callee_fndecl (exp
));
9854 /* Fold a call to __builtin_object_size, if possible. */
9857 fold_builtin_object_size (tree arglist
)
9859 tree ptr
, ost
, ret
= 0;
9860 int object_size_type
;
9862 if (!validate_arglist (arglist
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
9865 ptr
= TREE_VALUE (arglist
);
9866 ost
= TREE_VALUE (TREE_CHAIN (arglist
));
9869 if (TREE_CODE (ost
) != INTEGER_CST
9870 || tree_int_cst_sgn (ost
) < 0
9871 || compare_tree_int (ost
, 3) > 0)
9874 object_size_type
= tree_low_cst (ost
, 0);
9876 /* __builtin_object_size doesn't evaluate side-effects in its arguments;
9877 if there are any side-effects, it returns (size_t) -1 for types 0 and 1
9878 and (size_t) 0 for types 2 and 3. */
9879 if (TREE_SIDE_EFFECTS (ptr
))
9880 return fold_convert (size_type_node
,
9881 object_size_type
< 2
9882 ? integer_minus_one_node
: integer_zero_node
);
9884 if (TREE_CODE (ptr
) == ADDR_EXPR
)
9885 ret
= build_int_cstu (size_type_node
,
9886 compute_builtin_object_size (ptr
, object_size_type
));
9888 else if (TREE_CODE (ptr
) == SSA_NAME
)
9890 unsigned HOST_WIDE_INT bytes
;
9892 /* If object size is not known yet, delay folding until
9893 later. Maybe subsequent passes will help determining
9895 bytes
= compute_builtin_object_size (ptr
, object_size_type
);
9896 if (bytes
!= (unsigned HOST_WIDE_INT
) (object_size_type
< 2
9898 ret
= build_int_cstu (size_type_node
, bytes
);
9903 ret
= force_fit_type (ret
, -1, false, false);
9904 if (TREE_CONSTANT_OVERFLOW (ret
))
9911 /* Fold a call to the __mem{cpy,pcpy,move,set}_chk builtin.
9912 IGNORE is true, if return value can be ignored. FCODE is the BUILT_IN_*
9913 code of the builtin. If MAXLEN is not NULL, it is maximum length
9914 passed as third argument. */
9917 fold_builtin_memory_chk (tree fndecl
, tree arglist
, tree maxlen
, bool ignore
,
9918 enum built_in_function fcode
)
9920 tree dest
, src
, len
, size
, fn
;
9922 if (!validate_arglist (arglist
,
9924 fcode
== BUILT_IN_MEMSET_CHK
9925 ? INTEGER_TYPE
: POINTER_TYPE
,
9926 INTEGER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
9929 dest
= TREE_VALUE (arglist
);
9930 /* Actually val for __memset_chk, but it doesn't matter. */
9931 src
= TREE_VALUE (TREE_CHAIN (arglist
));
9932 len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
9933 size
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist
))));
9935 /* If SRC and DEST are the same (and not volatile), return DEST
9936 (resp. DEST+LEN for __mempcpy_chk). */
9937 if (fcode
!= BUILT_IN_MEMSET_CHK
&& operand_equal_p (src
, dest
, 0))
9939 if (fcode
!= BUILT_IN_MEMPCPY_CHK
)
9940 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl
)), dest
, len
);
9943 tree temp
= fold_convert (TREE_TYPE (dest
), len
);
9944 temp
= fold_build2 (PLUS_EXPR
, TREE_TYPE (dest
), dest
, temp
);
9945 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl
)), temp
);
9949 if (! host_integerp (size
, 1))
9952 if (! integer_all_onesp (size
))
9954 if (! host_integerp (len
, 1))
9956 /* If LEN is not constant, try MAXLEN too.
9957 For MAXLEN only allow optimizing into non-_ocs function
9958 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
9959 if (maxlen
== NULL_TREE
|| ! host_integerp (maxlen
, 1))
9961 if (fcode
== BUILT_IN_MEMPCPY_CHK
&& ignore
)
9963 /* (void) __mempcpy_chk () can be optimized into
9964 (void) __memcpy_chk (). */
9965 fn
= built_in_decls
[BUILT_IN_MEMCPY_CHK
];
9969 return build_function_call_expr (fn
, arglist
);
9977 if (tree_int_cst_lt (size
, maxlen
))
9981 arglist
= build_tree_list (NULL_TREE
, len
);
9982 arglist
= tree_cons (NULL_TREE
, src
, arglist
);
9983 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
9986 /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume
9987 mem{cpy,pcpy,move,set} is available. */
9990 case BUILT_IN_MEMCPY_CHK
:
9991 fn
= built_in_decls
[BUILT_IN_MEMCPY
];
9993 case BUILT_IN_MEMPCPY_CHK
:
9994 fn
= built_in_decls
[BUILT_IN_MEMPCPY
];
9996 case BUILT_IN_MEMMOVE_CHK
:
9997 fn
= built_in_decls
[BUILT_IN_MEMMOVE
];
9999 case BUILT_IN_MEMSET_CHK
:
10000 fn
= built_in_decls
[BUILT_IN_MEMSET
];
10009 return build_function_call_expr (fn
, arglist
);
10012 /* Fold a call to the __st[rp]cpy_chk builtin.
10013 IGNORE is true, if return value can be ignored. FCODE is the BUILT_IN_*
10014 code of the builtin. If MAXLEN is not NULL, it is maximum length of
10015 strings passed as second argument. */
10018 fold_builtin_stxcpy_chk (tree fndecl
, tree arglist
, tree maxlen
, bool ignore
,
10019 enum built_in_function fcode
)
10021 tree dest
, src
, size
, len
, fn
;
10023 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
,
10027 dest
= TREE_VALUE (arglist
);
10028 src
= TREE_VALUE (TREE_CHAIN (arglist
));
10029 size
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
10031 /* If SRC and DEST are the same (and not volatile), return DEST. */
10032 if (fcode
== BUILT_IN_STRCPY_CHK
&& operand_equal_p (src
, dest
, 0))
10033 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl
)), dest
);
10035 if (! host_integerp (size
, 1))
10038 if (! integer_all_onesp (size
))
10040 len
= c_strlen (src
, 1);
10041 if (! len
|| ! host_integerp (len
, 1))
10043 /* If LEN is not constant, try MAXLEN too.
10044 For MAXLEN only allow optimizing into non-_ocs function
10045 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
10046 if (maxlen
== NULL_TREE
|| ! host_integerp (maxlen
, 1))
10048 if (fcode
== BUILT_IN_STPCPY_CHK
)
10053 /* If return value of __stpcpy_chk is ignored,
10054 optimize into __strcpy_chk. */
10055 fn
= built_in_decls
[BUILT_IN_STRCPY_CHK
];
10059 return build_function_call_expr (fn
, arglist
);
10062 if (! len
|| TREE_SIDE_EFFECTS (len
))
10065 /* If c_strlen returned something, but not a constant,
10066 transform __strcpy_chk into __memcpy_chk. */
10067 fn
= built_in_decls
[BUILT_IN_MEMCPY_CHK
];
10071 len
= size_binop (PLUS_EXPR
, len
, ssize_int (1));
10072 arglist
= build_tree_list (NULL_TREE
, size
);
10073 arglist
= tree_cons (NULL_TREE
, len
, arglist
);
10074 arglist
= tree_cons (NULL_TREE
, src
, arglist
);
10075 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
10076 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl
)),
10077 build_function_call_expr (fn
, arglist
));
10083 if (! tree_int_cst_lt (maxlen
, size
))
10087 arglist
= build_tree_list (NULL_TREE
, src
);
10088 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
10090 /* If __builtin_st{r,p}cpy_chk is used, assume st{r,p}cpy is available. */
10091 fn
= built_in_decls
[fcode
== BUILT_IN_STPCPY_CHK
10092 ? BUILT_IN_STPCPY
: BUILT_IN_STRCPY
];
10096 return build_function_call_expr (fn
, arglist
);
10099 /* Fold a call to the __strncpy_chk builtin.
10100 If MAXLEN is not NULL, it is maximum length passed as third argument. */
10103 fold_builtin_strncpy_chk (tree arglist
, tree maxlen
)
10105 tree dest
, src
, size
, len
, fn
;
10107 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
,
10108 INTEGER_TYPE
, VOID_TYPE
))
10111 dest
= TREE_VALUE (arglist
);
10112 src
= TREE_VALUE (TREE_CHAIN (arglist
));
10113 len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
10114 size
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist
))));
10116 if (! host_integerp (size
, 1))
10119 if (! integer_all_onesp (size
))
10121 if (! host_integerp (len
, 1))
10123 /* If LEN is not constant, try MAXLEN too.
10124 For MAXLEN only allow optimizing into non-_ocs function
10125 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
10126 if (maxlen
== NULL_TREE
|| ! host_integerp (maxlen
, 1))
10132 if (tree_int_cst_lt (size
, maxlen
))
10136 arglist
= build_tree_list (NULL_TREE
, len
);
10137 arglist
= tree_cons (NULL_TREE
, src
, arglist
);
10138 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
10140 /* If __builtin_strncpy_chk is used, assume strncpy is available. */
10141 fn
= built_in_decls
[BUILT_IN_STRNCPY
];
10145 return build_function_call_expr (fn
, arglist
);
10148 /* Fold a call to the __strcat_chk builtin FNDECL with ARGLIST. */
10151 fold_builtin_strcat_chk (tree fndecl
, tree arglist
)
10153 tree dest
, src
, size
, fn
;
10156 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
,
10160 dest
= TREE_VALUE (arglist
);
10161 src
= TREE_VALUE (TREE_CHAIN (arglist
));
10162 size
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
10164 p
= c_getstr (src
);
10165 /* If the SRC parameter is "", return DEST. */
10166 if (p
&& *p
== '\0')
10167 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl
)), dest
, src
);
10169 if (! host_integerp (size
, 1) || ! integer_all_onesp (size
))
10172 arglist
= build_tree_list (NULL_TREE
, src
);
10173 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
10175 /* If __builtin_strcat_chk is used, assume strcat is available. */
10176 fn
= built_in_decls
[BUILT_IN_STRCAT
];
10180 return build_function_call_expr (fn
, arglist
);
10183 /* Fold a call to the __strncat_chk builtin EXP. */
10186 fold_builtin_strncat_chk (tree fndecl
, tree arglist
)
10188 tree dest
, src
, size
, len
, fn
;
10191 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
,
10192 INTEGER_TYPE
, VOID_TYPE
))
10195 dest
= TREE_VALUE (arglist
);
10196 src
= TREE_VALUE (TREE_CHAIN (arglist
));
10197 len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
10198 size
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist
))));
10200 p
= c_getstr (src
);
10201 /* If the SRC parameter is "" or if LEN is 0, return DEST. */
10202 if (p
&& *p
== '\0')
10203 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl
)), dest
, len
);
10204 else if (integer_zerop (len
))
10205 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl
)), dest
, src
);
10207 if (! host_integerp (size
, 1))
10210 if (! integer_all_onesp (size
))
10212 tree src_len
= c_strlen (src
, 1);
10214 && host_integerp (src_len
, 1)
10215 && host_integerp (len
, 1)
10216 && ! tree_int_cst_lt (len
, src_len
))
10218 /* If LEN >= strlen (SRC), optimize into __strcat_chk. */
10219 fn
= built_in_decls
[BUILT_IN_STRCAT_CHK
];
10223 arglist
= build_tree_list (NULL_TREE
, size
);
10224 arglist
= tree_cons (NULL_TREE
, src
, arglist
);
10225 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
10226 return build_function_call_expr (fn
, arglist
);
10231 arglist
= build_tree_list (NULL_TREE
, len
);
10232 arglist
= tree_cons (NULL_TREE
, src
, arglist
);
10233 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
10235 /* If __builtin_strncat_chk is used, assume strncat is available. */
10236 fn
= built_in_decls
[BUILT_IN_STRNCAT
];
10240 return build_function_call_expr (fn
, arglist
);
10243 /* Fold a call to __{,v}sprintf_chk with argument list ARGLIST. Return 0 if
10244 a normal call should be emitted rather than expanding the function
10245 inline. FCODE is either BUILT_IN_SPRINTF_CHK or BUILT_IN_VSPRINTF_CHK. */
10248 fold_builtin_sprintf_chk (tree arglist
, enum built_in_function fcode
)
10250 tree dest
, size
, len
, fn
, fmt
, flag
;
10251 const char *fmt_str
;
10253 /* Verify the required arguments in the original call. */
10256 dest
= TREE_VALUE (arglist
);
10257 if (! POINTER_TYPE_P (TREE_TYPE (dest
)))
10259 arglist
= TREE_CHAIN (arglist
);
10262 flag
= TREE_VALUE (arglist
);
10263 if (TREE_CODE (TREE_TYPE (flag
)) != INTEGER_TYPE
)
10265 arglist
= TREE_CHAIN (arglist
);
10268 size
= TREE_VALUE (arglist
);
10269 if (TREE_CODE (TREE_TYPE (size
)) != INTEGER_TYPE
)
10271 arglist
= TREE_CHAIN (arglist
);
10274 fmt
= TREE_VALUE (arglist
);
10275 if (! POINTER_TYPE_P (TREE_TYPE (fmt
)))
10277 arglist
= TREE_CHAIN (arglist
);
10279 if (! host_integerp (size
, 1))
10284 if (!init_target_chars())
10287 /* Check whether the format is a literal string constant. */
10288 fmt_str
= c_getstr (fmt
);
10289 if (fmt_str
!= NULL
)
10291 /* If the format doesn't contain % args or %%, we know the size. */
10292 if (strchr (fmt_str
, target_percent
) == 0)
10294 if (fcode
!= BUILT_IN_SPRINTF_CHK
|| arglist
== NULL_TREE
)
10295 len
= build_int_cstu (size_type_node
, strlen (fmt_str
));
10297 /* If the format is "%s" and first ... argument is a string literal,
10298 we know the size too. */
10299 else if (fcode
== BUILT_IN_SPRINTF_CHK
&& strcmp (fmt_str
, target_percent_s
) == 0)
10303 if (arglist
&& !TREE_CHAIN (arglist
))
10305 arg
= TREE_VALUE (arglist
);
10306 if (POINTER_TYPE_P (TREE_TYPE (arg
)))
10308 len
= c_strlen (arg
, 1);
10309 if (! len
|| ! host_integerp (len
, 1))
10316 if (! integer_all_onesp (size
))
10318 if (! len
|| ! tree_int_cst_lt (len
, size
))
10322 /* Only convert __{,v}sprintf_chk to {,v}sprintf if flag is 0
10323 or if format doesn't contain % chars or is "%s". */
10324 if (! integer_zerop (flag
))
10326 if (fmt_str
== NULL
)
10328 if (strchr (fmt_str
, target_percent
) != NULL
&& strcmp (fmt_str
, target_percent_s
))
10332 arglist
= tree_cons (NULL_TREE
, fmt
, arglist
);
10333 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
10335 /* If __builtin_{,v}sprintf_chk is used, assume {,v}sprintf is available. */
10336 fn
= built_in_decls
[fcode
== BUILT_IN_VSPRINTF_CHK
10337 ? BUILT_IN_VSPRINTF
: BUILT_IN_SPRINTF
];
10341 return build_function_call_expr (fn
, arglist
);
10344 /* Fold a call to {,v}snprintf with argument list ARGLIST. Return 0 if
10345 a normal call should be emitted rather than expanding the function
10346 inline. FCODE is either BUILT_IN_SNPRINTF_CHK or
10347 BUILT_IN_VSNPRINTF_CHK. If MAXLEN is not NULL, it is maximum length
10348 passed as second argument. */
10351 fold_builtin_snprintf_chk (tree arglist
, tree maxlen
,
10352 enum built_in_function fcode
)
10354 tree dest
, size
, len
, fn
, fmt
, flag
;
10355 const char *fmt_str
;
10357 /* Verify the required arguments in the original call. */
10360 dest
= TREE_VALUE (arglist
);
10361 if (! POINTER_TYPE_P (TREE_TYPE (dest
)))
10363 arglist
= TREE_CHAIN (arglist
);
10366 len
= TREE_VALUE (arglist
);
10367 if (TREE_CODE (TREE_TYPE (len
)) != INTEGER_TYPE
)
10369 arglist
= TREE_CHAIN (arglist
);
10372 flag
= TREE_VALUE (arglist
);
10373 if (TREE_CODE (TREE_TYPE (len
)) != INTEGER_TYPE
)
10375 arglist
= TREE_CHAIN (arglist
);
10378 size
= TREE_VALUE (arglist
);
10379 if (TREE_CODE (TREE_TYPE (size
)) != INTEGER_TYPE
)
10381 arglist
= TREE_CHAIN (arglist
);
10384 fmt
= TREE_VALUE (arglist
);
10385 if (! POINTER_TYPE_P (TREE_TYPE (fmt
)))
10387 arglist
= TREE_CHAIN (arglist
);
10389 if (! host_integerp (size
, 1))
10392 if (! integer_all_onesp (size
))
10394 if (! host_integerp (len
, 1))
10396 /* If LEN is not constant, try MAXLEN too.
10397 For MAXLEN only allow optimizing into non-_ocs function
10398 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
10399 if (maxlen
== NULL_TREE
|| ! host_integerp (maxlen
, 1))
10405 if (tree_int_cst_lt (size
, maxlen
))
10409 if (!init_target_chars())
10412 /* Only convert __{,v}snprintf_chk to {,v}snprintf if flag is 0
10413 or if format doesn't contain % chars or is "%s". */
10414 if (! integer_zerop (flag
))
10416 fmt_str
= c_getstr (fmt
);
10417 if (fmt_str
== NULL
)
10419 if (strchr (fmt_str
, target_percent
) != NULL
&& strcmp (fmt_str
, target_percent_s
))
10423 arglist
= tree_cons (NULL_TREE
, fmt
, arglist
);
10424 arglist
= tree_cons (NULL_TREE
, len
, arglist
);
10425 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
10427 /* If __builtin_{,v}snprintf_chk is used, assume {,v}snprintf is
10429 fn
= built_in_decls
[fcode
== BUILT_IN_VSNPRINTF_CHK
10430 ? BUILT_IN_VSNPRINTF
: BUILT_IN_SNPRINTF
];
10434 return build_function_call_expr (fn
, arglist
);
10437 /* Fold a call to the {,v}printf{,_unlocked} and __{,v}printf_chk builtins.
10439 Return 0 if no simplification was possible, otherwise return the
10440 simplified form of the call as a tree. FCODE is the BUILT_IN_*
10441 code of the function to be simplified. */
10444 fold_builtin_printf (tree fndecl
, tree arglist
, bool ignore
,
10445 enum built_in_function fcode
)
10447 tree fmt
, fn
= NULL_TREE
, fn_putchar
, fn_puts
, arg
, call
;
10448 const char *fmt_str
= NULL
;
10450 /* If the return value is used, don't do the transformation. */
10454 /* Verify the required arguments in the original call. */
10455 if (fcode
== BUILT_IN_PRINTF_CHK
|| fcode
== BUILT_IN_VPRINTF_CHK
)
10461 flag
= TREE_VALUE (arglist
);
10462 if (TREE_CODE (TREE_TYPE (flag
)) != INTEGER_TYPE
10463 || TREE_SIDE_EFFECTS (flag
))
10465 arglist
= TREE_CHAIN (arglist
);
10470 fmt
= TREE_VALUE (arglist
);
10471 if (! POINTER_TYPE_P (TREE_TYPE (fmt
)))
10473 arglist
= TREE_CHAIN (arglist
);
10475 /* Check whether the format is a literal string constant. */
10476 fmt_str
= c_getstr (fmt
);
10477 if (fmt_str
== NULL
)
10480 if (fcode
== BUILT_IN_PRINTF_UNLOCKED
)
10482 /* If we're using an unlocked function, assume the other
10483 unlocked functions exist explicitly. */
10484 fn_putchar
= built_in_decls
[BUILT_IN_PUTCHAR_UNLOCKED
];
10485 fn_puts
= built_in_decls
[BUILT_IN_PUTS_UNLOCKED
];
10489 fn_putchar
= implicit_built_in_decls
[BUILT_IN_PUTCHAR
];
10490 fn_puts
= implicit_built_in_decls
[BUILT_IN_PUTS
];
10493 if (!init_target_chars())
10496 if (strcmp (fmt_str
, target_percent_s
) == 0 || strchr (fmt_str
, target_percent
) == NULL
)
10500 if (strcmp (fmt_str
, target_percent_s
) == 0)
10502 if (fcode
== BUILT_IN_VPRINTF
|| fcode
== BUILT_IN_VPRINTF_CHK
)
10506 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist
)))
10507 || TREE_CHAIN (arglist
))
10510 str
= c_getstr (TREE_VALUE (arglist
));
10516 /* The format specifier doesn't contain any '%' characters. */
10517 if (fcode
!= BUILT_IN_VPRINTF
&& fcode
!= BUILT_IN_VPRINTF_CHK
10523 /* If the string was "", printf does nothing. */
10524 if (str
[0] == '\0')
10525 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl
)), 0);
10527 /* If the string has length of 1, call putchar. */
10528 if (str
[1] == '\0')
10530 /* Given printf("c"), (where c is any one character,)
10531 convert "c"[0] to an int and pass that to the replacement
10533 arg
= build_int_cst (NULL_TREE
, str
[0]);
10534 arglist
= build_tree_list (NULL_TREE
, arg
);
10539 /* If the string was "string\n", call puts("string"). */
10540 size_t len
= strlen (str
);
10541 if ((unsigned char)str
[len
- 1] == target_newline
)
10543 /* Create a NUL-terminated string that's one char shorter
10544 than the original, stripping off the trailing '\n'. */
10545 char *newstr
= alloca (len
);
10546 memcpy (newstr
, str
, len
- 1);
10547 newstr
[len
- 1] = 0;
10549 arg
= build_string_literal (len
, newstr
);
10550 arglist
= build_tree_list (NULL_TREE
, arg
);
10554 /* We'd like to arrange to call fputs(string,stdout) here,
10555 but we need stdout and don't have a way to get it yet. */
10560 /* The other optimizations can be done only on the non-va_list variants. */
10561 else if (fcode
== BUILT_IN_VPRINTF
|| fcode
== BUILT_IN_VPRINTF_CHK
)
10564 /* If the format specifier was "%s\n", call __builtin_puts(arg). */
10565 else if (strcmp (fmt_str
, target_percent_s_newline
) == 0)
10568 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist
)))
10569 || TREE_CHAIN (arglist
))
10574 /* If the format specifier was "%c", call __builtin_putchar(arg). */
10575 else if (strcmp (fmt_str
, target_percent_c
) == 0)
10578 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist
))) != INTEGER_TYPE
10579 || TREE_CHAIN (arglist
))
10587 call
= build_function_call_expr (fn
, arglist
);
10588 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl
)), call
);
10591 /* Fold a call to the {,v}fprintf{,_unlocked} and __{,v}printf_chk builtins.
10593 Return 0 if no simplification was possible, otherwise return the
10594 simplified form of the call as a tree. FCODE is the BUILT_IN_*
10595 code of the function to be simplified. */
10598 fold_builtin_fprintf (tree fndecl
, tree arglist
, bool ignore
,
10599 enum built_in_function fcode
)
10601 tree fp
, fmt
, fn
= NULL_TREE
, fn_fputc
, fn_fputs
, arg
, call
;
10602 const char *fmt_str
= NULL
;
10604 /* If the return value is used, don't do the transformation. */
10608 /* Verify the required arguments in the original call. */
10611 fp
= TREE_VALUE (arglist
);
10612 if (! POINTER_TYPE_P (TREE_TYPE (fp
)))
10614 arglist
= TREE_CHAIN (arglist
);
10616 if (fcode
== BUILT_IN_FPRINTF_CHK
|| fcode
== BUILT_IN_VFPRINTF_CHK
)
10622 flag
= TREE_VALUE (arglist
);
10623 if (TREE_CODE (TREE_TYPE (flag
)) != INTEGER_TYPE
10624 || TREE_SIDE_EFFECTS (flag
))
10626 arglist
= TREE_CHAIN (arglist
);
10631 fmt
= TREE_VALUE (arglist
);
10632 if (! POINTER_TYPE_P (TREE_TYPE (fmt
)))
10634 arglist
= TREE_CHAIN (arglist
);
10636 /* Check whether the format is a literal string constant. */
10637 fmt_str
= c_getstr (fmt
);
10638 if (fmt_str
== NULL
)
10641 if (fcode
== BUILT_IN_FPRINTF_UNLOCKED
)
10643 /* If we're using an unlocked function, assume the other
10644 unlocked functions exist explicitly. */
10645 fn_fputc
= built_in_decls
[BUILT_IN_FPUTC_UNLOCKED
];
10646 fn_fputs
= built_in_decls
[BUILT_IN_FPUTS_UNLOCKED
];
10650 fn_fputc
= implicit_built_in_decls
[BUILT_IN_FPUTC
];
10651 fn_fputs
= implicit_built_in_decls
[BUILT_IN_FPUTS
];
10654 if (!init_target_chars())
10657 /* If the format doesn't contain % args or %%, use strcpy. */
10658 if (strchr (fmt_str
, target_percent
) == NULL
)
10660 if (fcode
!= BUILT_IN_VFPRINTF
&& fcode
!= BUILT_IN_VFPRINTF_CHK
10664 /* If the format specifier was "", fprintf does nothing. */
10665 if (fmt_str
[0] == '\0')
10667 /* If FP has side-effects, just wait until gimplification is
10669 if (TREE_SIDE_EFFECTS (fp
))
10672 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl
)), 0);
10675 /* When "string" doesn't contain %, replace all cases of
10676 fprintf (fp, string) with fputs (string, fp). The fputs
10677 builtin will take care of special cases like length == 1. */
10678 arglist
= build_tree_list (NULL_TREE
, fp
);
10679 arglist
= tree_cons (NULL_TREE
, fmt
, arglist
);
10683 /* The other optimizations can be done only on the non-va_list variants. */
10684 else if (fcode
== BUILT_IN_VFPRINTF
|| fcode
== BUILT_IN_VFPRINTF_CHK
)
10687 /* If the format specifier was "%s", call __builtin_fputs (arg, fp). */
10688 else if (strcmp (fmt_str
, target_percent_s
) == 0)
10691 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist
)))
10692 || TREE_CHAIN (arglist
))
10694 arg
= TREE_VALUE (arglist
);
10695 arglist
= build_tree_list (NULL_TREE
, fp
);
10696 arglist
= tree_cons (NULL_TREE
, arg
, arglist
);
10700 /* If the format specifier was "%c", call __builtin_fputc (arg, fp). */
10701 else if (strcmp (fmt_str
, target_percent_c
) == 0)
10704 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist
))) != INTEGER_TYPE
10705 || TREE_CHAIN (arglist
))
10707 arg
= TREE_VALUE (arglist
);
10708 arglist
= build_tree_list (NULL_TREE
, fp
);
10709 arglist
= tree_cons (NULL_TREE
, arg
, arglist
);
10716 call
= build_function_call_expr (fn
, arglist
);
10717 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl
)), call
);
10720 /* Initialize format string characters in the target charset. */
10723 init_target_chars (void)
10728 target_newline
= lang_hooks
.to_target_charset ('\n');
10729 target_percent
= lang_hooks
.to_target_charset ('%');
10730 target_c
= lang_hooks
.to_target_charset ('c');
10731 target_s
= lang_hooks
.to_target_charset ('s');
10732 if (target_newline
== 0 || target_percent
== 0 || target_c
== 0
10736 target_percent_c
[0] = target_percent
;
10737 target_percent_c
[1] = target_c
;
10738 target_percent_c
[2] = '\0';
10740 target_percent_s
[0] = target_percent
;
10741 target_percent_s
[1] = target_s
;
10742 target_percent_s
[2] = '\0';
10744 target_percent_s_newline
[0] = target_percent
;
10745 target_percent_s_newline
[1] = target_s
;
10746 target_percent_s_newline
[2] = target_newline
;
10747 target_percent_s_newline
[3] = '\0';