1 /* Expand builtin functions.
2 Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3 1999, 2000, 2001, 2002 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) 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
];
78 static int get_pointer_alignment
PARAMS ((tree
, unsigned int));
79 static tree c_strlen
PARAMS ((tree
));
80 static const char *c_getstr
PARAMS ((tree
));
81 static rtx c_readstr
PARAMS ((const char *,
83 static int target_char_cast
PARAMS ((tree
, char *));
84 static rtx get_memory_rtx
PARAMS ((tree
));
85 static int apply_args_size
PARAMS ((void));
86 static int apply_result_size
PARAMS ((void));
87 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
88 static rtx result_vector
PARAMS ((int, rtx
));
90 static rtx expand_builtin_setjmp
PARAMS ((tree
, rtx
));
91 static void expand_builtin_prefetch
PARAMS ((tree
));
92 static rtx expand_builtin_apply_args
PARAMS ((void));
93 static rtx expand_builtin_apply_args_1
PARAMS ((void));
94 static rtx expand_builtin_apply
PARAMS ((rtx
, rtx
, rtx
));
95 static void expand_builtin_return
PARAMS ((rtx
));
96 static enum type_class type_to_class
PARAMS ((tree
));
97 static rtx expand_builtin_classify_type
PARAMS ((tree
));
98 static rtx expand_builtin_mathfn
PARAMS ((tree
, rtx
, rtx
));
99 static rtx expand_builtin_constant_p
PARAMS ((tree
));
100 static rtx expand_builtin_args_info
PARAMS ((tree
));
101 static rtx expand_builtin_next_arg
PARAMS ((tree
));
102 static rtx expand_builtin_va_start
PARAMS ((tree
));
103 static rtx expand_builtin_va_end
PARAMS ((tree
));
104 static rtx expand_builtin_va_copy
PARAMS ((tree
));
105 static rtx expand_builtin_memcmp
PARAMS ((tree
, tree
, rtx
,
107 static rtx expand_builtin_strcmp
PARAMS ((tree
, rtx
,
109 static rtx expand_builtin_strncmp
PARAMS ((tree
, rtx
,
111 static rtx builtin_memcpy_read_str
PARAMS ((PTR
, HOST_WIDE_INT
,
113 static rtx expand_builtin_strcat
PARAMS ((tree
, rtx
,
115 static rtx expand_builtin_strncat
PARAMS ((tree
, rtx
,
117 static rtx expand_builtin_strspn
PARAMS ((tree
, rtx
,
119 static rtx expand_builtin_strcspn
PARAMS ((tree
, rtx
,
121 static rtx expand_builtin_memcpy
PARAMS ((tree
, rtx
,
123 static rtx expand_builtin_strcpy
PARAMS ((tree
, rtx
,
125 static rtx builtin_strncpy_read_str
PARAMS ((PTR
, HOST_WIDE_INT
,
127 static rtx expand_builtin_strncpy
PARAMS ((tree
, rtx
,
129 static rtx builtin_memset_read_str
PARAMS ((PTR
, HOST_WIDE_INT
,
131 static rtx builtin_memset_gen_str
PARAMS ((PTR
, HOST_WIDE_INT
,
133 static rtx expand_builtin_memset
PARAMS ((tree
, rtx
,
135 static rtx expand_builtin_bzero
PARAMS ((tree
));
136 static rtx expand_builtin_strlen
PARAMS ((tree
, rtx
));
137 static rtx expand_builtin_strstr
PARAMS ((tree
, rtx
,
139 static rtx expand_builtin_strpbrk
PARAMS ((tree
, rtx
,
141 static rtx expand_builtin_strchr
PARAMS ((tree
, rtx
,
143 static rtx expand_builtin_strrchr
PARAMS ((tree
, rtx
,
145 static rtx expand_builtin_alloca
PARAMS ((tree
, rtx
));
146 static rtx expand_builtin_ffs
PARAMS ((tree
, rtx
, rtx
));
147 static rtx expand_builtin_frame_address
PARAMS ((tree
));
148 static rtx expand_builtin_fputs
PARAMS ((tree
, int, int));
149 static tree stabilize_va_list
PARAMS ((tree
, int));
150 static rtx expand_builtin_expect
PARAMS ((tree
, rtx
));
151 static tree fold_builtin_constant_p
PARAMS ((tree
));
152 static tree fold_builtin_classify_type
PARAMS ((tree
));
153 static tree fold_builtin_inf
PARAMS ((tree
, int));
154 static tree fold_builtin_nan
PARAMS ((tree
, tree
, int));
155 static int validate_arglist
PARAMS ((tree
, ...));
157 /* Return the alignment in bits of EXP, a pointer valued expression.
158 But don't return more than MAX_ALIGN no matter what.
159 The alignment returned is, by default, the alignment of the thing that
160 EXP points to. If it is not a POINTER_TYPE, 0 is returned.
162 Otherwise, look at the expression to see if we can do better, i.e., if the
163 expression is actually pointing at an object whose alignment is tighter. */
166 get_pointer_alignment (exp
, max_align
)
168 unsigned int max_align
;
170 unsigned int align
, inner
;
172 if (TREE_CODE (TREE_TYPE (exp
)) != POINTER_TYPE
)
175 align
= TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp
)));
176 align
= MIN (align
, max_align
);
180 switch (TREE_CODE (exp
))
184 case NON_LVALUE_EXPR
:
185 exp
= TREE_OPERAND (exp
, 0);
186 if (TREE_CODE (TREE_TYPE (exp
)) != POINTER_TYPE
)
189 inner
= TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp
)));
190 align
= MIN (inner
, max_align
);
194 /* If sum of pointer + int, restrict our maximum alignment to that
195 imposed by the integer. If not, we can't do any better than
197 if (! host_integerp (TREE_OPERAND (exp
, 1), 1))
200 while (((tree_low_cst (TREE_OPERAND (exp
, 1), 1))
201 & (max_align
/ BITS_PER_UNIT
- 1))
205 exp
= TREE_OPERAND (exp
, 0);
209 /* See what we are pointing at and look at its alignment. */
210 exp
= TREE_OPERAND (exp
, 0);
211 if (TREE_CODE (exp
) == FUNCTION_DECL
)
212 align
= FUNCTION_BOUNDARY
;
213 else if (DECL_P (exp
))
214 align
= DECL_ALIGN (exp
);
215 #ifdef CONSTANT_ALIGNMENT
216 else if (TREE_CODE_CLASS (TREE_CODE (exp
)) == 'c')
217 align
= CONSTANT_ALIGNMENT (exp
, align
);
219 return MIN (align
, max_align
);
227 /* Compute the length of a C string. TREE_STRING_LENGTH is not the right
228 way, because it could contain a zero byte in the middle.
229 TREE_STRING_LENGTH is the size of the character array, not the string.
231 The value returned is of type `ssizetype'.
233 Unfortunately, string_constant can't access the values of const char
234 arrays with initializers, so neither can we do so here. */
241 HOST_WIDE_INT offset
;
245 src
= string_constant (src
, &offset_node
);
249 max
= TREE_STRING_LENGTH (src
) - 1;
250 ptr
= TREE_STRING_POINTER (src
);
252 if (offset_node
&& TREE_CODE (offset_node
) != INTEGER_CST
)
254 /* If the string has an internal zero byte (e.g., "foo\0bar"), we can't
255 compute the offset to the following null if we don't know where to
256 start searching for it. */
259 for (i
= 0; i
< max
; i
++)
263 /* We don't know the starting offset, but we do know that the string
264 has no internal zero bytes. We can assume that the offset falls
265 within the bounds of the string; otherwise, the programmer deserves
266 what he gets. Subtract the offset from the length of the string,
267 and return that. This would perhaps not be valid if we were dealing
268 with named arrays in addition to literal string constants. */
270 return size_diffop (size_int (max
), offset_node
);
273 /* We have a known offset into the string. Start searching there for
274 a null character if we can represent it as a single HOST_WIDE_INT. */
275 if (offset_node
== 0)
277 else if (! host_integerp (offset_node
, 0))
280 offset
= tree_low_cst (offset_node
, 0);
282 /* If the offset is known to be out of bounds, warn, and call strlen at
284 if (offset
< 0 || offset
> max
)
286 warning ("offset outside bounds of constant string");
290 /* Use strlen to search for the first zero byte. Since any strings
291 constructed with build_string will have nulls appended, we win even
292 if we get handed something like (char[4])"abcd".
294 Since OFFSET is our starting index into the string, no further
295 calculation is needed. */
296 return ssize_int (strlen (ptr
+ offset
));
299 /* Return a char pointer for a C string if it is a string constant
300 or sum of string constant and integer constant. */
308 src
= string_constant (src
, &offset_node
);
312 if (offset_node
== 0)
313 return TREE_STRING_POINTER (src
);
314 else if (!host_integerp (offset_node
, 1)
315 || compare_tree_int (offset_node
, TREE_STRING_LENGTH (src
) - 1) > 0)
318 return TREE_STRING_POINTER (src
) + tree_low_cst (offset_node
, 1);
321 /* Return a CONST_INT or CONST_DOUBLE corresponding to target reading
322 GET_MODE_BITSIZE (MODE) bits from string constant STR. */
325 c_readstr (str
, mode
)
327 enum machine_mode mode
;
333 if (GET_MODE_CLASS (mode
) != MODE_INT
)
338 for (i
= 0; i
< GET_MODE_SIZE (mode
); i
++)
341 if (WORDS_BIG_ENDIAN
)
342 j
= GET_MODE_SIZE (mode
) - i
- 1;
343 if (BYTES_BIG_ENDIAN
!= WORDS_BIG_ENDIAN
344 && GET_MODE_SIZE (mode
) > UNITS_PER_WORD
)
345 j
= j
+ UNITS_PER_WORD
- 2 * (j
% UNITS_PER_WORD
) - 1;
347 if (j
> 2 * HOST_BITS_PER_WIDE_INT
)
350 ch
= (unsigned char) str
[i
];
351 c
[j
/ HOST_BITS_PER_WIDE_INT
] |= ch
<< (j
% HOST_BITS_PER_WIDE_INT
);
353 return immed_double_const (c
[0], c
[1], mode
);
356 /* Cast a target constant CST to target CHAR and if that value fits into
357 host char type, return zero and put that value into variable pointed by
361 target_char_cast (cst
, p
)
365 unsigned HOST_WIDE_INT val
, hostval
;
367 if (!host_integerp (cst
, 1)
368 || CHAR_TYPE_SIZE
> HOST_BITS_PER_WIDE_INT
)
371 val
= tree_low_cst (cst
, 1);
372 if (CHAR_TYPE_SIZE
< HOST_BITS_PER_WIDE_INT
)
373 val
&= (((unsigned HOST_WIDE_INT
) 1) << CHAR_TYPE_SIZE
) - 1;
376 if (HOST_BITS_PER_CHAR
< HOST_BITS_PER_WIDE_INT
)
377 hostval
&= (((unsigned HOST_WIDE_INT
) 1) << HOST_BITS_PER_CHAR
) - 1;
386 /* Given TEM, a pointer to a stack frame, follow the dynamic chain COUNT
387 times to get the address of either a higher stack frame, or a return
388 address located within it (depending on FNDECL_CODE). */
391 expand_builtin_return_addr (fndecl_code
, count
, tem
)
392 enum built_in_function fndecl_code
;
398 /* Some machines need special handling before we can access
399 arbitrary frames. For example, on the sparc, we must first flush
400 all register windows to the stack. */
401 #ifdef SETUP_FRAME_ADDRESSES
403 SETUP_FRAME_ADDRESSES ();
406 /* On the sparc, the return address is not in the frame, it is in a
407 register. There is no way to access it off of the current frame
408 pointer, but it can be accessed off the previous frame pointer by
409 reading the value from the register window save area. */
410 #ifdef RETURN_ADDR_IN_PREVIOUS_FRAME
411 if (fndecl_code
== BUILT_IN_RETURN_ADDRESS
)
415 /* Scan back COUNT frames to the specified frame. */
416 for (i
= 0; i
< count
; i
++)
418 /* Assume the dynamic chain pointer is in the word that the
419 frame address points to, unless otherwise specified. */
420 #ifdef DYNAMIC_CHAIN_ADDRESS
421 tem
= DYNAMIC_CHAIN_ADDRESS (tem
);
423 tem
= memory_address (Pmode
, tem
);
424 tem
= gen_rtx_MEM (Pmode
, tem
);
425 set_mem_alias_set (tem
, get_frame_alias_set ());
426 tem
= copy_to_reg (tem
);
429 /* For __builtin_frame_address, return what we've got. */
430 if (fndecl_code
== BUILT_IN_FRAME_ADDRESS
)
433 /* For __builtin_return_address, Get the return address from that
435 #ifdef RETURN_ADDR_RTX
436 tem
= RETURN_ADDR_RTX (count
, tem
);
438 tem
= memory_address (Pmode
,
439 plus_constant (tem
, GET_MODE_SIZE (Pmode
)));
440 tem
= gen_rtx_MEM (Pmode
, tem
);
441 set_mem_alias_set (tem
, get_frame_alias_set ());
446 /* Alias set used for setjmp buffer. */
447 static HOST_WIDE_INT setjmp_alias_set
= -1;
449 /* Construct the leading half of a __builtin_setjmp call. Control will
450 return to RECEIVER_LABEL. This is used directly by sjlj exception
454 expand_builtin_setjmp_setup (buf_addr
, receiver_label
)
458 enum machine_mode sa_mode
= STACK_SAVEAREA_MODE (SAVE_NONLOCAL
);
462 if (setjmp_alias_set
== -1)
463 setjmp_alias_set
= new_alias_set ();
465 #ifdef POINTERS_EXTEND_UNSIGNED
466 if (GET_MODE (buf_addr
) != Pmode
)
467 buf_addr
= convert_memory_address (Pmode
, buf_addr
);
470 buf_addr
= force_reg (Pmode
, force_operand (buf_addr
, NULL_RTX
));
474 /* We store the frame pointer and the address of receiver_label in
475 the buffer and use the rest of it for the stack save area, which
476 is machine-dependent. */
478 #ifndef BUILTIN_SETJMP_FRAME_VALUE
479 #define BUILTIN_SETJMP_FRAME_VALUE virtual_stack_vars_rtx
482 mem
= gen_rtx_MEM (Pmode
, buf_addr
);
483 set_mem_alias_set (mem
, setjmp_alias_set
);
484 emit_move_insn (mem
, BUILTIN_SETJMP_FRAME_VALUE
);
486 mem
= gen_rtx_MEM (Pmode
, plus_constant (buf_addr
, GET_MODE_SIZE (Pmode
))),
487 set_mem_alias_set (mem
, setjmp_alias_set
);
489 emit_move_insn (validize_mem (mem
),
490 force_reg (Pmode
, gen_rtx_LABEL_REF (Pmode
, receiver_label
)));
492 stack_save
= gen_rtx_MEM (sa_mode
,
493 plus_constant (buf_addr
,
494 2 * GET_MODE_SIZE (Pmode
)));
495 set_mem_alias_set (stack_save
, setjmp_alias_set
);
496 emit_stack_save (SAVE_NONLOCAL
, &stack_save
, NULL_RTX
);
498 /* If there is further processing to do, do it. */
499 #ifdef HAVE_builtin_setjmp_setup
500 if (HAVE_builtin_setjmp_setup
)
501 emit_insn (gen_builtin_setjmp_setup (buf_addr
));
504 /* Tell optimize_save_area_alloca that extra work is going to
505 need to go on during alloca. */
506 current_function_calls_setjmp
= 1;
508 /* Set this so all the registers get saved in our frame; we need to be
509 able to copy the saved values for any registers from frames we unwind. */
510 current_function_has_nonlocal_label
= 1;
513 /* Construct the trailing part of a __builtin_setjmp call.
514 This is used directly by sjlj exception handling code. */
517 expand_builtin_setjmp_receiver (receiver_label
)
518 rtx receiver_label ATTRIBUTE_UNUSED
;
520 /* Clobber the FP when we get here, so we have to make sure it's
521 marked as used by this function. */
522 emit_insn (gen_rtx_USE (VOIDmode
, hard_frame_pointer_rtx
));
524 /* Mark the static chain as clobbered here so life information
525 doesn't get messed up for it. */
526 emit_insn (gen_rtx_CLOBBER (VOIDmode
, static_chain_rtx
));
528 /* Now put in the code to restore the frame pointer, and argument
529 pointer, if needed. The code below is from expand_end_bindings
530 in stmt.c; see detailed documentation there. */
531 #ifdef HAVE_nonlocal_goto
532 if (! HAVE_nonlocal_goto
)
534 emit_move_insn (virtual_stack_vars_rtx
, hard_frame_pointer_rtx
);
536 #if ARG_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
537 if (fixed_regs
[ARG_POINTER_REGNUM
])
539 #ifdef ELIMINABLE_REGS
541 static const struct elims
{const int from
, to
;} elim_regs
[] = ELIMINABLE_REGS
;
543 for (i
= 0; i
< ARRAY_SIZE (elim_regs
); i
++)
544 if (elim_regs
[i
].from
== ARG_POINTER_REGNUM
545 && elim_regs
[i
].to
== HARD_FRAME_POINTER_REGNUM
)
548 if (i
== ARRAY_SIZE (elim_regs
))
551 /* Now restore our arg pointer from the address at which it
552 was saved in our stack frame. */
553 emit_move_insn (virtual_incoming_args_rtx
,
554 copy_to_reg (get_arg_pointer_save_area (cfun
)));
559 #ifdef HAVE_builtin_setjmp_receiver
560 if (HAVE_builtin_setjmp_receiver
)
561 emit_insn (gen_builtin_setjmp_receiver (receiver_label
));
564 #ifdef HAVE_nonlocal_goto_receiver
565 if (HAVE_nonlocal_goto_receiver
)
566 emit_insn (gen_nonlocal_goto_receiver ());
571 /* @@@ This is a kludge. Not all machine descriptions define a blockage
572 insn, but we must not allow the code we just generated to be reordered
573 by scheduling. Specifically, the update of the frame pointer must
574 happen immediately, not later. So emit an ASM_INPUT to act as blockage
576 emit_insn (gen_rtx_ASM_INPUT (VOIDmode
, ""));
579 /* __builtin_setjmp is passed a pointer to an array of five words (not
580 all will be used on all machines). It operates similarly to the C
581 library function of the same name, but is more efficient. Much of
582 the code below (and for longjmp) is copied from the handling of
585 NOTE: This is intended for use by GNAT and the exception handling
586 scheme in the compiler and will only work in the method used by
590 expand_builtin_setjmp (arglist
, target
)
594 rtx buf_addr
, next_lab
, cont_lab
;
596 if (!validate_arglist (arglist
, POINTER_TYPE
, VOID_TYPE
))
599 if (target
== 0 || GET_CODE (target
) != REG
600 || REGNO (target
) < FIRST_PSEUDO_REGISTER
)
601 target
= gen_reg_rtx (TYPE_MODE (integer_type_node
));
603 buf_addr
= expand_expr (TREE_VALUE (arglist
), NULL_RTX
, VOIDmode
, 0);
605 next_lab
= gen_label_rtx ();
606 cont_lab
= gen_label_rtx ();
608 expand_builtin_setjmp_setup (buf_addr
, next_lab
);
610 /* Set TARGET to zero and branch to the continue label. */
611 emit_move_insn (target
, const0_rtx
);
612 emit_jump_insn (gen_jump (cont_lab
));
614 emit_label (next_lab
);
616 expand_builtin_setjmp_receiver (next_lab
);
618 /* Set TARGET to one. */
619 emit_move_insn (target
, const1_rtx
);
620 emit_label (cont_lab
);
622 /* Tell flow about the strange goings on. Putting `next_lab' on
623 `nonlocal_goto_handler_labels' to indicates that function
624 calls may traverse the arc back to this label. */
626 current_function_has_nonlocal_label
= 1;
627 nonlocal_goto_handler_labels
628 = gen_rtx_EXPR_LIST (VOIDmode
, next_lab
, nonlocal_goto_handler_labels
);
633 /* __builtin_longjmp is passed a pointer to an array of five words (not
634 all will be used on all machines). It operates similarly to the C
635 library function of the same name, but is more efficient. Much of
636 the code below is copied from the handling of non-local gotos.
638 NOTE: This is intended for use by GNAT and the exception handling
639 scheme in the compiler and will only work in the method used by
643 expand_builtin_longjmp (buf_addr
, value
)
646 rtx fp
, lab
, stack
, insn
, last
;
647 enum machine_mode sa_mode
= STACK_SAVEAREA_MODE (SAVE_NONLOCAL
);
649 if (setjmp_alias_set
== -1)
650 setjmp_alias_set
= new_alias_set ();
652 #ifdef POINTERS_EXTEND_UNSIGNED
653 if (GET_MODE (buf_addr
) != Pmode
)
654 buf_addr
= convert_memory_address (Pmode
, buf_addr
);
657 buf_addr
= force_reg (Pmode
, buf_addr
);
659 /* We used to store value in static_chain_rtx, but that fails if pointers
660 are smaller than integers. We instead require that the user must pass
661 a second argument of 1, because that is what builtin_setjmp will
662 return. This also makes EH slightly more efficient, since we are no
663 longer copying around a value that we don't care about. */
664 if (value
!= const1_rtx
)
667 current_function_calls_longjmp
= 1;
669 last
= get_last_insn ();
670 #ifdef HAVE_builtin_longjmp
671 if (HAVE_builtin_longjmp
)
672 emit_insn (gen_builtin_longjmp (buf_addr
));
676 fp
= gen_rtx_MEM (Pmode
, buf_addr
);
677 lab
= gen_rtx_MEM (Pmode
, plus_constant (buf_addr
,
678 GET_MODE_SIZE (Pmode
)));
680 stack
= gen_rtx_MEM (sa_mode
, plus_constant (buf_addr
,
681 2 * GET_MODE_SIZE (Pmode
)));
682 set_mem_alias_set (fp
, setjmp_alias_set
);
683 set_mem_alias_set (lab
, setjmp_alias_set
);
684 set_mem_alias_set (stack
, setjmp_alias_set
);
686 /* Pick up FP, label, and SP from the block and jump. This code is
687 from expand_goto in stmt.c; see there for detailed comments. */
688 #if HAVE_nonlocal_goto
689 if (HAVE_nonlocal_goto
)
690 /* We have to pass a value to the nonlocal_goto pattern that will
691 get copied into the static_chain pointer, but it does not matter
692 what that value is, because builtin_setjmp does not use it. */
693 emit_insn (gen_nonlocal_goto (value
, lab
, stack
, fp
));
697 lab
= copy_to_reg (lab
);
699 emit_move_insn (hard_frame_pointer_rtx
, fp
);
700 emit_stack_restore (SAVE_NONLOCAL
, stack
, NULL_RTX
);
702 emit_insn (gen_rtx_USE (VOIDmode
, hard_frame_pointer_rtx
));
703 emit_insn (gen_rtx_USE (VOIDmode
, stack_pointer_rtx
));
704 emit_indirect_jump (lab
);
708 /* Search backwards and mark the jump insn as a non-local goto.
709 Note that this precludes the use of __builtin_longjmp to a
710 __builtin_setjmp target in the same function. However, we've
711 already cautioned the user that these functions are for
712 internal exception handling use only. */
713 for (insn
= get_last_insn (); insn
; insn
= PREV_INSN (insn
))
717 if (GET_CODE (insn
) == JUMP_INSN
)
719 REG_NOTES (insn
) = alloc_EXPR_LIST (REG_NON_LOCAL_GOTO
, const0_rtx
,
723 else if (GET_CODE (insn
) == CALL_INSN
)
728 /* Expand a call to __builtin_prefetch. For a target that does not support
729 data prefetch, evaluate the memory address argument in case it has side
733 expand_builtin_prefetch (arglist
)
736 tree arg0
, arg1
, arg2
;
739 if (!validate_arglist (arglist
, POINTER_TYPE
, 0))
742 arg0
= TREE_VALUE (arglist
);
743 /* Arguments 1 and 2 are optional; argument 1 (read/write) defaults to
744 zero (read) and argument 2 (locality) defaults to 3 (high degree of
746 if (TREE_CHAIN (arglist
))
748 arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
749 if (TREE_CHAIN (TREE_CHAIN (arglist
)))
750 arg2
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
752 arg2
= build_int_2 (3, 0);
756 arg1
= integer_zero_node
;
757 arg2
= build_int_2 (3, 0);
760 /* Argument 0 is an address. */
761 op0
= expand_expr (arg0
, NULL_RTX
, Pmode
, EXPAND_NORMAL
);
763 /* Argument 1 (read/write flag) must be a compile-time constant int. */
764 if (TREE_CODE (arg1
) != INTEGER_CST
)
766 error ("second arg to `__builtin_prefetch' must be a constant");
767 arg1
= integer_zero_node
;
769 op1
= expand_expr (arg1
, NULL_RTX
, VOIDmode
, 0);
770 /* Argument 1 must be either zero or one. */
771 if (INTVAL (op1
) != 0 && INTVAL (op1
) != 1)
773 warning ("invalid second arg to __builtin_prefetch; using zero");
777 /* Argument 2 (locality) must be a compile-time constant int. */
778 if (TREE_CODE (arg2
) != INTEGER_CST
)
780 error ("third arg to `__builtin_prefetch' must be a constant");
781 arg2
= integer_zero_node
;
783 op2
= expand_expr (arg2
, NULL_RTX
, VOIDmode
, 0);
784 /* Argument 2 must be 0, 1, 2, or 3. */
785 if (INTVAL (op2
) < 0 || INTVAL (op2
) > 3)
787 warning ("invalid third arg to __builtin_prefetch; using zero");
794 if ((! (*insn_data
[(int) CODE_FOR_prefetch
].operand
[0].predicate
)
796 insn_data
[(int) CODE_FOR_prefetch
].operand
[0].mode
))
797 || (GET_MODE(op0
) != Pmode
))
799 #ifdef POINTERS_EXTEND_UNSIGNED
800 if (GET_MODE(op0
) != Pmode
)
801 op0
= convert_memory_address (Pmode
, op0
);
803 op0
= force_reg (Pmode
, op0
);
805 emit_insn (gen_prefetch (op0
, op1
, op2
));
809 op0
= protect_from_queue (op0
, 0);
810 /* Don't do anything with direct references to volatile memory, but
811 generate code to handle other side effects. */
812 if (GET_CODE (op0
) != MEM
&& side_effects_p (op0
))
816 /* Get a MEM rtx for expression EXP which is the address of an operand
817 to be used to be used in a string instruction (cmpstrsi, movstrsi, ..). */
823 rtx addr
= expand_expr (exp
, NULL_RTX
, ptr_mode
, EXPAND_SUM
);
826 #ifdef POINTERS_EXTEND_UNSIGNED
827 if (GET_MODE (addr
) != Pmode
)
828 addr
= convert_memory_address (Pmode
, addr
);
831 mem
= gen_rtx_MEM (BLKmode
, memory_address (BLKmode
, addr
));
833 /* Get an expression we can use to find the attributes to assign to MEM.
834 If it is an ADDR_EXPR, use the operand. Otherwise, dereference it if
835 we can. First remove any nops. */
836 while ((TREE_CODE (exp
) == NOP_EXPR
|| TREE_CODE (exp
) == CONVERT_EXPR
837 || TREE_CODE (exp
) == NON_LVALUE_EXPR
)
838 && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (exp
, 0))))
839 exp
= TREE_OPERAND (exp
, 0);
841 if (TREE_CODE (exp
) == ADDR_EXPR
)
843 exp
= TREE_OPERAND (exp
, 0);
844 set_mem_attributes (mem
, exp
, 0);
846 else if (POINTER_TYPE_P (TREE_TYPE (exp
)))
848 exp
= build1 (INDIRECT_REF
, TREE_TYPE (TREE_TYPE (exp
)), exp
);
849 /* memcpy, memset and other builtin stringops can alias with anything. */
850 set_mem_alias_set (mem
, 0);
856 /* Built-in functions to perform an untyped call and return. */
858 /* For each register that may be used for calling a function, this
859 gives a mode used to copy the register's value. VOIDmode indicates
860 the register is not used for calling a function. If the machine
861 has register windows, this gives only the outbound registers.
862 INCOMING_REGNO gives the corresponding inbound register. */
863 static enum machine_mode apply_args_mode
[FIRST_PSEUDO_REGISTER
];
865 /* For each register that may be used for returning values, this gives
866 a mode used to copy the register's value. VOIDmode indicates the
867 register is not used for returning values. If the machine has
868 register windows, this gives only the outbound registers.
869 INCOMING_REGNO gives the corresponding inbound register. */
870 static enum machine_mode apply_result_mode
[FIRST_PSEUDO_REGISTER
];
872 /* For each register that may be used for calling a function, this
873 gives the offset of that register into the block returned by
874 __builtin_apply_args. 0 indicates that the register is not
875 used for calling a function. */
876 static int apply_args_reg_offset
[FIRST_PSEUDO_REGISTER
];
878 /* Return the offset of register REGNO into the block returned by
879 __builtin_apply_args. This is not declared static, since it is
880 needed in objc-act.c. */
883 apply_args_register_offset (regno
)
888 /* Arguments are always put in outgoing registers (in the argument
889 block) if such make sense. */
890 #ifdef OUTGOING_REGNO
891 regno
= OUTGOING_REGNO (regno
);
893 return apply_args_reg_offset
[regno
];
896 /* Return the size required for the block returned by __builtin_apply_args,
897 and initialize apply_args_mode. */
902 static int size
= -1;
905 enum machine_mode mode
;
907 /* The values computed by this function never change. */
910 /* The first value is the incoming arg-pointer. */
911 size
= GET_MODE_SIZE (Pmode
);
913 /* The second value is the structure value address unless this is
914 passed as an "invisible" first argument. */
915 if (struct_value_rtx
)
916 size
+= GET_MODE_SIZE (Pmode
);
918 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
919 if (FUNCTION_ARG_REGNO_P (regno
))
921 /* Search for the proper mode for copying this register's
922 value. I'm not sure this is right, but it works so far. */
923 enum machine_mode best_mode
= VOIDmode
;
925 for (mode
= GET_CLASS_NARROWEST_MODE (MODE_INT
);
927 mode
= GET_MODE_WIDER_MODE (mode
))
928 if (HARD_REGNO_MODE_OK (regno
, mode
)
929 && HARD_REGNO_NREGS (regno
, mode
) == 1)
932 if (best_mode
== VOIDmode
)
933 for (mode
= GET_CLASS_NARROWEST_MODE (MODE_FLOAT
);
935 mode
= GET_MODE_WIDER_MODE (mode
))
936 if (HARD_REGNO_MODE_OK (regno
, mode
)
937 && have_insn_for (SET
, mode
))
940 if (best_mode
== VOIDmode
)
941 for (mode
= GET_CLASS_NARROWEST_MODE (MODE_VECTOR_FLOAT
);
943 mode
= GET_MODE_WIDER_MODE (mode
))
944 if (HARD_REGNO_MODE_OK (regno
, mode
)
945 && have_insn_for (SET
, mode
))
948 if (best_mode
== VOIDmode
)
949 for (mode
= GET_CLASS_NARROWEST_MODE (MODE_VECTOR_INT
);
951 mode
= GET_MODE_WIDER_MODE (mode
))
952 if (HARD_REGNO_MODE_OK (regno
, mode
)
953 && have_insn_for (SET
, mode
))
957 if (mode
== VOIDmode
)
960 align
= GET_MODE_ALIGNMENT (mode
) / BITS_PER_UNIT
;
961 if (size
% align
!= 0)
962 size
= CEIL (size
, align
) * align
;
963 apply_args_reg_offset
[regno
] = size
;
964 size
+= GET_MODE_SIZE (mode
);
965 apply_args_mode
[regno
] = mode
;
969 apply_args_mode
[regno
] = VOIDmode
;
970 apply_args_reg_offset
[regno
] = 0;
976 /* Return the size required for the block returned by __builtin_apply,
977 and initialize apply_result_mode. */
982 static int size
= -1;
984 enum machine_mode mode
;
986 /* The values computed by this function never change. */
991 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
992 if (FUNCTION_VALUE_REGNO_P (regno
))
994 /* Search for the proper mode for copying this register's
995 value. I'm not sure this is right, but it works so far. */
996 enum machine_mode best_mode
= VOIDmode
;
998 for (mode
= GET_CLASS_NARROWEST_MODE (MODE_INT
);
1000 mode
= GET_MODE_WIDER_MODE (mode
))
1001 if (HARD_REGNO_MODE_OK (regno
, mode
))
1004 if (best_mode
== VOIDmode
)
1005 for (mode
= GET_CLASS_NARROWEST_MODE (MODE_FLOAT
);
1007 mode
= GET_MODE_WIDER_MODE (mode
))
1008 if (HARD_REGNO_MODE_OK (regno
, mode
)
1009 && have_insn_for (SET
, mode
))
1012 if (best_mode
== VOIDmode
)
1013 for (mode
= GET_CLASS_NARROWEST_MODE (MODE_VECTOR_FLOAT
);
1015 mode
= GET_MODE_WIDER_MODE (mode
))
1016 if (HARD_REGNO_MODE_OK (regno
, mode
)
1017 && have_insn_for (SET
, mode
))
1020 if (best_mode
== VOIDmode
)
1021 for (mode
= GET_CLASS_NARROWEST_MODE (MODE_VECTOR_INT
);
1023 mode
= GET_MODE_WIDER_MODE (mode
))
1024 if (HARD_REGNO_MODE_OK (regno
, mode
)
1025 && have_insn_for (SET
, mode
))
1029 if (mode
== VOIDmode
)
1032 align
= GET_MODE_ALIGNMENT (mode
) / BITS_PER_UNIT
;
1033 if (size
% align
!= 0)
1034 size
= CEIL (size
, align
) * align
;
1035 size
+= GET_MODE_SIZE (mode
);
1036 apply_result_mode
[regno
] = mode
;
1039 apply_result_mode
[regno
] = VOIDmode
;
1041 /* Allow targets that use untyped_call and untyped_return to override
1042 the size so that machine-specific information can be stored here. */
1043 #ifdef APPLY_RESULT_SIZE
1044 size
= APPLY_RESULT_SIZE
;
1050 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
1051 /* Create a vector describing the result block RESULT. If SAVEP is true,
1052 the result block is used to save the values; otherwise it is used to
1053 restore the values. */
1056 result_vector (savep
, result
)
1060 int regno
, size
, align
, nelts
;
1061 enum machine_mode mode
;
1063 rtx
*savevec
= (rtx
*) alloca (FIRST_PSEUDO_REGISTER
* sizeof (rtx
));
1066 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
1067 if ((mode
= apply_result_mode
[regno
]) != VOIDmode
)
1069 align
= GET_MODE_ALIGNMENT (mode
) / BITS_PER_UNIT
;
1070 if (size
% align
!= 0)
1071 size
= CEIL (size
, align
) * align
;
1072 reg
= gen_rtx_REG (mode
, savep
? regno
: INCOMING_REGNO (regno
));
1073 mem
= adjust_address (result
, mode
, size
);
1074 savevec
[nelts
++] = (savep
1075 ? gen_rtx_SET (VOIDmode
, mem
, reg
)
1076 : gen_rtx_SET (VOIDmode
, reg
, mem
));
1077 size
+= GET_MODE_SIZE (mode
);
1079 return gen_rtx_PARALLEL (VOIDmode
, gen_rtvec_v (nelts
, savevec
));
1081 #endif /* HAVE_untyped_call or HAVE_untyped_return */
1083 /* Save the state required to perform an untyped call with the same
1084 arguments as were passed to the current function. */
1087 expand_builtin_apply_args_1 ()
1090 int size
, align
, regno
;
1091 enum machine_mode mode
;
1093 /* Create a block where the arg-pointer, structure value address,
1094 and argument registers can be saved. */
1095 registers
= assign_stack_local (BLKmode
, apply_args_size (), -1);
1097 /* Walk past the arg-pointer and structure value address. */
1098 size
= GET_MODE_SIZE (Pmode
);
1099 if (struct_value_rtx
)
1100 size
+= GET_MODE_SIZE (Pmode
);
1102 /* Save each register used in calling a function to the block. */
1103 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
1104 if ((mode
= apply_args_mode
[regno
]) != VOIDmode
)
1108 align
= GET_MODE_ALIGNMENT (mode
) / BITS_PER_UNIT
;
1109 if (size
% align
!= 0)
1110 size
= CEIL (size
, align
) * align
;
1112 tem
= gen_rtx_REG (mode
, INCOMING_REGNO (regno
));
1114 emit_move_insn (adjust_address (registers
, mode
, size
), tem
);
1115 size
+= GET_MODE_SIZE (mode
);
1118 /* Save the arg pointer to the block. */
1119 emit_move_insn (adjust_address (registers
, Pmode
, 0),
1120 copy_to_reg (virtual_incoming_args_rtx
));
1121 size
= GET_MODE_SIZE (Pmode
);
1123 /* Save the structure value address unless this is passed as an
1124 "invisible" first argument. */
1125 if (struct_value_incoming_rtx
)
1127 emit_move_insn (adjust_address (registers
, Pmode
, size
),
1128 copy_to_reg (struct_value_incoming_rtx
));
1129 size
+= GET_MODE_SIZE (Pmode
);
1132 /* Return the address of the block. */
1133 return copy_addr_to_reg (XEXP (registers
, 0));
1136 /* __builtin_apply_args returns block of memory allocated on
1137 the stack into which is stored the arg pointer, structure
1138 value address, static chain, and all the registers that might
1139 possibly be used in performing a function call. The code is
1140 moved to the start of the function so the incoming values are
1144 expand_builtin_apply_args ()
1146 /* Don't do __builtin_apply_args more than once in a function.
1147 Save the result of the first call and reuse it. */
1148 if (apply_args_value
!= 0)
1149 return apply_args_value
;
1151 /* When this function is called, it means that registers must be
1152 saved on entry to this function. So we migrate the
1153 call to the first insn of this function. */
1158 temp
= expand_builtin_apply_args_1 ();
1162 apply_args_value
= temp
;
1164 /* Put the insns after the NOTE that starts the function.
1165 If this is inside a start_sequence, make the outer-level insn
1166 chain current, so the code is placed at the start of the
1168 push_topmost_sequence ();
1169 emit_insn_before (seq
, NEXT_INSN (get_insns ()));
1170 pop_topmost_sequence ();
1175 /* Perform an untyped call and save the state required to perform an
1176 untyped return of whatever value was returned by the given function. */
1179 expand_builtin_apply (function
, arguments
, argsize
)
1180 rtx function
, arguments
, argsize
;
1182 int size
, align
, regno
;
1183 enum machine_mode mode
;
1184 rtx incoming_args
, result
, reg
, dest
, src
, call_insn
;
1185 rtx old_stack_level
= 0;
1186 rtx call_fusage
= 0;
1188 #ifdef POINTERS_EXTEND_UNSIGNED
1189 if (GET_MODE (arguments
) != Pmode
)
1190 arguments
= convert_memory_address (Pmode
, arguments
);
1193 /* Create a block where the return registers can be saved. */
1194 result
= assign_stack_local (BLKmode
, apply_result_size (), -1);
1196 /* Fetch the arg pointer from the ARGUMENTS block. */
1197 incoming_args
= gen_reg_rtx (Pmode
);
1198 emit_move_insn (incoming_args
, gen_rtx_MEM (Pmode
, arguments
));
1199 #ifndef STACK_GROWS_DOWNWARD
1200 incoming_args
= expand_simple_binop (Pmode
, MINUS
, incoming_args
, argsize
,
1201 incoming_args
, 0, OPTAB_LIB_WIDEN
);
1204 /* Perform postincrements before actually calling the function. */
1207 /* Push a new argument block and copy the arguments. Do not allow
1208 the (potential) memcpy call below to interfere with our stack
1210 do_pending_stack_adjust ();
1213 /* Save the stack with nonlocal if available */
1214 #ifdef HAVE_save_stack_nonlocal
1215 if (HAVE_save_stack_nonlocal
)
1216 emit_stack_save (SAVE_NONLOCAL
, &old_stack_level
, NULL_RTX
);
1219 emit_stack_save (SAVE_BLOCK
, &old_stack_level
, NULL_RTX
);
1221 /* Push a block of memory onto the stack to store the memory arguments.
1222 Save the address in a register, and copy the memory arguments. ??? I
1223 haven't figured out how the calling convention macros effect this,
1224 but it's likely that the source and/or destination addresses in
1225 the block copy will need updating in machine specific ways. */
1226 dest
= allocate_dynamic_stack_space (argsize
, 0, BITS_PER_UNIT
);
1227 dest
= gen_rtx_MEM (BLKmode
, dest
);
1228 set_mem_align (dest
, PARM_BOUNDARY
);
1229 src
= gen_rtx_MEM (BLKmode
, incoming_args
);
1230 set_mem_align (src
, PARM_BOUNDARY
);
1231 emit_block_move (dest
, src
, argsize
, BLOCK_OP_NORMAL
);
1233 /* Refer to the argument block. */
1235 arguments
= gen_rtx_MEM (BLKmode
, arguments
);
1236 set_mem_align (arguments
, PARM_BOUNDARY
);
1238 /* Walk past the arg-pointer and structure value address. */
1239 size
= GET_MODE_SIZE (Pmode
);
1240 if (struct_value_rtx
)
1241 size
+= GET_MODE_SIZE (Pmode
);
1243 /* Restore each of the registers previously saved. Make USE insns
1244 for each of these registers for use in making the call. */
1245 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
1246 if ((mode
= apply_args_mode
[regno
]) != VOIDmode
)
1248 align
= GET_MODE_ALIGNMENT (mode
) / BITS_PER_UNIT
;
1249 if (size
% align
!= 0)
1250 size
= CEIL (size
, align
) * align
;
1251 reg
= gen_rtx_REG (mode
, regno
);
1252 emit_move_insn (reg
, adjust_address (arguments
, mode
, size
));
1253 use_reg (&call_fusage
, reg
);
1254 size
+= GET_MODE_SIZE (mode
);
1257 /* Restore the structure value address unless this is passed as an
1258 "invisible" first argument. */
1259 size
= GET_MODE_SIZE (Pmode
);
1260 if (struct_value_rtx
)
1262 rtx value
= gen_reg_rtx (Pmode
);
1263 emit_move_insn (value
, adjust_address (arguments
, Pmode
, size
));
1264 emit_move_insn (struct_value_rtx
, value
);
1265 if (GET_CODE (struct_value_rtx
) == REG
)
1266 use_reg (&call_fusage
, struct_value_rtx
);
1267 size
+= GET_MODE_SIZE (Pmode
);
1270 /* All arguments and registers used for the call are set up by now! */
1271 function
= prepare_call_address (function
, NULL_TREE
, &call_fusage
, 0, 0);
1273 /* Ensure address is valid. SYMBOL_REF is already valid, so no need,
1274 and we don't want to load it into a register as an optimization,
1275 because prepare_call_address already did it if it should be done. */
1276 if (GET_CODE (function
) != SYMBOL_REF
)
1277 function
= memory_address (FUNCTION_MODE
, function
);
1279 /* Generate the actual call instruction and save the return value. */
1280 #ifdef HAVE_untyped_call
1281 if (HAVE_untyped_call
)
1282 emit_call_insn (gen_untyped_call (gen_rtx_MEM (FUNCTION_MODE
, function
),
1283 result
, result_vector (1, result
)));
1286 #ifdef HAVE_call_value
1287 if (HAVE_call_value
)
1291 /* Locate the unique return register. It is not possible to
1292 express a call that sets more than one return register using
1293 call_value; use untyped_call for that. In fact, untyped_call
1294 only needs to save the return registers in the given block. */
1295 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
1296 if ((mode
= apply_result_mode
[regno
]) != VOIDmode
)
1299 abort (); /* HAVE_untyped_call required. */
1300 valreg
= gen_rtx_REG (mode
, regno
);
1303 emit_call_insn (GEN_CALL_VALUE (valreg
,
1304 gen_rtx_MEM (FUNCTION_MODE
, function
),
1305 const0_rtx
, NULL_RTX
, const0_rtx
));
1307 emit_move_insn (adjust_address (result
, GET_MODE (valreg
), 0), valreg
);
1313 /* Find the CALL insn we just emitted. */
1314 for (call_insn
= get_last_insn ();
1315 call_insn
&& GET_CODE (call_insn
) != CALL_INSN
;
1316 call_insn
= PREV_INSN (call_insn
))
1322 /* Put the register usage information on the CALL. If there is already
1323 some usage information, put ours at the end. */
1324 if (CALL_INSN_FUNCTION_USAGE (call_insn
))
1328 for (link
= CALL_INSN_FUNCTION_USAGE (call_insn
); XEXP (link
, 1) != 0;
1329 link
= XEXP (link
, 1))
1332 XEXP (link
, 1) = call_fusage
;
1335 CALL_INSN_FUNCTION_USAGE (call_insn
) = call_fusage
;
1337 /* Restore the stack. */
1338 #ifdef HAVE_save_stack_nonlocal
1339 if (HAVE_save_stack_nonlocal
)
1340 emit_stack_restore (SAVE_NONLOCAL
, old_stack_level
, NULL_RTX
);
1343 emit_stack_restore (SAVE_BLOCK
, old_stack_level
, NULL_RTX
);
1347 /* Return the address of the result block. */
1348 return copy_addr_to_reg (XEXP (result
, 0));
1351 /* Perform an untyped return. */
1354 expand_builtin_return (result
)
1357 int size
, align
, regno
;
1358 enum machine_mode mode
;
1360 rtx call_fusage
= 0;
1362 #ifdef POINTERS_EXTEND_UNSIGNED
1363 if (GET_MODE (result
) != Pmode
)
1364 result
= convert_memory_address (Pmode
, result
);
1367 apply_result_size ();
1368 result
= gen_rtx_MEM (BLKmode
, result
);
1370 #ifdef HAVE_untyped_return
1371 if (HAVE_untyped_return
)
1373 emit_jump_insn (gen_untyped_return (result
, result_vector (0, result
)));
1379 /* Restore the return value and note that each value is used. */
1381 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
1382 if ((mode
= apply_result_mode
[regno
]) != VOIDmode
)
1384 align
= GET_MODE_ALIGNMENT (mode
) / BITS_PER_UNIT
;
1385 if (size
% align
!= 0)
1386 size
= CEIL (size
, align
) * align
;
1387 reg
= gen_rtx_REG (mode
, INCOMING_REGNO (regno
));
1388 emit_move_insn (reg
, adjust_address (result
, mode
, size
));
1390 push_to_sequence (call_fusage
);
1391 emit_insn (gen_rtx_USE (VOIDmode
, reg
));
1392 call_fusage
= get_insns ();
1394 size
+= GET_MODE_SIZE (mode
);
1397 /* Put the USE insns before the return. */
1398 emit_insn (call_fusage
);
1400 /* Return whatever values was restored by jumping directly to the end
1402 expand_null_return ();
1405 /* Used by expand_builtin_classify_type and fold_builtin_classify_type. */
1407 static enum type_class
1408 type_to_class (type
)
1411 switch (TREE_CODE (type
))
1413 case VOID_TYPE
: return void_type_class
;
1414 case INTEGER_TYPE
: return integer_type_class
;
1415 case CHAR_TYPE
: return char_type_class
;
1416 case ENUMERAL_TYPE
: return enumeral_type_class
;
1417 case BOOLEAN_TYPE
: return boolean_type_class
;
1418 case POINTER_TYPE
: return pointer_type_class
;
1419 case REFERENCE_TYPE
: return reference_type_class
;
1420 case OFFSET_TYPE
: return offset_type_class
;
1421 case REAL_TYPE
: return real_type_class
;
1422 case COMPLEX_TYPE
: return complex_type_class
;
1423 case FUNCTION_TYPE
: return function_type_class
;
1424 case METHOD_TYPE
: return method_type_class
;
1425 case RECORD_TYPE
: return record_type_class
;
1427 case QUAL_UNION_TYPE
: return union_type_class
;
1428 case ARRAY_TYPE
: return (TYPE_STRING_FLAG (type
)
1429 ? string_type_class
: array_type_class
);
1430 case SET_TYPE
: return set_type_class
;
1431 case FILE_TYPE
: return file_type_class
;
1432 case LANG_TYPE
: return lang_type_class
;
1433 default: return no_type_class
;
1437 /* Expand a call to __builtin_classify_type with arguments found in
1441 expand_builtin_classify_type (arglist
)
1445 return GEN_INT (type_to_class (TREE_TYPE (TREE_VALUE (arglist
))));
1446 return GEN_INT (no_type_class
);
1449 /* Expand expression EXP, which is a call to __builtin_constant_p. */
1452 expand_builtin_constant_p (exp
)
1455 tree arglist
= TREE_OPERAND (exp
, 1);
1456 enum machine_mode value_mode
= TYPE_MODE (TREE_TYPE (exp
));
1461 arglist
= TREE_VALUE (arglist
);
1463 /* We have taken care of the easy cases during constant folding. This
1464 case is not obvious, so emit (constant_p_rtx (ARGLIST)) and let CSE get a
1465 chance to see if it can deduce whether ARGLIST is constant. */
1467 tmp
= expand_expr (arglist
, NULL_RTX
, VOIDmode
, 0);
1468 tmp
= gen_rtx_CONSTANT_P_RTX (value_mode
, tmp
);
1472 /* Expand a call to one of the builtin math functions (sin, cos, or sqrt).
1473 Return 0 if a normal call should be emitted rather than expanding the
1474 function in-line. EXP is the expression that is a call to the builtin
1475 function; if convenient, the result should be placed in TARGET.
1476 SUBTARGET may be used as the target for computing one of EXP's operands. */
1479 expand_builtin_mathfn (exp
, target
, subtarget
)
1481 rtx target
, subtarget
;
1483 optab builtin_optab
;
1485 tree fndecl
= TREE_OPERAND (TREE_OPERAND (exp
, 0), 0);
1486 tree arglist
= TREE_OPERAND (exp
, 1);
1487 enum machine_mode argmode
;
1488 bool errno_set
= true;
1490 if (!validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
1493 /* Stabilize and compute the argument. */
1494 if (TREE_CODE (TREE_VALUE (arglist
)) != VAR_DECL
1495 && TREE_CODE (TREE_VALUE (arglist
)) != PARM_DECL
)
1497 exp
= copy_node (exp
);
1498 TREE_OPERAND (exp
, 1) = arglist
;
1499 /* Wrap the computation of the argument in a SAVE_EXPR. That
1500 way, if we need to expand the argument again (as in the
1501 flag_errno_math case below where we cannot directly set
1502 errno), we will not perform side-effects more than once.
1503 Note that here we're mutating the original EXP as well as the
1504 copy; that's the right thing to do in case the original EXP
1505 is expanded later. */
1506 TREE_VALUE (arglist
) = save_expr (TREE_VALUE (arglist
));
1507 arglist
= copy_node (arglist
);
1509 op0
= expand_expr (TREE_VALUE (arglist
), subtarget
, VOIDmode
, 0);
1511 /* Make a suitable register to place result in. */
1512 target
= gen_reg_rtx (TYPE_MODE (TREE_TYPE (exp
)));
1517 switch (DECL_FUNCTION_CODE (fndecl
))
1522 builtin_optab
= sin_optab
; break;
1526 builtin_optab
= cos_optab
; break;
1528 case BUILT_IN_SQRTF
:
1529 case BUILT_IN_SQRTL
:
1530 builtin_optab
= sqrt_optab
; break;
1534 builtin_optab
= exp_optab
; break;
1538 builtin_optab
= log_optab
; break;
1539 case BUILT_IN_FLOOR
:
1540 case BUILT_IN_FLOORF
:
1541 case BUILT_IN_FLOORL
:
1542 errno_set
= false ; builtin_optab
= floor_optab
; break;
1544 case BUILT_IN_CEILF
:
1545 case BUILT_IN_CEILL
:
1546 errno_set
= false ; builtin_optab
= ceil_optab
; break;
1547 case BUILT_IN_TRUNC
:
1548 case BUILT_IN_TRUNCF
:
1549 case BUILT_IN_TRUNCL
:
1550 errno_set
= false ; builtin_optab
= trunc_optab
; break;
1551 case BUILT_IN_ROUND
:
1552 case BUILT_IN_ROUNDF
:
1553 case BUILT_IN_ROUNDL
:
1554 errno_set
= false ; builtin_optab
= round_optab
; break;
1555 case BUILT_IN_NEARBYINT
:
1556 case BUILT_IN_NEARBYINTF
:
1557 case BUILT_IN_NEARBYINTL
:
1558 errno_set
= false ; builtin_optab
= nearbyint_optab
; break;
1563 /* Compute into TARGET.
1564 Set TARGET to wherever the result comes back. */
1565 argmode
= TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist
)));
1566 target
= expand_unop (argmode
, builtin_optab
, op0
, target
, 0);
1568 /* If we were unable to expand via the builtin, stop the
1569 sequence (without outputting the insns) and return 0, causing
1570 a call to the library function. */
1577 /* If errno must be maintained, we must set it to EDOM for NaN results. */
1579 if (flag_errno_math
&& errno_set
&& HONOR_NANS (argmode
))
1583 lab1
= gen_label_rtx ();
1585 /* Test the result; if it is NaN, set errno=EDOM because
1586 the argument was not in the domain. */
1587 emit_cmp_and_jump_insns (target
, target
, EQ
, 0, GET_MODE (target
),
1592 #ifdef GEN_ERRNO_RTX
1593 rtx errno_rtx
= GEN_ERRNO_RTX
;
1596 = gen_rtx_MEM (word_mode
, gen_rtx_SYMBOL_REF (Pmode
, "errno"));
1599 emit_move_insn (errno_rtx
, GEN_INT (TARGET_EDOM
));
1602 /* We can't set errno=EDOM directly; let the library call do it.
1603 Pop the arguments right away in case the call gets deleted. */
1605 expand_call (exp
, target
, 0);
1612 /* Output the entire sequence. */
1613 insns
= get_insns ();
1620 /* Expand expression EXP which is a call to the strlen builtin. Return 0
1621 if we failed the caller should emit a normal call, otherwise
1622 try to get the result in TARGET, if convenient. */
1625 expand_builtin_strlen (exp
, target
)
1629 tree arglist
= TREE_OPERAND (exp
, 1);
1630 enum machine_mode value_mode
= TYPE_MODE (TREE_TYPE (exp
));
1632 if (!validate_arglist (arglist
, POINTER_TYPE
, VOID_TYPE
))
1637 tree src
= TREE_VALUE (arglist
);
1640 = get_pointer_alignment (src
, BIGGEST_ALIGNMENT
) / BITS_PER_UNIT
;
1642 rtx result
, src_reg
, char_rtx
, before_strlen
;
1643 enum machine_mode insn_mode
= value_mode
, char_mode
;
1644 enum insn_code icode
= CODE_FOR_nothing
;
1646 /* If SRC is not a pointer type, don't do this operation inline. */
1650 /* Bail out if we can't compute strlen in the right mode. */
1651 while (insn_mode
!= VOIDmode
)
1653 icode
= strlen_optab
->handlers
[(int) insn_mode
].insn_code
;
1654 if (icode
!= CODE_FOR_nothing
)
1657 insn_mode
= GET_MODE_WIDER_MODE (insn_mode
);
1659 if (insn_mode
== VOIDmode
)
1662 /* Make a place to write the result of the instruction. */
1665 && GET_CODE (result
) == REG
1666 && GET_MODE (result
) == insn_mode
1667 && REGNO (result
) >= FIRST_PSEUDO_REGISTER
))
1668 result
= gen_reg_rtx (insn_mode
);
1670 /* Make a place to hold the source address. We will not expand
1671 the actual source until we are sure that the expansion will
1672 not fail -- there are trees that cannot be expanded twice. */
1673 src_reg
= gen_reg_rtx (Pmode
);
1675 /* Mark the beginning of the strlen sequence so we can emit the
1676 source operand later. */
1677 before_strlen
= get_last_insn ();
1679 char_rtx
= const0_rtx
;
1680 char_mode
= insn_data
[(int) icode
].operand
[2].mode
;
1681 if (! (*insn_data
[(int) icode
].operand
[2].predicate
) (char_rtx
,
1683 char_rtx
= copy_to_mode_reg (char_mode
, char_rtx
);
1685 pat
= GEN_FCN (icode
) (result
, gen_rtx_MEM (BLKmode
, src_reg
),
1686 char_rtx
, GEN_INT (align
));
1691 /* Now that we are assured of success, expand the source. */
1693 pat
= memory_address (BLKmode
,
1694 expand_expr (src
, src_reg
, ptr_mode
, EXPAND_SUM
));
1696 emit_move_insn (src_reg
, pat
);
1701 emit_insn_after (pat
, before_strlen
);
1703 emit_insn_before (pat
, get_insns ());
1705 /* Return the value in the proper mode for this function. */
1706 if (GET_MODE (result
) == value_mode
)
1708 else if (target
!= 0)
1709 convert_move (target
, result
, 0);
1711 target
= convert_to_mode (value_mode
, result
, 0);
1717 /* Expand a call to the strstr builtin. Return 0 if we failed the
1718 caller should emit a normal call, otherwise try to get the result
1719 in TARGET, if convenient (and in mode MODE if that's convenient). */
1722 expand_builtin_strstr (arglist
, target
, mode
)
1725 enum machine_mode mode
;
1727 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
1731 tree s1
= TREE_VALUE (arglist
), s2
= TREE_VALUE (TREE_CHAIN (arglist
));
1733 const char *p1
, *p2
;
1742 const char *r
= strstr (p1
, p2
);
1747 /* Return an offset into the constant string argument. */
1748 return expand_expr (fold (build (PLUS_EXPR
, TREE_TYPE (s1
),
1749 s1
, ssize_int (r
- p1
))),
1750 target
, mode
, EXPAND_NORMAL
);
1754 return expand_expr (s1
, target
, mode
, EXPAND_NORMAL
);
1759 fn
= built_in_decls
[BUILT_IN_STRCHR
];
1763 /* New argument list transforming strstr(s1, s2) to
1764 strchr(s1, s2[0]). */
1766 build_tree_list (NULL_TREE
, build_int_2 (p2
[0], 0));
1767 arglist
= tree_cons (NULL_TREE
, s1
, arglist
);
1768 return expand_expr (build_function_call_expr (fn
, arglist
),
1769 target
, mode
, EXPAND_NORMAL
);
1773 /* Expand a call to the strchr builtin. Return 0 if we failed the
1774 caller should emit a normal call, otherwise try to get the result
1775 in TARGET, if convenient (and in mode MODE if that's convenient). */
1778 expand_builtin_strchr (arglist
, target
, mode
)
1781 enum machine_mode mode
;
1783 if (!validate_arglist (arglist
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
1787 tree s1
= TREE_VALUE (arglist
), s2
= TREE_VALUE (TREE_CHAIN (arglist
));
1790 if (TREE_CODE (s2
) != INTEGER_CST
)
1799 if (target_char_cast (s2
, &c
))
1807 /* Return an offset into the constant string argument. */
1808 return expand_expr (fold (build (PLUS_EXPR
, TREE_TYPE (s1
),
1809 s1
, ssize_int (r
- p1
))),
1810 target
, mode
, EXPAND_NORMAL
);
1813 /* FIXME: Should use here strchrM optab so that ports can optimize
1819 /* Expand a call to the strrchr builtin. Return 0 if we failed the
1820 caller should emit a normal call, otherwise try to get the result
1821 in TARGET, if convenient (and in mode MODE if that's convenient). */
1824 expand_builtin_strrchr (arglist
, target
, mode
)
1827 enum machine_mode mode
;
1829 if (!validate_arglist (arglist
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
1833 tree s1
= TREE_VALUE (arglist
), s2
= TREE_VALUE (TREE_CHAIN (arglist
));
1837 if (TREE_CODE (s2
) != INTEGER_CST
)
1846 if (target_char_cast (s2
, &c
))
1849 r
= strrchr (p1
, c
);
1854 /* Return an offset into the constant string argument. */
1855 return expand_expr (fold (build (PLUS_EXPR
, TREE_TYPE (s1
),
1856 s1
, ssize_int (r
- p1
))),
1857 target
, mode
, EXPAND_NORMAL
);
1860 if (! integer_zerop (s2
))
1863 fn
= built_in_decls
[BUILT_IN_STRCHR
];
1867 /* Transform strrchr(s1, '\0') to strchr(s1, '\0'). */
1868 return expand_expr (build_function_call_expr (fn
, arglist
),
1869 target
, mode
, EXPAND_NORMAL
);
1873 /* Expand a call to the strpbrk builtin. Return 0 if we failed the
1874 caller should emit a normal call, otherwise try to get the result
1875 in TARGET, if convenient (and in mode MODE if that's convenient). */
1878 expand_builtin_strpbrk (arglist
, target
, mode
)
1881 enum machine_mode mode
;
1883 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
1887 tree s1
= TREE_VALUE (arglist
), s2
= TREE_VALUE (TREE_CHAIN (arglist
));
1889 const char *p1
, *p2
;
1898 const char *r
= strpbrk (p1
, p2
);
1903 /* Return an offset into the constant string argument. */
1904 return expand_expr (fold (build (PLUS_EXPR
, TREE_TYPE (s1
),
1905 s1
, ssize_int (r
- p1
))),
1906 target
, mode
, EXPAND_NORMAL
);
1911 /* strpbrk(x, "") == NULL.
1912 Evaluate and ignore the arguments in case they had
1914 expand_expr (s1
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
1919 return 0; /* Really call strpbrk. */
1921 fn
= built_in_decls
[BUILT_IN_STRCHR
];
1925 /* New argument list transforming strpbrk(s1, s2) to
1926 strchr(s1, s2[0]). */
1928 build_tree_list (NULL_TREE
, build_int_2 (p2
[0], 0));
1929 arglist
= tree_cons (NULL_TREE
, s1
, arglist
);
1930 return expand_expr (build_function_call_expr (fn
, arglist
),
1931 target
, mode
, EXPAND_NORMAL
);
1935 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
1936 bytes from constant string DATA + OFFSET and return it as target
1940 builtin_memcpy_read_str (data
, offset
, mode
)
1942 HOST_WIDE_INT offset
;
1943 enum machine_mode mode
;
1945 const char *str
= (const char *) data
;
1948 || ((unsigned HOST_WIDE_INT
) offset
+ GET_MODE_SIZE (mode
)
1949 > strlen (str
) + 1))
1950 abort (); /* Attempt to read past the end of constant string. */
1952 return c_readstr (str
+ offset
, mode
);
1955 /* Expand a call to the memcpy builtin, with arguments in ARGLIST.
1956 Return 0 if we failed, the caller should emit a normal call, otherwise
1957 try to get the result in TARGET, if convenient (and in mode MODE if
1958 that's convenient). */
1961 expand_builtin_memcpy (arglist
, target
, mode
)
1964 enum machine_mode mode
;
1966 if (!validate_arglist (arglist
,
1967 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
1971 tree dest
= TREE_VALUE (arglist
);
1972 tree src
= TREE_VALUE (TREE_CHAIN (arglist
));
1973 tree len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
1974 const char *src_str
;
1976 unsigned int src_align
= get_pointer_alignment (src
, BIGGEST_ALIGNMENT
);
1977 unsigned int dest_align
1978 = get_pointer_alignment (dest
, BIGGEST_ALIGNMENT
);
1979 rtx dest_mem
, src_mem
, dest_addr
, len_rtx
;
1981 /* If DEST is not a pointer type, call the normal function. */
1982 if (dest_align
== 0)
1985 /* If the LEN parameter is zero, return DEST. */
1986 if (host_integerp (len
, 1) && tree_low_cst (len
, 1) == 0)
1988 /* Evaluate and ignore SRC in case it has side-effects. */
1989 expand_expr (src
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
1990 return expand_expr (dest
, target
, mode
, EXPAND_NORMAL
);
1993 /* If either SRC is not a pointer type, don't do this
1994 operation in-line. */
1998 dest_mem
= get_memory_rtx (dest
);
1999 set_mem_align (dest_mem
, dest_align
);
2000 len_rtx
= expand_expr (len
, NULL_RTX
, VOIDmode
, 0);
2001 src_str
= c_getstr (src
);
2003 /* If SRC is a string constant and block move would be done
2004 by pieces, we can avoid loading the string from memory
2005 and only stored the computed constants. */
2007 && GET_CODE (len_rtx
) == CONST_INT
2008 && (unsigned HOST_WIDE_INT
) INTVAL (len_rtx
) <= strlen (src_str
) + 1
2009 && can_store_by_pieces (INTVAL (len_rtx
), builtin_memcpy_read_str
,
2010 (PTR
) src_str
, dest_align
))
2012 store_by_pieces (dest_mem
, INTVAL (len_rtx
),
2013 builtin_memcpy_read_str
,
2014 (PTR
) src_str
, dest_align
);
2015 dest_mem
= force_operand (XEXP (dest_mem
, 0), NULL_RTX
);
2016 #ifdef POINTERS_EXTEND_UNSIGNED
2017 if (GET_MODE (dest_mem
) != ptr_mode
)
2018 dest_mem
= convert_memory_address (ptr_mode
, dest_mem
);
2023 src_mem
= get_memory_rtx (src
);
2024 set_mem_align (src_mem
, src_align
);
2026 /* Copy word part most expediently. */
2027 dest_addr
= emit_block_move (dest_mem
, src_mem
, len_rtx
,
2032 dest_addr
= force_operand (XEXP (dest_mem
, 0), NULL_RTX
);
2033 #ifdef POINTERS_EXTEND_UNSIGNED
2034 if (GET_MODE (dest_addr
) != ptr_mode
)
2035 dest_addr
= convert_memory_address (ptr_mode
, dest_addr
);
2043 /* Expand expression EXP, which is a call to the strcpy builtin. Return 0
2044 if we failed the caller should emit a normal call, otherwise try to get
2045 the result in TARGET, if convenient (and in mode MODE if that's
2049 expand_builtin_strcpy (exp
, target
, mode
)
2052 enum machine_mode mode
;
2054 tree arglist
= TREE_OPERAND (exp
, 1);
2057 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
2060 fn
= built_in_decls
[BUILT_IN_MEMCPY
];
2064 len
= c_strlen (TREE_VALUE (TREE_CHAIN (arglist
)));
2068 len
= size_binop (PLUS_EXPR
, len
, ssize_int (1));
2069 chainon (arglist
, build_tree_list (NULL_TREE
, len
));
2070 return expand_expr (build_function_call_expr (fn
, arglist
),
2071 target
, mode
, EXPAND_NORMAL
);
2074 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
2075 bytes from constant string DATA + OFFSET and return it as target
2079 builtin_strncpy_read_str (data
, offset
, mode
)
2081 HOST_WIDE_INT offset
;
2082 enum machine_mode mode
;
2084 const char *str
= (const char *) data
;
2086 if ((unsigned HOST_WIDE_INT
) offset
> strlen (str
))
2089 return c_readstr (str
+ offset
, mode
);
2092 /* Expand expression EXP, which is a call to the strncpy builtin. Return 0
2093 if we failed the caller should emit a normal call. */
2096 expand_builtin_strncpy (arglist
, target
, mode
)
2099 enum machine_mode mode
;
2101 if (!validate_arglist (arglist
,
2102 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
2106 tree slen
= c_strlen (TREE_VALUE (TREE_CHAIN (arglist
)));
2107 tree len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
2110 /* We must be passed a constant len parameter. */
2111 if (TREE_CODE (len
) != INTEGER_CST
)
2114 /* If the len parameter is zero, return the dst parameter. */
2115 if (integer_zerop (len
))
2117 /* Evaluate and ignore the src argument in case it has
2119 expand_expr (TREE_VALUE (TREE_CHAIN (arglist
)), const0_rtx
,
2120 VOIDmode
, EXPAND_NORMAL
);
2121 /* Return the dst parameter. */
2122 return expand_expr (TREE_VALUE (arglist
), target
, mode
,
2126 /* Now, we must be passed a constant src ptr parameter. */
2127 if (slen
== 0 || TREE_CODE (slen
) != INTEGER_CST
)
2130 slen
= size_binop (PLUS_EXPR
, slen
, ssize_int (1));
2132 /* We're required to pad with trailing zeros if the requested
2133 len is greater than strlen(s2)+1. In that case try to
2134 use store_by_pieces, if it fails, punt. */
2135 if (tree_int_cst_lt (slen
, len
))
2137 tree dest
= TREE_VALUE (arglist
);
2138 unsigned int dest_align
2139 = get_pointer_alignment (dest
, BIGGEST_ALIGNMENT
);
2140 const char *p
= c_getstr (TREE_VALUE (TREE_CHAIN (arglist
)));
2143 if (!p
|| dest_align
== 0 || !host_integerp (len
, 1)
2144 || !can_store_by_pieces (tree_low_cst (len
, 1),
2145 builtin_strncpy_read_str
,
2146 (PTR
) p
, dest_align
))
2149 dest_mem
= get_memory_rtx (dest
);
2150 store_by_pieces (dest_mem
, tree_low_cst (len
, 1),
2151 builtin_strncpy_read_str
,
2152 (PTR
) p
, dest_align
);
2153 dest_mem
= force_operand (XEXP (dest_mem
, 0), NULL_RTX
);
2154 #ifdef POINTERS_EXTEND_UNSIGNED
2155 if (GET_MODE (dest_mem
) != ptr_mode
)
2156 dest_mem
= convert_memory_address (ptr_mode
, dest_mem
);
2161 /* OK transform into builtin memcpy. */
2162 fn
= built_in_decls
[BUILT_IN_MEMCPY
];
2165 return expand_expr (build_function_call_expr (fn
, arglist
),
2166 target
, mode
, EXPAND_NORMAL
);
2170 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
2171 bytes from constant string DATA + OFFSET and return it as target
2175 builtin_memset_read_str (data
, offset
, mode
)
2177 HOST_WIDE_INT offset ATTRIBUTE_UNUSED
;
2178 enum machine_mode mode
;
2180 const char *c
= (const char *) data
;
2181 char *p
= alloca (GET_MODE_SIZE (mode
));
2183 memset (p
, *c
, GET_MODE_SIZE (mode
));
2185 return c_readstr (p
, mode
);
2188 /* Callback routine for store_by_pieces. Return the RTL of a register
2189 containing GET_MODE_SIZE (MODE) consecutive copies of the unsigned
2190 char value given in the RTL register data. For example, if mode is
2191 4 bytes wide, return the RTL for 0x01010101*data. */
2194 builtin_memset_gen_str (data
, offset
, mode
)
2196 HOST_WIDE_INT offset ATTRIBUTE_UNUSED
;
2197 enum machine_mode mode
;
2203 size
= GET_MODE_SIZE (mode
);
2208 memset (p
, 1, size
);
2209 coeff
= c_readstr (p
, mode
);
2211 target
= convert_to_mode (mode
, (rtx
) data
, 1);
2212 target
= expand_mult (mode
, target
, coeff
, NULL_RTX
, 1);
2213 return force_reg (mode
, target
);
2216 /* Expand expression EXP, which is a call to the memset builtin. Return 0
2217 if we failed the caller should emit a normal call, otherwise try to get
2218 the result in TARGET, if convenient (and in mode MODE if that's
2222 expand_builtin_memset (exp
, target
, mode
)
2225 enum machine_mode mode
;
2227 tree arglist
= TREE_OPERAND (exp
, 1);
2229 if (!validate_arglist (arglist
,
2230 POINTER_TYPE
, INTEGER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
2234 tree dest
= TREE_VALUE (arglist
);
2235 tree val
= TREE_VALUE (TREE_CHAIN (arglist
));
2236 tree len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
2239 unsigned int dest_align
2240 = get_pointer_alignment (dest
, BIGGEST_ALIGNMENT
);
2241 rtx dest_mem
, dest_addr
, len_rtx
;
2243 /* If DEST is not a pointer type, don't do this
2244 operation in-line. */
2245 if (dest_align
== 0)
2248 /* If the LEN parameter is zero, return DEST. */
2249 if (host_integerp (len
, 1) && tree_low_cst (len
, 1) == 0)
2251 /* Evaluate and ignore VAL in case it has side-effects. */
2252 expand_expr (val
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
2253 return expand_expr (dest
, target
, mode
, EXPAND_NORMAL
);
2256 if (TREE_CODE (val
) != INTEGER_CST
)
2260 if (!host_integerp (len
, 1))
2263 if (optimize_size
&& tree_low_cst (len
, 1) > 1)
2266 /* Assume that we can memset by pieces if we can store the
2267 * the coefficients by pieces (in the required modes).
2268 * We can't pass builtin_memset_gen_str as that emits RTL. */
2270 if (!can_store_by_pieces (tree_low_cst (len
, 1),
2271 builtin_memset_read_str
,
2272 (PTR
) &c
, dest_align
))
2275 val
= fold (build1 (CONVERT_EXPR
, unsigned_char_type_node
, val
));
2276 val_rtx
= expand_expr (val
, NULL_RTX
, VOIDmode
, 0);
2277 val_rtx
= force_reg (TYPE_MODE (unsigned_char_type_node
),
2279 dest_mem
= get_memory_rtx (dest
);
2280 store_by_pieces (dest_mem
, tree_low_cst (len
, 1),
2281 builtin_memset_gen_str
,
2282 (PTR
) val_rtx
, dest_align
);
2283 dest_mem
= force_operand (XEXP (dest_mem
, 0), NULL_RTX
);
2284 #ifdef POINTERS_EXTEND_UNSIGNED
2285 if (GET_MODE (dest_mem
) != ptr_mode
)
2286 dest_mem
= convert_memory_address (ptr_mode
, dest_mem
);
2291 if (target_char_cast (val
, &c
))
2296 if (!host_integerp (len
, 1))
2298 if (!can_store_by_pieces (tree_low_cst (len
, 1),
2299 builtin_memset_read_str
, (PTR
) &c
,
2303 dest_mem
= get_memory_rtx (dest
);
2304 store_by_pieces (dest_mem
, tree_low_cst (len
, 1),
2305 builtin_memset_read_str
,
2306 (PTR
) &c
, dest_align
);
2307 dest_mem
= force_operand (XEXP (dest_mem
, 0), NULL_RTX
);
2308 #ifdef POINTERS_EXTEND_UNSIGNED
2309 if (GET_MODE (dest_mem
) != ptr_mode
)
2310 dest_mem
= convert_memory_address (ptr_mode
, dest_mem
);
2315 len_rtx
= expand_expr (len
, NULL_RTX
, VOIDmode
, 0);
2317 dest_mem
= get_memory_rtx (dest
);
2318 set_mem_align (dest_mem
, dest_align
);
2319 dest_addr
= clear_storage (dest_mem
, len_rtx
);
2323 dest_addr
= force_operand (XEXP (dest_mem
, 0), NULL_RTX
);
2324 #ifdef POINTERS_EXTEND_UNSIGNED
2325 if (GET_MODE (dest_addr
) != ptr_mode
)
2326 dest_addr
= convert_memory_address (ptr_mode
, dest_addr
);
2334 /* Expand expression EXP, which is a call to the bzero builtin. Return 0
2335 if we failed the caller should emit a normal call. */
2338 expand_builtin_bzero (exp
)
2341 tree arglist
= TREE_OPERAND (exp
, 1);
2342 tree dest
, size
, newarglist
;
2345 if (!validate_arglist (arglist
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
2348 dest
= TREE_VALUE (arglist
);
2349 size
= TREE_VALUE (TREE_CHAIN (arglist
));
2351 /* New argument list transforming bzero(ptr x, int y) to
2352 memset(ptr x, int 0, size_t y). This is done this way
2353 so that if it isn't expanded inline, we fallback to
2354 calling bzero instead of memset. */
2356 newarglist
= build_tree_list (NULL_TREE
, convert (sizetype
, size
));
2357 newarglist
= tree_cons (NULL_TREE
, integer_zero_node
, newarglist
);
2358 newarglist
= tree_cons (NULL_TREE
, dest
, newarglist
);
2360 TREE_OPERAND (exp
, 1) = newarglist
;
2361 result
= expand_builtin_memset (exp
, const0_rtx
, VOIDmode
);
2363 /* Always restore the original arguments. */
2364 TREE_OPERAND (exp
, 1) = arglist
;
2369 /* Expand expression EXP, which is a call to the memcmp or the strcmp builtin.
2370 ARGLIST is the argument list for this call. Return 0 if we failed and the
2371 caller should emit a normal call, otherwise try to get the result in
2372 TARGET, if convenient (and in mode MODE, if that's convenient). */
2375 expand_builtin_memcmp (exp
, arglist
, target
, mode
)
2376 tree exp ATTRIBUTE_UNUSED
;
2379 enum machine_mode mode
;
2381 tree arg1
, arg2
, len
;
2382 const char *p1
, *p2
;
2384 if (!validate_arglist (arglist
,
2385 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
2388 arg1
= TREE_VALUE (arglist
);
2389 arg2
= TREE_VALUE (TREE_CHAIN (arglist
));
2390 len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
2392 /* If the len parameter is zero, return zero. */
2393 if (host_integerp (len
, 1) && tree_low_cst (len
, 1) == 0)
2395 /* Evaluate and ignore arg1 and arg2 in case they have
2397 expand_expr (arg1
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
2398 expand_expr (arg2
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
2402 p1
= c_getstr (arg1
);
2403 p2
= c_getstr (arg2
);
2405 /* If all arguments are constant, and the value of len is not greater
2406 than the lengths of arg1 and arg2, evaluate at compile-time. */
2407 if (host_integerp (len
, 1) && p1
&& p2
2408 && compare_tree_int (len
, strlen (p1
) + 1) <= 0
2409 && compare_tree_int (len
, strlen (p2
) + 1) <= 0)
2411 const int r
= memcmp (p1
, p2
, tree_low_cst (len
, 1));
2413 return (r
< 0 ? constm1_rtx
: (r
> 0 ? const1_rtx
: const0_rtx
));
2416 /* If len parameter is one, return an expression corresponding to
2417 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
2418 if (host_integerp (len
, 1) && tree_low_cst (len
, 1) == 1)
2420 tree cst_uchar_node
= build_type_variant (unsigned_char_type_node
, 1, 0);
2421 tree cst_uchar_ptr_node
= build_pointer_type (cst_uchar_node
);
2423 fold (build1 (CONVERT_EXPR
, integer_type_node
,
2424 build1 (INDIRECT_REF
, cst_uchar_node
,
2425 build1 (NOP_EXPR
, cst_uchar_ptr_node
, arg1
))));
2427 fold (build1 (CONVERT_EXPR
, integer_type_node
,
2428 build1 (INDIRECT_REF
, cst_uchar_node
,
2429 build1 (NOP_EXPR
, cst_uchar_ptr_node
, arg2
))));
2430 tree result
= fold (build (MINUS_EXPR
, integer_type_node
, ind1
, ind2
));
2431 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
2434 #ifdef HAVE_cmpstrsi
2436 rtx arg1_rtx
, arg2_rtx
, arg3_rtx
;
2441 = get_pointer_alignment (arg1
, BIGGEST_ALIGNMENT
) / BITS_PER_UNIT
;
2443 = get_pointer_alignment (arg2
, BIGGEST_ALIGNMENT
) / BITS_PER_UNIT
;
2444 enum machine_mode insn_mode
2445 = insn_data
[(int) CODE_FOR_cmpstrsi
].operand
[0].mode
;
2447 /* If we don't have POINTER_TYPE, call the function. */
2448 if (arg1_align
== 0 || arg2_align
== 0)
2451 /* Make a place to write the result of the instruction. */
2454 && GET_CODE (result
) == REG
&& GET_MODE (result
) == insn_mode
2455 && REGNO (result
) >= FIRST_PSEUDO_REGISTER
))
2456 result
= gen_reg_rtx (insn_mode
);
2458 arg1_rtx
= get_memory_rtx (arg1
);
2459 arg2_rtx
= get_memory_rtx (arg2
);
2460 arg3_rtx
= expand_expr (len
, NULL_RTX
, VOIDmode
, 0);
2464 insn
= gen_cmpstrsi (result
, arg1_rtx
, arg2_rtx
, arg3_rtx
,
2465 GEN_INT (MIN (arg1_align
, arg2_align
)));
2470 emit_library_call_value (memcmp_libfunc
, result
, LCT_PURE_MAKE_BLOCK
,
2471 TYPE_MODE (integer_type_node
), 3,
2472 XEXP (arg1_rtx
, 0), Pmode
,
2473 XEXP (arg2_rtx
, 0), Pmode
,
2474 convert_to_mode (TYPE_MODE (sizetype
), arg3_rtx
,
2475 TREE_UNSIGNED (sizetype
)),
2476 TYPE_MODE (sizetype
));
2478 /* Return the value in the proper mode for this function. */
2479 mode
= TYPE_MODE (TREE_TYPE (exp
));
2480 if (GET_MODE (result
) == mode
)
2482 else if (target
!= 0)
2484 convert_move (target
, result
, 0);
2488 return convert_to_mode (mode
, result
, 0);
2495 /* Expand expression EXP, which is a call to the strcmp builtin. Return 0
2496 if we failed the caller should emit a normal call, otherwise try to get
2497 the result in TARGET, if convenient. */
2500 expand_builtin_strcmp (exp
, target
, mode
)
2503 enum machine_mode mode
;
2505 tree arglist
= TREE_OPERAND (exp
, 1);
2506 tree arg1
, arg2
, len
, len2
, fn
;
2507 const char *p1
, *p2
;
2509 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
2512 arg1
= TREE_VALUE (arglist
);
2513 arg2
= TREE_VALUE (TREE_CHAIN (arglist
));
2515 p1
= c_getstr (arg1
);
2516 p2
= c_getstr (arg2
);
2520 const int i
= strcmp (p1
, p2
);
2521 return (i
< 0 ? constm1_rtx
: (i
> 0 ? const1_rtx
: const0_rtx
));
2524 /* If either arg is "", return an expression corresponding to
2525 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
2526 if ((p1
&& *p1
== '\0') || (p2
&& *p2
== '\0'))
2528 tree cst_uchar_node
= build_type_variant (unsigned_char_type_node
, 1, 0);
2529 tree cst_uchar_ptr_node
= build_pointer_type (cst_uchar_node
);
2531 fold (build1 (CONVERT_EXPR
, integer_type_node
,
2532 build1 (INDIRECT_REF
, cst_uchar_node
,
2533 build1 (NOP_EXPR
, cst_uchar_ptr_node
, arg1
))));
2535 fold (build1 (CONVERT_EXPR
, integer_type_node
,
2536 build1 (INDIRECT_REF
, cst_uchar_node
,
2537 build1 (NOP_EXPR
, cst_uchar_ptr_node
, arg2
))));
2538 tree result
= fold (build (MINUS_EXPR
, integer_type_node
, ind1
, ind2
));
2539 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
2542 len
= c_strlen (arg1
);
2543 len2
= c_strlen (arg2
);
2546 len
= size_binop (PLUS_EXPR
, ssize_int (1), len
);
2549 len2
= size_binop (PLUS_EXPR
, ssize_int (1), len2
);
2551 /* If we don't have a constant length for the first, use the length
2552 of the second, if we know it. We don't require a constant for
2553 this case; some cost analysis could be done if both are available
2554 but neither is constant. For now, assume they're equally cheap
2555 unless one has side effects.
2557 If both strings have constant lengths, use the smaller. This
2558 could arise if optimization results in strcpy being called with
2559 two fixed strings, or if the code was machine-generated. We should
2560 add some code to the `memcmp' handler below to deal with such
2561 situations, someday. */
2563 if (!len
|| TREE_CODE (len
) != INTEGER_CST
)
2565 if (len2
&& !TREE_SIDE_EFFECTS (len2
))
2570 else if (len2
&& TREE_CODE (len2
) == INTEGER_CST
2571 && tree_int_cst_lt (len2
, len
))
2574 /* If both arguments have side effects, we cannot optimize. */
2575 if (TREE_SIDE_EFFECTS (len
))
2578 fn
= built_in_decls
[BUILT_IN_MEMCMP
];
2582 chainon (arglist
, build_tree_list (NULL_TREE
, len
));
2583 return expand_expr (build_function_call_expr (fn
, arglist
),
2584 target
, mode
, EXPAND_NORMAL
);
2587 /* Expand expression EXP, which is a call to the strncmp builtin. Return 0
2588 if we failed the caller should emit a normal call, otherwise try to get
2589 the result in TARGET, if convenient. */
2592 expand_builtin_strncmp (exp
, target
, mode
)
2595 enum machine_mode mode
;
2597 tree arglist
= TREE_OPERAND (exp
, 1);
2598 tree fn
, newarglist
, len
= 0;
2599 tree arg1
, arg2
, arg3
;
2600 const char *p1
, *p2
;
2602 if (!validate_arglist (arglist
,
2603 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
2606 arg1
= TREE_VALUE (arglist
);
2607 arg2
= TREE_VALUE (TREE_CHAIN (arglist
));
2608 arg3
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
2610 /* If the len parameter is zero, return zero. */
2611 if (host_integerp (arg3
, 1) && tree_low_cst (arg3
, 1) == 0)
2613 /* Evaluate and ignore arg1 and arg2 in case they have
2615 expand_expr (arg1
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
2616 expand_expr (arg2
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
2620 p1
= c_getstr (arg1
);
2621 p2
= c_getstr (arg2
);
2623 /* If all arguments are constant, evaluate at compile-time. */
2624 if (host_integerp (arg3
, 1) && p1
&& p2
)
2626 const int r
= strncmp (p1
, p2
, tree_low_cst (arg3
, 1));
2627 return (r
< 0 ? constm1_rtx
: (r
> 0 ? const1_rtx
: const0_rtx
));
2630 /* If len == 1 or (either string parameter is "" and (len >= 1)),
2631 return (*(const u_char*)arg1 - *(const u_char*)arg2). */
2632 if (host_integerp (arg3
, 1)
2633 && (tree_low_cst (arg3
, 1) == 1
2634 || (tree_low_cst (arg3
, 1) > 1
2635 && ((p1
&& *p1
== '\0') || (p2
&& *p2
== '\0')))))
2637 tree cst_uchar_node
= build_type_variant (unsigned_char_type_node
, 1, 0);
2638 tree cst_uchar_ptr_node
= build_pointer_type (cst_uchar_node
);
2640 fold (build1 (CONVERT_EXPR
, integer_type_node
,
2641 build1 (INDIRECT_REF
, cst_uchar_node
,
2642 build1 (NOP_EXPR
, cst_uchar_ptr_node
, arg1
))));
2644 fold (build1 (CONVERT_EXPR
, integer_type_node
,
2645 build1 (INDIRECT_REF
, cst_uchar_node
,
2646 build1 (NOP_EXPR
, cst_uchar_ptr_node
, arg2
))));
2647 tree result
= fold (build (MINUS_EXPR
, integer_type_node
, ind1
, ind2
));
2648 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
2651 /* If c_strlen can determine an expression for one of the string
2652 lengths, and it doesn't have side effects, then call
2653 expand_builtin_memcmp() using length MIN(strlen(string)+1, arg3). */
2655 /* Perhaps one of the strings is really constant, if so prefer
2656 that constant length over the other string's length. */
2658 len
= c_strlen (arg1
);
2660 len
= c_strlen (arg2
);
2662 /* If we still don't have a len, try either string arg as long
2663 as they don't have side effects. */
2664 if (!len
&& !TREE_SIDE_EFFECTS (arg1
))
2665 len
= c_strlen (arg1
);
2666 if (!len
&& !TREE_SIDE_EFFECTS (arg2
))
2667 len
= c_strlen (arg2
);
2668 /* If we still don't have a length, punt. */
2672 fn
= built_in_decls
[BUILT_IN_MEMCMP
];
2676 /* Add one to the string length. */
2677 len
= fold (size_binop (PLUS_EXPR
, len
, ssize_int (1)));
2679 /* The actual new length parameter is MIN(len,arg3). */
2680 len
= fold (build (MIN_EXPR
, TREE_TYPE (len
), len
, arg3
));
2682 newarglist
= build_tree_list (NULL_TREE
, len
);
2683 newarglist
= tree_cons (NULL_TREE
, arg2
, newarglist
);
2684 newarglist
= tree_cons (NULL_TREE
, arg1
, newarglist
);
2685 return expand_expr (build_function_call_expr (fn
, newarglist
),
2686 target
, mode
, EXPAND_NORMAL
);
2689 /* Expand expression EXP, which is a call to the strcat builtin.
2690 Return 0 if we failed the caller should emit a normal call,
2691 otherwise try to get the result in TARGET, if convenient. */
2694 expand_builtin_strcat (arglist
, target
, mode
)
2697 enum machine_mode mode
;
2699 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
2703 tree dst
= TREE_VALUE (arglist
),
2704 src
= TREE_VALUE (TREE_CHAIN (arglist
));
2705 const char *p
= c_getstr (src
);
2707 /* If the string length is zero, return the dst parameter. */
2708 if (p
&& *p
== '\0')
2709 return expand_expr (dst
, target
, mode
, EXPAND_NORMAL
);
2715 /* Expand expression EXP, which is a call to the strncat builtin.
2716 Return 0 if we failed the caller should emit a normal call,
2717 otherwise try to get the result in TARGET, if convenient. */
2720 expand_builtin_strncat (arglist
, target
, mode
)
2723 enum machine_mode mode
;
2725 if (!validate_arglist (arglist
,
2726 POINTER_TYPE
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
2730 tree dst
= TREE_VALUE (arglist
),
2731 src
= TREE_VALUE (TREE_CHAIN (arglist
)),
2732 len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
2733 const char *p
= c_getstr (src
);
2735 /* If the requested length is zero, or the src parameter string
2736 length is zero, return the dst parameter. */
2737 if (integer_zerop (len
) || (p
&& *p
== '\0'))
2739 /* Evaluate and ignore the src and len parameters in case
2740 they have side-effects. */
2741 expand_expr (src
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
2742 expand_expr (len
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
2743 return expand_expr (dst
, target
, mode
, EXPAND_NORMAL
);
2746 /* If the requested len is greater than or equal to the string
2747 length, call strcat. */
2748 if (TREE_CODE (len
) == INTEGER_CST
&& p
2749 && compare_tree_int (len
, strlen (p
)) >= 0)
2752 = tree_cons (NULL_TREE
, dst
, build_tree_list (NULL_TREE
, src
));
2753 tree fn
= built_in_decls
[BUILT_IN_STRCAT
];
2755 /* If the replacement _DECL isn't initialized, don't do the
2760 return expand_expr (build_function_call_expr (fn
, newarglist
),
2761 target
, mode
, EXPAND_NORMAL
);
2767 /* Expand expression EXP, which is a call to the strspn builtin.
2768 Return 0 if we failed the caller should emit a normal call,
2769 otherwise try to get the result in TARGET, if convenient. */
2772 expand_builtin_strspn (arglist
, target
, mode
)
2775 enum machine_mode mode
;
2777 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
2781 tree s1
= TREE_VALUE (arglist
), s2
= TREE_VALUE (TREE_CHAIN (arglist
));
2782 const char *p1
= c_getstr (s1
), *p2
= c_getstr (s2
);
2784 /* If both arguments are constants, evaluate at compile-time. */
2787 const size_t r
= strspn (p1
, p2
);
2788 return expand_expr (size_int (r
), target
, mode
, EXPAND_NORMAL
);
2791 /* If either argument is "", return 0. */
2792 if ((p1
&& *p1
== '\0') || (p2
&& *p2
== '\0'))
2794 /* Evaluate and ignore both arguments in case either one has
2796 expand_expr (s1
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
2797 expand_expr (s2
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
2804 /* Expand expression EXP, which is a call to the strcspn builtin.
2805 Return 0 if we failed the caller should emit a normal call,
2806 otherwise try to get the result in TARGET, if convenient. */
2809 expand_builtin_strcspn (arglist
, target
, mode
)
2812 enum machine_mode mode
;
2814 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
2818 tree s1
= TREE_VALUE (arglist
), s2
= TREE_VALUE (TREE_CHAIN (arglist
));
2819 const char *p1
= c_getstr (s1
), *p2
= c_getstr (s2
);
2821 /* If both arguments are constants, evaluate at compile-time. */
2824 const size_t r
= strcspn (p1
, p2
);
2825 return expand_expr (size_int (r
), target
, mode
, EXPAND_NORMAL
);
2828 /* If the first argument is "", return 0. */
2829 if (p1
&& *p1
== '\0')
2831 /* Evaluate and ignore argument s2 in case it has
2833 expand_expr (s2
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
2837 /* If the second argument is "", return __builtin_strlen(s1). */
2838 if (p2
&& *p2
== '\0')
2840 tree newarglist
= build_tree_list (NULL_TREE
, s1
),
2841 fn
= built_in_decls
[BUILT_IN_STRLEN
];
2843 /* If the replacement _DECL isn't initialized, don't do the
2848 return expand_expr (build_function_call_expr (fn
, newarglist
),
2849 target
, mode
, EXPAND_NORMAL
);
2855 /* Expand a call to __builtin_saveregs, generating the result in TARGET,
2856 if that's convenient. */
2859 expand_builtin_saveregs ()
2863 /* Don't do __builtin_saveregs more than once in a function.
2864 Save the result of the first call and reuse it. */
2865 if (saveregs_value
!= 0)
2866 return saveregs_value
;
2868 /* When this function is called, it means that registers must be
2869 saved on entry to this function. So we migrate the call to the
2870 first insn of this function. */
2874 #ifdef EXPAND_BUILTIN_SAVEREGS
2875 /* Do whatever the machine needs done in this case. */
2876 val
= EXPAND_BUILTIN_SAVEREGS ();
2878 /* ??? We used to try and build up a call to the out of line function,
2879 guessing about what registers needed saving etc. This became much
2880 harder with __builtin_va_start, since we don't have a tree for a
2881 call to __builtin_saveregs to fall back on. There was exactly one
2882 port (i860) that used this code, and I'm unconvinced it could actually
2883 handle the general case. So we no longer try to handle anything
2884 weird and make the backend absorb the evil. */
2886 error ("__builtin_saveregs not supported by this target");
2893 saveregs_value
= val
;
2895 /* Put the insns after the NOTE that starts the function. If this
2896 is inside a start_sequence, make the outer-level insn chain current, so
2897 the code is placed at the start of the function. */
2898 push_topmost_sequence ();
2899 emit_insn_after (seq
, get_insns ());
2900 pop_topmost_sequence ();
2905 /* __builtin_args_info (N) returns word N of the arg space info
2906 for the current function. The number and meanings of words
2907 is controlled by the definition of CUMULATIVE_ARGS. */
2910 expand_builtin_args_info (exp
)
2913 tree arglist
= TREE_OPERAND (exp
, 1);
2914 int nwords
= sizeof (CUMULATIVE_ARGS
) / sizeof (int);
2915 int *word_ptr
= (int *) ¤t_function_args_info
;
2917 /* These are used by the code below that is if 0'ed away */
2919 tree type
, elts
, result
;
2922 if (sizeof (CUMULATIVE_ARGS
) % sizeof (int) != 0)
2927 if (!host_integerp (TREE_VALUE (arglist
), 0))
2928 error ("argument of `__builtin_args_info' must be constant");
2931 HOST_WIDE_INT wordnum
= tree_low_cst (TREE_VALUE (arglist
), 0);
2933 if (wordnum
< 0 || wordnum
>= nwords
)
2934 error ("argument of `__builtin_args_info' out of range");
2936 return GEN_INT (word_ptr
[wordnum
]);
2940 error ("missing argument in `__builtin_args_info'");
2945 for (i
= 0; i
< nwords
; i
++)
2946 elts
= tree_cons (NULL_TREE
, build_int_2 (word_ptr
[i
], 0));
2948 type
= build_array_type (integer_type_node
,
2949 build_index_type (build_int_2 (nwords
, 0)));
2950 result
= build (CONSTRUCTOR
, type
, NULL_TREE
, nreverse (elts
));
2951 TREE_CONSTANT (result
) = 1;
2952 TREE_STATIC (result
) = 1;
2953 result
= build1 (INDIRECT_REF
, build_pointer_type (type
), result
);
2954 TREE_CONSTANT (result
) = 1;
2955 return expand_expr (result
, NULL_RTX
, VOIDmode
, 0);
2959 /* Expand ARGLIST, from a call to __builtin_next_arg. */
2962 expand_builtin_next_arg (arglist
)
2965 tree fntype
= TREE_TYPE (current_function_decl
);
2967 if (TYPE_ARG_TYPES (fntype
) == 0
2968 || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype
)))
2971 error ("`va_start' used in function with fixed args");
2977 tree last_parm
= tree_last (DECL_ARGUMENTS (current_function_decl
));
2978 tree arg
= TREE_VALUE (arglist
);
2980 /* Strip off all nops for the sake of the comparison. This
2981 is not quite the same as STRIP_NOPS. It does more.
2982 We must also strip off INDIRECT_EXPR for C++ reference
2984 while (TREE_CODE (arg
) == NOP_EXPR
2985 || TREE_CODE (arg
) == CONVERT_EXPR
2986 || TREE_CODE (arg
) == NON_LVALUE_EXPR
2987 || TREE_CODE (arg
) == INDIRECT_REF
)
2988 arg
= TREE_OPERAND (arg
, 0);
2989 if (arg
!= last_parm
)
2990 warning ("second parameter of `va_start' not last named argument");
2993 /* Evidently an out of date version of <stdarg.h>; can't validate
2994 va_start's second argument, but can still work as intended. */
2995 warning ("`__builtin_next_arg' called without an argument");
2997 return expand_binop (Pmode
, add_optab
,
2998 current_function_internal_arg_pointer
,
2999 current_function_arg_offset_rtx
,
3000 NULL_RTX
, 0, OPTAB_LIB_WIDEN
);
3003 /* Make it easier for the backends by protecting the valist argument
3004 from multiple evaluations. */
3007 stabilize_va_list (valist
, needs_lvalue
)
3011 if (TREE_CODE (va_list_type_node
) == ARRAY_TYPE
)
3013 if (TREE_SIDE_EFFECTS (valist
))
3014 valist
= save_expr (valist
);
3016 /* For this case, the backends will be expecting a pointer to
3017 TREE_TYPE (va_list_type_node), but it's possible we've
3018 actually been given an array (an actual va_list_type_node).
3020 if (TREE_CODE (TREE_TYPE (valist
)) == ARRAY_TYPE
)
3022 tree p1
= build_pointer_type (TREE_TYPE (va_list_type_node
));
3023 tree p2
= build_pointer_type (va_list_type_node
);
3025 valist
= build1 (ADDR_EXPR
, p2
, valist
);
3026 valist
= fold (build1 (NOP_EXPR
, p1
, valist
));
3035 if (! TREE_SIDE_EFFECTS (valist
))
3038 pt
= build_pointer_type (va_list_type_node
);
3039 valist
= fold (build1 (ADDR_EXPR
, pt
, valist
));
3040 TREE_SIDE_EFFECTS (valist
) = 1;
3043 if (TREE_SIDE_EFFECTS (valist
))
3044 valist
= save_expr (valist
);
3045 valist
= fold (build1 (INDIRECT_REF
, TREE_TYPE (TREE_TYPE (valist
)),
3052 /* The "standard" implementation of va_start: just assign `nextarg' to
3056 std_expand_builtin_va_start (valist
, nextarg
)
3062 t
= build (MODIFY_EXPR
, TREE_TYPE (valist
), valist
,
3063 make_tree (ptr_type_node
, nextarg
));
3064 TREE_SIDE_EFFECTS (t
) = 1;
3066 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
3069 /* Expand ARGLIST, from a call to __builtin_va_start. */
3072 expand_builtin_va_start (arglist
)
3078 chain
= TREE_CHAIN (arglist
);
3080 if (TREE_CHAIN (chain
))
3081 error ("too many arguments to function `va_start'");
3083 nextarg
= expand_builtin_next_arg (chain
);
3084 valist
= stabilize_va_list (TREE_VALUE (arglist
), 1);
3086 #ifdef EXPAND_BUILTIN_VA_START
3087 EXPAND_BUILTIN_VA_START (valist
, nextarg
);
3089 std_expand_builtin_va_start (valist
, nextarg
);
3095 /* The "standard" implementation of va_arg: read the value from the
3096 current (padded) address and increment by the (padded) size. */
3099 std_expand_builtin_va_arg (valist
, type
)
3102 tree addr_tree
, t
, type_size
= NULL
;
3103 tree align
, alignm1
;
3107 /* Compute the rounded size of the type. */
3108 align
= size_int (PARM_BOUNDARY
/ BITS_PER_UNIT
);
3109 alignm1
= size_int (PARM_BOUNDARY
/ BITS_PER_UNIT
- 1);
3110 if (type
== error_mark_node
3111 || (type_size
= TYPE_SIZE_UNIT (TYPE_MAIN_VARIANT (type
))) == NULL
3112 || TREE_OVERFLOW (type_size
))
3113 rounded_size
= size_zero_node
;
3115 rounded_size
= fold (build (MULT_EXPR
, sizetype
,
3116 fold (build (TRUNC_DIV_EXPR
, sizetype
,
3117 fold (build (PLUS_EXPR
, sizetype
,
3118 type_size
, alignm1
)),
3124 if (PAD_VARARGS_DOWN
&& ! integer_zerop (rounded_size
))
3126 /* Small args are padded downward. */
3127 addr_tree
= fold (build (PLUS_EXPR
, TREE_TYPE (addr_tree
), addr_tree
,
3128 fold (build (COND_EXPR
, sizetype
,
3129 fold (build (GT_EXPR
, sizetype
,
3133 fold (build (MINUS_EXPR
, sizetype
,
3138 addr
= expand_expr (addr_tree
, NULL_RTX
, Pmode
, EXPAND_NORMAL
);
3139 addr
= copy_to_reg (addr
);
3141 /* Compute new value for AP. */
3142 if (! integer_zerop (rounded_size
))
3144 t
= build (MODIFY_EXPR
, TREE_TYPE (valist
), valist
,
3145 build (PLUS_EXPR
, TREE_TYPE (valist
), valist
,
3147 TREE_SIDE_EFFECTS (t
) = 1;
3148 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
3154 /* Expand __builtin_va_arg, which is not really a builtin function, but
3155 a very special sort of operator. */
3158 expand_builtin_va_arg (valist
, type
)
3162 tree promoted_type
, want_va_type
, have_va_type
;
3164 /* Verify that valist is of the proper type. */
3166 want_va_type
= va_list_type_node
;
3167 have_va_type
= TREE_TYPE (valist
);
3168 if (TREE_CODE (want_va_type
) == ARRAY_TYPE
)
3170 /* If va_list is an array type, the argument may have decayed
3171 to a pointer type, e.g. by being passed to another function.
3172 In that case, unwrap both types so that we can compare the
3173 underlying records. */
3174 if (TREE_CODE (have_va_type
) == ARRAY_TYPE
3175 || TREE_CODE (have_va_type
) == POINTER_TYPE
)
3177 want_va_type
= TREE_TYPE (want_va_type
);
3178 have_va_type
= TREE_TYPE (have_va_type
);
3181 if (TYPE_MAIN_VARIANT (want_va_type
) != TYPE_MAIN_VARIANT (have_va_type
))
3183 error ("first argument to `va_arg' not of type `va_list'");
3187 /* Generate a diagnostic for requesting data of a type that cannot
3188 be passed through `...' due to type promotion at the call site. */
3189 else if ((promoted_type
= (*lang_hooks
.types
.type_promotes_to
) (type
))
3192 const char *name
= "<anonymous type>", *pname
= 0;
3193 static bool gave_help
;
3195 if (TYPE_NAME (type
))
3197 if (TREE_CODE (TYPE_NAME (type
)) == IDENTIFIER_NODE
)
3198 name
= IDENTIFIER_POINTER (TYPE_NAME (type
));
3199 else if (TREE_CODE (TYPE_NAME (type
)) == TYPE_DECL
3200 && DECL_NAME (TYPE_NAME (type
)))
3201 name
= IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type
)));
3203 if (TYPE_NAME (promoted_type
))
3205 if (TREE_CODE (TYPE_NAME (promoted_type
)) == IDENTIFIER_NODE
)
3206 pname
= IDENTIFIER_POINTER (TYPE_NAME (promoted_type
));
3207 else if (TREE_CODE (TYPE_NAME (promoted_type
)) == TYPE_DECL
3208 && DECL_NAME (TYPE_NAME (promoted_type
)))
3209 pname
= IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (promoted_type
)));
3212 /* Unfortunately, this is merely undefined, rather than a constraint
3213 violation, so we cannot make this an error. If this call is never
3214 executed, the program is still strictly conforming. */
3215 warning ("`%s' is promoted to `%s' when passed through `...'",
3220 warning ("(so you should pass `%s' not `%s' to `va_arg')",
3224 /* We can, however, treat "undefined" any way we please.
3225 Call abort to encourage the user to fix the program. */
3226 expand_builtin_trap ();
3228 /* This is dead code, but go ahead and finish so that the
3229 mode of the result comes out right. */
3234 /* Make it easier for the backends by protecting the valist argument
3235 from multiple evaluations. */
3236 valist
= stabilize_va_list (valist
, 0);
3238 #ifdef EXPAND_BUILTIN_VA_ARG
3239 addr
= EXPAND_BUILTIN_VA_ARG (valist
, type
);
3241 addr
= std_expand_builtin_va_arg (valist
, type
);
3245 #ifdef POINTERS_EXTEND_UNSIGNED
3246 if (GET_MODE (addr
) != Pmode
)
3247 addr
= convert_memory_address (Pmode
, addr
);
3250 result
= gen_rtx_MEM (TYPE_MODE (type
), addr
);
3251 set_mem_alias_set (result
, get_varargs_alias_set ());
3256 /* Expand ARGLIST, from a call to __builtin_va_end. */
3259 expand_builtin_va_end (arglist
)
3262 tree valist
= TREE_VALUE (arglist
);
3264 #ifdef EXPAND_BUILTIN_VA_END
3265 valist
= stabilize_va_list (valist
, 0);
3266 EXPAND_BUILTIN_VA_END (arglist
);
3268 /* Evaluate for side effects, if needed. I hate macros that don't
3270 if (TREE_SIDE_EFFECTS (valist
))
3271 expand_expr (valist
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
3277 /* Expand ARGLIST, from a call to __builtin_va_copy. We do this as a
3278 builtin rather than just as an assignment in stdarg.h because of the
3279 nastiness of array-type va_list types. */
3282 expand_builtin_va_copy (arglist
)
3287 dst
= TREE_VALUE (arglist
);
3288 src
= TREE_VALUE (TREE_CHAIN (arglist
));
3290 dst
= stabilize_va_list (dst
, 1);
3291 src
= stabilize_va_list (src
, 0);
3293 if (TREE_CODE (va_list_type_node
) != ARRAY_TYPE
)
3295 t
= build (MODIFY_EXPR
, va_list_type_node
, dst
, src
);
3296 TREE_SIDE_EFFECTS (t
) = 1;
3297 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
3301 rtx dstb
, srcb
, size
;
3303 /* Evaluate to pointers. */
3304 dstb
= expand_expr (dst
, NULL_RTX
, Pmode
, EXPAND_NORMAL
);
3305 srcb
= expand_expr (src
, NULL_RTX
, Pmode
, EXPAND_NORMAL
);
3306 size
= expand_expr (TYPE_SIZE_UNIT (va_list_type_node
), NULL_RTX
,
3307 VOIDmode
, EXPAND_NORMAL
);
3309 #ifdef POINTERS_EXTEND_UNSIGNED
3310 if (GET_MODE (dstb
) != Pmode
)
3311 dstb
= convert_memory_address (Pmode
, dstb
);
3313 if (GET_MODE (srcb
) != Pmode
)
3314 srcb
= convert_memory_address (Pmode
, srcb
);
3317 /* "Dereference" to BLKmode memories. */
3318 dstb
= gen_rtx_MEM (BLKmode
, dstb
);
3319 set_mem_alias_set (dstb
, get_alias_set (TREE_TYPE (TREE_TYPE (dst
))));
3320 set_mem_align (dstb
, TYPE_ALIGN (va_list_type_node
));
3321 srcb
= gen_rtx_MEM (BLKmode
, srcb
);
3322 set_mem_alias_set (srcb
, get_alias_set (TREE_TYPE (TREE_TYPE (src
))));
3323 set_mem_align (srcb
, TYPE_ALIGN (va_list_type_node
));
3326 emit_block_move (dstb
, srcb
, size
, BLOCK_OP_NORMAL
);
3332 /* Expand a call to one of the builtin functions __builtin_frame_address or
3333 __builtin_return_address. */
3336 expand_builtin_frame_address (exp
)
3339 tree fndecl
= TREE_OPERAND (TREE_OPERAND (exp
, 0), 0);
3340 tree arglist
= TREE_OPERAND (exp
, 1);
3342 /* The argument must be a nonnegative integer constant.
3343 It counts the number of frames to scan up the stack.
3344 The value is the return address saved in that frame. */
3346 /* Warning about missing arg was already issued. */
3348 else if (! host_integerp (TREE_VALUE (arglist
), 1))
3350 if (DECL_FUNCTION_CODE (fndecl
) == BUILT_IN_FRAME_ADDRESS
)
3351 error ("invalid arg to `__builtin_frame_address'");
3353 error ("invalid arg to `__builtin_return_address'");
3359 = expand_builtin_return_addr (DECL_FUNCTION_CODE (fndecl
),
3360 tree_low_cst (TREE_VALUE (arglist
), 1),
3361 hard_frame_pointer_rtx
);
3363 /* Some ports cannot access arbitrary stack frames. */
3366 if (DECL_FUNCTION_CODE (fndecl
) == BUILT_IN_FRAME_ADDRESS
)
3367 warning ("unsupported arg to `__builtin_frame_address'");
3369 warning ("unsupported arg to `__builtin_return_address'");
3373 /* For __builtin_frame_address, return what we've got. */
3374 if (DECL_FUNCTION_CODE (fndecl
) == BUILT_IN_FRAME_ADDRESS
)
3377 if (GET_CODE (tem
) != REG
3378 && ! CONSTANT_P (tem
))
3379 tem
= copy_to_mode_reg (Pmode
, tem
);
3384 /* Expand a call to the alloca builtin, with arguments ARGLIST. Return 0 if
3385 we failed and the caller should emit a normal call, otherwise try to get
3386 the result in TARGET, if convenient. */
3389 expand_builtin_alloca (arglist
, target
)
3396 if (!validate_arglist (arglist
, INTEGER_TYPE
, VOID_TYPE
))
3399 /* Compute the argument. */
3400 op0
= expand_expr (TREE_VALUE (arglist
), NULL_RTX
, VOIDmode
, 0);
3402 /* Allocate the desired space. */
3403 result
= allocate_dynamic_stack_space (op0
, target
, BITS_PER_UNIT
);
3405 #ifdef POINTERS_EXTEND_UNSIGNED
3406 if (GET_MODE (result
) != ptr_mode
)
3407 result
= convert_memory_address (ptr_mode
, result
);
3413 /* Expand a call to the ffs builtin. The arguments are in ARGLIST.
3414 Return 0 if a normal call should be emitted rather than expanding the
3415 function in-line. If convenient, the result should be placed in TARGET.
3416 SUBTARGET may be used as the target for computing one of EXP's operands. */
3419 expand_builtin_ffs (arglist
, target
, subtarget
)
3421 rtx target
, subtarget
;
3424 if (!validate_arglist (arglist
, INTEGER_TYPE
, VOID_TYPE
))
3427 /* Compute the argument. */
3428 op0
= expand_expr (TREE_VALUE (arglist
), subtarget
, VOIDmode
, 0);
3429 /* Compute ffs, into TARGET if possible.
3430 Set TARGET to wherever the result comes back. */
3431 target
= expand_unop (TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist
))),
3432 ffs_optab
, op0
, target
, 1);
3438 /* If the string passed to fputs is a constant and is one character
3439 long, we attempt to transform this call into __builtin_fputc(). */
3442 expand_builtin_fputs (arglist
, ignore
, unlocked
)
3448 tree fn_fputc
= unlocked
? built_in_decls
[BUILT_IN_FPUTC_UNLOCKED
]
3449 : built_in_decls
[BUILT_IN_FPUTC
];
3450 tree fn_fwrite
= unlocked
? built_in_decls
[BUILT_IN_FWRITE_UNLOCKED
]
3451 : built_in_decls
[BUILT_IN_FWRITE
];
3453 /* If the return value is used, or the replacement _DECL isn't
3454 initialized, don't do the transformation. */
3455 if (!ignore
|| !fn_fputc
|| !fn_fwrite
)
3458 /* Verify the arguments in the original call. */
3459 if (!validate_arglist (arglist
, POINTER_TYPE
, POINTER_TYPE
, VOID_TYPE
))
3462 /* Get the length of the string passed to fputs. If the length
3463 can't be determined, punt. */
3464 if (!(len
= c_strlen (TREE_VALUE (arglist
)))
3465 || TREE_CODE (len
) != INTEGER_CST
)
3468 switch (compare_tree_int (len
, 1))
3470 case -1: /* length is 0, delete the call entirely . */
3472 /* Evaluate and ignore the argument in case it has
3474 expand_expr (TREE_VALUE (TREE_CHAIN (arglist
)), const0_rtx
,
3475 VOIDmode
, EXPAND_NORMAL
);
3478 case 0: /* length is 1, call fputc. */
3480 const char *p
= c_getstr (TREE_VALUE (arglist
));
3484 /* New argument list transforming fputs(string, stream) to
3485 fputc(string[0], stream). */
3487 build_tree_list (NULL_TREE
, TREE_VALUE (TREE_CHAIN (arglist
)));
3489 tree_cons (NULL_TREE
, build_int_2 (p
[0], 0), arglist
);
3495 case 1: /* length is greater than 1, call fwrite. */
3497 tree string_arg
= TREE_VALUE (arglist
);
3499 /* New argument list transforming fputs(string, stream) to
3500 fwrite(string, 1, len, stream). */
3501 arglist
= build_tree_list (NULL_TREE
, TREE_VALUE (TREE_CHAIN (arglist
)));
3502 arglist
= tree_cons (NULL_TREE
, len
, arglist
);
3503 arglist
= tree_cons (NULL_TREE
, size_one_node
, arglist
);
3504 arglist
= tree_cons (NULL_TREE
, string_arg
, arglist
);
3512 return expand_expr (build_function_call_expr (fn
, arglist
),
3513 (ignore
? const0_rtx
: NULL_RTX
),
3514 VOIDmode
, EXPAND_NORMAL
);
3517 /* Expand a call to __builtin_expect. We return our argument and emit a
3518 NOTE_INSN_EXPECTED_VALUE note. This is the expansion of __builtin_expect in
3519 a non-jump context. */
3522 expand_builtin_expect (arglist
, target
)
3529 if (arglist
== NULL_TREE
3530 || TREE_CHAIN (arglist
) == NULL_TREE
)
3532 exp
= TREE_VALUE (arglist
);
3533 c
= TREE_VALUE (TREE_CHAIN (arglist
));
3535 if (TREE_CODE (c
) != INTEGER_CST
)
3537 error ("second arg to `__builtin_expect' must be a constant");
3538 c
= integer_zero_node
;
3541 target
= expand_expr (exp
, target
, VOIDmode
, EXPAND_NORMAL
);
3543 /* Don't bother with expected value notes for integral constants. */
3544 if (GET_CODE (target
) != CONST_INT
)
3546 /* We do need to force this into a register so that we can be
3547 moderately sure to be able to correctly interpret the branch
3549 target
= force_reg (GET_MODE (target
), target
);
3551 rtx_c
= expand_expr (c
, NULL_RTX
, GET_MODE (target
), EXPAND_NORMAL
);
3553 note
= emit_note (NULL
, NOTE_INSN_EXPECTED_VALUE
);
3554 NOTE_EXPECTED_VALUE (note
) = gen_rtx_EQ (VOIDmode
, target
, rtx_c
);
3560 /* Like expand_builtin_expect, except do this in a jump context. This is
3561 called from do_jump if the conditional is a __builtin_expect. Return either
3562 a list of insns to emit the jump or NULL if we cannot optimize
3563 __builtin_expect. We need to optimize this at jump time so that machines
3564 like the PowerPC don't turn the test into a SCC operation, and then jump
3565 based on the test being 0/1. */
3568 expand_builtin_expect_jump (exp
, if_false_label
, if_true_label
)
3573 tree arglist
= TREE_OPERAND (exp
, 1);
3574 tree arg0
= TREE_VALUE (arglist
);
3575 tree arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
3578 /* Only handle __builtin_expect (test, 0) and
3579 __builtin_expect (test, 1). */
3580 if (TREE_CODE (TREE_TYPE (arg1
)) == INTEGER_TYPE
3581 && (integer_zerop (arg1
) || integer_onep (arg1
)))
3586 /* If we fail to locate an appropriate conditional jump, we'll
3587 fall back to normal evaluation. Ensure that the expression
3588 can be re-evaluated. */
3589 switch (unsafe_for_reeval (arg0
))
3594 case 1: /* Mildly unsafe. */
3595 arg0
= unsave_expr (arg0
);
3598 case 2: /* Wildly unsafe. */
3602 /* Expand the jump insns. */
3604 do_jump (arg0
, if_false_label
, if_true_label
);
3608 /* Now that the __builtin_expect has been validated, go through and add
3609 the expect's to each of the conditional jumps. If we run into an
3610 error, just give up and generate the 'safe' code of doing a SCC
3611 operation and then doing a branch on that. */
3613 while (insn
!= NULL_RTX
)
3615 rtx next
= NEXT_INSN (insn
);
3618 if (GET_CODE (insn
) == JUMP_INSN
&& any_condjump_p (insn
)
3619 && (pattern
= pc_set (insn
)) != NULL_RTX
)
3621 rtx ifelse
= SET_SRC (pattern
);
3625 if (GET_CODE (ifelse
) != IF_THEN_ELSE
)
3628 if (GET_CODE (XEXP (ifelse
, 1)) == LABEL_REF
)
3631 label
= XEXP (XEXP (ifelse
, 1), 0);
3633 /* An inverted jump reverses the probabilities. */
3634 else if (GET_CODE (XEXP (ifelse
, 2)) == LABEL_REF
)
3637 label
= XEXP (XEXP (ifelse
, 2), 0);
3639 /* We shouldn't have to worry about conditional returns during
3640 the expansion stage, but handle it gracefully anyway. */
3641 else if (GET_CODE (XEXP (ifelse
, 1)) == RETURN
)
3646 /* An inverted return reverses the probabilities. */
3647 else if (GET_CODE (XEXP (ifelse
, 2)) == RETURN
)
3655 /* If the test is expected to fail, reverse the
3657 if (integer_zerop (arg1
))
3660 /* If we are jumping to the false label, reverse the
3662 if (label
== NULL_RTX
)
3663 ; /* conditional return */
3664 else if (label
== if_false_label
)
3666 else if (label
!= if_true_label
)
3670 predict_insn_def (insn
, PRED_BUILTIN_EXPECT
, taken
);
3677 /* If no jumps were modified, fail and do __builtin_expect the normal
3687 expand_builtin_trap ()
3691 emit_insn (gen_trap ());
3694 emit_library_call (abort_libfunc
, LCT_NORETURN
, VOIDmode
, 0);
3698 /* Expand an expression EXP that calls a built-in function,
3699 with result going to TARGET if that's convenient
3700 (and in mode MODE if that's convenient).
3701 SUBTARGET may be used as the target for computing one of EXP's operands.
3702 IGNORE is nonzero if the value is to be ignored. */
3705 expand_builtin (exp
, target
, subtarget
, mode
, ignore
)
3709 enum machine_mode mode
;
3712 tree fndecl
= TREE_OPERAND (TREE_OPERAND (exp
, 0), 0);
3713 tree arglist
= TREE_OPERAND (exp
, 1);
3714 enum built_in_function fcode
= DECL_FUNCTION_CODE (fndecl
);
3716 if (DECL_BUILT_IN_CLASS (fndecl
) == BUILT_IN_MD
)
3717 return (*targetm
.expand_builtin
) (exp
, target
, subtarget
, mode
, ignore
);
3719 /* When not optimizing, generate calls to library functions for a certain
3721 if (!optimize
&& !CALLED_AS_BUILT_IN (fndecl
))
3725 case BUILT_IN_SQRTF
:
3726 case BUILT_IN_SQRTL
:
3736 case BUILT_IN_MEMSET
:
3737 case BUILT_IN_MEMCPY
:
3738 case BUILT_IN_MEMCMP
:
3740 case BUILT_IN_BZERO
:
3741 case BUILT_IN_INDEX
:
3742 case BUILT_IN_RINDEX
:
3743 case BUILT_IN_STRCHR
:
3744 case BUILT_IN_STRRCHR
:
3745 case BUILT_IN_STRLEN
:
3746 case BUILT_IN_STRCPY
:
3747 case BUILT_IN_STRNCPY
:
3748 case BUILT_IN_STRNCMP
:
3749 case BUILT_IN_STRSTR
:
3750 case BUILT_IN_STRPBRK
:
3751 case BUILT_IN_STRCAT
:
3752 case BUILT_IN_STRNCAT
:
3753 case BUILT_IN_STRSPN
:
3754 case BUILT_IN_STRCSPN
:
3755 case BUILT_IN_STRCMP
:
3757 case BUILT_IN_PUTCHAR
:
3759 case BUILT_IN_PRINTF
:
3760 case BUILT_IN_FPUTC
:
3761 case BUILT_IN_FPUTS
:
3762 case BUILT_IN_FWRITE
:
3763 case BUILT_IN_PUTCHAR_UNLOCKED
:
3764 case BUILT_IN_PUTS_UNLOCKED
:
3765 case BUILT_IN_PRINTF_UNLOCKED
:
3766 case BUILT_IN_FPUTC_UNLOCKED
:
3767 case BUILT_IN_FPUTS_UNLOCKED
:
3768 case BUILT_IN_FWRITE_UNLOCKED
:
3769 case BUILT_IN_FLOOR
:
3770 case BUILT_IN_FLOORF
:
3771 case BUILT_IN_FLOORL
:
3773 case BUILT_IN_CEILF
:
3774 case BUILT_IN_CEILL
:
3775 case BUILT_IN_TRUNC
:
3776 case BUILT_IN_TRUNCF
:
3777 case BUILT_IN_TRUNCL
:
3778 case BUILT_IN_ROUND
:
3779 case BUILT_IN_ROUNDF
:
3780 case BUILT_IN_ROUNDL
:
3781 case BUILT_IN_NEARBYINT
:
3782 case BUILT_IN_NEARBYINTF
:
3783 case BUILT_IN_NEARBYINTL
:
3784 return expand_call (exp
, target
, ignore
);
3794 case BUILT_IN_LLABS
:
3795 case BUILT_IN_IMAXABS
:
3797 case BUILT_IN_FABSF
:
3798 case BUILT_IN_FABSL
:
3799 /* build_function_call changes these into ABS_EXPR. */
3803 case BUILT_IN_CONJF
:
3804 case BUILT_IN_CONJL
:
3805 case BUILT_IN_CREAL
:
3806 case BUILT_IN_CREALF
:
3807 case BUILT_IN_CREALL
:
3808 case BUILT_IN_CIMAG
:
3809 case BUILT_IN_CIMAGF
:
3810 case BUILT_IN_CIMAGL
:
3811 /* expand_tree_builtin changes these into CONJ_EXPR, REALPART_EXPR
3812 and IMAGPART_EXPR. */
3827 /* Treat these like sqrt only if unsafe math optimizations are allowed,
3828 because of possible accuracy problems. */
3829 if (! flag_unsafe_math_optimizations
)
3832 case BUILT_IN_SQRTF
:
3833 case BUILT_IN_SQRTL
:
3834 case BUILT_IN_FLOOR
:
3835 case BUILT_IN_FLOORF
:
3836 case BUILT_IN_FLOORL
:
3838 case BUILT_IN_CEILF
:
3839 case BUILT_IN_CEILL
:
3840 case BUILT_IN_TRUNC
:
3841 case BUILT_IN_TRUNCF
:
3842 case BUILT_IN_TRUNCL
:
3843 case BUILT_IN_ROUND
:
3844 case BUILT_IN_ROUNDF
:
3845 case BUILT_IN_ROUNDL
:
3846 case BUILT_IN_NEARBYINT
:
3847 case BUILT_IN_NEARBYINTF
:
3848 case BUILT_IN_NEARBYINTL
:
3849 target
= expand_builtin_mathfn (exp
, target
, subtarget
);
3854 case BUILT_IN_APPLY_ARGS
:
3855 return expand_builtin_apply_args ();
3857 /* __builtin_apply (FUNCTION, ARGUMENTS, ARGSIZE) invokes
3858 FUNCTION with a copy of the parameters described by
3859 ARGUMENTS, and ARGSIZE. It returns a block of memory
3860 allocated on the stack into which is stored all the registers
3861 that might possibly be used for returning the result of a
3862 function. ARGUMENTS is the value returned by
3863 __builtin_apply_args. ARGSIZE is the number of bytes of
3864 arguments that must be copied. ??? How should this value be
3865 computed? We'll also need a safe worst case value for varargs
3867 case BUILT_IN_APPLY
:
3868 if (!validate_arglist (arglist
, POINTER_TYPE
,
3869 POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
)
3870 && !validate_arglist (arglist
, REFERENCE_TYPE
,
3871 POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
3879 for (t
= arglist
, i
= 0; t
; t
= TREE_CHAIN (t
), i
++)
3880 ops
[i
] = expand_expr (TREE_VALUE (t
), NULL_RTX
, VOIDmode
, 0);
3882 return expand_builtin_apply (ops
[0], ops
[1], ops
[2]);
3885 /* __builtin_return (RESULT) causes the function to return the
3886 value described by RESULT. RESULT is address of the block of
3887 memory returned by __builtin_apply. */
3888 case BUILT_IN_RETURN
:
3889 if (validate_arglist (arglist
, POINTER_TYPE
, VOID_TYPE
))
3890 expand_builtin_return (expand_expr (TREE_VALUE (arglist
),
3891 NULL_RTX
, VOIDmode
, 0));
3894 case BUILT_IN_SAVEREGS
:
3895 return expand_builtin_saveregs ();
3897 case BUILT_IN_ARGS_INFO
:
3898 return expand_builtin_args_info (exp
);
3900 /* Return the address of the first anonymous stack arg. */
3901 case BUILT_IN_NEXT_ARG
:
3902 return expand_builtin_next_arg (arglist
);
3904 case BUILT_IN_CLASSIFY_TYPE
:
3905 return expand_builtin_classify_type (arglist
);
3907 case BUILT_IN_CONSTANT_P
:
3908 return expand_builtin_constant_p (exp
);
3910 case BUILT_IN_FRAME_ADDRESS
:
3911 case BUILT_IN_RETURN_ADDRESS
:
3912 return expand_builtin_frame_address (exp
);
3914 /* Returns the address of the area where the structure is returned.
3916 case BUILT_IN_AGGREGATE_INCOMING_ADDRESS
:
3918 || ! AGGREGATE_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl
)))
3919 || GET_CODE (DECL_RTL (DECL_RESULT (current_function_decl
))) != MEM
)
3922 return XEXP (DECL_RTL (DECL_RESULT (current_function_decl
)), 0);
3924 case BUILT_IN_ALLOCA
:
3925 target
= expand_builtin_alloca (arglist
, target
);
3931 target
= expand_builtin_ffs (arglist
, target
, subtarget
);
3936 case BUILT_IN_STRLEN
:
3937 target
= expand_builtin_strlen (exp
, target
);
3942 case BUILT_IN_STRCPY
:
3943 target
= expand_builtin_strcpy (exp
, target
, mode
);
3948 case BUILT_IN_STRNCPY
:
3949 target
= expand_builtin_strncpy (arglist
, target
, mode
);
3954 case BUILT_IN_STRCAT
:
3955 target
= expand_builtin_strcat (arglist
, target
, mode
);
3960 case BUILT_IN_STRNCAT
:
3961 target
= expand_builtin_strncat (arglist
, target
, mode
);
3966 case BUILT_IN_STRSPN
:
3967 target
= expand_builtin_strspn (arglist
, target
, mode
);
3972 case BUILT_IN_STRCSPN
:
3973 target
= expand_builtin_strcspn (arglist
, target
, mode
);
3978 case BUILT_IN_STRSTR
:
3979 target
= expand_builtin_strstr (arglist
, target
, mode
);
3984 case BUILT_IN_STRPBRK
:
3985 target
= expand_builtin_strpbrk (arglist
, target
, mode
);
3990 case BUILT_IN_INDEX
:
3991 case BUILT_IN_STRCHR
:
3992 target
= expand_builtin_strchr (arglist
, target
, mode
);
3997 case BUILT_IN_RINDEX
:
3998 case BUILT_IN_STRRCHR
:
3999 target
= expand_builtin_strrchr (arglist
, target
, mode
);
4004 case BUILT_IN_MEMCPY
:
4005 target
= expand_builtin_memcpy (arglist
, target
, mode
);
4010 case BUILT_IN_MEMSET
:
4011 target
= expand_builtin_memset (exp
, target
, mode
);
4016 case BUILT_IN_BZERO
:
4017 target
= expand_builtin_bzero (exp
);
4022 case BUILT_IN_STRCMP
:
4023 target
= expand_builtin_strcmp (exp
, target
, mode
);
4028 case BUILT_IN_STRNCMP
:
4029 target
= expand_builtin_strncmp (exp
, target
, mode
);
4035 case BUILT_IN_MEMCMP
:
4036 target
= expand_builtin_memcmp (exp
, arglist
, target
, mode
);
4041 case BUILT_IN_SETJMP
:
4042 target
= expand_builtin_setjmp (arglist
, target
);
4047 /* __builtin_longjmp is passed a pointer to an array of five words.
4048 It's similar to the C library longjmp function but works with
4049 __builtin_setjmp above. */
4050 case BUILT_IN_LONGJMP
:
4051 if (!validate_arglist (arglist
, POINTER_TYPE
, INTEGER_TYPE
, VOID_TYPE
))
4055 rtx buf_addr
= expand_expr (TREE_VALUE (arglist
), subtarget
,
4057 rtx value
= expand_expr (TREE_VALUE (TREE_CHAIN (arglist
)),
4058 NULL_RTX
, VOIDmode
, 0);
4060 if (value
!= const1_rtx
)
4062 error ("__builtin_longjmp second argument must be 1");
4066 expand_builtin_longjmp (buf_addr
, value
);
4071 expand_builtin_trap ();
4074 case BUILT_IN_FPUTS
:
4075 target
= expand_builtin_fputs (arglist
, ignore
,/*unlocked=*/ 0);
4079 case BUILT_IN_FPUTS_UNLOCKED
:
4080 target
= expand_builtin_fputs (arglist
, ignore
,/*unlocked=*/ 1);
4085 /* Various hooks for the DWARF 2 __throw routine. */
4086 case BUILT_IN_UNWIND_INIT
:
4087 expand_builtin_unwind_init ();
4089 case BUILT_IN_DWARF_CFA
:
4090 return virtual_cfa_rtx
;
4091 #ifdef DWARF2_UNWIND_INFO
4092 case BUILT_IN_DWARF_FP_REGNUM
:
4093 return expand_builtin_dwarf_fp_regnum ();
4094 case BUILT_IN_INIT_DWARF_REG_SIZES
:
4095 expand_builtin_init_dwarf_reg_sizes (TREE_VALUE (arglist
));
4098 case BUILT_IN_FROB_RETURN_ADDR
:
4099 return expand_builtin_frob_return_addr (TREE_VALUE (arglist
));
4100 case BUILT_IN_EXTRACT_RETURN_ADDR
:
4101 return expand_builtin_extract_return_addr (TREE_VALUE (arglist
));
4102 case BUILT_IN_EH_RETURN
:
4103 expand_builtin_eh_return (TREE_VALUE (arglist
),
4104 TREE_VALUE (TREE_CHAIN (arglist
)));
4106 #ifdef EH_RETURN_DATA_REGNO
4107 case BUILT_IN_EH_RETURN_DATA_REGNO
:
4108 return expand_builtin_eh_return_data_regno (arglist
);
4110 case BUILT_IN_VA_START
:
4111 case BUILT_IN_STDARG_START
:
4112 return expand_builtin_va_start (arglist
);
4113 case BUILT_IN_VA_END
:
4114 return expand_builtin_va_end (arglist
);
4115 case BUILT_IN_VA_COPY
:
4116 return expand_builtin_va_copy (arglist
);
4117 case BUILT_IN_EXPECT
:
4118 return expand_builtin_expect (arglist
, target
);
4119 case BUILT_IN_PREFETCH
:
4120 expand_builtin_prefetch (arglist
);
4124 default: /* just do library call, if unknown builtin */
4125 if (!DECL_ASSEMBLER_NAME_SET_P (fndecl
))
4126 error ("built-in function `%s' not currently supported",
4127 IDENTIFIER_POINTER (DECL_NAME (fndecl
)));
4130 /* The switch statement above can drop through to cause the function
4131 to be called normally. */
4132 return expand_call (exp
, target
, ignore
);
4135 /* Determine whether a tree node represents a call to a built-in
4136 math function. If the tree T is a call to a built-in function
4137 taking a single real argument, then the return value is the
4138 DECL_FUNCTION_CODE of the call, e.g. BUILT_IN_SQRT. Otherwise
4139 the return value is END_BUILTINS. */
4141 enum built_in_function
4142 builtin_mathfn_code (t
)
4145 tree fndecl
, arglist
;
4147 if (TREE_CODE (t
) != CALL_EXPR
4148 || TREE_CODE (TREE_OPERAND (t
, 0)) != ADDR_EXPR
)
4149 return END_BUILTINS
;
4151 fndecl
= TREE_OPERAND (TREE_OPERAND (t
, 0), 0);
4152 if (TREE_CODE (fndecl
) != FUNCTION_DECL
4153 || ! DECL_BUILT_IN (fndecl
)
4154 || DECL_BUILT_IN_CLASS (fndecl
) == BUILT_IN_MD
)
4155 return END_BUILTINS
;
4157 arglist
= TREE_OPERAND (t
, 1);
4159 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist
))) != REAL_TYPE
4160 || TREE_CHAIN (arglist
))
4161 return END_BUILTINS
;
4163 return DECL_FUNCTION_CODE (fndecl
);
4166 /* Fold a call to __builtin_constant_p, if we know it will evaluate to a
4167 constant. ARGLIST is the argument list of the call. */
4170 fold_builtin_constant_p (arglist
)
4176 arglist
= TREE_VALUE (arglist
);
4178 /* We return 1 for a numeric type that's known to be a constant
4179 value at compile-time or for an aggregate type that's a
4180 literal constant. */
4181 STRIP_NOPS (arglist
);
4183 /* If we know this is a constant, emit the constant of one. */
4184 if (TREE_CODE_CLASS (TREE_CODE (arglist
)) == 'c'
4185 || (TREE_CODE (arglist
) == CONSTRUCTOR
4186 && TREE_CONSTANT (arglist
))
4187 || (TREE_CODE (arglist
) == ADDR_EXPR
4188 && TREE_CODE (TREE_OPERAND (arglist
, 0)) == STRING_CST
))
4189 return integer_one_node
;
4191 /* If we aren't going to be running CSE or this expression
4192 has side effects, show we don't know it to be a constant.
4193 Likewise if it's a pointer or aggregate type since in those
4194 case we only want literals, since those are only optimized
4195 when generating RTL, not later.
4196 And finally, if we are compiling an initializer, not code, we
4197 need to return a definite result now; there's not going to be any
4198 more optimization done. */
4199 if (TREE_SIDE_EFFECTS (arglist
) || cse_not_expected
4200 || AGGREGATE_TYPE_P (TREE_TYPE (arglist
))
4201 || POINTER_TYPE_P (TREE_TYPE (arglist
))
4203 return integer_zero_node
;
4208 /* Fold a call to __builtin_classify_type. */
4211 fold_builtin_classify_type (arglist
)
4215 return build_int_2 (no_type_class
, 0);
4217 return build_int_2 (type_to_class (TREE_TYPE (TREE_VALUE (arglist
))), 0);
4220 /* Fold a call to __builtin_inf or __builtin_huge_val. */
4223 fold_builtin_inf (type
, warn
)
4227 REAL_VALUE_TYPE real
;
4229 if (!MODE_HAS_INFINITIES (TYPE_MODE (type
)) && warn
)
4230 warning ("target format does not support infinity");
4233 return build_real (type
, real
);
4236 /* Fold a call to __builtin_nan or __builtin_nans. */
4239 fold_builtin_nan (arglist
, type
, quiet
)
4243 REAL_VALUE_TYPE real
;
4246 if (!validate_arglist (arglist
, POINTER_TYPE
, VOID_TYPE
))
4248 str
= c_getstr (TREE_VALUE (arglist
));
4252 if (!real_nan (&real
, str
, quiet
, TYPE_MODE (type
)))
4255 return build_real (type
, real
);
4258 /* Used by constant folding to eliminate some builtin calls early. EXP is
4259 the CALL_EXPR of a call to a builtin function. */
4265 tree fndecl
= TREE_OPERAND (TREE_OPERAND (exp
, 0), 0);
4266 tree arglist
= TREE_OPERAND (exp
, 1);
4267 enum built_in_function fcode
= DECL_FUNCTION_CODE (fndecl
);
4269 if (DECL_BUILT_IN_CLASS (fndecl
) == BUILT_IN_MD
)
4274 case BUILT_IN_CONSTANT_P
:
4275 return fold_builtin_constant_p (arglist
);
4277 case BUILT_IN_CLASSIFY_TYPE
:
4278 return fold_builtin_classify_type (arglist
);
4280 case BUILT_IN_STRLEN
:
4281 if (validate_arglist (arglist
, POINTER_TYPE
, VOID_TYPE
))
4283 tree len
= c_strlen (TREE_VALUE (arglist
));
4286 /* Convert from the internal "sizetype" type to "size_t". */
4288 len
= convert (size_type_node
, len
);
4295 case BUILT_IN_SQRTF
:
4296 case BUILT_IN_SQRTL
:
4297 if (validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
4299 enum built_in_function fcode
;
4300 tree arg
= TREE_VALUE (arglist
);
4302 /* Optimize sqrt of constant value. */
4303 if (TREE_CODE (arg
) == REAL_CST
4304 && ! TREE_CONSTANT_OVERFLOW (arg
))
4306 enum machine_mode mode
;
4307 REAL_VALUE_TYPE r
, x
;
4309 x
= TREE_REAL_CST (arg
);
4310 mode
= TYPE_MODE (TREE_TYPE (arg
));
4311 if (!HONOR_SNANS (mode
) || !real_isnan (&x
))
4313 real_sqrt (&r
, mode
, &x
);
4314 return build_real (TREE_TYPE (arg
), r
);
4318 /* Optimize sqrt(exp(x)) = exp(x/2.0). */
4319 fcode
= builtin_mathfn_code (arg
);
4320 if (flag_unsafe_math_optimizations
4321 && (fcode
== BUILT_IN_EXP
4322 || fcode
== BUILT_IN_EXPF
4323 || fcode
== BUILT_IN_EXPL
))
4325 tree expfn
= TREE_OPERAND (TREE_OPERAND (arg
, 0), 0);
4326 arg
= build (RDIV_EXPR
, TREE_TYPE (arg
),
4327 TREE_VALUE (TREE_OPERAND (arg
, 1)),
4328 build_real (TREE_TYPE (arg
), dconst2
));
4329 arglist
= build_tree_list (NULL_TREE
, arg
);
4330 return build_function_call_expr (expfn
, arglist
);
4338 if (validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
4340 enum built_in_function fcode
;
4341 tree arg
= TREE_VALUE (arglist
);
4343 /* Optimize exp(0.0) = 1.0. */
4344 if (real_zerop (arg
))
4345 return build_real (TREE_TYPE (arg
), dconst1
);
4347 /* Optimize exp(log(x)) = x. */
4348 fcode
= builtin_mathfn_code (arg
);
4349 if (flag_unsafe_math_optimizations
4350 && (fcode
== BUILT_IN_LOG
4351 || fcode
== BUILT_IN_LOGF
4352 || fcode
== BUILT_IN_LOGL
))
4353 return TREE_VALUE (TREE_OPERAND (arg
, 1));
4360 if (validate_arglist (arglist
, REAL_TYPE
, VOID_TYPE
))
4362 enum built_in_function fcode
;
4363 tree arg
= TREE_VALUE (arglist
);
4365 /* Optimize log(1.0) = 0.0. */
4366 if (real_onep (arg
))
4367 return build_real (TREE_TYPE (arg
), dconst0
);
4369 /* Optimize log(exp(x)) = x. */
4370 fcode
= builtin_mathfn_code (arg
);
4371 if (flag_unsafe_math_optimizations
4372 && (fcode
== BUILT_IN_EXP
4373 || fcode
== BUILT_IN_EXPF
4374 || fcode
== BUILT_IN_EXPL
))
4375 return TREE_VALUE (TREE_OPERAND (arg
, 1));
4377 /* Optimize log(sqrt(x)) = log(x)/2.0. */
4378 if (flag_unsafe_math_optimizations
4379 && (fcode
== BUILT_IN_SQRT
4380 || fcode
== BUILT_IN_SQRTF
4381 || fcode
== BUILT_IN_SQRTL
))
4383 tree logfn
= build_function_call_expr (fndecl
,
4384 TREE_OPERAND (arg
, 1));
4385 return fold (build (RDIV_EXPR
, TREE_TYPE (arg
), logfn
,
4386 build_real (TREE_TYPE (arg
), dconst2
)));
4394 return fold_builtin_inf (TREE_TYPE (TREE_TYPE (fndecl
)), true);
4396 case BUILT_IN_HUGE_VAL
:
4397 case BUILT_IN_HUGE_VALF
:
4398 case BUILT_IN_HUGE_VALL
:
4399 return fold_builtin_inf (TREE_TYPE (TREE_TYPE (fndecl
)), false);
4404 return fold_builtin_nan (arglist
, TREE_TYPE (TREE_TYPE (fndecl
)), true);
4407 case BUILT_IN_NANSF
:
4408 case BUILT_IN_NANSL
:
4409 return fold_builtin_nan (arglist
, TREE_TYPE (TREE_TYPE (fndecl
)), false);
4418 /* Conveniently construct a function call expression. */
4421 build_function_call_expr (fn
, arglist
)
4426 call_expr
= build1 (ADDR_EXPR
, build_pointer_type (TREE_TYPE (fn
)), fn
);
4427 call_expr
= build (CALL_EXPR
, TREE_TYPE (TREE_TYPE (fn
)),
4428 call_expr
, arglist
);
4429 TREE_SIDE_EFFECTS (call_expr
) = 1;
4430 return fold (call_expr
);
4433 /* This function validates the types of a function call argument list
4434 represented as a tree chain of parameters against a specified list
4435 of tree_codes. If the last specifier is a 0, that represents an
4436 ellipses, otherwise the last specifier must be a VOID_TYPE. */
4439 validate_arglist
VPARAMS ((tree arglist
, ...))
4441 enum tree_code code
;
4444 VA_OPEN (ap
, arglist
);
4445 VA_FIXEDARG (ap
, tree
, arglist
);
4449 code
= va_arg (ap
, enum tree_code
);
4453 /* This signifies an ellipses, any further arguments are all ok. */
4457 /* This signifies an endlink, if no arguments remain, return
4458 true, otherwise return false. */
4462 /* If no parameters remain or the parameter's code does not
4463 match the specified code, return false. Otherwise continue
4464 checking any remaining arguments. */
4466 || code
!= TREE_CODE (TREE_TYPE (TREE_VALUE (arglist
))))
4470 arglist
= TREE_CHAIN (arglist
);
4474 /* We need gotos here since we can only have one VA_CLOSE in a
4482 /* Default version of target-specific builtin setup that does nothing. */
4485 default_init_builtins ()
4489 /* Default target-specific builtin expander that does nothing. */
4492 default_expand_builtin (exp
, target
, subtarget
, mode
, ignore
)
4493 tree exp ATTRIBUTE_UNUSED
;
4494 rtx target ATTRIBUTE_UNUSED
;
4495 rtx subtarget ATTRIBUTE_UNUSED
;
4496 enum machine_mode mode ATTRIBUTE_UNUSED
;
4497 int ignore ATTRIBUTE_UNUSED
;