1 /* Expand builtin functions.
2 Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3 2000, 2001, 2002, 2003 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 /* Register mappings for target machines without register windows. */
52 #ifndef INCOMING_REGNO
53 #define INCOMING_REGNO(OUT) (OUT)
55 #ifndef OUTGOING_REGNO
56 #define OUTGOING_REGNO(IN) (IN)
59 #ifndef PAD_VARARGS_DOWN
60 #define PAD_VARARGS_DOWN BYTES_BIG_ENDIAN
63 /* Define the names of the builtin function types and codes. */
64 const char *const built_in_class_names
[4]
65 = {"NOT_BUILT_IN", "BUILT_IN_FRONTEND", "BUILT_IN_MD", "BUILT_IN_NORMAL"};
67 #define DEF_BUILTIN(X, N, C, T, LT, B, F, NA, AT, IM) #X,
68 const char *const built_in_names
[(int) END_BUILTINS
] =
70 #include "builtins.def"
74 /* Setup an array of _DECL trees, make sure each element is
75 initialized to NULL_TREE. */
76 tree built_in_decls
[(int) END_BUILTINS
];
77 /* Declarations used when constructing the builtin implicitly in the compiler.
78 It may be NULL_TREE when this is invalid (for instance runtime is not
79 required to implement the function call in all cases. */
80 tree implicit_built_in_decls
[(int) END_BUILTINS
];
82 /* Trigonometric and mathematical constants used in builtin folding. */
83 static bool builtin_dconsts_init
= 0;
84 static REAL_VALUE_TYPE dconstpi
;
85 static REAL_VALUE_TYPE dconste
;
87 static int get_pointer_alignment (tree
, unsigned int);
88 static tree
c_strlen (tree
);
89 static const char *c_getstr (tree
);
90 static rtx
c_readstr (const char *, enum machine_mode
);
91 static int target_char_cast (tree
, char *);
92 static rtx
get_memory_rtx (tree
);
93 static int apply_args_size (void);
94 static int apply_result_size (void);
95 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
96 static rtx
result_vector (int, rtx
);
98 static rtx
expand_builtin_setjmp (tree
, rtx
);
99 static void expand_builtin_prefetch (tree
);
100 static rtx
expand_builtin_apply_args (void);
101 static rtx
expand_builtin_apply_args_1 (void);
102 static rtx
expand_builtin_apply (rtx
, rtx
, rtx
);
103 static void expand_builtin_return (rtx
);
104 static enum type_class
type_to_class (tree
);
105 static rtx
expand_builtin_classify_type (tree
);
106 static void expand_errno_check (tree
, rtx
);
107 static rtx
expand_builtin_mathfn (tree
, rtx
, rtx
);
108 static rtx
expand_builtin_mathfn_2 (tree
, rtx
, rtx
);
109 static rtx
expand_builtin_constant_p (tree
, enum machine_mode
);
110 static rtx
expand_builtin_args_info (tree
);
111 static rtx
expand_builtin_next_arg (tree
);
112 static rtx
expand_builtin_va_start (tree
);
113 static rtx
expand_builtin_va_end (tree
);
114 static rtx
expand_builtin_va_copy (tree
);
115 static rtx
expand_builtin_memcmp (tree
, tree
, rtx
, enum machine_mode
);
116 static rtx
expand_builtin_strcmp (tree
, rtx
, enum machine_mode
);
117 static rtx
expand_builtin_strncmp (tree
, rtx
, enum machine_mode
);
118 static rtx
builtin_memcpy_read_str (void *, HOST_WIDE_INT
, enum machine_mode
);
119 static rtx
expand_builtin_strcat (tree
, rtx
, enum machine_mode
);
120 static rtx
expand_builtin_strncat (tree
, rtx
, enum machine_mode
);
121 static rtx
expand_builtin_strspn (tree
, rtx
, enum machine_mode
);
122 static rtx
expand_builtin_strcspn (tree
, rtx
, enum machine_mode
);
123 static rtx
expand_builtin_memcpy (tree
, rtx
, enum machine_mode
);
124 static rtx
expand_builtin_mempcpy (tree
, rtx
, enum machine_mode
, int);
125 static rtx
expand_builtin_memmove (tree
, rtx
, enum machine_mode
);
126 static rtx
expand_builtin_bcopy (tree
);
127 static rtx
expand_builtin_strcpy (tree
, rtx
, enum machine_mode
);
128 static rtx
expand_builtin_stpcpy (tree
, rtx
, enum machine_mode
);
129 static rtx
builtin_strncpy_read_str (void *, HOST_WIDE_INT
, enum machine_mode
);
130 static rtx
expand_builtin_strncpy (tree
, rtx
, enum machine_mode
);
131 static rtx
builtin_memset_read_str (void *, HOST_WIDE_INT
, enum machine_mode
);
132 static rtx
builtin_memset_gen_str (void *, HOST_WIDE_INT
, enum machine_mode
);
133 static rtx
expand_builtin_memset (tree
, rtx
, enum machine_mode
);
134 static rtx
expand_builtin_bzero (tree
);
135 static rtx
expand_builtin_strlen (tree
, rtx
, enum machine_mode
);
136 static rtx
expand_builtin_strstr (tree
, rtx
, enum machine_mode
);
137 static rtx
expand_builtin_strpbrk (tree
, rtx
, enum machine_mode
);
138 static rtx
expand_builtin_strchr (tree
, rtx
, enum machine_mode
);
139 static rtx
expand_builtin_strrchr (tree
, rtx
, enum machine_mode
);
140 static rtx
expand_builtin_alloca (tree
, rtx
);
141 static rtx
expand_builtin_unop (enum machine_mode
, tree
, rtx
, rtx
, optab
);
142 static rtx
expand_builtin_frame_address (tree
, tree
);
143 static rtx
expand_builtin_fputs (tree
, int, int);
144 static tree
stabilize_va_list (tree
, int);
145 static rtx
expand_builtin_expect (tree
, rtx
);
146 static tree
fold_builtin_constant_p (tree
);
147 static tree
fold_builtin_classify_type (tree
);
148 static tree
fold_builtin_inf (tree
, int);
149 static tree
fold_builtin_nan (tree
, tree
, int);
150 static int validate_arglist (tree
, ...);
151 static tree
fold_trunc_transparent_mathfn (tree
);
152 static bool readonly_data_expr (tree
);
153 static rtx
expand_builtin_fabs (tree
, rtx
, rtx
);
154 static rtx
expand_builtin_cabs (tree
, rtx
);
155 static void init_builtin_dconsts (void);
156 static tree
fold_builtin_cabs (tree
, tree
, tree
);
158 /* Initialize mathematical constants for constant folding builtins.
159 These constants need to be given to at least 160 bits precision. */
162 init_builtin_dconsts (void)
164 real_from_string (&dconstpi
,
165 "3.1415926535897932384626433832795028841971693993751058209749445923078");
166 real_from_string (&dconste
,
167 "2.7182818284590452353602874713526624977572470936999595749669676277241");
169 builtin_dconsts_init
= true;
172 /* Return the alignment in bits of EXP, a pointer valued expression.
173 But don't return more than MAX_ALIGN no matter what.
174 The alignment returned is, by default, the alignment of the thing that
175 EXP points to. If it is not a POINTER_TYPE, 0 is returned.
177 Otherwise, look at the expression to see if we can do better, i.e., if the
178 expression is actually pointing at an object whose alignment is tighter. */
181 get_pointer_alignment (tree exp
, unsigned int max_align
)
183 unsigned int align
, inner
;
185 if (TREE_CODE (TREE_TYPE (exp
)) != POINTER_TYPE
)
188 align
= TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp
)));
189 align
= MIN (align
, max_align
);
193 switch (TREE_CODE (exp
))
197 case NON_LVALUE_EXPR
:
198 exp
= TREE_OPERAND (exp
, 0);
199 if (TREE_CODE (TREE_TYPE (exp
)) != POINTER_TYPE
)
202 inner
= TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp
)));
203 align
= MIN (inner
, max_align
);
207 /* If sum of pointer + int, restrict our maximum alignment to that
208 imposed by the integer. If not, we can't do any better than
210 if (! host_integerp (TREE_OPERAND (exp
, 1), 1))
213 while (((tree_low_cst (TREE_OPERAND (exp
, 1), 1))
214 & (max_align
/ BITS_PER_UNIT
- 1))
218 exp
= TREE_OPERAND (exp
, 0);
222 /* See what we are pointing at and look at its alignment. */
223 exp
= TREE_OPERAND (exp
, 0);
224 if (TREE_CODE (exp
) == FUNCTION_DECL
)
225 align
= FUNCTION_BOUNDARY
;
226 else if (DECL_P (exp
))
227 align
= DECL_ALIGN (exp
);
228 #ifdef CONSTANT_ALIGNMENT
229 else if (TREE_CODE_CLASS (TREE_CODE (exp
)) == 'c')
230 align
= CONSTANT_ALIGNMENT (exp
, align
);
232 return MIN (align
, max_align
);
240 /* Compute the length of a C string. TREE_STRING_LENGTH is not the right
241 way, because it could contain a zero byte in the middle.
242 TREE_STRING_LENGTH is the size of the character array, not the string.
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. */
253 HOST_WIDE_INT offset
;
257 src
= string_constant (src
, &offset_node
);
261 max
= TREE_STRING_LENGTH (src
) - 1;
262 ptr
= TREE_STRING_POINTER (src
);
264 if (offset_node
&& TREE_CODE (offset_node
) != INTEGER_CST
)
266 /* If the string has an internal zero byte (e.g., "foo\0bar"), we can't
267 compute the offset to the following null if we don't know where to
268 start searching for it. */
271 for (i
= 0; i
< max
; i
++)
275 /* We don't know the starting offset, but we do know that the string
276 has no internal zero bytes. We can assume that the offset falls
277 within the bounds of the string; otherwise, the programmer deserves
278 what he gets. Subtract the offset from the length of the string,
279 and return that. This would perhaps not be valid if we were dealing
280 with named arrays in addition to literal string constants. */
282 return size_diffop (size_int (max
), offset_node
);
285 /* We have a known offset into the string. Start searching there for
286 a null character if we can represent it as a single HOST_WIDE_INT. */
287 if (offset_node
== 0)
289 else if (! host_integerp (offset_node
, 0))
292 offset
= tree_low_cst (offset_node
, 0);
294 /* If the offset is known to be out of bounds, warn, and call strlen at
296 if (offset
< 0 || offset
> max
)
298 warning ("offset outside bounds of constant string");
302 /* Use strlen to search for the first zero byte. Since any strings
303 constructed with build_string will have nulls appended, we win even
304 if we get handed something like (char[4])"abcd".
306 Since OFFSET is our starting index into the string, no further
307 calculation is needed. */
308 return ssize_int (strlen (ptr
+ offset
));
311 /* Return a char pointer for a C string if it is a string constant
312 or sum of string constant and integer constant. */
319 src
= string_constant (src
, &offset_node
);
323 if (offset_node
== 0)
324 return TREE_STRING_POINTER (src
);
325 else if (!host_integerp (offset_node
, 1)
326 || compare_tree_int (offset_node
, TREE_STRING_LENGTH (src
) - 1) > 0)
329 return TREE_STRING_POINTER (src
) + tree_low_cst (offset_node
, 1);
332 /* Return a CONST_INT or CONST_DOUBLE corresponding to target reading
333 GET_MODE_BITSIZE (MODE) bits from string constant STR. */
336 c_readstr (const char *str
, enum machine_mode mode
)
342 if (GET_MODE_CLASS (mode
) != MODE_INT
)
347 for (i
= 0; i
< GET_MODE_SIZE (mode
); i
++)
350 if (WORDS_BIG_ENDIAN
)
351 j
= GET_MODE_SIZE (mode
) - i
- 1;
352 if (BYTES_BIG_ENDIAN
!= WORDS_BIG_ENDIAN
353 && GET_MODE_SIZE (mode
) > UNITS_PER_WORD
)
354 j
= j
+ UNITS_PER_WORD
- 2 * (j
% UNITS_PER_WORD
) - 1;
356 if (j
> 2 * HOST_BITS_PER_WIDE_INT
)
359 ch
= (unsigned char) str
[i
];
360 c
[j
/ HOST_BITS_PER_WIDE_INT
] |= ch
<< (j
% HOST_BITS_PER_WIDE_INT
);
362 return immed_double_const (c
[0], c
[1], mode
);
365 /* Cast a target constant CST to target CHAR and if that value fits into
366 host char type, return zero and put that value into variable pointed by
370 target_char_cast (tree cst
, char *p
)
372 unsigned HOST_WIDE_INT val
, hostval
;
374 if (!host_integerp (cst
, 1)
375 || CHAR_TYPE_SIZE
> HOST_BITS_PER_WIDE_INT
)
378 val
= tree_low_cst (cst
, 1);
379 if (CHAR_TYPE_SIZE
< HOST_BITS_PER_WIDE_INT
)
380 val
&= (((unsigned HOST_WIDE_INT
) 1) << CHAR_TYPE_SIZE
) - 1;
383 if (HOST_BITS_PER_CHAR
< HOST_BITS_PER_WIDE_INT
)
384 hostval
&= (((unsigned HOST_WIDE_INT
) 1) << HOST_BITS_PER_CHAR
) - 1;
393 /* Given TEM, a pointer to a stack frame, follow the dynamic chain COUNT
394 times to get the address of either a higher stack frame, or a return
395 address located within it (depending on FNDECL_CODE). */
398 expand_builtin_return_addr (enum built_in_function fndecl_code
, int count
,
403 /* Some machines need special handling before we can access
404 arbitrary frames. For example, on the sparc, we must first flush
405 all register windows to the stack. */
406 #ifdef SETUP_FRAME_ADDRESSES
408 SETUP_FRAME_ADDRESSES ();
411 /* On the sparc, the return address is not in the frame, it is in a
412 register. There is no way to access it off of the current frame
413 pointer, but it can be accessed off the previous frame pointer by
414 reading the value from the register window save area. */
415 #ifdef RETURN_ADDR_IN_PREVIOUS_FRAME
416 if (fndecl_code
== BUILT_IN_RETURN_ADDRESS
)
420 /* Scan back COUNT frames to the specified frame. */
421 for (i
= 0; i
< count
; i
++)
423 /* Assume the dynamic chain pointer is in the word that the
424 frame address points to, unless otherwise specified. */
425 #ifdef DYNAMIC_CHAIN_ADDRESS
426 tem
= DYNAMIC_CHAIN_ADDRESS (tem
);
428 tem
= memory_address (Pmode
, tem
);
429 tem
= gen_rtx_MEM (Pmode
, tem
);
430 set_mem_alias_set (tem
, get_frame_alias_set ());
431 tem
= copy_to_reg (tem
);
434 /* For __builtin_frame_address, return what we've got. */
435 if (fndecl_code
== BUILT_IN_FRAME_ADDRESS
)
438 /* For __builtin_return_address, Get the return address from that
440 #ifdef RETURN_ADDR_RTX
441 tem
= RETURN_ADDR_RTX (count
, tem
);
443 tem
= memory_address (Pmode
,
444 plus_constant (tem
, GET_MODE_SIZE (Pmode
)));
445 tem
= gen_rtx_MEM (Pmode
, tem
);
446 set_mem_alias_set (tem
, get_frame_alias_set ());
451 /* Alias set used for setjmp buffer. */
452 static HOST_WIDE_INT setjmp_alias_set
= -1;
454 /* Construct the leading half of a __builtin_setjmp call. Control will
455 return to RECEIVER_LABEL. This is used directly by sjlj exception
459 expand_builtin_setjmp_setup (rtx buf_addr
, rtx receiver_label
)
461 enum machine_mode sa_mode
= STACK_SAVEAREA_MODE (SAVE_NONLOCAL
);
465 if (setjmp_alias_set
== -1)
466 setjmp_alias_set
= new_alias_set ();
468 #ifdef POINTERS_EXTEND_UNSIGNED
469 if (GET_MODE (buf_addr
) != Pmode
)
470 buf_addr
= convert_memory_address (Pmode
, buf_addr
);
473 buf_addr
= force_reg (Pmode
, force_operand (buf_addr
, NULL_RTX
));
477 /* We store the frame pointer and the address of receiver_label in
478 the buffer and use the rest of it for the stack save area, which
479 is machine-dependent. */
481 #ifndef BUILTIN_SETJMP_FRAME_VALUE
482 #define BUILTIN_SETJMP_FRAME_VALUE virtual_stack_vars_rtx
485 mem
= gen_rtx_MEM (Pmode
, buf_addr
);
486 set_mem_alias_set (mem
, setjmp_alias_set
);
487 emit_move_insn (mem
, BUILTIN_SETJMP_FRAME_VALUE
);
489 mem
= gen_rtx_MEM (Pmode
, plus_constant (buf_addr
, GET_MODE_SIZE (Pmode
))),
490 set_mem_alias_set (mem
, setjmp_alias_set
);
492 emit_move_insn (validize_mem (mem
),
493 force_reg (Pmode
, gen_rtx_LABEL_REF (Pmode
, receiver_label
)));
495 stack_save
= gen_rtx_MEM (sa_mode
,
496 plus_constant (buf_addr
,
497 2 * GET_MODE_SIZE (Pmode
)));
498 set_mem_alias_set (stack_save
, setjmp_alias_set
);
499 emit_stack_save (SAVE_NONLOCAL
, &stack_save
, NULL_RTX
);
501 /* If there is further processing to do, do it. */
502 #ifdef HAVE_builtin_setjmp_setup
503 if (HAVE_builtin_setjmp_setup
)
504 emit_insn (gen_builtin_setjmp_setup (buf_addr
));
507 /* Tell optimize_save_area_alloca that extra work is going to
508 need to go on during alloca. */
509 current_function_calls_setjmp
= 1;
511 /* Set this so all the registers get saved in our frame; we need to be
512 able to copy the saved values for any registers from frames we unwind. */
513 current_function_has_nonlocal_label
= 1;
516 /* Construct the trailing part of a __builtin_setjmp call.
517 This is used directly by sjlj exception handling code. */
520 expand_builtin_setjmp_receiver (rtx receiver_label ATTRIBUTE_UNUSED
)
522 /* Clobber the FP when we get here, so we have to make sure it's
523 marked as used by this function. */
524 emit_insn (gen_rtx_USE (VOIDmode
, hard_frame_pointer_rtx
));
526 /* Mark the static chain as clobbered here so life information
527 doesn't get messed up for it. */
528 emit_insn (gen_rtx_CLOBBER (VOIDmode
, static_chain_rtx
));
530 /* Now put in the code to restore the frame pointer, and argument
531 pointer, if needed. The code below is from expand_end_bindings
532 in stmt.c; see detailed documentation there. */
533 #ifdef HAVE_nonlocal_goto
534 if (! HAVE_nonlocal_goto
)
536 emit_move_insn (virtual_stack_vars_rtx
, hard_frame_pointer_rtx
);
538 #if ARG_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
539 if (fixed_regs
[ARG_POINTER_REGNUM
])
541 #ifdef ELIMINABLE_REGS
543 static const struct elims
{const int from
, to
;} elim_regs
[] = ELIMINABLE_REGS
;
545 for (i
= 0; i
< ARRAY_SIZE (elim_regs
); i
++)
546 if (elim_regs
[i
].from
== ARG_POINTER_REGNUM
547 && elim_regs
[i
].to
== HARD_FRAME_POINTER_REGNUM
)
550 if (i
== ARRAY_SIZE (elim_regs
))
553 /* Now restore our arg pointer from the address at which it
554 was saved in our stack frame. */
555 emit_move_insn (virtual_incoming_args_rtx
,
556 copy_to_reg (get_arg_pointer_save_area (cfun
)));
561 #ifdef HAVE_builtin_setjmp_receiver
562 if (HAVE_builtin_setjmp_receiver
)
563 emit_insn (gen_builtin_setjmp_receiver (receiver_label
));
566 #ifdef HAVE_nonlocal_goto_receiver
567 if (HAVE_nonlocal_goto_receiver
)
568 emit_insn (gen_nonlocal_goto_receiver ());
573 /* @@@ This is a kludge. Not all machine descriptions define a blockage
574 insn, but we must not allow the code we just generated to be reordered
575 by scheduling. Specifically, the update of the frame pointer must
576 happen immediately, not later. So emit an ASM_INPUT to act as blockage
578 emit_insn (gen_rtx_ASM_INPUT (VOIDmode
, ""));
581 /* __builtin_setjmp is passed a pointer to an array of five words (not
582 all will be used on all machines). It operates similarly to the C
583 library function of the same name, but is more efficient. Much of
584 the code below (and for longjmp) is copied from the handling of
587 NOTE: This is intended for use by GNAT and the exception handling
588 scheme in the compiler and will only work in the method used by
592 expand_builtin_setjmp (tree arglist
, rtx target
)
594 rtx buf_addr
, next_lab
, cont_lab
;
596 if (!validate_arglist (arglist
, POINTER_TYPE
, VOID_TYPE
))
599 if (target
== 0 || GET_CODE (target
) != REG
600 || REGNO (target
) < FIRST_PSEUDO_REGISTER
)
601 target
= gen_reg_rtx (TYPE_MODE (integer_type_node
));
603 buf_addr
= expand_expr (TREE_VALUE (arglist
), NULL_RTX
, VOIDmode
, 0);
605 next_lab
= gen_label_rtx ();
606 cont_lab
= gen_label_rtx ();
608 expand_builtin_setjmp_setup (buf_addr
, next_lab
);
610 /* Set TARGET to zero and branch to the continue label. */
611 emit_move_insn (target
, const0_rtx
);
612 emit_jump_insn (gen_jump (cont_lab
));
614 emit_label (next_lab
);
616 expand_builtin_setjmp_receiver (next_lab
);
618 /* Set TARGET to one. */
619 emit_move_insn (target
, const1_rtx
);
620 emit_label (cont_lab
);
622 /* Tell flow about the strange goings on. Putting `next_lab' on
623 `nonlocal_goto_handler_labels' to indicates that function
624 calls may traverse the arc back to this label. */
626 current_function_has_nonlocal_label
= 1;
627 nonlocal_goto_handler_labels
628 = gen_rtx_EXPR_LIST (VOIDmode
, next_lab
, nonlocal_goto_handler_labels
);
633 /* __builtin_longjmp is passed a pointer to an array of five words (not
634 all will be used on all machines). It operates similarly to the C
635 library function of the same name, but is more efficient. Much of
636 the code below is copied from the handling of non-local gotos.
638 NOTE: This is intended for use by GNAT and the exception handling
639 scheme in the compiler and will only work in the method used by
643 expand_builtin_longjmp (rtx buf_addr
, rtx value
)
645 rtx fp
, lab
, stack
, insn
, last
;
646 enum machine_mode sa_mode
= STACK_SAVEAREA_MODE (SAVE_NONLOCAL
);
648 if (setjmp_alias_set
== -1)
649 setjmp_alias_set
= new_alias_set ();
651 #ifdef POINTERS_EXTEND_UNSIGNED
652 if (GET_MODE (buf_addr
) != Pmode
)
653 buf_addr
= convert_memory_address (Pmode
, buf_addr
);
656 buf_addr
= force_reg (Pmode
, buf_addr
);
658 /* We used to store value in static_chain_rtx, but that fails if pointers
659 are smaller than integers. We instead require that the user must pass
660 a second argument of 1, because that is what builtin_setjmp will
661 return. This also makes EH slightly more efficient, since we are no
662 longer copying around a value that we don't care about. */
663 if (value
!= const1_rtx
)
666 current_function_calls_longjmp
= 1;
668 last
= get_last_insn ();
669 #ifdef HAVE_builtin_longjmp
670 if (HAVE_builtin_longjmp
)
671 emit_insn (gen_builtin_longjmp (buf_addr
));
675 fp
= gen_rtx_MEM (Pmode
, buf_addr
);
676 lab
= gen_rtx_MEM (Pmode
, plus_constant (buf_addr
,
677 GET_MODE_SIZE (Pmode
)));
679 stack
= gen_rtx_MEM (sa_mode
, plus_constant (buf_addr
,
680 2 * GET_MODE_SIZE (Pmode
)));
681 set_mem_alias_set (fp
, setjmp_alias_set
);
682 set_mem_alias_set (lab
, setjmp_alias_set
);
683 set_mem_alias_set (stack
, setjmp_alias_set
);
685 /* Pick up FP, label, and SP from the block and jump. This code is
686 from expand_goto in stmt.c; see there for detailed comments. */
687 #if HAVE_nonlocal_goto
688 if (HAVE_nonlocal_goto
)
689 /* We have to pass a value to the nonlocal_goto pattern that will
690 get copied into the static_chain pointer, but it does not matter
691 what that value is, because builtin_setjmp does not use it. */
692 emit_insn (gen_nonlocal_goto (value
, lab
, stack
, fp
));
696 lab
= copy_to_reg (lab
);
698 emit_move_insn (hard_frame_pointer_rtx
, fp
);
699 emit_stack_restore (SAVE_NONLOCAL
, stack
, NULL_RTX
);
701 emit_insn (gen_rtx_USE (VOIDmode
, hard_frame_pointer_rtx
));
702 emit_insn (gen_rtx_USE (VOIDmode
, stack_pointer_rtx
));
703 emit_indirect_jump (lab
);
707 /* Search backwards and mark the jump insn as a non-local goto.
708 Note that this precludes the use of __builtin_longjmp to a
709 __builtin_setjmp target in the same function. However, we've
710 already cautioned the user that these functions are for
711 internal exception handling use only. */
712 for (insn
= get_last_insn (); insn
; insn
= PREV_INSN (insn
))
716 if (GET_CODE (insn
) == JUMP_INSN
)
718 REG_NOTES (insn
) = alloc_EXPR_LIST (REG_NON_LOCAL_GOTO
, const0_rtx
,
722 else if (GET_CODE (insn
) == CALL_INSN
)
727 /* Expand a call to __builtin_prefetch. For a target that does not support
728 data prefetch, evaluate the memory address argument in case it has side
732 expand_builtin_prefetch (tree arglist
)
734 tree arg0
, arg1
, arg2
;
737 if (!validate_arglist (arglist
, POINTER_TYPE
, 0))
740 arg0
= TREE_VALUE (arglist
);
741 /* Arguments 1 and 2 are optional; argument 1 (read/write) defaults to
742 zero (read) and argument 2 (locality) defaults to 3 (high degree of
744 if (TREE_CHAIN (arglist
))
746 arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
747 if (TREE_CHAIN (TREE_CHAIN (arglist
)))
748 arg2
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
750 arg2
= build_int_2 (3, 0);
754 arg1
= integer_zero_node
;
755 arg2
= build_int_2 (3, 0);
758 /* Argument 0 is an address. */
759 op0
= expand_expr (arg0
, NULL_RTX
, Pmode
, EXPAND_NORMAL
);
761 /* Argument 1 (read/write flag) must be a compile-time constant int. */
762 if (TREE_CODE (arg1
) != INTEGER_CST
)
764 error ("second arg to `__builtin_prefetch' must be a constant");
765 arg1
= integer_zero_node
;
767 op1
= expand_expr (arg1
, NULL_RTX
, VOIDmode
, 0);
768 /* Argument 1 must be either zero or one. */
769 if (INTVAL (op1
) != 0 && INTVAL (op1
) != 1)
771 warning ("invalid second arg to __builtin_prefetch; using zero");
775 /* Argument 2 (locality) must be a compile-time constant int. */
776 if (TREE_CODE (arg2
) != INTEGER_CST
)
778 error ("third arg to `__builtin_prefetch' must be a constant");
779 arg2
= integer_zero_node
;
781 op2
= expand_expr (arg2
, NULL_RTX
, VOIDmode
, 0);
782 /* Argument 2 must be 0, 1, 2, or 3. */
783 if (INTVAL (op2
) < 0 || INTVAL (op2
) > 3)
785 warning ("invalid third arg to __builtin_prefetch; using zero");
792 if ((! (*insn_data
[(int) CODE_FOR_prefetch
].operand
[0].predicate
)
794 insn_data
[(int) CODE_FOR_prefetch
].operand
[0].mode
))
795 || (GET_MODE(op0
) != Pmode
))
797 #ifdef POINTERS_EXTEND_UNSIGNED
798 if (GET_MODE(op0
) != Pmode
)
799 op0
= convert_memory_address (Pmode
, op0
);
801 op0
= force_reg (Pmode
, op0
);
803 emit_insn (gen_prefetch (op0
, op1
, op2
));
807 op0
= protect_from_queue (op0
, 0);
808 /* Don't do anything with direct references to volatile memory, but
809 generate code to handle other side effects. */
810 if (GET_CODE (op0
) != MEM
&& side_effects_p (op0
))
814 /* Get a MEM rtx for expression EXP which is the address of an operand
815 to be used to be used in a string instruction (cmpstrsi, movstrsi, ..). */
818 get_memory_rtx (tree exp
)
820 rtx addr
= expand_expr (exp
, NULL_RTX
, ptr_mode
, EXPAND_SUM
);
823 #ifdef POINTERS_EXTEND_UNSIGNED
824 if (GET_MODE (addr
) != Pmode
)
825 addr
= convert_memory_address (Pmode
, addr
);
828 mem
= gen_rtx_MEM (BLKmode
, memory_address (BLKmode
, addr
));
830 /* Get an expression we can use to find the attributes to assign to MEM.
831 If it is an ADDR_EXPR, use the operand. Otherwise, dereference it if
832 we can. First remove any nops. */
833 while ((TREE_CODE (exp
) == NOP_EXPR
|| TREE_CODE (exp
) == CONVERT_EXPR
834 || TREE_CODE (exp
) == NON_LVALUE_EXPR
)
835 && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (exp
, 0))))
836 exp
= TREE_OPERAND (exp
, 0);
838 if (TREE_CODE (exp
) == ADDR_EXPR
)
840 exp
= TREE_OPERAND (exp
, 0);
841 set_mem_attributes (mem
, exp
, 0);
843 else if (POINTER_TYPE_P (TREE_TYPE (exp
)))
845 exp
= build1 (INDIRECT_REF
, TREE_TYPE (TREE_TYPE (exp
)), exp
);
846 /* memcpy, memset and other builtin stringops can alias with anything. */
847 set_mem_alias_set (mem
, 0);
853 /* Built-in functions to perform an untyped call and return. */
855 /* For each register that may be used for calling a function, this
856 gives a mode used to copy the register's value. VOIDmode indicates
857 the register is not used for calling a function. If the machine
858 has register windows, this gives only the outbound registers.
859 INCOMING_REGNO gives the corresponding inbound register. */
860 static enum machine_mode apply_args_mode
[FIRST_PSEUDO_REGISTER
];
862 /* For each register that may be used for returning values, this gives
863 a mode used to copy the register's value. VOIDmode indicates the
864 register is not used for returning values. If the machine has
865 register windows, this gives only the outbound registers.
866 INCOMING_REGNO gives the corresponding inbound register. */
867 static enum machine_mode apply_result_mode
[FIRST_PSEUDO_REGISTER
];
869 /* For each register that may be used for calling a function, this
870 gives the offset of that register into the block returned by
871 __builtin_apply_args. 0 indicates that the register is not
872 used for calling a function. */
873 static int apply_args_reg_offset
[FIRST_PSEUDO_REGISTER
];
875 /* Return the offset of register REGNO into the block returned by
876 __builtin_apply_args. This is not declared static, since it is
877 needed in objc-act.c. */
880 apply_args_register_offset (int regno
)
884 /* Arguments are always put in outgoing registers (in the argument
885 block) if such make sense. */
886 #ifdef OUTGOING_REGNO
887 regno
= OUTGOING_REGNO (regno
);
889 return apply_args_reg_offset
[regno
];
892 /* Return the size required for the block returned by __builtin_apply_args,
893 and initialize apply_args_mode. */
896 apply_args_size (void)
898 static int size
= -1;
901 enum machine_mode mode
;
903 /* The values computed by this function never change. */
906 /* The first value is the incoming arg-pointer. */
907 size
= GET_MODE_SIZE (Pmode
);
909 /* The second value is the structure value address unless this is
910 passed as an "invisible" first argument. */
911 if (struct_value_rtx
)
912 size
+= GET_MODE_SIZE (Pmode
);
914 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
915 if (FUNCTION_ARG_REGNO_P (regno
))
917 /* Search for the proper mode for copying this register's
918 value. I'm not sure this is right, but it works so far. */
919 enum machine_mode best_mode
= VOIDmode
;
921 for (mode
= GET_CLASS_NARROWEST_MODE (MODE_INT
);
923 mode
= GET_MODE_WIDER_MODE (mode
))
924 if (HARD_REGNO_MODE_OK (regno
, mode
)
925 && HARD_REGNO_NREGS (regno
, mode
) == 1)
928 if (best_mode
== VOIDmode
)
929 for (mode
= GET_CLASS_NARROWEST_MODE (MODE_FLOAT
);
931 mode
= GET_MODE_WIDER_MODE (mode
))
932 if (HARD_REGNO_MODE_OK (regno
, mode
)
933 && have_insn_for (SET
, mode
))
936 if (best_mode
== VOIDmode
)
937 for (mode
= GET_CLASS_NARROWEST_MODE (MODE_VECTOR_FLOAT
);
939 mode
= GET_MODE_WIDER_MODE (mode
))
940 if (HARD_REGNO_MODE_OK (regno
, mode
)
941 && have_insn_for (SET
, mode
))
944 if (best_mode
== VOIDmode
)
945 for (mode
= GET_CLASS_NARROWEST_MODE (MODE_VECTOR_INT
);
947 mode
= GET_MODE_WIDER_MODE (mode
))
948 if (HARD_REGNO_MODE_OK (regno
, mode
)
949 && have_insn_for (SET
, mode
))
953 if (mode
== VOIDmode
)
956 align
= GET_MODE_ALIGNMENT (mode
) / BITS_PER_UNIT
;
957 if (size
% align
!= 0)
958 size
= CEIL (size
, align
) * align
;
959 apply_args_reg_offset
[regno
] = size
;
960 size
+= GET_MODE_SIZE (mode
);
961 apply_args_mode
[regno
] = mode
;
965 apply_args_mode
[regno
] = VOIDmode
;
966 apply_args_reg_offset
[regno
] = 0;
972 /* Return the size required for the block returned by __builtin_apply,
973 and initialize apply_result_mode. */
976 apply_result_size (void)
978 static int size
= -1;
980 enum machine_mode mode
;
982 /* The values computed by this function never change. */
987 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
988 if (FUNCTION_VALUE_REGNO_P (regno
))
990 /* Search for the proper mode for copying this register's
991 value. I'm not sure this is right, but it works so far. */
992 enum machine_mode best_mode
= VOIDmode
;
994 for (mode
= GET_CLASS_NARROWEST_MODE (MODE_INT
);
996 mode
= GET_MODE_WIDER_MODE (mode
))
997 if (HARD_REGNO_MODE_OK (regno
, mode
))
1000 if (best_mode
== VOIDmode
)
1001 for (mode
= GET_CLASS_NARROWEST_MODE (MODE_FLOAT
);
1003 mode
= GET_MODE_WIDER_MODE (mode
))
1004 if (HARD_REGNO_MODE_OK (regno
, mode
)
1005 && have_insn_for (SET
, mode
))
1008 if (best_mode
== VOIDmode
)
1009 for (mode
= GET_CLASS_NARROWEST_MODE (MODE_VECTOR_FLOAT
);
1011 mode
= GET_MODE_WIDER_MODE (mode
))
1012 if (HARD_REGNO_MODE_OK (regno
, mode
)
1013 && have_insn_for (SET
, mode
))
1016 if (best_mode
== VOIDmode
)
1017 for (mode
= GET_CLASS_NARROWEST_MODE (MODE_VECTOR_INT
);
1019 mode
= GET_MODE_WIDER_MODE (mode
))
1020 if (HARD_REGNO_MODE_OK (regno
, mode
)
1021 && have_insn_for (SET
, mode
))
1025 if (mode
== VOIDmode
)
1028 align
= GET_MODE_ALIGNMENT (mode
) / BITS_PER_UNIT
;
1029 if (size
% align
!= 0)
1030 size
= CEIL (size
, align
) * align
;
1031 size
+= GET_MODE_SIZE (mode
);
1032 apply_result_mode
[regno
] = mode
;
1035 apply_result_mode
[regno
] = VOIDmode
;
1037 /* Allow targets that use untyped_call and untyped_return to override
1038 the size so that machine-specific information can be stored here. */
1039 #ifdef APPLY_RESULT_SIZE
1040 size
= APPLY_RESULT_SIZE
;
1046 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
1047 /* Create a vector describing the result block RESULT. If SAVEP is true,
1048 the result block is used to save the values; otherwise it is used to
1049 restore the values. */
1052 result_vector (int savep
, rtx result
)
1054 int regno
, size
, align
, nelts
;
1055 enum machine_mode mode
;
1057 rtx
*savevec
= (rtx
*) alloca (FIRST_PSEUDO_REGISTER
* sizeof (rtx
));
1060 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
1061 if ((mode
= apply_result_mode
[regno
]) != VOIDmode
)
1063 align
= GET_MODE_ALIGNMENT (mode
) / BITS_PER_UNIT
;
1064 if (size
% align
!= 0)
1065 size
= CEIL (size
, align
) * align
;
1066 reg
= gen_rtx_REG (mode
, savep
? regno
: INCOMING_REGNO (regno
));
1067 mem
= adjust_address (result
, mode
, size
);
1068 savevec
[nelts
++] = (savep
1069 ? gen_rtx_SET (VOIDmode
, mem
, reg
)
1070 : gen_rtx_SET (VOIDmode
, reg
, mem
));
1071 size
+= GET_MODE_SIZE (mode
);
1073 return gen_rtx_PARALLEL (VOIDmode
, gen_rtvec_v (nelts
, savevec
));
1075 #endif /* HAVE_untyped_call or HAVE_untyped_return */
1077 /* Save the state required to perform an untyped call with the same
1078 arguments as were passed to the current function. */
1081 expand_builtin_apply_args_1 (void)
1084 int size
, align
, regno
;
1085 enum machine_mode mode
;
1087 /* Create a block where the arg-pointer, structure value address,
1088 and argument registers can be saved. */
1089 registers
= assign_stack_local (BLKmode
, apply_args_size (), -1);
1091 /* Walk past the arg-pointer and structure value address. */
1092 size
= GET_MODE_SIZE (Pmode
);
1093 if (struct_value_rtx
)
1094 size
+= GET_MODE_SIZE (Pmode
);
1096 /* Save each register used in calling a function to the block. */
1097 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
1098 if ((mode
= apply_args_mode
[regno
]) != VOIDmode
)
1102 align
= GET_MODE_ALIGNMENT (mode
) / BITS_PER_UNIT
;
1103 if (size
% align
!= 0)
1104 size
= CEIL (size
, align
) * align
;
1106 tem
= gen_rtx_REG (mode
, INCOMING_REGNO (regno
));
1108 emit_move_insn (adjust_address (registers
, mode
, size
), tem
);
1109 size
+= GET_MODE_SIZE (mode
);
1112 /* Save the arg pointer to the block. */
1113 emit_move_insn (adjust_address (registers
, Pmode
, 0),
1114 copy_to_reg (virtual_incoming_args_rtx
));
1115 size
= GET_MODE_SIZE (Pmode
);
1117 /* Save the structure value address unless this is passed as an
1118 "invisible" first argument. */
1119 if (struct_value_incoming_rtx
)
1121 emit_move_insn (adjust_address (registers
, Pmode
, size
),
1122 copy_to_reg (struct_value_incoming_rtx
));
1123 size
+= GET_MODE_SIZE (Pmode
);
1126 /* Return the address of the block. */
1127 return copy_addr_to_reg (XEXP (registers
, 0));
1130 /* __builtin_apply_args returns block of memory allocated on
1131 the stack into which is stored the arg pointer, structure
1132 value address, static chain, and all the registers that might
1133 possibly be used in performing a function call. The code is
1134 moved to the start of the function so the incoming values are
1138 expand_builtin_apply_args (void)
1140 /* Don't do __builtin_apply_args more than once in a function.
1141 Save the result of the first call and reuse it. */
1142 if (apply_args_value
!= 0)
1143 return apply_args_value
;
1145 /* When this function is called, it means that registers must be
1146 saved on entry to this function. So we migrate the
1147 call to the first insn of this function. */
1152 temp
= expand_builtin_apply_args_1 ();
1156 apply_args_value
= temp
;
1158 /* Put the insns after the NOTE that starts the function.
1159 If this is inside a start_sequence, make the outer-level insn
1160 chain current, so the code is placed at the start of the
1162 push_topmost_sequence ();
1163 emit_insn_before (seq
, NEXT_INSN (get_insns ()));
1164 pop_topmost_sequence ();
1169 /* Perform an untyped call and save the state required to perform an
1170 untyped return of whatever value was returned by the given function. */
1173 expand_builtin_apply (rtx function
, rtx arguments
, rtx argsize
)
1175 int size
, align
, regno
;
1176 enum machine_mode mode
;
1177 rtx incoming_args
, result
, reg
, dest
, src
, call_insn
;
1178 rtx old_stack_level
= 0;
1179 rtx call_fusage
= 0;
1181 #ifdef POINTERS_EXTEND_UNSIGNED
1182 if (GET_MODE (arguments
) != Pmode
)
1183 arguments
= convert_memory_address (Pmode
, arguments
);
1186 /* Create a block where the return registers can be saved. */
1187 result
= assign_stack_local (BLKmode
, apply_result_size (), -1);
1189 /* Fetch the arg pointer from the ARGUMENTS block. */
1190 incoming_args
= gen_reg_rtx (Pmode
);
1191 emit_move_insn (incoming_args
, gen_rtx_MEM (Pmode
, arguments
));
1192 #ifndef STACK_GROWS_DOWNWARD
1193 incoming_args
= expand_simple_binop (Pmode
, MINUS
, incoming_args
, argsize
,
1194 incoming_args
, 0, OPTAB_LIB_WIDEN
);
1197 /* Perform postincrements before actually calling the function. */
1200 /* Push a new argument block and copy the arguments. Do not allow
1201 the (potential) memcpy call below to interfere with our stack
1203 do_pending_stack_adjust ();
1206 /* Save the stack with nonlocal if available */
1207 #ifdef HAVE_save_stack_nonlocal
1208 if (HAVE_save_stack_nonlocal
)
1209 emit_stack_save (SAVE_NONLOCAL
, &old_stack_level
, NULL_RTX
);
1212 emit_stack_save (SAVE_BLOCK
, &old_stack_level
, NULL_RTX
);
1214 /* Push a block of memory onto the stack to store the memory arguments.
1215 Save the address in a register, and copy the memory arguments. ??? I
1216 haven't figured out how the calling convention macros effect this,
1217 but it's likely that the source and/or destination addresses in
1218 the block copy will need updating in machine specific ways. */
1219 dest
= allocate_dynamic_stack_space (argsize
, 0, BITS_PER_UNIT
);
1220 dest
= gen_rtx_MEM (BLKmode
, dest
);
1221 set_mem_align (dest
, PARM_BOUNDARY
);
1222 src
= gen_rtx_MEM (BLKmode
, incoming_args
);
1223 set_mem_align (src
, PARM_BOUNDARY
);
1224 emit_block_move (dest
, src
, argsize
, BLOCK_OP_NORMAL
);
1226 /* Refer to the argument block. */
1228 arguments
= gen_rtx_MEM (BLKmode
, arguments
);
1229 set_mem_align (arguments
, PARM_BOUNDARY
);
1231 /* Walk past the arg-pointer and structure value address. */
1232 size
= GET_MODE_SIZE (Pmode
);
1233 if (struct_value_rtx
)
1234 size
+= GET_MODE_SIZE (Pmode
);
1236 /* Restore each of the registers previously saved. Make USE insns
1237 for each of these registers for use in making the call. */
1238 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
1239 if ((mode
= apply_args_mode
[regno
]) != VOIDmode
)
1241 align
= GET_MODE_ALIGNMENT (mode
) / BITS_PER_UNIT
;
1242 if (size
% align
!= 0)
1243 size
= CEIL (size
, align
) * align
;
1244 reg
= gen_rtx_REG (mode
, regno
);
1245 emit_move_insn (reg
, adjust_address (arguments
, mode
, size
));
1246 use_reg (&call_fusage
, reg
);
1247 size
+= GET_MODE_SIZE (mode
);
1250 /* Restore the structure value address unless this is passed as an
1251 "invisible" first argument. */
1252 size
= GET_MODE_SIZE (Pmode
);
1253 if (struct_value_rtx
)
1255 rtx value
= gen_reg_rtx (Pmode
);
1256 emit_move_insn (value
, adjust_address (arguments
, Pmode
, size
));
1257 emit_move_insn (struct_value_rtx
, value
);
1258 if (GET_CODE (struct_value_rtx
) == REG
)
1259 use_reg (&call_fusage
, struct_value_rtx
);
1260 size
+= GET_MODE_SIZE (Pmode
);
1263 /* All arguments and registers used for the call are set up by now! */
1264 function
= prepare_call_address (function
, NULL_TREE
, &call_fusage
, 0, 0);
1266 /* Ensure address is valid. SYMBOL_REF is already valid, so no need,
1267 and we don't want to load it into a register as an optimization,
1268 because prepare_call_address already did it if it should be done. */
1269 if (GET_CODE (function
) != SYMBOL_REF
)
1270 function
= memory_address (FUNCTION_MODE
, function
);
1272 /* Generate the actual call instruction and save the return value. */
1273 #ifdef HAVE_untyped_call
1274 if (HAVE_untyped_call
)
1275 emit_call_insn (gen_untyped_call (gen_rtx_MEM (FUNCTION_MODE
, function
),
1276 result
, result_vector (1, result
)));
1279 #ifdef HAVE_call_value
1280 if (HAVE_call_value
)
1284 /* Locate the unique return register. It is not possible to
1285 express a call that sets more than one return register using
1286 call_value; use untyped_call for that. In fact, untyped_call
1287 only needs to save the return registers in the given block. */
1288 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
1289 if ((mode
= apply_result_mode
[regno
]) != VOIDmode
)
1292 abort (); /* HAVE_untyped_call required. */
1293 valreg
= gen_rtx_REG (mode
, regno
);
1296 emit_call_insn (GEN_CALL_VALUE (valreg
,
1297 gen_rtx_MEM (FUNCTION_MODE
, function
),
1298 const0_rtx
, NULL_RTX
, const0_rtx
));
1300 emit_move_insn (adjust_address (result
, GET_MODE (valreg
), 0), valreg
);
1306 /* Find the CALL insn we just emitted, and attach the register usage
1308 call_insn
= last_call_insn ();
1309 add_function_usage_to (call_insn
, call_fusage
);
1311 /* Restore the stack. */
1312 #ifdef HAVE_save_stack_nonlocal
1313 if (HAVE_save_stack_nonlocal
)
1314 emit_stack_restore (SAVE_NONLOCAL
, old_stack_level
, NULL_RTX
);
1317 emit_stack_restore (SAVE_BLOCK
, old_stack_level
, NULL_RTX
);
1321 /* Return the address of the result block. */
1322 return copy_addr_to_reg (XEXP (result
, 0));
1325 /* Perform an untyped return. */
1328 expand_builtin_return (rtx result
)
1330 int size
, align
, regno
;
1331 enum machine_mode mode
;
1333 rtx call_fusage
= 0;
1335 #ifdef POINTERS_EXTEND_UNSIGNED
1336 if (GET_MODE (result
) != Pmode
)
1337 result
= convert_memory_address (Pmode
, result
);
1340 apply_result_size ();
1341 result
= gen_rtx_MEM (BLKmode
, result
);
1343 #ifdef HAVE_untyped_return
1344 if (HAVE_untyped_return
)
1346 emit_jump_insn (gen_untyped_return (result
, result_vector (0, result
)));
1352 /* Restore the return value and note that each value is used. */
1354 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
1355 if ((mode
= apply_result_mode
[regno
]) != VOIDmode
)
1357 align
= GET_MODE_ALIGNMENT (mode
) / BITS_PER_UNIT
;
1358 if (size
% align
!= 0)
1359 size
= CEIL (size
, align
) * align
;
1360 reg
= gen_rtx_REG (mode
, INCOMING_REGNO (regno
));
1361 emit_move_insn (reg
, adjust_address (result
, mode
, size
));
1363 push_to_sequence (call_fusage
);
1364 emit_insn (gen_rtx_USE (VOIDmode
, reg
));
1365 call_fusage
= get_insns ();
1367 size
+= GET_MODE_SIZE (mode
);
1370 /* Put the USE insns before the return. */
1371 emit_insn (call_fusage
);
1373 /* Return whatever values was restored by jumping directly to the end
1375 expand_null_return ();
1378 /* Used by expand_builtin_classify_type and fold_builtin_classify_type. */
1380 static enum type_class
1381 type_to_class (tree type
)
1383 switch (TREE_CODE (type
))
1385 case VOID_TYPE
: return void_type_class
;
1386 case INTEGER_TYPE
: return integer_type_class
;
1387 case CHAR_TYPE
: return char_type_class
;
1388 case ENUMERAL_TYPE
: return enumeral_type_class
;
1389 case BOOLEAN_TYPE
: return boolean_type_class
;
1390 case POINTER_TYPE
: return pointer_type_class
;
1391 case REFERENCE_TYPE
: return reference_type_class
;
1392 case OFFSET_TYPE
: return offset_type_class
;
1393 case REAL_TYPE
: return real_type_class
;
1394 case COMPLEX_TYPE
: return complex_type_class
;
1395 case FUNCTION_TYPE
: return function_type_class
;
1396 case METHOD_TYPE
: return method_type_class
;
1397 case RECORD_TYPE
: return record_type_class
;
1399 case QUAL_UNION_TYPE
: return union_type_class
;
1400 case ARRAY_TYPE
: return (TYPE_STRING_FLAG (type
)
1401 ? string_type_class
: array_type_class
);
1402 case SET_TYPE
: return set_type_class
;
1403 case FILE_TYPE
: return file_type_class
;
1404 case LANG_TYPE
: return lang_type_class
;
1405 default: return no_type_class
;
1409 /* Expand a call to __builtin_classify_type with arguments found in
1413 expand_builtin_classify_type (tree arglist
)
1416 return GEN_INT (type_to_class (TREE_TYPE (TREE_VALUE (arglist
))));
1417 return GEN_INT (no_type_class
);
1420 /* Expand expression EXP, which is a call to __builtin_constant_p. */
1423 expand_builtin_constant_p (tree arglist
, enum machine_mode target_mode
)
1429 arglist
= TREE_VALUE (arglist
);
1431 /* We have taken care of the easy cases during constant folding. This
1432 case is not obvious, so emit (constant_p_rtx (ARGLIST)) and let CSE
1433 get a chance to see if it can deduce whether ARGLIST is constant. */
1435 current_function_calls_constant_p
= 1;
1437 tmp
= expand_expr (arglist
, NULL_RTX
, VOIDmode
, 0);
1438 tmp
= gen_rtx_CONSTANT_P_RTX (target_mode
, tmp
);
1442 /* Return mathematic function equivalent to FN but operating directly on TYPE,
1445 mathfn_built_in (tree type
, enum built_in_function fn
)
1447 enum built_in_function fcode
= NOT_BUILT_IN
;
1448 if (TYPE_MODE (type
) == TYPE_MODE (double_type_node
))
1452 case BUILT_IN_SQRTF
:
1453 case BUILT_IN_SQRTL
:
1454 fcode
= BUILT_IN_SQRT
;
1459 fcode
= BUILT_IN_SIN
;
1464 fcode
= BUILT_IN_COS
;
1469 fcode
= BUILT_IN_EXP
;
1474 fcode
= BUILT_IN_LOG
;
1479 fcode
= BUILT_IN_TAN
;
1482 case BUILT_IN_ATANF
:
1483 case BUILT_IN_ATANL
:
1484 fcode
= BUILT_IN_ATAN
;
1486 case BUILT_IN_FLOOR
:
1487 case BUILT_IN_FLOORF
:
1488 case BUILT_IN_FLOORL
:
1489 fcode
= BUILT_IN_FLOOR
;
1492 case BUILT_IN_CEILF
:
1493 case BUILT_IN_CEILL
:
1494 fcode
= BUILT_IN_CEIL
;
1496 case BUILT_IN_TRUNC
:
1497 case BUILT_IN_TRUNCF
:
1498 case BUILT_IN_TRUNCL
:
1499 fcode
= BUILT_IN_TRUNC
;
1501 case BUILT_IN_ROUND
:
1502 case BUILT_IN_ROUNDF
:
1503 case BUILT_IN_ROUNDL
:
1504 fcode
= BUILT_IN_ROUND
;
1506 case BUILT_IN_NEARBYINT
:
1507 case BUILT_IN_NEARBYINTF
:
1508 case BUILT_IN_NEARBYINTL
:
1509 fcode
= BUILT_IN_NEARBYINT
;
1514 else if (TYPE_MODE (type
) == TYPE_MODE (float_type_node
))
1518 case BUILT_IN_SQRTF
:
1519 case BUILT_IN_SQRTL
:
1520 fcode
= BUILT_IN_SQRTF
;
1525 fcode
= BUILT_IN_SINF
;
1530 fcode
= BUILT_IN_COSF
;
1535 fcode
= BUILT_IN_EXPF
;
1540 fcode
= BUILT_IN_LOGF
;
1545 fcode
= BUILT_IN_TANF
;
1548 case BUILT_IN_ATANF
:
1549 case BUILT_IN_ATANL
:
1550 fcode
= BUILT_IN_ATANF
;
1552 case BUILT_IN_FLOOR
:
1553 case BUILT_IN_FLOORF
:
1554 case BUILT_IN_FLOORL
:
1555 fcode
= BUILT_IN_FLOORF
;
1558 case BUILT_IN_CEILF
:
1559 case BUILT_IN_CEILL
:
1560 fcode
= BUILT_IN_CEILF
;
1562 case BUILT_IN_TRUNC
:
1563 case BUILT_IN_TRUNCF
:
1564 case BUILT_IN_TRUNCL
:
1565 fcode
= BUILT_IN_TRUNCF
;
1567 case BUILT_IN_ROUND
:
1568 case BUILT_IN_ROUNDF
:
1569 case BUILT_IN_ROUNDL
:
1570 fcode
= BUILT_IN_ROUNDF
;
1572 case BUILT_IN_NEARBYINT
:
1573 case BUILT_IN_NEARBYINTF
:
1574 case BUILT_IN_NEARBYINTL
:
1575 fcode
= BUILT_IN_NEARBYINTF
;
1580 else if (TYPE_MODE (type
) == TYPE_MODE (long_double_type_node
))
1584 case BUILT_IN_SQRTF
:
1585 case BUILT_IN_SQRTL
:
1586 fcode
= BUILT_IN_SQRTL
;
1591 fcode
= BUILT_IN_SINL
;
1596 fcode
= BUILT_IN_COSL
;
1601 fcode
= BUILT_IN_EXPL
;
1606 fcode
= BUILT_IN_LOGL
;
1611 fcode
= BUILT_IN_TANL
;
1614 case BUILT_IN_ATANF
:
1615 case BUILT_IN_ATANL
:
1616 fcode
= BUILT_IN_ATANL
;
1618 case BUILT_IN_FLOOR
:
1619 case BUILT_IN_FLOORF
:
1620 case BUILT_IN_FLOORL
:
1621 fcode
= BUILT_IN_FLOORL
;
1624 case BUILT_IN_CEILF
:
1625 case BUILT_IN_CEILL
:
1626 fcode
= BUILT_IN_CEILL
;
1628 case BUILT_IN_TRUNC
:
1629 case BUILT_IN_TRUNCF
:
1630 case BUILT_IN_TRUNCL
:
1631 fcode
= BUILT_IN_TRUNCL
;
1633 case BUILT_IN_ROUND
:
1634 case BUILT_IN_ROUNDF
:
1635 case BUILT_IN_ROUNDL
:
1636 fcode
= BUILT_IN_ROUNDL
;
1638 case BUILT_IN_NEARBYINT
:
1639 case BUILT_IN_NEARBYINTF
:
1640 case BUILT_IN_NEARBYINTL
:
1641 fcode
= BUILT_IN_NEARBYINTL
;
1646 return implicit_built_in_decls
[fcode
];
1649 /* If errno must be maintained, expand the RTL to check if the result,
1650 TARGET, of a built-in function call, EXP, is NaN, and if so set
1654 expand_errno_check (tree exp
, rtx target
)
1656 rtx lab
= gen_label_rtx ();
1658 /* Test the result; if it is NaN, set errno=EDOM because
1659 the argument was not in the domain. */
1660 emit_cmp_and_jump_insns (target
, target
, EQ
, 0, GET_MODE (target
),
1664 /* If this built-in doesn't throw an exception, set errno directly. */
1665 if (TREE_NOTHROW (TREE_OPERAND (TREE_OPERAND (exp
, 0), 0)))
1667 #ifdef GEN_ERRNO_RTX
1668 rtx errno_rtx
= GEN_ERRNO_RTX
;
1671 = gen_rtx_MEM (word_mode
, gen_rtx_SYMBOL_REF (Pmode
, "errno"));
1673 emit_move_insn (errno_rtx
, GEN_INT (TARGET_EDOM
));
1679 /* We can't set errno=EDOM directly; let the library call do it.
1680 Pop the arguments right away in case the call gets deleted. */
1682 expand_call (exp
, target
, 0);
1688 /* Expand a call to one of the builtin math functions (sin, cos, or sqrt).
1689 Return 0 if a normal call should be emitted rather than expanding the
1690 function in-line. EXP is the expression that is a call to the builtin
1691 function; if convenient, the result should be placed in TARGET.
1692 SUBTARGET may be used as the target for computing one of EXP's operands. */
1695 expand_builtin_mathfn (tree exp
, rtx target
, rtx subtarget
)
1697 optab builtin_optab
;
1699 tree fndecl
= TREE_OPERAND (TREE_OPERAND (exp
, 0), 0);
1700 tree arglist
= TREE_OPERAND (exp
, 1);
1701 enum machine_mode mode
;
1702 bool errno_set
= false;
1705 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
1708 arg
= TREE_VALUE (arglist
);
1710 switch (DECL_FUNCTION_CODE (fndecl
))
1715 builtin_optab
= sin_optab
; break;
1719 builtin_optab
= cos_optab
; break;
1721 case BUILT_IN_SQRTF
:
1722 case BUILT_IN_SQRTL
:
1723 errno_set
= ! tree_expr_nonnegative_p (arg
);
1724 builtin_optab
= sqrt_optab
;
1729 errno_set
= true; builtin_optab
= exp_optab
; break;
1733 errno_set
= true; builtin_optab
= log_optab
; break;
1737 builtin_optab
= tan_optab
; break;
1739 case BUILT_IN_ATANF
:
1740 case BUILT_IN_ATANL
:
1741 builtin_optab
= atan_optab
; break;
1742 case BUILT_IN_FLOOR
:
1743 case BUILT_IN_FLOORF
:
1744 case BUILT_IN_FLOORL
:
1745 builtin_optab
= floor_optab
; break;
1747 case BUILT_IN_CEILF
:
1748 case BUILT_IN_CEILL
:
1749 builtin_optab
= ceil_optab
; break;
1750 case BUILT_IN_TRUNC
:
1751 case BUILT_IN_TRUNCF
:
1752 case BUILT_IN_TRUNCL
:
1753 builtin_optab
= trunc_optab
; break;
1754 case BUILT_IN_ROUND
:
1755 case BUILT_IN_ROUNDF
:
1756 case BUILT_IN_ROUNDL
:
1757 builtin_optab
= round_optab
; break;
1758 case BUILT_IN_NEARBYINT
:
1759 case BUILT_IN_NEARBYINTF
:
1760 case BUILT_IN_NEARBYINTL
:
1761 builtin_optab
= nearbyint_optab
; break;
1766 /* Make a suitable register to place result in. */
1767 mode
= TYPE_MODE (TREE_TYPE (exp
));
1768 target
= gen_reg_rtx (mode
);
1770 if (! flag_errno_math
|| ! HONOR_NANS (mode
))
1773 /* Stabilize and compute the argument. */
1775 switch (TREE_CODE (arg
))
1784 /* Wrap the computation of the argument in a SAVE_EXPR, as we
1785 need to expand the argument again in expand_errno_check. This
1786 way, we will not perform side-effects more the once. */
1787 arg
= save_expr (arg
);
1788 arglist
= build_tree_list (NULL_TREE
, arg
);
1789 exp
= build_function_call_expr (fndecl
, arglist
);
1793 op0
= expand_expr (arg
, subtarget
, VOIDmode
, 0);
1798 /* Compute into TARGET.
1799 Set TARGET to wherever the result comes back. */
1800 target
= expand_unop (mode
, builtin_optab
, op0
, target
, 0);
1802 /* If we were unable to expand via the builtin, stop the
1803 sequence (without outputting the insns) and return 0, causing
1804 a call to the library function. */
1812 expand_errno_check (exp
, target
);
1814 /* Output the entire sequence. */
1815 insns
= get_insns ();
1822 /* Expand a call to the builtin binary math functions (pow and atan2).
1823 Return 0 if a normal call should be emitted rather than expanding the
1824 function in-line. EXP is the expression that is a call to the builtin
1825 function; if convenient, the result should be placed in TARGET.
1826 SUBTARGET may be used as the target for computing one of EXP's
1830 expand_builtin_mathfn_2 (tree exp
, rtx target
, rtx subtarget
)
1832 optab builtin_optab
;
1833 rtx op0
, op1
, insns
;
1834 tree fndecl
= TREE_OPERAND (TREE_OPERAND (exp
, 0), 0);
1835 tree arglist
= TREE_OPERAND (exp
, 1);
1836 tree arg0
, arg1
, temp
;
1837 enum machine_mode mode
;
1838 bool errno_set
= true;
1841 if (!validate_arglist (arglist
, REAL_TYPE
, REAL_TYPE
, VOID_TYPE
))
1844 arg0
= TREE_VALUE (arglist
);
1845 arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
1847 switch (DECL_FUNCTION_CODE (fndecl
))
1852 builtin_optab
= pow_optab
; break;
1853 case BUILT_IN_ATAN2
:
1854 case BUILT_IN_ATAN2F
:
1855 case BUILT_IN_ATAN2L
:
1856 builtin_optab
= atan2_optab
; break;
1861 /* Make a suitable register to place result in. */
1862 mode
= TYPE_MODE (TREE_TYPE (exp
));
1863 target
= gen_reg_rtx (mode
);
1865 if (! flag_errno_math
|| ! HONOR_NANS (mode
))
1868 /* Stabilize the arguments. */
1871 switch (TREE_CODE (arg1
))
1877 temp
= TREE_CHAIN (arglist
);
1882 arg1
= save_expr (arg1
);
1883 temp
= build_tree_list (NULL_TREE
, arg1
);
1887 switch (TREE_CODE (arg0
))
1894 arglist
= build_tree_list (temp
, arg0
);
1899 arg0
= save_expr (arg0
);
1900 arglist
= build_tree_list (temp
, arg0
);
1905 exp
= build_function_call_expr (fndecl
, arglist
);
1908 op0
= expand_expr (arg0
, subtarget
, VOIDmode
, 0);
1909 op1
= expand_expr (arg1
, 0, VOIDmode
, 0);
1914 /* Compute into TARGET.
1915 Set TARGET to wherever the result comes back. */
1916 target
= expand_binop (mode
, builtin_optab
, op0
, op1
,
1917 target
, 0, OPTAB_DIRECT
);
1919 /* If we were unable to expand via the builtin, stop the
1920 sequence (without outputting the insns) and return 0, causing
1921 a call to the library function. */
1929 expand_errno_check (exp
, target
);
1931 /* Output the entire sequence. */
1932 insns
= get_insns ();
1939 /* Expand expression EXP which is a call to the strlen builtin. Return 0
1940 if we failed the caller should emit a normal call, otherwise
1941 try to get the result in TARGET, if convenient. */
1944 expand_builtin_strlen (tree arglist
, rtx target
,
1945 enum machine_mode target_mode
)
1947 if (!validate_arglist (arglist
, POINTER_TYPE
, VOID_TYPE
))
1952 tree len
, src
= TREE_VALUE (arglist
);
1953 rtx result
, src_reg
, char_rtx
, before_strlen
;
1954 enum machine_mode insn_mode
= target_mode
, char_mode
;
1955 enum insn_code icode
= CODE_FOR_nothing
;
1958 /* If the length can be computed at compile-time, return it. */
1959 len
= c_strlen (src
);
1961 return expand_expr (len
, target
, target_mode
, EXPAND_NORMAL
);
1963 align
= get_pointer_alignment (src
, BIGGEST_ALIGNMENT
) / BITS_PER_UNIT
;
1965 /* If SRC is not a pointer type, don't do this operation inline. */
1969 /* Bail out if we can't compute strlen in the right mode. */
1970 while (insn_mode
!= VOIDmode
)
1972 icode
= strlen_optab
->handlers
[(int) insn_mode
].insn_code
;
1973 if (icode
!= CODE_FOR_nothing
)
1976 insn_mode
= GET_MODE_WIDER_MODE (insn_mode
);
1978 if (insn_mode
== VOIDmode
)
1981 /* Make a place to write the result of the instruction. */
1984 && GET_CODE (result
) == REG
1985 && GET_MODE (result
) == insn_mode
1986 && REGNO (result
) >= FIRST_PSEUDO_REGISTER
))
1987 result
= gen_reg_rtx (insn_mode
);
1989 /* Make a place to hold the source address. We will not expand
1990 the actual source until we are sure that the expansion will
1991 not fail -- there are trees that cannot be expanded twice. */
1992 src_reg
= gen_reg_rtx (Pmode
);
1994 /* Mark the beginning of the strlen sequence so we can emit the
1995 source operand later. */
1996 before_strlen
= get_last_insn ();
1998 char_rtx
= const0_rtx
;
1999 char_mode
= insn_data
[(int) icode
].operand
[2].mode
;
2000 if (! (*insn_data
[(int) icode
].operand
[2].predicate
) (char_rtx
,
2002 char_rtx
= copy_to_mode_reg (char_mode
, char_rtx
);
2004 pat
= GEN_FCN (icode
) (result
, gen_rtx_MEM (BLKmode
, src_reg
),
2005 char_rtx
, GEN_INT (align
));
2010 /* Now that we are assured of success, expand the source. */
2012 pat
= memory_address (BLKmode
,
2013 expand_expr (src
, src_reg
, ptr_mode
, EXPAND_SUM
));
2015 emit_move_insn (src_reg
, pat
);
2020 emit_insn_after (pat
, before_strlen
);
2022 emit_insn_before (pat
, get_insns ());
2024 /* Return the value in the proper mode for this function. */
2025 if (GET_MODE (result
) == target_mode
)
2027 else if (target
!= 0)
2028 convert_move (target
, result
, 0);
2030 target
= convert_to_mode (target_mode
, result
, 0);
2036 /* Expand a call to the strstr builtin. Return 0 if we failed the
2037 caller should emit a normal call, otherwise try to get the result
2038 in TARGET, if convenient (and in mode MODE if that's convenient). */
2041 expand_builtin_strstr (tree arglist
, rtx target
, enum machine_mode mode
)
2043 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
2047 tree s1
= TREE_VALUE (arglist
), s2
= TREE_VALUE (TREE_CHAIN (arglist
));
2049 const char *p1
, *p2
;
2058 const char *r
= strstr (p1
, p2
);
2063 /* Return an offset into the constant string argument. */
2064 return expand_expr (fold (build (PLUS_EXPR
, TREE_TYPE (s1
),
2065 s1
, ssize_int (r
- p1
))),
2066 target
, mode
, EXPAND_NORMAL
);
2070 return expand_expr (s1
, target
, mode
, EXPAND_NORMAL
);
2075 fn
= implicit_built_in_decls
[BUILT_IN_STRCHR
];
2079 /* New argument list transforming strstr(s1, s2) to
2080 strchr(s1, s2[0]). */
2082 build_tree_list (NULL_TREE
, build_int_2 (p2
[0], 0));
2083 arglist
= tree_cons (NULL_TREE
, s1
, arglist
);
2084 return expand_expr (build_function_call_expr (fn
, arglist
),
2085 target
, mode
, EXPAND_NORMAL
);
2089 /* Expand a call to the strchr builtin. Return 0 if we failed the
2090 caller should emit a normal call, otherwise try to get the result
2091 in TARGET, if convenient (and in mode MODE if that's convenient). */
2094 expand_builtin_strchr (tree arglist
, rtx target
, enum machine_mode mode
)
2096 if (!validate_arglist (arglist
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
2100 tree s1
= TREE_VALUE (arglist
), s2
= TREE_VALUE (TREE_CHAIN (arglist
));
2103 if (TREE_CODE (s2
) != INTEGER_CST
)
2112 if (target_char_cast (s2
, &c
))
2120 /* Return an offset into the constant string argument. */
2121 return expand_expr (fold (build (PLUS_EXPR
, TREE_TYPE (s1
),
2122 s1
, ssize_int (r
- p1
))),
2123 target
, mode
, EXPAND_NORMAL
);
2126 /* FIXME: Should use here strchrM optab so that ports can optimize
2132 /* Expand a call to the strrchr builtin. Return 0 if we failed the
2133 caller should emit a normal call, otherwise try to get the result
2134 in TARGET, if convenient (and in mode MODE if that's convenient). */
2137 expand_builtin_strrchr (tree arglist
, rtx target
, enum machine_mode mode
)
2139 if (!validate_arglist (arglist
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
2143 tree s1
= TREE_VALUE (arglist
), s2
= TREE_VALUE (TREE_CHAIN (arglist
));
2147 if (TREE_CODE (s2
) != INTEGER_CST
)
2156 if (target_char_cast (s2
, &c
))
2159 r
= strrchr (p1
, c
);
2164 /* Return an offset into the constant string argument. */
2165 return expand_expr (fold (build (PLUS_EXPR
, TREE_TYPE (s1
),
2166 s1
, ssize_int (r
- p1
))),
2167 target
, mode
, EXPAND_NORMAL
);
2170 if (! integer_zerop (s2
))
2173 fn
= implicit_built_in_decls
[BUILT_IN_STRCHR
];
2177 /* Transform strrchr(s1, '\0') to strchr(s1, '\0'). */
2178 return expand_expr (build_function_call_expr (fn
, arglist
),
2179 target
, mode
, EXPAND_NORMAL
);
2183 /* Expand a call to the strpbrk builtin. Return 0 if we failed the
2184 caller should emit a normal call, otherwise try to get the result
2185 in TARGET, if convenient (and in mode MODE if that's convenient). */
2188 expand_builtin_strpbrk (tree arglist
, rtx target
, enum machine_mode mode
)
2190 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
2194 tree s1
= TREE_VALUE (arglist
), s2
= TREE_VALUE (TREE_CHAIN (arglist
));
2196 const char *p1
, *p2
;
2205 const char *r
= strpbrk (p1
, p2
);
2210 /* Return an offset into the constant string argument. */
2211 return expand_expr (fold (build (PLUS_EXPR
, TREE_TYPE (s1
),
2212 s1
, ssize_int (r
- p1
))),
2213 target
, mode
, EXPAND_NORMAL
);
2218 /* strpbrk(x, "") == NULL.
2219 Evaluate and ignore the arguments in case they had
2221 expand_expr (s1
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
2226 return 0; /* Really call strpbrk. */
2228 fn
= implicit_built_in_decls
[BUILT_IN_STRCHR
];
2232 /* New argument list transforming strpbrk(s1, s2) to
2233 strchr(s1, s2[0]). */
2235 build_tree_list (NULL_TREE
, build_int_2 (p2
[0], 0));
2236 arglist
= tree_cons (NULL_TREE
, s1
, arglist
);
2237 return expand_expr (build_function_call_expr (fn
, arglist
),
2238 target
, mode
, EXPAND_NORMAL
);
2242 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
2243 bytes from constant string DATA + OFFSET and return it as target
2247 builtin_memcpy_read_str (void *data
, HOST_WIDE_INT offset
,
2248 enum machine_mode mode
)
2250 const char *str
= (const char *) data
;
2253 || ((unsigned HOST_WIDE_INT
) offset
+ GET_MODE_SIZE (mode
)
2254 > strlen (str
) + 1))
2255 abort (); /* Attempt to read past the end of constant string. */
2257 return c_readstr (str
+ offset
, mode
);
2260 /* Expand a call to the memcpy builtin, with arguments in ARGLIST.
2261 Return 0 if we failed, the caller should emit a normal call,
2262 otherwise try to get the result in TARGET, if convenient (and in
2263 mode MODE if that's convenient). */
2265 expand_builtin_memcpy (tree arglist
, rtx target
, enum machine_mode mode
)
2267 if (!validate_arglist (arglist
,
2268 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
2272 tree dest
= TREE_VALUE (arglist
);
2273 tree src
= TREE_VALUE (TREE_CHAIN (arglist
));
2274 tree len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
2275 const char *src_str
;
2276 unsigned int src_align
= get_pointer_alignment (src
, BIGGEST_ALIGNMENT
);
2277 unsigned int dest_align
2278 = get_pointer_alignment (dest
, BIGGEST_ALIGNMENT
);
2279 rtx dest_mem
, src_mem
, dest_addr
, len_rtx
;
2281 /* If DEST is not a pointer type, call the normal function. */
2282 if (dest_align
== 0)
2285 /* If the LEN parameter is zero, return DEST. */
2286 if (host_integerp (len
, 1) && tree_low_cst (len
, 1) == 0)
2288 /* Evaluate and ignore SRC in case it has side-effects. */
2289 expand_expr (src
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
2290 return expand_expr (dest
, target
, mode
, EXPAND_NORMAL
);
2293 /* If either SRC is not a pointer type, don't do this
2294 operation in-line. */
2298 dest_mem
= get_memory_rtx (dest
);
2299 set_mem_align (dest_mem
, dest_align
);
2300 len_rtx
= expand_expr (len
, NULL_RTX
, VOIDmode
, 0);
2301 src_str
= c_getstr (src
);
2303 /* If SRC is a string constant and block move would be done
2304 by pieces, we can avoid loading the string from memory
2305 and only stored the computed constants. */
2307 && GET_CODE (len_rtx
) == CONST_INT
2308 && (unsigned HOST_WIDE_INT
) INTVAL (len_rtx
) <= strlen (src_str
) + 1
2309 && can_store_by_pieces (INTVAL (len_rtx
), builtin_memcpy_read_str
,
2310 (void *) src_str
, dest_align
))
2312 dest_mem
= store_by_pieces (dest_mem
, INTVAL (len_rtx
),
2313 builtin_memcpy_read_str
,
2314 (void *) src_str
, dest_align
, 0);
2315 dest_mem
= force_operand (XEXP (dest_mem
, 0), NULL_RTX
);
2316 #ifdef POINTERS_EXTEND_UNSIGNED
2317 if (GET_MODE (dest_mem
) != ptr_mode
)
2318 dest_mem
= convert_memory_address (ptr_mode
, dest_mem
);
2323 src_mem
= get_memory_rtx (src
);
2324 set_mem_align (src_mem
, src_align
);
2326 /* Copy word part most expediently. */
2327 dest_addr
= emit_block_move (dest_mem
, src_mem
, len_rtx
,
2332 dest_addr
= force_operand (XEXP (dest_mem
, 0), NULL_RTX
);
2333 #ifdef POINTERS_EXTEND_UNSIGNED
2334 if (GET_MODE (dest_addr
) != ptr_mode
)
2335 dest_addr
= convert_memory_address (ptr_mode
, dest_addr
);
2342 /* Expand a call to the mempcpy builtin, with arguments in ARGLIST.
2343 Return 0 if we failed the caller should emit a normal call,
2344 otherwise try to get the result in TARGET, if convenient (and in
2345 mode MODE if that's convenient). If ENDP is 0 return the
2346 destination pointer, if ENDP is 1 return the end pointer ala
2347 mempcpy, and if ENDP is 2 return the end pointer minus one ala
2351 expand_builtin_mempcpy (tree arglist
, rtx target
, enum machine_mode mode
,
2354 if (!validate_arglist (arglist
,
2355 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
2357 /* If return value is ignored, transform mempcpy into memcpy. */
2358 else if (target
== const0_rtx
)
2360 tree fn
= implicit_built_in_decls
[BUILT_IN_MEMCPY
];
2365 return expand_expr (build_function_call_expr (fn
, arglist
),
2366 target
, mode
, EXPAND_NORMAL
);
2370 tree dest
= TREE_VALUE (arglist
);
2371 tree src
= TREE_VALUE (TREE_CHAIN (arglist
));
2372 tree len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
2373 const char *src_str
;
2374 unsigned int src_align
= get_pointer_alignment (src
, BIGGEST_ALIGNMENT
);
2375 unsigned int dest_align
2376 = get_pointer_alignment (dest
, BIGGEST_ALIGNMENT
);
2377 rtx dest_mem
, src_mem
, len_rtx
;
2379 /* If DEST is not a pointer type or LEN is not constant,
2380 call the normal function. */
2381 if (dest_align
== 0 || !host_integerp (len
, 1))
2384 /* If the LEN parameter is zero, return DEST. */
2385 if (tree_low_cst (len
, 1) == 0)
2387 /* Evaluate and ignore SRC in case it has side-effects. */
2388 expand_expr (src
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
2389 return expand_expr (dest
, target
, mode
, EXPAND_NORMAL
);
2392 /* If either SRC is not a pointer type, don't do this
2393 operation in-line. */
2397 len_rtx
= expand_expr (len
, NULL_RTX
, VOIDmode
, 0);
2398 src_str
= c_getstr (src
);
2400 /* If SRC is a string constant and block move would be done
2401 by pieces, we can avoid loading the string from memory
2402 and only stored the computed constants. */
2404 && GET_CODE (len_rtx
) == CONST_INT
2405 && (unsigned HOST_WIDE_INT
) INTVAL (len_rtx
) <= strlen (src_str
) + 1
2406 && can_store_by_pieces (INTVAL (len_rtx
), builtin_memcpy_read_str
,
2407 (void *) src_str
, dest_align
))
2409 dest_mem
= get_memory_rtx (dest
);
2410 set_mem_align (dest_mem
, dest_align
);
2411 dest_mem
= store_by_pieces (dest_mem
, INTVAL (len_rtx
),
2412 builtin_memcpy_read_str
,
2413 (void *) src_str
, dest_align
, endp
);
2414 dest_mem
= force_operand (XEXP (dest_mem
, 0), NULL_RTX
);
2415 #ifdef POINTERS_EXTEND_UNSIGNED
2416 if (GET_MODE (dest_mem
) != ptr_mode
)
2417 dest_mem
= convert_memory_address (ptr_mode
, dest_mem
);
2422 if (GET_CODE (len_rtx
) == CONST_INT
2423 && can_move_by_pieces (INTVAL (len_rtx
),
2424 MIN (dest_align
, src_align
)))
2426 dest_mem
= get_memory_rtx (dest
);
2427 set_mem_align (dest_mem
, dest_align
);
2428 src_mem
= get_memory_rtx (src
);
2429 set_mem_align (src_mem
, src_align
);
2430 dest_mem
= move_by_pieces (dest_mem
, src_mem
, INTVAL (len_rtx
),
2431 MIN (dest_align
, src_align
), endp
);
2432 dest_mem
= force_operand (XEXP (dest_mem
, 0), NULL_RTX
);
2433 #ifdef POINTERS_EXTEND_UNSIGNED
2434 if (GET_MODE (dest_mem
) != ptr_mode
)
2435 dest_mem
= convert_memory_address (ptr_mode
, dest_mem
);
2444 /* Expand expression EXP, which is a call to the memmove builtin. Return 0
2445 if we failed the caller should emit a normal call. */
2448 expand_builtin_memmove (tree arglist
, rtx target
, enum machine_mode mode
)
2450 if (!validate_arglist (arglist
,
2451 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
2455 tree dest
= TREE_VALUE (arglist
);
2456 tree src
= TREE_VALUE (TREE_CHAIN (arglist
));
2457 tree len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
2459 unsigned int src_align
= get_pointer_alignment (src
, BIGGEST_ALIGNMENT
);
2460 unsigned int dest_align
2461 = get_pointer_alignment (dest
, BIGGEST_ALIGNMENT
);
2463 /* If DEST is not a pointer type, call the normal function. */
2464 if (dest_align
== 0)
2467 /* If the LEN parameter is zero, return DEST. */
2468 if (host_integerp (len
, 1) && tree_low_cst (len
, 1) == 0)
2470 /* Evaluate and ignore SRC in case it has side-effects. */
2471 expand_expr (src
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
2472 return expand_expr (dest
, target
, mode
, EXPAND_NORMAL
);
2475 /* If either SRC is not a pointer type, don't do this
2476 operation in-line. */
2480 /* If src is categorized for a readonly section we can use
2482 if (readonly_data_expr (src
))
2484 tree
const fn
= implicit_built_in_decls
[BUILT_IN_MEMCPY
];
2487 return expand_expr (build_function_call_expr (fn
, arglist
),
2488 target
, mode
, EXPAND_NORMAL
);
2491 /* Otherwise, call the normal function. */
2496 /* Expand expression EXP, which is a call to the bcopy builtin. Return 0
2497 if we failed the caller should emit a normal call. */
2500 expand_builtin_bcopy (tree arglist
)
2502 tree src
, dest
, size
, newarglist
;
2504 if (!validate_arglist (arglist
,
2505 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
2508 src
= TREE_VALUE (arglist
);
2509 dest
= TREE_VALUE (TREE_CHAIN (arglist
));
2510 size
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
2512 /* New argument list transforming bcopy(ptr x, ptr y, int z) to
2513 memmove(ptr y, ptr x, size_t z). This is done this way
2514 so that if it isn't expanded inline, we fallback to
2515 calling bcopy instead of memmove. */
2517 newarglist
= build_tree_list (NULL_TREE
, convert (sizetype
, size
));
2518 newarglist
= tree_cons (NULL_TREE
, src
, newarglist
);
2519 newarglist
= tree_cons (NULL_TREE
, dest
, newarglist
);
2521 return expand_builtin_memmove (newarglist
, const0_rtx
, VOIDmode
);
2524 /* Expand expression EXP, which is a call to the strcpy builtin. Return 0
2525 if we failed the caller should emit a normal call, otherwise try to get
2526 the result in TARGET, if convenient (and in mode MODE if that's
2530 expand_builtin_strcpy (tree arglist
, rtx target
, enum machine_mode mode
)
2534 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
2537 fn
= implicit_built_in_decls
[BUILT_IN_MEMCPY
];
2541 len
= c_strlen (TREE_VALUE (TREE_CHAIN (arglist
)));
2545 len
= size_binop (PLUS_EXPR
, len
, ssize_int (1));
2546 chainon (arglist
, build_tree_list (NULL_TREE
, len
));
2547 return expand_expr (build_function_call_expr (fn
, arglist
),
2548 target
, mode
, EXPAND_NORMAL
);
2551 /* Expand a call to the stpcpy builtin, with arguments in ARGLIST.
2552 Return 0 if we failed the caller should emit a normal call,
2553 otherwise try to get the result in TARGET, if convenient (and in
2554 mode MODE if that's convenient). */
2557 expand_builtin_stpcpy (tree arglist
, rtx target
, enum machine_mode mode
)
2559 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
2566 /* If return value is ignored, transform stpcpy into strcpy. */
2567 if (target
== const0_rtx
)
2569 tree fn
= implicit_built_in_decls
[BUILT_IN_STRCPY
];
2573 return expand_expr (build_function_call_expr (fn
, arglist
),
2574 target
, mode
, EXPAND_NORMAL
);
2577 /* Ensure we get an actual string whose length can be evaluated at
2578 compile-time, not an expression containing a string. This is
2579 because the latter will potentially produce pessimized code
2580 when used to produce the return value. */
2581 src
= TREE_VALUE (TREE_CHAIN (arglist
));
2582 if (! c_getstr (src
) || ! (len
= c_strlen (src
)))
2585 len
= fold (size_binop (PLUS_EXPR
, len
, ssize_int (1)));
2586 newarglist
= copy_list (arglist
);
2587 chainon (newarglist
, build_tree_list (NULL_TREE
, len
));
2588 return expand_builtin_mempcpy (newarglist
, target
, mode
, /*endp=*/2);
2592 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
2593 bytes from constant string DATA + OFFSET and return it as target
2597 builtin_strncpy_read_str (void *data
, HOST_WIDE_INT offset
,
2598 enum machine_mode mode
)
2600 const char *str
= (const char *) data
;
2602 if ((unsigned HOST_WIDE_INT
) offset
> strlen (str
))
2605 return c_readstr (str
+ offset
, mode
);
2608 /* Expand expression EXP, which is a call to the strncpy builtin. Return 0
2609 if we failed the caller should emit a normal call. */
2612 expand_builtin_strncpy (tree arglist
, rtx target
, enum machine_mode mode
)
2614 if (!validate_arglist (arglist
,
2615 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
2619 tree slen
= c_strlen (TREE_VALUE (TREE_CHAIN (arglist
)));
2620 tree len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
2623 /* We must be passed a constant len parameter. */
2624 if (TREE_CODE (len
) != INTEGER_CST
)
2627 /* If the len parameter is zero, return the dst parameter. */
2628 if (integer_zerop (len
))
2630 /* Evaluate and ignore the src argument in case it has
2632 expand_expr (TREE_VALUE (TREE_CHAIN (arglist
)), const0_rtx
,
2633 VOIDmode
, EXPAND_NORMAL
);
2634 /* Return the dst parameter. */
2635 return expand_expr (TREE_VALUE (arglist
), target
, mode
,
2639 /* Now, we must be passed a constant src ptr parameter. */
2640 if (slen
== 0 || TREE_CODE (slen
) != INTEGER_CST
)
2643 slen
= size_binop (PLUS_EXPR
, slen
, ssize_int (1));
2645 /* We're required to pad with trailing zeros if the requested
2646 len is greater than strlen(s2)+1. In that case try to
2647 use store_by_pieces, if it fails, punt. */
2648 if (tree_int_cst_lt (slen
, len
))
2650 tree dest
= TREE_VALUE (arglist
);
2651 unsigned int dest_align
2652 = get_pointer_alignment (dest
, BIGGEST_ALIGNMENT
);
2653 const char *p
= c_getstr (TREE_VALUE (TREE_CHAIN (arglist
)));
2656 if (!p
|| dest_align
== 0 || !host_integerp (len
, 1)
2657 || !can_store_by_pieces (tree_low_cst (len
, 1),
2658 builtin_strncpy_read_str
,
2659 (void *) p
, dest_align
))
2662 dest_mem
= get_memory_rtx (dest
);
2663 store_by_pieces (dest_mem
, tree_low_cst (len
, 1),
2664 builtin_strncpy_read_str
,
2665 (void *) p
, dest_align
, 0);
2666 dest_mem
= force_operand (XEXP (dest_mem
, 0), NULL_RTX
);
2667 #ifdef POINTERS_EXTEND_UNSIGNED
2668 if (GET_MODE (dest_mem
) != ptr_mode
)
2669 dest_mem
= convert_memory_address (ptr_mode
, dest_mem
);
2674 /* OK transform into builtin memcpy. */
2675 fn
= implicit_built_in_decls
[BUILT_IN_MEMCPY
];
2678 return expand_expr (build_function_call_expr (fn
, arglist
),
2679 target
, mode
, EXPAND_NORMAL
);
2683 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
2684 bytes from constant string DATA + OFFSET and return it as target
2688 builtin_memset_read_str (void *data
, HOST_WIDE_INT offset ATTRIBUTE_UNUSED
,
2689 enum machine_mode mode
)
2691 const char *c
= (const char *) data
;
2692 char *p
= alloca (GET_MODE_SIZE (mode
));
2694 memset (p
, *c
, GET_MODE_SIZE (mode
));
2696 return c_readstr (p
, mode
);
2699 /* Callback routine for store_by_pieces. Return the RTL of a register
2700 containing GET_MODE_SIZE (MODE) consecutive copies of the unsigned
2701 char value given in the RTL register data. For example, if mode is
2702 4 bytes wide, return the RTL for 0x01010101*data. */
2705 builtin_memset_gen_str (void *data
, HOST_WIDE_INT offset ATTRIBUTE_UNUSED
,
2706 enum machine_mode mode
)
2712 size
= GET_MODE_SIZE (mode
);
2717 memset (p
, 1, size
);
2718 coeff
= c_readstr (p
, mode
);
2720 target
= convert_to_mode (mode
, (rtx
) data
, 1);
2721 target
= expand_mult (mode
, target
, coeff
, NULL_RTX
, 1);
2722 return force_reg (mode
, target
);
2725 /* Expand expression EXP, which is a call to the memset builtin. Return 0
2726 if we failed the caller should emit a normal call, otherwise try to get
2727 the result in TARGET, if convenient (and in mode MODE if that's
2731 expand_builtin_memset (tree arglist
, rtx target
, enum machine_mode mode
)
2733 if (!validate_arglist (arglist
,
2734 POINTER_TYPE
, INTEGER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
2738 tree dest
= TREE_VALUE (arglist
);
2739 tree val
= TREE_VALUE (TREE_CHAIN (arglist
));
2740 tree len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
2743 unsigned int dest_align
2744 = get_pointer_alignment (dest
, BIGGEST_ALIGNMENT
);
2745 rtx dest_mem
, dest_addr
, len_rtx
;
2747 /* If DEST is not a pointer type, don't do this
2748 operation in-line. */
2749 if (dest_align
== 0)
2752 /* If the LEN parameter is zero, return DEST. */
2753 if (host_integerp (len
, 1) && tree_low_cst (len
, 1) == 0)
2755 /* Evaluate and ignore VAL in case it has side-effects. */
2756 expand_expr (val
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
2757 return expand_expr (dest
, target
, mode
, EXPAND_NORMAL
);
2760 if (TREE_CODE (val
) != INTEGER_CST
)
2764 if (!host_integerp (len
, 1))
2767 if (optimize_size
&& tree_low_cst (len
, 1) > 1)
2770 /* Assume that we can memset by pieces if we can store the
2771 * the coefficients by pieces (in the required modes).
2772 * We can't pass builtin_memset_gen_str as that emits RTL. */
2774 if (!can_store_by_pieces (tree_low_cst (len
, 1),
2775 builtin_memset_read_str
,
2779 val
= fold (build1 (CONVERT_EXPR
, unsigned_char_type_node
, val
));
2780 val_rtx
= expand_expr (val
, NULL_RTX
, VOIDmode
, 0);
2781 val_rtx
= force_reg (TYPE_MODE (unsigned_char_type_node
),
2783 dest_mem
= get_memory_rtx (dest
);
2784 store_by_pieces (dest_mem
, tree_low_cst (len
, 1),
2785 builtin_memset_gen_str
,
2786 val_rtx
, dest_align
, 0);
2787 dest_mem
= force_operand (XEXP (dest_mem
, 0), NULL_RTX
);
2788 #ifdef POINTERS_EXTEND_UNSIGNED
2789 if (GET_MODE (dest_mem
) != ptr_mode
)
2790 dest_mem
= convert_memory_address (ptr_mode
, dest_mem
);
2795 if (target_char_cast (val
, &c
))
2800 if (!host_integerp (len
, 1))
2802 if (!can_store_by_pieces (tree_low_cst (len
, 1),
2803 builtin_memset_read_str
, &c
,
2807 dest_mem
= get_memory_rtx (dest
);
2808 store_by_pieces (dest_mem
, tree_low_cst (len
, 1),
2809 builtin_memset_read_str
,
2811 dest_mem
= force_operand (XEXP (dest_mem
, 0), NULL_RTX
);
2812 #ifdef POINTERS_EXTEND_UNSIGNED
2813 if (GET_MODE (dest_mem
) != ptr_mode
)
2814 dest_mem
= convert_memory_address (ptr_mode
, dest_mem
);
2819 len_rtx
= expand_expr (len
, NULL_RTX
, VOIDmode
, 0);
2821 dest_mem
= get_memory_rtx (dest
);
2822 set_mem_align (dest_mem
, dest_align
);
2823 dest_addr
= clear_storage (dest_mem
, len_rtx
);
2827 dest_addr
= force_operand (XEXP (dest_mem
, 0), NULL_RTX
);
2828 #ifdef POINTERS_EXTEND_UNSIGNED
2829 if (GET_MODE (dest_addr
) != ptr_mode
)
2830 dest_addr
= convert_memory_address (ptr_mode
, dest_addr
);
2838 /* Expand expression EXP, which is a call to the bzero builtin. Return 0
2839 if we failed the caller should emit a normal call. */
2842 expand_builtin_bzero (tree arglist
)
2844 tree dest
, size
, newarglist
;
2846 if (!validate_arglist (arglist
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
2849 dest
= TREE_VALUE (arglist
);
2850 size
= TREE_VALUE (TREE_CHAIN (arglist
));
2852 /* New argument list transforming bzero(ptr x, int y) to
2853 memset(ptr x, int 0, size_t y). This is done this way
2854 so that if it isn't expanded inline, we fallback to
2855 calling bzero instead of memset. */
2857 newarglist
= build_tree_list (NULL_TREE
, convert (sizetype
, size
));
2858 newarglist
= tree_cons (NULL_TREE
, integer_zero_node
, newarglist
);
2859 newarglist
= tree_cons (NULL_TREE
, dest
, newarglist
);
2861 return expand_builtin_memset (newarglist
, const0_rtx
, VOIDmode
);
2864 /* Expand expression EXP, which is a call to the memcmp built-in function.
2865 ARGLIST is the argument list for this call. Return 0 if we failed and the
2866 caller should emit a normal call, otherwise try to get the result in
2867 TARGET, if convenient (and in mode MODE, if that's convenient). */
2870 expand_builtin_memcmp (tree exp ATTRIBUTE_UNUSED
, tree arglist
, rtx target
,
2871 enum machine_mode mode
)
2873 tree arg1
, arg2
, len
;
2874 const char *p1
, *p2
;
2876 if (!validate_arglist (arglist
,
2877 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
2880 arg1
= TREE_VALUE (arglist
);
2881 arg2
= TREE_VALUE (TREE_CHAIN (arglist
));
2882 len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
2884 /* If the len parameter is zero, return zero. */
2885 if (host_integerp (len
, 1) && tree_low_cst (len
, 1) == 0)
2887 /* Evaluate and ignore arg1 and arg2 in case they have
2889 expand_expr (arg1
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
2890 expand_expr (arg2
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
2894 p1
= c_getstr (arg1
);
2895 p2
= c_getstr (arg2
);
2897 /* If all arguments are constant, and the value of len is not greater
2898 than the lengths of arg1 and arg2, evaluate at compile-time. */
2899 if (host_integerp (len
, 1) && p1
&& p2
2900 && compare_tree_int (len
, strlen (p1
) + 1) <= 0
2901 && compare_tree_int (len
, strlen (p2
) + 1) <= 0)
2903 const int r
= memcmp (p1
, p2
, tree_low_cst (len
, 1));
2905 return (r
< 0 ? constm1_rtx
: (r
> 0 ? const1_rtx
: const0_rtx
));
2908 /* If len parameter is one, return an expression corresponding to
2909 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
2910 if (host_integerp (len
, 1) && tree_low_cst (len
, 1) == 1)
2912 tree cst_uchar_node
= build_type_variant (unsigned_char_type_node
, 1, 0);
2913 tree cst_uchar_ptr_node
= build_pointer_type (cst_uchar_node
);
2915 fold (build1 (CONVERT_EXPR
, integer_type_node
,
2916 build1 (INDIRECT_REF
, cst_uchar_node
,
2917 build1 (NOP_EXPR
, cst_uchar_ptr_node
, arg1
))));
2919 fold (build1 (CONVERT_EXPR
, integer_type_node
,
2920 build1 (INDIRECT_REF
, cst_uchar_node
,
2921 build1 (NOP_EXPR
, cst_uchar_ptr_node
, arg2
))));
2922 tree result
= fold (build (MINUS_EXPR
, integer_type_node
, ind1
, ind2
));
2923 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
2926 #ifdef HAVE_cmpstrsi
2928 rtx arg1_rtx
, arg2_rtx
, arg3_rtx
;
2933 = get_pointer_alignment (arg1
, BIGGEST_ALIGNMENT
) / BITS_PER_UNIT
;
2935 = get_pointer_alignment (arg2
, BIGGEST_ALIGNMENT
) / BITS_PER_UNIT
;
2936 enum machine_mode insn_mode
2937 = insn_data
[(int) CODE_FOR_cmpstrsi
].operand
[0].mode
;
2939 /* If we don't have POINTER_TYPE, call the function. */
2940 if (arg1_align
== 0 || arg2_align
== 0)
2943 /* Make a place to write the result of the instruction. */
2946 && GET_CODE (result
) == REG
&& GET_MODE (result
) == insn_mode
2947 && REGNO (result
) >= FIRST_PSEUDO_REGISTER
))
2948 result
= gen_reg_rtx (insn_mode
);
2950 arg1_rtx
= get_memory_rtx (arg1
);
2951 arg2_rtx
= get_memory_rtx (arg2
);
2952 arg3_rtx
= expand_expr (len
, NULL_RTX
, VOIDmode
, 0);
2956 insn
= gen_cmpstrsi (result
, arg1_rtx
, arg2_rtx
, arg3_rtx
,
2957 GEN_INT (MIN (arg1_align
, arg2_align
)));
2962 emit_library_call_value (memcmp_libfunc
, result
, LCT_PURE_MAKE_BLOCK
,
2963 TYPE_MODE (integer_type_node
), 3,
2964 XEXP (arg1_rtx
, 0), Pmode
,
2965 XEXP (arg2_rtx
, 0), Pmode
,
2966 convert_to_mode (TYPE_MODE (sizetype
), arg3_rtx
,
2967 TREE_UNSIGNED (sizetype
)),
2968 TYPE_MODE (sizetype
));
2970 /* Return the value in the proper mode for this function. */
2971 mode
= TYPE_MODE (TREE_TYPE (exp
));
2972 if (GET_MODE (result
) == mode
)
2974 else if (target
!= 0)
2976 convert_move (target
, result
, 0);
2980 return convert_to_mode (mode
, result
, 0);
2987 /* Expand expression EXP, which is a call to the strcmp builtin. Return 0
2988 if we failed the caller should emit a normal call, otherwise try to get
2989 the result in TARGET, if convenient. */
2992 expand_builtin_strcmp (tree exp
, rtx target
, enum machine_mode mode
)
2994 tree arglist
= TREE_OPERAND (exp
, 1);
2996 const char *p1
, *p2
;
2998 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
3001 arg1
= TREE_VALUE (arglist
);
3002 arg2
= TREE_VALUE (TREE_CHAIN (arglist
));
3004 p1
= c_getstr (arg1
);
3005 p2
= c_getstr (arg2
);
3009 const int i
= strcmp (p1
, p2
);
3010 return (i
< 0 ? constm1_rtx
: (i
> 0 ? const1_rtx
: const0_rtx
));
3013 /* If either arg is "", return an expression corresponding to
3014 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
3015 if ((p1
&& *p1
== '\0') || (p2
&& *p2
== '\0'))
3017 tree cst_uchar_node
= build_type_variant (unsigned_char_type_node
, 1, 0);
3018 tree cst_uchar_ptr_node
= build_pointer_type (cst_uchar_node
);
3020 fold (build1 (CONVERT_EXPR
, integer_type_node
,
3021 build1 (INDIRECT_REF
, cst_uchar_node
,
3022 build1 (NOP_EXPR
, cst_uchar_ptr_node
, arg1
))));
3024 fold (build1 (CONVERT_EXPR
, integer_type_node
,
3025 build1 (INDIRECT_REF
, cst_uchar_node
,
3026 build1 (NOP_EXPR
, cst_uchar_ptr_node
, arg2
))));
3027 tree result
= fold (build (MINUS_EXPR
, integer_type_node
, ind1
, ind2
));
3028 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
3031 #ifdef HAVE_cmpstrsi
3034 tree len
, len1
, len2
;
3035 rtx arg1_rtx
, arg2_rtx
, arg3_rtx
;
3039 = get_pointer_alignment (arg1
, BIGGEST_ALIGNMENT
) / BITS_PER_UNIT
;
3041 = get_pointer_alignment (arg2
, BIGGEST_ALIGNMENT
) / BITS_PER_UNIT
;
3042 enum machine_mode insn_mode
3043 = insn_data
[(int) CODE_FOR_cmpstrsi
].operand
[0].mode
;
3045 len1
= c_strlen (arg1
);
3046 len2
= c_strlen (arg2
);
3049 len1
= size_binop (PLUS_EXPR
, ssize_int (1), len1
);
3051 len2
= size_binop (PLUS_EXPR
, ssize_int (1), len2
);
3053 /* If we don't have a constant length for the first, use the length
3054 of the second, if we know it. We don't require a constant for
3055 this case; some cost analysis could be done if both are available
3056 but neither is constant. For now, assume they're equally cheap,
3057 unless one has side effects. If both strings have constant lengths,
3064 else if (TREE_SIDE_EFFECTS (len1
))
3066 else if (TREE_SIDE_EFFECTS (len2
))
3068 else if (TREE_CODE (len1
) != INTEGER_CST
)
3070 else if (TREE_CODE (len2
) != INTEGER_CST
)
3072 else if (tree_int_cst_lt (len1
, len2
))
3077 /* If both arguments have side effects, we cannot optimize. */
3078 if (!len
|| TREE_SIDE_EFFECTS (len
))
3081 /* If we don't have POINTER_TYPE, call the function. */
3082 if (arg1_align
== 0 || arg2_align
== 0)
3085 /* Make a place to write the result of the instruction. */
3088 && GET_CODE (result
) == REG
&& GET_MODE (result
) == insn_mode
3089 && REGNO (result
) >= FIRST_PSEUDO_REGISTER
))
3090 result
= gen_reg_rtx (insn_mode
);
3092 arg1_rtx
= get_memory_rtx (arg1
);
3093 arg2_rtx
= get_memory_rtx (arg2
);
3094 arg3_rtx
= expand_expr (len
, NULL_RTX
, VOIDmode
, 0);
3095 insn
= gen_cmpstrsi (result
, arg1_rtx
, arg2_rtx
, arg3_rtx
,
3096 GEN_INT (MIN (arg1_align
, arg2_align
)));
3102 /* Return the value in the proper mode for this function. */
3103 mode
= TYPE_MODE (TREE_TYPE (exp
));
3104 if (GET_MODE (result
) == mode
)
3107 return convert_to_mode (mode
, result
, 0);
3108 convert_move (target
, result
, 0);
3115 /* Expand expression EXP, which is a call to the strncmp builtin. Return 0
3116 if we failed the caller should emit a normal call, otherwise try to get
3117 the result in TARGET, if convenient. */
3120 expand_builtin_strncmp (tree exp
, rtx target
, enum machine_mode mode
)
3122 tree arglist
= TREE_OPERAND (exp
, 1);
3123 tree arg1
, arg2
, arg3
;
3124 const char *p1
, *p2
;
3126 if (!validate_arglist (arglist
,
3127 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
3130 arg1
= TREE_VALUE (arglist
);
3131 arg2
= TREE_VALUE (TREE_CHAIN (arglist
));
3132 arg3
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
3134 /* If the len parameter is zero, return zero. */
3135 if (host_integerp (arg3
, 1) && tree_low_cst (arg3
, 1) == 0)
3137 /* Evaluate and ignore arg1 and arg2 in case they have
3139 expand_expr (arg1
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
3140 expand_expr (arg2
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
3144 p1
= c_getstr (arg1
);
3145 p2
= c_getstr (arg2
);
3147 /* If all arguments are constant, evaluate at compile-time. */
3148 if (host_integerp (arg3
, 1) && p1
&& p2
)
3150 const int r
= strncmp (p1
, p2
, tree_low_cst (arg3
, 1));
3151 return (r
< 0 ? constm1_rtx
: (r
> 0 ? const1_rtx
: const0_rtx
));
3154 /* If len == 1 or (either string parameter is "" and (len >= 1)),
3155 return (*(const u_char*)arg1 - *(const u_char*)arg2). */
3156 if (host_integerp (arg3
, 1)
3157 && (tree_low_cst (arg3
, 1) == 1
3158 || (tree_low_cst (arg3
, 1) > 1
3159 && ((p1
&& *p1
== '\0') || (p2
&& *p2
== '\0')))))
3161 tree cst_uchar_node
= build_type_variant (unsigned_char_type_node
, 1, 0);
3162 tree cst_uchar_ptr_node
= build_pointer_type (cst_uchar_node
);
3164 fold (build1 (CONVERT_EXPR
, integer_type_node
,
3165 build1 (INDIRECT_REF
, cst_uchar_node
,
3166 build1 (NOP_EXPR
, cst_uchar_ptr_node
, arg1
))));
3168 fold (build1 (CONVERT_EXPR
, integer_type_node
,
3169 build1 (INDIRECT_REF
, cst_uchar_node
,
3170 build1 (NOP_EXPR
, cst_uchar_ptr_node
, arg2
))));
3171 tree result
= fold (build (MINUS_EXPR
, integer_type_node
, ind1
, ind2
));
3172 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
3175 /* If c_strlen can determine an expression for one of the string
3176 lengths, and it doesn't have side effects, then emit cmpstrsi
3177 using length MIN(strlen(string)+1, arg3). */
3178 #ifdef HAVE_cmpstrsi
3181 tree len
, len1
, len2
;
3182 rtx arg1_rtx
, arg2_rtx
, arg3_rtx
;
3186 = get_pointer_alignment (arg1
, BIGGEST_ALIGNMENT
) / BITS_PER_UNIT
;
3188 = get_pointer_alignment (arg2
, BIGGEST_ALIGNMENT
) / BITS_PER_UNIT
;
3189 enum machine_mode insn_mode
3190 = insn_data
[(int) CODE_FOR_cmpstrsi
].operand
[0].mode
;
3192 len1
= c_strlen (arg1
);
3193 len2
= c_strlen (arg2
);
3196 len1
= size_binop (PLUS_EXPR
, ssize_int (1), len1
);
3198 len2
= size_binop (PLUS_EXPR
, ssize_int (1), len2
);
3200 /* If we don't have a constant length for the first, use the length
3201 of the second, if we know it. We don't require a constant for
3202 this case; some cost analysis could be done if both are available
3203 but neither is constant. For now, assume they're equally cheap,
3204 unless one has side effects. If both strings have constant lengths,
3211 else if (TREE_SIDE_EFFECTS (len1
))
3213 else if (TREE_SIDE_EFFECTS (len2
))
3215 else if (TREE_CODE (len1
) != INTEGER_CST
)
3217 else if (TREE_CODE (len2
) != INTEGER_CST
)
3219 else if (tree_int_cst_lt (len1
, len2
))
3224 /* If both arguments have side effects, we cannot optimize. */
3225 if (!len
|| TREE_SIDE_EFFECTS (len
))
3228 /* The actual new length parameter is MIN(len,arg3). */
3229 len
= fold (build (MIN_EXPR
, TREE_TYPE (len
), len
, arg3
));
3231 /* If we don't have POINTER_TYPE, call the function. */
3232 if (arg1_align
== 0 || arg2_align
== 0)
3235 /* Make a place to write the result of the instruction. */
3238 && GET_CODE (result
) == REG
&& GET_MODE (result
) == insn_mode
3239 && REGNO (result
) >= FIRST_PSEUDO_REGISTER
))
3240 result
= gen_reg_rtx (insn_mode
);
3242 arg1_rtx
= get_memory_rtx (arg1
);
3243 arg2_rtx
= get_memory_rtx (arg2
);
3244 arg3_rtx
= expand_expr (len
, NULL_RTX
, VOIDmode
, 0);
3245 insn
= gen_cmpstrsi (result
, arg1_rtx
, arg2_rtx
, arg3_rtx
,
3246 GEN_INT (MIN (arg1_align
, arg2_align
)));
3252 /* Return the value in the proper mode for this function. */
3253 mode
= TYPE_MODE (TREE_TYPE (exp
));
3254 if (GET_MODE (result
) == mode
)
3257 return convert_to_mode (mode
, result
, 0);
3258 convert_move (target
, result
, 0);
3265 /* Expand expression EXP, which is a call to the strcat builtin.
3266 Return 0 if we failed the caller should emit a normal call,
3267 otherwise try to get the result in TARGET, if convenient. */
3270 expand_builtin_strcat (tree arglist
, rtx target
, enum machine_mode mode
)
3272 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
3276 tree dst
= TREE_VALUE (arglist
),
3277 src
= TREE_VALUE (TREE_CHAIN (arglist
));
3278 const char *p
= c_getstr (src
);
3280 /* If the string length is zero, return the dst parameter. */
3281 if (p
&& *p
== '\0')
3282 return expand_expr (dst
, target
, mode
, EXPAND_NORMAL
);
3288 /* Expand expression EXP, which is a call to the strncat builtin.
3289 Return 0 if we failed the caller should emit a normal call,
3290 otherwise try to get the result in TARGET, if convenient. */
3293 expand_builtin_strncat (tree arglist
, rtx target
, enum machine_mode mode
)
3295 if (!validate_arglist (arglist
,
3296 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
3300 tree dst
= TREE_VALUE (arglist
),
3301 src
= TREE_VALUE (TREE_CHAIN (arglist
)),
3302 len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
3303 const char *p
= c_getstr (src
);
3305 /* If the requested length is zero, or the src parameter string
3306 length is zero, return the dst parameter. */
3307 if (integer_zerop (len
) || (p
&& *p
== '\0'))
3309 /* Evaluate and ignore the src and len parameters in case
3310 they have side-effects. */
3311 expand_expr (src
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
3312 expand_expr (len
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
3313 return expand_expr (dst
, target
, mode
, EXPAND_NORMAL
);
3316 /* If the requested len is greater than or equal to the string
3317 length, call strcat. */
3318 if (TREE_CODE (len
) == INTEGER_CST
&& p
3319 && compare_tree_int (len
, strlen (p
)) >= 0)
3322 = tree_cons (NULL_TREE
, dst
, build_tree_list (NULL_TREE
, src
));
3323 tree fn
= implicit_built_in_decls
[BUILT_IN_STRCAT
];
3325 /* If the replacement _DECL isn't initialized, don't do the
3330 return expand_expr (build_function_call_expr (fn
, newarglist
),
3331 target
, mode
, EXPAND_NORMAL
);
3337 /* Expand expression EXP, which is a call to the strspn builtin.
3338 Return 0 if we failed the caller should emit a normal call,
3339 otherwise try to get the result in TARGET, if convenient. */
3342 expand_builtin_strspn (tree arglist
, rtx target
, enum machine_mode mode
)
3344 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
3348 tree s1
= TREE_VALUE (arglist
), s2
= TREE_VALUE (TREE_CHAIN (arglist
));
3349 const char *p1
= c_getstr (s1
), *p2
= c_getstr (s2
);
3351 /* If both arguments are constants, evaluate at compile-time. */
3354 const size_t r
= strspn (p1
, p2
);
3355 return expand_expr (size_int (r
), target
, mode
, EXPAND_NORMAL
);
3358 /* If either argument is "", return 0. */
3359 if ((p1
&& *p1
== '\0') || (p2
&& *p2
== '\0'))
3361 /* Evaluate and ignore both arguments in case either one has
3363 expand_expr (s1
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
3364 expand_expr (s2
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
3371 /* Expand expression EXP, which is a call to the strcspn builtin.
3372 Return 0 if we failed the caller should emit a normal call,
3373 otherwise try to get the result in TARGET, if convenient. */
3376 expand_builtin_strcspn (tree arglist
, rtx target
, enum machine_mode mode
)
3378 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
3382 tree s1
= TREE_VALUE (arglist
), s2
= TREE_VALUE (TREE_CHAIN (arglist
));
3383 const char *p1
= c_getstr (s1
), *p2
= c_getstr (s2
);
3385 /* If both arguments are constants, evaluate at compile-time. */
3388 const size_t r
= strcspn (p1
, p2
);
3389 return expand_expr (size_int (r
), target
, mode
, EXPAND_NORMAL
);
3392 /* If the first argument is "", return 0. */
3393 if (p1
&& *p1
== '\0')
3395 /* Evaluate and ignore argument s2 in case it has
3397 expand_expr (s2
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
3401 /* If the second argument is "", return __builtin_strlen(s1). */
3402 if (p2
&& *p2
== '\0')
3404 tree newarglist
= build_tree_list (NULL_TREE
, s1
),
3405 fn
= implicit_built_in_decls
[BUILT_IN_STRLEN
];
3407 /* If the replacement _DECL isn't initialized, don't do the
3412 return expand_expr (build_function_call_expr (fn
, newarglist
),
3413 target
, mode
, EXPAND_NORMAL
);
3419 /* Expand a call to __builtin_saveregs, generating the result in TARGET,
3420 if that's convenient. */
3423 expand_builtin_saveregs (void)
3427 /* Don't do __builtin_saveregs more than once in a function.
3428 Save the result of the first call and reuse it. */
3429 if (saveregs_value
!= 0)
3430 return saveregs_value
;
3432 /* When this function is called, it means that registers must be
3433 saved on entry to this function. So we migrate the call to the
3434 first insn of this function. */
3438 #ifdef EXPAND_BUILTIN_SAVEREGS
3439 /* Do whatever the machine needs done in this case. */
3440 val
= EXPAND_BUILTIN_SAVEREGS ();
3442 /* ??? We used to try and build up a call to the out of line function,
3443 guessing about what registers needed saving etc. This became much
3444 harder with __builtin_va_start, since we don't have a tree for a
3445 call to __builtin_saveregs to fall back on. There was exactly one
3446 port (i860) that used this code, and I'm unconvinced it could actually
3447 handle the general case. So we no longer try to handle anything
3448 weird and make the backend absorb the evil. */
3450 error ("__builtin_saveregs not supported by this target");
3457 saveregs_value
= val
;
3459 /* Put the insns after the NOTE that starts the function. If this
3460 is inside a start_sequence, make the outer-level insn chain current, so
3461 the code is placed at the start of the function. */
3462 push_topmost_sequence ();
3463 emit_insn_after (seq
, get_insns ());
3464 pop_topmost_sequence ();
3469 /* __builtin_args_info (N) returns word N of the arg space info
3470 for the current function. The number and meanings of words
3471 is controlled by the definition of CUMULATIVE_ARGS. */
3474 expand_builtin_args_info (tree arglist
)
3476 int nwords
= sizeof (CUMULATIVE_ARGS
) / sizeof (int);
3477 int *word_ptr
= (int *) ¤t_function_args_info
;
3479 if (sizeof (CUMULATIVE_ARGS
) % sizeof (int) != 0)
3484 if (!host_integerp (TREE_VALUE (arglist
), 0))
3485 error ("argument of `__builtin_args_info' must be constant");
3488 HOST_WIDE_INT wordnum
= tree_low_cst (TREE_VALUE (arglist
), 0);
3490 if (wordnum
< 0 || wordnum
>= nwords
)
3491 error ("argument of `__builtin_args_info' out of range");
3493 return GEN_INT (word_ptr
[wordnum
]);
3497 error ("missing argument in `__builtin_args_info'");
3502 /* Expand ARGLIST, from a call to __builtin_next_arg. */
3505 expand_builtin_next_arg (tree arglist
)
3507 tree fntype
= TREE_TYPE (current_function_decl
);
3509 if (TYPE_ARG_TYPES (fntype
) == 0
3510 || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype
)))
3513 error ("`va_start' used in function with fixed args");
3519 tree last_parm
= tree_last (DECL_ARGUMENTS (current_function_decl
));
3520 tree arg
= TREE_VALUE (arglist
);
3522 /* Strip off all nops for the sake of the comparison. This
3523 is not quite the same as STRIP_NOPS. It does more.
3524 We must also strip off INDIRECT_EXPR for C++ reference
3526 while (TREE_CODE (arg
) == NOP_EXPR
3527 || TREE_CODE (arg
) == CONVERT_EXPR
3528 || TREE_CODE (arg
) == NON_LVALUE_EXPR
3529 || TREE_CODE (arg
) == INDIRECT_REF
)
3530 arg
= TREE_OPERAND (arg
, 0);
3531 if (arg
!= last_parm
)
3532 warning ("second parameter of `va_start' not last named argument");
3535 /* Evidently an out of date version of <stdarg.h>; can't validate
3536 va_start's second argument, but can still work as intended. */
3537 warning ("`__builtin_next_arg' called without an argument");
3539 return expand_binop (Pmode
, add_optab
,
3540 current_function_internal_arg_pointer
,
3541 current_function_arg_offset_rtx
,
3542 NULL_RTX
, 0, OPTAB_LIB_WIDEN
);
3545 /* Make it easier for the backends by protecting the valist argument
3546 from multiple evaluations. */
3549 stabilize_va_list (tree valist
, int needs_lvalue
)
3551 if (TREE_CODE (va_list_type_node
) == ARRAY_TYPE
)
3553 if (TREE_SIDE_EFFECTS (valist
))
3554 valist
= save_expr (valist
);
3556 /* For this case, the backends will be expecting a pointer to
3557 TREE_TYPE (va_list_type_node), but it's possible we've
3558 actually been given an array (an actual va_list_type_node).
3560 if (TREE_CODE (TREE_TYPE (valist
)) == ARRAY_TYPE
)
3562 tree p1
= build_pointer_type (TREE_TYPE (va_list_type_node
));
3563 tree p2
= build_pointer_type (va_list_type_node
);
3565 valist
= build1 (ADDR_EXPR
, p2
, valist
);
3566 valist
= fold (build1 (NOP_EXPR
, p1
, valist
));
3575 if (! TREE_SIDE_EFFECTS (valist
))
3578 pt
= build_pointer_type (va_list_type_node
);
3579 valist
= fold (build1 (ADDR_EXPR
, pt
, valist
));
3580 TREE_SIDE_EFFECTS (valist
) = 1;
3583 if (TREE_SIDE_EFFECTS (valist
))
3584 valist
= save_expr (valist
);
3585 valist
= fold (build1 (INDIRECT_REF
, TREE_TYPE (TREE_TYPE (valist
)),
3592 /* The "standard" implementation of va_start: just assign `nextarg' to
3596 std_expand_builtin_va_start (tree valist
, rtx nextarg
)
3600 t
= build (MODIFY_EXPR
, TREE_TYPE (valist
), valist
,
3601 make_tree (ptr_type_node
, nextarg
));
3602 TREE_SIDE_EFFECTS (t
) = 1;
3604 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
3607 /* Expand ARGLIST, from a call to __builtin_va_start. */
3610 expand_builtin_va_start (tree arglist
)
3615 chain
= TREE_CHAIN (arglist
);
3617 if (TREE_CHAIN (chain
))
3618 error ("too many arguments to function `va_start'");
3620 nextarg
= expand_builtin_next_arg (chain
);
3621 valist
= stabilize_va_list (TREE_VALUE (arglist
), 1);
3623 #ifdef EXPAND_BUILTIN_VA_START
3624 EXPAND_BUILTIN_VA_START (valist
, nextarg
);
3626 std_expand_builtin_va_start (valist
, nextarg
);
3632 /* The "standard" implementation of va_arg: read the value from the
3633 current (padded) address and increment by the (padded) size. */
3636 std_expand_builtin_va_arg (tree valist
, tree type
)
3638 tree addr_tree
, t
, type_size
= NULL
;
3639 tree align
, alignm1
;
3643 /* Compute the rounded size of the type. */
3644 align
= size_int (PARM_BOUNDARY
/ BITS_PER_UNIT
);
3645 alignm1
= size_int (PARM_BOUNDARY
/ BITS_PER_UNIT
- 1);
3646 if (type
== error_mark_node
3647 || (type_size
= TYPE_SIZE_UNIT (TYPE_MAIN_VARIANT (type
))) == NULL
3648 || TREE_OVERFLOW (type_size
))
3649 rounded_size
= size_zero_node
;
3651 rounded_size
= fold (build (MULT_EXPR
, sizetype
,
3652 fold (build (TRUNC_DIV_EXPR
, sizetype
,
3653 fold (build (PLUS_EXPR
, sizetype
,
3654 type_size
, alignm1
)),
3660 if (PAD_VARARGS_DOWN
&& ! integer_zerop (rounded_size
))
3662 /* Small args are padded downward. */
3663 addr_tree
= fold (build (PLUS_EXPR
, TREE_TYPE (addr_tree
), addr_tree
,
3664 fold (build (COND_EXPR
, sizetype
,
3665 fold (build (GT_EXPR
, sizetype
,
3669 fold (build (MINUS_EXPR
, sizetype
,
3674 addr
= expand_expr (addr_tree
, NULL_RTX
, Pmode
, EXPAND_NORMAL
);
3675 addr
= copy_to_reg (addr
);
3677 /* Compute new value for AP. */
3678 if (! integer_zerop (rounded_size
))
3680 t
= build (MODIFY_EXPR
, TREE_TYPE (valist
), valist
,
3681 build (PLUS_EXPR
, TREE_TYPE (valist
), valist
,
3683 TREE_SIDE_EFFECTS (t
) = 1;
3684 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
3690 /* Expand __builtin_va_arg, which is not really a builtin function, but
3691 a very special sort of operator. */
3694 expand_builtin_va_arg (tree valist
, tree type
)
3697 tree promoted_type
, want_va_type
, have_va_type
;
3699 /* Verify that valist is of the proper type. */
3701 want_va_type
= va_list_type_node
;
3702 have_va_type
= TREE_TYPE (valist
);
3703 if (TREE_CODE (want_va_type
) == ARRAY_TYPE
)
3705 /* If va_list is an array type, the argument may have decayed
3706 to a pointer type, e.g. by being passed to another function.
3707 In that case, unwrap both types so that we can compare the
3708 underlying records. */
3709 if (TREE_CODE (have_va_type
) == ARRAY_TYPE
3710 || TREE_CODE (have_va_type
) == POINTER_TYPE
)
3712 want_va_type
= TREE_TYPE (want_va_type
);
3713 have_va_type
= TREE_TYPE (have_va_type
);
3716 if (TYPE_MAIN_VARIANT (want_va_type
) != TYPE_MAIN_VARIANT (have_va_type
))
3718 error ("first argument to `va_arg' not of type `va_list'");
3722 /* Generate a diagnostic for requesting data of a type that cannot
3723 be passed through `...' due to type promotion at the call site. */
3724 else if ((promoted_type
= (*lang_hooks
.types
.type_promotes_to
) (type
))
3727 const char *name
= "<anonymous type>", *pname
= 0;
3728 static bool gave_help
;
3730 if (TYPE_NAME (type
))
3732 if (TREE_CODE (TYPE_NAME (type
)) == IDENTIFIER_NODE
)
3733 name
= IDENTIFIER_POINTER (TYPE_NAME (type
));
3734 else if (TREE_CODE (TYPE_NAME (type
)) == TYPE_DECL
3735 && DECL_NAME (TYPE_NAME (type
)))
3736 name
= IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type
)));
3738 if (TYPE_NAME (promoted_type
))
3740 if (TREE_CODE (TYPE_NAME (promoted_type
)) == IDENTIFIER_NODE
)
3741 pname
= IDENTIFIER_POINTER (TYPE_NAME (promoted_type
));
3742 else if (TREE_CODE (TYPE_NAME (promoted_type
)) == TYPE_DECL
3743 && DECL_NAME (TYPE_NAME (promoted_type
)))
3744 pname
= IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (promoted_type
)));
3747 /* Unfortunately, this is merely undefined, rather than a constraint
3748 violation, so we cannot make this an error. If this call is never
3749 executed, the program is still strictly conforming. */
3750 warning ("`%s' is promoted to `%s' when passed through `...'",
3755 warning ("(so you should pass `%s' not `%s' to `va_arg')",
3759 /* We can, however, treat "undefined" any way we please.
3760 Call abort to encourage the user to fix the program. */
3761 expand_builtin_trap ();
3763 /* This is dead code, but go ahead and finish so that the
3764 mode of the result comes out right. */
3769 /* Make it easier for the backends by protecting the valist argument
3770 from multiple evaluations. */
3771 valist
= stabilize_va_list (valist
, 0);
3773 #ifdef EXPAND_BUILTIN_VA_ARG
3774 addr
= EXPAND_BUILTIN_VA_ARG (valist
, type
);
3776 addr
= std_expand_builtin_va_arg (valist
, type
);
3780 #ifdef POINTERS_EXTEND_UNSIGNED
3781 if (GET_MODE (addr
) != Pmode
)
3782 addr
= convert_memory_address (Pmode
, addr
);
3785 result
= gen_rtx_MEM (TYPE_MODE (type
), addr
);
3786 set_mem_alias_set (result
, get_varargs_alias_set ());
3791 /* Expand ARGLIST, from a call to __builtin_va_end. */
3794 expand_builtin_va_end (tree arglist
)
3796 tree valist
= TREE_VALUE (arglist
);
3798 #ifdef EXPAND_BUILTIN_VA_END
3799 valist
= stabilize_va_list (valist
, 0);
3800 EXPAND_BUILTIN_VA_END (arglist
);
3802 /* Evaluate for side effects, if needed. I hate macros that don't
3804 if (TREE_SIDE_EFFECTS (valist
))
3805 expand_expr (valist
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
3811 /* Expand ARGLIST, from a call to __builtin_va_copy. We do this as a
3812 builtin rather than just as an assignment in stdarg.h because of the
3813 nastiness of array-type va_list types. */
3816 expand_builtin_va_copy (tree arglist
)
3820 dst
= TREE_VALUE (arglist
);
3821 src
= TREE_VALUE (TREE_CHAIN (arglist
));
3823 dst
= stabilize_va_list (dst
, 1);
3824 src
= stabilize_va_list (src
, 0);
3826 if (TREE_CODE (va_list_type_node
) != ARRAY_TYPE
)
3828 t
= build (MODIFY_EXPR
, va_list_type_node
, dst
, src
);
3829 TREE_SIDE_EFFECTS (t
) = 1;
3830 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
3834 rtx dstb
, srcb
, size
;
3836 /* Evaluate to pointers. */
3837 dstb
= expand_expr (dst
, NULL_RTX
, Pmode
, EXPAND_NORMAL
);
3838 srcb
= expand_expr (src
, NULL_RTX
, Pmode
, EXPAND_NORMAL
);
3839 size
= expand_expr (TYPE_SIZE_UNIT (va_list_type_node
), NULL_RTX
,
3840 VOIDmode
, EXPAND_NORMAL
);
3842 #ifdef POINTERS_EXTEND_UNSIGNED
3843 if (GET_MODE (dstb
) != Pmode
)
3844 dstb
= convert_memory_address (Pmode
, dstb
);
3846 if (GET_MODE (srcb
) != Pmode
)
3847 srcb
= convert_memory_address (Pmode
, srcb
);
3850 /* "Dereference" to BLKmode memories. */
3851 dstb
= gen_rtx_MEM (BLKmode
, dstb
);
3852 set_mem_alias_set (dstb
, get_alias_set (TREE_TYPE (TREE_TYPE (dst
))));
3853 set_mem_align (dstb
, TYPE_ALIGN (va_list_type_node
));
3854 srcb
= gen_rtx_MEM (BLKmode
, srcb
);
3855 set_mem_alias_set (srcb
, get_alias_set (TREE_TYPE (TREE_TYPE (src
))));
3856 set_mem_align (srcb
, TYPE_ALIGN (va_list_type_node
));
3859 emit_block_move (dstb
, srcb
, size
, BLOCK_OP_NORMAL
);
3865 /* Expand a call to one of the builtin functions __builtin_frame_address or
3866 __builtin_return_address. */
3869 expand_builtin_frame_address (tree fndecl
, tree arglist
)
3871 /* The argument must be a nonnegative integer constant.
3872 It counts the number of frames to scan up the stack.
3873 The value is the return address saved in that frame. */
3875 /* Warning about missing arg was already issued. */
3877 else if (! host_integerp (TREE_VALUE (arglist
), 1))
3879 if (DECL_FUNCTION_CODE (fndecl
) == BUILT_IN_FRAME_ADDRESS
)
3880 error ("invalid arg to `__builtin_frame_address'");
3882 error ("invalid arg to `__builtin_return_address'");
3888 = expand_builtin_return_addr (DECL_FUNCTION_CODE (fndecl
),
3889 tree_low_cst (TREE_VALUE (arglist
), 1),
3890 hard_frame_pointer_rtx
);
3892 /* Some ports cannot access arbitrary stack frames. */
3895 if (DECL_FUNCTION_CODE (fndecl
) == BUILT_IN_FRAME_ADDRESS
)
3896 warning ("unsupported arg to `__builtin_frame_address'");
3898 warning ("unsupported arg to `__builtin_return_address'");
3902 /* For __builtin_frame_address, return what we've got. */
3903 if (DECL_FUNCTION_CODE (fndecl
) == BUILT_IN_FRAME_ADDRESS
)
3906 if (GET_CODE (tem
) != REG
3907 && ! CONSTANT_P (tem
))
3908 tem
= copy_to_mode_reg (Pmode
, tem
);
3913 /* Expand a call to the alloca builtin, with arguments ARGLIST. Return 0 if
3914 we failed and the caller should emit a normal call, otherwise try to get
3915 the result in TARGET, if convenient. */
3918 expand_builtin_alloca (tree arglist
, rtx target
)
3923 if (!validate_arglist (arglist
, INTEGER_TYPE
, VOID_TYPE
))
3926 /* Compute the argument. */
3927 op0
= expand_expr (TREE_VALUE (arglist
), NULL_RTX
, VOIDmode
, 0);
3929 /* Allocate the desired space. */
3930 result
= allocate_dynamic_stack_space (op0
, target
, BITS_PER_UNIT
);
3932 #ifdef POINTERS_EXTEND_UNSIGNED
3933 if (GET_MODE (result
) != ptr_mode
)
3934 result
= convert_memory_address (ptr_mode
, result
);
3940 /* Expand a call to a unary builtin. The arguments are in ARGLIST.
3941 Return 0 if a normal call should be emitted rather than expanding the
3942 function in-line. If convenient, the result should be placed in TARGET.
3943 SUBTARGET may be used as the target for computing one of EXP's operands. */
3946 expand_builtin_unop (enum machine_mode target_mode
, tree arglist
, rtx target
,
3947 rtx subtarget
, optab op_optab
)
3950 if (!validate_arglist (arglist
, INTEGER_TYPE
, VOID_TYPE
))
3953 /* Compute the argument. */
3954 op0
= expand_expr (TREE_VALUE (arglist
), subtarget
, VOIDmode
, 0);
3955 /* Compute op, into TARGET if possible.
3956 Set TARGET to wherever the result comes back. */
3957 target
= expand_unop (TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist
))),
3958 op_optab
, op0
, target
, 1);
3962 return convert_to_mode (target_mode
, target
, 0);
3965 /* If the string passed to fputs is a constant and is one character
3966 long, we attempt to transform this call into __builtin_fputc(). */
3969 expand_builtin_fputs (tree arglist
, int ignore
, int unlocked
)
3972 tree fn_fputc
= unlocked
? implicit_built_in_decls
[BUILT_IN_FPUTC_UNLOCKED
]
3973 : implicit_built_in_decls
[BUILT_IN_FPUTC
];
3974 tree fn_fwrite
= unlocked
? implicit_built_in_decls
[BUILT_IN_FWRITE_UNLOCKED
]
3975 : implicit_built_in_decls
[BUILT_IN_FWRITE
];
3977 /* If the return value is used, or the replacement _DECL isn't
3978 initialized, don't do the transformation. */
3979 if (!ignore
|| !fn_fputc
|| !fn_fwrite
)
3982 /* Verify the arguments in the original call. */
3983 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
3986 /* Get the length of the string passed to fputs. If the length
3987 can't be determined, punt. */
3988 if (!(len
= c_strlen (TREE_VALUE (arglist
)))
3989 || TREE_CODE (len
) != INTEGER_CST
)
3992 switch (compare_tree_int (len
, 1))
3994 case -1: /* length is 0, delete the call entirely . */
3996 /* Evaluate and ignore the argument in case it has
3998 expand_expr (TREE_VALUE (TREE_CHAIN (arglist
)), const0_rtx
,
3999 VOIDmode
, EXPAND_NORMAL
);
4002 case 0: /* length is 1, call fputc. */
4004 const char *p
= c_getstr (TREE_VALUE (arglist
));
4008 /* New argument list transforming fputs(string, stream) to
4009 fputc(string[0], stream). */
4011 build_tree_list (NULL_TREE
, TREE_VALUE (TREE_CHAIN (arglist
)));
4013 tree_cons (NULL_TREE
, build_int_2 (p
[0], 0), arglist
);
4019 case 1: /* length is greater than 1, call fwrite. */
4023 /* If optimizing for size keep fputs. */
4026 string_arg
= TREE_VALUE (arglist
);
4027 /* New argument list transforming fputs(string, stream) to
4028 fwrite(string, 1, len, stream). */
4029 arglist
= build_tree_list (NULL_TREE
, TREE_VALUE (TREE_CHAIN (arglist
)));
4030 arglist
= tree_cons (NULL_TREE
, len
, arglist
);
4031 arglist
= tree_cons (NULL_TREE
, size_one_node
, arglist
);
4032 arglist
= tree_cons (NULL_TREE
, string_arg
, arglist
);
4040 return expand_expr (build_function_call_expr (fn
, arglist
),
4041 (ignore
? const0_rtx
: NULL_RTX
),
4042 VOIDmode
, EXPAND_NORMAL
);
4045 /* Expand a call to __builtin_expect. We return our argument and emit a
4046 NOTE_INSN_EXPECTED_VALUE note. This is the expansion of __builtin_expect in
4047 a non-jump context. */
4050 expand_builtin_expect (tree arglist
, rtx target
)
4055 if (arglist
== NULL_TREE
4056 || TREE_CHAIN (arglist
) == NULL_TREE
)
4058 exp
= TREE_VALUE (arglist
);
4059 c
= TREE_VALUE (TREE_CHAIN (arglist
));
4061 if (TREE_CODE (c
) != INTEGER_CST
)
4063 error ("second arg to `__builtin_expect' must be a constant");
4064 c
= integer_zero_node
;
4067 target
= expand_expr (exp
, target
, VOIDmode
, EXPAND_NORMAL
);
4069 /* Don't bother with expected value notes for integral constants. */
4070 if (flag_guess_branch_prob
&& GET_CODE (target
) != CONST_INT
)
4072 /* We do need to force this into a register so that we can be
4073 moderately sure to be able to correctly interpret the branch
4075 target
= force_reg (GET_MODE (target
), target
);
4077 rtx_c
= expand_expr (c
, NULL_RTX
, GET_MODE (target
), EXPAND_NORMAL
);
4079 note
= emit_note (NULL
, NOTE_INSN_EXPECTED_VALUE
);
4080 NOTE_EXPECTED_VALUE (note
) = gen_rtx_EQ (VOIDmode
, target
, rtx_c
);
4086 /* Like expand_builtin_expect, except do this in a jump context. This is
4087 called from do_jump if the conditional is a __builtin_expect. Return either
4088 a list of insns to emit the jump or NULL if we cannot optimize
4089 __builtin_expect. We need to optimize this at jump time so that machines
4090 like the PowerPC don't turn the test into a SCC operation, and then jump
4091 based on the test being 0/1. */
4094 expand_builtin_expect_jump (tree exp
, rtx if_false_label
, rtx if_true_label
)
4096 tree arglist
= TREE_OPERAND (exp
, 1);
4097 tree arg0
= TREE_VALUE (arglist
);
4098 tree arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
4101 /* Only handle __builtin_expect (test, 0) and
4102 __builtin_expect (test, 1). */
4103 if (TREE_CODE (TREE_TYPE (arg1
)) == INTEGER_TYPE
4104 && (integer_zerop (arg1
) || integer_onep (arg1
)))
4109 /* If we fail to locate an appropriate conditional jump, we'll
4110 fall back to normal evaluation. Ensure that the expression
4111 can be re-evaluated. */
4112 switch (unsafe_for_reeval (arg0
))
4117 case 1: /* Mildly unsafe. */
4118 arg0
= unsave_expr (arg0
);
4121 case 2: /* Wildly unsafe. */
4125 /* Expand the jump insns. */
4127 do_jump (arg0
, if_false_label
, if_true_label
);
4131 /* Now that the __builtin_expect has been validated, go through and add
4132 the expect's to each of the conditional jumps. If we run into an
4133 error, just give up and generate the 'safe' code of doing a SCC
4134 operation and then doing a branch on that. */
4136 while (insn
!= NULL_RTX
)
4138 rtx next
= NEXT_INSN (insn
);
4140 if (GET_CODE (insn
) == JUMP_INSN
&& any_condjump_p (insn
))
4142 rtx ifelse
= SET_SRC (pc_set (insn
));
4146 if (GET_CODE (XEXP (ifelse
, 1)) == LABEL_REF
)
4149 label
= XEXP (XEXP (ifelse
, 1), 0);
4151 /* An inverted jump reverses the probabilities. */
4152 else if (GET_CODE (XEXP (ifelse
, 2)) == LABEL_REF
)
4155 label
= XEXP (XEXP (ifelse
, 2), 0);
4157 /* We shouldn't have to worry about conditional returns during
4158 the expansion stage, but handle it gracefully anyway. */
4159 else if (GET_CODE (XEXP (ifelse
, 1)) == RETURN
)
4164 /* An inverted return reverses the probabilities. */
4165 else if (GET_CODE (XEXP (ifelse
, 2)) == RETURN
)
4173 /* If the test is expected to fail, reverse the
4175 if (integer_zerop (arg1
))
4178 /* If we are jumping to the false label, reverse the
4180 if (label
== NULL_RTX
)
4181 ; /* conditional return */
4182 else if (label
== if_false_label
)
4184 else if (label
!= if_true_label
)
4188 predict_insn_def (insn
, PRED_BUILTIN_EXPECT
, taken
);
4195 /* If no jumps were modified, fail and do __builtin_expect the normal
4205 expand_builtin_trap (void)
4209 emit_insn (gen_trap ());
4212 emit_library_call (abort_libfunc
, LCT_NORETURN
, VOIDmode
, 0);
4216 /* Expand a call to fabs, fabsf or fabsl with arguments ARGLIST.
4217 Return 0 if a normal call should be emitted rather than expanding
4218 the function inline. If convenient, the result should be placed
4219 in TARGET. SUBTARGET may be used as the target for computing
4223 expand_builtin_fabs (tree arglist
, rtx target
, rtx subtarget
)
4225 enum machine_mode mode
;
4229 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
4232 arg
= TREE_VALUE (arglist
);
4233 mode
= TYPE_MODE (TREE_TYPE (arg
));
4234 op0
= expand_expr (arg
, subtarget
, VOIDmode
, 0);
4235 return expand_abs (mode
, op0
, target
, 0, safe_from_p (target
, arg
, 1));
4238 /* Expand a call to cabs, cabsf or cabsl with arguments ARGLIST.
4239 Return 0 if a normal call should be emitted rather than expanding
4240 the function inline. If convenient, the result should be placed
4244 expand_builtin_cabs (tree arglist
, rtx target
)
4246 enum machine_mode mode
;
4250 if (arglist
== 0 || TREE_CHAIN (arglist
))
4252 arg
= TREE_VALUE (arglist
);
4253 if (TREE_CODE (TREE_TYPE (arg
)) != COMPLEX_TYPE
4254 || TREE_CODE (TREE_TYPE (TREE_TYPE (arg
))) != REAL_TYPE
)
4257 mode
= TYPE_MODE (TREE_TYPE (arg
));
4258 op0
= expand_expr (arg
, NULL_RTX
, VOIDmode
, 0);
4259 return expand_complex_abs (mode
, op0
, target
, 0);
4263 /* Expand an expression EXP that calls a built-in function,
4264 with result going to TARGET if that's convenient
4265 (and in mode MODE if that's convenient).
4266 SUBTARGET may be used as the target for computing one of EXP's operands.
4267 IGNORE is nonzero if the value is to be ignored. */
4270 expand_builtin (tree exp
, rtx target
, rtx subtarget
, enum machine_mode mode
,
4273 tree fndecl
= TREE_OPERAND (TREE_OPERAND (exp
, 0), 0);
4274 tree arglist
= TREE_OPERAND (exp
, 1);
4275 enum built_in_function fcode
= DECL_FUNCTION_CODE (fndecl
);
4276 enum machine_mode target_mode
= TYPE_MODE (TREE_TYPE (exp
));
4278 /* Perform postincrements before expanding builtin functions. Â */
4281 if (DECL_BUILT_IN_CLASS (fndecl
) == BUILT_IN_MD
)
4282 return (*targetm
.expand_builtin
) (exp
, target
, subtarget
, mode
, ignore
);
4284 /* When not optimizing, generate calls to library functions for a certain
4286 if (!optimize
&& !CALLED_AS_BUILT_IN (fndecl
))
4290 case BUILT_IN_SQRTF
:
4291 case BUILT_IN_SQRTL
:
4308 case BUILT_IN_ATANF
:
4309 case BUILT_IN_ATANL
:
4313 case BUILT_IN_ATAN2
:
4314 case BUILT_IN_ATAN2F
:
4315 case BUILT_IN_ATAN2L
:
4316 case BUILT_IN_MEMSET
:
4317 case BUILT_IN_MEMCPY
:
4318 case BUILT_IN_MEMCMP
:
4319 case BUILT_IN_MEMPCPY
:
4320 case BUILT_IN_MEMMOVE
:
4322 case BUILT_IN_BZERO
:
4323 case BUILT_IN_BCOPY
:
4324 case BUILT_IN_INDEX
:
4325 case BUILT_IN_RINDEX
:
4326 case BUILT_IN_STPCPY
:
4327 case BUILT_IN_STRCHR
:
4328 case BUILT_IN_STRRCHR
:
4329 case BUILT_IN_STRLEN
:
4330 case BUILT_IN_STRCPY
:
4331 case BUILT_IN_STRNCPY
:
4332 case BUILT_IN_STRNCMP
:
4333 case BUILT_IN_STRSTR
:
4334 case BUILT_IN_STRPBRK
:
4335 case BUILT_IN_STRCAT
:
4336 case BUILT_IN_STRNCAT
:
4337 case BUILT_IN_STRSPN
:
4338 case BUILT_IN_STRCSPN
:
4339 case BUILT_IN_STRCMP
:
4341 case BUILT_IN_PUTCHAR
:
4343 case BUILT_IN_PRINTF
:
4344 case BUILT_IN_FPUTC
:
4345 case BUILT_IN_FPUTS
:
4346 case BUILT_IN_FWRITE
:
4347 case BUILT_IN_PUTCHAR_UNLOCKED
:
4348 case BUILT_IN_PUTS_UNLOCKED
:
4349 case BUILT_IN_PRINTF_UNLOCKED
:
4350 case BUILT_IN_FPUTC_UNLOCKED
:
4351 case BUILT_IN_FPUTS_UNLOCKED
:
4352 case BUILT_IN_FWRITE_UNLOCKED
:
4353 case BUILT_IN_FLOOR
:
4354 case BUILT_IN_FLOORF
:
4355 case BUILT_IN_FLOORL
:
4357 case BUILT_IN_CEILF
:
4358 case BUILT_IN_CEILL
:
4359 case BUILT_IN_TRUNC
:
4360 case BUILT_IN_TRUNCF
:
4361 case BUILT_IN_TRUNCL
:
4362 case BUILT_IN_ROUND
:
4363 case BUILT_IN_ROUNDF
:
4364 case BUILT_IN_ROUNDL
:
4365 case BUILT_IN_NEARBYINT
:
4366 case BUILT_IN_NEARBYINTF
:
4367 case BUILT_IN_NEARBYINTL
:
4368 return expand_call (exp
, target
, ignore
);
4374 /* The built-in function expanders test for target == const0_rtx
4375 to determine whether the function's result will be ignored. */
4377 target
= const0_rtx
;
4379 /* If the result of a pure or const built-in function is ignored, and
4380 none of its arguments are volatile, we can avoid expanding the
4381 built-in call and just evaluate the arguments for side-effects. */
4382 if (target
== const0_rtx
4383 && (DECL_IS_PURE (fndecl
) || TREE_READONLY (fndecl
)))
4385 bool volatilep
= false;
4388 for (arg
= arglist
; arg
; arg
= TREE_CHAIN (arg
))
4389 if (TREE_THIS_VOLATILE (TREE_VALUE (arg
)))
4397 for (arg
= arglist
; arg
; arg
= TREE_CHAIN (arg
))
4398 expand_expr (TREE_VALUE (arg
), const0_rtx
,
4399 VOIDmode
, EXPAND_NORMAL
);
4408 case BUILT_IN_LLABS
:
4409 case BUILT_IN_IMAXABS
:
4410 /* build_function_call changes these into ABS_EXPR. */
4414 case BUILT_IN_FABSF
:
4415 case BUILT_IN_FABSL
:
4416 target
= expand_builtin_fabs (arglist
, target
, subtarget
);
4422 case BUILT_IN_CABSF
:
4423 case BUILT_IN_CABSL
:
4424 if (flag_unsafe_math_optimizations
)
4426 target
= expand_builtin_cabs (arglist
, target
);
4433 case BUILT_IN_CONJF
:
4434 case BUILT_IN_CONJL
:
4435 case BUILT_IN_CREAL
:
4436 case BUILT_IN_CREALF
:
4437 case BUILT_IN_CREALL
:
4438 case BUILT_IN_CIMAG
:
4439 case BUILT_IN_CIMAGF
:
4440 case BUILT_IN_CIMAGL
:
4441 /* expand_tree_builtin changes these into CONJ_EXPR, REALPART_EXPR
4442 and IMAGPART_EXPR. */
4461 case BUILT_IN_ATANF
:
4462 case BUILT_IN_ATANL
:
4463 /* Treat these like sqrt only if unsafe math optimizations are allowed,
4464 because of possible accuracy problems. */
4465 if (! flag_unsafe_math_optimizations
)
4468 case BUILT_IN_SQRTF
:
4469 case BUILT_IN_SQRTL
:
4470 case BUILT_IN_FLOOR
:
4471 case BUILT_IN_FLOORF
:
4472 case BUILT_IN_FLOORL
:
4474 case BUILT_IN_CEILF
:
4475 case BUILT_IN_CEILL
:
4476 case BUILT_IN_TRUNC
:
4477 case BUILT_IN_TRUNCF
:
4478 case BUILT_IN_TRUNCL
:
4479 case BUILT_IN_ROUND
:
4480 case BUILT_IN_ROUNDF
:
4481 case BUILT_IN_ROUNDL
:
4482 case BUILT_IN_NEARBYINT
:
4483 case BUILT_IN_NEARBYINTF
:
4484 case BUILT_IN_NEARBYINTL
:
4485 target
= expand_builtin_mathfn (exp
, target
, subtarget
);
4493 case BUILT_IN_ATAN2
:
4494 case BUILT_IN_ATAN2F
:
4495 case BUILT_IN_ATAN2L
:
4496 if (! flag_unsafe_math_optimizations
)
4498 target
= expand_builtin_mathfn_2 (exp
, target
, subtarget
);
4503 case BUILT_IN_APPLY_ARGS
:
4504 return expand_builtin_apply_args ();
4506 /* __builtin_apply (FUNCTION, ARGUMENTS, ARGSIZE) invokes
4507 FUNCTION with a copy of the parameters described by
4508 ARGUMENTS, and ARGSIZE. It returns a block of memory
4509 allocated on the stack into which is stored all the registers
4510 that might possibly be used for returning the result of a
4511 function. ARGUMENTS is the value returned by
4512 __builtin_apply_args. ARGSIZE is the number of bytes of
4513 arguments that must be copied. ??? How should this value be
4514 computed? We'll also need a safe worst case value for varargs
4516 case BUILT_IN_APPLY
:
4517 if (!validate_arglist (arglist
, POINTER_TYPE
,
4518 POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
)
4519 && !validate_arglist (arglist
, REFERENCE_TYPE
,
4520 POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
4528 for (t
= arglist
, i
= 0; t
; t
= TREE_CHAIN (t
), i
++)
4529 ops
[i
] = expand_expr (TREE_VALUE (t
), NULL_RTX
, VOIDmode
, 0);
4531 return expand_builtin_apply (ops
[0], ops
[1], ops
[2]);
4534 /* __builtin_return (RESULT) causes the function to return the
4535 value described by RESULT. RESULT is address of the block of
4536 memory returned by __builtin_apply. */
4537 case BUILT_IN_RETURN
:
4538 if (validate_arglist (arglist
, POINTER_TYPE
, VOID_TYPE
))
4539 expand_builtin_return (expand_expr (TREE_VALUE (arglist
),
4540 NULL_RTX
, VOIDmode
, 0));
4543 case BUILT_IN_SAVEREGS
:
4544 return expand_builtin_saveregs ();
4546 case BUILT_IN_ARGS_INFO
:
4547 return expand_builtin_args_info (arglist
);
4549 /* Return the address of the first anonymous stack arg. */
4550 case BUILT_IN_NEXT_ARG
:
4551 return expand_builtin_next_arg (arglist
);
4553 case BUILT_IN_CLASSIFY_TYPE
:
4554 return expand_builtin_classify_type (arglist
);
4556 case BUILT_IN_CONSTANT_P
:
4557 return expand_builtin_constant_p (arglist
, target_mode
);
4559 case BUILT_IN_FRAME_ADDRESS
:
4560 case BUILT_IN_RETURN_ADDRESS
:
4561 return expand_builtin_frame_address (fndecl
, arglist
);
4563 /* Returns the address of the area where the structure is returned.
4565 case BUILT_IN_AGGREGATE_INCOMING_ADDRESS
:
4567 || ! AGGREGATE_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl
)))
4568 || GET_CODE (DECL_RTL (DECL_RESULT (current_function_decl
))) != MEM
)
4571 return XEXP (DECL_RTL (DECL_RESULT (current_function_decl
)), 0);
4573 case BUILT_IN_ALLOCA
:
4574 target
= expand_builtin_alloca (arglist
, target
);
4581 case BUILT_IN_FFSLL
:
4582 target
= expand_builtin_unop (target_mode
, arglist
, target
,
4583 subtarget
, ffs_optab
);
4590 case BUILT_IN_CLZLL
:
4591 target
= expand_builtin_unop (target_mode
, arglist
, target
,
4592 subtarget
, clz_optab
);
4599 case BUILT_IN_CTZLL
:
4600 target
= expand_builtin_unop (target_mode
, arglist
, target
,
4601 subtarget
, ctz_optab
);
4606 case BUILT_IN_POPCOUNT
:
4607 case BUILT_IN_POPCOUNTL
:
4608 case BUILT_IN_POPCOUNTLL
:
4609 target
= expand_builtin_unop (target_mode
, arglist
, target
,
4610 subtarget
, popcount_optab
);
4615 case BUILT_IN_PARITY
:
4616 case BUILT_IN_PARITYL
:
4617 case BUILT_IN_PARITYLL
:
4618 target
= expand_builtin_unop (target_mode
, arglist
, target
,
4619 subtarget
, parity_optab
);
4624 case BUILT_IN_STRLEN
:
4625 target
= expand_builtin_strlen (arglist
, target
, target_mode
);
4630 case BUILT_IN_STRCPY
:
4631 target
= expand_builtin_strcpy (arglist
, target
, mode
);
4636 case BUILT_IN_STRNCPY
:
4637 target
= expand_builtin_strncpy (arglist
, target
, mode
);
4642 case BUILT_IN_STPCPY
:
4643 target
= expand_builtin_stpcpy (arglist
, target
, mode
);
4648 case BUILT_IN_STRCAT
:
4649 target
= expand_builtin_strcat (arglist
, target
, mode
);
4654 case BUILT_IN_STRNCAT
:
4655 target
= expand_builtin_strncat (arglist
, target
, mode
);
4660 case BUILT_IN_STRSPN
:
4661 target
= expand_builtin_strspn (arglist
, target
, mode
);
4666 case BUILT_IN_STRCSPN
:
4667 target
= expand_builtin_strcspn (arglist
, target
, mode
);
4672 case BUILT_IN_STRSTR
:
4673 target
= expand_builtin_strstr (arglist
, target
, mode
);
4678 case BUILT_IN_STRPBRK
:
4679 target
= expand_builtin_strpbrk (arglist
, target
, mode
);
4684 case BUILT_IN_INDEX
:
4685 case BUILT_IN_STRCHR
:
4686 target
= expand_builtin_strchr (arglist
, target
, mode
);
4691 case BUILT_IN_RINDEX
:
4692 case BUILT_IN_STRRCHR
:
4693 target
= expand_builtin_strrchr (arglist
, target
, mode
);
4698 case BUILT_IN_MEMCPY
:
4699 target
= expand_builtin_memcpy (arglist
, target
, mode
);
4704 case BUILT_IN_MEMPCPY
:
4705 target
= expand_builtin_mempcpy (arglist
, target
, mode
, /*endp=*/ 1);
4710 case BUILT_IN_MEMMOVE
:
4711 target
= expand_builtin_memmove (arglist
, target
, mode
);
4716 case BUILT_IN_BCOPY
:
4717 target
= expand_builtin_bcopy (arglist
);
4722 case BUILT_IN_MEMSET
:
4723 target
= expand_builtin_memset (arglist
, target
, mode
);
4728 case BUILT_IN_BZERO
:
4729 target
= expand_builtin_bzero (arglist
);
4734 case BUILT_IN_STRCMP
:
4735 target
= expand_builtin_strcmp (exp
, target
, mode
);
4740 case BUILT_IN_STRNCMP
:
4741 target
= expand_builtin_strncmp (exp
, target
, mode
);
4747 case BUILT_IN_MEMCMP
:
4748 target
= expand_builtin_memcmp (exp
, arglist
, target
, mode
);
4753 case BUILT_IN_SETJMP
:
4754 target
= expand_builtin_setjmp (arglist
, target
);
4759 /* __builtin_longjmp is passed a pointer to an array of five words.
4760 It's similar to the C library longjmp function but works with
4761 __builtin_setjmp above. */
4762 case BUILT_IN_LONGJMP
:
4763 if (!validate_arglist (arglist
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
4767 rtx buf_addr
= expand_expr (TREE_VALUE (arglist
), subtarget
,
4769 rtx value
= expand_expr (TREE_VALUE (TREE_CHAIN (arglist
)),
4770 NULL_RTX
, VOIDmode
, 0);
4772 if (value
!= const1_rtx
)
4774 error ("__builtin_longjmp second argument must be 1");
4778 expand_builtin_longjmp (buf_addr
, value
);
4783 expand_builtin_trap ();
4786 case BUILT_IN_FPUTS
:
4787 target
= expand_builtin_fputs (arglist
, ignore
,/*unlocked=*/ 0);
4791 case BUILT_IN_FPUTS_UNLOCKED
:
4792 target
= expand_builtin_fputs (arglist
, ignore
,/*unlocked=*/ 1);
4797 /* Various hooks for the DWARF 2 __throw routine. */
4798 case BUILT_IN_UNWIND_INIT
:
4799 expand_builtin_unwind_init ();
4801 case BUILT_IN_DWARF_CFA
:
4802 return virtual_cfa_rtx
;
4803 #ifdef DWARF2_UNWIND_INFO
4804 case BUILT_IN_DWARF_SP_COLUMN
:
4805 return expand_builtin_dwarf_sp_column ();
4806 case BUILT_IN_INIT_DWARF_REG_SIZES
:
4807 expand_builtin_init_dwarf_reg_sizes (TREE_VALUE (arglist
));
4810 case BUILT_IN_FROB_RETURN_ADDR
:
4811 return expand_builtin_frob_return_addr (TREE_VALUE (arglist
));
4812 case BUILT_IN_EXTRACT_RETURN_ADDR
:
4813 return expand_builtin_extract_return_addr (TREE_VALUE (arglist
));
4814 case BUILT_IN_EH_RETURN
:
4815 expand_builtin_eh_return (TREE_VALUE (arglist
),
4816 TREE_VALUE (TREE_CHAIN (arglist
)));
4818 #ifdef EH_RETURN_DATA_REGNO
4819 case BUILT_IN_EH_RETURN_DATA_REGNO
:
4820 return expand_builtin_eh_return_data_regno (arglist
);
4822 case BUILT_IN_VA_START
:
4823 case BUILT_IN_STDARG_START
:
4824 return expand_builtin_va_start (arglist
);
4825 case BUILT_IN_VA_END
:
4826 return expand_builtin_va_end (arglist
);
4827 case BUILT_IN_VA_COPY
:
4828 return expand_builtin_va_copy (arglist
);
4829 case BUILT_IN_EXPECT
:
4830 return expand_builtin_expect (arglist
, target
);
4831 case BUILT_IN_PREFETCH
:
4832 expand_builtin_prefetch (arglist
);
4836 default: /* just do library call, if unknown builtin */
4837 if (!DECL_ASSEMBLER_NAME_SET_P (fndecl
))
4838 error ("built-in function `%s' not currently supported",
4839 IDENTIFIER_POINTER (DECL_NAME (fndecl
)));
4842 /* The switch statement above can drop through to cause the function
4843 to be called normally. */
4844 return expand_call (exp
, target
, ignore
);
4847 /* Determine whether a tree node represents a call to a built-in
4848 math function. If the tree T is a call to a built-in function
4849 taking a single real argument, then the return value is the
4850 DECL_FUNCTION_CODE of the call, e.g. BUILT_IN_SQRT. Otherwise
4851 the return value is END_BUILTINS. */
4853 enum built_in_function
4854 builtin_mathfn_code (tree t
)
4856 tree fndecl
, arglist
;
4858 if (TREE_CODE (t
) != CALL_EXPR
4859 || TREE_CODE (TREE_OPERAND (t
, 0)) != ADDR_EXPR
)
4860 return END_BUILTINS
;
4862 fndecl
= TREE_OPERAND (TREE_OPERAND (t
, 0), 0);
4863 if (TREE_CODE (fndecl
) != FUNCTION_DECL
4864 || ! DECL_BUILT_IN (fndecl
)
4865 || DECL_BUILT_IN_CLASS (fndecl
) == BUILT_IN_MD
)
4866 return END_BUILTINS
;
4868 arglist
= TREE_OPERAND (t
, 1);
4870 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist
))) != REAL_TYPE
)
4871 return END_BUILTINS
;
4873 arglist
= TREE_CHAIN (arglist
);
4874 switch (DECL_FUNCTION_CODE (fndecl
))
4879 case BUILT_IN_ATAN2
:
4880 case BUILT_IN_ATAN2F
:
4881 case BUILT_IN_ATAN2L
:
4883 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist
))) != REAL_TYPE
4884 || TREE_CHAIN (arglist
))
4885 return END_BUILTINS
;
4890 return END_BUILTINS
;
4894 return DECL_FUNCTION_CODE (fndecl
);
4897 /* Fold a call to __builtin_constant_p, if we know it will evaluate to a
4898 constant. ARGLIST is the argument list of the call. */
4901 fold_builtin_constant_p (tree arglist
)
4906 arglist
= TREE_VALUE (arglist
);
4908 /* We return 1 for a numeric type that's known to be a constant
4909 value at compile-time or for an aggregate type that's a
4910 literal constant. */
4911 STRIP_NOPS (arglist
);
4913 /* If we know this is a constant, emit the constant of one. */
4914 if (TREE_CODE_CLASS (TREE_CODE (arglist
)) == 'c'
4915 || (TREE_CODE (arglist
) == CONSTRUCTOR
4916 && TREE_CONSTANT (arglist
))
4917 || (TREE_CODE (arglist
) == ADDR_EXPR
4918 && TREE_CODE (TREE_OPERAND (arglist
, 0)) == STRING_CST
))
4919 return integer_one_node
;
4921 /* If we aren't going to be running CSE or this expression
4922 has side effects, show we don't know it to be a constant.
4923 Likewise if it's a pointer or aggregate type since in those
4924 case we only want literals, since those are only optimized
4925 when generating RTL, not later.
4926 And finally, if we are compiling an initializer, not code, we
4927 need to return a definite result now; there's not going to be any
4928 more optimization done. */
4929 if (TREE_SIDE_EFFECTS (arglist
) || cse_not_expected
4930 || AGGREGATE_TYPE_P (TREE_TYPE (arglist
))
4931 || POINTER_TYPE_P (TREE_TYPE (arglist
))
4933 return integer_zero_node
;
4938 /* Fold a call to __builtin_classify_type. */
4941 fold_builtin_classify_type (tree arglist
)
4944 return build_int_2 (no_type_class
, 0);
4946 return build_int_2 (type_to_class (TREE_TYPE (TREE_VALUE (arglist
))), 0);
4949 /* Fold a call to __builtin_inf or __builtin_huge_val. */
4952 fold_builtin_inf (tree type
, int warn
)
4954 REAL_VALUE_TYPE real
;
4956 if (!MODE_HAS_INFINITIES (TYPE_MODE (type
)) && warn
)
4957 warning ("target format does not support infinity");
4960 return build_real (type
, real
);
4963 /* Fold a call to __builtin_nan or __builtin_nans. */
4966 fold_builtin_nan (tree arglist
, tree type
, int quiet
)
4968 REAL_VALUE_TYPE real
;
4971 if (!validate_arglist (arglist
, POINTER_TYPE
, VOID_TYPE
))
4973 str
= c_getstr (TREE_VALUE (arglist
));
4977 if (!real_nan (&real
, str
, quiet
, TYPE_MODE (type
)))
4980 return build_real (type
, real
);
4983 /* EXP is assumed to me builtin call where truncation can be propagated
4984 across (for instance floor((double)f) == (double)floorf (f).
4985 Do the transformation. */
4987 fold_trunc_transparent_mathfn (tree exp
)
4989 tree fndecl
= TREE_OPERAND (TREE_OPERAND (exp
, 0), 0);
4990 tree arglist
= TREE_OPERAND (exp
, 1);
4991 enum built_in_function fcode
= DECL_FUNCTION_CODE (fndecl
);
4993 if (optimize
&& validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
4995 tree arg0
= strip_float_extensions (TREE_VALUE (arglist
));
4996 tree ftype
= TREE_TYPE (exp
);
4997 tree newtype
= TREE_TYPE (arg0
);
5000 if (TYPE_PRECISION (newtype
) < TYPE_PRECISION (ftype
)
5001 && (decl
= mathfn_built_in (newtype
, fcode
)))
5004 build_tree_list (NULL_TREE
, fold (convert (newtype
, arg0
)));
5005 return convert (ftype
,
5006 build_function_call_expr (decl
, arglist
));
5012 /* Fold function call to builtin cabs, cabsf or cabsl. FNDECL is the
5013 function's DECL, ARGLIST is the argument list and TYPE is the return
5014 type. Return NULL_TREE if no simplification can be made. */
5017 fold_builtin_cabs (tree fndecl
, tree arglist
, tree type
)
5021 if (!arglist
|| TREE_CHAIN (arglist
))
5024 arg
= TREE_VALUE (arglist
);
5025 if (TREE_CODE (TREE_TYPE (arg
)) != COMPLEX_TYPE
5026 || TREE_CODE (TREE_TYPE (TREE_TYPE (arg
))) != REAL_TYPE
)
5029 /* Evaluate cabs of a constant at compile-time. */
5030 if (flag_unsafe_math_optimizations
5031 && TREE_CODE (arg
) == COMPLEX_CST
5032 && TREE_CODE (TREE_REALPART (arg
)) == REAL_CST
5033 && TREE_CODE (TREE_IMAGPART (arg
)) == REAL_CST
5034 && ! TREE_CONSTANT_OVERFLOW (TREE_REALPART (arg
))
5035 && ! TREE_CONSTANT_OVERFLOW (TREE_IMAGPART (arg
)))
5037 REAL_VALUE_TYPE r
, i
;
5039 r
= TREE_REAL_CST (TREE_REALPART (arg
));
5040 i
= TREE_REAL_CST (TREE_IMAGPART (arg
));
5042 real_arithmetic (&r
, MULT_EXPR
, &r
, &r
);
5043 real_arithmetic (&i
, MULT_EXPR
, &i
, &i
);
5044 real_arithmetic (&r
, PLUS_EXPR
, &r
, &i
);
5045 if (real_sqrt (&r
, TYPE_MODE (type
), &r
)
5046 || ! flag_trapping_math
)
5047 return build_real (type
, r
);
5050 /* If either part is zero, cabs is fabs of the other. */
5051 if (TREE_CODE (arg
) == COMPLEX_EXPR
5052 && real_zerop (TREE_OPERAND (arg
, 0)))
5053 return fold (build1 (ABS_EXPR
, type
, TREE_OPERAND (arg
, 1)));
5054 if (TREE_CODE (arg
) == COMPLEX_EXPR
5055 && real_zerop (TREE_OPERAND (arg
, 1)))
5056 return fold (build1 (ABS_EXPR
, type
, TREE_OPERAND (arg
, 0)));
5058 if (flag_unsafe_math_optimizations
)
5060 enum built_in_function fcode
;
5063 fcode
= DECL_FUNCTION_CODE (fndecl
);
5064 if (fcode
== BUILT_IN_CABS
)
5065 sqrtfn
= implicit_built_in_decls
[BUILT_IN_SQRT
];
5066 else if (fcode
== BUILT_IN_CABSF
)
5067 sqrtfn
= implicit_built_in_decls
[BUILT_IN_SQRTF
];
5068 else if (fcode
== BUILT_IN_CABSL
)
5069 sqrtfn
= implicit_built_in_decls
[BUILT_IN_SQRTL
];
5073 if (sqrtfn
!= NULL_TREE
)
5075 tree rpart
, ipart
, result
, arglist
;
5077 rpart
= fold (build1 (REALPART_EXPR
, type
, arg
));
5078 ipart
= fold (build1 (IMAGPART_EXPR
, type
, arg
));
5080 rpart
= save_expr (rpart
);
5081 ipart
= save_expr (ipart
);
5083 result
= fold (build (PLUS_EXPR
, type
,
5084 fold (build (MULT_EXPR
, type
,
5086 fold (build (MULT_EXPR
, type
,
5089 arglist
= build_tree_list (NULL_TREE
, result
);
5090 return build_function_call_expr (sqrtfn
, arglist
);
5097 /* Used by constant folding to eliminate some builtin calls early. EXP is
5098 the CALL_EXPR of a call to a builtin function. */
5101 fold_builtin (tree exp
)
5103 tree fndecl
= TREE_OPERAND (TREE_OPERAND (exp
, 0), 0);
5104 tree arglist
= TREE_OPERAND (exp
, 1);
5105 tree type
= TREE_TYPE (TREE_TYPE (fndecl
));
5107 if (DECL_BUILT_IN_CLASS (fndecl
) == BUILT_IN_MD
)
5110 switch (DECL_FUNCTION_CODE (fndecl
))
5112 case BUILT_IN_CONSTANT_P
:
5113 return fold_builtin_constant_p (arglist
);
5115 case BUILT_IN_CLASSIFY_TYPE
:
5116 return fold_builtin_classify_type (arglist
);
5118 case BUILT_IN_STRLEN
:
5119 if (validate_arglist (arglist
, POINTER_TYPE
, VOID_TYPE
))
5121 tree len
= c_strlen (TREE_VALUE (arglist
));
5124 /* Convert from the internal "sizetype" type to "size_t". */
5126 len
= convert (size_type_node
, len
);
5133 case BUILT_IN_FABSF
:
5134 case BUILT_IN_FABSL
:
5135 if (validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
5136 return fold (build1 (ABS_EXPR
, type
, TREE_VALUE (arglist
)));
5140 case BUILT_IN_CABSF
:
5141 case BUILT_IN_CABSL
:
5142 return fold_builtin_cabs (fndecl
, arglist
, type
);
5145 case BUILT_IN_SQRTF
:
5146 case BUILT_IN_SQRTL
:
5147 if (validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
5149 enum built_in_function fcode
;
5150 tree arg
= TREE_VALUE (arglist
);
5152 /* Optimize sqrt of constant value. */
5153 if (TREE_CODE (arg
) == REAL_CST
5154 && ! TREE_CONSTANT_OVERFLOW (arg
))
5156 REAL_VALUE_TYPE r
, x
;
5158 x
= TREE_REAL_CST (arg
);
5159 if (real_sqrt (&r
, TYPE_MODE (type
), &x
)
5160 || (!flag_trapping_math
&& !flag_errno_math
))
5161 return build_real (type
, r
);
5164 /* Optimize sqrt(exp(x)) = exp(x*0.5). */
5165 fcode
= builtin_mathfn_code (arg
);
5166 if (flag_unsafe_math_optimizations
5167 && (fcode
== BUILT_IN_EXP
5168 || fcode
== BUILT_IN_EXPF
5169 || fcode
== BUILT_IN_EXPL
))
5171 tree expfn
= TREE_OPERAND (TREE_OPERAND (arg
, 0), 0);
5172 arg
= fold (build (MULT_EXPR
, type
,
5173 TREE_VALUE (TREE_OPERAND (arg
, 1)),
5174 build_real (type
, dconsthalf
)));
5175 arglist
= build_tree_list (NULL_TREE
, arg
);
5176 return build_function_call_expr (expfn
, arglist
);
5179 /* Optimize sqrt(pow(x,y)) = pow(x,y*0.5). */
5180 if (flag_unsafe_math_optimizations
5181 && (fcode
== BUILT_IN_POW
5182 || fcode
== BUILT_IN_POWF
5183 || fcode
== BUILT_IN_POWL
))
5185 tree powfn
= TREE_OPERAND (TREE_OPERAND (arg
, 0), 0);
5186 tree arg0
= TREE_VALUE (TREE_OPERAND (arg
, 1));
5187 tree arg1
= TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg
, 1)));
5188 tree narg1
= fold (build (MULT_EXPR
, type
, arg1
,
5189 build_real (type
, dconsthalf
)));
5190 arglist
= tree_cons (NULL_TREE
, arg0
,
5191 build_tree_list (NULL_TREE
, narg1
));
5192 return build_function_call_expr (powfn
, arglist
);
5200 if (validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
5202 tree arg
= TREE_VALUE (arglist
);
5204 /* Optimize sin(0.0) = 0.0. */
5205 if (real_zerop (arg
))
5213 if (validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
5215 tree arg
= TREE_VALUE (arglist
);
5217 /* Optimize cos(0.0) = 1.0. */
5218 if (real_zerop (arg
))
5219 return build_real (type
, dconst1
);
5221 /* Optimize cos(-x) into cos(x). */
5222 if (TREE_CODE (arg
) == NEGATE_EXPR
)
5224 tree arglist
= build_tree_list (NULL_TREE
,
5225 TREE_OPERAND (arg
, 0));
5226 return build_function_call_expr (fndecl
, arglist
);
5234 if (validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
5236 enum built_in_function fcode
;
5237 tree arg
= TREE_VALUE (arglist
);
5239 /* Optimize exp(0.0) = 1.0. */
5240 if (real_zerop (arg
))
5241 return build_real (type
, dconst1
);
5243 /* Optimize exp(1.0) = e. */
5244 if (real_onep (arg
))
5246 REAL_VALUE_TYPE cst
;
5248 if (! builtin_dconsts_init
)
5249 init_builtin_dconsts ();
5250 real_convert (&cst
, TYPE_MODE (type
), &dconste
);
5251 return build_real (type
, cst
);
5254 /* Attempt to evaluate exp at compile-time. */
5255 if (flag_unsafe_math_optimizations
5256 && TREE_CODE (arg
) == REAL_CST
5257 && ! TREE_CONSTANT_OVERFLOW (arg
))
5259 REAL_VALUE_TYPE cint
;
5263 c
= TREE_REAL_CST (arg
);
5264 n
= real_to_integer (&c
);
5265 real_from_integer (&cint
, VOIDmode
, n
,
5267 if (real_identical (&c
, &cint
))
5271 if (! builtin_dconsts_init
)
5272 init_builtin_dconsts ();
5273 real_powi (&x
, TYPE_MODE (type
), &dconste
, n
);
5274 return build_real (type
, x
);
5278 /* Optimize exp(log(x)) = x. */
5279 fcode
= builtin_mathfn_code (arg
);
5280 if (flag_unsafe_math_optimizations
5281 && (fcode
== BUILT_IN_LOG
5282 || fcode
== BUILT_IN_LOGF
5283 || fcode
== BUILT_IN_LOGL
))
5284 return TREE_VALUE (TREE_OPERAND (arg
, 1));
5291 if (validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
5293 enum built_in_function fcode
;
5294 tree arg
= TREE_VALUE (arglist
);
5296 /* Optimize log(1.0) = 0.0. */
5297 if (real_onep (arg
))
5298 return build_real (type
, dconst0
);
5300 /* Optimize log(exp(x)) = x. */
5301 fcode
= builtin_mathfn_code (arg
);
5302 if (flag_unsafe_math_optimizations
5303 && (fcode
== BUILT_IN_EXP
5304 || fcode
== BUILT_IN_EXPF
5305 || fcode
== BUILT_IN_EXPL
))
5306 return TREE_VALUE (TREE_OPERAND (arg
, 1));
5308 /* Optimize log(sqrt(x)) = log(x)*0.5. */
5309 if (flag_unsafe_math_optimizations
5310 && (fcode
== BUILT_IN_SQRT
5311 || fcode
== BUILT_IN_SQRTF
5312 || fcode
== BUILT_IN_SQRTL
))
5314 tree logfn
= build_function_call_expr (fndecl
,
5315 TREE_OPERAND (arg
, 1));
5316 return fold (build (MULT_EXPR
, type
, logfn
,
5317 build_real (type
, dconsthalf
)));
5320 /* Optimize log(pow(x,y)) = y*log(x). */
5321 if (flag_unsafe_math_optimizations
5322 && (fcode
== BUILT_IN_POW
5323 || fcode
== BUILT_IN_POWF
5324 || fcode
== BUILT_IN_POWL
))
5326 tree arg0
, arg1
, logfn
;
5328 arg0
= TREE_VALUE (TREE_OPERAND (arg
, 1));
5329 arg1
= TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg
, 1)));
5330 arglist
= build_tree_list (NULL_TREE
, arg0
);
5331 logfn
= build_function_call_expr (fndecl
, arglist
);
5332 return fold (build (MULT_EXPR
, type
, arg1
, logfn
));
5340 if (validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
5342 enum built_in_function fcode
;
5343 tree arg
= TREE_VALUE (arglist
);
5345 /* Optimize tan(0.0) = 0.0. */
5346 if (real_zerop (arg
))
5349 /* Optimize tan(atan(x)) = x. */
5350 fcode
= builtin_mathfn_code (arg
);
5351 if (flag_unsafe_math_optimizations
5352 && (fcode
== BUILT_IN_ATAN
5353 || fcode
== BUILT_IN_ATANF
5354 || fcode
== BUILT_IN_ATANL
))
5355 return TREE_VALUE (TREE_OPERAND (arg
, 1));
5360 case BUILT_IN_ATANF
:
5361 case BUILT_IN_ATANL
:
5362 if (validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
5364 tree arg
= TREE_VALUE (arglist
);
5366 /* Optimize atan(0.0) = 0.0. */
5367 if (real_zerop (arg
))
5370 /* Optimize atan(1.0) = pi/4. */
5371 if (real_onep (arg
))
5373 REAL_VALUE_TYPE cst
;
5375 if (! builtin_dconsts_init
)
5376 init_builtin_dconsts ();
5377 real_convert (&cst
, TYPE_MODE (type
), &dconstpi
);
5379 return build_real (type
, cst
);
5387 if (validate_arglist (arglist
, REAL_TYPE
, REAL_TYPE
, VOID_TYPE
))
5389 enum built_in_function fcode
;
5390 tree arg0
= TREE_VALUE (arglist
);
5391 tree arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
5393 /* Optimize pow(1.0,y) = 1.0. */
5394 if (real_onep (arg0
))
5395 return omit_one_operand (type
, build_real (type
, dconst1
), arg1
);
5397 if (TREE_CODE (arg1
) == REAL_CST
5398 && ! TREE_CONSTANT_OVERFLOW (arg1
))
5401 c
= TREE_REAL_CST (arg1
);
5403 /* Optimize pow(x,0.0) = 1.0. */
5404 if (REAL_VALUES_EQUAL (c
, dconst0
))
5405 return omit_one_operand (type
, build_real (type
, dconst1
),
5408 /* Optimize pow(x,1.0) = x. */
5409 if (REAL_VALUES_EQUAL (c
, dconst1
))
5412 /* Optimize pow(x,-1.0) = 1.0/x. */
5413 if (REAL_VALUES_EQUAL (c
, dconstm1
))
5414 return fold (build (RDIV_EXPR
, type
,
5415 build_real (type
, dconst1
),
5418 /* Optimize pow(x,2.0) = x*x. */
5419 if (REAL_VALUES_EQUAL (c
, dconst2
)
5420 && (*lang_hooks
.decls
.global_bindings_p
) () == 0
5421 && ! CONTAINS_PLACEHOLDER_P (arg0
))
5423 arg0
= save_expr (arg0
);
5424 return fold (build (MULT_EXPR
, type
, arg0
, arg0
));
5427 /* Optimize pow(x,-2.0) = 1.0/(x*x). */
5428 if (flag_unsafe_math_optimizations
5429 && REAL_VALUES_EQUAL (c
, dconstm2
)
5430 && (*lang_hooks
.decls
.global_bindings_p
) () == 0
5431 && ! CONTAINS_PLACEHOLDER_P (arg0
))
5433 arg0
= save_expr (arg0
);
5434 return fold (build (RDIV_EXPR
, type
,
5435 build_real (type
, dconst1
),
5436 fold (build (MULT_EXPR
, type
,
5440 /* Optimize pow(x,0.5) = sqrt(x). */
5441 if (flag_unsafe_math_optimizations
5442 && REAL_VALUES_EQUAL (c
, dconsthalf
))
5446 fcode
= DECL_FUNCTION_CODE (fndecl
);
5447 if (fcode
== BUILT_IN_POW
)
5448 sqrtfn
= implicit_built_in_decls
[BUILT_IN_SQRT
];
5449 else if (fcode
== BUILT_IN_POWF
)
5450 sqrtfn
= implicit_built_in_decls
[BUILT_IN_SQRTF
];
5451 else if (fcode
== BUILT_IN_POWL
)
5452 sqrtfn
= implicit_built_in_decls
[BUILT_IN_SQRTL
];
5456 if (sqrtfn
!= NULL_TREE
)
5458 tree arglist
= build_tree_list (NULL_TREE
, arg0
);
5459 return build_function_call_expr (sqrtfn
, arglist
);
5463 /* Attempt to evaluate pow at compile-time. */
5464 if (TREE_CODE (arg0
) == REAL_CST
5465 && ! TREE_CONSTANT_OVERFLOW (arg0
))
5467 REAL_VALUE_TYPE cint
;
5470 n
= real_to_integer (&c
);
5471 real_from_integer (&cint
, VOIDmode
, n
,
5473 if (real_identical (&c
, &cint
))
5478 x
= TREE_REAL_CST (arg0
);
5479 inexact
= real_powi (&x
, TYPE_MODE (type
), &x
, n
);
5480 if (flag_unsafe_math_optimizations
|| !inexact
)
5481 return build_real (type
, x
);
5486 /* Optimize pow(exp(x),y) = exp(x*y). */
5487 fcode
= builtin_mathfn_code (arg0
);
5488 if (flag_unsafe_math_optimizations
5489 && (fcode
== BUILT_IN_EXP
5490 || fcode
== BUILT_IN_EXPF
5491 || fcode
== BUILT_IN_EXPL
))
5493 tree expfn
= TREE_OPERAND (TREE_OPERAND (arg0
, 0), 0);
5494 tree arg
= TREE_VALUE (TREE_OPERAND (arg0
, 1));
5495 arg
= fold (build (MULT_EXPR
, type
, arg
, arg1
));
5496 arglist
= build_tree_list (NULL_TREE
, arg
);
5497 return build_function_call_expr (expfn
, arglist
);
5500 /* Optimize pow(sqrt(x),y) = pow(x,y*0.5). */
5501 if (flag_unsafe_math_optimizations
5502 && (fcode
== BUILT_IN_SQRT
5503 || fcode
== BUILT_IN_SQRTF
5504 || fcode
== BUILT_IN_SQRTL
))
5506 tree narg0
= TREE_VALUE (TREE_OPERAND (arg0
, 1));
5507 tree narg1
= fold (build (MULT_EXPR
, type
, arg1
,
5508 build_real (type
, dconsthalf
)));
5510 arglist
= tree_cons (NULL_TREE
, narg0
,
5511 build_tree_list (NULL_TREE
, narg1
));
5512 return build_function_call_expr (fndecl
, arglist
);
5515 /* Optimize pow(pow(x,y),z) = pow(x,y*z). */
5516 if (flag_unsafe_math_optimizations
5517 && (fcode
== BUILT_IN_POW
5518 || fcode
== BUILT_IN_POWF
5519 || fcode
== BUILT_IN_POWL
))
5521 tree arg00
= TREE_VALUE (TREE_OPERAND (arg0
, 1));
5522 tree arg01
= TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg0
, 1)));
5523 tree narg1
= fold (build (MULT_EXPR
, type
, arg01
, arg1
));
5524 arglist
= tree_cons (NULL_TREE
, arg00
,
5525 build_tree_list (NULL_TREE
, narg1
));
5526 return build_function_call_expr (fndecl
, arglist
);
5534 return fold_builtin_inf (type
, true);
5536 case BUILT_IN_HUGE_VAL
:
5537 case BUILT_IN_HUGE_VALF
:
5538 case BUILT_IN_HUGE_VALL
:
5539 return fold_builtin_inf (type
, false);
5544 return fold_builtin_nan (arglist
, type
, true);
5547 case BUILT_IN_NANSF
:
5548 case BUILT_IN_NANSL
:
5549 return fold_builtin_nan (arglist
, type
, false);
5551 case BUILT_IN_FLOOR
:
5552 case BUILT_IN_FLOORF
:
5553 case BUILT_IN_FLOORL
:
5555 case BUILT_IN_CEILF
:
5556 case BUILT_IN_CEILL
:
5557 case BUILT_IN_TRUNC
:
5558 case BUILT_IN_TRUNCF
:
5559 case BUILT_IN_TRUNCL
:
5560 case BUILT_IN_ROUND
:
5561 case BUILT_IN_ROUNDF
:
5562 case BUILT_IN_ROUNDL
:
5563 case BUILT_IN_NEARBYINT
:
5564 case BUILT_IN_NEARBYINTF
:
5565 case BUILT_IN_NEARBYINTL
:
5566 return fold_trunc_transparent_mathfn (exp
);
5575 /* Conveniently construct a function call expression. */
5578 build_function_call_expr (tree fn
, tree arglist
)
5582 call_expr
= build1 (ADDR_EXPR
, build_pointer_type (TREE_TYPE (fn
)), fn
);
5583 call_expr
= build (CALL_EXPR
, TREE_TYPE (TREE_TYPE (fn
)),
5584 call_expr
, arglist
);
5585 TREE_SIDE_EFFECTS (call_expr
) = 1;
5586 return fold (call_expr
);
5589 /* This function validates the types of a function call argument list
5590 represented as a tree chain of parameters against a specified list
5591 of tree_codes. If the last specifier is a 0, that represents an
5592 ellipses, otherwise the last specifier must be a VOID_TYPE. */
5595 validate_arglist (tree arglist
, ...)
5597 enum tree_code code
;
5601 va_start (ap
, arglist
);
5605 code
= va_arg (ap
, enum tree_code
);
5609 /* This signifies an ellipses, any further arguments are all ok. */
5613 /* This signifies an endlink, if no arguments remain, return
5614 true, otherwise return false. */
5618 /* If no parameters remain or the parameter's code does not
5619 match the specified code, return false. Otherwise continue
5620 checking any remaining arguments. */
5622 || code
!= TREE_CODE (TREE_TYPE (TREE_VALUE (arglist
))))
5626 arglist
= TREE_CHAIN (arglist
);
5630 /* We need gotos here since we can only have one VA_CLOSE in a
5638 /* Default version of target-specific builtin setup that does nothing. */
5641 default_init_builtins (void)
5645 /* Default target-specific builtin expander that does nothing. */
5648 default_expand_builtin (tree exp ATTRIBUTE_UNUSED
,
5649 rtx target ATTRIBUTE_UNUSED
,
5650 rtx subtarget ATTRIBUTE_UNUSED
,
5651 enum machine_mode mode ATTRIBUTE_UNUSED
,
5652 int ignore ATTRIBUTE_UNUSED
)
5657 /* Instantiate all remaining CONSTANT_P_RTX nodes. */
5660 purge_builtin_constant_p (void)
5662 rtx insn
, set
, arg
, new, note
;
5664 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
5666 && (set
= single_set (insn
)) != NULL_RTX
5667 && (GET_CODE (arg
= SET_SRC (set
)) == CONSTANT_P_RTX
5668 || (GET_CODE (arg
) == SUBREG
5669 && (GET_CODE (arg
= SUBREG_REG (arg
))
5670 == CONSTANT_P_RTX
))))
5672 arg
= XEXP (arg
, 0);
5673 new = CONSTANT_P (arg
) ? const1_rtx
: const0_rtx
;
5674 validate_change (insn
, &SET_SRC (set
), new, 0);
5676 /* Remove the REG_EQUAL note from the insn. */
5677 if ((note
= find_reg_note (insn
, REG_EQUAL
, NULL_RTX
)) != 0)
5678 remove_note (insn
, note
);
5682 /* Returns true is EXP represents data that would potentially reside
5683 in a readonly section. */
5686 readonly_data_expr (tree exp
)
5690 if (TREE_CODE (exp
) == ADDR_EXPR
)
5691 return decl_readonly_section (TREE_OPERAND (exp
, 0), 0);