1 /* Expand builtin functions.
2 Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING. If not, write to the Free
19 Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
24 #include "coretypes.h"
30 #include "tree-gimple.h"
33 #include "hard-reg-set.h"
36 #include "insn-config.h"
42 #include "typeclass.h"
47 #include "langhooks.h"
48 #include "basic-block.h"
49 #include "tree-mudflap.h"
51 #ifndef PAD_VARARGS_DOWN
52 #define PAD_VARARGS_DOWN BYTES_BIG_ENDIAN
55 /* Define the names of the builtin function types and codes. */
56 const char *const built_in_class_names
[4]
57 = {"NOT_BUILT_IN", "BUILT_IN_FRONTEND", "BUILT_IN_MD", "BUILT_IN_NORMAL"};
59 #define DEF_BUILTIN(X, N, C, T, LT, B, F, NA, AT, IM, COND) #X,
60 const char * built_in_names
[(int) END_BUILTINS
] =
62 #include "builtins.def"
66 /* Setup an array of _DECL trees, make sure each element is
67 initialized to NULL_TREE. */
68 tree built_in_decls
[(int) END_BUILTINS
];
69 /* Declarations used when constructing the builtin implicitly in the compiler.
70 It may be NULL_TREE when this is invalid (for instance runtime is not
71 required to implement the function call in all cases). */
72 tree implicit_built_in_decls
[(int) END_BUILTINS
];
74 static int get_pointer_alignment (tree
, unsigned int);
75 static const char *c_getstr (tree
);
76 static rtx
c_readstr (const char *, enum machine_mode
);
77 static int target_char_cast (tree
, char *);
78 static rtx
get_memory_rtx (tree
, tree
);
79 static int apply_args_size (void);
80 static int apply_result_size (void);
81 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
82 static rtx
result_vector (int, rtx
);
84 static rtx
expand_builtin_setjmp (tree
, rtx
);
85 static void expand_builtin_update_setjmp_buf (rtx
);
86 static void expand_builtin_prefetch (tree
);
87 static rtx
expand_builtin_apply_args (void);
88 static rtx
expand_builtin_apply_args_1 (void);
89 static rtx
expand_builtin_apply (rtx
, rtx
, rtx
);
90 static void expand_builtin_return (rtx
);
91 static enum type_class
type_to_class (tree
);
92 static rtx
expand_builtin_classify_type (tree
);
93 static void expand_errno_check (tree
, rtx
);
94 static rtx
expand_builtin_mathfn (tree
, rtx
, rtx
);
95 static rtx
expand_builtin_mathfn_2 (tree
, rtx
, rtx
);
96 static rtx
expand_builtin_mathfn_3 (tree
, rtx
, rtx
);
97 static rtx
expand_builtin_sincos (tree
);
98 static rtx
expand_builtin_int_roundingfn (tree
, rtx
, rtx
);
99 static rtx
expand_builtin_args_info (tree
);
100 static rtx
expand_builtin_next_arg (void);
101 static rtx
expand_builtin_va_start (tree
);
102 static rtx
expand_builtin_va_end (tree
);
103 static rtx
expand_builtin_va_copy (tree
);
104 static rtx
expand_builtin_memcmp (tree
, tree
, rtx
, enum machine_mode
);
105 static rtx
expand_builtin_strcmp (tree
, rtx
, enum machine_mode
);
106 static rtx
expand_builtin_strncmp (tree
, rtx
, enum machine_mode
);
107 static rtx
builtin_memcpy_read_str (void *, HOST_WIDE_INT
, enum machine_mode
);
108 static rtx
expand_builtin_strcat (tree
, tree
, rtx
, enum machine_mode
);
109 static rtx
expand_builtin_strncat (tree
, rtx
, enum machine_mode
);
110 static rtx
expand_builtin_strspn (tree
, rtx
, enum machine_mode
);
111 static rtx
expand_builtin_strcspn (tree
, rtx
, enum machine_mode
);
112 static rtx
expand_builtin_memcpy (tree
, rtx
, enum machine_mode
);
113 static rtx
expand_builtin_mempcpy (tree
, tree
, rtx
, enum machine_mode
, int);
114 static rtx
expand_builtin_memmove (tree
, tree
, rtx
, enum machine_mode
, tree
);
115 static rtx
expand_builtin_bcopy (tree
);
116 static rtx
expand_builtin_strcpy (tree
, tree
, rtx
, enum machine_mode
);
117 static rtx
expand_builtin_stpcpy (tree
, rtx
, enum machine_mode
);
118 static rtx
builtin_strncpy_read_str (void *, HOST_WIDE_INT
, enum machine_mode
);
119 static rtx
expand_builtin_strncpy (tree
, rtx
, enum machine_mode
);
120 static rtx
builtin_memset_read_str (void *, HOST_WIDE_INT
, enum machine_mode
);
121 static rtx
builtin_memset_gen_str (void *, HOST_WIDE_INT
, enum machine_mode
);
122 static rtx
expand_builtin_memset (tree
, rtx
, enum machine_mode
, tree
);
123 static rtx
expand_builtin_bzero (tree
);
124 static rtx
expand_builtin_strlen (tree
, rtx
, enum machine_mode
);
125 static rtx
expand_builtin_strstr (tree
, tree
, rtx
, enum machine_mode
);
126 static rtx
expand_builtin_strpbrk (tree
, tree
, rtx
, enum machine_mode
);
127 static rtx
expand_builtin_strchr (tree
, tree
, rtx
, enum machine_mode
);
128 static rtx
expand_builtin_strrchr (tree
, tree
, rtx
, enum machine_mode
);
129 static rtx
expand_builtin_alloca (tree
, rtx
);
130 static rtx
expand_builtin_unop (enum machine_mode
, tree
, rtx
, rtx
, optab
);
131 static rtx
expand_builtin_frame_address (tree
, tree
);
132 static rtx
expand_builtin_fputs (tree
, rtx
, bool);
133 static rtx
expand_builtin_printf (tree
, rtx
, enum machine_mode
, bool);
134 static rtx
expand_builtin_fprintf (tree
, rtx
, enum machine_mode
, bool);
135 static rtx
expand_builtin_sprintf (tree
, rtx
, enum machine_mode
);
136 static tree
stabilize_va_list (tree
, int);
137 static rtx
expand_builtin_expect (tree
, rtx
);
138 static tree
fold_builtin_constant_p (tree
);
139 static tree
fold_builtin_classify_type (tree
);
140 static tree
fold_builtin_strlen (tree
);
141 static tree
fold_builtin_inf (tree
, int);
142 static tree
fold_builtin_nan (tree
, tree
, int);
143 static int validate_arglist (tree
, ...);
144 static bool integer_valued_real_p (tree
);
145 static tree
fold_trunc_transparent_mathfn (tree
, tree
);
146 static bool readonly_data_expr (tree
);
147 static rtx
expand_builtin_fabs (tree
, rtx
, rtx
);
148 static rtx
expand_builtin_signbit (tree
, rtx
);
149 static tree
fold_builtin_cabs (tree
, tree
);
150 static tree
fold_builtin_sqrt (tree
, tree
);
151 static tree
fold_builtin_cbrt (tree
, tree
);
152 static tree
fold_builtin_pow (tree
, tree
, tree
);
153 static tree
fold_builtin_powi (tree
, tree
, tree
);
154 static tree
fold_builtin_sin (tree
);
155 static tree
fold_builtin_cos (tree
, tree
, tree
);
156 static tree
fold_builtin_tan (tree
);
157 static tree
fold_builtin_atan (tree
, tree
);
158 static tree
fold_builtin_trunc (tree
, tree
);
159 static tree
fold_builtin_floor (tree
, tree
);
160 static tree
fold_builtin_ceil (tree
, tree
);
161 static tree
fold_builtin_round (tree
, tree
);
162 static tree
fold_builtin_int_roundingfn (tree
, tree
);
163 static tree
fold_builtin_bitop (tree
, tree
);
164 static tree
fold_builtin_memcpy (tree
, tree
);
165 static tree
fold_builtin_mempcpy (tree
, tree
, int);
166 static tree
fold_builtin_memmove (tree
, tree
);
167 static tree
fold_builtin_strchr (tree
, tree
);
168 static tree
fold_builtin_memcmp (tree
);
169 static tree
fold_builtin_strcmp (tree
);
170 static tree
fold_builtin_strncmp (tree
);
171 static tree
fold_builtin_signbit (tree
, tree
);
172 static tree
fold_builtin_copysign (tree
, tree
, tree
);
173 static tree
fold_builtin_isascii (tree
);
174 static tree
fold_builtin_toascii (tree
);
175 static tree
fold_builtin_isdigit (tree
);
176 static tree
fold_builtin_fabs (tree
, tree
);
177 static tree
fold_builtin_abs (tree
, tree
);
178 static tree
fold_builtin_unordered_cmp (tree
, tree
, enum tree_code
,
180 static tree
fold_builtin_1 (tree
, tree
, bool);
182 static tree
fold_builtin_strpbrk (tree
, tree
);
183 static tree
fold_builtin_strstr (tree
, tree
);
184 static tree
fold_builtin_strrchr (tree
, tree
);
185 static tree
fold_builtin_strcat (tree
);
186 static tree
fold_builtin_strncat (tree
);
187 static tree
fold_builtin_strspn (tree
);
188 static tree
fold_builtin_strcspn (tree
);
189 static tree
fold_builtin_sprintf (tree
, int);
191 static rtx
expand_builtin_object_size (tree
);
192 static rtx
expand_builtin_memory_chk (tree
, rtx
, enum machine_mode
,
193 enum built_in_function
);
194 static void maybe_emit_chk_warning (tree
, enum built_in_function
);
195 static void maybe_emit_sprintf_chk_warning (tree
, enum built_in_function
);
196 static tree
fold_builtin_object_size (tree
);
197 static tree
fold_builtin_strcat_chk (tree
, tree
);
198 static tree
fold_builtin_strncat_chk (tree
, tree
);
199 static tree
fold_builtin_sprintf_chk (tree
, enum built_in_function
);
200 static tree
fold_builtin_printf (tree
, tree
, bool, enum built_in_function
);
201 static tree
fold_builtin_fprintf (tree
, tree
, bool, enum built_in_function
);
202 static bool init_target_chars (void);
204 static unsigned HOST_WIDE_INT target_newline
;
205 static unsigned HOST_WIDE_INT target_percent
;
206 static unsigned HOST_WIDE_INT target_c
;
207 static unsigned HOST_WIDE_INT target_s
;
208 static char target_percent_c
[3];
209 static char target_percent_s
[3];
210 static char target_percent_s_newline
[4];
212 /* Return true if NODE should be considered for inline expansion regardless
213 of the optimization level. This means whenever a function is invoked with
214 its "internal" name, which normally contains the prefix "__builtin". */
216 static bool called_as_built_in (tree node
)
218 const char *name
= IDENTIFIER_POINTER (DECL_NAME (node
));
219 if (strncmp (name
, "__builtin_", 10) == 0)
221 if (strncmp (name
, "__sync_", 7) == 0)
226 /* Return the alignment in bits of EXP, a pointer valued expression.
227 But don't return more than MAX_ALIGN no matter what.
228 The alignment returned is, by default, the alignment of the thing that
229 EXP points to. If it is not a POINTER_TYPE, 0 is returned.
231 Otherwise, look at the expression to see if we can do better, i.e., if the
232 expression is actually pointing at an object whose alignment is tighter. */
235 get_pointer_alignment (tree exp
, unsigned int max_align
)
237 unsigned int align
, inner
;
239 if (! POINTER_TYPE_P (TREE_TYPE (exp
)))
242 align
= TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp
)));
243 align
= MIN (align
, max_align
);
247 switch (TREE_CODE (exp
))
251 case NON_LVALUE_EXPR
:
252 exp
= TREE_OPERAND (exp
, 0);
253 if (! POINTER_TYPE_P (TREE_TYPE (exp
)))
256 inner
= TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp
)));
257 align
= MIN (inner
, max_align
);
261 /* If sum of pointer + int, restrict our maximum alignment to that
262 imposed by the integer. If not, we can't do any better than
264 if (! host_integerp (TREE_OPERAND (exp
, 1), 1))
267 while (((tree_low_cst (TREE_OPERAND (exp
, 1), 1))
268 & (max_align
/ BITS_PER_UNIT
- 1))
272 exp
= TREE_OPERAND (exp
, 0);
276 /* See what we are pointing at and look at its alignment. */
277 exp
= TREE_OPERAND (exp
, 0);
278 if (TREE_CODE (exp
) == FUNCTION_DECL
)
279 align
= FUNCTION_BOUNDARY
;
280 else if (DECL_P (exp
))
281 align
= DECL_ALIGN (exp
);
282 #ifdef CONSTANT_ALIGNMENT
283 else if (CONSTANT_CLASS_P (exp
))
284 align
= CONSTANT_ALIGNMENT (exp
, align
);
286 return MIN (align
, max_align
);
294 /* Compute the length of a C string. TREE_STRING_LENGTH is not the right
295 way, because it could contain a zero byte in the middle.
296 TREE_STRING_LENGTH is the size of the character array, not the string.
298 ONLY_VALUE should be nonzero if the result is not going to be emitted
299 into the instruction stream and zero if it is going to be expanded.
300 E.g. with i++ ? "foo" : "bar", if ONLY_VALUE is nonzero, constant 3
301 is returned, otherwise NULL, since
302 len = c_strlen (src, 1); if (len) expand_expr (len, ...); would not
303 evaluate the side-effects.
305 The value returned is of type `ssizetype'.
307 Unfortunately, string_constant can't access the values of const char
308 arrays with initializers, so neither can we do so here. */
311 c_strlen (tree src
, int only_value
)
314 HOST_WIDE_INT offset
;
319 if (TREE_CODE (src
) == COND_EXPR
320 && (only_value
|| !TREE_SIDE_EFFECTS (TREE_OPERAND (src
, 0))))
324 len1
= c_strlen (TREE_OPERAND (src
, 1), only_value
);
325 len2
= c_strlen (TREE_OPERAND (src
, 2), only_value
);
326 if (tree_int_cst_equal (len1
, len2
))
330 if (TREE_CODE (src
) == COMPOUND_EXPR
331 && (only_value
|| !TREE_SIDE_EFFECTS (TREE_OPERAND (src
, 0))))
332 return c_strlen (TREE_OPERAND (src
, 1), only_value
);
334 src
= string_constant (src
, &offset_node
);
338 max
= TREE_STRING_LENGTH (src
) - 1;
339 ptr
= TREE_STRING_POINTER (src
);
341 if (offset_node
&& TREE_CODE (offset_node
) != INTEGER_CST
)
343 /* If the string has an internal zero byte (e.g., "foo\0bar"), we can't
344 compute the offset to the following null if we don't know where to
345 start searching for it. */
348 for (i
= 0; i
< max
; i
++)
352 /* We don't know the starting offset, but we do know that the string
353 has no internal zero bytes. We can assume that the offset falls
354 within the bounds of the string; otherwise, the programmer deserves
355 what he gets. Subtract the offset from the length of the string,
356 and return that. This would perhaps not be valid if we were dealing
357 with named arrays in addition to literal string constants. */
359 return size_diffop (size_int (max
), offset_node
);
362 /* We have a known offset into the string. Start searching there for
363 a null character if we can represent it as a single HOST_WIDE_INT. */
364 if (offset_node
== 0)
366 else if (! host_integerp (offset_node
, 0))
369 offset
= tree_low_cst (offset_node
, 0);
371 /* If the offset is known to be out of bounds, warn, and call strlen at
373 if (offset
< 0 || offset
> max
)
375 warning (0, "offset outside bounds of constant string");
379 /* Use strlen to search for the first zero byte. Since any strings
380 constructed with build_string will have nulls appended, we win even
381 if we get handed something like (char[4])"abcd".
383 Since OFFSET is our starting index into the string, no further
384 calculation is needed. */
385 return ssize_int (strlen (ptr
+ offset
));
388 /* Return a char pointer for a C string if it is a string constant
389 or sum of string constant and integer constant. */
396 src
= string_constant (src
, &offset_node
);
400 if (offset_node
== 0)
401 return TREE_STRING_POINTER (src
);
402 else if (!host_integerp (offset_node
, 1)
403 || compare_tree_int (offset_node
, TREE_STRING_LENGTH (src
) - 1) > 0)
406 return TREE_STRING_POINTER (src
) + tree_low_cst (offset_node
, 1);
409 /* Return a CONST_INT or CONST_DOUBLE corresponding to target reading
410 GET_MODE_BITSIZE (MODE) bits from string constant STR. */
413 c_readstr (const char *str
, enum machine_mode mode
)
419 gcc_assert (GET_MODE_CLASS (mode
) == MODE_INT
);
424 for (i
= 0; i
< GET_MODE_SIZE (mode
); i
++)
427 if (WORDS_BIG_ENDIAN
)
428 j
= GET_MODE_SIZE (mode
) - i
- 1;
429 if (BYTES_BIG_ENDIAN
!= WORDS_BIG_ENDIAN
430 && GET_MODE_SIZE (mode
) > UNITS_PER_WORD
)
431 j
= j
+ UNITS_PER_WORD
- 2 * (j
% UNITS_PER_WORD
) - 1;
433 gcc_assert (j
<= 2 * HOST_BITS_PER_WIDE_INT
);
436 ch
= (unsigned char) str
[i
];
437 c
[j
/ HOST_BITS_PER_WIDE_INT
] |= ch
<< (j
% HOST_BITS_PER_WIDE_INT
);
439 return immed_double_const (c
[0], c
[1], mode
);
442 /* Cast a target constant CST to target CHAR and if that value fits into
443 host char type, return zero and put that value into variable pointed to by
447 target_char_cast (tree cst
, char *p
)
449 unsigned HOST_WIDE_INT val
, hostval
;
451 if (!host_integerp (cst
, 1)
452 || CHAR_TYPE_SIZE
> HOST_BITS_PER_WIDE_INT
)
455 val
= tree_low_cst (cst
, 1);
456 if (CHAR_TYPE_SIZE
< HOST_BITS_PER_WIDE_INT
)
457 val
&= (((unsigned HOST_WIDE_INT
) 1) << CHAR_TYPE_SIZE
) - 1;
460 if (HOST_BITS_PER_CHAR
< HOST_BITS_PER_WIDE_INT
)
461 hostval
&= (((unsigned HOST_WIDE_INT
) 1) << HOST_BITS_PER_CHAR
) - 1;
470 /* Similar to save_expr, but assumes that arbitrary code is not executed
471 in between the multiple evaluations. In particular, we assume that a
472 non-addressable local variable will not be modified. */
475 builtin_save_expr (tree exp
)
477 if (TREE_ADDRESSABLE (exp
) == 0
478 && (TREE_CODE (exp
) == PARM_DECL
479 || (TREE_CODE (exp
) == VAR_DECL
&& !TREE_STATIC (exp
))))
482 return save_expr (exp
);
485 /* Given TEM, a pointer to a stack frame, follow the dynamic chain COUNT
486 times to get the address of either a higher stack frame, or a return
487 address located within it (depending on FNDECL_CODE). */
490 expand_builtin_return_addr (enum built_in_function fndecl_code
, int count
)
494 #ifdef INITIAL_FRAME_ADDRESS_RTX
495 rtx tem
= INITIAL_FRAME_ADDRESS_RTX
;
499 /* For a zero count, we don't care what frame address we return, so frame
500 pointer elimination is OK, and using the soft frame pointer is OK.
501 For a non-zero count, we require a stable offset from the current frame
502 pointer to the previous one, so we must use the hard frame pointer, and
503 we must disable frame pointer elimination. */
505 tem
= frame_pointer_rtx
;
508 tem
= hard_frame_pointer_rtx
;
510 /* Tell reload not to eliminate the frame pointer. */
511 current_function_accesses_prior_frames
= 1;
515 /* Some machines need special handling before we can access
516 arbitrary frames. For example, on the sparc, we must first flush
517 all register windows to the stack. */
518 #ifdef SETUP_FRAME_ADDRESSES
520 SETUP_FRAME_ADDRESSES ();
523 /* On the sparc, the return address is not in the frame, it is in a
524 register. There is no way to access it off of the current frame
525 pointer, but it can be accessed off the previous frame pointer by
526 reading the value from the register window save area. */
527 #ifdef RETURN_ADDR_IN_PREVIOUS_FRAME
528 if (fndecl_code
== BUILT_IN_RETURN_ADDRESS
)
532 /* Scan back COUNT frames to the specified frame. */
533 for (i
= 0; i
< count
; i
++)
535 /* Assume the dynamic chain pointer is in the word that the
536 frame address points to, unless otherwise specified. */
537 #ifdef DYNAMIC_CHAIN_ADDRESS
538 tem
= DYNAMIC_CHAIN_ADDRESS (tem
);
540 tem
= memory_address (Pmode
, tem
);
541 tem
= gen_frame_mem (Pmode
, tem
);
542 tem
= copy_to_reg (tem
);
545 /* For __builtin_frame_address, return what we've got. */
546 if (fndecl_code
== BUILT_IN_FRAME_ADDRESS
)
549 /* For __builtin_return_address, Get the return address from that
551 #ifdef RETURN_ADDR_RTX
552 tem
= RETURN_ADDR_RTX (count
, tem
);
554 tem
= memory_address (Pmode
,
555 plus_constant (tem
, GET_MODE_SIZE (Pmode
)));
556 tem
= gen_frame_mem (Pmode
, tem
);
561 /* Alias set used for setjmp buffer. */
562 static HOST_WIDE_INT setjmp_alias_set
= -1;
564 /* Construct the leading half of a __builtin_setjmp call. Control will
565 return to RECEIVER_LABEL. This is used directly by sjlj exception
569 expand_builtin_setjmp_setup (rtx buf_addr
, rtx receiver_label
)
571 enum machine_mode sa_mode
= STACK_SAVEAREA_MODE (SAVE_NONLOCAL
);
575 if (setjmp_alias_set
== -1)
576 setjmp_alias_set
= new_alias_set ();
578 buf_addr
= convert_memory_address (Pmode
, buf_addr
);
580 buf_addr
= force_reg (Pmode
, force_operand (buf_addr
, NULL_RTX
));
582 /* We store the frame pointer and the address of receiver_label in
583 the buffer and use the rest of it for the stack save area, which
584 is machine-dependent. */
586 mem
= gen_rtx_MEM (Pmode
, buf_addr
);
587 set_mem_alias_set (mem
, setjmp_alias_set
);
588 emit_move_insn (mem
, targetm
.builtin_setjmp_frame_value ());
590 mem
= gen_rtx_MEM (Pmode
, plus_constant (buf_addr
, GET_MODE_SIZE (Pmode
))),
591 set_mem_alias_set (mem
, setjmp_alias_set
);
593 emit_move_insn (validize_mem (mem
),
594 force_reg (Pmode
, gen_rtx_LABEL_REF (Pmode
, receiver_label
)));
596 stack_save
= gen_rtx_MEM (sa_mode
,
597 plus_constant (buf_addr
,
598 2 * GET_MODE_SIZE (Pmode
)));
599 set_mem_alias_set (stack_save
, setjmp_alias_set
);
600 emit_stack_save (SAVE_NONLOCAL
, &stack_save
, NULL_RTX
);
602 /* If there is further processing to do, do it. */
603 #ifdef HAVE_builtin_setjmp_setup
604 if (HAVE_builtin_setjmp_setup
)
605 emit_insn (gen_builtin_setjmp_setup (buf_addr
));
608 /* Tell optimize_save_area_alloca that extra work is going to
609 need to go on during alloca. */
610 current_function_calls_setjmp
= 1;
612 /* Set this so all the registers get saved in our frame; we need to be
613 able to copy the saved values for any registers from frames we unwind. */
614 current_function_has_nonlocal_label
= 1;
617 /* Construct the trailing part of a __builtin_setjmp call.
618 This is used directly by sjlj exception handling code. */
621 expand_builtin_setjmp_receiver (rtx receiver_label ATTRIBUTE_UNUSED
)
623 /* Clobber the FP when we get here, so we have to make sure it's
624 marked as used by this function. */
625 emit_insn (gen_rtx_USE (VOIDmode
, hard_frame_pointer_rtx
));
627 /* Mark the static chain as clobbered here so life information
628 doesn't get messed up for it. */
629 emit_insn (gen_rtx_CLOBBER (VOIDmode
, static_chain_rtx
));
631 /* Now put in the code to restore the frame pointer, and argument
632 pointer, if needed. */
633 #ifdef HAVE_nonlocal_goto
634 if (! HAVE_nonlocal_goto
)
636 emit_move_insn (virtual_stack_vars_rtx
, hard_frame_pointer_rtx
);
638 #if ARG_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
639 if (fixed_regs
[ARG_POINTER_REGNUM
])
641 #ifdef ELIMINABLE_REGS
643 static const struct elims
{const int from
, to
;} elim_regs
[] = ELIMINABLE_REGS
;
645 for (i
= 0; i
< ARRAY_SIZE (elim_regs
); i
++)
646 if (elim_regs
[i
].from
== ARG_POINTER_REGNUM
647 && elim_regs
[i
].to
== HARD_FRAME_POINTER_REGNUM
)
650 if (i
== ARRAY_SIZE (elim_regs
))
653 /* Now restore our arg pointer from the address at which it
654 was saved in our stack frame. */
655 emit_move_insn (virtual_incoming_args_rtx
,
656 copy_to_reg (get_arg_pointer_save_area (cfun
)));
661 #ifdef HAVE_builtin_setjmp_receiver
662 if (HAVE_builtin_setjmp_receiver
)
663 emit_insn (gen_builtin_setjmp_receiver (receiver_label
));
666 #ifdef HAVE_nonlocal_goto_receiver
667 if (HAVE_nonlocal_goto_receiver
)
668 emit_insn (gen_nonlocal_goto_receiver ());
673 /* @@@ This is a kludge. Not all machine descriptions define a blockage
674 insn, but we must not allow the code we just generated to be reordered
675 by scheduling. Specifically, the update of the frame pointer must
676 happen immediately, not later. So emit an ASM_INPUT to act as blockage
678 emit_insn (gen_rtx_ASM_INPUT (VOIDmode
, ""));
681 /* __builtin_setjmp is passed a pointer to an array of five words (not
682 all will be used on all machines). It operates similarly to the C
683 library function of the same name, but is more efficient. Much of
684 the code below (and for longjmp) is copied from the handling of
687 NOTE: This is intended for use by GNAT and the exception handling
688 scheme in the compiler and will only work in the method used by
692 expand_builtin_setjmp (tree arglist
, rtx target
)
694 rtx buf_addr
, next_lab
, cont_lab
;
696 if (!validate_arglist (arglist
, POINTER_TYPE
, VOID_TYPE
))
699 if (target
== 0 || !REG_P (target
)
700 || REGNO (target
) < FIRST_PSEUDO_REGISTER
)
701 target
= gen_reg_rtx (TYPE_MODE (integer_type_node
));
703 buf_addr
= expand_normal (TREE_VALUE (arglist
));
705 next_lab
= gen_label_rtx ();
706 cont_lab
= gen_label_rtx ();
708 expand_builtin_setjmp_setup (buf_addr
, next_lab
);
710 /* Set TARGET to zero and branch to the continue label. Use emit_jump to
711 ensure that pending stack adjustments are flushed. */
712 emit_move_insn (target
, const0_rtx
);
713 emit_jump (cont_lab
);
715 emit_label (next_lab
);
717 expand_builtin_setjmp_receiver (next_lab
);
719 /* Set TARGET to one. */
720 emit_move_insn (target
, const1_rtx
);
721 emit_label (cont_lab
);
723 /* Tell flow about the strange goings on. Putting `next_lab' on
724 `nonlocal_goto_handler_labels' to indicates that function
725 calls may traverse the arc back to this label. */
727 current_function_has_nonlocal_label
= 1;
728 nonlocal_goto_handler_labels
729 = gen_rtx_EXPR_LIST (VOIDmode
, next_lab
, nonlocal_goto_handler_labels
);
734 /* __builtin_longjmp is passed a pointer to an array of five words (not
735 all will be used on all machines). It operates similarly to the C
736 library function of the same name, but is more efficient. Much of
737 the code below is copied from the handling of non-local gotos.
739 NOTE: This is intended for use by GNAT and the exception handling
740 scheme in the compiler and will only work in the method used by
744 expand_builtin_longjmp (rtx buf_addr
, rtx value
)
746 rtx fp
, lab
, stack
, insn
, last
;
747 enum machine_mode sa_mode
= STACK_SAVEAREA_MODE (SAVE_NONLOCAL
);
749 if (setjmp_alias_set
== -1)
750 setjmp_alias_set
= new_alias_set ();
752 buf_addr
= convert_memory_address (Pmode
, buf_addr
);
754 buf_addr
= force_reg (Pmode
, buf_addr
);
756 /* We used to store value in static_chain_rtx, but that fails if pointers
757 are smaller than integers. We instead require that the user must pass
758 a second argument of 1, because that is what builtin_setjmp will
759 return. This also makes EH slightly more efficient, since we are no
760 longer copying around a value that we don't care about. */
761 gcc_assert (value
== const1_rtx
);
763 last
= get_last_insn ();
764 #ifdef HAVE_builtin_longjmp
765 if (HAVE_builtin_longjmp
)
766 emit_insn (gen_builtin_longjmp (buf_addr
));
770 fp
= gen_rtx_MEM (Pmode
, buf_addr
);
771 lab
= gen_rtx_MEM (Pmode
, plus_constant (buf_addr
,
772 GET_MODE_SIZE (Pmode
)));
774 stack
= gen_rtx_MEM (sa_mode
, plus_constant (buf_addr
,
775 2 * GET_MODE_SIZE (Pmode
)));
776 set_mem_alias_set (fp
, setjmp_alias_set
);
777 set_mem_alias_set (lab
, setjmp_alias_set
);
778 set_mem_alias_set (stack
, setjmp_alias_set
);
780 /* Pick up FP, label, and SP from the block and jump. This code is
781 from expand_goto in stmt.c; see there for detailed comments. */
782 #if HAVE_nonlocal_goto
783 if (HAVE_nonlocal_goto
)
784 /* We have to pass a value to the nonlocal_goto pattern that will
785 get copied into the static_chain pointer, but it does not matter
786 what that value is, because builtin_setjmp does not use it. */
787 emit_insn (gen_nonlocal_goto (value
, lab
, stack
, fp
));
791 lab
= copy_to_reg (lab
);
793 emit_insn (gen_rtx_CLOBBER (VOIDmode
,
794 gen_rtx_MEM (BLKmode
,
795 gen_rtx_SCRATCH (VOIDmode
))));
796 emit_insn (gen_rtx_CLOBBER (VOIDmode
,
797 gen_rtx_MEM (BLKmode
,
798 hard_frame_pointer_rtx
)));
800 emit_move_insn (hard_frame_pointer_rtx
, fp
);
801 emit_stack_restore (SAVE_NONLOCAL
, stack
, NULL_RTX
);
803 emit_insn (gen_rtx_USE (VOIDmode
, hard_frame_pointer_rtx
));
804 emit_insn (gen_rtx_USE (VOIDmode
, stack_pointer_rtx
));
805 emit_indirect_jump (lab
);
809 /* Search backwards and mark the jump insn as a non-local goto.
810 Note that this precludes the use of __builtin_longjmp to a
811 __builtin_setjmp target in the same function. However, we've
812 already cautioned the user that these functions are for
813 internal exception handling use only. */
814 for (insn
= get_last_insn (); insn
; insn
= PREV_INSN (insn
))
816 gcc_assert (insn
!= last
);
820 REG_NOTES (insn
) = alloc_EXPR_LIST (REG_NON_LOCAL_GOTO
, const0_rtx
,
824 else if (CALL_P (insn
))
829 /* Expand a call to __builtin_nonlocal_goto. We're passed the target label
830 and the address of the save area. */
833 expand_builtin_nonlocal_goto (tree arglist
)
835 tree t_label
, t_save_area
;
836 rtx r_label
, r_save_area
, r_fp
, r_sp
, insn
;
838 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
841 t_label
= TREE_VALUE (arglist
);
842 arglist
= TREE_CHAIN (arglist
);
843 t_save_area
= TREE_VALUE (arglist
);
845 r_label
= expand_normal (t_label
);
846 r_label
= convert_memory_address (Pmode
, r_label
);
847 r_save_area
= expand_normal (t_save_area
);
848 r_save_area
= convert_memory_address (Pmode
, r_save_area
);
849 r_fp
= gen_rtx_MEM (Pmode
, r_save_area
);
850 r_sp
= gen_rtx_MEM (STACK_SAVEAREA_MODE (SAVE_NONLOCAL
),
851 plus_constant (r_save_area
, GET_MODE_SIZE (Pmode
)));
853 current_function_has_nonlocal_goto
= 1;
855 #if HAVE_nonlocal_goto
856 /* ??? We no longer need to pass the static chain value, afaik. */
857 if (HAVE_nonlocal_goto
)
858 emit_insn (gen_nonlocal_goto (const0_rtx
, r_label
, r_sp
, r_fp
));
862 r_label
= copy_to_reg (r_label
);
864 emit_insn (gen_rtx_CLOBBER (VOIDmode
,
865 gen_rtx_MEM (BLKmode
,
866 gen_rtx_SCRATCH (VOIDmode
))));
868 emit_insn (gen_rtx_CLOBBER (VOIDmode
,
869 gen_rtx_MEM (BLKmode
,
870 hard_frame_pointer_rtx
)));
872 /* Restore frame pointer for containing function.
873 This sets the actual hard register used for the frame pointer
874 to the location of the function's incoming static chain info.
875 The non-local goto handler will then adjust it to contain the
876 proper value and reload the argument pointer, if needed. */
877 emit_move_insn (hard_frame_pointer_rtx
, r_fp
);
878 emit_stack_restore (SAVE_NONLOCAL
, r_sp
, NULL_RTX
);
880 /* USE of hard_frame_pointer_rtx added for consistency;
881 not clear if really needed. */
882 emit_insn (gen_rtx_USE (VOIDmode
, hard_frame_pointer_rtx
));
883 emit_insn (gen_rtx_USE (VOIDmode
, stack_pointer_rtx
));
884 emit_indirect_jump (r_label
);
887 /* Search backwards to the jump insn and mark it as a
889 for (insn
= get_last_insn (); insn
; insn
= PREV_INSN (insn
))
893 REG_NOTES (insn
) = alloc_EXPR_LIST (REG_NON_LOCAL_GOTO
,
894 const0_rtx
, REG_NOTES (insn
));
897 else if (CALL_P (insn
))
904 /* __builtin_update_setjmp_buf is passed a pointer to an array of five words
905 (not all will be used on all machines) that was passed to __builtin_setjmp.
906 It updates the stack pointer in that block to correspond to the current
910 expand_builtin_update_setjmp_buf (rtx buf_addr
)
912 enum machine_mode sa_mode
= Pmode
;
916 #ifdef HAVE_save_stack_nonlocal
917 if (HAVE_save_stack_nonlocal
)
918 sa_mode
= insn_data
[(int) CODE_FOR_save_stack_nonlocal
].operand
[0].mode
;
920 #ifdef STACK_SAVEAREA_MODE
921 sa_mode
= STACK_SAVEAREA_MODE (SAVE_NONLOCAL
);
925 = gen_rtx_MEM (sa_mode
,
928 plus_constant (buf_addr
, 2 * GET_MODE_SIZE (Pmode
))));
932 emit_insn (gen_setjmp ());
935 emit_stack_save (SAVE_NONLOCAL
, &stack_save
, NULL_RTX
);
938 /* Expand a call to __builtin_prefetch. For a target that does not support
939 data prefetch, evaluate the memory address argument in case it has side
943 expand_builtin_prefetch (tree arglist
)
945 tree arg0
, arg1
, arg2
;
948 if (!validate_arglist (arglist
, POINTER_TYPE
, 0))
951 arg0
= TREE_VALUE (arglist
);
952 /* Arguments 1 and 2 are optional; argument 1 (read/write) defaults to
953 zero (read) and argument 2 (locality) defaults to 3 (high degree of
955 if (TREE_CHAIN (arglist
))
957 arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
958 if (TREE_CHAIN (TREE_CHAIN (arglist
)))
959 arg2
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
961 arg2
= build_int_cst (NULL_TREE
, 3);
965 arg1
= integer_zero_node
;
966 arg2
= build_int_cst (NULL_TREE
, 3);
969 /* Argument 0 is an address. */
970 op0
= expand_expr (arg0
, NULL_RTX
, Pmode
, EXPAND_NORMAL
);
972 /* Argument 1 (read/write flag) must be a compile-time constant int. */
973 if (TREE_CODE (arg1
) != INTEGER_CST
)
975 error ("second argument to %<__builtin_prefetch%> must be a constant");
976 arg1
= integer_zero_node
;
978 op1
= expand_normal (arg1
);
979 /* Argument 1 must be either zero or one. */
980 if (INTVAL (op1
) != 0 && INTVAL (op1
) != 1)
982 warning (0, "invalid second argument to %<__builtin_prefetch%>;"
987 /* Argument 2 (locality) must be a compile-time constant int. */
988 if (TREE_CODE (arg2
) != INTEGER_CST
)
990 error ("third argument to %<__builtin_prefetch%> must be a constant");
991 arg2
= integer_zero_node
;
993 op2
= expand_normal (arg2
);
994 /* Argument 2 must be 0, 1, 2, or 3. */
995 if (INTVAL (op2
) < 0 || INTVAL (op2
) > 3)
997 warning (0, "invalid third argument to %<__builtin_prefetch%>; using zero");
1001 #ifdef HAVE_prefetch
1004 if ((! (*insn_data
[(int) CODE_FOR_prefetch
].operand
[0].predicate
)
1006 insn_data
[(int) CODE_FOR_prefetch
].operand
[0].mode
))
1007 || (GET_MODE (op0
) != Pmode
))
1009 op0
= convert_memory_address (Pmode
, op0
);
1010 op0
= force_reg (Pmode
, op0
);
1012 emit_insn (gen_prefetch (op0
, op1
, op2
));
1016 /* Don't do anything with direct references to volatile memory, but
1017 generate code to handle other side effects. */
1018 if (!MEM_P (op0
) && side_effects_p (op0
))
1022 /* Get a MEM rtx for expression EXP which is the address of an operand
1023 to be used in a string instruction (cmpstrsi, movmemsi, ..). LEN is
1024 the maximum length of the block of memory that might be accessed or
1028 get_memory_rtx (tree exp
, tree len
)
1030 rtx addr
= expand_expr (exp
, NULL_RTX
, ptr_mode
, EXPAND_NORMAL
);
1031 rtx mem
= gen_rtx_MEM (BLKmode
, memory_address (BLKmode
, addr
));
1033 /* Get an expression we can use to find the attributes to assign to MEM.
1034 If it is an ADDR_EXPR, use the operand. Otherwise, dereference it if
1035 we can. First remove any nops. */
1036 while ((TREE_CODE (exp
) == NOP_EXPR
|| TREE_CODE (exp
) == CONVERT_EXPR
1037 || TREE_CODE (exp
) == NON_LVALUE_EXPR
)
1038 && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (exp
, 0))))
1039 exp
= TREE_OPERAND (exp
, 0);
1041 if (TREE_CODE (exp
) == ADDR_EXPR
)
1042 exp
= TREE_OPERAND (exp
, 0);
1043 else if (POINTER_TYPE_P (TREE_TYPE (exp
)))
1044 exp
= build1 (INDIRECT_REF
, TREE_TYPE (TREE_TYPE (exp
)), exp
);
1048 /* Honor attributes derived from exp, except for the alias set
1049 (as builtin stringops may alias with anything) and the size
1050 (as stringops may access multiple array elements). */
1053 set_mem_attributes (mem
, exp
, 0);
1055 /* Allow the string and memory builtins to overflow from one
1056 field into another, see http://gcc.gnu.org/PR23561.
1057 Thus avoid COMPONENT_REFs in MEM_EXPR unless we know the whole
1058 memory accessed by the string or memory builtin will fit
1059 within the field. */
1060 if (MEM_EXPR (mem
) && TREE_CODE (MEM_EXPR (mem
)) == COMPONENT_REF
)
1062 tree mem_expr
= MEM_EXPR (mem
);
1063 HOST_WIDE_INT offset
= -1, length
= -1;
1066 while (TREE_CODE (inner
) == ARRAY_REF
1067 || TREE_CODE (inner
) == NOP_EXPR
1068 || TREE_CODE (inner
) == CONVERT_EXPR
1069 || TREE_CODE (inner
) == NON_LVALUE_EXPR
1070 || TREE_CODE (inner
) == VIEW_CONVERT_EXPR
1071 || TREE_CODE (inner
) == SAVE_EXPR
)
1072 inner
= TREE_OPERAND (inner
, 0);
1074 gcc_assert (TREE_CODE (inner
) == COMPONENT_REF
);
1076 if (MEM_OFFSET (mem
)
1077 && GET_CODE (MEM_OFFSET (mem
)) == CONST_INT
)
1078 offset
= INTVAL (MEM_OFFSET (mem
));
1080 if (offset
>= 0 && len
&& host_integerp (len
, 0))
1081 length
= tree_low_cst (len
, 0);
1083 while (TREE_CODE (inner
) == COMPONENT_REF
)
1085 tree field
= TREE_OPERAND (inner
, 1);
1086 gcc_assert (! DECL_BIT_FIELD (field
));
1087 gcc_assert (TREE_CODE (mem_expr
) == COMPONENT_REF
);
1088 gcc_assert (field
== TREE_OPERAND (mem_expr
, 1));
1091 && TYPE_SIZE_UNIT (TREE_TYPE (inner
))
1092 && host_integerp (TYPE_SIZE_UNIT (TREE_TYPE (inner
)), 0))
1095 = tree_low_cst (TYPE_SIZE_UNIT (TREE_TYPE (inner
)), 0);
1096 /* If we can prove the memory starting at XEXP (mem, 0)
1097 and ending at XEXP (mem, 0) + LENGTH will fit into
1098 this field, we can keep that COMPONENT_REF in MEM_EXPR. */
1101 && offset
+ length
<= size
)
1106 && host_integerp (DECL_FIELD_OFFSET (field
), 0))
1107 offset
+= tree_low_cst (DECL_FIELD_OFFSET (field
), 0)
1108 + tree_low_cst (DECL_FIELD_BIT_OFFSET (field
), 1)
1116 mem_expr
= TREE_OPERAND (mem_expr
, 0);
1117 inner
= TREE_OPERAND (inner
, 0);
1120 if (mem_expr
== NULL
)
1122 if (mem_expr
!= MEM_EXPR (mem
))
1124 set_mem_expr (mem
, mem_expr
);
1125 set_mem_offset (mem
, offset
>= 0 ? GEN_INT (offset
) : NULL_RTX
);
1128 set_mem_alias_set (mem
, 0);
1129 set_mem_size (mem
, NULL_RTX
);
1135 /* Built-in functions to perform an untyped call and return. */
1137 /* For each register that may be used for calling a function, this
1138 gives a mode used to copy the register's value. VOIDmode indicates
1139 the register is not used for calling a function. If the machine
1140 has register windows, this gives only the outbound registers.
1141 INCOMING_REGNO gives the corresponding inbound register. */
1142 static enum machine_mode apply_args_mode
[FIRST_PSEUDO_REGISTER
];
1144 /* For each register that may be used for returning values, this gives
1145 a mode used to copy the register's value. VOIDmode indicates the
1146 register is not used for returning values. If the machine has
1147 register windows, this gives only the outbound registers.
1148 INCOMING_REGNO gives the corresponding inbound register. */
1149 static enum machine_mode apply_result_mode
[FIRST_PSEUDO_REGISTER
];
1151 /* For each register that may be used for calling a function, this
1152 gives the offset of that register into the block returned by
1153 __builtin_apply_args. 0 indicates that the register is not
1154 used for calling a function. */
1155 static int apply_args_reg_offset
[FIRST_PSEUDO_REGISTER
];
1157 /* Return the size required for the block returned by __builtin_apply_args,
1158 and initialize apply_args_mode. */
1161 apply_args_size (void)
1163 static int size
= -1;
1166 enum machine_mode mode
;
1168 /* The values computed by this function never change. */
1171 /* The first value is the incoming arg-pointer. */
1172 size
= GET_MODE_SIZE (Pmode
);
1174 /* The second value is the structure value address unless this is
1175 passed as an "invisible" first argument. */
1176 if (targetm
.calls
.struct_value_rtx (cfun
? TREE_TYPE (cfun
->decl
) : 0, 0))
1177 size
+= GET_MODE_SIZE (Pmode
);
1179 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
1180 if (FUNCTION_ARG_REGNO_P (regno
))
1182 mode
= reg_raw_mode
[regno
];
1184 gcc_assert (mode
!= VOIDmode
);
1186 align
= GET_MODE_ALIGNMENT (mode
) / BITS_PER_UNIT
;
1187 if (size
% align
!= 0)
1188 size
= CEIL (size
, align
) * align
;
1189 apply_args_reg_offset
[regno
] = size
;
1190 size
+= GET_MODE_SIZE (mode
);
1191 apply_args_mode
[regno
] = mode
;
1195 apply_args_mode
[regno
] = VOIDmode
;
1196 apply_args_reg_offset
[regno
] = 0;
1202 /* Return the size required for the block returned by __builtin_apply,
1203 and initialize apply_result_mode. */
1206 apply_result_size (void)
1208 static int size
= -1;
1210 enum machine_mode mode
;
1212 /* The values computed by this function never change. */
1217 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
1218 if (FUNCTION_VALUE_REGNO_P (regno
))
1220 mode
= reg_raw_mode
[regno
];
1222 gcc_assert (mode
!= VOIDmode
);
1224 align
= GET_MODE_ALIGNMENT (mode
) / BITS_PER_UNIT
;
1225 if (size
% align
!= 0)
1226 size
= CEIL (size
, align
) * align
;
1227 size
+= GET_MODE_SIZE (mode
);
1228 apply_result_mode
[regno
] = mode
;
1231 apply_result_mode
[regno
] = VOIDmode
;
1233 /* Allow targets that use untyped_call and untyped_return to override
1234 the size so that machine-specific information can be stored here. */
1235 #ifdef APPLY_RESULT_SIZE
1236 size
= APPLY_RESULT_SIZE
;
1242 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
1243 /* Create a vector describing the result block RESULT. If SAVEP is true,
1244 the result block is used to save the values; otherwise it is used to
1245 restore the values. */
1248 result_vector (int savep
, rtx result
)
1250 int regno
, size
, align
, nelts
;
1251 enum machine_mode mode
;
1253 rtx
*savevec
= alloca (FIRST_PSEUDO_REGISTER
* sizeof (rtx
));
1256 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
1257 if ((mode
= apply_result_mode
[regno
]) != VOIDmode
)
1259 align
= GET_MODE_ALIGNMENT (mode
) / BITS_PER_UNIT
;
1260 if (size
% align
!= 0)
1261 size
= CEIL (size
, align
) * align
;
1262 reg
= gen_rtx_REG (mode
, savep
? regno
: INCOMING_REGNO (regno
));
1263 mem
= adjust_address (result
, mode
, size
);
1264 savevec
[nelts
++] = (savep
1265 ? gen_rtx_SET (VOIDmode
, mem
, reg
)
1266 : gen_rtx_SET (VOIDmode
, reg
, mem
));
1267 size
+= GET_MODE_SIZE (mode
);
1269 return gen_rtx_PARALLEL (VOIDmode
, gen_rtvec_v (nelts
, savevec
));
1271 #endif /* HAVE_untyped_call or HAVE_untyped_return */
1273 /* Save the state required to perform an untyped call with the same
1274 arguments as were passed to the current function. */
1277 expand_builtin_apply_args_1 (void)
1280 int size
, align
, regno
;
1281 enum machine_mode mode
;
1282 rtx struct_incoming_value
= targetm
.calls
.struct_value_rtx (cfun
? TREE_TYPE (cfun
->decl
) : 0, 1);
1284 /* Create a block where the arg-pointer, structure value address,
1285 and argument registers can be saved. */
1286 registers
= assign_stack_local (BLKmode
, apply_args_size (), -1);
1288 /* Walk past the arg-pointer and structure value address. */
1289 size
= GET_MODE_SIZE (Pmode
);
1290 if (targetm
.calls
.struct_value_rtx (cfun
? TREE_TYPE (cfun
->decl
) : 0, 0))
1291 size
+= GET_MODE_SIZE (Pmode
);
1293 /* Save each register used in calling a function to the block. */
1294 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
1295 if ((mode
= apply_args_mode
[regno
]) != VOIDmode
)
1297 align
= GET_MODE_ALIGNMENT (mode
) / BITS_PER_UNIT
;
1298 if (size
% align
!= 0)
1299 size
= CEIL (size
, align
) * align
;
1301 tem
= gen_rtx_REG (mode
, INCOMING_REGNO (regno
));
1303 emit_move_insn (adjust_address (registers
, mode
, size
), tem
);
1304 size
+= GET_MODE_SIZE (mode
);
1307 /* Save the arg pointer to the block. */
1308 tem
= copy_to_reg (virtual_incoming_args_rtx
);
1309 #ifdef STACK_GROWS_DOWNWARD
1310 /* We need the pointer as the caller actually passed them to us, not
1311 as we might have pretended they were passed. Make sure it's a valid
1312 operand, as emit_move_insn isn't expected to handle a PLUS. */
1314 = force_operand (plus_constant (tem
, current_function_pretend_args_size
),
1317 emit_move_insn (adjust_address (registers
, Pmode
, 0), tem
);
1319 size
= GET_MODE_SIZE (Pmode
);
1321 /* Save the structure value address unless this is passed as an
1322 "invisible" first argument. */
1323 if (struct_incoming_value
)
1325 emit_move_insn (adjust_address (registers
, Pmode
, size
),
1326 copy_to_reg (struct_incoming_value
));
1327 size
+= GET_MODE_SIZE (Pmode
);
1330 /* Return the address of the block. */
1331 return copy_addr_to_reg (XEXP (registers
, 0));
1334 /* __builtin_apply_args returns block of memory allocated on
1335 the stack into which is stored the arg pointer, structure
1336 value address, static chain, and all the registers that might
1337 possibly be used in performing a function call. The code is
1338 moved to the start of the function so the incoming values are
1342 expand_builtin_apply_args (void)
1344 /* Don't do __builtin_apply_args more than once in a function.
1345 Save the result of the first call and reuse it. */
1346 if (apply_args_value
!= 0)
1347 return apply_args_value
;
1349 /* When this function is called, it means that registers must be
1350 saved on entry to this function. So we migrate the
1351 call to the first insn of this function. */
1356 temp
= expand_builtin_apply_args_1 ();
1360 apply_args_value
= temp
;
1362 /* Put the insns after the NOTE that starts the function.
1363 If this is inside a start_sequence, make the outer-level insn
1364 chain current, so the code is placed at the start of the
1366 push_topmost_sequence ();
1367 emit_insn_before (seq
, NEXT_INSN (entry_of_function ()));
1368 pop_topmost_sequence ();
1373 /* Perform an untyped call and save the state required to perform an
1374 untyped return of whatever value was returned by the given function. */
1377 expand_builtin_apply (rtx function
, rtx arguments
, rtx argsize
)
1379 int size
, align
, regno
;
1380 enum machine_mode mode
;
1381 rtx incoming_args
, result
, reg
, dest
, src
, call_insn
;
1382 rtx old_stack_level
= 0;
1383 rtx call_fusage
= 0;
1384 rtx struct_value
= targetm
.calls
.struct_value_rtx (cfun
? TREE_TYPE (cfun
->decl
) : 0, 0);
1386 arguments
= convert_memory_address (Pmode
, arguments
);
1388 /* Create a block where the return registers can be saved. */
1389 result
= assign_stack_local (BLKmode
, apply_result_size (), -1);
1391 /* Fetch the arg pointer from the ARGUMENTS block. */
1392 incoming_args
= gen_reg_rtx (Pmode
);
1393 emit_move_insn (incoming_args
, gen_rtx_MEM (Pmode
, arguments
));
1394 #ifndef STACK_GROWS_DOWNWARD
1395 incoming_args
= expand_simple_binop (Pmode
, MINUS
, incoming_args
, argsize
,
1396 incoming_args
, 0, OPTAB_LIB_WIDEN
);
1399 /* Push a new argument block and copy the arguments. Do not allow
1400 the (potential) memcpy call below to interfere with our stack
1402 do_pending_stack_adjust ();
1405 /* Save the stack with nonlocal if available. */
1406 #ifdef HAVE_save_stack_nonlocal
1407 if (HAVE_save_stack_nonlocal
)
1408 emit_stack_save (SAVE_NONLOCAL
, &old_stack_level
, NULL_RTX
);
1411 emit_stack_save (SAVE_BLOCK
, &old_stack_level
, NULL_RTX
);
1413 /* Allocate a block of memory onto the stack and copy the memory
1414 arguments to the outgoing arguments address. */
1415 allocate_dynamic_stack_space (argsize
, 0, BITS_PER_UNIT
);
1416 dest
= virtual_outgoing_args_rtx
;
1417 #ifndef STACK_GROWS_DOWNWARD
1418 if (GET_CODE (argsize
) == CONST_INT
)
1419 dest
= plus_constant (dest
, -INTVAL (argsize
));
1421 dest
= gen_rtx_PLUS (Pmode
, dest
, negate_rtx (Pmode
, argsize
));
1423 dest
= gen_rtx_MEM (BLKmode
, dest
);
1424 set_mem_align (dest
, PARM_BOUNDARY
);
1425 src
= gen_rtx_MEM (BLKmode
, incoming_args
);
1426 set_mem_align (src
, PARM_BOUNDARY
);
1427 emit_block_move (dest
, src
, argsize
, BLOCK_OP_NORMAL
);
1429 /* Refer to the argument block. */
1431 arguments
= gen_rtx_MEM (BLKmode
, arguments
);
1432 set_mem_align (arguments
, PARM_BOUNDARY
);
1434 /* Walk past the arg-pointer and structure value address. */
1435 size
= GET_MODE_SIZE (Pmode
);
1437 size
+= GET_MODE_SIZE (Pmode
);
1439 /* Restore each of the registers previously saved. Make USE insns
1440 for each of these registers for use in making the call. */
1441 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
1442 if ((mode
= apply_args_mode
[regno
]) != VOIDmode
)
1444 align
= GET_MODE_ALIGNMENT (mode
) / BITS_PER_UNIT
;
1445 if (size
% align
!= 0)
1446 size
= CEIL (size
, align
) * align
;
1447 reg
= gen_rtx_REG (mode
, regno
);
1448 emit_move_insn (reg
, adjust_address (arguments
, mode
, size
));
1449 use_reg (&call_fusage
, reg
);
1450 size
+= GET_MODE_SIZE (mode
);
1453 /* Restore the structure value address unless this is passed as an
1454 "invisible" first argument. */
1455 size
= GET_MODE_SIZE (Pmode
);
1458 rtx value
= gen_reg_rtx (Pmode
);
1459 emit_move_insn (value
, adjust_address (arguments
, Pmode
, size
));
1460 emit_move_insn (struct_value
, value
);
1461 if (REG_P (struct_value
))
1462 use_reg (&call_fusage
, struct_value
);
1463 size
+= GET_MODE_SIZE (Pmode
);
1466 /* All arguments and registers used for the call are set up by now! */
1467 function
= prepare_call_address (function
, NULL
, &call_fusage
, 0, 0);
1469 /* Ensure address is valid. SYMBOL_REF is already valid, so no need,
1470 and we don't want to load it into a register as an optimization,
1471 because prepare_call_address already did it if it should be done. */
1472 if (GET_CODE (function
) != SYMBOL_REF
)
1473 function
= memory_address (FUNCTION_MODE
, function
);
1475 /* Generate the actual call instruction and save the return value. */
1476 #ifdef HAVE_untyped_call
1477 if (HAVE_untyped_call
)
1478 emit_call_insn (gen_untyped_call (gen_rtx_MEM (FUNCTION_MODE
, function
),
1479 result
, result_vector (1, result
)));
1482 #ifdef HAVE_call_value
1483 if (HAVE_call_value
)
1487 /* Locate the unique return register. It is not possible to
1488 express a call that sets more than one return register using
1489 call_value; use untyped_call for that. In fact, untyped_call
1490 only needs to save the return registers in the given block. */
1491 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
1492 if ((mode
= apply_result_mode
[regno
]) != VOIDmode
)
1494 gcc_assert (!valreg
); /* HAVE_untyped_call required. */
1496 valreg
= gen_rtx_REG (mode
, regno
);
1499 emit_call_insn (GEN_CALL_VALUE (valreg
,
1500 gen_rtx_MEM (FUNCTION_MODE
, function
),
1501 const0_rtx
, NULL_RTX
, const0_rtx
));
1503 emit_move_insn (adjust_address (result
, GET_MODE (valreg
), 0), valreg
);
1509 /* Find the CALL insn we just emitted, and attach the register usage
1511 call_insn
= last_call_insn ();
1512 add_function_usage_to (call_insn
, call_fusage
);
1514 /* Restore the stack. */
1515 #ifdef HAVE_save_stack_nonlocal
1516 if (HAVE_save_stack_nonlocal
)
1517 emit_stack_restore (SAVE_NONLOCAL
, old_stack_level
, NULL_RTX
);
1520 emit_stack_restore (SAVE_BLOCK
, old_stack_level
, NULL_RTX
);
1524 /* Return the address of the result block. */
1525 result
= copy_addr_to_reg (XEXP (result
, 0));
1526 return convert_memory_address (ptr_mode
, result
);
1529 /* Perform an untyped return. */
1532 expand_builtin_return (rtx result
)
1534 int size
, align
, regno
;
1535 enum machine_mode mode
;
1537 rtx call_fusage
= 0;
1539 result
= convert_memory_address (Pmode
, result
);
1541 apply_result_size ();
1542 result
= gen_rtx_MEM (BLKmode
, result
);
1544 #ifdef HAVE_untyped_return
1545 if (HAVE_untyped_return
)
1547 emit_jump_insn (gen_untyped_return (result
, result_vector (0, result
)));
1553 /* Restore the return value and note that each value is used. */
1555 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
1556 if ((mode
= apply_result_mode
[regno
]) != VOIDmode
)
1558 align
= GET_MODE_ALIGNMENT (mode
) / BITS_PER_UNIT
;
1559 if (size
% align
!= 0)
1560 size
= CEIL (size
, align
) * align
;
1561 reg
= gen_rtx_REG (mode
, INCOMING_REGNO (regno
));
1562 emit_move_insn (reg
, adjust_address (result
, mode
, size
));
1564 push_to_sequence (call_fusage
);
1565 emit_insn (gen_rtx_USE (VOIDmode
, reg
));
1566 call_fusage
= get_insns ();
1568 size
+= GET_MODE_SIZE (mode
);
1571 /* Put the USE insns before the return. */
1572 emit_insn (call_fusage
);
1574 /* Return whatever values was restored by jumping directly to the end
1576 expand_naked_return ();
1579 /* Used by expand_builtin_classify_type and fold_builtin_classify_type. */
1581 static enum type_class
1582 type_to_class (tree type
)
1584 switch (TREE_CODE (type
))
1586 case VOID_TYPE
: return void_type_class
;
1587 case INTEGER_TYPE
: return integer_type_class
;
1588 case ENUMERAL_TYPE
: return enumeral_type_class
;
1589 case BOOLEAN_TYPE
: return boolean_type_class
;
1590 case POINTER_TYPE
: return pointer_type_class
;
1591 case REFERENCE_TYPE
: return reference_type_class
;
1592 case OFFSET_TYPE
: return offset_type_class
;
1593 case REAL_TYPE
: return real_type_class
;
1594 case COMPLEX_TYPE
: return complex_type_class
;
1595 case FUNCTION_TYPE
: return function_type_class
;
1596 case METHOD_TYPE
: return method_type_class
;
1597 case RECORD_TYPE
: return record_type_class
;
1599 case QUAL_UNION_TYPE
: return union_type_class
;
1600 case ARRAY_TYPE
: return (TYPE_STRING_FLAG (type
)
1601 ? string_type_class
: array_type_class
);
1602 case LANG_TYPE
: return lang_type_class
;
1603 default: return no_type_class
;
1607 /* Expand a call to __builtin_classify_type with arguments found in
1611 expand_builtin_classify_type (tree arglist
)
1614 return GEN_INT (type_to_class (TREE_TYPE (TREE_VALUE (arglist
))));
1615 return GEN_INT (no_type_class
);
1618 /* This helper macro, meant to be used in mathfn_built_in below,
1619 determines which among a set of three builtin math functions is
1620 appropriate for a given type mode. The `F' and `L' cases are
1621 automatically generated from the `double' case. */
1622 #define CASE_MATHFN(BUILT_IN_MATHFN) \
1623 case BUILT_IN_MATHFN: case BUILT_IN_MATHFN##F: case BUILT_IN_MATHFN##L: \
1624 fcode = BUILT_IN_MATHFN; fcodef = BUILT_IN_MATHFN##F ; \
1625 fcodel = BUILT_IN_MATHFN##L ; break;
1627 /* Return mathematic function equivalent to FN but operating directly
1628 on TYPE, if available. If we can't do the conversion, return zero. */
1630 mathfn_built_in (tree type
, enum built_in_function fn
)
1632 enum built_in_function fcode
, fcodef
, fcodel
;
1636 CASE_MATHFN (BUILT_IN_ACOS
)
1637 CASE_MATHFN (BUILT_IN_ACOSH
)
1638 CASE_MATHFN (BUILT_IN_ASIN
)
1639 CASE_MATHFN (BUILT_IN_ASINH
)
1640 CASE_MATHFN (BUILT_IN_ATAN
)
1641 CASE_MATHFN (BUILT_IN_ATAN2
)
1642 CASE_MATHFN (BUILT_IN_ATANH
)
1643 CASE_MATHFN (BUILT_IN_CBRT
)
1644 CASE_MATHFN (BUILT_IN_CEIL
)
1645 CASE_MATHFN (BUILT_IN_COPYSIGN
)
1646 CASE_MATHFN (BUILT_IN_COS
)
1647 CASE_MATHFN (BUILT_IN_COSH
)
1648 CASE_MATHFN (BUILT_IN_DREM
)
1649 CASE_MATHFN (BUILT_IN_ERF
)
1650 CASE_MATHFN (BUILT_IN_ERFC
)
1651 CASE_MATHFN (BUILT_IN_EXP
)
1652 CASE_MATHFN (BUILT_IN_EXP10
)
1653 CASE_MATHFN (BUILT_IN_EXP2
)
1654 CASE_MATHFN (BUILT_IN_EXPM1
)
1655 CASE_MATHFN (BUILT_IN_FABS
)
1656 CASE_MATHFN (BUILT_IN_FDIM
)
1657 CASE_MATHFN (BUILT_IN_FLOOR
)
1658 CASE_MATHFN (BUILT_IN_FMA
)
1659 CASE_MATHFN (BUILT_IN_FMAX
)
1660 CASE_MATHFN (BUILT_IN_FMIN
)
1661 CASE_MATHFN (BUILT_IN_FMOD
)
1662 CASE_MATHFN (BUILT_IN_FREXP
)
1663 CASE_MATHFN (BUILT_IN_GAMMA
)
1664 CASE_MATHFN (BUILT_IN_HUGE_VAL
)
1665 CASE_MATHFN (BUILT_IN_HYPOT
)
1666 CASE_MATHFN (BUILT_IN_ILOGB
)
1667 CASE_MATHFN (BUILT_IN_INF
)
1668 CASE_MATHFN (BUILT_IN_J0
)
1669 CASE_MATHFN (BUILT_IN_J1
)
1670 CASE_MATHFN (BUILT_IN_JN
)
1671 CASE_MATHFN (BUILT_IN_LCEIL
)
1672 CASE_MATHFN (BUILT_IN_LDEXP
)
1673 CASE_MATHFN (BUILT_IN_LFLOOR
)
1674 CASE_MATHFN (BUILT_IN_LGAMMA
)
1675 CASE_MATHFN (BUILT_IN_LLCEIL
)
1676 CASE_MATHFN (BUILT_IN_LLFLOOR
)
1677 CASE_MATHFN (BUILT_IN_LLRINT
)
1678 CASE_MATHFN (BUILT_IN_LLROUND
)
1679 CASE_MATHFN (BUILT_IN_LOG
)
1680 CASE_MATHFN (BUILT_IN_LOG10
)
1681 CASE_MATHFN (BUILT_IN_LOG1P
)
1682 CASE_MATHFN (BUILT_IN_LOG2
)
1683 CASE_MATHFN (BUILT_IN_LOGB
)
1684 CASE_MATHFN (BUILT_IN_LRINT
)
1685 CASE_MATHFN (BUILT_IN_LROUND
)
1686 CASE_MATHFN (BUILT_IN_MODF
)
1687 CASE_MATHFN (BUILT_IN_NAN
)
1688 CASE_MATHFN (BUILT_IN_NANS
)
1689 CASE_MATHFN (BUILT_IN_NEARBYINT
)
1690 CASE_MATHFN (BUILT_IN_NEXTAFTER
)
1691 CASE_MATHFN (BUILT_IN_NEXTTOWARD
)
1692 CASE_MATHFN (BUILT_IN_POW
)
1693 CASE_MATHFN (BUILT_IN_POWI
)
1694 CASE_MATHFN (BUILT_IN_POW10
)
1695 CASE_MATHFN (BUILT_IN_REMAINDER
)
1696 CASE_MATHFN (BUILT_IN_REMQUO
)
1697 CASE_MATHFN (BUILT_IN_RINT
)
1698 CASE_MATHFN (BUILT_IN_ROUND
)
1699 CASE_MATHFN (BUILT_IN_SCALB
)
1700 CASE_MATHFN (BUILT_IN_SCALBLN
)
1701 CASE_MATHFN (BUILT_IN_SCALBN
)
1702 CASE_MATHFN (BUILT_IN_SIGNIFICAND
)
1703 CASE_MATHFN (BUILT_IN_SIN
)
1704 CASE_MATHFN (BUILT_IN_SINCOS
)
1705 CASE_MATHFN (BUILT_IN_SINH
)
1706 CASE_MATHFN (BUILT_IN_SQRT
)
1707 CASE_MATHFN (BUILT_IN_TAN
)
1708 CASE_MATHFN (BUILT_IN_TANH
)
1709 CASE_MATHFN (BUILT_IN_TGAMMA
)
1710 CASE_MATHFN (BUILT_IN_TRUNC
)
1711 CASE_MATHFN (BUILT_IN_Y0
)
1712 CASE_MATHFN (BUILT_IN_Y1
)
1713 CASE_MATHFN (BUILT_IN_YN
)
1719 if (TYPE_MAIN_VARIANT (type
) == double_type_node
)
1720 return implicit_built_in_decls
[fcode
];
1721 else if (TYPE_MAIN_VARIANT (type
) == float_type_node
)
1722 return implicit_built_in_decls
[fcodef
];
1723 else if (TYPE_MAIN_VARIANT (type
) == long_double_type_node
)
1724 return implicit_built_in_decls
[fcodel
];
1729 /* If errno must be maintained, expand the RTL to check if the result,
1730 TARGET, of a built-in function call, EXP, is NaN, and if so set
1734 expand_errno_check (tree exp
, rtx target
)
1736 rtx lab
= gen_label_rtx ();
1738 /* Test the result; if it is NaN, set errno=EDOM because
1739 the argument was not in the domain. */
1740 emit_cmp_and_jump_insns (target
, target
, EQ
, 0, GET_MODE (target
),
1744 /* If this built-in doesn't throw an exception, set errno directly. */
1745 if (TREE_NOTHROW (TREE_OPERAND (TREE_OPERAND (exp
, 0), 0)))
1747 #ifdef GEN_ERRNO_RTX
1748 rtx errno_rtx
= GEN_ERRNO_RTX
;
1751 = gen_rtx_MEM (word_mode
, gen_rtx_SYMBOL_REF (Pmode
, "errno"));
1753 emit_move_insn (errno_rtx
, GEN_INT (TARGET_EDOM
));
1759 /* We can't set errno=EDOM directly; let the library call do it.
1760 Pop the arguments right away in case the call gets deleted. */
1762 expand_call (exp
, target
, 0);
1768 /* Expand a call to one of the builtin math functions (sqrt, exp, or log).
1769 Return 0 if a normal call should be emitted rather than expanding the
1770 function in-line. EXP is the expression that is a call to the builtin
1771 function; if convenient, the result should be placed in TARGET.
1772 SUBTARGET may be used as the target for computing one of EXP's operands. */
1775 expand_builtin_mathfn (tree exp
, rtx target
, rtx subtarget
)
1777 optab builtin_optab
;
1778 rtx op0
, insns
, before_call
;
1779 tree fndecl
= get_callee_fndecl (exp
);
1780 tree arglist
= TREE_OPERAND (exp
, 1);
1781 enum machine_mode mode
;
1782 bool errno_set
= false;
1785 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
1788 arg
= TREE_VALUE (arglist
);
1790 switch (DECL_FUNCTION_CODE (fndecl
))
1792 CASE_FLT_FN (BUILT_IN_SQRT
):
1793 errno_set
= ! tree_expr_nonnegative_p (arg
);
1794 builtin_optab
= sqrt_optab
;
1796 CASE_FLT_FN (BUILT_IN_EXP
):
1797 errno_set
= true; builtin_optab
= exp_optab
; break;
1798 CASE_FLT_FN (BUILT_IN_EXP10
):
1799 CASE_FLT_FN (BUILT_IN_POW10
):
1800 errno_set
= true; builtin_optab
= exp10_optab
; break;
1801 CASE_FLT_FN (BUILT_IN_EXP2
):
1802 errno_set
= true; builtin_optab
= exp2_optab
; break;
1803 CASE_FLT_FN (BUILT_IN_EXPM1
):
1804 errno_set
= true; builtin_optab
= expm1_optab
; break;
1805 CASE_FLT_FN (BUILT_IN_LOGB
):
1806 errno_set
= true; builtin_optab
= logb_optab
; break;
1807 CASE_FLT_FN (BUILT_IN_ILOGB
):
1808 errno_set
= true; builtin_optab
= ilogb_optab
; break;
1809 CASE_FLT_FN (BUILT_IN_LOG
):
1810 errno_set
= true; builtin_optab
= log_optab
; break;
1811 CASE_FLT_FN (BUILT_IN_LOG10
):
1812 errno_set
= true; builtin_optab
= log10_optab
; break;
1813 CASE_FLT_FN (BUILT_IN_LOG2
):
1814 errno_set
= true; builtin_optab
= log2_optab
; break;
1815 CASE_FLT_FN (BUILT_IN_LOG1P
):
1816 errno_set
= true; builtin_optab
= log1p_optab
; break;
1817 CASE_FLT_FN (BUILT_IN_ASIN
):
1818 builtin_optab
= asin_optab
; break;
1819 CASE_FLT_FN (BUILT_IN_ACOS
):
1820 builtin_optab
= acos_optab
; break;
1821 CASE_FLT_FN (BUILT_IN_TAN
):
1822 builtin_optab
= tan_optab
; break;
1823 CASE_FLT_FN (BUILT_IN_ATAN
):
1824 builtin_optab
= atan_optab
; break;
1825 CASE_FLT_FN (BUILT_IN_FLOOR
):
1826 builtin_optab
= floor_optab
; break;
1827 CASE_FLT_FN (BUILT_IN_CEIL
):
1828 builtin_optab
= ceil_optab
; break;
1829 CASE_FLT_FN (BUILT_IN_TRUNC
):
1830 builtin_optab
= btrunc_optab
; break;
1831 CASE_FLT_FN (BUILT_IN_ROUND
):
1832 builtin_optab
= round_optab
; break;
1833 CASE_FLT_FN (BUILT_IN_NEARBYINT
):
1834 builtin_optab
= nearbyint_optab
; break;
1835 CASE_FLT_FN (BUILT_IN_RINT
):
1836 builtin_optab
= rint_optab
; break;
1837 CASE_FLT_FN (BUILT_IN_LRINT
):
1838 CASE_FLT_FN (BUILT_IN_LLRINT
):
1839 builtin_optab
= lrint_optab
; break;
1844 /* Make a suitable register to place result in. */
1845 mode
= TYPE_MODE (TREE_TYPE (exp
));
1847 if (! flag_errno_math
|| ! HONOR_NANS (mode
))
1850 /* Before working hard, check whether the instruction is available. */
1851 if (builtin_optab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
)
1853 target
= gen_reg_rtx (mode
);
1855 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
1856 need to expand the argument again. This way, we will not perform
1857 side-effects more the once. */
1858 narg
= builtin_save_expr (arg
);
1862 arglist
= build_tree_list (NULL_TREE
, arg
);
1863 exp
= build_function_call_expr (fndecl
, arglist
);
1866 op0
= expand_expr (arg
, subtarget
, VOIDmode
, 0);
1870 /* Compute into TARGET.
1871 Set TARGET to wherever the result comes back. */
1872 target
= expand_unop (mode
, builtin_optab
, op0
, target
, 0);
1877 expand_errno_check (exp
, target
);
1879 /* Output the entire sequence. */
1880 insns
= get_insns ();
1886 /* If we were unable to expand via the builtin, stop the sequence
1887 (without outputting the insns) and call to the library function
1888 with the stabilized argument list. */
1892 before_call
= get_last_insn ();
1894 target
= expand_call (exp
, target
, target
== const0_rtx
);
1896 /* If this is a sqrt operation and we don't care about errno, try to
1897 attach a REG_EQUAL note with a SQRT rtx to the emitted libcall.
1898 This allows the semantics of the libcall to be visible to the RTL
1900 if (builtin_optab
== sqrt_optab
&& !errno_set
)
1902 /* Search backwards through the insns emitted by expand_call looking
1903 for the instruction with the REG_RETVAL note. */
1904 rtx last
= get_last_insn ();
1905 while (last
!= before_call
)
1907 if (find_reg_note (last
, REG_RETVAL
, NULL
))
1909 rtx note
= find_reg_note (last
, REG_EQUAL
, NULL
);
1910 /* Check that the REQ_EQUAL note is an EXPR_LIST with
1911 two elements, i.e. symbol_ref(sqrt) and the operand. */
1913 && GET_CODE (note
) == EXPR_LIST
1914 && GET_CODE (XEXP (note
, 0)) == EXPR_LIST
1915 && XEXP (XEXP (note
, 0), 1) != NULL_RTX
1916 && XEXP (XEXP (XEXP (note
, 0), 1), 1) == NULL_RTX
)
1918 rtx operand
= XEXP (XEXP (XEXP (note
, 0), 1), 0);
1919 /* Check operand is a register with expected mode. */
1922 && GET_MODE (operand
) == mode
)
1924 /* Replace the REG_EQUAL note with a SQRT rtx. */
1925 rtx equiv
= gen_rtx_SQRT (mode
, operand
);
1926 set_unique_reg_note (last
, REG_EQUAL
, equiv
);
1931 last
= PREV_INSN (last
);
1938 /* Expand a call to the builtin binary math functions (pow and atan2).
1939 Return 0 if a normal call should be emitted rather than expanding the
1940 function in-line. EXP is the expression that is a call to the builtin
1941 function; if convenient, the result should be placed in TARGET.
1942 SUBTARGET may be used as the target for computing one of EXP's
1946 expand_builtin_mathfn_2 (tree exp
, rtx target
, rtx subtarget
)
1948 optab builtin_optab
;
1949 rtx op0
, op1
, insns
;
1950 int op1_type
= REAL_TYPE
;
1951 tree fndecl
= get_callee_fndecl (exp
);
1952 tree arglist
= TREE_OPERAND (exp
, 1);
1953 tree arg0
, arg1
, temp
, narg
;
1954 enum machine_mode mode
;
1955 bool errno_set
= true;
1958 if ((DECL_FUNCTION_CODE (fndecl
) == BUILT_IN_LDEXP
)
1959 || (DECL_FUNCTION_CODE (fndecl
) == BUILT_IN_LDEXPF
)
1960 || (DECL_FUNCTION_CODE (fndecl
) == BUILT_IN_LDEXPL
))
1961 op1_type
= INTEGER_TYPE
;
1963 if (!validate_arglist (arglist
, REAL_TYPE
, op1_type
, VOID_TYPE
))
1966 arg0
= TREE_VALUE (arglist
);
1967 arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
1969 switch (DECL_FUNCTION_CODE (fndecl
))
1971 CASE_FLT_FN (BUILT_IN_POW
):
1972 builtin_optab
= pow_optab
; break;
1973 CASE_FLT_FN (BUILT_IN_ATAN2
):
1974 builtin_optab
= atan2_optab
; break;
1975 CASE_FLT_FN (BUILT_IN_LDEXP
):
1976 builtin_optab
= ldexp_optab
; break;
1977 CASE_FLT_FN (BUILT_IN_FMOD
):
1978 builtin_optab
= fmod_optab
; break;
1979 CASE_FLT_FN (BUILT_IN_DREM
):
1980 builtin_optab
= drem_optab
; break;
1985 /* Make a suitable register to place result in. */
1986 mode
= TYPE_MODE (TREE_TYPE (exp
));
1988 /* Before working hard, check whether the instruction is available. */
1989 if (builtin_optab
->handlers
[(int) mode
].insn_code
== CODE_FOR_nothing
)
1992 target
= gen_reg_rtx (mode
);
1994 if (! flag_errno_math
|| ! HONOR_NANS (mode
))
1997 /* Always stabilize the argument list. */
1998 narg
= builtin_save_expr (arg1
);
2002 temp
= build_tree_list (NULL_TREE
, narg
);
2006 temp
= TREE_CHAIN (arglist
);
2008 narg
= builtin_save_expr (arg0
);
2012 arglist
= tree_cons (NULL_TREE
, narg
, temp
);
2016 arglist
= tree_cons (NULL_TREE
, arg0
, temp
);
2019 exp
= build_function_call_expr (fndecl
, arglist
);
2021 op0
= expand_expr (arg0
, subtarget
, VOIDmode
, EXPAND_NORMAL
);
2022 op1
= expand_normal (arg1
);
2026 /* Compute into TARGET.
2027 Set TARGET to wherever the result comes back. */
2028 target
= expand_binop (mode
, builtin_optab
, op0
, op1
,
2029 target
, 0, OPTAB_DIRECT
);
2031 /* If we were unable to expand via the builtin, stop the sequence
2032 (without outputting the insns) and call to the library function
2033 with the stabilized argument list. */
2037 return expand_call (exp
, target
, target
== const0_rtx
);
2041 expand_errno_check (exp
, target
);
2043 /* Output the entire sequence. */
2044 insns
= get_insns ();
2051 /* Expand a call to the builtin sin and cos math functions.
2052 Return 0 if a normal call should be emitted rather than expanding the
2053 function in-line. EXP is the expression that is a call to the builtin
2054 function; if convenient, the result should be placed in TARGET.
2055 SUBTARGET may be used as the target for computing one of EXP's
2059 expand_builtin_mathfn_3 (tree exp
, rtx target
, rtx subtarget
)
2061 optab builtin_optab
;
2063 tree fndecl
= get_callee_fndecl (exp
);
2064 tree arglist
= TREE_OPERAND (exp
, 1);
2065 enum machine_mode mode
;
2068 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
2071 arg
= TREE_VALUE (arglist
);
2073 switch (DECL_FUNCTION_CODE (fndecl
))
2075 CASE_FLT_FN (BUILT_IN_SIN
):
2076 CASE_FLT_FN (BUILT_IN_COS
):
2077 builtin_optab
= sincos_optab
; break;
2082 /* Make a suitable register to place result in. */
2083 mode
= TYPE_MODE (TREE_TYPE (exp
));
2085 /* Check if sincos insn is available, otherwise fallback
2086 to sin or cos insn. */
2087 if (builtin_optab
->handlers
[(int) mode
].insn_code
== CODE_FOR_nothing
) {
2088 switch (DECL_FUNCTION_CODE (fndecl
))
2090 CASE_FLT_FN (BUILT_IN_SIN
):
2091 builtin_optab
= sin_optab
; break;
2092 CASE_FLT_FN (BUILT_IN_COS
):
2093 builtin_optab
= cos_optab
; break;
2099 /* Before working hard, check whether the instruction is available. */
2100 if (builtin_optab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
)
2102 target
= gen_reg_rtx (mode
);
2104 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2105 need to expand the argument again. This way, we will not perform
2106 side-effects more the once. */
2107 narg
= save_expr (arg
);
2111 arglist
= build_tree_list (NULL_TREE
, arg
);
2112 exp
= build_function_call_expr (fndecl
, arglist
);
2115 op0
= expand_expr (arg
, subtarget
, VOIDmode
, 0);
2119 /* Compute into TARGET.
2120 Set TARGET to wherever the result comes back. */
2121 if (builtin_optab
== sincos_optab
)
2125 switch (DECL_FUNCTION_CODE (fndecl
))
2127 CASE_FLT_FN (BUILT_IN_SIN
):
2128 result
= expand_twoval_unop (builtin_optab
, op0
, 0, target
, 0);
2130 CASE_FLT_FN (BUILT_IN_COS
):
2131 result
= expand_twoval_unop (builtin_optab
, op0
, target
, 0, 0);
2136 gcc_assert (result
);
2140 target
= expand_unop (mode
, builtin_optab
, op0
, target
, 0);
2145 /* Output the entire sequence. */
2146 insns
= get_insns ();
2152 /* If we were unable to expand via the builtin, stop the sequence
2153 (without outputting the insns) and call to the library function
2154 with the stabilized argument list. */
2158 target
= expand_call (exp
, target
, target
== const0_rtx
);
2163 /* Expand a call to the builtin sincos math function.
2164 Return 0 if a normal call should be emitted rather than expanding the
2165 function in-line. EXP is the expression that is a call to the builtin
2169 expand_builtin_sincos (tree exp
)
2171 rtx op0
, op1
, op2
, target1
, target2
;
2172 tree arglist
= TREE_OPERAND (exp
, 1);
2173 enum machine_mode mode
;
2174 tree arg
, sinp
, cosp
;
2177 if (!validate_arglist (arglist
, REAL_TYPE
,
2178 POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
2181 arg
= TREE_VALUE (arglist
);
2182 sinp
= TREE_VALUE (TREE_CHAIN (arglist
));
2183 cosp
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
2185 /* Make a suitable register to place result in. */
2186 mode
= TYPE_MODE (TREE_TYPE (arg
));
2188 /* Check if sincos insn is available, otherwise emit the call. */
2189 if (sincos_optab
->handlers
[(int) mode
].insn_code
== CODE_FOR_nothing
)
2192 target1
= gen_reg_rtx (mode
);
2193 target2
= gen_reg_rtx (mode
);
2195 op0
= expand_normal (arg
);
2196 op1
= expand_normal (build_fold_indirect_ref (sinp
));
2197 op2
= expand_normal (build_fold_indirect_ref (cosp
));
2199 /* Compute into target1 and target2.
2200 Set TARGET to wherever the result comes back. */
2201 result
= expand_twoval_unop (sincos_optab
, op0
, target2
, target1
, 0);
2202 gcc_assert (result
);
2204 /* Move target1 and target2 to the memory locations indicated
2206 emit_move_insn (op1
, target1
);
2207 emit_move_insn (op2
, target2
);
2212 /* Expand a call to one of the builtin rounding functions (lfloor).
2213 If expanding via optab fails, lower expression to (int)(floor(x)).
2214 EXP is the expression that is a call to the builtin function;
2215 if convenient, the result should be placed in TARGET. SUBTARGET may
2216 be used as the target for computing one of EXP's operands. */
2219 expand_builtin_int_roundingfn (tree exp
, rtx target
, rtx subtarget
)
2221 optab builtin_optab
;
2222 rtx op0
, insns
, tmp
;
2223 tree fndecl
= get_callee_fndecl (exp
);
2224 tree arglist
= TREE_OPERAND (exp
, 1);
2225 enum built_in_function fallback_fn
;
2226 tree fallback_fndecl
;
2227 enum machine_mode mode
;
2230 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
2233 arg
= TREE_VALUE (arglist
);
2235 switch (DECL_FUNCTION_CODE (fndecl
))
2237 CASE_FLT_FN (BUILT_IN_LCEIL
):
2238 CASE_FLT_FN (BUILT_IN_LLCEIL
):
2239 builtin_optab
= lceil_optab
;
2240 fallback_fn
= BUILT_IN_CEIL
;
2243 CASE_FLT_FN (BUILT_IN_LFLOOR
):
2244 CASE_FLT_FN (BUILT_IN_LLFLOOR
):
2245 builtin_optab
= lfloor_optab
;
2246 fallback_fn
= BUILT_IN_FLOOR
;
2253 /* Make a suitable register to place result in. */
2254 mode
= TYPE_MODE (TREE_TYPE (exp
));
2256 /* Before working hard, check whether the instruction is available. */
2257 if (builtin_optab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
)
2259 target
= gen_reg_rtx (mode
);
2261 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2262 need to expand the argument again. This way, we will not perform
2263 side-effects more the once. */
2264 narg
= builtin_save_expr (arg
);
2268 arglist
= build_tree_list (NULL_TREE
, arg
);
2269 exp
= build_function_call_expr (fndecl
, arglist
);
2272 op0
= expand_expr (arg
, subtarget
, VOIDmode
, 0);
2276 /* Compute into TARGET.
2277 Set TARGET to wherever the result comes back. */
2278 target
= expand_unop (mode
, builtin_optab
, op0
, target
, 0);
2282 /* Output the entire sequence. */
2283 insns
= get_insns ();
2289 /* If we were unable to expand via the builtin, stop the sequence
2290 (without outputting the insns). */
2294 /* Fall back to floating point rounding optab. */
2295 fallback_fndecl
= mathfn_built_in (TREE_TYPE (arg
), fallback_fn
);
2296 /* We shouldn't get here on targets without TARGET_C99_FUNCTIONS.
2297 ??? Perhaps convert (int)floorf(x) into (int)floor((double)x). */
2298 gcc_assert (fallback_fndecl
!= NULL_TREE
);
2299 exp
= build_function_call_expr (fallback_fndecl
, arglist
);
2301 tmp
= expand_builtin_mathfn (exp
, NULL_RTX
, NULL_RTX
);
2303 /* Truncate the result of floating point optab to integer
2304 via expand_fix (). */
2305 target
= gen_reg_rtx (mode
);
2306 expand_fix (target
, tmp
, 0);
2311 /* To evaluate powi(x,n), the floating point value x raised to the
2312 constant integer exponent n, we use a hybrid algorithm that
2313 combines the "window method" with look-up tables. For an
2314 introduction to exponentiation algorithms and "addition chains",
2315 see section 4.6.3, "Evaluation of Powers" of Donald E. Knuth,
2316 "Seminumerical Algorithms", Vol. 2, "The Art of Computer Programming",
2317 3rd Edition, 1998, and Daniel M. Gordon, "A Survey of Fast Exponentiation
2318 Methods", Journal of Algorithms, Vol. 27, pp. 129-146, 1998. */
2320 /* Provide a default value for POWI_MAX_MULTS, the maximum number of
2321 multiplications to inline before calling the system library's pow
2322 function. powi(x,n) requires at worst 2*bits(n)-2 multiplications,
2323 so this default never requires calling pow, powf or powl. */
2325 #ifndef POWI_MAX_MULTS
2326 #define POWI_MAX_MULTS (2*HOST_BITS_PER_WIDE_INT-2)
2329 /* The size of the "optimal power tree" lookup table. All
2330 exponents less than this value are simply looked up in the
2331 powi_table below. This threshold is also used to size the
2332 cache of pseudo registers that hold intermediate results. */
2333 #define POWI_TABLE_SIZE 256
2335 /* The size, in bits of the window, used in the "window method"
2336 exponentiation algorithm. This is equivalent to a radix of
2337 (1<<POWI_WINDOW_SIZE) in the corresponding "m-ary method". */
2338 #define POWI_WINDOW_SIZE 3
2340 /* The following table is an efficient representation of an
2341 "optimal power tree". For each value, i, the corresponding
2342 value, j, in the table states than an optimal evaluation
2343 sequence for calculating pow(x,i) can be found by evaluating
2344 pow(x,j)*pow(x,i-j). An optimal power tree for the first
2345 100 integers is given in Knuth's "Seminumerical algorithms". */
2347 static const unsigned char powi_table
[POWI_TABLE_SIZE
] =
2349 0, 1, 1, 2, 2, 3, 3, 4, /* 0 - 7 */
2350 4, 6, 5, 6, 6, 10, 7, 9, /* 8 - 15 */
2351 8, 16, 9, 16, 10, 12, 11, 13, /* 16 - 23 */
2352 12, 17, 13, 18, 14, 24, 15, 26, /* 24 - 31 */
2353 16, 17, 17, 19, 18, 33, 19, 26, /* 32 - 39 */
2354 20, 25, 21, 40, 22, 27, 23, 44, /* 40 - 47 */
2355 24, 32, 25, 34, 26, 29, 27, 44, /* 48 - 55 */
2356 28, 31, 29, 34, 30, 60, 31, 36, /* 56 - 63 */
2357 32, 64, 33, 34, 34, 46, 35, 37, /* 64 - 71 */
2358 36, 65, 37, 50, 38, 48, 39, 69, /* 72 - 79 */
2359 40, 49, 41, 43, 42, 51, 43, 58, /* 80 - 87 */
2360 44, 64, 45, 47, 46, 59, 47, 76, /* 88 - 95 */
2361 48, 65, 49, 66, 50, 67, 51, 66, /* 96 - 103 */
2362 52, 70, 53, 74, 54, 104, 55, 74, /* 104 - 111 */
2363 56, 64, 57, 69, 58, 78, 59, 68, /* 112 - 119 */
2364 60, 61, 61, 80, 62, 75, 63, 68, /* 120 - 127 */
2365 64, 65, 65, 128, 66, 129, 67, 90, /* 128 - 135 */
2366 68, 73, 69, 131, 70, 94, 71, 88, /* 136 - 143 */
2367 72, 128, 73, 98, 74, 132, 75, 121, /* 144 - 151 */
2368 76, 102, 77, 124, 78, 132, 79, 106, /* 152 - 159 */
2369 80, 97, 81, 160, 82, 99, 83, 134, /* 160 - 167 */
2370 84, 86, 85, 95, 86, 160, 87, 100, /* 168 - 175 */
2371 88, 113, 89, 98, 90, 107, 91, 122, /* 176 - 183 */
2372 92, 111, 93, 102, 94, 126, 95, 150, /* 184 - 191 */
2373 96, 128, 97, 130, 98, 133, 99, 195, /* 192 - 199 */
2374 100, 128, 101, 123, 102, 164, 103, 138, /* 200 - 207 */
2375 104, 145, 105, 146, 106, 109, 107, 149, /* 208 - 215 */
2376 108, 200, 109, 146, 110, 170, 111, 157, /* 216 - 223 */
2377 112, 128, 113, 130, 114, 182, 115, 132, /* 224 - 231 */
2378 116, 200, 117, 132, 118, 158, 119, 206, /* 232 - 239 */
2379 120, 240, 121, 162, 122, 147, 123, 152, /* 240 - 247 */
2380 124, 166, 125, 214, 126, 138, 127, 153, /* 248 - 255 */
2384 /* Return the number of multiplications required to calculate
2385 powi(x,n) where n is less than POWI_TABLE_SIZE. This is a
2386 subroutine of powi_cost. CACHE is an array indicating
2387 which exponents have already been calculated. */
2390 powi_lookup_cost (unsigned HOST_WIDE_INT n
, bool *cache
)
2392 /* If we've already calculated this exponent, then this evaluation
2393 doesn't require any additional multiplications. */
2398 return powi_lookup_cost (n
- powi_table
[n
], cache
)
2399 + powi_lookup_cost (powi_table
[n
], cache
) + 1;
2402 /* Return the number of multiplications required to calculate
2403 powi(x,n) for an arbitrary x, given the exponent N. This
2404 function needs to be kept in sync with expand_powi below. */
2407 powi_cost (HOST_WIDE_INT n
)
2409 bool cache
[POWI_TABLE_SIZE
];
2410 unsigned HOST_WIDE_INT digit
;
2411 unsigned HOST_WIDE_INT val
;
2417 /* Ignore the reciprocal when calculating the cost. */
2418 val
= (n
< 0) ? -n
: n
;
2420 /* Initialize the exponent cache. */
2421 memset (cache
, 0, POWI_TABLE_SIZE
* sizeof (bool));
2426 while (val
>= POWI_TABLE_SIZE
)
2430 digit
= val
& ((1 << POWI_WINDOW_SIZE
) - 1);
2431 result
+= powi_lookup_cost (digit
, cache
)
2432 + POWI_WINDOW_SIZE
+ 1;
2433 val
>>= POWI_WINDOW_SIZE
;
2442 return result
+ powi_lookup_cost (val
, cache
);
2445 /* Recursive subroutine of expand_powi. This function takes the array,
2446 CACHE, of already calculated exponents and an exponent N and returns
2447 an RTX that corresponds to CACHE[1]**N, as calculated in mode MODE. */
2450 expand_powi_1 (enum machine_mode mode
, unsigned HOST_WIDE_INT n
, rtx
*cache
)
2452 unsigned HOST_WIDE_INT digit
;
2456 if (n
< POWI_TABLE_SIZE
)
2461 target
= gen_reg_rtx (mode
);
2464 op0
= expand_powi_1 (mode
, n
- powi_table
[n
], cache
);
2465 op1
= expand_powi_1 (mode
, powi_table
[n
], cache
);
2469 target
= gen_reg_rtx (mode
);
2470 digit
= n
& ((1 << POWI_WINDOW_SIZE
) - 1);
2471 op0
= expand_powi_1 (mode
, n
- digit
, cache
);
2472 op1
= expand_powi_1 (mode
, digit
, cache
);
2476 target
= gen_reg_rtx (mode
);
2477 op0
= expand_powi_1 (mode
, n
>> 1, cache
);
2481 result
= expand_mult (mode
, op0
, op1
, target
, 0);
2482 if (result
!= target
)
2483 emit_move_insn (target
, result
);
2487 /* Expand the RTL to evaluate powi(x,n) in mode MODE. X is the
2488 floating point operand in mode MODE, and N is the exponent. This
2489 function needs to be kept in sync with powi_cost above. */
2492 expand_powi (rtx x
, enum machine_mode mode
, HOST_WIDE_INT n
)
2494 unsigned HOST_WIDE_INT val
;
2495 rtx cache
[POWI_TABLE_SIZE
];
2499 return CONST1_RTX (mode
);
2501 val
= (n
< 0) ? -n
: n
;
2503 memset (cache
, 0, sizeof (cache
));
2506 result
= expand_powi_1 (mode
, (n
< 0) ? -n
: n
, cache
);
2508 /* If the original exponent was negative, reciprocate the result. */
2510 result
= expand_binop (mode
, sdiv_optab
, CONST1_RTX (mode
),
2511 result
, NULL_RTX
, 0, OPTAB_LIB_WIDEN
);
2516 /* Expand a call to the pow built-in mathematical function. Return 0 if
2517 a normal call should be emitted rather than expanding the function
2518 in-line. EXP is the expression that is a call to the builtin
2519 function; if convenient, the result should be placed in TARGET. */
2522 expand_builtin_pow (tree exp
, rtx target
, rtx subtarget
)
2524 tree arglist
= TREE_OPERAND (exp
, 1);
2527 if (! validate_arglist (arglist
, REAL_TYPE
, REAL_TYPE
, VOID_TYPE
))
2530 arg0
= TREE_VALUE (arglist
);
2531 arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
2533 if (TREE_CODE (arg1
) == REAL_CST
2534 && ! TREE_CONSTANT_OVERFLOW (arg1
))
2536 REAL_VALUE_TYPE cint
;
2540 c
= TREE_REAL_CST (arg1
);
2541 n
= real_to_integer (&c
);
2542 real_from_integer (&cint
, VOIDmode
, n
, n
< 0 ? -1 : 0, 0);
2543 if (real_identical (&c
, &cint
))
2545 /* If the exponent is -1, 0, 1 or 2, then expand_powi is exact.
2546 Otherwise, check the number of multiplications required.
2547 Note that pow never sets errno for an integer exponent. */
2548 if ((n
>= -1 && n
<= 2)
2549 || (flag_unsafe_math_optimizations
2551 && powi_cost (n
) <= POWI_MAX_MULTS
))
2553 enum machine_mode mode
= TYPE_MODE (TREE_TYPE (exp
));
2554 rtx op
= expand_expr (arg0
, subtarget
, VOIDmode
, 0);
2555 op
= force_reg (mode
, op
);
2556 return expand_powi (op
, mode
, n
);
2561 if (! flag_unsafe_math_optimizations
)
2563 return expand_builtin_mathfn_2 (exp
, target
, subtarget
);
2566 /* Expand a call to the powi built-in mathematical function. Return 0 if
2567 a normal call should be emitted rather than expanding the function
2568 in-line. EXP is the expression that is a call to the builtin
2569 function; if convenient, the result should be placed in TARGET. */
2572 expand_builtin_powi (tree exp
, rtx target
, rtx subtarget
)
2574 tree arglist
= TREE_OPERAND (exp
, 1);
2577 enum machine_mode mode
;
2578 enum machine_mode mode2
;
2580 if (! validate_arglist (arglist
, REAL_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
2583 arg0
= TREE_VALUE (arglist
);
2584 arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
2585 mode
= TYPE_MODE (TREE_TYPE (exp
));
2587 /* Handle constant power. */
2589 if (TREE_CODE (arg1
) == INTEGER_CST
2590 && ! TREE_CONSTANT_OVERFLOW (arg1
))
2592 HOST_WIDE_INT n
= TREE_INT_CST_LOW (arg1
);
2594 /* If the exponent is -1, 0, 1 or 2, then expand_powi is exact.
2595 Otherwise, check the number of multiplications required. */
2596 if ((TREE_INT_CST_HIGH (arg1
) == 0
2597 || TREE_INT_CST_HIGH (arg1
) == -1)
2598 && ((n
>= -1 && n
<= 2)
2600 && powi_cost (n
) <= POWI_MAX_MULTS
)))
2602 op0
= expand_expr (arg0
, subtarget
, VOIDmode
, 0);
2603 op0
= force_reg (mode
, op0
);
2604 return expand_powi (op0
, mode
, n
);
2608 /* Emit a libcall to libgcc. */
2610 /* Mode of the 2nd argument must match that of an int. */
2611 mode2
= mode_for_size (INT_TYPE_SIZE
, MODE_INT
, 0);
2613 if (target
== NULL_RTX
)
2614 target
= gen_reg_rtx (mode
);
2616 op0
= expand_expr (arg0
, subtarget
, mode
, 0);
2617 if (GET_MODE (op0
) != mode
)
2618 op0
= convert_to_mode (mode
, op0
, 0);
2619 op1
= expand_expr (arg1
, 0, mode2
, 0);
2620 if (GET_MODE (op1
) != mode2
)
2621 op1
= convert_to_mode (mode2
, op1
, 0);
2623 target
= emit_library_call_value (powi_optab
->handlers
[(int) mode
].libfunc
,
2624 target
, LCT_CONST_MAKE_BLOCK
, mode
, 2,
2625 op0
, mode
, op1
, mode2
);
2630 /* Expand expression EXP which is a call to the strlen builtin. Return 0
2631 if we failed the caller should emit a normal call, otherwise
2632 try to get the result in TARGET, if convenient. */
2635 expand_builtin_strlen (tree arglist
, rtx target
,
2636 enum machine_mode target_mode
)
2638 if (!validate_arglist (arglist
, POINTER_TYPE
, VOID_TYPE
))
2643 tree len
, src
= TREE_VALUE (arglist
);
2644 rtx result
, src_reg
, char_rtx
, before_strlen
;
2645 enum machine_mode insn_mode
= target_mode
, char_mode
;
2646 enum insn_code icode
= CODE_FOR_nothing
;
2649 /* If the length can be computed at compile-time, return it. */
2650 len
= c_strlen (src
, 0);
2652 return expand_expr (len
, target
, target_mode
, EXPAND_NORMAL
);
2654 /* If the length can be computed at compile-time and is constant
2655 integer, but there are side-effects in src, evaluate
2656 src for side-effects, then return len.
2657 E.g. x = strlen (i++ ? "xfoo" + 1 : "bar");
2658 can be optimized into: i++; x = 3; */
2659 len
= c_strlen (src
, 1);
2660 if (len
&& TREE_CODE (len
) == INTEGER_CST
)
2662 expand_expr (src
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
2663 return expand_expr (len
, target
, target_mode
, EXPAND_NORMAL
);
2666 align
= get_pointer_alignment (src
, BIGGEST_ALIGNMENT
) / BITS_PER_UNIT
;
2668 /* If SRC is not a pointer type, don't do this operation inline. */
2672 /* Bail out if we can't compute strlen in the right mode. */
2673 while (insn_mode
!= VOIDmode
)
2675 icode
= strlen_optab
->handlers
[(int) insn_mode
].insn_code
;
2676 if (icode
!= CODE_FOR_nothing
)
2679 insn_mode
= GET_MODE_WIDER_MODE (insn_mode
);
2681 if (insn_mode
== VOIDmode
)
2684 /* Make a place to write the result of the instruction. */
2688 && GET_MODE (result
) == insn_mode
2689 && REGNO (result
) >= FIRST_PSEUDO_REGISTER
))
2690 result
= gen_reg_rtx (insn_mode
);
2692 /* Make a place to hold the source address. We will not expand
2693 the actual source until we are sure that the expansion will
2694 not fail -- there are trees that cannot be expanded twice. */
2695 src_reg
= gen_reg_rtx (Pmode
);
2697 /* Mark the beginning of the strlen sequence so we can emit the
2698 source operand later. */
2699 before_strlen
= get_last_insn ();
2701 char_rtx
= const0_rtx
;
2702 char_mode
= insn_data
[(int) icode
].operand
[2].mode
;
2703 if (! (*insn_data
[(int) icode
].operand
[2].predicate
) (char_rtx
,
2705 char_rtx
= copy_to_mode_reg (char_mode
, char_rtx
);
2707 pat
= GEN_FCN (icode
) (result
, gen_rtx_MEM (BLKmode
, src_reg
),
2708 char_rtx
, GEN_INT (align
));
2713 /* Now that we are assured of success, expand the source. */
2715 pat
= expand_expr (src
, src_reg
, ptr_mode
, EXPAND_NORMAL
);
2717 emit_move_insn (src_reg
, pat
);
2722 emit_insn_after (pat
, before_strlen
);
2724 emit_insn_before (pat
, get_insns ());
2726 /* Return the value in the proper mode for this function. */
2727 if (GET_MODE (result
) == target_mode
)
2729 else if (target
!= 0)
2730 convert_move (target
, result
, 0);
2732 target
= convert_to_mode (target_mode
, result
, 0);
2738 /* Expand a call to the strstr builtin. Return 0 if we failed the
2739 caller should emit a normal call, otherwise try to get the result
2740 in TARGET, if convenient (and in mode MODE if that's convenient). */
2743 expand_builtin_strstr (tree arglist
, tree type
, rtx target
, enum machine_mode mode
)
2745 if (validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
2747 tree result
= fold_builtin_strstr (arglist
, type
);
2749 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
2754 /* Expand a call to the strchr builtin. Return 0 if we failed the
2755 caller should emit a normal call, otherwise try to get the result
2756 in TARGET, if convenient (and in mode MODE if that's convenient). */
2759 expand_builtin_strchr (tree arglist
, tree type
, rtx target
, enum machine_mode mode
)
2761 if (validate_arglist (arglist
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
2763 tree result
= fold_builtin_strchr (arglist
, type
);
2765 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
2767 /* FIXME: Should use strchrM optab so that ports can optimize this. */
2772 /* Expand a call to the strrchr builtin. Return 0 if we failed the
2773 caller should emit a normal call, otherwise try to get the result
2774 in TARGET, if convenient (and in mode MODE if that's convenient). */
2777 expand_builtin_strrchr (tree arglist
, tree type
, rtx target
, enum machine_mode mode
)
2779 if (validate_arglist (arglist
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
2781 tree result
= fold_builtin_strrchr (arglist
, type
);
2783 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
2788 /* Expand a call to the strpbrk builtin. Return 0 if we failed the
2789 caller should emit a normal call, otherwise try to get the result
2790 in TARGET, if convenient (and in mode MODE if that's convenient). */
2793 expand_builtin_strpbrk (tree arglist
, tree type
, rtx target
, enum machine_mode mode
)
2795 if (validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
2797 tree result
= fold_builtin_strpbrk (arglist
, type
);
2799 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
2804 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
2805 bytes from constant string DATA + OFFSET and return it as target
2809 builtin_memcpy_read_str (void *data
, HOST_WIDE_INT offset
,
2810 enum machine_mode mode
)
2812 const char *str
= (const char *) data
;
2814 gcc_assert (offset
>= 0
2815 && ((unsigned HOST_WIDE_INT
) offset
+ GET_MODE_SIZE (mode
)
2816 <= strlen (str
) + 1));
2818 return c_readstr (str
+ offset
, mode
);
2821 /* Expand a call to the memcpy builtin, with arguments in ARGLIST.
2822 Return 0 if we failed, the caller should emit a normal call,
2823 otherwise try to get the result in TARGET, if convenient (and in
2824 mode MODE if that's convenient). */
2826 expand_builtin_memcpy (tree exp
, rtx target
, enum machine_mode mode
)
2828 tree fndecl
= get_callee_fndecl (exp
);
2829 tree arglist
= TREE_OPERAND (exp
, 1);
2830 if (!validate_arglist (arglist
,
2831 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
2835 tree dest
= TREE_VALUE (arglist
);
2836 tree src
= TREE_VALUE (TREE_CHAIN (arglist
));
2837 tree len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
2838 const char *src_str
;
2839 unsigned int src_align
= get_pointer_alignment (src
, BIGGEST_ALIGNMENT
);
2840 unsigned int dest_align
2841 = get_pointer_alignment (dest
, BIGGEST_ALIGNMENT
);
2842 rtx dest_mem
, src_mem
, dest_addr
, len_rtx
;
2843 tree result
= fold_builtin_memcpy (fndecl
, arglist
);
2846 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
2848 /* If DEST is not a pointer type, call the normal function. */
2849 if (dest_align
== 0)
2852 /* If either SRC is not a pointer type, don't do this
2853 operation in-line. */
2857 dest_mem
= get_memory_rtx (dest
, len
);
2858 set_mem_align (dest_mem
, dest_align
);
2859 len_rtx
= expand_normal (len
);
2860 src_str
= c_getstr (src
);
2862 /* If SRC is a string constant and block move would be done
2863 by pieces, we can avoid loading the string from memory
2864 and only stored the computed constants. */
2866 && GET_CODE (len_rtx
) == CONST_INT
2867 && (unsigned HOST_WIDE_INT
) INTVAL (len_rtx
) <= strlen (src_str
) + 1
2868 && can_store_by_pieces (INTVAL (len_rtx
), builtin_memcpy_read_str
,
2869 (void *) src_str
, dest_align
))
2871 dest_mem
= store_by_pieces (dest_mem
, INTVAL (len_rtx
),
2872 builtin_memcpy_read_str
,
2873 (void *) src_str
, dest_align
, 0);
2874 dest_mem
= force_operand (XEXP (dest_mem
, 0), NULL_RTX
);
2875 dest_mem
= convert_memory_address (ptr_mode
, dest_mem
);
2879 src_mem
= get_memory_rtx (src
, len
);
2880 set_mem_align (src_mem
, src_align
);
2882 /* Copy word part most expediently. */
2883 dest_addr
= emit_block_move (dest_mem
, src_mem
, len_rtx
,
2884 CALL_EXPR_TAILCALL (exp
)
2885 ? BLOCK_OP_TAILCALL
: BLOCK_OP_NORMAL
);
2889 dest_addr
= force_operand (XEXP (dest_mem
, 0), NULL_RTX
);
2890 dest_addr
= convert_memory_address (ptr_mode
, dest_addr
);
2896 /* Expand a call to the mempcpy builtin, with arguments in ARGLIST.
2897 Return 0 if we failed; the caller should emit a normal call,
2898 otherwise try to get the result in TARGET, if convenient (and in
2899 mode MODE if that's convenient). If ENDP is 0 return the
2900 destination pointer, if ENDP is 1 return the end pointer ala
2901 mempcpy, and if ENDP is 2 return the end pointer minus one ala
2905 expand_builtin_mempcpy (tree arglist
, tree type
, rtx target
, enum machine_mode mode
,
2908 if (!validate_arglist (arglist
,
2909 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
2911 /* If return value is ignored, transform mempcpy into memcpy. */
2912 else if (target
== const0_rtx
)
2914 tree fn
= implicit_built_in_decls
[BUILT_IN_MEMCPY
];
2919 return expand_expr (build_function_call_expr (fn
, arglist
),
2920 target
, mode
, EXPAND_NORMAL
);
2924 tree dest
= TREE_VALUE (arglist
);
2925 tree src
= TREE_VALUE (TREE_CHAIN (arglist
));
2926 tree len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
2927 const char *src_str
;
2928 unsigned int src_align
= get_pointer_alignment (src
, BIGGEST_ALIGNMENT
);
2929 unsigned int dest_align
2930 = get_pointer_alignment (dest
, BIGGEST_ALIGNMENT
);
2931 rtx dest_mem
, src_mem
, len_rtx
;
2932 tree result
= fold_builtin_mempcpy (arglist
, type
, endp
);
2935 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
2937 /* If either SRC or DEST is not a pointer type, don't do this
2938 operation in-line. */
2939 if (dest_align
== 0 || src_align
== 0)
2942 /* If LEN is not constant, call the normal function. */
2943 if (! host_integerp (len
, 1))
2946 len_rtx
= expand_normal (len
);
2947 src_str
= c_getstr (src
);
2949 /* If SRC is a string constant and block move would be done
2950 by pieces, we can avoid loading the string from memory
2951 and only stored the computed constants. */
2953 && GET_CODE (len_rtx
) == CONST_INT
2954 && (unsigned HOST_WIDE_INT
) INTVAL (len_rtx
) <= strlen (src_str
) + 1
2955 && can_store_by_pieces (INTVAL (len_rtx
), builtin_memcpy_read_str
,
2956 (void *) src_str
, dest_align
))
2958 dest_mem
= get_memory_rtx (dest
, len
);
2959 set_mem_align (dest_mem
, dest_align
);
2960 dest_mem
= store_by_pieces (dest_mem
, INTVAL (len_rtx
),
2961 builtin_memcpy_read_str
,
2962 (void *) src_str
, dest_align
, endp
);
2963 dest_mem
= force_operand (XEXP (dest_mem
, 0), NULL_RTX
);
2964 dest_mem
= convert_memory_address (ptr_mode
, dest_mem
);
2968 if (GET_CODE (len_rtx
) == CONST_INT
2969 && can_move_by_pieces (INTVAL (len_rtx
),
2970 MIN (dest_align
, src_align
)))
2972 dest_mem
= get_memory_rtx (dest
, len
);
2973 set_mem_align (dest_mem
, dest_align
);
2974 src_mem
= get_memory_rtx (src
, len
);
2975 set_mem_align (src_mem
, src_align
);
2976 dest_mem
= move_by_pieces (dest_mem
, src_mem
, INTVAL (len_rtx
),
2977 MIN (dest_align
, src_align
), endp
);
2978 dest_mem
= force_operand (XEXP (dest_mem
, 0), NULL_RTX
);
2979 dest_mem
= convert_memory_address (ptr_mode
, dest_mem
);
2987 /* Expand expression EXP, which is a call to the memmove builtin. Return 0
2988 if we failed; the caller should emit a normal call. */
2991 expand_builtin_memmove (tree arglist
, tree type
, rtx target
,
2992 enum machine_mode mode
, tree orig_exp
)
2994 if (!validate_arglist (arglist
,
2995 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
2999 tree dest
= TREE_VALUE (arglist
);
3000 tree src
= TREE_VALUE (TREE_CHAIN (arglist
));
3001 tree len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
3003 unsigned int src_align
= get_pointer_alignment (src
, BIGGEST_ALIGNMENT
);
3004 unsigned int dest_align
3005 = get_pointer_alignment (dest
, BIGGEST_ALIGNMENT
);
3006 tree result
= fold_builtin_memmove (arglist
, type
);
3009 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
3011 /* If DEST is not a pointer type, call the normal function. */
3012 if (dest_align
== 0)
3015 /* If either SRC is not a pointer type, don't do this
3016 operation in-line. */
3020 /* If src is categorized for a readonly section we can use
3022 if (readonly_data_expr (src
))
3024 tree fn
= implicit_built_in_decls
[BUILT_IN_MEMCPY
];
3027 fn
= build_function_call_expr (fn
, arglist
);
3028 if (TREE_CODE (fn
) == CALL_EXPR
)
3029 CALL_EXPR_TAILCALL (fn
) = CALL_EXPR_TAILCALL (orig_exp
);
3030 return expand_expr (fn
, target
, mode
, EXPAND_NORMAL
);
3033 /* If length is 1 and we can expand memcpy call inline,
3034 it is ok to use memcpy as well. */
3035 if (integer_onep (len
))
3037 rtx ret
= expand_builtin_mempcpy (arglist
, type
, target
, mode
,
3043 /* Otherwise, call the normal function. */
3048 /* Expand expression EXP, which is a call to the bcopy builtin. Return 0
3049 if we failed the caller should emit a normal call. */
3052 expand_builtin_bcopy (tree exp
)
3054 tree arglist
= TREE_OPERAND (exp
, 1);
3055 tree type
= TREE_TYPE (exp
);
3056 tree src
, dest
, size
, newarglist
;
3058 if (!validate_arglist (arglist
,
3059 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
3062 src
= TREE_VALUE (arglist
);
3063 dest
= TREE_VALUE (TREE_CHAIN (arglist
));
3064 size
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
3066 /* New argument list transforming bcopy(ptr x, ptr y, int z) to
3067 memmove(ptr y, ptr x, size_t z). This is done this way
3068 so that if it isn't expanded inline, we fallback to
3069 calling bcopy instead of memmove. */
3071 newarglist
= build_tree_list (NULL_TREE
, fold_convert (sizetype
, size
));
3072 newarglist
= tree_cons (NULL_TREE
, src
, newarglist
);
3073 newarglist
= tree_cons (NULL_TREE
, dest
, newarglist
);
3075 return expand_builtin_memmove (newarglist
, type
, const0_rtx
, VOIDmode
, exp
);
3079 # define HAVE_movstr 0
3080 # define CODE_FOR_movstr CODE_FOR_nothing
3083 /* Expand into a movstr instruction, if one is available. Return 0 if
3084 we failed, the caller should emit a normal call, otherwise try to
3085 get the result in TARGET, if convenient. If ENDP is 0 return the
3086 destination pointer, if ENDP is 1 return the end pointer ala
3087 mempcpy, and if ENDP is 2 return the end pointer minus one ala
3091 expand_movstr (tree dest
, tree src
, rtx target
, int endp
)
3097 const struct insn_data
* data
;
3102 dest_mem
= get_memory_rtx (dest
, NULL
);
3103 src_mem
= get_memory_rtx (src
, NULL
);
3106 target
= force_reg (Pmode
, XEXP (dest_mem
, 0));
3107 dest_mem
= replace_equiv_address (dest_mem
, target
);
3108 end
= gen_reg_rtx (Pmode
);
3112 if (target
== 0 || target
== const0_rtx
)
3114 end
= gen_reg_rtx (Pmode
);
3122 data
= insn_data
+ CODE_FOR_movstr
;
3124 if (data
->operand
[0].mode
!= VOIDmode
)
3125 end
= gen_lowpart (data
->operand
[0].mode
, end
);
3127 insn
= data
->genfun (end
, dest_mem
, src_mem
);
3133 /* movstr is supposed to set end to the address of the NUL
3134 terminator. If the caller requested a mempcpy-like return value,
3136 if (endp
== 1 && target
!= const0_rtx
)
3138 rtx tem
= plus_constant (gen_lowpart (GET_MODE (target
), end
), 1);
3139 emit_move_insn (target
, force_operand (tem
, NULL_RTX
));
3145 /* Expand expression EXP, which is a call to the strcpy builtin. Return 0
3146 if we failed the caller should emit a normal call, otherwise try to get
3147 the result in TARGET, if convenient (and in mode MODE if that's
3151 expand_builtin_strcpy (tree fndecl
, tree arglist
, rtx target
, enum machine_mode mode
)
3153 if (validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
3155 tree result
= fold_builtin_strcpy (fndecl
, arglist
, 0);
3157 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
3159 return expand_movstr (TREE_VALUE (arglist
),
3160 TREE_VALUE (TREE_CHAIN (arglist
)),
3161 target
, /*endp=*/0);
3166 /* Expand a call to the stpcpy builtin, with arguments in ARGLIST.
3167 Return 0 if we failed the caller should emit a normal call,
3168 otherwise try to get the result in TARGET, if convenient (and in
3169 mode MODE if that's convenient). */
3172 expand_builtin_stpcpy (tree exp
, rtx target
, enum machine_mode mode
)
3174 tree arglist
= TREE_OPERAND (exp
, 1);
3175 /* If return value is ignored, transform stpcpy into strcpy. */
3176 if (target
== const0_rtx
)
3178 tree fn
= implicit_built_in_decls
[BUILT_IN_STRCPY
];
3182 return expand_expr (build_function_call_expr (fn
, arglist
),
3183 target
, mode
, EXPAND_NORMAL
);
3186 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
3190 tree dst
, src
, len
, lenp1
;
3194 /* Ensure we get an actual string whose length can be evaluated at
3195 compile-time, not an expression containing a string. This is
3196 because the latter will potentially produce pessimized code
3197 when used to produce the return value. */
3198 src
= TREE_VALUE (TREE_CHAIN (arglist
));
3199 if (! c_getstr (src
) || ! (len
= c_strlen (src
, 0)))
3200 return expand_movstr (TREE_VALUE (arglist
),
3201 TREE_VALUE (TREE_CHAIN (arglist
)),
3202 target
, /*endp=*/2);
3204 dst
= TREE_VALUE (arglist
);
3205 lenp1
= size_binop (PLUS_EXPR
, len
, ssize_int (1));
3206 narglist
= build_tree_list (NULL_TREE
, lenp1
);
3207 narglist
= tree_cons (NULL_TREE
, src
, narglist
);
3208 narglist
= tree_cons (NULL_TREE
, dst
, narglist
);
3209 ret
= expand_builtin_mempcpy (narglist
, TREE_TYPE (exp
),
3210 target
, mode
, /*endp=*/2);
3215 if (TREE_CODE (len
) == INTEGER_CST
)
3217 rtx len_rtx
= expand_normal (len
);
3219 if (GET_CODE (len_rtx
) == CONST_INT
)
3221 ret
= expand_builtin_strcpy (get_callee_fndecl (exp
),
3222 arglist
, target
, mode
);
3228 if (mode
!= VOIDmode
)
3229 target
= gen_reg_rtx (mode
);
3231 target
= gen_reg_rtx (GET_MODE (ret
));
3233 if (GET_MODE (target
) != GET_MODE (ret
))
3234 ret
= gen_lowpart (GET_MODE (target
), ret
);
3236 ret
= plus_constant (ret
, INTVAL (len_rtx
));
3237 ret
= emit_move_insn (target
, force_operand (ret
, NULL_RTX
));
3245 return expand_movstr (TREE_VALUE (arglist
),
3246 TREE_VALUE (TREE_CHAIN (arglist
)),
3247 target
, /*endp=*/2);
3251 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
3252 bytes from constant string DATA + OFFSET and return it as target
3256 builtin_strncpy_read_str (void *data
, HOST_WIDE_INT offset
,
3257 enum machine_mode mode
)
3259 const char *str
= (const char *) data
;
3261 if ((unsigned HOST_WIDE_INT
) offset
> strlen (str
))
3264 return c_readstr (str
+ offset
, mode
);
3267 /* Expand expression EXP, which is a call to the strncpy builtin. Return 0
3268 if we failed the caller should emit a normal call. */
3271 expand_builtin_strncpy (tree exp
, rtx target
, enum machine_mode mode
)
3273 tree fndecl
= get_callee_fndecl (exp
);
3274 tree arglist
= TREE_OPERAND (exp
, 1);
3275 if (validate_arglist (arglist
,
3276 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
3278 tree slen
= c_strlen (TREE_VALUE (TREE_CHAIN (arglist
)), 1);
3279 tree len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
3280 tree result
= fold_builtin_strncpy (fndecl
, arglist
, slen
);
3283 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
3285 /* We must be passed a constant len and src parameter. */
3286 if (!host_integerp (len
, 1) || !slen
|| !host_integerp (slen
, 1))
3289 slen
= size_binop (PLUS_EXPR
, slen
, ssize_int (1));
3291 /* We're required to pad with trailing zeros if the requested
3292 len is greater than strlen(s2)+1. In that case try to
3293 use store_by_pieces, if it fails, punt. */
3294 if (tree_int_cst_lt (slen
, len
))
3296 tree dest
= TREE_VALUE (arglist
);
3297 unsigned int dest_align
3298 = get_pointer_alignment (dest
, BIGGEST_ALIGNMENT
);
3299 const char *p
= c_getstr (TREE_VALUE (TREE_CHAIN (arglist
)));
3302 if (!p
|| dest_align
== 0 || !host_integerp (len
, 1)
3303 || !can_store_by_pieces (tree_low_cst (len
, 1),
3304 builtin_strncpy_read_str
,
3305 (void *) p
, dest_align
))
3308 dest_mem
= get_memory_rtx (dest
, len
);
3309 store_by_pieces (dest_mem
, tree_low_cst (len
, 1),
3310 builtin_strncpy_read_str
,
3311 (void *) p
, dest_align
, 0);
3312 dest_mem
= force_operand (XEXP (dest_mem
, 0), NULL_RTX
);
3313 dest_mem
= convert_memory_address (ptr_mode
, dest_mem
);
3320 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
3321 bytes from constant string DATA + OFFSET and return it as target
3325 builtin_memset_read_str (void *data
, HOST_WIDE_INT offset ATTRIBUTE_UNUSED
,
3326 enum machine_mode mode
)
3328 const char *c
= (const char *) data
;
3329 char *p
= alloca (GET_MODE_SIZE (mode
));
3331 memset (p
, *c
, GET_MODE_SIZE (mode
));
3333 return c_readstr (p
, mode
);
3336 /* Callback routine for store_by_pieces. Return the RTL of a register
3337 containing GET_MODE_SIZE (MODE) consecutive copies of the unsigned
3338 char value given in the RTL register data. For example, if mode is
3339 4 bytes wide, return the RTL for 0x01010101*data. */
3342 builtin_memset_gen_str (void *data
, HOST_WIDE_INT offset ATTRIBUTE_UNUSED
,
3343 enum machine_mode mode
)
3349 size
= GET_MODE_SIZE (mode
);
3354 memset (p
, 1, size
);
3355 coeff
= c_readstr (p
, mode
);
3357 target
= convert_to_mode (mode
, (rtx
) data
, 1);
3358 target
= expand_mult (mode
, target
, coeff
, NULL_RTX
, 1);
3359 return force_reg (mode
, target
);
3362 /* Expand expression EXP, which is a call to the memset builtin. Return 0
3363 if we failed the caller should emit a normal call, otherwise try to get
3364 the result in TARGET, if convenient (and in mode MODE if that's
3368 expand_builtin_memset (tree arglist
, rtx target
, enum machine_mode mode
,
3371 if (!validate_arglist (arglist
,
3372 POINTER_TYPE
, INTEGER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
3376 tree dest
= TREE_VALUE (arglist
);
3377 tree val
= TREE_VALUE (TREE_CHAIN (arglist
));
3378 tree len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
3381 unsigned int dest_align
3382 = get_pointer_alignment (dest
, BIGGEST_ALIGNMENT
);
3383 rtx dest_mem
, dest_addr
, len_rtx
;
3385 /* If DEST is not a pointer type, don't do this
3386 operation in-line. */
3387 if (dest_align
== 0)
3390 /* If the LEN parameter is zero, return DEST. */
3391 if (integer_zerop (len
))
3393 /* Evaluate and ignore VAL in case it has side-effects. */
3394 expand_expr (val
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
3395 return expand_expr (dest
, target
, mode
, EXPAND_NORMAL
);
3398 len_rtx
= expand_normal (len
);
3399 dest_mem
= get_memory_rtx (dest
, len
);
3401 if (TREE_CODE (val
) != INTEGER_CST
)
3405 val
= fold_build1 (CONVERT_EXPR
, unsigned_char_type_node
, val
);
3406 val_rtx
= expand_normal (val
);
3408 /* Assume that we can memset by pieces if we can store the
3409 * the coefficients by pieces (in the required modes).
3410 * We can't pass builtin_memset_gen_str as that emits RTL. */
3412 if (host_integerp (len
, 1)
3413 && !(optimize_size
&& tree_low_cst (len
, 1) > 1)
3414 && can_store_by_pieces (tree_low_cst (len
, 1),
3415 builtin_memset_read_str
, &c
, dest_align
))
3417 val_rtx
= force_reg (TYPE_MODE (unsigned_char_type_node
),
3419 store_by_pieces (dest_mem
, tree_low_cst (len
, 1),
3420 builtin_memset_gen_str
, val_rtx
, dest_align
, 0);
3422 else if (!set_storage_via_setmem(dest_mem
, len_rtx
, val_rtx
,
3426 dest_mem
= force_operand (XEXP (dest_mem
, 0), NULL_RTX
);
3427 dest_mem
= convert_memory_address (ptr_mode
, dest_mem
);
3431 if (target_char_cast (val
, &c
))
3436 if (host_integerp (len
, 1)
3437 && !(optimize_size
&& tree_low_cst (len
, 1) > 1)
3438 && can_store_by_pieces (tree_low_cst (len
, 1),
3439 builtin_memset_read_str
, &c
, dest_align
))
3440 store_by_pieces (dest_mem
, tree_low_cst (len
, 1),
3441 builtin_memset_read_str
, &c
, dest_align
, 0);
3442 else if (!set_storage_via_setmem (dest_mem
, len_rtx
, GEN_INT (c
),
3446 dest_mem
= force_operand (XEXP (dest_mem
, 0), NULL_RTX
);
3447 dest_mem
= convert_memory_address (ptr_mode
, dest_mem
);
3451 set_mem_align (dest_mem
, dest_align
);
3452 dest_addr
= clear_storage (dest_mem
, len_rtx
,
3453 CALL_EXPR_TAILCALL (orig_exp
)
3454 ? BLOCK_OP_TAILCALL
: BLOCK_OP_NORMAL
);
3458 dest_addr
= force_operand (XEXP (dest_mem
, 0), NULL_RTX
);
3459 dest_addr
= convert_memory_address (ptr_mode
, dest_addr
);
3466 /* Expand expression EXP, which is a call to the bzero builtin. Return 0
3467 if we failed the caller should emit a normal call. */
3470 expand_builtin_bzero (tree exp
)
3472 tree arglist
= TREE_OPERAND (exp
, 1);
3473 tree dest
, size
, newarglist
;
3475 if (!validate_arglist (arglist
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
3478 dest
= TREE_VALUE (arglist
);
3479 size
= TREE_VALUE (TREE_CHAIN (arglist
));
3481 /* New argument list transforming bzero(ptr x, int y) to
3482 memset(ptr x, int 0, size_t y). This is done this way
3483 so that if it isn't expanded inline, we fallback to
3484 calling bzero instead of memset. */
3486 newarglist
= build_tree_list (NULL_TREE
, fold_convert (sizetype
, size
));
3487 newarglist
= tree_cons (NULL_TREE
, integer_zero_node
, newarglist
);
3488 newarglist
= tree_cons (NULL_TREE
, dest
, newarglist
);
3490 return expand_builtin_memset (newarglist
, const0_rtx
, VOIDmode
, exp
);
3493 /* Expand expression EXP, which is a call to the memcmp built-in function.
3494 ARGLIST is the argument list for this call. Return 0 if we failed and the
3495 caller should emit a normal call, otherwise try to get the result in
3496 TARGET, if convenient (and in mode MODE, if that's convenient). */
3499 expand_builtin_memcmp (tree exp ATTRIBUTE_UNUSED
, tree arglist
, rtx target
,
3500 enum machine_mode mode
)
3502 if (!validate_arglist (arglist
,
3503 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
3507 tree result
= fold_builtin_memcmp (arglist
);
3509 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
3512 #if defined HAVE_cmpmemsi || defined HAVE_cmpstrnsi
3514 tree arg1
= TREE_VALUE (arglist
);
3515 tree arg2
= TREE_VALUE (TREE_CHAIN (arglist
));
3516 tree len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
3517 rtx arg1_rtx
, arg2_rtx
, arg3_rtx
;
3522 = get_pointer_alignment (arg1
, BIGGEST_ALIGNMENT
) / BITS_PER_UNIT
;
3524 = get_pointer_alignment (arg2
, BIGGEST_ALIGNMENT
) / BITS_PER_UNIT
;
3525 enum machine_mode insn_mode
;
3527 #ifdef HAVE_cmpmemsi
3529 insn_mode
= insn_data
[(int) CODE_FOR_cmpmemsi
].operand
[0].mode
;
3532 #ifdef HAVE_cmpstrnsi
3534 insn_mode
= insn_data
[(int) CODE_FOR_cmpstrnsi
].operand
[0].mode
;
3539 /* If we don't have POINTER_TYPE, call the function. */
3540 if (arg1_align
== 0 || arg2_align
== 0)
3543 /* Make a place to write the result of the instruction. */
3546 && REG_P (result
) && GET_MODE (result
) == insn_mode
3547 && REGNO (result
) >= FIRST_PSEUDO_REGISTER
))
3548 result
= gen_reg_rtx (insn_mode
);
3550 arg1_rtx
= get_memory_rtx (arg1
, len
);
3551 arg2_rtx
= get_memory_rtx (arg2
, len
);
3552 arg3_rtx
= expand_normal (len
);
3554 /* Set MEM_SIZE as appropriate. */
3555 if (GET_CODE (arg3_rtx
) == CONST_INT
)
3557 set_mem_size (arg1_rtx
, arg3_rtx
);
3558 set_mem_size (arg2_rtx
, arg3_rtx
);
3561 #ifdef HAVE_cmpmemsi
3563 insn
= gen_cmpmemsi (result
, arg1_rtx
, arg2_rtx
, arg3_rtx
,
3564 GEN_INT (MIN (arg1_align
, arg2_align
)));
3567 #ifdef HAVE_cmpstrnsi
3569 insn
= gen_cmpstrnsi (result
, arg1_rtx
, arg2_rtx
, arg3_rtx
,
3570 GEN_INT (MIN (arg1_align
, arg2_align
)));
3578 emit_library_call_value (memcmp_libfunc
, result
, LCT_PURE_MAKE_BLOCK
,
3579 TYPE_MODE (integer_type_node
), 3,
3580 XEXP (arg1_rtx
, 0), Pmode
,
3581 XEXP (arg2_rtx
, 0), Pmode
,
3582 convert_to_mode (TYPE_MODE (sizetype
), arg3_rtx
,
3583 TYPE_UNSIGNED (sizetype
)),
3584 TYPE_MODE (sizetype
));
3586 /* Return the value in the proper mode for this function. */
3587 mode
= TYPE_MODE (TREE_TYPE (exp
));
3588 if (GET_MODE (result
) == mode
)
3590 else if (target
!= 0)
3592 convert_move (target
, result
, 0);
3596 return convert_to_mode (mode
, result
, 0);
3603 /* Expand expression EXP, which is a call to the strcmp builtin. Return 0
3604 if we failed the caller should emit a normal call, otherwise try to get
3605 the result in TARGET, if convenient. */
3608 expand_builtin_strcmp (tree exp
, rtx target
, enum machine_mode mode
)
3610 tree arglist
= TREE_OPERAND (exp
, 1);
3612 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
3616 tree result
= fold_builtin_strcmp (arglist
);
3618 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
3621 #if defined HAVE_cmpstrsi || defined HAVE_cmpstrnsi
3622 if (cmpstr_optab
[SImode
] != CODE_FOR_nothing
3623 || cmpstrn_optab
[SImode
] != CODE_FOR_nothing
)
3625 rtx arg1_rtx
, arg2_rtx
;
3626 rtx result
, insn
= NULL_RTX
;
3629 tree arg1
= TREE_VALUE (arglist
);
3630 tree arg2
= TREE_VALUE (TREE_CHAIN (arglist
));
3632 = get_pointer_alignment (arg1
, BIGGEST_ALIGNMENT
) / BITS_PER_UNIT
;
3634 = get_pointer_alignment (arg2
, BIGGEST_ALIGNMENT
) / BITS_PER_UNIT
;
3636 /* If we don't have POINTER_TYPE, call the function. */
3637 if (arg1_align
== 0 || arg2_align
== 0)
3640 /* Stabilize the arguments in case gen_cmpstr(n)si fail. */
3641 arg1
= builtin_save_expr (arg1
);
3642 arg2
= builtin_save_expr (arg2
);
3644 arg1_rtx
= get_memory_rtx (arg1
, NULL
);
3645 arg2_rtx
= get_memory_rtx (arg2
, NULL
);
3647 #ifdef HAVE_cmpstrsi
3648 /* Try to call cmpstrsi. */
3651 enum machine_mode insn_mode
3652 = insn_data
[(int) CODE_FOR_cmpstrsi
].operand
[0].mode
;
3654 /* Make a place to write the result of the instruction. */
3657 && REG_P (result
) && GET_MODE (result
) == insn_mode
3658 && REGNO (result
) >= FIRST_PSEUDO_REGISTER
))
3659 result
= gen_reg_rtx (insn_mode
);
3661 insn
= gen_cmpstrsi (result
, arg1_rtx
, arg2_rtx
,
3662 GEN_INT (MIN (arg1_align
, arg2_align
)));
3666 /* Try to determine at least one length and call cmpstrnsi. */
3667 if (!insn
&& HAVE_cmpstrnsi
)
3672 enum machine_mode insn_mode
3673 = insn_data
[(int) CODE_FOR_cmpstrnsi
].operand
[0].mode
;
3674 tree len1
= c_strlen (arg1
, 1);
3675 tree len2
= c_strlen (arg2
, 1);
3678 len1
= size_binop (PLUS_EXPR
, ssize_int (1), len1
);
3680 len2
= size_binop (PLUS_EXPR
, ssize_int (1), len2
);
3682 /* If we don't have a constant length for the first, use the length
3683 of the second, if we know it. We don't require a constant for
3684 this case; some cost analysis could be done if both are available
3685 but neither is constant. For now, assume they're equally cheap,
3686 unless one has side effects. If both strings have constant lengths,
3693 else if (TREE_SIDE_EFFECTS (len1
))
3695 else if (TREE_SIDE_EFFECTS (len2
))
3697 else if (TREE_CODE (len1
) != INTEGER_CST
)
3699 else if (TREE_CODE (len2
) != INTEGER_CST
)
3701 else if (tree_int_cst_lt (len1
, len2
))
3706 /* If both arguments have side effects, we cannot optimize. */
3707 if (!len
|| TREE_SIDE_EFFECTS (len
))
3710 /* Stabilize the arguments in case gen_cmpstrnsi fails. */
3711 arg3_rtx
= expand_normal (len
);
3713 /* Make a place to write the result of the instruction. */
3716 && REG_P (result
) && GET_MODE (result
) == insn_mode
3717 && REGNO (result
) >= FIRST_PSEUDO_REGISTER
))
3718 result
= gen_reg_rtx (insn_mode
);
3720 insn
= gen_cmpstrnsi (result
, arg1_rtx
, arg2_rtx
, arg3_rtx
,
3721 GEN_INT (MIN (arg1_align
, arg2_align
)));
3729 /* Return the value in the proper mode for this function. */
3730 mode
= TYPE_MODE (TREE_TYPE (exp
));
3731 if (GET_MODE (result
) == mode
)
3734 return convert_to_mode (mode
, result
, 0);
3735 convert_move (target
, result
, 0);
3739 /* Expand the library call ourselves using a stabilized argument
3740 list to avoid re-evaluating the function's arguments twice. */
3741 arglist
= build_tree_list (NULL_TREE
, arg2
);
3742 arglist
= tree_cons (NULL_TREE
, arg1
, arglist
);
3743 fndecl
= get_callee_fndecl (exp
);
3744 fn
= build_function_call_expr (fndecl
, arglist
);
3745 if (TREE_CODE (fn
) == CALL_EXPR
)
3746 CALL_EXPR_TAILCALL (fn
) = CALL_EXPR_TAILCALL (exp
);
3747 return expand_call (fn
, target
, target
== const0_rtx
);
3753 /* Expand expression EXP, which is a call to the strncmp builtin. Return 0
3754 if we failed the caller should emit a normal call, otherwise try to get
3755 the result in TARGET, if convenient. */
3758 expand_builtin_strncmp (tree exp
, rtx target
, enum machine_mode mode
)
3760 tree arglist
= TREE_OPERAND (exp
, 1);
3762 if (!validate_arglist (arglist
,
3763 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
3767 tree result
= fold_builtin_strncmp (arglist
);
3769 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
3772 /* If c_strlen can determine an expression for one of the string
3773 lengths, and it doesn't have side effects, then emit cmpstrnsi
3774 using length MIN(strlen(string)+1, arg3). */
3775 #ifdef HAVE_cmpstrnsi
3778 tree arg1
= TREE_VALUE (arglist
);
3779 tree arg2
= TREE_VALUE (TREE_CHAIN (arglist
));
3780 tree arg3
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
3781 tree len
, len1
, len2
;
3782 rtx arg1_rtx
, arg2_rtx
, arg3_rtx
;
3787 = get_pointer_alignment (arg1
, BIGGEST_ALIGNMENT
) / BITS_PER_UNIT
;
3789 = get_pointer_alignment (arg2
, BIGGEST_ALIGNMENT
) / BITS_PER_UNIT
;
3790 enum machine_mode insn_mode
3791 = insn_data
[(int) CODE_FOR_cmpstrnsi
].operand
[0].mode
;
3793 len1
= c_strlen (arg1
, 1);
3794 len2
= c_strlen (arg2
, 1);
3797 len1
= size_binop (PLUS_EXPR
, ssize_int (1), len1
);
3799 len2
= size_binop (PLUS_EXPR
, ssize_int (1), len2
);
3801 /* If we don't have a constant length for the first, use the length
3802 of the second, if we know it. We don't require a constant for
3803 this case; some cost analysis could be done if both are available
3804 but neither is constant. For now, assume they're equally cheap,
3805 unless one has side effects. If both strings have constant lengths,
3812 else if (TREE_SIDE_EFFECTS (len1
))
3814 else if (TREE_SIDE_EFFECTS (len2
))
3816 else if (TREE_CODE (len1
) != INTEGER_CST
)
3818 else if (TREE_CODE (len2
) != INTEGER_CST
)
3820 else if (tree_int_cst_lt (len1
, len2
))
3825 /* If both arguments have side effects, we cannot optimize. */
3826 if (!len
|| TREE_SIDE_EFFECTS (len
))
3829 /* The actual new length parameter is MIN(len,arg3). */
3830 len
= fold_build2 (MIN_EXPR
, TREE_TYPE (len
), len
,
3831 fold_convert (TREE_TYPE (len
), arg3
));
3833 /* If we don't have POINTER_TYPE, call the function. */
3834 if (arg1_align
== 0 || arg2_align
== 0)
3837 /* Make a place to write the result of the instruction. */
3840 && REG_P (result
) && GET_MODE (result
) == insn_mode
3841 && REGNO (result
) >= FIRST_PSEUDO_REGISTER
))
3842 result
= gen_reg_rtx (insn_mode
);
3844 /* Stabilize the arguments in case gen_cmpstrnsi fails. */
3845 arg1
= builtin_save_expr (arg1
);
3846 arg2
= builtin_save_expr (arg2
);
3847 len
= builtin_save_expr (len
);
3849 arg1_rtx
= get_memory_rtx (arg1
, len
);
3850 arg2_rtx
= get_memory_rtx (arg2
, len
);
3851 arg3_rtx
= expand_normal (len
);
3852 insn
= gen_cmpstrnsi (result
, arg1_rtx
, arg2_rtx
, arg3_rtx
,
3853 GEN_INT (MIN (arg1_align
, arg2_align
)));
3858 /* Return the value in the proper mode for this function. */
3859 mode
= TYPE_MODE (TREE_TYPE (exp
));
3860 if (GET_MODE (result
) == mode
)
3863 return convert_to_mode (mode
, result
, 0);
3864 convert_move (target
, result
, 0);
3868 /* Expand the library call ourselves using a stabilized argument
3869 list to avoid re-evaluating the function's arguments twice. */
3870 arglist
= build_tree_list (NULL_TREE
, len
);
3871 arglist
= tree_cons (NULL_TREE
, arg2
, arglist
);
3872 arglist
= tree_cons (NULL_TREE
, arg1
, arglist
);
3873 fndecl
= get_callee_fndecl (exp
);
3874 fn
= build_function_call_expr (fndecl
, arglist
);
3875 if (TREE_CODE (fn
) == CALL_EXPR
)
3876 CALL_EXPR_TAILCALL (fn
) = CALL_EXPR_TAILCALL (exp
);
3877 return expand_call (fn
, target
, target
== const0_rtx
);
3883 /* Expand expression EXP, which is a call to the strcat builtin.
3884 Return 0 if we failed the caller should emit a normal call,
3885 otherwise try to get the result in TARGET, if convenient. */
3888 expand_builtin_strcat (tree fndecl
, tree arglist
, rtx target
, enum machine_mode mode
)
3890 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
3894 tree dst
= TREE_VALUE (arglist
),
3895 src
= TREE_VALUE (TREE_CHAIN (arglist
));
3896 const char *p
= c_getstr (src
);
3898 /* If the string length is zero, return the dst parameter. */
3899 if (p
&& *p
== '\0')
3900 return expand_expr (dst
, target
, mode
, EXPAND_NORMAL
);
3904 /* See if we can store by pieces into (dst + strlen(dst)). */
3905 tree newsrc
, newdst
,
3906 strlen_fn
= implicit_built_in_decls
[BUILT_IN_STRLEN
];
3909 /* Stabilize the argument list. */
3910 newsrc
= builtin_save_expr (src
);
3912 arglist
= build_tree_list (NULL_TREE
, newsrc
);
3914 arglist
= TREE_CHAIN (arglist
); /* Reusing arglist if safe. */
3916 dst
= builtin_save_expr (dst
);
3920 /* Create strlen (dst). */
3922 build_function_call_expr (strlen_fn
,
3923 build_tree_list (NULL_TREE
, dst
));
3924 /* Create (dst + (cast) strlen (dst)). */
3925 newdst
= fold_convert (TREE_TYPE (dst
), newdst
);
3926 newdst
= fold_build2 (PLUS_EXPR
, TREE_TYPE (dst
), dst
, newdst
);
3928 newdst
= builtin_save_expr (newdst
);
3929 arglist
= tree_cons (NULL_TREE
, newdst
, arglist
);
3931 if (!expand_builtin_strcpy (fndecl
, arglist
, target
, mode
))
3933 end_sequence (); /* Stop sequence. */
3937 /* Output the entire sequence. */
3938 insns
= get_insns ();
3942 return expand_expr (dst
, target
, mode
, EXPAND_NORMAL
);
3949 /* Expand expression EXP, which is a call to the strncat builtin.
3950 Return 0 if we failed the caller should emit a normal call,
3951 otherwise try to get the result in TARGET, if convenient. */
3954 expand_builtin_strncat (tree arglist
, rtx target
, enum machine_mode mode
)
3956 if (validate_arglist (arglist
,
3957 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
3959 tree result
= fold_builtin_strncat (arglist
);
3961 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
3966 /* Expand expression EXP, which is a call to the strspn builtin.
3967 Return 0 if we failed the caller should emit a normal call,
3968 otherwise try to get the result in TARGET, if convenient. */
3971 expand_builtin_strspn (tree arglist
, rtx target
, enum machine_mode mode
)
3973 if (validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
3975 tree result
= fold_builtin_strspn (arglist
);
3977 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
3982 /* Expand expression EXP, which is a call to the strcspn builtin.
3983 Return 0 if we failed the caller should emit a normal call,
3984 otherwise try to get the result in TARGET, if convenient. */
3987 expand_builtin_strcspn (tree arglist
, rtx target
, enum machine_mode mode
)
3989 if (validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
3991 tree result
= fold_builtin_strcspn (arglist
);
3993 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
3998 /* Expand a call to __builtin_saveregs, generating the result in TARGET,
3999 if that's convenient. */
4002 expand_builtin_saveregs (void)
4006 /* Don't do __builtin_saveregs more than once in a function.
4007 Save the result of the first call and reuse it. */
4008 if (saveregs_value
!= 0)
4009 return saveregs_value
;
4011 /* When this function is called, it means that registers must be
4012 saved on entry to this function. So we migrate the call to the
4013 first insn of this function. */
4017 /* Do whatever the machine needs done in this case. */
4018 val
= targetm
.calls
.expand_builtin_saveregs ();
4023 saveregs_value
= val
;
4025 /* Put the insns after the NOTE that starts the function. If this
4026 is inside a start_sequence, make the outer-level insn chain current, so
4027 the code is placed at the start of the function. */
4028 push_topmost_sequence ();
4029 emit_insn_after (seq
, entry_of_function ());
4030 pop_topmost_sequence ();
4035 /* __builtin_args_info (N) returns word N of the arg space info
4036 for the current function. The number and meanings of words
4037 is controlled by the definition of CUMULATIVE_ARGS. */
4040 expand_builtin_args_info (tree arglist
)
4042 int nwords
= sizeof (CUMULATIVE_ARGS
) / sizeof (int);
4043 int *word_ptr
= (int *) ¤t_function_args_info
;
4045 gcc_assert (sizeof (CUMULATIVE_ARGS
) % sizeof (int) == 0);
4049 if (!host_integerp (TREE_VALUE (arglist
), 0))
4050 error ("argument of %<__builtin_args_info%> must be constant");
4053 HOST_WIDE_INT wordnum
= tree_low_cst (TREE_VALUE (arglist
), 0);
4055 if (wordnum
< 0 || wordnum
>= nwords
)
4056 error ("argument of %<__builtin_args_info%> out of range");
4058 return GEN_INT (word_ptr
[wordnum
]);
4062 error ("missing argument in %<__builtin_args_info%>");
4067 /* Expand a call to __builtin_next_arg. */
4070 expand_builtin_next_arg (void)
4072 /* Checking arguments is already done in fold_builtin_next_arg
4073 that must be called before this function. */
4074 return expand_binop (Pmode
, add_optab
,
4075 current_function_internal_arg_pointer
,
4076 current_function_arg_offset_rtx
,
4077 NULL_RTX
, 0, OPTAB_LIB_WIDEN
);
4080 /* Make it easier for the backends by protecting the valist argument
4081 from multiple evaluations. */
4084 stabilize_va_list (tree valist
, int needs_lvalue
)
4086 if (TREE_CODE (va_list_type_node
) == ARRAY_TYPE
)
4088 if (TREE_SIDE_EFFECTS (valist
))
4089 valist
= save_expr (valist
);
4091 /* For this case, the backends will be expecting a pointer to
4092 TREE_TYPE (va_list_type_node), but it's possible we've
4093 actually been given an array (an actual va_list_type_node).
4095 if (TREE_CODE (TREE_TYPE (valist
)) == ARRAY_TYPE
)
4097 tree p1
= build_pointer_type (TREE_TYPE (va_list_type_node
));
4098 valist
= build_fold_addr_expr_with_type (valist
, p1
);
4107 if (! TREE_SIDE_EFFECTS (valist
))
4110 pt
= build_pointer_type (va_list_type_node
);
4111 valist
= fold_build1 (ADDR_EXPR
, pt
, valist
);
4112 TREE_SIDE_EFFECTS (valist
) = 1;
4115 if (TREE_SIDE_EFFECTS (valist
))
4116 valist
= save_expr (valist
);
4117 valist
= build_fold_indirect_ref (valist
);
4123 /* The "standard" definition of va_list is void*. */
4126 std_build_builtin_va_list (void)
4128 return ptr_type_node
;
4131 /* The "standard" implementation of va_start: just assign `nextarg' to
4135 std_expand_builtin_va_start (tree valist
, rtx nextarg
)
4139 t
= build2 (MODIFY_EXPR
, TREE_TYPE (valist
), valist
,
4140 make_tree (ptr_type_node
, nextarg
));
4141 TREE_SIDE_EFFECTS (t
) = 1;
4143 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
4146 /* Expand ARGLIST, from a call to __builtin_va_start. */
4149 expand_builtin_va_start (tree arglist
)
4154 chain
= TREE_CHAIN (arglist
);
4158 error ("too few arguments to function %<va_start%>");
4162 if (fold_builtin_next_arg (chain
))
4165 nextarg
= expand_builtin_next_arg ();
4166 valist
= stabilize_va_list (TREE_VALUE (arglist
), 1);
4168 #ifdef EXPAND_BUILTIN_VA_START
4169 EXPAND_BUILTIN_VA_START (valist
, nextarg
);
4171 std_expand_builtin_va_start (valist
, nextarg
);
4177 /* The "standard" implementation of va_arg: read the value from the
4178 current (padded) address and increment by the (padded) size. */
4181 std_gimplify_va_arg_expr (tree valist
, tree type
, tree
*pre_p
, tree
*post_p
)
4183 tree addr
, t
, type_size
, rounded_size
, valist_tmp
;
4184 unsigned HOST_WIDE_INT align
, boundary
;
4187 #ifdef ARGS_GROW_DOWNWARD
4188 /* All of the alignment and movement below is for args-grow-up machines.
4189 As of 2004, there are only 3 ARGS_GROW_DOWNWARD targets, and they all
4190 implement their own specialized gimplify_va_arg_expr routines. */
4194 indirect
= pass_by_reference (NULL
, TYPE_MODE (type
), type
, false);
4196 type
= build_pointer_type (type
);
4198 align
= PARM_BOUNDARY
/ BITS_PER_UNIT
;
4199 boundary
= FUNCTION_ARG_BOUNDARY (TYPE_MODE (type
), type
) / BITS_PER_UNIT
;
4201 /* Hoist the valist value into a temporary for the moment. */
4202 valist_tmp
= get_initialized_tmp_var (valist
, pre_p
, NULL
);
4204 /* va_list pointer is aligned to PARM_BOUNDARY. If argument actually
4205 requires greater alignment, we must perform dynamic alignment. */
4206 if (boundary
> align
4207 && !integer_zerop (TYPE_SIZE (type
)))
4209 t
= fold_convert (TREE_TYPE (valist
), size_int (boundary
- 1));
4210 t
= build2 (MODIFY_EXPR
, TREE_TYPE (valist
), valist_tmp
,
4211 build2 (PLUS_EXPR
, TREE_TYPE (valist
), valist_tmp
, t
));
4212 gimplify_and_add (t
, pre_p
);
4214 t
= fold_convert (TREE_TYPE (valist
), size_int (-boundary
));
4215 t
= build2 (MODIFY_EXPR
, TREE_TYPE (valist
), valist_tmp
,
4216 build2 (BIT_AND_EXPR
, TREE_TYPE (valist
), valist_tmp
, t
));
4217 gimplify_and_add (t
, pre_p
);
4222 /* If the actual alignment is less than the alignment of the type,
4223 adjust the type accordingly so that we don't assume strict alignment
4224 when deferencing the pointer. */
4225 boundary
*= BITS_PER_UNIT
;
4226 if (boundary
< TYPE_ALIGN (type
))
4228 type
= build_variant_type_copy (type
);
4229 TYPE_ALIGN (type
) = boundary
;
4232 /* Compute the rounded size of the type. */
4233 type_size
= size_in_bytes (type
);
4234 rounded_size
= round_up (type_size
, align
);
4236 /* Reduce rounded_size so it's sharable with the postqueue. */
4237 gimplify_expr (&rounded_size
, pre_p
, post_p
, is_gimple_val
, fb_rvalue
);
4241 if (PAD_VARARGS_DOWN
&& !integer_zerop (rounded_size
))
4243 /* Small args are padded downward. */
4244 t
= fold_build2 (GT_EXPR
, sizetype
, rounded_size
, size_int (align
));
4245 t
= fold_build3 (COND_EXPR
, sizetype
, t
, size_zero_node
,
4246 size_binop (MINUS_EXPR
, rounded_size
, type_size
));
4247 t
= fold_convert (TREE_TYPE (addr
), t
);
4248 addr
= fold_build2 (PLUS_EXPR
, TREE_TYPE (addr
), addr
, t
);
4251 /* Compute new value for AP. */
4252 t
= fold_convert (TREE_TYPE (valist
), rounded_size
);
4253 t
= build2 (PLUS_EXPR
, TREE_TYPE (valist
), valist_tmp
, t
);
4254 t
= build2 (MODIFY_EXPR
, TREE_TYPE (valist
), valist
, t
);
4255 gimplify_and_add (t
, pre_p
);
4257 addr
= fold_convert (build_pointer_type (type
), addr
);
4260 addr
= build_va_arg_indirect_ref (addr
);
4262 return build_va_arg_indirect_ref (addr
);
4265 /* Build an indirect-ref expression over the given TREE, which represents a
4266 piece of a va_arg() expansion. */
4268 build_va_arg_indirect_ref (tree addr
)
4270 addr
= build_fold_indirect_ref (addr
);
4272 if (flag_mudflap
) /* Don't instrument va_arg INDIRECT_REF. */
4278 /* Return a dummy expression of type TYPE in order to keep going after an
4282 dummy_object (tree type
)
4284 tree t
= convert (build_pointer_type (type
), null_pointer_node
);
4285 return build1 (INDIRECT_REF
, type
, t
);
4288 /* Gimplify __builtin_va_arg, aka VA_ARG_EXPR, which is not really a
4289 builtin function, but a very special sort of operator. */
4291 enum gimplify_status
4292 gimplify_va_arg_expr (tree
*expr_p
, tree
*pre_p
, tree
*post_p
)
4294 tree promoted_type
, want_va_type
, have_va_type
;
4295 tree valist
= TREE_OPERAND (*expr_p
, 0);
4296 tree type
= TREE_TYPE (*expr_p
);
4299 /* Verify that valist is of the proper type. */
4300 want_va_type
= va_list_type_node
;
4301 have_va_type
= TREE_TYPE (valist
);
4303 if (have_va_type
== error_mark_node
)
4306 if (TREE_CODE (want_va_type
) == ARRAY_TYPE
)
4308 /* If va_list is an array type, the argument may have decayed
4309 to a pointer type, e.g. by being passed to another function.
4310 In that case, unwrap both types so that we can compare the
4311 underlying records. */
4312 if (TREE_CODE (have_va_type
) == ARRAY_TYPE
4313 || POINTER_TYPE_P (have_va_type
))
4315 want_va_type
= TREE_TYPE (want_va_type
);
4316 have_va_type
= TREE_TYPE (have_va_type
);
4320 if (TYPE_MAIN_VARIANT (want_va_type
) != TYPE_MAIN_VARIANT (have_va_type
))
4322 error ("first argument to %<va_arg%> not of type %<va_list%>");
4326 /* Generate a diagnostic for requesting data of a type that cannot
4327 be passed through `...' due to type promotion at the call site. */
4328 else if ((promoted_type
= lang_hooks
.types
.type_promotes_to (type
))
4331 static bool gave_help
;
4333 /* Unfortunately, this is merely undefined, rather than a constraint
4334 violation, so we cannot make this an error. If this call is never
4335 executed, the program is still strictly conforming. */
4336 warning (0, "%qT is promoted to %qT when passed through %<...%>",
4337 type
, promoted_type
);
4341 warning (0, "(so you should pass %qT not %qT to %<va_arg%>)",
4342 promoted_type
, type
);
4345 /* We can, however, treat "undefined" any way we please.
4346 Call abort to encourage the user to fix the program. */
4347 inform ("if this code is reached, the program will abort");
4348 t
= build_function_call_expr (implicit_built_in_decls
[BUILT_IN_TRAP
],
4350 append_to_statement_list (t
, pre_p
);
4352 /* This is dead code, but go ahead and finish so that the
4353 mode of the result comes out right. */
4354 *expr_p
= dummy_object (type
);
4359 /* Make it easier for the backends by protecting the valist argument
4360 from multiple evaluations. */
4361 if (TREE_CODE (va_list_type_node
) == ARRAY_TYPE
)
4363 /* For this case, the backends will be expecting a pointer to
4364 TREE_TYPE (va_list_type_node), but it's possible we've
4365 actually been given an array (an actual va_list_type_node).
4367 if (TREE_CODE (TREE_TYPE (valist
)) == ARRAY_TYPE
)
4369 tree p1
= build_pointer_type (TREE_TYPE (va_list_type_node
));
4370 valist
= build_fold_addr_expr_with_type (valist
, p1
);
4372 gimplify_expr (&valist
, pre_p
, post_p
, is_gimple_val
, fb_rvalue
);
4375 gimplify_expr (&valist
, pre_p
, post_p
, is_gimple_min_lval
, fb_lvalue
);
4377 if (!targetm
.gimplify_va_arg_expr
)
4378 /* FIXME:Once most targets are converted we should merely
4379 assert this is non-null. */
4382 *expr_p
= targetm
.gimplify_va_arg_expr (valist
, type
, pre_p
, post_p
);
4387 /* Expand ARGLIST, from a call to __builtin_va_end. */
4390 expand_builtin_va_end (tree arglist
)
4392 tree valist
= TREE_VALUE (arglist
);
4394 /* Evaluate for side effects, if needed. I hate macros that don't
4396 if (TREE_SIDE_EFFECTS (valist
))
4397 expand_expr (valist
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
4402 /* Expand ARGLIST, from a call to __builtin_va_copy. We do this as a
4403 builtin rather than just as an assignment in stdarg.h because of the
4404 nastiness of array-type va_list types. */
4407 expand_builtin_va_copy (tree arglist
)
4411 dst
= TREE_VALUE (arglist
);
4412 src
= TREE_VALUE (TREE_CHAIN (arglist
));
4414 dst
= stabilize_va_list (dst
, 1);
4415 src
= stabilize_va_list (src
, 0);
4417 if (TREE_CODE (va_list_type_node
) != ARRAY_TYPE
)
4419 t
= build2 (MODIFY_EXPR
, va_list_type_node
, dst
, src
);
4420 TREE_SIDE_EFFECTS (t
) = 1;
4421 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
4425 rtx dstb
, srcb
, size
;
4427 /* Evaluate to pointers. */
4428 dstb
= expand_expr (dst
, NULL_RTX
, Pmode
, EXPAND_NORMAL
);
4429 srcb
= expand_expr (src
, NULL_RTX
, Pmode
, EXPAND_NORMAL
);
4430 size
= expand_expr (TYPE_SIZE_UNIT (va_list_type_node
), NULL_RTX
,
4431 VOIDmode
, EXPAND_NORMAL
);
4433 dstb
= convert_memory_address (Pmode
, dstb
);
4434 srcb
= convert_memory_address (Pmode
, srcb
);
4436 /* "Dereference" to BLKmode memories. */
4437 dstb
= gen_rtx_MEM (BLKmode
, dstb
);
4438 set_mem_alias_set (dstb
, get_alias_set (TREE_TYPE (TREE_TYPE (dst
))));
4439 set_mem_align (dstb
, TYPE_ALIGN (va_list_type_node
));
4440 srcb
= gen_rtx_MEM (BLKmode
, srcb
);
4441 set_mem_alias_set (srcb
, get_alias_set (TREE_TYPE (TREE_TYPE (src
))));
4442 set_mem_align (srcb
, TYPE_ALIGN (va_list_type_node
));
4445 emit_block_move (dstb
, srcb
, size
, BLOCK_OP_NORMAL
);
4451 /* Expand a call to one of the builtin functions __builtin_frame_address or
4452 __builtin_return_address. */
4455 expand_builtin_frame_address (tree fndecl
, tree arglist
)
4457 /* The argument must be a nonnegative integer constant.
4458 It counts the number of frames to scan up the stack.
4459 The value is the return address saved in that frame. */
4461 /* Warning about missing arg was already issued. */
4463 else if (! host_integerp (TREE_VALUE (arglist
), 1))
4465 if (DECL_FUNCTION_CODE (fndecl
) == BUILT_IN_FRAME_ADDRESS
)
4466 error ("invalid argument to %<__builtin_frame_address%>");
4468 error ("invalid argument to %<__builtin_return_address%>");
4474 = expand_builtin_return_addr (DECL_FUNCTION_CODE (fndecl
),
4475 tree_low_cst (TREE_VALUE (arglist
), 1));
4477 /* Some ports cannot access arbitrary stack frames. */
4480 if (DECL_FUNCTION_CODE (fndecl
) == BUILT_IN_FRAME_ADDRESS
)
4481 warning (0, "unsupported argument to %<__builtin_frame_address%>");
4483 warning (0, "unsupported argument to %<__builtin_return_address%>");
4487 /* For __builtin_frame_address, return what we've got. */
4488 if (DECL_FUNCTION_CODE (fndecl
) == BUILT_IN_FRAME_ADDRESS
)
4492 && ! CONSTANT_P (tem
))
4493 tem
= copy_to_mode_reg (Pmode
, tem
);
4498 /* Expand a call to the alloca builtin, with arguments ARGLIST. Return 0 if
4499 we failed and the caller should emit a normal call, otherwise try to get
4500 the result in TARGET, if convenient. */
4503 expand_builtin_alloca (tree arglist
, rtx target
)
4508 /* In -fmudflap-instrumented code, alloca() and __builtin_alloca()
4509 should always expand to function calls. These can be intercepted
4514 if (!validate_arglist (arglist
, INTEGER_TYPE
, VOID_TYPE
))
4517 /* Compute the argument. */
4518 op0
= expand_normal (TREE_VALUE (arglist
));
4520 /* Allocate the desired space. */
4521 result
= allocate_dynamic_stack_space (op0
, target
, BITS_PER_UNIT
);
4522 result
= convert_memory_address (ptr_mode
, result
);
4527 /* Expand a call to a unary builtin. The arguments are in ARGLIST.
4528 Return 0 if a normal call should be emitted rather than expanding the
4529 function in-line. If convenient, the result should be placed in TARGET.
4530 SUBTARGET may be used as the target for computing one of EXP's operands. */
4533 expand_builtin_unop (enum machine_mode target_mode
, tree arglist
, rtx target
,
4534 rtx subtarget
, optab op_optab
)
4537 if (!validate_arglist (arglist
, INTEGER_TYPE
, VOID_TYPE
))
4540 /* Compute the argument. */
4541 op0
= expand_expr (TREE_VALUE (arglist
), subtarget
, VOIDmode
, 0);
4542 /* Compute op, into TARGET if possible.
4543 Set TARGET to wherever the result comes back. */
4544 target
= expand_unop (TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist
))),
4545 op_optab
, op0
, target
, 1);
4546 gcc_assert (target
);
4548 return convert_to_mode (target_mode
, target
, 0);
4551 /* If the string passed to fputs is a constant and is one character
4552 long, we attempt to transform this call into __builtin_fputc(). */
4555 expand_builtin_fputs (tree arglist
, rtx target
, bool unlocked
)
4557 /* Verify the arguments in the original call. */
4558 if (validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
4560 tree result
= fold_builtin_fputs (arglist
, (target
== const0_rtx
),
4561 unlocked
, NULL_TREE
);
4563 return expand_expr (result
, target
, VOIDmode
, EXPAND_NORMAL
);
4568 /* Expand a call to __builtin_expect. We return our argument and emit a
4569 NOTE_INSN_EXPECTED_VALUE note. This is the expansion of __builtin_expect in
4570 a non-jump context. */
4573 expand_builtin_expect (tree arglist
, rtx target
)
4578 if (arglist
== NULL_TREE
4579 || TREE_CHAIN (arglist
) == NULL_TREE
)
4581 exp
= TREE_VALUE (arglist
);
4582 c
= TREE_VALUE (TREE_CHAIN (arglist
));
4584 if (TREE_CODE (c
) != INTEGER_CST
)
4586 error ("second argument to %<__builtin_expect%> must be a constant");
4587 c
= integer_zero_node
;
4590 target
= expand_expr (exp
, target
, VOIDmode
, EXPAND_NORMAL
);
4592 /* Don't bother with expected value notes for integral constants. */
4593 if (flag_guess_branch_prob
&& GET_CODE (target
) != CONST_INT
)
4595 /* We do need to force this into a register so that we can be
4596 moderately sure to be able to correctly interpret the branch
4598 target
= force_reg (GET_MODE (target
), target
);
4600 rtx_c
= expand_expr (c
, NULL_RTX
, GET_MODE (target
), EXPAND_NORMAL
);
4602 note
= emit_note (NOTE_INSN_EXPECTED_VALUE
);
4603 NOTE_EXPECTED_VALUE (note
) = gen_rtx_EQ (VOIDmode
, target
, rtx_c
);
4609 /* Like expand_builtin_expect, except do this in a jump context. This is
4610 called from do_jump if the conditional is a __builtin_expect. Return either
4611 a list of insns to emit the jump or NULL if we cannot optimize
4612 __builtin_expect. We need to optimize this at jump time so that machines
4613 like the PowerPC don't turn the test into a SCC operation, and then jump
4614 based on the test being 0/1. */
4617 expand_builtin_expect_jump (tree exp
, rtx if_false_label
, rtx if_true_label
)
4619 tree arglist
= TREE_OPERAND (exp
, 1);
4620 tree arg0
= TREE_VALUE (arglist
);
4621 tree arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
4624 /* Only handle __builtin_expect (test, 0) and
4625 __builtin_expect (test, 1). */
4626 if (TREE_CODE (TREE_TYPE (arg1
)) == INTEGER_TYPE
4627 && (integer_zerop (arg1
) || integer_onep (arg1
)))
4629 rtx insn
, drop_through_label
, temp
;
4631 /* Expand the jump insns. */
4633 do_jump (arg0
, if_false_label
, if_true_label
);
4636 drop_through_label
= get_last_insn ();
4637 if (drop_through_label
&& NOTE_P (drop_through_label
))
4638 drop_through_label
= prev_nonnote_insn (drop_through_label
);
4639 if (drop_through_label
&& !LABEL_P (drop_through_label
))
4640 drop_through_label
= NULL_RTX
;
4643 if (! if_true_label
)
4644 if_true_label
= drop_through_label
;
4645 if (! if_false_label
)
4646 if_false_label
= drop_through_label
;
4648 /* Go through and add the expect's to each of the conditional jumps. */
4650 while (insn
!= NULL_RTX
)
4652 rtx next
= NEXT_INSN (insn
);
4654 if (JUMP_P (insn
) && any_condjump_p (insn
))
4656 rtx ifelse
= SET_SRC (pc_set (insn
));
4657 rtx then_dest
= XEXP (ifelse
, 1);
4658 rtx else_dest
= XEXP (ifelse
, 2);
4661 /* First check if we recognize any of the labels. */
4662 if (GET_CODE (then_dest
) == LABEL_REF
4663 && XEXP (then_dest
, 0) == if_true_label
)
4665 else if (GET_CODE (then_dest
) == LABEL_REF
4666 && XEXP (then_dest
, 0) == if_false_label
)
4668 else if (GET_CODE (else_dest
) == LABEL_REF
4669 && XEXP (else_dest
, 0) == if_false_label
)
4671 else if (GET_CODE (else_dest
) == LABEL_REF
4672 && XEXP (else_dest
, 0) == if_true_label
)
4674 /* Otherwise check where we drop through. */
4675 else if (else_dest
== pc_rtx
)
4677 if (next
&& NOTE_P (next
))
4678 next
= next_nonnote_insn (next
);
4680 if (next
&& JUMP_P (next
)
4681 && any_uncondjump_p (next
))
4682 temp
= XEXP (SET_SRC (pc_set (next
)), 0);
4686 /* TEMP is either a CODE_LABEL, NULL_RTX or something
4687 else that can't possibly match either target label. */
4688 if (temp
== if_false_label
)
4690 else if (temp
== if_true_label
)
4693 else if (then_dest
== pc_rtx
)
4695 if (next
&& NOTE_P (next
))
4696 next
= next_nonnote_insn (next
);
4698 if (next
&& JUMP_P (next
)
4699 && any_uncondjump_p (next
))
4700 temp
= XEXP (SET_SRC (pc_set (next
)), 0);
4704 if (temp
== if_false_label
)
4706 else if (temp
== if_true_label
)
4712 /* If the test is expected to fail, reverse the
4714 if (integer_zerop (arg1
))
4716 predict_insn_def (insn
, PRED_BUILTIN_EXPECT
, taken
);
4728 expand_builtin_trap (void)
4732 emit_insn (gen_trap ());
4735 emit_library_call (abort_libfunc
, LCT_NORETURN
, VOIDmode
, 0);
4739 /* Expand a call to fabs, fabsf or fabsl with arguments ARGLIST.
4740 Return 0 if a normal call should be emitted rather than expanding
4741 the function inline. If convenient, the result should be placed
4742 in TARGET. SUBTARGET may be used as the target for computing
4746 expand_builtin_fabs (tree arglist
, rtx target
, rtx subtarget
)
4748 enum machine_mode mode
;
4752 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
4755 arg
= TREE_VALUE (arglist
);
4756 mode
= TYPE_MODE (TREE_TYPE (arg
));
4757 op0
= expand_expr (arg
, subtarget
, VOIDmode
, 0);
4758 return expand_abs (mode
, op0
, target
, 0, safe_from_p (target
, arg
, 1));
4761 /* Expand a call to copysign, copysignf, or copysignl with arguments ARGLIST.
4762 Return NULL is a normal call should be emitted rather than expanding the
4763 function inline. If convenient, the result should be placed in TARGET.
4764 SUBTARGET may be used as the target for computing the operand. */
4767 expand_builtin_copysign (tree arglist
, rtx target
, rtx subtarget
)
4772 if (!validate_arglist (arglist
, REAL_TYPE
, REAL_TYPE
, VOID_TYPE
))
4775 arg
= TREE_VALUE (arglist
);
4776 op0
= expand_expr (arg
, subtarget
, VOIDmode
, EXPAND_NORMAL
);
4778 arg
= TREE_VALUE (TREE_CHAIN (arglist
));
4779 op1
= expand_normal (arg
);
4781 return expand_copysign (op0
, op1
, target
);
4784 /* Create a new constant string literal and return a char* pointer to it.
4785 The STRING_CST value is the LEN characters at STR. */
4787 build_string_literal (int len
, const char *str
)
4789 tree t
, elem
, index
, type
;
4791 t
= build_string (len
, str
);
4792 elem
= build_type_variant (char_type_node
, 1, 0);
4793 index
= build_index_type (build_int_cst (NULL_TREE
, len
- 1));
4794 type
= build_array_type (elem
, index
);
4795 TREE_TYPE (t
) = type
;
4796 TREE_CONSTANT (t
) = 1;
4797 TREE_INVARIANT (t
) = 1;
4798 TREE_READONLY (t
) = 1;
4799 TREE_STATIC (t
) = 1;
4801 type
= build_pointer_type (type
);
4802 t
= build1 (ADDR_EXPR
, type
, t
);
4804 type
= build_pointer_type (elem
);
4805 t
= build1 (NOP_EXPR
, type
, t
);
4809 /* Expand EXP, a call to printf or printf_unlocked.
4810 Return 0 if a normal call should be emitted rather than transforming
4811 the function inline. If convenient, the result should be placed in
4812 TARGET with mode MODE. UNLOCKED indicates this is a printf_unlocked
4815 expand_builtin_printf (tree exp
, rtx target
, enum machine_mode mode
,
4818 tree arglist
= TREE_OPERAND (exp
, 1);
4819 /* If we're using an unlocked function, assume the other unlocked
4820 functions exist explicitly. */
4821 tree
const fn_putchar
= unlocked
? built_in_decls
[BUILT_IN_PUTCHAR_UNLOCKED
]
4822 : implicit_built_in_decls
[BUILT_IN_PUTCHAR
];
4823 tree
const fn_puts
= unlocked
? built_in_decls
[BUILT_IN_PUTS_UNLOCKED
]
4824 : implicit_built_in_decls
[BUILT_IN_PUTS
];
4825 const char *fmt_str
;
4828 /* If the return value is used, don't do the transformation. */
4829 if (target
!= const0_rtx
)
4832 /* Verify the required arguments in the original call. */
4835 fmt
= TREE_VALUE (arglist
);
4836 if (! POINTER_TYPE_P (TREE_TYPE (fmt
)))
4838 arglist
= TREE_CHAIN (arglist
);
4840 /* Check whether the format is a literal string constant. */
4841 fmt_str
= c_getstr (fmt
);
4842 if (fmt_str
== NULL
)
4845 if (!init_target_chars())
4848 /* If the format specifier was "%s\n", call __builtin_puts(arg). */
4849 if (strcmp (fmt_str
, target_percent_s_newline
) == 0)
4852 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist
)))
4853 || TREE_CHAIN (arglist
))
4857 /* If the format specifier was "%c", call __builtin_putchar(arg). */
4858 else if (strcmp (fmt_str
, target_percent_c
) == 0)
4861 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist
))) != INTEGER_TYPE
4862 || TREE_CHAIN (arglist
))
4868 /* We can't handle anything else with % args or %% ... yet. */
4869 if (strchr (fmt_str
, target_percent
))
4875 /* If the format specifier was "", printf does nothing. */
4876 if (fmt_str
[0] == '\0')
4878 /* If the format specifier has length of 1, call putchar. */
4879 if (fmt_str
[1] == '\0')
4881 /* Given printf("c"), (where c is any one character,)
4882 convert "c"[0] to an int and pass that to the replacement
4884 arg
= build_int_cst (NULL_TREE
, fmt_str
[0]);
4885 arglist
= build_tree_list (NULL_TREE
, arg
);
4890 /* If the format specifier was "string\n", call puts("string"). */
4891 size_t len
= strlen (fmt_str
);
4892 if ((unsigned char)fmt_str
[len
- 1] == target_newline
)
4894 /* Create a NUL-terminated string that's one char shorter
4895 than the original, stripping off the trailing '\n'. */
4896 char *newstr
= alloca (len
);
4897 memcpy (newstr
, fmt_str
, len
- 1);
4898 newstr
[len
- 1] = 0;
4900 arg
= build_string_literal (len
, newstr
);
4901 arglist
= build_tree_list (NULL_TREE
, arg
);
4905 /* We'd like to arrange to call fputs(string,stdout) here,
4906 but we need stdout and don't have a way to get it yet. */
4913 fn
= build_function_call_expr (fn
, arglist
);
4914 if (TREE_CODE (fn
) == CALL_EXPR
)
4915 CALL_EXPR_TAILCALL (fn
) = CALL_EXPR_TAILCALL (exp
);
4916 return expand_expr (fn
, target
, mode
, EXPAND_NORMAL
);
4919 /* Expand EXP, a call to fprintf or fprintf_unlocked.
4920 Return 0 if a normal call should be emitted rather than transforming
4921 the function inline. If convenient, the result should be placed in
4922 TARGET with mode MODE. UNLOCKED indicates this is a fprintf_unlocked
4925 expand_builtin_fprintf (tree exp
, rtx target
, enum machine_mode mode
,
4928 tree arglist
= TREE_OPERAND (exp
, 1);
4929 /* If we're using an unlocked function, assume the other unlocked
4930 functions exist explicitly. */
4931 tree
const fn_fputc
= unlocked
? built_in_decls
[BUILT_IN_FPUTC_UNLOCKED
]
4932 : implicit_built_in_decls
[BUILT_IN_FPUTC
];
4933 tree
const fn_fputs
= unlocked
? built_in_decls
[BUILT_IN_FPUTS_UNLOCKED
]
4934 : implicit_built_in_decls
[BUILT_IN_FPUTS
];
4935 const char *fmt_str
;
4936 tree fn
, fmt
, fp
, arg
;
4938 /* If the return value is used, don't do the transformation. */
4939 if (target
!= const0_rtx
)
4942 /* Verify the required arguments in the original call. */
4945 fp
= TREE_VALUE (arglist
);
4946 if (! POINTER_TYPE_P (TREE_TYPE (fp
)))
4948 arglist
= TREE_CHAIN (arglist
);
4951 fmt
= TREE_VALUE (arglist
);
4952 if (! POINTER_TYPE_P (TREE_TYPE (fmt
)))
4954 arglist
= TREE_CHAIN (arglist
);
4956 /* Check whether the format is a literal string constant. */
4957 fmt_str
= c_getstr (fmt
);
4958 if (fmt_str
== NULL
)
4961 if (!init_target_chars())
4964 /* If the format specifier was "%s", call __builtin_fputs(arg,fp). */
4965 if (strcmp (fmt_str
, target_percent_s
) == 0)
4968 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist
)))
4969 || TREE_CHAIN (arglist
))
4971 arg
= TREE_VALUE (arglist
);
4972 arglist
= build_tree_list (NULL_TREE
, fp
);
4973 arglist
= tree_cons (NULL_TREE
, arg
, arglist
);
4976 /* If the format specifier was "%c", call __builtin_fputc(arg,fp). */
4977 else if (strcmp (fmt_str
, target_percent_c
) == 0)
4980 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist
))) != INTEGER_TYPE
4981 || TREE_CHAIN (arglist
))
4983 arg
= TREE_VALUE (arglist
);
4984 arglist
= build_tree_list (NULL_TREE
, fp
);
4985 arglist
= tree_cons (NULL_TREE
, arg
, arglist
);
4990 /* We can't handle anything else with % args or %% ... yet. */
4991 if (strchr (fmt_str
, target_percent
))
4997 /* If the format specifier was "", fprintf does nothing. */
4998 if (fmt_str
[0] == '\0')
5000 /* Evaluate and ignore FILE* argument for side-effects. */
5001 expand_expr (fp
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
5005 /* When "string" doesn't contain %, replace all cases of
5006 fprintf(stream,string) with fputs(string,stream). The fputs
5007 builtin will take care of special cases like length == 1. */
5008 arglist
= build_tree_list (NULL_TREE
, fp
);
5009 arglist
= tree_cons (NULL_TREE
, fmt
, arglist
);
5015 fn
= build_function_call_expr (fn
, arglist
);
5016 if (TREE_CODE (fn
) == CALL_EXPR
)
5017 CALL_EXPR_TAILCALL (fn
) = CALL_EXPR_TAILCALL (exp
);
5018 return expand_expr (fn
, target
, mode
, EXPAND_NORMAL
);
5021 /* Expand a call to sprintf with argument list ARGLIST. Return 0 if
5022 a normal call should be emitted rather than expanding the function
5023 inline. If convenient, the result should be placed in TARGET with
5027 expand_builtin_sprintf (tree arglist
, rtx target
, enum machine_mode mode
)
5029 tree orig_arglist
, dest
, fmt
;
5030 const char *fmt_str
;
5032 orig_arglist
= arglist
;
5034 /* Verify the required arguments in the original call. */
5037 dest
= TREE_VALUE (arglist
);
5038 if (! POINTER_TYPE_P (TREE_TYPE (dest
)))
5040 arglist
= TREE_CHAIN (arglist
);
5043 fmt
= TREE_VALUE (arglist
);
5044 if (! POINTER_TYPE_P (TREE_TYPE (fmt
)))
5046 arglist
= TREE_CHAIN (arglist
);
5048 /* Check whether the format is a literal string constant. */
5049 fmt_str
= c_getstr (fmt
);
5050 if (fmt_str
== NULL
)
5053 if (!init_target_chars())
5056 /* If the format doesn't contain % args or %%, use strcpy. */
5057 if (strchr (fmt_str
, target_percent
) == 0)
5059 tree fn
= implicit_built_in_decls
[BUILT_IN_STRCPY
];
5062 if (arglist
|| ! fn
)
5064 expand_expr (build_function_call_expr (fn
, orig_arglist
),
5065 const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
5066 if (target
== const0_rtx
)
5068 exp
= build_int_cst (NULL_TREE
, strlen (fmt_str
));
5069 return expand_expr (exp
, target
, mode
, EXPAND_NORMAL
);
5071 /* If the format is "%s", use strcpy if the result isn't used. */
5072 else if (strcmp (fmt_str
, target_percent_s
) == 0)
5075 fn
= implicit_built_in_decls
[BUILT_IN_STRCPY
];
5080 if (! arglist
|| TREE_CHAIN (arglist
))
5082 arg
= TREE_VALUE (arglist
);
5083 if (! POINTER_TYPE_P (TREE_TYPE (arg
)))
5086 if (target
!= const0_rtx
)
5088 len
= c_strlen (arg
, 1);
5089 if (! len
|| TREE_CODE (len
) != INTEGER_CST
)
5095 arglist
= build_tree_list (NULL_TREE
, arg
);
5096 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
5097 expand_expr (build_function_call_expr (fn
, arglist
),
5098 const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
5100 if (target
== const0_rtx
)
5102 return expand_expr (len
, target
, mode
, EXPAND_NORMAL
);
5108 /* Expand a call to either the entry or exit function profiler. */
5111 expand_builtin_profile_func (bool exitp
)
5115 this = DECL_RTL (current_function_decl
);
5116 gcc_assert (MEM_P (this));
5117 this = XEXP (this, 0);
5120 which
= profile_function_exit_libfunc
;
5122 which
= profile_function_entry_libfunc
;
5124 emit_library_call (which
, LCT_NORMAL
, VOIDmode
, 2, this, Pmode
,
5125 expand_builtin_return_addr (BUILT_IN_RETURN_ADDRESS
,
5132 /* Given a trampoline address, make sure it satisfies TRAMPOLINE_ALIGNMENT. */
5135 round_trampoline_addr (rtx tramp
)
5137 rtx temp
, addend
, mask
;
5139 /* If we don't need too much alignment, we'll have been guaranteed
5140 proper alignment by get_trampoline_type. */
5141 if (TRAMPOLINE_ALIGNMENT
<= STACK_BOUNDARY
)
5144 /* Round address up to desired boundary. */
5145 temp
= gen_reg_rtx (Pmode
);
5146 addend
= GEN_INT (TRAMPOLINE_ALIGNMENT
/ BITS_PER_UNIT
- 1);
5147 mask
= GEN_INT (-TRAMPOLINE_ALIGNMENT
/ BITS_PER_UNIT
);
5149 temp
= expand_simple_binop (Pmode
, PLUS
, tramp
, addend
,
5150 temp
, 0, OPTAB_LIB_WIDEN
);
5151 tramp
= expand_simple_binop (Pmode
, AND
, temp
, mask
,
5152 temp
, 0, OPTAB_LIB_WIDEN
);
5158 expand_builtin_init_trampoline (tree arglist
)
5160 tree t_tramp
, t_func
, t_chain
;
5161 rtx r_tramp
, r_func
, r_chain
;
5162 #ifdef TRAMPOLINE_TEMPLATE
5166 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
,
5167 POINTER_TYPE
, VOID_TYPE
))
5170 t_tramp
= TREE_VALUE (arglist
);
5171 arglist
= TREE_CHAIN (arglist
);
5172 t_func
= TREE_VALUE (arglist
);
5173 arglist
= TREE_CHAIN (arglist
);
5174 t_chain
= TREE_VALUE (arglist
);
5176 r_tramp
= expand_normal (t_tramp
);
5177 r_func
= expand_normal (t_func
);
5178 r_chain
= expand_normal (t_chain
);
5180 /* Generate insns to initialize the trampoline. */
5181 r_tramp
= round_trampoline_addr (r_tramp
);
5182 #ifdef TRAMPOLINE_TEMPLATE
5183 blktramp
= gen_rtx_MEM (BLKmode
, r_tramp
);
5184 set_mem_align (blktramp
, TRAMPOLINE_ALIGNMENT
);
5185 emit_block_move (blktramp
, assemble_trampoline_template (),
5186 GEN_INT (TRAMPOLINE_SIZE
), BLOCK_OP_NORMAL
);
5188 trampolines_created
= 1;
5189 INITIALIZE_TRAMPOLINE (r_tramp
, r_func
, r_chain
);
5195 expand_builtin_adjust_trampoline (tree arglist
)
5199 if (!validate_arglist (arglist
, POINTER_TYPE
, VOID_TYPE
))
5202 tramp
= expand_normal (TREE_VALUE (arglist
));
5203 tramp
= round_trampoline_addr (tramp
);
5204 #ifdef TRAMPOLINE_ADJUST_ADDRESS
5205 TRAMPOLINE_ADJUST_ADDRESS (tramp
);
5211 /* Expand a call to the built-in signbit, signbitf or signbitl function.
5212 Return NULL_RTX if a normal call should be emitted rather than expanding
5213 the function in-line. EXP is the expression that is a call to the builtin
5214 function; if convenient, the result should be placed in TARGET. */
5217 expand_builtin_signbit (tree exp
, rtx target
)
5219 const struct real_format
*fmt
;
5220 enum machine_mode fmode
, imode
, rmode
;
5221 HOST_WIDE_INT hi
, lo
;
5226 arglist
= TREE_OPERAND (exp
, 1);
5227 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
5230 arg
= TREE_VALUE (arglist
);
5231 fmode
= TYPE_MODE (TREE_TYPE (arg
));
5232 rmode
= TYPE_MODE (TREE_TYPE (exp
));
5233 fmt
= REAL_MODE_FORMAT (fmode
);
5235 /* For floating point formats without a sign bit, implement signbit
5237 bitpos
= fmt
->signbit_ro
;
5240 /* But we can't do this if the format supports signed zero. */
5241 if (fmt
->has_signed_zero
&& HONOR_SIGNED_ZEROS (fmode
))
5244 arg
= fold_build2 (LT_EXPR
, TREE_TYPE (exp
), arg
,
5245 build_real (TREE_TYPE (arg
), dconst0
));
5246 return expand_expr (arg
, target
, VOIDmode
, EXPAND_NORMAL
);
5249 temp
= expand_normal (arg
);
5250 if (GET_MODE_SIZE (fmode
) <= UNITS_PER_WORD
)
5252 imode
= int_mode_for_mode (fmode
);
5253 if (imode
== BLKmode
)
5255 temp
= gen_lowpart (imode
, temp
);
5260 /* Handle targets with different FP word orders. */
5261 if (FLOAT_WORDS_BIG_ENDIAN
)
5262 word
= (GET_MODE_BITSIZE (fmode
) - bitpos
) / BITS_PER_WORD
;
5264 word
= bitpos
/ BITS_PER_WORD
;
5265 temp
= operand_subword_force (temp
, word
, fmode
);
5266 bitpos
= bitpos
% BITS_PER_WORD
;
5269 /* Force the intermediate word_mode (or narrower) result into a
5270 register. This avoids attempting to create paradoxical SUBREGs
5271 of floating point modes below. */
5272 temp
= force_reg (imode
, temp
);
5274 /* If the bitpos is within the "result mode" lowpart, the operation
5275 can be implement with a single bitwise AND. Otherwise, we need
5276 a right shift and an AND. */
5278 if (bitpos
< GET_MODE_BITSIZE (rmode
))
5280 if (bitpos
< HOST_BITS_PER_WIDE_INT
)
5283 lo
= (HOST_WIDE_INT
) 1 << bitpos
;
5287 hi
= (HOST_WIDE_INT
) 1 << (bitpos
- HOST_BITS_PER_WIDE_INT
);
5292 temp
= gen_lowpart (rmode
, temp
);
5293 temp
= expand_binop (rmode
, and_optab
, temp
,
5294 immed_double_const (lo
, hi
, rmode
),
5295 NULL_RTX
, 1, OPTAB_LIB_WIDEN
);
5299 /* Perform a logical right shift to place the signbit in the least
5300 significant bit, then truncate the result to the desired mode
5301 and mask just this bit. */
5302 temp
= expand_shift (RSHIFT_EXPR
, imode
, temp
,
5303 build_int_cst (NULL_TREE
, bitpos
), NULL_RTX
, 1);
5304 temp
= gen_lowpart (rmode
, temp
);
5305 temp
= expand_binop (rmode
, and_optab
, temp
, const1_rtx
,
5306 NULL_RTX
, 1, OPTAB_LIB_WIDEN
);
5312 /* Expand fork or exec calls. TARGET is the desired target of the
5313 call. ARGLIST is the list of arguments of the call. FN is the
5314 identificator of the actual function. IGNORE is nonzero if the
5315 value is to be ignored. */
5318 expand_builtin_fork_or_exec (tree fn
, tree arglist
, rtx target
, int ignore
)
5323 /* If we are not profiling, just call the function. */
5324 if (!profile_arc_flag
)
5327 /* Otherwise call the wrapper. This should be equivalent for the rest of
5328 compiler, so the code does not diverge, and the wrapper may run the
5329 code necessary for keeping the profiling sane. */
5331 switch (DECL_FUNCTION_CODE (fn
))
5334 id
= get_identifier ("__gcov_fork");
5337 case BUILT_IN_EXECL
:
5338 id
= get_identifier ("__gcov_execl");
5341 case BUILT_IN_EXECV
:
5342 id
= get_identifier ("__gcov_execv");
5345 case BUILT_IN_EXECLP
:
5346 id
= get_identifier ("__gcov_execlp");
5349 case BUILT_IN_EXECLE
:
5350 id
= get_identifier ("__gcov_execle");
5353 case BUILT_IN_EXECVP
:
5354 id
= get_identifier ("__gcov_execvp");
5357 case BUILT_IN_EXECVE
:
5358 id
= get_identifier ("__gcov_execve");
5365 decl
= build_decl (FUNCTION_DECL
, id
, TREE_TYPE (fn
));
5366 DECL_EXTERNAL (decl
) = 1;
5367 TREE_PUBLIC (decl
) = 1;
5368 DECL_ARTIFICIAL (decl
) = 1;
5369 TREE_NOTHROW (decl
) = 1;
5370 call
= build_function_call_expr (decl
, arglist
);
5372 return expand_call (call
, target
, ignore
);
5376 /* Reconstitute a mode for a __sync intrinsic operation. Since the type of
5377 the pointer in these functions is void*, the tree optimizers may remove
5378 casts. The mode computed in expand_builtin isn't reliable either, due
5379 to __sync_bool_compare_and_swap.
5381 FCODE_DIFF should be fcode - base, where base is the FOO_1 code for the
5382 group of builtins. This gives us log2 of the mode size. */
5384 static inline enum machine_mode
5385 get_builtin_sync_mode (int fcode_diff
)
5387 /* The size is not negotiable, so ask not to get BLKmode in return
5388 if the target indicates that a smaller size would be better. */
5389 return mode_for_size (BITS_PER_UNIT
<< fcode_diff
, MODE_INT
, 0);
5392 /* Expand the memory expression LOC and return the appropriate memory operand
5393 for the builtin_sync operations. */
5396 get_builtin_sync_mem (tree loc
, enum machine_mode mode
)
5400 addr
= expand_expr (loc
, NULL
, Pmode
, EXPAND_SUM
);
5402 /* Note that we explicitly do not want any alias information for this
5403 memory, so that we kill all other live memories. Otherwise we don't
5404 satisfy the full barrier semantics of the intrinsic. */
5405 mem
= validize_mem (gen_rtx_MEM (mode
, addr
));
5407 set_mem_align (mem
, get_pointer_alignment (loc
, BIGGEST_ALIGNMENT
));
5408 set_mem_alias_set (mem
, ALIAS_SET_MEMORY_BARRIER
);
5409 MEM_VOLATILE_P (mem
) = 1;
5414 /* Expand the __sync_xxx_and_fetch and __sync_fetch_and_xxx intrinsics.
5415 ARGLIST is the operands list to the function. CODE is the rtx code
5416 that corresponds to the arithmetic or logical operation from the name;
5417 an exception here is that NOT actually means NAND. TARGET is an optional
5418 place for us to store the results; AFTER is true if this is the
5419 fetch_and_xxx form. IGNORE is true if we don't actually care about
5420 the result of the operation at all. */
5423 expand_builtin_sync_operation (enum machine_mode mode
, tree arglist
,
5424 enum rtx_code code
, bool after
,
5425 rtx target
, bool ignore
)
5429 /* Expand the operands. */
5430 mem
= get_builtin_sync_mem (TREE_VALUE (arglist
), mode
);
5432 arglist
= TREE_CHAIN (arglist
);
5433 val
= expand_expr (TREE_VALUE (arglist
), NULL
, mode
, EXPAND_NORMAL
);
5436 return expand_sync_operation (mem
, val
, code
);
5438 return expand_sync_fetch_operation (mem
, val
, code
, after
, target
);
5441 /* Expand the __sync_val_compare_and_swap and __sync_bool_compare_and_swap
5442 intrinsics. ARGLIST is the operands list to the function. IS_BOOL is
5443 true if this is the boolean form. TARGET is a place for us to store the
5444 results; this is NOT optional if IS_BOOL is true. */
5447 expand_builtin_compare_and_swap (enum machine_mode mode
, tree arglist
,
5448 bool is_bool
, rtx target
)
5450 rtx old_val
, new_val
, mem
;
5452 /* Expand the operands. */
5453 mem
= get_builtin_sync_mem (TREE_VALUE (arglist
), mode
);
5455 arglist
= TREE_CHAIN (arglist
);
5456 old_val
= expand_expr (TREE_VALUE (arglist
), NULL
, mode
, EXPAND_NORMAL
);
5458 arglist
= TREE_CHAIN (arglist
);
5459 new_val
= expand_expr (TREE_VALUE (arglist
), NULL
, mode
, EXPAND_NORMAL
);
5462 return expand_bool_compare_and_swap (mem
, old_val
, new_val
, target
);
5464 return expand_val_compare_and_swap (mem
, old_val
, new_val
, target
);
5467 /* Expand the __sync_lock_test_and_set intrinsic. Note that the most
5468 general form is actually an atomic exchange, and some targets only
5469 support a reduced form with the second argument being a constant 1.
5470 ARGLIST is the operands list to the function; TARGET is an optional
5471 place for us to store the results. */
5474 expand_builtin_lock_test_and_set (enum machine_mode mode
, tree arglist
,
5479 /* Expand the operands. */
5480 mem
= get_builtin_sync_mem (TREE_VALUE (arglist
), mode
);
5482 arglist
= TREE_CHAIN (arglist
);
5483 val
= expand_expr (TREE_VALUE (arglist
), NULL
, mode
, EXPAND_NORMAL
);
5485 return expand_sync_lock_test_and_set (mem
, val
, target
);
5488 /* Expand the __sync_synchronize intrinsic. */
5491 expand_builtin_synchronize (void)
5495 #ifdef HAVE_memory_barrier
5496 if (HAVE_memory_barrier
)
5498 emit_insn (gen_memory_barrier ());
5503 /* If no explicit memory barrier instruction is available, create an
5504 empty asm stmt with a memory clobber. */
5505 x
= build4 (ASM_EXPR
, void_type_node
, build_string (0, ""), NULL
, NULL
,
5506 tree_cons (NULL
, build_string (6, "memory"), NULL
));
5507 ASM_VOLATILE_P (x
) = 1;
5508 expand_asm_expr (x
);
5511 /* Expand the __sync_lock_release intrinsic. ARGLIST is the operands list
5515 expand_builtin_lock_release (enum machine_mode mode
, tree arglist
)
5517 enum insn_code icode
;
5519 rtx val
= const0_rtx
;
5521 /* Expand the operands. */
5522 mem
= get_builtin_sync_mem (TREE_VALUE (arglist
), mode
);
5524 /* If there is an explicit operation in the md file, use it. */
5525 icode
= sync_lock_release
[mode
];
5526 if (icode
!= CODE_FOR_nothing
)
5528 if (!insn_data
[icode
].operand
[1].predicate (val
, mode
))
5529 val
= force_reg (mode
, val
);
5531 insn
= GEN_FCN (icode
) (mem
, val
);
5539 /* Otherwise we can implement this operation by emitting a barrier
5540 followed by a store of zero. */
5541 expand_builtin_synchronize ();
5542 emit_move_insn (mem
, val
);
5545 /* Expand an expression EXP that calls a built-in function,
5546 with result going to TARGET if that's convenient
5547 (and in mode MODE if that's convenient).
5548 SUBTARGET may be used as the target for computing one of EXP's operands.
5549 IGNORE is nonzero if the value is to be ignored. */
5552 expand_builtin (tree exp
, rtx target
, rtx subtarget
, enum machine_mode mode
,
5555 tree fndecl
= get_callee_fndecl (exp
);
5556 tree arglist
= TREE_OPERAND (exp
, 1);
5557 enum built_in_function fcode
= DECL_FUNCTION_CODE (fndecl
);
5558 enum machine_mode target_mode
= TYPE_MODE (TREE_TYPE (exp
));
5560 if (DECL_BUILT_IN_CLASS (fndecl
) == BUILT_IN_MD
)
5561 return targetm
.expand_builtin (exp
, target
, subtarget
, mode
, ignore
);
5564 /* Try expanding the builtin via the generic target hook. */
5565 rtx tmp
= targetm
.expand_library_builtin (exp
, target
, subtarget
,
5567 if (tmp
!= NULL_RTX
)
5571 /* When not optimizing, generate calls to library functions for a certain
5574 && !called_as_built_in (fndecl
)
5575 && DECL_ASSEMBLER_NAME_SET_P (fndecl
)
5576 && fcode
!= BUILT_IN_ALLOCA
)
5577 return expand_call (exp
, target
, ignore
);
5579 /* The built-in function expanders test for target == const0_rtx
5580 to determine whether the function's result will be ignored. */
5582 target
= const0_rtx
;
5584 /* If the result of a pure or const built-in function is ignored, and
5585 none of its arguments are volatile, we can avoid expanding the
5586 built-in call and just evaluate the arguments for side-effects. */
5587 if (target
== const0_rtx
5588 && (DECL_IS_PURE (fndecl
) || TREE_READONLY (fndecl
)))
5590 bool volatilep
= false;
5593 for (arg
= arglist
; arg
; arg
= TREE_CHAIN (arg
))
5594 if (TREE_THIS_VOLATILE (TREE_VALUE (arg
)))
5602 for (arg
= arglist
; arg
; arg
= TREE_CHAIN (arg
))
5603 expand_expr (TREE_VALUE (arg
), const0_rtx
,
5604 VOIDmode
, EXPAND_NORMAL
);
5611 CASE_FLT_FN (BUILT_IN_FABS
):
5612 target
= expand_builtin_fabs (arglist
, target
, subtarget
);
5617 CASE_FLT_FN (BUILT_IN_COPYSIGN
):
5618 target
= expand_builtin_copysign (arglist
, target
, subtarget
);
5623 /* Just do a normal library call if we were unable to fold
5625 CASE_FLT_FN (BUILT_IN_CABS
):
5628 CASE_FLT_FN (BUILT_IN_EXP
):
5629 CASE_FLT_FN (BUILT_IN_EXP10
):
5630 CASE_FLT_FN (BUILT_IN_POW10
):
5631 CASE_FLT_FN (BUILT_IN_EXP2
):
5632 CASE_FLT_FN (BUILT_IN_EXPM1
):
5633 CASE_FLT_FN (BUILT_IN_LOGB
):
5634 CASE_FLT_FN (BUILT_IN_ILOGB
):
5635 CASE_FLT_FN (BUILT_IN_LOG
):
5636 CASE_FLT_FN (BUILT_IN_LOG10
):
5637 CASE_FLT_FN (BUILT_IN_LOG2
):
5638 CASE_FLT_FN (BUILT_IN_LOG1P
):
5639 CASE_FLT_FN (BUILT_IN_TAN
):
5640 CASE_FLT_FN (BUILT_IN_ASIN
):
5641 CASE_FLT_FN (BUILT_IN_ACOS
):
5642 CASE_FLT_FN (BUILT_IN_ATAN
):
5643 /* Treat these like sqrt only if unsafe math optimizations are allowed,
5644 because of possible accuracy problems. */
5645 if (! flag_unsafe_math_optimizations
)
5647 CASE_FLT_FN (BUILT_IN_SQRT
):
5648 CASE_FLT_FN (BUILT_IN_FLOOR
):
5649 CASE_FLT_FN (BUILT_IN_CEIL
):
5650 CASE_FLT_FN (BUILT_IN_TRUNC
):
5651 CASE_FLT_FN (BUILT_IN_ROUND
):
5652 CASE_FLT_FN (BUILT_IN_NEARBYINT
):
5653 CASE_FLT_FN (BUILT_IN_RINT
):
5654 CASE_FLT_FN (BUILT_IN_LRINT
):
5655 CASE_FLT_FN (BUILT_IN_LLRINT
):
5656 target
= expand_builtin_mathfn (exp
, target
, subtarget
);
5661 CASE_FLT_FN (BUILT_IN_LCEIL
):
5662 CASE_FLT_FN (BUILT_IN_LLCEIL
):
5663 CASE_FLT_FN (BUILT_IN_LFLOOR
):
5664 CASE_FLT_FN (BUILT_IN_LLFLOOR
):
5665 target
= expand_builtin_int_roundingfn (exp
, target
, subtarget
);
5670 CASE_FLT_FN (BUILT_IN_POW
):
5671 target
= expand_builtin_pow (exp
, target
, subtarget
);
5676 CASE_FLT_FN (BUILT_IN_POWI
):
5677 target
= expand_builtin_powi (exp
, target
, subtarget
);
5682 CASE_FLT_FN (BUILT_IN_ATAN2
):
5683 CASE_FLT_FN (BUILT_IN_LDEXP
):
5684 CASE_FLT_FN (BUILT_IN_FMOD
):
5685 CASE_FLT_FN (BUILT_IN_DREM
):
5686 if (! flag_unsafe_math_optimizations
)
5688 target
= expand_builtin_mathfn_2 (exp
, target
, subtarget
);
5693 CASE_FLT_FN (BUILT_IN_SIN
):
5694 CASE_FLT_FN (BUILT_IN_COS
):
5695 if (! flag_unsafe_math_optimizations
)
5697 target
= expand_builtin_mathfn_3 (exp
, target
, subtarget
);
5702 CASE_FLT_FN (BUILT_IN_SINCOS
):
5703 if (! flag_unsafe_math_optimizations
)
5705 target
= expand_builtin_sincos (exp
);
5710 case BUILT_IN_APPLY_ARGS
:
5711 return expand_builtin_apply_args ();
5713 /* __builtin_apply (FUNCTION, ARGUMENTS, ARGSIZE) invokes
5714 FUNCTION with a copy of the parameters described by
5715 ARGUMENTS, and ARGSIZE. It returns a block of memory
5716 allocated on the stack into which is stored all the registers
5717 that might possibly be used for returning the result of a
5718 function. ARGUMENTS is the value returned by
5719 __builtin_apply_args. ARGSIZE is the number of bytes of
5720 arguments that must be copied. ??? How should this value be
5721 computed? We'll also need a safe worst case value for varargs
5723 case BUILT_IN_APPLY
:
5724 if (!validate_arglist (arglist
, POINTER_TYPE
,
5725 POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
)
5726 && !validate_arglist (arglist
, REFERENCE_TYPE
,
5727 POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
5735 for (t
= arglist
, i
= 0; t
; t
= TREE_CHAIN (t
), i
++)
5736 ops
[i
] = expand_normal (TREE_VALUE (t
));
5738 return expand_builtin_apply (ops
[0], ops
[1], ops
[2]);
5741 /* __builtin_return (RESULT) causes the function to return the
5742 value described by RESULT. RESULT is address of the block of
5743 memory returned by __builtin_apply. */
5744 case BUILT_IN_RETURN
:
5745 if (validate_arglist (arglist
, POINTER_TYPE
, VOID_TYPE
))
5746 expand_builtin_return (expand_normal (TREE_VALUE (arglist
)));
5749 case BUILT_IN_SAVEREGS
:
5750 return expand_builtin_saveregs ();
5752 case BUILT_IN_ARGS_INFO
:
5753 return expand_builtin_args_info (arglist
);
5755 /* Return the address of the first anonymous stack arg. */
5756 case BUILT_IN_NEXT_ARG
:
5757 if (fold_builtin_next_arg (arglist
))
5759 return expand_builtin_next_arg ();
5761 case BUILT_IN_CLASSIFY_TYPE
:
5762 return expand_builtin_classify_type (arglist
);
5764 case BUILT_IN_CONSTANT_P
:
5767 case BUILT_IN_FRAME_ADDRESS
:
5768 case BUILT_IN_RETURN_ADDRESS
:
5769 return expand_builtin_frame_address (fndecl
, arglist
);
5771 /* Returns the address of the area where the structure is returned.
5773 case BUILT_IN_AGGREGATE_INCOMING_ADDRESS
:
5775 || ! AGGREGATE_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl
)))
5776 || !MEM_P (DECL_RTL (DECL_RESULT (current_function_decl
))))
5779 return XEXP (DECL_RTL (DECL_RESULT (current_function_decl
)), 0);
5781 case BUILT_IN_ALLOCA
:
5782 target
= expand_builtin_alloca (arglist
, target
);
5787 case BUILT_IN_STACK_SAVE
:
5788 return expand_stack_save ();
5790 case BUILT_IN_STACK_RESTORE
:
5791 expand_stack_restore (TREE_VALUE (arglist
));
5794 CASE_INT_FN (BUILT_IN_FFS
):
5795 case BUILT_IN_FFSIMAX
:
5796 target
= expand_builtin_unop (target_mode
, arglist
, target
,
5797 subtarget
, ffs_optab
);
5802 CASE_INT_FN (BUILT_IN_CLZ
):
5803 case BUILT_IN_CLZIMAX
:
5804 target
= expand_builtin_unop (target_mode
, arglist
, target
,
5805 subtarget
, clz_optab
);
5810 CASE_INT_FN (BUILT_IN_CTZ
):
5811 case BUILT_IN_CTZIMAX
:
5812 target
= expand_builtin_unop (target_mode
, arglist
, target
,
5813 subtarget
, ctz_optab
);
5818 CASE_INT_FN (BUILT_IN_POPCOUNT
):
5819 case BUILT_IN_POPCOUNTIMAX
:
5820 target
= expand_builtin_unop (target_mode
, arglist
, target
,
5821 subtarget
, popcount_optab
);
5826 CASE_INT_FN (BUILT_IN_PARITY
):
5827 case BUILT_IN_PARITYIMAX
:
5828 target
= expand_builtin_unop (target_mode
, arglist
, target
,
5829 subtarget
, parity_optab
);
5834 case BUILT_IN_STRLEN
:
5835 target
= expand_builtin_strlen (arglist
, target
, target_mode
);
5840 case BUILT_IN_STRCPY
:
5841 target
= expand_builtin_strcpy (fndecl
, arglist
, target
, mode
);
5846 case BUILT_IN_STRNCPY
:
5847 target
= expand_builtin_strncpy (exp
, target
, mode
);
5852 case BUILT_IN_STPCPY
:
5853 target
= expand_builtin_stpcpy (exp
, target
, mode
);
5858 case BUILT_IN_STRCAT
:
5859 target
= expand_builtin_strcat (fndecl
, arglist
, target
, mode
);
5864 case BUILT_IN_STRNCAT
:
5865 target
= expand_builtin_strncat (arglist
, target
, mode
);
5870 case BUILT_IN_STRSPN
:
5871 target
= expand_builtin_strspn (arglist
, target
, mode
);
5876 case BUILT_IN_STRCSPN
:
5877 target
= expand_builtin_strcspn (arglist
, target
, mode
);
5882 case BUILT_IN_STRSTR
:
5883 target
= expand_builtin_strstr (arglist
, TREE_TYPE (exp
), target
, mode
);
5888 case BUILT_IN_STRPBRK
:
5889 target
= expand_builtin_strpbrk (arglist
, TREE_TYPE (exp
), target
, mode
);
5894 case BUILT_IN_INDEX
:
5895 case BUILT_IN_STRCHR
:
5896 target
= expand_builtin_strchr (arglist
, TREE_TYPE (exp
), target
, mode
);
5901 case BUILT_IN_RINDEX
:
5902 case BUILT_IN_STRRCHR
:
5903 target
= expand_builtin_strrchr (arglist
, TREE_TYPE (exp
), target
, mode
);
5908 case BUILT_IN_MEMCPY
:
5909 target
= expand_builtin_memcpy (exp
, target
, mode
);
5914 case BUILT_IN_MEMPCPY
:
5915 target
= expand_builtin_mempcpy (arglist
, TREE_TYPE (exp
), target
, mode
, /*endp=*/ 1);
5920 case BUILT_IN_MEMMOVE
:
5921 target
= expand_builtin_memmove (arglist
, TREE_TYPE (exp
), target
,
5927 case BUILT_IN_BCOPY
:
5928 target
= expand_builtin_bcopy (exp
);
5933 case BUILT_IN_MEMSET
:
5934 target
= expand_builtin_memset (arglist
, target
, mode
, exp
);
5939 case BUILT_IN_BZERO
:
5940 target
= expand_builtin_bzero (exp
);
5945 case BUILT_IN_STRCMP
:
5946 target
= expand_builtin_strcmp (exp
, target
, mode
);
5951 case BUILT_IN_STRNCMP
:
5952 target
= expand_builtin_strncmp (exp
, target
, mode
);
5958 case BUILT_IN_MEMCMP
:
5959 target
= expand_builtin_memcmp (exp
, arglist
, target
, mode
);
5964 case BUILT_IN_SETJMP
:
5965 target
= expand_builtin_setjmp (arglist
, target
);
5970 /* __builtin_longjmp is passed a pointer to an array of five words.
5971 It's similar to the C library longjmp function but works with
5972 __builtin_setjmp above. */
5973 case BUILT_IN_LONGJMP
:
5974 if (!validate_arglist (arglist
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
5978 rtx buf_addr
= expand_expr (TREE_VALUE (arglist
), subtarget
,
5979 VOIDmode
, EXPAND_NORMAL
);
5980 rtx value
= expand_normal (TREE_VALUE (TREE_CHAIN (arglist
)));
5982 if (value
!= const1_rtx
)
5984 error ("%<__builtin_longjmp%> second argument must be 1");
5988 expand_builtin_longjmp (buf_addr
, value
);
5992 case BUILT_IN_NONLOCAL_GOTO
:
5993 target
= expand_builtin_nonlocal_goto (arglist
);
5998 /* This updates the setjmp buffer that is its argument with the value
5999 of the current stack pointer. */
6000 case BUILT_IN_UPDATE_SETJMP_BUF
:
6001 if (validate_arglist (arglist
, POINTER_TYPE
, VOID_TYPE
))
6004 = expand_normal (TREE_VALUE (arglist
));
6006 expand_builtin_update_setjmp_buf (buf_addr
);
6012 expand_builtin_trap ();
6015 case BUILT_IN_PRINTF
:
6016 target
= expand_builtin_printf (exp
, target
, mode
, false);
6021 case BUILT_IN_PRINTF_UNLOCKED
:
6022 target
= expand_builtin_printf (exp
, target
, mode
, true);
6027 case BUILT_IN_FPUTS
:
6028 target
= expand_builtin_fputs (arglist
, target
, false);
6032 case BUILT_IN_FPUTS_UNLOCKED
:
6033 target
= expand_builtin_fputs (arglist
, target
, true);
6038 case BUILT_IN_FPRINTF
:
6039 target
= expand_builtin_fprintf (exp
, target
, mode
, false);
6044 case BUILT_IN_FPRINTF_UNLOCKED
:
6045 target
= expand_builtin_fprintf (exp
, target
, mode
, true);
6050 case BUILT_IN_SPRINTF
:
6051 target
= expand_builtin_sprintf (arglist
, target
, mode
);
6056 CASE_FLT_FN (BUILT_IN_SIGNBIT
):
6057 target
= expand_builtin_signbit (exp
, target
);
6062 /* Various hooks for the DWARF 2 __throw routine. */
6063 case BUILT_IN_UNWIND_INIT
:
6064 expand_builtin_unwind_init ();
6066 case BUILT_IN_DWARF_CFA
:
6067 return virtual_cfa_rtx
;
6068 #ifdef DWARF2_UNWIND_INFO
6069 case BUILT_IN_DWARF_SP_COLUMN
:
6070 return expand_builtin_dwarf_sp_column ();
6071 case BUILT_IN_INIT_DWARF_REG_SIZES
:
6072 expand_builtin_init_dwarf_reg_sizes (TREE_VALUE (arglist
));
6075 case BUILT_IN_FROB_RETURN_ADDR
:
6076 return expand_builtin_frob_return_addr (TREE_VALUE (arglist
));
6077 case BUILT_IN_EXTRACT_RETURN_ADDR
:
6078 return expand_builtin_extract_return_addr (TREE_VALUE (arglist
));
6079 case BUILT_IN_EH_RETURN
:
6080 expand_builtin_eh_return (TREE_VALUE (arglist
),
6081 TREE_VALUE (TREE_CHAIN (arglist
)));
6083 #ifdef EH_RETURN_DATA_REGNO
6084 case BUILT_IN_EH_RETURN_DATA_REGNO
:
6085 return expand_builtin_eh_return_data_regno (arglist
);
6087 case BUILT_IN_EXTEND_POINTER
:
6088 return expand_builtin_extend_pointer (TREE_VALUE (arglist
));
6090 case BUILT_IN_VA_START
:
6091 case BUILT_IN_STDARG_START
:
6092 return expand_builtin_va_start (arglist
);
6093 case BUILT_IN_VA_END
:
6094 return expand_builtin_va_end (arglist
);
6095 case BUILT_IN_VA_COPY
:
6096 return expand_builtin_va_copy (arglist
);
6097 case BUILT_IN_EXPECT
:
6098 return expand_builtin_expect (arglist
, target
);
6099 case BUILT_IN_PREFETCH
:
6100 expand_builtin_prefetch (arglist
);
6103 case BUILT_IN_PROFILE_FUNC_ENTER
:
6104 return expand_builtin_profile_func (false);
6105 case BUILT_IN_PROFILE_FUNC_EXIT
:
6106 return expand_builtin_profile_func (true);
6108 case BUILT_IN_INIT_TRAMPOLINE
:
6109 return expand_builtin_init_trampoline (arglist
);
6110 case BUILT_IN_ADJUST_TRAMPOLINE
:
6111 return expand_builtin_adjust_trampoline (arglist
);
6114 case BUILT_IN_EXECL
:
6115 case BUILT_IN_EXECV
:
6116 case BUILT_IN_EXECLP
:
6117 case BUILT_IN_EXECLE
:
6118 case BUILT_IN_EXECVP
:
6119 case BUILT_IN_EXECVE
:
6120 target
= expand_builtin_fork_or_exec (fndecl
, arglist
, target
, ignore
);
6125 case BUILT_IN_FETCH_AND_ADD_1
:
6126 case BUILT_IN_FETCH_AND_ADD_2
:
6127 case BUILT_IN_FETCH_AND_ADD_4
:
6128 case BUILT_IN_FETCH_AND_ADD_8
:
6129 case BUILT_IN_FETCH_AND_ADD_16
:
6130 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_FETCH_AND_ADD_1
);
6131 target
= expand_builtin_sync_operation (mode
, arglist
, PLUS
,
6132 false, target
, ignore
);
6137 case BUILT_IN_FETCH_AND_SUB_1
:
6138 case BUILT_IN_FETCH_AND_SUB_2
:
6139 case BUILT_IN_FETCH_AND_SUB_4
:
6140 case BUILT_IN_FETCH_AND_SUB_8
:
6141 case BUILT_IN_FETCH_AND_SUB_16
:
6142 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_FETCH_AND_SUB_1
);
6143 target
= expand_builtin_sync_operation (mode
, arglist
, MINUS
,
6144 false, target
, ignore
);
6149 case BUILT_IN_FETCH_AND_OR_1
:
6150 case BUILT_IN_FETCH_AND_OR_2
:
6151 case BUILT_IN_FETCH_AND_OR_4
:
6152 case BUILT_IN_FETCH_AND_OR_8
:
6153 case BUILT_IN_FETCH_AND_OR_16
:
6154 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_FETCH_AND_OR_1
);
6155 target
= expand_builtin_sync_operation (mode
, arglist
, IOR
,
6156 false, target
, ignore
);
6161 case BUILT_IN_FETCH_AND_AND_1
:
6162 case BUILT_IN_FETCH_AND_AND_2
:
6163 case BUILT_IN_FETCH_AND_AND_4
:
6164 case BUILT_IN_FETCH_AND_AND_8
:
6165 case BUILT_IN_FETCH_AND_AND_16
:
6166 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_FETCH_AND_AND_1
);
6167 target
= expand_builtin_sync_operation (mode
, arglist
, AND
,
6168 false, target
, ignore
);
6173 case BUILT_IN_FETCH_AND_XOR_1
:
6174 case BUILT_IN_FETCH_AND_XOR_2
:
6175 case BUILT_IN_FETCH_AND_XOR_4
:
6176 case BUILT_IN_FETCH_AND_XOR_8
:
6177 case BUILT_IN_FETCH_AND_XOR_16
:
6178 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_FETCH_AND_XOR_1
);
6179 target
= expand_builtin_sync_operation (mode
, arglist
, XOR
,
6180 false, target
, ignore
);
6185 case BUILT_IN_FETCH_AND_NAND_1
:
6186 case BUILT_IN_FETCH_AND_NAND_2
:
6187 case BUILT_IN_FETCH_AND_NAND_4
:
6188 case BUILT_IN_FETCH_AND_NAND_8
:
6189 case BUILT_IN_FETCH_AND_NAND_16
:
6190 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_FETCH_AND_NAND_1
);
6191 target
= expand_builtin_sync_operation (mode
, arglist
, NOT
,
6192 false, target
, ignore
);
6197 case BUILT_IN_ADD_AND_FETCH_1
:
6198 case BUILT_IN_ADD_AND_FETCH_2
:
6199 case BUILT_IN_ADD_AND_FETCH_4
:
6200 case BUILT_IN_ADD_AND_FETCH_8
:
6201 case BUILT_IN_ADD_AND_FETCH_16
:
6202 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_ADD_AND_FETCH_1
);
6203 target
= expand_builtin_sync_operation (mode
, arglist
, PLUS
,
6204 true, target
, ignore
);
6209 case BUILT_IN_SUB_AND_FETCH_1
:
6210 case BUILT_IN_SUB_AND_FETCH_2
:
6211 case BUILT_IN_SUB_AND_FETCH_4
:
6212 case BUILT_IN_SUB_AND_FETCH_8
:
6213 case BUILT_IN_SUB_AND_FETCH_16
:
6214 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_SUB_AND_FETCH_1
);
6215 target
= expand_builtin_sync_operation (mode
, arglist
, MINUS
,
6216 true, target
, ignore
);
6221 case BUILT_IN_OR_AND_FETCH_1
:
6222 case BUILT_IN_OR_AND_FETCH_2
:
6223 case BUILT_IN_OR_AND_FETCH_4
:
6224 case BUILT_IN_OR_AND_FETCH_8
:
6225 case BUILT_IN_OR_AND_FETCH_16
:
6226 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_OR_AND_FETCH_1
);
6227 target
= expand_builtin_sync_operation (mode
, arglist
, IOR
,
6228 true, target
, ignore
);
6233 case BUILT_IN_AND_AND_FETCH_1
:
6234 case BUILT_IN_AND_AND_FETCH_2
:
6235 case BUILT_IN_AND_AND_FETCH_4
:
6236 case BUILT_IN_AND_AND_FETCH_8
:
6237 case BUILT_IN_AND_AND_FETCH_16
:
6238 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_AND_AND_FETCH_1
);
6239 target
= expand_builtin_sync_operation (mode
, arglist
, AND
,
6240 true, target
, ignore
);
6245 case BUILT_IN_XOR_AND_FETCH_1
:
6246 case BUILT_IN_XOR_AND_FETCH_2
:
6247 case BUILT_IN_XOR_AND_FETCH_4
:
6248 case BUILT_IN_XOR_AND_FETCH_8
:
6249 case BUILT_IN_XOR_AND_FETCH_16
:
6250 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_XOR_AND_FETCH_1
);
6251 target
= expand_builtin_sync_operation (mode
, arglist
, XOR
,
6252 true, target
, ignore
);
6257 case BUILT_IN_NAND_AND_FETCH_1
:
6258 case BUILT_IN_NAND_AND_FETCH_2
:
6259 case BUILT_IN_NAND_AND_FETCH_4
:
6260 case BUILT_IN_NAND_AND_FETCH_8
:
6261 case BUILT_IN_NAND_AND_FETCH_16
:
6262 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_NAND_AND_FETCH_1
);
6263 target
= expand_builtin_sync_operation (mode
, arglist
, NOT
,
6264 true, target
, ignore
);
6269 case BUILT_IN_BOOL_COMPARE_AND_SWAP_1
:
6270 case BUILT_IN_BOOL_COMPARE_AND_SWAP_2
:
6271 case BUILT_IN_BOOL_COMPARE_AND_SWAP_4
:
6272 case BUILT_IN_BOOL_COMPARE_AND_SWAP_8
:
6273 case BUILT_IN_BOOL_COMPARE_AND_SWAP_16
:
6274 if (mode
== VOIDmode
)
6275 mode
= TYPE_MODE (boolean_type_node
);
6276 if (!target
|| !register_operand (target
, mode
))
6277 target
= gen_reg_rtx (mode
);
6279 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_BOOL_COMPARE_AND_SWAP_1
);
6280 target
= expand_builtin_compare_and_swap (mode
, arglist
, true, target
);
6285 case BUILT_IN_VAL_COMPARE_AND_SWAP_1
:
6286 case BUILT_IN_VAL_COMPARE_AND_SWAP_2
:
6287 case BUILT_IN_VAL_COMPARE_AND_SWAP_4
:
6288 case BUILT_IN_VAL_COMPARE_AND_SWAP_8
:
6289 case BUILT_IN_VAL_COMPARE_AND_SWAP_16
:
6290 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_VAL_COMPARE_AND_SWAP_1
);
6291 target
= expand_builtin_compare_and_swap (mode
, arglist
, false, target
);
6296 case BUILT_IN_LOCK_TEST_AND_SET_1
:
6297 case BUILT_IN_LOCK_TEST_AND_SET_2
:
6298 case BUILT_IN_LOCK_TEST_AND_SET_4
:
6299 case BUILT_IN_LOCK_TEST_AND_SET_8
:
6300 case BUILT_IN_LOCK_TEST_AND_SET_16
:
6301 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_LOCK_TEST_AND_SET_1
);
6302 target
= expand_builtin_lock_test_and_set (mode
, arglist
, target
);
6307 case BUILT_IN_LOCK_RELEASE_1
:
6308 case BUILT_IN_LOCK_RELEASE_2
:
6309 case BUILT_IN_LOCK_RELEASE_4
:
6310 case BUILT_IN_LOCK_RELEASE_8
:
6311 case BUILT_IN_LOCK_RELEASE_16
:
6312 mode
= get_builtin_sync_mode (fcode
- BUILT_IN_LOCK_RELEASE_1
);
6313 expand_builtin_lock_release (mode
, arglist
);
6316 case BUILT_IN_SYNCHRONIZE
:
6317 expand_builtin_synchronize ();
6320 case BUILT_IN_OBJECT_SIZE
:
6321 return expand_builtin_object_size (exp
);
6323 case BUILT_IN_MEMCPY_CHK
:
6324 case BUILT_IN_MEMPCPY_CHK
:
6325 case BUILT_IN_MEMMOVE_CHK
:
6326 case BUILT_IN_MEMSET_CHK
:
6327 target
= expand_builtin_memory_chk (exp
, target
, mode
, fcode
);
6332 case BUILT_IN_STRCPY_CHK
:
6333 case BUILT_IN_STPCPY_CHK
:
6334 case BUILT_IN_STRNCPY_CHK
:
6335 case BUILT_IN_STRCAT_CHK
:
6336 case BUILT_IN_SNPRINTF_CHK
:
6337 case BUILT_IN_VSNPRINTF_CHK
:
6338 maybe_emit_chk_warning (exp
, fcode
);
6341 case BUILT_IN_SPRINTF_CHK
:
6342 case BUILT_IN_VSPRINTF_CHK
:
6343 maybe_emit_sprintf_chk_warning (exp
, fcode
);
6346 default: /* just do library call, if unknown builtin */
6350 /* The switch statement above can drop through to cause the function
6351 to be called normally. */
6352 return expand_call (exp
, target
, ignore
);
6355 /* Determine whether a tree node represents a call to a built-in
6356 function. If the tree T is a call to a built-in function with
6357 the right number of arguments of the appropriate types, return
6358 the DECL_FUNCTION_CODE of the call, e.g. BUILT_IN_SQRT.
6359 Otherwise the return value is END_BUILTINS. */
6361 enum built_in_function
6362 builtin_mathfn_code (tree t
)
6364 tree fndecl
, arglist
, parmlist
;
6365 tree argtype
, parmtype
;
6367 if (TREE_CODE (t
) != CALL_EXPR
6368 || TREE_CODE (TREE_OPERAND (t
, 0)) != ADDR_EXPR
)
6369 return END_BUILTINS
;
6371 fndecl
= get_callee_fndecl (t
);
6372 if (fndecl
== NULL_TREE
6373 || TREE_CODE (fndecl
) != FUNCTION_DECL
6374 || ! DECL_BUILT_IN (fndecl
)
6375 || DECL_BUILT_IN_CLASS (fndecl
) == BUILT_IN_MD
)
6376 return END_BUILTINS
;
6378 arglist
= TREE_OPERAND (t
, 1);
6379 parmlist
= TYPE_ARG_TYPES (TREE_TYPE (fndecl
));
6380 for (; parmlist
; parmlist
= TREE_CHAIN (parmlist
))
6382 /* If a function doesn't take a variable number of arguments,
6383 the last element in the list will have type `void'. */
6384 parmtype
= TREE_VALUE (parmlist
);
6385 if (VOID_TYPE_P (parmtype
))
6388 return END_BUILTINS
;
6389 return DECL_FUNCTION_CODE (fndecl
);
6393 return END_BUILTINS
;
6395 argtype
= TREE_TYPE (TREE_VALUE (arglist
));
6397 if (SCALAR_FLOAT_TYPE_P (parmtype
))
6399 if (! SCALAR_FLOAT_TYPE_P (argtype
))
6400 return END_BUILTINS
;
6402 else if (COMPLEX_FLOAT_TYPE_P (parmtype
))
6404 if (! COMPLEX_FLOAT_TYPE_P (argtype
))
6405 return END_BUILTINS
;
6407 else if (POINTER_TYPE_P (parmtype
))
6409 if (! POINTER_TYPE_P (argtype
))
6410 return END_BUILTINS
;
6412 else if (INTEGRAL_TYPE_P (parmtype
))
6414 if (! INTEGRAL_TYPE_P (argtype
))
6415 return END_BUILTINS
;
6418 return END_BUILTINS
;
6420 arglist
= TREE_CHAIN (arglist
);
6423 /* Variable-length argument list. */
6424 return DECL_FUNCTION_CODE (fndecl
);
6427 /* Fold a call to __builtin_constant_p, if we know it will evaluate to a
6428 constant. ARGLIST is the argument list of the call. */
6431 fold_builtin_constant_p (tree arglist
)
6436 arglist
= TREE_VALUE (arglist
);
6438 /* We return 1 for a numeric type that's known to be a constant
6439 value at compile-time or for an aggregate type that's a
6440 literal constant. */
6441 STRIP_NOPS (arglist
);
6443 /* If we know this is a constant, emit the constant of one. */
6444 if (CONSTANT_CLASS_P (arglist
)
6445 || (TREE_CODE (arglist
) == CONSTRUCTOR
6446 && TREE_CONSTANT (arglist
)))
6447 return integer_one_node
;
6448 if (TREE_CODE (arglist
) == ADDR_EXPR
)
6450 tree op
= TREE_OPERAND (arglist
, 0);
6451 if (TREE_CODE (op
) == STRING_CST
6452 || (TREE_CODE (op
) == ARRAY_REF
6453 && integer_zerop (TREE_OPERAND (op
, 1))
6454 && TREE_CODE (TREE_OPERAND (op
, 0)) == STRING_CST
))
6455 return integer_one_node
;
6458 /* If this expression has side effects, show we don't know it to be a
6459 constant. Likewise if it's a pointer or aggregate type since in
6460 those case we only want literals, since those are only optimized
6461 when generating RTL, not later.
6462 And finally, if we are compiling an initializer, not code, we
6463 need to return a definite result now; there's not going to be any
6464 more optimization done. */
6465 if (TREE_SIDE_EFFECTS (arglist
)
6466 || AGGREGATE_TYPE_P (TREE_TYPE (arglist
))
6467 || POINTER_TYPE_P (TREE_TYPE (arglist
))
6469 return integer_zero_node
;
6474 /* Fold a call to __builtin_expect, if we expect that a comparison against
6475 the argument will fold to a constant. In practice, this means a true
6476 constant or the address of a non-weak symbol. ARGLIST is the argument
6477 list of the call. */
6480 fold_builtin_expect (tree arglist
)
6487 arg
= TREE_VALUE (arglist
);
6489 /* If the argument isn't invariant, then there's nothing we can do. */
6490 if (!TREE_INVARIANT (arg
))
6493 /* If we're looking at an address of a weak decl, then do not fold. */
6496 if (TREE_CODE (inner
) == ADDR_EXPR
)
6500 inner
= TREE_OPERAND (inner
, 0);
6502 while (TREE_CODE (inner
) == COMPONENT_REF
6503 || TREE_CODE (inner
) == ARRAY_REF
);
6504 if (DECL_P (inner
) && DECL_WEAK (inner
))
6508 /* Otherwise, ARG already has the proper type for the return value. */
6512 /* Fold a call to __builtin_classify_type. */
6515 fold_builtin_classify_type (tree arglist
)
6518 return build_int_cst (NULL_TREE
, no_type_class
);
6520 return build_int_cst (NULL_TREE
,
6521 type_to_class (TREE_TYPE (TREE_VALUE (arglist
))));
6524 /* Fold a call to __builtin_strlen. */
6527 fold_builtin_strlen (tree arglist
)
6529 if (!validate_arglist (arglist
, POINTER_TYPE
, VOID_TYPE
))
6533 tree len
= c_strlen (TREE_VALUE (arglist
), 0);
6537 /* Convert from the internal "sizetype" type to "size_t". */
6539 len
= fold_convert (size_type_node
, len
);
6547 /* Fold a call to __builtin_inf or __builtin_huge_val. */
6550 fold_builtin_inf (tree type
, int warn
)
6552 REAL_VALUE_TYPE real
;
6554 /* __builtin_inff is intended to be usable to define INFINITY on all
6555 targets. If an infinity is not available, INFINITY expands "to a
6556 positive constant of type float that overflows at translation
6557 time", footnote "In this case, using INFINITY will violate the
6558 constraint in 6.4.4 and thus require a diagnostic." (C99 7.12#4).
6559 Thus we pedwarn to ensure this constraint violation is
6561 if (!MODE_HAS_INFINITIES (TYPE_MODE (type
)) && warn
)
6562 pedwarn ("target format does not support infinity");
6565 return build_real (type
, real
);
6568 /* Fold a call to __builtin_nan or __builtin_nans. */
6571 fold_builtin_nan (tree arglist
, tree type
, int quiet
)
6573 REAL_VALUE_TYPE real
;
6576 if (!validate_arglist (arglist
, POINTER_TYPE
, VOID_TYPE
))
6578 str
= c_getstr (TREE_VALUE (arglist
));
6582 if (!real_nan (&real
, str
, quiet
, TYPE_MODE (type
)))
6585 return build_real (type
, real
);
6588 /* Return true if the floating point expression T has an integer value.
6589 We also allow +Inf, -Inf and NaN to be considered integer values. */
6592 integer_valued_real_p (tree t
)
6594 switch (TREE_CODE (t
))
6601 case NON_LVALUE_EXPR
:
6602 return integer_valued_real_p (TREE_OPERAND (t
, 0));
6607 return integer_valued_real_p (TREE_OPERAND (t
, 1));
6614 return integer_valued_real_p (TREE_OPERAND (t
, 0))
6615 && integer_valued_real_p (TREE_OPERAND (t
, 1));
6618 return integer_valued_real_p (TREE_OPERAND (t
, 1))
6619 && integer_valued_real_p (TREE_OPERAND (t
, 2));
6622 if (! TREE_CONSTANT_OVERFLOW (t
))
6624 REAL_VALUE_TYPE c
, cint
;
6626 c
= TREE_REAL_CST (t
);
6627 real_trunc (&cint
, TYPE_MODE (TREE_TYPE (t
)), &c
);
6628 return real_identical (&c
, &cint
);
6634 tree type
= TREE_TYPE (TREE_OPERAND (t
, 0));
6635 if (TREE_CODE (type
) == INTEGER_TYPE
)
6637 if (TREE_CODE (type
) == REAL_TYPE
)
6638 return integer_valued_real_p (TREE_OPERAND (t
, 0));
6643 switch (builtin_mathfn_code (t
))
6645 CASE_FLT_FN (BUILT_IN_CEIL
):
6646 CASE_FLT_FN (BUILT_IN_FLOOR
):
6647 CASE_FLT_FN (BUILT_IN_NEARBYINT
):
6648 CASE_FLT_FN (BUILT_IN_RINT
):
6649 CASE_FLT_FN (BUILT_IN_ROUND
):
6650 CASE_FLT_FN (BUILT_IN_TRUNC
):
6664 /* EXP is assumed to be builtin call where truncation can be propagated
6665 across (for instance floor((double)f) == (double)floorf (f).
6666 Do the transformation. */
6669 fold_trunc_transparent_mathfn (tree fndecl
, tree arglist
)
6671 enum built_in_function fcode
= DECL_FUNCTION_CODE (fndecl
);
6674 if (! validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
6677 arg
= TREE_VALUE (arglist
);
6678 /* Integer rounding functions are idempotent. */
6679 if (fcode
== builtin_mathfn_code (arg
))
6682 /* If argument is already integer valued, and we don't need to worry
6683 about setting errno, there's no need to perform rounding. */
6684 if (! flag_errno_math
&& integer_valued_real_p (arg
))
6689 tree arg0
= strip_float_extensions (arg
);
6690 tree ftype
= TREE_TYPE (TREE_TYPE (fndecl
));
6691 tree newtype
= TREE_TYPE (arg0
);
6694 if (TYPE_PRECISION (newtype
) < TYPE_PRECISION (ftype
)
6695 && (decl
= mathfn_built_in (newtype
, fcode
)))
6698 build_tree_list (NULL_TREE
, fold_convert (newtype
, arg0
));
6699 return fold_convert (ftype
,
6700 build_function_call_expr (decl
, arglist
));
6706 /* EXP is assumed to be builtin call which can narrow the FP type of
6707 the argument, for instance lround((double)f) -> lroundf (f). */
6710 fold_fixed_mathfn (tree fndecl
, tree arglist
)
6712 enum built_in_function fcode
= DECL_FUNCTION_CODE (fndecl
);
6715 if (! validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
6718 arg
= TREE_VALUE (arglist
);
6720 /* If argument is already integer valued, and we don't need to worry
6721 about setting errno, there's no need to perform rounding. */
6722 if (! flag_errno_math
&& integer_valued_real_p (arg
))
6723 return fold_build1 (FIX_TRUNC_EXPR
, TREE_TYPE (TREE_TYPE (fndecl
)), arg
);
6727 tree ftype
= TREE_TYPE (arg
);
6728 tree arg0
= strip_float_extensions (arg
);
6729 tree newtype
= TREE_TYPE (arg0
);
6732 if (TYPE_PRECISION (newtype
) < TYPE_PRECISION (ftype
)
6733 && (decl
= mathfn_built_in (newtype
, fcode
)))
6736 build_tree_list (NULL_TREE
, fold_convert (newtype
, arg0
));
6737 return build_function_call_expr (decl
, arglist
);
6743 /* Fold function call to builtin cabs, cabsf or cabsl. ARGLIST
6744 is the argument list and TYPE is the return type. Return
6745 NULL_TREE if no if no simplification can be made. */
6748 fold_builtin_cabs (tree arglist
, tree type
)
6752 if (!arglist
|| TREE_CHAIN (arglist
))
6755 arg
= TREE_VALUE (arglist
);
6756 if (TREE_CODE (TREE_TYPE (arg
)) != COMPLEX_TYPE
6757 || TREE_CODE (TREE_TYPE (TREE_TYPE (arg
))) != REAL_TYPE
)
6760 /* Evaluate cabs of a constant at compile-time. */
6761 if (flag_unsafe_math_optimizations
6762 && TREE_CODE (arg
) == COMPLEX_CST
6763 && TREE_CODE (TREE_REALPART (arg
)) == REAL_CST
6764 && TREE_CODE (TREE_IMAGPART (arg
)) == REAL_CST
6765 && ! TREE_CONSTANT_OVERFLOW (TREE_REALPART (arg
))
6766 && ! TREE_CONSTANT_OVERFLOW (TREE_IMAGPART (arg
)))
6768 REAL_VALUE_TYPE r
, i
;
6770 r
= TREE_REAL_CST (TREE_REALPART (arg
));
6771 i
= TREE_REAL_CST (TREE_IMAGPART (arg
));
6773 real_arithmetic (&r
, MULT_EXPR
, &r
, &r
);
6774 real_arithmetic (&i
, MULT_EXPR
, &i
, &i
);
6775 real_arithmetic (&r
, PLUS_EXPR
, &r
, &i
);
6776 if (real_sqrt (&r
, TYPE_MODE (type
), &r
)
6777 || ! flag_trapping_math
)
6778 return build_real (type
, r
);
6781 /* If either part is zero, cabs is fabs of the other. */
6782 if (TREE_CODE (arg
) == COMPLEX_EXPR
6783 && real_zerop (TREE_OPERAND (arg
, 0)))
6784 return fold_build1 (ABS_EXPR
, type
, TREE_OPERAND (arg
, 1));
6785 if (TREE_CODE (arg
) == COMPLEX_EXPR
6786 && real_zerop (TREE_OPERAND (arg
, 1)))
6787 return fold_build1 (ABS_EXPR
, type
, TREE_OPERAND (arg
, 0));
6789 /* Don't do this when optimizing for size. */
6790 if (flag_unsafe_math_optimizations
6791 && optimize
&& !optimize_size
)
6793 tree sqrtfn
= mathfn_built_in (type
, BUILT_IN_SQRT
);
6795 if (sqrtfn
!= NULL_TREE
)
6797 tree rpart
, ipart
, result
, arglist
;
6799 arg
= builtin_save_expr (arg
);
6801 rpart
= fold_build1 (REALPART_EXPR
, type
, arg
);
6802 ipart
= fold_build1 (IMAGPART_EXPR
, type
, arg
);
6804 rpart
= builtin_save_expr (rpart
);
6805 ipart
= builtin_save_expr (ipart
);
6807 result
= fold_build2 (PLUS_EXPR
, type
,
6808 fold_build2 (MULT_EXPR
, type
,
6810 fold_build2 (MULT_EXPR
, type
,
6813 arglist
= build_tree_list (NULL_TREE
, result
);
6814 return build_function_call_expr (sqrtfn
, arglist
);
6821 /* Fold a builtin function call to sqrt, sqrtf, or sqrtl. Return
6822 NULL_TREE if no simplification can be made. */
6825 fold_builtin_sqrt (tree arglist
, tree type
)
6828 enum built_in_function fcode
;
6829 tree arg
= TREE_VALUE (arglist
);
6831 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
6834 /* Optimize sqrt of constant value. */
6835 if (TREE_CODE (arg
) == REAL_CST
6836 && ! TREE_CONSTANT_OVERFLOW (arg
))
6838 REAL_VALUE_TYPE r
, x
;
6840 x
= TREE_REAL_CST (arg
);
6841 if (real_sqrt (&r
, TYPE_MODE (type
), &x
)
6842 || (!flag_trapping_math
&& !flag_errno_math
))
6843 return build_real (type
, r
);
6846 /* Optimize sqrt(expN(x)) = expN(x*0.5). */
6847 fcode
= builtin_mathfn_code (arg
);
6848 if (flag_unsafe_math_optimizations
&& BUILTIN_EXPONENT_P (fcode
))
6850 tree expfn
= TREE_OPERAND (TREE_OPERAND (arg
, 0), 0);
6851 arg
= fold_build2 (MULT_EXPR
, type
,
6852 TREE_VALUE (TREE_OPERAND (arg
, 1)),
6853 build_real (type
, dconsthalf
));
6854 arglist
= build_tree_list (NULL_TREE
, arg
);
6855 return build_function_call_expr (expfn
, arglist
);
6858 /* Optimize sqrt(Nroot(x)) -> pow(x,1/(2*N)). */
6859 if (flag_unsafe_math_optimizations
&& BUILTIN_ROOT_P (fcode
))
6861 tree powfn
= mathfn_built_in (type
, BUILT_IN_POW
);
6865 tree arg0
= TREE_VALUE (TREE_OPERAND (arg
, 1));
6867 /* The inner root was either sqrt or cbrt. */
6868 REAL_VALUE_TYPE dconstroot
=
6869 BUILTIN_SQRT_P (fcode
) ? dconsthalf
: dconstthird
;
6871 /* Adjust for the outer root. */
6872 SET_REAL_EXP (&dconstroot
, REAL_EXP (&dconstroot
) - 1);
6873 dconstroot
= real_value_truncate (TYPE_MODE (type
), dconstroot
);
6874 tree_root
= build_real (type
, dconstroot
);
6875 arglist
= tree_cons (NULL_TREE
, arg0
,
6876 build_tree_list (NULL_TREE
, tree_root
));
6877 return build_function_call_expr (powfn
, arglist
);
6881 /* Optimize sqrt(pow(x,y)) = pow(|x|,y*0.5). */
6882 if (flag_unsafe_math_optimizations
6883 && (fcode
== BUILT_IN_POW
6884 || fcode
== BUILT_IN_POWF
6885 || fcode
== BUILT_IN_POWL
))
6887 tree powfn
= TREE_OPERAND (TREE_OPERAND (arg
, 0), 0);
6888 tree arg0
= TREE_VALUE (TREE_OPERAND (arg
, 1));
6889 tree arg1
= TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg
, 1)));
6891 if (!tree_expr_nonnegative_p (arg0
))
6892 arg0
= build1 (ABS_EXPR
, type
, arg0
);
6893 narg1
= fold_build2 (MULT_EXPR
, type
, arg1
,
6894 build_real (type
, dconsthalf
));
6895 arglist
= tree_cons (NULL_TREE
, arg0
,
6896 build_tree_list (NULL_TREE
, narg1
));
6897 return build_function_call_expr (powfn
, arglist
);
6903 /* Fold a builtin function call to cbrt, cbrtf, or cbrtl. Return
6904 NULL_TREE if no simplification can be made. */
6906 fold_builtin_cbrt (tree arglist
, tree type
)
6908 tree arg
= TREE_VALUE (arglist
);
6909 const enum built_in_function fcode
= builtin_mathfn_code (arg
);
6911 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
6914 /* Optimize cbrt of constant value. */
6915 if (real_zerop (arg
) || real_onep (arg
) || real_minus_onep (arg
))
6918 if (flag_unsafe_math_optimizations
)
6920 /* Optimize cbrt(expN(x)) -> expN(x/3). */
6921 if (BUILTIN_EXPONENT_P (fcode
))
6923 tree expfn
= TREE_OPERAND (TREE_OPERAND (arg
, 0), 0);
6924 const REAL_VALUE_TYPE third_trunc
=
6925 real_value_truncate (TYPE_MODE (type
), dconstthird
);
6926 arg
= fold_build2 (MULT_EXPR
, type
,
6927 TREE_VALUE (TREE_OPERAND (arg
, 1)),
6928 build_real (type
, third_trunc
));
6929 arglist
= build_tree_list (NULL_TREE
, arg
);
6930 return build_function_call_expr (expfn
, arglist
);
6933 /* Optimize cbrt(sqrt(x)) -> pow(x,1/6). */
6934 if (BUILTIN_SQRT_P (fcode
))
6936 tree powfn
= mathfn_built_in (type
, BUILT_IN_POW
);
6940 tree arg0
= TREE_VALUE (TREE_OPERAND (arg
, 1));
6942 REAL_VALUE_TYPE dconstroot
= dconstthird
;
6944 SET_REAL_EXP (&dconstroot
, REAL_EXP (&dconstroot
) - 1);
6945 dconstroot
= real_value_truncate (TYPE_MODE (type
), dconstroot
);
6946 tree_root
= build_real (type
, dconstroot
);
6947 arglist
= tree_cons (NULL_TREE
, arg0
,
6948 build_tree_list (NULL_TREE
, tree_root
));
6949 return build_function_call_expr (powfn
, arglist
);
6953 /* Optimize cbrt(cbrt(x)) -> pow(x,1/9) iff x is nonnegative. */
6954 if (BUILTIN_CBRT_P (fcode
))
6956 tree arg0
= TREE_VALUE (TREE_OPERAND (arg
, 1));
6957 if (tree_expr_nonnegative_p (arg0
))
6959 tree powfn
= mathfn_built_in (type
, BUILT_IN_POW
);
6964 REAL_VALUE_TYPE dconstroot
;
6966 real_arithmetic (&dconstroot
, MULT_EXPR
, &dconstthird
, &dconstthird
);
6967 dconstroot
= real_value_truncate (TYPE_MODE (type
), dconstroot
);
6968 tree_root
= build_real (type
, dconstroot
);
6969 arglist
= tree_cons (NULL_TREE
, arg0
,
6970 build_tree_list (NULL_TREE
, tree_root
));
6971 return build_function_call_expr (powfn
, arglist
);
6976 /* Optimize cbrt(pow(x,y)) -> pow(x,y/3) iff x is nonnegative. */
6977 if (fcode
== BUILT_IN_POW
|| fcode
== BUILT_IN_POWF
6978 || fcode
== BUILT_IN_POWL
)
6980 tree arg00
= TREE_VALUE (TREE_OPERAND (arg
, 1));
6981 tree arg01
= TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg
, 1)));
6982 if (tree_expr_nonnegative_p (arg00
))
6984 tree powfn
= TREE_OPERAND (TREE_OPERAND (arg
, 0), 0);
6985 const REAL_VALUE_TYPE dconstroot
6986 = real_value_truncate (TYPE_MODE (type
), dconstthird
);
6987 tree narg01
= fold_build2 (MULT_EXPR
, type
, arg01
,
6988 build_real (type
, dconstroot
));
6989 arglist
= tree_cons (NULL_TREE
, arg00
,
6990 build_tree_list (NULL_TREE
, narg01
));
6991 return build_function_call_expr (powfn
, arglist
);
6998 /* Fold function call to builtin sin, sinf, or sinl. Return
6999 NULL_TREE if no simplification can be made. */
7001 fold_builtin_sin (tree arglist
)
7003 tree arg
= TREE_VALUE (arglist
);
7005 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
7008 /* Optimize sin (0.0) = 0.0. */
7009 if (real_zerop (arg
))
7015 /* Fold function call to builtin cos, cosf, or cosl. Return
7016 NULL_TREE if no simplification can be made. */
7018 fold_builtin_cos (tree arglist
, tree type
, tree fndecl
)
7020 tree arg
= TREE_VALUE (arglist
);
7022 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
7025 /* Optimize cos (0.0) = 1.0. */
7026 if (real_zerop (arg
))
7027 return build_real (type
, dconst1
);
7029 /* Optimize cos(-x) into cos (x). */
7030 if (TREE_CODE (arg
) == NEGATE_EXPR
)
7032 tree args
= build_tree_list (NULL_TREE
,
7033 TREE_OPERAND (arg
, 0));
7034 return build_function_call_expr (fndecl
, args
);
7040 /* Fold function call to builtin tan, tanf, or tanl. Return
7041 NULL_TREE if no simplification can be made. */
7043 fold_builtin_tan (tree arglist
)
7045 enum built_in_function fcode
;
7046 tree arg
= TREE_VALUE (arglist
);
7048 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
7051 /* Optimize tan(0.0) = 0.0. */
7052 if (real_zerop (arg
))
7055 /* Optimize tan(atan(x)) = x. */
7056 fcode
= builtin_mathfn_code (arg
);
7057 if (flag_unsafe_math_optimizations
7058 && (fcode
== BUILT_IN_ATAN
7059 || fcode
== BUILT_IN_ATANF
7060 || fcode
== BUILT_IN_ATANL
))
7061 return TREE_VALUE (TREE_OPERAND (arg
, 1));
7066 /* Fold function call to builtin atan, atanf, or atanl. Return
7067 NULL_TREE if no simplification can be made. */
7070 fold_builtin_atan (tree arglist
, tree type
)
7073 tree arg
= TREE_VALUE (arglist
);
7075 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
7078 /* Optimize atan(0.0) = 0.0. */
7079 if (real_zerop (arg
))
7082 /* Optimize atan(1.0) = pi/4. */
7083 if (real_onep (arg
))
7085 REAL_VALUE_TYPE cst
;
7087 real_convert (&cst
, TYPE_MODE (type
), &dconstpi
);
7088 SET_REAL_EXP (&cst
, REAL_EXP (&cst
) - 2);
7089 return build_real (type
, cst
);
7095 /* Fold function call to builtin trunc, truncf or truncl. Return
7096 NULL_TREE if no simplification can be made. */
7099 fold_builtin_trunc (tree fndecl
, tree arglist
)
7103 if (! validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
7106 /* Optimize trunc of constant value. */
7107 arg
= TREE_VALUE (arglist
);
7108 if (TREE_CODE (arg
) == REAL_CST
&& ! TREE_CONSTANT_OVERFLOW (arg
))
7110 REAL_VALUE_TYPE r
, x
;
7111 tree type
= TREE_TYPE (TREE_TYPE (fndecl
));
7113 x
= TREE_REAL_CST (arg
);
7114 real_trunc (&r
, TYPE_MODE (type
), &x
);
7115 return build_real (type
, r
);
7118 return fold_trunc_transparent_mathfn (fndecl
, arglist
);
7121 /* Fold function call to builtin floor, floorf or floorl. Return
7122 NULL_TREE if no simplification can be made. */
7125 fold_builtin_floor (tree fndecl
, tree arglist
)
7129 if (! validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
7132 /* Optimize floor of constant value. */
7133 arg
= TREE_VALUE (arglist
);
7134 if (TREE_CODE (arg
) == REAL_CST
&& ! TREE_CONSTANT_OVERFLOW (arg
))
7138 x
= TREE_REAL_CST (arg
);
7139 if (! REAL_VALUE_ISNAN (x
) || ! flag_errno_math
)
7141 tree type
= TREE_TYPE (TREE_TYPE (fndecl
));
7144 real_floor (&r
, TYPE_MODE (type
), &x
);
7145 return build_real (type
, r
);
7149 return fold_trunc_transparent_mathfn (fndecl
, arglist
);
7152 /* Fold function call to builtin ceil, ceilf or ceill. Return
7153 NULL_TREE if no simplification can be made. */
7156 fold_builtin_ceil (tree fndecl
, tree arglist
)
7160 if (! validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
7163 /* Optimize ceil of constant value. */
7164 arg
= TREE_VALUE (arglist
);
7165 if (TREE_CODE (arg
) == REAL_CST
&& ! TREE_CONSTANT_OVERFLOW (arg
))
7169 x
= TREE_REAL_CST (arg
);
7170 if (! REAL_VALUE_ISNAN (x
) || ! flag_errno_math
)
7172 tree type
= TREE_TYPE (TREE_TYPE (fndecl
));
7175 real_ceil (&r
, TYPE_MODE (type
), &x
);
7176 return build_real (type
, r
);
7180 return fold_trunc_transparent_mathfn (fndecl
, arglist
);
7183 /* Fold function call to builtin round, roundf or roundl. Return
7184 NULL_TREE if no simplification can be made. */
7187 fold_builtin_round (tree fndecl
, tree arglist
)
7191 if (! validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
7194 /* Optimize round of constant value. */
7195 arg
= TREE_VALUE (arglist
);
7196 if (TREE_CODE (arg
) == REAL_CST
&& ! TREE_CONSTANT_OVERFLOW (arg
))
7200 x
= TREE_REAL_CST (arg
);
7201 if (! REAL_VALUE_ISNAN (x
) || ! flag_errno_math
)
7203 tree type
= TREE_TYPE (TREE_TYPE (fndecl
));
7206 real_round (&r
, TYPE_MODE (type
), &x
);
7207 return build_real (type
, r
);
7211 return fold_trunc_transparent_mathfn (fndecl
, arglist
);
7214 /* Fold function call to builtin lround, lroundf or lroundl (or the
7215 corresponding long long versions) and other rounding functions.
7216 Return NULL_TREE if no simplification can be made. */
7219 fold_builtin_int_roundingfn (tree fndecl
, tree arglist
)
7223 if (! validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
7226 /* Optimize lround of constant value. */
7227 arg
= TREE_VALUE (arglist
);
7228 if (TREE_CODE (arg
) == REAL_CST
&& ! TREE_CONSTANT_OVERFLOW (arg
))
7230 const REAL_VALUE_TYPE x
= TREE_REAL_CST (arg
);
7232 if (! REAL_VALUE_ISNAN (x
) && ! REAL_VALUE_ISINF (x
))
7234 tree itype
= TREE_TYPE (TREE_TYPE (fndecl
));
7235 tree ftype
= TREE_TYPE (arg
), result
;
7236 HOST_WIDE_INT hi
, lo
;
7239 switch (DECL_FUNCTION_CODE (fndecl
))
7241 CASE_FLT_FN (BUILT_IN_LFLOOR
):
7242 CASE_FLT_FN (BUILT_IN_LLFLOOR
):
7243 real_floor (&r
, TYPE_MODE (ftype
), &x
);
7246 CASE_FLT_FN (BUILT_IN_LCEIL
):
7247 CASE_FLT_FN (BUILT_IN_LLCEIL
):
7248 real_ceil (&r
, TYPE_MODE (ftype
), &x
);
7251 CASE_FLT_FN (BUILT_IN_LROUND
):
7252 CASE_FLT_FN (BUILT_IN_LLROUND
):
7253 real_round (&r
, TYPE_MODE (ftype
), &x
);
7260 REAL_VALUE_TO_INT (&lo
, &hi
, r
);
7261 result
= build_int_cst_wide (NULL_TREE
, lo
, hi
);
7262 if (int_fits_type_p (result
, itype
))
7263 return fold_convert (itype
, result
);
7267 return fold_fixed_mathfn (fndecl
, arglist
);
7270 /* Fold function call to builtin ffs, clz, ctz, popcount and parity
7271 and their long and long long variants (i.e. ffsl and ffsll).
7272 Return NULL_TREE if no simplification can be made. */
7275 fold_builtin_bitop (tree fndecl
, tree arglist
)
7279 if (! validate_arglist (arglist
, INTEGER_TYPE
, VOID_TYPE
))
7282 /* Optimize for constant argument. */
7283 arg
= TREE_VALUE (arglist
);
7284 if (TREE_CODE (arg
) == INTEGER_CST
&& ! TREE_CONSTANT_OVERFLOW (arg
))
7286 HOST_WIDE_INT hi
, width
, result
;
7287 unsigned HOST_WIDE_INT lo
;
7290 type
= TREE_TYPE (arg
);
7291 width
= TYPE_PRECISION (type
);
7292 lo
= TREE_INT_CST_LOW (arg
);
7294 /* Clear all the bits that are beyond the type's precision. */
7295 if (width
> HOST_BITS_PER_WIDE_INT
)
7297 hi
= TREE_INT_CST_HIGH (arg
);
7298 if (width
< 2 * HOST_BITS_PER_WIDE_INT
)
7299 hi
&= ~((HOST_WIDE_INT
) (-1) >> (width
- HOST_BITS_PER_WIDE_INT
));
7304 if (width
< HOST_BITS_PER_WIDE_INT
)
7305 lo
&= ~((unsigned HOST_WIDE_INT
) (-1) << width
);
7308 switch (DECL_FUNCTION_CODE (fndecl
))
7310 CASE_INT_FN (BUILT_IN_FFS
):
7312 result
= exact_log2 (lo
& -lo
) + 1;
7314 result
= HOST_BITS_PER_WIDE_INT
+ exact_log2 (hi
& -hi
) + 1;
7319 CASE_INT_FN (BUILT_IN_CLZ
):
7321 result
= width
- floor_log2 (hi
) - 1 - HOST_BITS_PER_WIDE_INT
;
7323 result
= width
- floor_log2 (lo
) - 1;
7324 else if (! CLZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type
), result
))
7328 CASE_INT_FN (BUILT_IN_CTZ
):
7330 result
= exact_log2 (lo
& -lo
);
7332 result
= HOST_BITS_PER_WIDE_INT
+ exact_log2 (hi
& -hi
);
7333 else if (! CTZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type
), result
))
7337 CASE_INT_FN (BUILT_IN_POPCOUNT
):
7340 result
++, lo
&= lo
- 1;
7342 result
++, hi
&= hi
- 1;
7345 CASE_INT_FN (BUILT_IN_PARITY
):
7348 result
++, lo
&= lo
- 1;
7350 result
++, hi
&= hi
- 1;
7358 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl
)), result
);
7364 /* Return true if EXPR is the real constant contained in VALUE. */
7367 real_dconstp (tree expr
, const REAL_VALUE_TYPE
*value
)
7371 return ((TREE_CODE (expr
) == REAL_CST
7372 && ! TREE_CONSTANT_OVERFLOW (expr
)
7373 && REAL_VALUES_EQUAL (TREE_REAL_CST (expr
), *value
))
7374 || (TREE_CODE (expr
) == COMPLEX_CST
7375 && real_dconstp (TREE_REALPART (expr
), value
)
7376 && real_zerop (TREE_IMAGPART (expr
))));
7379 /* A subroutine of fold_builtin to fold the various logarithmic
7380 functions. EXP is the CALL_EXPR of a call to a builtin logN
7381 function. VALUE is the base of the logN function. */
7384 fold_builtin_logarithm (tree fndecl
, tree arglist
,
7385 const REAL_VALUE_TYPE
*value
)
7387 if (validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
7389 tree type
= TREE_TYPE (TREE_TYPE (fndecl
));
7390 tree arg
= TREE_VALUE (arglist
);
7391 const enum built_in_function fcode
= builtin_mathfn_code (arg
);
7393 /* Optimize logN(1.0) = 0.0. */
7394 if (real_onep (arg
))
7395 return build_real (type
, dconst0
);
7397 /* Optimize logN(N) = 1.0. If N can't be truncated to MODE
7398 exactly, then only do this if flag_unsafe_math_optimizations. */
7399 if (exact_real_truncate (TYPE_MODE (type
), value
)
7400 || flag_unsafe_math_optimizations
)
7402 const REAL_VALUE_TYPE value_truncate
=
7403 real_value_truncate (TYPE_MODE (type
), *value
);
7404 if (real_dconstp (arg
, &value_truncate
))
7405 return build_real (type
, dconst1
);
7408 /* Special case, optimize logN(expN(x)) = x. */
7409 if (flag_unsafe_math_optimizations
7410 && ((value
== &dconste
7411 && (fcode
== BUILT_IN_EXP
7412 || fcode
== BUILT_IN_EXPF
7413 || fcode
== BUILT_IN_EXPL
))
7414 || (value
== &dconst2
7415 && (fcode
== BUILT_IN_EXP2
7416 || fcode
== BUILT_IN_EXP2F
7417 || fcode
== BUILT_IN_EXP2L
))
7418 || (value
== &dconst10
&& (BUILTIN_EXP10_P (fcode
)))))
7419 return fold_convert (type
, TREE_VALUE (TREE_OPERAND (arg
, 1)));
7421 /* Optimize logN(func()) for various exponential functions. We
7422 want to determine the value "x" and the power "exponent" in
7423 order to transform logN(x**exponent) into exponent*logN(x). */
7424 if (flag_unsafe_math_optimizations
)
7426 tree exponent
= 0, x
= 0;
7430 CASE_FLT_FN (BUILT_IN_EXP
):
7431 /* Prepare to do logN(exp(exponent) -> exponent*logN(e). */
7432 x
= build_real (type
,
7433 real_value_truncate (TYPE_MODE (type
), dconste
));
7434 exponent
= TREE_VALUE (TREE_OPERAND (arg
, 1));
7436 CASE_FLT_FN (BUILT_IN_EXP2
):
7437 /* Prepare to do logN(exp2(exponent) -> exponent*logN(2). */
7438 x
= build_real (type
, dconst2
);
7439 exponent
= TREE_VALUE (TREE_OPERAND (arg
, 1));
7441 CASE_FLT_FN (BUILT_IN_EXP10
):
7442 CASE_FLT_FN (BUILT_IN_POW10
):
7443 /* Prepare to do logN(exp10(exponent) -> exponent*logN(10). */
7444 x
= build_real (type
, dconst10
);
7445 exponent
= TREE_VALUE (TREE_OPERAND (arg
, 1));
7447 CASE_FLT_FN (BUILT_IN_SQRT
):
7448 /* Prepare to do logN(sqrt(x) -> 0.5*logN(x). */
7449 x
= TREE_VALUE (TREE_OPERAND (arg
, 1));
7450 exponent
= build_real (type
, dconsthalf
);
7452 CASE_FLT_FN (BUILT_IN_CBRT
):
7453 /* Prepare to do logN(cbrt(x) -> (1/3)*logN(x). */
7454 x
= TREE_VALUE (TREE_OPERAND (arg
, 1));
7455 exponent
= build_real (type
, real_value_truncate (TYPE_MODE (type
),
7458 CASE_FLT_FN (BUILT_IN_POW
):
7459 /* Prepare to do logN(pow(x,exponent) -> exponent*logN(x). */
7460 x
= TREE_VALUE (TREE_OPERAND (arg
, 1));
7461 exponent
= TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg
, 1)));
7467 /* Now perform the optimization. */
7471 arglist
= build_tree_list (NULL_TREE
, x
);
7472 logfn
= build_function_call_expr (fndecl
, arglist
);
7473 return fold_build2 (MULT_EXPR
, type
, exponent
, logfn
);
7481 /* Fold a builtin function call to pow, powf, or powl. Return
7482 NULL_TREE if no simplification can be made. */
7484 fold_builtin_pow (tree fndecl
, tree arglist
, tree type
)
7486 tree arg0
= TREE_VALUE (arglist
);
7487 tree arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
7489 if (!validate_arglist (arglist
, REAL_TYPE
, REAL_TYPE
, VOID_TYPE
))
7492 /* Optimize pow(1.0,y) = 1.0. */
7493 if (real_onep (arg0
))
7494 return omit_one_operand (type
, build_real (type
, dconst1
), arg1
);
7496 if (TREE_CODE (arg1
) == REAL_CST
7497 && ! TREE_CONSTANT_OVERFLOW (arg1
))
7499 REAL_VALUE_TYPE cint
;
7503 c
= TREE_REAL_CST (arg1
);
7505 /* Optimize pow(x,0.0) = 1.0. */
7506 if (REAL_VALUES_EQUAL (c
, dconst0
))
7507 return omit_one_operand (type
, build_real (type
, dconst1
),
7510 /* Optimize pow(x,1.0) = x. */
7511 if (REAL_VALUES_EQUAL (c
, dconst1
))
7514 /* Optimize pow(x,-1.0) = 1.0/x. */
7515 if (REAL_VALUES_EQUAL (c
, dconstm1
))
7516 return fold_build2 (RDIV_EXPR
, type
,
7517 build_real (type
, dconst1
), arg0
);
7519 /* Optimize pow(x,0.5) = sqrt(x). */
7520 if (flag_unsafe_math_optimizations
7521 && REAL_VALUES_EQUAL (c
, dconsthalf
))
7523 tree sqrtfn
= mathfn_built_in (type
, BUILT_IN_SQRT
);
7525 if (sqrtfn
!= NULL_TREE
)
7527 tree arglist
= build_tree_list (NULL_TREE
, arg0
);
7528 return build_function_call_expr (sqrtfn
, arglist
);
7532 /* Check for an integer exponent. */
7533 n
= real_to_integer (&c
);
7534 real_from_integer (&cint
, VOIDmode
, n
, n
< 0 ? -1 : 0, 0);
7535 if (real_identical (&c
, &cint
))
7537 /* Attempt to evaluate pow at compile-time. */
7538 if (TREE_CODE (arg0
) == REAL_CST
7539 && ! TREE_CONSTANT_OVERFLOW (arg0
))
7544 x
= TREE_REAL_CST (arg0
);
7545 inexact
= real_powi (&x
, TYPE_MODE (type
), &x
, n
);
7546 if (flag_unsafe_math_optimizations
|| !inexact
)
7547 return build_real (type
, x
);
7550 /* Strip sign ops from even integer powers. */
7551 if ((n
& 1) == 0 && flag_unsafe_math_optimizations
)
7553 tree narg0
= fold_strip_sign_ops (arg0
);
7556 arglist
= build_tree_list (NULL_TREE
, arg1
);
7557 arglist
= tree_cons (NULL_TREE
, narg0
, arglist
);
7558 return build_function_call_expr (fndecl
, arglist
);
7564 if (flag_unsafe_math_optimizations
)
7566 const enum built_in_function fcode
= builtin_mathfn_code (arg0
);
7568 /* Optimize pow(expN(x),y) = expN(x*y). */
7569 if (BUILTIN_EXPONENT_P (fcode
))
7571 tree expfn
= TREE_OPERAND (TREE_OPERAND (arg0
, 0), 0);
7572 tree arg
= TREE_VALUE (TREE_OPERAND (arg0
, 1));
7573 arg
= fold_build2 (MULT_EXPR
, type
, arg
, arg1
);
7574 arglist
= build_tree_list (NULL_TREE
, arg
);
7575 return build_function_call_expr (expfn
, arglist
);
7578 /* Optimize pow(sqrt(x),y) = pow(x,y*0.5). */
7579 if (BUILTIN_SQRT_P (fcode
))
7581 tree narg0
= TREE_VALUE (TREE_OPERAND (arg0
, 1));
7582 tree narg1
= fold_build2 (MULT_EXPR
, type
, arg1
,
7583 build_real (type
, dconsthalf
));
7585 arglist
= tree_cons (NULL_TREE
, narg0
,
7586 build_tree_list (NULL_TREE
, narg1
));
7587 return build_function_call_expr (fndecl
, arglist
);
7590 /* Optimize pow(cbrt(x),y) = pow(x,y/3) iff x is nonnegative. */
7591 if (BUILTIN_CBRT_P (fcode
))
7593 tree arg
= TREE_VALUE (TREE_OPERAND (arg0
, 1));
7594 if (tree_expr_nonnegative_p (arg
))
7596 const REAL_VALUE_TYPE dconstroot
7597 = real_value_truncate (TYPE_MODE (type
), dconstthird
);
7598 tree narg1
= fold_build2 (MULT_EXPR
, type
, arg1
,
7599 build_real (type
, dconstroot
));
7600 arglist
= tree_cons (NULL_TREE
, arg
,
7601 build_tree_list (NULL_TREE
, narg1
));
7602 return build_function_call_expr (fndecl
, arglist
);
7606 /* Optimize pow(pow(x,y),z) = pow(x,y*z). */
7607 if (fcode
== BUILT_IN_POW
|| fcode
== BUILT_IN_POWF
7608 || fcode
== BUILT_IN_POWL
)
7610 tree arg00
= TREE_VALUE (TREE_OPERAND (arg0
, 1));
7611 tree arg01
= TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg0
, 1)));
7612 tree narg1
= fold_build2 (MULT_EXPR
, type
, arg01
, arg1
);
7613 arglist
= tree_cons (NULL_TREE
, arg00
,
7614 build_tree_list (NULL_TREE
, narg1
));
7615 return build_function_call_expr (fndecl
, arglist
);
7622 /* Fold a builtin function call to powi, powif, or powil. Return
7623 NULL_TREE if no simplification can be made. */
7625 fold_builtin_powi (tree fndecl ATTRIBUTE_UNUSED
, tree arglist
, tree type
)
7627 tree arg0
= TREE_VALUE (arglist
);
7628 tree arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
7630 if (!validate_arglist (arglist
, REAL_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
7633 /* Optimize pow(1.0,y) = 1.0. */
7634 if (real_onep (arg0
))
7635 return omit_one_operand (type
, build_real (type
, dconst1
), arg1
);
7637 if (host_integerp (arg1
, 0))
7639 HOST_WIDE_INT c
= TREE_INT_CST_LOW (arg1
);
7641 /* Evaluate powi at compile-time. */
7642 if (TREE_CODE (arg0
) == REAL_CST
7643 && ! TREE_CONSTANT_OVERFLOW (arg0
))
7646 x
= TREE_REAL_CST (arg0
);
7647 real_powi (&x
, TYPE_MODE (type
), &x
, c
);
7648 return build_real (type
, x
);
7651 /* Optimize pow(x,0) = 1.0. */
7653 return omit_one_operand (type
, build_real (type
, dconst1
),
7656 /* Optimize pow(x,1) = x. */
7660 /* Optimize pow(x,-1) = 1.0/x. */
7662 return fold_build2 (RDIV_EXPR
, type
,
7663 build_real (type
, dconst1
), arg0
);
7669 /* A subroutine of fold_builtin to fold the various exponent
7670 functions. EXP is the CALL_EXPR of a call to a builtin function.
7671 VALUE is the value which will be raised to a power. */
7674 fold_builtin_exponent (tree fndecl
, tree arglist
,
7675 const REAL_VALUE_TYPE
*value
)
7677 if (validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
7679 tree type
= TREE_TYPE (TREE_TYPE (fndecl
));
7680 tree arg
= TREE_VALUE (arglist
);
7682 /* Optimize exp*(0.0) = 1.0. */
7683 if (real_zerop (arg
))
7684 return build_real (type
, dconst1
);
7686 /* Optimize expN(1.0) = N. */
7687 if (real_onep (arg
))
7689 REAL_VALUE_TYPE cst
;
7691 real_convert (&cst
, TYPE_MODE (type
), value
);
7692 return build_real (type
, cst
);
7695 /* Attempt to evaluate expN(integer) at compile-time. */
7696 if (flag_unsafe_math_optimizations
7697 && TREE_CODE (arg
) == REAL_CST
7698 && ! TREE_CONSTANT_OVERFLOW (arg
))
7700 REAL_VALUE_TYPE cint
;
7704 c
= TREE_REAL_CST (arg
);
7705 n
= real_to_integer (&c
);
7706 real_from_integer (&cint
, VOIDmode
, n
,
7708 if (real_identical (&c
, &cint
))
7712 real_powi (&x
, TYPE_MODE (type
), value
, n
);
7713 return build_real (type
, x
);
7717 /* Optimize expN(logN(x)) = x. */
7718 if (flag_unsafe_math_optimizations
)
7720 const enum built_in_function fcode
= builtin_mathfn_code (arg
);
7722 if ((value
== &dconste
7723 && (fcode
== BUILT_IN_LOG
7724 || fcode
== BUILT_IN_LOGF
7725 || fcode
== BUILT_IN_LOGL
))
7726 || (value
== &dconst2
7727 && (fcode
== BUILT_IN_LOG2
7728 || fcode
== BUILT_IN_LOG2F
7729 || fcode
== BUILT_IN_LOG2L
))
7730 || (value
== &dconst10
7731 && (fcode
== BUILT_IN_LOG10
7732 || fcode
== BUILT_IN_LOG10F
7733 || fcode
== BUILT_IN_LOG10L
)))
7734 return fold_convert (type
, TREE_VALUE (TREE_OPERAND (arg
, 1)));
7741 /* Fold function call to builtin memcpy. Return
7742 NULL_TREE if no simplification can be made. */
7745 fold_builtin_memcpy (tree fndecl
, tree arglist
)
7747 tree dest
, src
, len
;
7749 if (!validate_arglist (arglist
,
7750 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
7753 dest
= TREE_VALUE (arglist
);
7754 src
= TREE_VALUE (TREE_CHAIN (arglist
));
7755 len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
7757 /* If the LEN parameter is zero, return DEST. */
7758 if (integer_zerop (len
))
7759 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl
)), dest
, src
);
7761 /* If SRC and DEST are the same (and not volatile), return DEST. */
7762 if (operand_equal_p (src
, dest
, 0))
7763 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl
)), dest
, len
);
7768 /* Fold function call to builtin mempcpy. Return
7769 NULL_TREE if no simplification can be made. */
7772 fold_builtin_mempcpy (tree arglist
, tree type
, int endp
)
7774 if (validate_arglist (arglist
,
7775 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
7777 tree dest
= TREE_VALUE (arglist
);
7778 tree src
= TREE_VALUE (TREE_CHAIN (arglist
));
7779 tree len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
7781 /* If the LEN parameter is zero, return DEST. */
7782 if (integer_zerop (len
))
7783 return omit_one_operand (type
, dest
, src
);
7785 /* If SRC and DEST are the same (and not volatile), return DEST+LEN. */
7786 if (operand_equal_p (src
, dest
, 0))
7789 return omit_one_operand (type
, dest
, len
);
7792 len
= fold_build2 (MINUS_EXPR
, TREE_TYPE (len
), len
,
7795 len
= fold_convert (TREE_TYPE (dest
), len
);
7796 len
= fold_build2 (PLUS_EXPR
, TREE_TYPE (dest
), dest
, len
);
7797 return fold_convert (type
, len
);
7803 /* Fold function call to builtin memmove. Return
7804 NULL_TREE if no simplification can be made. */
7807 fold_builtin_memmove (tree arglist
, tree type
)
7809 tree dest
, src
, len
;
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 (type
, dest
, src
);
7823 /* If SRC and DEST are the same (and not volatile), return DEST. */
7824 if (operand_equal_p (src
, dest
, 0))
7825 return omit_one_operand (type
, dest
, len
);
7830 /* Fold function call to builtin strcpy. If LEN is not NULL, it represents
7831 the length of the string to be copied. Return NULL_TREE if no
7832 simplification can be made. */
7835 fold_builtin_strcpy (tree fndecl
, tree arglist
, tree len
)
7839 if (!validate_arglist (arglist
,
7840 POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
7843 dest
= TREE_VALUE (arglist
);
7844 src
= TREE_VALUE (TREE_CHAIN (arglist
));
7846 /* If SRC and DEST are the same (and not volatile), return DEST. */
7847 if (operand_equal_p (src
, dest
, 0))
7848 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl
)), dest
);
7853 fn
= implicit_built_in_decls
[BUILT_IN_MEMCPY
];
7859 len
= c_strlen (src
, 1);
7860 if (! len
|| TREE_SIDE_EFFECTS (len
))
7864 len
= size_binop (PLUS_EXPR
, len
, ssize_int (1));
7865 arglist
= build_tree_list (NULL_TREE
, len
);
7866 arglist
= tree_cons (NULL_TREE
, src
, arglist
);
7867 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
7868 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl
)),
7869 build_function_call_expr (fn
, arglist
));
7872 /* Fold function call to builtin strncpy. If SLEN is not NULL, it represents
7873 the length of the source string. Return NULL_TREE if no simplification
7877 fold_builtin_strncpy (tree fndecl
, tree arglist
, tree slen
)
7879 tree dest
, src
, len
, fn
;
7881 if (!validate_arglist (arglist
,
7882 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
7885 dest
= TREE_VALUE (arglist
);
7886 src
= TREE_VALUE (TREE_CHAIN (arglist
));
7887 len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
7889 /* If the LEN parameter is zero, return DEST. */
7890 if (integer_zerop (len
))
7891 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl
)), dest
, src
);
7893 /* We can't compare slen with len as constants below if len is not a
7895 if (len
== 0 || TREE_CODE (len
) != INTEGER_CST
)
7899 slen
= c_strlen (src
, 1);
7901 /* Now, we must be passed a constant src ptr parameter. */
7902 if (slen
== 0 || TREE_CODE (slen
) != INTEGER_CST
)
7905 slen
= size_binop (PLUS_EXPR
, slen
, ssize_int (1));
7907 /* We do not support simplification of this case, though we do
7908 support it when expanding trees into RTL. */
7909 /* FIXME: generate a call to __builtin_memset. */
7910 if (tree_int_cst_lt (slen
, len
))
7913 /* OK transform into builtin memcpy. */
7914 fn
= implicit_built_in_decls
[BUILT_IN_MEMCPY
];
7917 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl
)),
7918 build_function_call_expr (fn
, arglist
));
7921 /* Fold function call to builtin memcmp. Return
7922 NULL_TREE if no simplification can be made. */
7925 fold_builtin_memcmp (tree arglist
)
7927 tree arg1
, arg2
, len
;
7928 const char *p1
, *p2
;
7930 if (!validate_arglist (arglist
,
7931 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
7934 arg1
= TREE_VALUE (arglist
);
7935 arg2
= TREE_VALUE (TREE_CHAIN (arglist
));
7936 len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
7938 /* If the LEN parameter is zero, return zero. */
7939 if (integer_zerop (len
))
7940 return omit_two_operands (integer_type_node
, integer_zero_node
,
7943 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
7944 if (operand_equal_p (arg1
, arg2
, 0))
7945 return omit_one_operand (integer_type_node
, integer_zero_node
, len
);
7947 p1
= c_getstr (arg1
);
7948 p2
= c_getstr (arg2
);
7950 /* If all arguments are constant, and the value of len is not greater
7951 than the lengths of arg1 and arg2, evaluate at compile-time. */
7952 if (host_integerp (len
, 1) && p1
&& p2
7953 && compare_tree_int (len
, strlen (p1
) + 1) <= 0
7954 && compare_tree_int (len
, strlen (p2
) + 1) <= 0)
7956 const int r
= memcmp (p1
, p2
, tree_low_cst (len
, 1));
7959 return integer_one_node
;
7961 return integer_minus_one_node
;
7963 return integer_zero_node
;
7966 /* If len parameter is one, return an expression corresponding to
7967 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
7968 if (host_integerp (len
, 1) && tree_low_cst (len
, 1) == 1)
7970 tree cst_uchar_node
= build_type_variant (unsigned_char_type_node
, 1, 0);
7971 tree cst_uchar_ptr_node
7972 = build_pointer_type_for_mode (cst_uchar_node
, ptr_mode
, true);
7974 tree ind1
= fold_convert (integer_type_node
,
7975 build1 (INDIRECT_REF
, cst_uchar_node
,
7976 fold_convert (cst_uchar_ptr_node
,
7978 tree ind2
= fold_convert (integer_type_node
,
7979 build1 (INDIRECT_REF
, cst_uchar_node
,
7980 fold_convert (cst_uchar_ptr_node
,
7982 return fold_build2 (MINUS_EXPR
, integer_type_node
, ind1
, ind2
);
7988 /* Fold function call to builtin strcmp. Return
7989 NULL_TREE if no simplification can be made. */
7992 fold_builtin_strcmp (tree arglist
)
7995 const char *p1
, *p2
;
7997 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
8000 arg1
= TREE_VALUE (arglist
);
8001 arg2
= TREE_VALUE (TREE_CHAIN (arglist
));
8003 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
8004 if (operand_equal_p (arg1
, arg2
, 0))
8005 return integer_zero_node
;
8007 p1
= c_getstr (arg1
);
8008 p2
= c_getstr (arg2
);
8012 const int i
= strcmp (p1
, p2
);
8014 return integer_minus_one_node
;
8016 return integer_one_node
;
8018 return integer_zero_node
;
8021 /* If the second arg is "", return *(const unsigned char*)arg1. */
8022 if (p2
&& *p2
== '\0')
8024 tree cst_uchar_node
= build_type_variant (unsigned_char_type_node
, 1, 0);
8025 tree cst_uchar_ptr_node
8026 = build_pointer_type_for_mode (cst_uchar_node
, ptr_mode
, true);
8028 return fold_convert (integer_type_node
,
8029 build1 (INDIRECT_REF
, cst_uchar_node
,
8030 fold_convert (cst_uchar_ptr_node
,
8034 /* If the first arg is "", return -*(const unsigned char*)arg2. */
8035 if (p1
&& *p1
== '\0')
8037 tree cst_uchar_node
= build_type_variant (unsigned_char_type_node
, 1, 0);
8038 tree cst_uchar_ptr_node
8039 = build_pointer_type_for_mode (cst_uchar_node
, ptr_mode
, true);
8041 tree temp
= fold_convert (integer_type_node
,
8042 build1 (INDIRECT_REF
, cst_uchar_node
,
8043 fold_convert (cst_uchar_ptr_node
,
8045 return fold_build1 (NEGATE_EXPR
, integer_type_node
, temp
);
8051 /* Fold function call to builtin strncmp. Return
8052 NULL_TREE if no simplification can be made. */
8055 fold_builtin_strncmp (tree arglist
)
8057 tree arg1
, arg2
, len
;
8058 const char *p1
, *p2
;
8060 if (!validate_arglist (arglist
,
8061 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
8064 arg1
= TREE_VALUE (arglist
);
8065 arg2
= TREE_VALUE (TREE_CHAIN (arglist
));
8066 len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
8068 /* If the LEN parameter is zero, return zero. */
8069 if (integer_zerop (len
))
8070 return omit_two_operands (integer_type_node
, integer_zero_node
,
8073 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
8074 if (operand_equal_p (arg1
, arg2
, 0))
8075 return omit_one_operand (integer_type_node
, integer_zero_node
, len
);
8077 p1
= c_getstr (arg1
);
8078 p2
= c_getstr (arg2
);
8080 if (host_integerp (len
, 1) && p1
&& p2
)
8082 const int i
= strncmp (p1
, p2
, tree_low_cst (len
, 1));
8084 return integer_one_node
;
8086 return integer_minus_one_node
;
8088 return integer_zero_node
;
8091 /* If the second arg is "", and the length is greater than zero,
8092 return *(const unsigned char*)arg1. */
8093 if (p2
&& *p2
== '\0'
8094 && TREE_CODE (len
) == INTEGER_CST
8095 && tree_int_cst_sgn (len
) == 1)
8097 tree cst_uchar_node
= build_type_variant (unsigned_char_type_node
, 1, 0);
8098 tree cst_uchar_ptr_node
8099 = build_pointer_type_for_mode (cst_uchar_node
, ptr_mode
, true);
8101 return fold_convert (integer_type_node
,
8102 build1 (INDIRECT_REF
, cst_uchar_node
,
8103 fold_convert (cst_uchar_ptr_node
,
8107 /* If the first arg is "", and the length is greater than zero,
8108 return -*(const unsigned char*)arg2. */
8109 if (p1
&& *p1
== '\0'
8110 && TREE_CODE (len
) == INTEGER_CST
8111 && tree_int_cst_sgn (len
) == 1)
8113 tree cst_uchar_node
= build_type_variant (unsigned_char_type_node
, 1, 0);
8114 tree cst_uchar_ptr_node
8115 = build_pointer_type_for_mode (cst_uchar_node
, ptr_mode
, true);
8117 tree temp
= fold_convert (integer_type_node
,
8118 build1 (INDIRECT_REF
, cst_uchar_node
,
8119 fold_convert (cst_uchar_ptr_node
,
8121 return fold_build1 (NEGATE_EXPR
, integer_type_node
, temp
);
8124 /* If len parameter is one, return an expression corresponding to
8125 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
8126 if (host_integerp (len
, 1) && tree_low_cst (len
, 1) == 1)
8128 tree cst_uchar_node
= build_type_variant (unsigned_char_type_node
, 1, 0);
8129 tree cst_uchar_ptr_node
8130 = build_pointer_type_for_mode (cst_uchar_node
, ptr_mode
, true);
8132 tree ind1
= fold_convert (integer_type_node
,
8133 build1 (INDIRECT_REF
, cst_uchar_node
,
8134 fold_convert (cst_uchar_ptr_node
,
8136 tree ind2
= fold_convert (integer_type_node
,
8137 build1 (INDIRECT_REF
, cst_uchar_node
,
8138 fold_convert (cst_uchar_ptr_node
,
8140 return fold_build2 (MINUS_EXPR
, integer_type_node
, ind1
, ind2
);
8146 /* Fold function call to builtin signbit, signbitf or signbitl. Return
8147 NULL_TREE if no simplification can be made. */
8150 fold_builtin_signbit (tree fndecl
, tree arglist
)
8152 tree type
= TREE_TYPE (TREE_TYPE (fndecl
));
8155 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
8158 arg
= TREE_VALUE (arglist
);
8160 /* If ARG is a compile-time constant, determine the result. */
8161 if (TREE_CODE (arg
) == REAL_CST
8162 && !TREE_CONSTANT_OVERFLOW (arg
))
8166 c
= TREE_REAL_CST (arg
);
8167 temp
= REAL_VALUE_NEGATIVE (c
) ? integer_one_node
: integer_zero_node
;
8168 return fold_convert (type
, temp
);
8171 /* If ARG is non-negative, the result is always zero. */
8172 if (tree_expr_nonnegative_p (arg
))
8173 return omit_one_operand (type
, integer_zero_node
, arg
);
8175 /* If ARG's format doesn't have signed zeros, return "arg < 0.0". */
8176 if (!HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg
))))
8177 return fold_build2 (LT_EXPR
, type
, arg
,
8178 build_real (TREE_TYPE (arg
), dconst0
));
8183 /* Fold function call to builtin copysign, copysignf or copysignl.
8184 Return NULL_TREE if no simplification can be made. */
8187 fold_builtin_copysign (tree fndecl
, tree arglist
, tree type
)
8189 tree arg1
, arg2
, tem
;
8191 if (!validate_arglist (arglist
, REAL_TYPE
, REAL_TYPE
, VOID_TYPE
))
8194 arg1
= TREE_VALUE (arglist
);
8195 arg2
= TREE_VALUE (TREE_CHAIN (arglist
));
8197 /* copysign(X,X) is X. */
8198 if (operand_equal_p (arg1
, arg2
, 0))
8199 return fold_convert (type
, arg1
);
8201 /* If ARG1 and ARG2 are compile-time constants, determine the result. */
8202 if (TREE_CODE (arg1
) == REAL_CST
8203 && TREE_CODE (arg2
) == REAL_CST
8204 && !TREE_CONSTANT_OVERFLOW (arg1
)
8205 && !TREE_CONSTANT_OVERFLOW (arg2
))
8207 REAL_VALUE_TYPE c1
, c2
;
8209 c1
= TREE_REAL_CST (arg1
);
8210 c2
= TREE_REAL_CST (arg2
);
8211 real_copysign (&c1
, &c2
);
8212 return build_real (type
, c1
);
8216 /* copysign(X, Y) is fabs(X) when Y is always non-negative.
8217 Remember to evaluate Y for side-effects. */
8218 if (tree_expr_nonnegative_p (arg2
))
8219 return omit_one_operand (type
,
8220 fold_build1 (ABS_EXPR
, type
, arg1
),
8223 /* Strip sign changing operations for the first argument. */
8224 tem
= fold_strip_sign_ops (arg1
);
8227 arglist
= tree_cons (NULL_TREE
, tem
, TREE_CHAIN (arglist
));
8228 return build_function_call_expr (fndecl
, arglist
);
8234 /* Fold a call to builtin isascii. */
8237 fold_builtin_isascii (tree arglist
)
8239 if (! validate_arglist (arglist
, INTEGER_TYPE
, VOID_TYPE
))
8243 /* Transform isascii(c) -> ((c & ~0x7f) == 0). */
8244 tree arg
= TREE_VALUE (arglist
);
8246 arg
= build2 (BIT_AND_EXPR
, integer_type_node
, arg
,
8247 build_int_cst (NULL_TREE
,
8248 ~ (unsigned HOST_WIDE_INT
) 0x7f));
8249 arg
= fold_build2 (EQ_EXPR
, integer_type_node
,
8250 arg
, integer_zero_node
);
8252 if (in_gimple_form
&& !TREE_CONSTANT (arg
))
8259 /* Fold a call to builtin toascii. */
8262 fold_builtin_toascii (tree arglist
)
8264 if (! validate_arglist (arglist
, INTEGER_TYPE
, VOID_TYPE
))
8268 /* Transform toascii(c) -> (c & 0x7f). */
8269 tree arg
= TREE_VALUE (arglist
);
8271 return fold_build2 (BIT_AND_EXPR
, integer_type_node
, arg
,
8272 build_int_cst (NULL_TREE
, 0x7f));
8276 /* Fold a call to builtin isdigit. */
8279 fold_builtin_isdigit (tree arglist
)
8281 if (! validate_arglist (arglist
, INTEGER_TYPE
, VOID_TYPE
))
8285 /* Transform isdigit(c) -> (unsigned)(c) - '0' <= 9. */
8286 /* According to the C standard, isdigit is unaffected by locale.
8287 However, it definitely is affected by the target character set. */
8289 unsigned HOST_WIDE_INT target_digit0
8290 = lang_hooks
.to_target_charset ('0');
8292 if (target_digit0
== 0)
8295 arg
= fold_convert (unsigned_type_node
, TREE_VALUE (arglist
));
8296 arg
= build2 (MINUS_EXPR
, unsigned_type_node
, arg
,
8297 build_int_cst (unsigned_type_node
, target_digit0
));
8298 arg
= fold_build2 (LE_EXPR
, integer_type_node
, arg
,
8299 build_int_cst (unsigned_type_node
, 9));
8300 if (in_gimple_form
&& !TREE_CONSTANT (arg
))
8307 /* Fold a call to fabs, fabsf or fabsl. */
8310 fold_builtin_fabs (tree arglist
, tree type
)
8314 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
8317 arg
= TREE_VALUE (arglist
);
8318 arg
= fold_convert (type
, arg
);
8319 if (TREE_CODE (arg
) == REAL_CST
)
8320 return fold_abs_const (arg
, type
);
8321 return fold_build1 (ABS_EXPR
, type
, arg
);
8324 /* Fold a call to abs, labs, llabs or imaxabs. */
8327 fold_builtin_abs (tree arglist
, tree type
)
8331 if (!validate_arglist (arglist
, INTEGER_TYPE
, VOID_TYPE
))
8334 arg
= TREE_VALUE (arglist
);
8335 arg
= fold_convert (type
, arg
);
8336 if (TREE_CODE (arg
) == INTEGER_CST
)
8337 return fold_abs_const (arg
, type
);
8338 return fold_build1 (ABS_EXPR
, type
, arg
);
8341 /* Fold a call to __builtin_isnan(), __builtin_isinf, __builtin_finite.
8342 EXP is the CALL_EXPR for the call. */
8345 fold_builtin_classify (tree fndecl
, tree arglist
, int builtin_index
)
8347 tree type
= TREE_TYPE (TREE_TYPE (fndecl
));
8351 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
8353 /* Check that we have exactly one argument. */
8356 error ("too few arguments to function %qs",
8357 IDENTIFIER_POINTER (DECL_NAME (fndecl
)));
8358 return error_mark_node
;
8360 else if (TREE_CHAIN (arglist
) != 0)
8362 error ("too many arguments to function %qs",
8363 IDENTIFIER_POINTER (DECL_NAME (fndecl
)));
8364 return error_mark_node
;
8368 error ("non-floating-point argument to function %qs",
8369 IDENTIFIER_POINTER (DECL_NAME (fndecl
)));
8370 return error_mark_node
;
8374 arg
= TREE_VALUE (arglist
);
8375 switch (builtin_index
)
8377 case BUILT_IN_ISINF
:
8378 if (!MODE_HAS_INFINITIES (TYPE_MODE (TREE_TYPE (arg
))))
8379 return omit_one_operand (type
, integer_zero_node
, arg
);
8381 if (TREE_CODE (arg
) == REAL_CST
)
8383 r
= TREE_REAL_CST (arg
);
8384 if (real_isinf (&r
))
8385 return real_compare (GT_EXPR
, &r
, &dconst0
)
8386 ? integer_one_node
: integer_minus_one_node
;
8388 return integer_zero_node
;
8393 case BUILT_IN_FINITE
:
8394 if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg
)))
8395 && !MODE_HAS_INFINITIES (TYPE_MODE (TREE_TYPE (arg
))))
8396 return omit_one_operand (type
, integer_zero_node
, arg
);
8398 if (TREE_CODE (arg
) == REAL_CST
)
8400 r
= TREE_REAL_CST (arg
);
8401 return real_isinf (&r
) || real_isnan (&r
)
8402 ? integer_zero_node
: integer_one_node
;
8407 case BUILT_IN_ISNAN
:
8408 if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg
))))
8409 return omit_one_operand (type
, integer_zero_node
, arg
);
8411 if (TREE_CODE (arg
) == REAL_CST
)
8413 r
= TREE_REAL_CST (arg
);
8414 return real_isnan (&r
) ? integer_one_node
: integer_zero_node
;
8417 arg
= builtin_save_expr (arg
);
8418 return fold_build2 (UNORDERED_EXPR
, type
, arg
, arg
);
8425 /* Fold a call to an unordered comparison function such as
8426 __builtin_isgreater(). FNDECL is the FUNCTION_DECL for the function
8427 being called and ARGLIST is the argument list for the call.
8428 UNORDERED_CODE and ORDERED_CODE are comparison codes that give
8429 the opposite of the desired result. UNORDERED_CODE is used
8430 for modes that can hold NaNs and ORDERED_CODE is used for
8434 fold_builtin_unordered_cmp (tree fndecl
, tree arglist
,
8435 enum tree_code unordered_code
,
8436 enum tree_code ordered_code
)
8438 tree type
= TREE_TYPE (TREE_TYPE (fndecl
));
8439 enum tree_code code
;
8442 enum tree_code code0
, code1
;
8443 tree cmp_type
= NULL_TREE
;
8445 if (!validate_arglist (arglist
, REAL_TYPE
, REAL_TYPE
, VOID_TYPE
))
8447 /* Check that we have exactly two arguments. */
8448 if (arglist
== 0 || TREE_CHAIN (arglist
) == 0)
8450 error ("too few arguments to function %qs",
8451 IDENTIFIER_POINTER (DECL_NAME (fndecl
)));
8452 return error_mark_node
;
8454 else if (TREE_CHAIN (TREE_CHAIN (arglist
)) != 0)
8456 error ("too many arguments to function %qs",
8457 IDENTIFIER_POINTER (DECL_NAME (fndecl
)));
8458 return error_mark_node
;
8462 arg0
= TREE_VALUE (arglist
);
8463 arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
8465 type0
= TREE_TYPE (arg0
);
8466 type1
= TREE_TYPE (arg1
);
8468 code0
= TREE_CODE (type0
);
8469 code1
= TREE_CODE (type1
);
8471 if (code0
== REAL_TYPE
&& code1
== REAL_TYPE
)
8472 /* Choose the wider of two real types. */
8473 cmp_type
= TYPE_PRECISION (type0
) >= TYPE_PRECISION (type1
)
8475 else if (code0
== REAL_TYPE
&& code1
== INTEGER_TYPE
)
8477 else if (code0
== INTEGER_TYPE
&& code1
== REAL_TYPE
)
8481 error ("non-floating-point argument to function %qs",
8482 IDENTIFIER_POINTER (DECL_NAME (fndecl
)));
8483 return error_mark_node
;
8486 arg0
= fold_convert (cmp_type
, arg0
);
8487 arg1
= fold_convert (cmp_type
, arg1
);
8489 if (unordered_code
== UNORDERED_EXPR
)
8491 if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg0
))))
8492 return omit_two_operands (type
, integer_zero_node
, arg0
, arg1
);
8493 return fold_build2 (UNORDERED_EXPR
, type
, arg0
, arg1
);
8496 code
= MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg0
))) ? unordered_code
8498 return fold_build1 (TRUTH_NOT_EXPR
, type
,
8499 fold_build2 (code
, type
, arg0
, arg1
));
8502 /* Used by constant folding to simplify calls to builtin functions. EXP is
8503 the CALL_EXPR of a call to a builtin function. IGNORE is true if the
8504 result of the function call is ignored. This function returns NULL_TREE
8505 if no simplification was possible. */
8508 fold_builtin_1 (tree fndecl
, tree arglist
, bool ignore
)
8510 tree type
= TREE_TYPE (TREE_TYPE (fndecl
));
8511 enum built_in_function fcode
;
8513 if (DECL_BUILT_IN_CLASS (fndecl
) == BUILT_IN_MD
)
8514 return targetm
.fold_builtin (fndecl
, arglist
, ignore
);
8516 fcode
= DECL_FUNCTION_CODE (fndecl
);
8519 case BUILT_IN_FPUTS
:
8520 return fold_builtin_fputs (arglist
, ignore
, false, NULL_TREE
);
8522 case BUILT_IN_FPUTS_UNLOCKED
:
8523 return fold_builtin_fputs (arglist
, ignore
, true, NULL_TREE
);
8525 case BUILT_IN_STRSTR
:
8526 return fold_builtin_strstr (arglist
, type
);
8528 case BUILT_IN_STRCAT
:
8529 return fold_builtin_strcat (arglist
);
8531 case BUILT_IN_STRNCAT
:
8532 return fold_builtin_strncat (arglist
);
8534 case BUILT_IN_STRSPN
:
8535 return fold_builtin_strspn (arglist
);
8537 case BUILT_IN_STRCSPN
:
8538 return fold_builtin_strcspn (arglist
);
8540 case BUILT_IN_STRCHR
:
8541 case BUILT_IN_INDEX
:
8542 return fold_builtin_strchr (arglist
, type
);
8544 case BUILT_IN_STRRCHR
:
8545 case BUILT_IN_RINDEX
:
8546 return fold_builtin_strrchr (arglist
, type
);
8548 case BUILT_IN_STRCPY
:
8549 return fold_builtin_strcpy (fndecl
, arglist
, NULL_TREE
);
8551 case BUILT_IN_STRNCPY
:
8552 return fold_builtin_strncpy (fndecl
, arglist
, NULL_TREE
);
8554 case BUILT_IN_STRCMP
:
8555 return fold_builtin_strcmp (arglist
);
8557 case BUILT_IN_STRNCMP
:
8558 return fold_builtin_strncmp (arglist
);
8560 case BUILT_IN_STRPBRK
:
8561 return fold_builtin_strpbrk (arglist
, type
);
8564 case BUILT_IN_MEMCMP
:
8565 return fold_builtin_memcmp (arglist
);
8567 case BUILT_IN_SPRINTF
:
8568 return fold_builtin_sprintf (arglist
, ignore
);
8570 case BUILT_IN_CONSTANT_P
:
8574 val
= fold_builtin_constant_p (arglist
);
8575 /* Gimplification will pull the CALL_EXPR for the builtin out of
8576 an if condition. When not optimizing, we'll not CSE it back.
8577 To avoid link error types of regressions, return false now. */
8578 if (!val
&& !optimize
)
8579 val
= integer_zero_node
;
8584 case BUILT_IN_EXPECT
:
8585 return fold_builtin_expect (arglist
);
8587 case BUILT_IN_CLASSIFY_TYPE
:
8588 return fold_builtin_classify_type (arglist
);
8590 case BUILT_IN_STRLEN
:
8591 return fold_builtin_strlen (arglist
);
8593 CASE_FLT_FN (BUILT_IN_FABS
):
8594 return fold_builtin_fabs (arglist
, type
);
8598 case BUILT_IN_LLABS
:
8599 case BUILT_IN_IMAXABS
:
8600 return fold_builtin_abs (arglist
, type
);
8602 CASE_FLT_FN (BUILT_IN_CONJ
):
8603 if (validate_arglist (arglist
, COMPLEX_TYPE
, VOID_TYPE
))
8604 return fold_build1 (CONJ_EXPR
, type
, TREE_VALUE (arglist
));
8607 CASE_FLT_FN (BUILT_IN_CREAL
):
8608 if (validate_arglist (arglist
, COMPLEX_TYPE
, VOID_TYPE
))
8609 return non_lvalue (fold_build1 (REALPART_EXPR
, type
,
8610 TREE_VALUE (arglist
)));
8613 CASE_FLT_FN (BUILT_IN_CIMAG
):
8614 if (validate_arglist (arglist
, COMPLEX_TYPE
, VOID_TYPE
))
8615 return non_lvalue (fold_build1 (IMAGPART_EXPR
, type
,
8616 TREE_VALUE (arglist
)));
8619 CASE_FLT_FN (BUILT_IN_CABS
):
8620 return fold_builtin_cabs (arglist
, type
);
8622 CASE_FLT_FN (BUILT_IN_SQRT
):
8623 return fold_builtin_sqrt (arglist
, type
);
8625 CASE_FLT_FN (BUILT_IN_CBRT
):
8626 return fold_builtin_cbrt (arglist
, type
);
8628 CASE_FLT_FN (BUILT_IN_SIN
):
8629 return fold_builtin_sin (arglist
);
8631 CASE_FLT_FN (BUILT_IN_COS
):
8632 return fold_builtin_cos (arglist
, type
, fndecl
);
8634 CASE_FLT_FN (BUILT_IN_EXP
):
8635 return fold_builtin_exponent (fndecl
, arglist
, &dconste
);
8637 CASE_FLT_FN (BUILT_IN_EXP2
):
8638 return fold_builtin_exponent (fndecl
, arglist
, &dconst2
);
8640 CASE_FLT_FN (BUILT_IN_EXP10
):
8641 CASE_FLT_FN (BUILT_IN_POW10
):
8642 return fold_builtin_exponent (fndecl
, arglist
, &dconst10
);
8644 CASE_FLT_FN (BUILT_IN_LOG
):
8645 return fold_builtin_logarithm (fndecl
, arglist
, &dconste
);
8647 CASE_FLT_FN (BUILT_IN_LOG2
):
8648 return fold_builtin_logarithm (fndecl
, arglist
, &dconst2
);
8650 CASE_FLT_FN (BUILT_IN_LOG10
):
8651 return fold_builtin_logarithm (fndecl
, arglist
, &dconst10
);
8653 CASE_FLT_FN (BUILT_IN_TAN
):
8654 return fold_builtin_tan (arglist
);
8656 CASE_FLT_FN (BUILT_IN_ATAN
):
8657 return fold_builtin_atan (arglist
, type
);
8659 CASE_FLT_FN (BUILT_IN_POW
):
8660 return fold_builtin_pow (fndecl
, arglist
, type
);
8662 CASE_FLT_FN (BUILT_IN_POWI
):
8663 return fold_builtin_powi (fndecl
, arglist
, type
);
8665 CASE_FLT_FN (BUILT_IN_INF
):
8666 case BUILT_IN_INFD32
:
8667 case BUILT_IN_INFD64
:
8668 case BUILT_IN_INFD128
:
8669 return fold_builtin_inf (type
, true);
8671 CASE_FLT_FN (BUILT_IN_HUGE_VAL
):
8672 return fold_builtin_inf (type
, false);
8674 CASE_FLT_FN (BUILT_IN_NAN
):
8675 case BUILT_IN_NAND32
:
8676 case BUILT_IN_NAND64
:
8677 case BUILT_IN_NAND128
:
8678 return fold_builtin_nan (arglist
, type
, true);
8680 CASE_FLT_FN (BUILT_IN_NANS
):
8681 return fold_builtin_nan (arglist
, type
, false);
8683 CASE_FLT_FN (BUILT_IN_FLOOR
):
8684 return fold_builtin_floor (fndecl
, arglist
);
8686 CASE_FLT_FN (BUILT_IN_CEIL
):
8687 return fold_builtin_ceil (fndecl
, arglist
);
8689 CASE_FLT_FN (BUILT_IN_TRUNC
):
8690 return fold_builtin_trunc (fndecl
, arglist
);
8692 CASE_FLT_FN (BUILT_IN_ROUND
):
8693 return fold_builtin_round (fndecl
, arglist
);
8695 CASE_FLT_FN (BUILT_IN_NEARBYINT
):
8696 CASE_FLT_FN (BUILT_IN_RINT
):
8697 return fold_trunc_transparent_mathfn (fndecl
, arglist
);
8699 CASE_FLT_FN (BUILT_IN_LCEIL
):
8700 CASE_FLT_FN (BUILT_IN_LLCEIL
):
8701 CASE_FLT_FN (BUILT_IN_LFLOOR
):
8702 CASE_FLT_FN (BUILT_IN_LLFLOOR
):
8703 CASE_FLT_FN (BUILT_IN_LROUND
):
8704 CASE_FLT_FN (BUILT_IN_LLROUND
):
8705 return fold_builtin_int_roundingfn (fndecl
, arglist
);
8707 CASE_FLT_FN (BUILT_IN_LRINT
):
8708 CASE_FLT_FN (BUILT_IN_LLRINT
):
8709 return fold_fixed_mathfn (fndecl
, arglist
);
8711 CASE_INT_FN (BUILT_IN_FFS
):
8712 CASE_INT_FN (BUILT_IN_CLZ
):
8713 CASE_INT_FN (BUILT_IN_CTZ
):
8714 CASE_INT_FN (BUILT_IN_POPCOUNT
):
8715 CASE_INT_FN (BUILT_IN_PARITY
):
8716 return fold_builtin_bitop (fndecl
, arglist
);
8718 case BUILT_IN_MEMCPY
:
8719 return fold_builtin_memcpy (fndecl
, arglist
);
8721 case BUILT_IN_MEMPCPY
:
8722 return fold_builtin_mempcpy (arglist
, type
, /*endp=*/1);
8724 case BUILT_IN_MEMMOVE
:
8725 return fold_builtin_memmove (arglist
, type
);
8727 CASE_FLT_FN (BUILT_IN_SIGNBIT
):
8728 return fold_builtin_signbit (fndecl
, arglist
);
8730 case BUILT_IN_ISASCII
:
8731 return fold_builtin_isascii (arglist
);
8733 case BUILT_IN_TOASCII
:
8734 return fold_builtin_toascii (arglist
);
8736 case BUILT_IN_ISDIGIT
:
8737 return fold_builtin_isdigit (arglist
);
8739 CASE_FLT_FN (BUILT_IN_COPYSIGN
):
8740 return fold_builtin_copysign (fndecl
, arglist
, type
);
8742 CASE_FLT_FN (BUILT_IN_FINITE
):
8743 case BUILT_IN_FINITED32
:
8744 case BUILT_IN_FINITED64
:
8745 case BUILT_IN_FINITED128
:
8746 return fold_builtin_classify (fndecl
, arglist
, BUILT_IN_FINITE
);
8748 CASE_FLT_FN (BUILT_IN_ISINF
):
8749 case BUILT_IN_ISINFD32
:
8750 case BUILT_IN_ISINFD64
:
8751 case BUILT_IN_ISINFD128
:
8752 return fold_builtin_classify (fndecl
, arglist
, BUILT_IN_ISINF
);
8754 CASE_FLT_FN (BUILT_IN_ISNAN
):
8755 case BUILT_IN_ISNAND32
:
8756 case BUILT_IN_ISNAND64
:
8757 case BUILT_IN_ISNAND128
:
8758 return fold_builtin_classify (fndecl
, arglist
, BUILT_IN_ISNAN
);
8760 case BUILT_IN_ISGREATER
:
8761 return fold_builtin_unordered_cmp (fndecl
, arglist
, UNLE_EXPR
, LE_EXPR
);
8762 case BUILT_IN_ISGREATEREQUAL
:
8763 return fold_builtin_unordered_cmp (fndecl
, arglist
, UNLT_EXPR
, LT_EXPR
);
8764 case BUILT_IN_ISLESS
:
8765 return fold_builtin_unordered_cmp (fndecl
, arglist
, UNGE_EXPR
, GE_EXPR
);
8766 case BUILT_IN_ISLESSEQUAL
:
8767 return fold_builtin_unordered_cmp (fndecl
, arglist
, UNGT_EXPR
, GT_EXPR
);
8768 case BUILT_IN_ISLESSGREATER
:
8769 return fold_builtin_unordered_cmp (fndecl
, arglist
, UNEQ_EXPR
, EQ_EXPR
);
8770 case BUILT_IN_ISUNORDERED
:
8771 return fold_builtin_unordered_cmp (fndecl
, arglist
, UNORDERED_EXPR
,
8774 /* We do the folding for va_start in the expander. */
8775 case BUILT_IN_VA_START
:
8778 case BUILT_IN_OBJECT_SIZE
:
8779 return fold_builtin_object_size (arglist
);
8780 case BUILT_IN_MEMCPY_CHK
:
8781 case BUILT_IN_MEMPCPY_CHK
:
8782 case BUILT_IN_MEMMOVE_CHK
:
8783 case BUILT_IN_MEMSET_CHK
:
8784 return fold_builtin_memory_chk (fndecl
, arglist
, NULL_TREE
, ignore
,
8785 DECL_FUNCTION_CODE (fndecl
));
8786 case BUILT_IN_STRCPY_CHK
:
8787 case BUILT_IN_STPCPY_CHK
:
8788 return fold_builtin_stxcpy_chk (fndecl
, arglist
, NULL_TREE
, ignore
,
8789 DECL_FUNCTION_CODE (fndecl
));
8790 case BUILT_IN_STRNCPY_CHK
:
8791 return fold_builtin_strncpy_chk (arglist
, NULL_TREE
);
8792 case BUILT_IN_STRCAT_CHK
:
8793 return fold_builtin_strcat_chk (fndecl
, arglist
);
8794 case BUILT_IN_STRNCAT_CHK
:
8795 return fold_builtin_strncat_chk (fndecl
, arglist
);
8796 case BUILT_IN_SPRINTF_CHK
:
8797 case BUILT_IN_VSPRINTF_CHK
:
8798 return fold_builtin_sprintf_chk (arglist
, DECL_FUNCTION_CODE (fndecl
));
8799 case BUILT_IN_SNPRINTF_CHK
:
8800 case BUILT_IN_VSNPRINTF_CHK
:
8801 return fold_builtin_snprintf_chk (arglist
, NULL_TREE
,
8802 DECL_FUNCTION_CODE (fndecl
));
8804 case BUILT_IN_PRINTF
:
8805 case BUILT_IN_PRINTF_UNLOCKED
:
8806 case BUILT_IN_VPRINTF
:
8807 case BUILT_IN_PRINTF_CHK
:
8808 case BUILT_IN_VPRINTF_CHK
:
8809 return fold_builtin_printf (fndecl
, arglist
, ignore
,
8810 DECL_FUNCTION_CODE (fndecl
));
8812 case BUILT_IN_FPRINTF
:
8813 case BUILT_IN_FPRINTF_UNLOCKED
:
8814 case BUILT_IN_VFPRINTF
:
8815 case BUILT_IN_FPRINTF_CHK
:
8816 case BUILT_IN_VFPRINTF_CHK
:
8817 return fold_builtin_fprintf (fndecl
, arglist
, ignore
,
8818 DECL_FUNCTION_CODE (fndecl
));
8827 /* A wrapper function for builtin folding that prevents warnings for
8828 "statement without effect" and the like, caused by removing the
8829 call node earlier than the warning is generated. */
8832 fold_builtin (tree fndecl
, tree arglist
, bool ignore
)
8834 tree exp
= fold_builtin_1 (fndecl
, arglist
, ignore
);
8837 exp
= build1 (NOP_EXPR
, TREE_TYPE (exp
), exp
);
8838 TREE_NO_WARNING (exp
) = 1;
8844 /* Conveniently construct a function call expression. */
8847 build_function_call_expr (tree fn
, tree arglist
)
8851 call_expr
= build1 (ADDR_EXPR
, build_pointer_type (TREE_TYPE (fn
)), fn
);
8852 return fold_build3 (CALL_EXPR
, TREE_TYPE (TREE_TYPE (fn
)),
8853 call_expr
, arglist
, NULL_TREE
);
8856 /* This function validates the types of a function call argument list
8857 represented as a tree chain of parameters against a specified list
8858 of tree_codes. If the last specifier is a 0, that represents an
8859 ellipses, otherwise the last specifier must be a VOID_TYPE. */
8862 validate_arglist (tree arglist
, ...)
8864 enum tree_code code
;
8868 va_start (ap
, arglist
);
8872 code
= va_arg (ap
, enum tree_code
);
8876 /* This signifies an ellipses, any further arguments are all ok. */
8880 /* This signifies an endlink, if no arguments remain, return
8881 true, otherwise return false. */
8885 /* If no parameters remain or the parameter's code does not
8886 match the specified code, return false. Otherwise continue
8887 checking any remaining arguments. */
8890 if (code
== POINTER_TYPE
)
8892 if (! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist
))))
8895 else if (code
!= TREE_CODE (TREE_TYPE (TREE_VALUE (arglist
))))
8899 arglist
= TREE_CHAIN (arglist
);
8903 /* We need gotos here since we can only have one VA_CLOSE in a
8911 /* Default target-specific builtin expander that does nothing. */
8914 default_expand_builtin (tree exp ATTRIBUTE_UNUSED
,
8915 rtx target ATTRIBUTE_UNUSED
,
8916 rtx subtarget ATTRIBUTE_UNUSED
,
8917 enum machine_mode mode ATTRIBUTE_UNUSED
,
8918 int ignore ATTRIBUTE_UNUSED
)
8923 /* Default target-specific library builtin expander that does nothing. */
8926 default_expand_library_builtin (tree exp ATTRIBUTE_UNUSED
,
8927 rtx target ATTRIBUTE_UNUSED
,
8928 rtx subtarget ATTRIBUTE_UNUSED
,
8929 enum machine_mode mode ATTRIBUTE_UNUSED
,
8930 int ignore ATTRIBUTE_UNUSED
)
8935 /* Returns true is EXP represents data that would potentially reside
8936 in a readonly section. */
8939 readonly_data_expr (tree exp
)
8943 if (TREE_CODE (exp
) != ADDR_EXPR
)
8946 exp
= get_base_address (TREE_OPERAND (exp
, 0));
8950 /* Make sure we call decl_readonly_section only for trees it
8951 can handle (since it returns true for everything it doesn't
8953 if (TREE_CODE (exp
) == STRING_CST
8954 || TREE_CODE (exp
) == CONSTRUCTOR
8955 || (TREE_CODE (exp
) == VAR_DECL
&& TREE_STATIC (exp
)))
8956 return decl_readonly_section (exp
, 0);
8961 /* Simplify a call to the strstr builtin.
8963 Return 0 if no simplification was possible, otherwise return the
8964 simplified form of the call as a tree.
8966 The simplified form may be a constant or other expression which
8967 computes the same value, but in a more efficient manner (including
8968 calls to other builtin functions).
8970 The call may contain arguments which need to be evaluated, but
8971 which are not useful to determine the result of the call. In
8972 this case we return a chain of COMPOUND_EXPRs. The LHS of each
8973 COMPOUND_EXPR will be an argument which must be evaluated.
8974 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
8975 COMPOUND_EXPR in the chain will contain the tree for the simplified
8976 form of the builtin function call. */
8979 fold_builtin_strstr (tree arglist
, tree type
)
8981 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
8985 tree s1
= TREE_VALUE (arglist
), s2
= TREE_VALUE (TREE_CHAIN (arglist
));
8987 const char *p1
, *p2
;
8996 const char *r
= strstr (p1
, p2
);
9000 return build_int_cst (TREE_TYPE (s1
), 0);
9002 /* Return an offset into the constant string argument. */
9003 tem
= fold_build2 (PLUS_EXPR
, TREE_TYPE (s1
),
9004 s1
, build_int_cst (TREE_TYPE (s1
), r
- p1
));
9005 return fold_convert (type
, tem
);
9008 /* The argument is const char *, and the result is char *, so we need
9009 a type conversion here to avoid a warning. */
9011 return fold_convert (type
, s1
);
9016 fn
= implicit_built_in_decls
[BUILT_IN_STRCHR
];
9020 /* New argument list transforming strstr(s1, s2) to
9021 strchr(s1, s2[0]). */
9022 arglist
= build_tree_list (NULL_TREE
,
9023 build_int_cst (NULL_TREE
, p2
[0]));
9024 arglist
= tree_cons (NULL_TREE
, s1
, arglist
);
9025 return build_function_call_expr (fn
, arglist
);
9029 /* Simplify a call to the strchr builtin.
9031 Return 0 if no simplification was possible, otherwise return the
9032 simplified form of the call as a tree.
9034 The simplified form may be a constant or other expression which
9035 computes the same value, but in a more efficient manner (including
9036 calls to other builtin functions).
9038 The call may contain arguments which need to be evaluated, but
9039 which are not useful to determine the result of the call. In
9040 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9041 COMPOUND_EXPR will be an argument which must be evaluated.
9042 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9043 COMPOUND_EXPR in the chain will contain the tree for the simplified
9044 form of the builtin function call. */
9047 fold_builtin_strchr (tree arglist
, tree type
)
9049 if (!validate_arglist (arglist
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
9053 tree s1
= TREE_VALUE (arglist
), s2
= TREE_VALUE (TREE_CHAIN (arglist
));
9056 if (TREE_CODE (s2
) != INTEGER_CST
)
9066 if (target_char_cast (s2
, &c
))
9072 return build_int_cst (TREE_TYPE (s1
), 0);
9074 /* Return an offset into the constant string argument. */
9075 tem
= fold_build2 (PLUS_EXPR
, TREE_TYPE (s1
),
9076 s1
, build_int_cst (TREE_TYPE (s1
), r
- p1
));
9077 return fold_convert (type
, tem
);
9083 /* Simplify a call to the strrchr builtin.
9085 Return 0 if no simplification was possible, otherwise return the
9086 simplified form of the call as a tree.
9088 The simplified form may be a constant or other expression which
9089 computes the same value, but in a more efficient manner (including
9090 calls to other builtin functions).
9092 The call may contain arguments which need to be evaluated, but
9093 which are not useful to determine the result of the call. In
9094 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9095 COMPOUND_EXPR will be an argument which must be evaluated.
9096 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9097 COMPOUND_EXPR in the chain will contain the tree for the simplified
9098 form of the builtin function call. */
9101 fold_builtin_strrchr (tree arglist
, tree type
)
9103 if (!validate_arglist (arglist
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
9107 tree s1
= TREE_VALUE (arglist
), s2
= TREE_VALUE (TREE_CHAIN (arglist
));
9111 if (TREE_CODE (s2
) != INTEGER_CST
)
9121 if (target_char_cast (s2
, &c
))
9124 r
= strrchr (p1
, c
);
9127 return build_int_cst (TREE_TYPE (s1
), 0);
9129 /* Return an offset into the constant string argument. */
9130 tem
= fold_build2 (PLUS_EXPR
, TREE_TYPE (s1
),
9131 s1
, build_int_cst (TREE_TYPE (s1
), r
- p1
));
9132 return fold_convert (type
, tem
);
9135 if (! integer_zerop (s2
))
9138 fn
= implicit_built_in_decls
[BUILT_IN_STRCHR
];
9142 /* Transform strrchr(s1, '\0') to strchr(s1, '\0'). */
9143 return build_function_call_expr (fn
, arglist
);
9147 /* Simplify a call to the strpbrk builtin.
9149 Return 0 if no simplification was possible, otherwise return the
9150 simplified form of the call as a tree.
9152 The simplified form may be a constant or other expression which
9153 computes the same value, but in a more efficient manner (including
9154 calls to other builtin functions).
9156 The call may contain arguments which need to be evaluated, but
9157 which are not useful to determine the result of the call. In
9158 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9159 COMPOUND_EXPR will be an argument which must be evaluated.
9160 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9161 COMPOUND_EXPR in the chain will contain the tree for the simplified
9162 form of the builtin function call. */
9165 fold_builtin_strpbrk (tree arglist
, tree type
)
9167 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
9171 tree s1
= TREE_VALUE (arglist
), s2
= TREE_VALUE (TREE_CHAIN (arglist
));
9173 const char *p1
, *p2
;
9182 const char *r
= strpbrk (p1
, p2
);
9186 return build_int_cst (TREE_TYPE (s1
), 0);
9188 /* Return an offset into the constant string argument. */
9189 tem
= fold_build2 (PLUS_EXPR
, TREE_TYPE (s1
),
9190 s1
, build_int_cst (TREE_TYPE (s1
), r
- p1
));
9191 return fold_convert (type
, tem
);
9195 /* strpbrk(x, "") == NULL.
9196 Evaluate and ignore s1 in case it had side-effects. */
9197 return omit_one_operand (TREE_TYPE (s1
), integer_zero_node
, s1
);
9200 return 0; /* Really call strpbrk. */
9202 fn
= implicit_built_in_decls
[BUILT_IN_STRCHR
];
9206 /* New argument list transforming strpbrk(s1, s2) to
9207 strchr(s1, s2[0]). */
9208 arglist
= build_tree_list (NULL_TREE
,
9209 build_int_cst (NULL_TREE
, p2
[0]));
9210 arglist
= tree_cons (NULL_TREE
, s1
, arglist
);
9211 return build_function_call_expr (fn
, arglist
);
9215 /* Simplify a call to the strcat builtin.
9217 Return 0 if no simplification was possible, otherwise return the
9218 simplified form of the call as a tree.
9220 The simplified form may be a constant or other expression which
9221 computes the same value, but in a more efficient manner (including
9222 calls to other builtin functions).
9224 The call may contain arguments which need to be evaluated, but
9225 which are not useful to determine the result of the call. In
9226 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9227 COMPOUND_EXPR will be an argument which must be evaluated.
9228 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9229 COMPOUND_EXPR in the chain will contain the tree for the simplified
9230 form of the builtin function call. */
9233 fold_builtin_strcat (tree arglist
)
9235 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
9239 tree dst
= TREE_VALUE (arglist
),
9240 src
= TREE_VALUE (TREE_CHAIN (arglist
));
9241 const char *p
= c_getstr (src
);
9243 /* If the string length is zero, return the dst parameter. */
9244 if (p
&& *p
== '\0')
9251 /* Simplify a call to the strncat builtin.
9253 Return 0 if no simplification was possible, otherwise return the
9254 simplified form of the call as a tree.
9256 The simplified form may be a constant or other expression which
9257 computes the same value, but in a more efficient manner (including
9258 calls to other builtin functions).
9260 The call may contain arguments which need to be evaluated, but
9261 which are not useful to determine the result of the call. In
9262 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9263 COMPOUND_EXPR will be an argument which must be evaluated.
9264 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9265 COMPOUND_EXPR in the chain will contain the tree for the simplified
9266 form of the builtin function call. */
9269 fold_builtin_strncat (tree arglist
)
9271 if (!validate_arglist (arglist
,
9272 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
9276 tree dst
= TREE_VALUE (arglist
);
9277 tree src
= TREE_VALUE (TREE_CHAIN (arglist
));
9278 tree len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
9279 const char *p
= c_getstr (src
);
9281 /* If the requested length is zero, or the src parameter string
9282 length is zero, return the dst parameter. */
9283 if (integer_zerop (len
) || (p
&& *p
== '\0'))
9284 return omit_two_operands (TREE_TYPE (dst
), dst
, src
, len
);
9286 /* If the requested len is greater than or equal to the string
9287 length, call strcat. */
9288 if (TREE_CODE (len
) == INTEGER_CST
&& p
9289 && compare_tree_int (len
, strlen (p
)) >= 0)
9292 = tree_cons (NULL_TREE
, dst
, build_tree_list (NULL_TREE
, src
));
9293 tree fn
= implicit_built_in_decls
[BUILT_IN_STRCAT
];
9295 /* If the replacement _DECL isn't initialized, don't do the
9300 return build_function_call_expr (fn
, newarglist
);
9306 /* Simplify a call to the strspn builtin.
9308 Return 0 if no simplification was possible, otherwise return the
9309 simplified form of the call as a tree.
9311 The simplified form may be a constant or other expression which
9312 computes the same value, but in a more efficient manner (including
9313 calls to other builtin functions).
9315 The call may contain arguments which need to be evaluated, but
9316 which are not useful to determine the result of the call. In
9317 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9318 COMPOUND_EXPR will be an argument which must be evaluated.
9319 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9320 COMPOUND_EXPR in the chain will contain the tree for the simplified
9321 form of the builtin function call. */
9324 fold_builtin_strspn (tree arglist
)
9326 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
9330 tree s1
= TREE_VALUE (arglist
), s2
= TREE_VALUE (TREE_CHAIN (arglist
));
9331 const char *p1
= c_getstr (s1
), *p2
= c_getstr (s2
);
9333 /* If both arguments are constants, evaluate at compile-time. */
9336 const size_t r
= strspn (p1
, p2
);
9337 return size_int (r
);
9340 /* If either argument is "", return 0. */
9341 if ((p1
&& *p1
== '\0') || (p2
&& *p2
== '\0'))
9342 /* Evaluate and ignore both arguments in case either one has
9344 return omit_two_operands (integer_type_node
, integer_zero_node
,
9350 /* Simplify a call to the strcspn builtin.
9352 Return 0 if no simplification was possible, otherwise return the
9353 simplified form of the call as a tree.
9355 The simplified form may be a constant or other expression which
9356 computes the same value, but in a more efficient manner (including
9357 calls to other builtin functions).
9359 The call may contain arguments which need to be evaluated, but
9360 which are not useful to determine the result of the call. In
9361 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9362 COMPOUND_EXPR will be an argument which must be evaluated.
9363 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9364 COMPOUND_EXPR in the chain will contain the tree for the simplified
9365 form of the builtin function call. */
9368 fold_builtin_strcspn (tree arglist
)
9370 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
9374 tree s1
= TREE_VALUE (arglist
), s2
= TREE_VALUE (TREE_CHAIN (arglist
));
9375 const char *p1
= c_getstr (s1
), *p2
= c_getstr (s2
);
9377 /* If both arguments are constants, evaluate at compile-time. */
9380 const size_t r
= strcspn (p1
, p2
);
9381 return size_int (r
);
9384 /* If the first argument is "", return 0. */
9385 if (p1
&& *p1
== '\0')
9387 /* Evaluate and ignore argument s2 in case it has
9389 return omit_one_operand (integer_type_node
,
9390 integer_zero_node
, s2
);
9393 /* If the second argument is "", return __builtin_strlen(s1). */
9394 if (p2
&& *p2
== '\0')
9396 tree newarglist
= build_tree_list (NULL_TREE
, s1
),
9397 fn
= implicit_built_in_decls
[BUILT_IN_STRLEN
];
9399 /* If the replacement _DECL isn't initialized, don't do the
9404 return build_function_call_expr (fn
, newarglist
);
9410 /* Fold a call to the fputs builtin. IGNORE is true if the value returned
9411 by the builtin will be ignored. UNLOCKED is true is true if this
9412 actually a call to fputs_unlocked. If LEN in non-NULL, it represents
9413 the known length of the string. Return NULL_TREE if no simplification
9417 fold_builtin_fputs (tree arglist
, bool ignore
, bool unlocked
, tree len
)
9420 /* If we're using an unlocked function, assume the other unlocked
9421 functions exist explicitly. */
9422 tree
const fn_fputc
= unlocked
? built_in_decls
[BUILT_IN_FPUTC_UNLOCKED
]
9423 : implicit_built_in_decls
[BUILT_IN_FPUTC
];
9424 tree
const fn_fwrite
= unlocked
? built_in_decls
[BUILT_IN_FWRITE_UNLOCKED
]
9425 : implicit_built_in_decls
[BUILT_IN_FWRITE
];
9427 /* If the return value is used, don't do the transformation. */
9431 /* Verify the arguments in the original call. */
9432 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
9436 len
= c_strlen (TREE_VALUE (arglist
), 0);
9438 /* Get the length of the string passed to fputs. If the length
9439 can't be determined, punt. */
9441 || TREE_CODE (len
) != INTEGER_CST
)
9444 switch (compare_tree_int (len
, 1))
9446 case -1: /* length is 0, delete the call entirely . */
9447 return omit_one_operand (integer_type_node
, integer_zero_node
,
9448 TREE_VALUE (TREE_CHAIN (arglist
)));
9450 case 0: /* length is 1, call fputc. */
9452 const char *p
= c_getstr (TREE_VALUE (arglist
));
9456 /* New argument list transforming fputs(string, stream) to
9457 fputc(string[0], stream). */
9458 arglist
= build_tree_list (NULL_TREE
,
9459 TREE_VALUE (TREE_CHAIN (arglist
)));
9460 arglist
= tree_cons (NULL_TREE
,
9461 build_int_cst (NULL_TREE
, p
[0]),
9468 case 1: /* length is greater than 1, call fwrite. */
9472 /* If optimizing for size keep fputs. */
9475 string_arg
= TREE_VALUE (arglist
);
9476 /* New argument list transforming fputs(string, stream) to
9477 fwrite(string, 1, len, stream). */
9478 arglist
= build_tree_list (NULL_TREE
,
9479 TREE_VALUE (TREE_CHAIN (arglist
)));
9480 arglist
= tree_cons (NULL_TREE
, len
, arglist
);
9481 arglist
= tree_cons (NULL_TREE
, size_one_node
, arglist
);
9482 arglist
= tree_cons (NULL_TREE
, string_arg
, arglist
);
9490 /* If the replacement _DECL isn't initialized, don't do the
9495 /* These optimizations are only performed when the result is ignored,
9496 hence there's no need to cast the result to integer_type_node. */
9497 return build_function_call_expr (fn
, arglist
);
9500 /* Fold the new_arg's arguments (ARGLIST). Returns true if there was an error
9501 produced. False otherwise. This is done so that we don't output the error
9502 or warning twice or three times. */
9504 fold_builtin_next_arg (tree arglist
)
9506 tree fntype
= TREE_TYPE (current_function_decl
);
9508 if (TYPE_ARG_TYPES (fntype
) == 0
9509 || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype
)))
9512 error ("%<va_start%> used in function with fixed args");
9517 /* Evidently an out of date version of <stdarg.h>; can't validate
9518 va_start's second argument, but can still work as intended. */
9519 warning (0, "%<__builtin_next_arg%> called without an argument");
9522 /* We use __builtin_va_start (ap, 0, 0) or __builtin_next_arg (0, 0)
9523 when we checked the arguments and if needed issued a warning. */
9524 else if (!TREE_CHAIN (arglist
)
9525 || !integer_zerop (TREE_VALUE (arglist
))
9526 || !integer_zerop (TREE_VALUE (TREE_CHAIN (arglist
)))
9527 || TREE_CHAIN (TREE_CHAIN (arglist
)))
9529 tree last_parm
= tree_last (DECL_ARGUMENTS (current_function_decl
));
9530 tree arg
= TREE_VALUE (arglist
);
9532 if (TREE_CHAIN (arglist
))
9534 error ("%<va_start%> used with too many arguments");
9538 /* Strip off all nops for the sake of the comparison. This
9539 is not quite the same as STRIP_NOPS. It does more.
9540 We must also strip off INDIRECT_EXPR for C++ reference
9542 while (TREE_CODE (arg
) == NOP_EXPR
9543 || TREE_CODE (arg
) == CONVERT_EXPR
9544 || TREE_CODE (arg
) == NON_LVALUE_EXPR
9545 || TREE_CODE (arg
) == INDIRECT_REF
)
9546 arg
= TREE_OPERAND (arg
, 0);
9547 if (arg
!= last_parm
)
9549 /* FIXME: Sometimes with the tree optimizers we can get the
9550 not the last argument even though the user used the last
9551 argument. We just warn and set the arg to be the last
9552 argument so that we will get wrong-code because of
9554 warning (0, "second parameter of %<va_start%> not last named argument");
9556 /* We want to verify the second parameter just once before the tree
9557 optimizers are run and then avoid keeping it in the tree,
9558 as otherwise we could warn even for correct code like:
9559 void foo (int i, ...)
9560 { va_list ap; i++; va_start (ap, i); va_end (ap); } */
9561 TREE_VALUE (arglist
) = integer_zero_node
;
9562 TREE_CHAIN (arglist
) = build_tree_list (NULL
, integer_zero_node
);
9568 /* Simplify a call to the sprintf builtin.
9570 Return 0 if no simplification was possible, otherwise return the
9571 simplified form of the call as a tree. If IGNORED is true, it means that
9572 the caller does not use the returned value of the function. */
9575 fold_builtin_sprintf (tree arglist
, int ignored
)
9577 tree call
, retval
, dest
, fmt
;
9578 const char *fmt_str
= NULL
;
9580 /* Verify the required arguments in the original call. We deal with two
9581 types of sprintf() calls: 'sprintf (str, fmt)' and
9582 'sprintf (dest, "%s", orig)'. */
9583 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
)
9584 && !validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, POINTER_TYPE
,
9588 /* Get the destination string and the format specifier. */
9589 dest
= TREE_VALUE (arglist
);
9590 fmt
= TREE_VALUE (TREE_CHAIN (arglist
));
9592 /* Check whether the format is a literal string constant. */
9593 fmt_str
= c_getstr (fmt
);
9594 if (fmt_str
== NULL
)
9600 if (!init_target_chars())
9603 /* If the format doesn't contain % args or %%, use strcpy. */
9604 if (strchr (fmt_str
, target_percent
) == NULL
)
9606 tree fn
= implicit_built_in_decls
[BUILT_IN_STRCPY
];
9611 /* Convert sprintf (str, fmt) into strcpy (str, fmt) when
9612 'format' is known to contain no % formats. */
9613 arglist
= build_tree_list (NULL_TREE
, fmt
);
9614 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
9615 call
= build_function_call_expr (fn
, arglist
);
9617 retval
= build_int_cst (NULL_TREE
, strlen (fmt_str
));
9620 /* If the format is "%s", use strcpy if the result isn't used. */
9621 else if (fmt_str
&& strcmp (fmt_str
, target_percent_s
) == 0)
9624 fn
= implicit_built_in_decls
[BUILT_IN_STRCPY
];
9629 /* Convert sprintf (str1, "%s", str2) into strcpy (str1, str2). */
9630 orig
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
9631 arglist
= build_tree_list (NULL_TREE
, orig
);
9632 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
9635 retval
= c_strlen (orig
, 1);
9636 if (!retval
|| TREE_CODE (retval
) != INTEGER_CST
)
9639 call
= build_function_call_expr (fn
, arglist
);
9645 (TREE_TYPE (TREE_TYPE (implicit_built_in_decls
[BUILT_IN_SPRINTF
])),
9647 return build2 (COMPOUND_EXPR
, TREE_TYPE (retval
), call
, retval
);
9653 /* Expand a call to __builtin_object_size. */
9656 expand_builtin_object_size (tree exp
)
9659 int object_size_type
;
9660 tree fndecl
= get_callee_fndecl (exp
);
9661 tree arglist
= TREE_OPERAND (exp
, 1);
9662 location_t locus
= EXPR_LOCATION (exp
);
9664 if (!validate_arglist (arglist
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
9666 error ("%Hfirst argument of %D must be a pointer, second integer constant",
9668 expand_builtin_trap ();
9672 ost
= TREE_VALUE (TREE_CHAIN (arglist
));
9675 if (TREE_CODE (ost
) != INTEGER_CST
9676 || tree_int_cst_sgn (ost
) < 0
9677 || compare_tree_int (ost
, 3) > 0)
9679 error ("%Hlast argument of %D is not integer constant between 0 and 3",
9681 expand_builtin_trap ();
9685 object_size_type
= tree_low_cst (ost
, 0);
9687 return object_size_type
< 2 ? constm1_rtx
: const0_rtx
;
9690 /* Expand EXP, a call to the __mem{cpy,pcpy,move,set}_chk builtin.
9691 FCODE is the BUILT_IN_* to use.
9692 Return 0 if we failed; the caller should emit a normal call,
9693 otherwise try to get the result in TARGET, if convenient (and in
9694 mode MODE if that's convenient). */
9697 expand_builtin_memory_chk (tree exp
, rtx target
, enum machine_mode mode
,
9698 enum built_in_function fcode
)
9700 tree arglist
= TREE_OPERAND (exp
, 1);
9701 tree dest
, src
, len
, size
;
9703 if (!validate_arglist (arglist
,
9705 fcode
== BUILT_IN_MEMSET_CHK
9706 ? INTEGER_TYPE
: POINTER_TYPE
,
9707 INTEGER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
9710 dest
= TREE_VALUE (arglist
);
9711 src
= TREE_VALUE (TREE_CHAIN (arglist
));
9712 len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
9713 size
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist
))));
9715 if (! host_integerp (size
, 1))
9718 if (host_integerp (len
, 1) || integer_all_onesp (size
))
9722 if (! integer_all_onesp (size
) && tree_int_cst_lt (size
, len
))
9724 location_t locus
= EXPR_LOCATION (exp
);
9725 warning (0, "%Hcall to %D will always overflow destination buffer",
9726 &locus
, get_callee_fndecl (exp
));
9730 arglist
= build_tree_list (NULL_TREE
, len
);
9731 arglist
= tree_cons (NULL_TREE
, src
, arglist
);
9732 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
9735 /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume
9736 mem{cpy,pcpy,move,set} is available. */
9739 case BUILT_IN_MEMCPY_CHK
:
9740 fn
= built_in_decls
[BUILT_IN_MEMCPY
];
9742 case BUILT_IN_MEMPCPY_CHK
:
9743 fn
= built_in_decls
[BUILT_IN_MEMPCPY
];
9745 case BUILT_IN_MEMMOVE_CHK
:
9746 fn
= built_in_decls
[BUILT_IN_MEMMOVE
];
9748 case BUILT_IN_MEMSET_CHK
:
9749 fn
= built_in_decls
[BUILT_IN_MEMSET
];
9758 fn
= build_function_call_expr (fn
, arglist
);
9759 if (TREE_CODE (fn
) == CALL_EXPR
)
9760 CALL_EXPR_TAILCALL (fn
) = CALL_EXPR_TAILCALL (exp
);
9761 return expand_expr (fn
, target
, mode
, EXPAND_NORMAL
);
9763 else if (fcode
== BUILT_IN_MEMSET_CHK
)
9767 unsigned int dest_align
9768 = get_pointer_alignment (dest
, BIGGEST_ALIGNMENT
);
9770 /* If DEST is not a pointer type, call the normal function. */
9771 if (dest_align
== 0)
9774 /* If SRC and DEST are the same (and not volatile), do nothing. */
9775 if (operand_equal_p (src
, dest
, 0))
9779 if (fcode
!= BUILT_IN_MEMPCPY_CHK
)
9781 /* Evaluate and ignore LEN in case it has side-effects. */
9782 expand_expr (len
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
9783 return expand_expr (dest
, target
, mode
, EXPAND_NORMAL
);
9786 len
= fold_convert (TREE_TYPE (dest
), len
);
9787 expr
= fold_build2 (PLUS_EXPR
, TREE_TYPE (dest
), dest
, len
);
9788 return expand_expr (expr
, target
, mode
, EXPAND_NORMAL
);
9791 /* __memmove_chk special case. */
9792 if (fcode
== BUILT_IN_MEMMOVE_CHK
)
9794 unsigned int src_align
9795 = get_pointer_alignment (src
, BIGGEST_ALIGNMENT
);
9800 /* If src is categorized for a readonly section we can use
9801 normal __memcpy_chk. */
9802 if (readonly_data_expr (src
))
9804 tree fn
= built_in_decls
[BUILT_IN_MEMCPY_CHK
];
9807 fn
= build_function_call_expr (fn
, arglist
);
9808 if (TREE_CODE (fn
) == CALL_EXPR
)
9809 CALL_EXPR_TAILCALL (fn
) = CALL_EXPR_TAILCALL (exp
);
9810 return expand_expr (fn
, target
, mode
, EXPAND_NORMAL
);
9817 /* Emit warning if a buffer overflow is detected at compile time. */
9820 maybe_emit_chk_warning (tree exp
, enum built_in_function fcode
)
9822 int arg_mask
, is_strlen
= 0;
9823 tree arglist
= TREE_OPERAND (exp
, 1), a
;
9829 case BUILT_IN_STRCPY_CHK
:
9830 case BUILT_IN_STPCPY_CHK
:
9831 /* For __strcat_chk the warning will be emitted only if overflowing
9832 by at least strlen (dest) + 1 bytes. */
9833 case BUILT_IN_STRCAT_CHK
:
9837 case BUILT_IN_STRNCPY_CHK
:
9840 case BUILT_IN_SNPRINTF_CHK
:
9841 case BUILT_IN_VSNPRINTF_CHK
:
9850 for (a
= arglist
; a
&& arg_mask
; a
= TREE_CHAIN (a
), arg_mask
>>= 1)
9862 len
= TREE_VALUE (len
);
9863 size
= TREE_VALUE (size
);
9865 if (! host_integerp (size
, 1) || integer_all_onesp (size
))
9870 len
= c_strlen (len
, 1);
9871 if (! len
|| ! host_integerp (len
, 1) || tree_int_cst_lt (len
, size
))
9874 else if (! host_integerp (len
, 1) || ! tree_int_cst_lt (size
, len
))
9877 locus
= EXPR_LOCATION (exp
);
9878 warning (0, "%Hcall to %D will always overflow destination buffer",
9879 &locus
, get_callee_fndecl (exp
));
9882 /* Emit warning if a buffer overflow is detected at compile time
9883 in __sprintf_chk/__vsprintf_chk calls. */
9886 maybe_emit_sprintf_chk_warning (tree exp
, enum built_in_function fcode
)
9888 tree arglist
= TREE_OPERAND (exp
, 1);
9889 tree dest
, size
, len
, fmt
, flag
;
9890 const char *fmt_str
;
9892 /* Verify the required arguments in the original call. */
9895 dest
= TREE_VALUE (arglist
);
9896 arglist
= TREE_CHAIN (arglist
);
9899 flag
= TREE_VALUE (arglist
);
9900 arglist
= TREE_CHAIN (arglist
);
9903 size
= TREE_VALUE (arglist
);
9904 arglist
= TREE_CHAIN (arglist
);
9907 fmt
= TREE_VALUE (arglist
);
9908 arglist
= TREE_CHAIN (arglist
);
9910 if (! host_integerp (size
, 1) || integer_all_onesp (size
))
9913 /* Check whether the format is a literal string constant. */
9914 fmt_str
= c_getstr (fmt
);
9915 if (fmt_str
== NULL
)
9918 if (!init_target_chars())
9921 /* If the format doesn't contain % args or %%, we know its size. */
9922 if (strchr (fmt_str
, target_percent
) == 0)
9923 len
= build_int_cstu (size_type_node
, strlen (fmt_str
));
9924 /* If the format is "%s" and first ... argument is a string literal,
9926 else if (fcode
== BUILT_IN_SPRINTF_CHK
&& strcmp (fmt_str
, target_percent_s
) == 0)
9932 arg
= TREE_VALUE (arglist
);
9933 if (! POINTER_TYPE_P (TREE_TYPE (arg
)))
9936 len
= c_strlen (arg
, 1);
9937 if (!len
|| ! host_integerp (len
, 1))
9943 if (! tree_int_cst_lt (len
, size
))
9945 location_t locus
= EXPR_LOCATION (exp
);
9946 warning (0, "%Hcall to %D will always overflow destination buffer",
9947 &locus
, get_callee_fndecl (exp
));
9951 /* Fold a call to __builtin_object_size, if possible. */
9954 fold_builtin_object_size (tree arglist
)
9956 tree ptr
, ost
, ret
= 0;
9957 int object_size_type
;
9959 if (!validate_arglist (arglist
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
9962 ptr
= TREE_VALUE (arglist
);
9963 ost
= TREE_VALUE (TREE_CHAIN (arglist
));
9966 if (TREE_CODE (ost
) != INTEGER_CST
9967 || tree_int_cst_sgn (ost
) < 0
9968 || compare_tree_int (ost
, 3) > 0)
9971 object_size_type
= tree_low_cst (ost
, 0);
9973 /* __builtin_object_size doesn't evaluate side-effects in its arguments;
9974 if there are any side-effects, it returns (size_t) -1 for types 0 and 1
9975 and (size_t) 0 for types 2 and 3. */
9976 if (TREE_SIDE_EFFECTS (ptr
))
9977 return fold_convert (size_type_node
,
9978 object_size_type
< 2
9979 ? integer_minus_one_node
: integer_zero_node
);
9981 if (TREE_CODE (ptr
) == ADDR_EXPR
)
9982 ret
= build_int_cstu (size_type_node
,
9983 compute_builtin_object_size (ptr
, object_size_type
));
9985 else if (TREE_CODE (ptr
) == SSA_NAME
)
9987 unsigned HOST_WIDE_INT bytes
;
9989 /* If object size is not known yet, delay folding until
9990 later. Maybe subsequent passes will help determining
9992 bytes
= compute_builtin_object_size (ptr
, object_size_type
);
9993 if (bytes
!= (unsigned HOST_WIDE_INT
) (object_size_type
< 2
9995 ret
= build_int_cstu (size_type_node
, bytes
);
10000 ret
= force_fit_type (ret
, -1, false, false);
10001 if (TREE_CONSTANT_OVERFLOW (ret
))
10008 /* Fold a call to the __mem{cpy,pcpy,move,set}_chk builtin.
10009 IGNORE is true, if return value can be ignored. FCODE is the BUILT_IN_*
10010 code of the builtin. If MAXLEN is not NULL, it is maximum length
10011 passed as third argument. */
10014 fold_builtin_memory_chk (tree fndecl
, tree arglist
, tree maxlen
, bool ignore
,
10015 enum built_in_function fcode
)
10017 tree dest
, src
, len
, size
, fn
;
10019 if (!validate_arglist (arglist
,
10021 fcode
== BUILT_IN_MEMSET_CHK
10022 ? INTEGER_TYPE
: POINTER_TYPE
,
10023 INTEGER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
10026 dest
= TREE_VALUE (arglist
);
10027 /* Actually val for __memset_chk, but it doesn't matter. */
10028 src
= TREE_VALUE (TREE_CHAIN (arglist
));
10029 len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
10030 size
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist
))));
10032 /* If SRC and DEST are the same (and not volatile), return DEST
10033 (resp. DEST+LEN for __mempcpy_chk). */
10034 if (fcode
!= BUILT_IN_MEMSET_CHK
&& operand_equal_p (src
, dest
, 0))
10036 if (fcode
!= BUILT_IN_MEMPCPY_CHK
)
10037 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl
)), dest
, len
);
10040 tree temp
= fold_convert (TREE_TYPE (dest
), len
);
10041 temp
= fold_build2 (PLUS_EXPR
, TREE_TYPE (dest
), dest
, temp
);
10042 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl
)), temp
);
10046 if (! host_integerp (size
, 1))
10049 if (! integer_all_onesp (size
))
10051 if (! host_integerp (len
, 1))
10053 /* If LEN is not constant, try MAXLEN too.
10054 For MAXLEN only allow optimizing into non-_ocs function
10055 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
10056 if (maxlen
== NULL_TREE
|| ! host_integerp (maxlen
, 1))
10058 if (fcode
== BUILT_IN_MEMPCPY_CHK
&& ignore
)
10060 /* (void) __mempcpy_chk () can be optimized into
10061 (void) __memcpy_chk (). */
10062 fn
= built_in_decls
[BUILT_IN_MEMCPY_CHK
];
10066 return build_function_call_expr (fn
, arglist
);
10074 if (tree_int_cst_lt (size
, maxlen
))
10078 arglist
= build_tree_list (NULL_TREE
, len
);
10079 arglist
= tree_cons (NULL_TREE
, src
, arglist
);
10080 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
10083 /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume
10084 mem{cpy,pcpy,move,set} is available. */
10087 case BUILT_IN_MEMCPY_CHK
:
10088 fn
= built_in_decls
[BUILT_IN_MEMCPY
];
10090 case BUILT_IN_MEMPCPY_CHK
:
10091 fn
= built_in_decls
[BUILT_IN_MEMPCPY
];
10093 case BUILT_IN_MEMMOVE_CHK
:
10094 fn
= built_in_decls
[BUILT_IN_MEMMOVE
];
10096 case BUILT_IN_MEMSET_CHK
:
10097 fn
= built_in_decls
[BUILT_IN_MEMSET
];
10106 return build_function_call_expr (fn
, arglist
);
10109 /* Fold a call to the __st[rp]cpy_chk builtin.
10110 IGNORE is true, if return value can be ignored. FCODE is the BUILT_IN_*
10111 code of the builtin. If MAXLEN is not NULL, it is maximum length of
10112 strings passed as second argument. */
10115 fold_builtin_stxcpy_chk (tree fndecl
, tree arglist
, tree maxlen
, bool ignore
,
10116 enum built_in_function fcode
)
10118 tree dest
, src
, size
, len
, fn
;
10120 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
,
10124 dest
= TREE_VALUE (arglist
);
10125 src
= TREE_VALUE (TREE_CHAIN (arglist
));
10126 size
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
10128 /* If SRC and DEST are the same (and not volatile), return DEST. */
10129 if (fcode
== BUILT_IN_STRCPY_CHK
&& operand_equal_p (src
, dest
, 0))
10130 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl
)), dest
);
10132 if (! host_integerp (size
, 1))
10135 if (! integer_all_onesp (size
))
10137 len
= c_strlen (src
, 1);
10138 if (! len
|| ! host_integerp (len
, 1))
10140 /* If LEN is not constant, try MAXLEN too.
10141 For MAXLEN only allow optimizing into non-_ocs function
10142 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
10143 if (maxlen
== NULL_TREE
|| ! host_integerp (maxlen
, 1))
10145 if (fcode
== BUILT_IN_STPCPY_CHK
)
10150 /* If return value of __stpcpy_chk is ignored,
10151 optimize into __strcpy_chk. */
10152 fn
= built_in_decls
[BUILT_IN_STRCPY_CHK
];
10156 return build_function_call_expr (fn
, arglist
);
10159 if (! len
|| TREE_SIDE_EFFECTS (len
))
10162 /* If c_strlen returned something, but not a constant,
10163 transform __strcpy_chk into __memcpy_chk. */
10164 fn
= built_in_decls
[BUILT_IN_MEMCPY_CHK
];
10168 len
= size_binop (PLUS_EXPR
, len
, ssize_int (1));
10169 arglist
= build_tree_list (NULL_TREE
, size
);
10170 arglist
= tree_cons (NULL_TREE
, len
, arglist
);
10171 arglist
= tree_cons (NULL_TREE
, src
, arglist
);
10172 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
10173 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl
)),
10174 build_function_call_expr (fn
, arglist
));
10180 if (! tree_int_cst_lt (maxlen
, size
))
10184 arglist
= build_tree_list (NULL_TREE
, src
);
10185 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
10187 /* If __builtin_st{r,p}cpy_chk is used, assume st{r,p}cpy is available. */
10188 fn
= built_in_decls
[fcode
== BUILT_IN_STPCPY_CHK
10189 ? BUILT_IN_STPCPY
: BUILT_IN_STRCPY
];
10193 return build_function_call_expr (fn
, arglist
);
10196 /* Fold a call to the __strncpy_chk builtin.
10197 If MAXLEN is not NULL, it is maximum length passed as third argument. */
10200 fold_builtin_strncpy_chk (tree arglist
, tree maxlen
)
10202 tree dest
, src
, size
, len
, fn
;
10204 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
,
10205 INTEGER_TYPE
, VOID_TYPE
))
10208 dest
= TREE_VALUE (arglist
);
10209 src
= TREE_VALUE (TREE_CHAIN (arglist
));
10210 len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
10211 size
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist
))));
10213 if (! host_integerp (size
, 1))
10216 if (! integer_all_onesp (size
))
10218 if (! host_integerp (len
, 1))
10220 /* If LEN is not constant, try MAXLEN too.
10221 For MAXLEN only allow optimizing into non-_ocs function
10222 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
10223 if (maxlen
== NULL_TREE
|| ! host_integerp (maxlen
, 1))
10229 if (tree_int_cst_lt (size
, maxlen
))
10233 arglist
= build_tree_list (NULL_TREE
, len
);
10234 arglist
= tree_cons (NULL_TREE
, src
, arglist
);
10235 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
10237 /* If __builtin_strncpy_chk is used, assume strncpy is available. */
10238 fn
= built_in_decls
[BUILT_IN_STRNCPY
];
10242 return build_function_call_expr (fn
, arglist
);
10245 /* Fold a call to the __strcat_chk builtin FNDECL with ARGLIST. */
10248 fold_builtin_strcat_chk (tree fndecl
, tree arglist
)
10250 tree dest
, src
, size
, fn
;
10253 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
,
10257 dest
= TREE_VALUE (arglist
);
10258 src
= TREE_VALUE (TREE_CHAIN (arglist
));
10259 size
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
10261 p
= c_getstr (src
);
10262 /* If the SRC parameter is "", return DEST. */
10263 if (p
&& *p
== '\0')
10264 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl
)), dest
, src
);
10266 if (! host_integerp (size
, 1) || ! integer_all_onesp (size
))
10269 arglist
= build_tree_list (NULL_TREE
, src
);
10270 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
10272 /* If __builtin_strcat_chk is used, assume strcat is available. */
10273 fn
= built_in_decls
[BUILT_IN_STRCAT
];
10277 return build_function_call_expr (fn
, arglist
);
10280 /* Fold a call to the __strncat_chk builtin EXP. */
10283 fold_builtin_strncat_chk (tree fndecl
, tree arglist
)
10285 tree dest
, src
, size
, len
, fn
;
10288 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
,
10289 INTEGER_TYPE
, VOID_TYPE
))
10292 dest
= TREE_VALUE (arglist
);
10293 src
= TREE_VALUE (TREE_CHAIN (arglist
));
10294 len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
10295 size
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist
))));
10297 p
= c_getstr (src
);
10298 /* If the SRC parameter is "" or if LEN is 0, return DEST. */
10299 if (p
&& *p
== '\0')
10300 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl
)), dest
, len
);
10301 else if (integer_zerop (len
))
10302 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl
)), dest
, src
);
10304 if (! host_integerp (size
, 1))
10307 if (! integer_all_onesp (size
))
10309 tree src_len
= c_strlen (src
, 1);
10311 && host_integerp (src_len
, 1)
10312 && host_integerp (len
, 1)
10313 && ! tree_int_cst_lt (len
, src_len
))
10315 /* If LEN >= strlen (SRC), optimize into __strcat_chk. */
10316 fn
= built_in_decls
[BUILT_IN_STRCAT_CHK
];
10320 arglist
= build_tree_list (NULL_TREE
, size
);
10321 arglist
= tree_cons (NULL_TREE
, src
, arglist
);
10322 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
10323 return build_function_call_expr (fn
, arglist
);
10328 arglist
= build_tree_list (NULL_TREE
, len
);
10329 arglist
= tree_cons (NULL_TREE
, src
, arglist
);
10330 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
10332 /* If __builtin_strncat_chk is used, assume strncat is available. */
10333 fn
= built_in_decls
[BUILT_IN_STRNCAT
];
10337 return build_function_call_expr (fn
, arglist
);
10340 /* Fold a call to __{,v}sprintf_chk with argument list ARGLIST. Return 0 if
10341 a normal call should be emitted rather than expanding the function
10342 inline. FCODE is either BUILT_IN_SPRINTF_CHK or BUILT_IN_VSPRINTF_CHK. */
10345 fold_builtin_sprintf_chk (tree arglist
, enum built_in_function fcode
)
10347 tree dest
, size
, len
, fn
, fmt
, flag
;
10348 const char *fmt_str
;
10350 /* Verify the required arguments in the original call. */
10353 dest
= TREE_VALUE (arglist
);
10354 if (! POINTER_TYPE_P (TREE_TYPE (dest
)))
10356 arglist
= TREE_CHAIN (arglist
);
10359 flag
= TREE_VALUE (arglist
);
10360 if (TREE_CODE (TREE_TYPE (flag
)) != INTEGER_TYPE
)
10362 arglist
= TREE_CHAIN (arglist
);
10365 size
= TREE_VALUE (arglist
);
10366 if (TREE_CODE (TREE_TYPE (size
)) != INTEGER_TYPE
)
10368 arglist
= TREE_CHAIN (arglist
);
10371 fmt
= TREE_VALUE (arglist
);
10372 if (! POINTER_TYPE_P (TREE_TYPE (fmt
)))
10374 arglist
= TREE_CHAIN (arglist
);
10376 if (! host_integerp (size
, 1))
10381 if (!init_target_chars())
10384 /* Check whether the format is a literal string constant. */
10385 fmt_str
= c_getstr (fmt
);
10386 if (fmt_str
!= NULL
)
10388 /* If the format doesn't contain % args or %%, we know the size. */
10389 if (strchr (fmt_str
, target_percent
) == 0)
10391 if (fcode
!= BUILT_IN_SPRINTF_CHK
|| arglist
== NULL_TREE
)
10392 len
= build_int_cstu (size_type_node
, strlen (fmt_str
));
10394 /* If the format is "%s" and first ... argument is a string literal,
10395 we know the size too. */
10396 else if (fcode
== BUILT_IN_SPRINTF_CHK
&& strcmp (fmt_str
, target_percent_s
) == 0)
10400 if (arglist
&& !TREE_CHAIN (arglist
))
10402 arg
= TREE_VALUE (arglist
);
10403 if (POINTER_TYPE_P (TREE_TYPE (arg
)))
10405 len
= c_strlen (arg
, 1);
10406 if (! len
|| ! host_integerp (len
, 1))
10413 if (! integer_all_onesp (size
))
10415 if (! len
|| ! tree_int_cst_lt (len
, size
))
10419 /* Only convert __{,v}sprintf_chk to {,v}sprintf if flag is 0
10420 or if format doesn't contain % chars or is "%s". */
10421 if (! integer_zerop (flag
))
10423 if (fmt_str
== NULL
)
10425 if (strchr (fmt_str
, target_percent
) != NULL
&& strcmp (fmt_str
, target_percent_s
))
10429 arglist
= tree_cons (NULL_TREE
, fmt
, arglist
);
10430 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
10432 /* If __builtin_{,v}sprintf_chk is used, assume {,v}sprintf is available. */
10433 fn
= built_in_decls
[fcode
== BUILT_IN_VSPRINTF_CHK
10434 ? BUILT_IN_VSPRINTF
: BUILT_IN_SPRINTF
];
10438 return build_function_call_expr (fn
, arglist
);
10441 /* Fold a call to {,v}snprintf with argument list ARGLIST. Return 0 if
10442 a normal call should be emitted rather than expanding the function
10443 inline. FCODE is either BUILT_IN_SNPRINTF_CHK or
10444 BUILT_IN_VSNPRINTF_CHK. If MAXLEN is not NULL, it is maximum length
10445 passed as second argument. */
10448 fold_builtin_snprintf_chk (tree arglist
, tree maxlen
,
10449 enum built_in_function fcode
)
10451 tree dest
, size
, len
, fn
, fmt
, flag
;
10452 const char *fmt_str
;
10454 /* Verify the required arguments in the original call. */
10457 dest
= TREE_VALUE (arglist
);
10458 if (! POINTER_TYPE_P (TREE_TYPE (dest
)))
10460 arglist
= TREE_CHAIN (arglist
);
10463 len
= TREE_VALUE (arglist
);
10464 if (TREE_CODE (TREE_TYPE (len
)) != INTEGER_TYPE
)
10466 arglist
= TREE_CHAIN (arglist
);
10469 flag
= TREE_VALUE (arglist
);
10470 if (TREE_CODE (TREE_TYPE (len
)) != INTEGER_TYPE
)
10472 arglist
= TREE_CHAIN (arglist
);
10475 size
= TREE_VALUE (arglist
);
10476 if (TREE_CODE (TREE_TYPE (size
)) != INTEGER_TYPE
)
10478 arglist
= TREE_CHAIN (arglist
);
10481 fmt
= TREE_VALUE (arglist
);
10482 if (! POINTER_TYPE_P (TREE_TYPE (fmt
)))
10484 arglist
= TREE_CHAIN (arglist
);
10486 if (! host_integerp (size
, 1))
10489 if (! integer_all_onesp (size
))
10491 if (! host_integerp (len
, 1))
10493 /* If LEN is not constant, try MAXLEN too.
10494 For MAXLEN only allow optimizing into non-_ocs function
10495 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
10496 if (maxlen
== NULL_TREE
|| ! host_integerp (maxlen
, 1))
10502 if (tree_int_cst_lt (size
, maxlen
))
10506 if (!init_target_chars())
10509 /* Only convert __{,v}snprintf_chk to {,v}snprintf if flag is 0
10510 or if format doesn't contain % chars or is "%s". */
10511 if (! integer_zerop (flag
))
10513 fmt_str
= c_getstr (fmt
);
10514 if (fmt_str
== NULL
)
10516 if (strchr (fmt_str
, target_percent
) != NULL
&& strcmp (fmt_str
, target_percent_s
))
10520 arglist
= tree_cons (NULL_TREE
, fmt
, arglist
);
10521 arglist
= tree_cons (NULL_TREE
, len
, arglist
);
10522 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
10524 /* If __builtin_{,v}snprintf_chk is used, assume {,v}snprintf is
10526 fn
= built_in_decls
[fcode
== BUILT_IN_VSNPRINTF_CHK
10527 ? BUILT_IN_VSNPRINTF
: BUILT_IN_SNPRINTF
];
10531 return build_function_call_expr (fn
, arglist
);
10534 /* Fold a call to the {,v}printf{,_unlocked} and __{,v}printf_chk builtins.
10536 Return 0 if no simplification was possible, otherwise return the
10537 simplified form of the call as a tree. FCODE is the BUILT_IN_*
10538 code of the function to be simplified. */
10541 fold_builtin_printf (tree fndecl
, tree arglist
, bool ignore
,
10542 enum built_in_function fcode
)
10544 tree fmt
, fn
= NULL_TREE
, fn_putchar
, fn_puts
, arg
, call
;
10545 const char *fmt_str
= NULL
;
10547 /* If the return value is used, don't do the transformation. */
10551 /* Verify the required arguments in the original call. */
10552 if (fcode
== BUILT_IN_PRINTF_CHK
|| fcode
== BUILT_IN_VPRINTF_CHK
)
10558 flag
= TREE_VALUE (arglist
);
10559 if (TREE_CODE (TREE_TYPE (flag
)) != INTEGER_TYPE
10560 || TREE_SIDE_EFFECTS (flag
))
10562 arglist
= TREE_CHAIN (arglist
);
10567 fmt
= TREE_VALUE (arglist
);
10568 if (! POINTER_TYPE_P (TREE_TYPE (fmt
)))
10570 arglist
= TREE_CHAIN (arglist
);
10572 /* Check whether the format is a literal string constant. */
10573 fmt_str
= c_getstr (fmt
);
10574 if (fmt_str
== NULL
)
10577 if (fcode
== BUILT_IN_PRINTF_UNLOCKED
)
10579 /* If we're using an unlocked function, assume the other
10580 unlocked functions exist explicitly. */
10581 fn_putchar
= built_in_decls
[BUILT_IN_PUTCHAR_UNLOCKED
];
10582 fn_puts
= built_in_decls
[BUILT_IN_PUTS_UNLOCKED
];
10586 fn_putchar
= implicit_built_in_decls
[BUILT_IN_PUTCHAR
];
10587 fn_puts
= implicit_built_in_decls
[BUILT_IN_PUTS
];
10590 if (!init_target_chars())
10593 if (strcmp (fmt_str
, target_percent_s
) == 0 || strchr (fmt_str
, target_percent
) == NULL
)
10597 if (strcmp (fmt_str
, target_percent_s
) == 0)
10599 if (fcode
== BUILT_IN_VPRINTF
|| fcode
== BUILT_IN_VPRINTF_CHK
)
10603 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist
)))
10604 || TREE_CHAIN (arglist
))
10607 str
= c_getstr (TREE_VALUE (arglist
));
10613 /* The format specifier doesn't contain any '%' characters. */
10614 if (fcode
!= BUILT_IN_VPRINTF
&& fcode
!= BUILT_IN_VPRINTF_CHK
10620 /* If the string was "", printf does nothing. */
10621 if (str
[0] == '\0')
10622 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl
)), 0);
10624 /* If the string has length of 1, call putchar. */
10625 if (str
[1] == '\0')
10627 /* Given printf("c"), (where c is any one character,)
10628 convert "c"[0] to an int and pass that to the replacement
10630 arg
= build_int_cst (NULL_TREE
, str
[0]);
10631 arglist
= build_tree_list (NULL_TREE
, arg
);
10636 /* If the string was "string\n", call puts("string"). */
10637 size_t len
= strlen (str
);
10638 if ((unsigned char)str
[len
- 1] == target_newline
)
10640 /* Create a NUL-terminated string that's one char shorter
10641 than the original, stripping off the trailing '\n'. */
10642 char *newstr
= alloca (len
);
10643 memcpy (newstr
, str
, len
- 1);
10644 newstr
[len
- 1] = 0;
10646 arg
= build_string_literal (len
, newstr
);
10647 arglist
= build_tree_list (NULL_TREE
, arg
);
10651 /* We'd like to arrange to call fputs(string,stdout) here,
10652 but we need stdout and don't have a way to get it yet. */
10657 /* The other optimizations can be done only on the non-va_list variants. */
10658 else if (fcode
== BUILT_IN_VPRINTF
|| fcode
== BUILT_IN_VPRINTF_CHK
)
10661 /* If the format specifier was "%s\n", call __builtin_puts(arg). */
10662 else if (strcmp (fmt_str
, target_percent_s_newline
) == 0)
10665 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist
)))
10666 || TREE_CHAIN (arglist
))
10671 /* If the format specifier was "%c", call __builtin_putchar(arg). */
10672 else if (strcmp (fmt_str
, target_percent_c
) == 0)
10675 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist
))) != INTEGER_TYPE
10676 || TREE_CHAIN (arglist
))
10684 call
= build_function_call_expr (fn
, arglist
);
10685 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl
)), call
);
10688 /* Fold a call to the {,v}fprintf{,_unlocked} and __{,v}printf_chk builtins.
10690 Return 0 if no simplification was possible, otherwise return the
10691 simplified form of the call as a tree. FCODE is the BUILT_IN_*
10692 code of the function to be simplified. */
10695 fold_builtin_fprintf (tree fndecl
, tree arglist
, bool ignore
,
10696 enum built_in_function fcode
)
10698 tree fp
, fmt
, fn
= NULL_TREE
, fn_fputc
, fn_fputs
, arg
, call
;
10699 const char *fmt_str
= NULL
;
10701 /* If the return value is used, don't do the transformation. */
10705 /* Verify the required arguments in the original call. */
10708 fp
= TREE_VALUE (arglist
);
10709 if (! POINTER_TYPE_P (TREE_TYPE (fp
)))
10711 arglist
= TREE_CHAIN (arglist
);
10713 if (fcode
== BUILT_IN_FPRINTF_CHK
|| fcode
== BUILT_IN_VFPRINTF_CHK
)
10719 flag
= TREE_VALUE (arglist
);
10720 if (TREE_CODE (TREE_TYPE (flag
)) != INTEGER_TYPE
10721 || TREE_SIDE_EFFECTS (flag
))
10723 arglist
= TREE_CHAIN (arglist
);
10728 fmt
= TREE_VALUE (arglist
);
10729 if (! POINTER_TYPE_P (TREE_TYPE (fmt
)))
10731 arglist
= TREE_CHAIN (arglist
);
10733 /* Check whether the format is a literal string constant. */
10734 fmt_str
= c_getstr (fmt
);
10735 if (fmt_str
== NULL
)
10738 if (fcode
== BUILT_IN_FPRINTF_UNLOCKED
)
10740 /* If we're using an unlocked function, assume the other
10741 unlocked functions exist explicitly. */
10742 fn_fputc
= built_in_decls
[BUILT_IN_FPUTC_UNLOCKED
];
10743 fn_fputs
= built_in_decls
[BUILT_IN_FPUTS_UNLOCKED
];
10747 fn_fputc
= implicit_built_in_decls
[BUILT_IN_FPUTC
];
10748 fn_fputs
= implicit_built_in_decls
[BUILT_IN_FPUTS
];
10751 if (!init_target_chars())
10754 /* If the format doesn't contain % args or %%, use strcpy. */
10755 if (strchr (fmt_str
, target_percent
) == NULL
)
10757 if (fcode
!= BUILT_IN_VFPRINTF
&& fcode
!= BUILT_IN_VFPRINTF_CHK
10761 /* If the format specifier was "", fprintf does nothing. */
10762 if (fmt_str
[0] == '\0')
10764 /* If FP has side-effects, just wait until gimplification is
10766 if (TREE_SIDE_EFFECTS (fp
))
10769 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl
)), 0);
10772 /* When "string" doesn't contain %, replace all cases of
10773 fprintf (fp, string) with fputs (string, fp). The fputs
10774 builtin will take care of special cases like length == 1. */
10775 arglist
= build_tree_list (NULL_TREE
, fp
);
10776 arglist
= tree_cons (NULL_TREE
, fmt
, arglist
);
10780 /* The other optimizations can be done only on the non-va_list variants. */
10781 else if (fcode
== BUILT_IN_VFPRINTF
|| fcode
== BUILT_IN_VFPRINTF_CHK
)
10784 /* If the format specifier was "%s", call __builtin_fputs (arg, fp). */
10785 else if (strcmp (fmt_str
, target_percent_s
) == 0)
10788 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist
)))
10789 || TREE_CHAIN (arglist
))
10791 arg
= TREE_VALUE (arglist
);
10792 arglist
= build_tree_list (NULL_TREE
, fp
);
10793 arglist
= tree_cons (NULL_TREE
, arg
, arglist
);
10797 /* If the format specifier was "%c", call __builtin_fputc (arg, fp). */
10798 else if (strcmp (fmt_str
, target_percent_c
) == 0)
10801 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist
))) != INTEGER_TYPE
10802 || TREE_CHAIN (arglist
))
10804 arg
= TREE_VALUE (arglist
);
10805 arglist
= build_tree_list (NULL_TREE
, fp
);
10806 arglist
= tree_cons (NULL_TREE
, arg
, arglist
);
10813 call
= build_function_call_expr (fn
, arglist
);
10814 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl
)), call
);
10817 /* Initialize format string characters in the target charset. */
10820 init_target_chars (void)
10825 target_newline
= lang_hooks
.to_target_charset ('\n');
10826 target_percent
= lang_hooks
.to_target_charset ('%');
10827 target_c
= lang_hooks
.to_target_charset ('c');
10828 target_s
= lang_hooks
.to_target_charset ('s');
10829 if (target_newline
== 0 || target_percent
== 0 || target_c
== 0
10833 target_percent_c
[0] = target_percent
;
10834 target_percent_c
[1] = target_c
;
10835 target_percent_c
[2] = '\0';
10837 target_percent_s
[0] = target_percent
;
10838 target_percent_s
[1] = target_s
;
10839 target_percent_s
[2] = '\0';
10841 target_percent_s_newline
[0] = target_percent
;
10842 target_percent_s_newline
[1] = target_s
;
10843 target_percent_s_newline
[2] = target_newline
;
10844 target_percent_s_newline
[3] = '\0';