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) STRINGX(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 static int get_pointer_alignment
PARAMS ((tree
, unsigned int));
83 static tree c_strlen
PARAMS ((tree
));
84 static const char *c_getstr
PARAMS ((tree
));
85 static rtx c_readstr
PARAMS ((const char *,
87 static int target_char_cast
PARAMS ((tree
, char *));
88 static rtx get_memory_rtx
PARAMS ((tree
));
89 static int apply_args_size
PARAMS ((void));
90 static int apply_result_size
PARAMS ((void));
91 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
92 static rtx result_vector
PARAMS ((int, rtx
));
94 static rtx expand_builtin_setjmp
PARAMS ((tree
, rtx
));
95 static void expand_builtin_prefetch
PARAMS ((tree
));
96 static rtx expand_builtin_apply_args
PARAMS ((void));
97 static rtx expand_builtin_apply_args_1
PARAMS ((void));
98 static rtx expand_builtin_apply
PARAMS ((rtx
, rtx
, rtx
));
99 static void expand_builtin_return
PARAMS ((rtx
));
100 static enum type_class type_to_class
PARAMS ((tree
));
101 static rtx expand_builtin_classify_type
PARAMS ((tree
));
102 static void expand_errno_check
PARAMS ((tree
, rtx
));
103 static rtx expand_builtin_mathfn
PARAMS ((tree
, rtx
, rtx
));
104 static rtx expand_builtin_mathfn_2
PARAMS ((tree
, rtx
, rtx
));
105 static rtx expand_builtin_constant_p
PARAMS ((tree
, enum machine_mode
));
106 static rtx expand_builtin_args_info
PARAMS ((tree
));
107 static rtx expand_builtin_next_arg
PARAMS ((tree
));
108 static rtx expand_builtin_va_start
PARAMS ((tree
));
109 static rtx expand_builtin_va_end
PARAMS ((tree
));
110 static rtx expand_builtin_va_copy
PARAMS ((tree
));
111 static rtx expand_builtin_memcmp
PARAMS ((tree
, tree
, rtx
,
113 static rtx expand_builtin_strcmp
PARAMS ((tree
, rtx
,
115 static rtx expand_builtin_strncmp
PARAMS ((tree
, rtx
,
117 static rtx builtin_memcpy_read_str
PARAMS ((PTR
, HOST_WIDE_INT
,
119 static rtx expand_builtin_strcat
PARAMS ((tree
, rtx
,
121 static rtx expand_builtin_strncat
PARAMS ((tree
, rtx
,
123 static rtx expand_builtin_strspn
PARAMS ((tree
, rtx
,
125 static rtx expand_builtin_strcspn
PARAMS ((tree
, rtx
,
127 static rtx expand_builtin_memcpy
PARAMS ((tree
, rtx
,
128 enum machine_mode
, int));
129 static rtx expand_builtin_mempcpy
PARAMS ((tree
, rtx
,
131 static rtx expand_builtin_memmove
PARAMS ((tree
, rtx
,
133 static rtx expand_builtin_bcopy
PARAMS ((tree
));
134 static rtx expand_builtin_strcpy
PARAMS ((tree
, rtx
,
136 static rtx expand_builtin_stpcpy
PARAMS ((tree
, rtx
,
138 static rtx builtin_strncpy_read_str
PARAMS ((PTR
, HOST_WIDE_INT
,
140 static rtx expand_builtin_strncpy
PARAMS ((tree
, rtx
,
142 static rtx builtin_memset_read_str
PARAMS ((PTR
, HOST_WIDE_INT
,
144 static rtx builtin_memset_gen_str
PARAMS ((PTR
, HOST_WIDE_INT
,
146 static rtx expand_builtin_memset
PARAMS ((tree
, rtx
,
148 static rtx expand_builtin_bzero
PARAMS ((tree
));
149 static rtx expand_builtin_strlen
PARAMS ((tree
, rtx
, enum machine_mode
));
150 static rtx expand_builtin_strstr
PARAMS ((tree
, rtx
,
152 static rtx expand_builtin_strpbrk
PARAMS ((tree
, rtx
,
154 static rtx expand_builtin_strchr
PARAMS ((tree
, rtx
,
156 static rtx expand_builtin_strrchr
PARAMS ((tree
, rtx
,
158 static rtx expand_builtin_alloca
PARAMS ((tree
, rtx
));
159 static rtx expand_builtin_unop
PARAMS ((enum machine_mode
,
160 tree
, rtx
, rtx
, optab
));
161 static rtx expand_builtin_frame_address
PARAMS ((tree
, tree
));
162 static rtx expand_builtin_fputs
PARAMS ((tree
, int, int));
163 static tree stabilize_va_list
PARAMS ((tree
, int));
164 static rtx expand_builtin_expect
PARAMS ((tree
, rtx
));
165 static tree fold_builtin_constant_p
PARAMS ((tree
));
166 static tree fold_builtin_classify_type
PARAMS ((tree
));
167 static tree fold_builtin_inf
PARAMS ((tree
, int));
168 static tree fold_builtin_nan
PARAMS ((tree
, tree
, int));
169 static int validate_arglist
PARAMS ((tree
, ...));
170 static tree fold_trunc_transparent_mathfn
PARAMS ((tree
));
171 static bool readonly_data_expr
PARAMS ((tree
));
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 (exp
, max_align
)
184 unsigned int max_align
;
186 unsigned int align
, inner
;
188 if (TREE_CODE (TREE_TYPE (exp
)) != POINTER_TYPE
)
191 align
= TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp
)));
192 align
= MIN (align
, max_align
);
196 switch (TREE_CODE (exp
))
200 case NON_LVALUE_EXPR
:
201 exp
= TREE_OPERAND (exp
, 0);
202 if (TREE_CODE (TREE_TYPE (exp
)) != POINTER_TYPE
)
205 inner
= TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp
)));
206 align
= MIN (inner
, max_align
);
210 /* If sum of pointer + int, restrict our maximum alignment to that
211 imposed by the integer. If not, we can't do any better than
213 if (! host_integerp (TREE_OPERAND (exp
, 1), 1))
216 while (((tree_low_cst (TREE_OPERAND (exp
, 1), 1))
217 & (max_align
/ BITS_PER_UNIT
- 1))
221 exp
= TREE_OPERAND (exp
, 0);
225 /* See what we are pointing at and look at its alignment. */
226 exp
= TREE_OPERAND (exp
, 0);
227 if (TREE_CODE (exp
) == FUNCTION_DECL
)
228 align
= FUNCTION_BOUNDARY
;
229 else if (DECL_P (exp
))
230 align
= DECL_ALIGN (exp
);
231 #ifdef CONSTANT_ALIGNMENT
232 else if (TREE_CODE_CLASS (TREE_CODE (exp
)) == 'c')
233 align
= CONSTANT_ALIGNMENT (exp
, align
);
235 return MIN (align
, max_align
);
243 /* Compute the length of a C string. TREE_STRING_LENGTH is not the right
244 way, because it could contain a zero byte in the middle.
245 TREE_STRING_LENGTH is the size of the character array, not the string.
247 The value returned is of type `ssizetype'.
249 Unfortunately, string_constant can't access the values of const char
250 arrays with initializers, so neither can we do so here. */
257 HOST_WIDE_INT offset
;
261 src
= string_constant (src
, &offset_node
);
265 max
= TREE_STRING_LENGTH (src
) - 1;
266 ptr
= TREE_STRING_POINTER (src
);
268 if (offset_node
&& TREE_CODE (offset_node
) != INTEGER_CST
)
270 /* If the string has an internal zero byte (e.g., "foo\0bar"), we can't
271 compute the offset to the following null if we don't know where to
272 start searching for it. */
275 for (i
= 0; i
< max
; i
++)
279 /* We don't know the starting offset, but we do know that the string
280 has no internal zero bytes. We can assume that the offset falls
281 within the bounds of the string; otherwise, the programmer deserves
282 what he gets. Subtract the offset from the length of the string,
283 and return that. This would perhaps not be valid if we were dealing
284 with named arrays in addition to literal string constants. */
286 return size_diffop (size_int (max
), offset_node
);
289 /* We have a known offset into the string. Start searching there for
290 a null character if we can represent it as a single HOST_WIDE_INT. */
291 if (offset_node
== 0)
293 else if (! host_integerp (offset_node
, 0))
296 offset
= tree_low_cst (offset_node
, 0);
298 /* If the offset is known to be out of bounds, warn, and call strlen at
300 if (offset
< 0 || offset
> max
)
302 warning ("offset outside bounds of constant string");
306 /* Use strlen to search for the first zero byte. Since any strings
307 constructed with build_string will have nulls appended, we win even
308 if we get handed something like (char[4])"abcd".
310 Since OFFSET is our starting index into the string, no further
311 calculation is needed. */
312 return ssize_int (strlen (ptr
+ offset
));
315 /* Return a char pointer for a C string if it is a string constant
316 or sum of string constant and integer constant. */
324 src
= string_constant (src
, &offset_node
);
328 if (offset_node
== 0)
329 return TREE_STRING_POINTER (src
);
330 else if (!host_integerp (offset_node
, 1)
331 || compare_tree_int (offset_node
, TREE_STRING_LENGTH (src
) - 1) > 0)
334 return TREE_STRING_POINTER (src
) + tree_low_cst (offset_node
, 1);
337 /* Return a CONST_INT or CONST_DOUBLE corresponding to target reading
338 GET_MODE_BITSIZE (MODE) bits from string constant STR. */
341 c_readstr (str
, mode
)
343 enum machine_mode mode
;
349 if (GET_MODE_CLASS (mode
) != MODE_INT
)
354 for (i
= 0; i
< GET_MODE_SIZE (mode
); i
++)
357 if (WORDS_BIG_ENDIAN
)
358 j
= GET_MODE_SIZE (mode
) - i
- 1;
359 if (BYTES_BIG_ENDIAN
!= WORDS_BIG_ENDIAN
360 && GET_MODE_SIZE (mode
) > UNITS_PER_WORD
)
361 j
= j
+ UNITS_PER_WORD
- 2 * (j
% UNITS_PER_WORD
) - 1;
363 if (j
> 2 * HOST_BITS_PER_WIDE_INT
)
366 ch
= (unsigned char) str
[i
];
367 c
[j
/ HOST_BITS_PER_WIDE_INT
] |= ch
<< (j
% HOST_BITS_PER_WIDE_INT
);
369 return immed_double_const (c
[0], c
[1], mode
);
372 /* Cast a target constant CST to target CHAR and if that value fits into
373 host char type, return zero and put that value into variable pointed by
377 target_char_cast (cst
, p
)
381 unsigned HOST_WIDE_INT val
, hostval
;
383 if (!host_integerp (cst
, 1)
384 || CHAR_TYPE_SIZE
> HOST_BITS_PER_WIDE_INT
)
387 val
= tree_low_cst (cst
, 1);
388 if (CHAR_TYPE_SIZE
< HOST_BITS_PER_WIDE_INT
)
389 val
&= (((unsigned HOST_WIDE_INT
) 1) << CHAR_TYPE_SIZE
) - 1;
392 if (HOST_BITS_PER_CHAR
< HOST_BITS_PER_WIDE_INT
)
393 hostval
&= (((unsigned HOST_WIDE_INT
) 1) << HOST_BITS_PER_CHAR
) - 1;
402 /* Given TEM, a pointer to a stack frame, follow the dynamic chain COUNT
403 times to get the address of either a higher stack frame, or a return
404 address located within it (depending on FNDECL_CODE). */
407 expand_builtin_return_addr (fndecl_code
, count
, tem
)
408 enum built_in_function fndecl_code
;
414 /* Some machines need special handling before we can access
415 arbitrary frames. For example, on the sparc, we must first flush
416 all register windows to the stack. */
417 #ifdef SETUP_FRAME_ADDRESSES
419 SETUP_FRAME_ADDRESSES ();
422 /* On the sparc, the return address is not in the frame, it is in a
423 register. There is no way to access it off of the current frame
424 pointer, but it can be accessed off the previous frame pointer by
425 reading the value from the register window save area. */
426 #ifdef RETURN_ADDR_IN_PREVIOUS_FRAME
427 if (fndecl_code
== BUILT_IN_RETURN_ADDRESS
)
431 /* Scan back COUNT frames to the specified frame. */
432 for (i
= 0; i
< count
; i
++)
434 /* Assume the dynamic chain pointer is in the word that the
435 frame address points to, unless otherwise specified. */
436 #ifdef DYNAMIC_CHAIN_ADDRESS
437 tem
= DYNAMIC_CHAIN_ADDRESS (tem
);
439 tem
= memory_address (Pmode
, tem
);
440 tem
= gen_rtx_MEM (Pmode
, tem
);
441 set_mem_alias_set (tem
, get_frame_alias_set ());
442 tem
= copy_to_reg (tem
);
445 /* For __builtin_frame_address, return what we've got. */
446 if (fndecl_code
== BUILT_IN_FRAME_ADDRESS
)
449 /* For __builtin_return_address, Get the return address from that
451 #ifdef RETURN_ADDR_RTX
452 tem
= RETURN_ADDR_RTX (count
, tem
);
454 tem
= memory_address (Pmode
,
455 plus_constant (tem
, GET_MODE_SIZE (Pmode
)));
456 tem
= gen_rtx_MEM (Pmode
, tem
);
457 set_mem_alias_set (tem
, get_frame_alias_set ());
462 /* Alias set used for setjmp buffer. */
463 static HOST_WIDE_INT setjmp_alias_set
= -1;
465 /* Construct the leading half of a __builtin_setjmp call. Control will
466 return to RECEIVER_LABEL. This is used directly by sjlj exception
470 expand_builtin_setjmp_setup (buf_addr
, receiver_label
)
474 enum machine_mode sa_mode
= STACK_SAVEAREA_MODE (SAVE_NONLOCAL
);
478 if (setjmp_alias_set
== -1)
479 setjmp_alias_set
= new_alias_set ();
481 #ifdef POINTERS_EXTEND_UNSIGNED
482 if (GET_MODE (buf_addr
) != Pmode
)
483 buf_addr
= convert_memory_address (Pmode
, buf_addr
);
486 buf_addr
= force_reg (Pmode
, force_operand (buf_addr
, NULL_RTX
));
490 /* We store the frame pointer and the address of receiver_label in
491 the buffer and use the rest of it for the stack save area, which
492 is machine-dependent. */
494 #ifndef BUILTIN_SETJMP_FRAME_VALUE
495 #define BUILTIN_SETJMP_FRAME_VALUE virtual_stack_vars_rtx
498 mem
= gen_rtx_MEM (Pmode
, buf_addr
);
499 set_mem_alias_set (mem
, setjmp_alias_set
);
500 emit_move_insn (mem
, BUILTIN_SETJMP_FRAME_VALUE
);
502 mem
= gen_rtx_MEM (Pmode
, plus_constant (buf_addr
, GET_MODE_SIZE (Pmode
))),
503 set_mem_alias_set (mem
, setjmp_alias_set
);
505 emit_move_insn (validize_mem (mem
),
506 force_reg (Pmode
, gen_rtx_LABEL_REF (Pmode
, receiver_label
)));
508 stack_save
= gen_rtx_MEM (sa_mode
,
509 plus_constant (buf_addr
,
510 2 * GET_MODE_SIZE (Pmode
)));
511 set_mem_alias_set (stack_save
, setjmp_alias_set
);
512 emit_stack_save (SAVE_NONLOCAL
, &stack_save
, NULL_RTX
);
514 /* If there is further processing to do, do it. */
515 #ifdef HAVE_builtin_setjmp_setup
516 if (HAVE_builtin_setjmp_setup
)
517 emit_insn (gen_builtin_setjmp_setup (buf_addr
));
520 /* Tell optimize_save_area_alloca that extra work is going to
521 need to go on during alloca. */
522 current_function_calls_setjmp
= 1;
524 /* Set this so all the registers get saved in our frame; we need to be
525 able to copy the saved values for any registers from frames we unwind. */
526 current_function_has_nonlocal_label
= 1;
529 /* Construct the trailing part of a __builtin_setjmp call.
530 This is used directly by sjlj exception handling code. */
533 expand_builtin_setjmp_receiver (receiver_label
)
534 rtx receiver_label ATTRIBUTE_UNUSED
;
536 /* Clobber the FP when we get here, so we have to make sure it's
537 marked as used by this function. */
538 emit_insn (gen_rtx_USE (VOIDmode
, hard_frame_pointer_rtx
));
540 /* Mark the static chain as clobbered here so life information
541 doesn't get messed up for it. */
542 emit_insn (gen_rtx_CLOBBER (VOIDmode
, static_chain_rtx
));
544 /* Now put in the code to restore the frame pointer, and argument
545 pointer, if needed. The code below is from expand_end_bindings
546 in stmt.c; see detailed documentation there. */
547 #ifdef HAVE_nonlocal_goto
548 if (! HAVE_nonlocal_goto
)
550 emit_move_insn (virtual_stack_vars_rtx
, hard_frame_pointer_rtx
);
552 #if ARG_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
553 if (fixed_regs
[ARG_POINTER_REGNUM
])
555 #ifdef ELIMINABLE_REGS
557 static const struct elims
{const int from
, to
;} elim_regs
[] = ELIMINABLE_REGS
;
559 for (i
= 0; i
< ARRAY_SIZE (elim_regs
); i
++)
560 if (elim_regs
[i
].from
== ARG_POINTER_REGNUM
561 && elim_regs
[i
].to
== HARD_FRAME_POINTER_REGNUM
)
564 if (i
== ARRAY_SIZE (elim_regs
))
567 /* Now restore our arg pointer from the address at which it
568 was saved in our stack frame. */
569 emit_move_insn (virtual_incoming_args_rtx
,
570 copy_to_reg (get_arg_pointer_save_area (cfun
)));
575 #ifdef HAVE_builtin_setjmp_receiver
576 if (HAVE_builtin_setjmp_receiver
)
577 emit_insn (gen_builtin_setjmp_receiver (receiver_label
));
580 #ifdef HAVE_nonlocal_goto_receiver
581 if (HAVE_nonlocal_goto_receiver
)
582 emit_insn (gen_nonlocal_goto_receiver ());
587 /* @@@ This is a kludge. Not all machine descriptions define a blockage
588 insn, but we must not allow the code we just generated to be reordered
589 by scheduling. Specifically, the update of the frame pointer must
590 happen immediately, not later. So emit an ASM_INPUT to act as blockage
592 emit_insn (gen_rtx_ASM_INPUT (VOIDmode
, ""));
595 /* __builtin_setjmp is passed a pointer to an array of five words (not
596 all will be used on all machines). It operates similarly to the C
597 library function of the same name, but is more efficient. Much of
598 the code below (and for longjmp) is copied from the handling of
601 NOTE: This is intended for use by GNAT and the exception handling
602 scheme in the compiler and will only work in the method used by
606 expand_builtin_setjmp (arglist
, target
)
610 rtx buf_addr
, next_lab
, cont_lab
;
612 if (!validate_arglist (arglist
, POINTER_TYPE
, VOID_TYPE
))
615 if (target
== 0 || GET_CODE (target
) != REG
616 || REGNO (target
) < FIRST_PSEUDO_REGISTER
)
617 target
= gen_reg_rtx (TYPE_MODE (integer_type_node
));
619 buf_addr
= expand_expr (TREE_VALUE (arglist
), NULL_RTX
, VOIDmode
, 0);
621 next_lab
= gen_label_rtx ();
622 cont_lab
= gen_label_rtx ();
624 expand_builtin_setjmp_setup (buf_addr
, next_lab
);
626 /* Set TARGET to zero and branch to the continue label. */
627 emit_move_insn (target
, const0_rtx
);
628 emit_jump_insn (gen_jump (cont_lab
));
630 emit_label (next_lab
);
632 expand_builtin_setjmp_receiver (next_lab
);
634 /* Set TARGET to one. */
635 emit_move_insn (target
, const1_rtx
);
636 emit_label (cont_lab
);
638 /* Tell flow about the strange goings on. Putting `next_lab' on
639 `nonlocal_goto_handler_labels' to indicates that function
640 calls may traverse the arc back to this label. */
642 current_function_has_nonlocal_label
= 1;
643 nonlocal_goto_handler_labels
644 = gen_rtx_EXPR_LIST (VOIDmode
, next_lab
, nonlocal_goto_handler_labels
);
649 /* __builtin_longjmp is passed a pointer to an array of five words (not
650 all will be used on all machines). It operates similarly to the C
651 library function of the same name, but is more efficient. Much of
652 the code below is copied from the handling of non-local gotos.
654 NOTE: This is intended for use by GNAT and the exception handling
655 scheme in the compiler and will only work in the method used by
659 expand_builtin_longjmp (buf_addr
, value
)
662 rtx fp
, lab
, stack
, insn
, last
;
663 enum machine_mode sa_mode
= STACK_SAVEAREA_MODE (SAVE_NONLOCAL
);
665 if (setjmp_alias_set
== -1)
666 setjmp_alias_set
= new_alias_set ();
668 #ifdef POINTERS_EXTEND_UNSIGNED
669 if (GET_MODE (buf_addr
) != Pmode
)
670 buf_addr
= convert_memory_address (Pmode
, buf_addr
);
673 buf_addr
= force_reg (Pmode
, buf_addr
);
675 /* We used to store value in static_chain_rtx, but that fails if pointers
676 are smaller than integers. We instead require that the user must pass
677 a second argument of 1, because that is what builtin_setjmp will
678 return. This also makes EH slightly more efficient, since we are no
679 longer copying around a value that we don't care about. */
680 if (value
!= const1_rtx
)
683 current_function_calls_longjmp
= 1;
685 last
= get_last_insn ();
686 #ifdef HAVE_builtin_longjmp
687 if (HAVE_builtin_longjmp
)
688 emit_insn (gen_builtin_longjmp (buf_addr
));
692 fp
= gen_rtx_MEM (Pmode
, buf_addr
);
693 lab
= gen_rtx_MEM (Pmode
, plus_constant (buf_addr
,
694 GET_MODE_SIZE (Pmode
)));
696 stack
= gen_rtx_MEM (sa_mode
, plus_constant (buf_addr
,
697 2 * GET_MODE_SIZE (Pmode
)));
698 set_mem_alias_set (fp
, setjmp_alias_set
);
699 set_mem_alias_set (lab
, setjmp_alias_set
);
700 set_mem_alias_set (stack
, setjmp_alias_set
);
702 /* Pick up FP, label, and SP from the block and jump. This code is
703 from expand_goto in stmt.c; see there for detailed comments. */
704 #if HAVE_nonlocal_goto
705 if (HAVE_nonlocal_goto
)
706 /* We have to pass a value to the nonlocal_goto pattern that will
707 get copied into the static_chain pointer, but it does not matter
708 what that value is, because builtin_setjmp does not use it. */
709 emit_insn (gen_nonlocal_goto (value
, lab
, stack
, fp
));
713 lab
= copy_to_reg (lab
);
715 emit_move_insn (hard_frame_pointer_rtx
, fp
);
716 emit_stack_restore (SAVE_NONLOCAL
, stack
, NULL_RTX
);
718 emit_insn (gen_rtx_USE (VOIDmode
, hard_frame_pointer_rtx
));
719 emit_insn (gen_rtx_USE (VOIDmode
, stack_pointer_rtx
));
720 emit_indirect_jump (lab
);
724 /* Search backwards and mark the jump insn as a non-local goto.
725 Note that this precludes the use of __builtin_longjmp to a
726 __builtin_setjmp target in the same function. However, we've
727 already cautioned the user that these functions are for
728 internal exception handling use only. */
729 for (insn
= get_last_insn (); insn
; insn
= PREV_INSN (insn
))
733 if (GET_CODE (insn
) == JUMP_INSN
)
735 REG_NOTES (insn
) = alloc_EXPR_LIST (REG_NON_LOCAL_GOTO
, const0_rtx
,
739 else if (GET_CODE (insn
) == CALL_INSN
)
744 /* Expand a call to __builtin_prefetch. For a target that does not support
745 data prefetch, evaluate the memory address argument in case it has side
749 expand_builtin_prefetch (arglist
)
752 tree arg0
, arg1
, arg2
;
755 if (!validate_arglist (arglist
, POINTER_TYPE
, 0))
758 arg0
= TREE_VALUE (arglist
);
759 /* Arguments 1 and 2 are optional; argument 1 (read/write) defaults to
760 zero (read) and argument 2 (locality) defaults to 3 (high degree of
762 if (TREE_CHAIN (arglist
))
764 arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
765 if (TREE_CHAIN (TREE_CHAIN (arglist
)))
766 arg2
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
768 arg2
= build_int_2 (3, 0);
772 arg1
= integer_zero_node
;
773 arg2
= build_int_2 (3, 0);
776 /* Argument 0 is an address. */
777 op0
= expand_expr (arg0
, NULL_RTX
, Pmode
, EXPAND_NORMAL
);
779 /* Argument 1 (read/write flag) must be a compile-time constant int. */
780 if (TREE_CODE (arg1
) != INTEGER_CST
)
782 error ("second arg to `__builtin_prefetch' must be a constant");
783 arg1
= integer_zero_node
;
785 op1
= expand_expr (arg1
, NULL_RTX
, VOIDmode
, 0);
786 /* Argument 1 must be either zero or one. */
787 if (INTVAL (op1
) != 0 && INTVAL (op1
) != 1)
789 warning ("invalid second arg to __builtin_prefetch; using zero");
793 /* Argument 2 (locality) must be a compile-time constant int. */
794 if (TREE_CODE (arg2
) != INTEGER_CST
)
796 error ("third arg to `__builtin_prefetch' must be a constant");
797 arg2
= integer_zero_node
;
799 op2
= expand_expr (arg2
, NULL_RTX
, VOIDmode
, 0);
800 /* Argument 2 must be 0, 1, 2, or 3. */
801 if (INTVAL (op2
) < 0 || INTVAL (op2
) > 3)
803 warning ("invalid third arg to __builtin_prefetch; using zero");
810 if ((! (*insn_data
[(int) CODE_FOR_prefetch
].operand
[0].predicate
)
812 insn_data
[(int) CODE_FOR_prefetch
].operand
[0].mode
))
813 || (GET_MODE(op0
) != Pmode
))
815 #ifdef POINTERS_EXTEND_UNSIGNED
816 if (GET_MODE(op0
) != Pmode
)
817 op0
= convert_memory_address (Pmode
, op0
);
819 op0
= force_reg (Pmode
, op0
);
821 emit_insn (gen_prefetch (op0
, op1
, op2
));
825 op0
= protect_from_queue (op0
, 0);
826 /* Don't do anything with direct references to volatile memory, but
827 generate code to handle other side effects. */
828 if (GET_CODE (op0
) != MEM
&& side_effects_p (op0
))
832 /* Get a MEM rtx for expression EXP which is the address of an operand
833 to be used to be used in a string instruction (cmpstrsi, movstrsi, ..). */
839 rtx addr
= expand_expr (exp
, NULL_RTX
, ptr_mode
, EXPAND_SUM
);
842 #ifdef POINTERS_EXTEND_UNSIGNED
843 if (GET_MODE (addr
) != Pmode
)
844 addr
= convert_memory_address (Pmode
, addr
);
847 mem
= gen_rtx_MEM (BLKmode
, memory_address (BLKmode
, addr
));
849 /* Get an expression we can use to find the attributes to assign to MEM.
850 If it is an ADDR_EXPR, use the operand. Otherwise, dereference it if
851 we can. First remove any nops. */
852 while ((TREE_CODE (exp
) == NOP_EXPR
|| TREE_CODE (exp
) == CONVERT_EXPR
853 || TREE_CODE (exp
) == NON_LVALUE_EXPR
)
854 && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (exp
, 0))))
855 exp
= TREE_OPERAND (exp
, 0);
857 if (TREE_CODE (exp
) == ADDR_EXPR
)
859 exp
= TREE_OPERAND (exp
, 0);
860 set_mem_attributes (mem
, exp
, 0);
862 else if (POINTER_TYPE_P (TREE_TYPE (exp
)))
864 exp
= build1 (INDIRECT_REF
, TREE_TYPE (TREE_TYPE (exp
)), exp
);
865 /* memcpy, memset and other builtin stringops can alias with anything. */
866 set_mem_alias_set (mem
, 0);
872 /* Built-in functions to perform an untyped call and return. */
874 /* For each register that may be used for calling a function, this
875 gives a mode used to copy the register's value. VOIDmode indicates
876 the register is not used for calling a function. If the machine
877 has register windows, this gives only the outbound registers.
878 INCOMING_REGNO gives the corresponding inbound register. */
879 static enum machine_mode apply_args_mode
[FIRST_PSEUDO_REGISTER
];
881 /* For each register that may be used for returning values, this gives
882 a mode used to copy the register's value. VOIDmode indicates the
883 register is not used for returning values. If the machine has
884 register windows, this gives only the outbound registers.
885 INCOMING_REGNO gives the corresponding inbound register. */
886 static enum machine_mode apply_result_mode
[FIRST_PSEUDO_REGISTER
];
888 /* For each register that may be used for calling a function, this
889 gives the offset of that register into the block returned by
890 __builtin_apply_args. 0 indicates that the register is not
891 used for calling a function. */
892 static int apply_args_reg_offset
[FIRST_PSEUDO_REGISTER
];
894 /* Return the offset of register REGNO into the block returned by
895 __builtin_apply_args. This is not declared static, since it is
896 needed in objc-act.c. */
899 apply_args_register_offset (regno
)
904 /* Arguments are always put in outgoing registers (in the argument
905 block) if such make sense. */
906 #ifdef OUTGOING_REGNO
907 regno
= OUTGOING_REGNO (regno
);
909 return apply_args_reg_offset
[regno
];
912 /* Return the size required for the block returned by __builtin_apply_args,
913 and initialize apply_args_mode. */
918 static int size
= -1;
921 enum machine_mode mode
;
923 /* The values computed by this function never change. */
926 /* The first value is the incoming arg-pointer. */
927 size
= GET_MODE_SIZE (Pmode
);
929 /* The second value is the structure value address unless this is
930 passed as an "invisible" first argument. */
931 if (struct_value_rtx
)
932 size
+= GET_MODE_SIZE (Pmode
);
934 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
935 if (FUNCTION_ARG_REGNO_P (regno
))
937 /* Search for the proper mode for copying this register's
938 value. I'm not sure this is right, but it works so far. */
939 enum machine_mode best_mode
= VOIDmode
;
941 for (mode
= GET_CLASS_NARROWEST_MODE (MODE_INT
);
943 mode
= GET_MODE_WIDER_MODE (mode
))
944 if (HARD_REGNO_MODE_OK (regno
, mode
)
945 && HARD_REGNO_NREGS (regno
, mode
) == 1)
948 if (best_mode
== VOIDmode
)
949 for (mode
= GET_CLASS_NARROWEST_MODE (MODE_FLOAT
);
951 mode
= GET_MODE_WIDER_MODE (mode
))
952 if (HARD_REGNO_MODE_OK (regno
, mode
)
953 && have_insn_for (SET
, mode
))
956 if (best_mode
== VOIDmode
)
957 for (mode
= GET_CLASS_NARROWEST_MODE (MODE_VECTOR_FLOAT
);
959 mode
= GET_MODE_WIDER_MODE (mode
))
960 if (HARD_REGNO_MODE_OK (regno
, mode
)
961 && have_insn_for (SET
, mode
))
964 if (best_mode
== VOIDmode
)
965 for (mode
= GET_CLASS_NARROWEST_MODE (MODE_VECTOR_INT
);
967 mode
= GET_MODE_WIDER_MODE (mode
))
968 if (HARD_REGNO_MODE_OK (regno
, mode
)
969 && have_insn_for (SET
, mode
))
973 if (mode
== VOIDmode
)
976 align
= GET_MODE_ALIGNMENT (mode
) / BITS_PER_UNIT
;
977 if (size
% align
!= 0)
978 size
= CEIL (size
, align
) * align
;
979 apply_args_reg_offset
[regno
] = size
;
980 size
+= GET_MODE_SIZE (mode
);
981 apply_args_mode
[regno
] = mode
;
985 apply_args_mode
[regno
] = VOIDmode
;
986 apply_args_reg_offset
[regno
] = 0;
992 /* Return the size required for the block returned by __builtin_apply,
993 and initialize apply_result_mode. */
998 static int size
= -1;
1000 enum machine_mode mode
;
1002 /* The values computed by this function never change. */
1007 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
1008 if (FUNCTION_VALUE_REGNO_P (regno
))
1010 /* Search for the proper mode for copying this register's
1011 value. I'm not sure this is right, but it works so far. */
1012 enum machine_mode best_mode
= VOIDmode
;
1014 for (mode
= GET_CLASS_NARROWEST_MODE (MODE_INT
);
1016 mode
= GET_MODE_WIDER_MODE (mode
))
1017 if (HARD_REGNO_MODE_OK (regno
, mode
))
1020 if (best_mode
== VOIDmode
)
1021 for (mode
= GET_CLASS_NARROWEST_MODE (MODE_FLOAT
);
1023 mode
= GET_MODE_WIDER_MODE (mode
))
1024 if (HARD_REGNO_MODE_OK (regno
, mode
)
1025 && have_insn_for (SET
, mode
))
1028 if (best_mode
== VOIDmode
)
1029 for (mode
= GET_CLASS_NARROWEST_MODE (MODE_VECTOR_FLOAT
);
1031 mode
= GET_MODE_WIDER_MODE (mode
))
1032 if (HARD_REGNO_MODE_OK (regno
, mode
)
1033 && have_insn_for (SET
, mode
))
1036 if (best_mode
== VOIDmode
)
1037 for (mode
= GET_CLASS_NARROWEST_MODE (MODE_VECTOR_INT
);
1039 mode
= GET_MODE_WIDER_MODE (mode
))
1040 if (HARD_REGNO_MODE_OK (regno
, mode
)
1041 && have_insn_for (SET
, mode
))
1045 if (mode
== VOIDmode
)
1048 align
= GET_MODE_ALIGNMENT (mode
) / BITS_PER_UNIT
;
1049 if (size
% align
!= 0)
1050 size
= CEIL (size
, align
) * align
;
1051 size
+= GET_MODE_SIZE (mode
);
1052 apply_result_mode
[regno
] = mode
;
1055 apply_result_mode
[regno
] = VOIDmode
;
1057 /* Allow targets that use untyped_call and untyped_return to override
1058 the size so that machine-specific information can be stored here. */
1059 #ifdef APPLY_RESULT_SIZE
1060 size
= APPLY_RESULT_SIZE
;
1066 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
1067 /* Create a vector describing the result block RESULT. If SAVEP is true,
1068 the result block is used to save the values; otherwise it is used to
1069 restore the values. */
1072 result_vector (savep
, result
)
1076 int regno
, size
, align
, nelts
;
1077 enum machine_mode mode
;
1079 rtx
*savevec
= (rtx
*) alloca (FIRST_PSEUDO_REGISTER
* sizeof (rtx
));
1082 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
1083 if ((mode
= apply_result_mode
[regno
]) != VOIDmode
)
1085 align
= GET_MODE_ALIGNMENT (mode
) / BITS_PER_UNIT
;
1086 if (size
% align
!= 0)
1087 size
= CEIL (size
, align
) * align
;
1088 reg
= gen_rtx_REG (mode
, savep
? regno
: INCOMING_REGNO (regno
));
1089 mem
= adjust_address (result
, mode
, size
);
1090 savevec
[nelts
++] = (savep
1091 ? gen_rtx_SET (VOIDmode
, mem
, reg
)
1092 : gen_rtx_SET (VOIDmode
, reg
, mem
));
1093 size
+= GET_MODE_SIZE (mode
);
1095 return gen_rtx_PARALLEL (VOIDmode
, gen_rtvec_v (nelts
, savevec
));
1097 #endif /* HAVE_untyped_call or HAVE_untyped_return */
1099 /* Save the state required to perform an untyped call with the same
1100 arguments as were passed to the current function. */
1103 expand_builtin_apply_args_1 ()
1106 int size
, align
, regno
;
1107 enum machine_mode mode
;
1109 /* Create a block where the arg-pointer, structure value address,
1110 and argument registers can be saved. */
1111 registers
= assign_stack_local (BLKmode
, apply_args_size (), -1);
1113 /* Walk past the arg-pointer and structure value address. */
1114 size
= GET_MODE_SIZE (Pmode
);
1115 if (struct_value_rtx
)
1116 size
+= GET_MODE_SIZE (Pmode
);
1118 /* Save each register used in calling a function to the block. */
1119 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
1120 if ((mode
= apply_args_mode
[regno
]) != VOIDmode
)
1124 align
= GET_MODE_ALIGNMENT (mode
) / BITS_PER_UNIT
;
1125 if (size
% align
!= 0)
1126 size
= CEIL (size
, align
) * align
;
1128 tem
= gen_rtx_REG (mode
, INCOMING_REGNO (regno
));
1130 emit_move_insn (adjust_address (registers
, mode
, size
), tem
);
1131 size
+= GET_MODE_SIZE (mode
);
1134 /* Save the arg pointer to the block. */
1135 emit_move_insn (adjust_address (registers
, Pmode
, 0),
1136 copy_to_reg (virtual_incoming_args_rtx
));
1137 size
= GET_MODE_SIZE (Pmode
);
1139 /* Save the structure value address unless this is passed as an
1140 "invisible" first argument. */
1141 if (struct_value_incoming_rtx
)
1143 emit_move_insn (adjust_address (registers
, Pmode
, size
),
1144 copy_to_reg (struct_value_incoming_rtx
));
1145 size
+= GET_MODE_SIZE (Pmode
);
1148 /* Return the address of the block. */
1149 return copy_addr_to_reg (XEXP (registers
, 0));
1152 /* __builtin_apply_args returns block of memory allocated on
1153 the stack into which is stored the arg pointer, structure
1154 value address, static chain, and all the registers that might
1155 possibly be used in performing a function call. The code is
1156 moved to the start of the function so the incoming values are
1160 expand_builtin_apply_args ()
1162 /* Don't do __builtin_apply_args more than once in a function.
1163 Save the result of the first call and reuse it. */
1164 if (apply_args_value
!= 0)
1165 return apply_args_value
;
1167 /* When this function is called, it means that registers must be
1168 saved on entry to this function. So we migrate the
1169 call to the first insn of this function. */
1174 temp
= expand_builtin_apply_args_1 ();
1178 apply_args_value
= temp
;
1180 /* Put the insns after the NOTE that starts the function.
1181 If this is inside a start_sequence, make the outer-level insn
1182 chain current, so the code is placed at the start of the
1184 push_topmost_sequence ();
1185 emit_insn_before (seq
, NEXT_INSN (get_insns ()));
1186 pop_topmost_sequence ();
1191 /* Perform an untyped call and save the state required to perform an
1192 untyped return of whatever value was returned by the given function. */
1195 expand_builtin_apply (function
, arguments
, argsize
)
1196 rtx function
, arguments
, argsize
;
1198 int size
, align
, regno
;
1199 enum machine_mode mode
;
1200 rtx incoming_args
, result
, reg
, dest
, src
, call_insn
;
1201 rtx old_stack_level
= 0;
1202 rtx call_fusage
= 0;
1204 #ifdef POINTERS_EXTEND_UNSIGNED
1205 if (GET_MODE (arguments
) != Pmode
)
1206 arguments
= convert_memory_address (Pmode
, arguments
);
1209 /* Create a block where the return registers can be saved. */
1210 result
= assign_stack_local (BLKmode
, apply_result_size (), -1);
1212 /* Fetch the arg pointer from the ARGUMENTS block. */
1213 incoming_args
= gen_reg_rtx (Pmode
);
1214 emit_move_insn (incoming_args
, gen_rtx_MEM (Pmode
, arguments
));
1215 #ifndef STACK_GROWS_DOWNWARD
1216 incoming_args
= expand_simple_binop (Pmode
, MINUS
, incoming_args
, argsize
,
1217 incoming_args
, 0, OPTAB_LIB_WIDEN
);
1220 /* Perform postincrements before actually calling the function. */
1223 /* Push a new argument block and copy the arguments. Do not allow
1224 the (potential) memcpy call below to interfere with our stack
1226 do_pending_stack_adjust ();
1229 /* Save the stack with nonlocal if available */
1230 #ifdef HAVE_save_stack_nonlocal
1231 if (HAVE_save_stack_nonlocal
)
1232 emit_stack_save (SAVE_NONLOCAL
, &old_stack_level
, NULL_RTX
);
1235 emit_stack_save (SAVE_BLOCK
, &old_stack_level
, NULL_RTX
);
1237 /* Push a block of memory onto the stack to store the memory arguments.
1238 Save the address in a register, and copy the memory arguments. ??? I
1239 haven't figured out how the calling convention macros effect this,
1240 but it's likely that the source and/or destination addresses in
1241 the block copy will need updating in machine specific ways. */
1242 dest
= allocate_dynamic_stack_space (argsize
, 0, BITS_PER_UNIT
);
1243 dest
= gen_rtx_MEM (BLKmode
, dest
);
1244 set_mem_align (dest
, PARM_BOUNDARY
);
1245 src
= gen_rtx_MEM (BLKmode
, incoming_args
);
1246 set_mem_align (src
, PARM_BOUNDARY
);
1247 emit_block_move (dest
, src
, argsize
, BLOCK_OP_NORMAL
);
1249 /* Refer to the argument block. */
1251 arguments
= gen_rtx_MEM (BLKmode
, arguments
);
1252 set_mem_align (arguments
, PARM_BOUNDARY
);
1254 /* Walk past the arg-pointer and structure value address. */
1255 size
= GET_MODE_SIZE (Pmode
);
1256 if (struct_value_rtx
)
1257 size
+= GET_MODE_SIZE (Pmode
);
1259 /* Restore each of the registers previously saved. Make USE insns
1260 for each of these registers for use in making the call. */
1261 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
1262 if ((mode
= apply_args_mode
[regno
]) != VOIDmode
)
1264 align
= GET_MODE_ALIGNMENT (mode
) / BITS_PER_UNIT
;
1265 if (size
% align
!= 0)
1266 size
= CEIL (size
, align
) * align
;
1267 reg
= gen_rtx_REG (mode
, regno
);
1268 emit_move_insn (reg
, adjust_address (arguments
, mode
, size
));
1269 use_reg (&call_fusage
, reg
);
1270 size
+= GET_MODE_SIZE (mode
);
1273 /* Restore the structure value address unless this is passed as an
1274 "invisible" first argument. */
1275 size
= GET_MODE_SIZE (Pmode
);
1276 if (struct_value_rtx
)
1278 rtx value
= gen_reg_rtx (Pmode
);
1279 emit_move_insn (value
, adjust_address (arguments
, Pmode
, size
));
1280 emit_move_insn (struct_value_rtx
, value
);
1281 if (GET_CODE (struct_value_rtx
) == REG
)
1282 use_reg (&call_fusage
, struct_value_rtx
);
1283 size
+= GET_MODE_SIZE (Pmode
);
1286 /* All arguments and registers used for the call are set up by now! */
1287 function
= prepare_call_address (function
, NULL_TREE
, &call_fusage
, 0, 0);
1289 /* Ensure address is valid. SYMBOL_REF is already valid, so no need,
1290 and we don't want to load it into a register as an optimization,
1291 because prepare_call_address already did it if it should be done. */
1292 if (GET_CODE (function
) != SYMBOL_REF
)
1293 function
= memory_address (FUNCTION_MODE
, function
);
1295 /* Generate the actual call instruction and save the return value. */
1296 #ifdef HAVE_untyped_call
1297 if (HAVE_untyped_call
)
1298 emit_call_insn (gen_untyped_call (gen_rtx_MEM (FUNCTION_MODE
, function
),
1299 result
, result_vector (1, result
)));
1302 #ifdef HAVE_call_value
1303 if (HAVE_call_value
)
1307 /* Locate the unique return register. It is not possible to
1308 express a call that sets more than one return register using
1309 call_value; use untyped_call for that. In fact, untyped_call
1310 only needs to save the return registers in the given block. */
1311 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
1312 if ((mode
= apply_result_mode
[regno
]) != VOIDmode
)
1315 abort (); /* HAVE_untyped_call required. */
1316 valreg
= gen_rtx_REG (mode
, regno
);
1319 emit_call_insn (GEN_CALL_VALUE (valreg
,
1320 gen_rtx_MEM (FUNCTION_MODE
, function
),
1321 const0_rtx
, NULL_RTX
, const0_rtx
));
1323 emit_move_insn (adjust_address (result
, GET_MODE (valreg
), 0), valreg
);
1329 /* Find the CALL insn we just emitted, and attach the register usage
1331 call_insn
= last_call_insn ();
1332 add_function_usage_to (call_insn
, call_fusage
);
1334 /* Restore the stack. */
1335 #ifdef HAVE_save_stack_nonlocal
1336 if (HAVE_save_stack_nonlocal
)
1337 emit_stack_restore (SAVE_NONLOCAL
, old_stack_level
, NULL_RTX
);
1340 emit_stack_restore (SAVE_BLOCK
, old_stack_level
, NULL_RTX
);
1344 /* Return the address of the result block. */
1345 return copy_addr_to_reg (XEXP (result
, 0));
1348 /* Perform an untyped return. */
1351 expand_builtin_return (result
)
1354 int size
, align
, regno
;
1355 enum machine_mode mode
;
1357 rtx call_fusage
= 0;
1359 #ifdef POINTERS_EXTEND_UNSIGNED
1360 if (GET_MODE (result
) != Pmode
)
1361 result
= convert_memory_address (Pmode
, result
);
1364 apply_result_size ();
1365 result
= gen_rtx_MEM (BLKmode
, result
);
1367 #ifdef HAVE_untyped_return
1368 if (HAVE_untyped_return
)
1370 emit_jump_insn (gen_untyped_return (result
, result_vector (0, result
)));
1376 /* Restore the return value and note that each value is used. */
1378 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
1379 if ((mode
= apply_result_mode
[regno
]) != VOIDmode
)
1381 align
= GET_MODE_ALIGNMENT (mode
) / BITS_PER_UNIT
;
1382 if (size
% align
!= 0)
1383 size
= CEIL (size
, align
) * align
;
1384 reg
= gen_rtx_REG (mode
, INCOMING_REGNO (regno
));
1385 emit_move_insn (reg
, adjust_address (result
, mode
, size
));
1387 push_to_sequence (call_fusage
);
1388 emit_insn (gen_rtx_USE (VOIDmode
, reg
));
1389 call_fusage
= get_insns ();
1391 size
+= GET_MODE_SIZE (mode
);
1394 /* Put the USE insns before the return. */
1395 emit_insn (call_fusage
);
1397 /* Return whatever values was restored by jumping directly to the end
1399 expand_null_return ();
1402 /* Used by expand_builtin_classify_type and fold_builtin_classify_type. */
1404 static enum type_class
1405 type_to_class (type
)
1408 switch (TREE_CODE (type
))
1410 case VOID_TYPE
: return void_type_class
;
1411 case INTEGER_TYPE
: return integer_type_class
;
1412 case CHAR_TYPE
: return char_type_class
;
1413 case ENUMERAL_TYPE
: return enumeral_type_class
;
1414 case BOOLEAN_TYPE
: return boolean_type_class
;
1415 case POINTER_TYPE
: return pointer_type_class
;
1416 case REFERENCE_TYPE
: return reference_type_class
;
1417 case OFFSET_TYPE
: return offset_type_class
;
1418 case REAL_TYPE
: return real_type_class
;
1419 case COMPLEX_TYPE
: return complex_type_class
;
1420 case FUNCTION_TYPE
: return function_type_class
;
1421 case METHOD_TYPE
: return method_type_class
;
1422 case RECORD_TYPE
: return record_type_class
;
1424 case QUAL_UNION_TYPE
: return union_type_class
;
1425 case ARRAY_TYPE
: return (TYPE_STRING_FLAG (type
)
1426 ? string_type_class
: array_type_class
);
1427 case SET_TYPE
: return set_type_class
;
1428 case FILE_TYPE
: return file_type_class
;
1429 case LANG_TYPE
: return lang_type_class
;
1430 default: return no_type_class
;
1434 /* Expand a call to __builtin_classify_type with arguments found in
1438 expand_builtin_classify_type (arglist
)
1442 return GEN_INT (type_to_class (TREE_TYPE (TREE_VALUE (arglist
))));
1443 return GEN_INT (no_type_class
);
1446 /* Expand expression EXP, which is a call to __builtin_constant_p. */
1449 expand_builtin_constant_p (arglist
, target_mode
)
1451 enum machine_mode target_mode
;
1457 arglist
= TREE_VALUE (arglist
);
1459 /* We have taken care of the easy cases during constant folding. This
1460 case is not obvious, so emit (constant_p_rtx (ARGLIST)) and let CSE
1461 get a chance to see if it can deduce whether ARGLIST is constant. */
1463 current_function_calls_constant_p
= 1;
1465 tmp
= expand_expr (arglist
, NULL_RTX
, VOIDmode
, 0);
1466 tmp
= gen_rtx_CONSTANT_P_RTX (target_mode
, tmp
);
1470 /* Return mathematic function equivalent to FN but operating directly on TYPE,
1473 mathfn_built_in (type
, fn
)
1475 enum built_in_function fn
;
1477 enum built_in_function fcode
= NOT_BUILT_IN
;
1478 if (TYPE_MODE (type
) == TYPE_MODE (double_type_node
))
1482 case BUILT_IN_SQRTF
:
1483 case BUILT_IN_SQRTL
:
1484 fcode
= BUILT_IN_SQRT
;
1489 fcode
= BUILT_IN_SIN
;
1494 fcode
= BUILT_IN_COS
;
1499 fcode
= BUILT_IN_EXP
;
1504 fcode
= BUILT_IN_LOG
;
1509 fcode
= BUILT_IN_TAN
;
1512 case BUILT_IN_ATANF
:
1513 case BUILT_IN_ATANL
:
1514 fcode
= BUILT_IN_ATAN
;
1516 case BUILT_IN_FLOOR
:
1517 case BUILT_IN_FLOORF
:
1518 case BUILT_IN_FLOORL
:
1519 fcode
= BUILT_IN_FLOOR
;
1522 case BUILT_IN_CEILF
:
1523 case BUILT_IN_CEILL
:
1524 fcode
= BUILT_IN_CEIL
;
1526 case BUILT_IN_TRUNC
:
1527 case BUILT_IN_TRUNCF
:
1528 case BUILT_IN_TRUNCL
:
1529 fcode
= BUILT_IN_TRUNC
;
1531 case BUILT_IN_ROUND
:
1532 case BUILT_IN_ROUNDF
:
1533 case BUILT_IN_ROUNDL
:
1534 fcode
= BUILT_IN_ROUND
;
1536 case BUILT_IN_NEARBYINT
:
1537 case BUILT_IN_NEARBYINTF
:
1538 case BUILT_IN_NEARBYINTL
:
1539 fcode
= BUILT_IN_NEARBYINT
;
1544 else if (TYPE_MODE (type
) == TYPE_MODE (float_type_node
))
1548 case BUILT_IN_SQRTF
:
1549 case BUILT_IN_SQRTL
:
1550 fcode
= BUILT_IN_SQRTF
;
1555 fcode
= BUILT_IN_SINF
;
1560 fcode
= BUILT_IN_COSF
;
1565 fcode
= BUILT_IN_EXPF
;
1570 fcode
= BUILT_IN_LOGF
;
1575 fcode
= BUILT_IN_TANF
;
1578 case BUILT_IN_ATANF
:
1579 case BUILT_IN_ATANL
:
1580 fcode
= BUILT_IN_ATANF
;
1582 case BUILT_IN_FLOOR
:
1583 case BUILT_IN_FLOORF
:
1584 case BUILT_IN_FLOORL
:
1585 fcode
= BUILT_IN_FLOORF
;
1588 case BUILT_IN_CEILF
:
1589 case BUILT_IN_CEILL
:
1590 fcode
= BUILT_IN_CEILF
;
1592 case BUILT_IN_TRUNC
:
1593 case BUILT_IN_TRUNCF
:
1594 case BUILT_IN_TRUNCL
:
1595 fcode
= BUILT_IN_TRUNCF
;
1597 case BUILT_IN_ROUND
:
1598 case BUILT_IN_ROUNDF
:
1599 case BUILT_IN_ROUNDL
:
1600 fcode
= BUILT_IN_ROUNDF
;
1602 case BUILT_IN_NEARBYINT
:
1603 case BUILT_IN_NEARBYINTF
:
1604 case BUILT_IN_NEARBYINTL
:
1605 fcode
= BUILT_IN_NEARBYINTF
;
1610 else if (TYPE_MODE (type
) == TYPE_MODE (long_double_type_node
))
1614 case BUILT_IN_SQRTF
:
1615 case BUILT_IN_SQRTL
:
1616 fcode
= BUILT_IN_SQRTL
;
1621 fcode
= BUILT_IN_SINL
;
1626 fcode
= BUILT_IN_COSL
;
1631 fcode
= BUILT_IN_EXPL
;
1636 fcode
= BUILT_IN_LOGL
;
1641 fcode
= BUILT_IN_TANL
;
1644 case BUILT_IN_ATANF
:
1645 case BUILT_IN_ATANL
:
1646 fcode
= BUILT_IN_ATANL
;
1648 case BUILT_IN_FLOOR
:
1649 case BUILT_IN_FLOORF
:
1650 case BUILT_IN_FLOORL
:
1651 fcode
= BUILT_IN_FLOORL
;
1654 case BUILT_IN_CEILF
:
1655 case BUILT_IN_CEILL
:
1656 fcode
= BUILT_IN_CEILL
;
1658 case BUILT_IN_TRUNC
:
1659 case BUILT_IN_TRUNCF
:
1660 case BUILT_IN_TRUNCL
:
1661 fcode
= BUILT_IN_TRUNCL
;
1663 case BUILT_IN_ROUND
:
1664 case BUILT_IN_ROUNDF
:
1665 case BUILT_IN_ROUNDL
:
1666 fcode
= BUILT_IN_ROUNDL
;
1668 case BUILT_IN_NEARBYINT
:
1669 case BUILT_IN_NEARBYINTF
:
1670 case BUILT_IN_NEARBYINTL
:
1671 fcode
= BUILT_IN_NEARBYINTL
;
1676 return implicit_built_in_decls
[fcode
];
1679 /* If errno must be maintained, expand the RTL to check if the result,
1680 TARGET, of a built-in function call, EXP, is NaN, and if so set
1684 expand_errno_check (exp
, target
)
1690 if (flag_errno_math
&& HONOR_NANS (GET_MODE (target
)))
1692 lab
= gen_label_rtx ();
1694 /* Test the result; if it is NaN, set errno=EDOM because
1695 the argument was not in the domain. */
1696 emit_cmp_and_jump_insns (target
, target
, EQ
, 0, GET_MODE (target
),
1701 #ifdef GEN_ERRNO_RTX
1702 rtx errno_rtx
= GEN_ERRNO_RTX
;
1705 = gen_rtx_MEM (word_mode
, gen_rtx_SYMBOL_REF (Pmode
, "errno"));
1708 emit_move_insn (errno_rtx
, GEN_INT (TARGET_EDOM
));
1711 /* We can't set errno=EDOM directly; let the library call do it.
1712 Pop the arguments right away in case the call gets deleted. */
1714 expand_call (exp
, target
, 0);
1723 /* Expand a call to one of the builtin math functions (sin, cos, or sqrt).
1724 Return 0 if a normal call should be emitted rather than expanding the
1725 function in-line. EXP is the expression that is a call to the builtin
1726 function; if convenient, the result should be placed in TARGET.
1727 SUBTARGET may be used as the target for computing one of EXP's operands. */
1730 expand_builtin_mathfn (exp
, target
, subtarget
)
1732 rtx target
, subtarget
;
1734 optab builtin_optab
;
1736 tree fndecl
= TREE_OPERAND (TREE_OPERAND (exp
, 0), 0);
1737 tree arglist
= TREE_OPERAND (exp
, 1);
1738 enum machine_mode argmode
;
1739 bool errno_set
= true;
1741 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
1744 /* Stabilize and compute the argument. */
1745 if (TREE_CODE (TREE_VALUE (arglist
)) != VAR_DECL
1746 && TREE_CODE (TREE_VALUE (arglist
)) != PARM_DECL
)
1748 exp
= copy_node (exp
);
1749 TREE_OPERAND (exp
, 1) = arglist
;
1750 /* Wrap the computation of the argument in a SAVE_EXPR. That
1751 way, if we need to expand the argument again (as in the
1752 flag_errno_math case below where we cannot directly set
1753 errno), we will not perform side-effects more than once.
1754 Note that here we're mutating the original EXP as well as the
1755 copy; that's the right thing to do in case the original EXP
1756 is expanded later. */
1757 TREE_VALUE (arglist
) = save_expr (TREE_VALUE (arglist
));
1758 arglist
= copy_node (arglist
);
1760 op0
= expand_expr (TREE_VALUE (arglist
), subtarget
, VOIDmode
, 0);
1762 /* Make a suitable register to place result in. */
1763 target
= gen_reg_rtx (TYPE_MODE (TREE_TYPE (exp
)));
1768 switch (DECL_FUNCTION_CODE (fndecl
))
1773 builtin_optab
= sin_optab
; break;
1777 builtin_optab
= cos_optab
; break;
1779 case BUILT_IN_SQRTF
:
1780 case BUILT_IN_SQRTL
:
1781 builtin_optab
= sqrt_optab
; break;
1785 builtin_optab
= exp_optab
; break;
1789 builtin_optab
= log_optab
; break;
1790 case BUILT_IN_FLOOR
:
1791 case BUILT_IN_FLOORF
:
1792 case BUILT_IN_FLOORL
:
1793 errno_set
= false ; builtin_optab
= floor_optab
; break;
1795 case BUILT_IN_CEILF
:
1796 case BUILT_IN_CEILL
:
1797 errno_set
= false ; builtin_optab
= ceil_optab
; break;
1798 case BUILT_IN_TRUNC
:
1799 case BUILT_IN_TRUNCF
:
1800 case BUILT_IN_TRUNCL
:
1801 errno_set
= false ; builtin_optab
= trunc_optab
; break;
1802 case BUILT_IN_ROUND
:
1803 case BUILT_IN_ROUNDF
:
1804 case BUILT_IN_ROUNDL
:
1805 errno_set
= false ; builtin_optab
= round_optab
; break;
1806 case BUILT_IN_NEARBYINT
:
1807 case BUILT_IN_NEARBYINTF
:
1808 case BUILT_IN_NEARBYINTL
:
1809 errno_set
= false ; builtin_optab
= nearbyint_optab
; break;
1814 /* Compute into TARGET.
1815 Set TARGET to wherever the result comes back. */
1816 argmode
= TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist
)));
1817 target
= expand_unop (argmode
, builtin_optab
, op0
, target
, 0);
1819 /* If we were unable to expand via the builtin, stop the
1820 sequence (without outputting the insns) and return 0, causing
1821 a call to the library function. */
1829 expand_errno_check (exp
, target
);
1831 /* Output the entire sequence. */
1832 insns
= get_insns ();
1839 /* Expand a call to the builtin binary math functions (pow and atan2).
1840 Return 0 if a normal call should be emitted rather than expanding the
1841 function in-line. EXP is the expression that is a call to the builtin
1842 function; if convenient, the result should be placed in TARGET.
1843 SUBTARGET may be used as the target for computing one of EXP's
1847 expand_builtin_mathfn_2 (exp
, target
, subtarget
)
1849 rtx target
, subtarget
;
1851 optab builtin_optab
;
1852 rtx op0
, op1
, insns
;
1853 tree fndecl
= TREE_OPERAND (TREE_OPERAND (exp
, 0), 0);
1854 tree arglist
= TREE_OPERAND (exp
, 1);
1856 enum machine_mode argmode
;
1857 bool errno_set
= true;
1860 if (!validate_arglist (arglist
, REAL_TYPE
, REAL_TYPE
, VOID_TYPE
))
1863 arg0
= TREE_VALUE (arglist
);
1864 arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
1866 /* Stabilize the arguments. */
1867 if (TREE_CODE (arg0
) != VAR_DECL
&& TREE_CODE (arg0
) != PARM_DECL
)
1869 arg0
= save_expr (arg0
);
1870 TREE_VALUE (arglist
) = arg0
;
1873 if (TREE_CODE (arg1
) != VAR_DECL
&& TREE_CODE (arg1
) != PARM_DECL
)
1875 arg1
= save_expr (arg1
);
1876 TREE_VALUE (TREE_CHAIN (arglist
)) = arg1
;
1882 exp
= copy_node (exp
);
1883 arglist
= tree_cons (NULL_TREE
, arg0
,
1884 build_tree_list (NULL_TREE
, arg1
));
1885 TREE_OPERAND (exp
, 1) = arglist
;
1888 op0
= expand_expr (arg0
, subtarget
, VOIDmode
, 0);
1889 op1
= expand_expr (arg1
, 0, VOIDmode
, 0);
1891 /* Make a suitable register to place result in. */
1892 target
= gen_reg_rtx (TYPE_MODE (TREE_TYPE (exp
)));
1897 switch (DECL_FUNCTION_CODE (fndecl
))
1902 builtin_optab
= pow_optab
; break;
1903 case BUILT_IN_ATAN2
:
1904 case BUILT_IN_ATAN2F
:
1905 case BUILT_IN_ATAN2L
:
1906 builtin_optab
= atan2_optab
; break;
1911 /* Compute into TARGET.
1912 Set TARGET to wherever the result comes back. */
1913 argmode
= TYPE_MODE (TREE_TYPE (arg0
));
1914 target
= expand_binop (argmode
, builtin_optab
, op0
, op1
,
1915 target
, 0, OPTAB_DIRECT
);
1917 /* If we were unable to expand via the builtin, stop the
1918 sequence (without outputting the insns) and return 0, causing
1919 a call to the library function. */
1927 expand_errno_check (exp
, target
);
1929 /* Output the entire sequence. */
1930 insns
= get_insns ();
1937 /* Expand expression EXP which is a call to the strlen builtin. Return 0
1938 if we failed the caller should emit a normal call, otherwise
1939 try to get the result in TARGET, if convenient. */
1942 expand_builtin_strlen (arglist
, target
, target_mode
)
1945 enum machine_mode target_mode
;
1947 if (!validate_arglist (arglist
, POINTER_TYPE
, VOID_TYPE
))
1952 tree len
, src
= TREE_VALUE (arglist
);
1953 rtx result
, src_reg
, char_rtx
, before_strlen
;
1954 enum machine_mode insn_mode
= target_mode
, char_mode
;
1955 enum insn_code icode
= CODE_FOR_nothing
;
1958 /* If the length can be computed at compile-time, return it. */
1959 len
= c_strlen (src
);
1961 return expand_expr (len
, target
, target_mode
, EXPAND_NORMAL
);
1963 align
= get_pointer_alignment (src
, BIGGEST_ALIGNMENT
) / BITS_PER_UNIT
;
1965 /* If SRC is not a pointer type, don't do this operation inline. */
1969 /* Bail out if we can't compute strlen in the right mode. */
1970 while (insn_mode
!= VOIDmode
)
1972 icode
= strlen_optab
->handlers
[(int) insn_mode
].insn_code
;
1973 if (icode
!= CODE_FOR_nothing
)
1976 insn_mode
= GET_MODE_WIDER_MODE (insn_mode
);
1978 if (insn_mode
== VOIDmode
)
1981 /* Make a place to write the result of the instruction. */
1984 && GET_CODE (result
) == REG
1985 && GET_MODE (result
) == insn_mode
1986 && REGNO (result
) >= FIRST_PSEUDO_REGISTER
))
1987 result
= gen_reg_rtx (insn_mode
);
1989 /* Make a place to hold the source address. We will not expand
1990 the actual source until we are sure that the expansion will
1991 not fail -- there are trees that cannot be expanded twice. */
1992 src_reg
= gen_reg_rtx (Pmode
);
1994 /* Mark the beginning of the strlen sequence so we can emit the
1995 source operand later. */
1996 before_strlen
= get_last_insn ();
1998 char_rtx
= const0_rtx
;
1999 char_mode
= insn_data
[(int) icode
].operand
[2].mode
;
2000 if (! (*insn_data
[(int) icode
].operand
[2].predicate
) (char_rtx
,
2002 char_rtx
= copy_to_mode_reg (char_mode
, char_rtx
);
2004 pat
= GEN_FCN (icode
) (result
, gen_rtx_MEM (BLKmode
, src_reg
),
2005 char_rtx
, GEN_INT (align
));
2010 /* Now that we are assured of success, expand the source. */
2012 pat
= memory_address (BLKmode
,
2013 expand_expr (src
, src_reg
, ptr_mode
, EXPAND_SUM
));
2015 emit_move_insn (src_reg
, pat
);
2020 emit_insn_after (pat
, before_strlen
);
2022 emit_insn_before (pat
, get_insns ());
2024 /* Return the value in the proper mode for this function. */
2025 if (GET_MODE (result
) == target_mode
)
2027 else if (target
!= 0)
2028 convert_move (target
, result
, 0);
2030 target
= convert_to_mode (target_mode
, result
, 0);
2036 /* Expand a call to the strstr builtin. Return 0 if we failed the
2037 caller should emit a normal call, otherwise try to get the result
2038 in TARGET, if convenient (and in mode MODE if that's convenient). */
2041 expand_builtin_strstr (arglist
, target
, mode
)
2044 enum machine_mode mode
;
2046 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
2050 tree s1
= TREE_VALUE (arglist
), s2
= TREE_VALUE (TREE_CHAIN (arglist
));
2052 const char *p1
, *p2
;
2061 const char *r
= strstr (p1
, p2
);
2066 /* Return an offset into the constant string argument. */
2067 return expand_expr (fold (build (PLUS_EXPR
, TREE_TYPE (s1
),
2068 s1
, ssize_int (r
- p1
))),
2069 target
, mode
, EXPAND_NORMAL
);
2073 return expand_expr (s1
, target
, mode
, EXPAND_NORMAL
);
2078 fn
= implicit_built_in_decls
[BUILT_IN_STRCHR
];
2082 /* New argument list transforming strstr(s1, s2) to
2083 strchr(s1, s2[0]). */
2085 build_tree_list (NULL_TREE
, build_int_2 (p2
[0], 0));
2086 arglist
= tree_cons (NULL_TREE
, s1
, arglist
);
2087 return expand_expr (build_function_call_expr (fn
, arglist
),
2088 target
, mode
, EXPAND_NORMAL
);
2092 /* Expand a call to the strchr builtin. Return 0 if we failed the
2093 caller should emit a normal call, otherwise try to get the result
2094 in TARGET, if convenient (and in mode MODE if that's convenient). */
2097 expand_builtin_strchr (arglist
, target
, mode
)
2100 enum machine_mode mode
;
2102 if (!validate_arglist (arglist
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
2106 tree s1
= TREE_VALUE (arglist
), s2
= TREE_VALUE (TREE_CHAIN (arglist
));
2109 if (TREE_CODE (s2
) != INTEGER_CST
)
2118 if (target_char_cast (s2
, &c
))
2126 /* Return an offset into the constant string argument. */
2127 return expand_expr (fold (build (PLUS_EXPR
, TREE_TYPE (s1
),
2128 s1
, ssize_int (r
- p1
))),
2129 target
, mode
, EXPAND_NORMAL
);
2132 /* FIXME: Should use here strchrM optab so that ports can optimize
2138 /* Expand a call to the strrchr builtin. Return 0 if we failed the
2139 caller should emit a normal call, otherwise try to get the result
2140 in TARGET, if convenient (and in mode MODE if that's convenient). */
2143 expand_builtin_strrchr (arglist
, target
, mode
)
2146 enum machine_mode mode
;
2148 if (!validate_arglist (arglist
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
2152 tree s1
= TREE_VALUE (arglist
), s2
= TREE_VALUE (TREE_CHAIN (arglist
));
2156 if (TREE_CODE (s2
) != INTEGER_CST
)
2165 if (target_char_cast (s2
, &c
))
2168 r
= strrchr (p1
, c
);
2173 /* Return an offset into the constant string argument. */
2174 return expand_expr (fold (build (PLUS_EXPR
, TREE_TYPE (s1
),
2175 s1
, ssize_int (r
- p1
))),
2176 target
, mode
, EXPAND_NORMAL
);
2179 if (! integer_zerop (s2
))
2182 fn
= implicit_built_in_decls
[BUILT_IN_STRCHR
];
2186 /* Transform strrchr(s1, '\0') to strchr(s1, '\0'). */
2187 return expand_expr (build_function_call_expr (fn
, arglist
),
2188 target
, mode
, EXPAND_NORMAL
);
2192 /* Expand a call to the strpbrk builtin. Return 0 if we failed the
2193 caller should emit a normal call, otherwise try to get the result
2194 in TARGET, if convenient (and in mode MODE if that's convenient). */
2197 expand_builtin_strpbrk (arglist
, target
, mode
)
2200 enum machine_mode mode
;
2202 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
2206 tree s1
= TREE_VALUE (arglist
), s2
= TREE_VALUE (TREE_CHAIN (arglist
));
2208 const char *p1
, *p2
;
2217 const char *r
= strpbrk (p1
, p2
);
2222 /* Return an offset into the constant string argument. */
2223 return expand_expr (fold (build (PLUS_EXPR
, TREE_TYPE (s1
),
2224 s1
, ssize_int (r
- p1
))),
2225 target
, mode
, EXPAND_NORMAL
);
2230 /* strpbrk(x, "") == NULL.
2231 Evaluate and ignore the arguments in case they had
2233 expand_expr (s1
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
2238 return 0; /* Really call strpbrk. */
2240 fn
= implicit_built_in_decls
[BUILT_IN_STRCHR
];
2244 /* New argument list transforming strpbrk(s1, s2) to
2245 strchr(s1, s2[0]). */
2247 build_tree_list (NULL_TREE
, build_int_2 (p2
[0], 0));
2248 arglist
= tree_cons (NULL_TREE
, s1
, arglist
);
2249 return expand_expr (build_function_call_expr (fn
, arglist
),
2250 target
, mode
, EXPAND_NORMAL
);
2254 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
2255 bytes from constant string DATA + OFFSET and return it as target
2259 builtin_memcpy_read_str (data
, offset
, mode
)
2261 HOST_WIDE_INT offset
;
2262 enum machine_mode mode
;
2264 const char *str
= (const char *) data
;
2267 || ((unsigned HOST_WIDE_INT
) offset
+ GET_MODE_SIZE (mode
)
2268 > strlen (str
) + 1))
2269 abort (); /* Attempt to read past the end of constant string. */
2271 return c_readstr (str
+ offset
, mode
);
2274 /* Expand a call to the memcpy builtin, with arguments in ARGLIST.
2275 Return 0 if we failed, the caller should emit a normal call,
2276 otherwise try to get the result in TARGET, if convenient (and in
2277 mode MODE if that's convenient). If ENDP is 0 return the
2278 destination pointer, if ENDP is 1 return the end pointer ala
2279 mempcpy, and if ENDP is 2 return the end pointer minus one ala
2282 expand_builtin_memcpy (arglist
, target
, mode
, endp
)
2285 enum machine_mode mode
;
2288 if (!validate_arglist (arglist
,
2289 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
2293 tree dest
= TREE_VALUE (arglist
);
2294 tree src
= TREE_VALUE (TREE_CHAIN (arglist
));
2295 tree len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
2296 const char *src_str
;
2298 unsigned int src_align
= get_pointer_alignment (src
, BIGGEST_ALIGNMENT
);
2299 unsigned int dest_align
2300 = get_pointer_alignment (dest
, BIGGEST_ALIGNMENT
);
2301 rtx dest_mem
, src_mem
, dest_addr
, len_rtx
;
2303 /* If DEST is not a pointer type, call the normal function. */
2304 if (dest_align
== 0)
2307 /* If the LEN parameter is zero, return DEST. */
2308 if (host_integerp (len
, 1) && tree_low_cst (len
, 1) == 0)
2310 /* Evaluate and ignore SRC in case it has side-effects. */
2311 expand_expr (src
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
2312 return expand_expr (dest
, target
, mode
, EXPAND_NORMAL
);
2315 /* If either SRC is not a pointer type, don't do this
2316 operation in-line. */
2320 dest_mem
= get_memory_rtx (dest
);
2321 set_mem_align (dest_mem
, dest_align
);
2322 len_rtx
= expand_expr (len
, NULL_RTX
, VOIDmode
, 0);
2323 src_str
= c_getstr (src
);
2325 /* If SRC is a string constant and block move would be done
2326 by pieces, we can avoid loading the string from memory
2327 and only stored the computed constants. */
2329 && GET_CODE (len_rtx
) == CONST_INT
2330 && (unsigned HOST_WIDE_INT
) INTVAL (len_rtx
) <= strlen (src_str
) + 1
2331 && can_store_by_pieces (INTVAL (len_rtx
), builtin_memcpy_read_str
,
2332 (PTR
) src_str
, dest_align
))
2334 store_by_pieces (dest_mem
, INTVAL (len_rtx
),
2335 builtin_memcpy_read_str
,
2336 (PTR
) src_str
, dest_align
);
2337 dest_mem
= force_operand (XEXP (dest_mem
, 0), NULL_RTX
);
2338 #ifdef POINTERS_EXTEND_UNSIGNED
2339 if (GET_MODE (dest_mem
) != ptr_mode
)
2340 dest_mem
= convert_memory_address (ptr_mode
, dest_mem
);
2345 rtx delta
= len_rtx
;
2348 delta
= GEN_INT (INTVAL (delta
) - 1);
2350 result
= simplify_gen_binary (PLUS
, GET_MODE (dest_mem
),
2352 return force_operand (result
, NULL_RTX
);
2358 src_mem
= get_memory_rtx (src
);
2359 set_mem_align (src_mem
, src_align
);
2361 /* Copy word part most expediently. */
2362 dest_addr
= emit_block_move (dest_mem
, src_mem
, len_rtx
,
2367 dest_addr
= force_operand (XEXP (dest_mem
, 0), NULL_RTX
);
2368 #ifdef POINTERS_EXTEND_UNSIGNED
2369 if (GET_MODE (dest_addr
) != ptr_mode
)
2370 dest_addr
= convert_memory_address (ptr_mode
, dest_addr
);
2376 rtx result
= force_operand (len_rtx
, NULL_RTX
);
2380 result
= simplify_gen_binary (MINUS
, GET_MODE (dest_addr
),
2381 result
, const1_rtx
);
2382 result
= force_operand (result
, NULL_RTX
);
2385 result
= simplify_gen_binary (PLUS
, GET_MODE (dest_addr
),
2387 return force_operand (result
, NULL_RTX
);
2394 /* Expand a call to the mempcpy builtin, with arguments in ARGLIST.
2395 Return 0 if we failed the caller should emit a normal call,
2396 otherwise try to get the result in TARGET, if convenient (and in
2397 mode MODE if that's convenient). */
2400 expand_builtin_mempcpy (arglist
, target
, mode
)
2403 enum machine_mode mode
;
2405 if (!validate_arglist (arglist
,
2406 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
2410 /* If return value is ignored, transform mempcpy into memcpy. */
2411 if (target
== const0_rtx
)
2414 rtx ret
= expand_builtin_memcpy (arglist
, target
, mode
, /*endp=*/0);
2419 fn
= implicit_built_in_decls
[BUILT_IN_MEMCPY
];
2423 return expand_expr (build_function_call_expr (fn
, arglist
),
2424 target
, mode
, EXPAND_NORMAL
);
2427 return expand_builtin_memcpy (arglist
, target
, mode
, /*endp=*/1);
2431 /* Expand expression EXP, which is a call to the memmove builtin. Return 0
2432 if we failed the caller should emit a normal call. */
2435 expand_builtin_memmove (arglist
, target
, mode
)
2438 enum machine_mode mode
;
2440 if (!validate_arglist (arglist
,
2441 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
2445 tree dest
= TREE_VALUE (arglist
);
2446 tree src
= TREE_VALUE (TREE_CHAIN (arglist
));
2447 tree len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
2449 unsigned int src_align
= get_pointer_alignment (src
, BIGGEST_ALIGNMENT
);
2450 unsigned int dest_align
2451 = get_pointer_alignment (dest
, BIGGEST_ALIGNMENT
);
2453 /* If DEST is not a pointer type, call the normal function. */
2454 if (dest_align
== 0)
2457 /* If the LEN parameter is zero, return DEST. */
2458 if (host_integerp (len
, 1) && tree_low_cst (len
, 1) == 0)
2460 /* Evaluate and ignore SRC in case it has side-effects. */
2461 expand_expr (src
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
2462 return expand_expr (dest
, target
, mode
, EXPAND_NORMAL
);
2465 /* If either SRC is not a pointer type, don't do this
2466 operation in-line. */
2470 /* If src is categorized for a readonly section we can use
2472 if (readonly_data_expr (src
))
2474 tree
const fn
= implicit_built_in_decls
[BUILT_IN_MEMCPY
];
2477 return expand_expr (build_function_call_expr (fn
, arglist
),
2478 target
, mode
, EXPAND_NORMAL
);
2481 /* Otherwise, call the normal function. */
2486 /* Expand expression EXP, which is a call to the bcopy builtin. Return 0
2487 if we failed the caller should emit a normal call. */
2490 expand_builtin_bcopy (arglist
)
2493 tree src
, dest
, size
, newarglist
;
2495 if (!validate_arglist (arglist
,
2496 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
2499 src
= TREE_VALUE (arglist
);
2500 dest
= TREE_VALUE (TREE_CHAIN (arglist
));
2501 size
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
2503 /* New argument list transforming bcopy(ptr x, ptr y, int z) to
2504 memmove(ptr y, ptr x, size_t z). This is done this way
2505 so that if it isn't expanded inline, we fallback to
2506 calling bcopy instead of memmove. */
2508 newarglist
= build_tree_list (NULL_TREE
, convert (sizetype
, size
));
2509 newarglist
= tree_cons (NULL_TREE
, src
, newarglist
);
2510 newarglist
= tree_cons (NULL_TREE
, dest
, newarglist
);
2512 return expand_builtin_memmove (newarglist
, const0_rtx
, VOIDmode
);
2515 /* Expand expression EXP, which is a call to the strcpy builtin. Return 0
2516 if we failed the caller should emit a normal call, otherwise try to get
2517 the result in TARGET, if convenient (and in mode MODE if that's
2521 expand_builtin_strcpy (arglist
, target
, mode
)
2524 enum machine_mode mode
;
2528 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
2531 fn
= implicit_built_in_decls
[BUILT_IN_MEMCPY
];
2535 len
= c_strlen (TREE_VALUE (TREE_CHAIN (arglist
)));
2539 len
= size_binop (PLUS_EXPR
, len
, ssize_int (1));
2540 chainon (arglist
, build_tree_list (NULL_TREE
, len
));
2541 return expand_expr (build_function_call_expr (fn
, arglist
),
2542 target
, mode
, EXPAND_NORMAL
);
2545 /* Expand a call to the stpcpy builtin, with arguments in ARGLIST.
2546 Return 0 if we failed the caller should emit a normal call,
2547 otherwise try to get the result in TARGET, if convenient (and in
2548 mode MODE if that's convenient). */
2551 expand_builtin_stpcpy (arglist
, target
, mode
)
2554 enum machine_mode mode
;
2556 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
2563 /* If return value is ignored, transform stpcpy into strcpy. */
2564 if (target
== const0_rtx
)
2567 rtx ret
= expand_builtin_strcpy (arglist
, target
, mode
);
2572 fn
= implicit_built_in_decls
[BUILT_IN_STRCPY
];
2576 return expand_expr (build_function_call_expr (fn
, arglist
),
2577 target
, mode
, EXPAND_NORMAL
);
2580 /* Ensure we get an actual string who length can be evaluated at
2581 compile-time, not an expression containing a string. This is
2582 because the latter will potentially produce pessimized code
2583 when used to produce the return value. */
2584 src
= TREE_VALUE (TREE_CHAIN (arglist
));
2585 if (! c_getstr (src
) || ! (len
= c_strlen (src
)))
2588 len
= fold (size_binop (PLUS_EXPR
, len
, ssize_int (1)));
2589 newarglist
= copy_list (arglist
);
2590 chainon (newarglist
, build_tree_list (NULL_TREE
, len
));
2591 return expand_builtin_memcpy (newarglist
, target
, mode
, /*endp=*/2);
2595 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
2596 bytes from constant string DATA + OFFSET and return it as target
2600 builtin_strncpy_read_str (data
, offset
, mode
)
2602 HOST_WIDE_INT offset
;
2603 enum machine_mode mode
;
2605 const char *str
= (const char *) data
;
2607 if ((unsigned HOST_WIDE_INT
) offset
> strlen (str
))
2610 return c_readstr (str
+ offset
, mode
);
2613 /* Expand expression EXP, which is a call to the strncpy builtin. Return 0
2614 if we failed the caller should emit a normal call. */
2617 expand_builtin_strncpy (arglist
, target
, mode
)
2620 enum machine_mode mode
;
2622 if (!validate_arglist (arglist
,
2623 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
2627 tree slen
= c_strlen (TREE_VALUE (TREE_CHAIN (arglist
)));
2628 tree len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
2631 /* We must be passed a constant len parameter. */
2632 if (TREE_CODE (len
) != INTEGER_CST
)
2635 /* If the len parameter is zero, return the dst parameter. */
2636 if (integer_zerop (len
))
2638 /* Evaluate and ignore the src argument in case it has
2640 expand_expr (TREE_VALUE (TREE_CHAIN (arglist
)), const0_rtx
,
2641 VOIDmode
, EXPAND_NORMAL
);
2642 /* Return the dst parameter. */
2643 return expand_expr (TREE_VALUE (arglist
), target
, mode
,
2647 /* Now, we must be passed a constant src ptr parameter. */
2648 if (slen
== 0 || TREE_CODE (slen
) != INTEGER_CST
)
2651 slen
= size_binop (PLUS_EXPR
, slen
, ssize_int (1));
2653 /* We're required to pad with trailing zeros if the requested
2654 len is greater than strlen(s2)+1. In that case try to
2655 use store_by_pieces, if it fails, punt. */
2656 if (tree_int_cst_lt (slen
, len
))
2658 tree dest
= TREE_VALUE (arglist
);
2659 unsigned int dest_align
2660 = get_pointer_alignment (dest
, BIGGEST_ALIGNMENT
);
2661 const char *p
= c_getstr (TREE_VALUE (TREE_CHAIN (arglist
)));
2664 if (!p
|| dest_align
== 0 || !host_integerp (len
, 1)
2665 || !can_store_by_pieces (tree_low_cst (len
, 1),
2666 builtin_strncpy_read_str
,
2667 (PTR
) p
, dest_align
))
2670 dest_mem
= get_memory_rtx (dest
);
2671 store_by_pieces (dest_mem
, tree_low_cst (len
, 1),
2672 builtin_strncpy_read_str
,
2673 (PTR
) p
, dest_align
);
2674 dest_mem
= force_operand (XEXP (dest_mem
, 0), NULL_RTX
);
2675 #ifdef POINTERS_EXTEND_UNSIGNED
2676 if (GET_MODE (dest_mem
) != ptr_mode
)
2677 dest_mem
= convert_memory_address (ptr_mode
, dest_mem
);
2682 /* OK transform into builtin memcpy. */
2683 fn
= implicit_built_in_decls
[BUILT_IN_MEMCPY
];
2686 return expand_expr (build_function_call_expr (fn
, arglist
),
2687 target
, mode
, EXPAND_NORMAL
);
2691 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
2692 bytes from constant string DATA + OFFSET and return it as target
2696 builtin_memset_read_str (data
, offset
, mode
)
2698 HOST_WIDE_INT offset ATTRIBUTE_UNUSED
;
2699 enum machine_mode mode
;
2701 const char *c
= (const char *) data
;
2702 char *p
= alloca (GET_MODE_SIZE (mode
));
2704 memset (p
, *c
, GET_MODE_SIZE (mode
));
2706 return c_readstr (p
, mode
);
2709 /* Callback routine for store_by_pieces. Return the RTL of a register
2710 containing GET_MODE_SIZE (MODE) consecutive copies of the unsigned
2711 char value given in the RTL register data. For example, if mode is
2712 4 bytes wide, return the RTL for 0x01010101*data. */
2715 builtin_memset_gen_str (data
, offset
, mode
)
2717 HOST_WIDE_INT offset ATTRIBUTE_UNUSED
;
2718 enum machine_mode mode
;
2724 size
= GET_MODE_SIZE (mode
);
2729 memset (p
, 1, size
);
2730 coeff
= c_readstr (p
, mode
);
2732 target
= convert_to_mode (mode
, (rtx
) data
, 1);
2733 target
= expand_mult (mode
, target
, coeff
, NULL_RTX
, 1);
2734 return force_reg (mode
, target
);
2737 /* Expand expression EXP, which is a call to the memset builtin. Return 0
2738 if we failed the caller should emit a normal call, otherwise try to get
2739 the result in TARGET, if convenient (and in mode MODE if that's
2743 expand_builtin_memset (arglist
, target
, mode
)
2746 enum machine_mode mode
;
2748 if (!validate_arglist (arglist
,
2749 POINTER_TYPE
, INTEGER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
2753 tree dest
= TREE_VALUE (arglist
);
2754 tree val
= TREE_VALUE (TREE_CHAIN (arglist
));
2755 tree len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
2758 unsigned int dest_align
2759 = get_pointer_alignment (dest
, BIGGEST_ALIGNMENT
);
2760 rtx dest_mem
, dest_addr
, len_rtx
;
2762 /* If DEST is not a pointer type, don't do this
2763 operation in-line. */
2764 if (dest_align
== 0)
2767 /* If the LEN parameter is zero, return DEST. */
2768 if (host_integerp (len
, 1) && tree_low_cst (len
, 1) == 0)
2770 /* Evaluate and ignore VAL in case it has side-effects. */
2771 expand_expr (val
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
2772 return expand_expr (dest
, target
, mode
, EXPAND_NORMAL
);
2775 if (TREE_CODE (val
) != INTEGER_CST
)
2779 if (!host_integerp (len
, 1))
2782 if (optimize_size
&& tree_low_cst (len
, 1) > 1)
2785 /* Assume that we can memset by pieces if we can store the
2786 * the coefficients by pieces (in the required modes).
2787 * We can't pass builtin_memset_gen_str as that emits RTL. */
2789 if (!can_store_by_pieces (tree_low_cst (len
, 1),
2790 builtin_memset_read_str
,
2791 (PTR
) &c
, dest_align
))
2794 val
= fold (build1 (CONVERT_EXPR
, unsigned_char_type_node
, val
));
2795 val_rtx
= expand_expr (val
, NULL_RTX
, VOIDmode
, 0);
2796 val_rtx
= force_reg (TYPE_MODE (unsigned_char_type_node
),
2798 dest_mem
= get_memory_rtx (dest
);
2799 store_by_pieces (dest_mem
, tree_low_cst (len
, 1),
2800 builtin_memset_gen_str
,
2801 (PTR
) val_rtx
, dest_align
);
2802 dest_mem
= force_operand (XEXP (dest_mem
, 0), NULL_RTX
);
2803 #ifdef POINTERS_EXTEND_UNSIGNED
2804 if (GET_MODE (dest_mem
) != ptr_mode
)
2805 dest_mem
= convert_memory_address (ptr_mode
, dest_mem
);
2810 if (target_char_cast (val
, &c
))
2815 if (!host_integerp (len
, 1))
2817 if (!can_store_by_pieces (tree_low_cst (len
, 1),
2818 builtin_memset_read_str
, (PTR
) &c
,
2822 dest_mem
= get_memory_rtx (dest
);
2823 store_by_pieces (dest_mem
, tree_low_cst (len
, 1),
2824 builtin_memset_read_str
,
2825 (PTR
) &c
, dest_align
);
2826 dest_mem
= force_operand (XEXP (dest_mem
, 0), NULL_RTX
);
2827 #ifdef POINTERS_EXTEND_UNSIGNED
2828 if (GET_MODE (dest_mem
) != ptr_mode
)
2829 dest_mem
= convert_memory_address (ptr_mode
, dest_mem
);
2834 len_rtx
= expand_expr (len
, NULL_RTX
, VOIDmode
, 0);
2836 dest_mem
= get_memory_rtx (dest
);
2837 set_mem_align (dest_mem
, dest_align
);
2838 dest_addr
= clear_storage (dest_mem
, len_rtx
);
2842 dest_addr
= force_operand (XEXP (dest_mem
, 0), NULL_RTX
);
2843 #ifdef POINTERS_EXTEND_UNSIGNED
2844 if (GET_MODE (dest_addr
) != ptr_mode
)
2845 dest_addr
= convert_memory_address (ptr_mode
, dest_addr
);
2853 /* Expand expression EXP, which is a call to the bzero builtin. Return 0
2854 if we failed the caller should emit a normal call. */
2857 expand_builtin_bzero (arglist
)
2860 tree dest
, size
, newarglist
;
2862 if (!validate_arglist (arglist
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
2865 dest
= TREE_VALUE (arglist
);
2866 size
= TREE_VALUE (TREE_CHAIN (arglist
));
2868 /* New argument list transforming bzero(ptr x, int y) to
2869 memset(ptr x, int 0, size_t y). This is done this way
2870 so that if it isn't expanded inline, we fallback to
2871 calling bzero instead of memset. */
2873 newarglist
= build_tree_list (NULL_TREE
, convert (sizetype
, size
));
2874 newarglist
= tree_cons (NULL_TREE
, integer_zero_node
, newarglist
);
2875 newarglist
= tree_cons (NULL_TREE
, dest
, newarglist
);
2877 return expand_builtin_memset (newarglist
, const0_rtx
, VOIDmode
);
2880 /* Expand expression EXP, which is a call to the memcmp built-in function.
2881 ARGLIST is the argument list for this call. Return 0 if we failed and the
2882 caller should emit a normal call, otherwise try to get the result in
2883 TARGET, if convenient (and in mode MODE, if that's convenient). */
2886 expand_builtin_memcmp (exp
, arglist
, target
, mode
)
2887 tree exp ATTRIBUTE_UNUSED
;
2890 enum machine_mode mode
;
2892 tree arg1
, arg2
, len
;
2893 const char *p1
, *p2
;
2895 if (!validate_arglist (arglist
,
2896 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
2899 arg1
= TREE_VALUE (arglist
);
2900 arg2
= TREE_VALUE (TREE_CHAIN (arglist
));
2901 len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
2903 /* If the len parameter is zero, return zero. */
2904 if (host_integerp (len
, 1) && tree_low_cst (len
, 1) == 0)
2906 /* Evaluate and ignore arg1 and arg2 in case they have
2908 expand_expr (arg1
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
2909 expand_expr (arg2
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
2913 p1
= c_getstr (arg1
);
2914 p2
= c_getstr (arg2
);
2916 /* If all arguments are constant, and the value of len is not greater
2917 than the lengths of arg1 and arg2, evaluate at compile-time. */
2918 if (host_integerp (len
, 1) && p1
&& p2
2919 && compare_tree_int (len
, strlen (p1
) + 1) <= 0
2920 && compare_tree_int (len
, strlen (p2
) + 1) <= 0)
2922 const int r
= memcmp (p1
, p2
, tree_low_cst (len
, 1));
2924 return (r
< 0 ? constm1_rtx
: (r
> 0 ? const1_rtx
: const0_rtx
));
2927 /* If len parameter is one, return an expression corresponding to
2928 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
2929 if (host_integerp (len
, 1) && tree_low_cst (len
, 1) == 1)
2931 tree cst_uchar_node
= build_type_variant (unsigned_char_type_node
, 1, 0);
2932 tree cst_uchar_ptr_node
= build_pointer_type (cst_uchar_node
);
2934 fold (build1 (CONVERT_EXPR
, integer_type_node
,
2935 build1 (INDIRECT_REF
, cst_uchar_node
,
2936 build1 (NOP_EXPR
, cst_uchar_ptr_node
, arg1
))));
2938 fold (build1 (CONVERT_EXPR
, integer_type_node
,
2939 build1 (INDIRECT_REF
, cst_uchar_node
,
2940 build1 (NOP_EXPR
, cst_uchar_ptr_node
, arg2
))));
2941 tree result
= fold (build (MINUS_EXPR
, integer_type_node
, ind1
, ind2
));
2942 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
2945 #ifdef HAVE_cmpstrsi
2947 rtx arg1_rtx
, arg2_rtx
, arg3_rtx
;
2952 = get_pointer_alignment (arg1
, BIGGEST_ALIGNMENT
) / BITS_PER_UNIT
;
2954 = get_pointer_alignment (arg2
, BIGGEST_ALIGNMENT
) / BITS_PER_UNIT
;
2955 enum machine_mode insn_mode
2956 = insn_data
[(int) CODE_FOR_cmpstrsi
].operand
[0].mode
;
2958 /* If we don't have POINTER_TYPE, call the function. */
2959 if (arg1_align
== 0 || arg2_align
== 0)
2962 /* Make a place to write the result of the instruction. */
2965 && GET_CODE (result
) == REG
&& GET_MODE (result
) == insn_mode
2966 && REGNO (result
) >= FIRST_PSEUDO_REGISTER
))
2967 result
= gen_reg_rtx (insn_mode
);
2969 arg1_rtx
= get_memory_rtx (arg1
);
2970 arg2_rtx
= get_memory_rtx (arg2
);
2971 arg3_rtx
= expand_expr (len
, NULL_RTX
, VOIDmode
, 0);
2975 insn
= gen_cmpstrsi (result
, arg1_rtx
, arg2_rtx
, arg3_rtx
,
2976 GEN_INT (MIN (arg1_align
, arg2_align
)));
2981 emit_library_call_value (memcmp_libfunc
, result
, LCT_PURE_MAKE_BLOCK
,
2982 TYPE_MODE (integer_type_node
), 3,
2983 XEXP (arg1_rtx
, 0), Pmode
,
2984 XEXP (arg2_rtx
, 0), Pmode
,
2985 convert_to_mode (TYPE_MODE (sizetype
), arg3_rtx
,
2986 TREE_UNSIGNED (sizetype
)),
2987 TYPE_MODE (sizetype
));
2989 /* Return the value in the proper mode for this function. */
2990 mode
= TYPE_MODE (TREE_TYPE (exp
));
2991 if (GET_MODE (result
) == mode
)
2993 else if (target
!= 0)
2995 convert_move (target
, result
, 0);
2999 return convert_to_mode (mode
, result
, 0);
3006 /* Expand expression EXP, which is a call to the strcmp builtin. Return 0
3007 if we failed the caller should emit a normal call, otherwise try to get
3008 the result in TARGET, if convenient. */
3011 expand_builtin_strcmp (exp
, target
, mode
)
3014 enum machine_mode mode
;
3016 tree arglist
= TREE_OPERAND (exp
, 1);
3018 const char *p1
, *p2
;
3020 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
3023 arg1
= TREE_VALUE (arglist
);
3024 arg2
= TREE_VALUE (TREE_CHAIN (arglist
));
3026 p1
= c_getstr (arg1
);
3027 p2
= c_getstr (arg2
);
3031 const int i
= strcmp (p1
, p2
);
3032 return (i
< 0 ? constm1_rtx
: (i
> 0 ? const1_rtx
: const0_rtx
));
3035 /* If either arg is "", return an expression corresponding to
3036 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
3037 if ((p1
&& *p1
== '\0') || (p2
&& *p2
== '\0'))
3039 tree cst_uchar_node
= build_type_variant (unsigned_char_type_node
, 1, 0);
3040 tree cst_uchar_ptr_node
= build_pointer_type (cst_uchar_node
);
3042 fold (build1 (CONVERT_EXPR
, integer_type_node
,
3043 build1 (INDIRECT_REF
, cst_uchar_node
,
3044 build1 (NOP_EXPR
, cst_uchar_ptr_node
, arg1
))));
3046 fold (build1 (CONVERT_EXPR
, integer_type_node
,
3047 build1 (INDIRECT_REF
, cst_uchar_node
,
3048 build1 (NOP_EXPR
, cst_uchar_ptr_node
, arg2
))));
3049 tree result
= fold (build (MINUS_EXPR
, integer_type_node
, ind1
, ind2
));
3050 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
3053 #ifdef HAVE_cmpstrsi
3056 tree len
, len1
, len2
;
3057 rtx arg1_rtx
, arg2_rtx
, arg3_rtx
;
3061 = get_pointer_alignment (arg1
, BIGGEST_ALIGNMENT
) / BITS_PER_UNIT
;
3063 = get_pointer_alignment (arg2
, BIGGEST_ALIGNMENT
) / BITS_PER_UNIT
;
3064 enum machine_mode insn_mode
3065 = insn_data
[(int) CODE_FOR_cmpstrsi
].operand
[0].mode
;
3067 len1
= c_strlen (arg1
);
3068 len2
= c_strlen (arg2
);
3071 len1
= size_binop (PLUS_EXPR
, ssize_int (1), len1
);
3073 len2
= size_binop (PLUS_EXPR
, ssize_int (1), len2
);
3075 /* If we don't have a constant length for the first, use the length
3076 of the second, if we know it. We don't require a constant for
3077 this case; some cost analysis could be done if both are available
3078 but neither is constant. For now, assume they're equally cheap,
3079 unless one has side effects. If both strings have constant lengths,
3086 else if (TREE_SIDE_EFFECTS (len1
))
3088 else if (TREE_SIDE_EFFECTS (len2
))
3090 else if (TREE_CODE (len1
) != INTEGER_CST
)
3092 else if (TREE_CODE (len2
) != INTEGER_CST
)
3094 else if (tree_int_cst_lt (len1
, len2
))
3099 /* If both arguments have side effects, we cannot optimize. */
3100 if (!len
|| TREE_SIDE_EFFECTS (len
))
3103 /* If we don't have POINTER_TYPE, call the function. */
3104 if (arg1_align
== 0 || arg2_align
== 0)
3107 /* Make a place to write the result of the instruction. */
3110 && GET_CODE (result
) == REG
&& GET_MODE (result
) == insn_mode
3111 && REGNO (result
) >= FIRST_PSEUDO_REGISTER
))
3112 result
= gen_reg_rtx (insn_mode
);
3114 arg1_rtx
= get_memory_rtx (arg1
);
3115 arg2_rtx
= get_memory_rtx (arg2
);
3116 arg3_rtx
= expand_expr (len
, NULL_RTX
, VOIDmode
, 0);
3117 insn
= gen_cmpstrsi (result
, arg1_rtx
, arg2_rtx
, arg3_rtx
,
3118 GEN_INT (MIN (arg1_align
, arg2_align
)));
3124 /* Return the value in the proper mode for this function. */
3125 mode
= TYPE_MODE (TREE_TYPE (exp
));
3126 if (GET_MODE (result
) == mode
)
3129 return convert_to_mode (mode
, result
, 0);
3130 convert_move (target
, result
, 0);
3137 /* Expand expression EXP, which is a call to the strncmp builtin. Return 0
3138 if we failed the caller should emit a normal call, otherwise try to get
3139 the result in TARGET, if convenient. */
3142 expand_builtin_strncmp (exp
, target
, mode
)
3145 enum machine_mode mode
;
3147 tree arglist
= TREE_OPERAND (exp
, 1);
3148 tree arg1
, arg2
, arg3
;
3149 const char *p1
, *p2
;
3151 if (!validate_arglist (arglist
,
3152 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
3155 arg1
= TREE_VALUE (arglist
);
3156 arg2
= TREE_VALUE (TREE_CHAIN (arglist
));
3157 arg3
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
3159 /* If the len parameter is zero, return zero. */
3160 if (host_integerp (arg3
, 1) && tree_low_cst (arg3
, 1) == 0)
3162 /* Evaluate and ignore arg1 and arg2 in case they have
3164 expand_expr (arg1
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
3165 expand_expr (arg2
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
3169 p1
= c_getstr (arg1
);
3170 p2
= c_getstr (arg2
);
3172 /* If all arguments are constant, evaluate at compile-time. */
3173 if (host_integerp (arg3
, 1) && p1
&& p2
)
3175 const int r
= strncmp (p1
, p2
, tree_low_cst (arg3
, 1));
3176 return (r
< 0 ? constm1_rtx
: (r
> 0 ? const1_rtx
: const0_rtx
));
3179 /* If len == 1 or (either string parameter is "" and (len >= 1)),
3180 return (*(const u_char*)arg1 - *(const u_char*)arg2). */
3181 if (host_integerp (arg3
, 1)
3182 && (tree_low_cst (arg3
, 1) == 1
3183 || (tree_low_cst (arg3
, 1) > 1
3184 && ((p1
&& *p1
== '\0') || (p2
&& *p2
== '\0')))))
3186 tree cst_uchar_node
= build_type_variant (unsigned_char_type_node
, 1, 0);
3187 tree cst_uchar_ptr_node
= build_pointer_type (cst_uchar_node
);
3189 fold (build1 (CONVERT_EXPR
, integer_type_node
,
3190 build1 (INDIRECT_REF
, cst_uchar_node
,
3191 build1 (NOP_EXPR
, cst_uchar_ptr_node
, arg1
))));
3193 fold (build1 (CONVERT_EXPR
, integer_type_node
,
3194 build1 (INDIRECT_REF
, cst_uchar_node
,
3195 build1 (NOP_EXPR
, cst_uchar_ptr_node
, arg2
))));
3196 tree result
= fold (build (MINUS_EXPR
, integer_type_node
, ind1
, ind2
));
3197 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
3200 /* If c_strlen can determine an expression for one of the string
3201 lengths, and it doesn't have side effects, then emit cmpstrsi
3202 using length MIN(strlen(string)+1, arg3). */
3203 #ifdef HAVE_cmpstrsi
3206 tree len
, len1
, len2
;
3207 rtx arg1_rtx
, arg2_rtx
, arg3_rtx
;
3211 = get_pointer_alignment (arg1
, BIGGEST_ALIGNMENT
) / BITS_PER_UNIT
;
3213 = get_pointer_alignment (arg2
, BIGGEST_ALIGNMENT
) / BITS_PER_UNIT
;
3214 enum machine_mode insn_mode
3215 = insn_data
[(int) CODE_FOR_cmpstrsi
].operand
[0].mode
;
3217 len1
= c_strlen (arg1
);
3218 len2
= c_strlen (arg2
);
3221 len1
= size_binop (PLUS_EXPR
, ssize_int (1), len1
);
3223 len2
= size_binop (PLUS_EXPR
, ssize_int (1), len2
);
3225 /* If we don't have a constant length for the first, use the length
3226 of the second, if we know it. We don't require a constant for
3227 this case; some cost analysis could be done if both are available
3228 but neither is constant. For now, assume they're equally cheap,
3229 unless one has side effects. If both strings have constant lengths,
3236 else if (TREE_SIDE_EFFECTS (len1
))
3238 else if (TREE_SIDE_EFFECTS (len2
))
3240 else if (TREE_CODE (len1
) != INTEGER_CST
)
3242 else if (TREE_CODE (len2
) != INTEGER_CST
)
3244 else if (tree_int_cst_lt (len1
, len2
))
3249 /* If both arguments have side effects, we cannot optimize. */
3250 if (!len
|| TREE_SIDE_EFFECTS (len
))
3253 /* The actual new length parameter is MIN(len,arg3). */
3254 len
= fold (build (MIN_EXPR
, TREE_TYPE (len
), len
, arg3
));
3256 /* If we don't have POINTER_TYPE, call the function. */
3257 if (arg1_align
== 0 || arg2_align
== 0)
3260 /* Make a place to write the result of the instruction. */
3263 && GET_CODE (result
) == REG
&& GET_MODE (result
) == insn_mode
3264 && REGNO (result
) >= FIRST_PSEUDO_REGISTER
))
3265 result
= gen_reg_rtx (insn_mode
);
3267 arg1_rtx
= get_memory_rtx (arg1
);
3268 arg2_rtx
= get_memory_rtx (arg2
);
3269 arg3_rtx
= expand_expr (len
, NULL_RTX
, VOIDmode
, 0);
3270 insn
= gen_cmpstrsi (result
, arg1_rtx
, arg2_rtx
, arg3_rtx
,
3271 GEN_INT (MIN (arg1_align
, arg2_align
)));
3277 /* Return the value in the proper mode for this function. */
3278 mode
= TYPE_MODE (TREE_TYPE (exp
));
3279 if (GET_MODE (result
) == mode
)
3282 return convert_to_mode (mode
, result
, 0);
3283 convert_move (target
, result
, 0);
3290 /* Expand expression EXP, which is a call to the strcat builtin.
3291 Return 0 if we failed the caller should emit a normal call,
3292 otherwise try to get the result in TARGET, if convenient. */
3295 expand_builtin_strcat (arglist
, target
, mode
)
3298 enum machine_mode mode
;
3300 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
3304 tree dst
= TREE_VALUE (arglist
),
3305 src
= TREE_VALUE (TREE_CHAIN (arglist
));
3306 const char *p
= c_getstr (src
);
3308 /* If the string length is zero, return the dst parameter. */
3309 if (p
&& *p
== '\0')
3310 return expand_expr (dst
, target
, mode
, EXPAND_NORMAL
);
3316 /* Expand expression EXP, which is a call to the strncat builtin.
3317 Return 0 if we failed the caller should emit a normal call,
3318 otherwise try to get the result in TARGET, if convenient. */
3321 expand_builtin_strncat (arglist
, target
, mode
)
3324 enum machine_mode mode
;
3326 if (!validate_arglist (arglist
,
3327 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
3331 tree dst
= TREE_VALUE (arglist
),
3332 src
= TREE_VALUE (TREE_CHAIN (arglist
)),
3333 len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
3334 const char *p
= c_getstr (src
);
3336 /* If the requested length is zero, or the src parameter string
3337 length is zero, return the dst parameter. */
3338 if (integer_zerop (len
) || (p
&& *p
== '\0'))
3340 /* Evaluate and ignore the src and len parameters in case
3341 they have side-effects. */
3342 expand_expr (src
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
3343 expand_expr (len
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
3344 return expand_expr (dst
, target
, mode
, EXPAND_NORMAL
);
3347 /* If the requested len is greater than or equal to the string
3348 length, call strcat. */
3349 if (TREE_CODE (len
) == INTEGER_CST
&& p
3350 && compare_tree_int (len
, strlen (p
)) >= 0)
3353 = tree_cons (NULL_TREE
, dst
, build_tree_list (NULL_TREE
, src
));
3354 tree fn
= implicit_built_in_decls
[BUILT_IN_STRCAT
];
3356 /* If the replacement _DECL isn't initialized, don't do the
3361 return expand_expr (build_function_call_expr (fn
, newarglist
),
3362 target
, mode
, EXPAND_NORMAL
);
3368 /* Expand expression EXP, which is a call to the strspn builtin.
3369 Return 0 if we failed the caller should emit a normal call,
3370 otherwise try to get the result in TARGET, if convenient. */
3373 expand_builtin_strspn (arglist
, target
, mode
)
3376 enum machine_mode mode
;
3378 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
3382 tree s1
= TREE_VALUE (arglist
), s2
= TREE_VALUE (TREE_CHAIN (arglist
));
3383 const char *p1
= c_getstr (s1
), *p2
= c_getstr (s2
);
3385 /* If both arguments are constants, evaluate at compile-time. */
3388 const size_t r
= strspn (p1
, p2
);
3389 return expand_expr (size_int (r
), target
, mode
, EXPAND_NORMAL
);
3392 /* If either argument is "", return 0. */
3393 if ((p1
&& *p1
== '\0') || (p2
&& *p2
== '\0'))
3395 /* Evaluate and ignore both arguments in case either one has
3397 expand_expr (s1
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
3398 expand_expr (s2
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
3405 /* Expand expression EXP, which is a call to the strcspn builtin.
3406 Return 0 if we failed the caller should emit a normal call,
3407 otherwise try to get the result in TARGET, if convenient. */
3410 expand_builtin_strcspn (arglist
, target
, mode
)
3413 enum machine_mode mode
;
3415 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
3419 tree s1
= TREE_VALUE (arglist
), s2
= TREE_VALUE (TREE_CHAIN (arglist
));
3420 const char *p1
= c_getstr (s1
), *p2
= c_getstr (s2
);
3422 /* If both arguments are constants, evaluate at compile-time. */
3425 const size_t r
= strcspn (p1
, p2
);
3426 return expand_expr (size_int (r
), target
, mode
, EXPAND_NORMAL
);
3429 /* If the first argument is "", return 0. */
3430 if (p1
&& *p1
== '\0')
3432 /* Evaluate and ignore argument s2 in case it has
3434 expand_expr (s2
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
3438 /* If the second argument is "", return __builtin_strlen(s1). */
3439 if (p2
&& *p2
== '\0')
3441 tree newarglist
= build_tree_list (NULL_TREE
, s1
),
3442 fn
= implicit_built_in_decls
[BUILT_IN_STRLEN
];
3444 /* If the replacement _DECL isn't initialized, don't do the
3449 return expand_expr (build_function_call_expr (fn
, newarglist
),
3450 target
, mode
, EXPAND_NORMAL
);
3456 /* Expand a call to __builtin_saveregs, generating the result in TARGET,
3457 if that's convenient. */
3460 expand_builtin_saveregs ()
3464 /* Don't do __builtin_saveregs more than once in a function.
3465 Save the result of the first call and reuse it. */
3466 if (saveregs_value
!= 0)
3467 return saveregs_value
;
3469 /* When this function is called, it means that registers must be
3470 saved on entry to this function. So we migrate the call to the
3471 first insn of this function. */
3475 #ifdef EXPAND_BUILTIN_SAVEREGS
3476 /* Do whatever the machine needs done in this case. */
3477 val
= EXPAND_BUILTIN_SAVEREGS ();
3479 /* ??? We used to try and build up a call to the out of line function,
3480 guessing about what registers needed saving etc. This became much
3481 harder with __builtin_va_start, since we don't have a tree for a
3482 call to __builtin_saveregs to fall back on. There was exactly one
3483 port (i860) that used this code, and I'm unconvinced it could actually
3484 handle the general case. So we no longer try to handle anything
3485 weird and make the backend absorb the evil. */
3487 error ("__builtin_saveregs not supported by this target");
3494 saveregs_value
= val
;
3496 /* Put the insns after the NOTE that starts the function. If this
3497 is inside a start_sequence, make the outer-level insn chain current, so
3498 the code is placed at the start of the function. */
3499 push_topmost_sequence ();
3500 emit_insn_after (seq
, get_insns ());
3501 pop_topmost_sequence ();
3506 /* __builtin_args_info (N) returns word N of the arg space info
3507 for the current function. The number and meanings of words
3508 is controlled by the definition of CUMULATIVE_ARGS. */
3511 expand_builtin_args_info (arglist
)
3514 int nwords
= sizeof (CUMULATIVE_ARGS
) / sizeof (int);
3515 int *word_ptr
= (int *) ¤t_function_args_info
;
3517 if (sizeof (CUMULATIVE_ARGS
) % sizeof (int) != 0)
3522 if (!host_integerp (TREE_VALUE (arglist
), 0))
3523 error ("argument of `__builtin_args_info' must be constant");
3526 HOST_WIDE_INT wordnum
= tree_low_cst (TREE_VALUE (arglist
), 0);
3528 if (wordnum
< 0 || wordnum
>= nwords
)
3529 error ("argument of `__builtin_args_info' out of range");
3531 return GEN_INT (word_ptr
[wordnum
]);
3535 error ("missing argument in `__builtin_args_info'");
3540 /* Expand ARGLIST, from a call to __builtin_next_arg. */
3543 expand_builtin_next_arg (arglist
)
3546 tree fntype
= TREE_TYPE (current_function_decl
);
3548 if (TYPE_ARG_TYPES (fntype
) == 0
3549 || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype
)))
3552 error ("`va_start' used in function with fixed args");
3558 tree last_parm
= tree_last (DECL_ARGUMENTS (current_function_decl
));
3559 tree arg
= TREE_VALUE (arglist
);
3561 /* Strip off all nops for the sake of the comparison. This
3562 is not quite the same as STRIP_NOPS. It does more.
3563 We must also strip off INDIRECT_EXPR for C++ reference
3565 while (TREE_CODE (arg
) == NOP_EXPR
3566 || TREE_CODE (arg
) == CONVERT_EXPR
3567 || TREE_CODE (arg
) == NON_LVALUE_EXPR
3568 || TREE_CODE (arg
) == INDIRECT_REF
)
3569 arg
= TREE_OPERAND (arg
, 0);
3570 if (arg
!= last_parm
)
3571 warning ("second parameter of `va_start' not last named argument");
3574 /* Evidently an out of date version of <stdarg.h>; can't validate
3575 va_start's second argument, but can still work as intended. */
3576 warning ("`__builtin_next_arg' called without an argument");
3578 return expand_binop (Pmode
, add_optab
,
3579 current_function_internal_arg_pointer
,
3580 current_function_arg_offset_rtx
,
3581 NULL_RTX
, 0, OPTAB_LIB_WIDEN
);
3584 /* Make it easier for the backends by protecting the valist argument
3585 from multiple evaluations. */
3588 stabilize_va_list (valist
, needs_lvalue
)
3592 if (TREE_CODE (va_list_type_node
) == ARRAY_TYPE
)
3594 if (TREE_SIDE_EFFECTS (valist
))
3595 valist
= save_expr (valist
);
3597 /* For this case, the backends will be expecting a pointer to
3598 TREE_TYPE (va_list_type_node), but it's possible we've
3599 actually been given an array (an actual va_list_type_node).
3601 if (TREE_CODE (TREE_TYPE (valist
)) == ARRAY_TYPE
)
3603 tree p1
= build_pointer_type (TREE_TYPE (va_list_type_node
));
3604 tree p2
= build_pointer_type (va_list_type_node
);
3606 valist
= build1 (ADDR_EXPR
, p2
, valist
);
3607 valist
= fold (build1 (NOP_EXPR
, p1
, valist
));
3616 if (! TREE_SIDE_EFFECTS (valist
))
3619 pt
= build_pointer_type (va_list_type_node
);
3620 valist
= fold (build1 (ADDR_EXPR
, pt
, valist
));
3621 TREE_SIDE_EFFECTS (valist
) = 1;
3624 if (TREE_SIDE_EFFECTS (valist
))
3625 valist
= save_expr (valist
);
3626 valist
= fold (build1 (INDIRECT_REF
, TREE_TYPE (TREE_TYPE (valist
)),
3633 /* The "standard" implementation of va_start: just assign `nextarg' to
3637 std_expand_builtin_va_start (valist
, nextarg
)
3643 t
= build (MODIFY_EXPR
, TREE_TYPE (valist
), valist
,
3644 make_tree (ptr_type_node
, nextarg
));
3645 TREE_SIDE_EFFECTS (t
) = 1;
3647 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
3650 /* Expand ARGLIST, from a call to __builtin_va_start. */
3653 expand_builtin_va_start (arglist
)
3659 chain
= TREE_CHAIN (arglist
);
3661 if (TREE_CHAIN (chain
))
3662 error ("too many arguments to function `va_start'");
3664 nextarg
= expand_builtin_next_arg (chain
);
3665 valist
= stabilize_va_list (TREE_VALUE (arglist
), 1);
3667 #ifdef EXPAND_BUILTIN_VA_START
3668 EXPAND_BUILTIN_VA_START (valist
, nextarg
);
3670 std_expand_builtin_va_start (valist
, nextarg
);
3676 /* The "standard" implementation of va_arg: read the value from the
3677 current (padded) address and increment by the (padded) size. */
3680 std_expand_builtin_va_arg (valist
, type
)
3683 tree addr_tree
, t
, type_size
= NULL
;
3684 tree align
, alignm1
;
3688 /* Compute the rounded size of the type. */
3689 align
= size_int (PARM_BOUNDARY
/ BITS_PER_UNIT
);
3690 alignm1
= size_int (PARM_BOUNDARY
/ BITS_PER_UNIT
- 1);
3691 if (type
== error_mark_node
3692 || (type_size
= TYPE_SIZE_UNIT (TYPE_MAIN_VARIANT (type
))) == NULL
3693 || TREE_OVERFLOW (type_size
))
3694 rounded_size
= size_zero_node
;
3696 rounded_size
= fold (build (MULT_EXPR
, sizetype
,
3697 fold (build (TRUNC_DIV_EXPR
, sizetype
,
3698 fold (build (PLUS_EXPR
, sizetype
,
3699 type_size
, alignm1
)),
3705 if (PAD_VARARGS_DOWN
&& ! integer_zerop (rounded_size
))
3707 /* Small args are padded downward. */
3708 addr_tree
= fold (build (PLUS_EXPR
, TREE_TYPE (addr_tree
), addr_tree
,
3709 fold (build (COND_EXPR
, sizetype
,
3710 fold (build (GT_EXPR
, sizetype
,
3714 fold (build (MINUS_EXPR
, sizetype
,
3719 addr
= expand_expr (addr_tree
, NULL_RTX
, Pmode
, EXPAND_NORMAL
);
3720 addr
= copy_to_reg (addr
);
3722 /* Compute new value for AP. */
3723 if (! integer_zerop (rounded_size
))
3725 t
= build (MODIFY_EXPR
, TREE_TYPE (valist
), valist
,
3726 build (PLUS_EXPR
, TREE_TYPE (valist
), valist
,
3728 TREE_SIDE_EFFECTS (t
) = 1;
3729 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
3735 /* Expand __builtin_va_arg, which is not really a builtin function, but
3736 a very special sort of operator. */
3739 expand_builtin_va_arg (valist
, type
)
3743 tree promoted_type
, want_va_type
, have_va_type
;
3745 /* Verify that valist is of the proper type. */
3747 want_va_type
= va_list_type_node
;
3748 have_va_type
= TREE_TYPE (valist
);
3749 if (TREE_CODE (want_va_type
) == ARRAY_TYPE
)
3751 /* If va_list is an array type, the argument may have decayed
3752 to a pointer type, e.g. by being passed to another function.
3753 In that case, unwrap both types so that we can compare the
3754 underlying records. */
3755 if (TREE_CODE (have_va_type
) == ARRAY_TYPE
3756 || TREE_CODE (have_va_type
) == POINTER_TYPE
)
3758 want_va_type
= TREE_TYPE (want_va_type
);
3759 have_va_type
= TREE_TYPE (have_va_type
);
3762 if (TYPE_MAIN_VARIANT (want_va_type
) != TYPE_MAIN_VARIANT (have_va_type
))
3764 error ("first argument to `va_arg' not of type `va_list'");
3768 /* Generate a diagnostic for requesting data of a type that cannot
3769 be passed through `...' due to type promotion at the call site. */
3770 else if ((promoted_type
= (*lang_hooks
.types
.type_promotes_to
) (type
))
3773 const char *name
= "<anonymous type>", *pname
= 0;
3774 static bool gave_help
;
3776 if (TYPE_NAME (type
))
3778 if (TREE_CODE (TYPE_NAME (type
)) == IDENTIFIER_NODE
)
3779 name
= IDENTIFIER_POINTER (TYPE_NAME (type
));
3780 else if (TREE_CODE (TYPE_NAME (type
)) == TYPE_DECL
3781 && DECL_NAME (TYPE_NAME (type
)))
3782 name
= IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type
)));
3784 if (TYPE_NAME (promoted_type
))
3786 if (TREE_CODE (TYPE_NAME (promoted_type
)) == IDENTIFIER_NODE
)
3787 pname
= IDENTIFIER_POINTER (TYPE_NAME (promoted_type
));
3788 else if (TREE_CODE (TYPE_NAME (promoted_type
)) == TYPE_DECL
3789 && DECL_NAME (TYPE_NAME (promoted_type
)))
3790 pname
= IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (promoted_type
)));
3793 /* Unfortunately, this is merely undefined, rather than a constraint
3794 violation, so we cannot make this an error. If this call is never
3795 executed, the program is still strictly conforming. */
3796 warning ("`%s' is promoted to `%s' when passed through `...'",
3801 warning ("(so you should pass `%s' not `%s' to `va_arg')",
3805 /* We can, however, treat "undefined" any way we please.
3806 Call abort to encourage the user to fix the program. */
3807 expand_builtin_trap ();
3809 /* This is dead code, but go ahead and finish so that the
3810 mode of the result comes out right. */
3815 /* Make it easier for the backends by protecting the valist argument
3816 from multiple evaluations. */
3817 valist
= stabilize_va_list (valist
, 0);
3819 #ifdef EXPAND_BUILTIN_VA_ARG
3820 addr
= EXPAND_BUILTIN_VA_ARG (valist
, type
);
3822 addr
= std_expand_builtin_va_arg (valist
, type
);
3826 #ifdef POINTERS_EXTEND_UNSIGNED
3827 if (GET_MODE (addr
) != Pmode
)
3828 addr
= convert_memory_address (Pmode
, addr
);
3831 result
= gen_rtx_MEM (TYPE_MODE (type
), addr
);
3832 set_mem_alias_set (result
, get_varargs_alias_set ());
3837 /* Expand ARGLIST, from a call to __builtin_va_end. */
3840 expand_builtin_va_end (arglist
)
3843 tree valist
= TREE_VALUE (arglist
);
3845 #ifdef EXPAND_BUILTIN_VA_END
3846 valist
= stabilize_va_list (valist
, 0);
3847 EXPAND_BUILTIN_VA_END (arglist
);
3849 /* Evaluate for side effects, if needed. I hate macros that don't
3851 if (TREE_SIDE_EFFECTS (valist
))
3852 expand_expr (valist
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
3858 /* Expand ARGLIST, from a call to __builtin_va_copy. We do this as a
3859 builtin rather than just as an assignment in stdarg.h because of the
3860 nastiness of array-type va_list types. */
3863 expand_builtin_va_copy (arglist
)
3868 dst
= TREE_VALUE (arglist
);
3869 src
= TREE_VALUE (TREE_CHAIN (arglist
));
3871 dst
= stabilize_va_list (dst
, 1);
3872 src
= stabilize_va_list (src
, 0);
3874 if (TREE_CODE (va_list_type_node
) != ARRAY_TYPE
)
3876 t
= build (MODIFY_EXPR
, va_list_type_node
, dst
, src
);
3877 TREE_SIDE_EFFECTS (t
) = 1;
3878 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
3882 rtx dstb
, srcb
, size
;
3884 /* Evaluate to pointers. */
3885 dstb
= expand_expr (dst
, NULL_RTX
, Pmode
, EXPAND_NORMAL
);
3886 srcb
= expand_expr (src
, NULL_RTX
, Pmode
, EXPAND_NORMAL
);
3887 size
= expand_expr (TYPE_SIZE_UNIT (va_list_type_node
), NULL_RTX
,
3888 VOIDmode
, EXPAND_NORMAL
);
3890 #ifdef POINTERS_EXTEND_UNSIGNED
3891 if (GET_MODE (dstb
) != Pmode
)
3892 dstb
= convert_memory_address (Pmode
, dstb
);
3894 if (GET_MODE (srcb
) != Pmode
)
3895 srcb
= convert_memory_address (Pmode
, srcb
);
3898 /* "Dereference" to BLKmode memories. */
3899 dstb
= gen_rtx_MEM (BLKmode
, dstb
);
3900 set_mem_alias_set (dstb
, get_alias_set (TREE_TYPE (TREE_TYPE (dst
))));
3901 set_mem_align (dstb
, TYPE_ALIGN (va_list_type_node
));
3902 srcb
= gen_rtx_MEM (BLKmode
, srcb
);
3903 set_mem_alias_set (srcb
, get_alias_set (TREE_TYPE (TREE_TYPE (src
))));
3904 set_mem_align (srcb
, TYPE_ALIGN (va_list_type_node
));
3907 emit_block_move (dstb
, srcb
, size
, BLOCK_OP_NORMAL
);
3913 /* Expand a call to one of the builtin functions __builtin_frame_address or
3914 __builtin_return_address. */
3917 expand_builtin_frame_address (fndecl
, arglist
)
3918 tree fndecl
, arglist
;
3920 /* The argument must be a nonnegative integer constant.
3921 It counts the number of frames to scan up the stack.
3922 The value is the return address saved in that frame. */
3924 /* Warning about missing arg was already issued. */
3926 else if (! host_integerp (TREE_VALUE (arglist
), 1))
3928 if (DECL_FUNCTION_CODE (fndecl
) == BUILT_IN_FRAME_ADDRESS
)
3929 error ("invalid arg to `__builtin_frame_address'");
3931 error ("invalid arg to `__builtin_return_address'");
3937 = expand_builtin_return_addr (DECL_FUNCTION_CODE (fndecl
),
3938 tree_low_cst (TREE_VALUE (arglist
), 1),
3939 hard_frame_pointer_rtx
);
3941 /* Some ports cannot access arbitrary stack frames. */
3944 if (DECL_FUNCTION_CODE (fndecl
) == BUILT_IN_FRAME_ADDRESS
)
3945 warning ("unsupported arg to `__builtin_frame_address'");
3947 warning ("unsupported arg to `__builtin_return_address'");
3951 /* For __builtin_frame_address, return what we've got. */
3952 if (DECL_FUNCTION_CODE (fndecl
) == BUILT_IN_FRAME_ADDRESS
)
3955 if (GET_CODE (tem
) != REG
3956 && ! CONSTANT_P (tem
))
3957 tem
= copy_to_mode_reg (Pmode
, tem
);
3962 /* Expand a call to the alloca builtin, with arguments ARGLIST. Return 0 if
3963 we failed and the caller should emit a normal call, otherwise try to get
3964 the result in TARGET, if convenient. */
3967 expand_builtin_alloca (arglist
, target
)
3974 if (!validate_arglist (arglist
, INTEGER_TYPE
, VOID_TYPE
))
3977 /* Compute the argument. */
3978 op0
= expand_expr (TREE_VALUE (arglist
), NULL_RTX
, VOIDmode
, 0);
3980 /* Allocate the desired space. */
3981 result
= allocate_dynamic_stack_space (op0
, target
, BITS_PER_UNIT
);
3983 #ifdef POINTERS_EXTEND_UNSIGNED
3984 if (GET_MODE (result
) != ptr_mode
)
3985 result
= convert_memory_address (ptr_mode
, result
);
3991 /* Expand a call to a unary builtin. The arguments are in ARGLIST.
3992 Return 0 if a normal call should be emitted rather than expanding the
3993 function in-line. If convenient, the result should be placed in TARGET.
3994 SUBTARGET may be used as the target for computing one of EXP's operands. */
3997 expand_builtin_unop (target_mode
, arglist
, target
, subtarget
, op_optab
)
3998 enum machine_mode target_mode
;
4000 rtx target
, subtarget
;
4004 if (!validate_arglist (arglist
, INTEGER_TYPE
, VOID_TYPE
))
4007 /* Compute the argument. */
4008 op0
= expand_expr (TREE_VALUE (arglist
), subtarget
, VOIDmode
, 0);
4009 /* Compute op, into TARGET if possible.
4010 Set TARGET to wherever the result comes back. */
4011 target
= expand_unop (TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist
))),
4012 op_optab
, op0
, target
, 1);
4016 return convert_to_mode (target_mode
, target
, 0);
4019 /* If the string passed to fputs is a constant and is one character
4020 long, we attempt to transform this call into __builtin_fputc(). */
4023 expand_builtin_fputs (arglist
, ignore
, unlocked
)
4029 tree fn_fputc
= unlocked
? implicit_built_in_decls
[BUILT_IN_FPUTC_UNLOCKED
]
4030 : implicit_built_in_decls
[BUILT_IN_FPUTC
];
4031 tree fn_fwrite
= unlocked
? implicit_built_in_decls
[BUILT_IN_FWRITE_UNLOCKED
]
4032 : implicit_built_in_decls
[BUILT_IN_FWRITE
];
4034 /* If the return value is used, or the replacement _DECL isn't
4035 initialized, don't do the transformation. */
4036 if (!ignore
|| !fn_fputc
|| !fn_fwrite
)
4039 /* Verify the arguments in the original call. */
4040 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
4043 /* Get the length of the string passed to fputs. If the length
4044 can't be determined, punt. */
4045 if (!(len
= c_strlen (TREE_VALUE (arglist
)))
4046 || TREE_CODE (len
) != INTEGER_CST
)
4049 switch (compare_tree_int (len
, 1))
4051 case -1: /* length is 0, delete the call entirely . */
4053 /* Evaluate and ignore the argument in case it has
4055 expand_expr (TREE_VALUE (TREE_CHAIN (arglist
)), const0_rtx
,
4056 VOIDmode
, EXPAND_NORMAL
);
4059 case 0: /* length is 1, call fputc. */
4061 const char *p
= c_getstr (TREE_VALUE (arglist
));
4065 /* New argument list transforming fputs(string, stream) to
4066 fputc(string[0], stream). */
4068 build_tree_list (NULL_TREE
, TREE_VALUE (TREE_CHAIN (arglist
)));
4070 tree_cons (NULL_TREE
, build_int_2 (p
[0], 0), arglist
);
4076 case 1: /* length is greater than 1, call fwrite. */
4080 /* If optimizing for size keep fputs. */
4083 string_arg
= TREE_VALUE (arglist
);
4084 /* New argument list transforming fputs(string, stream) to
4085 fwrite(string, 1, len, stream). */
4086 arglist
= build_tree_list (NULL_TREE
, TREE_VALUE (TREE_CHAIN (arglist
)));
4087 arglist
= tree_cons (NULL_TREE
, len
, arglist
);
4088 arglist
= tree_cons (NULL_TREE
, size_one_node
, arglist
);
4089 arglist
= tree_cons (NULL_TREE
, string_arg
, arglist
);
4097 return expand_expr (build_function_call_expr (fn
, arglist
),
4098 (ignore
? const0_rtx
: NULL_RTX
),
4099 VOIDmode
, EXPAND_NORMAL
);
4102 /* Expand a call to __builtin_expect. We return our argument and emit a
4103 NOTE_INSN_EXPECTED_VALUE note. This is the expansion of __builtin_expect in
4104 a non-jump context. */
4107 expand_builtin_expect (arglist
, target
)
4114 if (arglist
== NULL_TREE
4115 || TREE_CHAIN (arglist
) == NULL_TREE
)
4117 exp
= TREE_VALUE (arglist
);
4118 c
= TREE_VALUE (TREE_CHAIN (arglist
));
4120 if (TREE_CODE (c
) != INTEGER_CST
)
4122 error ("second arg to `__builtin_expect' must be a constant");
4123 c
= integer_zero_node
;
4126 target
= expand_expr (exp
, target
, VOIDmode
, EXPAND_NORMAL
);
4128 /* Don't bother with expected value notes for integral constants. */
4129 if (flag_guess_branch_prob
&& GET_CODE (target
) != CONST_INT
)
4131 /* We do need to force this into a register so that we can be
4132 moderately sure to be able to correctly interpret the branch
4134 target
= force_reg (GET_MODE (target
), target
);
4136 rtx_c
= expand_expr (c
, NULL_RTX
, GET_MODE (target
), EXPAND_NORMAL
);
4138 note
= emit_note (NULL
, NOTE_INSN_EXPECTED_VALUE
);
4139 NOTE_EXPECTED_VALUE (note
) = gen_rtx_EQ (VOIDmode
, target
, rtx_c
);
4145 /* Like expand_builtin_expect, except do this in a jump context. This is
4146 called from do_jump if the conditional is a __builtin_expect. Return either
4147 a list of insns to emit the jump or NULL if we cannot optimize
4148 __builtin_expect. We need to optimize this at jump time so that machines
4149 like the PowerPC don't turn the test into a SCC operation, and then jump
4150 based on the test being 0/1. */
4153 expand_builtin_expect_jump (exp
, if_false_label
, if_true_label
)
4158 tree arglist
= TREE_OPERAND (exp
, 1);
4159 tree arg0
= TREE_VALUE (arglist
);
4160 tree arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
4163 /* Only handle __builtin_expect (test, 0) and
4164 __builtin_expect (test, 1). */
4165 if (TREE_CODE (TREE_TYPE (arg1
)) == INTEGER_TYPE
4166 && (integer_zerop (arg1
) || integer_onep (arg1
)))
4171 /* If we fail to locate an appropriate conditional jump, we'll
4172 fall back to normal evaluation. Ensure that the expression
4173 can be re-evaluated. */
4174 switch (unsafe_for_reeval (arg0
))
4179 case 1: /* Mildly unsafe. */
4180 arg0
= unsave_expr (arg0
);
4183 case 2: /* Wildly unsafe. */
4187 /* Expand the jump insns. */
4189 do_jump (arg0
, if_false_label
, if_true_label
);
4193 /* Now that the __builtin_expect has been validated, go through and add
4194 the expect's to each of the conditional jumps. If we run into an
4195 error, just give up and generate the 'safe' code of doing a SCC
4196 operation and then doing a branch on that. */
4198 while (insn
!= NULL_RTX
)
4200 rtx next
= NEXT_INSN (insn
);
4203 if (GET_CODE (insn
) == JUMP_INSN
&& any_condjump_p (insn
)
4204 && (pattern
= pc_set (insn
)) != NULL_RTX
)
4206 rtx ifelse
= SET_SRC (pattern
);
4210 if (GET_CODE (ifelse
) != IF_THEN_ELSE
)
4213 if (GET_CODE (XEXP (ifelse
, 1)) == LABEL_REF
)
4216 label
= XEXP (XEXP (ifelse
, 1), 0);
4218 /* An inverted jump reverses the probabilities. */
4219 else if (GET_CODE (XEXP (ifelse
, 2)) == LABEL_REF
)
4222 label
= XEXP (XEXP (ifelse
, 2), 0);
4224 /* We shouldn't have to worry about conditional returns during
4225 the expansion stage, but handle it gracefully anyway. */
4226 else if (GET_CODE (XEXP (ifelse
, 1)) == RETURN
)
4231 /* An inverted return reverses the probabilities. */
4232 else if (GET_CODE (XEXP (ifelse
, 2)) == RETURN
)
4240 /* If the test is expected to fail, reverse the
4242 if (integer_zerop (arg1
))
4245 /* If we are jumping to the false label, reverse the
4247 if (label
== NULL_RTX
)
4248 ; /* conditional return */
4249 else if (label
== if_false_label
)
4251 else if (label
!= if_true_label
)
4255 predict_insn_def (insn
, PRED_BUILTIN_EXPECT
, taken
);
4262 /* If no jumps were modified, fail and do __builtin_expect the normal
4272 expand_builtin_trap ()
4276 emit_insn (gen_trap ());
4279 emit_library_call (abort_libfunc
, LCT_NORETURN
, VOIDmode
, 0);
4283 /* Expand an expression EXP that calls a built-in function,
4284 with result going to TARGET if that's convenient
4285 (and in mode MODE if that's convenient).
4286 SUBTARGET may be used as the target for computing one of EXP's operands.
4287 IGNORE is nonzero if the value is to be ignored. */
4290 expand_builtin (exp
, target
, subtarget
, mode
, ignore
)
4294 enum machine_mode mode
;
4297 tree fndecl
= TREE_OPERAND (TREE_OPERAND (exp
, 0), 0);
4298 tree arglist
= TREE_OPERAND (exp
, 1);
4299 enum built_in_function fcode
= DECL_FUNCTION_CODE (fndecl
);
4300 enum machine_mode target_mode
= TYPE_MODE (TREE_TYPE (exp
));
4302 /* Perform postincrements before expanding builtin functions. Â */
4305 if (DECL_BUILT_IN_CLASS (fndecl
) == BUILT_IN_MD
)
4306 return (*targetm
.expand_builtin
) (exp
, target
, subtarget
, mode
, ignore
);
4308 /* When not optimizing, generate calls to library functions for a certain
4310 if (!optimize
&& !CALLED_AS_BUILT_IN (fndecl
))
4314 case BUILT_IN_SQRTF
:
4315 case BUILT_IN_SQRTL
:
4332 case BUILT_IN_ATANF
:
4333 case BUILT_IN_ATANL
:
4337 case BUILT_IN_ATAN2
:
4338 case BUILT_IN_ATAN2F
:
4339 case BUILT_IN_ATAN2L
:
4340 case BUILT_IN_MEMSET
:
4341 case BUILT_IN_MEMCPY
:
4342 case BUILT_IN_MEMCMP
:
4343 case BUILT_IN_MEMPCPY
:
4344 case BUILT_IN_MEMMOVE
:
4346 case BUILT_IN_BZERO
:
4347 case BUILT_IN_BCOPY
:
4348 case BUILT_IN_INDEX
:
4349 case BUILT_IN_RINDEX
:
4350 case BUILT_IN_STPCPY
:
4351 case BUILT_IN_STRCHR
:
4352 case BUILT_IN_STRRCHR
:
4353 case BUILT_IN_STRLEN
:
4354 case BUILT_IN_STRCPY
:
4355 case BUILT_IN_STRNCPY
:
4356 case BUILT_IN_STRNCMP
:
4357 case BUILT_IN_STRSTR
:
4358 case BUILT_IN_STRPBRK
:
4359 case BUILT_IN_STRCAT
:
4360 case BUILT_IN_STRNCAT
:
4361 case BUILT_IN_STRSPN
:
4362 case BUILT_IN_STRCSPN
:
4363 case BUILT_IN_STRCMP
:
4365 case BUILT_IN_PUTCHAR
:
4367 case BUILT_IN_PRINTF
:
4368 case BUILT_IN_FPUTC
:
4369 case BUILT_IN_FPUTS
:
4370 case BUILT_IN_FWRITE
:
4371 case BUILT_IN_PUTCHAR_UNLOCKED
:
4372 case BUILT_IN_PUTS_UNLOCKED
:
4373 case BUILT_IN_PRINTF_UNLOCKED
:
4374 case BUILT_IN_FPUTC_UNLOCKED
:
4375 case BUILT_IN_FPUTS_UNLOCKED
:
4376 case BUILT_IN_FWRITE_UNLOCKED
:
4377 case BUILT_IN_FLOOR
:
4378 case BUILT_IN_FLOORF
:
4379 case BUILT_IN_FLOORL
:
4381 case BUILT_IN_CEILF
:
4382 case BUILT_IN_CEILL
:
4383 case BUILT_IN_TRUNC
:
4384 case BUILT_IN_TRUNCF
:
4385 case BUILT_IN_TRUNCL
:
4386 case BUILT_IN_ROUND
:
4387 case BUILT_IN_ROUNDF
:
4388 case BUILT_IN_ROUNDL
:
4389 case BUILT_IN_NEARBYINT
:
4390 case BUILT_IN_NEARBYINTF
:
4391 case BUILT_IN_NEARBYINTL
:
4392 return expand_call (exp
, target
, ignore
);
4398 /* The built-in function expanders test for target == const0_rtx
4399 to determine whether the function's result will be ignored. */
4401 target
= const0_rtx
;
4403 /* If the result of a pure or const built-in function is ignored, and
4404 none of its arguments are volatile, we can avoid expanding the
4405 built-in call and just evaluate the arguments for side-effects. */
4406 if (target
== const0_rtx
4407 && (DECL_IS_PURE (fndecl
) || TREE_READONLY (fndecl
)))
4409 bool volatilep
= false;
4412 for (arg
= arglist
; arg
; arg
= TREE_CHAIN (arg
))
4413 if (TREE_THIS_VOLATILE (TREE_VALUE (arg
)))
4421 for (arg
= arglist
; arg
; arg
= TREE_CHAIN (arg
))
4422 expand_expr (TREE_VALUE (arg
), const0_rtx
,
4423 VOIDmode
, EXPAND_NORMAL
);
4432 case BUILT_IN_LLABS
:
4433 case BUILT_IN_IMAXABS
:
4435 case BUILT_IN_FABSF
:
4436 case BUILT_IN_FABSL
:
4437 /* build_function_call changes these into ABS_EXPR. */
4441 case BUILT_IN_CONJF
:
4442 case BUILT_IN_CONJL
:
4443 case BUILT_IN_CREAL
:
4444 case BUILT_IN_CREALF
:
4445 case BUILT_IN_CREALL
:
4446 case BUILT_IN_CIMAG
:
4447 case BUILT_IN_CIMAGF
:
4448 case BUILT_IN_CIMAGL
:
4449 /* expand_tree_builtin changes these into CONJ_EXPR, REALPART_EXPR
4450 and IMAGPART_EXPR. */
4465 /* Treat these like sqrt only if unsafe math optimizations are allowed,
4466 because of possible accuracy problems. */
4467 if (! flag_unsafe_math_optimizations
)
4470 case BUILT_IN_SQRTF
:
4471 case BUILT_IN_SQRTL
:
4472 case BUILT_IN_FLOOR
:
4473 case BUILT_IN_FLOORF
:
4474 case BUILT_IN_FLOORL
:
4476 case BUILT_IN_CEILF
:
4477 case BUILT_IN_CEILL
:
4478 case BUILT_IN_TRUNC
:
4479 case BUILT_IN_TRUNCF
:
4480 case BUILT_IN_TRUNCL
:
4481 case BUILT_IN_ROUND
:
4482 case BUILT_IN_ROUNDF
:
4483 case BUILT_IN_ROUNDL
:
4484 case BUILT_IN_NEARBYINT
:
4485 case BUILT_IN_NEARBYINTF
:
4486 case BUILT_IN_NEARBYINTL
:
4487 target
= expand_builtin_mathfn (exp
, target
, subtarget
);
4495 case BUILT_IN_ATAN2
:
4496 case BUILT_IN_ATAN2F
:
4497 case BUILT_IN_ATAN2L
:
4498 if (! flag_unsafe_math_optimizations
)
4500 target
= expand_builtin_mathfn_2 (exp
, target
, subtarget
);
4505 case BUILT_IN_APPLY_ARGS
:
4506 return expand_builtin_apply_args ();
4508 /* __builtin_apply (FUNCTION, ARGUMENTS, ARGSIZE) invokes
4509 FUNCTION with a copy of the parameters described by
4510 ARGUMENTS, and ARGSIZE. It returns a block of memory
4511 allocated on the stack into which is stored all the registers
4512 that might possibly be used for returning the result of a
4513 function. ARGUMENTS is the value returned by
4514 __builtin_apply_args. ARGSIZE is the number of bytes of
4515 arguments that must be copied. ??? How should this value be
4516 computed? We'll also need a safe worst case value for varargs
4518 case BUILT_IN_APPLY
:
4519 if (!validate_arglist (arglist
, POINTER_TYPE
,
4520 POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
)
4521 && !validate_arglist (arglist
, REFERENCE_TYPE
,
4522 POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
4530 for (t
= arglist
, i
= 0; t
; t
= TREE_CHAIN (t
), i
++)
4531 ops
[i
] = expand_expr (TREE_VALUE (t
), NULL_RTX
, VOIDmode
, 0);
4533 return expand_builtin_apply (ops
[0], ops
[1], ops
[2]);
4536 /* __builtin_return (RESULT) causes the function to return the
4537 value described by RESULT. RESULT is address of the block of
4538 memory returned by __builtin_apply. */
4539 case BUILT_IN_RETURN
:
4540 if (validate_arglist (arglist
, POINTER_TYPE
, VOID_TYPE
))
4541 expand_builtin_return (expand_expr (TREE_VALUE (arglist
),
4542 NULL_RTX
, VOIDmode
, 0));
4545 case BUILT_IN_SAVEREGS
:
4546 return expand_builtin_saveregs ();
4548 case BUILT_IN_ARGS_INFO
:
4549 return expand_builtin_args_info (arglist
);
4551 /* Return the address of the first anonymous stack arg. */
4552 case BUILT_IN_NEXT_ARG
:
4553 return expand_builtin_next_arg (arglist
);
4555 case BUILT_IN_CLASSIFY_TYPE
:
4556 return expand_builtin_classify_type (arglist
);
4558 case BUILT_IN_CONSTANT_P
:
4559 return expand_builtin_constant_p (arglist
, target_mode
);
4561 case BUILT_IN_FRAME_ADDRESS
:
4562 case BUILT_IN_RETURN_ADDRESS
:
4563 return expand_builtin_frame_address (fndecl
, arglist
);
4565 /* Returns the address of the area where the structure is returned.
4567 case BUILT_IN_AGGREGATE_INCOMING_ADDRESS
:
4569 || ! AGGREGATE_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl
)))
4570 || GET_CODE (DECL_RTL (DECL_RESULT (current_function_decl
))) != MEM
)
4573 return XEXP (DECL_RTL (DECL_RESULT (current_function_decl
)), 0);
4575 case BUILT_IN_ALLOCA
:
4576 target
= expand_builtin_alloca (arglist
, target
);
4583 case BUILT_IN_FFSLL
:
4584 target
= expand_builtin_unop (target_mode
, arglist
, target
,
4585 subtarget
, ffs_optab
);
4592 case BUILT_IN_CLZLL
:
4593 target
= expand_builtin_unop (target_mode
, arglist
, target
,
4594 subtarget
, clz_optab
);
4601 case BUILT_IN_CTZLL
:
4602 target
= expand_builtin_unop (target_mode
, arglist
, target
,
4603 subtarget
, ctz_optab
);
4608 case BUILT_IN_POPCOUNT
:
4609 case BUILT_IN_POPCOUNTL
:
4610 case BUILT_IN_POPCOUNTLL
:
4611 target
= expand_builtin_unop (target_mode
, arglist
, target
,
4612 subtarget
, popcount_optab
);
4617 case BUILT_IN_PARITY
:
4618 case BUILT_IN_PARITYL
:
4619 case BUILT_IN_PARITYLL
:
4620 target
= expand_builtin_unop (target_mode
, arglist
, target
,
4621 subtarget
, parity_optab
);
4626 case BUILT_IN_STRLEN
:
4627 target
= expand_builtin_strlen (arglist
, target
, target_mode
);
4632 case BUILT_IN_STRCPY
:
4633 target
= expand_builtin_strcpy (arglist
, target
, mode
);
4638 case BUILT_IN_STRNCPY
:
4639 target
= expand_builtin_strncpy (arglist
, target
, mode
);
4644 case BUILT_IN_STPCPY
:
4645 target
= expand_builtin_stpcpy (arglist
, target
, mode
);
4650 case BUILT_IN_STRCAT
:
4651 target
= expand_builtin_strcat (arglist
, target
, mode
);
4656 case BUILT_IN_STRNCAT
:
4657 target
= expand_builtin_strncat (arglist
, target
, mode
);
4662 case BUILT_IN_STRSPN
:
4663 target
= expand_builtin_strspn (arglist
, target
, mode
);
4668 case BUILT_IN_STRCSPN
:
4669 target
= expand_builtin_strcspn (arglist
, target
, mode
);
4674 case BUILT_IN_STRSTR
:
4675 target
= expand_builtin_strstr (arglist
, target
, mode
);
4680 case BUILT_IN_STRPBRK
:
4681 target
= expand_builtin_strpbrk (arglist
, target
, mode
);
4686 case BUILT_IN_INDEX
:
4687 case BUILT_IN_STRCHR
:
4688 target
= expand_builtin_strchr (arglist
, target
, mode
);
4693 case BUILT_IN_RINDEX
:
4694 case BUILT_IN_STRRCHR
:
4695 target
= expand_builtin_strrchr (arglist
, target
, mode
);
4700 case BUILT_IN_MEMCPY
:
4701 target
= expand_builtin_memcpy (arglist
, target
, mode
, /*endp=*/0);
4706 case BUILT_IN_MEMPCPY
:
4707 target
= expand_builtin_mempcpy (arglist
, target
, mode
);
4712 case BUILT_IN_MEMMOVE
:
4713 target
= expand_builtin_memmove (arglist
, target
, mode
);
4718 case BUILT_IN_BCOPY
:
4719 target
= expand_builtin_bcopy (arglist
);
4724 case BUILT_IN_MEMSET
:
4725 target
= expand_builtin_memset (arglist
, target
, mode
);
4730 case BUILT_IN_BZERO
:
4731 target
= expand_builtin_bzero (arglist
);
4736 case BUILT_IN_STRCMP
:
4737 target
= expand_builtin_strcmp (exp
, target
, mode
);
4742 case BUILT_IN_STRNCMP
:
4743 target
= expand_builtin_strncmp (exp
, target
, mode
);
4749 case BUILT_IN_MEMCMP
:
4750 target
= expand_builtin_memcmp (exp
, arglist
, target
, mode
);
4755 case BUILT_IN_SETJMP
:
4756 target
= expand_builtin_setjmp (arglist
, target
);
4761 /* __builtin_longjmp is passed a pointer to an array of five words.
4762 It's similar to the C library longjmp function but works with
4763 __builtin_setjmp above. */
4764 case BUILT_IN_LONGJMP
:
4765 if (!validate_arglist (arglist
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
4769 rtx buf_addr
= expand_expr (TREE_VALUE (arglist
), subtarget
,
4771 rtx value
= expand_expr (TREE_VALUE (TREE_CHAIN (arglist
)),
4772 NULL_RTX
, VOIDmode
, 0);
4774 if (value
!= const1_rtx
)
4776 error ("__builtin_longjmp second argument must be 1");
4780 expand_builtin_longjmp (buf_addr
, value
);
4785 expand_builtin_trap ();
4788 case BUILT_IN_FPUTS
:
4789 target
= expand_builtin_fputs (arglist
, ignore
,/*unlocked=*/ 0);
4793 case BUILT_IN_FPUTS_UNLOCKED
:
4794 target
= expand_builtin_fputs (arglist
, ignore
,/*unlocked=*/ 1);
4799 /* Various hooks for the DWARF 2 __throw routine. */
4800 case BUILT_IN_UNWIND_INIT
:
4801 expand_builtin_unwind_init ();
4803 case BUILT_IN_DWARF_CFA
:
4804 return virtual_cfa_rtx
;
4805 #ifdef DWARF2_UNWIND_INFO
4806 case BUILT_IN_DWARF_SP_COLUMN
:
4807 return expand_builtin_dwarf_sp_column ();
4808 case BUILT_IN_INIT_DWARF_REG_SIZES
:
4809 expand_builtin_init_dwarf_reg_sizes (TREE_VALUE (arglist
));
4812 case BUILT_IN_FROB_RETURN_ADDR
:
4813 return expand_builtin_frob_return_addr (TREE_VALUE (arglist
));
4814 case BUILT_IN_EXTRACT_RETURN_ADDR
:
4815 return expand_builtin_extract_return_addr (TREE_VALUE (arglist
));
4816 case BUILT_IN_EH_RETURN
:
4817 expand_builtin_eh_return (TREE_VALUE (arglist
),
4818 TREE_VALUE (TREE_CHAIN (arglist
)));
4820 #ifdef EH_RETURN_DATA_REGNO
4821 case BUILT_IN_EH_RETURN_DATA_REGNO
:
4822 return expand_builtin_eh_return_data_regno (arglist
);
4824 case BUILT_IN_VA_START
:
4825 case BUILT_IN_STDARG_START
:
4826 return expand_builtin_va_start (arglist
);
4827 case BUILT_IN_VA_END
:
4828 return expand_builtin_va_end (arglist
);
4829 case BUILT_IN_VA_COPY
:
4830 return expand_builtin_va_copy (arglist
);
4831 case BUILT_IN_EXPECT
:
4832 return expand_builtin_expect (arglist
, target
);
4833 case BUILT_IN_PREFETCH
:
4834 expand_builtin_prefetch (arglist
);
4838 default: /* just do library call, if unknown builtin */
4839 if (!DECL_ASSEMBLER_NAME_SET_P (fndecl
))
4840 error ("built-in function `%s' not currently supported",
4841 IDENTIFIER_POINTER (DECL_NAME (fndecl
)));
4844 /* The switch statement above can drop through to cause the function
4845 to be called normally. */
4846 return expand_call (exp
, target
, ignore
);
4849 /* Determine whether a tree node represents a call to a built-in
4850 math function. If the tree T is a call to a built-in function
4851 taking a single real argument, then the return value is the
4852 DECL_FUNCTION_CODE of the call, e.g. BUILT_IN_SQRT. Otherwise
4853 the return value is END_BUILTINS. */
4855 enum built_in_function
4856 builtin_mathfn_code (t
)
4859 tree fndecl
, arglist
;
4861 if (TREE_CODE (t
) != CALL_EXPR
4862 || TREE_CODE (TREE_OPERAND (t
, 0)) != ADDR_EXPR
)
4863 return END_BUILTINS
;
4865 fndecl
= TREE_OPERAND (TREE_OPERAND (t
, 0), 0);
4866 if (TREE_CODE (fndecl
) != FUNCTION_DECL
4867 || ! DECL_BUILT_IN (fndecl
)
4868 || DECL_BUILT_IN_CLASS (fndecl
) == BUILT_IN_MD
)
4869 return END_BUILTINS
;
4871 arglist
= TREE_OPERAND (t
, 1);
4873 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist
))) != REAL_TYPE
)
4874 return END_BUILTINS
;
4876 arglist
= TREE_CHAIN (arglist
);
4877 switch (DECL_FUNCTION_CODE (fndecl
))
4882 case BUILT_IN_ATAN2
:
4883 case BUILT_IN_ATAN2F
:
4884 case BUILT_IN_ATAN2L
:
4886 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist
))) != REAL_TYPE
4887 || TREE_CHAIN (arglist
))
4888 return END_BUILTINS
;
4893 return END_BUILTINS
;
4897 return DECL_FUNCTION_CODE (fndecl
);
4900 /* Fold a call to __builtin_constant_p, if we know it will evaluate to a
4901 constant. ARGLIST is the argument list of the call. */
4904 fold_builtin_constant_p (arglist
)
4910 arglist
= TREE_VALUE (arglist
);
4912 /* We return 1 for a numeric type that's known to be a constant
4913 value at compile-time or for an aggregate type that's a
4914 literal constant. */
4915 STRIP_NOPS (arglist
);
4917 /* If we know this is a constant, emit the constant of one. */
4918 if (TREE_CODE_CLASS (TREE_CODE (arglist
)) == 'c'
4919 || (TREE_CODE (arglist
) == CONSTRUCTOR
4920 && TREE_CONSTANT (arglist
))
4921 || (TREE_CODE (arglist
) == ADDR_EXPR
4922 && TREE_CODE (TREE_OPERAND (arglist
, 0)) == STRING_CST
))
4923 return integer_one_node
;
4925 /* If we aren't going to be running CSE or this expression
4926 has side effects, show we don't know it to be a constant.
4927 Likewise if it's a pointer or aggregate type since in those
4928 case we only want literals, since those are only optimized
4929 when generating RTL, not later.
4930 And finally, if we are compiling an initializer, not code, we
4931 need to return a definite result now; there's not going to be any
4932 more optimization done. */
4933 if (TREE_SIDE_EFFECTS (arglist
) || cse_not_expected
4934 || AGGREGATE_TYPE_P (TREE_TYPE (arglist
))
4935 || POINTER_TYPE_P (TREE_TYPE (arglist
))
4937 return integer_zero_node
;
4942 /* Fold a call to __builtin_classify_type. */
4945 fold_builtin_classify_type (arglist
)
4949 return build_int_2 (no_type_class
, 0);
4951 return build_int_2 (type_to_class (TREE_TYPE (TREE_VALUE (arglist
))), 0);
4954 /* Fold a call to __builtin_inf or __builtin_huge_val. */
4957 fold_builtin_inf (type
, warn
)
4961 REAL_VALUE_TYPE real
;
4963 if (!MODE_HAS_INFINITIES (TYPE_MODE (type
)) && warn
)
4964 warning ("target format does not support infinity");
4967 return build_real (type
, real
);
4970 /* Fold a call to __builtin_nan or __builtin_nans. */
4973 fold_builtin_nan (arglist
, type
, quiet
)
4977 REAL_VALUE_TYPE real
;
4980 if (!validate_arglist (arglist
, POINTER_TYPE
, VOID_TYPE
))
4982 str
= c_getstr (TREE_VALUE (arglist
));
4986 if (!real_nan (&real
, str
, quiet
, TYPE_MODE (type
)))
4989 return build_real (type
, real
);
4992 /* EXP is assumed to me builtin call where truncation can be propagated
4993 across (for instance floor((double)f) == (double)floorf (f).
4994 Do the transformation. */
4996 fold_trunc_transparent_mathfn (exp
)
4999 tree fndecl
= TREE_OPERAND (TREE_OPERAND (exp
, 0), 0);
5000 tree arglist
= TREE_OPERAND (exp
, 1);
5001 enum built_in_function fcode
= DECL_FUNCTION_CODE (fndecl
);
5003 if (optimize
&& validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
5005 tree arg0
= strip_float_extensions (TREE_VALUE (arglist
));
5006 tree ftype
= TREE_TYPE (exp
);
5007 tree newtype
= TREE_TYPE (arg0
);
5010 if (TYPE_PRECISION (newtype
) < TYPE_PRECISION (ftype
)
5011 && (decl
= mathfn_built_in (newtype
, fcode
)))
5014 build_tree_list (NULL_TREE
, fold (convert (newtype
, arg0
)));
5015 return convert (ftype
,
5016 build_function_call_expr (decl
, arglist
));
5022 /* Used by constant folding to eliminate some builtin calls early. EXP is
5023 the CALL_EXPR of a call to a builtin function. */
5029 tree fndecl
= TREE_OPERAND (TREE_OPERAND (exp
, 0), 0);
5030 tree arglist
= TREE_OPERAND (exp
, 1);
5031 tree type
= TREE_TYPE (TREE_TYPE (fndecl
));
5033 if (DECL_BUILT_IN_CLASS (fndecl
) == BUILT_IN_MD
)
5036 switch (DECL_FUNCTION_CODE (fndecl
))
5038 case BUILT_IN_CONSTANT_P
:
5039 return fold_builtin_constant_p (arglist
);
5041 case BUILT_IN_CLASSIFY_TYPE
:
5042 return fold_builtin_classify_type (arglist
);
5044 case BUILT_IN_STRLEN
:
5045 if (validate_arglist (arglist
, POINTER_TYPE
, VOID_TYPE
))
5047 tree len
= c_strlen (TREE_VALUE (arglist
));
5050 /* Convert from the internal "sizetype" type to "size_t". */
5052 len
= convert (size_type_node
, len
);
5059 case BUILT_IN_SQRTF
:
5060 case BUILT_IN_SQRTL
:
5061 if (validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
5063 enum built_in_function fcode
;
5064 tree arg
= TREE_VALUE (arglist
);
5066 /* Optimize sqrt of constant value. */
5067 if (TREE_CODE (arg
) == REAL_CST
5068 && ! TREE_CONSTANT_OVERFLOW (arg
))
5070 REAL_VALUE_TYPE r
, x
;
5072 x
= TREE_REAL_CST (arg
);
5073 if (real_sqrt (&r
, TYPE_MODE (type
), &x
)
5074 || (!flag_trapping_math
&& !flag_errno_math
))
5075 return build_real (type
, r
);
5078 /* Optimize sqrt(exp(x)) = exp(x*0.5). */
5079 fcode
= builtin_mathfn_code (arg
);
5080 if (flag_unsafe_math_optimizations
5081 && (fcode
== BUILT_IN_EXP
5082 || fcode
== BUILT_IN_EXPF
5083 || fcode
== BUILT_IN_EXPL
))
5085 tree expfn
= TREE_OPERAND (TREE_OPERAND (arg
, 0), 0);
5086 arg
= fold (build (MULT_EXPR
, type
,
5087 TREE_VALUE (TREE_OPERAND (arg
, 1)),
5088 build_real (type
, dconsthalf
)));
5089 arglist
= build_tree_list (NULL_TREE
, arg
);
5090 return build_function_call_expr (expfn
, arglist
);
5093 /* Optimize sqrt(pow(x,y)) = pow(x,y*0.5). */
5094 if (flag_unsafe_math_optimizations
5095 && (fcode
== BUILT_IN_POW
5096 || fcode
== BUILT_IN_POWF
5097 || fcode
== BUILT_IN_POWL
))
5099 tree powfn
= TREE_OPERAND (TREE_OPERAND (arg
, 0), 0);
5100 tree arg0
= TREE_VALUE (TREE_OPERAND (arg
, 1));
5101 tree arg1
= TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg
, 1)));
5102 tree narg1
= fold (build (MULT_EXPR
, type
, arg1
,
5103 build_real (type
, dconsthalf
)));
5104 arglist
= tree_cons (NULL_TREE
, arg0
,
5105 build_tree_list (NULL_TREE
, narg1
));
5106 return build_function_call_expr (powfn
, arglist
);
5114 if (validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
5116 tree arg
= TREE_VALUE (arglist
);
5118 /* Optimize sin(0.0) = 0.0. */
5119 if (real_zerop (arg
))
5120 return build_real (type
, dconst0
);
5127 if (validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
5129 tree arg
= TREE_VALUE (arglist
);
5131 /* Optimize cos(0.0) = 1.0. */
5132 if (real_zerop (arg
))
5133 return build_real (type
, dconst1
);
5140 if (validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
5142 enum built_in_function fcode
;
5143 tree arg
= TREE_VALUE (arglist
);
5145 /* Optimize exp(0.0) = 1.0. */
5146 if (real_zerop (arg
))
5147 return build_real (type
, dconst1
);
5149 /* Optimize exp(log(x)) = x. */
5150 fcode
= builtin_mathfn_code (arg
);
5151 if (flag_unsafe_math_optimizations
5152 && (fcode
== BUILT_IN_LOG
5153 || fcode
== BUILT_IN_LOGF
5154 || fcode
== BUILT_IN_LOGL
))
5155 return TREE_VALUE (TREE_OPERAND (arg
, 1));
5162 if (validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
5164 enum built_in_function fcode
;
5165 tree arg
= TREE_VALUE (arglist
);
5167 /* Optimize log(1.0) = 0.0. */
5168 if (real_onep (arg
))
5169 return build_real (type
, dconst0
);
5171 /* Optimize log(exp(x)) = x. */
5172 fcode
= builtin_mathfn_code (arg
);
5173 if (flag_unsafe_math_optimizations
5174 && (fcode
== BUILT_IN_EXP
5175 || fcode
== BUILT_IN_EXPF
5176 || fcode
== BUILT_IN_EXPL
))
5177 return TREE_VALUE (TREE_OPERAND (arg
, 1));
5179 /* Optimize log(sqrt(x)) = log(x)*0.5. */
5180 if (flag_unsafe_math_optimizations
5181 && (fcode
== BUILT_IN_SQRT
5182 || fcode
== BUILT_IN_SQRTF
5183 || fcode
== BUILT_IN_SQRTL
))
5185 tree logfn
= build_function_call_expr (fndecl
,
5186 TREE_OPERAND (arg
, 1));
5187 return fold (build (MULT_EXPR
, type
, logfn
,
5188 build_real (type
, dconsthalf
)));
5191 /* Optimize log(pow(x,y)) = y*log(x). */
5192 if (flag_unsafe_math_optimizations
5193 && (fcode
== BUILT_IN_POW
5194 || fcode
== BUILT_IN_POWF
5195 || fcode
== BUILT_IN_POWL
))
5197 tree arg0
, arg1
, logfn
;
5199 arg0
= TREE_VALUE (TREE_OPERAND (arg
, 1));
5200 arg1
= TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg
, 1)));
5201 arglist
= build_tree_list (NULL_TREE
, arg0
);
5202 logfn
= build_function_call_expr (fndecl
, arglist
);
5203 return fold (build (MULT_EXPR
, type
, arg1
, logfn
));
5211 if (validate_arglist (arglist
, REAL_TYPE
, REAL_TYPE
, VOID_TYPE
))
5213 enum built_in_function fcode
;
5214 tree arg0
= TREE_VALUE (arglist
);
5215 tree arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
5217 /* Optimize pow(1.0,y) = 1.0. */
5218 if (real_onep (arg0
))
5219 return omit_one_operand (type
, build_real (type
, dconst1
), arg1
);
5221 if (TREE_CODE (arg1
) == REAL_CST
5222 && ! TREE_CONSTANT_OVERFLOW (arg1
))
5225 c
= TREE_REAL_CST (arg1
);
5227 /* Optimize pow(x,0.0) = 1.0. */
5228 if (REAL_VALUES_EQUAL (c
, dconst0
))
5229 return omit_one_operand (type
, build_real (type
, dconst1
),
5232 /* Optimize pow(x,1.0) = x. */
5233 if (REAL_VALUES_EQUAL (c
, dconst1
))
5236 /* Optimize pow(x,-1.0) = 1.0/x. */
5237 if (REAL_VALUES_EQUAL (c
, dconstm1
))
5238 return fold (build (RDIV_EXPR
, type
,
5239 build_real (type
, dconst1
),
5242 /* Optimize pow(x,2.0) = x*x. */
5243 if (REAL_VALUES_EQUAL (c
, dconst2
)
5244 && (*lang_hooks
.decls
.global_bindings_p
) () == 0
5245 && ! CONTAINS_PLACEHOLDER_P (arg0
))
5247 arg0
= save_expr (arg0
);
5248 return fold (build (MULT_EXPR
, type
, arg0
, arg0
));
5251 /* Optimize pow(x,-2.0) = 1.0/(x*x). */
5252 if (flag_unsafe_math_optimizations
5253 && REAL_VALUES_EQUAL (c
, dconstm2
)
5254 && (*lang_hooks
.decls
.global_bindings_p
) () == 0
5255 && ! CONTAINS_PLACEHOLDER_P (arg0
))
5257 arg0
= save_expr (arg0
);
5258 return fold (build (RDIV_EXPR
, type
,
5259 build_real (type
, dconst1
),
5260 fold (build (MULT_EXPR
, type
,
5264 /* Optimize pow(x,0.5) = sqrt(x). */
5265 if (flag_unsafe_math_optimizations
5266 && REAL_VALUES_EQUAL (c
, dconsthalf
))
5270 fcode
= DECL_FUNCTION_CODE (fndecl
);
5271 if (fcode
== BUILT_IN_POW
)
5272 sqrtfn
= implicit_built_in_decls
[BUILT_IN_SQRT
];
5273 else if (fcode
== BUILT_IN_POWF
)
5274 sqrtfn
= implicit_built_in_decls
[BUILT_IN_SQRTF
];
5275 else if (fcode
== BUILT_IN_POWL
)
5276 sqrtfn
= implicit_built_in_decls
[BUILT_IN_SQRTL
];
5280 if (sqrtfn
!= NULL_TREE
)
5282 tree arglist
= build_tree_list (NULL_TREE
, arg0
);
5283 return build_function_call_expr (sqrtfn
, arglist
);
5287 /* Attempt to evaluate pow at compile-time. */
5288 if (TREE_CODE (arg0
) == REAL_CST
5289 && ! TREE_CONSTANT_OVERFLOW (arg0
))
5291 REAL_VALUE_TYPE cint
;
5294 n
= real_to_integer(&c
);
5295 real_from_integer (&cint
, VOIDmode
, n
,
5297 if (real_identical (&c
, &cint
))
5302 x
= TREE_REAL_CST (arg0
);
5303 inexact
= real_powi (&x
, TYPE_MODE (type
), &x
, n
);
5304 if (flag_unsafe_math_optimizations
|| !inexact
)
5305 return build_real (type
, x
);
5310 /* Optimize pow(exp(x),y) = exp(x*y). */
5311 fcode
= builtin_mathfn_code (arg0
);
5312 if (flag_unsafe_math_optimizations
5313 && (fcode
== BUILT_IN_EXP
5314 || fcode
== BUILT_IN_EXPF
5315 || fcode
== BUILT_IN_EXPL
))
5317 tree expfn
= TREE_OPERAND (TREE_OPERAND (arg0
, 0), 0);
5318 tree arg
= TREE_VALUE (TREE_OPERAND (arg0
, 1));
5319 arg
= fold (build (MULT_EXPR
, type
, arg
, arg1
));
5320 arglist
= build_tree_list (NULL_TREE
, arg
);
5321 return build_function_call_expr (expfn
, arglist
);
5324 /* Optimize pow(sqrt(x),y) = pow(x,y*0.5). */
5325 if (flag_unsafe_math_optimizations
5326 && (fcode
== BUILT_IN_SQRT
5327 || fcode
== BUILT_IN_SQRTF
5328 || fcode
== BUILT_IN_SQRTL
))
5330 tree narg0
= TREE_VALUE (TREE_OPERAND (arg0
, 1));
5331 tree narg1
= fold (build (MULT_EXPR
, type
, arg1
,
5332 build_real (type
, dconsthalf
)));
5334 arglist
= tree_cons (NULL_TREE
, narg0
,
5335 build_tree_list (NULL_TREE
, narg1
));
5336 return build_function_call_expr (fndecl
, arglist
);
5339 /* Optimize pow(pow(x,y),z) = pow(x,y*z). */
5340 if (flag_unsafe_math_optimizations
5341 && (fcode
== BUILT_IN_POW
5342 || fcode
== BUILT_IN_POWF
5343 || fcode
== BUILT_IN_POWL
))
5345 tree arg00
= TREE_VALUE (TREE_OPERAND (arg0
, 1));
5346 tree arg01
= TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg0
, 1)));
5347 tree narg1
= fold (build (MULT_EXPR
, type
, arg01
, arg1
));
5348 arglist
= tree_cons (NULL_TREE
, arg00
,
5349 build_tree_list (NULL_TREE
, narg1
));
5350 return build_function_call_expr (fndecl
, arglist
);
5358 return fold_builtin_inf (type
, true);
5360 case BUILT_IN_HUGE_VAL
:
5361 case BUILT_IN_HUGE_VALF
:
5362 case BUILT_IN_HUGE_VALL
:
5363 return fold_builtin_inf (type
, false);
5368 return fold_builtin_nan (arglist
, type
, true);
5371 case BUILT_IN_NANSF
:
5372 case BUILT_IN_NANSL
:
5373 return fold_builtin_nan (arglist
, type
, false);
5375 case BUILT_IN_FLOOR
:
5376 case BUILT_IN_FLOORF
:
5377 case BUILT_IN_FLOORL
:
5379 case BUILT_IN_CEILF
:
5380 case BUILT_IN_CEILL
:
5381 case BUILT_IN_TRUNC
:
5382 case BUILT_IN_TRUNCF
:
5383 case BUILT_IN_TRUNCL
:
5384 case BUILT_IN_ROUND
:
5385 case BUILT_IN_ROUNDF
:
5386 case BUILT_IN_ROUNDL
:
5387 case BUILT_IN_NEARBYINT
:
5388 case BUILT_IN_NEARBYINTF
:
5389 case BUILT_IN_NEARBYINTL
:
5390 return fold_trunc_transparent_mathfn (exp
);
5399 /* Conveniently construct a function call expression. */
5402 build_function_call_expr (fn
, arglist
)
5407 call_expr
= build1 (ADDR_EXPR
, build_pointer_type (TREE_TYPE (fn
)), fn
);
5408 call_expr
= build (CALL_EXPR
, TREE_TYPE (TREE_TYPE (fn
)),
5409 call_expr
, arglist
);
5410 TREE_SIDE_EFFECTS (call_expr
) = 1;
5411 return fold (call_expr
);
5414 /* This function validates the types of a function call argument list
5415 represented as a tree chain of parameters against a specified list
5416 of tree_codes. If the last specifier is a 0, that represents an
5417 ellipses, otherwise the last specifier must be a VOID_TYPE. */
5420 validate_arglist (tree arglist
, ...)
5422 enum tree_code code
;
5426 va_start (ap
, arglist
);
5430 code
= va_arg (ap
, enum tree_code
);
5434 /* This signifies an ellipses, any further arguments are all ok. */
5438 /* This signifies an endlink, if no arguments remain, return
5439 true, otherwise return false. */
5443 /* If no parameters remain or the parameter's code does not
5444 match the specified code, return false. Otherwise continue
5445 checking any remaining arguments. */
5447 || code
!= TREE_CODE (TREE_TYPE (TREE_VALUE (arglist
))))
5451 arglist
= TREE_CHAIN (arglist
);
5455 /* We need gotos here since we can only have one VA_CLOSE in a
5463 /* Default version of target-specific builtin setup that does nothing. */
5466 default_init_builtins ()
5470 /* Default target-specific builtin expander that does nothing. */
5473 default_expand_builtin (exp
, target
, subtarget
, mode
, ignore
)
5474 tree exp ATTRIBUTE_UNUSED
;
5475 rtx target ATTRIBUTE_UNUSED
;
5476 rtx subtarget ATTRIBUTE_UNUSED
;
5477 enum machine_mode mode ATTRIBUTE_UNUSED
;
5478 int ignore ATTRIBUTE_UNUSED
;
5483 /* Instantiate all remaining CONSTANT_P_RTX nodes. */
5486 purge_builtin_constant_p ()
5488 rtx insn
, set
, arg
, new, note
;
5490 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
5492 && (set
= single_set (insn
)) != NULL_RTX
5493 && (GET_CODE (arg
= SET_SRC (set
)) == CONSTANT_P_RTX
5494 || (GET_CODE (arg
) == SUBREG
5495 && (GET_CODE (arg
= SUBREG_REG (arg
))
5496 == CONSTANT_P_RTX
))))
5498 arg
= XEXP (arg
, 0);
5499 new = CONSTANT_P (arg
) ? const1_rtx
: const0_rtx
;
5500 validate_change (insn
, &SET_SRC (set
), new, 0);
5502 /* Remove the REG_EQUAL note from the insn. */
5503 if ((note
= find_reg_note (insn
, REG_EQUAL
, NULL_RTX
)) != 0)
5504 remove_note (insn
, note
);
5508 /* Returns true is EXP represents data that would potentially reside
5509 in a readonly section. */
5512 readonly_data_expr (tree exp
)
5516 if (TREE_CODE (exp
) == ADDR_EXPR
)
5517 return decl_readonly_section (TREE_OPERAND (exp
, 0), 0);