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 rtx
expand_builtin_sprintf (tree
, rtx
, enum machine_mode
);
145 static tree
stabilize_va_list (tree
, int);
146 static rtx
expand_builtin_expect (tree
, rtx
);
147 static tree
fold_builtin_constant_p (tree
);
148 static tree
fold_builtin_classify_type (tree
);
149 static tree
fold_builtin_inf (tree
, int);
150 static tree
fold_builtin_nan (tree
, tree
, int);
151 static int validate_arglist (tree
, ...);
152 static tree
fold_trunc_transparent_mathfn (tree
);
153 static bool readonly_data_expr (tree
);
154 static rtx
expand_builtin_fabs (tree
, rtx
, rtx
);
155 static rtx
expand_builtin_cabs (tree
, rtx
);
156 static void init_builtin_dconsts (void);
157 static tree
fold_builtin_cabs (tree
, tree
, tree
);
159 /* Initialize mathematical constants for constant folding builtins.
160 These constants need to be given to at least 160 bits precision. */
163 init_builtin_dconsts (void)
165 real_from_string (&dconstpi
,
166 "3.1415926535897932384626433832795028841971693993751058209749445923078");
167 real_from_string (&dconste
,
168 "2.7182818284590452353602874713526624977572470936999595749669676277241");
170 builtin_dconsts_init
= true;
173 /* Return the alignment in bits of EXP, a pointer valued expression.
174 But don't return more than MAX_ALIGN no matter what.
175 The alignment returned is, by default, the alignment of the thing that
176 EXP points to. If it is not a POINTER_TYPE, 0 is returned.
178 Otherwise, look at the expression to see if we can do better, i.e., if the
179 expression is actually pointing at an object whose alignment is tighter. */
182 get_pointer_alignment (tree exp
, unsigned int max_align
)
184 unsigned int align
, inner
;
186 if (TREE_CODE (TREE_TYPE (exp
)) != POINTER_TYPE
)
189 align
= TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp
)));
190 align
= MIN (align
, max_align
);
194 switch (TREE_CODE (exp
))
198 case NON_LVALUE_EXPR
:
199 exp
= TREE_OPERAND (exp
, 0);
200 if (TREE_CODE (TREE_TYPE (exp
)) != POINTER_TYPE
)
203 inner
= TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp
)));
204 align
= MIN (inner
, max_align
);
208 /* If sum of pointer + int, restrict our maximum alignment to that
209 imposed by the integer. If not, we can't do any better than
211 if (! host_integerp (TREE_OPERAND (exp
, 1), 1))
214 while (((tree_low_cst (TREE_OPERAND (exp
, 1), 1))
215 & (max_align
/ BITS_PER_UNIT
- 1))
219 exp
= TREE_OPERAND (exp
, 0);
223 /* See what we are pointing at and look at its alignment. */
224 exp
= TREE_OPERAND (exp
, 0);
225 if (TREE_CODE (exp
) == FUNCTION_DECL
)
226 align
= FUNCTION_BOUNDARY
;
227 else if (DECL_P (exp
))
228 align
= DECL_ALIGN (exp
);
229 #ifdef CONSTANT_ALIGNMENT
230 else if (TREE_CODE_CLASS (TREE_CODE (exp
)) == 'c')
231 align
= CONSTANT_ALIGNMENT (exp
, align
);
233 return MIN (align
, max_align
);
241 /* Compute the length of a C string. TREE_STRING_LENGTH is not the right
242 way, because it could contain a zero byte in the middle.
243 TREE_STRING_LENGTH is the size of the character array, not the string.
245 The value returned is of type `ssizetype'.
247 Unfortunately, string_constant can't access the values of const char
248 arrays with initializers, so neither can we do so here. */
254 HOST_WIDE_INT offset
;
258 src
= string_constant (src
, &offset_node
);
262 max
= TREE_STRING_LENGTH (src
) - 1;
263 ptr
= TREE_STRING_POINTER (src
);
265 if (offset_node
&& TREE_CODE (offset_node
) != INTEGER_CST
)
267 /* If the string has an internal zero byte (e.g., "foo\0bar"), we can't
268 compute the offset to the following null if we don't know where to
269 start searching for it. */
272 for (i
= 0; i
< max
; i
++)
276 /* We don't know the starting offset, but we do know that the string
277 has no internal zero bytes. We can assume that the offset falls
278 within the bounds of the string; otherwise, the programmer deserves
279 what he gets. Subtract the offset from the length of the string,
280 and return that. This would perhaps not be valid if we were dealing
281 with named arrays in addition to literal string constants. */
283 return size_diffop (size_int (max
), offset_node
);
286 /* We have a known offset into the string. Start searching there for
287 a null character if we can represent it as a single HOST_WIDE_INT. */
288 if (offset_node
== 0)
290 else if (! host_integerp (offset_node
, 0))
293 offset
= tree_low_cst (offset_node
, 0);
295 /* If the offset is known to be out of bounds, warn, and call strlen at
297 if (offset
< 0 || offset
> max
)
299 warning ("offset outside bounds of constant string");
303 /* Use strlen to search for the first zero byte. Since any strings
304 constructed with build_string will have nulls appended, we win even
305 if we get handed something like (char[4])"abcd".
307 Since OFFSET is our starting index into the string, no further
308 calculation is needed. */
309 return ssize_int (strlen (ptr
+ offset
));
312 /* Return a char pointer for a C string if it is a string constant
313 or sum of string constant and integer constant. */
320 src
= string_constant (src
, &offset_node
);
324 if (offset_node
== 0)
325 return TREE_STRING_POINTER (src
);
326 else if (!host_integerp (offset_node
, 1)
327 || compare_tree_int (offset_node
, TREE_STRING_LENGTH (src
) - 1) > 0)
330 return TREE_STRING_POINTER (src
) + tree_low_cst (offset_node
, 1);
333 /* Return a CONST_INT or CONST_DOUBLE corresponding to target reading
334 GET_MODE_BITSIZE (MODE) bits from string constant STR. */
337 c_readstr (const char *str
, enum machine_mode mode
)
343 if (GET_MODE_CLASS (mode
) != MODE_INT
)
348 for (i
= 0; i
< GET_MODE_SIZE (mode
); i
++)
351 if (WORDS_BIG_ENDIAN
)
352 j
= GET_MODE_SIZE (mode
) - i
- 1;
353 if (BYTES_BIG_ENDIAN
!= WORDS_BIG_ENDIAN
354 && GET_MODE_SIZE (mode
) > UNITS_PER_WORD
)
355 j
= j
+ UNITS_PER_WORD
- 2 * (j
% UNITS_PER_WORD
) - 1;
357 if (j
> 2 * HOST_BITS_PER_WIDE_INT
)
360 ch
= (unsigned char) str
[i
];
361 c
[j
/ HOST_BITS_PER_WIDE_INT
] |= ch
<< (j
% HOST_BITS_PER_WIDE_INT
);
363 return immed_double_const (c
[0], c
[1], mode
);
366 /* Cast a target constant CST to target CHAR and if that value fits into
367 host char type, return zero and put that value into variable pointed by
371 target_char_cast (tree cst
, char *p
)
373 unsigned HOST_WIDE_INT val
, hostval
;
375 if (!host_integerp (cst
, 1)
376 || CHAR_TYPE_SIZE
> HOST_BITS_PER_WIDE_INT
)
379 val
= tree_low_cst (cst
, 1);
380 if (CHAR_TYPE_SIZE
< HOST_BITS_PER_WIDE_INT
)
381 val
&= (((unsigned HOST_WIDE_INT
) 1) << CHAR_TYPE_SIZE
) - 1;
384 if (HOST_BITS_PER_CHAR
< HOST_BITS_PER_WIDE_INT
)
385 hostval
&= (((unsigned HOST_WIDE_INT
) 1) << HOST_BITS_PER_CHAR
) - 1;
394 /* Given TEM, a pointer to a stack frame, follow the dynamic chain COUNT
395 times to get the address of either a higher stack frame, or a return
396 address located within it (depending on FNDECL_CODE). */
399 expand_builtin_return_addr (enum built_in_function fndecl_code
, int count
,
404 /* Some machines need special handling before we can access
405 arbitrary frames. For example, on the sparc, we must first flush
406 all register windows to the stack. */
407 #ifdef SETUP_FRAME_ADDRESSES
409 SETUP_FRAME_ADDRESSES ();
412 /* On the sparc, the return address is not in the frame, it is in a
413 register. There is no way to access it off of the current frame
414 pointer, but it can be accessed off the previous frame pointer by
415 reading the value from the register window save area. */
416 #ifdef RETURN_ADDR_IN_PREVIOUS_FRAME
417 if (fndecl_code
== BUILT_IN_RETURN_ADDRESS
)
421 /* Scan back COUNT frames to the specified frame. */
422 for (i
= 0; i
< count
; i
++)
424 /* Assume the dynamic chain pointer is in the word that the
425 frame address points to, unless otherwise specified. */
426 #ifdef DYNAMIC_CHAIN_ADDRESS
427 tem
= DYNAMIC_CHAIN_ADDRESS (tem
);
429 tem
= memory_address (Pmode
, tem
);
430 tem
= gen_rtx_MEM (Pmode
, tem
);
431 set_mem_alias_set (tem
, get_frame_alias_set ());
432 tem
= copy_to_reg (tem
);
435 /* For __builtin_frame_address, return what we've got. */
436 if (fndecl_code
== BUILT_IN_FRAME_ADDRESS
)
439 /* For __builtin_return_address, Get the return address from that
441 #ifdef RETURN_ADDR_RTX
442 tem
= RETURN_ADDR_RTX (count
, tem
);
444 tem
= memory_address (Pmode
,
445 plus_constant (tem
, GET_MODE_SIZE (Pmode
)));
446 tem
= gen_rtx_MEM (Pmode
, tem
);
447 set_mem_alias_set (tem
, get_frame_alias_set ());
452 /* Alias set used for setjmp buffer. */
453 static HOST_WIDE_INT setjmp_alias_set
= -1;
455 /* Construct the leading half of a __builtin_setjmp call. Control will
456 return to RECEIVER_LABEL. This is used directly by sjlj exception
460 expand_builtin_setjmp_setup (rtx buf_addr
, rtx receiver_label
)
462 enum machine_mode sa_mode
= STACK_SAVEAREA_MODE (SAVE_NONLOCAL
);
466 if (setjmp_alias_set
== -1)
467 setjmp_alias_set
= new_alias_set ();
469 #ifdef POINTERS_EXTEND_UNSIGNED
470 if (GET_MODE (buf_addr
) != Pmode
)
471 buf_addr
= convert_memory_address (Pmode
, buf_addr
);
474 buf_addr
= force_reg (Pmode
, force_operand (buf_addr
, NULL_RTX
));
478 /* We store the frame pointer and the address of receiver_label in
479 the buffer and use the rest of it for the stack save area, which
480 is machine-dependent. */
482 #ifndef BUILTIN_SETJMP_FRAME_VALUE
483 #define BUILTIN_SETJMP_FRAME_VALUE virtual_stack_vars_rtx
486 mem
= gen_rtx_MEM (Pmode
, buf_addr
);
487 set_mem_alias_set (mem
, setjmp_alias_set
);
488 emit_move_insn (mem
, BUILTIN_SETJMP_FRAME_VALUE
);
490 mem
= gen_rtx_MEM (Pmode
, plus_constant (buf_addr
, GET_MODE_SIZE (Pmode
))),
491 set_mem_alias_set (mem
, setjmp_alias_set
);
493 emit_move_insn (validize_mem (mem
),
494 force_reg (Pmode
, gen_rtx_LABEL_REF (Pmode
, receiver_label
)));
496 stack_save
= gen_rtx_MEM (sa_mode
,
497 plus_constant (buf_addr
,
498 2 * GET_MODE_SIZE (Pmode
)));
499 set_mem_alias_set (stack_save
, setjmp_alias_set
);
500 emit_stack_save (SAVE_NONLOCAL
, &stack_save
, NULL_RTX
);
502 /* If there is further processing to do, do it. */
503 #ifdef HAVE_builtin_setjmp_setup
504 if (HAVE_builtin_setjmp_setup
)
505 emit_insn (gen_builtin_setjmp_setup (buf_addr
));
508 /* Tell optimize_save_area_alloca that extra work is going to
509 need to go on during alloca. */
510 current_function_calls_setjmp
= 1;
512 /* Set this so all the registers get saved in our frame; we need to be
513 able to copy the saved values for any registers from frames we unwind. */
514 current_function_has_nonlocal_label
= 1;
517 /* Construct the trailing part of a __builtin_setjmp call.
518 This is used directly by sjlj exception handling code. */
521 expand_builtin_setjmp_receiver (rtx receiver_label ATTRIBUTE_UNUSED
)
523 /* Clobber the FP when we get here, so we have to make sure it's
524 marked as used by this function. */
525 emit_insn (gen_rtx_USE (VOIDmode
, hard_frame_pointer_rtx
));
527 /* Mark the static chain as clobbered here so life information
528 doesn't get messed up for it. */
529 emit_insn (gen_rtx_CLOBBER (VOIDmode
, static_chain_rtx
));
531 /* Now put in the code to restore the frame pointer, and argument
532 pointer, if needed. The code below is from expand_end_bindings
533 in stmt.c; see detailed documentation there. */
534 #ifdef HAVE_nonlocal_goto
535 if (! HAVE_nonlocal_goto
)
537 emit_move_insn (virtual_stack_vars_rtx
, hard_frame_pointer_rtx
);
539 #if ARG_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
540 if (fixed_regs
[ARG_POINTER_REGNUM
])
542 #ifdef ELIMINABLE_REGS
544 static const struct elims
{const int from
, to
;} elim_regs
[] = ELIMINABLE_REGS
;
546 for (i
= 0; i
< ARRAY_SIZE (elim_regs
); i
++)
547 if (elim_regs
[i
].from
== ARG_POINTER_REGNUM
548 && elim_regs
[i
].to
== HARD_FRAME_POINTER_REGNUM
)
551 if (i
== ARRAY_SIZE (elim_regs
))
554 /* Now restore our arg pointer from the address at which it
555 was saved in our stack frame. */
556 emit_move_insn (virtual_incoming_args_rtx
,
557 copy_to_reg (get_arg_pointer_save_area (cfun
)));
562 #ifdef HAVE_builtin_setjmp_receiver
563 if (HAVE_builtin_setjmp_receiver
)
564 emit_insn (gen_builtin_setjmp_receiver (receiver_label
));
567 #ifdef HAVE_nonlocal_goto_receiver
568 if (HAVE_nonlocal_goto_receiver
)
569 emit_insn (gen_nonlocal_goto_receiver ());
574 /* @@@ This is a kludge. Not all machine descriptions define a blockage
575 insn, but we must not allow the code we just generated to be reordered
576 by scheduling. Specifically, the update of the frame pointer must
577 happen immediately, not later. So emit an ASM_INPUT to act as blockage
579 emit_insn (gen_rtx_ASM_INPUT (VOIDmode
, ""));
582 /* __builtin_setjmp is passed a pointer to an array of five words (not
583 all will be used on all machines). It operates similarly to the C
584 library function of the same name, but is more efficient. Much of
585 the code below (and for longjmp) is copied from the handling of
588 NOTE: This is intended for use by GNAT and the exception handling
589 scheme in the compiler and will only work in the method used by
593 expand_builtin_setjmp (tree arglist
, rtx target
)
595 rtx buf_addr
, next_lab
, cont_lab
;
597 if (!validate_arglist (arglist
, POINTER_TYPE
, VOID_TYPE
))
600 if (target
== 0 || GET_CODE (target
) != REG
601 || REGNO (target
) < FIRST_PSEUDO_REGISTER
)
602 target
= gen_reg_rtx (TYPE_MODE (integer_type_node
));
604 buf_addr
= expand_expr (TREE_VALUE (arglist
), NULL_RTX
, VOIDmode
, 0);
606 next_lab
= gen_label_rtx ();
607 cont_lab
= gen_label_rtx ();
609 expand_builtin_setjmp_setup (buf_addr
, next_lab
);
611 /* Set TARGET to zero and branch to the continue label. */
612 emit_move_insn (target
, const0_rtx
);
613 emit_jump_insn (gen_jump (cont_lab
));
615 emit_label (next_lab
);
617 expand_builtin_setjmp_receiver (next_lab
);
619 /* Set TARGET to one. */
620 emit_move_insn (target
, const1_rtx
);
621 emit_label (cont_lab
);
623 /* Tell flow about the strange goings on. Putting `next_lab' on
624 `nonlocal_goto_handler_labels' to indicates that function
625 calls may traverse the arc back to this label. */
627 current_function_has_nonlocal_label
= 1;
628 nonlocal_goto_handler_labels
629 = gen_rtx_EXPR_LIST (VOIDmode
, next_lab
, nonlocal_goto_handler_labels
);
634 /* __builtin_longjmp is passed a pointer to an array of five words (not
635 all will be used on all machines). It operates similarly to the C
636 library function of the same name, but is more efficient. Much of
637 the code below is copied from the handling of non-local gotos.
639 NOTE: This is intended for use by GNAT and the exception handling
640 scheme in the compiler and will only work in the method used by
644 expand_builtin_longjmp (rtx buf_addr
, rtx value
)
646 rtx fp
, lab
, stack
, insn
, last
;
647 enum machine_mode sa_mode
= STACK_SAVEAREA_MODE (SAVE_NONLOCAL
);
649 if (setjmp_alias_set
== -1)
650 setjmp_alias_set
= new_alias_set ();
652 #ifdef POINTERS_EXTEND_UNSIGNED
653 if (GET_MODE (buf_addr
) != Pmode
)
654 buf_addr
= convert_memory_address (Pmode
, buf_addr
);
657 buf_addr
= force_reg (Pmode
, buf_addr
);
659 /* We used to store value in static_chain_rtx, but that fails if pointers
660 are smaller than integers. We instead require that the user must pass
661 a second argument of 1, because that is what builtin_setjmp will
662 return. This also makes EH slightly more efficient, since we are no
663 longer copying around a value that we don't care about. */
664 if (value
!= const1_rtx
)
667 current_function_calls_longjmp
= 1;
669 last
= get_last_insn ();
670 #ifdef HAVE_builtin_longjmp
671 if (HAVE_builtin_longjmp
)
672 emit_insn (gen_builtin_longjmp (buf_addr
));
676 fp
= gen_rtx_MEM (Pmode
, buf_addr
);
677 lab
= gen_rtx_MEM (Pmode
, plus_constant (buf_addr
,
678 GET_MODE_SIZE (Pmode
)));
680 stack
= gen_rtx_MEM (sa_mode
, plus_constant (buf_addr
,
681 2 * GET_MODE_SIZE (Pmode
)));
682 set_mem_alias_set (fp
, setjmp_alias_set
);
683 set_mem_alias_set (lab
, setjmp_alias_set
);
684 set_mem_alias_set (stack
, setjmp_alias_set
);
686 /* Pick up FP, label, and SP from the block and jump. This code is
687 from expand_goto in stmt.c; see there for detailed comments. */
688 #if HAVE_nonlocal_goto
689 if (HAVE_nonlocal_goto
)
690 /* We have to pass a value to the nonlocal_goto pattern that will
691 get copied into the static_chain pointer, but it does not matter
692 what that value is, because builtin_setjmp does not use it. */
693 emit_insn (gen_nonlocal_goto (value
, lab
, stack
, fp
));
697 lab
= copy_to_reg (lab
);
699 emit_move_insn (hard_frame_pointer_rtx
, fp
);
700 emit_stack_restore (SAVE_NONLOCAL
, stack
, NULL_RTX
);
702 emit_insn (gen_rtx_USE (VOIDmode
, hard_frame_pointer_rtx
));
703 emit_insn (gen_rtx_USE (VOIDmode
, stack_pointer_rtx
));
704 emit_indirect_jump (lab
);
708 /* Search backwards and mark the jump insn as a non-local goto.
709 Note that this precludes the use of __builtin_longjmp to a
710 __builtin_setjmp target in the same function. However, we've
711 already cautioned the user that these functions are for
712 internal exception handling use only. */
713 for (insn
= get_last_insn (); insn
; insn
= PREV_INSN (insn
))
717 if (GET_CODE (insn
) == JUMP_INSN
)
719 REG_NOTES (insn
) = alloc_EXPR_LIST (REG_NON_LOCAL_GOTO
, const0_rtx
,
723 else if (GET_CODE (insn
) == CALL_INSN
)
728 /* Expand a call to __builtin_prefetch. For a target that does not support
729 data prefetch, evaluate the memory address argument in case it has side
733 expand_builtin_prefetch (tree arglist
)
735 tree arg0
, arg1
, arg2
;
738 if (!validate_arglist (arglist
, POINTER_TYPE
, 0))
741 arg0
= TREE_VALUE (arglist
);
742 /* Arguments 1 and 2 are optional; argument 1 (read/write) defaults to
743 zero (read) and argument 2 (locality) defaults to 3 (high degree of
745 if (TREE_CHAIN (arglist
))
747 arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
748 if (TREE_CHAIN (TREE_CHAIN (arglist
)))
749 arg2
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
751 arg2
= build_int_2 (3, 0);
755 arg1
= integer_zero_node
;
756 arg2
= build_int_2 (3, 0);
759 /* Argument 0 is an address. */
760 op0
= expand_expr (arg0
, NULL_RTX
, Pmode
, EXPAND_NORMAL
);
762 /* Argument 1 (read/write flag) must be a compile-time constant int. */
763 if (TREE_CODE (arg1
) != INTEGER_CST
)
765 error ("second arg to `__builtin_prefetch' must be a constant");
766 arg1
= integer_zero_node
;
768 op1
= expand_expr (arg1
, NULL_RTX
, VOIDmode
, 0);
769 /* Argument 1 must be either zero or one. */
770 if (INTVAL (op1
) != 0 && INTVAL (op1
) != 1)
772 warning ("invalid second arg to __builtin_prefetch; using zero");
776 /* Argument 2 (locality) must be a compile-time constant int. */
777 if (TREE_CODE (arg2
) != INTEGER_CST
)
779 error ("third arg to `__builtin_prefetch' must be a constant");
780 arg2
= integer_zero_node
;
782 op2
= expand_expr (arg2
, NULL_RTX
, VOIDmode
, 0);
783 /* Argument 2 must be 0, 1, 2, or 3. */
784 if (INTVAL (op2
) < 0 || INTVAL (op2
) > 3)
786 warning ("invalid third arg to __builtin_prefetch; using zero");
793 if ((! (*insn_data
[(int) CODE_FOR_prefetch
].operand
[0].predicate
)
795 insn_data
[(int) CODE_FOR_prefetch
].operand
[0].mode
))
796 || (GET_MODE(op0
) != Pmode
))
798 #ifdef POINTERS_EXTEND_UNSIGNED
799 if (GET_MODE(op0
) != Pmode
)
800 op0
= convert_memory_address (Pmode
, op0
);
802 op0
= force_reg (Pmode
, op0
);
804 emit_insn (gen_prefetch (op0
, op1
, op2
));
808 op0
= protect_from_queue (op0
, 0);
809 /* Don't do anything with direct references to volatile memory, but
810 generate code to handle other side effects. */
811 if (GET_CODE (op0
) != MEM
&& side_effects_p (op0
))
815 /* Get a MEM rtx for expression EXP which is the address of an operand
816 to be used to be used in a string instruction (cmpstrsi, movstrsi, ..). */
819 get_memory_rtx (tree exp
)
821 rtx addr
= expand_expr (exp
, NULL_RTX
, ptr_mode
, EXPAND_SUM
);
824 #ifdef POINTERS_EXTEND_UNSIGNED
825 if (GET_MODE (addr
) != Pmode
)
826 addr
= convert_memory_address (Pmode
, addr
);
829 mem
= gen_rtx_MEM (BLKmode
, memory_address (BLKmode
, addr
));
831 /* Get an expression we can use to find the attributes to assign to MEM.
832 If it is an ADDR_EXPR, use the operand. Otherwise, dereference it if
833 we can. First remove any nops. */
834 while ((TREE_CODE (exp
) == NOP_EXPR
|| TREE_CODE (exp
) == CONVERT_EXPR
835 || TREE_CODE (exp
) == NON_LVALUE_EXPR
)
836 && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (exp
, 0))))
837 exp
= TREE_OPERAND (exp
, 0);
839 if (TREE_CODE (exp
) == ADDR_EXPR
)
841 exp
= TREE_OPERAND (exp
, 0);
842 set_mem_attributes (mem
, exp
, 0);
844 else if (POINTER_TYPE_P (TREE_TYPE (exp
)))
846 exp
= build1 (INDIRECT_REF
, TREE_TYPE (TREE_TYPE (exp
)), exp
);
847 /* memcpy, memset and other builtin stringops can alias with anything. */
848 set_mem_alias_set (mem
, 0);
854 /* Built-in functions to perform an untyped call and return. */
856 /* For each register that may be used for calling a function, this
857 gives a mode used to copy the register's value. VOIDmode indicates
858 the register is not used for calling a function. If the machine
859 has register windows, this gives only the outbound registers.
860 INCOMING_REGNO gives the corresponding inbound register. */
861 static enum machine_mode apply_args_mode
[FIRST_PSEUDO_REGISTER
];
863 /* For each register that may be used for returning values, this gives
864 a mode used to copy the register's value. VOIDmode indicates the
865 register is not used for returning values. If the machine has
866 register windows, this gives only the outbound registers.
867 INCOMING_REGNO gives the corresponding inbound register. */
868 static enum machine_mode apply_result_mode
[FIRST_PSEUDO_REGISTER
];
870 /* For each register that may be used for calling a function, this
871 gives the offset of that register into the block returned by
872 __builtin_apply_args. 0 indicates that the register is not
873 used for calling a function. */
874 static int apply_args_reg_offset
[FIRST_PSEUDO_REGISTER
];
876 /* Return the offset of register REGNO into the block returned by
877 __builtin_apply_args. This is not declared static, since it is
878 needed in objc-act.c. */
881 apply_args_register_offset (int regno
)
885 /* Arguments are always put in outgoing registers (in the argument
886 block) if such make sense. */
887 #ifdef OUTGOING_REGNO
888 regno
= OUTGOING_REGNO (regno
);
890 return apply_args_reg_offset
[regno
];
893 /* Return the size required for the block returned by __builtin_apply_args,
894 and initialize apply_args_mode. */
897 apply_args_size (void)
899 static int size
= -1;
902 enum machine_mode mode
;
904 /* The values computed by this function never change. */
907 /* The first value is the incoming arg-pointer. */
908 size
= GET_MODE_SIZE (Pmode
);
910 /* The second value is the structure value address unless this is
911 passed as an "invisible" first argument. */
912 if (struct_value_rtx
)
913 size
+= GET_MODE_SIZE (Pmode
);
915 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
916 if (FUNCTION_ARG_REGNO_P (regno
))
918 /* Search for the proper mode for copying this register's
919 value. I'm not sure this is right, but it works so far. */
920 enum machine_mode best_mode
= VOIDmode
;
922 for (mode
= GET_CLASS_NARROWEST_MODE (MODE_INT
);
924 mode
= GET_MODE_WIDER_MODE (mode
))
925 if (HARD_REGNO_MODE_OK (regno
, mode
)
926 && HARD_REGNO_NREGS (regno
, mode
) == 1)
929 if (best_mode
== VOIDmode
)
930 for (mode
= GET_CLASS_NARROWEST_MODE (MODE_FLOAT
);
932 mode
= GET_MODE_WIDER_MODE (mode
))
933 if (HARD_REGNO_MODE_OK (regno
, mode
)
934 && have_insn_for (SET
, mode
))
937 if (best_mode
== VOIDmode
)
938 for (mode
= GET_CLASS_NARROWEST_MODE (MODE_VECTOR_FLOAT
);
940 mode
= GET_MODE_WIDER_MODE (mode
))
941 if (HARD_REGNO_MODE_OK (regno
, mode
)
942 && have_insn_for (SET
, mode
))
945 if (best_mode
== VOIDmode
)
946 for (mode
= GET_CLASS_NARROWEST_MODE (MODE_VECTOR_INT
);
948 mode
= GET_MODE_WIDER_MODE (mode
))
949 if (HARD_REGNO_MODE_OK (regno
, mode
)
950 && have_insn_for (SET
, mode
))
954 if (mode
== VOIDmode
)
957 align
= GET_MODE_ALIGNMENT (mode
) / BITS_PER_UNIT
;
958 if (size
% align
!= 0)
959 size
= CEIL (size
, align
) * align
;
960 apply_args_reg_offset
[regno
] = size
;
961 size
+= GET_MODE_SIZE (mode
);
962 apply_args_mode
[regno
] = mode
;
966 apply_args_mode
[regno
] = VOIDmode
;
967 apply_args_reg_offset
[regno
] = 0;
973 /* Return the size required for the block returned by __builtin_apply,
974 and initialize apply_result_mode. */
977 apply_result_size (void)
979 static int size
= -1;
981 enum machine_mode mode
;
983 /* The values computed by this function never change. */
988 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
989 if (FUNCTION_VALUE_REGNO_P (regno
))
991 /* Search for the proper mode for copying this register's
992 value. I'm not sure this is right, but it works so far. */
993 enum machine_mode best_mode
= VOIDmode
;
995 for (mode
= GET_CLASS_NARROWEST_MODE (MODE_INT
);
997 mode
= GET_MODE_WIDER_MODE (mode
))
998 if (HARD_REGNO_MODE_OK (regno
, mode
))
1001 if (best_mode
== VOIDmode
)
1002 for (mode
= GET_CLASS_NARROWEST_MODE (MODE_FLOAT
);
1004 mode
= GET_MODE_WIDER_MODE (mode
))
1005 if (HARD_REGNO_MODE_OK (regno
, mode
)
1006 && have_insn_for (SET
, mode
))
1009 if (best_mode
== VOIDmode
)
1010 for (mode
= GET_CLASS_NARROWEST_MODE (MODE_VECTOR_FLOAT
);
1012 mode
= GET_MODE_WIDER_MODE (mode
))
1013 if (HARD_REGNO_MODE_OK (regno
, mode
)
1014 && have_insn_for (SET
, mode
))
1017 if (best_mode
== VOIDmode
)
1018 for (mode
= GET_CLASS_NARROWEST_MODE (MODE_VECTOR_INT
);
1020 mode
= GET_MODE_WIDER_MODE (mode
))
1021 if (HARD_REGNO_MODE_OK (regno
, mode
)
1022 && have_insn_for (SET
, mode
))
1026 if (mode
== VOIDmode
)
1029 align
= GET_MODE_ALIGNMENT (mode
) / BITS_PER_UNIT
;
1030 if (size
% align
!= 0)
1031 size
= CEIL (size
, align
) * align
;
1032 size
+= GET_MODE_SIZE (mode
);
1033 apply_result_mode
[regno
] = mode
;
1036 apply_result_mode
[regno
] = VOIDmode
;
1038 /* Allow targets that use untyped_call and untyped_return to override
1039 the size so that machine-specific information can be stored here. */
1040 #ifdef APPLY_RESULT_SIZE
1041 size
= APPLY_RESULT_SIZE
;
1047 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
1048 /* Create a vector describing the result block RESULT. If SAVEP is true,
1049 the result block is used to save the values; otherwise it is used to
1050 restore the values. */
1053 result_vector (int savep
, rtx result
)
1055 int regno
, size
, align
, nelts
;
1056 enum machine_mode mode
;
1058 rtx
*savevec
= (rtx
*) alloca (FIRST_PSEUDO_REGISTER
* sizeof (rtx
));
1061 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
1062 if ((mode
= apply_result_mode
[regno
]) != VOIDmode
)
1064 align
= GET_MODE_ALIGNMENT (mode
) / BITS_PER_UNIT
;
1065 if (size
% align
!= 0)
1066 size
= CEIL (size
, align
) * align
;
1067 reg
= gen_rtx_REG (mode
, savep
? regno
: INCOMING_REGNO (regno
));
1068 mem
= adjust_address (result
, mode
, size
);
1069 savevec
[nelts
++] = (savep
1070 ? gen_rtx_SET (VOIDmode
, mem
, reg
)
1071 : gen_rtx_SET (VOIDmode
, reg
, mem
));
1072 size
+= GET_MODE_SIZE (mode
);
1074 return gen_rtx_PARALLEL (VOIDmode
, gen_rtvec_v (nelts
, savevec
));
1076 #endif /* HAVE_untyped_call or HAVE_untyped_return */
1078 /* Save the state required to perform an untyped call with the same
1079 arguments as were passed to the current function. */
1082 expand_builtin_apply_args_1 (void)
1085 int size
, align
, regno
;
1086 enum machine_mode mode
;
1088 /* Create a block where the arg-pointer, structure value address,
1089 and argument registers can be saved. */
1090 registers
= assign_stack_local (BLKmode
, apply_args_size (), -1);
1092 /* Walk past the arg-pointer and structure value address. */
1093 size
= GET_MODE_SIZE (Pmode
);
1094 if (struct_value_rtx
)
1095 size
+= GET_MODE_SIZE (Pmode
);
1097 /* Save each register used in calling a function to the block. */
1098 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
1099 if ((mode
= apply_args_mode
[regno
]) != VOIDmode
)
1103 align
= GET_MODE_ALIGNMENT (mode
) / BITS_PER_UNIT
;
1104 if (size
% align
!= 0)
1105 size
= CEIL (size
, align
) * align
;
1107 tem
= gen_rtx_REG (mode
, INCOMING_REGNO (regno
));
1109 emit_move_insn (adjust_address (registers
, mode
, size
), tem
);
1110 size
+= GET_MODE_SIZE (mode
);
1113 /* Save the arg pointer to the block. */
1114 emit_move_insn (adjust_address (registers
, Pmode
, 0),
1115 copy_to_reg (virtual_incoming_args_rtx
));
1116 size
= GET_MODE_SIZE (Pmode
);
1118 /* Save the structure value address unless this is passed as an
1119 "invisible" first argument. */
1120 if (struct_value_incoming_rtx
)
1122 emit_move_insn (adjust_address (registers
, Pmode
, size
),
1123 copy_to_reg (struct_value_incoming_rtx
));
1124 size
+= GET_MODE_SIZE (Pmode
);
1127 /* Return the address of the block. */
1128 return copy_addr_to_reg (XEXP (registers
, 0));
1131 /* __builtin_apply_args returns block of memory allocated on
1132 the stack into which is stored the arg pointer, structure
1133 value address, static chain, and all the registers that might
1134 possibly be used in performing a function call. The code is
1135 moved to the start of the function so the incoming values are
1139 expand_builtin_apply_args (void)
1141 /* Don't do __builtin_apply_args more than once in a function.
1142 Save the result of the first call and reuse it. */
1143 if (apply_args_value
!= 0)
1144 return apply_args_value
;
1146 /* When this function is called, it means that registers must be
1147 saved on entry to this function. So we migrate the
1148 call to the first insn of this function. */
1153 temp
= expand_builtin_apply_args_1 ();
1157 apply_args_value
= temp
;
1159 /* Put the insns after the NOTE that starts the function.
1160 If this is inside a start_sequence, make the outer-level insn
1161 chain current, so the code is placed at the start of the
1163 push_topmost_sequence ();
1164 emit_insn_before (seq
, NEXT_INSN (get_insns ()));
1165 pop_topmost_sequence ();
1170 /* Perform an untyped call and save the state required to perform an
1171 untyped return of whatever value was returned by the given function. */
1174 expand_builtin_apply (rtx function
, rtx arguments
, rtx argsize
)
1176 int size
, align
, regno
;
1177 enum machine_mode mode
;
1178 rtx incoming_args
, result
, reg
, dest
, src
, call_insn
;
1179 rtx old_stack_level
= 0;
1180 rtx call_fusage
= 0;
1182 #ifdef POINTERS_EXTEND_UNSIGNED
1183 if (GET_MODE (arguments
) != Pmode
)
1184 arguments
= convert_memory_address (Pmode
, arguments
);
1187 /* Create a block where the return registers can be saved. */
1188 result
= assign_stack_local (BLKmode
, apply_result_size (), -1);
1190 /* Fetch the arg pointer from the ARGUMENTS block. */
1191 incoming_args
= gen_reg_rtx (Pmode
);
1192 emit_move_insn (incoming_args
, gen_rtx_MEM (Pmode
, arguments
));
1193 #ifndef STACK_GROWS_DOWNWARD
1194 incoming_args
= expand_simple_binop (Pmode
, MINUS
, incoming_args
, argsize
,
1195 incoming_args
, 0, OPTAB_LIB_WIDEN
);
1198 /* Perform postincrements before actually calling the function. */
1201 /* Push a new argument block and copy the arguments. Do not allow
1202 the (potential) memcpy call below to interfere with our stack
1204 do_pending_stack_adjust ();
1207 /* Save the stack with nonlocal if available */
1208 #ifdef HAVE_save_stack_nonlocal
1209 if (HAVE_save_stack_nonlocal
)
1210 emit_stack_save (SAVE_NONLOCAL
, &old_stack_level
, NULL_RTX
);
1213 emit_stack_save (SAVE_BLOCK
, &old_stack_level
, NULL_RTX
);
1215 /* Push a block of memory onto the stack to store the memory arguments.
1216 Save the address in a register, and copy the memory arguments. ??? I
1217 haven't figured out how the calling convention macros effect this,
1218 but it's likely that the source and/or destination addresses in
1219 the block copy will need updating in machine specific ways. */
1220 dest
= allocate_dynamic_stack_space (argsize
, 0, BITS_PER_UNIT
);
1221 dest
= gen_rtx_MEM (BLKmode
, dest
);
1222 set_mem_align (dest
, PARM_BOUNDARY
);
1223 src
= gen_rtx_MEM (BLKmode
, incoming_args
);
1224 set_mem_align (src
, PARM_BOUNDARY
);
1225 emit_block_move (dest
, src
, argsize
, BLOCK_OP_NORMAL
);
1227 /* Refer to the argument block. */
1229 arguments
= gen_rtx_MEM (BLKmode
, arguments
);
1230 set_mem_align (arguments
, PARM_BOUNDARY
);
1232 /* Walk past the arg-pointer and structure value address. */
1233 size
= GET_MODE_SIZE (Pmode
);
1234 if (struct_value_rtx
)
1235 size
+= GET_MODE_SIZE (Pmode
);
1237 /* Restore each of the registers previously saved. Make USE insns
1238 for each of these registers for use in making the call. */
1239 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
1240 if ((mode
= apply_args_mode
[regno
]) != VOIDmode
)
1242 align
= GET_MODE_ALIGNMENT (mode
) / BITS_PER_UNIT
;
1243 if (size
% align
!= 0)
1244 size
= CEIL (size
, align
) * align
;
1245 reg
= gen_rtx_REG (mode
, regno
);
1246 emit_move_insn (reg
, adjust_address (arguments
, mode
, size
));
1247 use_reg (&call_fusage
, reg
);
1248 size
+= GET_MODE_SIZE (mode
);
1251 /* Restore the structure value address unless this is passed as an
1252 "invisible" first argument. */
1253 size
= GET_MODE_SIZE (Pmode
);
1254 if (struct_value_rtx
)
1256 rtx value
= gen_reg_rtx (Pmode
);
1257 emit_move_insn (value
, adjust_address (arguments
, Pmode
, size
));
1258 emit_move_insn (struct_value_rtx
, value
);
1259 if (GET_CODE (struct_value_rtx
) == REG
)
1260 use_reg (&call_fusage
, struct_value_rtx
);
1261 size
+= GET_MODE_SIZE (Pmode
);
1264 /* All arguments and registers used for the call are set up by now! */
1265 function
= prepare_call_address (function
, NULL_TREE
, &call_fusage
, 0, 0);
1267 /* Ensure address is valid. SYMBOL_REF is already valid, so no need,
1268 and we don't want to load it into a register as an optimization,
1269 because prepare_call_address already did it if it should be done. */
1270 if (GET_CODE (function
) != SYMBOL_REF
)
1271 function
= memory_address (FUNCTION_MODE
, function
);
1273 /* Generate the actual call instruction and save the return value. */
1274 #ifdef HAVE_untyped_call
1275 if (HAVE_untyped_call
)
1276 emit_call_insn (gen_untyped_call (gen_rtx_MEM (FUNCTION_MODE
, function
),
1277 result
, result_vector (1, result
)));
1280 #ifdef HAVE_call_value
1281 if (HAVE_call_value
)
1285 /* Locate the unique return register. It is not possible to
1286 express a call that sets more than one return register using
1287 call_value; use untyped_call for that. In fact, untyped_call
1288 only needs to save the return registers in the given block. */
1289 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
1290 if ((mode
= apply_result_mode
[regno
]) != VOIDmode
)
1293 abort (); /* HAVE_untyped_call required. */
1294 valreg
= gen_rtx_REG (mode
, regno
);
1297 emit_call_insn (GEN_CALL_VALUE (valreg
,
1298 gen_rtx_MEM (FUNCTION_MODE
, function
),
1299 const0_rtx
, NULL_RTX
, const0_rtx
));
1301 emit_move_insn (adjust_address (result
, GET_MODE (valreg
), 0), valreg
);
1307 /* Find the CALL insn we just emitted, and attach the register usage
1309 call_insn
= last_call_insn ();
1310 add_function_usage_to (call_insn
, call_fusage
);
1312 /* Restore the stack. */
1313 #ifdef HAVE_save_stack_nonlocal
1314 if (HAVE_save_stack_nonlocal
)
1315 emit_stack_restore (SAVE_NONLOCAL
, old_stack_level
, NULL_RTX
);
1318 emit_stack_restore (SAVE_BLOCK
, old_stack_level
, NULL_RTX
);
1322 /* Return the address of the result block. */
1323 return copy_addr_to_reg (XEXP (result
, 0));
1326 /* Perform an untyped return. */
1329 expand_builtin_return (rtx result
)
1331 int size
, align
, regno
;
1332 enum machine_mode mode
;
1334 rtx call_fusage
= 0;
1336 #ifdef POINTERS_EXTEND_UNSIGNED
1337 if (GET_MODE (result
) != Pmode
)
1338 result
= convert_memory_address (Pmode
, result
);
1341 apply_result_size ();
1342 result
= gen_rtx_MEM (BLKmode
, result
);
1344 #ifdef HAVE_untyped_return
1345 if (HAVE_untyped_return
)
1347 emit_jump_insn (gen_untyped_return (result
, result_vector (0, result
)));
1353 /* Restore the return value and note that each value is used. */
1355 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
1356 if ((mode
= apply_result_mode
[regno
]) != VOIDmode
)
1358 align
= GET_MODE_ALIGNMENT (mode
) / BITS_PER_UNIT
;
1359 if (size
% align
!= 0)
1360 size
= CEIL (size
, align
) * align
;
1361 reg
= gen_rtx_REG (mode
, INCOMING_REGNO (regno
));
1362 emit_move_insn (reg
, adjust_address (result
, mode
, size
));
1364 push_to_sequence (call_fusage
);
1365 emit_insn (gen_rtx_USE (VOIDmode
, reg
));
1366 call_fusage
= get_insns ();
1368 size
+= GET_MODE_SIZE (mode
);
1371 /* Put the USE insns before the return. */
1372 emit_insn (call_fusage
);
1374 /* Return whatever values was restored by jumping directly to the end
1376 expand_null_return ();
1379 /* Used by expand_builtin_classify_type and fold_builtin_classify_type. */
1381 static enum type_class
1382 type_to_class (tree type
)
1384 switch (TREE_CODE (type
))
1386 case VOID_TYPE
: return void_type_class
;
1387 case INTEGER_TYPE
: return integer_type_class
;
1388 case CHAR_TYPE
: return char_type_class
;
1389 case ENUMERAL_TYPE
: return enumeral_type_class
;
1390 case BOOLEAN_TYPE
: return boolean_type_class
;
1391 case POINTER_TYPE
: return pointer_type_class
;
1392 case REFERENCE_TYPE
: return reference_type_class
;
1393 case OFFSET_TYPE
: return offset_type_class
;
1394 case REAL_TYPE
: return real_type_class
;
1395 case COMPLEX_TYPE
: return complex_type_class
;
1396 case FUNCTION_TYPE
: return function_type_class
;
1397 case METHOD_TYPE
: return method_type_class
;
1398 case RECORD_TYPE
: return record_type_class
;
1400 case QUAL_UNION_TYPE
: return union_type_class
;
1401 case ARRAY_TYPE
: return (TYPE_STRING_FLAG (type
)
1402 ? string_type_class
: array_type_class
);
1403 case SET_TYPE
: return set_type_class
;
1404 case FILE_TYPE
: return file_type_class
;
1405 case LANG_TYPE
: return lang_type_class
;
1406 default: return no_type_class
;
1410 /* Expand a call to __builtin_classify_type with arguments found in
1414 expand_builtin_classify_type (tree arglist
)
1417 return GEN_INT (type_to_class (TREE_TYPE (TREE_VALUE (arglist
))));
1418 return GEN_INT (no_type_class
);
1421 /* Expand expression EXP, which is a call to __builtin_constant_p. */
1424 expand_builtin_constant_p (tree arglist
, enum machine_mode target_mode
)
1430 arglist
= TREE_VALUE (arglist
);
1432 /* We have taken care of the easy cases during constant folding. This
1433 case is not obvious, so emit (constant_p_rtx (ARGLIST)) and let CSE
1434 get a chance to see if it can deduce whether ARGLIST is constant. */
1436 current_function_calls_constant_p
= 1;
1438 tmp
= expand_expr (arglist
, NULL_RTX
, VOIDmode
, 0);
1439 tmp
= gen_rtx_CONSTANT_P_RTX (target_mode
, tmp
);
1443 /* Return mathematic function equivalent to FN but operating directly on TYPE,
1446 mathfn_built_in (tree type
, enum built_in_function fn
)
1448 enum built_in_function fcode
= NOT_BUILT_IN
;
1449 if (TYPE_MODE (type
) == TYPE_MODE (double_type_node
))
1453 case BUILT_IN_SQRTF
:
1454 case BUILT_IN_SQRTL
:
1455 fcode
= BUILT_IN_SQRT
;
1460 fcode
= BUILT_IN_SIN
;
1465 fcode
= BUILT_IN_COS
;
1470 fcode
= BUILT_IN_EXP
;
1475 fcode
= BUILT_IN_LOG
;
1480 fcode
= BUILT_IN_TAN
;
1483 case BUILT_IN_ATANF
:
1484 case BUILT_IN_ATANL
:
1485 fcode
= BUILT_IN_ATAN
;
1487 case BUILT_IN_FLOOR
:
1488 case BUILT_IN_FLOORF
:
1489 case BUILT_IN_FLOORL
:
1490 fcode
= BUILT_IN_FLOOR
;
1493 case BUILT_IN_CEILF
:
1494 case BUILT_IN_CEILL
:
1495 fcode
= BUILT_IN_CEIL
;
1497 case BUILT_IN_TRUNC
:
1498 case BUILT_IN_TRUNCF
:
1499 case BUILT_IN_TRUNCL
:
1500 fcode
= BUILT_IN_TRUNC
;
1502 case BUILT_IN_ROUND
:
1503 case BUILT_IN_ROUNDF
:
1504 case BUILT_IN_ROUNDL
:
1505 fcode
= BUILT_IN_ROUND
;
1507 case BUILT_IN_NEARBYINT
:
1508 case BUILT_IN_NEARBYINTF
:
1509 case BUILT_IN_NEARBYINTL
:
1510 fcode
= BUILT_IN_NEARBYINT
;
1515 else if (TYPE_MODE (type
) == TYPE_MODE (float_type_node
))
1519 case BUILT_IN_SQRTF
:
1520 case BUILT_IN_SQRTL
:
1521 fcode
= BUILT_IN_SQRTF
;
1526 fcode
= BUILT_IN_SINF
;
1531 fcode
= BUILT_IN_COSF
;
1536 fcode
= BUILT_IN_EXPF
;
1541 fcode
= BUILT_IN_LOGF
;
1546 fcode
= BUILT_IN_TANF
;
1549 case BUILT_IN_ATANF
:
1550 case BUILT_IN_ATANL
:
1551 fcode
= BUILT_IN_ATANF
;
1553 case BUILT_IN_FLOOR
:
1554 case BUILT_IN_FLOORF
:
1555 case BUILT_IN_FLOORL
:
1556 fcode
= BUILT_IN_FLOORF
;
1559 case BUILT_IN_CEILF
:
1560 case BUILT_IN_CEILL
:
1561 fcode
= BUILT_IN_CEILF
;
1563 case BUILT_IN_TRUNC
:
1564 case BUILT_IN_TRUNCF
:
1565 case BUILT_IN_TRUNCL
:
1566 fcode
= BUILT_IN_TRUNCF
;
1568 case BUILT_IN_ROUND
:
1569 case BUILT_IN_ROUNDF
:
1570 case BUILT_IN_ROUNDL
:
1571 fcode
= BUILT_IN_ROUNDF
;
1573 case BUILT_IN_NEARBYINT
:
1574 case BUILT_IN_NEARBYINTF
:
1575 case BUILT_IN_NEARBYINTL
:
1576 fcode
= BUILT_IN_NEARBYINTF
;
1581 else if (TYPE_MODE (type
) == TYPE_MODE (long_double_type_node
))
1585 case BUILT_IN_SQRTF
:
1586 case BUILT_IN_SQRTL
:
1587 fcode
= BUILT_IN_SQRTL
;
1592 fcode
= BUILT_IN_SINL
;
1597 fcode
= BUILT_IN_COSL
;
1602 fcode
= BUILT_IN_EXPL
;
1607 fcode
= BUILT_IN_LOGL
;
1612 fcode
= BUILT_IN_TANL
;
1615 case BUILT_IN_ATANF
:
1616 case BUILT_IN_ATANL
:
1617 fcode
= BUILT_IN_ATANL
;
1619 case BUILT_IN_FLOOR
:
1620 case BUILT_IN_FLOORF
:
1621 case BUILT_IN_FLOORL
:
1622 fcode
= BUILT_IN_FLOORL
;
1625 case BUILT_IN_CEILF
:
1626 case BUILT_IN_CEILL
:
1627 fcode
= BUILT_IN_CEILL
;
1629 case BUILT_IN_TRUNC
:
1630 case BUILT_IN_TRUNCF
:
1631 case BUILT_IN_TRUNCL
:
1632 fcode
= BUILT_IN_TRUNCL
;
1634 case BUILT_IN_ROUND
:
1635 case BUILT_IN_ROUNDF
:
1636 case BUILT_IN_ROUNDL
:
1637 fcode
= BUILT_IN_ROUNDL
;
1639 case BUILT_IN_NEARBYINT
:
1640 case BUILT_IN_NEARBYINTF
:
1641 case BUILT_IN_NEARBYINTL
:
1642 fcode
= BUILT_IN_NEARBYINTL
;
1647 return implicit_built_in_decls
[fcode
];
1650 /* If errno must be maintained, expand the RTL to check if the result,
1651 TARGET, of a built-in function call, EXP, is NaN, and if so set
1655 expand_errno_check (tree exp
, rtx target
)
1657 rtx lab
= gen_label_rtx ();
1659 /* Test the result; if it is NaN, set errno=EDOM because
1660 the argument was not in the domain. */
1661 emit_cmp_and_jump_insns (target
, target
, EQ
, 0, GET_MODE (target
),
1665 /* If this built-in doesn't throw an exception, set errno directly. */
1666 if (TREE_NOTHROW (TREE_OPERAND (TREE_OPERAND (exp
, 0), 0)))
1668 #ifdef GEN_ERRNO_RTX
1669 rtx errno_rtx
= GEN_ERRNO_RTX
;
1672 = gen_rtx_MEM (word_mode
, gen_rtx_SYMBOL_REF (Pmode
, "errno"));
1674 emit_move_insn (errno_rtx
, GEN_INT (TARGET_EDOM
));
1680 /* We can't set errno=EDOM directly; let the library call do it.
1681 Pop the arguments right away in case the call gets deleted. */
1683 expand_call (exp
, target
, 0);
1689 /* Expand a call to one of the builtin math functions (sin, cos, or sqrt).
1690 Return 0 if a normal call should be emitted rather than expanding the
1691 function in-line. EXP is the expression that is a call to the builtin
1692 function; if convenient, the result should be placed in TARGET.
1693 SUBTARGET may be used as the target for computing one of EXP's operands. */
1696 expand_builtin_mathfn (tree exp
, rtx target
, rtx subtarget
)
1698 optab builtin_optab
;
1700 tree fndecl
= TREE_OPERAND (TREE_OPERAND (exp
, 0), 0);
1701 tree arglist
= TREE_OPERAND (exp
, 1);
1702 enum machine_mode mode
;
1703 bool errno_set
= false;
1706 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
1709 arg
= TREE_VALUE (arglist
);
1711 switch (DECL_FUNCTION_CODE (fndecl
))
1716 builtin_optab
= sin_optab
; break;
1720 builtin_optab
= cos_optab
; break;
1722 case BUILT_IN_SQRTF
:
1723 case BUILT_IN_SQRTL
:
1724 errno_set
= ! tree_expr_nonnegative_p (arg
);
1725 builtin_optab
= sqrt_optab
;
1730 errno_set
= true; builtin_optab
= exp_optab
; break;
1734 errno_set
= true; builtin_optab
= log_optab
; break;
1738 builtin_optab
= tan_optab
; break;
1740 case BUILT_IN_ATANF
:
1741 case BUILT_IN_ATANL
:
1742 builtin_optab
= atan_optab
; break;
1743 case BUILT_IN_FLOOR
:
1744 case BUILT_IN_FLOORF
:
1745 case BUILT_IN_FLOORL
:
1746 builtin_optab
= floor_optab
; break;
1748 case BUILT_IN_CEILF
:
1749 case BUILT_IN_CEILL
:
1750 builtin_optab
= ceil_optab
; break;
1751 case BUILT_IN_TRUNC
:
1752 case BUILT_IN_TRUNCF
:
1753 case BUILT_IN_TRUNCL
:
1754 builtin_optab
= trunc_optab
; break;
1755 case BUILT_IN_ROUND
:
1756 case BUILT_IN_ROUNDF
:
1757 case BUILT_IN_ROUNDL
:
1758 builtin_optab
= round_optab
; break;
1759 case BUILT_IN_NEARBYINT
:
1760 case BUILT_IN_NEARBYINTF
:
1761 case BUILT_IN_NEARBYINTL
:
1762 builtin_optab
= nearbyint_optab
; break;
1767 /* Make a suitable register to place result in. */
1768 mode
= TYPE_MODE (TREE_TYPE (exp
));
1769 target
= gen_reg_rtx (mode
);
1771 if (! flag_errno_math
|| ! HONOR_NANS (mode
))
1774 /* Stabilize and compute the argument. */
1776 switch (TREE_CODE (arg
))
1785 /* Wrap the computation of the argument in a SAVE_EXPR, as we
1786 need to expand the argument again in expand_errno_check. This
1787 way, we will not perform side-effects more the once. */
1788 arg
= save_expr (arg
);
1789 arglist
= build_tree_list (NULL_TREE
, arg
);
1790 exp
= build_function_call_expr (fndecl
, arglist
);
1794 op0
= expand_expr (arg
, subtarget
, VOIDmode
, 0);
1799 /* Compute into TARGET.
1800 Set TARGET to wherever the result comes back. */
1801 target
= expand_unop (mode
, builtin_optab
, op0
, target
, 0);
1803 /* If we were unable to expand via the builtin, stop the
1804 sequence (without outputting the insns) and return 0, causing
1805 a call to the library function. */
1813 expand_errno_check (exp
, target
);
1815 /* Output the entire sequence. */
1816 insns
= get_insns ();
1823 /* Expand a call to the builtin binary math functions (pow and atan2).
1824 Return 0 if a normal call should be emitted rather than expanding the
1825 function in-line. EXP is the expression that is a call to the builtin
1826 function; if convenient, the result should be placed in TARGET.
1827 SUBTARGET may be used as the target for computing one of EXP's
1831 expand_builtin_mathfn_2 (tree exp
, rtx target
, rtx subtarget
)
1833 optab builtin_optab
;
1834 rtx op0
, op1
, insns
;
1835 tree fndecl
= TREE_OPERAND (TREE_OPERAND (exp
, 0), 0);
1836 tree arglist
= TREE_OPERAND (exp
, 1);
1837 tree arg0
, arg1
, temp
;
1838 enum machine_mode mode
;
1839 bool errno_set
= true;
1842 if (!validate_arglist (arglist
, REAL_TYPE
, REAL_TYPE
, VOID_TYPE
))
1845 arg0
= TREE_VALUE (arglist
);
1846 arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
1848 switch (DECL_FUNCTION_CODE (fndecl
))
1853 builtin_optab
= pow_optab
; break;
1854 case BUILT_IN_ATAN2
:
1855 case BUILT_IN_ATAN2F
:
1856 case BUILT_IN_ATAN2L
:
1857 builtin_optab
= atan2_optab
; break;
1862 /* Make a suitable register to place result in. */
1863 mode
= TYPE_MODE (TREE_TYPE (exp
));
1864 target
= gen_reg_rtx (mode
);
1866 if (! flag_errno_math
|| ! HONOR_NANS (mode
))
1869 /* Stabilize the arguments. */
1872 switch (TREE_CODE (arg1
))
1878 temp
= TREE_CHAIN (arglist
);
1883 arg1
= save_expr (arg1
);
1884 temp
= build_tree_list (NULL_TREE
, arg1
);
1888 switch (TREE_CODE (arg0
))
1895 arglist
= tree_cons (NULL_TREE
, arg0
, temp
);
1900 arg0
= save_expr (arg0
);
1901 arglist
= tree_cons (NULL_TREE
, arg0
, temp
);
1906 exp
= build_function_call_expr (fndecl
, arglist
);
1909 op0
= expand_expr (arg0
, subtarget
, VOIDmode
, 0);
1910 op1
= expand_expr (arg1
, 0, VOIDmode
, 0);
1915 /* Compute into TARGET.
1916 Set TARGET to wherever the result comes back. */
1917 target
= expand_binop (mode
, builtin_optab
, op0
, op1
,
1918 target
, 0, OPTAB_DIRECT
);
1920 /* If we were unable to expand via the builtin, stop the
1921 sequence (without outputting the insns) and return 0, causing
1922 a call to the library function. */
1930 expand_errno_check (exp
, target
);
1932 /* Output the entire sequence. */
1933 insns
= get_insns ();
1940 /* To evaluate powi(x,n), the floating point value x raised to the
1941 constant integer exponent n, we use a hybrid algorithm that
1942 combines the "window method" with look-up tables. For an
1943 introduction to exponentiation algorithms and "addition chains",
1944 see section 4.6.3, "Evaluation of Powers" of Donald E. Knuth,
1945 "Seminumerical Algorithms", Vol. 2, "The Art of Computer Programming",
1946 3rd Edition, 1998, and Daniel M. Gordon, "A Survey of Fast Exponentiation
1947 Methods", Journal of Algorithms, Vol. 27, pp. 129-146, 1998. */
1949 /* Provide a default value for POWI_MAX_MULTS, the maximum number of
1950 multiplications to inline before calling the system library's pow
1951 function. powi(x,n) requires at worst 2*bits(n)-2 multiplications,
1952 so this default never requires calling pow, powf or powl. */
1954 #ifndef POWI_MAX_MULTS
1955 #define POWI_MAX_MULTS (2*HOST_BITS_PER_WIDE_INT-2)
1958 /* The size of the "optimal power tree" lookup table. All
1959 exponents less than this value are simply looked up in the
1960 powi_table below. This threshold is also used to size the
1961 cache of pseudo registers that hold intermediate results. */
1962 #define POWI_TABLE_SIZE 256
1964 /* The size, in bits of the window, used in the "window method"
1965 exponentiation algorithm. This is equivalent to a radix of
1966 (1<<POWI_WINDOW_SIZE) in the corresponding "m-ary method". */
1967 #define POWI_WINDOW_SIZE 3
1969 /* The following table is an efficient representation of an
1970 "optimal power tree". For each value, i, the corresponding
1971 value, j, in the table states than an optimal evaluation
1972 sequence for calculating pow(x,i) can be found by evaluating
1973 pow(x,j)*pow(x,i-j). An optimal power tree for the first
1974 100 integers is given in Knuth's "Seminumerical algorithms". */
1976 static const unsigned char powi_table
[POWI_TABLE_SIZE
] =
1978 0, 1, 1, 2, 2, 3, 3, 4, /* 0 - 7 */
1979 4, 6, 5, 6, 6, 10, 7, 9, /* 8 - 15 */
1980 8, 16, 9, 16, 10, 12, 11, 13, /* 16 - 23 */
1981 12, 17, 13, 18, 14, 24, 15, 26, /* 24 - 31 */
1982 16, 17, 17, 19, 18, 33, 19, 26, /* 32 - 39 */
1983 20, 25, 21, 40, 22, 27, 23, 44, /* 40 - 47 */
1984 24, 32, 25, 34, 26, 29, 27, 44, /* 48 - 55 */
1985 28, 31, 29, 34, 30, 60, 31, 36, /* 56 - 63 */
1986 32, 64, 33, 34, 34, 46, 35, 37, /* 64 - 71 */
1987 36, 65, 37, 50, 38, 48, 39, 69, /* 72 - 79 */
1988 40, 49, 41, 43, 42, 51, 43, 58, /* 80 - 87 */
1989 44, 64, 45, 47, 46, 59, 47, 76, /* 88 - 95 */
1990 48, 65, 49, 66, 50, 67, 51, 66, /* 96 - 103 */
1991 52, 70, 53, 74, 54, 104, 55, 74, /* 104 - 111 */
1992 56, 64, 57, 69, 58, 78, 59, 68, /* 112 - 119 */
1993 60, 61, 61, 80, 62, 75, 63, 68, /* 120 - 127 */
1994 64, 65, 65, 128, 66, 129, 67, 90, /* 128 - 135 */
1995 68, 73, 69, 131, 70, 94, 71, 88, /* 136 - 143 */
1996 72, 128, 73, 98, 74, 132, 75, 121, /* 144 - 151 */
1997 76, 102, 77, 124, 78, 132, 79, 106, /* 152 - 159 */
1998 80, 97, 81, 160, 82, 99, 83, 134, /* 160 - 167 */
1999 84, 86, 85, 95, 86, 160, 87, 100, /* 168 - 175 */
2000 88, 113, 89, 98, 90, 107, 91, 122, /* 176 - 183 */
2001 92, 111, 93, 102, 94, 126, 95, 150, /* 184 - 191 */
2002 96, 128, 97, 130, 98, 133, 99, 195, /* 192 - 199 */
2003 100, 128, 101, 123, 102, 164, 103, 138, /* 200 - 207 */
2004 104, 145, 105, 146, 106, 109, 107, 149, /* 208 - 215 */
2005 108, 200, 109, 146, 110, 170, 111, 157, /* 216 - 223 */
2006 112, 128, 113, 130, 114, 182, 115, 132, /* 224 - 231 */
2007 116, 200, 117, 132, 118, 158, 119, 206, /* 232 - 239 */
2008 120, 240, 121, 162, 122, 147, 123, 152, /* 240 - 247 */
2009 124, 166, 125, 214, 126, 138, 127, 153, /* 248 - 255 */
2013 /* Return the number of multiplications required to calculate
2014 powi(x,n) where n is less than POWI_TABLE_SIZE. This is a
2015 subroutine of powi_cost. CACHE is an array indicating
2016 which exponents have already been calculated. */
2019 powi_lookup_cost (unsigned HOST_WIDE_INT n
, bool *cache
)
2021 /* If we've already calculated this exponent, then this evaluation
2022 doesn't require any additional multiplications. */
2027 return powi_lookup_cost (n
- powi_table
[n
], cache
)
2028 + powi_lookup_cost (powi_table
[n
], cache
) + 1;
2031 /* Return the number of multiplications required to calculate
2032 powi(x,n) for an arbitrary x, given the exponent N. This
2033 function needs to be kept in sync with expand_powi below. */
2036 powi_cost (HOST_WIDE_INT n
)
2038 bool cache
[POWI_TABLE_SIZE
];
2039 unsigned HOST_WIDE_INT digit
;
2040 unsigned HOST_WIDE_INT val
;
2046 /* Ignore the reciprocal when calculating the cost. */
2047 val
= (n
< 0) ? -n
: n
;
2049 /* Initialize the exponent cache. */
2050 memset (cache
, 0, POWI_TABLE_SIZE
* sizeof (bool));
2055 while (val
>= POWI_TABLE_SIZE
)
2059 digit
= val
& ((1 << POWI_WINDOW_SIZE
) - 1);
2060 result
+= powi_lookup_cost (digit
, cache
)
2061 + POWI_WINDOW_SIZE
+ 1;
2062 val
>>= POWI_WINDOW_SIZE
;
2071 return result
+ powi_lookup_cost (n
, cache
);
2074 /* Recursive subroutine of expand_powi. This function takes the array,
2075 CACHE, of already calculated exponents and an exponent N and returns
2076 an RTX that corresponds to CACHE[1]**N, as calculated in mode MODE. */
2079 expand_powi_1 (enum machine_mode mode
, unsigned HOST_WIDE_INT n
, rtx
*cache
)
2081 unsigned HOST_WIDE_INT digit
;
2085 if (n
< POWI_TABLE_SIZE
)
2090 target
= gen_reg_rtx (mode
);
2093 op0
= expand_powi_1 (mode
, n
- powi_table
[n
], cache
);
2094 op1
= expand_powi_1 (mode
, powi_table
[n
], cache
);
2098 target
= gen_reg_rtx (mode
);
2099 digit
= n
& ((1 << POWI_WINDOW_SIZE
) - 1);
2100 op0
= expand_powi_1 (mode
, n
- digit
, cache
);
2101 op1
= expand_powi_1 (mode
, digit
, cache
);
2105 target
= gen_reg_rtx (mode
);
2106 op0
= expand_powi_1 (mode
, n
>> 1, cache
);
2110 result
= expand_mult (mode
, op0
, op1
, target
, 0);
2111 if (result
!= target
)
2112 emit_move_insn (target
, result
);
2116 /* Expand the RTL to evaluate powi(x,n) in mode MODE. X is the
2117 floating point operand in mode MODE, and N is the exponent. This
2118 function needs to be kept in sync with powi_cost above. */
2121 expand_powi (rtx x
, enum machine_mode mode
, HOST_WIDE_INT n
)
2123 unsigned HOST_WIDE_INT val
;
2124 rtx cache
[POWI_TABLE_SIZE
];
2128 return CONST1_RTX (mode
);
2130 val
= (n
< 0) ? -n
: n
;
2132 memset (cache
, 0, sizeof(cache
));
2135 result
= expand_powi_1 (mode
, (n
< 0) ? -n
: n
, cache
);
2137 /* If the original exponent was negative, reciprocate the result. */
2139 result
= expand_binop (mode
, sdiv_optab
, CONST1_RTX (mode
),
2140 result
, NULL_RTX
, 0, OPTAB_LIB_WIDEN
);
2145 /* Expand a call to the pow built-in mathematical function. Return 0 if
2146 a normal call should be emitted rather than expanding the function
2147 in-line. EXP is the expression that is a call to the builtin
2148 function; if convenient, the result should be placed in TARGET. */
2151 expand_builtin_pow (tree exp
, rtx target
, rtx subtarget
)
2153 tree arglist
= TREE_OPERAND (exp
, 1);
2156 if (! validate_arglist (arglist
, REAL_TYPE
, REAL_TYPE
, VOID_TYPE
))
2159 arg0
= TREE_VALUE (arglist
);
2160 arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
2162 if (flag_unsafe_math_optimizations
2163 && ! flag_errno_math
2165 && TREE_CODE (arg1
) == REAL_CST
2166 && ! TREE_CONSTANT_OVERFLOW (arg1
))
2168 REAL_VALUE_TYPE cint
;
2172 c
= TREE_REAL_CST (arg1
);
2173 n
= real_to_integer (&c
);
2174 real_from_integer (&cint
, VOIDmode
, n
, n
< 0 ? -1 : 0, 0);
2175 if (real_identical (&c
, &cint
)
2176 && powi_cost (n
) <= POWI_MAX_MULTS
)
2178 enum machine_mode mode
= TYPE_MODE (TREE_TYPE (exp
));
2179 rtx op
= expand_expr (arg0
, subtarget
, VOIDmode
, 0);
2180 op
= force_reg (mode
, op
);
2181 return expand_powi (op
, mode
, n
);
2184 return expand_builtin_mathfn_2 (exp
, target
, NULL_RTX
);
2187 /* Expand expression EXP which is a call to the strlen builtin. Return 0
2188 if we failed the caller should emit a normal call, otherwise
2189 try to get the result in TARGET, if convenient. */
2192 expand_builtin_strlen (tree arglist
, rtx target
,
2193 enum machine_mode target_mode
)
2195 if (!validate_arglist (arglist
, POINTER_TYPE
, VOID_TYPE
))
2200 tree len
, src
= TREE_VALUE (arglist
);
2201 rtx result
, src_reg
, char_rtx
, before_strlen
;
2202 enum machine_mode insn_mode
= target_mode
, char_mode
;
2203 enum insn_code icode
= CODE_FOR_nothing
;
2206 /* If the length can be computed at compile-time, return it. */
2207 len
= c_strlen (src
);
2209 return expand_expr (len
, target
, target_mode
, EXPAND_NORMAL
);
2211 align
= get_pointer_alignment (src
, BIGGEST_ALIGNMENT
) / BITS_PER_UNIT
;
2213 /* If SRC is not a pointer type, don't do this operation inline. */
2217 /* Bail out if we can't compute strlen in the right mode. */
2218 while (insn_mode
!= VOIDmode
)
2220 icode
= strlen_optab
->handlers
[(int) insn_mode
].insn_code
;
2221 if (icode
!= CODE_FOR_nothing
)
2224 insn_mode
= GET_MODE_WIDER_MODE (insn_mode
);
2226 if (insn_mode
== VOIDmode
)
2229 /* Make a place to write the result of the instruction. */
2232 && GET_CODE (result
) == REG
2233 && GET_MODE (result
) == insn_mode
2234 && REGNO (result
) >= FIRST_PSEUDO_REGISTER
))
2235 result
= gen_reg_rtx (insn_mode
);
2237 /* Make a place to hold the source address. We will not expand
2238 the actual source until we are sure that the expansion will
2239 not fail -- there are trees that cannot be expanded twice. */
2240 src_reg
= gen_reg_rtx (Pmode
);
2242 /* Mark the beginning of the strlen sequence so we can emit the
2243 source operand later. */
2244 before_strlen
= get_last_insn ();
2246 char_rtx
= const0_rtx
;
2247 char_mode
= insn_data
[(int) icode
].operand
[2].mode
;
2248 if (! (*insn_data
[(int) icode
].operand
[2].predicate
) (char_rtx
,
2250 char_rtx
= copy_to_mode_reg (char_mode
, char_rtx
);
2252 pat
= GEN_FCN (icode
) (result
, gen_rtx_MEM (BLKmode
, src_reg
),
2253 char_rtx
, GEN_INT (align
));
2258 /* Now that we are assured of success, expand the source. */
2260 pat
= memory_address (BLKmode
,
2261 expand_expr (src
, src_reg
, ptr_mode
, EXPAND_SUM
));
2263 emit_move_insn (src_reg
, pat
);
2268 emit_insn_after (pat
, before_strlen
);
2270 emit_insn_before (pat
, get_insns ());
2272 /* Return the value in the proper mode for this function. */
2273 if (GET_MODE (result
) == target_mode
)
2275 else if (target
!= 0)
2276 convert_move (target
, result
, 0);
2278 target
= convert_to_mode (target_mode
, result
, 0);
2284 /* Expand a call to the strstr builtin. Return 0 if we failed the
2285 caller should emit a normal call, otherwise try to get the result
2286 in TARGET, if convenient (and in mode MODE if that's convenient). */
2289 expand_builtin_strstr (tree arglist
, rtx target
, enum machine_mode mode
)
2291 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
2295 tree s1
= TREE_VALUE (arglist
), s2
= TREE_VALUE (TREE_CHAIN (arglist
));
2297 const char *p1
, *p2
;
2306 const char *r
= strstr (p1
, p2
);
2311 /* Return an offset into the constant string argument. */
2312 return expand_expr (fold (build (PLUS_EXPR
, TREE_TYPE (s1
),
2313 s1
, ssize_int (r
- p1
))),
2314 target
, mode
, EXPAND_NORMAL
);
2318 return expand_expr (s1
, target
, mode
, EXPAND_NORMAL
);
2323 fn
= implicit_built_in_decls
[BUILT_IN_STRCHR
];
2327 /* New argument list transforming strstr(s1, s2) to
2328 strchr(s1, s2[0]). */
2330 build_tree_list (NULL_TREE
, build_int_2 (p2
[0], 0));
2331 arglist
= tree_cons (NULL_TREE
, s1
, arglist
);
2332 return expand_expr (build_function_call_expr (fn
, arglist
),
2333 target
, mode
, EXPAND_NORMAL
);
2337 /* Expand a call to the strchr builtin. Return 0 if we failed the
2338 caller should emit a normal call, otherwise try to get the result
2339 in TARGET, if convenient (and in mode MODE if that's convenient). */
2342 expand_builtin_strchr (tree arglist
, rtx target
, enum machine_mode mode
)
2344 if (!validate_arglist (arglist
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
2348 tree s1
= TREE_VALUE (arglist
), s2
= TREE_VALUE (TREE_CHAIN (arglist
));
2351 if (TREE_CODE (s2
) != INTEGER_CST
)
2360 if (target_char_cast (s2
, &c
))
2368 /* Return an offset into the constant string argument. */
2369 return expand_expr (fold (build (PLUS_EXPR
, TREE_TYPE (s1
),
2370 s1
, ssize_int (r
- p1
))),
2371 target
, mode
, EXPAND_NORMAL
);
2374 /* FIXME: Should use here strchrM optab so that ports can optimize
2380 /* Expand a call to the strrchr builtin. Return 0 if we failed the
2381 caller should emit a normal call, otherwise try to get the result
2382 in TARGET, if convenient (and in mode MODE if that's convenient). */
2385 expand_builtin_strrchr (tree arglist
, rtx target
, enum machine_mode mode
)
2387 if (!validate_arglist (arglist
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
2391 tree s1
= TREE_VALUE (arglist
), s2
= TREE_VALUE (TREE_CHAIN (arglist
));
2395 if (TREE_CODE (s2
) != INTEGER_CST
)
2404 if (target_char_cast (s2
, &c
))
2407 r
= strrchr (p1
, c
);
2412 /* Return an offset into the constant string argument. */
2413 return expand_expr (fold (build (PLUS_EXPR
, TREE_TYPE (s1
),
2414 s1
, ssize_int (r
- p1
))),
2415 target
, mode
, EXPAND_NORMAL
);
2418 if (! integer_zerop (s2
))
2421 fn
= implicit_built_in_decls
[BUILT_IN_STRCHR
];
2425 /* Transform strrchr(s1, '\0') to strchr(s1, '\0'). */
2426 return expand_expr (build_function_call_expr (fn
, arglist
),
2427 target
, mode
, EXPAND_NORMAL
);
2431 /* Expand a call to the strpbrk builtin. Return 0 if we failed the
2432 caller should emit a normal call, otherwise try to get the result
2433 in TARGET, if convenient (and in mode MODE if that's convenient). */
2436 expand_builtin_strpbrk (tree arglist
, rtx target
, enum machine_mode mode
)
2438 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
2442 tree s1
= TREE_VALUE (arglist
), s2
= TREE_VALUE (TREE_CHAIN (arglist
));
2444 const char *p1
, *p2
;
2453 const char *r
= strpbrk (p1
, p2
);
2458 /* Return an offset into the constant string argument. */
2459 return expand_expr (fold (build (PLUS_EXPR
, TREE_TYPE (s1
),
2460 s1
, ssize_int (r
- p1
))),
2461 target
, mode
, EXPAND_NORMAL
);
2466 /* strpbrk(x, "") == NULL.
2467 Evaluate and ignore the arguments in case they had
2469 expand_expr (s1
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
2474 return 0; /* Really call strpbrk. */
2476 fn
= implicit_built_in_decls
[BUILT_IN_STRCHR
];
2480 /* New argument list transforming strpbrk(s1, s2) to
2481 strchr(s1, s2[0]). */
2483 build_tree_list (NULL_TREE
, build_int_2 (p2
[0], 0));
2484 arglist
= tree_cons (NULL_TREE
, s1
, arglist
);
2485 return expand_expr (build_function_call_expr (fn
, arglist
),
2486 target
, mode
, EXPAND_NORMAL
);
2490 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
2491 bytes from constant string DATA + OFFSET and return it as target
2495 builtin_memcpy_read_str (void *data
, HOST_WIDE_INT offset
,
2496 enum machine_mode mode
)
2498 const char *str
= (const char *) data
;
2501 || ((unsigned HOST_WIDE_INT
) offset
+ GET_MODE_SIZE (mode
)
2502 > strlen (str
) + 1))
2503 abort (); /* Attempt to read past the end of constant string. */
2505 return c_readstr (str
+ offset
, mode
);
2508 /* Expand a call to the memcpy builtin, with arguments in ARGLIST.
2509 Return 0 if we failed, the caller should emit a normal call,
2510 otherwise try to get the result in TARGET, if convenient (and in
2511 mode MODE if that's convenient). */
2513 expand_builtin_memcpy (tree arglist
, rtx target
, enum machine_mode mode
)
2515 if (!validate_arglist (arglist
,
2516 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
2520 tree dest
= TREE_VALUE (arglist
);
2521 tree src
= TREE_VALUE (TREE_CHAIN (arglist
));
2522 tree len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
2523 const char *src_str
;
2524 unsigned int src_align
= get_pointer_alignment (src
, BIGGEST_ALIGNMENT
);
2525 unsigned int dest_align
2526 = get_pointer_alignment (dest
, BIGGEST_ALIGNMENT
);
2527 rtx dest_mem
, src_mem
, dest_addr
, len_rtx
;
2529 /* If DEST is not a pointer type, call the normal function. */
2530 if (dest_align
== 0)
2533 /* If the LEN parameter is zero, return DEST. */
2534 if (host_integerp (len
, 1) && tree_low_cst (len
, 1) == 0)
2536 /* Evaluate and ignore SRC in case it has side-effects. */
2537 expand_expr (src
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
2538 return expand_expr (dest
, target
, mode
, EXPAND_NORMAL
);
2541 /* If either SRC is not a pointer type, don't do this
2542 operation in-line. */
2546 dest_mem
= get_memory_rtx (dest
);
2547 set_mem_align (dest_mem
, dest_align
);
2548 len_rtx
= expand_expr (len
, NULL_RTX
, VOIDmode
, 0);
2549 src_str
= c_getstr (src
);
2551 /* If SRC is a string constant and block move would be done
2552 by pieces, we can avoid loading the string from memory
2553 and only stored the computed constants. */
2555 && GET_CODE (len_rtx
) == CONST_INT
2556 && (unsigned HOST_WIDE_INT
) INTVAL (len_rtx
) <= strlen (src_str
) + 1
2557 && can_store_by_pieces (INTVAL (len_rtx
), builtin_memcpy_read_str
,
2558 (void *) src_str
, dest_align
))
2560 dest_mem
= store_by_pieces (dest_mem
, INTVAL (len_rtx
),
2561 builtin_memcpy_read_str
,
2562 (void *) src_str
, dest_align
, 0);
2563 dest_mem
= force_operand (XEXP (dest_mem
, 0), NULL_RTX
);
2564 #ifdef POINTERS_EXTEND_UNSIGNED
2565 if (GET_MODE (dest_mem
) != ptr_mode
)
2566 dest_mem
= convert_memory_address (ptr_mode
, dest_mem
);
2571 src_mem
= get_memory_rtx (src
);
2572 set_mem_align (src_mem
, src_align
);
2574 /* Copy word part most expediently. */
2575 dest_addr
= emit_block_move (dest_mem
, src_mem
, len_rtx
,
2580 dest_addr
= force_operand (XEXP (dest_mem
, 0), NULL_RTX
);
2581 #ifdef POINTERS_EXTEND_UNSIGNED
2582 if (GET_MODE (dest_addr
) != ptr_mode
)
2583 dest_addr
= convert_memory_address (ptr_mode
, dest_addr
);
2590 /* Expand a call to the mempcpy builtin, with arguments in ARGLIST.
2591 Return 0 if we failed the caller should emit a normal call,
2592 otherwise try to get the result in TARGET, if convenient (and in
2593 mode MODE if that's convenient). If ENDP is 0 return the
2594 destination pointer, if ENDP is 1 return the end pointer ala
2595 mempcpy, and if ENDP is 2 return the end pointer minus one ala
2599 expand_builtin_mempcpy (tree arglist
, rtx target
, enum machine_mode mode
,
2602 if (!validate_arglist (arglist
,
2603 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
2605 /* If return value is ignored, transform mempcpy into memcpy. */
2606 else if (target
== const0_rtx
)
2608 tree fn
= implicit_built_in_decls
[BUILT_IN_MEMCPY
];
2613 return expand_expr (build_function_call_expr (fn
, arglist
),
2614 target
, mode
, EXPAND_NORMAL
);
2618 tree dest
= TREE_VALUE (arglist
);
2619 tree src
= TREE_VALUE (TREE_CHAIN (arglist
));
2620 tree len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
2621 const char *src_str
;
2622 unsigned int src_align
= get_pointer_alignment (src
, BIGGEST_ALIGNMENT
);
2623 unsigned int dest_align
2624 = get_pointer_alignment (dest
, BIGGEST_ALIGNMENT
);
2625 rtx dest_mem
, src_mem
, len_rtx
;
2627 /* If DEST is not a pointer type or LEN is not constant,
2628 call the normal function. */
2629 if (dest_align
== 0 || !host_integerp (len
, 1))
2632 /* If the LEN parameter is zero, return DEST. */
2633 if (tree_low_cst (len
, 1) == 0)
2635 /* Evaluate and ignore SRC in case it has side-effects. */
2636 expand_expr (src
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
2637 return expand_expr (dest
, target
, mode
, EXPAND_NORMAL
);
2640 /* If either SRC is not a pointer type, don't do this
2641 operation in-line. */
2645 len_rtx
= expand_expr (len
, NULL_RTX
, VOIDmode
, 0);
2646 src_str
= c_getstr (src
);
2648 /* If SRC is a string constant and block move would be done
2649 by pieces, we can avoid loading the string from memory
2650 and only stored the computed constants. */
2652 && GET_CODE (len_rtx
) == CONST_INT
2653 && (unsigned HOST_WIDE_INT
) INTVAL (len_rtx
) <= strlen (src_str
) + 1
2654 && can_store_by_pieces (INTVAL (len_rtx
), builtin_memcpy_read_str
,
2655 (void *) src_str
, dest_align
))
2657 dest_mem
= get_memory_rtx (dest
);
2658 set_mem_align (dest_mem
, dest_align
);
2659 dest_mem
= store_by_pieces (dest_mem
, INTVAL (len_rtx
),
2660 builtin_memcpy_read_str
,
2661 (void *) src_str
, dest_align
, endp
);
2662 dest_mem
= force_operand (XEXP (dest_mem
, 0), NULL_RTX
);
2663 #ifdef POINTERS_EXTEND_UNSIGNED
2664 if (GET_MODE (dest_mem
) != ptr_mode
)
2665 dest_mem
= convert_memory_address (ptr_mode
, dest_mem
);
2670 if (GET_CODE (len_rtx
) == CONST_INT
2671 && can_move_by_pieces (INTVAL (len_rtx
),
2672 MIN (dest_align
, src_align
)))
2674 dest_mem
= get_memory_rtx (dest
);
2675 set_mem_align (dest_mem
, dest_align
);
2676 src_mem
= get_memory_rtx (src
);
2677 set_mem_align (src_mem
, src_align
);
2678 dest_mem
= move_by_pieces (dest_mem
, src_mem
, INTVAL (len_rtx
),
2679 MIN (dest_align
, src_align
), endp
);
2680 dest_mem
= force_operand (XEXP (dest_mem
, 0), NULL_RTX
);
2681 #ifdef POINTERS_EXTEND_UNSIGNED
2682 if (GET_MODE (dest_mem
) != ptr_mode
)
2683 dest_mem
= convert_memory_address (ptr_mode
, dest_mem
);
2692 /* Expand expression EXP, which is a call to the memmove builtin. Return 0
2693 if we failed the caller should emit a normal call. */
2696 expand_builtin_memmove (tree arglist
, rtx target
, enum machine_mode mode
)
2698 if (!validate_arglist (arglist
,
2699 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
2703 tree dest
= TREE_VALUE (arglist
);
2704 tree src
= TREE_VALUE (TREE_CHAIN (arglist
));
2705 tree len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
2707 unsigned int src_align
= get_pointer_alignment (src
, BIGGEST_ALIGNMENT
);
2708 unsigned int dest_align
2709 = get_pointer_alignment (dest
, BIGGEST_ALIGNMENT
);
2711 /* If DEST is not a pointer type, call the normal function. */
2712 if (dest_align
== 0)
2715 /* If the LEN parameter is zero, return DEST. */
2716 if (host_integerp (len
, 1) && tree_low_cst (len
, 1) == 0)
2718 /* Evaluate and ignore SRC in case it has side-effects. */
2719 expand_expr (src
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
2720 return expand_expr (dest
, target
, mode
, EXPAND_NORMAL
);
2723 /* If either SRC is not a pointer type, don't do this
2724 operation in-line. */
2728 /* If src is categorized for a readonly section we can use
2730 if (readonly_data_expr (src
))
2732 tree
const fn
= implicit_built_in_decls
[BUILT_IN_MEMCPY
];
2735 return expand_expr (build_function_call_expr (fn
, arglist
),
2736 target
, mode
, EXPAND_NORMAL
);
2739 /* Otherwise, call the normal function. */
2744 /* Expand expression EXP, which is a call to the bcopy builtin. Return 0
2745 if we failed the caller should emit a normal call. */
2748 expand_builtin_bcopy (tree arglist
)
2750 tree src
, dest
, size
, newarglist
;
2752 if (!validate_arglist (arglist
,
2753 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
2756 src
= TREE_VALUE (arglist
);
2757 dest
= TREE_VALUE (TREE_CHAIN (arglist
));
2758 size
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
2760 /* New argument list transforming bcopy(ptr x, ptr y, int z) to
2761 memmove(ptr y, ptr x, size_t z). This is done this way
2762 so that if it isn't expanded inline, we fallback to
2763 calling bcopy instead of memmove. */
2765 newarglist
= build_tree_list (NULL_TREE
, convert (sizetype
, size
));
2766 newarglist
= tree_cons (NULL_TREE
, src
, newarglist
);
2767 newarglist
= tree_cons (NULL_TREE
, dest
, newarglist
);
2769 return expand_builtin_memmove (newarglist
, const0_rtx
, VOIDmode
);
2772 /* Expand expression EXP, which is a call to the strcpy builtin. Return 0
2773 if we failed the caller should emit a normal call, otherwise try to get
2774 the result in TARGET, if convenient (and in mode MODE if that's
2778 expand_builtin_strcpy (tree arglist
, rtx target
, enum machine_mode mode
)
2780 tree fn
, len
, src
, dst
;
2782 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
2785 fn
= implicit_built_in_decls
[BUILT_IN_MEMCPY
];
2789 src
= TREE_VALUE (TREE_CHAIN (arglist
));
2790 len
= c_strlen (src
);
2794 dst
= TREE_VALUE (arglist
);
2795 len
= size_binop (PLUS_EXPR
, len
, ssize_int (1));
2796 arglist
= build_tree_list (NULL_TREE
, len
);
2797 arglist
= tree_cons (NULL_TREE
, src
, arglist
);
2798 arglist
= tree_cons (NULL_TREE
, dst
, arglist
);
2799 return expand_expr (build_function_call_expr (fn
, arglist
),
2800 target
, mode
, EXPAND_NORMAL
);
2803 /* Expand a call to the stpcpy builtin, with arguments in ARGLIST.
2804 Return 0 if we failed the caller should emit a normal call,
2805 otherwise try to get the result in TARGET, if convenient (and in
2806 mode MODE if that's convenient). */
2809 expand_builtin_stpcpy (tree arglist
, rtx target
, enum machine_mode mode
)
2811 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
2817 /* If return value is ignored, transform stpcpy into strcpy. */
2818 if (target
== const0_rtx
)
2820 tree fn
= implicit_built_in_decls
[BUILT_IN_STRCPY
];
2824 return expand_expr (build_function_call_expr (fn
, arglist
),
2825 target
, mode
, EXPAND_NORMAL
);
2828 /* Ensure we get an actual string whose length can be evaluated at
2829 compile-time, not an expression containing a string. This is
2830 because the latter will potentially produce pessimized code
2831 when used to produce the return value. */
2832 src
= TREE_VALUE (TREE_CHAIN (arglist
));
2833 if (! c_getstr (src
) || ! (len
= c_strlen (src
)))
2836 dst
= TREE_VALUE (arglist
);
2837 len
= fold (size_binop (PLUS_EXPR
, len
, ssize_int (1)));
2838 arglist
= build_tree_list (NULL_TREE
, len
);
2839 arglist
= tree_cons (NULL_TREE
, src
, arglist
);
2840 arglist
= tree_cons (NULL_TREE
, dst
, arglist
);
2841 return expand_builtin_mempcpy (arglist
, target
, mode
, /*endp=*/2);
2845 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
2846 bytes from constant string DATA + OFFSET and return it as target
2850 builtin_strncpy_read_str (void *data
, HOST_WIDE_INT offset
,
2851 enum machine_mode mode
)
2853 const char *str
= (const char *) data
;
2855 if ((unsigned HOST_WIDE_INT
) offset
> strlen (str
))
2858 return c_readstr (str
+ offset
, mode
);
2861 /* Expand expression EXP, which is a call to the strncpy builtin. Return 0
2862 if we failed the caller should emit a normal call. */
2865 expand_builtin_strncpy (tree arglist
, rtx target
, enum machine_mode mode
)
2867 if (!validate_arglist (arglist
,
2868 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
2872 tree slen
= c_strlen (TREE_VALUE (TREE_CHAIN (arglist
)));
2873 tree len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
2876 /* We must be passed a constant len parameter. */
2877 if (TREE_CODE (len
) != INTEGER_CST
)
2880 /* If the len parameter is zero, return the dst parameter. */
2881 if (integer_zerop (len
))
2883 /* Evaluate and ignore the src argument in case it has
2885 expand_expr (TREE_VALUE (TREE_CHAIN (arglist
)), const0_rtx
,
2886 VOIDmode
, EXPAND_NORMAL
);
2887 /* Return the dst parameter. */
2888 return expand_expr (TREE_VALUE (arglist
), target
, mode
,
2892 /* Now, we must be passed a constant src ptr parameter. */
2893 if (slen
== 0 || TREE_CODE (slen
) != INTEGER_CST
)
2896 slen
= size_binop (PLUS_EXPR
, slen
, ssize_int (1));
2898 /* We're required to pad with trailing zeros if the requested
2899 len is greater than strlen(s2)+1. In that case try to
2900 use store_by_pieces, if it fails, punt. */
2901 if (tree_int_cst_lt (slen
, len
))
2903 tree dest
= TREE_VALUE (arglist
);
2904 unsigned int dest_align
2905 = get_pointer_alignment (dest
, BIGGEST_ALIGNMENT
);
2906 const char *p
= c_getstr (TREE_VALUE (TREE_CHAIN (arglist
)));
2909 if (!p
|| dest_align
== 0 || !host_integerp (len
, 1)
2910 || !can_store_by_pieces (tree_low_cst (len
, 1),
2911 builtin_strncpy_read_str
,
2912 (void *) p
, dest_align
))
2915 dest_mem
= get_memory_rtx (dest
);
2916 store_by_pieces (dest_mem
, tree_low_cst (len
, 1),
2917 builtin_strncpy_read_str
,
2918 (void *) p
, dest_align
, 0);
2919 dest_mem
= force_operand (XEXP (dest_mem
, 0), NULL_RTX
);
2920 #ifdef POINTERS_EXTEND_UNSIGNED
2921 if (GET_MODE (dest_mem
) != ptr_mode
)
2922 dest_mem
= convert_memory_address (ptr_mode
, dest_mem
);
2927 /* OK transform into builtin memcpy. */
2928 fn
= implicit_built_in_decls
[BUILT_IN_MEMCPY
];
2931 return expand_expr (build_function_call_expr (fn
, arglist
),
2932 target
, mode
, EXPAND_NORMAL
);
2936 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
2937 bytes from constant string DATA + OFFSET and return it as target
2941 builtin_memset_read_str (void *data
, HOST_WIDE_INT offset ATTRIBUTE_UNUSED
,
2942 enum machine_mode mode
)
2944 const char *c
= (const char *) data
;
2945 char *p
= alloca (GET_MODE_SIZE (mode
));
2947 memset (p
, *c
, GET_MODE_SIZE (mode
));
2949 return c_readstr (p
, mode
);
2952 /* Callback routine for store_by_pieces. Return the RTL of a register
2953 containing GET_MODE_SIZE (MODE) consecutive copies of the unsigned
2954 char value given in the RTL register data. For example, if mode is
2955 4 bytes wide, return the RTL for 0x01010101*data. */
2958 builtin_memset_gen_str (void *data
, HOST_WIDE_INT offset ATTRIBUTE_UNUSED
,
2959 enum machine_mode mode
)
2965 size
= GET_MODE_SIZE (mode
);
2970 memset (p
, 1, size
);
2971 coeff
= c_readstr (p
, mode
);
2973 target
= convert_to_mode (mode
, (rtx
) data
, 1);
2974 target
= expand_mult (mode
, target
, coeff
, NULL_RTX
, 1);
2975 return force_reg (mode
, target
);
2978 /* Expand expression EXP, which is a call to the memset builtin. Return 0
2979 if we failed the caller should emit a normal call, otherwise try to get
2980 the result in TARGET, if convenient (and in mode MODE if that's
2984 expand_builtin_memset (tree arglist
, rtx target
, enum machine_mode mode
)
2986 if (!validate_arglist (arglist
,
2987 POINTER_TYPE
, INTEGER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
2991 tree dest
= TREE_VALUE (arglist
);
2992 tree val
= TREE_VALUE (TREE_CHAIN (arglist
));
2993 tree len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
2996 unsigned int dest_align
2997 = get_pointer_alignment (dest
, BIGGEST_ALIGNMENT
);
2998 rtx dest_mem
, dest_addr
, len_rtx
;
3000 /* If DEST is not a pointer type, don't do this
3001 operation in-line. */
3002 if (dest_align
== 0)
3005 /* If the LEN parameter is zero, return DEST. */
3006 if (host_integerp (len
, 1) && tree_low_cst (len
, 1) == 0)
3008 /* Evaluate and ignore VAL in case it has side-effects. */
3009 expand_expr (val
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
3010 return expand_expr (dest
, target
, mode
, EXPAND_NORMAL
);
3013 if (TREE_CODE (val
) != INTEGER_CST
)
3017 if (!host_integerp (len
, 1))
3020 if (optimize_size
&& tree_low_cst (len
, 1) > 1)
3023 /* Assume that we can memset by pieces if we can store the
3024 * the coefficients by pieces (in the required modes).
3025 * We can't pass builtin_memset_gen_str as that emits RTL. */
3027 if (!can_store_by_pieces (tree_low_cst (len
, 1),
3028 builtin_memset_read_str
,
3032 val
= fold (build1 (CONVERT_EXPR
, unsigned_char_type_node
, val
));
3033 val_rtx
= expand_expr (val
, NULL_RTX
, VOIDmode
, 0);
3034 val_rtx
= force_reg (TYPE_MODE (unsigned_char_type_node
),
3036 dest_mem
= get_memory_rtx (dest
);
3037 store_by_pieces (dest_mem
, tree_low_cst (len
, 1),
3038 builtin_memset_gen_str
,
3039 val_rtx
, dest_align
, 0);
3040 dest_mem
= force_operand (XEXP (dest_mem
, 0), NULL_RTX
);
3041 #ifdef POINTERS_EXTEND_UNSIGNED
3042 if (GET_MODE (dest_mem
) != ptr_mode
)
3043 dest_mem
= convert_memory_address (ptr_mode
, dest_mem
);
3048 if (target_char_cast (val
, &c
))
3053 if (!host_integerp (len
, 1))
3055 if (!can_store_by_pieces (tree_low_cst (len
, 1),
3056 builtin_memset_read_str
, &c
,
3060 dest_mem
= get_memory_rtx (dest
);
3061 store_by_pieces (dest_mem
, tree_low_cst (len
, 1),
3062 builtin_memset_read_str
,
3064 dest_mem
= force_operand (XEXP (dest_mem
, 0), NULL_RTX
);
3065 #ifdef POINTERS_EXTEND_UNSIGNED
3066 if (GET_MODE (dest_mem
) != ptr_mode
)
3067 dest_mem
= convert_memory_address (ptr_mode
, dest_mem
);
3072 len_rtx
= expand_expr (len
, NULL_RTX
, VOIDmode
, 0);
3074 dest_mem
= get_memory_rtx (dest
);
3075 set_mem_align (dest_mem
, dest_align
);
3076 dest_addr
= clear_storage (dest_mem
, len_rtx
);
3080 dest_addr
= force_operand (XEXP (dest_mem
, 0), NULL_RTX
);
3081 #ifdef POINTERS_EXTEND_UNSIGNED
3082 if (GET_MODE (dest_addr
) != ptr_mode
)
3083 dest_addr
= convert_memory_address (ptr_mode
, dest_addr
);
3091 /* Expand expression EXP, which is a call to the bzero builtin. Return 0
3092 if we failed the caller should emit a normal call. */
3095 expand_builtin_bzero (tree arglist
)
3097 tree dest
, size
, newarglist
;
3099 if (!validate_arglist (arglist
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
3102 dest
= TREE_VALUE (arglist
);
3103 size
= TREE_VALUE (TREE_CHAIN (arglist
));
3105 /* New argument list transforming bzero(ptr x, int y) to
3106 memset(ptr x, int 0, size_t y). This is done this way
3107 so that if it isn't expanded inline, we fallback to
3108 calling bzero instead of memset. */
3110 newarglist
= build_tree_list (NULL_TREE
, convert (sizetype
, size
));
3111 newarglist
= tree_cons (NULL_TREE
, integer_zero_node
, newarglist
);
3112 newarglist
= tree_cons (NULL_TREE
, dest
, newarglist
);
3114 return expand_builtin_memset (newarglist
, const0_rtx
, VOIDmode
);
3117 /* Expand expression EXP, which is a call to the memcmp built-in function.
3118 ARGLIST is the argument list for this call. Return 0 if we failed and the
3119 caller should emit a normal call, otherwise try to get the result in
3120 TARGET, if convenient (and in mode MODE, if that's convenient). */
3123 expand_builtin_memcmp (tree exp ATTRIBUTE_UNUSED
, tree arglist
, rtx target
,
3124 enum machine_mode mode
)
3126 tree arg1
, arg2
, len
;
3127 const char *p1
, *p2
;
3129 if (!validate_arglist (arglist
,
3130 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
3133 arg1
= TREE_VALUE (arglist
);
3134 arg2
= TREE_VALUE (TREE_CHAIN (arglist
));
3135 len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
3137 /* If the len parameter is zero, return zero. */
3138 if (host_integerp (len
, 1) && tree_low_cst (len
, 1) == 0)
3140 /* Evaluate and ignore arg1 and arg2 in case they have
3142 expand_expr (arg1
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
3143 expand_expr (arg2
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
3147 p1
= c_getstr (arg1
);
3148 p2
= c_getstr (arg2
);
3150 /* If all arguments are constant, and the value of len is not greater
3151 than the lengths of arg1 and arg2, evaluate at compile-time. */
3152 if (host_integerp (len
, 1) && p1
&& p2
3153 && compare_tree_int (len
, strlen (p1
) + 1) <= 0
3154 && compare_tree_int (len
, strlen (p2
) + 1) <= 0)
3156 const int r
= memcmp (p1
, p2
, tree_low_cst (len
, 1));
3158 return (r
< 0 ? constm1_rtx
: (r
> 0 ? const1_rtx
: const0_rtx
));
3161 /* If len parameter is one, return an expression corresponding to
3162 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
3163 if (host_integerp (len
, 1) && tree_low_cst (len
, 1) == 1)
3165 tree cst_uchar_node
= build_type_variant (unsigned_char_type_node
, 1, 0);
3166 tree cst_uchar_ptr_node
= build_pointer_type (cst_uchar_node
);
3168 fold (build1 (CONVERT_EXPR
, integer_type_node
,
3169 build1 (INDIRECT_REF
, cst_uchar_node
,
3170 build1 (NOP_EXPR
, cst_uchar_ptr_node
, arg1
))));
3172 fold (build1 (CONVERT_EXPR
, integer_type_node
,
3173 build1 (INDIRECT_REF
, cst_uchar_node
,
3174 build1 (NOP_EXPR
, cst_uchar_ptr_node
, arg2
))));
3175 tree result
= fold (build (MINUS_EXPR
, integer_type_node
, ind1
, ind2
));
3176 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
3179 #ifdef HAVE_cmpstrsi
3181 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 /* If we don't have POINTER_TYPE, call the function. */
3193 if (arg1_align
== 0 || arg2_align
== 0)
3196 /* Make a place to write the result of the instruction. */
3199 && GET_CODE (result
) == REG
&& GET_MODE (result
) == insn_mode
3200 && REGNO (result
) >= FIRST_PSEUDO_REGISTER
))
3201 result
= gen_reg_rtx (insn_mode
);
3203 arg1_rtx
= get_memory_rtx (arg1
);
3204 arg2_rtx
= get_memory_rtx (arg2
);
3205 arg3_rtx
= expand_expr (len
, NULL_RTX
, VOIDmode
, 0);
3209 insn
= gen_cmpstrsi (result
, arg1_rtx
, arg2_rtx
, arg3_rtx
,
3210 GEN_INT (MIN (arg1_align
, arg2_align
)));
3215 emit_library_call_value (memcmp_libfunc
, result
, LCT_PURE_MAKE_BLOCK
,
3216 TYPE_MODE (integer_type_node
), 3,
3217 XEXP (arg1_rtx
, 0), Pmode
,
3218 XEXP (arg2_rtx
, 0), Pmode
,
3219 convert_to_mode (TYPE_MODE (sizetype
), arg3_rtx
,
3220 TREE_UNSIGNED (sizetype
)),
3221 TYPE_MODE (sizetype
));
3223 /* Return the value in the proper mode for this function. */
3224 mode
= TYPE_MODE (TREE_TYPE (exp
));
3225 if (GET_MODE (result
) == mode
)
3227 else if (target
!= 0)
3229 convert_move (target
, result
, 0);
3233 return convert_to_mode (mode
, result
, 0);
3240 /* Expand expression EXP, which is a call to the strcmp builtin. Return 0
3241 if we failed the caller should emit a normal call, otherwise try to get
3242 the result in TARGET, if convenient. */
3245 expand_builtin_strcmp (tree exp
, rtx target
, enum machine_mode mode
)
3247 tree arglist
= TREE_OPERAND (exp
, 1);
3249 const char *p1
, *p2
;
3251 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
3254 arg1
= TREE_VALUE (arglist
);
3255 arg2
= TREE_VALUE (TREE_CHAIN (arglist
));
3257 p1
= c_getstr (arg1
);
3258 p2
= c_getstr (arg2
);
3262 const int i
= strcmp (p1
, p2
);
3263 return (i
< 0 ? constm1_rtx
: (i
> 0 ? const1_rtx
: const0_rtx
));
3266 /* If either arg is "", return an expression corresponding to
3267 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
3268 if ((p1
&& *p1
== '\0') || (p2
&& *p2
== '\0'))
3270 tree cst_uchar_node
= build_type_variant (unsigned_char_type_node
, 1, 0);
3271 tree cst_uchar_ptr_node
= build_pointer_type (cst_uchar_node
);
3273 fold (build1 (CONVERT_EXPR
, integer_type_node
,
3274 build1 (INDIRECT_REF
, cst_uchar_node
,
3275 build1 (NOP_EXPR
, cst_uchar_ptr_node
, arg1
))));
3277 fold (build1 (CONVERT_EXPR
, integer_type_node
,
3278 build1 (INDIRECT_REF
, cst_uchar_node
,
3279 build1 (NOP_EXPR
, cst_uchar_ptr_node
, arg2
))));
3280 tree result
= fold (build (MINUS_EXPR
, integer_type_node
, ind1
, ind2
));
3281 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
3284 #ifdef HAVE_cmpstrsi
3287 tree len
, len1
, len2
;
3288 rtx arg1_rtx
, arg2_rtx
, arg3_rtx
;
3292 = get_pointer_alignment (arg1
, BIGGEST_ALIGNMENT
) / BITS_PER_UNIT
;
3294 = get_pointer_alignment (arg2
, BIGGEST_ALIGNMENT
) / BITS_PER_UNIT
;
3295 enum machine_mode insn_mode
3296 = insn_data
[(int) CODE_FOR_cmpstrsi
].operand
[0].mode
;
3298 len1
= c_strlen (arg1
);
3299 len2
= c_strlen (arg2
);
3302 len1
= size_binop (PLUS_EXPR
, ssize_int (1), len1
);
3304 len2
= size_binop (PLUS_EXPR
, ssize_int (1), len2
);
3306 /* If we don't have a constant length for the first, use the length
3307 of the second, if we know it. We don't require a constant for
3308 this case; some cost analysis could be done if both are available
3309 but neither is constant. For now, assume they're equally cheap,
3310 unless one has side effects. If both strings have constant lengths,
3317 else if (TREE_SIDE_EFFECTS (len1
))
3319 else if (TREE_SIDE_EFFECTS (len2
))
3321 else if (TREE_CODE (len1
) != INTEGER_CST
)
3323 else if (TREE_CODE (len2
) != INTEGER_CST
)
3325 else if (tree_int_cst_lt (len1
, len2
))
3330 /* If both arguments have side effects, we cannot optimize. */
3331 if (!len
|| TREE_SIDE_EFFECTS (len
))
3334 /* If we don't have POINTER_TYPE, call the function. */
3335 if (arg1_align
== 0 || arg2_align
== 0)
3338 /* Make a place to write the result of the instruction. */
3341 && GET_CODE (result
) == REG
&& GET_MODE (result
) == insn_mode
3342 && REGNO (result
) >= FIRST_PSEUDO_REGISTER
))
3343 result
= gen_reg_rtx (insn_mode
);
3345 arg1_rtx
= get_memory_rtx (arg1
);
3346 arg2_rtx
= get_memory_rtx (arg2
);
3347 arg3_rtx
= expand_expr (len
, NULL_RTX
, VOIDmode
, 0);
3348 insn
= gen_cmpstrsi (result
, arg1_rtx
, arg2_rtx
, arg3_rtx
,
3349 GEN_INT (MIN (arg1_align
, arg2_align
)));
3355 /* Return the value in the proper mode for this function. */
3356 mode
= TYPE_MODE (TREE_TYPE (exp
));
3357 if (GET_MODE (result
) == mode
)
3360 return convert_to_mode (mode
, result
, 0);
3361 convert_move (target
, result
, 0);
3368 /* Expand expression EXP, which is a call to the strncmp builtin. Return 0
3369 if we failed the caller should emit a normal call, otherwise try to get
3370 the result in TARGET, if convenient. */
3373 expand_builtin_strncmp (tree exp
, rtx target
, enum machine_mode mode
)
3375 tree arglist
= TREE_OPERAND (exp
, 1);
3376 tree arg1
, arg2
, arg3
;
3377 const char *p1
, *p2
;
3379 if (!validate_arglist (arglist
,
3380 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
3383 arg1
= TREE_VALUE (arglist
);
3384 arg2
= TREE_VALUE (TREE_CHAIN (arglist
));
3385 arg3
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
3387 /* If the len parameter is zero, return zero. */
3388 if (host_integerp (arg3
, 1) && tree_low_cst (arg3
, 1) == 0)
3390 /* Evaluate and ignore arg1 and arg2 in case they have
3392 expand_expr (arg1
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
3393 expand_expr (arg2
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
3397 p1
= c_getstr (arg1
);
3398 p2
= c_getstr (arg2
);
3400 /* If all arguments are constant, evaluate at compile-time. */
3401 if (host_integerp (arg3
, 1) && p1
&& p2
)
3403 const int r
= strncmp (p1
, p2
, tree_low_cst (arg3
, 1));
3404 return (r
< 0 ? constm1_rtx
: (r
> 0 ? const1_rtx
: const0_rtx
));
3407 /* If len == 1 or (either string parameter is "" and (len >= 1)),
3408 return (*(const u_char*)arg1 - *(const u_char*)arg2). */
3409 if (host_integerp (arg3
, 1)
3410 && (tree_low_cst (arg3
, 1) == 1
3411 || (tree_low_cst (arg3
, 1) > 1
3412 && ((p1
&& *p1
== '\0') || (p2
&& *p2
== '\0')))))
3414 tree cst_uchar_node
= build_type_variant (unsigned_char_type_node
, 1, 0);
3415 tree cst_uchar_ptr_node
= build_pointer_type (cst_uchar_node
);
3417 fold (build1 (CONVERT_EXPR
, integer_type_node
,
3418 build1 (INDIRECT_REF
, cst_uchar_node
,
3419 build1 (NOP_EXPR
, cst_uchar_ptr_node
, arg1
))));
3421 fold (build1 (CONVERT_EXPR
, integer_type_node
,
3422 build1 (INDIRECT_REF
, cst_uchar_node
,
3423 build1 (NOP_EXPR
, cst_uchar_ptr_node
, arg2
))));
3424 tree result
= fold (build (MINUS_EXPR
, integer_type_node
, ind1
, ind2
));
3425 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
3428 /* If c_strlen can determine an expression for one of the string
3429 lengths, and it doesn't have side effects, then emit cmpstrsi
3430 using length MIN(strlen(string)+1, arg3). */
3431 #ifdef HAVE_cmpstrsi
3434 tree len
, len1
, len2
;
3435 rtx arg1_rtx
, arg2_rtx
, arg3_rtx
;
3439 = get_pointer_alignment (arg1
, BIGGEST_ALIGNMENT
) / BITS_PER_UNIT
;
3441 = get_pointer_alignment (arg2
, BIGGEST_ALIGNMENT
) / BITS_PER_UNIT
;
3442 enum machine_mode insn_mode
3443 = insn_data
[(int) CODE_FOR_cmpstrsi
].operand
[0].mode
;
3445 len1
= c_strlen (arg1
);
3446 len2
= c_strlen (arg2
);
3449 len1
= size_binop (PLUS_EXPR
, ssize_int (1), len1
);
3451 len2
= size_binop (PLUS_EXPR
, ssize_int (1), len2
);
3453 /* If we don't have a constant length for the first, use the length
3454 of the second, if we know it. We don't require a constant for
3455 this case; some cost analysis could be done if both are available
3456 but neither is constant. For now, assume they're equally cheap,
3457 unless one has side effects. If both strings have constant lengths,
3464 else if (TREE_SIDE_EFFECTS (len1
))
3466 else if (TREE_SIDE_EFFECTS (len2
))
3468 else if (TREE_CODE (len1
) != INTEGER_CST
)
3470 else if (TREE_CODE (len2
) != INTEGER_CST
)
3472 else if (tree_int_cst_lt (len1
, len2
))
3477 /* If both arguments have side effects, we cannot optimize. */
3478 if (!len
|| TREE_SIDE_EFFECTS (len
))
3481 /* The actual new length parameter is MIN(len,arg3). */
3482 len
= fold (build (MIN_EXPR
, TREE_TYPE (len
), len
, arg3
));
3484 /* If we don't have POINTER_TYPE, call the function. */
3485 if (arg1_align
== 0 || arg2_align
== 0)
3488 /* Make a place to write the result of the instruction. */
3491 && GET_CODE (result
) == REG
&& GET_MODE (result
) == insn_mode
3492 && REGNO (result
) >= FIRST_PSEUDO_REGISTER
))
3493 result
= gen_reg_rtx (insn_mode
);
3495 arg1_rtx
= get_memory_rtx (arg1
);
3496 arg2_rtx
= get_memory_rtx (arg2
);
3497 arg3_rtx
= expand_expr (len
, NULL_RTX
, VOIDmode
, 0);
3498 insn
= gen_cmpstrsi (result
, arg1_rtx
, arg2_rtx
, arg3_rtx
,
3499 GEN_INT (MIN (arg1_align
, arg2_align
)));
3505 /* Return the value in the proper mode for this function. */
3506 mode
= TYPE_MODE (TREE_TYPE (exp
));
3507 if (GET_MODE (result
) == mode
)
3510 return convert_to_mode (mode
, result
, 0);
3511 convert_move (target
, result
, 0);
3518 /* Expand expression EXP, which is a call to the strcat builtin.
3519 Return 0 if we failed the caller should emit a normal call,
3520 otherwise try to get the result in TARGET, if convenient. */
3523 expand_builtin_strcat (tree arglist
, rtx target
, enum machine_mode mode
)
3525 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
3529 tree dst
= TREE_VALUE (arglist
),
3530 src
= TREE_VALUE (TREE_CHAIN (arglist
));
3531 const char *p
= c_getstr (src
);
3533 /* If the string length is zero, return the dst parameter. */
3534 if (p
&& *p
== '\0')
3535 return expand_expr (dst
, target
, mode
, EXPAND_NORMAL
);
3541 /* Expand expression EXP, which is a call to the strncat builtin.
3542 Return 0 if we failed the caller should emit a normal call,
3543 otherwise try to get the result in TARGET, if convenient. */
3546 expand_builtin_strncat (tree arglist
, rtx target
, enum machine_mode mode
)
3548 if (!validate_arglist (arglist
,
3549 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
3553 tree dst
= TREE_VALUE (arglist
),
3554 src
= TREE_VALUE (TREE_CHAIN (arglist
)),
3555 len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
3556 const char *p
= c_getstr (src
);
3558 /* If the requested length is zero, or the src parameter string
3559 length is zero, return the dst parameter. */
3560 if (integer_zerop (len
) || (p
&& *p
== '\0'))
3562 /* Evaluate and ignore the src and len parameters in case
3563 they have side-effects. */
3564 expand_expr (src
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
3565 expand_expr (len
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
3566 return expand_expr (dst
, target
, mode
, EXPAND_NORMAL
);
3569 /* If the requested len is greater than or equal to the string
3570 length, call strcat. */
3571 if (TREE_CODE (len
) == INTEGER_CST
&& p
3572 && compare_tree_int (len
, strlen (p
)) >= 0)
3575 = tree_cons (NULL_TREE
, dst
, build_tree_list (NULL_TREE
, src
));
3576 tree fn
= implicit_built_in_decls
[BUILT_IN_STRCAT
];
3578 /* If the replacement _DECL isn't initialized, don't do the
3583 return expand_expr (build_function_call_expr (fn
, newarglist
),
3584 target
, mode
, EXPAND_NORMAL
);
3590 /* Expand expression EXP, which is a call to the strspn builtin.
3591 Return 0 if we failed the caller should emit a normal call,
3592 otherwise try to get the result in TARGET, if convenient. */
3595 expand_builtin_strspn (tree arglist
, rtx target
, enum machine_mode mode
)
3597 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
3601 tree s1
= TREE_VALUE (arglist
), s2
= TREE_VALUE (TREE_CHAIN (arglist
));
3602 const char *p1
= c_getstr (s1
), *p2
= c_getstr (s2
);
3604 /* If both arguments are constants, evaluate at compile-time. */
3607 const size_t r
= strspn (p1
, p2
);
3608 return expand_expr (size_int (r
), target
, mode
, EXPAND_NORMAL
);
3611 /* If either argument is "", return 0. */
3612 if ((p1
&& *p1
== '\0') || (p2
&& *p2
== '\0'))
3614 /* Evaluate and ignore both arguments in case either one has
3616 expand_expr (s1
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
3617 expand_expr (s2
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
3624 /* Expand expression EXP, which is a call to the strcspn builtin.
3625 Return 0 if we failed the caller should emit a normal call,
3626 otherwise try to get the result in TARGET, if convenient. */
3629 expand_builtin_strcspn (tree arglist
, rtx target
, enum machine_mode mode
)
3631 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
3635 tree s1
= TREE_VALUE (arglist
), s2
= TREE_VALUE (TREE_CHAIN (arglist
));
3636 const char *p1
= c_getstr (s1
), *p2
= c_getstr (s2
);
3638 /* If both arguments are constants, evaluate at compile-time. */
3641 const size_t r
= strcspn (p1
, p2
);
3642 return expand_expr (size_int (r
), target
, mode
, EXPAND_NORMAL
);
3645 /* If the first argument is "", return 0. */
3646 if (p1
&& *p1
== '\0')
3648 /* Evaluate and ignore argument s2 in case it has
3650 expand_expr (s2
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
3654 /* If the second argument is "", return __builtin_strlen(s1). */
3655 if (p2
&& *p2
== '\0')
3657 tree newarglist
= build_tree_list (NULL_TREE
, s1
),
3658 fn
= implicit_built_in_decls
[BUILT_IN_STRLEN
];
3660 /* If the replacement _DECL isn't initialized, don't do the
3665 return expand_expr (build_function_call_expr (fn
, newarglist
),
3666 target
, mode
, EXPAND_NORMAL
);
3672 /* Expand a call to __builtin_saveregs, generating the result in TARGET,
3673 if that's convenient. */
3676 expand_builtin_saveregs (void)
3680 /* Don't do __builtin_saveregs more than once in a function.
3681 Save the result of the first call and reuse it. */
3682 if (saveregs_value
!= 0)
3683 return saveregs_value
;
3685 /* When this function is called, it means that registers must be
3686 saved on entry to this function. So we migrate the call to the
3687 first insn of this function. */
3691 #ifdef EXPAND_BUILTIN_SAVEREGS
3692 /* Do whatever the machine needs done in this case. */
3693 val
= EXPAND_BUILTIN_SAVEREGS ();
3695 /* ??? We used to try and build up a call to the out of line function,
3696 guessing about what registers needed saving etc. This became much
3697 harder with __builtin_va_start, since we don't have a tree for a
3698 call to __builtin_saveregs to fall back on. There was exactly one
3699 port (i860) that used this code, and I'm unconvinced it could actually
3700 handle the general case. So we no longer try to handle anything
3701 weird and make the backend absorb the evil. */
3703 error ("__builtin_saveregs not supported by this target");
3710 saveregs_value
= val
;
3712 /* Put the insns after the NOTE that starts the function. If this
3713 is inside a start_sequence, make the outer-level insn chain current, so
3714 the code is placed at the start of the function. */
3715 push_topmost_sequence ();
3716 emit_insn_after (seq
, get_insns ());
3717 pop_topmost_sequence ();
3722 /* __builtin_args_info (N) returns word N of the arg space info
3723 for the current function. The number and meanings of words
3724 is controlled by the definition of CUMULATIVE_ARGS. */
3727 expand_builtin_args_info (tree arglist
)
3729 int nwords
= sizeof (CUMULATIVE_ARGS
) / sizeof (int);
3730 int *word_ptr
= (int *) ¤t_function_args_info
;
3732 if (sizeof (CUMULATIVE_ARGS
) % sizeof (int) != 0)
3737 if (!host_integerp (TREE_VALUE (arglist
), 0))
3738 error ("argument of `__builtin_args_info' must be constant");
3741 HOST_WIDE_INT wordnum
= tree_low_cst (TREE_VALUE (arglist
), 0);
3743 if (wordnum
< 0 || wordnum
>= nwords
)
3744 error ("argument of `__builtin_args_info' out of range");
3746 return GEN_INT (word_ptr
[wordnum
]);
3750 error ("missing argument in `__builtin_args_info'");
3755 /* Expand ARGLIST, from a call to __builtin_next_arg. */
3758 expand_builtin_next_arg (tree arglist
)
3760 tree fntype
= TREE_TYPE (current_function_decl
);
3762 if (TYPE_ARG_TYPES (fntype
) == 0
3763 || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype
)))
3766 error ("`va_start' used in function with fixed args");
3772 tree last_parm
= tree_last (DECL_ARGUMENTS (current_function_decl
));
3773 tree arg
= TREE_VALUE (arglist
);
3775 /* Strip off all nops for the sake of the comparison. This
3776 is not quite the same as STRIP_NOPS. It does more.
3777 We must also strip off INDIRECT_EXPR for C++ reference
3779 while (TREE_CODE (arg
) == NOP_EXPR
3780 || TREE_CODE (arg
) == CONVERT_EXPR
3781 || TREE_CODE (arg
) == NON_LVALUE_EXPR
3782 || TREE_CODE (arg
) == INDIRECT_REF
)
3783 arg
= TREE_OPERAND (arg
, 0);
3784 if (arg
!= last_parm
)
3785 warning ("second parameter of `va_start' not last named argument");
3788 /* Evidently an out of date version of <stdarg.h>; can't validate
3789 va_start's second argument, but can still work as intended. */
3790 warning ("`__builtin_next_arg' called without an argument");
3792 return expand_binop (Pmode
, add_optab
,
3793 current_function_internal_arg_pointer
,
3794 current_function_arg_offset_rtx
,
3795 NULL_RTX
, 0, OPTAB_LIB_WIDEN
);
3798 /* Make it easier for the backends by protecting the valist argument
3799 from multiple evaluations. */
3802 stabilize_va_list (tree valist
, int needs_lvalue
)
3804 if (TREE_CODE (va_list_type_node
) == ARRAY_TYPE
)
3806 if (TREE_SIDE_EFFECTS (valist
))
3807 valist
= save_expr (valist
);
3809 /* For this case, the backends will be expecting a pointer to
3810 TREE_TYPE (va_list_type_node), but it's possible we've
3811 actually been given an array (an actual va_list_type_node).
3813 if (TREE_CODE (TREE_TYPE (valist
)) == ARRAY_TYPE
)
3815 tree p1
= build_pointer_type (TREE_TYPE (va_list_type_node
));
3816 tree p2
= build_pointer_type (va_list_type_node
);
3818 valist
= build1 (ADDR_EXPR
, p2
, valist
);
3819 valist
= fold (build1 (NOP_EXPR
, p1
, valist
));
3828 if (! TREE_SIDE_EFFECTS (valist
))
3831 pt
= build_pointer_type (va_list_type_node
);
3832 valist
= fold (build1 (ADDR_EXPR
, pt
, valist
));
3833 TREE_SIDE_EFFECTS (valist
) = 1;
3836 if (TREE_SIDE_EFFECTS (valist
))
3837 valist
= save_expr (valist
);
3838 valist
= fold (build1 (INDIRECT_REF
, TREE_TYPE (TREE_TYPE (valist
)),
3845 /* The "standard" implementation of va_start: just assign `nextarg' to
3849 std_expand_builtin_va_start (tree valist
, rtx nextarg
)
3853 t
= build (MODIFY_EXPR
, TREE_TYPE (valist
), valist
,
3854 make_tree (ptr_type_node
, nextarg
));
3855 TREE_SIDE_EFFECTS (t
) = 1;
3857 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
3860 /* Expand ARGLIST, from a call to __builtin_va_start. */
3863 expand_builtin_va_start (tree arglist
)
3868 chain
= TREE_CHAIN (arglist
);
3870 if (TREE_CHAIN (chain
))
3871 error ("too many arguments to function `va_start'");
3873 nextarg
= expand_builtin_next_arg (chain
);
3874 valist
= stabilize_va_list (TREE_VALUE (arglist
), 1);
3876 #ifdef EXPAND_BUILTIN_VA_START
3877 EXPAND_BUILTIN_VA_START (valist
, nextarg
);
3879 std_expand_builtin_va_start (valist
, nextarg
);
3885 /* The "standard" implementation of va_arg: read the value from the
3886 current (padded) address and increment by the (padded) size. */
3889 std_expand_builtin_va_arg (tree valist
, tree type
)
3891 tree addr_tree
, t
, type_size
= NULL
;
3892 tree align
, alignm1
;
3896 /* Compute the rounded size of the type. */
3897 align
= size_int (PARM_BOUNDARY
/ BITS_PER_UNIT
);
3898 alignm1
= size_int (PARM_BOUNDARY
/ BITS_PER_UNIT
- 1);
3899 if (type
== error_mark_node
3900 || (type_size
= TYPE_SIZE_UNIT (TYPE_MAIN_VARIANT (type
))) == NULL
3901 || TREE_OVERFLOW (type_size
))
3902 rounded_size
= size_zero_node
;
3904 rounded_size
= fold (build (MULT_EXPR
, sizetype
,
3905 fold (build (TRUNC_DIV_EXPR
, sizetype
,
3906 fold (build (PLUS_EXPR
, sizetype
,
3907 type_size
, alignm1
)),
3913 if (PAD_VARARGS_DOWN
&& ! integer_zerop (rounded_size
))
3915 /* Small args are padded downward. */
3916 addr_tree
= fold (build (PLUS_EXPR
, TREE_TYPE (addr_tree
), addr_tree
,
3917 fold (build (COND_EXPR
, sizetype
,
3918 fold (build (GT_EXPR
, sizetype
,
3922 fold (build (MINUS_EXPR
, sizetype
,
3927 addr
= expand_expr (addr_tree
, NULL_RTX
, Pmode
, EXPAND_NORMAL
);
3928 addr
= copy_to_reg (addr
);
3930 /* Compute new value for AP. */
3931 if (! integer_zerop (rounded_size
))
3933 t
= build (MODIFY_EXPR
, TREE_TYPE (valist
), valist
,
3934 build (PLUS_EXPR
, TREE_TYPE (valist
), valist
,
3936 TREE_SIDE_EFFECTS (t
) = 1;
3937 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
3943 /* Expand __builtin_va_arg, which is not really a builtin function, but
3944 a very special sort of operator. */
3947 expand_builtin_va_arg (tree valist
, tree type
)
3950 tree promoted_type
, want_va_type
, have_va_type
;
3952 /* Verify that valist is of the proper type. */
3954 want_va_type
= va_list_type_node
;
3955 have_va_type
= TREE_TYPE (valist
);
3956 if (TREE_CODE (want_va_type
) == ARRAY_TYPE
)
3958 /* If va_list is an array type, the argument may have decayed
3959 to a pointer type, e.g. by being passed to another function.
3960 In that case, unwrap both types so that we can compare the
3961 underlying records. */
3962 if (TREE_CODE (have_va_type
) == ARRAY_TYPE
3963 || TREE_CODE (have_va_type
) == POINTER_TYPE
)
3965 want_va_type
= TREE_TYPE (want_va_type
);
3966 have_va_type
= TREE_TYPE (have_va_type
);
3969 if (TYPE_MAIN_VARIANT (want_va_type
) != TYPE_MAIN_VARIANT (have_va_type
))
3971 error ("first argument to `va_arg' not of type `va_list'");
3975 /* Generate a diagnostic for requesting data of a type that cannot
3976 be passed through `...' due to type promotion at the call site. */
3977 else if ((promoted_type
= (*lang_hooks
.types
.type_promotes_to
) (type
))
3980 const char *name
= "<anonymous type>", *pname
= 0;
3981 static bool gave_help
;
3983 if (TYPE_NAME (type
))
3985 if (TREE_CODE (TYPE_NAME (type
)) == IDENTIFIER_NODE
)
3986 name
= IDENTIFIER_POINTER (TYPE_NAME (type
));
3987 else if (TREE_CODE (TYPE_NAME (type
)) == TYPE_DECL
3988 && DECL_NAME (TYPE_NAME (type
)))
3989 name
= IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type
)));
3991 if (TYPE_NAME (promoted_type
))
3993 if (TREE_CODE (TYPE_NAME (promoted_type
)) == IDENTIFIER_NODE
)
3994 pname
= IDENTIFIER_POINTER (TYPE_NAME (promoted_type
));
3995 else if (TREE_CODE (TYPE_NAME (promoted_type
)) == TYPE_DECL
3996 && DECL_NAME (TYPE_NAME (promoted_type
)))
3997 pname
= IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (promoted_type
)));
4000 /* Unfortunately, this is merely undefined, rather than a constraint
4001 violation, so we cannot make this an error. If this call is never
4002 executed, the program is still strictly conforming. */
4003 warning ("`%s' is promoted to `%s' when passed through `...'",
4008 warning ("(so you should pass `%s' not `%s' to `va_arg')",
4012 /* We can, however, treat "undefined" any way we please.
4013 Call abort to encourage the user to fix the program. */
4014 expand_builtin_trap ();
4016 /* This is dead code, but go ahead and finish so that the
4017 mode of the result comes out right. */
4022 /* Make it easier for the backends by protecting the valist argument
4023 from multiple evaluations. */
4024 valist
= stabilize_va_list (valist
, 0);
4026 #ifdef EXPAND_BUILTIN_VA_ARG
4027 addr
= EXPAND_BUILTIN_VA_ARG (valist
, type
);
4029 addr
= std_expand_builtin_va_arg (valist
, type
);
4033 #ifdef POINTERS_EXTEND_UNSIGNED
4034 if (GET_MODE (addr
) != Pmode
)
4035 addr
= convert_memory_address (Pmode
, addr
);
4038 result
= gen_rtx_MEM (TYPE_MODE (type
), addr
);
4039 set_mem_alias_set (result
, get_varargs_alias_set ());
4044 /* Expand ARGLIST, from a call to __builtin_va_end. */
4047 expand_builtin_va_end (tree arglist
)
4049 tree valist
= TREE_VALUE (arglist
);
4051 #ifdef EXPAND_BUILTIN_VA_END
4052 valist
= stabilize_va_list (valist
, 0);
4053 EXPAND_BUILTIN_VA_END (arglist
);
4055 /* Evaluate for side effects, if needed. I hate macros that don't
4057 if (TREE_SIDE_EFFECTS (valist
))
4058 expand_expr (valist
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
4064 /* Expand ARGLIST, from a call to __builtin_va_copy. We do this as a
4065 builtin rather than just as an assignment in stdarg.h because of the
4066 nastiness of array-type va_list types. */
4069 expand_builtin_va_copy (tree arglist
)
4073 dst
= TREE_VALUE (arglist
);
4074 src
= TREE_VALUE (TREE_CHAIN (arglist
));
4076 dst
= stabilize_va_list (dst
, 1);
4077 src
= stabilize_va_list (src
, 0);
4079 if (TREE_CODE (va_list_type_node
) != ARRAY_TYPE
)
4081 t
= build (MODIFY_EXPR
, va_list_type_node
, dst
, src
);
4082 TREE_SIDE_EFFECTS (t
) = 1;
4083 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
4087 rtx dstb
, srcb
, size
;
4089 /* Evaluate to pointers. */
4090 dstb
= expand_expr (dst
, NULL_RTX
, Pmode
, EXPAND_NORMAL
);
4091 srcb
= expand_expr (src
, NULL_RTX
, Pmode
, EXPAND_NORMAL
);
4092 size
= expand_expr (TYPE_SIZE_UNIT (va_list_type_node
), NULL_RTX
,
4093 VOIDmode
, EXPAND_NORMAL
);
4095 #ifdef POINTERS_EXTEND_UNSIGNED
4096 if (GET_MODE (dstb
) != Pmode
)
4097 dstb
= convert_memory_address (Pmode
, dstb
);
4099 if (GET_MODE (srcb
) != Pmode
)
4100 srcb
= convert_memory_address (Pmode
, srcb
);
4103 /* "Dereference" to BLKmode memories. */
4104 dstb
= gen_rtx_MEM (BLKmode
, dstb
);
4105 set_mem_alias_set (dstb
, get_alias_set (TREE_TYPE (TREE_TYPE (dst
))));
4106 set_mem_align (dstb
, TYPE_ALIGN (va_list_type_node
));
4107 srcb
= gen_rtx_MEM (BLKmode
, srcb
);
4108 set_mem_alias_set (srcb
, get_alias_set (TREE_TYPE (TREE_TYPE (src
))));
4109 set_mem_align (srcb
, TYPE_ALIGN (va_list_type_node
));
4112 emit_block_move (dstb
, srcb
, size
, BLOCK_OP_NORMAL
);
4118 /* Expand a call to one of the builtin functions __builtin_frame_address or
4119 __builtin_return_address. */
4122 expand_builtin_frame_address (tree fndecl
, tree arglist
)
4124 /* The argument must be a nonnegative integer constant.
4125 It counts the number of frames to scan up the stack.
4126 The value is the return address saved in that frame. */
4128 /* Warning about missing arg was already issued. */
4130 else if (! host_integerp (TREE_VALUE (arglist
), 1))
4132 if (DECL_FUNCTION_CODE (fndecl
) == BUILT_IN_FRAME_ADDRESS
)
4133 error ("invalid arg to `__builtin_frame_address'");
4135 error ("invalid arg to `__builtin_return_address'");
4141 = expand_builtin_return_addr (DECL_FUNCTION_CODE (fndecl
),
4142 tree_low_cst (TREE_VALUE (arglist
), 1),
4143 hard_frame_pointer_rtx
);
4145 /* Some ports cannot access arbitrary stack frames. */
4148 if (DECL_FUNCTION_CODE (fndecl
) == BUILT_IN_FRAME_ADDRESS
)
4149 warning ("unsupported arg to `__builtin_frame_address'");
4151 warning ("unsupported arg to `__builtin_return_address'");
4155 /* For __builtin_frame_address, return what we've got. */
4156 if (DECL_FUNCTION_CODE (fndecl
) == BUILT_IN_FRAME_ADDRESS
)
4159 if (GET_CODE (tem
) != REG
4160 && ! CONSTANT_P (tem
))
4161 tem
= copy_to_mode_reg (Pmode
, tem
);
4166 /* Expand a call to the alloca builtin, with arguments ARGLIST. Return 0 if
4167 we failed and the caller should emit a normal call, otherwise try to get
4168 the result in TARGET, if convenient. */
4171 expand_builtin_alloca (tree arglist
, rtx target
)
4176 if (!validate_arglist (arglist
, INTEGER_TYPE
, VOID_TYPE
))
4179 /* Compute the argument. */
4180 op0
= expand_expr (TREE_VALUE (arglist
), NULL_RTX
, VOIDmode
, 0);
4182 /* Allocate the desired space. */
4183 result
= allocate_dynamic_stack_space (op0
, target
, BITS_PER_UNIT
);
4185 #ifdef POINTERS_EXTEND_UNSIGNED
4186 if (GET_MODE (result
) != ptr_mode
)
4187 result
= convert_memory_address (ptr_mode
, result
);
4193 /* Expand a call to a unary builtin. The arguments are in ARGLIST.
4194 Return 0 if a normal call should be emitted rather than expanding the
4195 function in-line. If convenient, the result should be placed in TARGET.
4196 SUBTARGET may be used as the target for computing one of EXP's operands. */
4199 expand_builtin_unop (enum machine_mode target_mode
, tree arglist
, rtx target
,
4200 rtx subtarget
, optab op_optab
)
4203 if (!validate_arglist (arglist
, INTEGER_TYPE
, VOID_TYPE
))
4206 /* Compute the argument. */
4207 op0
= expand_expr (TREE_VALUE (arglist
), subtarget
, VOIDmode
, 0);
4208 /* Compute op, into TARGET if possible.
4209 Set TARGET to wherever the result comes back. */
4210 target
= expand_unop (TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist
))),
4211 op_optab
, op0
, target
, 1);
4215 return convert_to_mode (target_mode
, target
, 0);
4218 /* If the string passed to fputs is a constant and is one character
4219 long, we attempt to transform this call into __builtin_fputc(). */
4222 expand_builtin_fputs (tree arglist
, int ignore
, int unlocked
)
4225 tree fn_fputc
= unlocked
? implicit_built_in_decls
[BUILT_IN_FPUTC_UNLOCKED
]
4226 : implicit_built_in_decls
[BUILT_IN_FPUTC
];
4227 tree fn_fwrite
= unlocked
? implicit_built_in_decls
[BUILT_IN_FWRITE_UNLOCKED
]
4228 : implicit_built_in_decls
[BUILT_IN_FWRITE
];
4230 /* If the return value is used, or the replacement _DECL isn't
4231 initialized, don't do the transformation. */
4232 if (!ignore
|| !fn_fputc
|| !fn_fwrite
)
4235 /* Verify the arguments in the original call. */
4236 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
4239 /* Get the length of the string passed to fputs. If the length
4240 can't be determined, punt. */
4241 if (!(len
= c_strlen (TREE_VALUE (arglist
)))
4242 || TREE_CODE (len
) != INTEGER_CST
)
4245 switch (compare_tree_int (len
, 1))
4247 case -1: /* length is 0, delete the call entirely . */
4249 /* Evaluate and ignore the argument in case it has
4251 expand_expr (TREE_VALUE (TREE_CHAIN (arglist
)), const0_rtx
,
4252 VOIDmode
, EXPAND_NORMAL
);
4255 case 0: /* length is 1, call fputc. */
4257 const char *p
= c_getstr (TREE_VALUE (arglist
));
4261 /* New argument list transforming fputs(string, stream) to
4262 fputc(string[0], stream). */
4264 build_tree_list (NULL_TREE
, TREE_VALUE (TREE_CHAIN (arglist
)));
4266 tree_cons (NULL_TREE
, build_int_2 (p
[0], 0), arglist
);
4272 case 1: /* length is greater than 1, call fwrite. */
4276 /* If optimizing for size keep fputs. */
4279 string_arg
= TREE_VALUE (arglist
);
4280 /* New argument list transforming fputs(string, stream) to
4281 fwrite(string, 1, len, stream). */
4282 arglist
= build_tree_list (NULL_TREE
, TREE_VALUE (TREE_CHAIN (arglist
)));
4283 arglist
= tree_cons (NULL_TREE
, len
, arglist
);
4284 arglist
= tree_cons (NULL_TREE
, size_one_node
, arglist
);
4285 arglist
= tree_cons (NULL_TREE
, string_arg
, arglist
);
4293 return expand_expr (build_function_call_expr (fn
, arglist
),
4294 (ignore
? const0_rtx
: NULL_RTX
),
4295 VOIDmode
, EXPAND_NORMAL
);
4298 /* Expand a call to __builtin_expect. We return our argument and emit a
4299 NOTE_INSN_EXPECTED_VALUE note. This is the expansion of __builtin_expect in
4300 a non-jump context. */
4303 expand_builtin_expect (tree arglist
, rtx target
)
4308 if (arglist
== NULL_TREE
4309 || TREE_CHAIN (arglist
) == NULL_TREE
)
4311 exp
= TREE_VALUE (arglist
);
4312 c
= TREE_VALUE (TREE_CHAIN (arglist
));
4314 if (TREE_CODE (c
) != INTEGER_CST
)
4316 error ("second arg to `__builtin_expect' must be a constant");
4317 c
= integer_zero_node
;
4320 target
= expand_expr (exp
, target
, VOIDmode
, EXPAND_NORMAL
);
4322 /* Don't bother with expected value notes for integral constants. */
4323 if (flag_guess_branch_prob
&& GET_CODE (target
) != CONST_INT
)
4325 /* We do need to force this into a register so that we can be
4326 moderately sure to be able to correctly interpret the branch
4328 target
= force_reg (GET_MODE (target
), target
);
4330 rtx_c
= expand_expr (c
, NULL_RTX
, GET_MODE (target
), EXPAND_NORMAL
);
4332 note
= emit_note (NULL
, NOTE_INSN_EXPECTED_VALUE
);
4333 NOTE_EXPECTED_VALUE (note
) = gen_rtx_EQ (VOIDmode
, target
, rtx_c
);
4339 /* Like expand_builtin_expect, except do this in a jump context. This is
4340 called from do_jump if the conditional is a __builtin_expect. Return either
4341 a list of insns to emit the jump or NULL if we cannot optimize
4342 __builtin_expect. We need to optimize this at jump time so that machines
4343 like the PowerPC don't turn the test into a SCC operation, and then jump
4344 based on the test being 0/1. */
4347 expand_builtin_expect_jump (tree exp
, rtx if_false_label
, rtx if_true_label
)
4349 tree arglist
= TREE_OPERAND (exp
, 1);
4350 tree arg0
= TREE_VALUE (arglist
);
4351 tree arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
4354 /* Only handle __builtin_expect (test, 0) and
4355 __builtin_expect (test, 1). */
4356 if (TREE_CODE (TREE_TYPE (arg1
)) == INTEGER_TYPE
4357 && (integer_zerop (arg1
) || integer_onep (arg1
)))
4362 /* If we fail to locate an appropriate conditional jump, we'll
4363 fall back to normal evaluation. Ensure that the expression
4364 can be re-evaluated. */
4365 switch (unsafe_for_reeval (arg0
))
4370 case 1: /* Mildly unsafe. */
4371 arg0
= unsave_expr (arg0
);
4374 case 2: /* Wildly unsafe. */
4378 /* Expand the jump insns. */
4380 do_jump (arg0
, if_false_label
, if_true_label
);
4384 /* Now that the __builtin_expect has been validated, go through and add
4385 the expect's to each of the conditional jumps. If we run into an
4386 error, just give up and generate the 'safe' code of doing a SCC
4387 operation and then doing a branch on that. */
4389 while (insn
!= NULL_RTX
)
4391 rtx next
= NEXT_INSN (insn
);
4393 if (GET_CODE (insn
) == JUMP_INSN
&& any_condjump_p (insn
))
4395 rtx ifelse
= SET_SRC (pc_set (insn
));
4399 if (GET_CODE (XEXP (ifelse
, 1)) == LABEL_REF
)
4402 label
= XEXP (XEXP (ifelse
, 1), 0);
4404 /* An inverted jump reverses the probabilities. */
4405 else if (GET_CODE (XEXP (ifelse
, 2)) == LABEL_REF
)
4408 label
= XEXP (XEXP (ifelse
, 2), 0);
4410 /* We shouldn't have to worry about conditional returns during
4411 the expansion stage, but handle it gracefully anyway. */
4412 else if (GET_CODE (XEXP (ifelse
, 1)) == RETURN
)
4417 /* An inverted return reverses the probabilities. */
4418 else if (GET_CODE (XEXP (ifelse
, 2)) == RETURN
)
4426 /* If the test is expected to fail, reverse the
4428 if (integer_zerop (arg1
))
4431 /* If we are jumping to the false label, reverse the
4433 if (label
== NULL_RTX
)
4434 ; /* conditional return */
4435 else if (label
== if_false_label
)
4437 else if (label
!= if_true_label
)
4441 predict_insn_def (insn
, PRED_BUILTIN_EXPECT
, taken
);
4448 /* If no jumps were modified, fail and do __builtin_expect the normal
4458 expand_builtin_trap (void)
4462 emit_insn (gen_trap ());
4465 emit_library_call (abort_libfunc
, LCT_NORETURN
, VOIDmode
, 0);
4469 /* Expand a call to fabs, fabsf or fabsl with arguments ARGLIST.
4470 Return 0 if a normal call should be emitted rather than expanding
4471 the function inline. If convenient, the result should be placed
4472 in TARGET. SUBTARGET may be used as the target for computing
4476 expand_builtin_fabs (tree arglist
, rtx target
, rtx subtarget
)
4478 enum machine_mode mode
;
4482 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
4485 arg
= TREE_VALUE (arglist
);
4486 mode
= TYPE_MODE (TREE_TYPE (arg
));
4487 op0
= expand_expr (arg
, subtarget
, VOIDmode
, 0);
4488 return expand_abs (mode
, op0
, target
, 0, safe_from_p (target
, arg
, 1));
4491 /* Expand a call to cabs, cabsf or cabsl with arguments ARGLIST.
4492 Return 0 if a normal call should be emitted rather than expanding
4493 the function inline. If convenient, the result should be placed
4497 expand_builtin_cabs (tree arglist
, rtx target
)
4499 enum machine_mode mode
;
4503 if (arglist
== 0 || TREE_CHAIN (arglist
))
4505 arg
= TREE_VALUE (arglist
);
4506 if (TREE_CODE (TREE_TYPE (arg
)) != COMPLEX_TYPE
4507 || TREE_CODE (TREE_TYPE (TREE_TYPE (arg
))) != REAL_TYPE
)
4510 mode
= TYPE_MODE (TREE_TYPE (arg
));
4511 op0
= expand_expr (arg
, NULL_RTX
, VOIDmode
, 0);
4512 return expand_complex_abs (mode
, op0
, target
, 0);
4515 /* Expand a call to sprintf with argument list ARGLIST. Return 0 if
4516 a normal call should be emitted rather than expanding the function
4517 inline. If convenient, the result should be placed in TARGET with
4521 expand_builtin_sprintf (tree arglist
, rtx target
, enum machine_mode mode
)
4523 tree dest
, fmt
, stripped
;
4526 orig_arglist
= arglist
;
4528 /* Verify the required arguments in the original call. */
4531 dest
= TREE_VALUE (arglist
);
4532 if (TREE_CODE (TREE_TYPE (dest
)) != POINTER_TYPE
)
4534 arglist
= TREE_CHAIN (arglist
);
4537 fmt
= TREE_VALUE (arglist
);
4538 if (TREE_CODE (TREE_TYPE (dest
)) != POINTER_TYPE
)
4540 arglist
= TREE_CHAIN (arglist
);
4542 /* Check whether the format is a literal string constant. */
4544 STRIP_NOPS (stripped
);
4545 if (stripped
&& TREE_CODE (stripped
) == ADDR_EXPR
)
4546 stripped
= TREE_OPERAND (stripped
, 0);
4547 if (TREE_CODE (stripped
) != STRING_CST
)
4550 /* If the format doesn't contain % args or %%, use strcpy. */
4551 if (strchr (TREE_STRING_POINTER (stripped
), '%') == 0)
4553 tree fn
= implicit_built_in_decls
[BUILT_IN_STRCPY
];
4558 expand_expr (build_function_call_expr (fn
, orig_arglist
),
4559 const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
4560 if (target
== const0_rtx
)
4562 exp
= build_int_2 (TREE_STRING_LENGTH (stripped
) - 1, 0);
4563 exp
= fold (build1 (NOP_EXPR
, integer_type_node
, exp
));
4564 return expand_expr (exp
, target
, mode
, EXPAND_NORMAL
);
4566 /* If the format is "%s", use strcpy and possibly strlen. */
4567 else if (strcmp (TREE_STRING_POINTER (stripped
), "%s") == 0)
4569 tree strcpy_fn
, strlen_fn
, exp
, arg
;
4570 strcpy_fn
= implicit_built_in_decls
[BUILT_IN_STRCPY
];
4575 if (! arglist
|| TREE_CHAIN (arglist
))
4577 arg
= TREE_VALUE (arglist
);
4578 if (TREE_CODE (TREE_TYPE (arg
)) != POINTER_TYPE
)
4581 if (target
!= const0_rtx
)
4583 strlen_fn
= implicit_built_in_decls
[BUILT_IN_STRLEN
];
4586 arg
= save_expr (arg
);
4591 arglist
= build_tree_list (NULL_TREE
, arg
);
4592 arglist
= tree_cons (NULL_TREE
, dest
, arglist
);
4593 expand_expr (build_function_call_expr (strcpy_fn
, arglist
),
4594 const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
4596 if (target
== const0_rtx
)
4599 exp
= build_function_call_expr (strlen_fn
, TREE_CHAIN (arglist
));
4600 exp
= fold (build1 (NOP_EXPR
, integer_type_node
, exp
));
4601 return expand_expr (exp
, target
, mode
, EXPAND_NORMAL
);
4607 /* Expand an expression EXP that calls a built-in function,
4608 with result going to TARGET if that's convenient
4609 (and in mode MODE if that's convenient).
4610 SUBTARGET may be used as the target for computing one of EXP's operands.
4611 IGNORE is nonzero if the value is to be ignored. */
4614 expand_builtin (tree exp
, rtx target
, rtx subtarget
, enum machine_mode mode
,
4617 tree fndecl
= TREE_OPERAND (TREE_OPERAND (exp
, 0), 0);
4618 tree arglist
= TREE_OPERAND (exp
, 1);
4619 enum built_in_function fcode
= DECL_FUNCTION_CODE (fndecl
);
4620 enum machine_mode target_mode
= TYPE_MODE (TREE_TYPE (exp
));
4622 /* Perform postincrements before expanding builtin functions. Â */
4625 if (DECL_BUILT_IN_CLASS (fndecl
) == BUILT_IN_MD
)
4626 return (*targetm
.expand_builtin
) (exp
, target
, subtarget
, mode
, ignore
);
4628 /* When not optimizing, generate calls to library functions for a certain
4630 if (!optimize
&& !CALLED_AS_BUILT_IN (fndecl
))
4634 case BUILT_IN_SQRTF
:
4635 case BUILT_IN_SQRTL
:
4652 case BUILT_IN_ATANF
:
4653 case BUILT_IN_ATANL
:
4657 case BUILT_IN_ATAN2
:
4658 case BUILT_IN_ATAN2F
:
4659 case BUILT_IN_ATAN2L
:
4660 case BUILT_IN_MEMSET
:
4661 case BUILT_IN_MEMCPY
:
4662 case BUILT_IN_MEMCMP
:
4663 case BUILT_IN_MEMPCPY
:
4664 case BUILT_IN_MEMMOVE
:
4666 case BUILT_IN_BZERO
:
4667 case BUILT_IN_BCOPY
:
4668 case BUILT_IN_INDEX
:
4669 case BUILT_IN_RINDEX
:
4670 case BUILT_IN_SPRINTF
:
4671 case BUILT_IN_STPCPY
:
4672 case BUILT_IN_STRCHR
:
4673 case BUILT_IN_STRRCHR
:
4674 case BUILT_IN_STRLEN
:
4675 case BUILT_IN_STRCPY
:
4676 case BUILT_IN_STRNCPY
:
4677 case BUILT_IN_STRNCMP
:
4678 case BUILT_IN_STRSTR
:
4679 case BUILT_IN_STRPBRK
:
4680 case BUILT_IN_STRCAT
:
4681 case BUILT_IN_STRNCAT
:
4682 case BUILT_IN_STRSPN
:
4683 case BUILT_IN_STRCSPN
:
4684 case BUILT_IN_STRCMP
:
4686 case BUILT_IN_PUTCHAR
:
4688 case BUILT_IN_PRINTF
:
4689 case BUILT_IN_FPUTC
:
4690 case BUILT_IN_FPUTS
:
4691 case BUILT_IN_FWRITE
:
4692 case BUILT_IN_PUTCHAR_UNLOCKED
:
4693 case BUILT_IN_PUTS_UNLOCKED
:
4694 case BUILT_IN_PRINTF_UNLOCKED
:
4695 case BUILT_IN_FPUTC_UNLOCKED
:
4696 case BUILT_IN_FPUTS_UNLOCKED
:
4697 case BUILT_IN_FWRITE_UNLOCKED
:
4698 case BUILT_IN_FLOOR
:
4699 case BUILT_IN_FLOORF
:
4700 case BUILT_IN_FLOORL
:
4702 case BUILT_IN_CEILF
:
4703 case BUILT_IN_CEILL
:
4704 case BUILT_IN_TRUNC
:
4705 case BUILT_IN_TRUNCF
:
4706 case BUILT_IN_TRUNCL
:
4707 case BUILT_IN_ROUND
:
4708 case BUILT_IN_ROUNDF
:
4709 case BUILT_IN_ROUNDL
:
4710 case BUILT_IN_NEARBYINT
:
4711 case BUILT_IN_NEARBYINTF
:
4712 case BUILT_IN_NEARBYINTL
:
4713 return expand_call (exp
, target
, ignore
);
4719 /* The built-in function expanders test for target == const0_rtx
4720 to determine whether the function's result will be ignored. */
4722 target
= const0_rtx
;
4724 /* If the result of a pure or const built-in function is ignored, and
4725 none of its arguments are volatile, we can avoid expanding the
4726 built-in call and just evaluate the arguments for side-effects. */
4727 if (target
== const0_rtx
4728 && (DECL_IS_PURE (fndecl
) || TREE_READONLY (fndecl
)))
4730 bool volatilep
= false;
4733 for (arg
= arglist
; arg
; arg
= TREE_CHAIN (arg
))
4734 if (TREE_THIS_VOLATILE (TREE_VALUE (arg
)))
4742 for (arg
= arglist
; arg
; arg
= TREE_CHAIN (arg
))
4743 expand_expr (TREE_VALUE (arg
), const0_rtx
,
4744 VOIDmode
, EXPAND_NORMAL
);
4753 case BUILT_IN_LLABS
:
4754 case BUILT_IN_IMAXABS
:
4755 /* build_function_call changes these into ABS_EXPR. */
4759 case BUILT_IN_FABSF
:
4760 case BUILT_IN_FABSL
:
4761 target
= expand_builtin_fabs (arglist
, target
, subtarget
);
4767 case BUILT_IN_CABSF
:
4768 case BUILT_IN_CABSL
:
4769 if (flag_unsafe_math_optimizations
)
4771 target
= expand_builtin_cabs (arglist
, target
);
4778 case BUILT_IN_CONJF
:
4779 case BUILT_IN_CONJL
:
4780 case BUILT_IN_CREAL
:
4781 case BUILT_IN_CREALF
:
4782 case BUILT_IN_CREALL
:
4783 case BUILT_IN_CIMAG
:
4784 case BUILT_IN_CIMAGF
:
4785 case BUILT_IN_CIMAGL
:
4786 /* expand_tree_builtin changes these into CONJ_EXPR, REALPART_EXPR
4787 and IMAGPART_EXPR. */
4806 case BUILT_IN_ATANF
:
4807 case BUILT_IN_ATANL
:
4808 /* Treat these like sqrt only if unsafe math optimizations are allowed,
4809 because of possible accuracy problems. */
4810 if (! flag_unsafe_math_optimizations
)
4813 case BUILT_IN_SQRTF
:
4814 case BUILT_IN_SQRTL
:
4815 case BUILT_IN_FLOOR
:
4816 case BUILT_IN_FLOORF
:
4817 case BUILT_IN_FLOORL
:
4819 case BUILT_IN_CEILF
:
4820 case BUILT_IN_CEILL
:
4821 case BUILT_IN_TRUNC
:
4822 case BUILT_IN_TRUNCF
:
4823 case BUILT_IN_TRUNCL
:
4824 case BUILT_IN_ROUND
:
4825 case BUILT_IN_ROUNDF
:
4826 case BUILT_IN_ROUNDL
:
4827 case BUILT_IN_NEARBYINT
:
4828 case BUILT_IN_NEARBYINTF
:
4829 case BUILT_IN_NEARBYINTL
:
4830 target
= expand_builtin_mathfn (exp
, target
, subtarget
);
4838 if (! flag_unsafe_math_optimizations
)
4840 target
= expand_builtin_pow (exp
, target
, subtarget
);
4845 case BUILT_IN_ATAN2
:
4846 case BUILT_IN_ATAN2F
:
4847 case BUILT_IN_ATAN2L
:
4848 if (! flag_unsafe_math_optimizations
)
4850 target
= expand_builtin_mathfn_2 (exp
, target
, subtarget
);
4855 case BUILT_IN_APPLY_ARGS
:
4856 return expand_builtin_apply_args ();
4858 /* __builtin_apply (FUNCTION, ARGUMENTS, ARGSIZE) invokes
4859 FUNCTION with a copy of the parameters described by
4860 ARGUMENTS, and ARGSIZE. It returns a block of memory
4861 allocated on the stack into which is stored all the registers
4862 that might possibly be used for returning the result of a
4863 function. ARGUMENTS is the value returned by
4864 __builtin_apply_args. ARGSIZE is the number of bytes of
4865 arguments that must be copied. ??? How should this value be
4866 computed? We'll also need a safe worst case value for varargs
4868 case BUILT_IN_APPLY
:
4869 if (!validate_arglist (arglist
, POINTER_TYPE
,
4870 POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
)
4871 && !validate_arglist (arglist
, REFERENCE_TYPE
,
4872 POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
4880 for (t
= arglist
, i
= 0; t
; t
= TREE_CHAIN (t
), i
++)
4881 ops
[i
] = expand_expr (TREE_VALUE (t
), NULL_RTX
, VOIDmode
, 0);
4883 return expand_builtin_apply (ops
[0], ops
[1], ops
[2]);
4886 /* __builtin_return (RESULT) causes the function to return the
4887 value described by RESULT. RESULT is address of the block of
4888 memory returned by __builtin_apply. */
4889 case BUILT_IN_RETURN
:
4890 if (validate_arglist (arglist
, POINTER_TYPE
, VOID_TYPE
))
4891 expand_builtin_return (expand_expr (TREE_VALUE (arglist
),
4892 NULL_RTX
, VOIDmode
, 0));
4895 case BUILT_IN_SAVEREGS
:
4896 return expand_builtin_saveregs ();
4898 case BUILT_IN_ARGS_INFO
:
4899 return expand_builtin_args_info (arglist
);
4901 /* Return the address of the first anonymous stack arg. */
4902 case BUILT_IN_NEXT_ARG
:
4903 return expand_builtin_next_arg (arglist
);
4905 case BUILT_IN_CLASSIFY_TYPE
:
4906 return expand_builtin_classify_type (arglist
);
4908 case BUILT_IN_CONSTANT_P
:
4909 return expand_builtin_constant_p (arglist
, target_mode
);
4911 case BUILT_IN_FRAME_ADDRESS
:
4912 case BUILT_IN_RETURN_ADDRESS
:
4913 return expand_builtin_frame_address (fndecl
, arglist
);
4915 /* Returns the address of the area where the structure is returned.
4917 case BUILT_IN_AGGREGATE_INCOMING_ADDRESS
:
4919 || ! AGGREGATE_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl
)))
4920 || GET_CODE (DECL_RTL (DECL_RESULT (current_function_decl
))) != MEM
)
4923 return XEXP (DECL_RTL (DECL_RESULT (current_function_decl
)), 0);
4925 case BUILT_IN_ALLOCA
:
4926 target
= expand_builtin_alloca (arglist
, target
);
4933 case BUILT_IN_FFSLL
:
4934 target
= expand_builtin_unop (target_mode
, arglist
, target
,
4935 subtarget
, ffs_optab
);
4942 case BUILT_IN_CLZLL
:
4943 target
= expand_builtin_unop (target_mode
, arglist
, target
,
4944 subtarget
, clz_optab
);
4951 case BUILT_IN_CTZLL
:
4952 target
= expand_builtin_unop (target_mode
, arglist
, target
,
4953 subtarget
, ctz_optab
);
4958 case BUILT_IN_POPCOUNT
:
4959 case BUILT_IN_POPCOUNTL
:
4960 case BUILT_IN_POPCOUNTLL
:
4961 target
= expand_builtin_unop (target_mode
, arglist
, target
,
4962 subtarget
, popcount_optab
);
4967 case BUILT_IN_PARITY
:
4968 case BUILT_IN_PARITYL
:
4969 case BUILT_IN_PARITYLL
:
4970 target
= expand_builtin_unop (target_mode
, arglist
, target
,
4971 subtarget
, parity_optab
);
4976 case BUILT_IN_STRLEN
:
4977 target
= expand_builtin_strlen (arglist
, target
, target_mode
);
4982 case BUILT_IN_STRCPY
:
4983 target
= expand_builtin_strcpy (arglist
, target
, mode
);
4988 case BUILT_IN_STRNCPY
:
4989 target
= expand_builtin_strncpy (arglist
, target
, mode
);
4994 case BUILT_IN_STPCPY
:
4995 target
= expand_builtin_stpcpy (arglist
, target
, mode
);
5000 case BUILT_IN_STRCAT
:
5001 target
= expand_builtin_strcat (arglist
, target
, mode
);
5006 case BUILT_IN_STRNCAT
:
5007 target
= expand_builtin_strncat (arglist
, target
, mode
);
5012 case BUILT_IN_STRSPN
:
5013 target
= expand_builtin_strspn (arglist
, target
, mode
);
5018 case BUILT_IN_STRCSPN
:
5019 target
= expand_builtin_strcspn (arglist
, target
, mode
);
5024 case BUILT_IN_STRSTR
:
5025 target
= expand_builtin_strstr (arglist
, target
, mode
);
5030 case BUILT_IN_STRPBRK
:
5031 target
= expand_builtin_strpbrk (arglist
, target
, mode
);
5036 case BUILT_IN_INDEX
:
5037 case BUILT_IN_STRCHR
:
5038 target
= expand_builtin_strchr (arglist
, target
, mode
);
5043 case BUILT_IN_RINDEX
:
5044 case BUILT_IN_STRRCHR
:
5045 target
= expand_builtin_strrchr (arglist
, target
, mode
);
5050 case BUILT_IN_MEMCPY
:
5051 target
= expand_builtin_memcpy (arglist
, target
, mode
);
5056 case BUILT_IN_MEMPCPY
:
5057 target
= expand_builtin_mempcpy (arglist
, target
, mode
, /*endp=*/ 1);
5062 case BUILT_IN_MEMMOVE
:
5063 target
= expand_builtin_memmove (arglist
, target
, mode
);
5068 case BUILT_IN_BCOPY
:
5069 target
= expand_builtin_bcopy (arglist
);
5074 case BUILT_IN_MEMSET
:
5075 target
= expand_builtin_memset (arglist
, target
, mode
);
5080 case BUILT_IN_BZERO
:
5081 target
= expand_builtin_bzero (arglist
);
5086 case BUILT_IN_STRCMP
:
5087 target
= expand_builtin_strcmp (exp
, target
, mode
);
5092 case BUILT_IN_STRNCMP
:
5093 target
= expand_builtin_strncmp (exp
, target
, mode
);
5099 case BUILT_IN_MEMCMP
:
5100 target
= expand_builtin_memcmp (exp
, arglist
, target
, mode
);
5105 case BUILT_IN_SETJMP
:
5106 target
= expand_builtin_setjmp (arglist
, target
);
5111 /* __builtin_longjmp is passed a pointer to an array of five words.
5112 It's similar to the C library longjmp function but works with
5113 __builtin_setjmp above. */
5114 case BUILT_IN_LONGJMP
:
5115 if (!validate_arglist (arglist
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
5119 rtx buf_addr
= expand_expr (TREE_VALUE (arglist
), subtarget
,
5121 rtx value
= expand_expr (TREE_VALUE (TREE_CHAIN (arglist
)),
5122 NULL_RTX
, VOIDmode
, 0);
5124 if (value
!= const1_rtx
)
5126 error ("__builtin_longjmp second argument must be 1");
5130 expand_builtin_longjmp (buf_addr
, value
);
5135 expand_builtin_trap ();
5138 case BUILT_IN_FPUTS
:
5139 target
= expand_builtin_fputs (arglist
, ignore
,/*unlocked=*/ 0);
5143 case BUILT_IN_FPUTS_UNLOCKED
:
5144 target
= expand_builtin_fputs (arglist
, ignore
,/*unlocked=*/ 1);
5149 case BUILT_IN_SPRINTF
:
5150 target
= expand_builtin_sprintf (arglist
, target
, mode
);
5155 /* Various hooks for the DWARF 2 __throw routine. */
5156 case BUILT_IN_UNWIND_INIT
:
5157 expand_builtin_unwind_init ();
5159 case BUILT_IN_DWARF_CFA
:
5160 return virtual_cfa_rtx
;
5161 #ifdef DWARF2_UNWIND_INFO
5162 case BUILT_IN_DWARF_SP_COLUMN
:
5163 return expand_builtin_dwarf_sp_column ();
5164 case BUILT_IN_INIT_DWARF_REG_SIZES
:
5165 expand_builtin_init_dwarf_reg_sizes (TREE_VALUE (arglist
));
5168 case BUILT_IN_FROB_RETURN_ADDR
:
5169 return expand_builtin_frob_return_addr (TREE_VALUE (arglist
));
5170 case BUILT_IN_EXTRACT_RETURN_ADDR
:
5171 return expand_builtin_extract_return_addr (TREE_VALUE (arglist
));
5172 case BUILT_IN_EH_RETURN
:
5173 expand_builtin_eh_return (TREE_VALUE (arglist
),
5174 TREE_VALUE (TREE_CHAIN (arglist
)));
5176 #ifdef EH_RETURN_DATA_REGNO
5177 case BUILT_IN_EH_RETURN_DATA_REGNO
:
5178 return expand_builtin_eh_return_data_regno (arglist
);
5180 case BUILT_IN_VA_START
:
5181 case BUILT_IN_STDARG_START
:
5182 return expand_builtin_va_start (arglist
);
5183 case BUILT_IN_VA_END
:
5184 return expand_builtin_va_end (arglist
);
5185 case BUILT_IN_VA_COPY
:
5186 return expand_builtin_va_copy (arglist
);
5187 case BUILT_IN_EXPECT
:
5188 return expand_builtin_expect (arglist
, target
);
5189 case BUILT_IN_PREFETCH
:
5190 expand_builtin_prefetch (arglist
);
5194 default: /* just do library call, if unknown builtin */
5195 if (!DECL_ASSEMBLER_NAME_SET_P (fndecl
))
5196 error ("built-in function `%s' not currently supported",
5197 IDENTIFIER_POINTER (DECL_NAME (fndecl
)));
5200 /* The switch statement above can drop through to cause the function
5201 to be called normally. */
5202 return expand_call (exp
, target
, ignore
);
5205 /* Determine whether a tree node represents a call to a built-in
5206 math function. If the tree T is a call to a built-in function
5207 taking a single real argument, then the return value is the
5208 DECL_FUNCTION_CODE of the call, e.g. BUILT_IN_SQRT. Otherwise
5209 the return value is END_BUILTINS. */
5211 enum built_in_function
5212 builtin_mathfn_code (tree t
)
5214 tree fndecl
, arglist
;
5216 if (TREE_CODE (t
) != CALL_EXPR
5217 || TREE_CODE (TREE_OPERAND (t
, 0)) != ADDR_EXPR
)
5218 return END_BUILTINS
;
5220 fndecl
= TREE_OPERAND (TREE_OPERAND (t
, 0), 0);
5221 if (TREE_CODE (fndecl
) != FUNCTION_DECL
5222 || ! DECL_BUILT_IN (fndecl
)
5223 || DECL_BUILT_IN_CLASS (fndecl
) == BUILT_IN_MD
)
5224 return END_BUILTINS
;
5226 arglist
= TREE_OPERAND (t
, 1);
5228 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist
))) != REAL_TYPE
)
5229 return END_BUILTINS
;
5231 arglist
= TREE_CHAIN (arglist
);
5232 switch (DECL_FUNCTION_CODE (fndecl
))
5237 case BUILT_IN_ATAN2
:
5238 case BUILT_IN_ATAN2F
:
5239 case BUILT_IN_ATAN2L
:
5241 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist
))) != REAL_TYPE
5242 || TREE_CHAIN (arglist
))
5243 return END_BUILTINS
;
5248 return END_BUILTINS
;
5252 return DECL_FUNCTION_CODE (fndecl
);
5255 /* Fold a call to __builtin_constant_p, if we know it will evaluate to a
5256 constant. ARGLIST is the argument list of the call. */
5259 fold_builtin_constant_p (tree arglist
)
5264 arglist
= TREE_VALUE (arglist
);
5266 /* We return 1 for a numeric type that's known to be a constant
5267 value at compile-time or for an aggregate type that's a
5268 literal constant. */
5269 STRIP_NOPS (arglist
);
5271 /* If we know this is a constant, emit the constant of one. */
5272 if (TREE_CODE_CLASS (TREE_CODE (arglist
)) == 'c'
5273 || (TREE_CODE (arglist
) == CONSTRUCTOR
5274 && TREE_CONSTANT (arglist
))
5275 || (TREE_CODE (arglist
) == ADDR_EXPR
5276 && TREE_CODE (TREE_OPERAND (arglist
, 0)) == STRING_CST
))
5277 return integer_one_node
;
5279 /* If we aren't going to be running CSE or this expression
5280 has side effects, show we don't know it to be a constant.
5281 Likewise if it's a pointer or aggregate type since in those
5282 case we only want literals, since those are only optimized
5283 when generating RTL, not later.
5284 And finally, if we are compiling an initializer, not code, we
5285 need to return a definite result now; there's not going to be any
5286 more optimization done. */
5287 if (TREE_SIDE_EFFECTS (arglist
) || cse_not_expected
5288 || AGGREGATE_TYPE_P (TREE_TYPE (arglist
))
5289 || POINTER_TYPE_P (TREE_TYPE (arglist
))
5291 return integer_zero_node
;
5296 /* Fold a call to __builtin_classify_type. */
5299 fold_builtin_classify_type (tree arglist
)
5302 return build_int_2 (no_type_class
, 0);
5304 return build_int_2 (type_to_class (TREE_TYPE (TREE_VALUE (arglist
))), 0);
5307 /* Fold a call to __builtin_inf or __builtin_huge_val. */
5310 fold_builtin_inf (tree type
, int warn
)
5312 REAL_VALUE_TYPE real
;
5314 if (!MODE_HAS_INFINITIES (TYPE_MODE (type
)) && warn
)
5315 warning ("target format does not support infinity");
5318 return build_real (type
, real
);
5321 /* Fold a call to __builtin_nan or __builtin_nans. */
5324 fold_builtin_nan (tree arglist
, tree type
, int quiet
)
5326 REAL_VALUE_TYPE real
;
5329 if (!validate_arglist (arglist
, POINTER_TYPE
, VOID_TYPE
))
5331 str
= c_getstr (TREE_VALUE (arglist
));
5335 if (!real_nan (&real
, str
, quiet
, TYPE_MODE (type
)))
5338 return build_real (type
, real
);
5341 /* EXP is assumed to me builtin call where truncation can be propagated
5342 across (for instance floor((double)f) == (double)floorf (f).
5343 Do the transformation. */
5345 fold_trunc_transparent_mathfn (tree exp
)
5347 tree fndecl
= TREE_OPERAND (TREE_OPERAND (exp
, 0), 0);
5348 tree arglist
= TREE_OPERAND (exp
, 1);
5349 enum built_in_function fcode
= DECL_FUNCTION_CODE (fndecl
);
5351 if (optimize
&& validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
5353 tree arg0
= strip_float_extensions (TREE_VALUE (arglist
));
5354 tree ftype
= TREE_TYPE (exp
);
5355 tree newtype
= TREE_TYPE (arg0
);
5358 if (TYPE_PRECISION (newtype
) < TYPE_PRECISION (ftype
)
5359 && (decl
= mathfn_built_in (newtype
, fcode
)))
5362 build_tree_list (NULL_TREE
, fold (convert (newtype
, arg0
)));
5363 return convert (ftype
,
5364 build_function_call_expr (decl
, arglist
));
5370 /* Fold function call to builtin cabs, cabsf or cabsl. FNDECL is the
5371 function's DECL, ARGLIST is the argument list and TYPE is the return
5372 type. Return NULL_TREE if no simplification can be made. */
5375 fold_builtin_cabs (tree fndecl
, tree arglist
, tree type
)
5379 if (!arglist
|| TREE_CHAIN (arglist
))
5382 arg
= TREE_VALUE (arglist
);
5383 if (TREE_CODE (TREE_TYPE (arg
)) != COMPLEX_TYPE
5384 || TREE_CODE (TREE_TYPE (TREE_TYPE (arg
))) != REAL_TYPE
)
5387 /* Evaluate cabs of a constant at compile-time. */
5388 if (flag_unsafe_math_optimizations
5389 && TREE_CODE (arg
) == COMPLEX_CST
5390 && TREE_CODE (TREE_REALPART (arg
)) == REAL_CST
5391 && TREE_CODE (TREE_IMAGPART (arg
)) == REAL_CST
5392 && ! TREE_CONSTANT_OVERFLOW (TREE_REALPART (arg
))
5393 && ! TREE_CONSTANT_OVERFLOW (TREE_IMAGPART (arg
)))
5395 REAL_VALUE_TYPE r
, i
;
5397 r
= TREE_REAL_CST (TREE_REALPART (arg
));
5398 i
= TREE_REAL_CST (TREE_IMAGPART (arg
));
5400 real_arithmetic (&r
, MULT_EXPR
, &r
, &r
);
5401 real_arithmetic (&i
, MULT_EXPR
, &i
, &i
);
5402 real_arithmetic (&r
, PLUS_EXPR
, &r
, &i
);
5403 if (real_sqrt (&r
, TYPE_MODE (type
), &r
)
5404 || ! flag_trapping_math
)
5405 return build_real (type
, r
);
5408 /* If either part is zero, cabs is fabs of the other. */
5409 if (TREE_CODE (arg
) == COMPLEX_EXPR
5410 && real_zerop (TREE_OPERAND (arg
, 0)))
5411 return fold (build1 (ABS_EXPR
, type
, TREE_OPERAND (arg
, 1)));
5412 if (TREE_CODE (arg
) == COMPLEX_EXPR
5413 && real_zerop (TREE_OPERAND (arg
, 1)))
5414 return fold (build1 (ABS_EXPR
, type
, TREE_OPERAND (arg
, 0)));
5416 if (flag_unsafe_math_optimizations
)
5418 enum built_in_function fcode
;
5421 fcode
= DECL_FUNCTION_CODE (fndecl
);
5422 if (fcode
== BUILT_IN_CABS
)
5423 sqrtfn
= implicit_built_in_decls
[BUILT_IN_SQRT
];
5424 else if (fcode
== BUILT_IN_CABSF
)
5425 sqrtfn
= implicit_built_in_decls
[BUILT_IN_SQRTF
];
5426 else if (fcode
== BUILT_IN_CABSL
)
5427 sqrtfn
= implicit_built_in_decls
[BUILT_IN_SQRTL
];
5431 if (sqrtfn
!= NULL_TREE
)
5433 tree rpart
, ipart
, result
, arglist
;
5435 rpart
= fold (build1 (REALPART_EXPR
, type
, arg
));
5436 ipart
= fold (build1 (IMAGPART_EXPR
, type
, arg
));
5438 rpart
= save_expr (rpart
);
5439 ipart
= save_expr (ipart
);
5441 result
= fold (build (PLUS_EXPR
, type
,
5442 fold (build (MULT_EXPR
, type
,
5444 fold (build (MULT_EXPR
, type
,
5447 arglist
= build_tree_list (NULL_TREE
, result
);
5448 return build_function_call_expr (sqrtfn
, arglist
);
5455 /* Used by constant folding to eliminate some builtin calls early. EXP is
5456 the CALL_EXPR of a call to a builtin function. */
5459 fold_builtin (tree exp
)
5461 tree fndecl
= TREE_OPERAND (TREE_OPERAND (exp
, 0), 0);
5462 tree arglist
= TREE_OPERAND (exp
, 1);
5463 tree type
= TREE_TYPE (TREE_TYPE (fndecl
));
5465 if (DECL_BUILT_IN_CLASS (fndecl
) == BUILT_IN_MD
)
5468 switch (DECL_FUNCTION_CODE (fndecl
))
5470 case BUILT_IN_CONSTANT_P
:
5471 return fold_builtin_constant_p (arglist
);
5473 case BUILT_IN_CLASSIFY_TYPE
:
5474 return fold_builtin_classify_type (arglist
);
5476 case BUILT_IN_STRLEN
:
5477 if (validate_arglist (arglist
, POINTER_TYPE
, VOID_TYPE
))
5479 tree len
= c_strlen (TREE_VALUE (arglist
));
5482 /* Convert from the internal "sizetype" type to "size_t". */
5484 len
= convert (size_type_node
, len
);
5491 case BUILT_IN_FABSF
:
5492 case BUILT_IN_FABSL
:
5493 if (validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
5494 return fold (build1 (ABS_EXPR
, type
, TREE_VALUE (arglist
)));
5498 case BUILT_IN_CABSF
:
5499 case BUILT_IN_CABSL
:
5500 return fold_builtin_cabs (fndecl
, arglist
, type
);
5503 case BUILT_IN_SQRTF
:
5504 case BUILT_IN_SQRTL
:
5505 if (validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
5507 enum built_in_function fcode
;
5508 tree arg
= TREE_VALUE (arglist
);
5510 /* Optimize sqrt of constant value. */
5511 if (TREE_CODE (arg
) == REAL_CST
5512 && ! TREE_CONSTANT_OVERFLOW (arg
))
5514 REAL_VALUE_TYPE r
, x
;
5516 x
= TREE_REAL_CST (arg
);
5517 if (real_sqrt (&r
, TYPE_MODE (type
), &x
)
5518 || (!flag_trapping_math
&& !flag_errno_math
))
5519 return build_real (type
, r
);
5522 /* Optimize sqrt(exp(x)) = exp(x*0.5). */
5523 fcode
= builtin_mathfn_code (arg
);
5524 if (flag_unsafe_math_optimizations
5525 && (fcode
== BUILT_IN_EXP
5526 || fcode
== BUILT_IN_EXPF
5527 || fcode
== BUILT_IN_EXPL
))
5529 tree expfn
= TREE_OPERAND (TREE_OPERAND (arg
, 0), 0);
5530 arg
= fold (build (MULT_EXPR
, type
,
5531 TREE_VALUE (TREE_OPERAND (arg
, 1)),
5532 build_real (type
, dconsthalf
)));
5533 arglist
= build_tree_list (NULL_TREE
, arg
);
5534 return build_function_call_expr (expfn
, arglist
);
5537 /* Optimize sqrt(pow(x,y)) = pow(x,y*0.5). */
5538 if (flag_unsafe_math_optimizations
5539 && (fcode
== BUILT_IN_POW
5540 || fcode
== BUILT_IN_POWF
5541 || fcode
== BUILT_IN_POWL
))
5543 tree powfn
= TREE_OPERAND (TREE_OPERAND (arg
, 0), 0);
5544 tree arg0
= TREE_VALUE (TREE_OPERAND (arg
, 1));
5545 tree arg1
= TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg
, 1)));
5546 tree narg1
= fold (build (MULT_EXPR
, type
, arg1
,
5547 build_real (type
, dconsthalf
)));
5548 arglist
= tree_cons (NULL_TREE
, arg0
,
5549 build_tree_list (NULL_TREE
, narg1
));
5550 return build_function_call_expr (powfn
, arglist
);
5558 if (validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
5560 tree arg
= TREE_VALUE (arglist
);
5562 /* Optimize sin(0.0) = 0.0. */
5563 if (real_zerop (arg
))
5571 if (validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
5573 tree arg
= TREE_VALUE (arglist
);
5575 /* Optimize cos(0.0) = 1.0. */
5576 if (real_zerop (arg
))
5577 return build_real (type
, dconst1
);
5579 /* Optimize cos(-x) into cos(x). */
5580 if (TREE_CODE (arg
) == NEGATE_EXPR
)
5582 tree arglist
= build_tree_list (NULL_TREE
,
5583 TREE_OPERAND (arg
, 0));
5584 return build_function_call_expr (fndecl
, arglist
);
5592 if (validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
5594 enum built_in_function fcode
;
5595 tree arg
= TREE_VALUE (arglist
);
5597 /* Optimize exp(0.0) = 1.0. */
5598 if (real_zerop (arg
))
5599 return build_real (type
, dconst1
);
5601 /* Optimize exp(1.0) = e. */
5602 if (real_onep (arg
))
5604 REAL_VALUE_TYPE cst
;
5606 if (! builtin_dconsts_init
)
5607 init_builtin_dconsts ();
5608 real_convert (&cst
, TYPE_MODE (type
), &dconste
);
5609 return build_real (type
, cst
);
5612 /* Attempt to evaluate exp at compile-time. */
5613 if (flag_unsafe_math_optimizations
5614 && TREE_CODE (arg
) == REAL_CST
5615 && ! TREE_CONSTANT_OVERFLOW (arg
))
5617 REAL_VALUE_TYPE cint
;
5621 c
= TREE_REAL_CST (arg
);
5622 n
= real_to_integer (&c
);
5623 real_from_integer (&cint
, VOIDmode
, n
,
5625 if (real_identical (&c
, &cint
))
5629 if (! builtin_dconsts_init
)
5630 init_builtin_dconsts ();
5631 real_powi (&x
, TYPE_MODE (type
), &dconste
, n
);
5632 return build_real (type
, x
);
5636 /* Optimize exp(log(x)) = x. */
5637 fcode
= builtin_mathfn_code (arg
);
5638 if (flag_unsafe_math_optimizations
5639 && (fcode
== BUILT_IN_LOG
5640 || fcode
== BUILT_IN_LOGF
5641 || fcode
== BUILT_IN_LOGL
))
5642 return TREE_VALUE (TREE_OPERAND (arg
, 1));
5649 if (validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
5651 enum built_in_function fcode
;
5652 tree arg
= TREE_VALUE (arglist
);
5654 /* Optimize log(1.0) = 0.0. */
5655 if (real_onep (arg
))
5656 return build_real (type
, dconst0
);
5658 /* Optimize log(exp(x)) = x. */
5659 fcode
= builtin_mathfn_code (arg
);
5660 if (flag_unsafe_math_optimizations
5661 && (fcode
== BUILT_IN_EXP
5662 || fcode
== BUILT_IN_EXPF
5663 || fcode
== BUILT_IN_EXPL
))
5664 return TREE_VALUE (TREE_OPERAND (arg
, 1));
5666 /* Optimize log(sqrt(x)) = log(x)*0.5. */
5667 if (flag_unsafe_math_optimizations
5668 && (fcode
== BUILT_IN_SQRT
5669 || fcode
== BUILT_IN_SQRTF
5670 || fcode
== BUILT_IN_SQRTL
))
5672 tree logfn
= build_function_call_expr (fndecl
,
5673 TREE_OPERAND (arg
, 1));
5674 return fold (build (MULT_EXPR
, type
, logfn
,
5675 build_real (type
, dconsthalf
)));
5678 /* Optimize log(pow(x,y)) = y*log(x). */
5679 if (flag_unsafe_math_optimizations
5680 && (fcode
== BUILT_IN_POW
5681 || fcode
== BUILT_IN_POWF
5682 || fcode
== BUILT_IN_POWL
))
5684 tree arg0
, arg1
, logfn
;
5686 arg0
= TREE_VALUE (TREE_OPERAND (arg
, 1));
5687 arg1
= TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg
, 1)));
5688 arglist
= build_tree_list (NULL_TREE
, arg0
);
5689 logfn
= build_function_call_expr (fndecl
, arglist
);
5690 return fold (build (MULT_EXPR
, type
, arg1
, logfn
));
5698 if (validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
5700 enum built_in_function fcode
;
5701 tree arg
= TREE_VALUE (arglist
);
5703 /* Optimize tan(0.0) = 0.0. */
5704 if (real_zerop (arg
))
5707 /* Optimize tan(atan(x)) = x. */
5708 fcode
= builtin_mathfn_code (arg
);
5709 if (flag_unsafe_math_optimizations
5710 && (fcode
== BUILT_IN_ATAN
5711 || fcode
== BUILT_IN_ATANF
5712 || fcode
== BUILT_IN_ATANL
))
5713 return TREE_VALUE (TREE_OPERAND (arg
, 1));
5718 case BUILT_IN_ATANF
:
5719 case BUILT_IN_ATANL
:
5720 if (validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
5722 tree arg
= TREE_VALUE (arglist
);
5724 /* Optimize atan(0.0) = 0.0. */
5725 if (real_zerop (arg
))
5728 /* Optimize atan(1.0) = pi/4. */
5729 if (real_onep (arg
))
5731 REAL_VALUE_TYPE cst
;
5733 if (! builtin_dconsts_init
)
5734 init_builtin_dconsts ();
5735 real_convert (&cst
, TYPE_MODE (type
), &dconstpi
);
5737 return build_real (type
, cst
);
5745 if (validate_arglist (arglist
, REAL_TYPE
, REAL_TYPE
, VOID_TYPE
))
5747 enum built_in_function fcode
;
5748 tree arg0
= TREE_VALUE (arglist
);
5749 tree arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
5751 /* Optimize pow(1.0,y) = 1.0. */
5752 if (real_onep (arg0
))
5753 return omit_one_operand (type
, build_real (type
, dconst1
), arg1
);
5755 if (TREE_CODE (arg1
) == REAL_CST
5756 && ! TREE_CONSTANT_OVERFLOW (arg1
))
5759 c
= TREE_REAL_CST (arg1
);
5761 /* Optimize pow(x,0.0) = 1.0. */
5762 if (REAL_VALUES_EQUAL (c
, dconst0
))
5763 return omit_one_operand (type
, build_real (type
, dconst1
),
5766 /* Optimize pow(x,1.0) = x. */
5767 if (REAL_VALUES_EQUAL (c
, dconst1
))
5770 /* Optimize pow(x,-1.0) = 1.0/x. */
5771 if (REAL_VALUES_EQUAL (c
, dconstm1
))
5772 return fold (build (RDIV_EXPR
, type
,
5773 build_real (type
, dconst1
),
5776 /* Optimize pow(x,2.0) = x*x. */
5777 if (REAL_VALUES_EQUAL (c
, dconst2
)
5778 && (*lang_hooks
.decls
.global_bindings_p
) () == 0
5779 && ! CONTAINS_PLACEHOLDER_P (arg0
))
5781 arg0
= save_expr (arg0
);
5782 return fold (build (MULT_EXPR
, type
, arg0
, arg0
));
5785 /* Optimize pow(x,-2.0) = 1.0/(x*x). */
5786 if (flag_unsafe_math_optimizations
5787 && REAL_VALUES_EQUAL (c
, dconstm2
)
5788 && (*lang_hooks
.decls
.global_bindings_p
) () == 0
5789 && ! CONTAINS_PLACEHOLDER_P (arg0
))
5791 arg0
= save_expr (arg0
);
5792 return fold (build (RDIV_EXPR
, type
,
5793 build_real (type
, dconst1
),
5794 fold (build (MULT_EXPR
, type
,
5798 /* Optimize pow(x,0.5) = sqrt(x). */
5799 if (flag_unsafe_math_optimizations
5800 && REAL_VALUES_EQUAL (c
, dconsthalf
))
5804 fcode
= DECL_FUNCTION_CODE (fndecl
);
5805 if (fcode
== BUILT_IN_POW
)
5806 sqrtfn
= implicit_built_in_decls
[BUILT_IN_SQRT
];
5807 else if (fcode
== BUILT_IN_POWF
)
5808 sqrtfn
= implicit_built_in_decls
[BUILT_IN_SQRTF
];
5809 else if (fcode
== BUILT_IN_POWL
)
5810 sqrtfn
= implicit_built_in_decls
[BUILT_IN_SQRTL
];
5814 if (sqrtfn
!= NULL_TREE
)
5816 tree arglist
= build_tree_list (NULL_TREE
, arg0
);
5817 return build_function_call_expr (sqrtfn
, arglist
);
5821 /* Attempt to evaluate pow at compile-time. */
5822 if (TREE_CODE (arg0
) == REAL_CST
5823 && ! TREE_CONSTANT_OVERFLOW (arg0
))
5825 REAL_VALUE_TYPE cint
;
5828 n
= real_to_integer (&c
);
5829 real_from_integer (&cint
, VOIDmode
, n
,
5831 if (real_identical (&c
, &cint
))
5836 x
= TREE_REAL_CST (arg0
);
5837 inexact
= real_powi (&x
, TYPE_MODE (type
), &x
, n
);
5838 if (flag_unsafe_math_optimizations
|| !inexact
)
5839 return build_real (type
, x
);
5844 /* Optimize pow(exp(x),y) = exp(x*y). */
5845 fcode
= builtin_mathfn_code (arg0
);
5846 if (flag_unsafe_math_optimizations
5847 && (fcode
== BUILT_IN_EXP
5848 || fcode
== BUILT_IN_EXPF
5849 || fcode
== BUILT_IN_EXPL
))
5851 tree expfn
= TREE_OPERAND (TREE_OPERAND (arg0
, 0), 0);
5852 tree arg
= TREE_VALUE (TREE_OPERAND (arg0
, 1));
5853 arg
= fold (build (MULT_EXPR
, type
, arg
, arg1
));
5854 arglist
= build_tree_list (NULL_TREE
, arg
);
5855 return build_function_call_expr (expfn
, arglist
);
5858 /* Optimize pow(sqrt(x),y) = pow(x,y*0.5). */
5859 if (flag_unsafe_math_optimizations
5860 && (fcode
== BUILT_IN_SQRT
5861 || fcode
== BUILT_IN_SQRTF
5862 || fcode
== BUILT_IN_SQRTL
))
5864 tree narg0
= TREE_VALUE (TREE_OPERAND (arg0
, 1));
5865 tree narg1
= fold (build (MULT_EXPR
, type
, arg1
,
5866 build_real (type
, dconsthalf
)));
5868 arglist
= tree_cons (NULL_TREE
, narg0
,
5869 build_tree_list (NULL_TREE
, narg1
));
5870 return build_function_call_expr (fndecl
, arglist
);
5873 /* Optimize pow(pow(x,y),z) = pow(x,y*z). */
5874 if (flag_unsafe_math_optimizations
5875 && (fcode
== BUILT_IN_POW
5876 || fcode
== BUILT_IN_POWF
5877 || fcode
== BUILT_IN_POWL
))
5879 tree arg00
= TREE_VALUE (TREE_OPERAND (arg0
, 1));
5880 tree arg01
= TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg0
, 1)));
5881 tree narg1
= fold (build (MULT_EXPR
, type
, arg01
, arg1
));
5882 arglist
= tree_cons (NULL_TREE
, arg00
,
5883 build_tree_list (NULL_TREE
, narg1
));
5884 return build_function_call_expr (fndecl
, arglist
);
5892 return fold_builtin_inf (type
, true);
5894 case BUILT_IN_HUGE_VAL
:
5895 case BUILT_IN_HUGE_VALF
:
5896 case BUILT_IN_HUGE_VALL
:
5897 return fold_builtin_inf (type
, false);
5902 return fold_builtin_nan (arglist
, type
, true);
5905 case BUILT_IN_NANSF
:
5906 case BUILT_IN_NANSL
:
5907 return fold_builtin_nan (arglist
, type
, false);
5909 case BUILT_IN_FLOOR
:
5910 case BUILT_IN_FLOORF
:
5911 case BUILT_IN_FLOORL
:
5913 case BUILT_IN_CEILF
:
5914 case BUILT_IN_CEILL
:
5915 case BUILT_IN_TRUNC
:
5916 case BUILT_IN_TRUNCF
:
5917 case BUILT_IN_TRUNCL
:
5918 case BUILT_IN_ROUND
:
5919 case BUILT_IN_ROUNDF
:
5920 case BUILT_IN_ROUNDL
:
5921 case BUILT_IN_NEARBYINT
:
5922 case BUILT_IN_NEARBYINTF
:
5923 case BUILT_IN_NEARBYINTL
:
5924 return fold_trunc_transparent_mathfn (exp
);
5933 /* Conveniently construct a function call expression. */
5936 build_function_call_expr (tree fn
, tree arglist
)
5940 call_expr
= build1 (ADDR_EXPR
, build_pointer_type (TREE_TYPE (fn
)), fn
);
5941 call_expr
= build (CALL_EXPR
, TREE_TYPE (TREE_TYPE (fn
)),
5942 call_expr
, arglist
);
5943 TREE_SIDE_EFFECTS (call_expr
) = 1;
5944 return fold (call_expr
);
5947 /* This function validates the types of a function call argument list
5948 represented as a tree chain of parameters against a specified list
5949 of tree_codes. If the last specifier is a 0, that represents an
5950 ellipses, otherwise the last specifier must be a VOID_TYPE. */
5953 validate_arglist (tree arglist
, ...)
5955 enum tree_code code
;
5959 va_start (ap
, arglist
);
5963 code
= va_arg (ap
, enum tree_code
);
5967 /* This signifies an ellipses, any further arguments are all ok. */
5971 /* This signifies an endlink, if no arguments remain, return
5972 true, otherwise return false. */
5976 /* If no parameters remain or the parameter's code does not
5977 match the specified code, return false. Otherwise continue
5978 checking any remaining arguments. */
5980 || code
!= TREE_CODE (TREE_TYPE (TREE_VALUE (arglist
))))
5984 arglist
= TREE_CHAIN (arglist
);
5988 /* We need gotos here since we can only have one VA_CLOSE in a
5996 /* Default version of target-specific builtin setup that does nothing. */
5999 default_init_builtins (void)
6003 /* Default target-specific builtin expander that does nothing. */
6006 default_expand_builtin (tree exp ATTRIBUTE_UNUSED
,
6007 rtx target ATTRIBUTE_UNUSED
,
6008 rtx subtarget ATTRIBUTE_UNUSED
,
6009 enum machine_mode mode ATTRIBUTE_UNUSED
,
6010 int ignore ATTRIBUTE_UNUSED
)
6015 /* Instantiate all remaining CONSTANT_P_RTX nodes. */
6018 purge_builtin_constant_p (void)
6020 rtx insn
, set
, arg
, new, note
;
6022 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
6024 && (set
= single_set (insn
)) != NULL_RTX
6025 && (GET_CODE (arg
= SET_SRC (set
)) == CONSTANT_P_RTX
6026 || (GET_CODE (arg
) == SUBREG
6027 && (GET_CODE (arg
= SUBREG_REG (arg
))
6028 == CONSTANT_P_RTX
))))
6030 arg
= XEXP (arg
, 0);
6031 new = CONSTANT_P (arg
) ? const1_rtx
: const0_rtx
;
6032 validate_change (insn
, &SET_SRC (set
), new, 0);
6034 /* Remove the REG_EQUAL note from the insn. */
6035 if ((note
= find_reg_note (insn
, REG_EQUAL
, NULL_RTX
)) != 0)
6036 remove_note (insn
, note
);
6040 /* Returns true is EXP represents data that would potentially reside
6041 in a readonly section. */
6044 readonly_data_expr (tree exp
)
6048 if (TREE_CODE (exp
) == ADDR_EXPR
)
6049 return decl_readonly_section (TREE_OPERAND (exp
, 0), 0);