1 /* Expand builtin functions.
2 Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3 2000, 2001, 2002, 2003, 2004 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, 59 Temple Place - Suite 330, Boston, MA
24 #include "coretypes.h"
32 #include "hard-reg-set.h"
35 #include "insn-config.h"
41 #include "typeclass.h"
46 #include "langhooks.h"
48 #define CALLED_AS_BUILT_IN(NODE) \
49 (!strncmp (IDENTIFIER_POINTER (DECL_NAME (NODE)), "__builtin_", 10))
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) #X,
60 const char *const 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 tree
c_strlen (tree
, int);
76 static const char *c_getstr (tree
);
77 static rtx
c_readstr (const char *, enum machine_mode
);
78 static int target_char_cast (tree
, char *);
79 static rtx
get_memory_rtx (tree
);
80 static tree
build_string_literal (int, const char *);
81 static int apply_args_size (void);
82 static int apply_result_size (void);
83 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
84 static rtx
result_vector (int, rtx
);
86 static rtx
expand_builtin_setjmp (tree
, rtx
);
87 static void expand_builtin_prefetch (tree
);
88 static rtx
expand_builtin_apply_args (void);
89 static rtx
expand_builtin_apply_args_1 (void);
90 static rtx
expand_builtin_apply (rtx
, rtx
, rtx
);
91 static void expand_builtin_return (rtx
);
92 static enum type_class
type_to_class (tree
);
93 static rtx
expand_builtin_classify_type (tree
);
94 static void expand_errno_check (tree
, rtx
);
95 static rtx
expand_builtin_mathfn (tree
, rtx
, rtx
);
96 static rtx
expand_builtin_mathfn_2 (tree
, rtx
, rtx
);
97 static rtx
expand_builtin_mathfn_3 (tree
, rtx
, rtx
);
98 static rtx
expand_builtin_constant_p (tree
, enum machine_mode
);
99 static rtx
expand_builtin_args_info (tree
);
100 static rtx
expand_builtin_next_arg (tree
);
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
, 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
, rtx
, enum machine_mode
, int);
114 static rtx
expand_builtin_memmove (tree
, rtx
, enum machine_mode
);
115 static rtx
expand_builtin_bcopy (tree
);
116 static rtx
expand_builtin_strcpy (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
);
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
, rtx
, enum machine_mode
);
126 static rtx
expand_builtin_strpbrk (tree
, rtx
, enum machine_mode
);
127 static rtx
expand_builtin_strchr (tree
, rtx
, enum machine_mode
);
128 static rtx
expand_builtin_strrchr (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_inf (tree
, int);
141 static tree
fold_builtin_nan (tree
, tree
, int);
142 static int validate_arglist (tree
, ...);
143 static bool integer_valued_real_p (tree
);
144 static tree
fold_trunc_transparent_mathfn (tree
);
145 static bool readonly_data_expr (tree
);
146 static rtx
expand_builtin_fabs (tree
, rtx
, rtx
);
147 static rtx
expand_builtin_cabs (tree
, rtx
);
148 static rtx
expand_builtin_signbit (tree
, rtx
);
149 static tree
fold_builtin_cabs (tree
, tree
, tree
);
150 static tree
fold_builtin_trunc (tree
);
151 static tree
fold_builtin_floor (tree
);
152 static tree
fold_builtin_ceil (tree
);
153 static tree
fold_builtin_round (tree
);
154 static tree
fold_builtin_bitop (tree
);
155 static tree
fold_builtin_memcpy (tree
);
156 static tree
fold_builtin_mempcpy (tree
);
157 static tree
fold_builtin_memmove (tree
);
158 static tree
fold_builtin_strcpy (tree
);
159 static tree
fold_builtin_strncpy (tree
);
160 static tree
fold_builtin_memcmp (tree
);
161 static tree
fold_builtin_strcmp (tree
);
162 static tree
fold_builtin_strncmp (tree
);
163 static tree
fold_builtin_signbit (tree
);
165 /* Return the alignment in bits of EXP, a pointer valued expression.
166 But don't return more than MAX_ALIGN no matter what.
167 The alignment returned is, by default, the alignment of the thing that
168 EXP points to. If it is not a POINTER_TYPE, 0 is returned.
170 Otherwise, look at the expression to see if we can do better, i.e., if the
171 expression is actually pointing at an object whose alignment is tighter. */
174 get_pointer_alignment (tree exp
, unsigned int max_align
)
176 unsigned int align
, inner
;
178 if (TREE_CODE (TREE_TYPE (exp
)) != POINTER_TYPE
)
181 align
= TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp
)));
182 align
= MIN (align
, max_align
);
186 switch (TREE_CODE (exp
))
190 case NON_LVALUE_EXPR
:
191 exp
= TREE_OPERAND (exp
, 0);
192 if (TREE_CODE (TREE_TYPE (exp
)) != POINTER_TYPE
)
195 inner
= TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp
)));
196 align
= MIN (inner
, max_align
);
200 /* If sum of pointer + int, restrict our maximum alignment to that
201 imposed by the integer. If not, we can't do any better than
203 if (! host_integerp (TREE_OPERAND (exp
, 1), 1))
206 while (((tree_low_cst (TREE_OPERAND (exp
, 1), 1))
207 & (max_align
/ BITS_PER_UNIT
- 1))
211 exp
= TREE_OPERAND (exp
, 0);
215 /* See what we are pointing at and look at its alignment. */
216 exp
= TREE_OPERAND (exp
, 0);
217 if (TREE_CODE (exp
) == FUNCTION_DECL
)
218 align
= FUNCTION_BOUNDARY
;
219 else if (DECL_P (exp
))
220 align
= DECL_ALIGN (exp
);
221 #ifdef CONSTANT_ALIGNMENT
222 else if (TREE_CODE_CLASS (TREE_CODE (exp
)) == 'c')
223 align
= CONSTANT_ALIGNMENT (exp
, align
);
225 return MIN (align
, max_align
);
233 /* Compute the length of a C string. TREE_STRING_LENGTH is not the right
234 way, because it could contain a zero byte in the middle.
235 TREE_STRING_LENGTH is the size of the character array, not the string.
237 ONLY_VALUE should be nonzero if the result is not going to be emitted
238 into the instruction stream and zero if it is going to be expanded.
239 E.g. with i++ ? "foo" : "bar", if ONLY_VALUE is nonzero, constant 3
240 is returned, otherwise NULL, since
241 len = c_strlen (src, 1); if (len) expand_expr (len, ...); would not
242 evaluate the side-effects.
244 The value returned is of type `ssizetype'.
246 Unfortunately, string_constant can't access the values of const char
247 arrays with initializers, so neither can we do so here. */
250 c_strlen (tree src
, int only_value
)
253 HOST_WIDE_INT offset
;
258 if (TREE_CODE (src
) == COND_EXPR
259 && (only_value
|| !TREE_SIDE_EFFECTS (TREE_OPERAND (src
, 0))))
263 len1
= c_strlen (TREE_OPERAND (src
, 1), only_value
);
264 len2
= c_strlen (TREE_OPERAND (src
, 2), only_value
);
265 if (tree_int_cst_equal (len1
, len2
))
269 if (TREE_CODE (src
) == COMPOUND_EXPR
270 && (only_value
|| !TREE_SIDE_EFFECTS (TREE_OPERAND (src
, 0))))
271 return c_strlen (TREE_OPERAND (src
, 1), only_value
);
273 src
= string_constant (src
, &offset_node
);
277 max
= TREE_STRING_LENGTH (src
) - 1;
278 ptr
= TREE_STRING_POINTER (src
);
280 if (offset_node
&& TREE_CODE (offset_node
) != INTEGER_CST
)
282 /* If the string has an internal zero byte (e.g., "foo\0bar"), we can't
283 compute the offset to the following null if we don't know where to
284 start searching for it. */
287 for (i
= 0; i
< max
; i
++)
291 /* We don't know the starting offset, but we do know that the string
292 has no internal zero bytes. We can assume that the offset falls
293 within the bounds of the string; otherwise, the programmer deserves
294 what he gets. Subtract the offset from the length of the string,
295 and return that. This would perhaps not be valid if we were dealing
296 with named arrays in addition to literal string constants. */
298 return size_diffop (size_int (max
), offset_node
);
301 /* We have a known offset into the string. Start searching there for
302 a null character if we can represent it as a single HOST_WIDE_INT. */
303 if (offset_node
== 0)
305 else if (! host_integerp (offset_node
, 0))
308 offset
= tree_low_cst (offset_node
, 0);
310 /* If the offset is known to be out of bounds, warn, and call strlen at
312 if (offset
< 0 || offset
> max
)
314 warning ("offset outside bounds of constant string");
318 /* Use strlen to search for the first zero byte. Since any strings
319 constructed with build_string will have nulls appended, we win even
320 if we get handed something like (char[4])"abcd".
322 Since OFFSET is our starting index into the string, no further
323 calculation is needed. */
324 return ssize_int (strlen (ptr
+ offset
));
327 /* Return a char pointer for a C string if it is a string constant
328 or sum of string constant and integer constant. */
335 src
= string_constant (src
, &offset_node
);
339 if (offset_node
== 0)
340 return TREE_STRING_POINTER (src
);
341 else if (!host_integerp (offset_node
, 1)
342 || compare_tree_int (offset_node
, TREE_STRING_LENGTH (src
) - 1) > 0)
345 return TREE_STRING_POINTER (src
) + tree_low_cst (offset_node
, 1);
348 /* Return a CONST_INT or CONST_DOUBLE corresponding to target reading
349 GET_MODE_BITSIZE (MODE) bits from string constant STR. */
352 c_readstr (const char *str
, enum machine_mode mode
)
358 if (GET_MODE_CLASS (mode
) != MODE_INT
)
363 for (i
= 0; i
< GET_MODE_SIZE (mode
); i
++)
366 if (WORDS_BIG_ENDIAN
)
367 j
= GET_MODE_SIZE (mode
) - i
- 1;
368 if (BYTES_BIG_ENDIAN
!= WORDS_BIG_ENDIAN
369 && GET_MODE_SIZE (mode
) > UNITS_PER_WORD
)
370 j
= j
+ UNITS_PER_WORD
- 2 * (j
% UNITS_PER_WORD
) - 1;
372 if (j
> 2 * HOST_BITS_PER_WIDE_INT
)
375 ch
= (unsigned char) str
[i
];
376 c
[j
/ HOST_BITS_PER_WIDE_INT
] |= ch
<< (j
% HOST_BITS_PER_WIDE_INT
);
378 return immed_double_const (c
[0], c
[1], mode
);
381 /* Cast a target constant CST to target CHAR and if that value fits into
382 host char type, return zero and put that value into variable pointed by
386 target_char_cast (tree cst
, char *p
)
388 unsigned HOST_WIDE_INT val
, hostval
;
390 if (!host_integerp (cst
, 1)
391 || CHAR_TYPE_SIZE
> HOST_BITS_PER_WIDE_INT
)
394 val
= tree_low_cst (cst
, 1);
395 if (CHAR_TYPE_SIZE
< HOST_BITS_PER_WIDE_INT
)
396 val
&= (((unsigned HOST_WIDE_INT
) 1) << CHAR_TYPE_SIZE
) - 1;
399 if (HOST_BITS_PER_CHAR
< HOST_BITS_PER_WIDE_INT
)
400 hostval
&= (((unsigned HOST_WIDE_INT
) 1) << HOST_BITS_PER_CHAR
) - 1;
409 /* Given TEM, a pointer to a stack frame, follow the dynamic chain COUNT
410 times to get the address of either a higher stack frame, or a return
411 address located within it (depending on FNDECL_CODE). */
414 expand_builtin_return_addr (enum built_in_function fndecl_code
, int count
,
419 /* Some machines need special handling before we can access
420 arbitrary frames. For example, on the sparc, we must first flush
421 all register windows to the stack. */
422 #ifdef SETUP_FRAME_ADDRESSES
424 SETUP_FRAME_ADDRESSES ();
427 /* On the sparc, the return address is not in the frame, it is in a
428 register. There is no way to access it off of the current frame
429 pointer, but it can be accessed off the previous frame pointer by
430 reading the value from the register window save area. */
431 #ifdef RETURN_ADDR_IN_PREVIOUS_FRAME
432 if (fndecl_code
== BUILT_IN_RETURN_ADDRESS
)
436 /* Scan back COUNT frames to the specified frame. */
437 for (i
= 0; i
< count
; i
++)
439 /* Assume the dynamic chain pointer is in the word that the
440 frame address points to, unless otherwise specified. */
441 #ifdef DYNAMIC_CHAIN_ADDRESS
442 tem
= DYNAMIC_CHAIN_ADDRESS (tem
);
444 tem
= memory_address (Pmode
, tem
);
445 tem
= gen_rtx_MEM (Pmode
, tem
);
446 set_mem_alias_set (tem
, get_frame_alias_set ());
447 tem
= copy_to_reg (tem
);
450 /* For __builtin_frame_address, return what we've got. */
451 if (fndecl_code
== BUILT_IN_FRAME_ADDRESS
)
454 /* For __builtin_return_address, Get the return address from that
456 #ifdef RETURN_ADDR_RTX
457 tem
= RETURN_ADDR_RTX (count
, tem
);
459 tem
= memory_address (Pmode
,
460 plus_constant (tem
, GET_MODE_SIZE (Pmode
)));
461 tem
= gen_rtx_MEM (Pmode
, tem
);
462 set_mem_alias_set (tem
, get_frame_alias_set ());
467 /* Alias set used for setjmp buffer. */
468 static HOST_WIDE_INT setjmp_alias_set
= -1;
470 /* Construct the leading half of a __builtin_setjmp call. Control will
471 return to RECEIVER_LABEL. This is used directly by sjlj exception
475 expand_builtin_setjmp_setup (rtx buf_addr
, rtx receiver_label
)
477 enum machine_mode sa_mode
= STACK_SAVEAREA_MODE (SAVE_NONLOCAL
);
481 if (setjmp_alias_set
== -1)
482 setjmp_alias_set
= new_alias_set ();
484 buf_addr
= convert_memory_address (Pmode
, buf_addr
);
486 buf_addr
= force_reg (Pmode
, force_operand (buf_addr
, NULL_RTX
));
490 /* We store the frame pointer and the address of receiver_label in
491 the buffer and use the rest of it for the stack save area, which
492 is machine-dependent. */
494 mem
= gen_rtx_MEM (Pmode
, buf_addr
);
495 set_mem_alias_set (mem
, setjmp_alias_set
);
496 emit_move_insn (mem
, targetm
.builtin_setjmp_frame_value ());
498 mem
= gen_rtx_MEM (Pmode
, plus_constant (buf_addr
, GET_MODE_SIZE (Pmode
))),
499 set_mem_alias_set (mem
, setjmp_alias_set
);
501 emit_move_insn (validize_mem (mem
),
502 force_reg (Pmode
, gen_rtx_LABEL_REF (Pmode
, receiver_label
)));
504 stack_save
= gen_rtx_MEM (sa_mode
,
505 plus_constant (buf_addr
,
506 2 * GET_MODE_SIZE (Pmode
)));
507 set_mem_alias_set (stack_save
, setjmp_alias_set
);
508 emit_stack_save (SAVE_NONLOCAL
, &stack_save
, NULL_RTX
);
510 /* If there is further processing to do, do it. */
511 #ifdef HAVE_builtin_setjmp_setup
512 if (HAVE_builtin_setjmp_setup
)
513 emit_insn (gen_builtin_setjmp_setup (buf_addr
));
516 /* Tell optimize_save_area_alloca that extra work is going to
517 need to go on during alloca. */
518 current_function_calls_setjmp
= 1;
520 /* Set this so all the registers get saved in our frame; we need to be
521 able to copy the saved values for any registers from frames we unwind. */
522 current_function_has_nonlocal_label
= 1;
525 /* Construct the trailing part of a __builtin_setjmp call.
526 This is used directly by sjlj exception handling code. */
529 expand_builtin_setjmp_receiver (rtx receiver_label ATTRIBUTE_UNUSED
)
531 /* Clobber the FP when we get here, so we have to make sure it's
532 marked as used by this function. */
533 emit_insn (gen_rtx_USE (VOIDmode
, hard_frame_pointer_rtx
));
535 /* Mark the static chain as clobbered here so life information
536 doesn't get messed up for it. */
537 emit_insn (gen_rtx_CLOBBER (VOIDmode
, static_chain_rtx
));
539 /* Now put in the code to restore the frame pointer, and argument
540 pointer, if needed. The code below is from expand_end_bindings
541 in stmt.c; see detailed documentation there. */
542 #ifdef HAVE_nonlocal_goto
543 if (! HAVE_nonlocal_goto
)
545 emit_move_insn (virtual_stack_vars_rtx
, hard_frame_pointer_rtx
);
547 #if ARG_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
548 if (fixed_regs
[ARG_POINTER_REGNUM
])
550 #ifdef ELIMINABLE_REGS
552 static const struct elims
{const int from
, to
;} elim_regs
[] = ELIMINABLE_REGS
;
554 for (i
= 0; i
< ARRAY_SIZE (elim_regs
); i
++)
555 if (elim_regs
[i
].from
== ARG_POINTER_REGNUM
556 && elim_regs
[i
].to
== HARD_FRAME_POINTER_REGNUM
)
559 if (i
== ARRAY_SIZE (elim_regs
))
562 /* Now restore our arg pointer from the address at which it
563 was saved in our stack frame. */
564 emit_move_insn (virtual_incoming_args_rtx
,
565 copy_to_reg (get_arg_pointer_save_area (cfun
)));
570 #ifdef HAVE_builtin_setjmp_receiver
571 if (HAVE_builtin_setjmp_receiver
)
572 emit_insn (gen_builtin_setjmp_receiver (receiver_label
));
575 #ifdef HAVE_nonlocal_goto_receiver
576 if (HAVE_nonlocal_goto_receiver
)
577 emit_insn (gen_nonlocal_goto_receiver ());
582 /* @@@ This is a kludge. Not all machine descriptions define a blockage
583 insn, but we must not allow the code we just generated to be reordered
584 by scheduling. Specifically, the update of the frame pointer must
585 happen immediately, not later. So emit an ASM_INPUT to act as blockage
587 emit_insn (gen_rtx_ASM_INPUT (VOIDmode
, ""));
590 /* __builtin_setjmp is passed a pointer to an array of five words (not
591 all will be used on all machines). It operates similarly to the C
592 library function of the same name, but is more efficient. Much of
593 the code below (and for longjmp) is copied from the handling of
596 NOTE: This is intended for use by GNAT and the exception handling
597 scheme in the compiler and will only work in the method used by
601 expand_builtin_setjmp (tree arglist
, rtx target
)
603 rtx buf_addr
, next_lab
, cont_lab
;
605 if (!validate_arglist (arglist
, POINTER_TYPE
, VOID_TYPE
))
608 if (target
== 0 || GET_CODE (target
) != REG
609 || REGNO (target
) < FIRST_PSEUDO_REGISTER
)
610 target
= gen_reg_rtx (TYPE_MODE (integer_type_node
));
612 buf_addr
= expand_expr (TREE_VALUE (arglist
), NULL_RTX
, VOIDmode
, 0);
614 next_lab
= gen_label_rtx ();
615 cont_lab
= gen_label_rtx ();
617 expand_builtin_setjmp_setup (buf_addr
, next_lab
);
619 /* Set TARGET to zero and branch to the continue label. Use emit_jump to
620 ensure that pending stack adjustments are flushed. */
621 emit_move_insn (target
, const0_rtx
);
622 emit_jump (cont_lab
);
624 emit_label (next_lab
);
626 expand_builtin_setjmp_receiver (next_lab
);
628 /* Set TARGET to one. */
629 emit_move_insn (target
, const1_rtx
);
630 emit_label (cont_lab
);
632 /* Tell flow about the strange goings on. Putting `next_lab' on
633 `nonlocal_goto_handler_labels' to indicates that function
634 calls may traverse the arc back to this label. */
636 current_function_has_nonlocal_label
= 1;
637 nonlocal_goto_handler_labels
638 = gen_rtx_EXPR_LIST (VOIDmode
, next_lab
, nonlocal_goto_handler_labels
);
643 /* __builtin_longjmp is passed a pointer to an array of five words (not
644 all will be used on all machines). It operates similarly to the C
645 library function of the same name, but is more efficient. Much of
646 the code below is copied from the handling of non-local gotos.
648 NOTE: This is intended for use by GNAT and the exception handling
649 scheme in the compiler and will only work in the method used by
653 expand_builtin_longjmp (rtx buf_addr
, rtx value
)
655 rtx fp
, lab
, stack
, insn
, last
;
656 enum machine_mode sa_mode
= STACK_SAVEAREA_MODE (SAVE_NONLOCAL
);
658 if (setjmp_alias_set
== -1)
659 setjmp_alias_set
= new_alias_set ();
661 buf_addr
= convert_memory_address (Pmode
, buf_addr
);
663 buf_addr
= force_reg (Pmode
, buf_addr
);
665 /* We used to store value in static_chain_rtx, but that fails if pointers
666 are smaller than integers. We instead require that the user must pass
667 a second argument of 1, because that is what builtin_setjmp will
668 return. This also makes EH slightly more efficient, since we are no
669 longer copying around a value that we don't care about. */
670 if (value
!= const1_rtx
)
673 current_function_calls_longjmp
= 1;
675 last
= get_last_insn ();
676 #ifdef HAVE_builtin_longjmp
677 if (HAVE_builtin_longjmp
)
678 emit_insn (gen_builtin_longjmp (buf_addr
));
682 fp
= gen_rtx_MEM (Pmode
, buf_addr
);
683 lab
= gen_rtx_MEM (Pmode
, plus_constant (buf_addr
,
684 GET_MODE_SIZE (Pmode
)));
686 stack
= gen_rtx_MEM (sa_mode
, plus_constant (buf_addr
,
687 2 * GET_MODE_SIZE (Pmode
)));
688 set_mem_alias_set (fp
, setjmp_alias_set
);
689 set_mem_alias_set (lab
, setjmp_alias_set
);
690 set_mem_alias_set (stack
, setjmp_alias_set
);
692 /* Pick up FP, label, and SP from the block and jump. This code is
693 from expand_goto in stmt.c; see there for detailed comments. */
694 #if HAVE_nonlocal_goto
695 if (HAVE_nonlocal_goto
)
696 /* We have to pass a value to the nonlocal_goto pattern that will
697 get copied into the static_chain pointer, but it does not matter
698 what that value is, because builtin_setjmp does not use it. */
699 emit_insn (gen_nonlocal_goto (value
, lab
, stack
, fp
));
703 lab
= copy_to_reg (lab
);
705 emit_insn (gen_rtx_CLOBBER (VOIDmode
,
706 gen_rtx_MEM (BLKmode
,
707 gen_rtx_SCRATCH (VOIDmode
))));
708 emit_insn (gen_rtx_CLOBBER (VOIDmode
,
709 gen_rtx_MEM (BLKmode
,
710 hard_frame_pointer_rtx
)));
712 emit_move_insn (hard_frame_pointer_rtx
, fp
);
713 emit_stack_restore (SAVE_NONLOCAL
, stack
, NULL_RTX
);
715 emit_insn (gen_rtx_USE (VOIDmode
, hard_frame_pointer_rtx
));
716 emit_insn (gen_rtx_USE (VOIDmode
, stack_pointer_rtx
));
717 emit_indirect_jump (lab
);
721 /* Search backwards and mark the jump insn as a non-local goto.
722 Note that this precludes the use of __builtin_longjmp to a
723 __builtin_setjmp target in the same function. However, we've
724 already cautioned the user that these functions are for
725 internal exception handling use only. */
726 for (insn
= get_last_insn (); insn
; insn
= PREV_INSN (insn
))
730 if (GET_CODE (insn
) == JUMP_INSN
)
732 REG_NOTES (insn
) = alloc_EXPR_LIST (REG_NON_LOCAL_GOTO
, const0_rtx
,
736 else if (GET_CODE (insn
) == CALL_INSN
)
741 /* Expand a call to __builtin_prefetch. For a target that does not support
742 data prefetch, evaluate the memory address argument in case it has side
746 expand_builtin_prefetch (tree arglist
)
748 tree arg0
, arg1
, arg2
;
751 if (!validate_arglist (arglist
, POINTER_TYPE
, 0))
754 arg0
= TREE_VALUE (arglist
);
755 /* Arguments 1 and 2 are optional; argument 1 (read/write) defaults to
756 zero (read) and argument 2 (locality) defaults to 3 (high degree of
758 if (TREE_CHAIN (arglist
))
760 arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
761 if (TREE_CHAIN (TREE_CHAIN (arglist
)))
762 arg2
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
764 arg2
= build_int_2 (3, 0);
768 arg1
= integer_zero_node
;
769 arg2
= build_int_2 (3, 0);
772 /* Argument 0 is an address. */
773 op0
= expand_expr (arg0
, NULL_RTX
, Pmode
, EXPAND_NORMAL
);
775 /* Argument 1 (read/write flag) must be a compile-time constant int. */
776 if (TREE_CODE (arg1
) != INTEGER_CST
)
778 error ("second arg to `__builtin_prefetch' must be a constant");
779 arg1
= integer_zero_node
;
781 op1
= expand_expr (arg1
, NULL_RTX
, VOIDmode
, 0);
782 /* Argument 1 must be either zero or one. */
783 if (INTVAL (op1
) != 0 && INTVAL (op1
) != 1)
785 warning ("invalid second arg to __builtin_prefetch; using zero");
789 /* Argument 2 (locality) must be a compile-time constant int. */
790 if (TREE_CODE (arg2
) != INTEGER_CST
)
792 error ("third arg to `__builtin_prefetch' must be a constant");
793 arg2
= integer_zero_node
;
795 op2
= expand_expr (arg2
, NULL_RTX
, VOIDmode
, 0);
796 /* Argument 2 must be 0, 1, 2, or 3. */
797 if (INTVAL (op2
) < 0 || INTVAL (op2
) > 3)
799 warning ("invalid third arg to __builtin_prefetch; using zero");
806 if ((! (*insn_data
[(int) CODE_FOR_prefetch
].operand
[0].predicate
)
808 insn_data
[(int) CODE_FOR_prefetch
].operand
[0].mode
))
809 || (GET_MODE (op0
) != Pmode
))
811 op0
= convert_memory_address (Pmode
, op0
);
812 op0
= force_reg (Pmode
, op0
);
814 emit_insn (gen_prefetch (op0
, op1
, op2
));
818 op0
= protect_from_queue (op0
, 0);
819 /* Don't do anything with direct references to volatile memory, but
820 generate code to handle other side effects. */
821 if (GET_CODE (op0
) != MEM
&& side_effects_p (op0
))
825 /* Get a MEM rtx for expression EXP which is the address of an operand
826 to be used to be used in a string instruction (cmpstrsi, movstrsi, ..). */
829 get_memory_rtx (tree exp
)
831 rtx addr
= expand_expr (exp
, NULL_RTX
, ptr_mode
, EXPAND_SUM
);
834 addr
= convert_memory_address (Pmode
, addr
);
836 mem
= gen_rtx_MEM (BLKmode
, memory_address (BLKmode
, addr
));
838 /* Get an expression we can use to find the attributes to assign to MEM.
839 If it is an ADDR_EXPR, use the operand. Otherwise, dereference it if
840 we can. First remove any nops. */
841 while ((TREE_CODE (exp
) == NOP_EXPR
|| TREE_CODE (exp
) == CONVERT_EXPR
842 || TREE_CODE (exp
) == NON_LVALUE_EXPR
)
843 && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (exp
, 0))))
844 exp
= TREE_OPERAND (exp
, 0);
846 if (TREE_CODE (exp
) == ADDR_EXPR
)
848 exp
= TREE_OPERAND (exp
, 0);
849 set_mem_attributes (mem
, exp
, 0);
851 else if (POINTER_TYPE_P (TREE_TYPE (exp
)))
853 exp
= build1 (INDIRECT_REF
, TREE_TYPE (TREE_TYPE (exp
)), exp
);
854 /* memcpy, memset and other builtin stringops can alias with anything. */
855 set_mem_alias_set (mem
, 0);
861 /* Built-in functions to perform an untyped call and return. */
863 /* For each register that may be used for calling a function, this
864 gives a mode used to copy the register's value. VOIDmode indicates
865 the register is not used for calling a function. If the machine
866 has register windows, this gives only the outbound registers.
867 INCOMING_REGNO gives the corresponding inbound register. */
868 static enum machine_mode apply_args_mode
[FIRST_PSEUDO_REGISTER
];
870 /* For each register that may be used for returning values, this gives
871 a mode used to copy the register's value. VOIDmode indicates the
872 register is not used for returning values. If the machine has
873 register windows, this gives only the outbound registers.
874 INCOMING_REGNO gives the corresponding inbound register. */
875 static enum machine_mode apply_result_mode
[FIRST_PSEUDO_REGISTER
];
877 /* For each register that may be used for calling a function, this
878 gives the offset of that register into the block returned by
879 __builtin_apply_args. 0 indicates that the register is not
880 used for calling a function. */
881 static int apply_args_reg_offset
[FIRST_PSEUDO_REGISTER
];
883 /* Return the size required for the block returned by __builtin_apply_args,
884 and initialize apply_args_mode. */
887 apply_args_size (void)
889 static int size
= -1;
892 enum machine_mode mode
;
894 /* The values computed by this function never change. */
897 /* The first value is the incoming arg-pointer. */
898 size
= GET_MODE_SIZE (Pmode
);
900 /* The second value is the structure value address unless this is
901 passed as an "invisible" first argument. */
902 if (targetm
.calls
.struct_value_rtx (cfun
? TREE_TYPE (cfun
->decl
) : 0, 0))
903 size
+= GET_MODE_SIZE (Pmode
);
905 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
906 if (FUNCTION_ARG_REGNO_P (regno
))
908 mode
= reg_raw_mode
[regno
];
910 if (mode
== VOIDmode
)
913 align
= GET_MODE_ALIGNMENT (mode
) / BITS_PER_UNIT
;
914 if (size
% align
!= 0)
915 size
= CEIL (size
, align
) * align
;
916 apply_args_reg_offset
[regno
] = size
;
917 size
+= GET_MODE_SIZE (mode
);
918 apply_args_mode
[regno
] = mode
;
922 apply_args_mode
[regno
] = VOIDmode
;
923 apply_args_reg_offset
[regno
] = 0;
929 /* Return the size required for the block returned by __builtin_apply,
930 and initialize apply_result_mode. */
933 apply_result_size (void)
935 static int size
= -1;
937 enum machine_mode mode
;
939 /* The values computed by this function never change. */
944 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
945 if (FUNCTION_VALUE_REGNO_P (regno
))
947 mode
= reg_raw_mode
[regno
];
949 if (mode
== VOIDmode
)
952 align
= GET_MODE_ALIGNMENT (mode
) / BITS_PER_UNIT
;
953 if (size
% align
!= 0)
954 size
= CEIL (size
, align
) * align
;
955 size
+= GET_MODE_SIZE (mode
);
956 apply_result_mode
[regno
] = mode
;
959 apply_result_mode
[regno
] = VOIDmode
;
961 /* Allow targets that use untyped_call and untyped_return to override
962 the size so that machine-specific information can be stored here. */
963 #ifdef APPLY_RESULT_SIZE
964 size
= APPLY_RESULT_SIZE
;
970 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
971 /* Create a vector describing the result block RESULT. If SAVEP is true,
972 the result block is used to save the values; otherwise it is used to
973 restore the values. */
976 result_vector (int savep
, rtx result
)
978 int regno
, size
, align
, nelts
;
979 enum machine_mode mode
;
981 rtx
*savevec
= alloca (FIRST_PSEUDO_REGISTER
* sizeof (rtx
));
984 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
985 if ((mode
= apply_result_mode
[regno
]) != VOIDmode
)
987 align
= GET_MODE_ALIGNMENT (mode
) / BITS_PER_UNIT
;
988 if (size
% align
!= 0)
989 size
= CEIL (size
, align
) * align
;
990 reg
= gen_rtx_REG (mode
, savep
? regno
: INCOMING_REGNO (regno
));
991 mem
= adjust_address (result
, mode
, size
);
992 savevec
[nelts
++] = (savep
993 ? gen_rtx_SET (VOIDmode
, mem
, reg
)
994 : gen_rtx_SET (VOIDmode
, reg
, mem
));
995 size
+= GET_MODE_SIZE (mode
);
997 return gen_rtx_PARALLEL (VOIDmode
, gen_rtvec_v (nelts
, savevec
));
999 #endif /* HAVE_untyped_call or HAVE_untyped_return */
1001 /* Save the state required to perform an untyped call with the same
1002 arguments as were passed to the current function. */
1005 expand_builtin_apply_args_1 (void)
1008 int size
, align
, regno
;
1009 enum machine_mode mode
;
1010 rtx struct_incoming_value
= targetm
.calls
.struct_value_rtx (cfun
? TREE_TYPE (cfun
->decl
) : 0, 1);
1012 /* Create a block where the arg-pointer, structure value address,
1013 and argument registers can be saved. */
1014 registers
= assign_stack_local (BLKmode
, apply_args_size (), -1);
1016 /* Walk past the arg-pointer and structure value address. */
1017 size
= GET_MODE_SIZE (Pmode
);
1018 if (targetm
.calls
.struct_value_rtx (cfun
? TREE_TYPE (cfun
->decl
) : 0, 0))
1019 size
+= GET_MODE_SIZE (Pmode
);
1021 /* Save each register used in calling a function to the block. */
1022 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
1023 if ((mode
= apply_args_mode
[regno
]) != VOIDmode
)
1025 align
= GET_MODE_ALIGNMENT (mode
) / BITS_PER_UNIT
;
1026 if (size
% align
!= 0)
1027 size
= CEIL (size
, align
) * align
;
1029 tem
= gen_rtx_REG (mode
, INCOMING_REGNO (regno
));
1031 emit_move_insn (adjust_address (registers
, mode
, size
), tem
);
1032 size
+= GET_MODE_SIZE (mode
);
1035 /* Save the arg pointer to the block. */
1036 tem
= copy_to_reg (virtual_incoming_args_rtx
);
1037 #ifdef STACK_GROWS_DOWNWARD
1038 /* We need the pointer as the caller actually passed them to us, not
1039 as we might have pretended they were passed. Make sure it's a valid
1040 operand, as emit_move_insn isn't expected to handle a PLUS. */
1042 = force_operand (plus_constant (tem
, current_function_pretend_args_size
),
1045 emit_move_insn (adjust_address (registers
, Pmode
, 0), tem
);
1047 size
= GET_MODE_SIZE (Pmode
);
1049 /* Save the structure value address unless this is passed as an
1050 "invisible" first argument. */
1051 if (struct_incoming_value
)
1053 emit_move_insn (adjust_address (registers
, Pmode
, size
),
1054 copy_to_reg (struct_incoming_value
));
1055 size
+= GET_MODE_SIZE (Pmode
);
1058 /* Return the address of the block. */
1059 return copy_addr_to_reg (XEXP (registers
, 0));
1062 /* __builtin_apply_args returns block of memory allocated on
1063 the stack into which is stored the arg pointer, structure
1064 value address, static chain, and all the registers that might
1065 possibly be used in performing a function call. The code is
1066 moved to the start of the function so the incoming values are
1070 expand_builtin_apply_args (void)
1072 /* Don't do __builtin_apply_args more than once in a function.
1073 Save the result of the first call and reuse it. */
1074 if (apply_args_value
!= 0)
1075 return apply_args_value
;
1077 /* When this function is called, it means that registers must be
1078 saved on entry to this function. So we migrate the
1079 call to the first insn of this function. */
1084 temp
= expand_builtin_apply_args_1 ();
1088 apply_args_value
= temp
;
1090 /* Put the insns after the NOTE that starts the function.
1091 If this is inside a start_sequence, make the outer-level insn
1092 chain current, so the code is placed at the start of the
1094 push_topmost_sequence ();
1095 emit_insn_before (seq
, NEXT_INSN (get_insns ()));
1096 pop_topmost_sequence ();
1101 /* Perform an untyped call and save the state required to perform an
1102 untyped return of whatever value was returned by the given function. */
1105 expand_builtin_apply (rtx function
, rtx arguments
, rtx argsize
)
1107 int size
, align
, regno
;
1108 enum machine_mode mode
;
1109 rtx incoming_args
, result
, reg
, dest
, src
, call_insn
;
1110 rtx old_stack_level
= 0;
1111 rtx call_fusage
= 0;
1112 rtx struct_value
= targetm
.calls
.struct_value_rtx (cfun
? TREE_TYPE (cfun
->decl
) : 0, 0);
1114 arguments
= convert_memory_address (Pmode
, arguments
);
1116 /* Create a block where the return registers can be saved. */
1117 result
= assign_stack_local (BLKmode
, apply_result_size (), -1);
1119 /* Fetch the arg pointer from the ARGUMENTS block. */
1120 incoming_args
= gen_reg_rtx (Pmode
);
1121 emit_move_insn (incoming_args
, gen_rtx_MEM (Pmode
, arguments
));
1122 #ifndef STACK_GROWS_DOWNWARD
1123 incoming_args
= expand_simple_binop (Pmode
, MINUS
, incoming_args
, argsize
,
1124 incoming_args
, 0, OPTAB_LIB_WIDEN
);
1127 /* Perform postincrements before actually calling the function. */
1130 /* Push a new argument block and copy the arguments. Do not allow
1131 the (potential) memcpy call below to interfere with our stack
1133 do_pending_stack_adjust ();
1136 /* Save the stack with nonlocal if available. */
1137 #ifdef HAVE_save_stack_nonlocal
1138 if (HAVE_save_stack_nonlocal
)
1139 emit_stack_save (SAVE_NONLOCAL
, &old_stack_level
, NULL_RTX
);
1142 emit_stack_save (SAVE_BLOCK
, &old_stack_level
, NULL_RTX
);
1144 /* Allocate a block of memory onto the stack and copy the memory
1145 arguments to the outgoing arguments address. */
1146 allocate_dynamic_stack_space (argsize
, 0, BITS_PER_UNIT
);
1147 dest
= virtual_outgoing_args_rtx
;
1148 #ifndef STACK_GROWS_DOWNWARD
1149 if (GET_CODE (argsize
) == CONST_INT
)
1150 dest
= plus_constant (dest
, -INTVAL (argsize
));
1152 dest
= gen_rtx_PLUS (Pmode
, dest
, negate_rtx (Pmode
, argsize
));
1154 dest
= gen_rtx_MEM (BLKmode
, dest
);
1155 set_mem_align (dest
, PARM_BOUNDARY
);
1156 src
= gen_rtx_MEM (BLKmode
, incoming_args
);
1157 set_mem_align (src
, PARM_BOUNDARY
);
1158 emit_block_move (dest
, src
, argsize
, BLOCK_OP_NORMAL
);
1160 /* Refer to the argument block. */
1162 arguments
= gen_rtx_MEM (BLKmode
, arguments
);
1163 set_mem_align (arguments
, PARM_BOUNDARY
);
1165 /* Walk past the arg-pointer and structure value address. */
1166 size
= GET_MODE_SIZE (Pmode
);
1168 size
+= GET_MODE_SIZE (Pmode
);
1170 /* Restore each of the registers previously saved. Make USE insns
1171 for each of these registers for use in making the call. */
1172 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
1173 if ((mode
= apply_args_mode
[regno
]) != VOIDmode
)
1175 align
= GET_MODE_ALIGNMENT (mode
) / BITS_PER_UNIT
;
1176 if (size
% align
!= 0)
1177 size
= CEIL (size
, align
) * align
;
1178 reg
= gen_rtx_REG (mode
, regno
);
1179 emit_move_insn (reg
, adjust_address (arguments
, mode
, size
));
1180 use_reg (&call_fusage
, reg
);
1181 size
+= GET_MODE_SIZE (mode
);
1184 /* Restore the structure value address unless this is passed as an
1185 "invisible" first argument. */
1186 size
= GET_MODE_SIZE (Pmode
);
1189 rtx value
= gen_reg_rtx (Pmode
);
1190 emit_move_insn (value
, adjust_address (arguments
, Pmode
, size
));
1191 emit_move_insn (struct_value
, value
);
1192 if (GET_CODE (struct_value
) == REG
)
1193 use_reg (&call_fusage
, struct_value
);
1194 size
+= GET_MODE_SIZE (Pmode
);
1197 /* All arguments and registers used for the call are set up by now! */
1198 function
= prepare_call_address (function
, NULL_TREE
, &call_fusage
, 0, 0);
1200 /* Ensure address is valid. SYMBOL_REF is already valid, so no need,
1201 and we don't want to load it into a register as an optimization,
1202 because prepare_call_address already did it if it should be done. */
1203 if (GET_CODE (function
) != SYMBOL_REF
)
1204 function
= memory_address (FUNCTION_MODE
, function
);
1206 /* Generate the actual call instruction and save the return value. */
1207 #ifdef HAVE_untyped_call
1208 if (HAVE_untyped_call
)
1209 emit_call_insn (gen_untyped_call (gen_rtx_MEM (FUNCTION_MODE
, function
),
1210 result
, result_vector (1, result
)));
1213 #ifdef HAVE_call_value
1214 if (HAVE_call_value
)
1218 /* Locate the unique return register. It is not possible to
1219 express a call that sets more than one return register using
1220 call_value; use untyped_call for that. In fact, untyped_call
1221 only needs to save the return registers in the given block. */
1222 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
1223 if ((mode
= apply_result_mode
[regno
]) != VOIDmode
)
1226 abort (); /* HAVE_untyped_call required. */
1227 valreg
= gen_rtx_REG (mode
, regno
);
1230 emit_call_insn (GEN_CALL_VALUE (valreg
,
1231 gen_rtx_MEM (FUNCTION_MODE
, function
),
1232 const0_rtx
, NULL_RTX
, const0_rtx
));
1234 emit_move_insn (adjust_address (result
, GET_MODE (valreg
), 0), valreg
);
1240 /* Find the CALL insn we just emitted, and attach the register usage
1242 call_insn
= last_call_insn ();
1243 add_function_usage_to (call_insn
, call_fusage
);
1245 /* Restore the stack. */
1246 #ifdef HAVE_save_stack_nonlocal
1247 if (HAVE_save_stack_nonlocal
)
1248 emit_stack_restore (SAVE_NONLOCAL
, old_stack_level
, NULL_RTX
);
1251 emit_stack_restore (SAVE_BLOCK
, old_stack_level
, NULL_RTX
);
1255 /* Return the address of the result block. */
1256 result
= copy_addr_to_reg (XEXP (result
, 0));
1257 return convert_memory_address (ptr_mode
, result
);
1260 /* Perform an untyped return. */
1263 expand_builtin_return (rtx result
)
1265 int size
, align
, regno
;
1266 enum machine_mode mode
;
1268 rtx call_fusage
= 0;
1270 result
= convert_memory_address (Pmode
, result
);
1272 apply_result_size ();
1273 result
= gen_rtx_MEM (BLKmode
, result
);
1275 #ifdef HAVE_untyped_return
1276 if (HAVE_untyped_return
)
1278 emit_jump_insn (gen_untyped_return (result
, result_vector (0, result
)));
1284 /* Restore the return value and note that each value is used. */
1286 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
1287 if ((mode
= apply_result_mode
[regno
]) != VOIDmode
)
1289 align
= GET_MODE_ALIGNMENT (mode
) / BITS_PER_UNIT
;
1290 if (size
% align
!= 0)
1291 size
= CEIL (size
, align
) * align
;
1292 reg
= gen_rtx_REG (mode
, INCOMING_REGNO (regno
));
1293 emit_move_insn (reg
, adjust_address (result
, mode
, size
));
1295 push_to_sequence (call_fusage
);
1296 emit_insn (gen_rtx_USE (VOIDmode
, reg
));
1297 call_fusage
= get_insns ();
1299 size
+= GET_MODE_SIZE (mode
);
1302 /* Put the USE insns before the return. */
1303 emit_insn (call_fusage
);
1305 /* Return whatever values was restored by jumping directly to the end
1307 expand_naked_return ();
1310 /* Used by expand_builtin_classify_type and fold_builtin_classify_type. */
1312 static enum type_class
1313 type_to_class (tree type
)
1315 switch (TREE_CODE (type
))
1317 case VOID_TYPE
: return void_type_class
;
1318 case INTEGER_TYPE
: return integer_type_class
;
1319 case CHAR_TYPE
: return char_type_class
;
1320 case ENUMERAL_TYPE
: return enumeral_type_class
;
1321 case BOOLEAN_TYPE
: return boolean_type_class
;
1322 case POINTER_TYPE
: return pointer_type_class
;
1323 case REFERENCE_TYPE
: return reference_type_class
;
1324 case OFFSET_TYPE
: return offset_type_class
;
1325 case REAL_TYPE
: return real_type_class
;
1326 case COMPLEX_TYPE
: return complex_type_class
;
1327 case FUNCTION_TYPE
: return function_type_class
;
1328 case METHOD_TYPE
: return method_type_class
;
1329 case RECORD_TYPE
: return record_type_class
;
1331 case QUAL_UNION_TYPE
: return union_type_class
;
1332 case ARRAY_TYPE
: return (TYPE_STRING_FLAG (type
)
1333 ? string_type_class
: array_type_class
);
1334 case SET_TYPE
: return set_type_class
;
1335 case FILE_TYPE
: return file_type_class
;
1336 case LANG_TYPE
: return lang_type_class
;
1337 default: return no_type_class
;
1341 /* Expand a call to __builtin_classify_type with arguments found in
1345 expand_builtin_classify_type (tree arglist
)
1348 return GEN_INT (type_to_class (TREE_TYPE (TREE_VALUE (arglist
))));
1349 return GEN_INT (no_type_class
);
1352 /* Expand expression EXP, which is a call to __builtin_constant_p. */
1355 expand_builtin_constant_p (tree arglist
, enum machine_mode target_mode
)
1361 arglist
= TREE_VALUE (arglist
);
1363 /* We have taken care of the easy cases during constant folding. This
1364 case is not obvious, so emit (constant_p_rtx (ARGLIST)) and let CSE
1365 get a chance to see if it can deduce whether ARGLIST is constant.
1366 If CSE isn't going to run, of course, don't bother waiting. */
1368 if (cse_not_expected
)
1371 current_function_calls_constant_p
= 1;
1373 tmp
= expand_expr (arglist
, NULL_RTX
, VOIDmode
, 0);
1374 tmp
= gen_rtx_CONSTANT_P_RTX (target_mode
, tmp
);
1378 /* This helper macro, meant to be used in mathfn_built_in below,
1379 determines which among a set of three builtin math functions is
1380 appropriate for a given type mode. The `F' and `L' cases are
1381 automatically generated from the `double' case. */
1382 #define CASE_MATHFN(BUILT_IN_MATHFN) \
1383 case BUILT_IN_MATHFN: case BUILT_IN_MATHFN##F: case BUILT_IN_MATHFN##L: \
1384 fcode = BUILT_IN_MATHFN; fcodef = BUILT_IN_MATHFN##F ; \
1385 fcodel = BUILT_IN_MATHFN##L ; break;
1387 /* Return mathematic function equivalent to FN but operating directly
1388 on TYPE, if available. If we can't do the conversion, return zero. */
1390 mathfn_built_in (tree type
, enum built_in_function fn
)
1392 enum built_in_function fcode
, fcodef
, fcodel
;
1396 CASE_MATHFN (BUILT_IN_ACOS
)
1397 CASE_MATHFN (BUILT_IN_ACOSH
)
1398 CASE_MATHFN (BUILT_IN_ASIN
)
1399 CASE_MATHFN (BUILT_IN_ASINH
)
1400 CASE_MATHFN (BUILT_IN_ATAN
)
1401 CASE_MATHFN (BUILT_IN_ATAN2
)
1402 CASE_MATHFN (BUILT_IN_ATANH
)
1403 CASE_MATHFN (BUILT_IN_CBRT
)
1404 CASE_MATHFN (BUILT_IN_CEIL
)
1405 CASE_MATHFN (BUILT_IN_COPYSIGN
)
1406 CASE_MATHFN (BUILT_IN_COS
)
1407 CASE_MATHFN (BUILT_IN_COSH
)
1408 CASE_MATHFN (BUILT_IN_DREM
)
1409 CASE_MATHFN (BUILT_IN_ERF
)
1410 CASE_MATHFN (BUILT_IN_ERFC
)
1411 CASE_MATHFN (BUILT_IN_EXP
)
1412 CASE_MATHFN (BUILT_IN_EXP10
)
1413 CASE_MATHFN (BUILT_IN_EXP2
)
1414 CASE_MATHFN (BUILT_IN_EXPM1
)
1415 CASE_MATHFN (BUILT_IN_FABS
)
1416 CASE_MATHFN (BUILT_IN_FDIM
)
1417 CASE_MATHFN (BUILT_IN_FLOOR
)
1418 CASE_MATHFN (BUILT_IN_FMA
)
1419 CASE_MATHFN (BUILT_IN_FMAX
)
1420 CASE_MATHFN (BUILT_IN_FMIN
)
1421 CASE_MATHFN (BUILT_IN_FMOD
)
1422 CASE_MATHFN (BUILT_IN_FREXP
)
1423 CASE_MATHFN (BUILT_IN_GAMMA
)
1424 CASE_MATHFN (BUILT_IN_HUGE_VAL
)
1425 CASE_MATHFN (BUILT_IN_HYPOT
)
1426 CASE_MATHFN (BUILT_IN_ILOGB
)
1427 CASE_MATHFN (BUILT_IN_INF
)
1428 CASE_MATHFN (BUILT_IN_J0
)
1429 CASE_MATHFN (BUILT_IN_J1
)
1430 CASE_MATHFN (BUILT_IN_JN
)
1431 CASE_MATHFN (BUILT_IN_LDEXP
)
1432 CASE_MATHFN (BUILT_IN_LGAMMA
)
1433 CASE_MATHFN (BUILT_IN_LLRINT
)
1434 CASE_MATHFN (BUILT_IN_LLROUND
)
1435 CASE_MATHFN (BUILT_IN_LOG
)
1436 CASE_MATHFN (BUILT_IN_LOG10
)
1437 CASE_MATHFN (BUILT_IN_LOG1P
)
1438 CASE_MATHFN (BUILT_IN_LOG2
)
1439 CASE_MATHFN (BUILT_IN_LOGB
)
1440 CASE_MATHFN (BUILT_IN_LRINT
)
1441 CASE_MATHFN (BUILT_IN_LROUND
)
1442 CASE_MATHFN (BUILT_IN_MODF
)
1443 CASE_MATHFN (BUILT_IN_NAN
)
1444 CASE_MATHFN (BUILT_IN_NANS
)
1445 CASE_MATHFN (BUILT_IN_NEARBYINT
)
1446 CASE_MATHFN (BUILT_IN_NEXTAFTER
)
1447 CASE_MATHFN (BUILT_IN_NEXTTOWARD
)
1448 CASE_MATHFN (BUILT_IN_POW
)
1449 CASE_MATHFN (BUILT_IN_POW10
)
1450 CASE_MATHFN (BUILT_IN_REMAINDER
)
1451 CASE_MATHFN (BUILT_IN_REMQUO
)
1452 CASE_MATHFN (BUILT_IN_RINT
)
1453 CASE_MATHFN (BUILT_IN_ROUND
)
1454 CASE_MATHFN (BUILT_IN_SCALB
)
1455 CASE_MATHFN (BUILT_IN_SCALBLN
)
1456 CASE_MATHFN (BUILT_IN_SCALBN
)
1457 CASE_MATHFN (BUILT_IN_SIGNIFICAND
)
1458 CASE_MATHFN (BUILT_IN_SIN
)
1459 CASE_MATHFN (BUILT_IN_SINCOS
)
1460 CASE_MATHFN (BUILT_IN_SINH
)
1461 CASE_MATHFN (BUILT_IN_SQRT
)
1462 CASE_MATHFN (BUILT_IN_TAN
)
1463 CASE_MATHFN (BUILT_IN_TANH
)
1464 CASE_MATHFN (BUILT_IN_TGAMMA
)
1465 CASE_MATHFN (BUILT_IN_TRUNC
)
1466 CASE_MATHFN (BUILT_IN_Y0
)
1467 CASE_MATHFN (BUILT_IN_Y1
)
1468 CASE_MATHFN (BUILT_IN_YN
)
1474 if (TYPE_MAIN_VARIANT (type
) == double_type_node
)
1475 return implicit_built_in_decls
[fcode
];
1476 else if (TYPE_MAIN_VARIANT (type
) == float_type_node
)
1477 return implicit_built_in_decls
[fcodef
];
1478 else if (TYPE_MAIN_VARIANT (type
) == long_double_type_node
)
1479 return implicit_built_in_decls
[fcodel
];
1484 /* If errno must be maintained, expand the RTL to check if the result,
1485 TARGET, of a built-in function call, EXP, is NaN, and if so set
1489 expand_errno_check (tree exp
, rtx target
)
1491 rtx lab
= gen_label_rtx ();
1493 /* Test the result; if it is NaN, set errno=EDOM because
1494 the argument was not in the domain. */
1495 emit_cmp_and_jump_insns (target
, target
, EQ
, 0, GET_MODE (target
),
1499 /* If this built-in doesn't throw an exception, set errno directly. */
1500 if (TREE_NOTHROW (TREE_OPERAND (TREE_OPERAND (exp
, 0), 0)))
1502 #ifdef GEN_ERRNO_RTX
1503 rtx errno_rtx
= GEN_ERRNO_RTX
;
1506 = gen_rtx_MEM (word_mode
, gen_rtx_SYMBOL_REF (Pmode
, "errno"));
1508 emit_move_insn (errno_rtx
, GEN_INT (TARGET_EDOM
));
1514 /* We can't set errno=EDOM directly; let the library call do it.
1515 Pop the arguments right away in case the call gets deleted. */
1517 expand_call (exp
, target
, 0);
1523 /* Expand a call to one of the builtin math functions (sqrt, exp, or log).
1524 Return 0 if a normal call should be emitted rather than expanding the
1525 function in-line. EXP is the expression that is a call to the builtin
1526 function; if convenient, the result should be placed in TARGET.
1527 SUBTARGET may be used as the target for computing one of EXP's operands. */
1530 expand_builtin_mathfn (tree exp
, rtx target
, rtx subtarget
)
1532 optab builtin_optab
;
1533 rtx op0
, insns
, before_call
;
1534 tree fndecl
= get_callee_fndecl (exp
);
1535 tree arglist
= TREE_OPERAND (exp
, 1);
1536 enum machine_mode mode
;
1537 bool errno_set
= false;
1540 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
1543 arg
= TREE_VALUE (arglist
);
1545 switch (DECL_FUNCTION_CODE (fndecl
))
1548 case BUILT_IN_SQRTF
:
1549 case BUILT_IN_SQRTL
:
1550 errno_set
= ! tree_expr_nonnegative_p (arg
);
1551 builtin_optab
= sqrt_optab
;
1556 errno_set
= true; builtin_optab
= exp_optab
; break;
1557 case BUILT_IN_EXP10
:
1558 case BUILT_IN_EXP10F
:
1559 case BUILT_IN_EXP10L
:
1560 case BUILT_IN_POW10
:
1561 case BUILT_IN_POW10F
:
1562 case BUILT_IN_POW10L
:
1563 errno_set
= true; builtin_optab
= exp10_optab
; break;
1565 case BUILT_IN_EXP2F
:
1566 case BUILT_IN_EXP2L
:
1567 errno_set
= true; builtin_optab
= exp2_optab
; break;
1571 errno_set
= true; builtin_optab
= log_optab
; break;
1572 case BUILT_IN_LOG10
:
1573 case BUILT_IN_LOG10F
:
1574 case BUILT_IN_LOG10L
:
1575 errno_set
= true; builtin_optab
= log10_optab
; break;
1577 case BUILT_IN_LOG2F
:
1578 case BUILT_IN_LOG2L
:
1579 errno_set
= true; builtin_optab
= log2_optab
; break;
1583 builtin_optab
= tan_optab
; break;
1585 case BUILT_IN_ATANF
:
1586 case BUILT_IN_ATANL
:
1587 builtin_optab
= atan_optab
; break;
1588 case BUILT_IN_FLOOR
:
1589 case BUILT_IN_FLOORF
:
1590 case BUILT_IN_FLOORL
:
1591 builtin_optab
= floor_optab
; break;
1593 case BUILT_IN_CEILF
:
1594 case BUILT_IN_CEILL
:
1595 builtin_optab
= ceil_optab
; break;
1596 case BUILT_IN_TRUNC
:
1597 case BUILT_IN_TRUNCF
:
1598 case BUILT_IN_TRUNCL
:
1599 builtin_optab
= btrunc_optab
; break;
1600 case BUILT_IN_ROUND
:
1601 case BUILT_IN_ROUNDF
:
1602 case BUILT_IN_ROUNDL
:
1603 builtin_optab
= round_optab
; break;
1604 case BUILT_IN_NEARBYINT
:
1605 case BUILT_IN_NEARBYINTF
:
1606 case BUILT_IN_NEARBYINTL
:
1607 builtin_optab
= nearbyint_optab
; break;
1612 /* Make a suitable register to place result in. */
1613 mode
= TYPE_MODE (TREE_TYPE (exp
));
1615 if (! flag_errno_math
|| ! HONOR_NANS (mode
))
1618 /* Before working hard, check whether the instruction is available. */
1619 if (builtin_optab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
)
1621 target
= gen_reg_rtx (mode
);
1623 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
1624 need to expand the argument again. This way, we will not perform
1625 side-effects more the once. */
1626 narg
= save_expr (arg
);
1629 arglist
= build_tree_list (NULL_TREE
, arg
);
1630 exp
= build_function_call_expr (fndecl
, arglist
);
1633 op0
= expand_expr (arg
, subtarget
, VOIDmode
, 0);
1638 /* Compute into TARGET.
1639 Set TARGET to wherever the result comes back. */
1640 target
= expand_unop (mode
, builtin_optab
, op0
, target
, 0);
1645 expand_errno_check (exp
, target
);
1647 /* Output the entire sequence. */
1648 insns
= get_insns ();
1654 /* If we were unable to expand via the builtin, stop the sequence
1655 (without outputting the insns) and call to the library function
1656 with the stabilized argument list. */
1660 before_call
= get_last_insn ();
1662 target
= expand_call (exp
, target
, target
== const0_rtx
);
1664 /* If this is a sqrt operation and we don't care about errno, try to
1665 attach a REG_EQUAL note with a SQRT rtx to the emitted libcall.
1666 This allows the semantics of the libcall to be visible to the RTL
1668 if (builtin_optab
== sqrt_optab
&& !errno_set
)
1670 /* Search backwards through the insns emitted by expand_call looking
1671 for the instruction with the REG_RETVAL note. */
1672 rtx last
= get_last_insn ();
1673 while (last
!= before_call
)
1675 if (find_reg_note (last
, REG_RETVAL
, NULL
))
1677 rtx note
= find_reg_note (last
, REG_EQUAL
, NULL
);
1678 /* Check that the REQ_EQUAL note is an EXPR_LIST with
1679 two elements, i.e. symbol_ref(sqrt) and the operand. */
1681 && GET_CODE (note
) == EXPR_LIST
1682 && GET_CODE (XEXP (note
, 0)) == EXPR_LIST
1683 && XEXP (XEXP (note
, 0), 1) != NULL_RTX
1684 && XEXP (XEXP (XEXP (note
, 0), 1), 1) == NULL_RTX
)
1686 rtx operand
= XEXP (XEXP (XEXP (note
, 0), 1), 0);
1687 /* Check operand is a register with expected mode. */
1689 && GET_CODE (operand
) == REG
1690 && GET_MODE (operand
) == mode
)
1692 /* Replace the REG_EQUAL note with a SQRT rtx. */
1693 rtx equiv
= gen_rtx_SQRT (mode
, operand
);
1694 set_unique_reg_note (last
, REG_EQUAL
, equiv
);
1699 last
= PREV_INSN (last
);
1706 /* Expand a call to the builtin binary math functions (pow and atan2).
1707 Return 0 if a normal call should be emitted rather than expanding the
1708 function in-line. EXP is the expression that is a call to the builtin
1709 function; if convenient, the result should be placed in TARGET.
1710 SUBTARGET may be used as the target for computing one of EXP's
1714 expand_builtin_mathfn_2 (tree exp
, rtx target
, rtx subtarget
)
1716 optab builtin_optab
;
1717 rtx op0
, op1
, insns
;
1718 tree fndecl
= get_callee_fndecl (exp
);
1719 tree arglist
= TREE_OPERAND (exp
, 1);
1720 tree arg0
, arg1
, temp
, narg
;
1721 enum machine_mode mode
;
1722 bool errno_set
= true;
1725 if (!validate_arglist (arglist
, REAL_TYPE
, REAL_TYPE
, VOID_TYPE
))
1728 arg0
= TREE_VALUE (arglist
);
1729 arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
1731 switch (DECL_FUNCTION_CODE (fndecl
))
1736 builtin_optab
= pow_optab
; break;
1737 case BUILT_IN_ATAN2
:
1738 case BUILT_IN_ATAN2F
:
1739 case BUILT_IN_ATAN2L
:
1740 builtin_optab
= atan2_optab
; break;
1745 /* Make a suitable register to place result in. */
1746 mode
= TYPE_MODE (TREE_TYPE (exp
));
1748 /* Before working hard, check whether the instruction is available. */
1749 if (builtin_optab
->handlers
[(int) mode
].insn_code
== CODE_FOR_nothing
)
1752 target
= gen_reg_rtx (mode
);
1754 if (! flag_errno_math
|| ! HONOR_NANS (mode
))
1757 /* Alway stabilize the argument list. */
1758 narg
= save_expr (arg1
);
1761 temp
= build_tree_list (NULL_TREE
, narg
);
1765 temp
= TREE_CHAIN (arglist
);
1767 narg
= save_expr (arg0
);
1770 arglist
= tree_cons (NULL_TREE
, narg
, temp
);
1774 arglist
= tree_cons (NULL_TREE
, arg0
, temp
);
1777 exp
= build_function_call_expr (fndecl
, arglist
);
1779 op0
= expand_expr (arg0
, subtarget
, VOIDmode
, 0);
1780 op1
= expand_expr (arg1
, 0, VOIDmode
, 0);
1785 /* Compute into TARGET.
1786 Set TARGET to wherever the result comes back. */
1787 target
= expand_binop (mode
, builtin_optab
, op0
, op1
,
1788 target
, 0, OPTAB_DIRECT
);
1790 /* If we were unable to expand via the builtin, stop the sequence
1791 (without outputting the insns) and call to the library function
1792 with the stabilized argument list. */
1796 return expand_call (exp
, target
, target
== const0_rtx
);
1800 expand_errno_check (exp
, target
);
1802 /* Output the entire sequence. */
1803 insns
= get_insns ();
1810 /* Expand a call to the builtin sin and cos math functions.
1811 Return 0 if a normal call should be emitted rather than expanding the
1812 function in-line. EXP is the expression that is a call to the builtin
1813 function; if convenient, the result should be placed in TARGET.
1814 SUBTARGET may be used as the target for computing one of EXP's
1818 expand_builtin_mathfn_3 (tree exp
, rtx target
, rtx subtarget
)
1820 optab builtin_optab
;
1821 rtx op0
, insns
, before_call
;
1822 tree fndecl
= get_callee_fndecl (exp
);
1823 tree arglist
= TREE_OPERAND (exp
, 1);
1824 enum machine_mode mode
;
1825 bool errno_set
= false;
1828 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
1831 arg
= TREE_VALUE (arglist
);
1833 switch (DECL_FUNCTION_CODE (fndecl
))
1841 builtin_optab
= sincos_optab
; break;
1846 /* Make a suitable register to place result in. */
1847 mode
= TYPE_MODE (TREE_TYPE (exp
));
1849 if (! flag_errno_math
|| ! HONOR_NANS (mode
))
1852 /* Check if sincos insn is available, otherwise fallback
1853 to sin or cos insn. */
1854 if (builtin_optab
->handlers
[(int) mode
].insn_code
== CODE_FOR_nothing
) {
1855 switch (DECL_FUNCTION_CODE (fndecl
))
1860 builtin_optab
= sin_optab
; break;
1864 builtin_optab
= cos_optab
; break;
1870 /* Before working hard, check whether the instruction is available. */
1871 if (builtin_optab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
)
1873 target
= gen_reg_rtx (mode
);
1875 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
1876 need to expand the argument again. This way, we will not perform
1877 side-effects more the once. */
1878 narg
= save_expr (arg
);
1881 arglist
= build_tree_list (NULL_TREE
, arg
);
1882 exp
= build_function_call_expr (fndecl
, arglist
);
1885 op0
= expand_expr (arg
, subtarget
, VOIDmode
, 0);
1890 /* Compute into TARGET.
1891 Set TARGET to wherever the result comes back. */
1892 if (builtin_optab
== sincos_optab
)
1894 switch (DECL_FUNCTION_CODE (fndecl
))
1899 if (! expand_twoval_unop(builtin_optab
, 0, target
, op0
, 0))
1905 if (! expand_twoval_unop(builtin_optab
, target
, 0, op0
, 0))
1914 target
= expand_unop (mode
, builtin_optab
, op0
, target
, 0);
1920 expand_errno_check (exp
, target
);
1922 /* Output the entire sequence. */
1923 insns
= get_insns ();
1929 /* If we were unable to expand via the builtin, stop the sequence
1930 (without outputting the insns) and call to the library function
1931 with the stabilized argument list. */
1935 before_call
= get_last_insn ();
1937 target
= expand_call (exp
, target
, target
== const0_rtx
);
1942 /* To evaluate powi(x,n), the floating point value x raised to the
1943 constant integer exponent n, we use a hybrid algorithm that
1944 combines the "window method" with look-up tables. For an
1945 introduction to exponentiation algorithms and "addition chains",
1946 see section 4.6.3, "Evaluation of Powers" of Donald E. Knuth,
1947 "Seminumerical Algorithms", Vol. 2, "The Art of Computer Programming",
1948 3rd Edition, 1998, and Daniel M. Gordon, "A Survey of Fast Exponentiation
1949 Methods", Journal of Algorithms, Vol. 27, pp. 129-146, 1998. */
1951 /* Provide a default value for POWI_MAX_MULTS, the maximum number of
1952 multiplications to inline before calling the system library's pow
1953 function. powi(x,n) requires at worst 2*bits(n)-2 multiplications,
1954 so this default never requires calling pow, powf or powl. */
1956 #ifndef POWI_MAX_MULTS
1957 #define POWI_MAX_MULTS (2*HOST_BITS_PER_WIDE_INT-2)
1960 /* The size of the "optimal power tree" lookup table. All
1961 exponents less than this value are simply looked up in the
1962 powi_table below. This threshold is also used to size the
1963 cache of pseudo registers that hold intermediate results. */
1964 #define POWI_TABLE_SIZE 256
1966 /* The size, in bits of the window, used in the "window method"
1967 exponentiation algorithm. This is equivalent to a radix of
1968 (1<<POWI_WINDOW_SIZE) in the corresponding "m-ary method". */
1969 #define POWI_WINDOW_SIZE 3
1971 /* The following table is an efficient representation of an
1972 "optimal power tree". For each value, i, the corresponding
1973 value, j, in the table states than an optimal evaluation
1974 sequence for calculating pow(x,i) can be found by evaluating
1975 pow(x,j)*pow(x,i-j). An optimal power tree for the first
1976 100 integers is given in Knuth's "Seminumerical algorithms". */
1978 static const unsigned char powi_table
[POWI_TABLE_SIZE
] =
1980 0, 1, 1, 2, 2, 3, 3, 4, /* 0 - 7 */
1981 4, 6, 5, 6, 6, 10, 7, 9, /* 8 - 15 */
1982 8, 16, 9, 16, 10, 12, 11, 13, /* 16 - 23 */
1983 12, 17, 13, 18, 14, 24, 15, 26, /* 24 - 31 */
1984 16, 17, 17, 19, 18, 33, 19, 26, /* 32 - 39 */
1985 20, 25, 21, 40, 22, 27, 23, 44, /* 40 - 47 */
1986 24, 32, 25, 34, 26, 29, 27, 44, /* 48 - 55 */
1987 28, 31, 29, 34, 30, 60, 31, 36, /* 56 - 63 */
1988 32, 64, 33, 34, 34, 46, 35, 37, /* 64 - 71 */
1989 36, 65, 37, 50, 38, 48, 39, 69, /* 72 - 79 */
1990 40, 49, 41, 43, 42, 51, 43, 58, /* 80 - 87 */
1991 44, 64, 45, 47, 46, 59, 47, 76, /* 88 - 95 */
1992 48, 65, 49, 66, 50, 67, 51, 66, /* 96 - 103 */
1993 52, 70, 53, 74, 54, 104, 55, 74, /* 104 - 111 */
1994 56, 64, 57, 69, 58, 78, 59, 68, /* 112 - 119 */
1995 60, 61, 61, 80, 62, 75, 63, 68, /* 120 - 127 */
1996 64, 65, 65, 128, 66, 129, 67, 90, /* 128 - 135 */
1997 68, 73, 69, 131, 70, 94, 71, 88, /* 136 - 143 */
1998 72, 128, 73, 98, 74, 132, 75, 121, /* 144 - 151 */
1999 76, 102, 77, 124, 78, 132, 79, 106, /* 152 - 159 */
2000 80, 97, 81, 160, 82, 99, 83, 134, /* 160 - 167 */
2001 84, 86, 85, 95, 86, 160, 87, 100, /* 168 - 175 */
2002 88, 113, 89, 98, 90, 107, 91, 122, /* 176 - 183 */
2003 92, 111, 93, 102, 94, 126, 95, 150, /* 184 - 191 */
2004 96, 128, 97, 130, 98, 133, 99, 195, /* 192 - 199 */
2005 100, 128, 101, 123, 102, 164, 103, 138, /* 200 - 207 */
2006 104, 145, 105, 146, 106, 109, 107, 149, /* 208 - 215 */
2007 108, 200, 109, 146, 110, 170, 111, 157, /* 216 - 223 */
2008 112, 128, 113, 130, 114, 182, 115, 132, /* 224 - 231 */
2009 116, 200, 117, 132, 118, 158, 119, 206, /* 232 - 239 */
2010 120, 240, 121, 162, 122, 147, 123, 152, /* 240 - 247 */
2011 124, 166, 125, 214, 126, 138, 127, 153, /* 248 - 255 */
2015 /* Return the number of multiplications required to calculate
2016 powi(x,n) where n is less than POWI_TABLE_SIZE. This is a
2017 subroutine of powi_cost. CACHE is an array indicating
2018 which exponents have already been calculated. */
2021 powi_lookup_cost (unsigned HOST_WIDE_INT n
, bool *cache
)
2023 /* If we've already calculated this exponent, then this evaluation
2024 doesn't require any additional multiplications. */
2029 return powi_lookup_cost (n
- powi_table
[n
], cache
)
2030 + powi_lookup_cost (powi_table
[n
], cache
) + 1;
2033 /* Return the number of multiplications required to calculate
2034 powi(x,n) for an arbitrary x, given the exponent N. This
2035 function needs to be kept in sync with expand_powi below. */
2038 powi_cost (HOST_WIDE_INT n
)
2040 bool cache
[POWI_TABLE_SIZE
];
2041 unsigned HOST_WIDE_INT digit
;
2042 unsigned HOST_WIDE_INT val
;
2048 /* Ignore the reciprocal when calculating the cost. */
2049 val
= (n
< 0) ? -n
: n
;
2051 /* Initialize the exponent cache. */
2052 memset (cache
, 0, POWI_TABLE_SIZE
* sizeof (bool));
2057 while (val
>= POWI_TABLE_SIZE
)
2061 digit
= val
& ((1 << POWI_WINDOW_SIZE
) - 1);
2062 result
+= powi_lookup_cost (digit
, cache
)
2063 + POWI_WINDOW_SIZE
+ 1;
2064 val
>>= POWI_WINDOW_SIZE
;
2073 return result
+ powi_lookup_cost (val
, cache
);
2076 /* Recursive subroutine of expand_powi. This function takes the array,
2077 CACHE, of already calculated exponents and an exponent N and returns
2078 an RTX that corresponds to CACHE[1]**N, as calculated in mode MODE. */
2081 expand_powi_1 (enum machine_mode mode
, unsigned HOST_WIDE_INT n
, rtx
*cache
)
2083 unsigned HOST_WIDE_INT digit
;
2087 if (n
< POWI_TABLE_SIZE
)
2092 target
= gen_reg_rtx (mode
);
2095 op0
= expand_powi_1 (mode
, n
- powi_table
[n
], cache
);
2096 op1
= expand_powi_1 (mode
, powi_table
[n
], cache
);
2100 target
= gen_reg_rtx (mode
);
2101 digit
= n
& ((1 << POWI_WINDOW_SIZE
) - 1);
2102 op0
= expand_powi_1 (mode
, n
- digit
, cache
);
2103 op1
= expand_powi_1 (mode
, digit
, cache
);
2107 target
= gen_reg_rtx (mode
);
2108 op0
= expand_powi_1 (mode
, n
>> 1, cache
);
2112 result
= expand_mult (mode
, op0
, op1
, target
, 0);
2113 if (result
!= target
)
2114 emit_move_insn (target
, result
);
2118 /* Expand the RTL to evaluate powi(x,n) in mode MODE. X is the
2119 floating point operand in mode MODE, and N is the exponent. This
2120 function needs to be kept in sync with powi_cost above. */
2123 expand_powi (rtx x
, enum machine_mode mode
, HOST_WIDE_INT n
)
2125 unsigned HOST_WIDE_INT val
;
2126 rtx cache
[POWI_TABLE_SIZE
];
2130 return CONST1_RTX (mode
);
2132 val
= (n
< 0) ? -n
: n
;
2134 memset (cache
, 0, sizeof (cache
));
2137 result
= expand_powi_1 (mode
, (n
< 0) ? -n
: n
, cache
);
2139 /* If the original exponent was negative, reciprocate the result. */
2141 result
= expand_binop (mode
, sdiv_optab
, CONST1_RTX (mode
),
2142 result
, NULL_RTX
, 0, OPTAB_LIB_WIDEN
);
2147 /* Expand a call to the pow built-in mathematical function. Return 0 if
2148 a normal call should be emitted rather than expanding the function
2149 in-line. EXP is the expression that is a call to the builtin
2150 function; if convenient, the result should be placed in TARGET. */
2153 expand_builtin_pow (tree exp
, rtx target
, rtx subtarget
)
2155 tree arglist
= TREE_OPERAND (exp
, 1);
2158 if (! validate_arglist (arglist
, REAL_TYPE
, REAL_TYPE
, VOID_TYPE
))
2161 arg0
= TREE_VALUE (arglist
);
2162 arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
2164 if (TREE_CODE (arg1
) == REAL_CST
2165 && ! TREE_CONSTANT_OVERFLOW (arg1
))
2167 REAL_VALUE_TYPE cint
;
2171 c
= TREE_REAL_CST (arg1
);
2172 n
= real_to_integer (&c
);
2173 real_from_integer (&cint
, VOIDmode
, n
, n
< 0 ? -1 : 0, 0);
2174 if (real_identical (&c
, &cint
))
2176 /* If the exponent is -1, 0, 1 or 2, then expand_powi is exact.
2177 Otherwise, check the number of multiplications required.
2178 Note that pow never sets errno for an integer exponent. */
2179 if ((n
>= -1 && n
<= 2)
2180 || (flag_unsafe_math_optimizations
2182 && powi_cost (n
) <= POWI_MAX_MULTS
))
2184 enum machine_mode mode
= TYPE_MODE (TREE_TYPE (exp
));
2185 rtx op
= expand_expr (arg0
, subtarget
, VOIDmode
, 0);
2186 op
= force_reg (mode
, op
);
2187 return expand_powi (op
, mode
, n
);
2192 if (! flag_unsafe_math_optimizations
)
2194 return expand_builtin_mathfn_2 (exp
, target
, subtarget
);
2197 /* Expand expression EXP which is a call to the strlen builtin. Return 0
2198 if we failed the caller should emit a normal call, otherwise
2199 try to get the result in TARGET, if convenient. */
2202 expand_builtin_strlen (tree arglist
, rtx target
,
2203 enum machine_mode target_mode
)
2205 if (!validate_arglist (arglist
, POINTER_TYPE
, VOID_TYPE
))
2210 tree len
, src
= TREE_VALUE (arglist
);
2211 rtx result
, src_reg
, char_rtx
, before_strlen
;
2212 enum machine_mode insn_mode
= target_mode
, char_mode
;
2213 enum insn_code icode
= CODE_FOR_nothing
;
2216 /* If the length can be computed at compile-time, return it. */
2217 len
= c_strlen (src
, 0);
2219 return expand_expr (len
, target
, target_mode
, EXPAND_NORMAL
);
2221 /* If the length can be computed at compile-time and is constant
2222 integer, but there are side-effects in src, evaluate
2223 src for side-effects, then return len.
2224 E.g. x = strlen (i++ ? "xfoo" + 1 : "bar");
2225 can be optimized into: i++; x = 3; */
2226 len
= c_strlen (src
, 1);
2227 if (len
&& TREE_CODE (len
) == INTEGER_CST
)
2229 expand_expr (src
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
2230 return expand_expr (len
, target
, target_mode
, EXPAND_NORMAL
);
2233 align
= get_pointer_alignment (src
, BIGGEST_ALIGNMENT
) / BITS_PER_UNIT
;
2235 /* If SRC is not a pointer type, don't do this operation inline. */
2239 /* Bail out if we can't compute strlen in the right mode. */
2240 while (insn_mode
!= VOIDmode
)
2242 icode
= strlen_optab
->handlers
[(int) insn_mode
].insn_code
;
2243 if (icode
!= CODE_FOR_nothing
)
2246 insn_mode
= GET_MODE_WIDER_MODE (insn_mode
);
2248 if (insn_mode
== VOIDmode
)
2251 /* Make a place to write the result of the instruction. */
2254 && GET_CODE (result
) == REG
2255 && GET_MODE (result
) == insn_mode
2256 && REGNO (result
) >= FIRST_PSEUDO_REGISTER
))
2257 result
= gen_reg_rtx (insn_mode
);
2259 /* Make a place to hold the source address. We will not expand
2260 the actual source until we are sure that the expansion will
2261 not fail -- there are trees that cannot be expanded twice. */
2262 src_reg
= gen_reg_rtx (Pmode
);
2264 /* Mark the beginning of the strlen sequence so we can emit the
2265 source operand later. */
2266 before_strlen
= get_last_insn ();
2268 char_rtx
= const0_rtx
;
2269 char_mode
= insn_data
[(int) icode
].operand
[2].mode
;
2270 if (! (*insn_data
[(int) icode
].operand
[2].predicate
) (char_rtx
,
2272 char_rtx
= copy_to_mode_reg (char_mode
, char_rtx
);
2274 pat
= GEN_FCN (icode
) (result
, gen_rtx_MEM (BLKmode
, src_reg
),
2275 char_rtx
, GEN_INT (align
));
2280 /* Now that we are assured of success, expand the source. */
2282 pat
= memory_address (BLKmode
,
2283 expand_expr (src
, src_reg
, ptr_mode
, EXPAND_SUM
));
2285 emit_move_insn (src_reg
, pat
);
2290 emit_insn_after (pat
, before_strlen
);
2292 emit_insn_before (pat
, get_insns ());
2294 /* Return the value in the proper mode for this function. */
2295 if (GET_MODE (result
) == target_mode
)
2297 else if (target
!= 0)
2298 convert_move (target
, result
, 0);
2300 target
= convert_to_mode (target_mode
, result
, 0);
2306 /* Expand a call to the strstr builtin. Return 0 if we failed the
2307 caller should emit a normal call, otherwise try to get the result
2308 in TARGET, if convenient (and in mode MODE if that's convenient). */
2311 expand_builtin_strstr (tree arglist
, rtx target
, enum machine_mode mode
)
2313 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
2317 tree s1
= TREE_VALUE (arglist
), s2
= TREE_VALUE (TREE_CHAIN (arglist
));
2319 const char *p1
, *p2
;
2328 const char *r
= strstr (p1
, p2
);
2333 /* Return an offset into the constant string argument. */
2334 return expand_expr (fold (build (PLUS_EXPR
, TREE_TYPE (s1
),
2335 s1
, convert (TREE_TYPE (s1
),
2336 ssize_int (r
- p1
)))),
2337 target
, mode
, EXPAND_NORMAL
);
2341 return expand_expr (s1
, target
, mode
, EXPAND_NORMAL
);
2346 fn
= implicit_built_in_decls
[BUILT_IN_STRCHR
];
2350 /* New argument list transforming strstr(s1, s2) to
2351 strchr(s1, s2[0]). */
2353 build_tree_list (NULL_TREE
, build_int_2 (p2
[0], 0));
2354 arglist
= tree_cons (NULL_TREE
, s1
, arglist
);
2355 return expand_expr (build_function_call_expr (fn
, arglist
),
2356 target
, mode
, EXPAND_NORMAL
);
2360 /* Expand a call to the strchr builtin. Return 0 if we failed the
2361 caller should emit a normal call, otherwise try to get the result
2362 in TARGET, if convenient (and in mode MODE if that's convenient). */
2365 expand_builtin_strchr (tree arglist
, rtx target
, enum machine_mode mode
)
2367 if (!validate_arglist (arglist
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
2371 tree s1
= TREE_VALUE (arglist
), s2
= TREE_VALUE (TREE_CHAIN (arglist
));
2374 if (TREE_CODE (s2
) != INTEGER_CST
)
2383 if (target_char_cast (s2
, &c
))
2391 /* Return an offset into the constant string argument. */
2392 return expand_expr (fold (build (PLUS_EXPR
, TREE_TYPE (s1
),
2393 s1
, convert (TREE_TYPE (s1
),
2394 ssize_int (r
- p1
)))),
2395 target
, mode
, EXPAND_NORMAL
);
2398 /* FIXME: Should use here strchrM optab so that ports can optimize
2404 /* Expand a call to the strrchr builtin. Return 0 if we failed the
2405 caller should emit a normal call, otherwise try to get the result
2406 in TARGET, if convenient (and in mode MODE if that's convenient). */
2409 expand_builtin_strrchr (tree arglist
, rtx target
, enum machine_mode mode
)
2411 if (!validate_arglist (arglist
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
2415 tree s1
= TREE_VALUE (arglist
), s2
= TREE_VALUE (TREE_CHAIN (arglist
));
2419 if (TREE_CODE (s2
) != INTEGER_CST
)
2428 if (target_char_cast (s2
, &c
))
2431 r
= strrchr (p1
, c
);
2436 /* Return an offset into the constant string argument. */
2437 return expand_expr (fold (build (PLUS_EXPR
, TREE_TYPE (s1
),
2438 s1
, convert (TREE_TYPE (s1
),
2439 ssize_int (r
- p1
)))),
2440 target
, mode
, EXPAND_NORMAL
);
2443 if (! integer_zerop (s2
))
2446 fn
= implicit_built_in_decls
[BUILT_IN_STRCHR
];
2450 /* Transform strrchr(s1, '\0') to strchr(s1, '\0'). */
2451 return expand_expr (build_function_call_expr (fn
, arglist
),
2452 target
, mode
, EXPAND_NORMAL
);
2456 /* Expand a call to the strpbrk builtin. Return 0 if we failed the
2457 caller should emit a normal call, otherwise try to get the result
2458 in TARGET, if convenient (and in mode MODE if that's convenient). */
2461 expand_builtin_strpbrk (tree arglist
, rtx target
, enum machine_mode mode
)
2463 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
2467 tree s1
= TREE_VALUE (arglist
), s2
= TREE_VALUE (TREE_CHAIN (arglist
));
2469 const char *p1
, *p2
;
2478 const char *r
= strpbrk (p1
, p2
);
2483 /* Return an offset into the constant string argument. */
2484 return expand_expr (fold (build (PLUS_EXPR
, TREE_TYPE (s1
),
2485 s1
, convert (TREE_TYPE (s1
),
2486 ssize_int (r
- p1
)))),
2487 target
, mode
, EXPAND_NORMAL
);
2492 /* strpbrk(x, "") == NULL.
2493 Evaluate and ignore the arguments in case they had
2495 expand_expr (s1
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
2500 return 0; /* Really call strpbrk. */
2502 fn
= implicit_built_in_decls
[BUILT_IN_STRCHR
];
2506 /* New argument list transforming strpbrk(s1, s2) to
2507 strchr(s1, s2[0]). */
2509 build_tree_list (NULL_TREE
, build_int_2 (p2
[0], 0));
2510 arglist
= tree_cons (NULL_TREE
, s1
, arglist
);
2511 return expand_expr (build_function_call_expr (fn
, arglist
),
2512 target
, mode
, EXPAND_NORMAL
);
2516 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
2517 bytes from constant string DATA + OFFSET and return it as target
2521 builtin_memcpy_read_str (void *data
, HOST_WIDE_INT offset
,
2522 enum machine_mode mode
)
2524 const char *str
= (const char *) data
;
2527 || ((unsigned HOST_WIDE_INT
) offset
+ GET_MODE_SIZE (mode
)
2528 > strlen (str
) + 1))
2529 abort (); /* Attempt to read past the end of constant string. */
2531 return c_readstr (str
+ offset
, mode
);
2534 /* Expand a call to the memcpy builtin, with arguments in ARGLIST.
2535 Return 0 if we failed, the caller should emit a normal call,
2536 otherwise try to get the result in TARGET, if convenient (and in
2537 mode MODE if that's convenient). */
2539 expand_builtin_memcpy (tree arglist
, rtx target
, enum machine_mode mode
)
2541 if (!validate_arglist (arglist
,
2542 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
2546 tree dest
= TREE_VALUE (arglist
);
2547 tree src
= TREE_VALUE (TREE_CHAIN (arglist
));
2548 tree len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
2549 const char *src_str
;
2550 unsigned int src_align
= get_pointer_alignment (src
, BIGGEST_ALIGNMENT
);
2551 unsigned int dest_align
2552 = get_pointer_alignment (dest
, BIGGEST_ALIGNMENT
);
2553 rtx dest_mem
, src_mem
, dest_addr
, len_rtx
;
2555 /* If DEST is not a pointer type, call the normal function. */
2556 if (dest_align
== 0)
2559 /* If the LEN parameter is zero, return DEST. */
2560 if (integer_zerop (len
))
2562 /* Evaluate and ignore SRC in case it has side-effects. */
2563 expand_expr (src
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
2564 return expand_expr (dest
, target
, mode
, EXPAND_NORMAL
);
2567 /* If SRC and DEST are the same (and not volatile), return DEST. */
2568 if (operand_equal_p (src
, dest
, 0))
2570 /* Evaluate and ignore LEN in case it has side-effects. */
2571 expand_expr (len
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
2572 return expand_expr (dest
, target
, mode
, EXPAND_NORMAL
);
2575 /* If either SRC is not a pointer type, don't do this
2576 operation in-line. */
2580 dest_mem
= get_memory_rtx (dest
);
2581 set_mem_align (dest_mem
, dest_align
);
2582 len_rtx
= expand_expr (len
, NULL_RTX
, VOIDmode
, 0);
2583 src_str
= c_getstr (src
);
2585 /* If SRC is a string constant and block move would be done
2586 by pieces, we can avoid loading the string from memory
2587 and only stored the computed constants. */
2589 && GET_CODE (len_rtx
) == CONST_INT
2590 && (unsigned HOST_WIDE_INT
) INTVAL (len_rtx
) <= strlen (src_str
) + 1
2591 && can_store_by_pieces (INTVAL (len_rtx
), builtin_memcpy_read_str
,
2592 (void *) src_str
, dest_align
))
2594 dest_mem
= store_by_pieces (dest_mem
, INTVAL (len_rtx
),
2595 builtin_memcpy_read_str
,
2596 (void *) src_str
, dest_align
, 0);
2597 dest_mem
= force_operand (XEXP (dest_mem
, 0), NULL_RTX
);
2598 dest_mem
= convert_memory_address (ptr_mode
, dest_mem
);
2602 src_mem
= get_memory_rtx (src
);
2603 set_mem_align (src_mem
, src_align
);
2605 /* Copy word part most expediently. */
2606 dest_addr
= emit_block_move (dest_mem
, src_mem
, len_rtx
,
2611 dest_addr
= force_operand (XEXP (dest_mem
, 0), NULL_RTX
);
2612 dest_addr
= convert_memory_address (ptr_mode
, dest_addr
);
2618 /* Expand a call to the mempcpy builtin, with arguments in ARGLIST.
2619 Return 0 if we failed the caller should emit a normal call,
2620 otherwise try to get the result in TARGET, if convenient (and in
2621 mode MODE if that's convenient). If ENDP is 0 return the
2622 destination pointer, if ENDP is 1 return the end pointer ala
2623 mempcpy, and if ENDP is 2 return the end pointer minus one ala
2627 expand_builtin_mempcpy (tree arglist
, rtx target
, enum machine_mode mode
,
2630 if (!validate_arglist (arglist
,
2631 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
2633 /* If return value is ignored, transform mempcpy into memcpy. */
2634 else if (target
== const0_rtx
)
2636 tree fn
= implicit_built_in_decls
[BUILT_IN_MEMCPY
];
2641 return expand_expr (build_function_call_expr (fn
, arglist
),
2642 target
, mode
, EXPAND_NORMAL
);
2646 tree dest
= TREE_VALUE (arglist
);
2647 tree src
= TREE_VALUE (TREE_CHAIN (arglist
));
2648 tree len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
2649 const char *src_str
;
2650 unsigned int src_align
= get_pointer_alignment (src
, BIGGEST_ALIGNMENT
);
2651 unsigned int dest_align
2652 = get_pointer_alignment (dest
, BIGGEST_ALIGNMENT
);
2653 rtx dest_mem
, src_mem
, len_rtx
;
2655 /* If DEST is not a pointer type, call the normal function. */
2656 if (dest_align
== 0)
2659 /* If SRC and DEST are the same (and not volatile), do nothing. */
2660 if (operand_equal_p (src
, dest
, 0))
2666 /* Evaluate and ignore LEN in case it has side-effects. */
2667 expand_expr (len
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
2668 return expand_expr (dest
, target
, mode
, EXPAND_NORMAL
);
2672 len
= fold (build (MINUS_EXPR
, TREE_TYPE (len
), dest
,
2674 len
= convert (TREE_TYPE (dest
), len
);
2675 expr
= fold (build (PLUS_EXPR
, TREE_TYPE (dest
), dest
, len
));
2676 return expand_expr (expr
, target
, mode
, EXPAND_NORMAL
);
2679 /* If LEN is not constant, call the normal function. */
2680 if (! host_integerp (len
, 1))
2683 /* If the LEN parameter is zero, return DEST. */
2684 if (tree_low_cst (len
, 1) == 0)
2686 /* Evaluate and ignore SRC in case it has side-effects. */
2687 expand_expr (src
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
2688 return expand_expr (dest
, target
, mode
, EXPAND_NORMAL
);
2691 /* If either SRC is not a pointer type, don't do this
2692 operation in-line. */
2696 len_rtx
= expand_expr (len
, NULL_RTX
, VOIDmode
, 0);
2697 src_str
= c_getstr (src
);
2699 /* If SRC is a string constant and block move would be done
2700 by pieces, we can avoid loading the string from memory
2701 and only stored the computed constants. */
2703 && GET_CODE (len_rtx
) == CONST_INT
2704 && (unsigned HOST_WIDE_INT
) INTVAL (len_rtx
) <= strlen (src_str
) + 1
2705 && can_store_by_pieces (INTVAL (len_rtx
), builtin_memcpy_read_str
,
2706 (void *) src_str
, dest_align
))
2708 dest_mem
= get_memory_rtx (dest
);
2709 set_mem_align (dest_mem
, dest_align
);
2710 dest_mem
= store_by_pieces (dest_mem
, INTVAL (len_rtx
),
2711 builtin_memcpy_read_str
,
2712 (void *) src_str
, dest_align
, endp
);
2713 dest_mem
= force_operand (XEXP (dest_mem
, 0), NULL_RTX
);
2714 dest_mem
= convert_memory_address (ptr_mode
, dest_mem
);
2718 if (GET_CODE (len_rtx
) == CONST_INT
2719 && can_move_by_pieces (INTVAL (len_rtx
),
2720 MIN (dest_align
, src_align
)))
2722 dest_mem
= get_memory_rtx (dest
);
2723 set_mem_align (dest_mem
, dest_align
);
2724 src_mem
= get_memory_rtx (src
);
2725 set_mem_align (src_mem
, src_align
);
2726 dest_mem
= move_by_pieces (dest_mem
, src_mem
, INTVAL (len_rtx
),
2727 MIN (dest_align
, src_align
), endp
);
2728 dest_mem
= force_operand (XEXP (dest_mem
, 0), NULL_RTX
);
2729 dest_mem
= convert_memory_address (ptr_mode
, dest_mem
);
2737 /* Expand expression EXP, which is a call to the memmove builtin. Return 0
2738 if we failed the caller should emit a normal call. */
2741 expand_builtin_memmove (tree arglist
, rtx target
, enum machine_mode mode
)
2743 if (!validate_arglist (arglist
,
2744 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
2748 tree dest
= TREE_VALUE (arglist
);
2749 tree src
= TREE_VALUE (TREE_CHAIN (arglist
));
2750 tree len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
2752 unsigned int src_align
= get_pointer_alignment (src
, BIGGEST_ALIGNMENT
);
2753 unsigned int dest_align
2754 = get_pointer_alignment (dest
, BIGGEST_ALIGNMENT
);
2756 /* If DEST is not a pointer type, call the normal function. */
2757 if (dest_align
== 0)
2760 /* If the LEN parameter is zero, return DEST. */
2761 if (integer_zerop (len
))
2763 /* Evaluate and ignore SRC in case it has side-effects. */
2764 expand_expr (src
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
2765 return expand_expr (dest
, target
, mode
, EXPAND_NORMAL
);
2768 /* If SRC and DEST are the same (and not volatile), return DEST. */
2769 if (operand_equal_p (src
, dest
, 0))
2771 /* Evaluate and ignore LEN in case it has side-effects. */
2772 expand_expr (len
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
2773 return expand_expr (dest
, target
, mode
, EXPAND_NORMAL
);
2776 /* If either SRC is not a pointer type, don't do this
2777 operation in-line. */
2781 /* If src is categorized for a readonly section we can use
2783 if (readonly_data_expr (src
))
2785 tree
const fn
= implicit_built_in_decls
[BUILT_IN_MEMCPY
];
2788 return expand_expr (build_function_call_expr (fn
, arglist
),
2789 target
, mode
, EXPAND_NORMAL
);
2792 /* Otherwise, call the normal function. */
2797 /* Expand expression EXP, which is a call to the bcopy builtin. Return 0
2798 if we failed the caller should emit a normal call. */
2801 expand_builtin_bcopy (tree arglist
)
2803 tree src
, dest
, size
, newarglist
;
2805 if (!validate_arglist (arglist
,
2806 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
2809 src
= TREE_VALUE (arglist
);
2810 dest
= TREE_VALUE (TREE_CHAIN (arglist
));
2811 size
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
2813 /* New argument list transforming bcopy(ptr x, ptr y, int z) to
2814 memmove(ptr y, ptr x, size_t z). This is done this way
2815 so that if it isn't expanded inline, we fallback to
2816 calling bcopy instead of memmove. */
2818 newarglist
= build_tree_list (NULL_TREE
, convert (sizetype
, size
));
2819 newarglist
= tree_cons (NULL_TREE
, src
, newarglist
);
2820 newarglist
= tree_cons (NULL_TREE
, dest
, newarglist
);
2822 return expand_builtin_memmove (newarglist
, const0_rtx
, VOIDmode
);
2825 /* Expand expression EXP, which is a call to the strcpy builtin. Return 0
2826 if we failed the caller should emit a normal call, otherwise try to get
2827 the result in TARGET, if convenient (and in mode MODE if that's
2831 expand_builtin_strcpy (tree arglist
, rtx target
, enum machine_mode mode
)
2833 tree fn
, len
, src
, dst
;
2835 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
2838 src
= TREE_VALUE (TREE_CHAIN (arglist
));
2839 dst
= TREE_VALUE (arglist
);
2841 /* If SRC and DST are equal (and not volatile), return DST. */
2842 if (operand_equal_p (src
, dst
, 0))
2843 return expand_expr (dst
, target
, mode
, EXPAND_NORMAL
);
2845 fn
= implicit_built_in_decls
[BUILT_IN_MEMCPY
];
2849 len
= c_strlen (src
, 1);
2850 if (len
== 0 || TREE_SIDE_EFFECTS (len
))
2853 len
= size_binop (PLUS_EXPR
, len
, ssize_int (1));
2854 arglist
= build_tree_list (NULL_TREE
, len
);
2855 arglist
= tree_cons (NULL_TREE
, src
, arglist
);
2856 arglist
= tree_cons (NULL_TREE
, dst
, arglist
);
2857 return expand_expr (build_function_call_expr (fn
, arglist
),
2858 target
, mode
, EXPAND_NORMAL
);
2861 /* Expand a call to the stpcpy builtin, with arguments in ARGLIST.
2862 Return 0 if we failed the caller should emit a normal call,
2863 otherwise try to get the result in TARGET, if convenient (and in
2864 mode MODE if that's convenient). */
2867 expand_builtin_stpcpy (tree arglist
, rtx target
, enum machine_mode mode
)
2869 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
2875 /* If return value is ignored, transform stpcpy into strcpy. */
2876 if (target
== const0_rtx
)
2878 tree fn
= implicit_built_in_decls
[BUILT_IN_STRCPY
];
2882 return expand_expr (build_function_call_expr (fn
, arglist
),
2883 target
, mode
, EXPAND_NORMAL
);
2886 /* Ensure we get an actual string whose length can be evaluated at
2887 compile-time, not an expression containing a string. This is
2888 because the latter will potentially produce pessimized code
2889 when used to produce the return value. */
2890 src
= TREE_VALUE (TREE_CHAIN (arglist
));
2891 if (! c_getstr (src
) || ! (len
= c_strlen (src
, 0)))
2894 dst
= TREE_VALUE (arglist
);
2895 len
= fold (size_binop (PLUS_EXPR
, len
, ssize_int (1)));
2896 arglist
= build_tree_list (NULL_TREE
, len
);
2897 arglist
= tree_cons (NULL_TREE
, src
, arglist
);
2898 arglist
= tree_cons (NULL_TREE
, dst
, arglist
);
2899 return expand_builtin_mempcpy (arglist
, target
, mode
, /*endp=*/2);
2903 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
2904 bytes from constant string DATA + OFFSET and return it as target
2908 builtin_strncpy_read_str (void *data
, HOST_WIDE_INT offset
,
2909 enum machine_mode mode
)
2911 const char *str
= (const char *) data
;
2913 if ((unsigned HOST_WIDE_INT
) offset
> strlen (str
))
2916 return c_readstr (str
+ offset
, mode
);
2919 /* Expand expression EXP, which is a call to the strncpy builtin. Return 0
2920 if we failed the caller should emit a normal call. */
2923 expand_builtin_strncpy (tree arglist
, rtx target
, enum machine_mode mode
)
2925 if (!validate_arglist (arglist
,
2926 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
2930 tree slen
= c_strlen (TREE_VALUE (TREE_CHAIN (arglist
)), 1);
2931 tree len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
2934 /* We must be passed a constant len parameter. */
2935 if (TREE_CODE (len
) != INTEGER_CST
)
2938 /* If the len parameter is zero, return the dst parameter. */
2939 if (integer_zerop (len
))
2941 /* Evaluate and ignore the src argument in case it has
2943 expand_expr (TREE_VALUE (TREE_CHAIN (arglist
)), const0_rtx
,
2944 VOIDmode
, EXPAND_NORMAL
);
2945 /* Return the dst parameter. */
2946 return expand_expr (TREE_VALUE (arglist
), target
, mode
,
2950 /* Now, we must be passed a constant src ptr parameter. */
2951 if (slen
== 0 || TREE_CODE (slen
) != INTEGER_CST
)
2954 slen
= size_binop (PLUS_EXPR
, slen
, ssize_int (1));
2956 /* We're required to pad with trailing zeros if the requested
2957 len is greater than strlen(s2)+1. In that case try to
2958 use store_by_pieces, if it fails, punt. */
2959 if (tree_int_cst_lt (slen
, len
))
2961 tree dest
= TREE_VALUE (arglist
);
2962 unsigned int dest_align
2963 = get_pointer_alignment (dest
, BIGGEST_ALIGNMENT
);
2964 const char *p
= c_getstr (TREE_VALUE (TREE_CHAIN (arglist
)));
2967 if (!p
|| dest_align
== 0 || !host_integerp (len
, 1)
2968 || !can_store_by_pieces (tree_low_cst (len
, 1),
2969 builtin_strncpy_read_str
,
2970 (void *) p
, dest_align
))
2973 dest_mem
= get_memory_rtx (dest
);
2974 store_by_pieces (dest_mem
, tree_low_cst (len
, 1),
2975 builtin_strncpy_read_str
,
2976 (void *) p
, dest_align
, 0);
2977 dest_mem
= force_operand (XEXP (dest_mem
, 0), NULL_RTX
);
2978 dest_mem
= convert_memory_address (ptr_mode
, dest_mem
);
2982 /* OK transform into builtin memcpy. */
2983 fn
= implicit_built_in_decls
[BUILT_IN_MEMCPY
];
2986 return expand_expr (build_function_call_expr (fn
, arglist
),
2987 target
, mode
, EXPAND_NORMAL
);
2991 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
2992 bytes from constant string DATA + OFFSET and return it as target
2996 builtin_memset_read_str (void *data
, HOST_WIDE_INT offset ATTRIBUTE_UNUSED
,
2997 enum machine_mode mode
)
2999 const char *c
= (const char *) data
;
3000 char *p
= alloca (GET_MODE_SIZE (mode
));
3002 memset (p
, *c
, GET_MODE_SIZE (mode
));
3004 return c_readstr (p
, mode
);
3007 /* Callback routine for store_by_pieces. Return the RTL of a register
3008 containing GET_MODE_SIZE (MODE) consecutive copies of the unsigned
3009 char value given in the RTL register data. For example, if mode is
3010 4 bytes wide, return the RTL for 0x01010101*data. */
3013 builtin_memset_gen_str (void *data
, HOST_WIDE_INT offset ATTRIBUTE_UNUSED
,
3014 enum machine_mode mode
)
3020 size
= GET_MODE_SIZE (mode
);
3025 memset (p
, 1, size
);
3026 coeff
= c_readstr (p
, mode
);
3028 target
= convert_to_mode (mode
, (rtx
) data
, 1);
3029 target
= expand_mult (mode
, target
, coeff
, NULL_RTX
, 1);
3030 return force_reg (mode
, target
);
3033 /* Expand expression EXP, which is a call to the memset builtin. Return 0
3034 if we failed the caller should emit a normal call, otherwise try to get
3035 the result in TARGET, if convenient (and in mode MODE if that's
3039 expand_builtin_memset (tree arglist
, rtx target
, enum machine_mode mode
)
3041 if (!validate_arglist (arglist
,
3042 POINTER_TYPE
, INTEGER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
3046 tree dest
= TREE_VALUE (arglist
);
3047 tree val
= TREE_VALUE (TREE_CHAIN (arglist
));
3048 tree len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
3051 unsigned int dest_align
3052 = get_pointer_alignment (dest
, BIGGEST_ALIGNMENT
);
3053 rtx dest_mem
, dest_addr
, len_rtx
;
3055 /* If DEST is not a pointer type, don't do this
3056 operation in-line. */
3057 if (dest_align
== 0)
3060 /* If the LEN parameter is zero, return DEST. */
3061 if (integer_zerop (len
))
3063 /* Evaluate and ignore VAL in case it has side-effects. */
3064 expand_expr (val
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
3065 return expand_expr (dest
, target
, mode
, EXPAND_NORMAL
);
3068 if (TREE_CODE (val
) != INTEGER_CST
)
3072 if (!host_integerp (len
, 1))
3075 if (optimize_size
&& tree_low_cst (len
, 1) > 1)
3078 /* Assume that we can memset by pieces if we can store the
3079 * the coefficients by pieces (in the required modes).
3080 * We can't pass builtin_memset_gen_str as that emits RTL. */
3082 if (!can_store_by_pieces (tree_low_cst (len
, 1),
3083 builtin_memset_read_str
,
3087 val
= fold (build1 (CONVERT_EXPR
, unsigned_char_type_node
, val
));
3088 val_rtx
= expand_expr (val
, NULL_RTX
, VOIDmode
, 0);
3089 val_rtx
= force_reg (TYPE_MODE (unsigned_char_type_node
),
3091 dest_mem
= get_memory_rtx (dest
);
3092 store_by_pieces (dest_mem
, tree_low_cst (len
, 1),
3093 builtin_memset_gen_str
,
3094 val_rtx
, dest_align
, 0);
3095 dest_mem
= force_operand (XEXP (dest_mem
, 0), NULL_RTX
);
3096 dest_mem
= convert_memory_address (ptr_mode
, dest_mem
);
3100 if (target_char_cast (val
, &c
))
3105 if (!host_integerp (len
, 1))
3107 if (!can_store_by_pieces (tree_low_cst (len
, 1),
3108 builtin_memset_read_str
, &c
,
3112 dest_mem
= get_memory_rtx (dest
);
3113 store_by_pieces (dest_mem
, tree_low_cst (len
, 1),
3114 builtin_memset_read_str
,
3116 dest_mem
= force_operand (XEXP (dest_mem
, 0), NULL_RTX
);
3117 dest_mem
= convert_memory_address (ptr_mode
, dest_mem
);
3121 len_rtx
= expand_expr (len
, NULL_RTX
, VOIDmode
, 0);
3123 dest_mem
= get_memory_rtx (dest
);
3124 set_mem_align (dest_mem
, dest_align
);
3125 dest_addr
= clear_storage (dest_mem
, len_rtx
);
3129 dest_addr
= force_operand (XEXP (dest_mem
, 0), NULL_RTX
);
3130 dest_addr
= convert_memory_address (ptr_mode
, dest_addr
);
3137 /* Expand expression EXP, which is a call to the bzero builtin. Return 0
3138 if we failed the caller should emit a normal call. */
3141 expand_builtin_bzero (tree arglist
)
3143 tree dest
, size
, newarglist
;
3145 if (!validate_arglist (arglist
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
3148 dest
= TREE_VALUE (arglist
);
3149 size
= TREE_VALUE (TREE_CHAIN (arglist
));
3151 /* New argument list transforming bzero(ptr x, int y) to
3152 memset(ptr x, int 0, size_t y). This is done this way
3153 so that if it isn't expanded inline, we fallback to
3154 calling bzero instead of memset. */
3156 newarglist
= build_tree_list (NULL_TREE
, convert (sizetype
, size
));
3157 newarglist
= tree_cons (NULL_TREE
, integer_zero_node
, newarglist
);
3158 newarglist
= tree_cons (NULL_TREE
, dest
, newarglist
);
3160 return expand_builtin_memset (newarglist
, const0_rtx
, VOIDmode
);
3163 /* Expand expression EXP, which is a call to the memcmp built-in function.
3164 ARGLIST is the argument list for this call. Return 0 if we failed and the
3165 caller should emit a normal call, otherwise try to get the result in
3166 TARGET, if convenient (and in mode MODE, if that's convenient). */
3169 expand_builtin_memcmp (tree exp ATTRIBUTE_UNUSED
, tree arglist
, rtx target
,
3170 enum machine_mode mode
)
3172 tree arg1
, arg2
, len
;
3173 const char *p1
, *p2
;
3175 if (!validate_arglist (arglist
,
3176 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
3179 arg1
= TREE_VALUE (arglist
);
3180 arg2
= TREE_VALUE (TREE_CHAIN (arglist
));
3181 len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
3183 /* If the len parameter is zero, return zero. */
3184 if (integer_zerop (len
))
3186 /* Evaluate and ignore arg1 and arg2 in case they have
3188 expand_expr (arg1
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
3189 expand_expr (arg2
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
3193 /* If both arguments are equal (and not volatile), return zero. */
3194 if (operand_equal_p (arg1
, arg2
, 0))
3196 /* Evaluate and ignore len in case it has side-effects. */
3197 expand_expr (len
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
3201 p1
= c_getstr (arg1
);
3202 p2
= c_getstr (arg2
);
3204 /* If all arguments are constant, and the value of len is not greater
3205 than the lengths of arg1 and arg2, evaluate at compile-time. */
3206 if (host_integerp (len
, 1) && p1
&& p2
3207 && compare_tree_int (len
, strlen (p1
) + 1) <= 0
3208 && compare_tree_int (len
, strlen (p2
) + 1) <= 0)
3210 const int r
= memcmp (p1
, p2
, tree_low_cst (len
, 1));
3212 return (r
< 0 ? constm1_rtx
: (r
> 0 ? const1_rtx
: const0_rtx
));
3215 /* If len parameter is one, return an expression corresponding to
3216 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
3217 if (integer_onep (len
))
3219 tree cst_uchar_node
= build_type_variant (unsigned_char_type_node
, 1, 0);
3220 tree cst_uchar_ptr_node
= build_pointer_type (cst_uchar_node
);
3222 fold (build1 (CONVERT_EXPR
, integer_type_node
,
3223 build1 (INDIRECT_REF
, cst_uchar_node
,
3224 build1 (NOP_EXPR
, cst_uchar_ptr_node
, arg1
))));
3226 fold (build1 (CONVERT_EXPR
, integer_type_node
,
3227 build1 (INDIRECT_REF
, cst_uchar_node
,
3228 build1 (NOP_EXPR
, cst_uchar_ptr_node
, arg2
))));
3229 tree result
= fold (build (MINUS_EXPR
, integer_type_node
, ind1
, ind2
));
3230 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
3233 #if defined HAVE_cmpmemsi || defined HAVE_cmpstrsi
3235 rtx arg1_rtx
, arg2_rtx
, arg3_rtx
;
3240 = get_pointer_alignment (arg1
, BIGGEST_ALIGNMENT
) / BITS_PER_UNIT
;
3242 = get_pointer_alignment (arg2
, BIGGEST_ALIGNMENT
) / BITS_PER_UNIT
;
3243 enum machine_mode insn_mode
;
3245 #ifdef HAVE_cmpmemsi
3247 insn_mode
= insn_data
[(int) CODE_FOR_cmpmemsi
].operand
[0].mode
;
3250 #ifdef HAVE_cmpstrsi
3252 insn_mode
= insn_data
[(int) CODE_FOR_cmpstrsi
].operand
[0].mode
;
3257 /* If we don't have POINTER_TYPE, call the function. */
3258 if (arg1_align
== 0 || arg2_align
== 0)
3261 /* Make a place to write the result of the instruction. */
3264 && GET_CODE (result
) == REG
&& GET_MODE (result
) == insn_mode
3265 && REGNO (result
) >= FIRST_PSEUDO_REGISTER
))
3266 result
= gen_reg_rtx (insn_mode
);
3268 arg1_rtx
= get_memory_rtx (arg1
);
3269 arg2_rtx
= get_memory_rtx (arg2
);
3270 arg3_rtx
= expand_expr (len
, NULL_RTX
, VOIDmode
, 0);
3271 #ifdef HAVE_cmpmemsi
3273 insn
= gen_cmpmemsi (result
, arg1_rtx
, arg2_rtx
, arg3_rtx
,
3274 GEN_INT (MIN (arg1_align
, arg2_align
)));
3277 #ifdef HAVE_cmpstrsi
3279 insn
= gen_cmpstrsi (result
, arg1_rtx
, arg2_rtx
, arg3_rtx
,
3280 GEN_INT (MIN (arg1_align
, arg2_align
)));
3288 emit_library_call_value (memcmp_libfunc
, result
, LCT_PURE_MAKE_BLOCK
,
3289 TYPE_MODE (integer_type_node
), 3,
3290 XEXP (arg1_rtx
, 0), Pmode
,
3291 XEXP (arg2_rtx
, 0), Pmode
,
3292 convert_to_mode (TYPE_MODE (sizetype
), arg3_rtx
,
3293 TYPE_UNSIGNED (sizetype
)),
3294 TYPE_MODE (sizetype
));
3296 /* Return the value in the proper mode for this function. */
3297 mode
= TYPE_MODE (TREE_TYPE (exp
));
3298 if (GET_MODE (result
) == mode
)
3300 else if (target
!= 0)
3302 convert_move (target
, result
, 0);
3306 return convert_to_mode (mode
, result
, 0);
3313 /* Expand expression EXP, which is a call to the strcmp builtin. Return 0
3314 if we failed the caller should emit a normal call, otherwise try to get
3315 the result in TARGET, if convenient. */
3318 expand_builtin_strcmp (tree exp
, rtx target
, enum machine_mode mode
)
3320 tree arglist
= TREE_OPERAND (exp
, 1);
3322 const char *p1
, *p2
;
3324 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
3327 arg1
= TREE_VALUE (arglist
);
3328 arg2
= TREE_VALUE (TREE_CHAIN (arglist
));
3330 /* If both arguments are equal (and not volatile), return zero. */
3331 if (operand_equal_p (arg1
, arg2
, 0))
3334 p1
= c_getstr (arg1
);
3335 p2
= c_getstr (arg2
);
3339 const int i
= strcmp (p1
, p2
);
3340 return (i
< 0 ? constm1_rtx
: (i
> 0 ? const1_rtx
: const0_rtx
));
3343 /* If either arg is "", return an expression corresponding to
3344 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
3345 if ((p1
&& *p1
== '\0') || (p2
&& *p2
== '\0'))
3347 tree cst_uchar_node
= build_type_variant (unsigned_char_type_node
, 1, 0);
3348 tree cst_uchar_ptr_node
= build_pointer_type (cst_uchar_node
);
3350 fold (build1 (CONVERT_EXPR
, integer_type_node
,
3351 build1 (INDIRECT_REF
, cst_uchar_node
,
3352 build1 (NOP_EXPR
, cst_uchar_ptr_node
, arg1
))));
3354 fold (build1 (CONVERT_EXPR
, integer_type_node
,
3355 build1 (INDIRECT_REF
, cst_uchar_node
,
3356 build1 (NOP_EXPR
, cst_uchar_ptr_node
, arg2
))));
3357 tree result
= fold (build (MINUS_EXPR
, integer_type_node
, ind1
, ind2
));
3358 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
3361 #ifdef HAVE_cmpstrsi
3364 tree len
, len1
, len2
;
3365 rtx arg1_rtx
, arg2_rtx
, arg3_rtx
;
3370 = get_pointer_alignment (arg1
, BIGGEST_ALIGNMENT
) / BITS_PER_UNIT
;
3372 = get_pointer_alignment (arg2
, BIGGEST_ALIGNMENT
) / BITS_PER_UNIT
;
3373 enum machine_mode insn_mode
3374 = insn_data
[(int) CODE_FOR_cmpstrsi
].operand
[0].mode
;
3376 len1
= c_strlen (arg1
, 1);
3377 len2
= c_strlen (arg2
, 1);
3380 len1
= size_binop (PLUS_EXPR
, ssize_int (1), len1
);
3382 len2
= size_binop (PLUS_EXPR
, ssize_int (1), len2
);
3384 /* If we don't have a constant length for the first, use the length
3385 of the second, if we know it. We don't require a constant for
3386 this case; some cost analysis could be done if both are available
3387 but neither is constant. For now, assume they're equally cheap,
3388 unless one has side effects. If both strings have constant lengths,
3395 else if (TREE_SIDE_EFFECTS (len1
))
3397 else if (TREE_SIDE_EFFECTS (len2
))
3399 else if (TREE_CODE (len1
) != INTEGER_CST
)
3401 else if (TREE_CODE (len2
) != INTEGER_CST
)
3403 else if (tree_int_cst_lt (len1
, len2
))
3408 /* If both arguments have side effects, we cannot optimize. */
3409 if (!len
|| TREE_SIDE_EFFECTS (len
))
3412 /* If we don't have POINTER_TYPE, call the function. */
3413 if (arg1_align
== 0 || arg2_align
== 0)
3416 /* Make a place to write the result of the instruction. */
3419 && GET_CODE (result
) == REG
&& GET_MODE (result
) == insn_mode
3420 && REGNO (result
) >= FIRST_PSEUDO_REGISTER
))
3421 result
= gen_reg_rtx (insn_mode
);
3423 /* Stabilize the arguments in case gen_cmpstrsi fails. */
3424 arg1
= save_expr (arg1
);
3425 arg2
= save_expr (arg2
);
3427 arg1_rtx
= get_memory_rtx (arg1
);
3428 arg2_rtx
= get_memory_rtx (arg2
);
3429 arg3_rtx
= expand_expr (len
, NULL_RTX
, VOIDmode
, 0);
3430 insn
= gen_cmpstrsi (result
, arg1_rtx
, arg2_rtx
, arg3_rtx
,
3431 GEN_INT (MIN (arg1_align
, arg2_align
)));
3436 /* Return the value in the proper mode for this function. */
3437 mode
= TYPE_MODE (TREE_TYPE (exp
));
3438 if (GET_MODE (result
) == mode
)
3441 return convert_to_mode (mode
, result
, 0);
3442 convert_move (target
, result
, 0);
3446 /* Expand the library call ourselves using a stabilized argument
3447 list to avoid re-evaluating the function's arguments twice. */
3448 arglist
= build_tree_list (NULL_TREE
, arg2
);
3449 arglist
= tree_cons (NULL_TREE
, arg1
, arglist
);
3450 fndecl
= get_callee_fndecl (exp
);
3451 exp
= build_function_call_expr (fndecl
, arglist
);
3452 return expand_call (exp
, target
, target
== const0_rtx
);
3458 /* Expand expression EXP, which is a call to the strncmp builtin. Return 0
3459 if we failed the caller should emit a normal call, otherwise try to get
3460 the result in TARGET, if convenient. */
3463 expand_builtin_strncmp (tree exp
, rtx target
, enum machine_mode mode
)
3465 tree arglist
= TREE_OPERAND (exp
, 1);
3466 tree arg1
, arg2
, arg3
;
3467 const char *p1
, *p2
;
3469 if (!validate_arglist (arglist
,
3470 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
3473 arg1
= TREE_VALUE (arglist
);
3474 arg2
= TREE_VALUE (TREE_CHAIN (arglist
));
3475 arg3
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
3477 /* If the len parameter is zero, return zero. */
3478 if (integer_zerop (arg3
))
3480 /* Evaluate and ignore arg1 and arg2 in case they have
3482 expand_expr (arg1
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
3483 expand_expr (arg2
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
3487 /* If arg1 and arg2 are equal (and not volatile), return zero. */
3488 if (operand_equal_p (arg1
, arg2
, 0))
3490 /* Evaluate and ignore arg3 in case it has side-effects. */
3491 expand_expr (arg3
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
3495 p1
= c_getstr (arg1
);
3496 p2
= c_getstr (arg2
);
3498 /* If all arguments are constant, evaluate at compile-time. */
3499 if (host_integerp (arg3
, 1) && p1
&& p2
)
3501 const int r
= strncmp (p1
, p2
, tree_low_cst (arg3
, 1));
3502 return (r
< 0 ? constm1_rtx
: (r
> 0 ? const1_rtx
: const0_rtx
));
3505 /* If len == 1 or (either string parameter is "" and (len >= 1)),
3506 return (*(const u_char*)arg1 - *(const u_char*)arg2). */
3507 if (host_integerp (arg3
, 1)
3508 && (tree_low_cst (arg3
, 1) == 1
3509 || (tree_low_cst (arg3
, 1) > 1
3510 && ((p1
&& *p1
== '\0') || (p2
&& *p2
== '\0')))))
3512 tree cst_uchar_node
= build_type_variant (unsigned_char_type_node
, 1, 0);
3513 tree cst_uchar_ptr_node
= build_pointer_type (cst_uchar_node
);
3515 fold (build1 (CONVERT_EXPR
, integer_type_node
,
3516 build1 (INDIRECT_REF
, cst_uchar_node
,
3517 build1 (NOP_EXPR
, cst_uchar_ptr_node
, arg1
))));
3519 fold (build1 (CONVERT_EXPR
, integer_type_node
,
3520 build1 (INDIRECT_REF
, cst_uchar_node
,
3521 build1 (NOP_EXPR
, cst_uchar_ptr_node
, arg2
))));
3522 tree result
= fold (build (MINUS_EXPR
, integer_type_node
, ind1
, ind2
));
3523 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
3526 /* If c_strlen can determine an expression for one of the string
3527 lengths, and it doesn't have side effects, then emit cmpstrsi
3528 using length MIN(strlen(string)+1, arg3). */
3529 #ifdef HAVE_cmpstrsi
3532 tree len
, len1
, len2
;
3533 rtx arg1_rtx
, arg2_rtx
, arg3_rtx
;
3538 = get_pointer_alignment (arg1
, BIGGEST_ALIGNMENT
) / BITS_PER_UNIT
;
3540 = get_pointer_alignment (arg2
, BIGGEST_ALIGNMENT
) / BITS_PER_UNIT
;
3541 enum machine_mode insn_mode
3542 = insn_data
[(int) CODE_FOR_cmpstrsi
].operand
[0].mode
;
3544 len1
= c_strlen (arg1
, 1);
3545 len2
= c_strlen (arg2
, 1);
3548 len1
= size_binop (PLUS_EXPR
, ssize_int (1), len1
);
3550 len2
= size_binop (PLUS_EXPR
, ssize_int (1), len2
);
3552 /* If we don't have a constant length for the first, use the length
3553 of the second, if we know it. We don't require a constant for
3554 this case; some cost analysis could be done if both are available
3555 but neither is constant. For now, assume they're equally cheap,
3556 unless one has side effects. If both strings have constant lengths,
3563 else if (TREE_SIDE_EFFECTS (len1
))
3565 else if (TREE_SIDE_EFFECTS (len2
))
3567 else if (TREE_CODE (len1
) != INTEGER_CST
)
3569 else if (TREE_CODE (len2
) != INTEGER_CST
)
3571 else if (tree_int_cst_lt (len1
, len2
))
3576 /* If both arguments have side effects, we cannot optimize. */
3577 if (!len
|| TREE_SIDE_EFFECTS (len
))
3580 /* The actual new length parameter is MIN(len,arg3). */
3581 len
= fold (build (MIN_EXPR
, TREE_TYPE (len
), len
, arg3
));
3583 /* If we don't have POINTER_TYPE, call the function. */
3584 if (arg1_align
== 0 || arg2_align
== 0)
3587 /* Make a place to write the result of the instruction. */
3590 && GET_CODE (result
) == REG
&& GET_MODE (result
) == insn_mode
3591 && REGNO (result
) >= FIRST_PSEUDO_REGISTER
))
3592 result
= gen_reg_rtx (insn_mode
);
3594 /* Stabilize the arguments in case gen_cmpstrsi fails. */
3595 arg1
= save_expr (arg1
);
3596 arg2
= save_expr (arg2
);
3597 len
= save_expr (len
);
3599 arg1_rtx
= get_memory_rtx (arg1
);
3600 arg2_rtx
= get_memory_rtx (arg2
);
3601 arg3_rtx
= expand_expr (len
, NULL_RTX
, VOIDmode
, 0);
3602 insn
= gen_cmpstrsi (result
, arg1_rtx
, arg2_rtx
, arg3_rtx
,
3603 GEN_INT (MIN (arg1_align
, arg2_align
)));
3608 /* Return the value in the proper mode for this function. */
3609 mode
= TYPE_MODE (TREE_TYPE (exp
));
3610 if (GET_MODE (result
) == mode
)
3613 return convert_to_mode (mode
, result
, 0);
3614 convert_move (target
, result
, 0);
3618 /* Expand the library call ourselves using a stabilized argument
3619 list to avoid re-evaluating the function's arguments twice. */
3620 arglist
= build_tree_list (NULL_TREE
, len
);
3621 arglist
= tree_cons (NULL_TREE
, arg2
, arglist
);
3622 arglist
= tree_cons (NULL_TREE
, arg1
, arglist
);
3623 fndecl
= get_callee_fndecl (exp
);
3624 exp
= build_function_call_expr (fndecl
, arglist
);
3625 return expand_call (exp
, target
, target
== const0_rtx
);
3631 /* Expand expression EXP, which is a call to the strcat builtin.
3632 Return 0 if we failed the caller should emit a normal call,
3633 otherwise try to get the result in TARGET, if convenient. */
3636 expand_builtin_strcat (tree arglist
, rtx target
, enum machine_mode mode
)
3638 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
3642 tree dst
= TREE_VALUE (arglist
),
3643 src
= TREE_VALUE (TREE_CHAIN (arglist
));
3644 const char *p
= c_getstr (src
);
3648 /* If the string length is zero, return the dst parameter. */
3650 return expand_expr (dst
, target
, mode
, EXPAND_NORMAL
);
3651 else if (!optimize_size
)
3653 /* Otherwise if !optimize_size, see if we can store by
3654 pieces into (dst + strlen(dst)). */
3655 tree newdst
, arglist
,
3656 strlen_fn
= implicit_built_in_decls
[BUILT_IN_STRLEN
];
3658 /* This is the length argument. */
3659 arglist
= build_tree_list (NULL_TREE
,
3660 fold (size_binop (PLUS_EXPR
,
3663 /* Prepend src argument. */
3664 arglist
= tree_cons (NULL_TREE
, src
, arglist
);
3666 /* We're going to use dst more than once. */
3667 dst
= save_expr (dst
);
3669 /* Create strlen (dst). */
3671 fold (build_function_call_expr (strlen_fn
,
3672 build_tree_list (NULL_TREE
,
3674 /* Create (dst + strlen (dst)). */
3675 newdst
= fold (build (PLUS_EXPR
, TREE_TYPE (dst
), dst
, newdst
));
3677 /* Prepend the new dst argument. */
3678 arglist
= tree_cons (NULL_TREE
, newdst
, arglist
);
3680 /* We don't want to get turned into a memcpy if the
3681 target is const0_rtx, i.e. when the return value
3682 isn't used. That would produce pessimized code so
3683 pass in a target of zero, it should never actually be
3684 used. If this was successful return the original
3685 dst, not the result of mempcpy. */
3686 if (expand_builtin_mempcpy (arglist
, /*target=*/0, mode
, /*endp=*/0))
3687 return expand_expr (dst
, target
, mode
, EXPAND_NORMAL
);
3697 /* Expand expression EXP, which is a call to the strncat builtin.
3698 Return 0 if we failed the caller should emit a normal call,
3699 otherwise try to get the result in TARGET, if convenient. */
3702 expand_builtin_strncat (tree arglist
, rtx target
, enum machine_mode mode
)
3704 if (!validate_arglist (arglist
,
3705 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
3709 tree dst
= TREE_VALUE (arglist
),
3710 src
= TREE_VALUE (TREE_CHAIN (arglist
)),
3711 len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
3712 const char *p
= c_getstr (src
);
3714 /* If the requested length is zero, or the src parameter string
3715 length is zero, return the dst parameter. */
3716 if (integer_zerop (len
) || (p
&& *p
== '\0'))
3718 /* Evaluate and ignore the src and len parameters in case
3719 they have side-effects. */
3720 expand_expr (src
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
3721 expand_expr (len
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
3722 return expand_expr (dst
, target
, mode
, EXPAND_NORMAL
);
3725 /* If the requested len is greater than or equal to the string
3726 length, call strcat. */
3727 if (TREE_CODE (len
) == INTEGER_CST
&& p
3728 && compare_tree_int (len
, strlen (p
)) >= 0)
3731 = tree_cons (NULL_TREE
, dst
, build_tree_list (NULL_TREE
, src
));
3732 tree fn
= implicit_built_in_decls
[BUILT_IN_STRCAT
];
3734 /* If the replacement _DECL isn't initialized, don't do the
3739 return expand_expr (build_function_call_expr (fn
, newarglist
),
3740 target
, mode
, EXPAND_NORMAL
);
3746 /* Expand expression EXP, which is a call to the strspn builtin.
3747 Return 0 if we failed the caller should emit a normal call,
3748 otherwise try to get the result in TARGET, if convenient. */
3751 expand_builtin_strspn (tree arglist
, rtx target
, enum machine_mode mode
)
3753 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
3757 tree s1
= TREE_VALUE (arglist
), s2
= TREE_VALUE (TREE_CHAIN (arglist
));
3758 const char *p1
= c_getstr (s1
), *p2
= c_getstr (s2
);
3760 /* If both arguments are constants, evaluate at compile-time. */
3763 const size_t r
= strspn (p1
, p2
);
3764 return expand_expr (size_int (r
), target
, mode
, EXPAND_NORMAL
);
3767 /* If either argument is "", return 0. */
3768 if ((p1
&& *p1
== '\0') || (p2
&& *p2
== '\0'))
3770 /* Evaluate and ignore both arguments in case either one has
3772 expand_expr (s1
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
3773 expand_expr (s2
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
3780 /* Expand expression EXP, which is a call to the strcspn builtin.
3781 Return 0 if we failed the caller should emit a normal call,
3782 otherwise try to get the result in TARGET, if convenient. */
3785 expand_builtin_strcspn (tree arglist
, rtx target
, enum machine_mode mode
)
3787 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
3791 tree s1
= TREE_VALUE (arglist
), s2
= TREE_VALUE (TREE_CHAIN (arglist
));
3792 const char *p1
= c_getstr (s1
), *p2
= c_getstr (s2
);
3794 /* If both arguments are constants, evaluate at compile-time. */
3797 const size_t r
= strcspn (p1
, p2
);
3798 return expand_expr (size_int (r
), target
, mode
, EXPAND_NORMAL
);
3801 /* If the first argument is "", return 0. */
3802 if (p1
&& *p1
== '\0')
3804 /* Evaluate and ignore argument s2 in case it has
3806 expand_expr (s2
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
3810 /* If the second argument is "", return __builtin_strlen(s1). */
3811 if (p2
&& *p2
== '\0')
3813 tree newarglist
= build_tree_list (NULL_TREE
, s1
),
3814 fn
= implicit_built_in_decls
[BUILT_IN_STRLEN
];
3816 /* If the replacement _DECL isn't initialized, don't do the
3821 return expand_expr (build_function_call_expr (fn
, newarglist
),
3822 target
, mode
, EXPAND_NORMAL
);
3828 /* Expand a call to __builtin_saveregs, generating the result in TARGET,
3829 if that's convenient. */
3832 expand_builtin_saveregs (void)
3836 /* Don't do __builtin_saveregs more than once in a function.
3837 Save the result of the first call and reuse it. */
3838 if (saveregs_value
!= 0)
3839 return saveregs_value
;
3841 /* When this function is called, it means that registers must be
3842 saved on entry to this function. So we migrate the call to the
3843 first insn of this function. */
3847 /* Do whatever the machine needs done in this case. */
3848 val
= targetm
.calls
.expand_builtin_saveregs ();
3853 saveregs_value
= val
;
3855 /* Put the insns after the NOTE that starts the function. If this
3856 is inside a start_sequence, make the outer-level insn chain current, so
3857 the code is placed at the start of the function. */
3858 push_topmost_sequence ();
3859 emit_insn_after (seq
, get_insns ());
3860 pop_topmost_sequence ();
3865 /* __builtin_args_info (N) returns word N of the arg space info
3866 for the current function. The number and meanings of words
3867 is controlled by the definition of CUMULATIVE_ARGS. */
3870 expand_builtin_args_info (tree arglist
)
3872 int nwords
= sizeof (CUMULATIVE_ARGS
) / sizeof (int);
3873 int *word_ptr
= (int *) ¤t_function_args_info
;
3875 if (sizeof (CUMULATIVE_ARGS
) % sizeof (int) != 0)
3880 if (!host_integerp (TREE_VALUE (arglist
), 0))
3881 error ("argument of `__builtin_args_info' must be constant");
3884 HOST_WIDE_INT wordnum
= tree_low_cst (TREE_VALUE (arglist
), 0);
3886 if (wordnum
< 0 || wordnum
>= nwords
)
3887 error ("argument of `__builtin_args_info' out of range");
3889 return GEN_INT (word_ptr
[wordnum
]);
3893 error ("missing argument in `__builtin_args_info'");
3898 /* Expand ARGLIST, from a call to __builtin_next_arg. */
3901 expand_builtin_next_arg (tree arglist
)
3903 tree fntype
= TREE_TYPE (current_function_decl
);
3905 if (TYPE_ARG_TYPES (fntype
) == 0
3906 || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype
)))
3909 error ("`va_start' used in function with fixed args");
3915 tree last_parm
= tree_last (DECL_ARGUMENTS (current_function_decl
));
3916 tree arg
= TREE_VALUE (arglist
);
3918 /* Strip off all nops for the sake of the comparison. This
3919 is not quite the same as STRIP_NOPS. It does more.
3920 We must also strip off INDIRECT_EXPR for C++ reference
3922 while (TREE_CODE (arg
) == NOP_EXPR
3923 || TREE_CODE (arg
) == CONVERT_EXPR
3924 || TREE_CODE (arg
) == NON_LVALUE_EXPR
3925 || TREE_CODE (arg
) == INDIRECT_REF
)
3926 arg
= TREE_OPERAND (arg
, 0);
3927 if (arg
!= last_parm
)
3928 warning ("second parameter of `va_start' not last named argument");
3931 /* Evidently an out of date version of <stdarg.h>; can't validate
3932 va_start's second argument, but can still work as intended. */
3933 warning ("`__builtin_next_arg' called without an argument");
3935 return expand_binop (Pmode
, add_optab
,
3936 current_function_internal_arg_pointer
,
3937 current_function_arg_offset_rtx
,
3938 NULL_RTX
, 0, OPTAB_LIB_WIDEN
);
3941 /* Make it easier for the backends by protecting the valist argument
3942 from multiple evaluations. */
3945 stabilize_va_list (tree valist
, int needs_lvalue
)
3947 if (TREE_CODE (va_list_type_node
) == ARRAY_TYPE
)
3949 if (TREE_SIDE_EFFECTS (valist
))
3950 valist
= save_expr (valist
);
3952 /* For this case, the backends will be expecting a pointer to
3953 TREE_TYPE (va_list_type_node), but it's possible we've
3954 actually been given an array (an actual va_list_type_node).
3956 if (TREE_CODE (TREE_TYPE (valist
)) == ARRAY_TYPE
)
3958 tree p1
= build_pointer_type (TREE_TYPE (va_list_type_node
));
3959 tree p2
= build_pointer_type (va_list_type_node
);
3961 valist
= build1 (ADDR_EXPR
, p2
, valist
);
3962 valist
= fold (build1 (NOP_EXPR
, p1
, valist
));
3971 if (! TREE_SIDE_EFFECTS (valist
))
3974 pt
= build_pointer_type (va_list_type_node
);
3975 valist
= fold (build1 (ADDR_EXPR
, pt
, valist
));
3976 TREE_SIDE_EFFECTS (valist
) = 1;
3979 if (TREE_SIDE_EFFECTS (valist
))
3980 valist
= save_expr (valist
);
3981 valist
= fold (build1 (INDIRECT_REF
, TREE_TYPE (TREE_TYPE (valist
)),
3988 /* The "standard" definition of va_list is void*. */
3991 std_build_builtin_va_list (void)
3993 return ptr_type_node
;
3996 /* The "standard" implementation of va_start: just assign `nextarg' to
4000 std_expand_builtin_va_start (tree valist
, rtx nextarg
)
4004 t
= build (MODIFY_EXPR
, TREE_TYPE (valist
), valist
,
4005 make_tree (ptr_type_node
, nextarg
));
4006 TREE_SIDE_EFFECTS (t
) = 1;
4008 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
4011 /* Expand ARGLIST, from a call to __builtin_va_start. */
4014 expand_builtin_va_start (tree arglist
)
4019 chain
= TREE_CHAIN (arglist
);
4021 if (TREE_CHAIN (chain
))
4022 error ("too many arguments to function `va_start'");
4024 nextarg
= expand_builtin_next_arg (chain
);
4025 valist
= stabilize_va_list (TREE_VALUE (arglist
), 1);
4027 #ifdef EXPAND_BUILTIN_VA_START
4028 EXPAND_BUILTIN_VA_START (valist
, nextarg
);
4030 std_expand_builtin_va_start (valist
, nextarg
);
4036 /* The "standard" implementation of va_arg: read the value from the
4037 current (padded) address and increment by the (padded) size. */
4040 std_expand_builtin_va_arg (tree valist
, tree type
)
4042 tree addr_tree
, t
, type_size
= NULL
;
4043 tree align
, alignm1
;
4046 HOST_WIDE_INT boundary
;
4048 /* Compute the rounded size of the type. */
4049 align
= size_int (PARM_BOUNDARY
/ BITS_PER_UNIT
);
4050 alignm1
= size_int (PARM_BOUNDARY
/ BITS_PER_UNIT
- 1);
4051 boundary
= FUNCTION_ARG_BOUNDARY (TYPE_MODE (type
), type
);
4053 /* va_list pointer is aligned to PARM_BOUNDARY. If argument actually
4054 requires greater alignment, we must perform dynamic alignment. */
4056 if (boundary
> PARM_BOUNDARY
)
4058 if (!PAD_VARARGS_DOWN
)
4060 t
= build (MODIFY_EXPR
, TREE_TYPE (valist
), valist
,
4061 build (PLUS_EXPR
, TREE_TYPE (valist
), valist
,
4062 build_int_2 (boundary
/ BITS_PER_UNIT
- 1, 0)));
4063 TREE_SIDE_EFFECTS (t
) = 1;
4064 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
4066 t
= build (MODIFY_EXPR
, TREE_TYPE (valist
), valist
,
4067 build (BIT_AND_EXPR
, TREE_TYPE (valist
), valist
,
4068 build_int_2 (~(boundary
/ BITS_PER_UNIT
- 1), -1)));
4069 TREE_SIDE_EFFECTS (t
) = 1;
4070 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
4072 if (type
== error_mark_node
4073 || (type_size
= TYPE_SIZE_UNIT (TYPE_MAIN_VARIANT (type
))) == NULL
4074 || TREE_OVERFLOW (type_size
))
4075 rounded_size
= size_zero_node
;
4077 rounded_size
= fold (build (MULT_EXPR
, sizetype
,
4078 fold (build (TRUNC_DIV_EXPR
, sizetype
,
4079 fold (build (PLUS_EXPR
, sizetype
,
4080 type_size
, alignm1
)),
4086 if (PAD_VARARGS_DOWN
&& ! integer_zerop (rounded_size
))
4088 /* Small args are padded downward. */
4089 addr_tree
= fold (build (PLUS_EXPR
, TREE_TYPE (addr_tree
), addr_tree
,
4090 fold (build (COND_EXPR
, sizetype
,
4091 fold (build (GT_EXPR
, sizetype
,
4095 fold (build (MINUS_EXPR
, sizetype
,
4100 addr
= expand_expr (addr_tree
, NULL_RTX
, Pmode
, EXPAND_NORMAL
);
4101 addr
= copy_to_reg (addr
);
4103 /* Compute new value for AP. */
4104 if (! integer_zerop (rounded_size
))
4106 t
= build (MODIFY_EXPR
, TREE_TYPE (valist
), valist
,
4107 build (PLUS_EXPR
, TREE_TYPE (valist
), valist
,
4109 TREE_SIDE_EFFECTS (t
) = 1;
4110 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
4116 /* Expand __builtin_va_arg, which is not really a builtin function, but
4117 a very special sort of operator. */
4120 expand_builtin_va_arg (tree valist
, tree type
)
4123 tree promoted_type
, want_va_type
, have_va_type
;
4125 /* Verify that valist is of the proper type. */
4127 want_va_type
= va_list_type_node
;
4128 have_va_type
= TREE_TYPE (valist
);
4129 if (TREE_CODE (want_va_type
) == ARRAY_TYPE
)
4131 /* If va_list is an array type, the argument may have decayed
4132 to a pointer type, e.g. by being passed to another function.
4133 In that case, unwrap both types so that we can compare the
4134 underlying records. */
4135 if (TREE_CODE (have_va_type
) == ARRAY_TYPE
4136 || TREE_CODE (have_va_type
) == POINTER_TYPE
)
4138 want_va_type
= TREE_TYPE (want_va_type
);
4139 have_va_type
= TREE_TYPE (have_va_type
);
4142 if (TYPE_MAIN_VARIANT (want_va_type
) != TYPE_MAIN_VARIANT (have_va_type
))
4144 error ("first argument to `va_arg' not of type `va_list'");
4148 /* Generate a diagnostic for requesting data of a type that cannot
4149 be passed through `...' due to type promotion at the call site. */
4150 else if ((promoted_type
= lang_hooks
.types
.type_promotes_to (type
))
4153 const char *name
= "<anonymous type>", *pname
= 0;
4154 static bool gave_help
;
4156 if (TYPE_NAME (type
))
4158 if (TREE_CODE (TYPE_NAME (type
)) == IDENTIFIER_NODE
)
4159 name
= IDENTIFIER_POINTER (TYPE_NAME (type
));
4160 else if (TREE_CODE (TYPE_NAME (type
)) == TYPE_DECL
4161 && DECL_NAME (TYPE_NAME (type
)))
4162 name
= IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type
)));
4164 if (TYPE_NAME (promoted_type
))
4166 if (TREE_CODE (TYPE_NAME (promoted_type
)) == IDENTIFIER_NODE
)
4167 pname
= IDENTIFIER_POINTER (TYPE_NAME (promoted_type
));
4168 else if (TREE_CODE (TYPE_NAME (promoted_type
)) == TYPE_DECL
4169 && DECL_NAME (TYPE_NAME (promoted_type
)))
4170 pname
= IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (promoted_type
)));
4173 /* Unfortunately, this is merely undefined, rather than a constraint
4174 violation, so we cannot make this an error. If this call is never
4175 executed, the program is still strictly conforming. */
4176 warning ("`%s' is promoted to `%s' when passed through `...'",
4181 warning ("(so you should pass `%s' not `%s' to `va_arg')",
4185 /* We can, however, treat "undefined" any way we please.
4186 Call abort to encourage the user to fix the program. */
4187 inform ("if this code is reached, the program will abort");
4188 expand_builtin_trap ();
4190 /* This is dead code, but go ahead and finish so that the
4191 mode of the result comes out right. */
4196 /* Make it easier for the backends by protecting the valist argument
4197 from multiple evaluations. */
4198 valist
= stabilize_va_list (valist
, 0);
4200 #ifdef EXPAND_BUILTIN_VA_ARG
4201 addr
= EXPAND_BUILTIN_VA_ARG (valist
, type
);
4203 addr
= std_expand_builtin_va_arg (valist
, type
);
4207 addr
= convert_memory_address (Pmode
, addr
);
4209 result
= gen_rtx_MEM (TYPE_MODE (type
), addr
);
4210 set_mem_alias_set (result
, get_varargs_alias_set ());
4215 /* Expand ARGLIST, from a call to __builtin_va_end. */
4218 expand_builtin_va_end (tree arglist
)
4220 tree valist
= TREE_VALUE (arglist
);
4222 /* Evaluate for side effects, if needed. I hate macros that don't
4224 if (TREE_SIDE_EFFECTS (valist
))
4225 expand_expr (valist
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
4230 /* Expand ARGLIST, from a call to __builtin_va_copy. We do this as a
4231 builtin rather than just as an assignment in stdarg.h because of the
4232 nastiness of array-type va_list types. */
4235 expand_builtin_va_copy (tree arglist
)
4239 dst
= TREE_VALUE (arglist
);
4240 src
= TREE_VALUE (TREE_CHAIN (arglist
));
4242 dst
= stabilize_va_list (dst
, 1);
4243 src
= stabilize_va_list (src
, 0);
4245 if (TREE_CODE (va_list_type_node
) != ARRAY_TYPE
)
4247 t
= build (MODIFY_EXPR
, va_list_type_node
, dst
, src
);
4248 TREE_SIDE_EFFECTS (t
) = 1;
4249 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
4253 rtx dstb
, srcb
, size
;
4255 /* Evaluate to pointers. */
4256 dstb
= expand_expr (dst
, NULL_RTX
, Pmode
, EXPAND_NORMAL
);
4257 srcb
= expand_expr (src
, NULL_RTX
, Pmode
, EXPAND_NORMAL
);
4258 size
= expand_expr (TYPE_SIZE_UNIT (va_list_type_node
), NULL_RTX
,
4259 VOIDmode
, EXPAND_NORMAL
);
4261 dstb
= convert_memory_address (Pmode
, dstb
);
4262 srcb
= convert_memory_address (Pmode
, srcb
);
4264 /* "Dereference" to BLKmode memories. */
4265 dstb
= gen_rtx_MEM (BLKmode
, dstb
);
4266 set_mem_alias_set (dstb
, get_alias_set (TREE_TYPE (TREE_TYPE (dst
))));
4267 set_mem_align (dstb
, TYPE_ALIGN (va_list_type_node
));
4268 srcb
= gen_rtx_MEM (BLKmode
, srcb
);
4269 set_mem_alias_set (srcb
, get_alias_set (TREE_TYPE (TREE_TYPE (src
))));
4270 set_mem_align (srcb
, TYPE_ALIGN (va_list_type_node
));
4273 emit_block_move (dstb
, srcb
, size
, BLOCK_OP_NORMAL
);
4279 /* Expand a call to one of the builtin functions __builtin_frame_address or
4280 __builtin_return_address. */
4283 expand_builtin_frame_address (tree fndecl
, tree arglist
)
4285 /* The argument must be a nonnegative integer constant.
4286 It counts the number of frames to scan up the stack.
4287 The value is the return address saved in that frame. */
4289 /* Warning about missing arg was already issued. */
4291 else if (! host_integerp (TREE_VALUE (arglist
), 1))
4293 if (DECL_FUNCTION_CODE (fndecl
) == BUILT_IN_FRAME_ADDRESS
)
4294 error ("invalid arg to `__builtin_frame_address'");
4296 error ("invalid arg to `__builtin_return_address'");
4302 = expand_builtin_return_addr (DECL_FUNCTION_CODE (fndecl
),
4303 tree_low_cst (TREE_VALUE (arglist
), 1),
4304 hard_frame_pointer_rtx
);
4306 /* Some ports cannot access arbitrary stack frames. */
4309 if (DECL_FUNCTION_CODE (fndecl
) == BUILT_IN_FRAME_ADDRESS
)
4310 warning ("unsupported arg to `__builtin_frame_address'");
4312 warning ("unsupported arg to `__builtin_return_address'");
4316 /* For __builtin_frame_address, return what we've got. */
4317 if (DECL_FUNCTION_CODE (fndecl
) == BUILT_IN_FRAME_ADDRESS
)
4320 if (GET_CODE (tem
) != REG
4321 && ! CONSTANT_P (tem
))
4322 tem
= copy_to_mode_reg (Pmode
, tem
);
4327 /* Expand a call to the alloca builtin, with arguments ARGLIST. Return 0 if
4328 we failed and the caller should emit a normal call, otherwise try to get
4329 the result in TARGET, if convenient. */
4332 expand_builtin_alloca (tree arglist
, rtx target
)
4337 if (!validate_arglist (arglist
, INTEGER_TYPE
, VOID_TYPE
))
4340 /* Compute the argument. */
4341 op0
= expand_expr (TREE_VALUE (arglist
), NULL_RTX
, VOIDmode
, 0);
4343 /* Allocate the desired space. */
4344 result
= allocate_dynamic_stack_space (op0
, target
, BITS_PER_UNIT
);
4345 result
= convert_memory_address (ptr_mode
, result
);
4350 /* Expand a call to a unary builtin. The arguments are in ARGLIST.
4351 Return 0 if a normal call should be emitted rather than expanding the
4352 function in-line. If convenient, the result should be placed in TARGET.
4353 SUBTARGET may be used as the target for computing one of EXP's operands. */
4356 expand_builtin_unop (enum machine_mode target_mode
, tree arglist
, rtx target
,
4357 rtx subtarget
, optab op_optab
)
4360 if (!validate_arglist (arglist
, INTEGER_TYPE
, VOID_TYPE
))
4363 /* Compute the argument. */
4364 op0
= expand_expr (TREE_VALUE (arglist
), subtarget
, VOIDmode
, 0);
4365 /* Compute op, into TARGET if possible.
4366 Set TARGET to wherever the result comes back. */
4367 target
= expand_unop (TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist
))),
4368 op_optab
, op0
, target
, 1);
4372 return convert_to_mode (target_mode
, target
, 0);
4375 /* If the string passed to fputs is a constant and is one character
4376 long, we attempt to transform this call into __builtin_fputc(). */
4379 expand_builtin_fputs (tree arglist
, rtx target
, bool unlocked
)
4382 tree fn_fputc
= unlocked
? implicit_built_in_decls
[BUILT_IN_FPUTC_UNLOCKED
]
4383 : implicit_built_in_decls
[BUILT_IN_FPUTC
];
4384 tree fn_fwrite
= unlocked
? implicit_built_in_decls
[BUILT_IN_FWRITE_UNLOCKED
]
4385 : implicit_built_in_decls
[BUILT_IN_FWRITE
];
4387 /* If the return value is used, or the replacement _DECL isn't
4388 initialized, don't do the transformation. */
4389 if (target
!= const0_rtx
|| !fn_fputc
|| !fn_fwrite
)
4392 /* Verify the arguments in the original call. */
4393 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
4396 /* Get the length of the string passed to fputs. If the length
4397 can't be determined, punt. */
4398 if (!(len
= c_strlen (TREE_VALUE (arglist
), 1))
4399 || TREE_CODE (len
) != INTEGER_CST
)
4402 switch (compare_tree_int (len
, 1))
4404 case -1: /* length is 0, delete the call entirely . */
4406 /* Evaluate and ignore the argument in case it has
4408 expand_expr (TREE_VALUE (TREE_CHAIN (arglist
)), const0_rtx
,
4409 VOIDmode
, EXPAND_NORMAL
);
4412 case 0: /* length is 1, call fputc. */
4414 const char *p
= c_getstr (TREE_VALUE (arglist
));
4418 /* New argument list transforming fputs(string, stream) to
4419 fputc(string[0], stream). */
4421 build_tree_list (NULL_TREE
, TREE_VALUE (TREE_CHAIN (arglist
)));
4423 tree_cons (NULL_TREE
, build_int_2 (p
[0], 0), arglist
);
4429 case 1: /* length is greater than 1, call fwrite. */
4433 /* If optimizing for size keep fputs. */
4436 string_arg
= TREE_VALUE (arglist
);
4437 /* New argument list transforming fputs(string, stream) to
4438 fwrite(string, 1, len, stream). */
4439 arglist
= build_tree_list (NULL_TREE
, TREE_VALUE (TREE_CHAIN (arglist
)));
4440 arglist
= tree_cons (NULL_TREE
, len
, arglist
);
4441 arglist
= tree_cons (NULL_TREE
, size_one_node
, arglist
);
4442 arglist
= tree_cons (NULL_TREE
, string_arg
, arglist
);
4450 return expand_expr (build_function_call_expr (fn
, arglist
),
4451 const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
4454 /* Expand a call to __builtin_expect. We return our argument and emit a
4455 NOTE_INSN_EXPECTED_VALUE note. This is the expansion of __builtin_expect in
4456 a non-jump context. */
4459 expand_builtin_expect (tree arglist
, rtx target
)
4464 if (arglist
== NULL_TREE
4465 || TREE_CHAIN (arglist
) == NULL_TREE
)
4467 exp
= TREE_VALUE (arglist
);
4468 c
= TREE_VALUE (TREE_CHAIN (arglist
));
4470 if (TREE_CODE (c
) != INTEGER_CST
)
4472 error ("second arg to `__builtin_expect' must be a constant");
4473 c
= integer_zero_node
;
4476 target
= expand_expr (exp
, target
, VOIDmode
, EXPAND_NORMAL
);
4478 /* Don't bother with expected value notes for integral constants. */
4479 if (flag_guess_branch_prob
&& GET_CODE (target
) != CONST_INT
)
4481 /* We do need to force this into a register so that we can be
4482 moderately sure to be able to correctly interpret the branch
4484 target
= force_reg (GET_MODE (target
), target
);
4486 rtx_c
= expand_expr (c
, NULL_RTX
, GET_MODE (target
), EXPAND_NORMAL
);
4488 note
= emit_note (NOTE_INSN_EXPECTED_VALUE
);
4489 NOTE_EXPECTED_VALUE (note
) = gen_rtx_EQ (VOIDmode
, target
, rtx_c
);
4495 /* Like expand_builtin_expect, except do this in a jump context. This is
4496 called from do_jump if the conditional is a __builtin_expect. Return either
4497 a list of insns to emit the jump or NULL if we cannot optimize
4498 __builtin_expect. We need to optimize this at jump time so that machines
4499 like the PowerPC don't turn the test into a SCC operation, and then jump
4500 based on the test being 0/1. */
4503 expand_builtin_expect_jump (tree exp
, rtx if_false_label
, rtx if_true_label
)
4505 tree arglist
= TREE_OPERAND (exp
, 1);
4506 tree arg0
= TREE_VALUE (arglist
);
4507 tree arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
4510 /* Only handle __builtin_expect (test, 0) and
4511 __builtin_expect (test, 1). */
4512 if (TREE_CODE (TREE_TYPE (arg1
)) == INTEGER_TYPE
4513 && (integer_zerop (arg1
) || integer_onep (arg1
)))
4515 rtx insn
, drop_through_label
, temp
;
4517 /* Expand the jump insns. */
4519 do_jump (arg0
, if_false_label
, if_true_label
);
4522 drop_through_label
= get_last_insn ();
4523 if (drop_through_label
&& GET_CODE (drop_through_label
) == NOTE
)
4524 drop_through_label
= prev_nonnote_insn (drop_through_label
);
4525 if (drop_through_label
&& GET_CODE (drop_through_label
) != CODE_LABEL
)
4526 drop_through_label
= NULL_RTX
;
4529 if (! if_true_label
)
4530 if_true_label
= drop_through_label
;
4531 if (! if_false_label
)
4532 if_false_label
= drop_through_label
;
4534 /* Go through and add the expect's to each of the conditional jumps. */
4536 while (insn
!= NULL_RTX
)
4538 rtx next
= NEXT_INSN (insn
);
4540 if (GET_CODE (insn
) == JUMP_INSN
&& any_condjump_p (insn
))
4542 rtx ifelse
= SET_SRC (pc_set (insn
));
4543 rtx then_dest
= XEXP (ifelse
, 1);
4544 rtx else_dest
= XEXP (ifelse
, 2);
4547 /* First check if we recognize any of the labels. */
4548 if (GET_CODE (then_dest
) == LABEL_REF
4549 && XEXP (then_dest
, 0) == if_true_label
)
4551 else if (GET_CODE (then_dest
) == LABEL_REF
4552 && XEXP (then_dest
, 0) == if_false_label
)
4554 else if (GET_CODE (else_dest
) == LABEL_REF
4555 && XEXP (else_dest
, 0) == if_false_label
)
4557 else if (GET_CODE (else_dest
) == LABEL_REF
4558 && XEXP (else_dest
, 0) == if_true_label
)
4560 /* Otherwise check where we drop through. */
4561 else if (else_dest
== pc_rtx
)
4563 if (next
&& GET_CODE (next
) == NOTE
)
4564 next
= next_nonnote_insn (next
);
4566 if (next
&& GET_CODE (next
) == JUMP_INSN
4567 && any_uncondjump_p (next
))
4568 temp
= XEXP (SET_SRC (pc_set (next
)), 0);
4572 /* TEMP is either a CODE_LABEL, NULL_RTX or something
4573 else that can't possibly match either target label. */
4574 if (temp
== if_false_label
)
4576 else if (temp
== if_true_label
)
4579 else if (then_dest
== pc_rtx
)
4581 if (next
&& GET_CODE (next
) == NOTE
)
4582 next
= next_nonnote_insn (next
);
4584 if (next
&& GET_CODE (next
) == JUMP_INSN
4585 && any_uncondjump_p (next
))
4586 temp
= XEXP (SET_SRC (pc_set (next
)), 0);
4590 if (temp
== if_false_label
)
4592 else if (temp
== if_true_label
)
4598 /* If the test is expected to fail, reverse the
4600 if (integer_zerop (arg1
))
4602 predict_insn_def (insn
, PRED_BUILTIN_EXPECT
, taken
);
4614 expand_builtin_trap (void)
4618 emit_insn (gen_trap ());
4621 emit_library_call (abort_libfunc
, LCT_NORETURN
, VOIDmode
, 0);
4625 /* Expand a call to fabs, fabsf or fabsl with arguments ARGLIST.
4626 Return 0 if a normal call should be emitted rather than expanding
4627 the function inline. If convenient, the result should be placed
4628 in TARGET. SUBTARGET may be used as the target for computing
4632 expand_builtin_fabs (tree arglist
, rtx target
, rtx subtarget
)
4634 enum machine_mode mode
;
4638 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
4641 arg
= TREE_VALUE (arglist
);
4642 mode
= TYPE_MODE (TREE_TYPE (arg
));
4643 op0
= expand_expr (arg
, subtarget
, VOIDmode
, 0);
4644 return expand_abs (mode
, op0
, target
, 0, safe_from_p (target
, arg
, 1));
4647 /* Expand a call to cabs, cabsf or cabsl with arguments ARGLIST.
4648 Return 0 if a normal call should be emitted rather than expanding
4649 the function inline. If convenient, the result should be placed
4653 expand_builtin_cabs (tree arglist
, rtx target
)
4655 enum machine_mode mode
;
4659 if (arglist
== 0 || TREE_CHAIN (arglist
))
4661 arg
= TREE_VALUE (arglist
);
4662 if (TREE_CODE (TREE_TYPE (arg
)) != COMPLEX_TYPE
4663 || TREE_CODE (TREE_TYPE (TREE_TYPE (arg
))) != REAL_TYPE
)
4666 mode
= TYPE_MODE (TREE_TYPE (arg
));
4667 op0
= expand_expr (arg
, NULL_RTX
, VOIDmode
, 0);
4668 return expand_complex_abs (mode
, op0
, target
, 0);
4671 /* Create a new constant string literal and return a char* pointer to it.
4672 The STRING_CST value is the LEN characters at STR. */
4674 build_string_literal (int len
, const char *str
)
4676 tree t
, elem
, index
, type
;
4678 t
= build_string (len
, str
);
4679 elem
= build_type_variant (char_type_node
, 1, 0);
4680 index
= build_index_type (build_int_2 (len
- 1, 0));
4681 type
= build_array_type (elem
, index
);
4682 TREE_TYPE (t
) = type
;
4683 TREE_CONSTANT (t
) = 1;
4684 TREE_READONLY (t
) = 1;
4685 TREE_STATIC (t
) = 1;
4687 type
= build_pointer_type (type
);
4688 t
= build1 (ADDR_EXPR
, type
, t
);
4690 type
= build_pointer_type (elem
);
4691 t
= build1 (NOP_EXPR
, type
, t
);
4695 /* Expand a call to printf or printf_unlocked with argument list ARGLIST.
4696 Return 0 if a normal call should be emitted rather than transforming
4697 the function inline. If convenient, the result should be placed in
4698 TARGET with mode MODE. UNLOCKED indicates this is a printf_unlocked
4701 expand_builtin_printf (tree arglist
, rtx target
, enum machine_mode mode
,
4704 tree fn_putchar
= unlocked
4705 ? implicit_built_in_decls
[BUILT_IN_PUTCHAR_UNLOCKED
]
4706 : implicit_built_in_decls
[BUILT_IN_PUTCHAR
];
4707 tree fn_puts
= unlocked
? implicit_built_in_decls
[BUILT_IN_PUTS_UNLOCKED
]
4708 : implicit_built_in_decls
[BUILT_IN_PUTS
];
4709 const char *fmt_str
;
4712 /* If the return value is used, don't do the transformation. */
4713 if (target
!= const0_rtx
)
4716 /* Verify the required arguments in the original call. */
4719 fmt
= TREE_VALUE (arglist
);
4720 if (TREE_CODE (TREE_TYPE (fmt
)) != POINTER_TYPE
)
4722 arglist
= TREE_CHAIN (arglist
);
4724 /* Check whether the format is a literal string constant. */
4725 fmt_str
= c_getstr (fmt
);
4726 if (fmt_str
== NULL
)
4729 /* If the format specifier was "%s\n", call __builtin_puts(arg). */
4730 if (strcmp (fmt_str
, "%s\n") == 0)
4733 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist
))) != POINTER_TYPE
4734 || TREE_CHAIN (arglist
))
4738 /* If the format specifier was "%c", call __builtin_putchar(arg). */
4739 else if (strcmp (fmt_str
, "%c") == 0)
4742 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist
))) != INTEGER_TYPE
4743 || TREE_CHAIN (arglist
))
4749 /* We can't handle anything else with % args or %% ... yet. */
4750 if (strchr (fmt_str
, '%'))
4756 /* If the format specifier was "", printf does nothing. */
4757 if (fmt_str
[0] == '\0')
4759 /* If the format specifier has length of 1, call putchar. */
4760 if (fmt_str
[1] == '\0')
4762 /* Given printf("c"), (where c is any one character,)
4763 convert "c"[0] to an int and pass that to the replacement
4765 arg
= build_int_2 (fmt_str
[0], 0);
4766 arglist
= build_tree_list (NULL_TREE
, arg
);
4771 /* If the format specifier was "string\n", call puts("string"). */
4772 size_t len
= strlen (fmt_str
);
4773 if (fmt_str
[len
- 1] == '\n')
4775 /* Create a NUL-terminated string that's one char shorter
4776 than the original, stripping off the trailing '\n'. */
4777 char *newstr
= alloca (len
);
4778 memcpy (newstr
, fmt_str
, len
- 1);
4779 newstr
[len
- 1] = 0;
4781 arg
= build_string_literal (len
, newstr
);
4782 arglist
= build_tree_list (NULL_TREE
, arg
);
4786 /* We'd like to arrange to call fputs(string,stdout) here,
4787 but we need stdout and don't have a way to get it yet. */
4794 return expand_expr (build_function_call_expr (fn
, arglist
),
4795 target
, mode
, EXPAND_NORMAL
);
4798 /* Expand a call to fprintf or fprintf_unlocked with argument list ARGLIST.
4799 Return 0 if a normal call should be emitted rather than transforming
4800 the function inline. If convenient, the result should be placed in
4801 TARGET with mode MODE. UNLOCKED indicates this is a fprintf_unlocked
4804 expand_builtin_fprintf (tree arglist
, rtx target
, enum machine_mode mode
,
4807 tree fn_fputc
= unlocked
? implicit_built_in_decls
[BUILT_IN_FPUTC_UNLOCKED
]
4808 : implicit_built_in_decls
[BUILT_IN_FPUTC
];
4809 tree fn_fputs
= unlocked
? implicit_built_in_decls
[BUILT_IN_FPUTS_UNLOCKED
]
4810 : implicit_built_in_decls
[BUILT_IN_FPUTS
];
4811 const char *fmt_str
;
4812 tree fn
, fmt
, fp
, arg
;
4814 /* If the return value is used, don't do the transformation. */
4815 if (target
!= const0_rtx
)
4818 /* Verify the required arguments in the original call. */
4821 fp
= TREE_VALUE (arglist
);
4822 if (TREE_CODE (TREE_TYPE (fp
)) != POINTER_TYPE
)
4824 arglist
= TREE_CHAIN (arglist
);
4827 fmt
= TREE_VALUE (arglist
);
4828 if (TREE_CODE (TREE_TYPE (fmt
)) != POINTER_TYPE
)
4830 arglist
= TREE_CHAIN (arglist
);
4832 /* Check whether the format is a literal string constant. */
4833 fmt_str
= c_getstr (fmt
);
4834 if (fmt_str
== NULL
)
4837 /* If the format specifier was "%s", call __builtin_fputs(arg,fp). */
4838 if (strcmp (fmt_str
, "%s") == 0)
4841 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist
))) != POINTER_TYPE
4842 || TREE_CHAIN (arglist
))
4844 arg
= TREE_VALUE (arglist
);
4845 arglist
= build_tree_list (NULL_TREE
, fp
);
4846 arglist
= tree_cons (NULL_TREE
, arg
, arglist
);
4849 /* If the format specifier was "%c", call __builtin_fputc(arg,fp). */
4850 else if (strcmp (fmt_str
, "%c") == 0)
4853 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist
))) != INTEGER_TYPE
4854 || TREE_CHAIN (arglist
))
4856 arg
= TREE_VALUE (arglist
);
4857 arglist
= build_tree_list (NULL_TREE
, fp
);
4858 arglist
= tree_cons (NULL_TREE
, arg
, arglist
);
4863 /* We can't handle anything else with % args or %% ... yet. */
4864 if (strchr (fmt_str
, '%'))
4870 /* If the format specifier was "", fprintf does nothing. */
4871 if (fmt_str
[0] == '\0')
4873 /* Evaluate and ignore FILE* argument for side-effects. */
4874 expand_expr (fp
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
4878 /* When "string" doesn't contain %, replace all cases of
4879 fprintf(stream,string) with fputs(string,stream). The fputs
4880 builtin will take care of special cases like length == 1. */
4881 arglist
= build_tree_list (NULL_TREE
, fp
);
4882 arglist
= tree_cons (NULL_TREE
, fmt
, arglist
);
4888 return expand_expr (build_function_call_expr (fn
, arglist
),
4889 target
, mode
, EXPAND_NORMAL
);
4892 /* Expand a call to sprintf with argument list ARGLIST. Return 0 if
4893 a normal call should be emitted rather than expanding the function
4894 inline. If convenient, the result should be placed in TARGET with
4898 expand_builtin_sprintf (tree arglist
, rtx target
, enum machine_mode mode
)
4900 tree orig_arglist
, dest
, fmt
;
4901 const char *fmt_str
;
4903 orig_arglist
= arglist
;
4905 /* Verify the required arguments in the original call. */
4908 dest
= TREE_VALUE (arglist
);
4909 if (TREE_CODE (TREE_TYPE (dest
)) != POINTER_TYPE
)
4911 arglist
= TREE_CHAIN (arglist
);
4914 fmt
= TREE_VALUE (arglist
);
4915 if (TREE_CODE (TREE_TYPE (fmt
)) != POINTER_TYPE
)
4917 arglist
= TREE_CHAIN (arglist
);
4919 /* Check whether the format is a literal string constant. */
4920 fmt_str
= c_getstr (fmt
);
4921 if (fmt_str
== NULL
)
4924 /* If the format doesn't contain % args or %%, use strcpy. */
4925 if (strchr (fmt_str
, '%') == 0)
4927 tree fn
= implicit_built_in_decls
[BUILT_IN_STRCPY
];
4930 if (arglist
|| ! fn
)
4932 expand_expr (build_function_call_expr (fn
, orig_arglist
),
4933 const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
4934 if (target
== const0_rtx
)
4936 exp
= build_int_2 (strlen (fmt_str
), 0);
4937 exp
= fold (build1 (NOP_EXPR
, integer_type_node
, exp
));
4938 return expand_expr (exp
, target
, mode
, EXPAND_NORMAL
);
4940 /* If the format is "%s", use strcpy if the result isn't used. */
4941 else if (strcmp (fmt_str
, "%s") == 0)
4944 fn
= implicit_built_in_decls
[BUILT_IN_STRCPY
];
4949 if (! arglist
|| TREE_CHAIN (arglist
))
4951 arg
= TREE_VALUE (arglist
);
4952 if (TREE_CODE (TREE_TYPE (arg
)) != POINTER_TYPE
)
4955 if (target
!= const0_rtx
)
4957 len
= c_strlen (arg
, 1);
4958 if (! len
|| TREE_CODE (len
) != INTEGER_CST
)
4964 arglist
= build_tree_list (NULL_TREE
, arg
);
4965 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
4966 expand_expr (build_function_call_expr (fn
, arglist
),
4967 const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
4969 if (target
== const0_rtx
)
4971 return expand_expr (len
, target
, mode
, EXPAND_NORMAL
);
4977 /* Expand a call to the built-in signbit, signbitf or signbitl function.
4978 Return NULL_RTX if a normal call should be emitted rather than expanding
4979 the function in-line. EXP is the expression that is a call to the builtin
4980 function; if convenient, the result should be placed in TARGET. */
4983 expand_builtin_signbit (tree exp
, rtx target
)
4985 const struct real_format
*fmt
;
4986 enum machine_mode fmode
, imode
, rmode
;
4987 HOST_WIDE_INT hi
, lo
;
4992 arglist
= TREE_OPERAND (exp
, 1);
4993 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
4996 arg
= TREE_VALUE (arglist
);
4997 fmode
= TYPE_MODE (TREE_TYPE (arg
));
4998 rmode
= TYPE_MODE (TREE_TYPE (exp
));
4999 fmt
= REAL_MODE_FORMAT (fmode
);
5001 /* For floating point formats without a sign bit, implement signbit
5003 if (fmt
->signbit
< 0)
5005 /* But we can't do this if the format supports signed zero. */
5006 if (fmt
->has_signed_zero
&& HONOR_SIGNED_ZEROS (fmode
))
5009 arg
= fold (build (LT_EXPR
, TREE_TYPE (exp
), arg
,
5010 build_real (TREE_TYPE (arg
), dconst0
)));
5011 return expand_expr (arg
, target
, VOIDmode
, EXPAND_NORMAL
);
5014 imode
= int_mode_for_mode (fmode
);
5015 if (imode
== BLKmode
)
5018 bitpos
= fmt
->signbit
;
5019 /* Handle targets with different FP word orders. */
5020 if (FLOAT_WORDS_BIG_ENDIAN
!= WORDS_BIG_ENDIAN
)
5022 int nwords
= GET_MODE_BITSIZE (fmode
) / BITS_PER_WORD
;
5023 int word
= nwords
- (bitpos
/ BITS_PER_WORD
) - 1;
5024 bitpos
= word
* BITS_PER_WORD
+ bitpos
% BITS_PER_WORD
;
5027 /* If the sign bit is not in the lowpart and the floating point format
5028 is wider than an integer, check that is twice the size of an integer
5029 so that we can use gen_highpart below. */
5030 if (bitpos
>= GET_MODE_BITSIZE (rmode
)
5031 && GET_MODE_BITSIZE (imode
) != 2 * GET_MODE_BITSIZE (rmode
))
5034 temp
= expand_expr (arg
, NULL_RTX
, VOIDmode
, 0);
5035 temp
= gen_lowpart (imode
, temp
);
5037 if (GET_MODE_BITSIZE (imode
) > GET_MODE_BITSIZE (rmode
))
5039 if (BITS_BIG_ENDIAN
)
5040 bitpos
= GET_MODE_BITSIZE (imode
) - 1 - bitpos
;
5041 temp
= copy_to_mode_reg (imode
, temp
);
5042 temp
= extract_bit_field (temp
, 1, bitpos
, 1,
5043 NULL_RTX
, rmode
, rmode
,
5044 GET_MODE_SIZE (imode
));
5048 if (GET_MODE_BITSIZE (imode
) < GET_MODE_BITSIZE (rmode
))
5049 temp
= gen_lowpart (rmode
, temp
);
5050 if (bitpos
< HOST_BITS_PER_WIDE_INT
)
5053 lo
= (HOST_WIDE_INT
) 1 << bitpos
;
5057 hi
= (HOST_WIDE_INT
) 1 << (bitpos
- HOST_BITS_PER_WIDE_INT
);
5061 temp
= force_reg (rmode
, temp
);
5062 temp
= expand_binop (rmode
, and_optab
, temp
,
5063 immed_double_const (lo
, hi
, rmode
),
5064 target
, 1, OPTAB_LIB_WIDEN
);
5069 /* Expand an expression EXP that calls a built-in function,
5070 with result going to TARGET if that's convenient
5071 (and in mode MODE if that's convenient).
5072 SUBTARGET may be used as the target for computing one of EXP's operands.
5073 IGNORE is nonzero if the value is to be ignored. */
5076 expand_builtin (tree exp
, rtx target
, rtx subtarget
, enum machine_mode mode
,
5079 tree fndecl
= get_callee_fndecl (exp
);
5080 tree arglist
= TREE_OPERAND (exp
, 1);
5081 enum built_in_function fcode
= DECL_FUNCTION_CODE (fndecl
);
5082 enum machine_mode target_mode
= TYPE_MODE (TREE_TYPE (exp
));
5084 /* Perform postincrements before expanding builtin functions. */
5087 if (DECL_BUILT_IN_CLASS (fndecl
) == BUILT_IN_MD
)
5088 return targetm
.expand_builtin (exp
, target
, subtarget
, mode
, ignore
);
5090 /* When not optimizing, generate calls to library functions for a certain
5093 && !CALLED_AS_BUILT_IN (fndecl
)
5094 && DECL_ASSEMBLER_NAME_SET_P (fndecl
)
5095 && fcode
!= BUILT_IN_ALLOCA
)
5096 return expand_call (exp
, target
, ignore
);
5098 /* The built-in function expanders test for target == const0_rtx
5099 to determine whether the function's result will be ignored. */
5101 target
= const0_rtx
;
5103 /* If the result of a pure or const built-in function is ignored, and
5104 none of its arguments are volatile, we can avoid expanding the
5105 built-in call and just evaluate the arguments for side-effects. */
5106 if (target
== const0_rtx
5107 && (DECL_IS_PURE (fndecl
) || TREE_READONLY (fndecl
)))
5109 bool volatilep
= false;
5112 for (arg
= arglist
; arg
; arg
= TREE_CHAIN (arg
))
5113 if (TREE_THIS_VOLATILE (TREE_VALUE (arg
)))
5121 for (arg
= arglist
; arg
; arg
= TREE_CHAIN (arg
))
5122 expand_expr (TREE_VALUE (arg
), const0_rtx
,
5123 VOIDmode
, EXPAND_NORMAL
);
5132 case BUILT_IN_LLABS
:
5133 case BUILT_IN_IMAXABS
:
5134 /* build_function_call changes these into ABS_EXPR. */
5138 case BUILT_IN_FABSF
:
5139 case BUILT_IN_FABSL
:
5140 target
= expand_builtin_fabs (arglist
, target
, subtarget
);
5146 case BUILT_IN_CABSF
:
5147 case BUILT_IN_CABSL
:
5148 if (flag_unsafe_math_optimizations
)
5150 target
= expand_builtin_cabs (arglist
, target
);
5157 case BUILT_IN_CONJF
:
5158 case BUILT_IN_CONJL
:
5159 case BUILT_IN_CREAL
:
5160 case BUILT_IN_CREALF
:
5161 case BUILT_IN_CREALL
:
5162 case BUILT_IN_CIMAG
:
5163 case BUILT_IN_CIMAGF
:
5164 case BUILT_IN_CIMAGL
:
5165 /* expand_tree_builtin changes these into CONJ_EXPR, REALPART_EXPR
5166 and IMAGPART_EXPR. */
5172 case BUILT_IN_EXP10
:
5173 case BUILT_IN_EXP10F
:
5174 case BUILT_IN_EXP10L
:
5175 case BUILT_IN_POW10
:
5176 case BUILT_IN_POW10F
:
5177 case BUILT_IN_POW10L
:
5179 case BUILT_IN_EXP2F
:
5180 case BUILT_IN_EXP2L
:
5184 case BUILT_IN_LOG10
:
5185 case BUILT_IN_LOG10F
:
5186 case BUILT_IN_LOG10L
:
5188 case BUILT_IN_LOG2F
:
5189 case BUILT_IN_LOG2L
:
5194 case BUILT_IN_ATANF
:
5195 case BUILT_IN_ATANL
:
5196 /* Treat these like sqrt only if unsafe math optimizations are allowed,
5197 because of possible accuracy problems. */
5198 if (! flag_unsafe_math_optimizations
)
5201 case BUILT_IN_SQRTF
:
5202 case BUILT_IN_SQRTL
:
5203 case BUILT_IN_FLOOR
:
5204 case BUILT_IN_FLOORF
:
5205 case BUILT_IN_FLOORL
:
5207 case BUILT_IN_CEILF
:
5208 case BUILT_IN_CEILL
:
5209 case BUILT_IN_TRUNC
:
5210 case BUILT_IN_TRUNCF
:
5211 case BUILT_IN_TRUNCL
:
5212 case BUILT_IN_ROUND
:
5213 case BUILT_IN_ROUNDF
:
5214 case BUILT_IN_ROUNDL
:
5215 case BUILT_IN_NEARBYINT
:
5216 case BUILT_IN_NEARBYINTF
:
5217 case BUILT_IN_NEARBYINTL
:
5218 target
= expand_builtin_mathfn (exp
, target
, subtarget
);
5226 target
= expand_builtin_pow (exp
, target
, subtarget
);
5231 case BUILT_IN_ATAN2
:
5232 case BUILT_IN_ATAN2F
:
5233 case BUILT_IN_ATAN2L
:
5234 if (! flag_unsafe_math_optimizations
)
5236 target
= expand_builtin_mathfn_2 (exp
, target
, subtarget
);
5247 if (! flag_unsafe_math_optimizations
)
5249 target
= expand_builtin_mathfn_3 (exp
, target
, subtarget
);
5254 case BUILT_IN_APPLY_ARGS
:
5255 return expand_builtin_apply_args ();
5257 /* __builtin_apply (FUNCTION, ARGUMENTS, ARGSIZE) invokes
5258 FUNCTION with a copy of the parameters described by
5259 ARGUMENTS, and ARGSIZE. It returns a block of memory
5260 allocated on the stack into which is stored all the registers
5261 that might possibly be used for returning the result of a
5262 function. ARGUMENTS is the value returned by
5263 __builtin_apply_args. ARGSIZE is the number of bytes of
5264 arguments that must be copied. ??? How should this value be
5265 computed? We'll also need a safe worst case value for varargs
5267 case BUILT_IN_APPLY
:
5268 if (!validate_arglist (arglist
, POINTER_TYPE
,
5269 POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
)
5270 && !validate_arglist (arglist
, REFERENCE_TYPE
,
5271 POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
5279 for (t
= arglist
, i
= 0; t
; t
= TREE_CHAIN (t
), i
++)
5280 ops
[i
] = expand_expr (TREE_VALUE (t
), NULL_RTX
, VOIDmode
, 0);
5282 return expand_builtin_apply (ops
[0], ops
[1], ops
[2]);
5285 /* __builtin_return (RESULT) causes the function to return the
5286 value described by RESULT. RESULT is address of the block of
5287 memory returned by __builtin_apply. */
5288 case BUILT_IN_RETURN
:
5289 if (validate_arglist (arglist
, POINTER_TYPE
, VOID_TYPE
))
5290 expand_builtin_return (expand_expr (TREE_VALUE (arglist
),
5291 NULL_RTX
, VOIDmode
, 0));
5294 case BUILT_IN_SAVEREGS
:
5295 return expand_builtin_saveregs ();
5297 case BUILT_IN_ARGS_INFO
:
5298 return expand_builtin_args_info (arglist
);
5300 /* Return the address of the first anonymous stack arg. */
5301 case BUILT_IN_NEXT_ARG
:
5302 return expand_builtin_next_arg (arglist
);
5304 case BUILT_IN_CLASSIFY_TYPE
:
5305 return expand_builtin_classify_type (arglist
);
5307 case BUILT_IN_CONSTANT_P
:
5308 return expand_builtin_constant_p (arglist
, target_mode
);
5310 case BUILT_IN_FRAME_ADDRESS
:
5311 case BUILT_IN_RETURN_ADDRESS
:
5312 return expand_builtin_frame_address (fndecl
, arglist
);
5314 /* Returns the address of the area where the structure is returned.
5316 case BUILT_IN_AGGREGATE_INCOMING_ADDRESS
:
5318 || ! AGGREGATE_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl
)))
5319 || GET_CODE (DECL_RTL (DECL_RESULT (current_function_decl
))) != MEM
)
5322 return XEXP (DECL_RTL (DECL_RESULT (current_function_decl
)), 0);
5324 case BUILT_IN_ALLOCA
:
5325 target
= expand_builtin_alloca (arglist
, target
);
5332 case BUILT_IN_FFSLL
:
5333 target
= expand_builtin_unop (target_mode
, arglist
, target
,
5334 subtarget
, ffs_optab
);
5341 case BUILT_IN_CLZLL
:
5342 target
= expand_builtin_unop (target_mode
, arglist
, target
,
5343 subtarget
, clz_optab
);
5350 case BUILT_IN_CTZLL
:
5351 target
= expand_builtin_unop (target_mode
, arglist
, target
,
5352 subtarget
, ctz_optab
);
5357 case BUILT_IN_POPCOUNT
:
5358 case BUILT_IN_POPCOUNTL
:
5359 case BUILT_IN_POPCOUNTLL
:
5360 target
= expand_builtin_unop (target_mode
, arglist
, target
,
5361 subtarget
, popcount_optab
);
5366 case BUILT_IN_PARITY
:
5367 case BUILT_IN_PARITYL
:
5368 case BUILT_IN_PARITYLL
:
5369 target
= expand_builtin_unop (target_mode
, arglist
, target
,
5370 subtarget
, parity_optab
);
5375 case BUILT_IN_STRLEN
:
5376 target
= expand_builtin_strlen (arglist
, target
, target_mode
);
5381 case BUILT_IN_STRCPY
:
5382 target
= expand_builtin_strcpy (arglist
, target
, mode
);
5387 case BUILT_IN_STRNCPY
:
5388 target
= expand_builtin_strncpy (arglist
, target
, mode
);
5393 case BUILT_IN_STPCPY
:
5394 target
= expand_builtin_stpcpy (arglist
, target
, mode
);
5399 case BUILT_IN_STRCAT
:
5400 target
= expand_builtin_strcat (arglist
, target
, mode
);
5405 case BUILT_IN_STRNCAT
:
5406 target
= expand_builtin_strncat (arglist
, target
, mode
);
5411 case BUILT_IN_STRSPN
:
5412 target
= expand_builtin_strspn (arglist
, target
, mode
);
5417 case BUILT_IN_STRCSPN
:
5418 target
= expand_builtin_strcspn (arglist
, target
, mode
);
5423 case BUILT_IN_STRSTR
:
5424 target
= expand_builtin_strstr (arglist
, target
, mode
);
5429 case BUILT_IN_STRPBRK
:
5430 target
= expand_builtin_strpbrk (arglist
, target
, mode
);
5435 case BUILT_IN_INDEX
:
5436 case BUILT_IN_STRCHR
:
5437 target
= expand_builtin_strchr (arglist
, target
, mode
);
5442 case BUILT_IN_RINDEX
:
5443 case BUILT_IN_STRRCHR
:
5444 target
= expand_builtin_strrchr (arglist
, target
, mode
);
5449 case BUILT_IN_MEMCPY
:
5450 target
= expand_builtin_memcpy (arglist
, target
, mode
);
5455 case BUILT_IN_MEMPCPY
:
5456 target
= expand_builtin_mempcpy (arglist
, target
, mode
, /*endp=*/ 1);
5461 case BUILT_IN_MEMMOVE
:
5462 target
= expand_builtin_memmove (arglist
, target
, mode
);
5467 case BUILT_IN_BCOPY
:
5468 target
= expand_builtin_bcopy (arglist
);
5473 case BUILT_IN_MEMSET
:
5474 target
= expand_builtin_memset (arglist
, target
, mode
);
5479 case BUILT_IN_BZERO
:
5480 target
= expand_builtin_bzero (arglist
);
5485 case BUILT_IN_STRCMP
:
5486 target
= expand_builtin_strcmp (exp
, target
, mode
);
5491 case BUILT_IN_STRNCMP
:
5492 target
= expand_builtin_strncmp (exp
, target
, mode
);
5498 case BUILT_IN_MEMCMP
:
5499 target
= expand_builtin_memcmp (exp
, arglist
, target
, mode
);
5504 case BUILT_IN_SETJMP
:
5505 target
= expand_builtin_setjmp (arglist
, target
);
5510 /* __builtin_longjmp is passed a pointer to an array of five words.
5511 It's similar to the C library longjmp function but works with
5512 __builtin_setjmp above. */
5513 case BUILT_IN_LONGJMP
:
5514 if (!validate_arglist (arglist
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
5518 rtx buf_addr
= expand_expr (TREE_VALUE (arglist
), subtarget
,
5520 rtx value
= expand_expr (TREE_VALUE (TREE_CHAIN (arglist
)),
5521 NULL_RTX
, VOIDmode
, 0);
5523 if (value
!= const1_rtx
)
5525 error ("__builtin_longjmp second argument must be 1");
5529 expand_builtin_longjmp (buf_addr
, value
);
5534 expand_builtin_trap ();
5537 case BUILT_IN_PRINTF
:
5538 target
= expand_builtin_printf (arglist
, target
, mode
, false);
5543 case BUILT_IN_PRINTF_UNLOCKED
:
5544 target
= expand_builtin_printf (arglist
, target
, mode
, true);
5549 case BUILT_IN_FPUTS
:
5550 target
= expand_builtin_fputs (arglist
, target
, false);
5555 case BUILT_IN_FPUTS_UNLOCKED
:
5556 target
= expand_builtin_fputs (arglist
, target
, true);
5561 case BUILT_IN_FPRINTF
:
5562 target
= expand_builtin_fprintf (arglist
, target
, mode
, false);
5567 case BUILT_IN_FPRINTF_UNLOCKED
:
5568 target
= expand_builtin_fprintf (arglist
, target
, mode
, true);
5573 case BUILT_IN_SPRINTF
:
5574 target
= expand_builtin_sprintf (arglist
, target
, mode
);
5579 case BUILT_IN_SIGNBIT
:
5580 case BUILT_IN_SIGNBITF
:
5581 case BUILT_IN_SIGNBITL
:
5582 target
= expand_builtin_signbit (exp
, target
);
5587 /* Various hooks for the DWARF 2 __throw routine. */
5588 case BUILT_IN_UNWIND_INIT
:
5589 expand_builtin_unwind_init ();
5591 case BUILT_IN_DWARF_CFA
:
5592 return virtual_cfa_rtx
;
5593 #ifdef DWARF2_UNWIND_INFO
5594 case BUILT_IN_DWARF_SP_COLUMN
:
5595 return expand_builtin_dwarf_sp_column ();
5596 case BUILT_IN_INIT_DWARF_REG_SIZES
:
5597 expand_builtin_init_dwarf_reg_sizes (TREE_VALUE (arglist
));
5600 case BUILT_IN_FROB_RETURN_ADDR
:
5601 return expand_builtin_frob_return_addr (TREE_VALUE (arglist
));
5602 case BUILT_IN_EXTRACT_RETURN_ADDR
:
5603 return expand_builtin_extract_return_addr (TREE_VALUE (arglist
));
5604 case BUILT_IN_EH_RETURN
:
5605 expand_builtin_eh_return (TREE_VALUE (arglist
),
5606 TREE_VALUE (TREE_CHAIN (arglist
)));
5608 #ifdef EH_RETURN_DATA_REGNO
5609 case BUILT_IN_EH_RETURN_DATA_REGNO
:
5610 return expand_builtin_eh_return_data_regno (arglist
);
5612 case BUILT_IN_EXTEND_POINTER
:
5613 return expand_builtin_extend_pointer (TREE_VALUE (arglist
));
5615 case BUILT_IN_VA_START
:
5616 case BUILT_IN_STDARG_START
:
5617 return expand_builtin_va_start (arglist
);
5618 case BUILT_IN_VA_END
:
5619 return expand_builtin_va_end (arglist
);
5620 case BUILT_IN_VA_COPY
:
5621 return expand_builtin_va_copy (arglist
);
5622 case BUILT_IN_EXPECT
:
5623 return expand_builtin_expect (arglist
, target
);
5624 case BUILT_IN_PREFETCH
:
5625 expand_builtin_prefetch (arglist
);
5629 default: /* just do library call, if unknown builtin */
5630 if (!DECL_ASSEMBLER_NAME_SET_P (fndecl
))
5631 error ("built-in function `%s' not currently supported",
5632 IDENTIFIER_POINTER (DECL_NAME (fndecl
)));
5635 /* The switch statement above can drop through to cause the function
5636 to be called normally. */
5637 return expand_call (exp
, target
, ignore
);
5640 /* Determine whether a tree node represents a call to a built-in
5641 function. If the tree T is a call to a built-in function with
5642 the right number of arguments of the appropriate types, return
5643 the DECL_FUNCTION_CODE of the call, e.g. BUILT_IN_SQRT.
5644 Otherwise the return value is END_BUILTINS. */
5646 enum built_in_function
5647 builtin_mathfn_code (tree t
)
5649 tree fndecl
, arglist
, parmlist
;
5650 tree argtype
, parmtype
;
5652 if (TREE_CODE (t
) != CALL_EXPR
5653 || TREE_CODE (TREE_OPERAND (t
, 0)) != ADDR_EXPR
)
5654 return END_BUILTINS
;
5656 fndecl
= get_callee_fndecl (t
);
5657 if (fndecl
== NULL_TREE
5658 || TREE_CODE (fndecl
) != FUNCTION_DECL
5659 || ! DECL_BUILT_IN (fndecl
)
5660 || DECL_BUILT_IN_CLASS (fndecl
) == BUILT_IN_MD
)
5661 return END_BUILTINS
;
5663 arglist
= TREE_OPERAND (t
, 1);
5664 parmlist
= TYPE_ARG_TYPES (TREE_TYPE (fndecl
));
5665 for (; parmlist
; parmlist
= TREE_CHAIN (parmlist
))
5667 /* If a function doesn't take a variable number of arguments,
5668 the last element in the list will have type `void'. */
5669 parmtype
= TREE_VALUE (parmlist
);
5670 if (VOID_TYPE_P (parmtype
))
5673 return END_BUILTINS
;
5674 return DECL_FUNCTION_CODE (fndecl
);
5678 return END_BUILTINS
;
5680 argtype
= TREE_TYPE (TREE_VALUE (arglist
));
5682 if (SCALAR_FLOAT_TYPE_P (parmtype
))
5684 if (! SCALAR_FLOAT_TYPE_P (argtype
))
5685 return END_BUILTINS
;
5687 else if (COMPLEX_FLOAT_TYPE_P (parmtype
))
5689 if (! COMPLEX_FLOAT_TYPE_P (argtype
))
5690 return END_BUILTINS
;
5692 else if (POINTER_TYPE_P (parmtype
))
5694 if (! POINTER_TYPE_P (argtype
))
5695 return END_BUILTINS
;
5697 else if (INTEGRAL_TYPE_P (parmtype
))
5699 if (! INTEGRAL_TYPE_P (argtype
))
5700 return END_BUILTINS
;
5703 return END_BUILTINS
;
5705 arglist
= TREE_CHAIN (arglist
);
5708 /* Variable-length argument list. */
5709 return DECL_FUNCTION_CODE (fndecl
);
5712 /* Fold a call to __builtin_constant_p, if we know it will evaluate to a
5713 constant. ARGLIST is the argument list of the call. */
5716 fold_builtin_constant_p (tree arglist
)
5721 arglist
= TREE_VALUE (arglist
);
5723 /* We return 1 for a numeric type that's known to be a constant
5724 value at compile-time or for an aggregate type that's a
5725 literal constant. */
5726 STRIP_NOPS (arglist
);
5728 /* If we know this is a constant, emit the constant of one. */
5729 if (TREE_CODE_CLASS (TREE_CODE (arglist
)) == 'c'
5730 || (TREE_CODE (arglist
) == CONSTRUCTOR
5731 && TREE_CONSTANT (arglist
))
5732 || (TREE_CODE (arglist
) == ADDR_EXPR
5733 && TREE_CODE (TREE_OPERAND (arglist
, 0)) == STRING_CST
))
5734 return integer_one_node
;
5736 /* If this expression has side effects, show we don't know it to be a
5737 constant. Likewise if it's a pointer or aggregate type since in
5738 those case we only want literals, since those are only optimized
5739 when generating RTL, not later.
5740 And finally, if we are compiling an initializer, not code, we
5741 need to return a definite result now; there's not going to be any
5742 more optimization done. */
5743 if (TREE_SIDE_EFFECTS (arglist
)
5744 || AGGREGATE_TYPE_P (TREE_TYPE (arglist
))
5745 || POINTER_TYPE_P (TREE_TYPE (arglist
))
5747 return integer_zero_node
;
5752 /* Fold a call to __builtin_classify_type. */
5755 fold_builtin_classify_type (tree arglist
)
5758 return build_int_2 (no_type_class
, 0);
5760 return build_int_2 (type_to_class (TREE_TYPE (TREE_VALUE (arglist
))), 0);
5763 /* Fold a call to __builtin_inf or __builtin_huge_val. */
5766 fold_builtin_inf (tree type
, int warn
)
5768 REAL_VALUE_TYPE real
;
5770 if (!MODE_HAS_INFINITIES (TYPE_MODE (type
)) && warn
)
5771 warning ("target format does not support infinity");
5774 return build_real (type
, real
);
5777 /* Fold a call to __builtin_nan or __builtin_nans. */
5780 fold_builtin_nan (tree arglist
, tree type
, int quiet
)
5782 REAL_VALUE_TYPE real
;
5785 if (!validate_arglist (arglist
, POINTER_TYPE
, VOID_TYPE
))
5787 str
= c_getstr (TREE_VALUE (arglist
));
5791 if (!real_nan (&real
, str
, quiet
, TYPE_MODE (type
)))
5794 return build_real (type
, real
);
5797 /* Return true if the floating point expression T has an integer value.
5798 We also allow +Inf, -Inf and NaN to be considered integer values. */
5801 integer_valued_real_p (tree t
)
5803 switch (TREE_CODE (t
))
5810 case NON_LVALUE_EXPR
:
5811 return integer_valued_real_p (TREE_OPERAND (t
, 0));
5816 return integer_valued_real_p (TREE_OPERAND (t
, 1));
5823 return integer_valued_real_p (TREE_OPERAND (t
, 0))
5824 && integer_valued_real_p (TREE_OPERAND (t
, 1));
5827 return integer_valued_real_p (TREE_OPERAND (t
, 1))
5828 && integer_valued_real_p (TREE_OPERAND (t
, 2));
5831 if (! TREE_CONSTANT_OVERFLOW (t
))
5833 REAL_VALUE_TYPE c
, cint
;
5835 c
= TREE_REAL_CST (t
);
5836 real_trunc (&cint
, TYPE_MODE (TREE_TYPE (t
)), &c
);
5837 return real_identical (&c
, &cint
);
5842 tree type
= TREE_TYPE (TREE_OPERAND (t
, 0));
5843 if (TREE_CODE (type
) == INTEGER_TYPE
)
5845 if (TREE_CODE (type
) == REAL_TYPE
)
5846 return integer_valued_real_p (TREE_OPERAND (t
, 0));
5851 switch (builtin_mathfn_code (t
))
5854 case BUILT_IN_CEILF
:
5855 case BUILT_IN_CEILL
:
5856 case BUILT_IN_FLOOR
:
5857 case BUILT_IN_FLOORF
:
5858 case BUILT_IN_FLOORL
:
5859 case BUILT_IN_NEARBYINT
:
5860 case BUILT_IN_NEARBYINTF
:
5861 case BUILT_IN_NEARBYINTL
:
5863 case BUILT_IN_RINTF
:
5864 case BUILT_IN_RINTL
:
5865 case BUILT_IN_ROUND
:
5866 case BUILT_IN_ROUNDF
:
5867 case BUILT_IN_ROUNDL
:
5868 case BUILT_IN_TRUNC
:
5869 case BUILT_IN_TRUNCF
:
5870 case BUILT_IN_TRUNCL
:
5884 /* EXP is assumed to be builtin call where truncation can be propagated
5885 across (for instance floor((double)f) == (double)floorf (f).
5886 Do the transformation. */
5889 fold_trunc_transparent_mathfn (tree exp
)
5891 tree fndecl
= get_callee_fndecl (exp
);
5892 tree arglist
= TREE_OPERAND (exp
, 1);
5893 enum built_in_function fcode
= DECL_FUNCTION_CODE (fndecl
);
5896 if (! validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
5899 arg
= TREE_VALUE (arglist
);
5900 /* Integer rounding functions are idempotent. */
5901 if (fcode
== builtin_mathfn_code (arg
))
5904 /* If argument is already integer valued, and we don't need to worry
5905 about setting errno, there's no need to perform rounding. */
5906 if (! flag_errno_math
&& integer_valued_real_p (arg
))
5911 tree arg0
= strip_float_extensions (arg
);
5912 tree ftype
= TREE_TYPE (exp
);
5913 tree newtype
= TREE_TYPE (arg0
);
5916 if (TYPE_PRECISION (newtype
) < TYPE_PRECISION (ftype
)
5917 && (decl
= mathfn_built_in (newtype
, fcode
)))
5920 build_tree_list (NULL_TREE
, fold (convert (newtype
, arg0
)));
5921 return convert (ftype
,
5922 build_function_call_expr (decl
, arglist
));
5928 /* Fold function call to builtin cabs, cabsf or cabsl. FNDECL is the
5929 function's DECL, ARGLIST is the argument list and TYPE is the return
5930 type. Return NULL_TREE if no simplification can be made. */
5933 fold_builtin_cabs (tree fndecl
, tree arglist
, tree type
)
5937 if (!arglist
|| TREE_CHAIN (arglist
))
5940 arg
= TREE_VALUE (arglist
);
5941 if (TREE_CODE (TREE_TYPE (arg
)) != COMPLEX_TYPE
5942 || TREE_CODE (TREE_TYPE (TREE_TYPE (arg
))) != REAL_TYPE
)
5945 /* Evaluate cabs of a constant at compile-time. */
5946 if (flag_unsafe_math_optimizations
5947 && TREE_CODE (arg
) == COMPLEX_CST
5948 && TREE_CODE (TREE_REALPART (arg
)) == REAL_CST
5949 && TREE_CODE (TREE_IMAGPART (arg
)) == REAL_CST
5950 && ! TREE_CONSTANT_OVERFLOW (TREE_REALPART (arg
))
5951 && ! TREE_CONSTANT_OVERFLOW (TREE_IMAGPART (arg
)))
5953 REAL_VALUE_TYPE r
, i
;
5955 r
= TREE_REAL_CST (TREE_REALPART (arg
));
5956 i
= TREE_REAL_CST (TREE_IMAGPART (arg
));
5958 real_arithmetic (&r
, MULT_EXPR
, &r
, &r
);
5959 real_arithmetic (&i
, MULT_EXPR
, &i
, &i
);
5960 real_arithmetic (&r
, PLUS_EXPR
, &r
, &i
);
5961 if (real_sqrt (&r
, TYPE_MODE (type
), &r
)
5962 || ! flag_trapping_math
)
5963 return build_real (type
, r
);
5966 /* If either part is zero, cabs is fabs of the other. */
5967 if (TREE_CODE (arg
) == COMPLEX_EXPR
5968 && real_zerop (TREE_OPERAND (arg
, 0)))
5969 return fold (build1 (ABS_EXPR
, type
, TREE_OPERAND (arg
, 1)));
5970 if (TREE_CODE (arg
) == COMPLEX_EXPR
5971 && real_zerop (TREE_OPERAND (arg
, 1)))
5972 return fold (build1 (ABS_EXPR
, type
, TREE_OPERAND (arg
, 0)));
5974 if (flag_unsafe_math_optimizations
)
5976 enum built_in_function fcode
;
5979 fcode
= DECL_FUNCTION_CODE (fndecl
);
5980 if (fcode
== BUILT_IN_CABS
)
5981 sqrtfn
= implicit_built_in_decls
[BUILT_IN_SQRT
];
5982 else if (fcode
== BUILT_IN_CABSF
)
5983 sqrtfn
= implicit_built_in_decls
[BUILT_IN_SQRTF
];
5984 else if (fcode
== BUILT_IN_CABSL
)
5985 sqrtfn
= implicit_built_in_decls
[BUILT_IN_SQRTL
];
5989 if (sqrtfn
!= NULL_TREE
)
5991 tree rpart
, ipart
, result
, arglist
;
5993 arg
= save_expr (arg
);
5995 rpart
= fold (build1 (REALPART_EXPR
, type
, arg
));
5996 ipart
= fold (build1 (IMAGPART_EXPR
, type
, arg
));
5998 rpart
= save_expr (rpart
);
5999 ipart
= save_expr (ipart
);
6001 result
= fold (build (PLUS_EXPR
, type
,
6002 fold (build (MULT_EXPR
, type
,
6004 fold (build (MULT_EXPR
, type
,
6007 arglist
= build_tree_list (NULL_TREE
, result
);
6008 return build_function_call_expr (sqrtfn
, arglist
);
6015 /* Fold function call to builtin trunc, truncf or truncl. Return
6016 NULL_TREE if no simplification can be made. */
6019 fold_builtin_trunc (tree exp
)
6021 tree arglist
= TREE_OPERAND (exp
, 1);
6024 if (! validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
6027 /* Optimize trunc of constant value. */
6028 arg
= TREE_VALUE (arglist
);
6029 if (TREE_CODE (arg
) == REAL_CST
&& ! TREE_CONSTANT_OVERFLOW (arg
))
6031 REAL_VALUE_TYPE r
, x
;
6032 tree type
= TREE_TYPE (exp
);
6034 x
= TREE_REAL_CST (arg
);
6035 real_trunc (&r
, TYPE_MODE (type
), &x
);
6036 return build_real (type
, r
);
6039 return fold_trunc_transparent_mathfn (exp
);
6042 /* Fold function call to builtin floor, floorf or floorl. Return
6043 NULL_TREE if no simplification can be made. */
6046 fold_builtin_floor (tree exp
)
6048 tree arglist
= TREE_OPERAND (exp
, 1);
6051 if (! validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
6054 /* Optimize floor of constant value. */
6055 arg
= TREE_VALUE (arglist
);
6056 if (TREE_CODE (arg
) == REAL_CST
&& ! TREE_CONSTANT_OVERFLOW (arg
))
6060 x
= TREE_REAL_CST (arg
);
6061 if (! REAL_VALUE_ISNAN (x
) || ! flag_errno_math
)
6063 tree type
= TREE_TYPE (exp
);
6066 real_floor (&r
, TYPE_MODE (type
), &x
);
6067 return build_real (type
, r
);
6071 return fold_trunc_transparent_mathfn (exp
);
6074 /* Fold function call to builtin ceil, ceilf or ceill. Return
6075 NULL_TREE if no simplification can be made. */
6078 fold_builtin_ceil (tree exp
)
6080 tree arglist
= TREE_OPERAND (exp
, 1);
6083 if (! validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
6086 /* Optimize ceil of constant value. */
6087 arg
= TREE_VALUE (arglist
);
6088 if (TREE_CODE (arg
) == REAL_CST
&& ! TREE_CONSTANT_OVERFLOW (arg
))
6092 x
= TREE_REAL_CST (arg
);
6093 if (! REAL_VALUE_ISNAN (x
) || ! flag_errno_math
)
6095 tree type
= TREE_TYPE (exp
);
6098 real_ceil (&r
, TYPE_MODE (type
), &x
);
6099 return build_real (type
, r
);
6103 return fold_trunc_transparent_mathfn (exp
);
6106 /* Fold function call to builtin round, roundf or roundl. Return
6107 NULL_TREE if no simplification can be made. */
6110 fold_builtin_round (tree exp
)
6112 tree arglist
= TREE_OPERAND (exp
, 1);
6115 if (! validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
6118 /* Optimize ceil of constant value. */
6119 arg
= TREE_VALUE (arglist
);
6120 if (TREE_CODE (arg
) == REAL_CST
&& ! TREE_CONSTANT_OVERFLOW (arg
))
6124 x
= TREE_REAL_CST (arg
);
6125 if (! REAL_VALUE_ISNAN (x
) || ! flag_errno_math
)
6127 tree type
= TREE_TYPE (exp
);
6130 real_round (&r
, TYPE_MODE (type
), &x
);
6131 return build_real (type
, r
);
6135 return fold_trunc_transparent_mathfn (exp
);
6138 /* Fold function call to builtin ffs, clz, ctz, popcount and parity
6139 and their long and long long variants (i.e. ffsl and ffsll).
6140 Return NULL_TREE if no simplification can be made. */
6143 fold_builtin_bitop (tree exp
)
6145 tree fndecl
= get_callee_fndecl (exp
);
6146 tree arglist
= TREE_OPERAND (exp
, 1);
6149 if (! validate_arglist (arglist
, INTEGER_TYPE
, VOID_TYPE
))
6152 /* Optimize for constant argument. */
6153 arg
= TREE_VALUE (arglist
);
6154 if (TREE_CODE (arg
) == INTEGER_CST
&& ! TREE_CONSTANT_OVERFLOW (arg
))
6156 HOST_WIDE_INT hi
, width
, result
;
6157 unsigned HOST_WIDE_INT lo
;
6160 type
= TREE_TYPE (arg
);
6161 width
= TYPE_PRECISION (type
);
6162 lo
= TREE_INT_CST_LOW (arg
);
6164 /* Clear all the bits that are beyond the type's precision. */
6165 if (width
> HOST_BITS_PER_WIDE_INT
)
6167 hi
= TREE_INT_CST_HIGH (arg
);
6168 if (width
< 2 * HOST_BITS_PER_WIDE_INT
)
6169 hi
&= ~((HOST_WIDE_INT
) (-1) >> (width
- HOST_BITS_PER_WIDE_INT
));
6174 if (width
< HOST_BITS_PER_WIDE_INT
)
6175 lo
&= ~((unsigned HOST_WIDE_INT
) (-1) << width
);
6178 switch (DECL_FUNCTION_CODE (fndecl
))
6182 case BUILT_IN_FFSLL
:
6184 result
= exact_log2 (lo
& -lo
) + 1;
6186 result
= HOST_BITS_PER_WIDE_INT
+ exact_log2 (hi
& -hi
) + 1;
6193 case BUILT_IN_CLZLL
:
6195 result
= width
- floor_log2 (hi
) - 1 - HOST_BITS_PER_WIDE_INT
;
6197 result
= width
- floor_log2 (lo
) - 1;
6198 else if (! CLZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type
), result
))
6204 case BUILT_IN_CTZLL
:
6206 result
= exact_log2 (lo
& -lo
);
6208 result
= HOST_BITS_PER_WIDE_INT
+ exact_log2 (hi
& -hi
);
6209 else if (! CTZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type
), result
))
6213 case BUILT_IN_POPCOUNT
:
6214 case BUILT_IN_POPCOUNTL
:
6215 case BUILT_IN_POPCOUNTLL
:
6218 result
++, lo
&= lo
- 1;
6220 result
++, hi
&= hi
- 1;
6223 case BUILT_IN_PARITY
:
6224 case BUILT_IN_PARITYL
:
6225 case BUILT_IN_PARITYLL
:
6228 result
++, lo
&= lo
- 1;
6230 result
++, hi
&= hi
- 1;
6238 t
= build_int_2 (result
, 0);
6239 TREE_TYPE (t
) = TREE_TYPE (exp
);
6246 /* Return true if EXPR is the real constant contained in VALUE. */
6249 real_dconstp (tree expr
, const REAL_VALUE_TYPE
*value
)
6253 return ((TREE_CODE (expr
) == REAL_CST
6254 && ! TREE_CONSTANT_OVERFLOW (expr
)
6255 && REAL_VALUES_EQUAL (TREE_REAL_CST (expr
), *value
))
6256 || (TREE_CODE (expr
) == COMPLEX_CST
6257 && real_dconstp (TREE_REALPART (expr
), value
)
6258 && real_zerop (TREE_IMAGPART (expr
))));
6261 /* A subroutine of fold_builtin to fold the various logarithmic
6262 functions. EXP is the CALL_EXPR of a call to a builtin logN
6263 function. VALUE is the base of the logN function. */
6266 fold_builtin_logarithm (tree exp
, const REAL_VALUE_TYPE
*value
)
6268 tree arglist
= TREE_OPERAND (exp
, 1);
6270 if (validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
6272 tree fndecl
= get_callee_fndecl (exp
);
6273 tree type
= TREE_TYPE (TREE_TYPE (fndecl
));
6274 tree arg
= TREE_VALUE (arglist
);
6275 const enum built_in_function fcode
= builtin_mathfn_code (arg
);
6277 /* Optimize logN(1.0) = 0.0. */
6278 if (real_onep (arg
))
6279 return build_real (type
, dconst0
);
6281 /* Optimize logN(N) = 1.0. If N can't be truncated to MODE
6282 exactly, then only do this if flag_unsafe_math_optimizations. */
6283 if (exact_real_truncate (TYPE_MODE (type
), value
)
6284 || flag_unsafe_math_optimizations
)
6286 const REAL_VALUE_TYPE value_truncate
=
6287 real_value_truncate (TYPE_MODE (type
), *value
);
6288 if (real_dconstp (arg
, &value_truncate
))
6289 return build_real (type
, dconst1
);
6292 /* Special case, optimize logN(expN(x)) = x. */
6293 if (flag_unsafe_math_optimizations
6294 && ((value
== &dconste
6295 && (fcode
== BUILT_IN_EXP
6296 || fcode
== BUILT_IN_EXPF
6297 || fcode
== BUILT_IN_EXPL
))
6298 || (value
== &dconst2
6299 && (fcode
== BUILT_IN_EXP2
6300 || fcode
== BUILT_IN_EXP2F
6301 || fcode
== BUILT_IN_EXP2L
))
6302 || (value
== &dconst10
&& (BUILTIN_EXP10_P (fcode
)))))
6303 return convert (type
, TREE_VALUE (TREE_OPERAND (arg
, 1)));
6305 /* Optimize logN(func()) for various exponential functions. We
6306 want to determine the value "x" and the power "exponent" in
6307 order to transform logN(x**exponent) into exponent*logN(x). */
6308 if (flag_unsafe_math_optimizations
)
6310 tree exponent
= 0, x
= 0;
6317 /* Prepare to do logN(exp(exponent) -> exponent*logN(e). */
6318 x
= build_real (type
,
6319 real_value_truncate (TYPE_MODE (type
), dconste
));
6320 exponent
= TREE_VALUE (TREE_OPERAND (arg
, 1));
6323 case BUILT_IN_EXP2F
:
6324 case BUILT_IN_EXP2L
:
6325 /* Prepare to do logN(exp2(exponent) -> exponent*logN(2). */
6326 x
= build_real (type
, dconst2
);
6327 exponent
= TREE_VALUE (TREE_OPERAND (arg
, 1));
6329 case BUILT_IN_EXP10
:
6330 case BUILT_IN_EXP10F
:
6331 case BUILT_IN_EXP10L
:
6332 case BUILT_IN_POW10
:
6333 case BUILT_IN_POW10F
:
6334 case BUILT_IN_POW10L
:
6335 /* Prepare to do logN(exp10(exponent) -> exponent*logN(10). */
6336 x
= build_real (type
, dconst10
);
6337 exponent
= TREE_VALUE (TREE_OPERAND (arg
, 1));
6340 case BUILT_IN_SQRTF
:
6341 case BUILT_IN_SQRTL
:
6342 /* Prepare to do logN(sqrt(x) -> 0.5*logN(x). */
6343 x
= TREE_VALUE (TREE_OPERAND (arg
, 1));
6344 exponent
= build_real (type
, dconsthalf
);
6347 case BUILT_IN_CBRTF
:
6348 case BUILT_IN_CBRTL
:
6349 /* Prepare to do logN(cbrt(x) -> (1/3)*logN(x). */
6350 x
= TREE_VALUE (TREE_OPERAND (arg
, 1));
6351 exponent
= build_real (type
, real_value_truncate (TYPE_MODE (type
),
6357 /* Prepare to do logN(pow(x,exponent) -> exponent*logN(x). */
6358 x
= TREE_VALUE (TREE_OPERAND (arg
, 1));
6359 exponent
= TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg
, 1)));
6365 /* Now perform the optimization. */
6369 arglist
= build_tree_list (NULL_TREE
, x
);
6370 logfn
= build_function_call_expr (fndecl
, arglist
);
6371 return fold (build (MULT_EXPR
, type
, exponent
, logfn
));
6379 /* A subroutine of fold_builtin to fold the various exponent
6380 functions. EXP is the CALL_EXPR of a call to a builtin function.
6381 VALUE is the value which will be raised to a power. */
6384 fold_builtin_exponent (tree exp
, const REAL_VALUE_TYPE
*value
)
6386 tree arglist
= TREE_OPERAND (exp
, 1);
6388 if (validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
6390 tree fndecl
= get_callee_fndecl (exp
);
6391 tree type
= TREE_TYPE (TREE_TYPE (fndecl
));
6392 tree arg
= TREE_VALUE (arglist
);
6394 /* Optimize exp*(0.0) = 1.0. */
6395 if (real_zerop (arg
))
6396 return build_real (type
, dconst1
);
6398 /* Optimize expN(1.0) = N. */
6399 if (real_onep (arg
))
6401 REAL_VALUE_TYPE cst
;
6403 real_convert (&cst
, TYPE_MODE (type
), value
);
6404 return build_real (type
, cst
);
6407 /* Attempt to evaluate expN(integer) at compile-time. */
6408 if (flag_unsafe_math_optimizations
6409 && TREE_CODE (arg
) == REAL_CST
6410 && ! TREE_CONSTANT_OVERFLOW (arg
))
6412 REAL_VALUE_TYPE cint
;
6416 c
= TREE_REAL_CST (arg
);
6417 n
= real_to_integer (&c
);
6418 real_from_integer (&cint
, VOIDmode
, n
,
6420 if (real_identical (&c
, &cint
))
6424 real_powi (&x
, TYPE_MODE (type
), value
, n
);
6425 return build_real (type
, x
);
6429 /* Optimize expN(logN(x)) = x. */
6430 if (flag_unsafe_math_optimizations
)
6432 const enum built_in_function fcode
= builtin_mathfn_code (arg
);
6434 if ((value
== &dconste
6435 && (fcode
== BUILT_IN_LOG
6436 || fcode
== BUILT_IN_LOGF
6437 || fcode
== BUILT_IN_LOGL
))
6438 || (value
== &dconst2
6439 && (fcode
== BUILT_IN_LOG2
6440 || fcode
== BUILT_IN_LOG2F
6441 || fcode
== BUILT_IN_LOG2L
))
6442 || (value
== &dconst10
6443 && (fcode
== BUILT_IN_LOG10
6444 || fcode
== BUILT_IN_LOG10F
6445 || fcode
== BUILT_IN_LOG10L
)))
6446 return convert (type
, TREE_VALUE (TREE_OPERAND (arg
, 1)));
6453 /* Fold function call to builtin memcpy. Return
6454 NULL_TREE if no simplification can be made. */
6457 fold_builtin_memcpy (tree exp
)
6459 tree arglist
= TREE_OPERAND (exp
, 1);
6460 tree dest
, src
, len
;
6462 if (!validate_arglist (arglist
,
6463 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
6466 dest
= TREE_VALUE (arglist
);
6467 src
= TREE_VALUE (TREE_CHAIN (arglist
));
6468 len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
6470 /* If the LEN parameter is zero, return DEST. */
6471 if (integer_zerop (len
))
6472 return omit_one_operand (TREE_TYPE (exp
), dest
, src
);
6474 /* If SRC and DEST are the same (and not volatile), return DEST. */
6475 if (operand_equal_p (src
, dest
, 0))
6476 return omit_one_operand (TREE_TYPE (exp
), dest
, len
);
6481 /* Fold function call to builtin mempcpy. Return
6482 NULL_TREE if no simplification can be made. */
6485 fold_builtin_mempcpy (tree exp
)
6487 tree arglist
= TREE_OPERAND (exp
, 1);
6488 tree dest
, src
, len
;
6490 if (!validate_arglist (arglist
,
6491 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
6494 dest
= TREE_VALUE (arglist
);
6495 src
= TREE_VALUE (TREE_CHAIN (arglist
));
6496 len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
6498 /* If the LEN parameter is zero, return DEST. */
6499 if (integer_zerop (len
))
6500 return omit_one_operand (TREE_TYPE (exp
), dest
, src
);
6502 /* If SRC and DEST are the same (and not volatile), return DEST+LEN. */
6503 if (operand_equal_p (src
, dest
, 0))
6505 tree temp
= convert (TREE_TYPE (dest
), len
);
6506 temp
= fold (build (PLUS_EXPR
, TREE_TYPE (dest
), dest
, len
));
6507 return convert (TREE_TYPE (exp
), temp
);
6513 /* Fold function call to builtin memmove. Return
6514 NULL_TREE if no simplification can be made. */
6517 fold_builtin_memmove (tree exp
)
6519 tree arglist
= TREE_OPERAND (exp
, 1);
6520 tree dest
, src
, len
;
6522 if (!validate_arglist (arglist
,
6523 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
6526 dest
= TREE_VALUE (arglist
);
6527 src
= TREE_VALUE (TREE_CHAIN (arglist
));
6528 len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
6530 /* If the LEN parameter is zero, return DEST. */
6531 if (integer_zerop (len
))
6532 return omit_one_operand (TREE_TYPE (exp
), dest
, src
);
6534 /* If SRC and DEST are the same (and not volatile), return DEST. */
6535 if (operand_equal_p (src
, dest
, 0))
6536 return omit_one_operand (TREE_TYPE (exp
), dest
, len
);
6541 /* Fold function call to builtin strcpy. Return
6542 NULL_TREE if no simplification can be made. */
6545 fold_builtin_strcpy (tree exp
)
6547 tree arglist
= TREE_OPERAND (exp
, 1);
6550 if (!validate_arglist (arglist
,
6551 POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
6554 dest
= TREE_VALUE (arglist
);
6555 src
= TREE_VALUE (TREE_CHAIN (arglist
));
6557 /* If SRC and DEST are the same (and not volatile), return DEST. */
6558 if (operand_equal_p (src
, dest
, 0))
6559 return convert (TREE_TYPE (exp
), dest
);
6564 /* Fold function call to builtin strncpy. Return
6565 NULL_TREE if no simplification can be made. */
6568 fold_builtin_strncpy (tree exp
)
6570 tree arglist
= TREE_OPERAND (exp
, 1);
6571 tree dest
, src
, len
;
6573 if (!validate_arglist (arglist
,
6574 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
6577 dest
= TREE_VALUE (arglist
);
6578 src
= TREE_VALUE (TREE_CHAIN (arglist
));
6579 len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
6581 /* If the LEN parameter is zero, return DEST. */
6582 if (integer_zerop (len
))
6583 return omit_one_operand (TREE_TYPE (exp
), dest
, src
);
6588 /* Fold function call to builtin memcmp. Return
6589 NULL_TREE if no simplification can be made. */
6592 fold_builtin_memcmp (tree exp
)
6594 tree arglist
= TREE_OPERAND (exp
, 1);
6595 tree arg1
, arg2
, len
;
6597 if (!validate_arglist (arglist
,
6598 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
6601 arg1
= TREE_VALUE (arglist
);
6602 arg2
= TREE_VALUE (TREE_CHAIN (arglist
));
6603 len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
6605 /* If the LEN parameter is zero, return zero. */
6606 if (integer_zerop (len
))
6608 tree temp
= omit_one_operand (TREE_TYPE (exp
), integer_zero_node
, arg2
);
6609 return omit_one_operand (TREE_TYPE (exp
), temp
, arg1
);
6612 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
6613 if (operand_equal_p (arg1
, arg2
, 0))
6614 return omit_one_operand (TREE_TYPE (exp
), integer_zero_node
, len
);
6619 /* Fold function call to builtin strcmp. Return
6620 NULL_TREE if no simplification can be made. */
6623 fold_builtin_strcmp (tree exp
)
6625 tree arglist
= TREE_OPERAND (exp
, 1);
6627 const char *p1
, *p2
;
6629 if (!validate_arglist (arglist
,
6630 POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
6633 arg1
= TREE_VALUE (arglist
);
6634 arg2
= TREE_VALUE (TREE_CHAIN (arglist
));
6636 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
6637 if (operand_equal_p (arg1
, arg2
, 0))
6638 return convert (TREE_TYPE (exp
), integer_zero_node
);
6640 p1
= c_getstr (arg1
);
6641 p2
= c_getstr (arg2
);
6646 const int i
= strcmp (p1
, p2
);
6648 temp
= integer_minus_one_node
;
6650 temp
= integer_one_node
;
6652 temp
= integer_zero_node
;
6653 return convert (TREE_TYPE (exp
), temp
);
6659 /* Fold function call to builtin strncmp. Return
6660 NULL_TREE if no simplification can be made. */
6663 fold_builtin_strncmp (tree exp
)
6665 tree arglist
= TREE_OPERAND (exp
, 1);
6666 tree arg1
, arg2
, len
;
6667 const char *p1
, *p2
;
6669 if (!validate_arglist (arglist
,
6670 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
6673 arg1
= TREE_VALUE (arglist
);
6674 arg2
= TREE_VALUE (TREE_CHAIN (arglist
));
6675 len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
6677 /* If the LEN parameter is zero, return zero. */
6678 if (integer_zerop (len
))
6680 tree temp
= omit_one_operand (TREE_TYPE (exp
), integer_zero_node
, arg2
);
6681 return omit_one_operand (TREE_TYPE (exp
), temp
, arg1
);
6684 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
6685 if (operand_equal_p (arg1
, arg2
, 0))
6686 return omit_one_operand (TREE_TYPE (exp
), integer_zero_node
, len
);
6688 p1
= c_getstr (arg1
);
6689 p2
= c_getstr (arg2
);
6691 if (host_integerp (len
, 1) && p1
&& p2
)
6694 const int i
= strncmp (p1
, p2
, tree_low_cst (len
, 1));
6696 temp
= integer_minus_one_node
;
6698 temp
= integer_one_node
;
6700 temp
= integer_zero_node
;
6701 return convert (TREE_TYPE (exp
), temp
);
6707 /* Fold function call to builtin signbit, signbitf or signbitl. Return
6708 NULL_TREE if no simplification can be made. */
6711 fold_builtin_signbit (tree exp
)
6713 tree arglist
= TREE_OPERAND (exp
, 1);
6716 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
6719 arg
= TREE_VALUE (arglist
);
6721 /* If ARG is a compile-time constant, determine the result. */
6722 if (TREE_CODE (arg
) == REAL_CST
6723 && !TREE_CONSTANT_OVERFLOW (arg
))
6727 c
= TREE_REAL_CST (arg
);
6728 temp
= REAL_VALUE_NEGATIVE (c
) ? integer_one_node
: integer_zero_node
;
6729 return convert (TREE_TYPE (exp
), temp
);
6732 /* If ARG is non-negative, the result is always zero. */
6733 if (tree_expr_nonnegative_p (arg
))
6734 return omit_one_operand (TREE_TYPE (exp
), integer_zero_node
, arg
);
6736 /* If ARG's format doesn't have signed zeros, return "arg < 0.0". */
6737 if (!HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg
))))
6738 return fold (build (LT_EXPR
, TREE_TYPE (exp
), arg
,
6739 build_real (TREE_TYPE (arg
), dconst0
)));
6744 /* Fold a call to builtin isascii. */
6747 fold_builtin_isascii (tree arglist
)
6749 if (! validate_arglist (arglist
, INTEGER_TYPE
, VOID_TYPE
))
6753 /* Transform isascii(c) -> ((c & ~0x7f) == 0). */
6754 tree arg
= TREE_VALUE (arglist
);
6756 return fold (build (EQ_EXPR
, integer_type_node
,
6757 build (BIT_AND_EXPR
, integer_type_node
, arg
,
6758 build_int_2 (~ (unsigned HOST_WIDE_INT
) 0x7f,
6759 ~ (HOST_WIDE_INT
) 0)),
6760 integer_zero_node
));
6764 /* Fold a call to builtin toascii. */
6767 fold_builtin_toascii (tree arglist
)
6769 if (! validate_arglist (arglist
, INTEGER_TYPE
, VOID_TYPE
))
6773 /* Transform toascii(c) -> (c & 0x7f). */
6774 tree arg
= TREE_VALUE (arglist
);
6776 return fold (build (BIT_AND_EXPR
, integer_type_node
, arg
,
6777 build_int_2 (0x7f, 0)));
6782 /* Used by constant folding to eliminate some builtin calls early. EXP is
6783 the CALL_EXPR of a call to a builtin function. */
6786 fold_builtin (tree exp
)
6788 tree fndecl
= get_callee_fndecl (exp
);
6789 tree arglist
= TREE_OPERAND (exp
, 1);
6790 tree type
= TREE_TYPE (TREE_TYPE (fndecl
));
6792 if (DECL_BUILT_IN_CLASS (fndecl
) == BUILT_IN_MD
)
6795 switch (DECL_FUNCTION_CODE (fndecl
))
6797 case BUILT_IN_CONSTANT_P
:
6798 return fold_builtin_constant_p (arglist
);
6800 case BUILT_IN_CLASSIFY_TYPE
:
6801 return fold_builtin_classify_type (arglist
);
6803 case BUILT_IN_STRLEN
:
6804 if (validate_arglist (arglist
, POINTER_TYPE
, VOID_TYPE
))
6806 tree len
= c_strlen (TREE_VALUE (arglist
), 0);
6809 /* Convert from the internal "sizetype" type to "size_t". */
6811 len
= convert (size_type_node
, len
);
6818 case BUILT_IN_FABSF
:
6819 case BUILT_IN_FABSL
:
6820 if (validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
6821 return fold (build1 (ABS_EXPR
, type
, TREE_VALUE (arglist
)));
6825 case BUILT_IN_CABSF
:
6826 case BUILT_IN_CABSL
:
6827 return fold_builtin_cabs (fndecl
, arglist
, type
);
6830 case BUILT_IN_SQRTF
:
6831 case BUILT_IN_SQRTL
:
6832 if (validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
6834 enum built_in_function fcode
;
6835 tree arg
= TREE_VALUE (arglist
);
6837 /* Optimize sqrt of constant value. */
6838 if (TREE_CODE (arg
) == REAL_CST
6839 && ! TREE_CONSTANT_OVERFLOW (arg
))
6841 REAL_VALUE_TYPE r
, x
;
6843 x
= TREE_REAL_CST (arg
);
6844 if (real_sqrt (&r
, TYPE_MODE (type
), &x
)
6845 || (!flag_trapping_math
&& !flag_errno_math
))
6846 return build_real (type
, r
);
6849 /* Optimize sqrt(expN(x)) = expN(x*0.5). */
6850 fcode
= builtin_mathfn_code (arg
);
6851 if (flag_unsafe_math_optimizations
&& BUILTIN_EXPONENT_P (fcode
))
6853 tree expfn
= TREE_OPERAND (TREE_OPERAND (arg
, 0), 0);
6854 arg
= fold (build (MULT_EXPR
, type
,
6855 TREE_VALUE (TREE_OPERAND (arg
, 1)),
6856 build_real (type
, dconsthalf
)));
6857 arglist
= build_tree_list (NULL_TREE
, arg
);
6858 return build_function_call_expr (expfn
, arglist
);
6861 /* Optimize sqrt(Nroot(x)) -> pow(x,1/(2*N)). */
6862 if (flag_unsafe_math_optimizations
&& BUILTIN_ROOT_P (fcode
))
6864 tree powfn
= mathfn_built_in (type
, BUILT_IN_POW
);
6868 tree arg0
= TREE_VALUE (TREE_OPERAND (arg
, 1));
6870 /* The inner root was either sqrt or cbrt. */
6871 REAL_VALUE_TYPE dconstroot
=
6872 BUILTIN_SQRT_P (fcode
) ? dconsthalf
: dconstthird
;
6874 /* Adjust for the outer root. */
6875 SET_REAL_EXP (&dconstroot
, REAL_EXP (&dconstroot
) - 1);
6876 dconstroot
= real_value_truncate (TYPE_MODE (type
), dconstroot
);
6877 tree_root
= build_real (type
, dconstroot
);
6878 arglist
= tree_cons (NULL_TREE
, arg0
,
6879 build_tree_list (NULL_TREE
, tree_root
));
6880 return build_function_call_expr (powfn
, arglist
);
6884 /* Optimize sqrt(pow(x,y)) = pow(x,y*0.5). */
6885 if (flag_unsafe_math_optimizations
6886 && (fcode
== BUILT_IN_POW
6887 || fcode
== BUILT_IN_POWF
6888 || fcode
== BUILT_IN_POWL
))
6890 tree powfn
= TREE_OPERAND (TREE_OPERAND (arg
, 0), 0);
6891 tree arg0
= TREE_VALUE (TREE_OPERAND (arg
, 1));
6892 tree arg1
= TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg
, 1)));
6893 tree narg1
= fold (build (MULT_EXPR
, type
, arg1
,
6894 build_real (type
, dconsthalf
)));
6895 arglist
= tree_cons (NULL_TREE
, arg0
,
6896 build_tree_list (NULL_TREE
, narg1
));
6897 return build_function_call_expr (powfn
, arglist
);
6903 case BUILT_IN_CBRTF
:
6904 case BUILT_IN_CBRTL
:
6905 if (validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
6907 tree arg
= TREE_VALUE (arglist
);
6908 const enum built_in_function fcode
= builtin_mathfn_code (arg
);
6910 /* Optimize cbrt of constant value. */
6911 if (real_zerop (arg
) || real_onep (arg
) || real_minus_onep (arg
))
6914 /* Optimize cbrt(expN(x)) -> expN(x/3). */
6915 if (flag_unsafe_math_optimizations
&& BUILTIN_EXPONENT_P (fcode
))
6917 tree expfn
= TREE_OPERAND (TREE_OPERAND (arg
, 0), 0);
6918 const REAL_VALUE_TYPE third_trunc
=
6919 real_value_truncate (TYPE_MODE (type
), dconstthird
);
6920 arg
= fold (build (MULT_EXPR
, type
,
6921 TREE_VALUE (TREE_OPERAND (arg
, 1)),
6922 build_real (type
, third_trunc
)));
6923 arglist
= build_tree_list (NULL_TREE
, arg
);
6924 return build_function_call_expr (expfn
, arglist
);
6927 /* Optimize cbrt(sqrt(x)) -> pow(x,1/6). */
6928 /* We don't optimize cbrt(cbrt(x)) -> pow(x,1/9) because if
6929 x is negative pow will error but cbrt won't. */
6930 if (flag_unsafe_math_optimizations
&& BUILTIN_SQRT_P (fcode
))
6932 tree powfn
= mathfn_built_in (type
, BUILT_IN_POW
);
6936 tree arg0
= TREE_VALUE (TREE_OPERAND (arg
, 1));
6938 REAL_VALUE_TYPE dconstroot
= dconstthird
;
6940 SET_REAL_EXP (&dconstroot
, REAL_EXP (&dconstroot
) - 1);
6941 dconstroot
= real_value_truncate (TYPE_MODE (type
), dconstroot
);
6942 tree_root
= build_real (type
, dconstroot
);
6943 arglist
= tree_cons (NULL_TREE
, arg0
,
6944 build_tree_list (NULL_TREE
, tree_root
));
6945 return build_function_call_expr (powfn
, arglist
);
6955 if (validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
6957 tree arg
= TREE_VALUE (arglist
);
6959 /* Optimize sin(0.0) = 0.0. */
6960 if (real_zerop (arg
))
6968 if (validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
6970 tree arg
= TREE_VALUE (arglist
);
6972 /* Optimize cos(0.0) = 1.0. */
6973 if (real_zerop (arg
))
6974 return build_real (type
, dconst1
);
6976 /* Optimize cos(-x) into cos(x). */
6977 if (TREE_CODE (arg
) == NEGATE_EXPR
)
6979 tree arglist
= build_tree_list (NULL_TREE
,
6980 TREE_OPERAND (arg
, 0));
6981 return build_function_call_expr (fndecl
, arglist
);
6989 return fold_builtin_exponent (exp
, &dconste
);
6991 case BUILT_IN_EXP2F
:
6992 case BUILT_IN_EXP2L
:
6993 return fold_builtin_exponent (exp
, &dconst2
);
6994 case BUILT_IN_EXP10
:
6995 case BUILT_IN_EXP10F
:
6996 case BUILT_IN_EXP10L
:
6997 case BUILT_IN_POW10
:
6998 case BUILT_IN_POW10F
:
6999 case BUILT_IN_POW10L
:
7000 return fold_builtin_exponent (exp
, &dconst10
);
7004 return fold_builtin_logarithm (exp
, &dconste
);
7007 case BUILT_IN_LOG2F
:
7008 case BUILT_IN_LOG2L
:
7009 return fold_builtin_logarithm (exp
, &dconst2
);
7011 case BUILT_IN_LOG10
:
7012 case BUILT_IN_LOG10F
:
7013 case BUILT_IN_LOG10L
:
7014 return fold_builtin_logarithm (exp
, &dconst10
);
7020 if (validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
7022 enum built_in_function fcode
;
7023 tree arg
= TREE_VALUE (arglist
);
7025 /* Optimize tan(0.0) = 0.0. */
7026 if (real_zerop (arg
))
7029 /* Optimize tan(atan(x)) = x. */
7030 fcode
= builtin_mathfn_code (arg
);
7031 if (flag_unsafe_math_optimizations
7032 && (fcode
== BUILT_IN_ATAN
7033 || fcode
== BUILT_IN_ATANF
7034 || fcode
== BUILT_IN_ATANL
))
7035 return TREE_VALUE (TREE_OPERAND (arg
, 1));
7040 case BUILT_IN_ATANF
:
7041 case BUILT_IN_ATANL
:
7042 if (validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
7044 tree arg
= TREE_VALUE (arglist
);
7046 /* Optimize atan(0.0) = 0.0. */
7047 if (real_zerop (arg
))
7050 /* Optimize atan(1.0) = pi/4. */
7051 if (real_onep (arg
))
7053 REAL_VALUE_TYPE cst
;
7055 real_convert (&cst
, TYPE_MODE (type
), &dconstpi
);
7056 SET_REAL_EXP (&cst
, REAL_EXP (&cst
) - 2);
7057 return build_real (type
, cst
);
7065 if (validate_arglist (arglist
, REAL_TYPE
, REAL_TYPE
, VOID_TYPE
))
7067 enum built_in_function fcode
;
7068 tree arg0
= TREE_VALUE (arglist
);
7069 tree arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
7071 /* Optimize pow(1.0,y) = 1.0. */
7072 if (real_onep (arg0
))
7073 return omit_one_operand (type
, build_real (type
, dconst1
), arg1
);
7075 if (TREE_CODE (arg1
) == REAL_CST
7076 && ! TREE_CONSTANT_OVERFLOW (arg1
))
7079 c
= TREE_REAL_CST (arg1
);
7081 /* Optimize pow(x,0.0) = 1.0. */
7082 if (REAL_VALUES_EQUAL (c
, dconst0
))
7083 return omit_one_operand (type
, build_real (type
, dconst1
),
7086 /* Optimize pow(x,1.0) = x. */
7087 if (REAL_VALUES_EQUAL (c
, dconst1
))
7090 /* Optimize pow(x,-1.0) = 1.0/x. */
7091 if (REAL_VALUES_EQUAL (c
, dconstm1
))
7092 return fold (build (RDIV_EXPR
, type
,
7093 build_real (type
, dconst1
),
7096 /* Optimize pow(x,0.5) = sqrt(x). */
7097 if (flag_unsafe_math_optimizations
7098 && REAL_VALUES_EQUAL (c
, dconsthalf
))
7102 fcode
= DECL_FUNCTION_CODE (fndecl
);
7103 if (fcode
== BUILT_IN_POW
)
7104 sqrtfn
= implicit_built_in_decls
[BUILT_IN_SQRT
];
7105 else if (fcode
== BUILT_IN_POWF
)
7106 sqrtfn
= implicit_built_in_decls
[BUILT_IN_SQRTF
];
7107 else if (fcode
== BUILT_IN_POWL
)
7108 sqrtfn
= implicit_built_in_decls
[BUILT_IN_SQRTL
];
7112 if (sqrtfn
!= NULL_TREE
)
7114 tree arglist
= build_tree_list (NULL_TREE
, arg0
);
7115 return build_function_call_expr (sqrtfn
, arglist
);
7119 /* Attempt to evaluate pow at compile-time. */
7120 if (TREE_CODE (arg0
) == REAL_CST
7121 && ! TREE_CONSTANT_OVERFLOW (arg0
))
7123 REAL_VALUE_TYPE cint
;
7126 n
= real_to_integer (&c
);
7127 real_from_integer (&cint
, VOIDmode
, n
,
7129 if (real_identical (&c
, &cint
))
7134 x
= TREE_REAL_CST (arg0
);
7135 inexact
= real_powi (&x
, TYPE_MODE (type
), &x
, n
);
7136 if (flag_unsafe_math_optimizations
|| !inexact
)
7137 return build_real (type
, x
);
7142 /* Optimize pow(expN(x),y) = expN(x*y). */
7143 fcode
= builtin_mathfn_code (arg0
);
7144 if (flag_unsafe_math_optimizations
&& BUILTIN_EXPONENT_P (fcode
))
7146 tree expfn
= TREE_OPERAND (TREE_OPERAND (arg0
, 0), 0);
7147 tree arg
= TREE_VALUE (TREE_OPERAND (arg0
, 1));
7148 arg
= fold (build (MULT_EXPR
, type
, arg
, arg1
));
7149 arglist
= build_tree_list (NULL_TREE
, arg
);
7150 return build_function_call_expr (expfn
, arglist
);
7153 /* Optimize pow(sqrt(x),y) = pow(x,y*0.5). */
7154 if (flag_unsafe_math_optimizations
&& BUILTIN_SQRT_P (fcode
))
7156 tree narg0
= TREE_VALUE (TREE_OPERAND (arg0
, 1));
7157 tree narg1
= fold (build (MULT_EXPR
, type
, arg1
,
7158 build_real (type
, dconsthalf
)));
7160 arglist
= tree_cons (NULL_TREE
, narg0
,
7161 build_tree_list (NULL_TREE
, narg1
));
7162 return build_function_call_expr (fndecl
, arglist
);
7165 /* Optimize pow(pow(x,y),z) = pow(x,y*z). */
7166 if (flag_unsafe_math_optimizations
7167 && (fcode
== BUILT_IN_POW
7168 || fcode
== BUILT_IN_POWF
7169 || fcode
== BUILT_IN_POWL
))
7171 tree arg00
= TREE_VALUE (TREE_OPERAND (arg0
, 1));
7172 tree arg01
= TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg0
, 1)));
7173 tree narg1
= fold (build (MULT_EXPR
, type
, arg01
, arg1
));
7174 arglist
= tree_cons (NULL_TREE
, arg00
,
7175 build_tree_list (NULL_TREE
, narg1
));
7176 return build_function_call_expr (fndecl
, arglist
);
7184 return fold_builtin_inf (type
, true);
7186 case BUILT_IN_HUGE_VAL
:
7187 case BUILT_IN_HUGE_VALF
:
7188 case BUILT_IN_HUGE_VALL
:
7189 return fold_builtin_inf (type
, false);
7194 return fold_builtin_nan (arglist
, type
, true);
7197 case BUILT_IN_NANSF
:
7198 case BUILT_IN_NANSL
:
7199 return fold_builtin_nan (arglist
, type
, false);
7201 case BUILT_IN_FLOOR
:
7202 case BUILT_IN_FLOORF
:
7203 case BUILT_IN_FLOORL
:
7204 return fold_builtin_floor (exp
);
7207 case BUILT_IN_CEILF
:
7208 case BUILT_IN_CEILL
:
7209 return fold_builtin_ceil (exp
);
7211 case BUILT_IN_TRUNC
:
7212 case BUILT_IN_TRUNCF
:
7213 case BUILT_IN_TRUNCL
:
7214 return fold_builtin_trunc (exp
);
7216 case BUILT_IN_ROUND
:
7217 case BUILT_IN_ROUNDF
:
7218 case BUILT_IN_ROUNDL
:
7219 return fold_builtin_round (exp
);
7221 case BUILT_IN_NEARBYINT
:
7222 case BUILT_IN_NEARBYINTF
:
7223 case BUILT_IN_NEARBYINTL
:
7225 case BUILT_IN_RINTF
:
7226 case BUILT_IN_RINTL
:
7227 return fold_trunc_transparent_mathfn (exp
);
7231 case BUILT_IN_FFSLL
:
7234 case BUILT_IN_CLZLL
:
7237 case BUILT_IN_CTZLL
:
7238 case BUILT_IN_POPCOUNT
:
7239 case BUILT_IN_POPCOUNTL
:
7240 case BUILT_IN_POPCOUNTLL
:
7241 case BUILT_IN_PARITY
:
7242 case BUILT_IN_PARITYL
:
7243 case BUILT_IN_PARITYLL
:
7244 return fold_builtin_bitop (exp
);
7246 case BUILT_IN_MEMCPY
:
7247 return fold_builtin_memcpy (exp
);
7249 case BUILT_IN_MEMPCPY
:
7250 return fold_builtin_mempcpy (exp
);
7252 case BUILT_IN_MEMMOVE
:
7253 return fold_builtin_memmove (exp
);
7255 case BUILT_IN_STRCPY
:
7256 return fold_builtin_strcpy (exp
);
7258 case BUILT_IN_STRNCPY
:
7259 return fold_builtin_strncpy (exp
);
7261 case BUILT_IN_MEMCMP
:
7262 return fold_builtin_memcmp (exp
);
7264 case BUILT_IN_STRCMP
:
7265 return fold_builtin_strcmp (exp
);
7267 case BUILT_IN_STRNCMP
:
7268 return fold_builtin_strncmp (exp
);
7270 case BUILT_IN_SIGNBIT
:
7271 case BUILT_IN_SIGNBITF
:
7272 case BUILT_IN_SIGNBITL
:
7273 return fold_builtin_signbit (exp
);
7275 case BUILT_IN_ISASCII
:
7276 return fold_builtin_isascii (arglist
);
7278 case BUILT_IN_TOASCII
:
7279 return fold_builtin_toascii (arglist
);
7288 /* Conveniently construct a function call expression. */
7291 build_function_call_expr (tree fn
, tree arglist
)
7295 call_expr
= build1 (ADDR_EXPR
, build_pointer_type (TREE_TYPE (fn
)), fn
);
7296 call_expr
= build (CALL_EXPR
, TREE_TYPE (TREE_TYPE (fn
)),
7297 call_expr
, arglist
);
7298 return fold (call_expr
);
7301 /* This function validates the types of a function call argument list
7302 represented as a tree chain of parameters against a specified list
7303 of tree_codes. If the last specifier is a 0, that represents an
7304 ellipses, otherwise the last specifier must be a VOID_TYPE. */
7307 validate_arglist (tree arglist
, ...)
7309 enum tree_code code
;
7313 va_start (ap
, arglist
);
7317 code
= va_arg (ap
, enum tree_code
);
7321 /* This signifies an ellipses, any further arguments are all ok. */
7325 /* This signifies an endlink, if no arguments remain, return
7326 true, otherwise return false. */
7330 /* If no parameters remain or the parameter's code does not
7331 match the specified code, return false. Otherwise continue
7332 checking any remaining arguments. */
7334 || code
!= TREE_CODE (TREE_TYPE (TREE_VALUE (arglist
))))
7338 arglist
= TREE_CHAIN (arglist
);
7342 /* We need gotos here since we can only have one VA_CLOSE in a
7350 /* Default target-specific builtin expander that does nothing. */
7353 default_expand_builtin (tree exp ATTRIBUTE_UNUSED
,
7354 rtx target ATTRIBUTE_UNUSED
,
7355 rtx subtarget ATTRIBUTE_UNUSED
,
7356 enum machine_mode mode ATTRIBUTE_UNUSED
,
7357 int ignore ATTRIBUTE_UNUSED
)
7362 /* Instantiate all remaining CONSTANT_P_RTX nodes. */
7365 purge_builtin_constant_p (void)
7367 rtx insn
, set
, arg
, new, note
;
7369 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
7371 && (set
= single_set (insn
)) != NULL_RTX
7372 && (GET_CODE (arg
= SET_SRC (set
)) == CONSTANT_P_RTX
7373 || (GET_CODE (arg
) == SUBREG
7374 && (GET_CODE (arg
= SUBREG_REG (arg
))
7375 == CONSTANT_P_RTX
))))
7377 arg
= XEXP (arg
, 0);
7378 new = CONSTANT_P (arg
) ? const1_rtx
: const0_rtx
;
7379 validate_change (insn
, &SET_SRC (set
), new, 0);
7381 /* Remove the REG_EQUAL note from the insn. */
7382 if ((note
= find_reg_note (insn
, REG_EQUAL
, NULL_RTX
)) != 0)
7383 remove_note (insn
, note
);
7387 /* Returns true is EXP represents data that would potentially reside
7388 in a readonly section. */
7391 readonly_data_expr (tree exp
)
7395 if (TREE_CODE (exp
) == ADDR_EXPR
)
7396 return decl_readonly_section (TREE_OPERAND (exp
, 0), 0);