1 /* Expand builtin functions.
2 Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING. If not, write to the Free
19 Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
24 #include "coretypes.h"
30 #include "tree-gimple.h"
33 #include "hard-reg-set.h"
36 #include "insn-config.h"
42 #include "typeclass.h"
47 #include "langhooks.h"
48 #include "basic-block.h"
49 #include "tree-mudflap.h"
51 #ifndef PAD_VARARGS_DOWN
52 #define PAD_VARARGS_DOWN BYTES_BIG_ENDIAN
55 /* Define the names of the builtin function types and codes. */
56 const char *const built_in_class_names[4]
57 = {"NOT_BUILT_IN", "BUILT_IN_FRONTEND", "BUILT_IN_MD", "BUILT_IN_NORMAL"};
59 #define DEF_BUILTIN(X, N, C, T, LT, B, F, NA, AT, IM, COND) #X,
60 const char * built_in_names[(int) END_BUILTINS] =
62 #include "builtins.def"
66 /* Setup an array of _DECL trees, make sure each element is
67 initialized to NULL_TREE. */
68 tree built_in_decls[(int) END_BUILTINS];
69 /* Declarations used when constructing the builtin implicitly in the compiler.
70 It may be NULL_TREE when this is invalid (for instance runtime is not
71 required to implement the function call in all cases). */
72 tree implicit_built_in_decls[(int) END_BUILTINS];
74 static int get_pointer_alignment (tree, unsigned int);
75 static const char *c_getstr (tree);
76 static rtx c_readstr (const char *, enum machine_mode);
77 static int target_char_cast (tree, char *);
78 static rtx get_memory_rtx (tree, tree);
79 static int apply_args_size (void);
80 static int apply_result_size (void);
81 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
82 static rtx result_vector (int, rtx);
84 static rtx expand_builtin_setjmp (tree, rtx);
85 static void expand_builtin_update_setjmp_buf (rtx);
86 static void expand_builtin_prefetch (tree);
87 static rtx expand_builtin_apply_args (void);
88 static rtx expand_builtin_apply_args_1 (void);
89 static rtx expand_builtin_apply (rtx, rtx, rtx);
90 static void expand_builtin_return (rtx);
91 static enum type_class type_to_class (tree);
92 static rtx expand_builtin_classify_type (tree);
93 static void expand_errno_check (tree, rtx);
94 static rtx expand_builtin_mathfn (tree, rtx, rtx);
95 static rtx expand_builtin_mathfn_2 (tree, rtx, rtx);
96 static rtx expand_builtin_mathfn_3 (tree, rtx, rtx);
97 static rtx expand_builtin_sincos (tree);
98 static rtx expand_builtin_int_roundingfn (tree, rtx, rtx);
99 static rtx expand_builtin_args_info (tree);
100 static rtx expand_builtin_next_arg (void);
101 static rtx expand_builtin_va_start (tree);
102 static rtx expand_builtin_va_end (tree);
103 static rtx expand_builtin_va_copy (tree);
104 static rtx expand_builtin_memcmp (tree, tree, rtx, enum machine_mode);
105 static rtx expand_builtin_strcmp (tree, rtx, enum machine_mode);
106 static rtx expand_builtin_strncmp (tree, rtx, enum machine_mode);
107 static rtx builtin_memcpy_read_str (void *, HOST_WIDE_INT, enum machine_mode);
108 static rtx expand_builtin_strcat (tree, tree, rtx, enum machine_mode);
109 static rtx expand_builtin_strncat (tree, rtx, enum machine_mode);
110 static rtx expand_builtin_strspn (tree, rtx, enum machine_mode);
111 static rtx expand_builtin_strcspn (tree, rtx, enum machine_mode);
112 static rtx expand_builtin_memcpy (tree, rtx, enum machine_mode);
113 static rtx expand_builtin_mempcpy (tree, tree, rtx, enum machine_mode, int);
114 static rtx expand_builtin_memmove (tree, tree, rtx, enum machine_mode, tree);
115 static rtx expand_builtin_bcopy (tree);
116 static rtx expand_builtin_strcpy (tree, tree, rtx, enum machine_mode);
117 static rtx expand_builtin_stpcpy (tree, rtx, enum machine_mode);
118 static rtx builtin_strncpy_read_str (void *, HOST_WIDE_INT, enum machine_mode);
119 static rtx expand_builtin_strncpy (tree, rtx, enum machine_mode);
120 static rtx builtin_memset_read_str (void *, HOST_WIDE_INT, enum machine_mode);
121 static rtx builtin_memset_gen_str (void *, HOST_WIDE_INT, enum machine_mode);
122 static rtx expand_builtin_memset (tree, rtx, enum machine_mode, tree);
123 static rtx expand_builtin_bzero (tree);
124 static rtx expand_builtin_strlen (tree, rtx, enum machine_mode);
125 static rtx expand_builtin_strstr (tree, tree, rtx, enum machine_mode);
126 static rtx expand_builtin_strpbrk (tree, tree, rtx, enum machine_mode);
127 static rtx expand_builtin_strchr (tree, tree, rtx, enum machine_mode);
128 static rtx expand_builtin_strrchr (tree, tree, rtx, enum machine_mode);
129 static rtx expand_builtin_alloca (tree, rtx);
130 static rtx expand_builtin_unop (enum machine_mode, tree, rtx, rtx, optab);
131 static rtx expand_builtin_frame_address (tree, tree);
132 static rtx expand_builtin_fputs (tree, rtx, bool);
133 static rtx expand_builtin_printf (tree, rtx, enum machine_mode, bool);
134 static rtx expand_builtin_fprintf (tree, rtx, enum machine_mode, bool);
135 static rtx expand_builtin_sprintf (tree, rtx, enum machine_mode);
136 static tree stabilize_va_list (tree, int);
137 static rtx expand_builtin_expect (tree, rtx);
138 static tree fold_builtin_constant_p (tree);
139 static tree fold_builtin_classify_type (tree);
140 static tree fold_builtin_strlen (tree);
141 static tree fold_builtin_inf (tree, int);
142 static tree fold_builtin_nan (tree, tree, int);
143 static int validate_arglist (tree, ...);
144 static bool integer_valued_real_p (tree);
145 static tree fold_trunc_transparent_mathfn (tree, tree);
146 static bool readonly_data_expr (tree);
147 static rtx expand_builtin_fabs (tree, rtx, rtx);
148 static rtx expand_builtin_signbit (tree, rtx);
149 static tree fold_builtin_sqrt (tree, tree);
150 static tree fold_builtin_cbrt (tree, tree);
151 static tree fold_builtin_pow (tree, tree, tree);
152 static tree fold_builtin_powi (tree, tree, tree);
153 static tree fold_builtin_sin (tree);
154 static tree fold_builtin_cos (tree, tree, tree);
155 static tree fold_builtin_tan (tree);
156 static tree fold_builtin_atan (tree, tree);
157 static tree fold_builtin_trunc (tree, tree);
158 static tree fold_builtin_floor (tree, tree);
159 static tree fold_builtin_ceil (tree, tree);
160 static tree fold_builtin_round (tree, tree);
161 static tree fold_builtin_int_roundingfn (tree, tree);
162 static tree fold_builtin_bitop (tree, tree);
163 static tree fold_builtin_memcpy (tree, tree);
164 static tree fold_builtin_mempcpy (tree, tree, int);
165 static tree fold_builtin_memmove (tree, tree);
166 static tree fold_builtin_strchr (tree, tree);
167 static tree fold_builtin_memcmp (tree);
168 static tree fold_builtin_strcmp (tree);
169 static tree fold_builtin_strncmp (tree);
170 static tree fold_builtin_signbit (tree, tree);
171 static tree fold_builtin_copysign (tree, tree, tree);
172 static tree fold_builtin_isascii (tree);
173 static tree fold_builtin_toascii (tree);
174 static tree fold_builtin_isdigit (tree);
175 static tree fold_builtin_fabs (tree, tree);
176 static tree fold_builtin_abs (tree, tree);
177 static tree fold_builtin_unordered_cmp (tree, tree, enum tree_code,
179 static tree fold_builtin_1 (tree, tree, bool);
181 static tree fold_builtin_strpbrk (tree, tree);
182 static tree fold_builtin_strstr (tree, tree);
183 static tree fold_builtin_strrchr (tree, tree);
184 static tree fold_builtin_strcat (tree);
185 static tree fold_builtin_strncat (tree);
186 static tree fold_builtin_strspn (tree);
187 static tree fold_builtin_strcspn (tree);
188 static tree fold_builtin_sprintf (tree, int);
190 static rtx expand_builtin_object_size (tree);
191 static rtx expand_builtin_memory_chk (tree, rtx, enum machine_mode,
192 enum built_in_function);
193 static void maybe_emit_chk_warning (tree, enum built_in_function);
194 static void maybe_emit_sprintf_chk_warning (tree, enum built_in_function);
195 static tree fold_builtin_object_size (tree);
196 static tree fold_builtin_strcat_chk (tree, tree);
197 static tree fold_builtin_strncat_chk (tree, tree);
198 static tree fold_builtin_sprintf_chk (tree, enum built_in_function);
199 static tree fold_builtin_printf (tree, tree, bool, enum built_in_function);
200 static tree fold_builtin_fprintf (tree, tree, bool, enum built_in_function);
201 static bool init_target_chars (void);
203 static unsigned HOST_WIDE_INT target_newline;
204 static unsigned HOST_WIDE_INT target_percent;
205 static unsigned HOST_WIDE_INT target_c;
206 static unsigned HOST_WIDE_INT target_s;
207 static char target_percent_c[3];
208 static char target_percent_s[3];
209 static char target_percent_s_newline[4];
211 /* Return true if NODE should be considered for inline expansion regardless
212 of the optimization level. This means whenever a function is invoked with
213 its "internal" name, which normally contains the prefix "__builtin". */
215 static bool called_as_built_in (tree node)
217 const char *name = IDENTIFIER_POINTER (DECL_NAME (node));
218 if (strncmp (name, "__builtin_", 10) == 0)
220 if (strncmp (name, "__sync_", 7) == 0)
225 /* Return the alignment in bits of EXP, a pointer valued expression.
226 But don't return more than MAX_ALIGN no matter what.
227 The alignment returned is, by default, the alignment of the thing that
228 EXP points to. If it is not a POINTER_TYPE, 0 is returned.
230 Otherwise, look at the expression to see if we can do better, i.e., if the
231 expression is actually pointing at an object whose alignment is tighter. */
234 get_pointer_alignment (tree exp, unsigned int max_align)
236 unsigned int align, inner;
238 if (! POINTER_TYPE_P (TREE_TYPE (exp)))
241 align = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
242 align = MIN (align, max_align);
246 switch (TREE_CODE (exp))
250 case NON_LVALUE_EXPR:
251 exp = TREE_OPERAND (exp, 0);
252 if (! POINTER_TYPE_P (TREE_TYPE (exp)))
255 inner = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
256 align = MIN (inner, max_align);
260 /* If sum of pointer + int, restrict our maximum alignment to that
261 imposed by the integer. If not, we can't do any better than
263 if (! host_integerp (TREE_OPERAND (exp, 1), 1))
266 while (((tree_low_cst (TREE_OPERAND (exp, 1), 1))
267 & (max_align / BITS_PER_UNIT - 1))
271 exp = TREE_OPERAND (exp, 0);
275 /* See what we are pointing at and look at its alignment. */
276 exp = TREE_OPERAND (exp, 0);
278 if (handled_component_p (exp))
280 HOST_WIDE_INT bitsize, bitpos;
282 enum machine_mode mode;
283 int unsignedp, volatilep;
285 exp = get_inner_reference (exp, &bitsize, &bitpos, &offset,
286 &mode, &unsignedp, &volatilep, true);
288 inner = MIN (inner, (unsigned) (bitpos & -bitpos));
289 if (offset && TREE_CODE (offset) == PLUS_EXPR
290 && host_integerp (TREE_OPERAND (offset, 1), 1))
292 /* Any overflow in calculating offset_bits won't change
295 = ((unsigned) tree_low_cst (TREE_OPERAND (offset, 1), 1)
299 inner = MIN (inner, (offset_bits & -offset_bits));
300 offset = TREE_OPERAND (offset, 0);
302 if (offset && TREE_CODE (offset) == MULT_EXPR
303 && host_integerp (TREE_OPERAND (offset, 1), 1))
305 /* Any overflow in calculating offset_factor won't change
307 unsigned offset_factor
308 = ((unsigned) tree_low_cst (TREE_OPERAND (offset, 1), 1)
312 inner = MIN (inner, (offset_factor & -offset_factor));
315 inner = MIN (inner, BITS_PER_UNIT);
317 if (TREE_CODE (exp) == FUNCTION_DECL)
318 align = FUNCTION_BOUNDARY;
319 else if (DECL_P (exp))
320 align = MIN (inner, DECL_ALIGN (exp));
321 #ifdef CONSTANT_ALIGNMENT
322 else if (CONSTANT_CLASS_P (exp))
323 align = MIN (inner, (unsigned)CONSTANT_ALIGNMENT (exp, align));
325 else if (TREE_CODE (exp) == VIEW_CONVERT_EXPR
326 || TREE_CODE (exp) == INDIRECT_REF)
327 align = MIN (TYPE_ALIGN (TREE_TYPE (exp)), inner);
329 align = MIN (align, inner);
330 return MIN (align, max_align);
338 /* Compute the length of a C string. TREE_STRING_LENGTH is not the right
339 way, because it could contain a zero byte in the middle.
340 TREE_STRING_LENGTH is the size of the character array, not the string.
342 ONLY_VALUE should be nonzero if the result is not going to be emitted
343 into the instruction stream and zero if it is going to be expanded.
344 E.g. with i++ ? "foo" : "bar", if ONLY_VALUE is nonzero, constant 3
345 is returned, otherwise NULL, since
346 len = c_strlen (src, 1); if (len) expand_expr (len, ...); would not
347 evaluate the side-effects.
349 The value returned is of type `ssizetype'.
351 Unfortunately, string_constant can't access the values of const char
352 arrays with initializers, so neither can we do so here. */
355 c_strlen (tree src, int only_value)
358 HOST_WIDE_INT offset;
363 if (TREE_CODE (src) == COND_EXPR
364 && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0))))
368 len1 = c_strlen (TREE_OPERAND (src, 1), only_value);
369 len2 = c_strlen (TREE_OPERAND (src, 2), only_value);
370 if (tree_int_cst_equal (len1, len2))
374 if (TREE_CODE (src) == COMPOUND_EXPR
375 && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0))))
376 return c_strlen (TREE_OPERAND (src, 1), only_value);
378 src = string_constant (src, &offset_node);
382 max = TREE_STRING_LENGTH (src) - 1;
383 ptr = TREE_STRING_POINTER (src);
385 if (offset_node && TREE_CODE (offset_node) != INTEGER_CST)
387 /* If the string has an internal zero byte (e.g., "foo\0bar"), we can't
388 compute the offset to the following null if we don't know where to
389 start searching for it. */
392 for (i = 0; i < max; i++)
396 /* We don't know the starting offset, but we do know that the string
397 has no internal zero bytes. We can assume that the offset falls
398 within the bounds of the string; otherwise, the programmer deserves
399 what he gets. Subtract the offset from the length of the string,
400 and return that. This would perhaps not be valid if we were dealing
401 with named arrays in addition to literal string constants. */
403 return size_diffop (size_int (max), offset_node);
406 /* We have a known offset into the string. Start searching there for
407 a null character if we can represent it as a single HOST_WIDE_INT. */
408 if (offset_node == 0)
410 else if (! host_integerp (offset_node, 0))
413 offset = tree_low_cst (offset_node, 0);
415 /* If the offset is known to be out of bounds, warn, and call strlen at
417 if (offset < 0 || offset > max)
419 warning (0, "offset outside bounds of constant string");
423 /* Use strlen to search for the first zero byte. Since any strings
424 constructed with build_string will have nulls appended, we win even
425 if we get handed something like (char[4])"abcd".
427 Since OFFSET is our starting index into the string, no further
428 calculation is needed. */
429 return ssize_int (strlen (ptr + offset));
432 /* Return a char pointer for a C string if it is a string constant
433 or sum of string constant and integer constant. */
440 src = string_constant (src, &offset_node);
444 if (offset_node == 0)
445 return TREE_STRING_POINTER (src);
446 else if (!host_integerp (offset_node, 1)
447 || compare_tree_int (offset_node, TREE_STRING_LENGTH (src) - 1) > 0)
450 return TREE_STRING_POINTER (src) + tree_low_cst (offset_node, 1);
453 /* Return a CONST_INT or CONST_DOUBLE corresponding to target reading
454 GET_MODE_BITSIZE (MODE) bits from string constant STR. */
457 c_readstr (const char *str, enum machine_mode mode)
463 gcc_assert (GET_MODE_CLASS (mode) == MODE_INT);
468 for (i = 0; i < GET_MODE_SIZE (mode); i++)
471 if (WORDS_BIG_ENDIAN)
472 j = GET_MODE_SIZE (mode) - i - 1;
473 if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN
474 && GET_MODE_SIZE (mode) > UNITS_PER_WORD)
475 j = j + UNITS_PER_WORD - 2 * (j % UNITS_PER_WORD) - 1;
477 gcc_assert (j <= 2 * HOST_BITS_PER_WIDE_INT);
480 ch = (unsigned char) str[i];
481 c[j / HOST_BITS_PER_WIDE_INT] |= ch << (j % HOST_BITS_PER_WIDE_INT);
483 return immed_double_const (c[0], c[1], mode);
486 /* Cast a target constant CST to target CHAR and if that value fits into
487 host char type, return zero and put that value into variable pointed to by
491 target_char_cast (tree cst, char *p)
493 unsigned HOST_WIDE_INT val, hostval;
495 if (!host_integerp (cst, 1)
496 || CHAR_TYPE_SIZE > HOST_BITS_PER_WIDE_INT)
499 val = tree_low_cst (cst, 1);
500 if (CHAR_TYPE_SIZE < HOST_BITS_PER_WIDE_INT)
501 val &= (((unsigned HOST_WIDE_INT) 1) << CHAR_TYPE_SIZE) - 1;
504 if (HOST_BITS_PER_CHAR < HOST_BITS_PER_WIDE_INT)
505 hostval &= (((unsigned HOST_WIDE_INT) 1) << HOST_BITS_PER_CHAR) - 1;
514 /* Similar to save_expr, but assumes that arbitrary code is not executed
515 in between the multiple evaluations. In particular, we assume that a
516 non-addressable local variable will not be modified. */
519 builtin_save_expr (tree exp)
521 if (TREE_ADDRESSABLE (exp) == 0
522 && (TREE_CODE (exp) == PARM_DECL
523 || (TREE_CODE (exp) == VAR_DECL && !TREE_STATIC (exp))))
526 return save_expr (exp);
529 /* Given TEM, a pointer to a stack frame, follow the dynamic chain COUNT
530 times to get the address of either a higher stack frame, or a return
531 address located within it (depending on FNDECL_CODE). */
534 expand_builtin_return_addr (enum built_in_function fndecl_code, int count)
538 #ifdef INITIAL_FRAME_ADDRESS_RTX
539 rtx tem = INITIAL_FRAME_ADDRESS_RTX;
543 /* For a zero count with __builtin_return_address, we don't care what
544 frame address we return, because target-specific definitions will
545 override us. Therefore frame pointer elimination is OK, and using
546 the soft frame pointer is OK.
548 For a non-zero count, or a zero count with __builtin_frame_address,
549 we require a stable offset from the current frame pointer to the
550 previous one, so we must use the hard frame pointer, and
551 we must disable frame pointer elimination. */
552 if (count == 0 && fndecl_code == BUILT_IN_RETURN_ADDRESS)
553 tem = frame_pointer_rtx;
556 tem = hard_frame_pointer_rtx;
558 /* Tell reload not to eliminate the frame pointer. */
559 current_function_accesses_prior_frames = 1;
563 /* Some machines need special handling before we can access
564 arbitrary frames. For example, on the sparc, we must first flush
565 all register windows to the stack. */
566 #ifdef SETUP_FRAME_ADDRESSES
568 SETUP_FRAME_ADDRESSES ();
571 /* On the sparc, the return address is not in the frame, it is in a
572 register. There is no way to access it off of the current frame
573 pointer, but it can be accessed off the previous frame pointer by
574 reading the value from the register window save area. */
575 #ifdef RETURN_ADDR_IN_PREVIOUS_FRAME
576 if (fndecl_code == BUILT_IN_RETURN_ADDRESS)
580 /* Scan back COUNT frames to the specified frame. */
581 for (i = 0; i < count; i++)
583 /* Assume the dynamic chain pointer is in the word that the
584 frame address points to, unless otherwise specified. */
585 #ifdef DYNAMIC_CHAIN_ADDRESS
586 tem = DYNAMIC_CHAIN_ADDRESS (tem);
588 tem = memory_address (Pmode, tem);
589 tem = gen_frame_mem (Pmode, tem);
590 tem = copy_to_reg (tem);
593 /* For __builtin_frame_address, return what we've got. */
594 if (fndecl_code == BUILT_IN_FRAME_ADDRESS)
597 /* For __builtin_return_address, Get the return address from that
599 #ifdef RETURN_ADDR_RTX
600 tem = RETURN_ADDR_RTX (count, tem);
602 tem = memory_address (Pmode,
603 plus_constant (tem, GET_MODE_SIZE (Pmode)));
604 tem = gen_frame_mem (Pmode, tem);
609 /* Alias set used for setjmp buffer. */
610 static HOST_WIDE_INT setjmp_alias_set = -1;
612 /* Construct the leading half of a __builtin_setjmp call. Control will
613 return to RECEIVER_LABEL. This is used directly by sjlj exception
617 expand_builtin_setjmp_setup (rtx buf_addr, rtx receiver_label)
619 enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
623 if (setjmp_alias_set == -1)
624 setjmp_alias_set = new_alias_set ();
626 buf_addr = convert_memory_address (Pmode, buf_addr);
628 buf_addr = force_reg (Pmode, force_operand (buf_addr, NULL_RTX));
630 /* We store the frame pointer and the address of receiver_label in
631 the buffer and use the rest of it for the stack save area, which
632 is machine-dependent. */
634 mem = gen_rtx_MEM (Pmode, buf_addr);
635 set_mem_alias_set (mem, setjmp_alias_set);
636 emit_move_insn (mem, targetm.builtin_setjmp_frame_value ());
638 mem = gen_rtx_MEM (Pmode, plus_constant (buf_addr, GET_MODE_SIZE (Pmode))),
639 set_mem_alias_set (mem, setjmp_alias_set);
641 emit_move_insn (validize_mem (mem),
642 force_reg (Pmode, gen_rtx_LABEL_REF (Pmode, receiver_label)));
644 stack_save = gen_rtx_MEM (sa_mode,
645 plus_constant (buf_addr,
646 2 * GET_MODE_SIZE (Pmode)));
647 set_mem_alias_set (stack_save, setjmp_alias_set);
648 emit_stack_save (SAVE_NONLOCAL, &stack_save, NULL_RTX);
650 /* If there is further processing to do, do it. */
651 #ifdef HAVE_builtin_setjmp_setup
652 if (HAVE_builtin_setjmp_setup)
653 emit_insn (gen_builtin_setjmp_setup (buf_addr));
656 /* Tell optimize_save_area_alloca that extra work is going to
657 need to go on during alloca. */
658 current_function_calls_setjmp = 1;
660 /* Set this so all the registers get saved in our frame; we need to be
661 able to copy the saved values for any registers from frames we unwind. */
662 current_function_has_nonlocal_label = 1;
665 /* Construct the trailing part of a __builtin_setjmp call.
666 This is used directly by sjlj exception handling code. */
669 expand_builtin_setjmp_receiver (rtx receiver_label ATTRIBUTE_UNUSED)
671 /* Clobber the FP when we get here, so we have to make sure it's
672 marked as used by this function. */
673 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
675 /* Mark the static chain as clobbered here so life information
676 doesn't get messed up for it. */
677 emit_insn (gen_rtx_CLOBBER (VOIDmode, static_chain_rtx));
679 /* Now put in the code to restore the frame pointer, and argument
680 pointer, if needed. */
681 #ifdef HAVE_nonlocal_goto
682 if (! HAVE_nonlocal_goto)
684 emit_move_insn (virtual_stack_vars_rtx, hard_frame_pointer_rtx);
686 #if ARG_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
687 if (fixed_regs[ARG_POINTER_REGNUM])
689 #ifdef ELIMINABLE_REGS
691 static const struct elims {const int from, to;} elim_regs[] = ELIMINABLE_REGS;
693 for (i = 0; i < ARRAY_SIZE (elim_regs); i++)
694 if (elim_regs[i].from == ARG_POINTER_REGNUM
695 && elim_regs[i].to == HARD_FRAME_POINTER_REGNUM)
698 if (i == ARRAY_SIZE (elim_regs))
701 /* Now restore our arg pointer from the address at which it
702 was saved in our stack frame. */
703 emit_move_insn (virtual_incoming_args_rtx,
704 copy_to_reg (get_arg_pointer_save_area (cfun)));
709 #ifdef HAVE_builtin_setjmp_receiver
710 if (HAVE_builtin_setjmp_receiver)
711 emit_insn (gen_builtin_setjmp_receiver (receiver_label));
714 #ifdef HAVE_nonlocal_goto_receiver
715 if (HAVE_nonlocal_goto_receiver)
716 emit_insn (gen_nonlocal_goto_receiver ());
721 /* @@@ This is a kludge. Not all machine descriptions define a blockage
722 insn, but we must not allow the code we just generated to be reordered
723 by scheduling. Specifically, the update of the frame pointer must
724 happen immediately, not later. So emit an ASM_INPUT to act as blockage
726 emit_insn (gen_rtx_ASM_INPUT (VOIDmode, ""));
729 /* __builtin_setjmp is passed a pointer to an array of five words (not
730 all will be used on all machines). It operates similarly to the C
731 library function of the same name, but is more efficient. Much of
732 the code below (and for longjmp) is copied from the handling of
735 NOTE: This is intended for use by GNAT and the exception handling
736 scheme in the compiler and will only work in the method used by
740 expand_builtin_setjmp (tree arglist, rtx target)
742 rtx buf_addr, next_lab, cont_lab;
744 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
747 if (target == 0 || !REG_P (target)
748 || REGNO (target) < FIRST_PSEUDO_REGISTER)
749 target = gen_reg_rtx (TYPE_MODE (integer_type_node));
751 buf_addr = expand_normal (TREE_VALUE (arglist));
753 next_lab = gen_label_rtx ();
754 cont_lab = gen_label_rtx ();
756 expand_builtin_setjmp_setup (buf_addr, next_lab);
758 /* Set TARGET to zero and branch to the continue label. Use emit_jump to
759 ensure that pending stack adjustments are flushed. */
760 emit_move_insn (target, const0_rtx);
761 emit_jump (cont_lab);
763 emit_label (next_lab);
765 expand_builtin_setjmp_receiver (next_lab);
767 /* Set TARGET to one. */
768 emit_move_insn (target, const1_rtx);
769 emit_label (cont_lab);
771 /* Tell flow about the strange goings on. Putting `next_lab' on
772 `nonlocal_goto_handler_labels' to indicates that function
773 calls may traverse the arc back to this label. */
775 current_function_has_nonlocal_label = 1;
776 nonlocal_goto_handler_labels
777 = gen_rtx_EXPR_LIST (VOIDmode, next_lab, nonlocal_goto_handler_labels);
782 /* __builtin_longjmp is passed a pointer to an array of five words (not
783 all will be used on all machines). It operates similarly to the C
784 library function of the same name, but is more efficient. Much of
785 the code below is copied from the handling of non-local gotos.
787 NOTE: This is intended for use by GNAT and the exception handling
788 scheme in the compiler and will only work in the method used by
792 expand_builtin_longjmp (rtx buf_addr, rtx value)
794 rtx fp, lab, stack, insn, last;
795 enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
797 if (setjmp_alias_set == -1)
798 setjmp_alias_set = new_alias_set ();
800 buf_addr = convert_memory_address (Pmode, buf_addr);
802 buf_addr = force_reg (Pmode, buf_addr);
804 /* We used to store value in static_chain_rtx, but that fails if pointers
805 are smaller than integers. We instead require that the user must pass
806 a second argument of 1, because that is what builtin_setjmp will
807 return. This also makes EH slightly more efficient, since we are no
808 longer copying around a value that we don't care about. */
809 gcc_assert (value == const1_rtx);
811 last = get_last_insn ();
812 #ifdef HAVE_builtin_longjmp
813 if (HAVE_builtin_longjmp)
814 emit_insn (gen_builtin_longjmp (buf_addr));
818 fp = gen_rtx_MEM (Pmode, buf_addr);
819 lab = gen_rtx_MEM (Pmode, plus_constant (buf_addr,
820 GET_MODE_SIZE (Pmode)));
822 stack = gen_rtx_MEM (sa_mode, plus_constant (buf_addr,
823 2 * GET_MODE_SIZE (Pmode)));
824 set_mem_alias_set (fp, setjmp_alias_set);
825 set_mem_alias_set (lab, setjmp_alias_set);
826 set_mem_alias_set (stack, setjmp_alias_set);
828 /* Pick up FP, label, and SP from the block and jump. This code is
829 from expand_goto in stmt.c; see there for detailed comments. */
830 #ifdef HAVE_nonlocal_goto
831 if (HAVE_nonlocal_goto)
832 /* We have to pass a value to the nonlocal_goto pattern that will
833 get copied into the static_chain pointer, but it does not matter
834 what that value is, because builtin_setjmp does not use it. */
835 emit_insn (gen_nonlocal_goto (value, lab, stack, fp));
839 lab = copy_to_reg (lab);
841 emit_insn (gen_rtx_CLOBBER (VOIDmode,
842 gen_rtx_MEM (BLKmode,
843 gen_rtx_SCRATCH (VOIDmode))));
844 emit_insn (gen_rtx_CLOBBER (VOIDmode,
845 gen_rtx_MEM (BLKmode,
846 hard_frame_pointer_rtx)));
848 emit_move_insn (hard_frame_pointer_rtx, fp);
849 emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
851 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
852 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
853 emit_indirect_jump (lab);
857 /* Search backwards and mark the jump insn as a non-local goto.
858 Note that this precludes the use of __builtin_longjmp to a
859 __builtin_setjmp target in the same function. However, we've
860 already cautioned the user that these functions are for
861 internal exception handling use only. */
862 for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
864 gcc_assert (insn != last);
868 REG_NOTES (insn) = alloc_EXPR_LIST (REG_NON_LOCAL_GOTO, const0_rtx,
872 else if (CALL_P (insn))
877 /* Expand a call to __builtin_nonlocal_goto. We're passed the target label
878 and the address of the save area. */
881 expand_builtin_nonlocal_goto (tree arglist)
883 tree t_label, t_save_area;
884 rtx r_label, r_save_area, r_fp, r_sp, insn;
886 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
889 t_label = TREE_VALUE (arglist);
890 arglist = TREE_CHAIN (arglist);
891 t_save_area = TREE_VALUE (arglist);
893 r_label = expand_normal (t_label);
894 r_label = convert_memory_address (Pmode, r_label);
895 r_save_area = expand_normal (t_save_area);
896 r_save_area = convert_memory_address (Pmode, r_save_area);
897 r_fp = gen_rtx_MEM (Pmode, r_save_area);
898 r_sp = gen_rtx_MEM (STACK_SAVEAREA_MODE (SAVE_NONLOCAL),
899 plus_constant (r_save_area, GET_MODE_SIZE (Pmode)));
901 current_function_has_nonlocal_goto = 1;
903 #ifdef HAVE_nonlocal_goto
904 /* ??? We no longer need to pass the static chain value, afaik. */
905 if (HAVE_nonlocal_goto)
906 emit_insn (gen_nonlocal_goto (const0_rtx, r_label, r_sp, r_fp));
910 r_label = copy_to_reg (r_label);
912 emit_insn (gen_rtx_CLOBBER (VOIDmode,
913 gen_rtx_MEM (BLKmode,
914 gen_rtx_SCRATCH (VOIDmode))));
916 emit_insn (gen_rtx_CLOBBER (VOIDmode,
917 gen_rtx_MEM (BLKmode,
918 hard_frame_pointer_rtx)));
920 /* Restore frame pointer for containing function.
921 This sets the actual hard register used for the frame pointer
922 to the location of the function's incoming static chain info.
923 The non-local goto handler will then adjust it to contain the
924 proper value and reload the argument pointer, if needed. */
925 emit_move_insn (hard_frame_pointer_rtx, r_fp);
926 emit_stack_restore (SAVE_NONLOCAL, r_sp, NULL_RTX);
928 /* USE of hard_frame_pointer_rtx added for consistency;
929 not clear if really needed. */
930 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
931 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
932 emit_indirect_jump (r_label);
935 /* Search backwards to the jump insn and mark it as a
937 for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
941 REG_NOTES (insn) = alloc_EXPR_LIST (REG_NON_LOCAL_GOTO,
942 const0_rtx, REG_NOTES (insn));
945 else if (CALL_P (insn))
952 /* __builtin_update_setjmp_buf is passed a pointer to an array of five words
953 (not all will be used on all machines) that was passed to __builtin_setjmp.
954 It updates the stack pointer in that block to correspond to the current
958 expand_builtin_update_setjmp_buf (rtx buf_addr)
960 enum machine_mode sa_mode = Pmode;
964 #ifdef HAVE_save_stack_nonlocal
965 if (HAVE_save_stack_nonlocal)
966 sa_mode = insn_data[(int) CODE_FOR_save_stack_nonlocal].operand[0].mode;
968 #ifdef STACK_SAVEAREA_MODE
969 sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
973 = gen_rtx_MEM (sa_mode,
976 plus_constant (buf_addr, 2 * GET_MODE_SIZE (Pmode))));
980 emit_insn (gen_setjmp ());
983 emit_stack_save (SAVE_NONLOCAL, &stack_save, NULL_RTX);
986 /* Expand a call to __builtin_prefetch. For a target that does not support
987 data prefetch, evaluate the memory address argument in case it has side
991 expand_builtin_prefetch (tree arglist)
993 tree arg0, arg1, arg2;
996 if (!validate_arglist (arglist, POINTER_TYPE, 0))
999 arg0 = TREE_VALUE (arglist);
1000 /* Arguments 1 and 2 are optional; argument 1 (read/write) defaults to
1001 zero (read) and argument 2 (locality) defaults to 3 (high degree of
1003 if (TREE_CHAIN (arglist))
1005 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
1006 if (TREE_CHAIN (TREE_CHAIN (arglist)))
1007 arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
1009 arg2 = build_int_cst (NULL_TREE, 3);
1013 arg1 = integer_zero_node;
1014 arg2 = build_int_cst (NULL_TREE, 3);
1017 /* Argument 0 is an address. */
1018 op0 = expand_expr (arg0, NULL_RTX, Pmode, EXPAND_NORMAL);
1020 /* Argument 1 (read/write flag) must be a compile-time constant int. */
1021 if (TREE_CODE (arg1) != INTEGER_CST)
1023 error ("second argument to %<__builtin_prefetch%> must be a constant");
1024 arg1 = integer_zero_node;
1026 op1 = expand_normal (arg1);
1027 /* Argument 1 must be either zero or one. */
1028 if (INTVAL (op1) != 0 && INTVAL (op1) != 1)
1030 warning (0, "invalid second argument to %<__builtin_prefetch%>;"
1035 /* Argument 2 (locality) must be a compile-time constant int. */
1036 if (TREE_CODE (arg2) != INTEGER_CST)
1038 error ("third argument to %<__builtin_prefetch%> must be a constant");
1039 arg2 = integer_zero_node;
1041 op2 = expand_normal (arg2);
1042 /* Argument 2 must be 0, 1, 2, or 3. */
1043 if (INTVAL (op2) < 0 || INTVAL (op2) > 3)
1045 warning (0, "invalid third argument to %<__builtin_prefetch%>; using zero");
1049 #ifdef HAVE_prefetch
1052 if ((! (*insn_data[(int) CODE_FOR_prefetch].operand[0].predicate)
1054 insn_data[(int) CODE_FOR_prefetch].operand[0].mode))
1055 || (GET_MODE (op0) != Pmode))
1057 op0 = convert_memory_address (Pmode, op0);
1058 op0 = force_reg (Pmode, op0);
1060 emit_insn (gen_prefetch (op0, op1, op2));
1064 /* Don't do anything with direct references to volatile memory, but
1065 generate code to handle other side effects. */
1066 if (!MEM_P (op0) && side_effects_p (op0))
1070 /* Get a MEM rtx for expression EXP which is the address of an operand
1071 to be used in a string instruction (cmpstrsi, movmemsi, ..). LEN is
1072 the maximum length of the block of memory that might be accessed or
1076 get_memory_rtx (tree exp, tree len)
1078 rtx addr = expand_expr (exp, NULL_RTX, ptr_mode, EXPAND_NORMAL);
1079 rtx mem = gen_rtx_MEM (BLKmode, memory_address (BLKmode, addr));
1081 /* Get an expression we can use to find the attributes to assign to MEM.
1082 If it is an ADDR_EXPR, use the operand. Otherwise, dereference it if
1083 we can. First remove any nops. */
1084 while ((TREE_CODE (exp) == NOP_EXPR || TREE_CODE (exp) == CONVERT_EXPR
1085 || TREE_CODE (exp) == NON_LVALUE_EXPR)
1086 && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (exp, 0))))
1087 exp = TREE_OPERAND (exp, 0);
1089 if (TREE_CODE (exp) == ADDR_EXPR)
1090 exp = TREE_OPERAND (exp, 0);
1091 else if (POINTER_TYPE_P (TREE_TYPE (exp)))
1092 exp = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (exp)), exp);
1096 /* Honor attributes derived from exp, except for the alias set
1097 (as builtin stringops may alias with anything) and the size
1098 (as stringops may access multiple array elements). */
1101 set_mem_attributes (mem, exp, 0);
1103 /* Allow the string and memory builtins to overflow from one
1104 field into another, see http://gcc.gnu.org/PR23561.
1105 Thus avoid COMPONENT_REFs in MEM_EXPR unless we know the whole
1106 memory accessed by the string or memory builtin will fit
1107 within the field. */
1108 if (MEM_EXPR (mem) && TREE_CODE (MEM_EXPR (mem)) == COMPONENT_REF)
1110 tree mem_expr = MEM_EXPR (mem);
1111 HOST_WIDE_INT offset = -1, length = -1;
1114 while (TREE_CODE (inner) == ARRAY_REF
1115 || TREE_CODE (inner) == NOP_EXPR
1116 || TREE_CODE (inner) == CONVERT_EXPR
1117 || TREE_CODE (inner) == NON_LVALUE_EXPR
1118 || TREE_CODE (inner) == VIEW_CONVERT_EXPR
1119 || TREE_CODE (inner) == SAVE_EXPR)
1120 inner = TREE_OPERAND (inner, 0);
1122 gcc_assert (TREE_CODE (inner) == COMPONENT_REF);
1124 if (MEM_OFFSET (mem)
1125 && GET_CODE (MEM_OFFSET (mem)) == CONST_INT)
1126 offset = INTVAL (MEM_OFFSET (mem));
1128 if (offset >= 0 && len && host_integerp (len, 0))
1129 length = tree_low_cst (len, 0);
1131 while (TREE_CODE (inner) == COMPONENT_REF)
1133 tree field = TREE_OPERAND (inner, 1);
1134 gcc_assert (! DECL_BIT_FIELD (field));
1135 gcc_assert (TREE_CODE (mem_expr) == COMPONENT_REF);
1136 gcc_assert (field == TREE_OPERAND (mem_expr, 1));
1139 && TYPE_SIZE_UNIT (TREE_TYPE (inner))
1140 && host_integerp (TYPE_SIZE_UNIT (TREE_TYPE (inner)), 0))
1143 = tree_low_cst (TYPE_SIZE_UNIT (TREE_TYPE (inner)), 0);
1144 /* If we can prove the memory starting at XEXP (mem, 0)
1145 and ending at XEXP (mem, 0) + LENGTH will fit into
1146 this field, we can keep that COMPONENT_REF in MEM_EXPR. */
1149 && offset + length <= size)
1154 && host_integerp (DECL_FIELD_OFFSET (field), 0))
1155 offset += tree_low_cst (DECL_FIELD_OFFSET (field), 0)
1156 + tree_low_cst (DECL_FIELD_BIT_OFFSET (field), 1)
1164 mem_expr = TREE_OPERAND (mem_expr, 0);
1165 inner = TREE_OPERAND (inner, 0);
1168 if (mem_expr == NULL)
1170 if (mem_expr != MEM_EXPR (mem))
1172 set_mem_expr (mem, mem_expr);
1173 set_mem_offset (mem, offset >= 0 ? GEN_INT (offset) : NULL_RTX);
1176 set_mem_alias_set (mem, 0);
1177 set_mem_size (mem, NULL_RTX);
1183 /* Built-in functions to perform an untyped call and return. */
1185 /* For each register that may be used for calling a function, this
1186 gives a mode used to copy the register's value. VOIDmode indicates
1187 the register is not used for calling a function. If the machine
1188 has register windows, this gives only the outbound registers.
1189 INCOMING_REGNO gives the corresponding inbound register. */
1190 static enum machine_mode apply_args_mode[FIRST_PSEUDO_REGISTER];
1192 /* For each register that may be used for returning values, this gives
1193 a mode used to copy the register's value. VOIDmode indicates the
1194 register is not used for returning values. If the machine has
1195 register windows, this gives only the outbound registers.
1196 INCOMING_REGNO gives the corresponding inbound register. */
1197 static enum machine_mode apply_result_mode[FIRST_PSEUDO_REGISTER];
1199 /* For each register that may be used for calling a function, this
1200 gives the offset of that register into the block returned by
1201 __builtin_apply_args. 0 indicates that the register is not
1202 used for calling a function. */
1203 static int apply_args_reg_offset[FIRST_PSEUDO_REGISTER];
1205 /* Return the size required for the block returned by __builtin_apply_args,
1206 and initialize apply_args_mode. */
1209 apply_args_size (void)
1211 static int size = -1;
1214 enum machine_mode mode;
1216 /* The values computed by this function never change. */
1219 /* The first value is the incoming arg-pointer. */
1220 size = GET_MODE_SIZE (Pmode);
1222 /* The second value is the structure value address unless this is
1223 passed as an "invisible" first argument. */
1224 if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0))
1225 size += GET_MODE_SIZE (Pmode);
1227 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1228 if (FUNCTION_ARG_REGNO_P (regno))
1230 mode = reg_raw_mode[regno];
1232 gcc_assert (mode != VOIDmode);
1234 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1235 if (size % align != 0)
1236 size = CEIL (size, align) * align;
1237 apply_args_reg_offset[regno] = size;
1238 size += GET_MODE_SIZE (mode);
1239 apply_args_mode[regno] = mode;
1243 apply_args_mode[regno] = VOIDmode;
1244 apply_args_reg_offset[regno] = 0;
1250 /* Return the size required for the block returned by __builtin_apply,
1251 and initialize apply_result_mode. */
1254 apply_result_size (void)
1256 static int size = -1;
1258 enum machine_mode mode;
1260 /* The values computed by this function never change. */
1265 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1266 if (FUNCTION_VALUE_REGNO_P (regno))
1268 mode = reg_raw_mode[regno];
1270 gcc_assert (mode != VOIDmode);
1272 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1273 if (size % align != 0)
1274 size = CEIL (size, align) * align;
1275 size += GET_MODE_SIZE (mode);
1276 apply_result_mode[regno] = mode;
1279 apply_result_mode[regno] = VOIDmode;
1281 /* Allow targets that use untyped_call and untyped_return to override
1282 the size so that machine-specific information can be stored here. */
1283 #ifdef APPLY_RESULT_SIZE
1284 size = APPLY_RESULT_SIZE;
1290 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
1291 /* Create a vector describing the result block RESULT. If SAVEP is true,
1292 the result block is used to save the values; otherwise it is used to
1293 restore the values. */
1296 result_vector (int savep, rtx result)
1298 int regno, size, align, nelts;
1299 enum machine_mode mode;
1301 rtx *savevec = alloca (FIRST_PSEUDO_REGISTER * sizeof (rtx));
1304 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1305 if ((mode = apply_result_mode[regno]) != VOIDmode)
1307 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1308 if (size % align != 0)
1309 size = CEIL (size, align) * align;
1310 reg = gen_rtx_REG (mode, savep ? regno : INCOMING_REGNO (regno));
1311 mem = adjust_address (result, mode, size);
1312 savevec[nelts++] = (savep
1313 ? gen_rtx_SET (VOIDmode, mem, reg)
1314 : gen_rtx_SET (VOIDmode, reg, mem));
1315 size += GET_MODE_SIZE (mode);
1317 return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (nelts, savevec));
1319 #endif /* HAVE_untyped_call or HAVE_untyped_return */
1321 /* Save the state required to perform an untyped call with the same
1322 arguments as were passed to the current function. */
1325 expand_builtin_apply_args_1 (void)
1328 int size, align, regno;
1329 enum machine_mode mode;
1330 rtx struct_incoming_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 1);
1332 /* Create a block where the arg-pointer, structure value address,
1333 and argument registers can be saved. */
1334 registers = assign_stack_local (BLKmode, apply_args_size (), -1);
1336 /* Walk past the arg-pointer and structure value address. */
1337 size = GET_MODE_SIZE (Pmode);
1338 if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0))
1339 size += GET_MODE_SIZE (Pmode);
1341 /* Save each register used in calling a function to the block. */
1342 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1343 if ((mode = apply_args_mode[regno]) != VOIDmode)
1345 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1346 if (size % align != 0)
1347 size = CEIL (size, align) * align;
1349 tem = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1351 emit_move_insn (adjust_address (registers, mode, size), tem);
1352 size += GET_MODE_SIZE (mode);
1355 /* Save the arg pointer to the block. */
1356 tem = copy_to_reg (virtual_incoming_args_rtx);
1357 #ifdef STACK_GROWS_DOWNWARD
1358 /* We need the pointer as the caller actually passed them to us, not
1359 as we might have pretended they were passed. Make sure it's a valid
1360 operand, as emit_move_insn isn't expected to handle a PLUS. */
1362 = force_operand (plus_constant (tem, current_function_pretend_args_size),
1365 emit_move_insn (adjust_address (registers, Pmode, 0), tem);
1367 size = GET_MODE_SIZE (Pmode);
1369 /* Save the structure value address unless this is passed as an
1370 "invisible" first argument. */
1371 if (struct_incoming_value)
1373 emit_move_insn (adjust_address (registers, Pmode, size),
1374 copy_to_reg (struct_incoming_value));
1375 size += GET_MODE_SIZE (Pmode);
1378 /* Return the address of the block. */
1379 return copy_addr_to_reg (XEXP (registers, 0));
1382 /* __builtin_apply_args returns block of memory allocated on
1383 the stack into which is stored the arg pointer, structure
1384 value address, static chain, and all the registers that might
1385 possibly be used in performing a function call. The code is
1386 moved to the start of the function so the incoming values are
1390 expand_builtin_apply_args (void)
1392 /* Don't do __builtin_apply_args more than once in a function.
1393 Save the result of the first call and reuse it. */
1394 if (apply_args_value != 0)
1395 return apply_args_value;
1397 /* When this function is called, it means that registers must be
1398 saved on entry to this function. So we migrate the
1399 call to the first insn of this function. */
1404 temp = expand_builtin_apply_args_1 ();
1408 apply_args_value = temp;
1410 /* Put the insns after the NOTE that starts the function.
1411 If this is inside a start_sequence, make the outer-level insn
1412 chain current, so the code is placed at the start of the
1414 push_topmost_sequence ();
1415 emit_insn_before (seq, NEXT_INSN (entry_of_function ()));
1416 pop_topmost_sequence ();
1421 /* Perform an untyped call and save the state required to perform an
1422 untyped return of whatever value was returned by the given function. */
1425 expand_builtin_apply (rtx function, rtx arguments, rtx argsize)
1427 int size, align, regno;
1428 enum machine_mode mode;
1429 rtx incoming_args, result, reg, dest, src, call_insn;
1430 rtx old_stack_level = 0;
1431 rtx call_fusage = 0;
1432 rtx struct_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0);
1434 arguments = convert_memory_address (Pmode, arguments);
1436 /* Create a block where the return registers can be saved. */
1437 result = assign_stack_local (BLKmode, apply_result_size (), -1);
1439 /* Fetch the arg pointer from the ARGUMENTS block. */
1440 incoming_args = gen_reg_rtx (Pmode);
1441 emit_move_insn (incoming_args, gen_rtx_MEM (Pmode, arguments));
1442 #ifndef STACK_GROWS_DOWNWARD
1443 incoming_args = expand_simple_binop (Pmode, MINUS, incoming_args, argsize,
1444 incoming_args, 0, OPTAB_LIB_WIDEN);
1447 /* Push a new argument block and copy the arguments. Do not allow
1448 the (potential) memcpy call below to interfere with our stack
1450 do_pending_stack_adjust ();
1453 /* Save the stack with nonlocal if available. */
1454 #ifdef HAVE_save_stack_nonlocal
1455 if (HAVE_save_stack_nonlocal)
1456 emit_stack_save (SAVE_NONLOCAL, &old_stack_level, NULL_RTX);
1459 emit_stack_save (SAVE_BLOCK, &old_stack_level, NULL_RTX);
1461 /* Allocate a block of memory onto the stack and copy the memory
1462 arguments to the outgoing arguments address. */
1463 allocate_dynamic_stack_space (argsize, 0, BITS_PER_UNIT);
1464 dest = virtual_outgoing_args_rtx;
1465 #ifndef STACK_GROWS_DOWNWARD
1466 if (GET_CODE (argsize) == CONST_INT)
1467 dest = plus_constant (dest, -INTVAL (argsize));
1469 dest = gen_rtx_PLUS (Pmode, dest, negate_rtx (Pmode, argsize));
1471 dest = gen_rtx_MEM (BLKmode, dest);
1472 set_mem_align (dest, PARM_BOUNDARY);
1473 src = gen_rtx_MEM (BLKmode, incoming_args);
1474 set_mem_align (src, PARM_BOUNDARY);
1475 emit_block_move (dest, src, argsize, BLOCK_OP_NORMAL);
1477 /* Refer to the argument block. */
1479 arguments = gen_rtx_MEM (BLKmode, arguments);
1480 set_mem_align (arguments, PARM_BOUNDARY);
1482 /* Walk past the arg-pointer and structure value address. */
1483 size = GET_MODE_SIZE (Pmode);
1485 size += GET_MODE_SIZE (Pmode);
1487 /* Restore each of the registers previously saved. Make USE insns
1488 for each of these registers for use in making the call. */
1489 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1490 if ((mode = apply_args_mode[regno]) != VOIDmode)
1492 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1493 if (size % align != 0)
1494 size = CEIL (size, align) * align;
1495 reg = gen_rtx_REG (mode, regno);
1496 emit_move_insn (reg, adjust_address (arguments, mode, size));
1497 use_reg (&call_fusage, reg);
1498 size += GET_MODE_SIZE (mode);
1501 /* Restore the structure value address unless this is passed as an
1502 "invisible" first argument. */
1503 size = GET_MODE_SIZE (Pmode);
1506 rtx value = gen_reg_rtx (Pmode);
1507 emit_move_insn (value, adjust_address (arguments, Pmode, size));
1508 emit_move_insn (struct_value, value);
1509 if (REG_P (struct_value))
1510 use_reg (&call_fusage, struct_value);
1511 size += GET_MODE_SIZE (Pmode);
1514 /* All arguments and registers used for the call are set up by now! */
1515 function = prepare_call_address (function, NULL, &call_fusage, 0, 0);
1517 /* Ensure address is valid. SYMBOL_REF is already valid, so no need,
1518 and we don't want to load it into a register as an optimization,
1519 because prepare_call_address already did it if it should be done. */
1520 if (GET_CODE (function) != SYMBOL_REF)
1521 function = memory_address (FUNCTION_MODE, function);
1523 /* Generate the actual call instruction and save the return value. */
1524 #ifdef HAVE_untyped_call
1525 if (HAVE_untyped_call)
1526 emit_call_insn (gen_untyped_call (gen_rtx_MEM (FUNCTION_MODE, function),
1527 result, result_vector (1, result)));
1530 #ifdef HAVE_call_value
1531 if (HAVE_call_value)
1535 /* Locate the unique return register. It is not possible to
1536 express a call that sets more than one return register using
1537 call_value; use untyped_call for that. In fact, untyped_call
1538 only needs to save the return registers in the given block. */
1539 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1540 if ((mode = apply_result_mode[regno]) != VOIDmode)
1542 gcc_assert (!valreg); /* HAVE_untyped_call required. */
1544 valreg = gen_rtx_REG (mode, regno);
1547 emit_call_insn (GEN_CALL_VALUE (valreg,
1548 gen_rtx_MEM (FUNCTION_MODE, function),
1549 const0_rtx, NULL_RTX, const0_rtx));
1551 emit_move_insn (adjust_address (result, GET_MODE (valreg), 0), valreg);
1557 /* Find the CALL insn we just emitted, and attach the register usage
1559 call_insn = last_call_insn ();
1560 add_function_usage_to (call_insn, call_fusage);
1562 /* Restore the stack. */
1563 #ifdef HAVE_save_stack_nonlocal
1564 if (HAVE_save_stack_nonlocal)
1565 emit_stack_restore (SAVE_NONLOCAL, old_stack_level, NULL_RTX);
1568 emit_stack_restore (SAVE_BLOCK, old_stack_level, NULL_RTX);
1572 /* Return the address of the result block. */
1573 result = copy_addr_to_reg (XEXP (result, 0));
1574 return convert_memory_address (ptr_mode, result);
1577 /* Perform an untyped return. */
1580 expand_builtin_return (rtx result)
1582 int size, align, regno;
1583 enum machine_mode mode;
1585 rtx call_fusage = 0;
1587 result = convert_memory_address (Pmode, result);
1589 apply_result_size ();
1590 result = gen_rtx_MEM (BLKmode, result);
1592 #ifdef HAVE_untyped_return
1593 if (HAVE_untyped_return)
1595 emit_jump_insn (gen_untyped_return (result, result_vector (0, result)));
1601 /* Restore the return value and note that each value is used. */
1603 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1604 if ((mode = apply_result_mode[regno]) != VOIDmode)
1606 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1607 if (size % align != 0)
1608 size = CEIL (size, align) * align;
1609 reg = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1610 emit_move_insn (reg, adjust_address (result, mode, size));
1612 push_to_sequence (call_fusage);
1613 emit_insn (gen_rtx_USE (VOIDmode, reg));
1614 call_fusage = get_insns ();
1616 size += GET_MODE_SIZE (mode);
1619 /* Put the USE insns before the return. */
1620 emit_insn (call_fusage);
1622 /* Return whatever values was restored by jumping directly to the end
1624 expand_naked_return ();
1627 /* Used by expand_builtin_classify_type and fold_builtin_classify_type. */
1629 static enum type_class
1630 type_to_class (tree type)
1632 switch (TREE_CODE (type))
1634 case VOID_TYPE: return void_type_class;
1635 case INTEGER_TYPE: return integer_type_class;
1636 case ENUMERAL_TYPE: return enumeral_type_class;
1637 case BOOLEAN_TYPE: return boolean_type_class;
1638 case POINTER_TYPE: return pointer_type_class;
1639 case REFERENCE_TYPE: return reference_type_class;
1640 case OFFSET_TYPE: return offset_type_class;
1641 case REAL_TYPE: return real_type_class;
1642 case COMPLEX_TYPE: return complex_type_class;
1643 case FUNCTION_TYPE: return function_type_class;
1644 case METHOD_TYPE: return method_type_class;
1645 case RECORD_TYPE: return record_type_class;
1647 case QUAL_UNION_TYPE: return union_type_class;
1648 case ARRAY_TYPE: return (TYPE_STRING_FLAG (type)
1649 ? string_type_class : array_type_class);
1650 case LANG_TYPE: return lang_type_class;
1651 default: return no_type_class;
1655 /* Expand a call to __builtin_classify_type with arguments found in
1659 expand_builtin_classify_type (tree arglist)
1662 return GEN_INT (type_to_class (TREE_TYPE (TREE_VALUE (arglist))));
1663 return GEN_INT (no_type_class);
1666 /* This helper macro, meant to be used in mathfn_built_in below,
1667 determines which among a set of three builtin math functions is
1668 appropriate for a given type mode. The `F' and `L' cases are
1669 automatically generated from the `double' case. */
1670 #define CASE_MATHFN(BUILT_IN_MATHFN) \
1671 case BUILT_IN_MATHFN: case BUILT_IN_MATHFN##F: case BUILT_IN_MATHFN##L: \
1672 fcode = BUILT_IN_MATHFN; fcodef = BUILT_IN_MATHFN##F ; \
1673 fcodel = BUILT_IN_MATHFN##L ; break;
1675 /* Return mathematic function equivalent to FN but operating directly
1676 on TYPE, if available. If we can't do the conversion, return zero. */
1678 mathfn_built_in (tree type, enum built_in_function fn)
1680 enum built_in_function fcode, fcodef, fcodel;
1684 CASE_MATHFN (BUILT_IN_ACOS)
1685 CASE_MATHFN (BUILT_IN_ACOSH)
1686 CASE_MATHFN (BUILT_IN_ASIN)
1687 CASE_MATHFN (BUILT_IN_ASINH)
1688 CASE_MATHFN (BUILT_IN_ATAN)
1689 CASE_MATHFN (BUILT_IN_ATAN2)
1690 CASE_MATHFN (BUILT_IN_ATANH)
1691 CASE_MATHFN (BUILT_IN_CBRT)
1692 CASE_MATHFN (BUILT_IN_CEIL)
1693 CASE_MATHFN (BUILT_IN_COPYSIGN)
1694 CASE_MATHFN (BUILT_IN_COS)
1695 CASE_MATHFN (BUILT_IN_COSH)
1696 CASE_MATHFN (BUILT_IN_DREM)
1697 CASE_MATHFN (BUILT_IN_ERF)
1698 CASE_MATHFN (BUILT_IN_ERFC)
1699 CASE_MATHFN (BUILT_IN_EXP)
1700 CASE_MATHFN (BUILT_IN_EXP10)
1701 CASE_MATHFN (BUILT_IN_EXP2)
1702 CASE_MATHFN (BUILT_IN_EXPM1)
1703 CASE_MATHFN (BUILT_IN_FABS)
1704 CASE_MATHFN (BUILT_IN_FDIM)
1705 CASE_MATHFN (BUILT_IN_FLOOR)
1706 CASE_MATHFN (BUILT_IN_FMA)
1707 CASE_MATHFN (BUILT_IN_FMAX)
1708 CASE_MATHFN (BUILT_IN_FMIN)
1709 CASE_MATHFN (BUILT_IN_FMOD)
1710 CASE_MATHFN (BUILT_IN_FREXP)
1711 CASE_MATHFN (BUILT_IN_GAMMA)
1712 CASE_MATHFN (BUILT_IN_HUGE_VAL)
1713 CASE_MATHFN (BUILT_IN_HYPOT)
1714 CASE_MATHFN (BUILT_IN_ILOGB)
1715 CASE_MATHFN (BUILT_IN_INF)
1716 CASE_MATHFN (BUILT_IN_J0)
1717 CASE_MATHFN (BUILT_IN_J1)
1718 CASE_MATHFN (BUILT_IN_JN)
1719 CASE_MATHFN (BUILT_IN_LCEIL)
1720 CASE_MATHFN (BUILT_IN_LDEXP)
1721 CASE_MATHFN (BUILT_IN_LFLOOR)
1722 CASE_MATHFN (BUILT_IN_LGAMMA)
1723 CASE_MATHFN (BUILT_IN_LLCEIL)
1724 CASE_MATHFN (BUILT_IN_LLFLOOR)
1725 CASE_MATHFN (BUILT_IN_LLRINT)
1726 CASE_MATHFN (BUILT_IN_LLROUND)
1727 CASE_MATHFN (BUILT_IN_LOG)
1728 CASE_MATHFN (BUILT_IN_LOG10)
1729 CASE_MATHFN (BUILT_IN_LOG1P)
1730 CASE_MATHFN (BUILT_IN_LOG2)
1731 CASE_MATHFN (BUILT_IN_LOGB)
1732 CASE_MATHFN (BUILT_IN_LRINT)
1733 CASE_MATHFN (BUILT_IN_LROUND)
1734 CASE_MATHFN (BUILT_IN_MODF)
1735 CASE_MATHFN (BUILT_IN_NAN)
1736 CASE_MATHFN (BUILT_IN_NANS)
1737 CASE_MATHFN (BUILT_IN_NEARBYINT)
1738 CASE_MATHFN (BUILT_IN_NEXTAFTER)
1739 CASE_MATHFN (BUILT_IN_NEXTTOWARD)
1740 CASE_MATHFN (BUILT_IN_POW)
1741 CASE_MATHFN (BUILT_IN_POWI)
1742 CASE_MATHFN (BUILT_IN_POW10)
1743 CASE_MATHFN (BUILT_IN_REMAINDER)
1744 CASE_MATHFN (BUILT_IN_REMQUO)
1745 CASE_MATHFN (BUILT_IN_RINT)
1746 CASE_MATHFN (BUILT_IN_ROUND)
1747 CASE_MATHFN (BUILT_IN_SCALB)
1748 CASE_MATHFN (BUILT_IN_SCALBLN)
1749 CASE_MATHFN (BUILT_IN_SCALBN)
1750 CASE_MATHFN (BUILT_IN_SIGNIFICAND)
1751 CASE_MATHFN (BUILT_IN_SIN)
1752 CASE_MATHFN (BUILT_IN_SINCOS)
1753 CASE_MATHFN (BUILT_IN_SINH)
1754 CASE_MATHFN (BUILT_IN_SQRT)
1755 CASE_MATHFN (BUILT_IN_TAN)
1756 CASE_MATHFN (BUILT_IN_TANH)
1757 CASE_MATHFN (BUILT_IN_TGAMMA)
1758 CASE_MATHFN (BUILT_IN_TRUNC)
1759 CASE_MATHFN (BUILT_IN_Y0)
1760 CASE_MATHFN (BUILT_IN_Y1)
1761 CASE_MATHFN (BUILT_IN_YN)
1767 if (TYPE_MAIN_VARIANT (type) == double_type_node)
1768 return implicit_built_in_decls[fcode];
1769 else if (TYPE_MAIN_VARIANT (type) == float_type_node)
1770 return implicit_built_in_decls[fcodef];
1771 else if (TYPE_MAIN_VARIANT (type) == long_double_type_node)
1772 return implicit_built_in_decls[fcodel];
1777 /* If errno must be maintained, expand the RTL to check if the result,
1778 TARGET, of a built-in function call, EXP, is NaN, and if so set
1782 expand_errno_check (tree exp, rtx target)
1784 rtx lab = gen_label_rtx ();
1786 /* Test the result; if it is NaN, set errno=EDOM because
1787 the argument was not in the domain. */
1788 emit_cmp_and_jump_insns (target, target, EQ, 0, GET_MODE (target),
1792 /* If this built-in doesn't throw an exception, set errno directly. */
1793 if (TREE_NOTHROW (TREE_OPERAND (TREE_OPERAND (exp, 0), 0)))
1795 #ifdef GEN_ERRNO_RTX
1796 rtx errno_rtx = GEN_ERRNO_RTX;
1799 = gen_rtx_MEM (word_mode, gen_rtx_SYMBOL_REF (Pmode, "errno"));
1801 emit_move_insn (errno_rtx, GEN_INT (TARGET_EDOM));
1807 /* We can't set errno=EDOM directly; let the library call do it.
1808 Pop the arguments right away in case the call gets deleted. */
1810 expand_call (exp, target, 0);
1816 /* Expand a call to one of the builtin math functions (sqrt, exp, or log).
1817 Return 0 if a normal call should be emitted rather than expanding the
1818 function in-line. EXP is the expression that is a call to the builtin
1819 function; if convenient, the result should be placed in TARGET.
1820 SUBTARGET may be used as the target for computing one of EXP's operands. */
1823 expand_builtin_mathfn (tree exp, rtx target, rtx subtarget)
1825 optab builtin_optab;
1826 rtx op0, insns, before_call;
1827 tree fndecl = get_callee_fndecl (exp);
1828 tree arglist = TREE_OPERAND (exp, 1);
1829 enum machine_mode mode;
1830 bool errno_set = false;
1833 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
1836 arg = TREE_VALUE (arglist);
1838 switch (DECL_FUNCTION_CODE (fndecl))
1840 CASE_FLT_FN (BUILT_IN_SQRT):
1841 errno_set = ! tree_expr_nonnegative_p (arg);
1842 builtin_optab = sqrt_optab;
1844 CASE_FLT_FN (BUILT_IN_EXP):
1845 errno_set = true; builtin_optab = exp_optab; break;
1846 CASE_FLT_FN (BUILT_IN_EXP10):
1847 CASE_FLT_FN (BUILT_IN_POW10):
1848 errno_set = true; builtin_optab = exp10_optab; break;
1849 CASE_FLT_FN (BUILT_IN_EXP2):
1850 errno_set = true; builtin_optab = exp2_optab; break;
1851 CASE_FLT_FN (BUILT_IN_EXPM1):
1852 errno_set = true; builtin_optab = expm1_optab; break;
1853 CASE_FLT_FN (BUILT_IN_LOGB):
1854 errno_set = true; builtin_optab = logb_optab; break;
1855 CASE_FLT_FN (BUILT_IN_ILOGB):
1856 errno_set = true; builtin_optab = ilogb_optab; break;
1857 CASE_FLT_FN (BUILT_IN_LOG):
1858 errno_set = true; builtin_optab = log_optab; break;
1859 CASE_FLT_FN (BUILT_IN_LOG10):
1860 errno_set = true; builtin_optab = log10_optab; break;
1861 CASE_FLT_FN (BUILT_IN_LOG2):
1862 errno_set = true; builtin_optab = log2_optab; break;
1863 CASE_FLT_FN (BUILT_IN_LOG1P):
1864 errno_set = true; builtin_optab = log1p_optab; break;
1865 CASE_FLT_FN (BUILT_IN_ASIN):
1866 builtin_optab = asin_optab; break;
1867 CASE_FLT_FN (BUILT_IN_ACOS):
1868 builtin_optab = acos_optab; break;
1869 CASE_FLT_FN (BUILT_IN_TAN):
1870 builtin_optab = tan_optab; break;
1871 CASE_FLT_FN (BUILT_IN_ATAN):
1872 builtin_optab = atan_optab; break;
1873 CASE_FLT_FN (BUILT_IN_FLOOR):
1874 builtin_optab = floor_optab; break;
1875 CASE_FLT_FN (BUILT_IN_CEIL):
1876 builtin_optab = ceil_optab; break;
1877 CASE_FLT_FN (BUILT_IN_TRUNC):
1878 builtin_optab = btrunc_optab; break;
1879 CASE_FLT_FN (BUILT_IN_ROUND):
1880 builtin_optab = round_optab; break;
1881 CASE_FLT_FN (BUILT_IN_NEARBYINT):
1882 builtin_optab = nearbyint_optab; break;
1883 CASE_FLT_FN (BUILT_IN_RINT):
1884 builtin_optab = rint_optab; break;
1885 CASE_FLT_FN (BUILT_IN_LRINT):
1886 CASE_FLT_FN (BUILT_IN_LLRINT):
1887 builtin_optab = lrint_optab; break;
1892 /* Make a suitable register to place result in. */
1893 mode = TYPE_MODE (TREE_TYPE (exp));
1895 if (! flag_errno_math || ! HONOR_NANS (mode))
1898 /* Before working hard, check whether the instruction is available. */
1899 if (builtin_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1901 target = gen_reg_rtx (mode);
1903 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
1904 need to expand the argument again. This way, we will not perform
1905 side-effects more the once. */
1906 narg = builtin_save_expr (arg);
1910 arglist = build_tree_list (NULL_TREE, arg);
1911 exp = build_function_call_expr (fndecl, arglist);
1914 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
1918 /* Compute into TARGET.
1919 Set TARGET to wherever the result comes back. */
1920 target = expand_unop (mode, builtin_optab, op0, target, 0);
1925 expand_errno_check (exp, target);
1927 /* Output the entire sequence. */
1928 insns = get_insns ();
1934 /* If we were unable to expand via the builtin, stop the sequence
1935 (without outputting the insns) and call to the library function
1936 with the stabilized argument list. */
1940 before_call = get_last_insn ();
1942 target = expand_call (exp, target, target == const0_rtx);
1944 /* If this is a sqrt operation and we don't care about errno, try to
1945 attach a REG_EQUAL note with a SQRT rtx to the emitted libcall.
1946 This allows the semantics of the libcall to be visible to the RTL
1948 if (builtin_optab == sqrt_optab && !errno_set)
1950 /* Search backwards through the insns emitted by expand_call looking
1951 for the instruction with the REG_RETVAL note. */
1952 rtx last = get_last_insn ();
1953 while (last != before_call)
1955 if (find_reg_note (last, REG_RETVAL, NULL))
1957 rtx note = find_reg_note (last, REG_EQUAL, NULL);
1958 /* Check that the REQ_EQUAL note is an EXPR_LIST with
1959 two elements, i.e. symbol_ref(sqrt) and the operand. */
1961 && GET_CODE (note) == EXPR_LIST
1962 && GET_CODE (XEXP (note, 0)) == EXPR_LIST
1963 && XEXP (XEXP (note, 0), 1) != NULL_RTX
1964 && XEXP (XEXP (XEXP (note, 0), 1), 1) == NULL_RTX)
1966 rtx operand = XEXP (XEXP (XEXP (note, 0), 1), 0);
1967 /* Check operand is a register with expected mode. */
1970 && GET_MODE (operand) == mode)
1972 /* Replace the REG_EQUAL note with a SQRT rtx. */
1973 rtx equiv = gen_rtx_SQRT (mode, operand);
1974 set_unique_reg_note (last, REG_EQUAL, equiv);
1979 last = PREV_INSN (last);
1986 /* Expand a call to the builtin binary math functions (pow and atan2).
1987 Return 0 if a normal call should be emitted rather than expanding the
1988 function in-line. EXP is the expression that is a call to the builtin
1989 function; if convenient, the result should be placed in TARGET.
1990 SUBTARGET may be used as the target for computing one of EXP's
1994 expand_builtin_mathfn_2 (tree exp, rtx target, rtx subtarget)
1996 optab builtin_optab;
1997 rtx op0, op1, insns;
1998 int op1_type = REAL_TYPE;
1999 tree fndecl = get_callee_fndecl (exp);
2000 tree arglist = TREE_OPERAND (exp, 1);
2001 tree arg0, arg1, temp, narg;
2002 enum machine_mode mode;
2003 bool errno_set = true;
2006 if ((DECL_FUNCTION_CODE (fndecl) == BUILT_IN_LDEXP)
2007 || (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_LDEXPF)
2008 || (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_LDEXPL))
2009 op1_type = INTEGER_TYPE;
2011 if (!validate_arglist (arglist, REAL_TYPE, op1_type, VOID_TYPE))
2014 arg0 = TREE_VALUE (arglist);
2015 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
2017 switch (DECL_FUNCTION_CODE (fndecl))
2019 CASE_FLT_FN (BUILT_IN_POW):
2020 builtin_optab = pow_optab; break;
2021 CASE_FLT_FN (BUILT_IN_ATAN2):
2022 builtin_optab = atan2_optab; break;
2023 CASE_FLT_FN (BUILT_IN_LDEXP):
2024 builtin_optab = ldexp_optab; break;
2025 CASE_FLT_FN (BUILT_IN_FMOD):
2026 builtin_optab = fmod_optab; break;
2027 CASE_FLT_FN (BUILT_IN_DREM):
2028 builtin_optab = drem_optab; break;
2033 /* Make a suitable register to place result in. */
2034 mode = TYPE_MODE (TREE_TYPE (exp));
2036 /* Before working hard, check whether the instruction is available. */
2037 if (builtin_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing)
2040 target = gen_reg_rtx (mode);
2042 if (! flag_errno_math || ! HONOR_NANS (mode))
2045 /* Always stabilize the argument list. */
2046 narg = builtin_save_expr (arg1);
2050 temp = build_tree_list (NULL_TREE, narg);
2054 temp = TREE_CHAIN (arglist);
2056 narg = builtin_save_expr (arg0);
2060 arglist = tree_cons (NULL_TREE, narg, temp);
2064 arglist = tree_cons (NULL_TREE, arg0, temp);
2067 exp = build_function_call_expr (fndecl, arglist);
2069 op0 = expand_expr (arg0, subtarget, VOIDmode, EXPAND_NORMAL);
2070 op1 = expand_normal (arg1);
2074 /* Compute into TARGET.
2075 Set TARGET to wherever the result comes back. */
2076 target = expand_binop (mode, builtin_optab, op0, op1,
2077 target, 0, OPTAB_DIRECT);
2079 /* If we were unable to expand via the builtin, stop the sequence
2080 (without outputting the insns) and call to the library function
2081 with the stabilized argument list. */
2085 return expand_call (exp, target, target == const0_rtx);
2089 expand_errno_check (exp, target);
2091 /* Output the entire sequence. */
2092 insns = get_insns ();
2099 /* Expand a call to the builtin sin and cos math functions.
2100 Return 0 if a normal call should be emitted rather than expanding the
2101 function in-line. EXP is the expression that is a call to the builtin
2102 function; if convenient, the result should be placed in TARGET.
2103 SUBTARGET may be used as the target for computing one of EXP's
2107 expand_builtin_mathfn_3 (tree exp, rtx target, rtx subtarget)
2109 optab builtin_optab;
2111 tree fndecl = get_callee_fndecl (exp);
2112 tree arglist = TREE_OPERAND (exp, 1);
2113 enum machine_mode mode;
2116 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
2119 arg = TREE_VALUE (arglist);
2121 switch (DECL_FUNCTION_CODE (fndecl))
2123 CASE_FLT_FN (BUILT_IN_SIN):
2124 CASE_FLT_FN (BUILT_IN_COS):
2125 builtin_optab = sincos_optab; break;
2130 /* Make a suitable register to place result in. */
2131 mode = TYPE_MODE (TREE_TYPE (exp));
2133 /* Check if sincos insn is available, otherwise fallback
2134 to sin or cos insn. */
2135 if (builtin_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing) {
2136 switch (DECL_FUNCTION_CODE (fndecl))
2138 CASE_FLT_FN (BUILT_IN_SIN):
2139 builtin_optab = sin_optab; break;
2140 CASE_FLT_FN (BUILT_IN_COS):
2141 builtin_optab = cos_optab; break;
2147 /* Before working hard, check whether the instruction is available. */
2148 if (builtin_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2150 target = gen_reg_rtx (mode);
2152 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2153 need to expand the argument again. This way, we will not perform
2154 side-effects more the once. */
2155 narg = save_expr (arg);
2159 arglist = build_tree_list (NULL_TREE, arg);
2160 exp = build_function_call_expr (fndecl, arglist);
2163 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
2167 /* Compute into TARGET.
2168 Set TARGET to wherever the result comes back. */
2169 if (builtin_optab == sincos_optab)
2173 switch (DECL_FUNCTION_CODE (fndecl))
2175 CASE_FLT_FN (BUILT_IN_SIN):
2176 result = expand_twoval_unop (builtin_optab, op0, 0, target, 0);
2178 CASE_FLT_FN (BUILT_IN_COS):
2179 result = expand_twoval_unop (builtin_optab, op0, target, 0, 0);
2184 gcc_assert (result);
2188 target = expand_unop (mode, builtin_optab, op0, target, 0);
2193 /* Output the entire sequence. */
2194 insns = get_insns ();
2200 /* If we were unable to expand via the builtin, stop the sequence
2201 (without outputting the insns) and call to the library function
2202 with the stabilized argument list. */
2206 target = expand_call (exp, target, target == const0_rtx);
2211 /* Expand a call to the builtin sincos math function.
2212 Return 0 if a normal call should be emitted rather than expanding the
2213 function in-line. EXP is the expression that is a call to the builtin
2217 expand_builtin_sincos (tree exp)
2219 rtx op0, op1, op2, target1, target2;
2220 tree arglist = TREE_OPERAND (exp, 1);
2221 enum machine_mode mode;
2222 tree arg, sinp, cosp;
2225 if (!validate_arglist (arglist, REAL_TYPE,
2226 POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2229 arg = TREE_VALUE (arglist);
2230 sinp = TREE_VALUE (TREE_CHAIN (arglist));
2231 cosp = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2233 /* Make a suitable register to place result in. */
2234 mode = TYPE_MODE (TREE_TYPE (arg));
2236 /* Check if sincos insn is available, otherwise emit the call. */
2237 if (sincos_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing)
2240 target1 = gen_reg_rtx (mode);
2241 target2 = gen_reg_rtx (mode);
2243 op0 = expand_normal (arg);
2244 op1 = expand_normal (build_fold_indirect_ref (sinp));
2245 op2 = expand_normal (build_fold_indirect_ref (cosp));
2247 /* Compute into target1 and target2.
2248 Set TARGET to wherever the result comes back. */
2249 result = expand_twoval_unop (sincos_optab, op0, target2, target1, 0);
2250 gcc_assert (result);
2252 /* Move target1 and target2 to the memory locations indicated
2254 emit_move_insn (op1, target1);
2255 emit_move_insn (op2, target2);
2260 /* Expand a call to one of the builtin rounding functions (lfloor).
2261 If expanding via optab fails, lower expression to (int)(floor(x)).
2262 EXP is the expression that is a call to the builtin function;
2263 if convenient, the result should be placed in TARGET. SUBTARGET may
2264 be used as the target for computing one of EXP's operands. */
2267 expand_builtin_int_roundingfn (tree exp, rtx target, rtx subtarget)
2269 optab builtin_optab;
2270 rtx op0, insns, tmp;
2271 tree fndecl = get_callee_fndecl (exp);
2272 tree arglist = TREE_OPERAND (exp, 1);
2273 enum built_in_function fallback_fn;
2274 tree fallback_fndecl;
2275 enum machine_mode mode;
2278 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
2281 arg = TREE_VALUE (arglist);
2283 switch (DECL_FUNCTION_CODE (fndecl))
2285 CASE_FLT_FN (BUILT_IN_LCEIL):
2286 CASE_FLT_FN (BUILT_IN_LLCEIL):
2287 builtin_optab = lceil_optab;
2288 fallback_fn = BUILT_IN_CEIL;
2291 CASE_FLT_FN (BUILT_IN_LFLOOR):
2292 CASE_FLT_FN (BUILT_IN_LLFLOOR):
2293 builtin_optab = lfloor_optab;
2294 fallback_fn = BUILT_IN_FLOOR;
2301 /* Make a suitable register to place result in. */
2302 mode = TYPE_MODE (TREE_TYPE (exp));
2304 /* Before working hard, check whether the instruction is available. */
2305 if (builtin_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2307 target = gen_reg_rtx (mode);
2309 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2310 need to expand the argument again. This way, we will not perform
2311 side-effects more the once. */
2312 narg = builtin_save_expr (arg);
2316 arglist = build_tree_list (NULL_TREE, arg);
2317 exp = build_function_call_expr (fndecl, arglist);
2320 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
2324 /* Compute into TARGET.
2325 Set TARGET to wherever the result comes back. */
2326 target = expand_unop (mode, builtin_optab, op0, target, 0);
2330 /* Output the entire sequence. */
2331 insns = get_insns ();
2337 /* If we were unable to expand via the builtin, stop the sequence
2338 (without outputting the insns). */
2342 /* Fall back to floating point rounding optab. */
2343 fallback_fndecl = mathfn_built_in (TREE_TYPE (arg), fallback_fn);
2344 /* We shouldn't get here on targets without TARGET_C99_FUNCTIONS.
2345 ??? Perhaps convert (int)floorf(x) into (int)floor((double)x). */
2346 gcc_assert (fallback_fndecl != NULL_TREE);
2347 exp = build_function_call_expr (fallback_fndecl, arglist);
2349 tmp = expand_normal (exp);
2351 /* Truncate the result of floating point optab to integer
2352 via expand_fix (). */
2353 target = gen_reg_rtx (mode);
2354 expand_fix (target, tmp, 0);
2359 /* To evaluate powi(x,n), the floating point value x raised to the
2360 constant integer exponent n, we use a hybrid algorithm that
2361 combines the "window method" with look-up tables. For an
2362 introduction to exponentiation algorithms and "addition chains",
2363 see section 4.6.3, "Evaluation of Powers" of Donald E. Knuth,
2364 "Seminumerical Algorithms", Vol. 2, "The Art of Computer Programming",
2365 3rd Edition, 1998, and Daniel M. Gordon, "A Survey of Fast Exponentiation
2366 Methods", Journal of Algorithms, Vol. 27, pp. 129-146, 1998. */
2368 /* Provide a default value for POWI_MAX_MULTS, the maximum number of
2369 multiplications to inline before calling the system library's pow
2370 function. powi(x,n) requires at worst 2*bits(n)-2 multiplications,
2371 so this default never requires calling pow, powf or powl. */
2373 #ifndef POWI_MAX_MULTS
2374 #define POWI_MAX_MULTS (2*HOST_BITS_PER_WIDE_INT-2)
2377 /* The size of the "optimal power tree" lookup table. All
2378 exponents less than this value are simply looked up in the
2379 powi_table below. This threshold is also used to size the
2380 cache of pseudo registers that hold intermediate results. */
2381 #define POWI_TABLE_SIZE 256
2383 /* The size, in bits of the window, used in the "window method"
2384 exponentiation algorithm. This is equivalent to a radix of
2385 (1<<POWI_WINDOW_SIZE) in the corresponding "m-ary method". */
2386 #define POWI_WINDOW_SIZE 3
2388 /* The following table is an efficient representation of an
2389 "optimal power tree". For each value, i, the corresponding
2390 value, j, in the table states than an optimal evaluation
2391 sequence for calculating pow(x,i) can be found by evaluating
2392 pow(x,j)*pow(x,i-j). An optimal power tree for the first
2393 100 integers is given in Knuth's "Seminumerical algorithms". */
2395 static const unsigned char powi_table[POWI_TABLE_SIZE] =
2397 0, 1, 1, 2, 2, 3, 3, 4, /* 0 - 7 */
2398 4, 6, 5, 6, 6, 10, 7, 9, /* 8 - 15 */
2399 8, 16, 9, 16, 10, 12, 11, 13, /* 16 - 23 */
2400 12, 17, 13, 18, 14, 24, 15, 26, /* 24 - 31 */
2401 16, 17, 17, 19, 18, 33, 19, 26, /* 32 - 39 */
2402 20, 25, 21, 40, 22, 27, 23, 44, /* 40 - 47 */
2403 24, 32, 25, 34, 26, 29, 27, 44, /* 48 - 55 */
2404 28, 31, 29, 34, 30, 60, 31, 36, /* 56 - 63 */
2405 32, 64, 33, 34, 34, 46, 35, 37, /* 64 - 71 */
2406 36, 65, 37, 50, 38, 48, 39, 69, /* 72 - 79 */
2407 40, 49, 41, 43, 42, 51, 43, 58, /* 80 - 87 */
2408 44, 64, 45, 47, 46, 59, 47, 76, /* 88 - 95 */
2409 48, 65, 49, 66, 50, 67, 51, 66, /* 96 - 103 */
2410 52, 70, 53, 74, 54, 104, 55, 74, /* 104 - 111 */
2411 56, 64, 57, 69, 58, 78, 59, 68, /* 112 - 119 */
2412 60, 61, 61, 80, 62, 75, 63, 68, /* 120 - 127 */
2413 64, 65, 65, 128, 66, 129, 67, 90, /* 128 - 135 */
2414 68, 73, 69, 131, 70, 94, 71, 88, /* 136 - 143 */
2415 72, 128, 73, 98, 74, 132, 75, 121, /* 144 - 151 */
2416 76, 102, 77, 124, 78, 132, 79, 106, /* 152 - 159 */
2417 80, 97, 81, 160, 82, 99, 83, 134, /* 160 - 167 */
2418 84, 86, 85, 95, 86, 160, 87, 100, /* 168 - 175 */
2419 88, 113, 89, 98, 90, 107, 91, 122, /* 176 - 183 */
2420 92, 111, 93, 102, 94, 126, 95, 150, /* 184 - 191 */
2421 96, 128, 97, 130, 98, 133, 99, 195, /* 192 - 199 */
2422 100, 128, 101, 123, 102, 164, 103, 138, /* 200 - 207 */
2423 104, 145, 105, 146, 106, 109, 107, 149, /* 208 - 215 */
2424 108, 200, 109, 146, 110, 170, 111, 157, /* 216 - 223 */
2425 112, 128, 113, 130, 114, 182, 115, 132, /* 224 - 231 */
2426 116, 200, 117, 132, 118, 158, 119, 206, /* 232 - 239 */
2427 120, 240, 121, 162, 122, 147, 123, 152, /* 240 - 247 */
2428 124, 166, 125, 214, 126, 138, 127, 153, /* 248 - 255 */
2432 /* Return the number of multiplications required to calculate
2433 powi(x,n) where n is less than POWI_TABLE_SIZE. This is a
2434 subroutine of powi_cost. CACHE is an array indicating
2435 which exponents have already been calculated. */
2438 powi_lookup_cost (unsigned HOST_WIDE_INT n, bool *cache)
2440 /* If we've already calculated this exponent, then this evaluation
2441 doesn't require any additional multiplications. */
2446 return powi_lookup_cost (n - powi_table[n], cache)
2447 + powi_lookup_cost (powi_table[n], cache) + 1;
2450 /* Return the number of multiplications required to calculate
2451 powi(x,n) for an arbitrary x, given the exponent N. This
2452 function needs to be kept in sync with expand_powi below. */
2455 powi_cost (HOST_WIDE_INT n)
2457 bool cache[POWI_TABLE_SIZE];
2458 unsigned HOST_WIDE_INT digit;
2459 unsigned HOST_WIDE_INT val;
2465 /* Ignore the reciprocal when calculating the cost. */
2466 val = (n < 0) ? -n : n;
2468 /* Initialize the exponent cache. */
2469 memset (cache, 0, POWI_TABLE_SIZE * sizeof (bool));
2474 while (val >= POWI_TABLE_SIZE)
2478 digit = val & ((1 << POWI_WINDOW_SIZE) - 1);
2479 result += powi_lookup_cost (digit, cache)
2480 + POWI_WINDOW_SIZE + 1;
2481 val >>= POWI_WINDOW_SIZE;
2490 return result + powi_lookup_cost (val, cache);
2493 /* Recursive subroutine of expand_powi. This function takes the array,
2494 CACHE, of already calculated exponents and an exponent N and returns
2495 an RTX that corresponds to CACHE[1]**N, as calculated in mode MODE. */
2498 expand_powi_1 (enum machine_mode mode, unsigned HOST_WIDE_INT n, rtx *cache)
2500 unsigned HOST_WIDE_INT digit;
2504 if (n < POWI_TABLE_SIZE)
2509 target = gen_reg_rtx (mode);
2512 op0 = expand_powi_1 (mode, n - powi_table[n], cache);
2513 op1 = expand_powi_1 (mode, powi_table[n], cache);
2517 target = gen_reg_rtx (mode);
2518 digit = n & ((1 << POWI_WINDOW_SIZE) - 1);
2519 op0 = expand_powi_1 (mode, n - digit, cache);
2520 op1 = expand_powi_1 (mode, digit, cache);
2524 target = gen_reg_rtx (mode);
2525 op0 = expand_powi_1 (mode, n >> 1, cache);
2529 result = expand_mult (mode, op0, op1, target, 0);
2530 if (result != target)
2531 emit_move_insn (target, result);
2535 /* Expand the RTL to evaluate powi(x,n) in mode MODE. X is the
2536 floating point operand in mode MODE, and N is the exponent. This
2537 function needs to be kept in sync with powi_cost above. */
2540 expand_powi (rtx x, enum machine_mode mode, HOST_WIDE_INT n)
2542 unsigned HOST_WIDE_INT val;
2543 rtx cache[POWI_TABLE_SIZE];
2547 return CONST1_RTX (mode);
2549 val = (n < 0) ? -n : n;
2551 memset (cache, 0, sizeof (cache));
2554 result = expand_powi_1 (mode, (n < 0) ? -n : n, cache);
2556 /* If the original exponent was negative, reciprocate the result. */
2558 result = expand_binop (mode, sdiv_optab, CONST1_RTX (mode),
2559 result, NULL_RTX, 0, OPTAB_LIB_WIDEN);
2564 /* Expand a call to the pow built-in mathematical function. Return 0 if
2565 a normal call should be emitted rather than expanding the function
2566 in-line. EXP is the expression that is a call to the builtin
2567 function; if convenient, the result should be placed in TARGET. */
2570 expand_builtin_pow (tree exp, rtx target, rtx subtarget)
2572 tree arglist = TREE_OPERAND (exp, 1);
2575 if (! validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
2578 arg0 = TREE_VALUE (arglist);
2579 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
2581 if (TREE_CODE (arg1) == REAL_CST
2582 && ! TREE_CONSTANT_OVERFLOW (arg1))
2584 REAL_VALUE_TYPE cint;
2588 c = TREE_REAL_CST (arg1);
2589 n = real_to_integer (&c);
2590 real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
2591 if (real_identical (&c, &cint))
2593 /* If the exponent is -1, 0, 1 or 2, then expand_powi is exact.
2594 Otherwise, check the number of multiplications required.
2595 Note that pow never sets errno for an integer exponent. */
2596 if ((n >= -1 && n <= 2)
2597 || (flag_unsafe_math_optimizations
2599 && powi_cost (n) <= POWI_MAX_MULTS))
2601 enum machine_mode mode = TYPE_MODE (TREE_TYPE (exp));
2602 rtx op = expand_expr (arg0, subtarget, VOIDmode, 0);
2603 op = force_reg (mode, op);
2604 return expand_powi (op, mode, n);
2609 if (! flag_unsafe_math_optimizations)
2611 return expand_builtin_mathfn_2 (exp, target, subtarget);
2614 /* Expand a call to the powi built-in mathematical function. Return 0 if
2615 a normal call should be emitted rather than expanding the function
2616 in-line. EXP is the expression that is a call to the builtin
2617 function; if convenient, the result should be placed in TARGET. */
2620 expand_builtin_powi (tree exp, rtx target, rtx subtarget)
2622 tree arglist = TREE_OPERAND (exp, 1);
2625 enum machine_mode mode;
2626 enum machine_mode mode2;
2628 if (! validate_arglist (arglist, REAL_TYPE, INTEGER_TYPE, VOID_TYPE))
2631 arg0 = TREE_VALUE (arglist);
2632 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
2633 mode = TYPE_MODE (TREE_TYPE (exp));
2635 /* Handle constant power. */
2637 if (TREE_CODE (arg1) == INTEGER_CST
2638 && ! TREE_CONSTANT_OVERFLOW (arg1))
2640 HOST_WIDE_INT n = TREE_INT_CST_LOW (arg1);
2642 /* If the exponent is -1, 0, 1 or 2, then expand_powi is exact.
2643 Otherwise, check the number of multiplications required. */
2644 if ((TREE_INT_CST_HIGH (arg1) == 0
2645 || TREE_INT_CST_HIGH (arg1) == -1)
2646 && ((n >= -1 && n <= 2)
2648 && powi_cost (n) <= POWI_MAX_MULTS)))
2650 op0 = expand_expr (arg0, subtarget, VOIDmode, 0);
2651 op0 = force_reg (mode, op0);
2652 return expand_powi (op0, mode, n);
2656 /* Emit a libcall to libgcc. */
2658 /* Mode of the 2nd argument must match that of an int. */
2659 mode2 = mode_for_size (INT_TYPE_SIZE, MODE_INT, 0);
2661 if (target == NULL_RTX)
2662 target = gen_reg_rtx (mode);
2664 op0 = expand_expr (arg0, subtarget, mode, 0);
2665 if (GET_MODE (op0) != mode)
2666 op0 = convert_to_mode (mode, op0, 0);
2667 op1 = expand_expr (arg1, 0, mode2, 0);
2668 if (GET_MODE (op1) != mode2)
2669 op1 = convert_to_mode (mode2, op1, 0);
2671 target = emit_library_call_value (powi_optab->handlers[(int) mode].libfunc,
2672 target, LCT_CONST_MAKE_BLOCK, mode, 2,
2673 op0, mode, op1, mode2);
2678 /* Expand expression EXP which is a call to the strlen builtin. Return 0
2679 if we failed the caller should emit a normal call, otherwise
2680 try to get the result in TARGET, if convenient. */
2683 expand_builtin_strlen (tree arglist, rtx target,
2684 enum machine_mode target_mode)
2686 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
2691 tree len, src = TREE_VALUE (arglist);
2692 rtx result, src_reg, char_rtx, before_strlen;
2693 enum machine_mode insn_mode = target_mode, char_mode;
2694 enum insn_code icode = CODE_FOR_nothing;
2697 /* If the length can be computed at compile-time, return it. */
2698 len = c_strlen (src, 0);
2700 return expand_expr (len, target, target_mode, EXPAND_NORMAL);
2702 /* If the length can be computed at compile-time and is constant
2703 integer, but there are side-effects in src, evaluate
2704 src for side-effects, then return len.
2705 E.g. x = strlen (i++ ? "xfoo" + 1 : "bar");
2706 can be optimized into: i++; x = 3; */
2707 len = c_strlen (src, 1);
2708 if (len && TREE_CODE (len) == INTEGER_CST)
2710 expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
2711 return expand_expr (len, target, target_mode, EXPAND_NORMAL);
2714 align = get_pointer_alignment (src, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
2716 /* If SRC is not a pointer type, don't do this operation inline. */
2720 /* Bail out if we can't compute strlen in the right mode. */
2721 while (insn_mode != VOIDmode)
2723 icode = strlen_optab->handlers[(int) insn_mode].insn_code;
2724 if (icode != CODE_FOR_nothing)
2727 insn_mode = GET_MODE_WIDER_MODE (insn_mode);
2729 if (insn_mode == VOIDmode)
2732 /* Make a place to write the result of the instruction. */
2736 && GET_MODE (result) == insn_mode
2737 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
2738 result = gen_reg_rtx (insn_mode);
2740 /* Make a place to hold the source address. We will not expand
2741 the actual source until we are sure that the expansion will
2742 not fail -- there are trees that cannot be expanded twice. */
2743 src_reg = gen_reg_rtx (Pmode);
2745 /* Mark the beginning of the strlen sequence so we can emit the
2746 source operand later. */
2747 before_strlen = get_last_insn ();
2749 char_rtx = const0_rtx;
2750 char_mode = insn_data[(int) icode].operand[2].mode;
2751 if (! (*insn_data[(int) icode].operand[2].predicate) (char_rtx,
2753 char_rtx = copy_to_mode_reg (char_mode, char_rtx);
2755 pat = GEN_FCN (icode) (result, gen_rtx_MEM (BLKmode, src_reg),
2756 char_rtx, GEN_INT (align));
2761 /* Now that we are assured of success, expand the source. */
2763 pat = expand_expr (src, src_reg, ptr_mode, EXPAND_NORMAL);
2765 emit_move_insn (src_reg, pat);
2770 emit_insn_after (pat, before_strlen);
2772 emit_insn_before (pat, get_insns ());
2774 /* Return the value in the proper mode for this function. */
2775 if (GET_MODE (result) == target_mode)
2777 else if (target != 0)
2778 convert_move (target, result, 0);
2780 target = convert_to_mode (target_mode, result, 0);
2786 /* Expand a call to the strstr builtin. Return 0 if we failed the
2787 caller should emit a normal call, otherwise try to get the result
2788 in TARGET, if convenient (and in mode MODE if that's convenient). */
2791 expand_builtin_strstr (tree arglist, tree type, rtx target, enum machine_mode mode)
2793 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2795 tree result = fold_builtin_strstr (arglist, type);
2797 return expand_expr (result, target, mode, EXPAND_NORMAL);
2802 /* Expand a call to the strchr builtin. Return 0 if we failed the
2803 caller should emit a normal call, otherwise try to get the result
2804 in TARGET, if convenient (and in mode MODE if that's convenient). */
2807 expand_builtin_strchr (tree arglist, tree type, rtx target, enum machine_mode mode)
2809 if (validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2811 tree result = fold_builtin_strchr (arglist, type);
2813 return expand_expr (result, target, mode, EXPAND_NORMAL);
2815 /* FIXME: Should use strchrM optab so that ports can optimize this. */
2820 /* Expand a call to the strrchr builtin. Return 0 if we failed the
2821 caller should emit a normal call, otherwise try to get the result
2822 in TARGET, if convenient (and in mode MODE if that's convenient). */
2825 expand_builtin_strrchr (tree arglist, tree type, rtx target, enum machine_mode mode)
2827 if (validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2829 tree result = fold_builtin_strrchr (arglist, type);
2831 return expand_expr (result, target, mode, EXPAND_NORMAL);
2836 /* Expand a call to the strpbrk builtin. Return 0 if we failed the
2837 caller should emit a normal call, otherwise try to get the result
2838 in TARGET, if convenient (and in mode MODE if that's convenient). */
2841 expand_builtin_strpbrk (tree arglist, tree type, rtx target, enum machine_mode mode)
2843 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2845 tree result = fold_builtin_strpbrk (arglist, type);
2847 return expand_expr (result, target, mode, EXPAND_NORMAL);
2852 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
2853 bytes from constant string DATA + OFFSET and return it as target
2857 builtin_memcpy_read_str (void *data, HOST_WIDE_INT offset,
2858 enum machine_mode mode)
2860 const char *str = (const char *) data;
2862 gcc_assert (offset >= 0
2863 && ((unsigned HOST_WIDE_INT) offset + GET_MODE_SIZE (mode)
2864 <= strlen (str) + 1));
2866 return c_readstr (str + offset, mode);
2869 /* Expand a call to the memcpy builtin, with arguments in ARGLIST.
2870 Return 0 if we failed, the caller should emit a normal call,
2871 otherwise try to get the result in TARGET, if convenient (and in
2872 mode MODE if that's convenient). */
2874 expand_builtin_memcpy (tree exp, rtx target, enum machine_mode mode)
2876 tree fndecl = get_callee_fndecl (exp);
2877 tree arglist = TREE_OPERAND (exp, 1);
2878 if (!validate_arglist (arglist,
2879 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2883 tree dest = TREE_VALUE (arglist);
2884 tree src = TREE_VALUE (TREE_CHAIN (arglist));
2885 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2886 const char *src_str;
2887 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
2888 unsigned int dest_align
2889 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2890 rtx dest_mem, src_mem, dest_addr, len_rtx;
2891 tree result = fold_builtin_memcpy (fndecl, arglist);
2894 return expand_expr (result, target, mode, EXPAND_NORMAL);
2896 /* If DEST is not a pointer type, call the normal function. */
2897 if (dest_align == 0)
2900 /* If either SRC is not a pointer type, don't do this
2901 operation in-line. */
2905 dest_mem = get_memory_rtx (dest, len);
2906 set_mem_align (dest_mem, dest_align);
2907 len_rtx = expand_normal (len);
2908 src_str = c_getstr (src);
2910 /* If SRC is a string constant and block move would be done
2911 by pieces, we can avoid loading the string from memory
2912 and only stored the computed constants. */
2914 && GET_CODE (len_rtx) == CONST_INT
2915 && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
2916 && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
2917 (void *) src_str, dest_align))
2919 dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
2920 builtin_memcpy_read_str,
2921 (void *) src_str, dest_align, 0);
2922 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2923 dest_mem = convert_memory_address (ptr_mode, dest_mem);
2927 src_mem = get_memory_rtx (src, len);
2928 set_mem_align (src_mem, src_align);
2930 /* Copy word part most expediently. */
2931 dest_addr = emit_block_move (dest_mem, src_mem, len_rtx,
2932 CALL_EXPR_TAILCALL (exp)
2933 ? BLOCK_OP_TAILCALL : BLOCK_OP_NORMAL);
2937 dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2938 dest_addr = convert_memory_address (ptr_mode, dest_addr);
2944 /* Expand a call to the mempcpy builtin, with arguments in ARGLIST.
2945 Return 0 if we failed; the caller should emit a normal call,
2946 otherwise try to get the result in TARGET, if convenient (and in
2947 mode MODE if that's convenient). If ENDP is 0 return the
2948 destination pointer, if ENDP is 1 return the end pointer ala
2949 mempcpy, and if ENDP is 2 return the end pointer minus one ala
2953 expand_builtin_mempcpy (tree arglist, tree type, rtx target, enum machine_mode mode,
2956 if (!validate_arglist (arglist,
2957 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2959 /* If return value is ignored, transform mempcpy into memcpy. */
2960 else if (target == const0_rtx)
2962 tree fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
2967 return expand_expr (build_function_call_expr (fn, arglist),
2968 target, mode, EXPAND_NORMAL);
2972 tree dest = TREE_VALUE (arglist);
2973 tree src = TREE_VALUE (TREE_CHAIN (arglist));
2974 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2975 const char *src_str;
2976 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
2977 unsigned int dest_align
2978 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2979 rtx dest_mem, src_mem, len_rtx;
2980 tree result = fold_builtin_mempcpy (arglist, type, endp);
2983 return expand_expr (result, target, mode, EXPAND_NORMAL);
2985 /* If either SRC or DEST is not a pointer type, don't do this
2986 operation in-line. */
2987 if (dest_align == 0 || src_align == 0)
2990 /* If LEN is not constant, call the normal function. */
2991 if (! host_integerp (len, 1))
2994 len_rtx = expand_normal (len);
2995 src_str = c_getstr (src);
2997 /* If SRC is a string constant and block move would be done
2998 by pieces, we can avoid loading the string from memory
2999 and only stored the computed constants. */
3001 && GET_CODE (len_rtx) == CONST_INT
3002 && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
3003 && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
3004 (void *) src_str, dest_align))
3006 dest_mem = get_memory_rtx (dest, len);
3007 set_mem_align (dest_mem, dest_align);
3008 dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
3009 builtin_memcpy_read_str,
3010 (void *) src_str, dest_align, endp);
3011 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3012 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3016 if (GET_CODE (len_rtx) == CONST_INT
3017 && can_move_by_pieces (INTVAL (len_rtx),
3018 MIN (dest_align, src_align)))
3020 dest_mem = get_memory_rtx (dest, len);
3021 set_mem_align (dest_mem, dest_align);
3022 src_mem = get_memory_rtx (src, len);
3023 set_mem_align (src_mem, src_align);
3024 dest_mem = move_by_pieces (dest_mem, src_mem, INTVAL (len_rtx),
3025 MIN (dest_align, src_align), endp);
3026 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3027 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3035 /* Expand expression EXP, which is a call to the memmove builtin. Return 0
3036 if we failed; the caller should emit a normal call. */
3039 expand_builtin_memmove (tree arglist, tree type, rtx target,
3040 enum machine_mode mode, tree orig_exp)
3042 if (!validate_arglist (arglist,
3043 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3047 tree dest = TREE_VALUE (arglist);
3048 tree src = TREE_VALUE (TREE_CHAIN (arglist));
3049 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3051 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
3052 unsigned int dest_align
3053 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
3054 tree result = fold_builtin_memmove (arglist, type);
3057 return expand_expr (result, target, mode, EXPAND_NORMAL);
3059 /* If DEST is not a pointer type, call the normal function. */
3060 if (dest_align == 0)
3063 /* If either SRC is not a pointer type, don't do this
3064 operation in-line. */
3068 /* If src is categorized for a readonly section we can use
3070 if (readonly_data_expr (src))
3072 tree fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
3075 fn = build_function_call_expr (fn, arglist);
3076 if (TREE_CODE (fn) == CALL_EXPR)
3077 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (orig_exp);
3078 return expand_expr (fn, target, mode, EXPAND_NORMAL);
3081 /* If length is 1 and we can expand memcpy call inline,
3082 it is ok to use memcpy as well. */
3083 if (integer_onep (len))
3085 rtx ret = expand_builtin_mempcpy (arglist, type, target, mode,
3091 /* Otherwise, call the normal function. */
3096 /* Expand expression EXP, which is a call to the bcopy builtin. Return 0
3097 if we failed the caller should emit a normal call. */
3100 expand_builtin_bcopy (tree exp)
3102 tree arglist = TREE_OPERAND (exp, 1);
3103 tree type = TREE_TYPE (exp);
3104 tree src, dest, size, newarglist;
3106 if (!validate_arglist (arglist,
3107 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3110 src = TREE_VALUE (arglist);
3111 dest = TREE_VALUE (TREE_CHAIN (arglist));
3112 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3114 /* New argument list transforming bcopy(ptr x, ptr y, int z) to
3115 memmove(ptr y, ptr x, size_t z). This is done this way
3116 so that if it isn't expanded inline, we fallback to
3117 calling bcopy instead of memmove. */
3119 newarglist = build_tree_list (NULL_TREE, fold_convert (sizetype, size));
3120 newarglist = tree_cons (NULL_TREE, src, newarglist);
3121 newarglist = tree_cons (NULL_TREE, dest, newarglist);
3123 return expand_builtin_memmove (newarglist, type, const0_rtx, VOIDmode, exp);
3127 # define HAVE_movstr 0
3128 # define CODE_FOR_movstr CODE_FOR_nothing
3131 /* Expand into a movstr instruction, if one is available. Return 0 if
3132 we failed, the caller should emit a normal call, otherwise try to
3133 get the result in TARGET, if convenient. If ENDP is 0 return the
3134 destination pointer, if ENDP is 1 return the end pointer ala
3135 mempcpy, and if ENDP is 2 return the end pointer minus one ala
3139 expand_movstr (tree dest, tree src, rtx target, int endp)
3145 const struct insn_data * data;
3150 dest_mem = get_memory_rtx (dest, NULL);
3151 src_mem = get_memory_rtx (src, NULL);
3154 target = force_reg (Pmode, XEXP (dest_mem, 0));
3155 dest_mem = replace_equiv_address (dest_mem, target);
3156 end = gen_reg_rtx (Pmode);
3160 if (target == 0 || target == const0_rtx)
3162 end = gen_reg_rtx (Pmode);
3170 data = insn_data + CODE_FOR_movstr;
3172 if (data->operand[0].mode != VOIDmode)
3173 end = gen_lowpart (data->operand[0].mode, end);
3175 insn = data->genfun (end, dest_mem, src_mem);
3181 /* movstr is supposed to set end to the address of the NUL
3182 terminator. If the caller requested a mempcpy-like return value,
3184 if (endp == 1 && target != const0_rtx)
3186 rtx tem = plus_constant (gen_lowpart (GET_MODE (target), end), 1);
3187 emit_move_insn (target, force_operand (tem, NULL_RTX));
3193 /* Expand expression EXP, which is a call to the strcpy builtin. Return 0
3194 if we failed the caller should emit a normal call, otherwise try to get
3195 the result in TARGET, if convenient (and in mode MODE if that's
3199 expand_builtin_strcpy (tree fndecl, tree arglist, rtx target, enum machine_mode mode)
3201 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3203 tree result = fold_builtin_strcpy (fndecl, arglist, 0);
3205 return expand_expr (result, target, mode, EXPAND_NORMAL);
3207 return expand_movstr (TREE_VALUE (arglist),
3208 TREE_VALUE (TREE_CHAIN (arglist)),
3209 target, /*endp=*/0);
3214 /* Expand a call to the stpcpy builtin, with arguments in ARGLIST.
3215 Return 0 if we failed the caller should emit a normal call,
3216 otherwise try to get the result in TARGET, if convenient (and in
3217 mode MODE if that's convenient). */
3220 expand_builtin_stpcpy (tree exp, rtx target, enum machine_mode mode)
3222 tree arglist = TREE_OPERAND (exp, 1);
3223 /* If return value is ignored, transform stpcpy into strcpy. */
3224 if (target == const0_rtx)
3226 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
3230 return expand_expr (build_function_call_expr (fn, arglist),
3231 target, mode, EXPAND_NORMAL);
3234 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3238 tree dst, src, len, lenp1;
3242 /* Ensure we get an actual string whose length can be evaluated at
3243 compile-time, not an expression containing a string. This is
3244 because the latter will potentially produce pessimized code
3245 when used to produce the return value. */
3246 src = TREE_VALUE (TREE_CHAIN (arglist));
3247 if (! c_getstr (src) || ! (len = c_strlen (src, 0)))
3248 return expand_movstr (TREE_VALUE (arglist),
3249 TREE_VALUE (TREE_CHAIN (arglist)),
3250 target, /*endp=*/2);
3252 dst = TREE_VALUE (arglist);
3253 lenp1 = size_binop (PLUS_EXPR, len, ssize_int (1));
3254 narglist = build_tree_list (NULL_TREE, lenp1);
3255 narglist = tree_cons (NULL_TREE, src, narglist);
3256 narglist = tree_cons (NULL_TREE, dst, narglist);
3257 ret = expand_builtin_mempcpy (narglist, TREE_TYPE (exp),
3258 target, mode, /*endp=*/2);
3263 if (TREE_CODE (len) == INTEGER_CST)
3265 rtx len_rtx = expand_normal (len);
3267 if (GET_CODE (len_rtx) == CONST_INT)
3269 ret = expand_builtin_strcpy (get_callee_fndecl (exp),
3270 arglist, target, mode);
3276 if (mode != VOIDmode)
3277 target = gen_reg_rtx (mode);
3279 target = gen_reg_rtx (GET_MODE (ret));
3281 if (GET_MODE (target) != GET_MODE (ret))
3282 ret = gen_lowpart (GET_MODE (target), ret);
3284 ret = plus_constant (ret, INTVAL (len_rtx));
3285 ret = emit_move_insn (target, force_operand (ret, NULL_RTX));
3293 return expand_movstr (TREE_VALUE (arglist),
3294 TREE_VALUE (TREE_CHAIN (arglist)),
3295 target, /*endp=*/2);
3299 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
3300 bytes from constant string DATA + OFFSET and return it as target
3304 builtin_strncpy_read_str (void *data, HOST_WIDE_INT offset,
3305 enum machine_mode mode)
3307 const char *str = (const char *) data;
3309 if ((unsigned HOST_WIDE_INT) offset > strlen (str))
3312 return c_readstr (str + offset, mode);
3315 /* Expand expression EXP, which is a call to the strncpy builtin. Return 0
3316 if we failed the caller should emit a normal call. */
3319 expand_builtin_strncpy (tree exp, rtx target, enum machine_mode mode)
3321 tree fndecl = get_callee_fndecl (exp);
3322 tree arglist = TREE_OPERAND (exp, 1);
3323 if (validate_arglist (arglist,
3324 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3326 tree slen = c_strlen (TREE_VALUE (TREE_CHAIN (arglist)), 1);
3327 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3328 tree result = fold_builtin_strncpy (fndecl, arglist, slen);
3331 return expand_expr (result, target, mode, EXPAND_NORMAL);
3333 /* We must be passed a constant len and src parameter. */
3334 if (!host_integerp (len, 1) || !slen || !host_integerp (slen, 1))
3337 slen = size_binop (PLUS_EXPR, slen, ssize_int (1));
3339 /* We're required to pad with trailing zeros if the requested
3340 len is greater than strlen(s2)+1. In that case try to
3341 use store_by_pieces, if it fails, punt. */
3342 if (tree_int_cst_lt (slen, len))
3344 tree dest = TREE_VALUE (arglist);
3345 unsigned int dest_align
3346 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
3347 const char *p = c_getstr (TREE_VALUE (TREE_CHAIN (arglist)));
3350 if (!p || dest_align == 0 || !host_integerp (len, 1)
3351 || !can_store_by_pieces (tree_low_cst (len, 1),
3352 builtin_strncpy_read_str,
3353 (void *) p, dest_align))
3356 dest_mem = get_memory_rtx (dest, len);
3357 store_by_pieces (dest_mem, tree_low_cst (len, 1),
3358 builtin_strncpy_read_str,
3359 (void *) p, dest_align, 0);
3360 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3361 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3368 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
3369 bytes from constant string DATA + OFFSET and return it as target
3373 builtin_memset_read_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
3374 enum machine_mode mode)
3376 const char *c = (const char *) data;
3377 char *p = alloca (GET_MODE_SIZE (mode));
3379 memset (p, *c, GET_MODE_SIZE (mode));
3381 return c_readstr (p, mode);
3384 /* Callback routine for store_by_pieces. Return the RTL of a register
3385 containing GET_MODE_SIZE (MODE) consecutive copies of the unsigned
3386 char value given in the RTL register data. For example, if mode is
3387 4 bytes wide, return the RTL for 0x01010101*data. */
3390 builtin_memset_gen_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
3391 enum machine_mode mode)
3397 size = GET_MODE_SIZE (mode);
3402 memset (p, 1, size);
3403 coeff = c_readstr (p, mode);
3405 target = convert_to_mode (mode, (rtx) data, 1);
3406 target = expand_mult (mode, target, coeff, NULL_RTX, 1);
3407 return force_reg (mode, target);
3410 /* Expand expression EXP, which is a call to the memset builtin. Return 0
3411 if we failed the caller should emit a normal call, otherwise try to get
3412 the result in TARGET, if convenient (and in mode MODE if that's
3416 expand_builtin_memset (tree arglist, rtx target, enum machine_mode mode,
3419 if (!validate_arglist (arglist,
3420 POINTER_TYPE, INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
3424 tree dest = TREE_VALUE (arglist);
3425 tree val = TREE_VALUE (TREE_CHAIN (arglist));
3426 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3428 enum built_in_function fcode;
3430 unsigned int dest_align;
3431 rtx dest_mem, dest_addr, len_rtx;
3433 dest_align = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
3435 /* If DEST is not a pointer type, don't do this
3436 operation in-line. */
3437 if (dest_align == 0)
3440 /* If the LEN parameter is zero, return DEST. */
3441 if (integer_zerop (len))
3443 /* Evaluate and ignore VAL in case it has side-effects. */
3444 expand_expr (val, const0_rtx, VOIDmode, EXPAND_NORMAL);
3445 return expand_expr (dest, target, mode, EXPAND_NORMAL);
3448 /* Stabilize the arguments in case we fail. */
3449 dest = builtin_save_expr (dest);
3450 val = builtin_save_expr (val);
3451 len = builtin_save_expr (len);
3453 len_rtx = expand_normal (len);
3454 dest_mem = get_memory_rtx (dest, len);
3456 if (TREE_CODE (val) != INTEGER_CST)
3460 val_rtx = expand_normal (val);
3461 val_rtx = convert_to_mode (TYPE_MODE (unsigned_char_type_node),
3464 /* Assume that we can memset by pieces if we can store the
3465 * the coefficients by pieces (in the required modes).
3466 * We can't pass builtin_memset_gen_str as that emits RTL. */
3468 if (host_integerp (len, 1)
3469 && !(optimize_size && tree_low_cst (len, 1) > 1)
3470 && can_store_by_pieces (tree_low_cst (len, 1),
3471 builtin_memset_read_str, &c, dest_align))
3473 val_rtx = force_reg (TYPE_MODE (unsigned_char_type_node),
3475 store_by_pieces (dest_mem, tree_low_cst (len, 1),
3476 builtin_memset_gen_str, val_rtx, dest_align, 0);
3478 else if (!set_storage_via_setmem (dest_mem, len_rtx, val_rtx,
3482 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3483 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3487 if (target_char_cast (val, &c))
3492 if (host_integerp (len, 1)
3493 && !(optimize_size && tree_low_cst (len, 1) > 1)
3494 && can_store_by_pieces (tree_low_cst (len, 1),
3495 builtin_memset_read_str, &c, dest_align))
3496 store_by_pieces (dest_mem, tree_low_cst (len, 1),
3497 builtin_memset_read_str, &c, dest_align, 0);
3498 else if (!set_storage_via_setmem (dest_mem, len_rtx, GEN_INT (c),
3502 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3503 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3507 set_mem_align (dest_mem, dest_align);
3508 dest_addr = clear_storage (dest_mem, len_rtx,
3509 CALL_EXPR_TAILCALL (orig_exp)
3510 ? BLOCK_OP_TAILCALL : BLOCK_OP_NORMAL);
3514 dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3515 dest_addr = convert_memory_address (ptr_mode, dest_addr);
3521 fndecl = get_callee_fndecl (orig_exp);
3522 fcode = DECL_FUNCTION_CODE (fndecl);
3523 gcc_assert (fcode == BUILT_IN_MEMSET || fcode == BUILT_IN_BZERO);
3524 arglist = build_tree_list (NULL_TREE, len);
3525 if (fcode == BUILT_IN_MEMSET)
3526 arglist = tree_cons (NULL_TREE, val, arglist);
3527 arglist = tree_cons (NULL_TREE, dest, arglist);
3528 fn = build_function_call_expr (fndecl, arglist);
3529 if (TREE_CODE (fn) == CALL_EXPR)
3530 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (orig_exp);
3531 return expand_call (fn, target, target == const0_rtx);
3535 /* Expand expression EXP, which is a call to the bzero builtin. Return 0
3536 if we failed the caller should emit a normal call. */
3539 expand_builtin_bzero (tree exp)
3541 tree arglist = TREE_OPERAND (exp, 1);
3542 tree dest, size, newarglist;
3544 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3547 dest = TREE_VALUE (arglist);
3548 size = TREE_VALUE (TREE_CHAIN (arglist));
3550 /* New argument list transforming bzero(ptr x, int y) to
3551 memset(ptr x, int 0, size_t y). This is done this way
3552 so that if it isn't expanded inline, we fallback to
3553 calling bzero instead of memset. */
3555 newarglist = build_tree_list (NULL_TREE, fold_convert (sizetype, size));
3556 newarglist = tree_cons (NULL_TREE, integer_zero_node, newarglist);
3557 newarglist = tree_cons (NULL_TREE, dest, newarglist);
3559 return expand_builtin_memset (newarglist, const0_rtx, VOIDmode, exp);
3562 /* Expand expression EXP, which is a call to the memcmp built-in function.
3563 ARGLIST is the argument list for this call. Return 0 if we failed and the
3564 caller should emit a normal call, otherwise try to get the result in
3565 TARGET, if convenient (and in mode MODE, if that's convenient). */
3568 expand_builtin_memcmp (tree exp ATTRIBUTE_UNUSED, tree arglist, rtx target,
3569 enum machine_mode mode)
3571 if (!validate_arglist (arglist,
3572 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3576 tree result = fold_builtin_memcmp (arglist);
3578 return expand_expr (result, target, mode, EXPAND_NORMAL);
3581 #if defined HAVE_cmpmemsi || defined HAVE_cmpstrnsi
3583 tree arg1 = TREE_VALUE (arglist);
3584 tree arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3585 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3586 rtx arg1_rtx, arg2_rtx, arg3_rtx;
3591 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3593 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3594 enum machine_mode insn_mode;
3596 #ifdef HAVE_cmpmemsi
3598 insn_mode = insn_data[(int) CODE_FOR_cmpmemsi].operand[0].mode;
3601 #ifdef HAVE_cmpstrnsi
3603 insn_mode = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode;
3608 /* If we don't have POINTER_TYPE, call the function. */
3609 if (arg1_align == 0 || arg2_align == 0)
3612 /* Make a place to write the result of the instruction. */
3615 && REG_P (result) && GET_MODE (result) == insn_mode
3616 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3617 result = gen_reg_rtx (insn_mode);
3619 arg1_rtx = get_memory_rtx (arg1, len);
3620 arg2_rtx = get_memory_rtx (arg2, len);
3621 arg3_rtx = expand_normal (len);
3623 /* Set MEM_SIZE as appropriate. */
3624 if (GET_CODE (arg3_rtx) == CONST_INT)
3626 set_mem_size (arg1_rtx, arg3_rtx);
3627 set_mem_size (arg2_rtx, arg3_rtx);
3630 #ifdef HAVE_cmpmemsi
3632 insn = gen_cmpmemsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3633 GEN_INT (MIN (arg1_align, arg2_align)));
3636 #ifdef HAVE_cmpstrnsi
3638 insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3639 GEN_INT (MIN (arg1_align, arg2_align)));
3647 emit_library_call_value (memcmp_libfunc, result, LCT_PURE_MAKE_BLOCK,
3648 TYPE_MODE (integer_type_node), 3,
3649 XEXP (arg1_rtx, 0), Pmode,
3650 XEXP (arg2_rtx, 0), Pmode,
3651 convert_to_mode (TYPE_MODE (sizetype), arg3_rtx,
3652 TYPE_UNSIGNED (sizetype)),
3653 TYPE_MODE (sizetype));
3655 /* Return the value in the proper mode for this function. */
3656 mode = TYPE_MODE (TREE_TYPE (exp));
3657 if (GET_MODE (result) == mode)
3659 else if (target != 0)
3661 convert_move (target, result, 0);
3665 return convert_to_mode (mode, result, 0);
3672 /* Expand expression EXP, which is a call to the strcmp builtin. Return 0
3673 if we failed the caller should emit a normal call, otherwise try to get
3674 the result in TARGET, if convenient. */
3677 expand_builtin_strcmp (tree exp, rtx target, enum machine_mode mode)
3679 tree arglist = TREE_OPERAND (exp, 1);
3681 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3685 tree result = fold_builtin_strcmp (arglist);
3687 return expand_expr (result, target, mode, EXPAND_NORMAL);
3690 #if defined HAVE_cmpstrsi || defined HAVE_cmpstrnsi
3691 if (cmpstr_optab[SImode] != CODE_FOR_nothing
3692 || cmpstrn_optab[SImode] != CODE_FOR_nothing)
3694 rtx arg1_rtx, arg2_rtx;
3695 rtx result, insn = NULL_RTX;
3698 tree arg1 = TREE_VALUE (arglist);
3699 tree arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3701 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3703 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3705 /* If we don't have POINTER_TYPE, call the function. */
3706 if (arg1_align == 0 || arg2_align == 0)
3709 /* Stabilize the arguments in case gen_cmpstr(n)si fail. */
3710 arg1 = builtin_save_expr (arg1);
3711 arg2 = builtin_save_expr (arg2);
3713 arg1_rtx = get_memory_rtx (arg1, NULL);
3714 arg2_rtx = get_memory_rtx (arg2, NULL);
3716 #ifdef HAVE_cmpstrsi
3717 /* Try to call cmpstrsi. */
3720 enum machine_mode insn_mode
3721 = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
3723 /* Make a place to write the result of the instruction. */
3726 && REG_P (result) && GET_MODE (result) == insn_mode
3727 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3728 result = gen_reg_rtx (insn_mode);
3730 insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx,
3731 GEN_INT (MIN (arg1_align, arg2_align)));
3734 #ifdef HAVE_cmpstrnsi
3735 /* Try to determine at least one length and call cmpstrnsi. */
3736 if (!insn && HAVE_cmpstrnsi)
3741 enum machine_mode insn_mode
3742 = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode;
3743 tree len1 = c_strlen (arg1, 1);
3744 tree len2 = c_strlen (arg2, 1);
3747 len1 = size_binop (PLUS_EXPR, ssize_int (1), len1);
3749 len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
3751 /* If we don't have a constant length for the first, use the length
3752 of the second, if we know it. We don't require a constant for
3753 this case; some cost analysis could be done if both are available
3754 but neither is constant. For now, assume they're equally cheap,
3755 unless one has side effects. If both strings have constant lengths,
3762 else if (TREE_SIDE_EFFECTS (len1))
3764 else if (TREE_SIDE_EFFECTS (len2))
3766 else if (TREE_CODE (len1) != INTEGER_CST)
3768 else if (TREE_CODE (len2) != INTEGER_CST)
3770 else if (tree_int_cst_lt (len1, len2))
3775 /* If both arguments have side effects, we cannot optimize. */
3776 if (!len || TREE_SIDE_EFFECTS (len))
3779 arg3_rtx = expand_normal (len);
3781 /* Make a place to write the result of the instruction. */
3784 && REG_P (result) && GET_MODE (result) == insn_mode
3785 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3786 result = gen_reg_rtx (insn_mode);
3788 insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3789 GEN_INT (MIN (arg1_align, arg2_align)));
3797 /* Return the value in the proper mode for this function. */
3798 mode = TYPE_MODE (TREE_TYPE (exp));
3799 if (GET_MODE (result) == mode)
3802 return convert_to_mode (mode, result, 0);
3803 convert_move (target, result, 0);
3807 /* Expand the library call ourselves using a stabilized argument
3808 list to avoid re-evaluating the function's arguments twice. */
3809 #ifdef HAVE_cmpstrnsi
3812 arglist = build_tree_list (NULL_TREE, arg2);
3813 arglist = tree_cons (NULL_TREE, arg1, arglist);
3814 fndecl = get_callee_fndecl (exp);
3815 fn = build_function_call_expr (fndecl, arglist);
3816 if (TREE_CODE (fn) == CALL_EXPR)
3817 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
3818 return expand_call (fn, target, target == const0_rtx);
3824 /* Expand expression EXP, which is a call to the strncmp builtin. Return 0
3825 if we failed the caller should emit a normal call, otherwise try to get
3826 the result in TARGET, if convenient. */
3829 expand_builtin_strncmp (tree exp, rtx target, enum machine_mode mode)
3831 tree arglist = TREE_OPERAND (exp, 1);
3833 if (!validate_arglist (arglist,
3834 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3838 tree result = fold_builtin_strncmp (arglist);
3840 return expand_expr (result, target, mode, EXPAND_NORMAL);
3843 /* If c_strlen can determine an expression for one of the string
3844 lengths, and it doesn't have side effects, then emit cmpstrnsi
3845 using length MIN(strlen(string)+1, arg3). */
3846 #ifdef HAVE_cmpstrnsi
3849 tree arg1 = TREE_VALUE (arglist);
3850 tree arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3851 tree arg3 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3852 tree len, len1, len2;
3853 rtx arg1_rtx, arg2_rtx, arg3_rtx;
3858 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3860 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3861 enum machine_mode insn_mode
3862 = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode;
3864 len1 = c_strlen (arg1, 1);
3865 len2 = c_strlen (arg2, 1);
3868 len1 = size_binop (PLUS_EXPR, ssize_int (1), len1);
3870 len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
3872 /* If we don't have a constant length for the first, use the length
3873 of the second, if we know it. We don't require a constant for
3874 this case; some cost analysis could be done if both are available
3875 but neither is constant. For now, assume they're equally cheap,
3876 unless one has side effects. If both strings have constant lengths,
3883 else if (TREE_SIDE_EFFECTS (len1))
3885 else if (TREE_SIDE_EFFECTS (len2))
3887 else if (TREE_CODE (len1) != INTEGER_CST)
3889 else if (TREE_CODE (len2) != INTEGER_CST)
3891 else if (tree_int_cst_lt (len1, len2))
3896 /* If both arguments have side effects, we cannot optimize. */
3897 if (!len || TREE_SIDE_EFFECTS (len))
3900 /* The actual new length parameter is MIN(len,arg3). */
3901 len = fold_build2 (MIN_EXPR, TREE_TYPE (len), len,
3902 fold_convert (TREE_TYPE (len), arg3));
3904 /* If we don't have POINTER_TYPE, call the function. */
3905 if (arg1_align == 0 || arg2_align == 0)
3908 /* Make a place to write the result of the instruction. */
3911 && REG_P (result) && GET_MODE (result) == insn_mode
3912 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3913 result = gen_reg_rtx (insn_mode);
3915 /* Stabilize the arguments in case gen_cmpstrnsi fails. */
3916 arg1 = builtin_save_expr (arg1);
3917 arg2 = builtin_save_expr (arg2);
3918 len = builtin_save_expr (len);
3920 arg1_rtx = get_memory_rtx (arg1, len);
3921 arg2_rtx = get_memory_rtx (arg2, len);
3922 arg3_rtx = expand_normal (len);
3923 insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3924 GEN_INT (MIN (arg1_align, arg2_align)));
3929 /* Return the value in the proper mode for this function. */
3930 mode = TYPE_MODE (TREE_TYPE (exp));
3931 if (GET_MODE (result) == mode)
3934 return convert_to_mode (mode, result, 0);
3935 convert_move (target, result, 0);
3939 /* Expand the library call ourselves using a stabilized argument
3940 list to avoid re-evaluating the function's arguments twice. */
3941 arglist = build_tree_list (NULL_TREE, len);
3942 arglist = tree_cons (NULL_TREE, arg2, arglist);
3943 arglist = tree_cons (NULL_TREE, arg1, arglist);
3944 fndecl = get_callee_fndecl (exp);
3945 fn = build_function_call_expr (fndecl, arglist);
3946 if (TREE_CODE (fn) == CALL_EXPR)
3947 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
3948 return expand_call (fn, target, target == const0_rtx);
3954 /* Expand expression EXP, which is a call to the strcat builtin.
3955 Return 0 if we failed the caller should emit a normal call,
3956 otherwise try to get the result in TARGET, if convenient. */
3959 expand_builtin_strcat (tree fndecl, tree arglist, rtx target, enum machine_mode mode)
3961 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3965 tree dst = TREE_VALUE (arglist),
3966 src = TREE_VALUE (TREE_CHAIN (arglist));
3967 const char *p = c_getstr (src);
3969 /* If the string length is zero, return the dst parameter. */
3970 if (p && *p == '\0')
3971 return expand_expr (dst, target, mode, EXPAND_NORMAL);
3975 /* See if we can store by pieces into (dst + strlen(dst)). */
3976 tree newsrc, newdst,
3977 strlen_fn = implicit_built_in_decls[BUILT_IN_STRLEN];
3980 /* Stabilize the argument list. */
3981 newsrc = builtin_save_expr (src);
3983 arglist = build_tree_list (NULL_TREE, newsrc);
3985 arglist = TREE_CHAIN (arglist); /* Reusing arglist if safe. */
3987 dst = builtin_save_expr (dst);
3991 /* Create strlen (dst). */
3993 build_function_call_expr (strlen_fn,
3994 build_tree_list (NULL_TREE, dst));
3995 /* Create (dst + (cast) strlen (dst)). */
3996 newdst = fold_convert (TREE_TYPE (dst), newdst);
3997 newdst = fold_build2 (PLUS_EXPR, TREE_TYPE (dst), dst, newdst);
3999 newdst = builtin_save_expr (newdst);
4000 arglist = tree_cons (NULL_TREE, newdst, arglist);
4002 if (!expand_builtin_strcpy (fndecl, arglist, target, mode))
4004 end_sequence (); /* Stop sequence. */
4008 /* Output the entire sequence. */
4009 insns = get_insns ();
4013 return expand_expr (dst, target, mode, EXPAND_NORMAL);
4020 /* Expand expression EXP, which is a call to the strncat builtin.
4021 Return 0 if we failed the caller should emit a normal call,
4022 otherwise try to get the result in TARGET, if convenient. */
4025 expand_builtin_strncat (tree arglist, rtx target, enum machine_mode mode)
4027 if (validate_arglist (arglist,
4028 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
4030 tree result = fold_builtin_strncat (arglist);
4032 return expand_expr (result, target, mode, EXPAND_NORMAL);
4037 /* Expand expression EXP, which is a call to the strspn builtin.
4038 Return 0 if we failed the caller should emit a normal call,
4039 otherwise try to get the result in TARGET, if convenient. */
4042 expand_builtin_strspn (tree arglist, rtx target, enum machine_mode mode)
4044 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4046 tree result = fold_builtin_strspn (arglist);
4048 return expand_expr (result, target, mode, EXPAND_NORMAL);
4053 /* Expand expression EXP, which is a call to the strcspn builtin.
4054 Return 0 if we failed the caller should emit a normal call,
4055 otherwise try to get the result in TARGET, if convenient. */
4058 expand_builtin_strcspn (tree arglist, rtx target, enum machine_mode mode)
4060 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4062 tree result = fold_builtin_strcspn (arglist);
4064 return expand_expr (result, target, mode, EXPAND_NORMAL);
4069 /* Expand a call to __builtin_saveregs, generating the result in TARGET,
4070 if that's convenient. */
4073 expand_builtin_saveregs (void)
4077 /* Don't do __builtin_saveregs more than once in a function.
4078 Save the result of the first call and reuse it. */
4079 if (saveregs_value != 0)
4080 return saveregs_value;
4082 /* When this function is called, it means that registers must be
4083 saved on entry to this function. So we migrate the call to the
4084 first insn of this function. */
4088 /* Do whatever the machine needs done in this case. */
4089 val = targetm.calls.expand_builtin_saveregs ();
4094 saveregs_value = val;
4096 /* Put the insns after the NOTE that starts the function. If this
4097 is inside a start_sequence, make the outer-level insn chain current, so
4098 the code is placed at the start of the function. */
4099 push_topmost_sequence ();
4100 emit_insn_after (seq, entry_of_function ());
4101 pop_topmost_sequence ();
4106 /* __builtin_args_info (N) returns word N of the arg space info
4107 for the current function. The number and meanings of words
4108 is controlled by the definition of CUMULATIVE_ARGS. */
4111 expand_builtin_args_info (tree arglist)
4113 int nwords = sizeof (CUMULATIVE_ARGS) / sizeof (int);
4114 int *word_ptr = (int *) ¤t_function_args_info;
4116 gcc_assert (sizeof (CUMULATIVE_ARGS) % sizeof (int) == 0);
4120 if (!host_integerp (TREE_VALUE (arglist), 0))
4121 error ("argument of %<__builtin_args_info%> must be constant");
4124 HOST_WIDE_INT wordnum = tree_low_cst (TREE_VALUE (arglist), 0);
4126 if (wordnum < 0 || wordnum >= nwords)
4127 error ("argument of %<__builtin_args_info%> out of range");
4129 return GEN_INT (word_ptr[wordnum]);
4133 error ("missing argument in %<__builtin_args_info%>");
4138 /* Expand a call to __builtin_next_arg. */
4141 expand_builtin_next_arg (void)
4143 /* Checking arguments is already done in fold_builtin_next_arg
4144 that must be called before this function. */
4145 return expand_binop (Pmode, add_optab,
4146 current_function_internal_arg_pointer,
4147 current_function_arg_offset_rtx,
4148 NULL_RTX, 0, OPTAB_LIB_WIDEN);
4151 /* Make it easier for the backends by protecting the valist argument
4152 from multiple evaluations. */
4155 stabilize_va_list (tree valist, int needs_lvalue)
4157 if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
4159 if (TREE_SIDE_EFFECTS (valist))
4160 valist = save_expr (valist);
4162 /* For this case, the backends will be expecting a pointer to
4163 TREE_TYPE (va_list_type_node), but it's possible we've
4164 actually been given an array (an actual va_list_type_node).
4166 if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
4168 tree p1 = build_pointer_type (TREE_TYPE (va_list_type_node));
4169 valist = build_fold_addr_expr_with_type (valist, p1);
4178 if (! TREE_SIDE_EFFECTS (valist))
4181 pt = build_pointer_type (va_list_type_node);
4182 valist = fold_build1 (ADDR_EXPR, pt, valist);
4183 TREE_SIDE_EFFECTS (valist) = 1;
4186 if (TREE_SIDE_EFFECTS (valist))
4187 valist = save_expr (valist);
4188 valist = build_fold_indirect_ref (valist);
4194 /* The "standard" definition of va_list is void*. */
4197 std_build_builtin_va_list (void)
4199 return ptr_type_node;
4202 /* The "standard" implementation of va_start: just assign `nextarg' to
4206 std_expand_builtin_va_start (tree valist, rtx nextarg)
4210 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist,
4211 make_tree (ptr_type_node, nextarg));
4212 TREE_SIDE_EFFECTS (t) = 1;
4214 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4217 /* Expand ARGLIST, from a call to __builtin_va_start. */
4220 expand_builtin_va_start (tree arglist)
4225 chain = TREE_CHAIN (arglist);
4229 error ("too few arguments to function %<va_start%>");
4233 if (fold_builtin_next_arg (chain))
4236 nextarg = expand_builtin_next_arg ();
4237 valist = stabilize_va_list (TREE_VALUE (arglist), 1);
4239 #ifdef EXPAND_BUILTIN_VA_START
4240 EXPAND_BUILTIN_VA_START (valist, nextarg);
4242 std_expand_builtin_va_start (valist, nextarg);
4248 /* The "standard" implementation of va_arg: read the value from the
4249 current (padded) address and increment by the (padded) size. */
4252 std_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p, tree *post_p)
4254 tree addr, t, type_size, rounded_size, valist_tmp;
4255 unsigned HOST_WIDE_INT align, boundary;
4258 #ifdef ARGS_GROW_DOWNWARD
4259 /* All of the alignment and movement below is for args-grow-up machines.
4260 As of 2004, there are only 3 ARGS_GROW_DOWNWARD targets, and they all
4261 implement their own specialized gimplify_va_arg_expr routines. */
4265 indirect = pass_by_reference (NULL, TYPE_MODE (type), type, false);
4267 type = build_pointer_type (type);
4269 align = PARM_BOUNDARY / BITS_PER_UNIT;
4270 boundary = FUNCTION_ARG_BOUNDARY (TYPE_MODE (type), type) / BITS_PER_UNIT;
4272 /* Hoist the valist value into a temporary for the moment. */
4273 valist_tmp = get_initialized_tmp_var (valist, pre_p, NULL);
4275 /* va_list pointer is aligned to PARM_BOUNDARY. If argument actually
4276 requires greater alignment, we must perform dynamic alignment. */
4277 if (boundary > align
4278 && !integer_zerop (TYPE_SIZE (type)))
4280 t = fold_convert (TREE_TYPE (valist), size_int (boundary - 1));
4281 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
4282 build2 (PLUS_EXPR, TREE_TYPE (valist), valist_tmp, t));
4283 gimplify_and_add (t, pre_p);
4285 t = fold_convert (TREE_TYPE (valist), size_int (-boundary));
4286 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
4287 build2 (BIT_AND_EXPR, TREE_TYPE (valist), valist_tmp, t));
4288 gimplify_and_add (t, pre_p);
4293 /* If the actual alignment is less than the alignment of the type,
4294 adjust the type accordingly so that we don't assume strict alignment
4295 when deferencing the pointer. */
4296 boundary *= BITS_PER_UNIT;
4297 if (boundary < TYPE_ALIGN (type))
4299 type = build_variant_type_copy (type);
4300 TYPE_ALIGN (type) = boundary;
4303 /* Compute the rounded size of the type. */
4304 type_size = size_in_bytes (type);
4305 rounded_size = round_up (type_size, align);
4307 /* Reduce rounded_size so it's sharable with the postqueue. */
4308 gimplify_expr (&rounded_size, pre_p, post_p, is_gimple_val, fb_rvalue);
4312 if (PAD_VARARGS_DOWN && !integer_zerop (rounded_size))
4314 /* Small args are padded downward. */
4315 t = fold_build2 (GT_EXPR, sizetype, rounded_size, size_int (align));
4316 t = fold_build3 (COND_EXPR, sizetype, t, size_zero_node,
4317 size_binop (MINUS_EXPR, rounded_size, type_size));
4318 t = fold_convert (TREE_TYPE (addr), t);
4319 addr = fold_build2 (PLUS_EXPR, TREE_TYPE (addr), addr, t);
4322 /* Compute new value for AP. */
4323 t = fold_convert (TREE_TYPE (valist), rounded_size);
4324 t = build2 (PLUS_EXPR, TREE_TYPE (valist), valist_tmp, t);
4325 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist, t);
4326 gimplify_and_add (t, pre_p);
4328 addr = fold_convert (build_pointer_type (type), addr);
4331 addr = build_va_arg_indirect_ref (addr);
4333 return build_va_arg_indirect_ref (addr);
4336 /* Build an indirect-ref expression over the given TREE, which represents a
4337 piece of a va_arg() expansion. */
4339 build_va_arg_indirect_ref (tree addr)
4341 addr = build_fold_indirect_ref (addr);
4343 if (flag_mudflap) /* Don't instrument va_arg INDIRECT_REF. */
4349 /* Return a dummy expression of type TYPE in order to keep going after an
4353 dummy_object (tree type)
4355 tree t = build_int_cst (build_pointer_type (type), 0);
4356 return build1 (INDIRECT_REF, type, t);
4359 /* Gimplify __builtin_va_arg, aka VA_ARG_EXPR, which is not really a
4360 builtin function, but a very special sort of operator. */
4362 enum gimplify_status
4363 gimplify_va_arg_expr (tree *expr_p, tree *pre_p, tree *post_p)
4365 tree promoted_type, want_va_type, have_va_type;
4366 tree valist = TREE_OPERAND (*expr_p, 0);
4367 tree type = TREE_TYPE (*expr_p);
4370 /* Verify that valist is of the proper type. */
4371 want_va_type = va_list_type_node;
4372 have_va_type = TREE_TYPE (valist);
4374 if (have_va_type == error_mark_node)
4377 if (TREE_CODE (want_va_type) == ARRAY_TYPE)
4379 /* If va_list is an array type, the argument may have decayed
4380 to a pointer type, e.g. by being passed to another function.
4381 In that case, unwrap both types so that we can compare the
4382 underlying records. */
4383 if (TREE_CODE (have_va_type) == ARRAY_TYPE
4384 || POINTER_TYPE_P (have_va_type))
4386 want_va_type = TREE_TYPE (want_va_type);
4387 have_va_type = TREE_TYPE (have_va_type);
4391 if (TYPE_MAIN_VARIANT (want_va_type) != TYPE_MAIN_VARIANT (have_va_type))
4393 error ("first argument to %<va_arg%> not of type %<va_list%>");
4397 /* Generate a diagnostic for requesting data of a type that cannot
4398 be passed through `...' due to type promotion at the call site. */
4399 else if ((promoted_type = lang_hooks.types.type_promotes_to (type))
4402 static bool gave_help;
4404 /* Unfortunately, this is merely undefined, rather than a constraint
4405 violation, so we cannot make this an error. If this call is never
4406 executed, the program is still strictly conforming. */
4407 warning (0, "%qT is promoted to %qT when passed through %<...%>",
4408 type, promoted_type);
4412 warning (0, "(so you should pass %qT not %qT to %<va_arg%>)",
4413 promoted_type, type);
4416 /* We can, however, treat "undefined" any way we please.
4417 Call abort to encourage the user to fix the program. */
4418 inform ("if this code is reached, the program will abort");
4419 t = build_function_call_expr (implicit_built_in_decls[BUILT_IN_TRAP],
4421 append_to_statement_list (t, pre_p);
4423 /* This is dead code, but go ahead and finish so that the
4424 mode of the result comes out right. */
4425 *expr_p = dummy_object (type);
4430 /* Make it easier for the backends by protecting the valist argument
4431 from multiple evaluations. */
4432 if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
4434 /* For this case, the backends will be expecting a pointer to
4435 TREE_TYPE (va_list_type_node), but it's possible we've
4436 actually been given an array (an actual va_list_type_node).
4438 if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
4440 tree p1 = build_pointer_type (TREE_TYPE (va_list_type_node));
4441 valist = build_fold_addr_expr_with_type (valist, p1);
4443 gimplify_expr (&valist, pre_p, post_p, is_gimple_val, fb_rvalue);
4446 gimplify_expr (&valist, pre_p, post_p, is_gimple_min_lval, fb_lvalue);
4448 if (!targetm.gimplify_va_arg_expr)
4449 /* FIXME:Once most targets are converted we should merely
4450 assert this is non-null. */
4453 *expr_p = targetm.gimplify_va_arg_expr (valist, type, pre_p, post_p);
4458 /* Expand ARGLIST, from a call to __builtin_va_end. */
4461 expand_builtin_va_end (tree arglist)
4463 tree valist = TREE_VALUE (arglist);
4465 /* Evaluate for side effects, if needed. I hate macros that don't
4467 if (TREE_SIDE_EFFECTS (valist))
4468 expand_expr (valist, const0_rtx, VOIDmode, EXPAND_NORMAL);
4473 /* Expand ARGLIST, from a call to __builtin_va_copy. We do this as a
4474 builtin rather than just as an assignment in stdarg.h because of the
4475 nastiness of array-type va_list types. */
4478 expand_builtin_va_copy (tree arglist)
4482 dst = TREE_VALUE (arglist);
4483 src = TREE_VALUE (TREE_CHAIN (arglist));
4485 dst = stabilize_va_list (dst, 1);
4486 src = stabilize_va_list (src, 0);
4488 if (TREE_CODE (va_list_type_node) != ARRAY_TYPE)
4490 t = build2 (MODIFY_EXPR, va_list_type_node, dst, src);
4491 TREE_SIDE_EFFECTS (t) = 1;
4492 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4496 rtx dstb, srcb, size;
4498 /* Evaluate to pointers. */
4499 dstb = expand_expr (dst, NULL_RTX, Pmode, EXPAND_NORMAL);
4500 srcb = expand_expr (src, NULL_RTX, Pmode, EXPAND_NORMAL);
4501 size = expand_expr (TYPE_SIZE_UNIT (va_list_type_node), NULL_RTX,
4502 VOIDmode, EXPAND_NORMAL);
4504 dstb = convert_memory_address (Pmode, dstb);
4505 srcb = convert_memory_address (Pmode, srcb);
4507 /* "Dereference" to BLKmode memories. */
4508 dstb = gen_rtx_MEM (BLKmode, dstb);
4509 set_mem_alias_set (dstb, get_alias_set (TREE_TYPE (TREE_TYPE (dst))));
4510 set_mem_align (dstb, TYPE_ALIGN (va_list_type_node));
4511 srcb = gen_rtx_MEM (BLKmode, srcb);
4512 set_mem_alias_set (srcb, get_alias_set (TREE_TYPE (TREE_TYPE (src))));
4513 set_mem_align (srcb, TYPE_ALIGN (va_list_type_node));
4516 emit_block_move (dstb, srcb, size, BLOCK_OP_NORMAL);
4522 /* Expand a call to one of the builtin functions __builtin_frame_address or
4523 __builtin_return_address. */
4526 expand_builtin_frame_address (tree fndecl, tree arglist)
4528 /* The argument must be a nonnegative integer constant.
4529 It counts the number of frames to scan up the stack.
4530 The value is the return address saved in that frame. */
4532 /* Warning about missing arg was already issued. */
4534 else if (! host_integerp (TREE_VALUE (arglist), 1))
4536 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4537 error ("invalid argument to %<__builtin_frame_address%>");
4539 error ("invalid argument to %<__builtin_return_address%>");
4545 = expand_builtin_return_addr (DECL_FUNCTION_CODE (fndecl),
4546 tree_low_cst (TREE_VALUE (arglist), 1));
4548 /* Some ports cannot access arbitrary stack frames. */
4551 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4552 warning (0, "unsupported argument to %<__builtin_frame_address%>");
4554 warning (0, "unsupported argument to %<__builtin_return_address%>");
4558 /* For __builtin_frame_address, return what we've got. */
4559 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4563 && ! CONSTANT_P (tem))
4564 tem = copy_to_mode_reg (Pmode, tem);
4569 /* Expand a call to the alloca builtin, with arguments ARGLIST. Return 0 if
4570 we failed and the caller should emit a normal call, otherwise try to get
4571 the result in TARGET, if convenient. */
4574 expand_builtin_alloca (tree arglist, rtx target)
4579 /* In -fmudflap-instrumented code, alloca() and __builtin_alloca()
4580 should always expand to function calls. These can be intercepted
4585 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
4588 /* Compute the argument. */
4589 op0 = expand_normal (TREE_VALUE (arglist));
4591 /* Allocate the desired space. */
4592 result = allocate_dynamic_stack_space (op0, target, BITS_PER_UNIT);
4593 result = convert_memory_address (ptr_mode, result);
4598 /* Expand a call to a unary builtin. The arguments are in ARGLIST.
4599 Return 0 if a normal call should be emitted rather than expanding the
4600 function in-line. If convenient, the result should be placed in TARGET.
4601 SUBTARGET may be used as the target for computing one of EXP's operands. */
4604 expand_builtin_unop (enum machine_mode target_mode, tree arglist, rtx target,
4605 rtx subtarget, optab op_optab)
4608 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
4611 /* Compute the argument. */
4612 op0 = expand_expr (TREE_VALUE (arglist), subtarget, VOIDmode, 0);
4613 /* Compute op, into TARGET if possible.
4614 Set TARGET to wherever the result comes back. */
4615 target = expand_unop (TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist))),
4616 op_optab, op0, target, 1);
4617 gcc_assert (target);
4619 return convert_to_mode (target_mode, target, 0);
4622 /* If the string passed to fputs is a constant and is one character
4623 long, we attempt to transform this call into __builtin_fputc(). */
4626 expand_builtin_fputs (tree arglist, rtx target, bool unlocked)
4628 /* Verify the arguments in the original call. */
4629 if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4631 tree result = fold_builtin_fputs (arglist, (target == const0_rtx),
4632 unlocked, NULL_TREE);
4634 return expand_expr (result, target, VOIDmode, EXPAND_NORMAL);
4639 /* Expand a call to __builtin_expect. We return our argument and emit a
4640 NOTE_INSN_EXPECTED_VALUE note. This is the expansion of __builtin_expect in
4641 a non-jump context. */
4644 expand_builtin_expect (tree arglist, rtx target)
4649 if (arglist == NULL_TREE
4650 || TREE_CHAIN (arglist) == NULL_TREE)
4652 exp = TREE_VALUE (arglist);
4653 c = TREE_VALUE (TREE_CHAIN (arglist));
4655 if (TREE_CODE (c) != INTEGER_CST)
4657 error ("second argument to %<__builtin_expect%> must be a constant");
4658 c = integer_zero_node;
4661 target = expand_expr (exp, target, VOIDmode, EXPAND_NORMAL);
4663 /* Don't bother with expected value notes for integral constants. */
4664 if (flag_guess_branch_prob && GET_CODE (target) != CONST_INT)
4666 /* We do need to force this into a register so that we can be
4667 moderately sure to be able to correctly interpret the branch
4669 target = force_reg (GET_MODE (target), target);
4671 rtx_c = expand_expr (c, NULL_RTX, GET_MODE (target), EXPAND_NORMAL);
4673 note = emit_note (NOTE_INSN_EXPECTED_VALUE);
4674 NOTE_EXPECTED_VALUE (note) = gen_rtx_EQ (VOIDmode, target, rtx_c);
4680 /* Like expand_builtin_expect, except do this in a jump context. This is
4681 called from do_jump if the conditional is a __builtin_expect. Return either
4682 a list of insns to emit the jump or NULL if we cannot optimize
4683 __builtin_expect. We need to optimize this at jump time so that machines
4684 like the PowerPC don't turn the test into a SCC operation, and then jump
4685 based on the test being 0/1. */
4688 expand_builtin_expect_jump (tree exp, rtx if_false_label, rtx if_true_label)
4690 tree arglist = TREE_OPERAND (exp, 1);
4691 tree arg0 = TREE_VALUE (arglist);
4692 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
4695 /* Only handle __builtin_expect (test, 0) and
4696 __builtin_expect (test, 1). */
4697 if (TREE_CODE (TREE_TYPE (arg1)) == INTEGER_TYPE
4698 && (integer_zerop (arg1) || integer_onep (arg1)))
4700 rtx insn, drop_through_label, temp;
4702 /* Expand the jump insns. */
4704 do_jump (arg0, if_false_label, if_true_label);
4707 drop_through_label = get_last_insn ();
4708 if (drop_through_label && NOTE_P (drop_through_label))
4709 drop_through_label = prev_nonnote_insn (drop_through_label);
4710 if (drop_through_label && !LABEL_P (drop_through_label))
4711 drop_through_label = NULL_RTX;
4714 if (! if_true_label)
4715 if_true_label = drop_through_label;
4716 if (! if_false_label)
4717 if_false_label = drop_through_label;
4719 /* Go through and add the expect's to each of the conditional jumps. */
4721 while (insn != NULL_RTX)
4723 rtx next = NEXT_INSN (insn);
4725 if (JUMP_P (insn) && any_condjump_p (insn))
4727 rtx ifelse = SET_SRC (pc_set (insn));
4728 rtx then_dest = XEXP (ifelse, 1);
4729 rtx else_dest = XEXP (ifelse, 2);
4732 /* First check if we recognize any of the labels. */
4733 if (GET_CODE (then_dest) == LABEL_REF
4734 && XEXP (then_dest, 0) == if_true_label)
4736 else if (GET_CODE (then_dest) == LABEL_REF
4737 && XEXP (then_dest, 0) == if_false_label)
4739 else if (GET_CODE (else_dest) == LABEL_REF
4740 && XEXP (else_dest, 0) == if_false_label)
4742 else if (GET_CODE (else_dest) == LABEL_REF
4743 && XEXP (else_dest, 0) == if_true_label)
4745 /* Otherwise check where we drop through. */
4746 else if (else_dest == pc_rtx)
4748 if (next && NOTE_P (next))
4749 next = next_nonnote_insn (next);
4751 if (next && JUMP_P (next)
4752 && any_uncondjump_p (next))
4753 temp = XEXP (SET_SRC (pc_set (next)), 0);
4757 /* TEMP is either a CODE_LABEL, NULL_RTX or something
4758 else that can't possibly match either target label. */
4759 if (temp == if_false_label)
4761 else if (temp == if_true_label)
4764 else if (then_dest == pc_rtx)
4766 if (next && NOTE_P (next))
4767 next = next_nonnote_insn (next);
4769 if (next && JUMP_P (next)
4770 && any_uncondjump_p (next))
4771 temp = XEXP (SET_SRC (pc_set (next)), 0);
4775 if (temp == if_false_label)
4777 else if (temp == if_true_label)
4783 /* If the test is expected to fail, reverse the
4785 if (integer_zerop (arg1))
4787 predict_insn_def (insn, PRED_BUILTIN_EXPECT, taken);
4799 expand_builtin_trap (void)
4803 emit_insn (gen_trap ());
4806 emit_library_call (abort_libfunc, LCT_NORETURN, VOIDmode, 0);
4810 /* Expand a call to fabs, fabsf or fabsl with arguments ARGLIST.
4811 Return 0 if a normal call should be emitted rather than expanding
4812 the function inline. If convenient, the result should be placed
4813 in TARGET. SUBTARGET may be used as the target for computing
4817 expand_builtin_fabs (tree arglist, rtx target, rtx subtarget)
4819 enum machine_mode mode;
4823 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
4826 arg = TREE_VALUE (arglist);
4827 mode = TYPE_MODE (TREE_TYPE (arg));
4828 op0 = expand_expr (arg, subtarget, VOIDmode, 0);
4829 return expand_abs (mode, op0, target, 0, safe_from_p (target, arg, 1));
4832 /* Expand a call to copysign, copysignf, or copysignl with arguments ARGLIST.
4833 Return NULL is a normal call should be emitted rather than expanding the
4834 function inline. If convenient, the result should be placed in TARGET.
4835 SUBTARGET may be used as the target for computing the operand. */
4838 expand_builtin_copysign (tree arglist, rtx target, rtx subtarget)
4843 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
4846 arg = TREE_VALUE (arglist);
4847 op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL);
4849 arg = TREE_VALUE (TREE_CHAIN (arglist));
4850 op1 = expand_normal (arg);
4852 return expand_copysign (op0, op1, target);
4855 /* Create a new constant string literal and return a char* pointer to it.
4856 The STRING_CST value is the LEN characters at STR. */
4858 build_string_literal (int len, const char *str)
4860 tree t, elem, index, type;
4862 t = build_string (len, str);
4863 elem = build_type_variant (char_type_node, 1, 0);
4864 index = build_index_type (build_int_cst (NULL_TREE, len - 1));
4865 type = build_array_type (elem, index);
4866 TREE_TYPE (t) = type;
4867 TREE_CONSTANT (t) = 1;
4868 TREE_INVARIANT (t) = 1;
4869 TREE_READONLY (t) = 1;
4870 TREE_STATIC (t) = 1;
4872 type = build_pointer_type (type);
4873 t = build1 (ADDR_EXPR, type, t);
4875 type = build_pointer_type (elem);
4876 t = build1 (NOP_EXPR, type, t);
4880 /* Expand EXP, a call to printf or printf_unlocked.
4881 Return 0 if a normal call should be emitted rather than transforming
4882 the function inline. If convenient, the result should be placed in
4883 TARGET with mode MODE. UNLOCKED indicates this is a printf_unlocked
4886 expand_builtin_printf (tree exp, rtx target, enum machine_mode mode,
4889 tree arglist = TREE_OPERAND (exp, 1);
4890 /* If we're using an unlocked function, assume the other unlocked
4891 functions exist explicitly. */
4892 tree const fn_putchar = unlocked ? built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED]
4893 : implicit_built_in_decls[BUILT_IN_PUTCHAR];
4894 tree const fn_puts = unlocked ? built_in_decls[BUILT_IN_PUTS_UNLOCKED]
4895 : implicit_built_in_decls[BUILT_IN_PUTS];
4896 const char *fmt_str;
4899 /* If the return value is used, don't do the transformation. */
4900 if (target != const0_rtx)
4903 /* Verify the required arguments in the original call. */
4906 fmt = TREE_VALUE (arglist);
4907 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
4909 arglist = TREE_CHAIN (arglist);
4911 /* Check whether the format is a literal string constant. */
4912 fmt_str = c_getstr (fmt);
4913 if (fmt_str == NULL)
4916 if (!init_target_chars())
4919 /* If the format specifier was "%s\n", call __builtin_puts(arg). */
4920 if (strcmp (fmt_str, target_percent_s_newline) == 0)
4923 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
4924 || TREE_CHAIN (arglist))
4928 /* If the format specifier was "%c", call __builtin_putchar(arg). */
4929 else if (strcmp (fmt_str, target_percent_c) == 0)
4932 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
4933 || TREE_CHAIN (arglist))
4939 /* We can't handle anything else with % args or %% ... yet. */
4940 if (strchr (fmt_str, target_percent))
4946 /* If the format specifier was "", printf does nothing. */
4947 if (fmt_str[0] == '\0')
4949 /* If the format specifier has length of 1, call putchar. */
4950 if (fmt_str[1] == '\0')
4952 /* Given printf("c"), (where c is any one character,)
4953 convert "c"[0] to an int and pass that to the replacement
4955 arg = build_int_cst (NULL_TREE, fmt_str[0]);
4956 arglist = build_tree_list (NULL_TREE, arg);
4961 /* If the format specifier was "string\n", call puts("string"). */
4962 size_t len = strlen (fmt_str);
4963 if ((unsigned char)fmt_str[len - 1] == target_newline)
4965 /* Create a NUL-terminated string that's one char shorter
4966 than the original, stripping off the trailing '\n'. */
4967 char *newstr = alloca (len);
4968 memcpy (newstr, fmt_str, len - 1);
4969 newstr[len - 1] = 0;
4971 arg = build_string_literal (len, newstr);
4972 arglist = build_tree_list (NULL_TREE, arg);
4976 /* We'd like to arrange to call fputs(string,stdout) here,
4977 but we need stdout and don't have a way to get it yet. */
4984 fn = build_function_call_expr (fn, arglist);
4985 if (TREE_CODE (fn) == CALL_EXPR)
4986 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
4987 return expand_expr (fn, target, mode, EXPAND_NORMAL);
4990 /* Expand EXP, a call to fprintf or fprintf_unlocked.
4991 Return 0 if a normal call should be emitted rather than transforming
4992 the function inline. If convenient, the result should be placed in
4993 TARGET with mode MODE. UNLOCKED indicates this is a fprintf_unlocked
4996 expand_builtin_fprintf (tree exp, rtx target, enum machine_mode mode,
4999 tree arglist = TREE_OPERAND (exp, 1);
5000 /* If we're using an unlocked function, assume the other unlocked
5001 functions exist explicitly. */
5002 tree const fn_fputc = unlocked ? built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
5003 : implicit_built_in_decls[BUILT_IN_FPUTC];
5004 tree const fn_fputs = unlocked ? built_in_decls[BUILT_IN_FPUTS_UNLOCKED]
5005 : implicit_built_in_decls[BUILT_IN_FPUTS];
5006 const char *fmt_str;
5007 tree fn, fmt, fp, arg;
5009 /* If the return value is used, don't do the transformation. */
5010 if (target != const0_rtx)
5013 /* Verify the required arguments in the original call. */
5016 fp = TREE_VALUE (arglist);
5017 if (! POINTER_TYPE_P (TREE_TYPE (fp)))
5019 arglist = TREE_CHAIN (arglist);
5022 fmt = TREE_VALUE (arglist);
5023 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
5025 arglist = TREE_CHAIN (arglist);
5027 /* Check whether the format is a literal string constant. */
5028 fmt_str = c_getstr (fmt);
5029 if (fmt_str == NULL)
5032 if (!init_target_chars())
5035 /* If the format specifier was "%s", call __builtin_fputs(arg,fp). */
5036 if (strcmp (fmt_str, target_percent_s) == 0)
5039 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
5040 || TREE_CHAIN (arglist))
5042 arg = TREE_VALUE (arglist);
5043 arglist = build_tree_list (NULL_TREE, fp);
5044 arglist = tree_cons (NULL_TREE, arg, arglist);
5047 /* If the format specifier was "%c", call __builtin_fputc(arg,fp). */
5048 else if (strcmp (fmt_str, target_percent_c) == 0)
5051 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
5052 || TREE_CHAIN (arglist))
5054 arg = TREE_VALUE (arglist);
5055 arglist = build_tree_list (NULL_TREE, fp);
5056 arglist = tree_cons (NULL_TREE, arg, arglist);
5061 /* We can't handle anything else with % args or %% ... yet. */
5062 if (strchr (fmt_str, target_percent))
5068 /* If the format specifier was "", fprintf does nothing. */
5069 if (fmt_str[0] == '\0')
5071 /* Evaluate and ignore FILE* argument for side-effects. */
5072 expand_expr (fp, const0_rtx, VOIDmode, EXPAND_NORMAL);
5076 /* When "string" doesn't contain %, replace all cases of
5077 fprintf(stream,string) with fputs(string,stream). The fputs
5078 builtin will take care of special cases like length == 1. */
5079 arglist = build_tree_list (NULL_TREE, fp);
5080 arglist = tree_cons (NULL_TREE, fmt, arglist);
5086 fn = build_function_call_expr (fn, arglist);
5087 if (TREE_CODE (fn) == CALL_EXPR)
5088 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
5089 return expand_expr (fn, target, mode, EXPAND_NORMAL);
5092 /* Expand a call to sprintf with argument list ARGLIST. Return 0 if
5093 a normal call should be emitted rather than expanding the function
5094 inline. If convenient, the result should be placed in TARGET with
5098 expand_builtin_sprintf (tree arglist, rtx target, enum machine_mode mode)
5100 tree orig_arglist, dest, fmt;
5101 const char *fmt_str;
5103 orig_arglist = arglist;
5105 /* Verify the required arguments in the original call. */
5108 dest = TREE_VALUE (arglist);
5109 if (! POINTER_TYPE_P (TREE_TYPE (dest)))
5111 arglist = TREE_CHAIN (arglist);
5114 fmt = TREE_VALUE (arglist);
5115 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
5117 arglist = TREE_CHAIN (arglist);
5119 /* Check whether the format is a literal string constant. */
5120 fmt_str = c_getstr (fmt);
5121 if (fmt_str == NULL)
5124 if (!init_target_chars())
5127 /* If the format doesn't contain % args or %%, use strcpy. */
5128 if (strchr (fmt_str, target_percent) == 0)
5130 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
5133 if (arglist || ! fn)
5135 expand_expr (build_function_call_expr (fn, orig_arglist),
5136 const0_rtx, VOIDmode, EXPAND_NORMAL);
5137 if (target == const0_rtx)
5139 exp = build_int_cst (NULL_TREE, strlen (fmt_str));
5140 return expand_expr (exp, target, mode, EXPAND_NORMAL);
5142 /* If the format is "%s", use strcpy if the result isn't used. */
5143 else if (strcmp (fmt_str, target_percent_s) == 0)
5146 fn = implicit_built_in_decls[BUILT_IN_STRCPY];
5151 if (! arglist || TREE_CHAIN (arglist))
5153 arg = TREE_VALUE (arglist);
5154 if (! POINTER_TYPE_P (TREE_TYPE (arg)))
5157 if (target != const0_rtx)
5159 len = c_strlen (arg, 1);
5160 if (! len || TREE_CODE (len) != INTEGER_CST)
5166 arglist = build_tree_list (NULL_TREE, arg);
5167 arglist = tree_cons (NULL_TREE, dest, arglist);
5168 expand_expr (build_function_call_expr (fn, arglist),
5169 const0_rtx, VOIDmode, EXPAND_NORMAL);
5171 if (target == const0_rtx)
5173 return expand_expr (len, target, mode, EXPAND_NORMAL);
5179 /* Expand a call to either the entry or exit function profiler. */
5182 expand_builtin_profile_func (bool exitp)
5186 this = DECL_RTL (current_function_decl);
5187 gcc_assert (MEM_P (this));
5188 this = XEXP (this, 0);
5191 which = profile_function_exit_libfunc;
5193 which = profile_function_entry_libfunc;
5195 emit_library_call (which, LCT_NORMAL, VOIDmode, 2, this, Pmode,
5196 expand_builtin_return_addr (BUILT_IN_RETURN_ADDRESS,
5203 /* Given a trampoline address, make sure it satisfies TRAMPOLINE_ALIGNMENT. */
5206 round_trampoline_addr (rtx tramp)
5208 rtx temp, addend, mask;
5210 /* If we don't need too much alignment, we'll have been guaranteed
5211 proper alignment by get_trampoline_type. */
5212 if (TRAMPOLINE_ALIGNMENT <= STACK_BOUNDARY)
5215 /* Round address up to desired boundary. */
5216 temp = gen_reg_rtx (Pmode);
5217 addend = GEN_INT (TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT - 1);
5218 mask = GEN_INT (-TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT);
5220 temp = expand_simple_binop (Pmode, PLUS, tramp, addend,
5221 temp, 0, OPTAB_LIB_WIDEN);
5222 tramp = expand_simple_binop (Pmode, AND, temp, mask,
5223 temp, 0, OPTAB_LIB_WIDEN);
5229 expand_builtin_init_trampoline (tree arglist)
5231 tree t_tramp, t_func, t_chain;
5232 rtx r_tramp, r_func, r_chain;
5233 #ifdef TRAMPOLINE_TEMPLATE
5237 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE,
5238 POINTER_TYPE, VOID_TYPE))
5241 t_tramp = TREE_VALUE (arglist);
5242 arglist = TREE_CHAIN (arglist);
5243 t_func = TREE_VALUE (arglist);
5244 arglist = TREE_CHAIN (arglist);
5245 t_chain = TREE_VALUE (arglist);
5247 r_tramp = expand_normal (t_tramp);
5248 r_func = expand_normal (t_func);
5249 r_chain = expand_normal (t_chain);
5251 /* Generate insns to initialize the trampoline. */
5252 r_tramp = round_trampoline_addr (r_tramp);
5253 #ifdef TRAMPOLINE_TEMPLATE
5254 blktramp = gen_rtx_MEM (BLKmode, r_tramp);
5255 set_mem_align (blktramp, TRAMPOLINE_ALIGNMENT);
5256 emit_block_move (blktramp, assemble_trampoline_template (),
5257 GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL);
5259 trampolines_created = 1;
5260 INITIALIZE_TRAMPOLINE (r_tramp, r_func, r_chain);
5266 expand_builtin_adjust_trampoline (tree arglist)
5270 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5273 tramp = expand_normal (TREE_VALUE (arglist));
5274 tramp = round_trampoline_addr (tramp);
5275 #ifdef TRAMPOLINE_ADJUST_ADDRESS
5276 TRAMPOLINE_ADJUST_ADDRESS (tramp);
5282 /* Expand a call to the built-in signbit, signbitf or signbitl function.
5283 Return NULL_RTX if a normal call should be emitted rather than expanding
5284 the function in-line. EXP is the expression that is a call to the builtin
5285 function; if convenient, the result should be placed in TARGET. */
5288 expand_builtin_signbit (tree exp, rtx target)
5290 const struct real_format *fmt;
5291 enum machine_mode fmode, imode, rmode;
5292 HOST_WIDE_INT hi, lo;
5297 arglist = TREE_OPERAND (exp, 1);
5298 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
5301 arg = TREE_VALUE (arglist);
5302 fmode = TYPE_MODE (TREE_TYPE (arg));
5303 rmode = TYPE_MODE (TREE_TYPE (exp));
5304 fmt = REAL_MODE_FORMAT (fmode);
5306 /* For floating point formats without a sign bit, implement signbit
5308 bitpos = fmt->signbit_ro;
5311 /* But we can't do this if the format supports signed zero. */
5312 if (fmt->has_signed_zero && HONOR_SIGNED_ZEROS (fmode))
5315 arg = fold_build2 (LT_EXPR, TREE_TYPE (exp), arg,
5316 build_real (TREE_TYPE (arg), dconst0));
5317 return expand_expr (arg, target, VOIDmode, EXPAND_NORMAL);
5320 temp = expand_normal (arg);
5321 if (GET_MODE_SIZE (fmode) <= UNITS_PER_WORD)
5323 imode = int_mode_for_mode (fmode);
5324 if (imode == BLKmode)
5326 temp = gen_lowpart (imode, temp);
5331 /* Handle targets with different FP word orders. */
5332 if (FLOAT_WORDS_BIG_ENDIAN)
5333 word = (GET_MODE_BITSIZE (fmode) - bitpos) / BITS_PER_WORD;
5335 word = bitpos / BITS_PER_WORD;
5336 temp = operand_subword_force (temp, word, fmode);
5337 bitpos = bitpos % BITS_PER_WORD;
5340 /* Force the intermediate word_mode (or narrower) result into a
5341 register. This avoids attempting to create paradoxical SUBREGs
5342 of floating point modes below. */
5343 temp = force_reg (imode, temp);
5345 /* If the bitpos is within the "result mode" lowpart, the operation
5346 can be implement with a single bitwise AND. Otherwise, we need
5347 a right shift and an AND. */
5349 if (bitpos < GET_MODE_BITSIZE (rmode))
5351 if (bitpos < HOST_BITS_PER_WIDE_INT)
5354 lo = (HOST_WIDE_INT) 1 << bitpos;
5358 hi = (HOST_WIDE_INT) 1 << (bitpos - HOST_BITS_PER_WIDE_INT);
5363 temp = gen_lowpart (rmode, temp);
5364 temp = expand_binop (rmode, and_optab, temp,
5365 immed_double_const (lo, hi, rmode),
5366 NULL_RTX, 1, OPTAB_LIB_WIDEN);
5370 /* Perform a logical right shift to place the signbit in the least
5371 significant bit, then truncate the result to the desired mode
5372 and mask just this bit. */
5373 temp = expand_shift (RSHIFT_EXPR, imode, temp,
5374 build_int_cst (NULL_TREE, bitpos), NULL_RTX, 1);
5375 temp = gen_lowpart (rmode, temp);
5376 temp = expand_binop (rmode, and_optab, temp, const1_rtx,
5377 NULL_RTX, 1, OPTAB_LIB_WIDEN);
5383 /* Expand fork or exec calls. TARGET is the desired target of the
5384 call. ARGLIST is the list of arguments of the call. FN is the
5385 identificator of the actual function. IGNORE is nonzero if the
5386 value is to be ignored. */
5389 expand_builtin_fork_or_exec (tree fn, tree arglist, rtx target, int ignore)
5394 /* If we are not profiling, just call the function. */
5395 if (!profile_arc_flag)
5398 /* Otherwise call the wrapper. This should be equivalent for the rest of
5399 compiler, so the code does not diverge, and the wrapper may run the
5400 code necessary for keeping the profiling sane. */
5402 switch (DECL_FUNCTION_CODE (fn))
5405 id = get_identifier ("__gcov_fork");
5408 case BUILT_IN_EXECL:
5409 id = get_identifier ("__gcov_execl");
5412 case BUILT_IN_EXECV:
5413 id = get_identifier ("__gcov_execv");
5416 case BUILT_IN_EXECLP:
5417 id = get_identifier ("__gcov_execlp");
5420 case BUILT_IN_EXECLE:
5421 id = get_identifier ("__gcov_execle");
5424 case BUILT_IN_EXECVP:
5425 id = get_identifier ("__gcov_execvp");
5428 case BUILT_IN_EXECVE:
5429 id = get_identifier ("__gcov_execve");
5436 decl = build_decl (FUNCTION_DECL, id, TREE_TYPE (fn));
5437 DECL_EXTERNAL (decl) = 1;
5438 TREE_PUBLIC (decl) = 1;
5439 DECL_ARTIFICIAL (decl) = 1;
5440 TREE_NOTHROW (decl) = 1;
5441 DECL_VISIBILITY (decl) = VISIBILITY_DEFAULT;
5442 DECL_VISIBILITY_SPECIFIED (decl) = 1;
5443 call = build_function_call_expr (decl, arglist);
5445 return expand_call (call, target, ignore);
5449 /* Reconstitute a mode for a __sync intrinsic operation. Since the type of
5450 the pointer in these functions is void*, the tree optimizers may remove
5451 casts. The mode computed in expand_builtin isn't reliable either, due
5452 to __sync_bool_compare_and_swap.
5454 FCODE_DIFF should be fcode - base, where base is the FOO_1 code for the
5455 group of builtins. This gives us log2 of the mode size. */
5457 static inline enum machine_mode
5458 get_builtin_sync_mode (int fcode_diff)
5460 /* The size is not negotiable, so ask not to get BLKmode in return
5461 if the target indicates that a smaller size would be better. */
5462 return mode_for_size (BITS_PER_UNIT << fcode_diff, MODE_INT, 0);
5465 /* Expand the memory expression LOC and return the appropriate memory operand
5466 for the builtin_sync operations. */
5469 get_builtin_sync_mem (tree loc, enum machine_mode mode)
5473 addr = expand_expr (loc, NULL, Pmode, EXPAND_SUM);
5475 /* Note that we explicitly do not want any alias information for this
5476 memory, so that we kill all other live memories. Otherwise we don't
5477 satisfy the full barrier semantics of the intrinsic. */
5478 mem = validize_mem (gen_rtx_MEM (mode, addr));
5480 set_mem_align (mem, get_pointer_alignment (loc, BIGGEST_ALIGNMENT));
5481 set_mem_alias_set (mem, ALIAS_SET_MEMORY_BARRIER);
5482 MEM_VOLATILE_P (mem) = 1;
5487 /* Expand the __sync_xxx_and_fetch and __sync_fetch_and_xxx intrinsics.
5488 ARGLIST is the operands list to the function. CODE is the rtx code
5489 that corresponds to the arithmetic or logical operation from the name;
5490 an exception here is that NOT actually means NAND. TARGET is an optional
5491 place for us to store the results; AFTER is true if this is the
5492 fetch_and_xxx form. IGNORE is true if we don't actually care about
5493 the result of the operation at all. */
5496 expand_builtin_sync_operation (enum machine_mode mode, tree arglist,
5497 enum rtx_code code, bool after,
5498 rtx target, bool ignore)
5502 /* Expand the operands. */
5503 mem = get_builtin_sync_mem (TREE_VALUE (arglist), mode);
5505 arglist = TREE_CHAIN (arglist);
5506 val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
5509 return expand_sync_operation (mem, val, code);
5511 return expand_sync_fetch_operation (mem, val, code, after, target);
5514 /* Expand the __sync_val_compare_and_swap and __sync_bool_compare_and_swap
5515 intrinsics. ARGLIST is the operands list to the function. IS_BOOL is
5516 true if this is the boolean form. TARGET is a place for us to store the
5517 results; this is NOT optional if IS_BOOL is true. */
5520 expand_builtin_compare_and_swap (enum machine_mode mode, tree arglist,
5521 bool is_bool, rtx target)
5523 rtx old_val, new_val, mem;
5525 /* Expand the operands. */
5526 mem = get_builtin_sync_mem (TREE_VALUE (arglist), mode);
5528 arglist = TREE_CHAIN (arglist);
5529 old_val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
5531 arglist = TREE_CHAIN (arglist);
5532 new_val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
5535 return expand_bool_compare_and_swap (mem, old_val, new_val, target);
5537 return expand_val_compare_and_swap (mem, old_val, new_val, target);
5540 /* Expand the __sync_lock_test_and_set intrinsic. Note that the most
5541 general form is actually an atomic exchange, and some targets only
5542 support a reduced form with the second argument being a constant 1.
5543 ARGLIST is the operands list to the function; TARGET is an optional
5544 place for us to store the results. */
5547 expand_builtin_lock_test_and_set (enum machine_mode mode, tree arglist,
5552 /* Expand the operands. */
5553 mem = get_builtin_sync_mem (TREE_VALUE (arglist), mode);
5555 arglist = TREE_CHAIN (arglist);
5556 val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
5558 return expand_sync_lock_test_and_set (mem, val, target);
5561 /* Expand the __sync_synchronize intrinsic. */
5564 expand_builtin_synchronize (void)
5568 #ifdef HAVE_memory_barrier
5569 if (HAVE_memory_barrier)
5571 emit_insn (gen_memory_barrier ());
5576 /* If no explicit memory barrier instruction is available, create an
5577 empty asm stmt with a memory clobber. */
5578 x = build4 (ASM_EXPR, void_type_node, build_string (0, ""), NULL, NULL,
5579 tree_cons (NULL, build_string (6, "memory"), NULL));
5580 ASM_VOLATILE_P (x) = 1;
5581 expand_asm_expr (x);
5584 /* Expand the __sync_lock_release intrinsic. ARGLIST is the operands list
5588 expand_builtin_lock_release (enum machine_mode mode, tree arglist)
5590 enum insn_code icode;
5592 rtx val = const0_rtx;
5594 /* Expand the operands. */
5595 mem = get_builtin_sync_mem (TREE_VALUE (arglist), mode);
5597 /* If there is an explicit operation in the md file, use it. */
5598 icode = sync_lock_release[mode];
5599 if (icode != CODE_FOR_nothing)
5601 if (!insn_data[icode].operand[1].predicate (val, mode))
5602 val = force_reg (mode, val);
5604 insn = GEN_FCN (icode) (mem, val);
5612 /* Otherwise we can implement this operation by emitting a barrier
5613 followed by a store of zero. */
5614 expand_builtin_synchronize ();
5615 emit_move_insn (mem, val);
5618 /* Expand an expression EXP that calls a built-in function,
5619 with result going to TARGET if that's convenient
5620 (and in mode MODE if that's convenient).
5621 SUBTARGET may be used as the target for computing one of EXP's operands.
5622 IGNORE is nonzero if the value is to be ignored. */
5625 expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
5628 tree fndecl = get_callee_fndecl (exp);
5629 tree arglist = TREE_OPERAND (exp, 1);
5630 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
5631 enum machine_mode target_mode = TYPE_MODE (TREE_TYPE (exp));
5633 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
5634 return targetm.expand_builtin (exp, target, subtarget, mode, ignore);
5636 /* When not optimizing, generate calls to library functions for a certain
5639 && !called_as_built_in (fndecl)
5640 && DECL_ASSEMBLER_NAME_SET_P (fndecl)
5641 && fcode != BUILT_IN_ALLOCA)
5642 return expand_call (exp, target, ignore);
5644 /* The built-in function expanders test for target == const0_rtx
5645 to determine whether the function's result will be ignored. */
5647 target = const0_rtx;
5649 /* If the result of a pure or const built-in function is ignored, and
5650 none of its arguments are volatile, we can avoid expanding the
5651 built-in call and just evaluate the arguments for side-effects. */
5652 if (target == const0_rtx
5653 && (DECL_IS_PURE (fndecl) || TREE_READONLY (fndecl)))
5655 bool volatilep = false;
5658 for (arg = arglist; arg; arg = TREE_CHAIN (arg))
5659 if (TREE_THIS_VOLATILE (TREE_VALUE (arg)))
5667 for (arg = arglist; arg; arg = TREE_CHAIN (arg))
5668 expand_expr (TREE_VALUE (arg), const0_rtx,
5669 VOIDmode, EXPAND_NORMAL);
5676 CASE_FLT_FN (BUILT_IN_FABS):
5677 target = expand_builtin_fabs (arglist, target, subtarget);
5682 CASE_FLT_FN (BUILT_IN_COPYSIGN):
5683 target = expand_builtin_copysign (arglist, target, subtarget);
5688 /* Just do a normal library call if we were unable to fold
5690 CASE_FLT_FN (BUILT_IN_CABS):
5693 CASE_FLT_FN (BUILT_IN_EXP):
5694 CASE_FLT_FN (BUILT_IN_EXP10):
5695 CASE_FLT_FN (BUILT_IN_POW10):
5696 CASE_FLT_FN (BUILT_IN_EXP2):
5697 CASE_FLT_FN (BUILT_IN_EXPM1):
5698 CASE_FLT_FN (BUILT_IN_LOGB):
5699 CASE_FLT_FN (BUILT_IN_ILOGB):
5700 CASE_FLT_FN (BUILT_IN_LOG):
5701 CASE_FLT_FN (BUILT_IN_LOG10):
5702 CASE_FLT_FN (BUILT_IN_LOG2):
5703 CASE_FLT_FN (BUILT_IN_LOG1P):
5704 CASE_FLT_FN (BUILT_IN_TAN):
5705 CASE_FLT_FN (BUILT_IN_ASIN):
5706 CASE_FLT_FN (BUILT_IN_ACOS):
5707 CASE_FLT_FN (BUILT_IN_ATAN):
5708 /* Treat these like sqrt only if unsafe math optimizations are allowed,
5709 because of possible accuracy problems. */
5710 if (! flag_unsafe_math_optimizations)
5712 CASE_FLT_FN (BUILT_IN_SQRT):
5713 CASE_FLT_FN (BUILT_IN_FLOOR):
5714 CASE_FLT_FN (BUILT_IN_CEIL):
5715 CASE_FLT_FN (BUILT_IN_TRUNC):
5716 CASE_FLT_FN (BUILT_IN_ROUND):
5717 CASE_FLT_FN (BUILT_IN_NEARBYINT):
5718 CASE_FLT_FN (BUILT_IN_RINT):
5719 CASE_FLT_FN (BUILT_IN_LRINT):
5720 CASE_FLT_FN (BUILT_IN_LLRINT):
5721 target = expand_builtin_mathfn (exp, target, subtarget);
5726 CASE_FLT_FN (BUILT_IN_LCEIL):
5727 CASE_FLT_FN (BUILT_IN_LLCEIL):
5728 CASE_FLT_FN (BUILT_IN_LFLOOR):
5729 CASE_FLT_FN (BUILT_IN_LLFLOOR):
5730 target = expand_builtin_int_roundingfn (exp, target, subtarget);
5735 CASE_FLT_FN (BUILT_IN_POW):
5736 target = expand_builtin_pow (exp, target, subtarget);
5741 CASE_FLT_FN (BUILT_IN_POWI):
5742 target = expand_builtin_powi (exp, target, subtarget);
5747 CASE_FLT_FN (BUILT_IN_ATAN2):
5748 CASE_FLT_FN (BUILT_IN_LDEXP):
5749 CASE_FLT_FN (BUILT_IN_FMOD):
5750 CASE_FLT_FN (BUILT_IN_DREM):
5751 if (! flag_unsafe_math_optimizations)
5753 target = expand_builtin_mathfn_2 (exp, target, subtarget);
5758 CASE_FLT_FN (BUILT_IN_SIN):
5759 CASE_FLT_FN (BUILT_IN_COS):
5760 if (! flag_unsafe_math_optimizations)
5762 target = expand_builtin_mathfn_3 (exp, target, subtarget);
5767 CASE_FLT_FN (BUILT_IN_SINCOS):
5768 if (! flag_unsafe_math_optimizations)
5770 target = expand_builtin_sincos (exp);
5775 case BUILT_IN_APPLY_ARGS:
5776 return expand_builtin_apply_args ();
5778 /* __builtin_apply (FUNCTION, ARGUMENTS, ARGSIZE) invokes
5779 FUNCTION with a copy of the parameters described by
5780 ARGUMENTS, and ARGSIZE. It returns a block of memory
5781 allocated on the stack into which is stored all the registers
5782 that might possibly be used for returning the result of a
5783 function. ARGUMENTS is the value returned by
5784 __builtin_apply_args. ARGSIZE is the number of bytes of
5785 arguments that must be copied. ??? How should this value be
5786 computed? We'll also need a safe worst case value for varargs
5788 case BUILT_IN_APPLY:
5789 if (!validate_arglist (arglist, POINTER_TYPE,
5790 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)
5791 && !validate_arglist (arglist, REFERENCE_TYPE,
5792 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
5800 for (t = arglist, i = 0; t; t = TREE_CHAIN (t), i++)
5801 ops[i] = expand_normal (TREE_VALUE (t));
5803 return expand_builtin_apply (ops[0], ops[1], ops[2]);
5806 /* __builtin_return (RESULT) causes the function to return the
5807 value described by RESULT. RESULT is address of the block of
5808 memory returned by __builtin_apply. */
5809 case BUILT_IN_RETURN:
5810 if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5811 expand_builtin_return (expand_normal (TREE_VALUE (arglist)));
5814 case BUILT_IN_SAVEREGS:
5815 return expand_builtin_saveregs ();
5817 case BUILT_IN_ARGS_INFO:
5818 return expand_builtin_args_info (arglist);
5820 /* Return the address of the first anonymous stack arg. */
5821 case BUILT_IN_NEXT_ARG:
5822 if (fold_builtin_next_arg (arglist))
5824 return expand_builtin_next_arg ();
5826 case BUILT_IN_CLASSIFY_TYPE:
5827 return expand_builtin_classify_type (arglist);
5829 case BUILT_IN_CONSTANT_P:
5832 case BUILT_IN_FRAME_ADDRESS:
5833 case BUILT_IN_RETURN_ADDRESS:
5834 return expand_builtin_frame_address (fndecl, arglist);
5836 /* Returns the address of the area where the structure is returned.
5838 case BUILT_IN_AGGREGATE_INCOMING_ADDRESS:
5840 || ! AGGREGATE_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl)))
5841 || !MEM_P (DECL_RTL (DECL_RESULT (current_function_decl))))
5844 return XEXP (DECL_RTL (DECL_RESULT (current_function_decl)), 0);
5846 case BUILT_IN_ALLOCA:
5847 target = expand_builtin_alloca (arglist, target);
5852 case BUILT_IN_STACK_SAVE:
5853 return expand_stack_save ();
5855 case BUILT_IN_STACK_RESTORE:
5856 expand_stack_restore (TREE_VALUE (arglist));
5859 CASE_INT_FN (BUILT_IN_FFS):
5860 case BUILT_IN_FFSIMAX:
5861 target = expand_builtin_unop (target_mode, arglist, target,
5862 subtarget, ffs_optab);
5867 CASE_INT_FN (BUILT_IN_CLZ):
5868 case BUILT_IN_CLZIMAX:
5869 target = expand_builtin_unop (target_mode, arglist, target,
5870 subtarget, clz_optab);
5875 CASE_INT_FN (BUILT_IN_CTZ):
5876 case BUILT_IN_CTZIMAX:
5877 target = expand_builtin_unop (target_mode, arglist, target,
5878 subtarget, ctz_optab);
5883 CASE_INT_FN (BUILT_IN_POPCOUNT):
5884 case BUILT_IN_POPCOUNTIMAX:
5885 target = expand_builtin_unop (target_mode, arglist, target,
5886 subtarget, popcount_optab);
5891 CASE_INT_FN (BUILT_IN_PARITY):
5892 case BUILT_IN_PARITYIMAX:
5893 target = expand_builtin_unop (target_mode, arglist, target,
5894 subtarget, parity_optab);
5899 case BUILT_IN_STRLEN:
5900 target = expand_builtin_strlen (arglist, target, target_mode);
5905 case BUILT_IN_STRCPY:
5906 target = expand_builtin_strcpy (fndecl, arglist, target, mode);
5911 case BUILT_IN_STRNCPY:
5912 target = expand_builtin_strncpy (exp, target, mode);
5917 case BUILT_IN_STPCPY:
5918 target = expand_builtin_stpcpy (exp, target, mode);
5923 case BUILT_IN_STRCAT:
5924 target = expand_builtin_strcat (fndecl, arglist, target, mode);
5929 case BUILT_IN_STRNCAT:
5930 target = expand_builtin_strncat (arglist, target, mode);
5935 case BUILT_IN_STRSPN:
5936 target = expand_builtin_strspn (arglist, target, mode);
5941 case BUILT_IN_STRCSPN:
5942 target = expand_builtin_strcspn (arglist, target, mode);
5947 case BUILT_IN_STRSTR:
5948 target = expand_builtin_strstr (arglist, TREE_TYPE (exp), target, mode);
5953 case BUILT_IN_STRPBRK:
5954 target = expand_builtin_strpbrk (arglist, TREE_TYPE (exp), target, mode);
5959 case BUILT_IN_INDEX:
5960 case BUILT_IN_STRCHR:
5961 target = expand_builtin_strchr (arglist, TREE_TYPE (exp), target, mode);
5966 case BUILT_IN_RINDEX:
5967 case BUILT_IN_STRRCHR:
5968 target = expand_builtin_strrchr (arglist, TREE_TYPE (exp), target, mode);
5973 case BUILT_IN_MEMCPY:
5974 target = expand_builtin_memcpy (exp, target, mode);
5979 case BUILT_IN_MEMPCPY:
5980 target = expand_builtin_mempcpy (arglist, TREE_TYPE (exp), target, mode, /*endp=*/ 1);
5985 case BUILT_IN_MEMMOVE:
5986 target = expand_builtin_memmove (arglist, TREE_TYPE (exp), target,
5992 case BUILT_IN_BCOPY:
5993 target = expand_builtin_bcopy (exp);
5998 case BUILT_IN_MEMSET:
5999 target = expand_builtin_memset (arglist, target, mode, exp);
6004 case BUILT_IN_BZERO:
6005 target = expand_builtin_bzero (exp);
6010 case BUILT_IN_STRCMP:
6011 target = expand_builtin_strcmp (exp, target, mode);
6016 case BUILT_IN_STRNCMP:
6017 target = expand_builtin_strncmp (exp, target, mode);
6023 case BUILT_IN_MEMCMP:
6024 target = expand_builtin_memcmp (exp, arglist, target, mode);
6029 case BUILT_IN_SETJMP:
6030 target = expand_builtin_setjmp (arglist, target);
6035 /* __builtin_longjmp is passed a pointer to an array of five words.
6036 It's similar to the C library longjmp function but works with
6037 __builtin_setjmp above. */
6038 case BUILT_IN_LONGJMP:
6039 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
6043 rtx buf_addr = expand_expr (TREE_VALUE (arglist), subtarget,
6044 VOIDmode, EXPAND_NORMAL);
6045 rtx value = expand_normal (TREE_VALUE (TREE_CHAIN (arglist)));
6047 if (value != const1_rtx)
6049 error ("%<__builtin_longjmp%> second argument must be 1");
6053 expand_builtin_longjmp (buf_addr, value);
6057 case BUILT_IN_NONLOCAL_GOTO:
6058 target = expand_builtin_nonlocal_goto (arglist);
6063 /* This updates the setjmp buffer that is its argument with the value
6064 of the current stack pointer. */
6065 case BUILT_IN_UPDATE_SETJMP_BUF:
6066 if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6069 = expand_normal (TREE_VALUE (arglist));
6071 expand_builtin_update_setjmp_buf (buf_addr);
6077 expand_builtin_trap ();
6080 case BUILT_IN_PRINTF:
6081 target = expand_builtin_printf (exp, target, mode, false);
6086 case BUILT_IN_PRINTF_UNLOCKED:
6087 target = expand_builtin_printf (exp, target, mode, true);
6092 case BUILT_IN_FPUTS:
6093 target = expand_builtin_fputs (arglist, target, false);
6097 case BUILT_IN_FPUTS_UNLOCKED:
6098 target = expand_builtin_fputs (arglist, target, true);
6103 case BUILT_IN_FPRINTF:
6104 target = expand_builtin_fprintf (exp, target, mode, false);
6109 case BUILT_IN_FPRINTF_UNLOCKED:
6110 target = expand_builtin_fprintf (exp, target, mode, true);
6115 case BUILT_IN_SPRINTF:
6116 target = expand_builtin_sprintf (arglist, target, mode);
6121 CASE_FLT_FN (BUILT_IN_SIGNBIT):
6122 target = expand_builtin_signbit (exp, target);
6127 /* Various hooks for the DWARF 2 __throw routine. */
6128 case BUILT_IN_UNWIND_INIT:
6129 expand_builtin_unwind_init ();
6131 case BUILT_IN_DWARF_CFA:
6132 return virtual_cfa_rtx;
6133 #ifdef DWARF2_UNWIND_INFO
6134 case BUILT_IN_DWARF_SP_COLUMN:
6135 return expand_builtin_dwarf_sp_column ();
6136 case BUILT_IN_INIT_DWARF_REG_SIZES:
6137 expand_builtin_init_dwarf_reg_sizes (TREE_VALUE (arglist));
6140 case BUILT_IN_FROB_RETURN_ADDR:
6141 return expand_builtin_frob_return_addr (TREE_VALUE (arglist));
6142 case BUILT_IN_EXTRACT_RETURN_ADDR:
6143 return expand_builtin_extract_return_addr (TREE_VALUE (arglist));
6144 case BUILT_IN_EH_RETURN:
6145 expand_builtin_eh_return (TREE_VALUE (arglist),
6146 TREE_VALUE (TREE_CHAIN (arglist)));
6148 #ifdef EH_RETURN_DATA_REGNO
6149 case BUILT_IN_EH_RETURN_DATA_REGNO:
6150 return expand_builtin_eh_return_data_regno (arglist);
6152 case BUILT_IN_EXTEND_POINTER:
6153 return expand_builtin_extend_pointer (TREE_VALUE (arglist));
6155 case BUILT_IN_VA_START:
6156 case BUILT_IN_STDARG_START:
6157 return expand_builtin_va_start (arglist);
6158 case BUILT_IN_VA_END:
6159 return expand_builtin_va_end (arglist);
6160 case BUILT_IN_VA_COPY:
6161 return expand_builtin_va_copy (arglist);
6162 case BUILT_IN_EXPECT:
6163 return expand_builtin_expect (arglist, target);
6164 case BUILT_IN_PREFETCH:
6165 expand_builtin_prefetch (arglist);
6168 case BUILT_IN_PROFILE_FUNC_ENTER:
6169 return expand_builtin_profile_func (false);
6170 case BUILT_IN_PROFILE_FUNC_EXIT:
6171 return expand_builtin_profile_func (true);
6173 case BUILT_IN_INIT_TRAMPOLINE:
6174 return expand_builtin_init_trampoline (arglist);
6175 case BUILT_IN_ADJUST_TRAMPOLINE:
6176 return expand_builtin_adjust_trampoline (arglist);
6179 case BUILT_IN_EXECL:
6180 case BUILT_IN_EXECV:
6181 case BUILT_IN_EXECLP:
6182 case BUILT_IN_EXECLE:
6183 case BUILT_IN_EXECVP:
6184 case BUILT_IN_EXECVE:
6185 target = expand_builtin_fork_or_exec (fndecl, arglist, target, ignore);
6190 case BUILT_IN_FETCH_AND_ADD_1:
6191 case BUILT_IN_FETCH_AND_ADD_2:
6192 case BUILT_IN_FETCH_AND_ADD_4:
6193 case BUILT_IN_FETCH_AND_ADD_8:
6194 case BUILT_IN_FETCH_AND_ADD_16:
6195 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_ADD_1);
6196 target = expand_builtin_sync_operation (mode, arglist, PLUS,
6197 false, target, ignore);
6202 case BUILT_IN_FETCH_AND_SUB_1:
6203 case BUILT_IN_FETCH_AND_SUB_2:
6204 case BUILT_IN_FETCH_AND_SUB_4:
6205 case BUILT_IN_FETCH_AND_SUB_8:
6206 case BUILT_IN_FETCH_AND_SUB_16:
6207 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_SUB_1);
6208 target = expand_builtin_sync_operation (mode, arglist, MINUS,
6209 false, target, ignore);
6214 case BUILT_IN_FETCH_AND_OR_1:
6215 case BUILT_IN_FETCH_AND_OR_2:
6216 case BUILT_IN_FETCH_AND_OR_4:
6217 case BUILT_IN_FETCH_AND_OR_8:
6218 case BUILT_IN_FETCH_AND_OR_16:
6219 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_OR_1);
6220 target = expand_builtin_sync_operation (mode, arglist, IOR,
6221 false, target, ignore);
6226 case BUILT_IN_FETCH_AND_AND_1:
6227 case BUILT_IN_FETCH_AND_AND_2:
6228 case BUILT_IN_FETCH_AND_AND_4:
6229 case BUILT_IN_FETCH_AND_AND_8:
6230 case BUILT_IN_FETCH_AND_AND_16:
6231 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_AND_1);
6232 target = expand_builtin_sync_operation (mode, arglist, AND,
6233 false, target, ignore);
6238 case BUILT_IN_FETCH_AND_XOR_1:
6239 case BUILT_IN_FETCH_AND_XOR_2:
6240 case BUILT_IN_FETCH_AND_XOR_4:
6241 case BUILT_IN_FETCH_AND_XOR_8:
6242 case BUILT_IN_FETCH_AND_XOR_16:
6243 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_XOR_1);
6244 target = expand_builtin_sync_operation (mode, arglist, XOR,
6245 false, target, ignore);
6250 case BUILT_IN_FETCH_AND_NAND_1:
6251 case BUILT_IN_FETCH_AND_NAND_2:
6252 case BUILT_IN_FETCH_AND_NAND_4:
6253 case BUILT_IN_FETCH_AND_NAND_8:
6254 case BUILT_IN_FETCH_AND_NAND_16:
6255 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_NAND_1);
6256 target = expand_builtin_sync_operation (mode, arglist, NOT,
6257 false, target, ignore);
6262 case BUILT_IN_ADD_AND_FETCH_1:
6263 case BUILT_IN_ADD_AND_FETCH_2:
6264 case BUILT_IN_ADD_AND_FETCH_4:
6265 case BUILT_IN_ADD_AND_FETCH_8:
6266 case BUILT_IN_ADD_AND_FETCH_16:
6267 mode = get_builtin_sync_mode (fcode - BUILT_IN_ADD_AND_FETCH_1);
6268 target = expand_builtin_sync_operation (mode, arglist, PLUS,
6269 true, target, ignore);
6274 case BUILT_IN_SUB_AND_FETCH_1:
6275 case BUILT_IN_SUB_AND_FETCH_2:
6276 case BUILT_IN_SUB_AND_FETCH_4:
6277 case BUILT_IN_SUB_AND_FETCH_8:
6278 case BUILT_IN_SUB_AND_FETCH_16:
6279 mode = get_builtin_sync_mode (fcode - BUILT_IN_SUB_AND_FETCH_1);
6280 target = expand_builtin_sync_operation (mode, arglist, MINUS,
6281 true, target, ignore);
6286 case BUILT_IN_OR_AND_FETCH_1:
6287 case BUILT_IN_OR_AND_FETCH_2:
6288 case BUILT_IN_OR_AND_FETCH_4:
6289 case BUILT_IN_OR_AND_FETCH_8:
6290 case BUILT_IN_OR_AND_FETCH_16:
6291 mode = get_builtin_sync_mode (fcode - BUILT_IN_OR_AND_FETCH_1);
6292 target = expand_builtin_sync_operation (mode, arglist, IOR,
6293 true, target, ignore);
6298 case BUILT_IN_AND_AND_FETCH_1:
6299 case BUILT_IN_AND_AND_FETCH_2:
6300 case BUILT_IN_AND_AND_FETCH_4:
6301 case BUILT_IN_AND_AND_FETCH_8:
6302 case BUILT_IN_AND_AND_FETCH_16:
6303 mode = get_builtin_sync_mode (fcode - BUILT_IN_AND_AND_FETCH_1);
6304 target = expand_builtin_sync_operation (mode, arglist, AND,
6305 true, target, ignore);
6310 case BUILT_IN_XOR_AND_FETCH_1:
6311 case BUILT_IN_XOR_AND_FETCH_2:
6312 case BUILT_IN_XOR_AND_FETCH_4:
6313 case BUILT_IN_XOR_AND_FETCH_8:
6314 case BUILT_IN_XOR_AND_FETCH_16:
6315 mode = get_builtin_sync_mode (fcode - BUILT_IN_XOR_AND_FETCH_1);
6316 target = expand_builtin_sync_operation (mode, arglist, XOR,
6317 true, target, ignore);
6322 case BUILT_IN_NAND_AND_FETCH_1:
6323 case BUILT_IN_NAND_AND_FETCH_2:
6324 case BUILT_IN_NAND_AND_FETCH_4:
6325 case BUILT_IN_NAND_AND_FETCH_8:
6326 case BUILT_IN_NAND_AND_FETCH_16:
6327 mode = get_builtin_sync_mode (fcode - BUILT_IN_NAND_AND_FETCH_1);
6328 target = expand_builtin_sync_operation (mode, arglist, NOT,
6329 true, target, ignore);
6334 case BUILT_IN_BOOL_COMPARE_AND_SWAP_1:
6335 case BUILT_IN_BOOL_COMPARE_AND_SWAP_2:
6336 case BUILT_IN_BOOL_COMPARE_AND_SWAP_4:
6337 case BUILT_IN_BOOL_COMPARE_AND_SWAP_8:
6338 case BUILT_IN_BOOL_COMPARE_AND_SWAP_16:
6339 if (mode == VOIDmode)
6340 mode = TYPE_MODE (boolean_type_node);
6341 if (!target || !register_operand (target, mode))
6342 target = gen_reg_rtx (mode);
6344 mode = get_builtin_sync_mode (fcode - BUILT_IN_BOOL_COMPARE_AND_SWAP_1);
6345 target = expand_builtin_compare_and_swap (mode, arglist, true, target);
6350 case BUILT_IN_VAL_COMPARE_AND_SWAP_1:
6351 case BUILT_IN_VAL_COMPARE_AND_SWAP_2:
6352 case BUILT_IN_VAL_COMPARE_AND_SWAP_4:
6353 case BUILT_IN_VAL_COMPARE_AND_SWAP_8:
6354 case BUILT_IN_VAL_COMPARE_AND_SWAP_16:
6355 mode = get_builtin_sync_mode (fcode - BUILT_IN_VAL_COMPARE_AND_SWAP_1);
6356 target = expand_builtin_compare_and_swap (mode, arglist, false, target);
6361 case BUILT_IN_LOCK_TEST_AND_SET_1:
6362 case BUILT_IN_LOCK_TEST_AND_SET_2:
6363 case BUILT_IN_LOCK_TEST_AND_SET_4:
6364 case BUILT_IN_LOCK_TEST_AND_SET_8:
6365 case BUILT_IN_LOCK_TEST_AND_SET_16:
6366 mode = get_builtin_sync_mode (fcode - BUILT_IN_LOCK_TEST_AND_SET_1);
6367 target = expand_builtin_lock_test_and_set (mode, arglist, target);
6372 case BUILT_IN_LOCK_RELEASE_1:
6373 case BUILT_IN_LOCK_RELEASE_2:
6374 case BUILT_IN_LOCK_RELEASE_4:
6375 case BUILT_IN_LOCK_RELEASE_8:
6376 case BUILT_IN_LOCK_RELEASE_16:
6377 mode = get_builtin_sync_mode (fcode - BUILT_IN_LOCK_RELEASE_1);
6378 expand_builtin_lock_release (mode, arglist);
6381 case BUILT_IN_SYNCHRONIZE:
6382 expand_builtin_synchronize ();
6385 case BUILT_IN_OBJECT_SIZE:
6386 return expand_builtin_object_size (exp);
6388 case BUILT_IN_MEMCPY_CHK:
6389 case BUILT_IN_MEMPCPY_CHK:
6390 case BUILT_IN_MEMMOVE_CHK:
6391 case BUILT_IN_MEMSET_CHK:
6392 target = expand_builtin_memory_chk (exp, target, mode, fcode);
6397 case BUILT_IN_STRCPY_CHK:
6398 case BUILT_IN_STPCPY_CHK:
6399 case BUILT_IN_STRNCPY_CHK:
6400 case BUILT_IN_STRCAT_CHK:
6401 case BUILT_IN_SNPRINTF_CHK:
6402 case BUILT_IN_VSNPRINTF_CHK:
6403 maybe_emit_chk_warning (exp, fcode);
6406 case BUILT_IN_SPRINTF_CHK:
6407 case BUILT_IN_VSPRINTF_CHK:
6408 maybe_emit_sprintf_chk_warning (exp, fcode);
6411 default: /* just do library call, if unknown builtin */
6415 /* The switch statement above can drop through to cause the function
6416 to be called normally. */
6417 return expand_call (exp, target, ignore);
6420 /* Determine whether a tree node represents a call to a built-in
6421 function. If the tree T is a call to a built-in function with
6422 the right number of arguments of the appropriate types, return
6423 the DECL_FUNCTION_CODE of the call, e.g. BUILT_IN_SQRT.
6424 Otherwise the return value is END_BUILTINS. */
6426 enum built_in_function
6427 builtin_mathfn_code (tree t)
6429 tree fndecl, arglist, parmlist;
6430 tree argtype, parmtype;
6432 if (TREE_CODE (t) != CALL_EXPR
6433 || TREE_CODE (TREE_OPERAND (t, 0)) != ADDR_EXPR)
6434 return END_BUILTINS;
6436 fndecl = get_callee_fndecl (t);
6437 if (fndecl == NULL_TREE
6438 || TREE_CODE (fndecl) != FUNCTION_DECL
6439 || ! DECL_BUILT_IN (fndecl)
6440 || DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
6441 return END_BUILTINS;
6443 arglist = TREE_OPERAND (t, 1);
6444 parmlist = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
6445 for (; parmlist; parmlist = TREE_CHAIN (parmlist))
6447 /* If a function doesn't take a variable number of arguments,
6448 the last element in the list will have type `void'. */
6449 parmtype = TREE_VALUE (parmlist);
6450 if (VOID_TYPE_P (parmtype))
6453 return END_BUILTINS;
6454 return DECL_FUNCTION_CODE (fndecl);
6458 return END_BUILTINS;
6460 argtype = TREE_TYPE (TREE_VALUE (arglist));
6462 if (SCALAR_FLOAT_TYPE_P (parmtype))
6464 if (! SCALAR_FLOAT_TYPE_P (argtype))
6465 return END_BUILTINS;
6467 else if (COMPLEX_FLOAT_TYPE_P (parmtype))
6469 if (! COMPLEX_FLOAT_TYPE_P (argtype))
6470 return END_BUILTINS;
6472 else if (POINTER_TYPE_P (parmtype))
6474 if (! POINTER_TYPE_P (argtype))
6475 return END_BUILTINS;
6477 else if (INTEGRAL_TYPE_P (parmtype))
6479 if (! INTEGRAL_TYPE_P (argtype))
6480 return END_BUILTINS;
6483 return END_BUILTINS;
6485 arglist = TREE_CHAIN (arglist);
6488 /* Variable-length argument list. */
6489 return DECL_FUNCTION_CODE (fndecl);
6492 /* Fold a call to __builtin_constant_p, if we know it will evaluate to a
6493 constant. ARGLIST is the argument list of the call. */
6496 fold_builtin_constant_p (tree arglist)
6501 arglist = TREE_VALUE (arglist);
6503 /* We return 1 for a numeric type that's known to be a constant
6504 value at compile-time or for an aggregate type that's a
6505 literal constant. */
6506 STRIP_NOPS (arglist);
6508 /* If we know this is a constant, emit the constant of one. */
6509 if (CONSTANT_CLASS_P (arglist)
6510 || (TREE_CODE (arglist) == CONSTRUCTOR
6511 && TREE_CONSTANT (arglist)))
6512 return integer_one_node;
6513 if (TREE_CODE (arglist) == ADDR_EXPR)
6515 tree op = TREE_OPERAND (arglist, 0);
6516 if (TREE_CODE (op) == STRING_CST
6517 || (TREE_CODE (op) == ARRAY_REF
6518 && integer_zerop (TREE_OPERAND (op, 1))
6519 && TREE_CODE (TREE_OPERAND (op, 0)) == STRING_CST))
6520 return integer_one_node;
6523 /* If this expression has side effects, show we don't know it to be a
6524 constant. Likewise if it's a pointer or aggregate type since in
6525 those case we only want literals, since those are only optimized
6526 when generating RTL, not later.
6527 And finally, if we are compiling an initializer, not code, we
6528 need to return a definite result now; there's not going to be any
6529 more optimization done. */
6530 if (TREE_SIDE_EFFECTS (arglist)
6531 || AGGREGATE_TYPE_P (TREE_TYPE (arglist))
6532 || POINTER_TYPE_P (TREE_TYPE (arglist))
6534 || folding_initializer)
6535 return integer_zero_node;
6540 /* Fold a call to __builtin_expect, if we expect that a comparison against
6541 the argument will fold to a constant. In practice, this means a true
6542 constant or the address of a non-weak symbol. ARGLIST is the argument
6543 list of the call. */
6546 fold_builtin_expect (tree arglist)
6553 arg = TREE_VALUE (arglist);
6555 /* If the argument isn't invariant, then there's nothing we can do. */
6556 if (!TREE_INVARIANT (arg))
6559 /* If we're looking at an address of a weak decl, then do not fold. */
6562 if (TREE_CODE (inner) == ADDR_EXPR)
6566 inner = TREE_OPERAND (inner, 0);
6568 while (TREE_CODE (inner) == COMPONENT_REF
6569 || TREE_CODE (inner) == ARRAY_REF);
6570 if (DECL_P (inner) && DECL_WEAK (inner))
6574 /* Otherwise, ARG already has the proper type for the return value. */
6578 /* Fold a call to __builtin_classify_type. */
6581 fold_builtin_classify_type (tree arglist)
6584 return build_int_cst (NULL_TREE, no_type_class);
6586 return build_int_cst (NULL_TREE,
6587 type_to_class (TREE_TYPE (TREE_VALUE (arglist))));
6590 /* Fold a call to __builtin_strlen. */
6593 fold_builtin_strlen (tree arglist)
6595 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6599 tree len = c_strlen (TREE_VALUE (arglist), 0);
6603 /* Convert from the internal "sizetype" type to "size_t". */
6605 len = fold_convert (size_type_node, len);
6613 /* Fold a call to __builtin_inf or __builtin_huge_val. */
6616 fold_builtin_inf (tree type, int warn)
6618 REAL_VALUE_TYPE real;
6620 /* __builtin_inff is intended to be usable to define INFINITY on all
6621 targets. If an infinity is not available, INFINITY expands "to a
6622 positive constant of type float that overflows at translation
6623 time", footnote "In this case, using INFINITY will violate the
6624 constraint in 6.4.4 and thus require a diagnostic." (C99 7.12#4).
6625 Thus we pedwarn to ensure this constraint violation is
6627 if (!MODE_HAS_INFINITIES (TYPE_MODE (type)) && warn)
6628 pedwarn ("target format does not support infinity");
6631 return build_real (type, real);
6634 /* Fold a call to __builtin_nan or __builtin_nans. */
6637 fold_builtin_nan (tree arglist, tree type, int quiet)
6639 REAL_VALUE_TYPE real;
6642 if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6644 str = c_getstr (TREE_VALUE (arglist));
6648 if (!real_nan (&real, str, quiet, TYPE_MODE (type)))
6651 return build_real (type, real);
6654 /* Return true if the floating point expression T has an integer value.
6655 We also allow +Inf, -Inf and NaN to be considered integer values. */
6658 integer_valued_real_p (tree t)
6660 switch (TREE_CODE (t))
6667 case NON_LVALUE_EXPR:
6668 return integer_valued_real_p (TREE_OPERAND (t, 0));
6673 return integer_valued_real_p (TREE_OPERAND (t, 1));
6680 return integer_valued_real_p (TREE_OPERAND (t, 0))
6681 && integer_valued_real_p (TREE_OPERAND (t, 1));
6684 return integer_valued_real_p (TREE_OPERAND (t, 1))
6685 && integer_valued_real_p (TREE_OPERAND (t, 2));
6688 if (! TREE_CONSTANT_OVERFLOW (t))
6690 REAL_VALUE_TYPE c, cint;
6692 c = TREE_REAL_CST (t);
6693 real_trunc (&cint, TYPE_MODE (TREE_TYPE (t)), &c);
6694 return real_identical (&c, &cint);
6700 tree type = TREE_TYPE (TREE_OPERAND (t, 0));
6701 if (TREE_CODE (type) == INTEGER_TYPE)
6703 if (TREE_CODE (type) == REAL_TYPE)
6704 return integer_valued_real_p (TREE_OPERAND (t, 0));
6709 switch (builtin_mathfn_code (t))
6711 CASE_FLT_FN (BUILT_IN_CEIL):
6712 CASE_FLT_FN (BUILT_IN_FLOOR):
6713 CASE_FLT_FN (BUILT_IN_NEARBYINT):
6714 CASE_FLT_FN (BUILT_IN_RINT):
6715 CASE_FLT_FN (BUILT_IN_ROUND):
6716 CASE_FLT_FN (BUILT_IN_TRUNC):
6730 /* EXP is assumed to be builtin call where truncation can be propagated
6731 across (for instance floor((double)f) == (double)floorf (f).
6732 Do the transformation. */
6735 fold_trunc_transparent_mathfn (tree fndecl, tree arglist)
6737 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
6740 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6743 arg = TREE_VALUE (arglist);
6744 /* Integer rounding functions are idempotent. */
6745 if (fcode == builtin_mathfn_code (arg))
6748 /* If argument is already integer valued, and we don't need to worry
6749 about setting errno, there's no need to perform rounding. */
6750 if (! flag_errno_math && integer_valued_real_p (arg))
6755 tree arg0 = strip_float_extensions (arg);
6756 tree ftype = TREE_TYPE (TREE_TYPE (fndecl));
6757 tree newtype = TREE_TYPE (arg0);
6760 if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
6761 && (decl = mathfn_built_in (newtype, fcode)))
6764 build_tree_list (NULL_TREE, fold_convert (newtype, arg0));
6765 return fold_convert (ftype,
6766 build_function_call_expr (decl, arglist));
6772 /* EXP is assumed to be builtin call which can narrow the FP type of
6773 the argument, for instance lround((double)f) -> lroundf (f). */
6776 fold_fixed_mathfn (tree fndecl, tree arglist)
6778 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
6781 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6784 arg = TREE_VALUE (arglist);
6786 /* If argument is already integer valued, and we don't need to worry
6787 about setting errno, there's no need to perform rounding. */
6788 if (! flag_errno_math && integer_valued_real_p (arg))
6789 return fold_build1 (FIX_TRUNC_EXPR, TREE_TYPE (TREE_TYPE (fndecl)), arg);
6793 tree ftype = TREE_TYPE (arg);
6794 tree arg0 = strip_float_extensions (arg);
6795 tree newtype = TREE_TYPE (arg0);
6798 if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
6799 && (decl = mathfn_built_in (newtype, fcode)))
6802 build_tree_list (NULL_TREE, fold_convert (newtype, arg0));
6803 return build_function_call_expr (decl, arglist);
6807 /* Canonicalize llround (x) to lround (x) on LP64 targets where
6808 sizeof (long long) == sizeof (long). */
6809 if (TYPE_PRECISION (long_long_integer_type_node)
6810 == TYPE_PRECISION (long_integer_type_node))
6812 tree newfn = NULL_TREE;
6815 CASE_FLT_FN (BUILT_IN_LLCEIL):
6816 newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LCEIL);
6819 CASE_FLT_FN (BUILT_IN_LLFLOOR):
6820 newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LFLOOR);
6823 CASE_FLT_FN (BUILT_IN_LLROUND):
6824 newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LROUND);
6827 CASE_FLT_FN (BUILT_IN_LLRINT):
6828 newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LRINT);
6837 tree newcall = build_function_call_expr (newfn, arglist);
6838 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), newcall);
6845 /* Fold function call to builtin cabs, cabsf or cabsl. ARGLIST
6846 is the argument list, TYPE is the return type and FNDECL is the
6847 original function DECL. Return NULL_TREE if no if no simplification
6851 fold_builtin_cabs (tree arglist, tree type, tree fndecl)
6855 if (!arglist || TREE_CHAIN (arglist))
6858 arg = TREE_VALUE (arglist);
6859 if (TREE_CODE (TREE_TYPE (arg)) != COMPLEX_TYPE
6860 || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) != REAL_TYPE)
6863 /* Evaluate cabs of a constant at compile-time. */
6864 if (flag_unsafe_math_optimizations
6865 && TREE_CODE (arg) == COMPLEX_CST
6866 && TREE_CODE (TREE_REALPART (arg)) == REAL_CST
6867 && TREE_CODE (TREE_IMAGPART (arg)) == REAL_CST
6868 && ! TREE_CONSTANT_OVERFLOW (TREE_REALPART (arg))
6869 && ! TREE_CONSTANT_OVERFLOW (TREE_IMAGPART (arg)))
6871 REAL_VALUE_TYPE r, i;
6873 r = TREE_REAL_CST (TREE_REALPART (arg));
6874 i = TREE_REAL_CST (TREE_IMAGPART (arg));
6876 real_arithmetic (&r, MULT_EXPR, &r, &r);
6877 real_arithmetic (&i, MULT_EXPR, &i, &i);
6878 real_arithmetic (&r, PLUS_EXPR, &r, &i);
6879 if (real_sqrt (&r, TYPE_MODE (type), &r)
6880 || ! flag_trapping_math)
6881 return build_real (type, r);
6884 /* If either part is zero, cabs is fabs of the other. */
6885 if (TREE_CODE (arg) == COMPLEX_EXPR
6886 && real_zerop (TREE_OPERAND (arg, 0)))
6887 return fold_build1 (ABS_EXPR, type, TREE_OPERAND (arg, 1));
6888 if (TREE_CODE (arg) == COMPLEX_EXPR
6889 && real_zerop (TREE_OPERAND (arg, 1)))
6890 return fold_build1 (ABS_EXPR, type, TREE_OPERAND (arg, 0));
6892 /* Optimize cabs(-z) and cabs(conj(z)) as cabs(z). */
6893 if (TREE_CODE (arg) == NEGATE_EXPR
6894 || TREE_CODE (arg) == CONJ_EXPR)
6896 tree arglist = build_tree_list (NULL_TREE, TREE_OPERAND (arg, 0));
6897 return build_function_call_expr (fndecl, arglist);
6900 /* Don't do this when optimizing for size. */
6901 if (flag_unsafe_math_optimizations
6902 && optimize && !optimize_size)
6904 tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
6906 if (sqrtfn != NULL_TREE)
6908 tree rpart, ipart, result, arglist;
6910 arg = builtin_save_expr (arg);
6912 rpart = fold_build1 (REALPART_EXPR, type, arg);
6913 ipart = fold_build1 (IMAGPART_EXPR, type, arg);
6915 rpart = builtin_save_expr (rpart);
6916 ipart = builtin_save_expr (ipart);
6918 result = fold_build2 (PLUS_EXPR, type,
6919 fold_build2 (MULT_EXPR, type,
6921 fold_build2 (MULT_EXPR, type,
6924 arglist = build_tree_list (NULL_TREE, result);
6925 return build_function_call_expr (sqrtfn, arglist);
6932 /* Fold a builtin function call to sqrt, sqrtf, or sqrtl. Return
6933 NULL_TREE if no simplification can be made. */
6936 fold_builtin_sqrt (tree arglist, tree type)
6939 enum built_in_function fcode;
6940 tree arg = TREE_VALUE (arglist);
6942 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6945 /* Optimize sqrt of constant value. */
6946 if (TREE_CODE (arg) == REAL_CST
6947 && ! TREE_CONSTANT_OVERFLOW (arg))
6949 REAL_VALUE_TYPE r, x;
6951 x = TREE_REAL_CST (arg);
6952 if (real_sqrt (&r, TYPE_MODE (type), &x)
6953 || (!flag_trapping_math && !flag_errno_math))
6954 return build_real (type, r);
6957 /* Optimize sqrt(expN(x)) = expN(x*0.5). */
6958 fcode = builtin_mathfn_code (arg);
6959 if (flag_unsafe_math_optimizations && BUILTIN_EXPONENT_P (fcode))
6961 tree expfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
6962 arg = fold_build2 (MULT_EXPR, type,
6963 TREE_VALUE (TREE_OPERAND (arg, 1)),
6964 build_real (type, dconsthalf));
6965 arglist = build_tree_list (NULL_TREE, arg);
6966 return build_function_call_expr (expfn, arglist);
6969 /* Optimize sqrt(Nroot(x)) -> pow(x,1/(2*N)). */
6970 if (flag_unsafe_math_optimizations && BUILTIN_ROOT_P (fcode))
6972 tree powfn = mathfn_built_in (type, BUILT_IN_POW);
6976 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
6978 /* The inner root was either sqrt or cbrt. */
6979 REAL_VALUE_TYPE dconstroot =
6980 BUILTIN_SQRT_P (fcode) ? dconsthalf : dconstthird;
6982 /* Adjust for the outer root. */
6983 SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
6984 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
6985 tree_root = build_real (type, dconstroot);
6986 arglist = tree_cons (NULL_TREE, arg0,
6987 build_tree_list (NULL_TREE, tree_root));
6988 return build_function_call_expr (powfn, arglist);
6992 /* Optimize sqrt(pow(x,y)) = pow(|x|,y*0.5). */
6993 if (flag_unsafe_math_optimizations
6994 && (fcode == BUILT_IN_POW
6995 || fcode == BUILT_IN_POWF
6996 || fcode == BUILT_IN_POWL))
6998 tree powfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
6999 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
7000 tree arg1 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
7002 if (!tree_expr_nonnegative_p (arg0))
7003 arg0 = build1 (ABS_EXPR, type, arg0);
7004 narg1 = fold_build2 (MULT_EXPR, type, arg1,
7005 build_real (type, dconsthalf));
7006 arglist = tree_cons (NULL_TREE, arg0,
7007 build_tree_list (NULL_TREE, narg1));
7008 return build_function_call_expr (powfn, arglist);
7014 /* Fold a builtin function call to cbrt, cbrtf, or cbrtl. Return
7015 NULL_TREE if no simplification can be made. */
7017 fold_builtin_cbrt (tree arglist, tree type)
7019 tree arg = TREE_VALUE (arglist);
7020 const enum built_in_function fcode = builtin_mathfn_code (arg);
7022 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7025 /* Optimize cbrt of constant value. */
7026 if (real_zerop (arg) || real_onep (arg) || real_minus_onep (arg))
7029 if (flag_unsafe_math_optimizations)
7031 /* Optimize cbrt(expN(x)) -> expN(x/3). */
7032 if (BUILTIN_EXPONENT_P (fcode))
7034 tree expfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
7035 const REAL_VALUE_TYPE third_trunc =
7036 real_value_truncate (TYPE_MODE (type), dconstthird);
7037 arg = fold_build2 (MULT_EXPR, type,
7038 TREE_VALUE (TREE_OPERAND (arg, 1)),
7039 build_real (type, third_trunc));
7040 arglist = build_tree_list (NULL_TREE, arg);
7041 return build_function_call_expr (expfn, arglist);
7044 /* Optimize cbrt(sqrt(x)) -> pow(x,1/6). */
7045 if (BUILTIN_SQRT_P (fcode))
7047 tree powfn = mathfn_built_in (type, BUILT_IN_POW);
7051 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
7053 REAL_VALUE_TYPE dconstroot = dconstthird;
7055 SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
7056 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
7057 tree_root = build_real (type, dconstroot);
7058 arglist = tree_cons (NULL_TREE, arg0,
7059 build_tree_list (NULL_TREE, tree_root));
7060 return build_function_call_expr (powfn, arglist);
7064 /* Optimize cbrt(cbrt(x)) -> pow(x,1/9) iff x is nonnegative. */
7065 if (BUILTIN_CBRT_P (fcode))
7067 tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
7068 if (tree_expr_nonnegative_p (arg0))
7070 tree powfn = mathfn_built_in (type, BUILT_IN_POW);
7075 REAL_VALUE_TYPE dconstroot;
7077 real_arithmetic (&dconstroot, MULT_EXPR, &dconstthird, &dconstthird);
7078 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
7079 tree_root = build_real (type, dconstroot);
7080 arglist = tree_cons (NULL_TREE, arg0,
7081 build_tree_list (NULL_TREE, tree_root));
7082 return build_function_call_expr (powfn, arglist);
7087 /* Optimize cbrt(pow(x,y)) -> pow(x,y/3) iff x is nonnegative. */
7088 if (fcode == BUILT_IN_POW || fcode == BUILT_IN_POWF
7089 || fcode == BUILT_IN_POWL)
7091 tree arg00 = TREE_VALUE (TREE_OPERAND (arg, 1));
7092 tree arg01 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
7093 if (tree_expr_nonnegative_p (arg00))
7095 tree powfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
7096 const REAL_VALUE_TYPE dconstroot
7097 = real_value_truncate (TYPE_MODE (type), dconstthird);
7098 tree narg01 = fold_build2 (MULT_EXPR, type, arg01,
7099 build_real (type, dconstroot));
7100 arglist = tree_cons (NULL_TREE, arg00,
7101 build_tree_list (NULL_TREE, narg01));
7102 return build_function_call_expr (powfn, arglist);
7109 /* Fold function call to builtin sin, sinf, or sinl. Return
7110 NULL_TREE if no simplification can be made. */
7112 fold_builtin_sin (tree arglist)
7114 tree arg = TREE_VALUE (arglist);
7116 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7119 /* Optimize sin (0.0) = 0.0. */
7120 if (real_zerop (arg))
7126 /* Fold function call to builtin cos, cosf, or cosl. Return
7127 NULL_TREE if no simplification can be made. */
7129 fold_builtin_cos (tree arglist, tree type, tree fndecl)
7131 tree arg = TREE_VALUE (arglist);
7133 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7136 /* Optimize cos (0.0) = 1.0. */
7137 if (real_zerop (arg))
7138 return build_real (type, dconst1);
7140 /* Optimize cos(-x) into cos (x). */
7141 if (TREE_CODE (arg) == NEGATE_EXPR)
7143 tree args = build_tree_list (NULL_TREE,
7144 TREE_OPERAND (arg, 0));
7145 return build_function_call_expr (fndecl, args);
7151 /* Fold function call to builtin tan, tanf, or tanl. Return
7152 NULL_TREE if no simplification can be made. */
7154 fold_builtin_tan (tree arglist)
7156 enum built_in_function fcode;
7157 tree arg = TREE_VALUE (arglist);
7159 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7162 /* Optimize tan(0.0) = 0.0. */
7163 if (real_zerop (arg))
7166 /* Optimize tan(atan(x)) = x. */
7167 fcode = builtin_mathfn_code (arg);
7168 if (flag_unsafe_math_optimizations
7169 && (fcode == BUILT_IN_ATAN
7170 || fcode == BUILT_IN_ATANF
7171 || fcode == BUILT_IN_ATANL))
7172 return TREE_VALUE (TREE_OPERAND (arg, 1));
7177 /* Fold function call to builtin atan, atanf, or atanl. Return
7178 NULL_TREE if no simplification can be made. */
7181 fold_builtin_atan (tree arglist, tree type)
7184 tree arg = TREE_VALUE (arglist);
7186 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7189 /* Optimize atan(0.0) = 0.0. */
7190 if (real_zerop (arg))
7193 /* Optimize atan(1.0) = pi/4. */
7194 if (real_onep (arg))
7196 REAL_VALUE_TYPE cst;
7198 real_convert (&cst, TYPE_MODE (type), &dconstpi);
7199 SET_REAL_EXP (&cst, REAL_EXP (&cst) - 2);
7200 return build_real (type, cst);
7206 /* Fold function call to builtin trunc, truncf or truncl. Return
7207 NULL_TREE if no simplification can be made. */
7210 fold_builtin_trunc (tree fndecl, tree arglist)
7214 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7217 /* Optimize trunc of constant value. */
7218 arg = TREE_VALUE (arglist);
7219 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7221 REAL_VALUE_TYPE r, x;
7222 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7224 x = TREE_REAL_CST (arg);
7225 real_trunc (&r, TYPE_MODE (type), &x);
7226 return build_real (type, r);
7229 return fold_trunc_transparent_mathfn (fndecl, arglist);
7232 /* Fold function call to builtin floor, floorf or floorl. Return
7233 NULL_TREE if no simplification can be made. */
7236 fold_builtin_floor (tree fndecl, tree arglist)
7240 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7243 /* Optimize floor of constant value. */
7244 arg = TREE_VALUE (arglist);
7245 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7249 x = TREE_REAL_CST (arg);
7250 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7252 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7255 real_floor (&r, TYPE_MODE (type), &x);
7256 return build_real (type, r);
7260 return fold_trunc_transparent_mathfn (fndecl, arglist);
7263 /* Fold function call to builtin ceil, ceilf or ceill. Return
7264 NULL_TREE if no simplification can be made. */
7267 fold_builtin_ceil (tree fndecl, tree arglist)
7271 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7274 /* Optimize ceil of constant value. */
7275 arg = TREE_VALUE (arglist);
7276 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7280 x = TREE_REAL_CST (arg);
7281 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7283 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7286 real_ceil (&r, TYPE_MODE (type), &x);
7287 return build_real (type, r);
7291 return fold_trunc_transparent_mathfn (fndecl, arglist);
7294 /* Fold function call to builtin round, roundf or roundl. Return
7295 NULL_TREE if no simplification can be made. */
7298 fold_builtin_round (tree fndecl, tree arglist)
7302 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7305 /* Optimize round of constant value. */
7306 arg = TREE_VALUE (arglist);
7307 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7311 x = TREE_REAL_CST (arg);
7312 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7314 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7317 real_round (&r, TYPE_MODE (type), &x);
7318 return build_real (type, r);
7322 return fold_trunc_transparent_mathfn (fndecl, arglist);
7325 /* Fold function call to builtin lround, lroundf or lroundl (or the
7326 corresponding long long versions) and other rounding functions.
7327 Return NULL_TREE if no simplification can be made. */
7330 fold_builtin_int_roundingfn (tree fndecl, tree arglist)
7334 if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7337 /* Optimize lround of constant value. */
7338 arg = TREE_VALUE (arglist);
7339 if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7341 const REAL_VALUE_TYPE x = TREE_REAL_CST (arg);
7343 if (! REAL_VALUE_ISNAN (x) && ! REAL_VALUE_ISINF (x))
7345 tree itype = TREE_TYPE (TREE_TYPE (fndecl));
7346 tree ftype = TREE_TYPE (arg), result;
7347 HOST_WIDE_INT hi, lo;
7350 switch (DECL_FUNCTION_CODE (fndecl))
7352 CASE_FLT_FN (BUILT_IN_LFLOOR):
7353 CASE_FLT_FN (BUILT_IN_LLFLOOR):
7354 real_floor (&r, TYPE_MODE (ftype), &x);
7357 CASE_FLT_FN (BUILT_IN_LCEIL):
7358 CASE_FLT_FN (BUILT_IN_LLCEIL):
7359 real_ceil (&r, TYPE_MODE (ftype), &x);
7362 CASE_FLT_FN (BUILT_IN_LROUND):
7363 CASE_FLT_FN (BUILT_IN_LLROUND):
7364 real_round (&r, TYPE_MODE (ftype), &x);
7371 REAL_VALUE_TO_INT (&lo, &hi, r);
7372 result = build_int_cst_wide (NULL_TREE, lo, hi);
7373 if (int_fits_type_p (result, itype))
7374 return fold_convert (itype, result);
7378 return fold_fixed_mathfn (fndecl, arglist);
7381 /* Fold function call to builtin ffs, clz, ctz, popcount and parity
7382 and their long and long long variants (i.e. ffsl and ffsll).
7383 Return NULL_TREE if no simplification can be made. */
7386 fold_builtin_bitop (tree fndecl, tree arglist)
7390 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
7393 /* Optimize for constant argument. */
7394 arg = TREE_VALUE (arglist);
7395 if (TREE_CODE (arg) == INTEGER_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7397 HOST_WIDE_INT hi, width, result;
7398 unsigned HOST_WIDE_INT lo;
7401 type = TREE_TYPE (arg);
7402 width = TYPE_PRECISION (type);
7403 lo = TREE_INT_CST_LOW (arg);
7405 /* Clear all the bits that are beyond the type's precision. */
7406 if (width > HOST_BITS_PER_WIDE_INT)
7408 hi = TREE_INT_CST_HIGH (arg);
7409 if (width < 2 * HOST_BITS_PER_WIDE_INT)
7410 hi &= ~((HOST_WIDE_INT) (-1) >> (width - HOST_BITS_PER_WIDE_INT));
7415 if (width < HOST_BITS_PER_WIDE_INT)
7416 lo &= ~((unsigned HOST_WIDE_INT) (-1) << width);
7419 switch (DECL_FUNCTION_CODE (fndecl))
7421 CASE_INT_FN (BUILT_IN_FFS):
7423 result = exact_log2 (lo & -lo) + 1;
7425 result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi) + 1;
7430 CASE_INT_FN (BUILT_IN_CLZ):
7432 result = width - floor_log2 (hi) - 1 - HOST_BITS_PER_WIDE_INT;
7434 result = width - floor_log2 (lo) - 1;
7435 else if (! CLZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
7439 CASE_INT_FN (BUILT_IN_CTZ):
7441 result = exact_log2 (lo & -lo);
7443 result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi);
7444 else if (! CTZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
7448 CASE_INT_FN (BUILT_IN_POPCOUNT):
7451 result++, lo &= lo - 1;
7453 result++, hi &= hi - 1;
7456 CASE_INT_FN (BUILT_IN_PARITY):
7459 result++, lo &= lo - 1;
7461 result++, hi &= hi - 1;
7469 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), result);
7475 /* Return true if EXPR is the real constant contained in VALUE. */
7478 real_dconstp (tree expr, const REAL_VALUE_TYPE *value)
7482 return ((TREE_CODE (expr) == REAL_CST
7483 && ! TREE_CONSTANT_OVERFLOW (expr)
7484 && REAL_VALUES_EQUAL (TREE_REAL_CST (expr), *value))
7485 || (TREE_CODE (expr) == COMPLEX_CST
7486 && real_dconstp (TREE_REALPART (expr), value)
7487 && real_zerop (TREE_IMAGPART (expr))));
7490 /* A subroutine of fold_builtin to fold the various logarithmic
7491 functions. EXP is the CALL_EXPR of a call to a builtin logN
7492 function. VALUE is the base of the logN function. */
7495 fold_builtin_logarithm (tree fndecl, tree arglist,
7496 const REAL_VALUE_TYPE *value)
7498 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7500 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7501 tree arg = TREE_VALUE (arglist);
7502 const enum built_in_function fcode = builtin_mathfn_code (arg);
7504 /* Optimize logN(1.0) = 0.0. */
7505 if (real_onep (arg))
7506 return build_real (type, dconst0);
7508 /* Optimize logN(N) = 1.0. If N can't be truncated to MODE
7509 exactly, then only do this if flag_unsafe_math_optimizations. */
7510 if (exact_real_truncate (TYPE_MODE (type), value)
7511 || flag_unsafe_math_optimizations)
7513 const REAL_VALUE_TYPE value_truncate =
7514 real_value_truncate (TYPE_MODE (type), *value);
7515 if (real_dconstp (arg, &value_truncate))
7516 return build_real (type, dconst1);
7519 /* Special case, optimize logN(expN(x)) = x. */
7520 if (flag_unsafe_math_optimizations
7521 && ((value == &dconste
7522 && (fcode == BUILT_IN_EXP
7523 || fcode == BUILT_IN_EXPF
7524 || fcode == BUILT_IN_EXPL))
7525 || (value == &dconst2
7526 && (fcode == BUILT_IN_EXP2
7527 || fcode == BUILT_IN_EXP2F
7528 || fcode == BUILT_IN_EXP2L))
7529 || (value == &dconst10 && (BUILTIN_EXP10_P (fcode)))))
7530 return fold_convert (type, TREE_VALUE (TREE_OPERAND (arg, 1)));
7532 /* Optimize logN(func()) for various exponential functions. We
7533 want to determine the value "x" and the power "exponent" in
7534 order to transform logN(x**exponent) into exponent*logN(x). */
7535 if (flag_unsafe_math_optimizations)
7537 tree exponent = 0, x = 0;
7541 CASE_FLT_FN (BUILT_IN_EXP):
7542 /* Prepare to do logN(exp(exponent) -> exponent*logN(e). */
7543 x = build_real (type,
7544 real_value_truncate (TYPE_MODE (type), dconste));
7545 exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
7547 CASE_FLT_FN (BUILT_IN_EXP2):
7548 /* Prepare to do logN(exp2(exponent) -> exponent*logN(2). */
7549 x = build_real (type, dconst2);
7550 exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
7552 CASE_FLT_FN (BUILT_IN_EXP10):
7553 CASE_FLT_FN (BUILT_IN_POW10):
7554 /* Prepare to do logN(exp10(exponent) -> exponent*logN(10). */
7555 x = build_real (type, dconst10);
7556 exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
7558 CASE_FLT_FN (BUILT_IN_SQRT):
7559 /* Prepare to do logN(sqrt(x) -> 0.5*logN(x). */
7560 x = TREE_VALUE (TREE_OPERAND (arg, 1));
7561 exponent = build_real (type, dconsthalf);
7563 CASE_FLT_FN (BUILT_IN_CBRT):
7564 /* Prepare to do logN(cbrt(x) -> (1/3)*logN(x). */
7565 x = TREE_VALUE (TREE_OPERAND (arg, 1));
7566 exponent = build_real (type, real_value_truncate (TYPE_MODE (type),
7569 CASE_FLT_FN (BUILT_IN_POW):
7570 /* Prepare to do logN(pow(x,exponent) -> exponent*logN(x). */
7571 x = TREE_VALUE (TREE_OPERAND (arg, 1));
7572 exponent = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
7578 /* Now perform the optimization. */
7582 arglist = build_tree_list (NULL_TREE, x);
7583 logfn = build_function_call_expr (fndecl, arglist);
7584 return fold_build2 (MULT_EXPR, type, exponent, logfn);
7592 /* Fold a builtin function call to pow, powf, or powl. Return
7593 NULL_TREE if no simplification can be made. */
7595 fold_builtin_pow (tree fndecl, tree arglist, tree type)
7597 tree arg0 = TREE_VALUE (arglist);
7598 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7600 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
7603 /* Optimize pow(1.0,y) = 1.0. */
7604 if (real_onep (arg0))
7605 return omit_one_operand (type, build_real (type, dconst1), arg1);
7607 if (TREE_CODE (arg1) == REAL_CST
7608 && ! TREE_CONSTANT_OVERFLOW (arg1))
7610 REAL_VALUE_TYPE cint;
7614 c = TREE_REAL_CST (arg1);
7616 /* Optimize pow(x,0.0) = 1.0. */
7617 if (REAL_VALUES_EQUAL (c, dconst0))
7618 return omit_one_operand (type, build_real (type, dconst1),
7621 /* Optimize pow(x,1.0) = x. */
7622 if (REAL_VALUES_EQUAL (c, dconst1))
7625 /* Optimize pow(x,-1.0) = 1.0/x. */
7626 if (REAL_VALUES_EQUAL (c, dconstm1))
7627 return fold_build2 (RDIV_EXPR, type,
7628 build_real (type, dconst1), arg0);
7630 /* Optimize pow(x,0.5) = sqrt(x). */
7631 if (flag_unsafe_math_optimizations
7632 && REAL_VALUES_EQUAL (c, dconsthalf))
7634 tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
7636 if (sqrtfn != NULL_TREE)
7638 tree arglist = build_tree_list (NULL_TREE, arg0);
7639 return build_function_call_expr (sqrtfn, arglist);
7643 /* Check for an integer exponent. */
7644 n = real_to_integer (&c);
7645 real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
7646 if (real_identical (&c, &cint))
7648 /* Attempt to evaluate pow at compile-time. */
7649 if (TREE_CODE (arg0) == REAL_CST
7650 && ! TREE_CONSTANT_OVERFLOW (arg0))
7655 x = TREE_REAL_CST (arg0);
7656 inexact = real_powi (&x, TYPE_MODE (type), &x, n);
7657 if (flag_unsafe_math_optimizations || !inexact)
7658 return build_real (type, x);
7661 /* Strip sign ops from even integer powers. */
7662 if ((n & 1) == 0 && flag_unsafe_math_optimizations)
7664 tree narg0 = fold_strip_sign_ops (arg0);
7667 arglist = build_tree_list (NULL_TREE, arg1);
7668 arglist = tree_cons (NULL_TREE, narg0, arglist);
7669 return build_function_call_expr (fndecl, arglist);
7675 if (flag_unsafe_math_optimizations)
7677 const enum built_in_function fcode = builtin_mathfn_code (arg0);
7679 /* Optimize pow(expN(x),y) = expN(x*y). */
7680 if (BUILTIN_EXPONENT_P (fcode))
7682 tree expfn = TREE_OPERAND (TREE_OPERAND (arg0, 0), 0);
7683 tree arg = TREE_VALUE (TREE_OPERAND (arg0, 1));
7684 arg = fold_build2 (MULT_EXPR, type, arg, arg1);
7685 arglist = build_tree_list (NULL_TREE, arg);
7686 return build_function_call_expr (expfn, arglist);
7689 /* Optimize pow(sqrt(x),y) = pow(x,y*0.5). */
7690 if (BUILTIN_SQRT_P (fcode))
7692 tree narg0 = TREE_VALUE (TREE_OPERAND (arg0, 1));
7693 tree narg1 = fold_build2 (MULT_EXPR, type, arg1,
7694 build_real (type, dconsthalf));
7696 arglist = tree_cons (NULL_TREE, narg0,
7697 build_tree_list (NULL_TREE, narg1));
7698 return build_function_call_expr (fndecl, arglist);
7701 /* Optimize pow(cbrt(x),y) = pow(x,y/3) iff x is nonnegative. */
7702 if (BUILTIN_CBRT_P (fcode))
7704 tree arg = TREE_VALUE (TREE_OPERAND (arg0, 1));
7705 if (tree_expr_nonnegative_p (arg))
7707 const REAL_VALUE_TYPE dconstroot
7708 = real_value_truncate (TYPE_MODE (type), dconstthird);
7709 tree narg1 = fold_build2 (MULT_EXPR, type, arg1,
7710 build_real (type, dconstroot));
7711 arglist = tree_cons (NULL_TREE, arg,
7712 build_tree_list (NULL_TREE, narg1));
7713 return build_function_call_expr (fndecl, arglist);
7717 /* Optimize pow(pow(x,y),z) = pow(x,y*z). */
7718 if (fcode == BUILT_IN_POW || fcode == BUILT_IN_POWF
7719 || fcode == BUILT_IN_POWL)
7721 tree arg00 = TREE_VALUE (TREE_OPERAND (arg0, 1));
7722 tree arg01 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg0, 1)));
7723 tree narg1 = fold_build2 (MULT_EXPR, type, arg01, arg1);
7724 arglist = tree_cons (NULL_TREE, arg00,
7725 build_tree_list (NULL_TREE, narg1));
7726 return build_function_call_expr (fndecl, arglist);
7733 /* Fold a builtin function call to powi, powif, or powil. Return
7734 NULL_TREE if no simplification can be made. */
7736 fold_builtin_powi (tree fndecl ATTRIBUTE_UNUSED, tree arglist, tree type)
7738 tree arg0 = TREE_VALUE (arglist);
7739 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7741 if (!validate_arglist (arglist, REAL_TYPE, INTEGER_TYPE, VOID_TYPE))
7744 /* Optimize pow(1.0,y) = 1.0. */
7745 if (real_onep (arg0))
7746 return omit_one_operand (type, build_real (type, dconst1), arg1);
7748 if (host_integerp (arg1, 0))
7750 HOST_WIDE_INT c = TREE_INT_CST_LOW (arg1);
7752 /* Evaluate powi at compile-time. */
7753 if (TREE_CODE (arg0) == REAL_CST
7754 && ! TREE_CONSTANT_OVERFLOW (arg0))
7757 x = TREE_REAL_CST (arg0);
7758 real_powi (&x, TYPE_MODE (type), &x, c);
7759 return build_real (type, x);
7762 /* Optimize pow(x,0) = 1.0. */
7764 return omit_one_operand (type, build_real (type, dconst1),
7767 /* Optimize pow(x,1) = x. */
7771 /* Optimize pow(x,-1) = 1.0/x. */
7773 return fold_build2 (RDIV_EXPR, type,
7774 build_real (type, dconst1), arg0);
7780 /* A subroutine of fold_builtin to fold the various exponent
7781 functions. EXP is the CALL_EXPR of a call to a builtin function.
7782 VALUE is the value which will be raised to a power. */
7785 fold_builtin_exponent (tree fndecl, tree arglist,
7786 const REAL_VALUE_TYPE *value)
7788 if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7790 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7791 tree arg = TREE_VALUE (arglist);
7793 /* Optimize exp*(0.0) = 1.0. */
7794 if (real_zerop (arg))
7795 return build_real (type, dconst1);
7797 /* Optimize expN(1.0) = N. */
7798 if (real_onep (arg))
7800 REAL_VALUE_TYPE cst;
7802 real_convert (&cst, TYPE_MODE (type), value);
7803 return build_real (type, cst);
7806 /* Attempt to evaluate expN(integer) at compile-time. */
7807 if (flag_unsafe_math_optimizations
7808 && TREE_CODE (arg) == REAL_CST
7809 && ! TREE_CONSTANT_OVERFLOW (arg))
7811 REAL_VALUE_TYPE cint;
7815 c = TREE_REAL_CST (arg);
7816 n = real_to_integer (&c);
7817 real_from_integer (&cint, VOIDmode, n,
7819 if (real_identical (&c, &cint))
7823 real_powi (&x, TYPE_MODE (type), value, n);
7824 return build_real (type, x);
7828 /* Optimize expN(logN(x)) = x. */
7829 if (flag_unsafe_math_optimizations)
7831 const enum built_in_function fcode = builtin_mathfn_code (arg);
7833 if ((value == &dconste
7834 && (fcode == BUILT_IN_LOG
7835 || fcode == BUILT_IN_LOGF
7836 || fcode == BUILT_IN_LOGL))
7837 || (value == &dconst2
7838 && (fcode == BUILT_IN_LOG2
7839 || fcode == BUILT_IN_LOG2F
7840 || fcode == BUILT_IN_LOG2L))
7841 || (value == &dconst10
7842 && (fcode == BUILT_IN_LOG10
7843 || fcode == BUILT_IN_LOG10F
7844 || fcode == BUILT_IN_LOG10L)))
7845 return fold_convert (type, TREE_VALUE (TREE_OPERAND (arg, 1)));
7852 /* Fold function call to builtin memcpy. Return
7853 NULL_TREE if no simplification can be made. */
7856 fold_builtin_memcpy (tree fndecl, tree arglist)
7858 tree dest, src, len;
7860 if (!validate_arglist (arglist,
7861 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7864 dest = TREE_VALUE (arglist);
7865 src = TREE_VALUE (TREE_CHAIN (arglist));
7866 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7868 /* If the LEN parameter is zero, return DEST. */
7869 if (integer_zerop (len))
7870 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
7872 /* If SRC and DEST are the same (and not volatile), return DEST. */
7873 if (operand_equal_p (src, dest, 0))
7874 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, len);
7879 /* Fold function call to builtin mempcpy. Return
7880 NULL_TREE if no simplification can be made. */
7883 fold_builtin_mempcpy (tree arglist, tree type, int endp)
7885 if (validate_arglist (arglist,
7886 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7888 tree dest = TREE_VALUE (arglist);
7889 tree src = TREE_VALUE (TREE_CHAIN (arglist));
7890 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7892 /* If the LEN parameter is zero, return DEST. */
7893 if (integer_zerop (len))
7894 return omit_one_operand (type, dest, src);
7896 /* If SRC and DEST are the same (and not volatile), return DEST+LEN. */
7897 if (operand_equal_p (src, dest, 0))
7900 return omit_one_operand (type, dest, len);
7903 len = fold_build2 (MINUS_EXPR, TREE_TYPE (len), len,
7906 len = fold_convert (TREE_TYPE (dest), len);
7907 len = fold_build2 (PLUS_EXPR, TREE_TYPE (dest), dest, len);
7908 return fold_convert (type, len);
7914 /* Fold function call to builtin memmove. Return
7915 NULL_TREE if no simplification can be made. */
7918 fold_builtin_memmove (tree arglist, tree type)
7920 tree dest, src, len;
7922 if (!validate_arglist (arglist,
7923 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7926 dest = TREE_VALUE (arglist);
7927 src = TREE_VALUE (TREE_CHAIN (arglist));
7928 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7930 /* If the LEN parameter is zero, return DEST. */
7931 if (integer_zerop (len))
7932 return omit_one_operand (type, dest, src);
7934 /* If SRC and DEST are the same (and not volatile), return DEST. */
7935 if (operand_equal_p (src, dest, 0))
7936 return omit_one_operand (type, dest, len);
7941 /* Fold function call to builtin strcpy. If LEN is not NULL, it represents
7942 the length of the string to be copied. Return NULL_TREE if no
7943 simplification can be made. */
7946 fold_builtin_strcpy (tree fndecl, tree arglist, tree len)
7950 if (!validate_arglist (arglist,
7951 POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
7954 dest = TREE_VALUE (arglist);
7955 src = TREE_VALUE (TREE_CHAIN (arglist));
7957 /* If SRC and DEST are the same (and not volatile), return DEST. */
7958 if (operand_equal_p (src, dest, 0))
7959 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), dest);
7964 fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
7970 len = c_strlen (src, 1);
7971 if (! len || TREE_SIDE_EFFECTS (len))
7975 len = size_binop (PLUS_EXPR, len, ssize_int (1));
7976 arglist = build_tree_list (NULL_TREE, len);
7977 arglist = tree_cons (NULL_TREE, src, arglist);
7978 arglist = tree_cons (NULL_TREE, dest, arglist);
7979 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)),
7980 build_function_call_expr (fn, arglist));
7983 /* Fold function call to builtin strncpy. If SLEN is not NULL, it represents
7984 the length of the source string. Return NULL_TREE if no simplification
7988 fold_builtin_strncpy (tree fndecl, tree arglist, tree slen)
7990 tree dest, src, len, fn;
7992 if (!validate_arglist (arglist,
7993 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7996 dest = TREE_VALUE (arglist);
7997 src = TREE_VALUE (TREE_CHAIN (arglist));
7998 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8000 /* If the LEN parameter is zero, return DEST. */
8001 if (integer_zerop (len))
8002 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
8004 /* We can't compare slen with len as constants below if len is not a
8006 if (len == 0 || TREE_CODE (len) != INTEGER_CST)
8010 slen = c_strlen (src, 1);
8012 /* Now, we must be passed a constant src ptr parameter. */
8013 if (slen == 0 || TREE_CODE (slen) != INTEGER_CST)
8016 slen = size_binop (PLUS_EXPR, slen, ssize_int (1));
8018 /* We do not support simplification of this case, though we do
8019 support it when expanding trees into RTL. */
8020 /* FIXME: generate a call to __builtin_memset. */
8021 if (tree_int_cst_lt (slen, len))
8024 /* OK transform into builtin memcpy. */
8025 fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
8028 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)),
8029 build_function_call_expr (fn, arglist));
8032 /* Fold function call to builtin memcmp. Return
8033 NULL_TREE if no simplification can be made. */
8036 fold_builtin_memcmp (tree arglist)
8038 tree arg1, arg2, len;
8039 const char *p1, *p2;
8041 if (!validate_arglist (arglist,
8042 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8045 arg1 = TREE_VALUE (arglist);
8046 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
8047 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8049 /* If the LEN parameter is zero, return zero. */
8050 if (integer_zerop (len))
8051 return omit_two_operands (integer_type_node, integer_zero_node,
8054 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
8055 if (operand_equal_p (arg1, arg2, 0))
8056 return omit_one_operand (integer_type_node, integer_zero_node, len);
8058 p1 = c_getstr (arg1);
8059 p2 = c_getstr (arg2);
8061 /* If all arguments are constant, and the value of len is not greater
8062 than the lengths of arg1 and arg2, evaluate at compile-time. */
8063 if (host_integerp (len, 1) && p1 && p2
8064 && compare_tree_int (len, strlen (p1) + 1) <= 0
8065 && compare_tree_int (len, strlen (p2) + 1) <= 0)
8067 const int r = memcmp (p1, p2, tree_low_cst (len, 1));
8070 return integer_one_node;
8072 return integer_minus_one_node;
8074 return integer_zero_node;
8077 /* If len parameter is one, return an expression corresponding to
8078 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
8079 if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
8081 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8082 tree cst_uchar_ptr_node
8083 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8085 tree ind1 = fold_convert (integer_type_node,
8086 build1 (INDIRECT_REF, cst_uchar_node,
8087 fold_convert (cst_uchar_ptr_node,
8089 tree ind2 = fold_convert (integer_type_node,
8090 build1 (INDIRECT_REF, cst_uchar_node,
8091 fold_convert (cst_uchar_ptr_node,
8093 return fold_build2 (MINUS_EXPR, integer_type_node, ind1, ind2);
8099 /* Fold function call to builtin strcmp. Return
8100 NULL_TREE if no simplification can be made. */
8103 fold_builtin_strcmp (tree arglist)
8106 const char *p1, *p2;
8108 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
8111 arg1 = TREE_VALUE (arglist);
8112 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
8114 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
8115 if (operand_equal_p (arg1, arg2, 0))
8116 return integer_zero_node;
8118 p1 = c_getstr (arg1);
8119 p2 = c_getstr (arg2);
8123 const int i = strcmp (p1, p2);
8125 return integer_minus_one_node;
8127 return integer_one_node;
8129 return integer_zero_node;
8132 /* If the second arg is "", return *(const unsigned char*)arg1. */
8133 if (p2 && *p2 == '\0')
8135 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8136 tree cst_uchar_ptr_node
8137 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8139 return fold_convert (integer_type_node,
8140 build1 (INDIRECT_REF, cst_uchar_node,
8141 fold_convert (cst_uchar_ptr_node,
8145 /* If the first arg is "", return -*(const unsigned char*)arg2. */
8146 if (p1 && *p1 == '\0')
8148 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8149 tree cst_uchar_ptr_node
8150 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8152 tree temp = fold_convert (integer_type_node,
8153 build1 (INDIRECT_REF, cst_uchar_node,
8154 fold_convert (cst_uchar_ptr_node,
8156 return fold_build1 (NEGATE_EXPR, integer_type_node, temp);
8162 /* Fold function call to builtin strncmp. Return
8163 NULL_TREE if no simplification can be made. */
8166 fold_builtin_strncmp (tree arglist)
8168 tree arg1, arg2, len;
8169 const char *p1, *p2;
8171 if (!validate_arglist (arglist,
8172 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8175 arg1 = TREE_VALUE (arglist);
8176 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
8177 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8179 /* If the LEN parameter is zero, return zero. */
8180 if (integer_zerop (len))
8181 return omit_two_operands (integer_type_node, integer_zero_node,
8184 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
8185 if (operand_equal_p (arg1, arg2, 0))
8186 return omit_one_operand (integer_type_node, integer_zero_node, len);
8188 p1 = c_getstr (arg1);
8189 p2 = c_getstr (arg2);
8191 if (host_integerp (len, 1) && p1 && p2)
8193 const int i = strncmp (p1, p2, tree_low_cst (len, 1));
8195 return integer_one_node;
8197 return integer_minus_one_node;
8199 return integer_zero_node;
8202 /* If the second arg is "", and the length is greater than zero,
8203 return *(const unsigned char*)arg1. */
8204 if (p2 && *p2 == '\0'
8205 && TREE_CODE (len) == INTEGER_CST
8206 && tree_int_cst_sgn (len) == 1)
8208 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8209 tree cst_uchar_ptr_node
8210 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8212 return fold_convert (integer_type_node,
8213 build1 (INDIRECT_REF, cst_uchar_node,
8214 fold_convert (cst_uchar_ptr_node,
8218 /* If the first arg is "", and the length is greater than zero,
8219 return -*(const unsigned char*)arg2. */
8220 if (p1 && *p1 == '\0'
8221 && TREE_CODE (len) == INTEGER_CST
8222 && tree_int_cst_sgn (len) == 1)
8224 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8225 tree cst_uchar_ptr_node
8226 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8228 tree temp = fold_convert (integer_type_node,
8229 build1 (INDIRECT_REF, cst_uchar_node,
8230 fold_convert (cst_uchar_ptr_node,
8232 return fold_build1 (NEGATE_EXPR, integer_type_node, temp);
8235 /* If len parameter is one, return an expression corresponding to
8236 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
8237 if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
8239 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8240 tree cst_uchar_ptr_node
8241 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8243 tree ind1 = fold_convert (integer_type_node,
8244 build1 (INDIRECT_REF, cst_uchar_node,
8245 fold_convert (cst_uchar_ptr_node,
8247 tree ind2 = fold_convert (integer_type_node,
8248 build1 (INDIRECT_REF, cst_uchar_node,
8249 fold_convert (cst_uchar_ptr_node,
8251 return fold_build2 (MINUS_EXPR, integer_type_node, ind1, ind2);
8257 /* Fold function call to builtin signbit, signbitf or signbitl. Return
8258 NULL_TREE if no simplification can be made. */
8261 fold_builtin_signbit (tree fndecl, tree arglist)
8263 tree type = TREE_TYPE (TREE_TYPE (fndecl));
8266 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8269 arg = TREE_VALUE (arglist);
8271 /* If ARG is a compile-time constant, determine the result. */
8272 if (TREE_CODE (arg) == REAL_CST
8273 && !TREE_CONSTANT_OVERFLOW (arg))
8277 c = TREE_REAL_CST (arg);
8278 temp = REAL_VALUE_NEGATIVE (c) ? integer_one_node : integer_zero_node;
8279 return fold_convert (type, temp);
8282 /* If ARG is non-negative, the result is always zero. */
8283 if (tree_expr_nonnegative_p (arg))
8284 return omit_one_operand (type, integer_zero_node, arg);
8286 /* If ARG's format doesn't have signed zeros, return "arg < 0.0". */
8287 if (!HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg))))
8288 return fold_build2 (LT_EXPR, type, arg,
8289 build_real (TREE_TYPE (arg), dconst0));
8294 /* Fold function call to builtin copysign, copysignf or copysignl.
8295 Return NULL_TREE if no simplification can be made. */
8298 fold_builtin_copysign (tree fndecl, tree arglist, tree type)
8300 tree arg1, arg2, tem;
8302 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
8305 arg1 = TREE_VALUE (arglist);
8306 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
8308 /* copysign(X,X) is X. */
8309 if (operand_equal_p (arg1, arg2, 0))
8310 return fold_convert (type, arg1);
8312 /* If ARG1 and ARG2 are compile-time constants, determine the result. */
8313 if (TREE_CODE (arg1) == REAL_CST
8314 && TREE_CODE (arg2) == REAL_CST
8315 && !TREE_CONSTANT_OVERFLOW (arg1)
8316 && !TREE_CONSTANT_OVERFLOW (arg2))
8318 REAL_VALUE_TYPE c1, c2;
8320 c1 = TREE_REAL_CST (arg1);
8321 c2 = TREE_REAL_CST (arg2);
8322 /* c1.sign := c2.sign. */
8323 real_copysign (&c1, &c2);
8324 return build_real (type, c1);
8327 /* copysign(X, Y) is fabs(X) when Y is always non-negative.
8328 Remember to evaluate Y for side-effects. */
8329 if (tree_expr_nonnegative_p (arg2))
8330 return omit_one_operand (type,
8331 fold_build1 (ABS_EXPR, type, arg1),
8334 /* Strip sign changing operations for the first argument. */
8335 tem = fold_strip_sign_ops (arg1);
8338 arglist = tree_cons (NULL_TREE, tem, TREE_CHAIN (arglist));
8339 return build_function_call_expr (fndecl, arglist);
8345 /* Fold a call to builtin isascii. */
8348 fold_builtin_isascii (tree arglist)
8350 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8354 /* Transform isascii(c) -> ((c & ~0x7f) == 0). */
8355 tree arg = TREE_VALUE (arglist);
8357 arg = build2 (BIT_AND_EXPR, integer_type_node, arg,
8358 build_int_cst (NULL_TREE,
8359 ~ (unsigned HOST_WIDE_INT) 0x7f));
8360 arg = fold_build2 (EQ_EXPR, integer_type_node,
8361 arg, integer_zero_node);
8363 if (in_gimple_form && !TREE_CONSTANT (arg))
8370 /* Fold a call to builtin toascii. */
8373 fold_builtin_toascii (tree arglist)
8375 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8379 /* Transform toascii(c) -> (c & 0x7f). */
8380 tree arg = TREE_VALUE (arglist);
8382 return fold_build2 (BIT_AND_EXPR, integer_type_node, arg,
8383 build_int_cst (NULL_TREE, 0x7f));
8387 /* Fold a call to builtin isdigit. */
8390 fold_builtin_isdigit (tree arglist)
8392 if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8396 /* Transform isdigit(c) -> (unsigned)(c) - '0' <= 9. */
8397 /* According to the C standard, isdigit is unaffected by locale.
8398 However, it definitely is affected by the target character set. */
8400 unsigned HOST_WIDE_INT target_digit0
8401 = lang_hooks.to_target_charset ('0');
8403 if (target_digit0 == 0)
8406 arg = fold_convert (unsigned_type_node, TREE_VALUE (arglist));
8407 arg = build2 (MINUS_EXPR, unsigned_type_node, arg,
8408 build_int_cst (unsigned_type_node, target_digit0));
8409 arg = fold_build2 (LE_EXPR, integer_type_node, arg,
8410 build_int_cst (unsigned_type_node, 9));
8411 if (in_gimple_form && !TREE_CONSTANT (arg))
8418 /* Fold a call to fabs, fabsf or fabsl. */
8421 fold_builtin_fabs (tree arglist, tree type)
8425 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8428 arg = TREE_VALUE (arglist);
8429 arg = fold_convert (type, arg);
8430 if (TREE_CODE (arg) == REAL_CST)
8431 return fold_abs_const (arg, type);
8432 return fold_build1 (ABS_EXPR, type, arg);
8435 /* Fold a call to abs, labs, llabs or imaxabs. */
8438 fold_builtin_abs (tree arglist, tree type)
8442 if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8445 arg = TREE_VALUE (arglist);
8446 arg = fold_convert (type, arg);
8447 if (TREE_CODE (arg) == INTEGER_CST)
8448 return fold_abs_const (arg, type);
8449 return fold_build1 (ABS_EXPR, type, arg);
8452 /* Fold a call to __builtin_isnan(), __builtin_isinf, __builtin_finite.
8453 EXP is the CALL_EXPR for the call. */
8456 fold_builtin_classify (tree fndecl, tree arglist, int builtin_index)
8458 tree type = TREE_TYPE (TREE_TYPE (fndecl));
8462 if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8464 /* Check that we have exactly one argument. */
8467 error ("too few arguments to function %qs",
8468 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8469 return error_mark_node;
8471 else if (TREE_CHAIN (arglist) != 0)
8473 error ("too many arguments to function %qs",
8474 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8475 return error_mark_node;
8479 error ("non-floating-point argument to function %qs",
8480 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8481 return error_mark_node;
8485 arg = TREE_VALUE (arglist);
8486 switch (builtin_index)
8488 case BUILT_IN_ISINF:
8489 if (!MODE_HAS_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
8490 return omit_one_operand (type, integer_zero_node, arg);
8492 if (TREE_CODE (arg) == REAL_CST)
8494 r = TREE_REAL_CST (arg);
8495 if (real_isinf (&r))
8496 return real_compare (GT_EXPR, &r, &dconst0)
8497 ? integer_one_node : integer_minus_one_node;
8499 return integer_zero_node;
8504 case BUILT_IN_FINITE:
8505 if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg)))
8506 && !MODE_HAS_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
8507 return omit_one_operand (type, integer_zero_node, arg);
8509 if (TREE_CODE (arg) == REAL_CST)
8511 r = TREE_REAL_CST (arg);
8512 return real_isinf (&r) || real_isnan (&r)
8513 ? integer_zero_node : integer_one_node;
8518 case BUILT_IN_ISNAN:
8519 if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg))))
8520 return omit_one_operand (type, integer_zero_node, arg);
8522 if (TREE_CODE (arg) == REAL_CST)
8524 r = TREE_REAL_CST (arg);
8525 return real_isnan (&r) ? integer_one_node : integer_zero_node;
8528 arg = builtin_save_expr (arg);
8529 return fold_build2 (UNORDERED_EXPR, type, arg, arg);
8536 /* Fold a call to an unordered comparison function such as
8537 __builtin_isgreater(). FNDECL is the FUNCTION_DECL for the function
8538 being called and ARGLIST is the argument list for the call.
8539 UNORDERED_CODE and ORDERED_CODE are comparison codes that give
8540 the opposite of the desired result. UNORDERED_CODE is used
8541 for modes that can hold NaNs and ORDERED_CODE is used for
8545 fold_builtin_unordered_cmp (tree fndecl, tree arglist,
8546 enum tree_code unordered_code,
8547 enum tree_code ordered_code)
8549 tree type = TREE_TYPE (TREE_TYPE (fndecl));
8550 enum tree_code code;
8553 enum tree_code code0, code1;
8554 tree cmp_type = NULL_TREE;
8556 if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
8558 /* Check that we have exactly two arguments. */
8559 if (arglist == 0 || TREE_CHAIN (arglist) == 0)
8561 error ("too few arguments to function %qs",
8562 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8563 return error_mark_node;
8565 else if (TREE_CHAIN (TREE_CHAIN (arglist)) != 0)
8567 error ("too many arguments to function %qs",
8568 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8569 return error_mark_node;
8573 arg0 = TREE_VALUE (arglist);
8574 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
8576 type0 = TREE_TYPE (arg0);
8577 type1 = TREE_TYPE (arg1);
8579 code0 = TREE_CODE (type0);
8580 code1 = TREE_CODE (type1);
8582 if (code0 == REAL_TYPE && code1 == REAL_TYPE)
8583 /* Choose the wider of two real types. */
8584 cmp_type = TYPE_PRECISION (type0) >= TYPE_PRECISION (type1)
8586 else if (code0 == REAL_TYPE && code1 == INTEGER_TYPE)
8588 else if (code0 == INTEGER_TYPE && code1 == REAL_TYPE)
8592 error ("non-floating-point argument to function %qs",
8593 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8594 return error_mark_node;
8597 arg0 = fold_convert (cmp_type, arg0);
8598 arg1 = fold_convert (cmp_type, arg1);
8600 if (unordered_code == UNORDERED_EXPR)
8602 if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg0))))
8603 return omit_two_operands (type, integer_zero_node, arg0, arg1);
8604 return fold_build2 (UNORDERED_EXPR, type, arg0, arg1);
8607 code = MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg0))) ? unordered_code
8609 return fold_build1 (TRUTH_NOT_EXPR, type,
8610 fold_build2 (code, type, arg0, arg1));
8613 /* Used by constant folding to simplify calls to builtin functions. EXP is
8614 the CALL_EXPR of a call to a builtin function. IGNORE is true if the
8615 result of the function call is ignored. This function returns NULL_TREE
8616 if no simplification was possible. */
8619 fold_builtin_1 (tree fndecl, tree arglist, bool ignore)
8621 tree type = TREE_TYPE (TREE_TYPE (fndecl));
8622 enum built_in_function fcode;
8624 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
8625 return targetm.fold_builtin (fndecl, arglist, ignore);
8627 fcode = DECL_FUNCTION_CODE (fndecl);
8630 case BUILT_IN_FPUTS:
8631 return fold_builtin_fputs (arglist, ignore, false, NULL_TREE);
8633 case BUILT_IN_FPUTS_UNLOCKED:
8634 return fold_builtin_fputs (arglist, ignore, true, NULL_TREE);
8636 case BUILT_IN_STRSTR:
8637 return fold_builtin_strstr (arglist, type);
8639 case BUILT_IN_STRCAT:
8640 return fold_builtin_strcat (arglist);
8642 case BUILT_IN_STRNCAT:
8643 return fold_builtin_strncat (arglist);
8645 case BUILT_IN_STRSPN:
8646 return fold_builtin_strspn (arglist);
8648 case BUILT_IN_STRCSPN:
8649 return fold_builtin_strcspn (arglist);
8651 case BUILT_IN_STRCHR:
8652 case BUILT_IN_INDEX:
8653 return fold_builtin_strchr (arglist, type);
8655 case BUILT_IN_STRRCHR:
8656 case BUILT_IN_RINDEX:
8657 return fold_builtin_strrchr (arglist, type);
8659 case BUILT_IN_STRCPY:
8660 return fold_builtin_strcpy (fndecl, arglist, NULL_TREE);
8662 case BUILT_IN_STRNCPY:
8663 return fold_builtin_strncpy (fndecl, arglist, NULL_TREE);
8665 case BUILT_IN_STRCMP:
8666 return fold_builtin_strcmp (arglist);
8668 case BUILT_IN_STRNCMP:
8669 return fold_builtin_strncmp (arglist);
8671 case BUILT_IN_STRPBRK:
8672 return fold_builtin_strpbrk (arglist, type);
8675 case BUILT_IN_MEMCMP:
8676 return fold_builtin_memcmp (arglist);
8678 case BUILT_IN_SPRINTF:
8679 return fold_builtin_sprintf (arglist, ignore);
8681 case BUILT_IN_CONSTANT_P:
8685 val = fold_builtin_constant_p (arglist);
8686 /* Gimplification will pull the CALL_EXPR for the builtin out of
8687 an if condition. When not optimizing, we'll not CSE it back.
8688 To avoid link error types of regressions, return false now. */
8689 if (!val && !optimize)
8690 val = integer_zero_node;
8695 case BUILT_IN_EXPECT:
8696 return fold_builtin_expect (arglist);
8698 case BUILT_IN_CLASSIFY_TYPE:
8699 return fold_builtin_classify_type (arglist);
8701 case BUILT_IN_STRLEN:
8702 return fold_builtin_strlen (arglist);
8704 CASE_FLT_FN (BUILT_IN_FABS):
8705 return fold_builtin_fabs (arglist, type);
8709 case BUILT_IN_LLABS:
8710 case BUILT_IN_IMAXABS:
8711 return fold_builtin_abs (arglist, type);
8713 CASE_FLT_FN (BUILT_IN_CONJ):
8714 if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
8715 return fold_build1 (CONJ_EXPR, type, TREE_VALUE (arglist));
8718 CASE_FLT_FN (BUILT_IN_CREAL):
8719 if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
8720 return non_lvalue (fold_build1 (REALPART_EXPR, type,
8721 TREE_VALUE (arglist)));
8724 CASE_FLT_FN (BUILT_IN_CIMAG):
8725 if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
8726 return non_lvalue (fold_build1 (IMAGPART_EXPR, type,
8727 TREE_VALUE (arglist)));
8730 CASE_FLT_FN (BUILT_IN_CABS):
8731 return fold_builtin_cabs (arglist, type, fndecl);
8733 CASE_FLT_FN (BUILT_IN_SQRT):
8734 return fold_builtin_sqrt (arglist, type);
8736 CASE_FLT_FN (BUILT_IN_CBRT):
8737 return fold_builtin_cbrt (arglist, type);
8739 CASE_FLT_FN (BUILT_IN_SIN):
8740 return fold_builtin_sin (arglist);
8742 CASE_FLT_FN (BUILT_IN_COS):
8743 return fold_builtin_cos (arglist, type, fndecl);
8745 CASE_FLT_FN (BUILT_IN_EXP):
8746 return fold_builtin_exponent (fndecl, arglist, &dconste);
8748 CASE_FLT_FN (BUILT_IN_EXP2):
8749 return fold_builtin_exponent (fndecl, arglist, &dconst2);
8751 CASE_FLT_FN (BUILT_IN_EXP10):
8752 CASE_FLT_FN (BUILT_IN_POW10):
8753 return fold_builtin_exponent (fndecl, arglist, &dconst10);
8755 CASE_FLT_FN (BUILT_IN_LOG):
8756 return fold_builtin_logarithm (fndecl, arglist, &dconste);
8758 CASE_FLT_FN (BUILT_IN_LOG2):
8759 return fold_builtin_logarithm (fndecl, arglist, &dconst2);
8761 CASE_FLT_FN (BUILT_IN_LOG10):
8762 return fold_builtin_logarithm (fndecl, arglist, &dconst10);
8764 CASE_FLT_FN (BUILT_IN_TAN):
8765 return fold_builtin_tan (arglist);
8767 CASE_FLT_FN (BUILT_IN_ATAN):
8768 return fold_builtin_atan (arglist, type);
8770 CASE_FLT_FN (BUILT_IN_POW):
8771 return fold_builtin_pow (fndecl, arglist, type);
8773 CASE_FLT_FN (BUILT_IN_POWI):
8774 return fold_builtin_powi (fndecl, arglist, type);
8776 CASE_FLT_FN (BUILT_IN_INF):
8777 case BUILT_IN_INFD32:
8778 case BUILT_IN_INFD64:
8779 case BUILT_IN_INFD128:
8780 return fold_builtin_inf (type, true);
8782 CASE_FLT_FN (BUILT_IN_HUGE_VAL):
8783 return fold_builtin_inf (type, false);
8785 CASE_FLT_FN (BUILT_IN_NAN):
8786 case BUILT_IN_NAND32:
8787 case BUILT_IN_NAND64:
8788 case BUILT_IN_NAND128:
8789 return fold_builtin_nan (arglist, type, true);
8791 CASE_FLT_FN (BUILT_IN_NANS):
8792 return fold_builtin_nan (arglist, type, false);
8794 CASE_FLT_FN (BUILT_IN_FLOOR):
8795 return fold_builtin_floor (fndecl, arglist);
8797 CASE_FLT_FN (BUILT_IN_CEIL):
8798 return fold_builtin_ceil (fndecl, arglist);
8800 CASE_FLT_FN (BUILT_IN_TRUNC):
8801 return fold_builtin_trunc (fndecl, arglist);
8803 CASE_FLT_FN (BUILT_IN_ROUND):
8804 return fold_builtin_round (fndecl, arglist);
8806 CASE_FLT_FN (BUILT_IN_NEARBYINT):
8807 CASE_FLT_FN (BUILT_IN_RINT):
8808 return fold_trunc_transparent_mathfn (fndecl, arglist);
8810 CASE_FLT_FN (BUILT_IN_LCEIL):
8811 CASE_FLT_FN (BUILT_IN_LLCEIL):
8812 CASE_FLT_FN (BUILT_IN_LFLOOR):
8813 CASE_FLT_FN (BUILT_IN_LLFLOOR):
8814 CASE_FLT_FN (BUILT_IN_LROUND):
8815 CASE_FLT_FN (BUILT_IN_LLROUND):
8816 return fold_builtin_int_roundingfn (fndecl, arglist);
8818 CASE_FLT_FN (BUILT_IN_LRINT):
8819 CASE_FLT_FN (BUILT_IN_LLRINT):
8820 return fold_fixed_mathfn (fndecl, arglist);
8822 CASE_INT_FN (BUILT_IN_FFS):
8823 CASE_INT_FN (BUILT_IN_CLZ):
8824 CASE_INT_FN (BUILT_IN_CTZ):
8825 CASE_INT_FN (BUILT_IN_POPCOUNT):
8826 CASE_INT_FN (BUILT_IN_PARITY):
8827 return fold_builtin_bitop (fndecl, arglist);
8829 case BUILT_IN_MEMCPY:
8830 return fold_builtin_memcpy (fndecl, arglist);
8832 case BUILT_IN_MEMPCPY:
8833 return fold_builtin_mempcpy (arglist, type, /*endp=*/1);
8835 case BUILT_IN_MEMMOVE:
8836 return fold_builtin_memmove (arglist, type);
8838 CASE_FLT_FN (BUILT_IN_SIGNBIT):
8839 return fold_builtin_signbit (fndecl, arglist);
8841 case BUILT_IN_ISASCII:
8842 return fold_builtin_isascii (arglist);
8844 case BUILT_IN_TOASCII:
8845 return fold_builtin_toascii (arglist);
8847 case BUILT_IN_ISDIGIT:
8848 return fold_builtin_isdigit (arglist);
8850 CASE_FLT_FN (BUILT_IN_COPYSIGN):
8851 return fold_builtin_copysign (fndecl, arglist, type);
8853 CASE_FLT_FN (BUILT_IN_FINITE):
8854 case BUILT_IN_FINITED32:
8855 case BUILT_IN_FINITED64:
8856 case BUILT_IN_FINITED128:
8857 return fold_builtin_classify (fndecl, arglist, BUILT_IN_FINITE);
8859 CASE_FLT_FN (BUILT_IN_ISINF):
8860 case BUILT_IN_ISINFD32:
8861 case BUILT_IN_ISINFD64:
8862 case BUILT_IN_ISINFD128:
8863 return fold_builtin_classify (fndecl, arglist, BUILT_IN_ISINF);
8865 CASE_FLT_FN (BUILT_IN_ISNAN):
8866 case BUILT_IN_ISNAND32:
8867 case BUILT_IN_ISNAND64:
8868 case BUILT_IN_ISNAND128:
8869 return fold_builtin_classify (fndecl, arglist, BUILT_IN_ISNAN);
8871 case BUILT_IN_ISGREATER:
8872 return fold_builtin_unordered_cmp (fndecl, arglist, UNLE_EXPR, LE_EXPR);
8873 case BUILT_IN_ISGREATEREQUAL:
8874 return fold_builtin_unordered_cmp (fndecl, arglist, UNLT_EXPR, LT_EXPR);
8875 case BUILT_IN_ISLESS:
8876 return fold_builtin_unordered_cmp (fndecl, arglist, UNGE_EXPR, GE_EXPR);
8877 case BUILT_IN_ISLESSEQUAL:
8878 return fold_builtin_unordered_cmp (fndecl, arglist, UNGT_EXPR, GT_EXPR);
8879 case BUILT_IN_ISLESSGREATER:
8880 return fold_builtin_unordered_cmp (fndecl, arglist, UNEQ_EXPR, EQ_EXPR);
8881 case BUILT_IN_ISUNORDERED:
8882 return fold_builtin_unordered_cmp (fndecl, arglist, UNORDERED_EXPR,
8885 /* We do the folding for va_start in the expander. */
8886 case BUILT_IN_VA_START:
8889 case BUILT_IN_OBJECT_SIZE:
8890 return fold_builtin_object_size (arglist);
8891 case BUILT_IN_MEMCPY_CHK:
8892 case BUILT_IN_MEMPCPY_CHK:
8893 case BUILT_IN_MEMMOVE_CHK:
8894 case BUILT_IN_MEMSET_CHK:
8895 return fold_builtin_memory_chk (fndecl, arglist, NULL_TREE, ignore,
8896 DECL_FUNCTION_CODE (fndecl));
8897 case BUILT_IN_STRCPY_CHK:
8898 case BUILT_IN_STPCPY_CHK:
8899 return fold_builtin_stxcpy_chk (fndecl, arglist, NULL_TREE, ignore,
8900 DECL_FUNCTION_CODE (fndecl));
8901 case BUILT_IN_STRNCPY_CHK:
8902 return fold_builtin_strncpy_chk (arglist, NULL_TREE);
8903 case BUILT_IN_STRCAT_CHK:
8904 return fold_builtin_strcat_chk (fndecl, arglist);
8905 case BUILT_IN_STRNCAT_CHK:
8906 return fold_builtin_strncat_chk (fndecl, arglist);
8907 case BUILT_IN_SPRINTF_CHK:
8908 case BUILT_IN_VSPRINTF_CHK:
8909 return fold_builtin_sprintf_chk (arglist, DECL_FUNCTION_CODE (fndecl));
8910 case BUILT_IN_SNPRINTF_CHK:
8911 case BUILT_IN_VSNPRINTF_CHK:
8912 return fold_builtin_snprintf_chk (arglist, NULL_TREE,
8913 DECL_FUNCTION_CODE (fndecl));
8915 case BUILT_IN_PRINTF:
8916 case BUILT_IN_PRINTF_UNLOCKED:
8917 case BUILT_IN_VPRINTF:
8918 case BUILT_IN_PRINTF_CHK:
8919 case BUILT_IN_VPRINTF_CHK:
8920 return fold_builtin_printf (fndecl, arglist, ignore,
8921 DECL_FUNCTION_CODE (fndecl));
8923 case BUILT_IN_FPRINTF:
8924 case BUILT_IN_FPRINTF_UNLOCKED:
8925 case BUILT_IN_VFPRINTF:
8926 case BUILT_IN_FPRINTF_CHK:
8927 case BUILT_IN_VFPRINTF_CHK:
8928 return fold_builtin_fprintf (fndecl, arglist, ignore,
8929 DECL_FUNCTION_CODE (fndecl));
8938 /* A wrapper function for builtin folding that prevents warnings for
8939 "statement without effect" and the like, caused by removing the
8940 call node earlier than the warning is generated. */
8943 fold_builtin (tree fndecl, tree arglist, bool ignore)
8945 tree exp = fold_builtin_1 (fndecl, arglist, ignore);
8948 exp = build1 (NOP_EXPR, TREE_TYPE (exp), exp);
8949 TREE_NO_WARNING (exp) = 1;
8955 /* Conveniently construct a function call expression. */
8958 build_function_call_expr (tree fn, tree arglist)
8962 call_expr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
8963 return fold_build3 (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)),
8964 call_expr, arglist, NULL_TREE);
8967 /* This function validates the types of a function call argument list
8968 represented as a tree chain of parameters against a specified list
8969 of tree_codes. If the last specifier is a 0, that represents an
8970 ellipses, otherwise the last specifier must be a VOID_TYPE. */
8973 validate_arglist (tree arglist, ...)
8975 enum tree_code code;
8979 va_start (ap, arglist);
8983 code = va_arg (ap, enum tree_code);
8987 /* This signifies an ellipses, any further arguments are all ok. */
8991 /* This signifies an endlink, if no arguments remain, return
8992 true, otherwise return false. */
8996 /* If no parameters remain or the parameter's code does not
8997 match the specified code, return false. Otherwise continue
8998 checking any remaining arguments. */
9001 if (code == POINTER_TYPE)
9003 if (! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist))))
9006 else if (code != TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))))
9010 arglist = TREE_CHAIN (arglist);
9014 /* We need gotos here since we can only have one VA_CLOSE in a
9022 /* Default target-specific builtin expander that does nothing. */
9025 default_expand_builtin (tree exp ATTRIBUTE_UNUSED,
9026 rtx target ATTRIBUTE_UNUSED,
9027 rtx subtarget ATTRIBUTE_UNUSED,
9028 enum machine_mode mode ATTRIBUTE_UNUSED,
9029 int ignore ATTRIBUTE_UNUSED)
9034 /* Returns true is EXP represents data that would potentially reside
9035 in a readonly section. */
9038 readonly_data_expr (tree exp)
9042 if (TREE_CODE (exp) != ADDR_EXPR)
9045 exp = get_base_address (TREE_OPERAND (exp, 0));
9049 /* Make sure we call decl_readonly_section only for trees it
9050 can handle (since it returns true for everything it doesn't
9052 if (TREE_CODE (exp) == STRING_CST
9053 || TREE_CODE (exp) == CONSTRUCTOR
9054 || (TREE_CODE (exp) == VAR_DECL && TREE_STATIC (exp)))
9055 return decl_readonly_section (exp, 0);
9060 /* Simplify a call to the strstr builtin.
9062 Return 0 if no simplification was possible, otherwise return the
9063 simplified form of the call as a tree.
9065 The simplified form may be a constant or other expression which
9066 computes the same value, but in a more efficient manner (including
9067 calls to other builtin functions).
9069 The call may contain arguments which need to be evaluated, but
9070 which are not useful to determine the result of the call. In
9071 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9072 COMPOUND_EXPR will be an argument which must be evaluated.
9073 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9074 COMPOUND_EXPR in the chain will contain the tree for the simplified
9075 form of the builtin function call. */
9078 fold_builtin_strstr (tree arglist, tree type)
9080 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9084 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9086 const char *p1, *p2;
9095 const char *r = strstr (p1, p2);
9099 return build_int_cst (TREE_TYPE (s1), 0);
9101 /* Return an offset into the constant string argument. */
9102 tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
9103 s1, build_int_cst (TREE_TYPE (s1), r - p1));
9104 return fold_convert (type, tem);
9107 /* The argument is const char *, and the result is char *, so we need
9108 a type conversion here to avoid a warning. */
9110 return fold_convert (type, s1);
9115 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
9119 /* New argument list transforming strstr(s1, s2) to
9120 strchr(s1, s2[0]). */
9121 arglist = build_tree_list (NULL_TREE,
9122 build_int_cst (NULL_TREE, p2[0]));
9123 arglist = tree_cons (NULL_TREE, s1, arglist);
9124 return build_function_call_expr (fn, arglist);
9128 /* Simplify a call to the strchr builtin.
9130 Return 0 if no simplification was possible, otherwise return the
9131 simplified form of the call as a tree.
9133 The simplified form may be a constant or other expression which
9134 computes the same value, but in a more efficient manner (including
9135 calls to other builtin functions).
9137 The call may contain arguments which need to be evaluated, but
9138 which are not useful to determine the result of the call. In
9139 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9140 COMPOUND_EXPR will be an argument which must be evaluated.
9141 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9142 COMPOUND_EXPR in the chain will contain the tree for the simplified
9143 form of the builtin function call. */
9146 fold_builtin_strchr (tree arglist, tree type)
9148 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9152 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9155 if (TREE_CODE (s2) != INTEGER_CST)
9165 if (target_char_cast (s2, &c))
9171 return build_int_cst (TREE_TYPE (s1), 0);
9173 /* Return an offset into the constant string argument. */
9174 tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
9175 s1, build_int_cst (TREE_TYPE (s1), r - p1));
9176 return fold_convert (type, tem);
9182 /* Simplify a call to the strrchr builtin.
9184 Return 0 if no simplification was possible, otherwise return the
9185 simplified form of the call as a tree.
9187 The simplified form may be a constant or other expression which
9188 computes the same value, but in a more efficient manner (including
9189 calls to other builtin functions).
9191 The call may contain arguments which need to be evaluated, but
9192 which are not useful to determine the result of the call. In
9193 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9194 COMPOUND_EXPR will be an argument which must be evaluated.
9195 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9196 COMPOUND_EXPR in the chain will contain the tree for the simplified
9197 form of the builtin function call. */
9200 fold_builtin_strrchr (tree arglist, tree type)
9202 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9206 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9210 if (TREE_CODE (s2) != INTEGER_CST)
9220 if (target_char_cast (s2, &c))
9223 r = strrchr (p1, c);
9226 return build_int_cst (TREE_TYPE (s1), 0);
9228 /* Return an offset into the constant string argument. */
9229 tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
9230 s1, build_int_cst (TREE_TYPE (s1), r - p1));
9231 return fold_convert (type, tem);
9234 if (! integer_zerop (s2))
9237 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
9241 /* Transform strrchr(s1, '\0') to strchr(s1, '\0'). */
9242 return build_function_call_expr (fn, arglist);
9246 /* Simplify a call to the strpbrk builtin.
9248 Return 0 if no simplification was possible, otherwise return the
9249 simplified form of the call as a tree.
9251 The simplified form may be a constant or other expression which
9252 computes the same value, but in a more efficient manner (including
9253 calls to other builtin functions).
9255 The call may contain arguments which need to be evaluated, but
9256 which are not useful to determine the result of the call. In
9257 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9258 COMPOUND_EXPR will be an argument which must be evaluated.
9259 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9260 COMPOUND_EXPR in the chain will contain the tree for the simplified
9261 form of the builtin function call. */
9264 fold_builtin_strpbrk (tree arglist, tree type)
9266 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9270 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9272 const char *p1, *p2;
9281 const char *r = strpbrk (p1, p2);
9285 return build_int_cst (TREE_TYPE (s1), 0);
9287 /* Return an offset into the constant string argument. */
9288 tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
9289 s1, build_int_cst (TREE_TYPE (s1), r - p1));
9290 return fold_convert (type, tem);
9294 /* strpbrk(x, "") == NULL.
9295 Evaluate and ignore s1 in case it had side-effects. */
9296 return omit_one_operand (TREE_TYPE (s1), integer_zero_node, s1);
9299 return 0; /* Really call strpbrk. */
9301 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
9305 /* New argument list transforming strpbrk(s1, s2) to
9306 strchr(s1, s2[0]). */
9307 arglist = build_tree_list (NULL_TREE,
9308 build_int_cst (NULL_TREE, p2[0]));
9309 arglist = tree_cons (NULL_TREE, s1, arglist);
9310 return build_function_call_expr (fn, arglist);
9314 /* Simplify a call to the strcat builtin.
9316 Return 0 if no simplification was possible, otherwise return the
9317 simplified form of the call as a tree.
9319 The simplified form may be a constant or other expression which
9320 computes the same value, but in a more efficient manner (including
9321 calls to other builtin functions).
9323 The call may contain arguments which need to be evaluated, but
9324 which are not useful to determine the result of the call. In
9325 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9326 COMPOUND_EXPR will be an argument which must be evaluated.
9327 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9328 COMPOUND_EXPR in the chain will contain the tree for the simplified
9329 form of the builtin function call. */
9332 fold_builtin_strcat (tree arglist)
9334 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9338 tree dst = TREE_VALUE (arglist),
9339 src = TREE_VALUE (TREE_CHAIN (arglist));
9340 const char *p = c_getstr (src);
9342 /* If the string length is zero, return the dst parameter. */
9343 if (p && *p == '\0')
9350 /* Simplify a call to the strncat 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_strncat (tree arglist)
9370 if (!validate_arglist (arglist,
9371 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9375 tree dst = TREE_VALUE (arglist);
9376 tree src = TREE_VALUE (TREE_CHAIN (arglist));
9377 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
9378 const char *p = c_getstr (src);
9380 /* If the requested length is zero, or the src parameter string
9381 length is zero, return the dst parameter. */
9382 if (integer_zerop (len) || (p && *p == '\0'))
9383 return omit_two_operands (TREE_TYPE (dst), dst, src, len);
9385 /* If the requested len is greater than or equal to the string
9386 length, call strcat. */
9387 if (TREE_CODE (len) == INTEGER_CST && p
9388 && compare_tree_int (len, strlen (p)) >= 0)
9391 = tree_cons (NULL_TREE, dst, build_tree_list (NULL_TREE, src));
9392 tree fn = implicit_built_in_decls[BUILT_IN_STRCAT];
9394 /* If the replacement _DECL isn't initialized, don't do the
9399 return build_function_call_expr (fn, newarglist);
9405 /* Simplify a call to the strspn builtin.
9407 Return 0 if no simplification was possible, otherwise return the
9408 simplified form of the call as a tree.
9410 The simplified form may be a constant or other expression which
9411 computes the same value, but in a more efficient manner (including
9412 calls to other builtin functions).
9414 The call may contain arguments which need to be evaluated, but
9415 which are not useful to determine the result of the call. In
9416 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9417 COMPOUND_EXPR will be an argument which must be evaluated.
9418 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9419 COMPOUND_EXPR in the chain will contain the tree for the simplified
9420 form of the builtin function call. */
9423 fold_builtin_strspn (tree arglist)
9425 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9429 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9430 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
9432 /* If both arguments are constants, evaluate at compile-time. */
9435 const size_t r = strspn (p1, p2);
9436 return size_int (r);
9439 /* If either argument is "", return 0. */
9440 if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
9441 /* Evaluate and ignore both arguments in case either one has
9443 return omit_two_operands (integer_type_node, integer_zero_node,
9449 /* Simplify a call to the strcspn builtin.
9451 Return 0 if no simplification was possible, otherwise return the
9452 simplified form of the call as a tree.
9454 The simplified form may be a constant or other expression which
9455 computes the same value, but in a more efficient manner (including
9456 calls to other builtin functions).
9458 The call may contain arguments which need to be evaluated, but
9459 which are not useful to determine the result of the call. In
9460 this case we return a chain of COMPOUND_EXPRs. The LHS of each
9461 COMPOUND_EXPR will be an argument which must be evaluated.
9462 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
9463 COMPOUND_EXPR in the chain will contain the tree for the simplified
9464 form of the builtin function call. */
9467 fold_builtin_strcspn (tree arglist)
9469 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9473 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9474 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
9476 /* If both arguments are constants, evaluate at compile-time. */
9479 const size_t r = strcspn (p1, p2);
9480 return size_int (r);
9483 /* If the first argument is "", return 0. */
9484 if (p1 && *p1 == '\0')
9486 /* Evaluate and ignore argument s2 in case it has
9488 return omit_one_operand (integer_type_node,
9489 integer_zero_node, s2);
9492 /* If the second argument is "", return __builtin_strlen(s1). */
9493 if (p2 && *p2 == '\0')
9495 tree newarglist = build_tree_list (NULL_TREE, s1),
9496 fn = implicit_built_in_decls[BUILT_IN_STRLEN];
9498 /* If the replacement _DECL isn't initialized, don't do the
9503 return build_function_call_expr (fn, newarglist);
9509 /* Fold a call to the fputs builtin. IGNORE is true if the value returned
9510 by the builtin will be ignored. UNLOCKED is true is true if this
9511 actually a call to fputs_unlocked. If LEN in non-NULL, it represents
9512 the known length of the string. Return NULL_TREE if no simplification
9516 fold_builtin_fputs (tree arglist, bool ignore, bool unlocked, tree len)
9519 /* If we're using an unlocked function, assume the other unlocked
9520 functions exist explicitly. */
9521 tree const fn_fputc = unlocked ? built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
9522 : implicit_built_in_decls[BUILT_IN_FPUTC];
9523 tree const fn_fwrite = unlocked ? built_in_decls[BUILT_IN_FWRITE_UNLOCKED]
9524 : implicit_built_in_decls[BUILT_IN_FWRITE];
9526 /* If the return value is used, don't do the transformation. */
9530 /* Verify the arguments in the original call. */
9531 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9535 len = c_strlen (TREE_VALUE (arglist), 0);
9537 /* Get the length of the string passed to fputs. If the length
9538 can't be determined, punt. */
9540 || TREE_CODE (len) != INTEGER_CST)
9543 switch (compare_tree_int (len, 1))
9545 case -1: /* length is 0, delete the call entirely . */
9546 return omit_one_operand (integer_type_node, integer_zero_node,
9547 TREE_VALUE (TREE_CHAIN (arglist)));
9549 case 0: /* length is 1, call fputc. */
9551 const char *p = c_getstr (TREE_VALUE (arglist));
9555 /* New argument list transforming fputs(string, stream) to
9556 fputc(string[0], stream). */
9557 arglist = build_tree_list (NULL_TREE,
9558 TREE_VALUE (TREE_CHAIN (arglist)));
9559 arglist = tree_cons (NULL_TREE,
9560 build_int_cst (NULL_TREE, p[0]),
9567 case 1: /* length is greater than 1, call fwrite. */
9571 /* If optimizing for size keep fputs. */
9574 string_arg = TREE_VALUE (arglist);
9575 /* New argument list transforming fputs(string, stream) to
9576 fwrite(string, 1, len, stream). */
9577 arglist = build_tree_list (NULL_TREE,
9578 TREE_VALUE (TREE_CHAIN (arglist)));
9579 arglist = tree_cons (NULL_TREE, len, arglist);
9580 arglist = tree_cons (NULL_TREE, size_one_node, arglist);
9581 arglist = tree_cons (NULL_TREE, string_arg, arglist);
9589 /* If the replacement _DECL isn't initialized, don't do the
9594 /* These optimizations are only performed when the result is ignored,
9595 hence there's no need to cast the result to integer_type_node. */
9596 return build_function_call_expr (fn, arglist);
9599 /* Fold the new_arg's arguments (ARGLIST). Returns true if there was an error
9600 produced. False otherwise. This is done so that we don't output the error
9601 or warning twice or three times. */
9603 fold_builtin_next_arg (tree arglist)
9605 tree fntype = TREE_TYPE (current_function_decl);
9607 if (TYPE_ARG_TYPES (fntype) == 0
9608 || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
9611 error ("%<va_start%> used in function with fixed args");
9616 /* Evidently an out of date version of <stdarg.h>; can't validate
9617 va_start's second argument, but can still work as intended. */
9618 warning (0, "%<__builtin_next_arg%> called without an argument");
9621 /* We use __builtin_va_start (ap, 0, 0) or __builtin_next_arg (0, 0)
9622 when we checked the arguments and if needed issued a warning. */
9623 else if (!TREE_CHAIN (arglist)
9624 || !integer_zerop (TREE_VALUE (arglist))
9625 || !integer_zerop (TREE_VALUE (TREE_CHAIN (arglist)))
9626 || TREE_CHAIN (TREE_CHAIN (arglist)))
9628 tree last_parm = tree_last (DECL_ARGUMENTS (current_function_decl));
9629 tree arg = TREE_VALUE (arglist);
9631 if (TREE_CHAIN (arglist))
9633 error ("%<va_start%> used with too many arguments");
9637 /* Strip off all nops for the sake of the comparison. This
9638 is not quite the same as STRIP_NOPS. It does more.
9639 We must also strip off INDIRECT_EXPR for C++ reference
9641 while (TREE_CODE (arg) == NOP_EXPR
9642 || TREE_CODE (arg) == CONVERT_EXPR
9643 || TREE_CODE (arg) == NON_LVALUE_EXPR
9644 || TREE_CODE (arg) == INDIRECT_REF)
9645 arg = TREE_OPERAND (arg, 0);
9646 if (arg != last_parm)
9648 /* FIXME: Sometimes with the tree optimizers we can get the
9649 not the last argument even though the user used the last
9650 argument. We just warn and set the arg to be the last
9651 argument so that we will get wrong-code because of
9653 warning (0, "second parameter of %<va_start%> not last named argument");
9655 /* We want to verify the second parameter just once before the tree
9656 optimizers are run and then avoid keeping it in the tree,
9657 as otherwise we could warn even for correct code like:
9658 void foo (int i, ...)
9659 { va_list ap; i++; va_start (ap, i); va_end (ap); } */
9660 TREE_VALUE (arglist) = integer_zero_node;
9661 TREE_CHAIN (arglist) = build_tree_list (NULL, integer_zero_node);
9667 /* Simplify a call to the sprintf builtin.
9669 Return 0 if no simplification was possible, otherwise return the
9670 simplified form of the call as a tree. If IGNORED is true, it means that
9671 the caller does not use the returned value of the function. */
9674 fold_builtin_sprintf (tree arglist, int ignored)
9676 tree call, retval, dest, fmt;
9677 const char *fmt_str = NULL;
9679 /* Verify the required arguments in the original call. We deal with two
9680 types of sprintf() calls: 'sprintf (str, fmt)' and
9681 'sprintf (dest, "%s", orig)'. */
9682 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)
9683 && !validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, POINTER_TYPE,
9687 /* Get the destination string and the format specifier. */
9688 dest = TREE_VALUE (arglist);
9689 fmt = TREE_VALUE (TREE_CHAIN (arglist));
9691 /* Check whether the format is a literal string constant. */
9692 fmt_str = c_getstr (fmt);
9693 if (fmt_str == NULL)
9699 if (!init_target_chars())
9702 /* If the format doesn't contain % args or %%, use strcpy. */
9703 if (strchr (fmt_str, target_percent) == NULL)
9705 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
9710 /* Convert sprintf (str, fmt) into strcpy (str, fmt) when
9711 'format' is known to contain no % formats. */
9712 arglist = build_tree_list (NULL_TREE, fmt);
9713 arglist = tree_cons (NULL_TREE, dest, arglist);
9714 call = build_function_call_expr (fn, arglist);
9716 retval = build_int_cst (NULL_TREE, strlen (fmt_str));
9719 /* If the format is "%s", use strcpy if the result isn't used. */
9720 else if (fmt_str && strcmp (fmt_str, target_percent_s) == 0)
9723 fn = implicit_built_in_decls[BUILT_IN_STRCPY];
9728 /* Convert sprintf (str1, "%s", str2) into strcpy (str1, str2). */
9729 orig = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
9730 arglist = build_tree_list (NULL_TREE, orig);
9731 arglist = tree_cons (NULL_TREE, dest, arglist);
9734 retval = c_strlen (orig, 1);
9735 if (!retval || TREE_CODE (retval) != INTEGER_CST)
9738 call = build_function_call_expr (fn, arglist);
9743 retval = fold_convert
9744 (TREE_TYPE (TREE_TYPE (implicit_built_in_decls[BUILT_IN_SPRINTF])),
9746 return build2 (COMPOUND_EXPR, TREE_TYPE (retval), call, retval);
9752 /* Expand a call to __builtin_object_size. */
9755 expand_builtin_object_size (tree exp)
9758 int object_size_type;
9759 tree fndecl = get_callee_fndecl (exp);
9760 tree arglist = TREE_OPERAND (exp, 1);
9761 location_t locus = EXPR_LOCATION (exp);
9763 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9765 error ("%Hfirst argument of %D must be a pointer, second integer constant",
9767 expand_builtin_trap ();
9771 ost = TREE_VALUE (TREE_CHAIN (arglist));
9774 if (TREE_CODE (ost) != INTEGER_CST
9775 || tree_int_cst_sgn (ost) < 0
9776 || compare_tree_int (ost, 3) > 0)
9778 error ("%Hlast argument of %D is not integer constant between 0 and 3",
9780 expand_builtin_trap ();
9784 object_size_type = tree_low_cst (ost, 0);
9786 return object_size_type < 2 ? constm1_rtx : const0_rtx;
9789 /* Expand EXP, a call to the __mem{cpy,pcpy,move,set}_chk builtin.
9790 FCODE is the BUILT_IN_* to use.
9791 Return 0 if we failed; the caller should emit a normal call,
9792 otherwise try to get the result in TARGET, if convenient (and in
9793 mode MODE if that's convenient). */
9796 expand_builtin_memory_chk (tree exp, rtx target, enum machine_mode mode,
9797 enum built_in_function fcode)
9799 tree arglist = TREE_OPERAND (exp, 1);
9800 tree dest, src, len, size;
9802 if (!validate_arglist (arglist,
9804 fcode == BUILT_IN_MEMSET_CHK
9805 ? INTEGER_TYPE : POINTER_TYPE,
9806 INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
9809 dest = TREE_VALUE (arglist);
9810 src = TREE_VALUE (TREE_CHAIN (arglist));
9811 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
9812 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
9814 if (! host_integerp (size, 1))
9817 if (host_integerp (len, 1) || integer_all_onesp (size))
9821 if (! integer_all_onesp (size) && tree_int_cst_lt (size, len))
9823 location_t locus = EXPR_LOCATION (exp);
9824 warning (0, "%Hcall to %D will always overflow destination buffer",
9825 &locus, get_callee_fndecl (exp));
9829 arglist = build_tree_list (NULL_TREE, len);
9830 arglist = tree_cons (NULL_TREE, src, arglist);
9831 arglist = tree_cons (NULL_TREE, dest, arglist);
9834 /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume
9835 mem{cpy,pcpy,move,set} is available. */
9838 case BUILT_IN_MEMCPY_CHK:
9839 fn = built_in_decls[BUILT_IN_MEMCPY];
9841 case BUILT_IN_MEMPCPY_CHK:
9842 fn = built_in_decls[BUILT_IN_MEMPCPY];
9844 case BUILT_IN_MEMMOVE_CHK:
9845 fn = built_in_decls[BUILT_IN_MEMMOVE];
9847 case BUILT_IN_MEMSET_CHK:
9848 fn = built_in_decls[BUILT_IN_MEMSET];
9857 fn = build_function_call_expr (fn, arglist);
9858 if (TREE_CODE (fn) == CALL_EXPR)
9859 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
9860 return expand_expr (fn, target, mode, EXPAND_NORMAL);
9862 else if (fcode == BUILT_IN_MEMSET_CHK)
9866 unsigned int dest_align
9867 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
9869 /* If DEST is not a pointer type, call the normal function. */
9870 if (dest_align == 0)
9873 /* If SRC and DEST are the same (and not volatile), do nothing. */
9874 if (operand_equal_p (src, dest, 0))
9878 if (fcode != BUILT_IN_MEMPCPY_CHK)
9880 /* Evaluate and ignore LEN in case it has side-effects. */
9881 expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
9882 return expand_expr (dest, target, mode, EXPAND_NORMAL);
9885 len = fold_convert (TREE_TYPE (dest), len);
9886 expr = fold_build2 (PLUS_EXPR, TREE_TYPE (dest), dest, len);
9887 return expand_expr (expr, target, mode, EXPAND_NORMAL);
9890 /* __memmove_chk special case. */
9891 if (fcode == BUILT_IN_MEMMOVE_CHK)
9893 unsigned int src_align
9894 = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
9899 /* If src is categorized for a readonly section we can use
9900 normal __memcpy_chk. */
9901 if (readonly_data_expr (src))
9903 tree fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
9906 fn = build_function_call_expr (fn, arglist);
9907 if (TREE_CODE (fn) == CALL_EXPR)
9908 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
9909 return expand_expr (fn, target, mode, EXPAND_NORMAL);
9916 /* Emit warning if a buffer overflow is detected at compile time. */
9919 maybe_emit_chk_warning (tree exp, enum built_in_function fcode)
9921 int arg_mask, is_strlen = 0;
9922 tree arglist = TREE_OPERAND (exp, 1), a;
9928 case BUILT_IN_STRCPY_CHK:
9929 case BUILT_IN_STPCPY_CHK:
9930 /* For __strcat_chk the warning will be emitted only if overflowing
9931 by at least strlen (dest) + 1 bytes. */
9932 case BUILT_IN_STRCAT_CHK:
9936 case BUILT_IN_STRNCPY_CHK:
9939 case BUILT_IN_SNPRINTF_CHK:
9940 case BUILT_IN_VSNPRINTF_CHK:
9949 for (a = arglist; a && arg_mask; a = TREE_CHAIN (a), arg_mask >>= 1)
9961 len = TREE_VALUE (len);
9962 size = TREE_VALUE (size);
9964 if (! host_integerp (size, 1) || integer_all_onesp (size))
9969 len = c_strlen (len, 1);
9970 if (! len || ! host_integerp (len, 1) || tree_int_cst_lt (len, size))
9973 else if (! host_integerp (len, 1) || ! tree_int_cst_lt (size, len))
9976 locus = EXPR_LOCATION (exp);
9977 warning (0, "%Hcall to %D will always overflow destination buffer",
9978 &locus, get_callee_fndecl (exp));
9981 /* Emit warning if a buffer overflow is detected at compile time
9982 in __sprintf_chk/__vsprintf_chk calls. */
9985 maybe_emit_sprintf_chk_warning (tree exp, enum built_in_function fcode)
9987 tree arglist = TREE_OPERAND (exp, 1);
9988 tree dest, size, len, fmt, flag;
9989 const char *fmt_str;
9991 /* Verify the required arguments in the original call. */
9994 dest = TREE_VALUE (arglist);
9995 arglist = TREE_CHAIN (arglist);
9998 flag = TREE_VALUE (arglist);
9999 arglist = TREE_CHAIN (arglist);
10002 size = TREE_VALUE (arglist);
10003 arglist = TREE_CHAIN (arglist);
10006 fmt = TREE_VALUE (arglist);
10007 arglist = TREE_CHAIN (arglist);
10009 if (! host_integerp (size, 1) || integer_all_onesp (size))
10012 /* Check whether the format is a literal string constant. */
10013 fmt_str = c_getstr (fmt);
10014 if (fmt_str == NULL)
10017 if (!init_target_chars())
10020 /* If the format doesn't contain % args or %%, we know its size. */
10021 if (strchr (fmt_str, target_percent) == 0)
10022 len = build_int_cstu (size_type_node, strlen (fmt_str));
10023 /* If the format is "%s" and first ... argument is a string literal,
10025 else if (fcode == BUILT_IN_SPRINTF_CHK && strcmp (fmt_str, target_percent_s) == 0)
10031 arg = TREE_VALUE (arglist);
10032 if (! POINTER_TYPE_P (TREE_TYPE (arg)))
10035 len = c_strlen (arg, 1);
10036 if (!len || ! host_integerp (len, 1))
10042 if (! tree_int_cst_lt (len, size))
10044 location_t locus = EXPR_LOCATION (exp);
10045 warning (0, "%Hcall to %D will always overflow destination buffer",
10046 &locus, get_callee_fndecl (exp));
10050 /* Fold a call to __builtin_object_size, if possible. */
10053 fold_builtin_object_size (tree arglist)
10055 tree ptr, ost, ret = 0;
10056 int object_size_type;
10058 if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
10061 ptr = TREE_VALUE (arglist);
10062 ost = TREE_VALUE (TREE_CHAIN (arglist));
10065 if (TREE_CODE (ost) != INTEGER_CST
10066 || tree_int_cst_sgn (ost) < 0
10067 || compare_tree_int (ost, 3) > 0)
10070 object_size_type = tree_low_cst (ost, 0);
10072 /* __builtin_object_size doesn't evaluate side-effects in its arguments;
10073 if there are any side-effects, it returns (size_t) -1 for types 0 and 1
10074 and (size_t) 0 for types 2 and 3. */
10075 if (TREE_SIDE_EFFECTS (ptr))
10076 return fold_convert (size_type_node,
10077 object_size_type < 2
10078 ? integer_minus_one_node : integer_zero_node);
10080 if (TREE_CODE (ptr) == ADDR_EXPR)
10081 ret = build_int_cstu (size_type_node,
10082 compute_builtin_object_size (ptr, object_size_type));
10084 else if (TREE_CODE (ptr) == SSA_NAME)
10086 unsigned HOST_WIDE_INT bytes;
10088 /* If object size is not known yet, delay folding until
10089 later. Maybe subsequent passes will help determining
10091 bytes = compute_builtin_object_size (ptr, object_size_type);
10092 if (bytes != (unsigned HOST_WIDE_INT) (object_size_type < 2
10094 ret = build_int_cstu (size_type_node, bytes);
10099 ret = force_fit_type (ret, -1, false, false);
10100 if (TREE_CONSTANT_OVERFLOW (ret))
10107 /* Fold a call to the __mem{cpy,pcpy,move,set}_chk builtin.
10108 IGNORE is true, if return value can be ignored. FCODE is the BUILT_IN_*
10109 code of the builtin. If MAXLEN is not NULL, it is maximum length
10110 passed as third argument. */
10113 fold_builtin_memory_chk (tree fndecl, tree arglist, tree maxlen, bool ignore,
10114 enum built_in_function fcode)
10116 tree dest, src, len, size, fn;
10118 if (!validate_arglist (arglist,
10120 fcode == BUILT_IN_MEMSET_CHK
10121 ? INTEGER_TYPE : POINTER_TYPE,
10122 INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
10125 dest = TREE_VALUE (arglist);
10126 /* Actually val for __memset_chk, but it doesn't matter. */
10127 src = TREE_VALUE (TREE_CHAIN (arglist));
10128 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10129 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
10131 /* If SRC and DEST are the same (and not volatile), return DEST
10132 (resp. DEST+LEN for __mempcpy_chk). */
10133 if (fcode != BUILT_IN_MEMSET_CHK && operand_equal_p (src, dest, 0))
10135 if (fcode != BUILT_IN_MEMPCPY_CHK)
10136 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, len);
10139 tree temp = fold_convert (TREE_TYPE (dest), len);
10140 temp = fold_build2 (PLUS_EXPR, TREE_TYPE (dest), dest, temp);
10141 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), temp);
10145 if (! host_integerp (size, 1))
10148 if (! integer_all_onesp (size))
10150 if (! host_integerp (len, 1))
10152 /* If LEN is not constant, try MAXLEN too.
10153 For MAXLEN only allow optimizing into non-_ocs function
10154 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
10155 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
10157 if (fcode == BUILT_IN_MEMPCPY_CHK && ignore)
10159 /* (void) __mempcpy_chk () can be optimized into
10160 (void) __memcpy_chk (). */
10161 fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
10165 return build_function_call_expr (fn, arglist);
10173 if (tree_int_cst_lt (size, maxlen))
10177 arglist = build_tree_list (NULL_TREE, len);
10178 arglist = tree_cons (NULL_TREE, src, arglist);
10179 arglist = tree_cons (NULL_TREE, dest, arglist);
10182 /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume
10183 mem{cpy,pcpy,move,set} is available. */
10186 case BUILT_IN_MEMCPY_CHK:
10187 fn = built_in_decls[BUILT_IN_MEMCPY];
10189 case BUILT_IN_MEMPCPY_CHK:
10190 fn = built_in_decls[BUILT_IN_MEMPCPY];
10192 case BUILT_IN_MEMMOVE_CHK:
10193 fn = built_in_decls[BUILT_IN_MEMMOVE];
10195 case BUILT_IN_MEMSET_CHK:
10196 fn = built_in_decls[BUILT_IN_MEMSET];
10205 return build_function_call_expr (fn, arglist);
10208 /* Fold a call to the __st[rp]cpy_chk builtin.
10209 IGNORE is true, if return value can be ignored. FCODE is the BUILT_IN_*
10210 code of the builtin. If MAXLEN is not NULL, it is maximum length of
10211 strings passed as second argument. */
10214 fold_builtin_stxcpy_chk (tree fndecl, tree arglist, tree maxlen, bool ignore,
10215 enum built_in_function fcode)
10217 tree dest, src, size, len, fn;
10219 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
10223 dest = TREE_VALUE (arglist);
10224 src = TREE_VALUE (TREE_CHAIN (arglist));
10225 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10227 /* If SRC and DEST are the same (and not volatile), return DEST. */
10228 if (fcode == BUILT_IN_STRCPY_CHK && operand_equal_p (src, dest, 0))
10229 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), dest);
10231 if (! host_integerp (size, 1))
10234 if (! integer_all_onesp (size))
10236 len = c_strlen (src, 1);
10237 if (! len || ! host_integerp (len, 1))
10239 /* If LEN is not constant, try MAXLEN too.
10240 For MAXLEN only allow optimizing into non-_ocs function
10241 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
10242 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
10244 if (fcode == BUILT_IN_STPCPY_CHK)
10249 /* If return value of __stpcpy_chk is ignored,
10250 optimize into __strcpy_chk. */
10251 fn = built_in_decls[BUILT_IN_STRCPY_CHK];
10255 return build_function_call_expr (fn, arglist);
10258 if (! len || TREE_SIDE_EFFECTS (len))
10261 /* If c_strlen returned something, but not a constant,
10262 transform __strcpy_chk into __memcpy_chk. */
10263 fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
10267 len = size_binop (PLUS_EXPR, len, ssize_int (1));
10268 arglist = build_tree_list (NULL_TREE, size);
10269 arglist = tree_cons (NULL_TREE, len, arglist);
10270 arglist = tree_cons (NULL_TREE, src, arglist);
10271 arglist = tree_cons (NULL_TREE, dest, arglist);
10272 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)),
10273 build_function_call_expr (fn, arglist));
10279 if (! tree_int_cst_lt (maxlen, size))
10283 arglist = build_tree_list (NULL_TREE, src);
10284 arglist = tree_cons (NULL_TREE, dest, arglist);
10286 /* If __builtin_st{r,p}cpy_chk is used, assume st{r,p}cpy is available. */
10287 fn = built_in_decls[fcode == BUILT_IN_STPCPY_CHK
10288 ? BUILT_IN_STPCPY : BUILT_IN_STRCPY];
10292 return build_function_call_expr (fn, arglist);
10295 /* Fold a call to the __strncpy_chk builtin.
10296 If MAXLEN is not NULL, it is maximum length passed as third argument. */
10299 fold_builtin_strncpy_chk (tree arglist, tree maxlen)
10301 tree dest, src, size, len, fn;
10303 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
10304 INTEGER_TYPE, VOID_TYPE))
10307 dest = TREE_VALUE (arglist);
10308 src = TREE_VALUE (TREE_CHAIN (arglist));
10309 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10310 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
10312 if (! host_integerp (size, 1))
10315 if (! integer_all_onesp (size))
10317 if (! host_integerp (len, 1))
10319 /* If LEN is not constant, try MAXLEN too.
10320 For MAXLEN only allow optimizing into non-_ocs function
10321 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
10322 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
10328 if (tree_int_cst_lt (size, maxlen))
10332 arglist = build_tree_list (NULL_TREE, len);
10333 arglist = tree_cons (NULL_TREE, src, arglist);
10334 arglist = tree_cons (NULL_TREE, dest, arglist);
10336 /* If __builtin_strncpy_chk is used, assume strncpy is available. */
10337 fn = built_in_decls[BUILT_IN_STRNCPY];
10341 return build_function_call_expr (fn, arglist);
10344 /* Fold a call to the __strcat_chk builtin FNDECL with ARGLIST. */
10347 fold_builtin_strcat_chk (tree fndecl, tree arglist)
10349 tree dest, src, size, fn;
10352 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
10356 dest = TREE_VALUE (arglist);
10357 src = TREE_VALUE (TREE_CHAIN (arglist));
10358 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10360 p = c_getstr (src);
10361 /* If the SRC parameter is "", return DEST. */
10362 if (p && *p == '\0')
10363 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
10365 if (! host_integerp (size, 1) || ! integer_all_onesp (size))
10368 arglist = build_tree_list (NULL_TREE, src);
10369 arglist = tree_cons (NULL_TREE, dest, arglist);
10371 /* If __builtin_strcat_chk is used, assume strcat is available. */
10372 fn = built_in_decls[BUILT_IN_STRCAT];
10376 return build_function_call_expr (fn, arglist);
10379 /* Fold a call to the __strncat_chk builtin EXP. */
10382 fold_builtin_strncat_chk (tree fndecl, tree arglist)
10384 tree dest, src, size, len, fn;
10387 if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
10388 INTEGER_TYPE, VOID_TYPE))
10391 dest = TREE_VALUE (arglist);
10392 src = TREE_VALUE (TREE_CHAIN (arglist));
10393 len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10394 size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
10396 p = c_getstr (src);
10397 /* If the SRC parameter is "" or if LEN is 0, return DEST. */
10398 if (p && *p == '\0')
10399 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, len);
10400 else if (integer_zerop (len))
10401 return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
10403 if (! host_integerp (size, 1))
10406 if (! integer_all_onesp (size))
10408 tree src_len = c_strlen (src, 1);
10410 && host_integerp (src_len, 1)
10411 && host_integerp (len, 1)
10412 && ! tree_int_cst_lt (len, src_len))
10414 /* If LEN >= strlen (SRC), optimize into __strcat_chk. */
10415 fn = built_in_decls[BUILT_IN_STRCAT_CHK];
10419 arglist = build_tree_list (NULL_TREE, size);
10420 arglist = tree_cons (NULL_TREE, src, arglist);
10421 arglist = tree_cons (NULL_TREE, dest, arglist);
10422 return build_function_call_expr (fn, arglist);
10427 arglist = build_tree_list (NULL_TREE, len);
10428 arglist = tree_cons (NULL_TREE, src, arglist);
10429 arglist = tree_cons (NULL_TREE, dest, arglist);
10431 /* If __builtin_strncat_chk is used, assume strncat is available. */
10432 fn = built_in_decls[BUILT_IN_STRNCAT];
10436 return build_function_call_expr (fn, arglist);
10439 /* Fold a call to __{,v}sprintf_chk with argument list ARGLIST. Return 0 if
10440 a normal call should be emitted rather than expanding the function
10441 inline. FCODE is either BUILT_IN_SPRINTF_CHK or BUILT_IN_VSPRINTF_CHK. */
10444 fold_builtin_sprintf_chk (tree arglist, enum built_in_function fcode)
10446 tree dest, size, len, fn, fmt, flag;
10447 const char *fmt_str;
10449 /* Verify the required arguments in the original call. */
10452 dest = TREE_VALUE (arglist);
10453 if (! POINTER_TYPE_P (TREE_TYPE (dest)))
10455 arglist = TREE_CHAIN (arglist);
10458 flag = TREE_VALUE (arglist);
10459 if (TREE_CODE (TREE_TYPE (flag)) != INTEGER_TYPE)
10461 arglist = TREE_CHAIN (arglist);
10464 size = TREE_VALUE (arglist);
10465 if (TREE_CODE (TREE_TYPE (size)) != INTEGER_TYPE)
10467 arglist = TREE_CHAIN (arglist);
10470 fmt = TREE_VALUE (arglist);
10471 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
10473 arglist = TREE_CHAIN (arglist);
10475 if (! host_integerp (size, 1))
10480 if (!init_target_chars())
10483 /* Check whether the format is a literal string constant. */
10484 fmt_str = c_getstr (fmt);
10485 if (fmt_str != NULL)
10487 /* If the format doesn't contain % args or %%, we know the size. */
10488 if (strchr (fmt_str, target_percent) == 0)
10490 if (fcode != BUILT_IN_SPRINTF_CHK || arglist == NULL_TREE)
10491 len = build_int_cstu (size_type_node, strlen (fmt_str));
10493 /* If the format is "%s" and first ... argument is a string literal,
10494 we know the size too. */
10495 else if (fcode == BUILT_IN_SPRINTF_CHK && strcmp (fmt_str, target_percent_s) == 0)
10499 if (arglist && !TREE_CHAIN (arglist))
10501 arg = TREE_VALUE (arglist);
10502 if (POINTER_TYPE_P (TREE_TYPE (arg)))
10504 len = c_strlen (arg, 1);
10505 if (! len || ! host_integerp (len, 1))
10512 if (! integer_all_onesp (size))
10514 if (! len || ! tree_int_cst_lt (len, size))
10518 /* Only convert __{,v}sprintf_chk to {,v}sprintf if flag is 0
10519 or if format doesn't contain % chars or is "%s". */
10520 if (! integer_zerop (flag))
10522 if (fmt_str == NULL)
10524 if (strchr (fmt_str, target_percent) != NULL && strcmp (fmt_str, target_percent_s))
10528 arglist = tree_cons (NULL_TREE, fmt, arglist);
10529 arglist = tree_cons (NULL_TREE, dest, arglist);
10531 /* If __builtin_{,v}sprintf_chk is used, assume {,v}sprintf is available. */
10532 fn = built_in_decls[fcode == BUILT_IN_VSPRINTF_CHK
10533 ? BUILT_IN_VSPRINTF : BUILT_IN_SPRINTF];
10537 return build_function_call_expr (fn, arglist);
10540 /* Fold a call to {,v}snprintf with argument list ARGLIST. Return 0 if
10541 a normal call should be emitted rather than expanding the function
10542 inline. FCODE is either BUILT_IN_SNPRINTF_CHK or
10543 BUILT_IN_VSNPRINTF_CHK. If MAXLEN is not NULL, it is maximum length
10544 passed as second argument. */
10547 fold_builtin_snprintf_chk (tree arglist, tree maxlen,
10548 enum built_in_function fcode)
10550 tree dest, size, len, fn, fmt, flag;
10551 const char *fmt_str;
10553 /* Verify the required arguments in the original call. */
10556 dest = TREE_VALUE (arglist);
10557 if (! POINTER_TYPE_P (TREE_TYPE (dest)))
10559 arglist = TREE_CHAIN (arglist);
10562 len = TREE_VALUE (arglist);
10563 if (TREE_CODE (TREE_TYPE (len)) != INTEGER_TYPE)
10565 arglist = TREE_CHAIN (arglist);
10568 flag = TREE_VALUE (arglist);
10569 if (TREE_CODE (TREE_TYPE (len)) != INTEGER_TYPE)
10571 arglist = TREE_CHAIN (arglist);
10574 size = TREE_VALUE (arglist);
10575 if (TREE_CODE (TREE_TYPE (size)) != INTEGER_TYPE)
10577 arglist = TREE_CHAIN (arglist);
10580 fmt = TREE_VALUE (arglist);
10581 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
10583 arglist = TREE_CHAIN (arglist);
10585 if (! host_integerp (size, 1))
10588 if (! integer_all_onesp (size))
10590 if (! host_integerp (len, 1))
10592 /* If LEN is not constant, try MAXLEN too.
10593 For MAXLEN only allow optimizing into non-_ocs function
10594 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
10595 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
10601 if (tree_int_cst_lt (size, maxlen))
10605 if (!init_target_chars())
10608 /* Only convert __{,v}snprintf_chk to {,v}snprintf if flag is 0
10609 or if format doesn't contain % chars or is "%s". */
10610 if (! integer_zerop (flag))
10612 fmt_str = c_getstr (fmt);
10613 if (fmt_str == NULL)
10615 if (strchr (fmt_str, target_percent) != NULL && strcmp (fmt_str, target_percent_s))
10619 arglist = tree_cons (NULL_TREE, fmt, arglist);
10620 arglist = tree_cons (NULL_TREE, len, arglist);
10621 arglist = tree_cons (NULL_TREE, dest, arglist);
10623 /* If __builtin_{,v}snprintf_chk is used, assume {,v}snprintf is
10625 fn = built_in_decls[fcode == BUILT_IN_VSNPRINTF_CHK
10626 ? BUILT_IN_VSNPRINTF : BUILT_IN_SNPRINTF];
10630 return build_function_call_expr (fn, arglist);
10633 /* Fold a call to the {,v}printf{,_unlocked} and __{,v}printf_chk builtins.
10635 Return 0 if no simplification was possible, otherwise return the
10636 simplified form of the call as a tree. FCODE is the BUILT_IN_*
10637 code of the function to be simplified. */
10640 fold_builtin_printf (tree fndecl, tree arglist, bool ignore,
10641 enum built_in_function fcode)
10643 tree fmt, fn = NULL_TREE, fn_putchar, fn_puts, arg, call;
10644 const char *fmt_str = NULL;
10646 /* If the return value is used, don't do the transformation. */
10650 /* Verify the required arguments in the original call. */
10651 if (fcode == BUILT_IN_PRINTF_CHK || fcode == BUILT_IN_VPRINTF_CHK)
10657 flag = TREE_VALUE (arglist);
10658 if (TREE_CODE (TREE_TYPE (flag)) != INTEGER_TYPE
10659 || TREE_SIDE_EFFECTS (flag))
10661 arglist = TREE_CHAIN (arglist);
10666 fmt = TREE_VALUE (arglist);
10667 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
10669 arglist = TREE_CHAIN (arglist);
10671 /* Check whether the format is a literal string constant. */
10672 fmt_str = c_getstr (fmt);
10673 if (fmt_str == NULL)
10676 if (fcode == BUILT_IN_PRINTF_UNLOCKED)
10678 /* If we're using an unlocked function, assume the other
10679 unlocked functions exist explicitly. */
10680 fn_putchar = built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED];
10681 fn_puts = built_in_decls[BUILT_IN_PUTS_UNLOCKED];
10685 fn_putchar = implicit_built_in_decls[BUILT_IN_PUTCHAR];
10686 fn_puts = implicit_built_in_decls[BUILT_IN_PUTS];
10689 if (!init_target_chars())
10692 if (strcmp (fmt_str, target_percent_s) == 0 || strchr (fmt_str, target_percent) == NULL)
10696 if (strcmp (fmt_str, target_percent_s) == 0)
10698 if (fcode == BUILT_IN_VPRINTF || fcode == BUILT_IN_VPRINTF_CHK)
10702 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
10703 || TREE_CHAIN (arglist))
10706 str = c_getstr (TREE_VALUE (arglist));
10712 /* The format specifier doesn't contain any '%' characters. */
10713 if (fcode != BUILT_IN_VPRINTF && fcode != BUILT_IN_VPRINTF_CHK
10719 /* If the string was "", printf does nothing. */
10720 if (str[0] == '\0')
10721 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), 0);
10723 /* If the string has length of 1, call putchar. */
10724 if (str[1] == '\0')
10726 /* Given printf("c"), (where c is any one character,)
10727 convert "c"[0] to an int and pass that to the replacement
10729 arg = build_int_cst (NULL_TREE, str[0]);
10730 arglist = build_tree_list (NULL_TREE, arg);
10735 /* If the string was "string\n", call puts("string"). */
10736 size_t len = strlen (str);
10737 if ((unsigned char)str[len - 1] == target_newline)
10739 /* Create a NUL-terminated string that's one char shorter
10740 than the original, stripping off the trailing '\n'. */
10741 char *newstr = alloca (len);
10742 memcpy (newstr, str, len - 1);
10743 newstr[len - 1] = 0;
10745 arg = build_string_literal (len, newstr);
10746 arglist = build_tree_list (NULL_TREE, arg);
10750 /* We'd like to arrange to call fputs(string,stdout) here,
10751 but we need stdout and don't have a way to get it yet. */
10756 /* The other optimizations can be done only on the non-va_list variants. */
10757 else if (fcode == BUILT_IN_VPRINTF || fcode == BUILT_IN_VPRINTF_CHK)
10760 /* If the format specifier was "%s\n", call __builtin_puts(arg). */
10761 else if (strcmp (fmt_str, target_percent_s_newline) == 0)
10764 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
10765 || TREE_CHAIN (arglist))
10770 /* If the format specifier was "%c", call __builtin_putchar(arg). */
10771 else if (strcmp (fmt_str, target_percent_c) == 0)
10774 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
10775 || TREE_CHAIN (arglist))
10783 call = build_function_call_expr (fn, arglist);
10784 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), call);
10787 /* Fold a call to the {,v}fprintf{,_unlocked} and __{,v}printf_chk builtins.
10789 Return 0 if no simplification was possible, otherwise return the
10790 simplified form of the call as a tree. FCODE is the BUILT_IN_*
10791 code of the function to be simplified. */
10794 fold_builtin_fprintf (tree fndecl, tree arglist, bool ignore,
10795 enum built_in_function fcode)
10797 tree fp, fmt, fn = NULL_TREE, fn_fputc, fn_fputs, arg, call;
10798 const char *fmt_str = NULL;
10800 /* If the return value is used, don't do the transformation. */
10804 /* Verify the required arguments in the original call. */
10807 fp = TREE_VALUE (arglist);
10808 if (! POINTER_TYPE_P (TREE_TYPE (fp)))
10810 arglist = TREE_CHAIN (arglist);
10812 if (fcode == BUILT_IN_FPRINTF_CHK || fcode == BUILT_IN_VFPRINTF_CHK)
10818 flag = TREE_VALUE (arglist);
10819 if (TREE_CODE (TREE_TYPE (flag)) != INTEGER_TYPE
10820 || TREE_SIDE_EFFECTS (flag))
10822 arglist = TREE_CHAIN (arglist);
10827 fmt = TREE_VALUE (arglist);
10828 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
10830 arglist = TREE_CHAIN (arglist);
10832 /* Check whether the format is a literal string constant. */
10833 fmt_str = c_getstr (fmt);
10834 if (fmt_str == NULL)
10837 if (fcode == BUILT_IN_FPRINTF_UNLOCKED)
10839 /* If we're using an unlocked function, assume the other
10840 unlocked functions exist explicitly. */
10841 fn_fputc = built_in_decls[BUILT_IN_FPUTC_UNLOCKED];
10842 fn_fputs = built_in_decls[BUILT_IN_FPUTS_UNLOCKED];
10846 fn_fputc = implicit_built_in_decls[BUILT_IN_FPUTC];
10847 fn_fputs = implicit_built_in_decls[BUILT_IN_FPUTS];
10850 if (!init_target_chars())
10853 /* If the format doesn't contain % args or %%, use strcpy. */
10854 if (strchr (fmt_str, target_percent) == NULL)
10856 if (fcode != BUILT_IN_VFPRINTF && fcode != BUILT_IN_VFPRINTF_CHK
10860 /* If the format specifier was "", fprintf does nothing. */
10861 if (fmt_str[0] == '\0')
10863 /* If FP has side-effects, just wait until gimplification is
10865 if (TREE_SIDE_EFFECTS (fp))
10868 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), 0);
10871 /* When "string" doesn't contain %, replace all cases of
10872 fprintf (fp, string) with fputs (string, fp). The fputs
10873 builtin will take care of special cases like length == 1. */
10874 arglist = build_tree_list (NULL_TREE, fp);
10875 arglist = tree_cons (NULL_TREE, fmt, arglist);
10879 /* The other optimizations can be done only on the non-va_list variants. */
10880 else if (fcode == BUILT_IN_VFPRINTF || fcode == BUILT_IN_VFPRINTF_CHK)
10883 /* If the format specifier was "%s", call __builtin_fputs (arg, fp). */
10884 else if (strcmp (fmt_str, target_percent_s) == 0)
10887 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
10888 || TREE_CHAIN (arglist))
10890 arg = TREE_VALUE (arglist);
10891 arglist = build_tree_list (NULL_TREE, fp);
10892 arglist = tree_cons (NULL_TREE, arg, arglist);
10896 /* If the format specifier was "%c", call __builtin_fputc (arg, fp). */
10897 else if (strcmp (fmt_str, target_percent_c) == 0)
10900 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
10901 || TREE_CHAIN (arglist))
10903 arg = TREE_VALUE (arglist);
10904 arglist = build_tree_list (NULL_TREE, fp);
10905 arglist = tree_cons (NULL_TREE, arg, arglist);
10912 call = build_function_call_expr (fn, arglist);
10913 return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), call);
10916 /* Initialize format string characters in the target charset. */
10919 init_target_chars (void)
10924 target_newline = lang_hooks.to_target_charset ('\n');
10925 target_percent = lang_hooks.to_target_charset ('%');
10926 target_c = lang_hooks.to_target_charset ('c');
10927 target_s = lang_hooks.to_target_charset ('s');
10928 if (target_newline == 0 || target_percent == 0 || target_c == 0
10932 target_percent_c[0] = target_percent;
10933 target_percent_c[1] = target_c;
10934 target_percent_c[2] = '\0';
10936 target_percent_s[0] = target_percent;
10937 target_percent_s[1] = target_s;
10938 target_percent_s[2] = '\0';
10940 target_percent_s_newline[0] = target_percent;
10941 target_percent_s_newline[1] = target_s;
10942 target_percent_s_newline[2] = target_newline;
10943 target_percent_s_newline[3] = '\0';