1 /* Expand builtin functions.
2 Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3 1999, 2000 Free Software Foundation, Inc.
5 This file is part of GNU CC.
7 GNU CC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 GNU CC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU CC; see the file COPYING. If not, write to
19 the Free Software Foundation, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
30 #include "hard-reg-set.h"
33 #include "insn-flags.h"
34 #include "insn-codes.h"
35 #include "insn-config.h"
39 #include "typeclass.h"
44 #define CALLED_AS_BUILT_IN(NODE) \
45 (!strncmp (IDENTIFIER_POINTER (DECL_NAME (NODE)), "__builtin_", 10))
47 /* Register mappings for target machines without register windows. */
48 #ifndef INCOMING_REGNO
49 #define INCOMING_REGNO(OUT) (OUT)
51 #ifndef OUTGOING_REGNO
52 #define OUTGOING_REGNO(IN) (IN)
55 #ifndef PAD_VARARGS_DOWN
56 #define PAD_VARARGS_DOWN BYTES_BIG_ENDIAN
59 /* Define the names of the builtin function types and codes. */
60 const char *const built_in_class_names
[4]
61 = {"NOT_BUILT_IN", "BUILT_IN_FRONTEND", "BUILT_IN_MD", "BUILT_IN_NORMAL"};
63 #define DEF_BUILTIN(x) STRINGIFY(x),
64 const char *const built_in_names
[(int) END_BUILTINS
] =
66 #include "builtins.def"
70 /* Setup an array of _DECL trees, make sure each element is
71 initialized to NULL_TREE. */
72 #define DEF_BUILTIN(x) NULL_TREE,
73 tree built_in_decls
[(int) END_BUILTINS
] =
75 #include "builtins.def"
79 tree (*lang_type_promotes_to
) PARAMS ((tree
));
81 static int get_pointer_alignment
PARAMS ((tree
, unsigned));
82 static tree c_strlen
PARAMS ((tree
));
83 static const char *c_getstr
PARAMS ((tree
));
84 static rtx c_readstr
PARAMS ((const char *,
86 static int target_char_cast
PARAMS ((tree
, char *));
87 static rtx get_memory_rtx
PARAMS ((tree
));
88 static int apply_args_size
PARAMS ((void));
89 static int apply_result_size
PARAMS ((void));
90 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
91 static rtx result_vector
PARAMS ((int, rtx
));
93 static rtx expand_builtin_setjmp
PARAMS ((tree
, rtx
));
94 static rtx expand_builtin_apply_args
PARAMS ((void));
95 static rtx expand_builtin_apply_args_1
PARAMS ((void));
96 static rtx expand_builtin_apply
PARAMS ((rtx
, rtx
, rtx
));
97 static void expand_builtin_return
PARAMS ((rtx
));
98 static rtx expand_builtin_classify_type
PARAMS ((tree
));
99 static rtx expand_builtin_mathfn
PARAMS ((tree
, rtx
, rtx
));
100 static rtx expand_builtin_constant_p
PARAMS ((tree
));
101 static rtx expand_builtin_args_info
PARAMS ((tree
));
102 static rtx expand_builtin_next_arg
PARAMS ((tree
));
103 static rtx expand_builtin_va_start
PARAMS ((int, tree
));
104 static rtx expand_builtin_va_end
PARAMS ((tree
));
105 static rtx expand_builtin_va_copy
PARAMS ((tree
));
107 static rtx expand_builtin_memcmp
PARAMS ((tree
, tree
, rtx
));
109 static rtx expand_builtin_strcmp
PARAMS ((tree
, rtx
,
111 static rtx expand_builtin_strncmp
PARAMS ((tree
, rtx
,
113 static rtx builtin_memcpy_read_str
PARAMS ((PTR
, HOST_WIDE_INT
,
115 static rtx expand_builtin_strcat
PARAMS ((tree
, rtx
,
117 static rtx expand_builtin_strncat
PARAMS ((tree
, rtx
,
119 static rtx expand_builtin_strspn
PARAMS ((tree
, rtx
,
121 static rtx expand_builtin_strcspn
PARAMS ((tree
, rtx
,
123 static rtx expand_builtin_memcpy
PARAMS ((tree
));
124 static rtx expand_builtin_strcpy
PARAMS ((tree
));
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 expand_builtin_memset
PARAMS ((tree
));
132 static rtx expand_builtin_bzero
PARAMS ((tree
));
133 static rtx expand_builtin_strlen
PARAMS ((tree
, rtx
));
134 static rtx expand_builtin_strstr
PARAMS ((tree
, rtx
,
136 static rtx expand_builtin_strpbrk
PARAMS ((tree
, rtx
,
138 static rtx expand_builtin_strchr
PARAMS ((tree
, rtx
,
140 static rtx expand_builtin_strrchr
PARAMS ((tree
, rtx
,
142 static rtx expand_builtin_alloca
PARAMS ((tree
, rtx
));
143 static rtx expand_builtin_ffs
PARAMS ((tree
, rtx
, rtx
));
144 static rtx expand_builtin_frame_address
PARAMS ((tree
));
145 static rtx expand_builtin_fputs
PARAMS ((tree
, int));
146 static tree stabilize_va_list
PARAMS ((tree
, int));
147 static rtx expand_builtin_expect
PARAMS ((tree
, rtx
));
148 static tree fold_builtin_constant_p
PARAMS ((tree
));
150 /* Return the alignment in bits of EXP, a pointer valued expression.
151 But don't return more than MAX_ALIGN no matter what.
152 The alignment returned is, by default, the alignment of the thing that
153 EXP points to (if it is not a POINTER_TYPE, 0 is returned).
155 Otherwise, look at the expression to see if we can do better, i.e., if the
156 expression is actually pointing at an object whose alignment is tighter. */
159 get_pointer_alignment (exp
, max_align
)
163 unsigned align
, inner
;
165 if (TREE_CODE (TREE_TYPE (exp
)) != POINTER_TYPE
)
168 align
= TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp
)));
169 align
= MIN (align
, max_align
);
173 switch (TREE_CODE (exp
))
177 case NON_LVALUE_EXPR
:
178 exp
= TREE_OPERAND (exp
, 0);
179 if (TREE_CODE (TREE_TYPE (exp
)) != POINTER_TYPE
)
182 inner
= TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp
)));
183 align
= MIN (inner
, max_align
);
187 /* If sum of pointer + int, restrict our maximum alignment to that
188 imposed by the integer. If not, we can't do any better than
190 if (! host_integerp (TREE_OPERAND (exp
, 1), 1))
193 while (((tree_low_cst (TREE_OPERAND (exp
, 1), 1) * BITS_PER_UNIT
)
198 exp
= TREE_OPERAND (exp
, 0);
202 /* See what we are pointing at and look at its alignment. */
203 exp
= TREE_OPERAND (exp
, 0);
204 if (TREE_CODE (exp
) == FUNCTION_DECL
)
205 align
= FUNCTION_BOUNDARY
;
206 else if (DECL_P (exp
))
207 align
= DECL_ALIGN (exp
);
208 #ifdef CONSTANT_ALIGNMENT
209 else if (TREE_CODE_CLASS (TREE_CODE (exp
)) == 'c')
210 align
= CONSTANT_ALIGNMENT (exp
, align
);
212 return MIN (align
, max_align
);
220 /* Compute the length of a C string. TREE_STRING_LENGTH is not the right
221 way, because it could contain a zero byte in the middle.
222 TREE_STRING_LENGTH is the size of the character array, not the string.
224 The value returned is of type `ssizetype'.
226 Unfortunately, string_constant can't access the values of const char
227 arrays with initializers, so neither can we do so here. */
237 src
= string_constant (src
, &offset_node
);
241 max
= TREE_STRING_LENGTH (src
) - 1;
242 ptr
= TREE_STRING_POINTER (src
);
244 if (offset_node
&& TREE_CODE (offset_node
) != INTEGER_CST
)
246 /* If the string has an internal zero byte (e.g., "foo\0bar"), we can't
247 compute the offset to the following null if we don't know where to
248 start searching for it. */
251 for (i
= 0; i
< max
; i
++)
255 /* We don't know the starting offset, but we do know that the string
256 has no internal zero bytes. We can assume that the offset falls
257 within the bounds of the string; otherwise, the programmer deserves
258 what he gets. Subtract the offset from the length of the string,
259 and return that. This would perhaps not be valid if we were dealing
260 with named arrays in addition to literal string constants. */
262 return size_diffop (size_int (max
), offset_node
);
265 /* We have a known offset into the string. Start searching there for
267 if (offset_node
== 0)
271 /* Did we get a long long offset? If so, punt. */
272 if (TREE_INT_CST_HIGH (offset_node
) != 0)
274 offset
= TREE_INT_CST_LOW (offset_node
);
277 /* If the offset is known to be out of bounds, warn, and call strlen at
279 if (offset
< 0 || offset
> max
)
281 warning ("offset outside bounds of constant string");
285 /* Use strlen to search for the first zero byte. Since any strings
286 constructed with build_string will have nulls appended, we win even
287 if we get handed something like (char[4])"abcd".
289 Since OFFSET is our starting index into the string, no further
290 calculation is needed. */
291 return ssize_int (strlen (ptr
+ offset
));
294 /* Return a char pointer for a C string if it is a string constant
295 or sum of string constant and integer constant. */
305 src
= string_constant (src
, &offset_node
);
309 max
= TREE_STRING_LENGTH (src
) - 1;
310 ptr
= TREE_STRING_POINTER (src
);
314 else if (TREE_CODE (offset_node
) != INTEGER_CST
)
318 /* Did we get a long long offset? If so, punt. */
319 if (TREE_INT_CST_HIGH (offset_node
) != 0)
321 offset
= TREE_INT_CST_LOW (offset_node
);
322 if (offset
< 0 || offset
> max
)
329 /* Return a CONST_INT or CONST_DOUBLE corresponding to target
330 reading GET_MODE_BITSIZE (MODE) bits from string constant
334 c_readstr (str
, mode
)
336 enum machine_mode mode
;
342 if (GET_MODE_CLASS (mode
) != MODE_INT
)
347 for (i
= 0; i
< GET_MODE_SIZE (mode
); i
++)
350 if (WORDS_BIG_ENDIAN
)
351 j
= GET_MODE_SIZE (mode
) - i
- 1;
352 if (BYTES_BIG_ENDIAN
!= WORDS_BIG_ENDIAN
353 && GET_MODE_SIZE (mode
) > UNITS_PER_WORD
)
354 j
= j
+ UNITS_PER_WORD
- 2 * (j
% UNITS_PER_WORD
) - 1;
356 if (j
> 2 * HOST_BITS_PER_WIDE_INT
)
359 ch
= (unsigned char) str
[i
];
360 c
[j
/ HOST_BITS_PER_WIDE_INT
] |= ch
<< (j
% HOST_BITS_PER_WIDE_INT
);
362 return immed_double_const (c
[0], c
[1], mode
);
365 /* Cast a target constant CST to target CHAR and if that value fits into
366 host char type, return zero and put that value into variable pointed by
370 target_char_cast (cst
, p
)
374 unsigned HOST_WIDE_INT val
, hostval
;
376 if (TREE_CODE (cst
) != INTEGER_CST
377 || CHAR_TYPE_SIZE
> HOST_BITS_PER_WIDE_INT
)
380 val
= TREE_INT_CST_LOW (cst
);
381 if (CHAR_TYPE_SIZE
< HOST_BITS_PER_WIDE_INT
)
382 val
&= (((unsigned HOST_WIDE_INT
) 1) << CHAR_TYPE_SIZE
) - 1;
385 if (HOST_BITS_PER_CHAR
< HOST_BITS_PER_WIDE_INT
)
386 hostval
&= (((unsigned HOST_WIDE_INT
) 1) << HOST_BITS_PER_CHAR
) - 1;
395 /* Given TEM, a pointer to a stack frame, follow the dynamic chain COUNT
396 times to get the address of either a higher stack frame, or a return
397 address located within it (depending on FNDECL_CODE). */
400 expand_builtin_return_addr (fndecl_code
, count
, tem
)
401 enum built_in_function fndecl_code
;
407 /* Some machines need special handling before we can access
408 arbitrary frames. For example, on the sparc, we must first flush
409 all register windows to the stack. */
410 #ifdef SETUP_FRAME_ADDRESSES
412 SETUP_FRAME_ADDRESSES ();
415 /* On the sparc, the return address is not in the frame, it is in a
416 register. There is no way to access it off of the current frame
417 pointer, but it can be accessed off the previous frame pointer by
418 reading the value from the register window save area. */
419 #ifdef RETURN_ADDR_IN_PREVIOUS_FRAME
420 if (fndecl_code
== BUILT_IN_RETURN_ADDRESS
)
424 /* Scan back COUNT frames to the specified frame. */
425 for (i
= 0; i
< count
; i
++)
427 /* Assume the dynamic chain pointer is in the word that the
428 frame address points to, unless otherwise specified. */
429 #ifdef DYNAMIC_CHAIN_ADDRESS
430 tem
= DYNAMIC_CHAIN_ADDRESS (tem
);
432 tem
= memory_address (Pmode
, tem
);
433 tem
= copy_to_reg (gen_rtx_MEM (Pmode
, tem
));
434 MEM_ALIAS_SET (tem
) = get_frame_alias_set ();
437 /* For __builtin_frame_address, return what we've got. */
438 if (fndecl_code
== BUILT_IN_FRAME_ADDRESS
)
441 /* For __builtin_return_address, Get the return address from that
443 #ifdef RETURN_ADDR_RTX
444 tem
= RETURN_ADDR_RTX (count
, tem
);
446 tem
= memory_address (Pmode
,
447 plus_constant (tem
, GET_MODE_SIZE (Pmode
)));
448 tem
= gen_rtx_MEM (Pmode
, tem
);
449 MEM_ALIAS_SET (tem
) = get_frame_alias_set ();
454 /* Alias set used for setjmp buffer. */
455 static HOST_WIDE_INT setjmp_alias_set
= -1;
457 /* Construct the leading half of a __builtin_setjmp call. Control will
458 return to RECEIVER_LABEL. This is used directly by sjlj exception
462 expand_builtin_setjmp_setup (buf_addr
, receiver_label
)
466 enum machine_mode sa_mode
= STACK_SAVEAREA_MODE (SAVE_NONLOCAL
);
470 if (setjmp_alias_set
== -1)
471 setjmp_alias_set
= new_alias_set ();
473 #ifdef POINTERS_EXTEND_UNSIGNED
474 buf_addr
= convert_memory_address (Pmode
, buf_addr
);
477 buf_addr
= force_reg (Pmode
, force_operand (buf_addr
, NULL_RTX
));
481 /* We store the frame pointer and the address of receiver_label in
482 the buffer and use the rest of it for the stack save area, which
483 is machine-dependent. */
485 #ifndef BUILTIN_SETJMP_FRAME_VALUE
486 #define BUILTIN_SETJMP_FRAME_VALUE virtual_stack_vars_rtx
489 mem
= gen_rtx_MEM (Pmode
, buf_addr
);
490 MEM_ALIAS_SET (mem
) = setjmp_alias_set
;
491 emit_move_insn (mem
, BUILTIN_SETJMP_FRAME_VALUE
);
493 mem
= gen_rtx_MEM (Pmode
, plus_constant (buf_addr
, GET_MODE_SIZE (Pmode
))),
494 MEM_ALIAS_SET (mem
) = setjmp_alias_set
;
496 emit_move_insn (validize_mem (mem
),
497 force_reg (Pmode
, gen_rtx_LABEL_REF (Pmode
, receiver_label
)));
499 stack_save
= gen_rtx_MEM (sa_mode
,
500 plus_constant (buf_addr
,
501 2 * GET_MODE_SIZE (Pmode
)));
502 MEM_ALIAS_SET (stack_save
) = setjmp_alias_set
;
503 emit_stack_save (SAVE_NONLOCAL
, &stack_save
, NULL_RTX
);
505 /* If there is further processing to do, do it. */
506 #ifdef HAVE_builtin_setjmp_setup
507 if (HAVE_builtin_setjmp_setup
)
508 emit_insn (gen_builtin_setjmp_setup (buf_addr
));
511 /* Tell optimize_save_area_alloca that extra work is going to
512 need to go on during alloca. */
513 current_function_calls_setjmp
= 1;
515 /* Set this so all the registers get saved in our frame; we need to be
516 able to copy the saved values for any registers from frames we unwind. */
517 current_function_has_nonlocal_label
= 1;
520 /* Construct the trailing part of a __builtin_setjmp call.
521 This is used directly by sjlj exception handling code. */
524 expand_builtin_setjmp_receiver (receiver_label
)
525 rtx receiver_label ATTRIBUTE_UNUSED
;
527 /* Clobber the FP when we get here, so we have to make sure it's
528 marked as used by this function. */
529 emit_insn (gen_rtx_USE (VOIDmode
, hard_frame_pointer_rtx
));
531 /* Mark the static chain as clobbered here so life information
532 doesn't get messed up for it. */
533 emit_insn (gen_rtx_CLOBBER (VOIDmode
, static_chain_rtx
));
535 /* Now put in the code to restore the frame pointer, and argument
536 pointer, if needed. The code below is from expand_end_bindings
537 in stmt.c; see detailed documentation there. */
538 #ifdef HAVE_nonlocal_goto
539 if (! HAVE_nonlocal_goto
)
541 emit_move_insn (virtual_stack_vars_rtx
, hard_frame_pointer_rtx
);
543 #if ARG_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
544 if (fixed_regs
[ARG_POINTER_REGNUM
])
546 #ifdef ELIMINABLE_REGS
548 static struct elims
{int from
, to
;} elim_regs
[] = ELIMINABLE_REGS
;
550 for (i
= 0; i
< ARRAY_SIZE (elim_regs
); i
++)
551 if (elim_regs
[i
].from
== ARG_POINTER_REGNUM
552 && elim_regs
[i
].to
== HARD_FRAME_POINTER_REGNUM
)
555 if (i
== ARRAY_SIZE (elim_regs
))
558 /* Now restore our arg pointer from the address at which it
559 was saved in our stack frame.
560 If there hasn't be space allocated for it yet, make
562 if (arg_pointer_save_area
== 0)
563 arg_pointer_save_area
564 = assign_stack_local (Pmode
, GET_MODE_SIZE (Pmode
), 0);
565 emit_move_insn (virtual_incoming_args_rtx
,
566 copy_to_reg (arg_pointer_save_area
));
571 #ifdef HAVE_builtin_setjmp_receiver
572 if (HAVE_builtin_setjmp_receiver
)
573 emit_insn (gen_builtin_setjmp_receiver (receiver_label
));
576 #ifdef HAVE_nonlocal_goto_receiver
577 if (HAVE_nonlocal_goto_receiver
)
578 emit_insn (gen_nonlocal_goto_receiver ());
584 /* __builtin_setjmp is passed a pointer to an array of five words (not
585 all will be used on all machines). It operates similarly to the C
586 library function of the same name, but is more efficient. Much of
587 the code below (and for longjmp) is copied from the handling of
590 NOTE: This is intended for use by GNAT and the exception handling
591 scheme in the compiler and will only work in the method used by
595 expand_builtin_setjmp (arglist
, target
)
599 rtx buf_addr
, next_lab
, cont_lab
;
602 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist
))) != POINTER_TYPE
)
605 if (target
== 0 || GET_CODE (target
) != REG
606 || REGNO (target
) < FIRST_PSEUDO_REGISTER
)
607 target
= gen_reg_rtx (TYPE_MODE (integer_type_node
));
609 buf_addr
= expand_expr (TREE_VALUE (arglist
), NULL_RTX
, VOIDmode
, 0);
611 next_lab
= gen_label_rtx ();
612 cont_lab
= gen_label_rtx ();
614 expand_builtin_setjmp_setup (buf_addr
, next_lab
);
616 /* Set TARGET to zero and branch to the continue label. */
617 emit_move_insn (target
, const0_rtx
);
618 emit_jump_insn (gen_jump (cont_lab
));
620 emit_label (next_lab
);
622 expand_builtin_setjmp_receiver (next_lab
);
624 /* Set TARGET to one. */
625 emit_move_insn (target
, const1_rtx
);
626 emit_label (cont_lab
);
628 /* Tell flow about the strange goings on. Putting `next_lab' on
629 `nonlocal_goto_handler_labels' to indicates that function
630 calls may traverse the arc back to this label. */
632 current_function_has_nonlocal_label
= 1;
633 nonlocal_goto_handler_labels
634 = gen_rtx_EXPR_LIST (VOIDmode
, next_lab
, nonlocal_goto_handler_labels
);
639 /* __builtin_longjmp is passed a pointer to an array of five words (not
640 all will be used on all machines). It operates similarly to the C
641 library function of the same name, but is more efficient. Much of
642 the code below is copied from the handling of non-local gotos.
644 NOTE: This is intended for use by GNAT and the exception handling
645 scheme in the compiler and will only work in the method used by
649 expand_builtin_longjmp (buf_addr
, value
)
653 enum machine_mode sa_mode
= STACK_SAVEAREA_MODE (SAVE_NONLOCAL
);
655 if (setjmp_alias_set
== -1)
656 setjmp_alias_set
= new_alias_set ();
658 #ifdef POINTERS_EXTEND_UNSIGNED
659 buf_addr
= convert_memory_address (Pmode
, buf_addr
);
661 buf_addr
= force_reg (Pmode
, buf_addr
);
663 /* We used to store value in static_chain_rtx, but that fails if pointers
664 are smaller than integers. We instead require that the user must pass
665 a second argument of 1, because that is what builtin_setjmp will
666 return. This also makes EH slightly more efficient, since we are no
667 longer copying around a value that we don't care about. */
668 if (value
!= const1_rtx
)
671 current_function_calls_longjmp
= 1;
673 #ifdef HAVE_builtin_longjmp
674 if (HAVE_builtin_longjmp
)
675 emit_insn (gen_builtin_longjmp (buf_addr
));
679 fp
= gen_rtx_MEM (Pmode
, buf_addr
);
680 lab
= gen_rtx_MEM (Pmode
, plus_constant (buf_addr
,
681 GET_MODE_SIZE (Pmode
)));
683 stack
= gen_rtx_MEM (sa_mode
, plus_constant (buf_addr
,
684 2 * GET_MODE_SIZE (Pmode
)));
685 MEM_ALIAS_SET (fp
) = MEM_ALIAS_SET (lab
) = MEM_ALIAS_SET (stack
)
688 /* Pick up FP, label, and SP from the block and jump. This code is
689 from expand_goto in stmt.c; see there for detailed comments. */
690 #if HAVE_nonlocal_goto
691 if (HAVE_nonlocal_goto
)
692 /* We have to pass a value to the nonlocal_goto pattern that will
693 get copied into the static_chain pointer, but it does not matter
694 what that value is, because builtin_setjmp does not use it. */
695 emit_insn (gen_nonlocal_goto (value
, fp
, stack
, lab
));
699 lab
= copy_to_reg (lab
);
701 emit_move_insn (hard_frame_pointer_rtx
, fp
);
702 emit_stack_restore (SAVE_NONLOCAL
, stack
, NULL_RTX
);
704 emit_insn (gen_rtx_USE (VOIDmode
, hard_frame_pointer_rtx
));
705 emit_insn (gen_rtx_USE (VOIDmode
, stack_pointer_rtx
));
706 emit_indirect_jump (lab
);
711 /* Get a MEM rtx for expression EXP which is the address of an operand
712 to be used to be used in a string instruction (cmpstrsi, movstrsi, ..). */
718 rtx mem
= gen_rtx_MEM (BLKmode
,
719 memory_address (BLKmode
,
720 expand_expr (exp
, NULL_RTX
,
721 ptr_mode
, EXPAND_SUM
)));
723 /* Get an expression we can use to find the attributes to assign to MEM.
724 If it is an ADDR_EXPR, use the operand. Otherwise, dereference it if
725 we can. First remove any nops. */
726 while ((TREE_CODE (exp
) == NOP_EXPR
|| TREE_CODE (exp
) == CONVERT_EXPR
727 || TREE_CODE (exp
) == NON_LVALUE_EXPR
)
728 && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (exp
, 0))))
729 exp
= TREE_OPERAND (exp
, 0);
731 if (TREE_CODE (exp
) == ADDR_EXPR
)
732 exp
= TREE_OPERAND (exp
, 0);
733 else if (POINTER_TYPE_P (TREE_TYPE (exp
)))
734 exp
= build1 (INDIRECT_REF
, TREE_TYPE (TREE_TYPE (exp
)), exp
);
738 set_mem_attributes (mem
, exp
, 0);
740 /* memcpy, memset and other builtin stringops can alias with anything. */
741 MEM_ALIAS_SET (mem
) = 0;
745 /* Built-in functions to perform an untyped call and return. */
747 /* For each register that may be used for calling a function, this
748 gives a mode used to copy the register's value. VOIDmode indicates
749 the register is not used for calling a function. If the machine
750 has register windows, this gives only the outbound registers.
751 INCOMING_REGNO gives the corresponding inbound register. */
752 static enum machine_mode apply_args_mode
[FIRST_PSEUDO_REGISTER
];
754 /* For each register that may be used for returning values, this gives
755 a mode used to copy the register's value. VOIDmode indicates the
756 register is not used for returning values. If the machine has
757 register windows, this gives only the outbound registers.
758 INCOMING_REGNO gives the corresponding inbound register. */
759 static enum machine_mode apply_result_mode
[FIRST_PSEUDO_REGISTER
];
761 /* For each register that may be used for calling a function, this
762 gives the offset of that register into the block returned by
763 __builtin_apply_args. 0 indicates that the register is not
764 used for calling a function. */
765 static int apply_args_reg_offset
[FIRST_PSEUDO_REGISTER
];
767 /* Return the offset of register REGNO into the block returned by
768 __builtin_apply_args. This is not declared static, since it is
769 needed in objc-act.c. */
772 apply_args_register_offset (regno
)
777 /* Arguments are always put in outgoing registers (in the argument
778 block) if such make sense. */
779 #ifdef OUTGOING_REGNO
780 regno
= OUTGOING_REGNO(regno
);
782 return apply_args_reg_offset
[regno
];
785 /* Return the size required for the block returned by __builtin_apply_args,
786 and initialize apply_args_mode. */
791 static int size
= -1;
793 enum machine_mode mode
;
795 /* The values computed by this function never change. */
798 /* The first value is the incoming arg-pointer. */
799 size
= GET_MODE_SIZE (Pmode
);
801 /* The second value is the structure value address unless this is
802 passed as an "invisible" first argument. */
803 if (struct_value_rtx
)
804 size
+= GET_MODE_SIZE (Pmode
);
806 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
807 if (FUNCTION_ARG_REGNO_P (regno
))
809 /* Search for the proper mode for copying this register's
810 value. I'm not sure this is right, but it works so far. */
811 enum machine_mode best_mode
= VOIDmode
;
813 for (mode
= GET_CLASS_NARROWEST_MODE (MODE_INT
);
815 mode
= GET_MODE_WIDER_MODE (mode
))
816 if (HARD_REGNO_MODE_OK (regno
, mode
)
817 && HARD_REGNO_NREGS (regno
, mode
) == 1)
820 if (best_mode
== VOIDmode
)
821 for (mode
= GET_CLASS_NARROWEST_MODE (MODE_FLOAT
);
823 mode
= GET_MODE_WIDER_MODE (mode
))
824 if (HARD_REGNO_MODE_OK (regno
, mode
)
825 && (mov_optab
->handlers
[(int) mode
].insn_code
826 != CODE_FOR_nothing
))
830 if (mode
== VOIDmode
)
833 align
= GET_MODE_ALIGNMENT (mode
) / BITS_PER_UNIT
;
834 if (size
% align
!= 0)
835 size
= CEIL (size
, align
) * align
;
836 apply_args_reg_offset
[regno
] = size
;
837 size
+= GET_MODE_SIZE (mode
);
838 apply_args_mode
[regno
] = mode
;
842 apply_args_mode
[regno
] = VOIDmode
;
843 apply_args_reg_offset
[regno
] = 0;
849 /* Return the size required for the block returned by __builtin_apply,
850 and initialize apply_result_mode. */
855 static int size
= -1;
857 enum machine_mode mode
;
859 /* The values computed by this function never change. */
864 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
865 if (FUNCTION_VALUE_REGNO_P (regno
))
867 /* Search for the proper mode for copying this register's
868 value. I'm not sure this is right, but it works so far. */
869 enum machine_mode best_mode
= VOIDmode
;
871 for (mode
= GET_CLASS_NARROWEST_MODE (MODE_INT
);
873 mode
= GET_MODE_WIDER_MODE (mode
))
874 if (HARD_REGNO_MODE_OK (regno
, mode
))
877 if (best_mode
== VOIDmode
)
878 for (mode
= GET_CLASS_NARROWEST_MODE (MODE_FLOAT
);
880 mode
= GET_MODE_WIDER_MODE (mode
))
881 if (HARD_REGNO_MODE_OK (regno
, mode
)
882 && (mov_optab
->handlers
[(int) mode
].insn_code
883 != CODE_FOR_nothing
))
887 if (mode
== VOIDmode
)
890 align
= GET_MODE_ALIGNMENT (mode
) / BITS_PER_UNIT
;
891 if (size
% align
!= 0)
892 size
= CEIL (size
, align
) * align
;
893 size
+= GET_MODE_SIZE (mode
);
894 apply_result_mode
[regno
] = mode
;
897 apply_result_mode
[regno
] = VOIDmode
;
899 /* Allow targets that use untyped_call and untyped_return to override
900 the size so that machine-specific information can be stored here. */
901 #ifdef APPLY_RESULT_SIZE
902 size
= APPLY_RESULT_SIZE
;
908 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
909 /* Create a vector describing the result block RESULT. If SAVEP is true,
910 the result block is used to save the values; otherwise it is used to
911 restore the values. */
914 result_vector (savep
, result
)
918 int regno
, size
, align
, nelts
;
919 enum machine_mode mode
;
921 rtx
*savevec
= (rtx
*) alloca (FIRST_PSEUDO_REGISTER
* sizeof (rtx
));
924 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
925 if ((mode
= apply_result_mode
[regno
]) != VOIDmode
)
927 align
= GET_MODE_ALIGNMENT (mode
) / BITS_PER_UNIT
;
928 if (size
% align
!= 0)
929 size
= CEIL (size
, align
) * align
;
930 reg
= gen_rtx_REG (mode
, savep
? regno
: INCOMING_REGNO (regno
));
931 mem
= change_address (result
, mode
,
932 plus_constant (XEXP (result
, 0), size
));
933 savevec
[nelts
++] = (savep
934 ? gen_rtx_SET (VOIDmode
, mem
, reg
)
935 : gen_rtx_SET (VOIDmode
, reg
, mem
));
936 size
+= GET_MODE_SIZE (mode
);
938 return gen_rtx_PARALLEL (VOIDmode
, gen_rtvec_v (nelts
, savevec
));
940 #endif /* HAVE_untyped_call or HAVE_untyped_return */
942 /* Save the state required to perform an untyped call with the same
943 arguments as were passed to the current function. */
946 expand_builtin_apply_args_1 ()
949 int size
, align
, regno
;
950 enum machine_mode mode
;
952 /* Create a block where the arg-pointer, structure value address,
953 and argument registers can be saved. */
954 registers
= assign_stack_local (BLKmode
, apply_args_size (), -1);
956 /* Walk past the arg-pointer and structure value address. */
957 size
= GET_MODE_SIZE (Pmode
);
958 if (struct_value_rtx
)
959 size
+= GET_MODE_SIZE (Pmode
);
961 /* Save each register used in calling a function to the block. */
962 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
963 if ((mode
= apply_args_mode
[regno
]) != VOIDmode
)
967 align
= GET_MODE_ALIGNMENT (mode
) / BITS_PER_UNIT
;
968 if (size
% align
!= 0)
969 size
= CEIL (size
, align
) * align
;
971 tem
= gen_rtx_REG (mode
, INCOMING_REGNO (regno
));
973 emit_move_insn (change_address (registers
, mode
,
974 plus_constant (XEXP (registers
, 0),
977 size
+= GET_MODE_SIZE (mode
);
980 /* Save the arg pointer to the block. */
981 emit_move_insn (change_address (registers
, Pmode
, XEXP (registers
, 0)),
982 copy_to_reg (virtual_incoming_args_rtx
));
983 size
= GET_MODE_SIZE (Pmode
);
985 /* Save the structure value address unless this is passed as an
986 "invisible" first argument. */
987 if (struct_value_incoming_rtx
)
989 emit_move_insn (change_address (registers
, Pmode
,
990 plus_constant (XEXP (registers
, 0),
992 copy_to_reg (struct_value_incoming_rtx
));
993 size
+= GET_MODE_SIZE (Pmode
);
996 /* Return the address of the block. */
997 return copy_addr_to_reg (XEXP (registers
, 0));
1000 /* __builtin_apply_args returns block of memory allocated on
1001 the stack into which is stored the arg pointer, structure
1002 value address, static chain, and all the registers that might
1003 possibly be used in performing a function call. The code is
1004 moved to the start of the function so the incoming values are
1007 expand_builtin_apply_args ()
1009 /* Don't do __builtin_apply_args more than once in a function.
1010 Save the result of the first call and reuse it. */
1011 if (apply_args_value
!= 0)
1012 return apply_args_value
;
1014 /* When this function is called, it means that registers must be
1015 saved on entry to this function. So we migrate the
1016 call to the first insn of this function. */
1021 temp
= expand_builtin_apply_args_1 ();
1025 apply_args_value
= temp
;
1027 /* Put the sequence after the NOTE that starts the function.
1028 If this is inside a SEQUENCE, make the outer-level insn
1029 chain current, so the code is placed at the start of the
1031 push_topmost_sequence ();
1032 emit_insns_before (seq
, NEXT_INSN (get_insns ()));
1033 pop_topmost_sequence ();
1038 /* Perform an untyped call and save the state required to perform an
1039 untyped return of whatever value was returned by the given function. */
1042 expand_builtin_apply (function
, arguments
, argsize
)
1043 rtx function
, arguments
, argsize
;
1045 int size
, align
, regno
;
1046 enum machine_mode mode
;
1047 rtx incoming_args
, result
, reg
, dest
, call_insn
;
1048 rtx old_stack_level
= 0;
1049 rtx call_fusage
= 0;
1051 /* Create a block where the return registers can be saved. */
1052 result
= assign_stack_local (BLKmode
, apply_result_size (), -1);
1054 /* Fetch the arg pointer from the ARGUMENTS block. */
1055 incoming_args
= gen_reg_rtx (Pmode
);
1056 emit_move_insn (incoming_args
,
1057 gen_rtx_MEM (Pmode
, arguments
));
1058 #ifndef STACK_GROWS_DOWNWARD
1059 incoming_args
= expand_binop (Pmode
, sub_optab
, incoming_args
, argsize
,
1060 incoming_args
, 0, OPTAB_LIB_WIDEN
);
1063 /* Perform postincrements before actually calling the function. */
1066 /* Push a new argument block and copy the arguments. Do not allow
1067 the (potential) memcpy call below to interfere with our stack
1069 do_pending_stack_adjust ();
1072 /* Save the stack with nonlocal if available */
1073 #ifdef HAVE_save_stack_nonlocal
1074 if (HAVE_save_stack_nonlocal
)
1075 emit_stack_save (SAVE_NONLOCAL
, &old_stack_level
, NULL_RTX
);
1078 emit_stack_save (SAVE_BLOCK
, &old_stack_level
, NULL_RTX
);
1080 /* Push a block of memory onto the stack to store the memory arguments.
1081 Save the address in a register, and copy the memory arguments. ??? I
1082 haven't figured out how the calling convention macros effect this,
1083 but it's likely that the source and/or destination addresses in
1084 the block copy will need updating in machine specific ways. */
1085 dest
= allocate_dynamic_stack_space (argsize
, 0, BITS_PER_UNIT
);
1086 emit_block_move (gen_rtx_MEM (BLKmode
, dest
),
1087 gen_rtx_MEM (BLKmode
, incoming_args
),
1088 argsize
, PARM_BOUNDARY
);
1090 /* Refer to the argument block. */
1092 arguments
= gen_rtx_MEM (BLKmode
, arguments
);
1094 /* Walk past the arg-pointer and structure value address. */
1095 size
= GET_MODE_SIZE (Pmode
);
1096 if (struct_value_rtx
)
1097 size
+= GET_MODE_SIZE (Pmode
);
1099 /* Restore each of the registers previously saved. Make USE insns
1100 for each of these registers for use in making the call. */
1101 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
1102 if ((mode
= apply_args_mode
[regno
]) != VOIDmode
)
1104 align
= GET_MODE_ALIGNMENT (mode
) / BITS_PER_UNIT
;
1105 if (size
% align
!= 0)
1106 size
= CEIL (size
, align
) * align
;
1107 reg
= gen_rtx_REG (mode
, regno
);
1108 emit_move_insn (reg
,
1109 change_address (arguments
, mode
,
1110 plus_constant (XEXP (arguments
, 0),
1113 use_reg (&call_fusage
, reg
);
1114 size
+= GET_MODE_SIZE (mode
);
1117 /* Restore the structure value address unless this is passed as an
1118 "invisible" first argument. */
1119 size
= GET_MODE_SIZE (Pmode
);
1120 if (struct_value_rtx
)
1122 rtx value
= gen_reg_rtx (Pmode
);
1123 emit_move_insn (value
,
1124 change_address (arguments
, Pmode
,
1125 plus_constant (XEXP (arguments
, 0),
1127 emit_move_insn (struct_value_rtx
, value
);
1128 if (GET_CODE (struct_value_rtx
) == REG
)
1129 use_reg (&call_fusage
, struct_value_rtx
);
1130 size
+= GET_MODE_SIZE (Pmode
);
1133 /* All arguments and registers used for the call are set up by now! */
1134 function
= prepare_call_address (function
, NULL_TREE
, &call_fusage
, 0);
1136 /* Ensure address is valid. SYMBOL_REF is already valid, so no need,
1137 and we don't want to load it into a register as an optimization,
1138 because prepare_call_address already did it if it should be done. */
1139 if (GET_CODE (function
) != SYMBOL_REF
)
1140 function
= memory_address (FUNCTION_MODE
, function
);
1142 /* Generate the actual call instruction and save the return value. */
1143 #ifdef HAVE_untyped_call
1144 if (HAVE_untyped_call
)
1145 emit_call_insn (gen_untyped_call (gen_rtx_MEM (FUNCTION_MODE
, function
),
1146 result
, result_vector (1, result
)));
1149 #ifdef HAVE_call_value
1150 if (HAVE_call_value
)
1154 /* Locate the unique return register. It is not possible to
1155 express a call that sets more than one return register using
1156 call_value; use untyped_call for that. In fact, untyped_call
1157 only needs to save the return registers in the given block. */
1158 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
1159 if ((mode
= apply_result_mode
[regno
]) != VOIDmode
)
1162 abort (); /* HAVE_untyped_call required. */
1163 valreg
= gen_rtx_REG (mode
, regno
);
1166 emit_call_insn (GEN_CALL_VALUE (valreg
,
1167 gen_rtx_MEM (FUNCTION_MODE
, function
),
1168 const0_rtx
, NULL_RTX
, const0_rtx
));
1170 emit_move_insn (change_address (result
, GET_MODE (valreg
),
1178 /* Find the CALL insn we just emitted. */
1179 for (call_insn
= get_last_insn ();
1180 call_insn
&& GET_CODE (call_insn
) != CALL_INSN
;
1181 call_insn
= PREV_INSN (call_insn
))
1187 /* Put the register usage information on the CALL. If there is already
1188 some usage information, put ours at the end. */
1189 if (CALL_INSN_FUNCTION_USAGE (call_insn
))
1193 for (link
= CALL_INSN_FUNCTION_USAGE (call_insn
); XEXP (link
, 1) != 0;
1194 link
= XEXP (link
, 1))
1197 XEXP (link
, 1) = call_fusage
;
1200 CALL_INSN_FUNCTION_USAGE (call_insn
) = call_fusage
;
1202 /* Restore the stack. */
1203 #ifdef HAVE_save_stack_nonlocal
1204 if (HAVE_save_stack_nonlocal
)
1205 emit_stack_restore (SAVE_NONLOCAL
, old_stack_level
, NULL_RTX
);
1208 emit_stack_restore (SAVE_BLOCK
, old_stack_level
, NULL_RTX
);
1212 /* Return the address of the result block. */
1213 return copy_addr_to_reg (XEXP (result
, 0));
1216 /* Perform an untyped return. */
1219 expand_builtin_return (result
)
1222 int size
, align
, regno
;
1223 enum machine_mode mode
;
1225 rtx call_fusage
= 0;
1227 apply_result_size ();
1228 result
= gen_rtx_MEM (BLKmode
, result
);
1230 #ifdef HAVE_untyped_return
1231 if (HAVE_untyped_return
)
1233 emit_jump_insn (gen_untyped_return (result
, result_vector (0, result
)));
1239 /* Restore the return value and note that each value is used. */
1241 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
1242 if ((mode
= apply_result_mode
[regno
]) != VOIDmode
)
1244 align
= GET_MODE_ALIGNMENT (mode
) / BITS_PER_UNIT
;
1245 if (size
% align
!= 0)
1246 size
= CEIL (size
, align
) * align
;
1247 reg
= gen_rtx_REG (mode
, INCOMING_REGNO (regno
));
1248 emit_move_insn (reg
,
1249 change_address (result
, mode
,
1250 plus_constant (XEXP (result
, 0),
1253 push_to_sequence (call_fusage
);
1254 emit_insn (gen_rtx_USE (VOIDmode
, reg
));
1255 call_fusage
= get_insns ();
1257 size
+= GET_MODE_SIZE (mode
);
1260 /* Put the USE insns before the return. */
1261 emit_insns (call_fusage
);
1263 /* Return whatever values was restored by jumping directly to the end
1265 expand_null_return ();
1268 /* Expand a call to __builtin_classify_type with arguments found in
1271 expand_builtin_classify_type (arglist
)
1276 tree type
= TREE_TYPE (TREE_VALUE (arglist
));
1277 enum tree_code code
= TREE_CODE (type
);
1278 if (code
== VOID_TYPE
)
1279 return GEN_INT (void_type_class
);
1280 if (code
== INTEGER_TYPE
)
1281 return GEN_INT (integer_type_class
);
1282 if (code
== CHAR_TYPE
)
1283 return GEN_INT (char_type_class
);
1284 if (code
== ENUMERAL_TYPE
)
1285 return GEN_INT (enumeral_type_class
);
1286 if (code
== BOOLEAN_TYPE
)
1287 return GEN_INT (boolean_type_class
);
1288 if (code
== POINTER_TYPE
)
1289 return GEN_INT (pointer_type_class
);
1290 if (code
== REFERENCE_TYPE
)
1291 return GEN_INT (reference_type_class
);
1292 if (code
== OFFSET_TYPE
)
1293 return GEN_INT (offset_type_class
);
1294 if (code
== REAL_TYPE
)
1295 return GEN_INT (real_type_class
);
1296 if (code
== COMPLEX_TYPE
)
1297 return GEN_INT (complex_type_class
);
1298 if (code
== FUNCTION_TYPE
)
1299 return GEN_INT (function_type_class
);
1300 if (code
== METHOD_TYPE
)
1301 return GEN_INT (method_type_class
);
1302 if (code
== RECORD_TYPE
)
1303 return GEN_INT (record_type_class
);
1304 if (code
== UNION_TYPE
|| code
== QUAL_UNION_TYPE
)
1305 return GEN_INT (union_type_class
);
1306 if (code
== ARRAY_TYPE
)
1308 if (TYPE_STRING_FLAG (type
))
1309 return GEN_INT (string_type_class
);
1311 return GEN_INT (array_type_class
);
1313 if (code
== SET_TYPE
)
1314 return GEN_INT (set_type_class
);
1315 if (code
== FILE_TYPE
)
1316 return GEN_INT (file_type_class
);
1317 if (code
== LANG_TYPE
)
1318 return GEN_INT (lang_type_class
);
1320 return GEN_INT (no_type_class
);
1323 /* Expand expression EXP, which is a call to __builtin_constant_p. */
1325 expand_builtin_constant_p (exp
)
1328 tree arglist
= TREE_OPERAND (exp
, 1);
1329 enum machine_mode value_mode
= TYPE_MODE (TREE_TYPE (exp
));
1334 arglist
= TREE_VALUE (arglist
);
1336 /* We have taken care of the easy cases during constant folding. This
1337 case is not obvious, so emit (constant_p_rtx (ARGLIST)) and let CSE get a
1338 chance to see if it can deduce whether ARGLIST is constant. */
1340 tmp
= expand_expr (arglist
, NULL_RTX
, VOIDmode
, 0);
1341 tmp
= gen_rtx_CONSTANT_P_RTX (value_mode
, tmp
);
1345 /* Expand a call to one of the builtin math functions (sin, cos, or sqrt).
1346 Return 0 if a normal call should be emitted rather than expanding the
1347 function in-line. EXP is the expression that is a call to the builtin
1348 function; if convenient, the result should be placed in TARGET.
1349 SUBTARGET may be used as the target for computing one of EXP's operands. */
1351 expand_builtin_mathfn (exp
, target
, subtarget
)
1353 rtx target
, subtarget
;
1355 optab builtin_optab
;
1357 tree fndecl
= TREE_OPERAND (TREE_OPERAND (exp
, 0), 0);
1358 tree arglist
= TREE_OPERAND (exp
, 1);
1361 /* Arg could be wrong type if user redeclared this fcn wrong. */
1362 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist
))) != REAL_TYPE
)
1365 /* Stabilize and compute the argument. */
1366 if (TREE_CODE (TREE_VALUE (arglist
)) != VAR_DECL
1367 && TREE_CODE (TREE_VALUE (arglist
)) != PARM_DECL
)
1369 exp
= copy_node (exp
);
1370 TREE_OPERAND (exp
, 1) = arglist
;
1371 /* Wrap the computation of the argument in a SAVE_EXPR. That
1372 way, if we need to expand the argument again (as in the
1373 flag_errno_math case below where we cannot directly set
1374 errno), we will not perform side-effects more than once.
1375 Note that here we're mutating the original EXP as well as the
1376 copy; that's the right thing to do in case the original EXP
1377 is expanded later. */
1378 TREE_VALUE (arglist
) = save_expr (TREE_VALUE (arglist
));
1379 arglist
= copy_node (arglist
);
1381 op0
= expand_expr (TREE_VALUE (arglist
), subtarget
, VOIDmode
, 0);
1383 /* Make a suitable register to place result in. */
1384 target
= gen_reg_rtx (TYPE_MODE (TREE_TYPE (exp
)));
1389 switch (DECL_FUNCTION_CODE (fndecl
))
1392 builtin_optab
= sin_optab
; break;
1394 builtin_optab
= cos_optab
; break;
1395 case BUILT_IN_FSQRT
:
1396 builtin_optab
= sqrt_optab
; break;
1401 /* Compute into TARGET.
1402 Set TARGET to wherever the result comes back. */
1403 target
= expand_unop (TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist
))),
1404 builtin_optab
, op0
, target
, 0);
1406 /* If we were unable to expand via the builtin, stop the
1407 sequence (without outputting the insns) and return 0, causing
1408 a call to the library function. */
1415 /* Check the results by default. But if flag_fast_math is turned on,
1416 then assume sqrt will always be called with valid arguments. */
1418 if (flag_errno_math
&& ! flag_fast_math
)
1422 /* Don't define the builtin FP instructions
1423 if your machine is not IEEE. */
1424 if (TARGET_FLOAT_FORMAT
!= IEEE_FLOAT_FORMAT
)
1427 lab1
= gen_label_rtx ();
1429 /* Test the result; if it is NaN, set errno=EDOM because
1430 the argument was not in the domain. */
1431 emit_cmp_and_jump_insns (target
, target
, EQ
, 0, GET_MODE (target
),
1436 #ifdef GEN_ERRNO_RTX
1437 rtx errno_rtx
= GEN_ERRNO_RTX
;
1440 = gen_rtx_MEM (word_mode
, gen_rtx_SYMBOL_REF (Pmode
, "errno"));
1443 emit_move_insn (errno_rtx
, GEN_INT (TARGET_EDOM
));
1446 /* We can't set errno=EDOM directly; let the library call do it.
1447 Pop the arguments right away in case the call gets deleted. */
1449 expand_call (exp
, target
, 0);
1456 /* Output the entire sequence. */
1457 insns
= get_insns ();
1464 /* Expand expression EXP which is a call to the strlen builtin. Return 0
1465 if we failed the caller should emit a normal call, otherwise
1466 try to get the result in TARGET, if convenient. */
1469 expand_builtin_strlen (exp
, target
)
1473 tree arglist
= TREE_OPERAND (exp
, 1);
1474 enum machine_mode value_mode
= TYPE_MODE (TREE_TYPE (exp
));
1477 /* Arg could be non-pointer if user redeclared this fcn wrong. */
1478 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist
))) != POINTER_TYPE
)
1483 tree src
= TREE_VALUE (arglist
);
1486 = get_pointer_alignment (src
, BIGGEST_ALIGNMENT
) / BITS_PER_UNIT
;
1488 rtx result
, src_reg
, char_rtx
, before_strlen
;
1489 enum machine_mode insn_mode
= value_mode
, char_mode
;
1490 enum insn_code icode
= CODE_FOR_nothing
;
1492 /* If SRC is not a pointer type, don't do this operation inline. */
1496 /* Bail out if we can't compute strlen in the right mode. */
1497 while (insn_mode
!= VOIDmode
)
1499 icode
= strlen_optab
->handlers
[(int) insn_mode
].insn_code
;
1500 if (icode
!= CODE_FOR_nothing
)
1503 insn_mode
= GET_MODE_WIDER_MODE (insn_mode
);
1505 if (insn_mode
== VOIDmode
)
1508 /* Make a place to write the result of the instruction. */
1511 && GET_CODE (result
) == REG
1512 && GET_MODE (result
) == insn_mode
1513 && REGNO (result
) >= FIRST_PSEUDO_REGISTER
))
1514 result
= gen_reg_rtx (insn_mode
);
1516 /* Make a place to hold the source address. We will not expand
1517 the actual source until we are sure that the expansion will
1518 not fail -- there are trees that cannot be expanded twice. */
1519 src_reg
= gen_reg_rtx (Pmode
);
1521 /* Mark the beginning of the strlen sequence so we can emit the
1522 source operand later. */
1523 before_strlen
= get_last_insn();
1525 /* Check the string is readable and has an end. */
1526 if (current_function_check_memory_usage
)
1527 emit_library_call (chkr_check_str_libfunc
, LCT_CONST_MAKE_BLOCK
,
1528 VOIDmode
, 2, src_reg
, Pmode
,
1529 GEN_INT (MEMORY_USE_RO
),
1530 TYPE_MODE (integer_type_node
));
1532 char_rtx
= const0_rtx
;
1533 char_mode
= insn_data
[(int) icode
].operand
[2].mode
;
1534 if (! (*insn_data
[(int) icode
].operand
[2].predicate
) (char_rtx
,
1536 char_rtx
= copy_to_mode_reg (char_mode
, char_rtx
);
1538 pat
= GEN_FCN (icode
) (result
, gen_rtx_MEM (BLKmode
, src_reg
),
1539 char_rtx
, GEN_INT (align
));
1544 /* Now that we are assured of success, expand the source. */
1546 pat
= memory_address (BLKmode
,
1547 expand_expr (src
, src_reg
, ptr_mode
, EXPAND_SUM
));
1549 emit_move_insn (src_reg
, pat
);
1550 pat
= gen_sequence ();
1554 emit_insn_after (pat
, before_strlen
);
1556 emit_insn_before (pat
, get_insns ());
1558 /* Return the value in the proper mode for this function. */
1559 if (GET_MODE (result
) == value_mode
)
1561 else if (target
!= 0)
1562 convert_move (target
, result
, 0);
1564 target
= convert_to_mode (value_mode
, result
, 0);
1570 /* Expand a call to the strstr builtin. Return 0 if we failed the
1571 caller should emit a normal call, otherwise try to get the result
1572 in TARGET, if convenient (and in mode MODE if that's convenient). */
1575 expand_builtin_strstr (arglist
, target
, mode
)
1578 enum machine_mode mode
;
1581 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist
))) != POINTER_TYPE
1582 || TREE_CHAIN (arglist
) == 0
1583 || TREE_CODE (TREE_TYPE (TREE_VALUE (TREE_CHAIN (arglist
)))) != POINTER_TYPE
1584 || current_function_check_memory_usage
)
1588 tree s1
= TREE_VALUE (arglist
), s2
= TREE_VALUE (TREE_CHAIN (arglist
));
1590 const char *p1
, *p2
;
1599 const char *r
= strstr (p1
, p2
);
1604 /* Return an offset into the constant string argument. */
1605 return expand_expr (fold (build (PLUS_EXPR
, TREE_TYPE (s1
),
1606 s1
, ssize_int (r
- p1
))),
1607 target
, mode
, EXPAND_NORMAL
);
1611 return expand_expr (s1
, target
, mode
, EXPAND_NORMAL
);
1616 fn
= built_in_decls
[BUILT_IN_STRCHR
];
1620 /* New argument list transforming strstr(s1, s2) to
1621 strchr(s1, s2[0]). */
1623 build_tree_list (NULL_TREE
, build_int_2 (p2
[0], 0));
1624 arglist
= tree_cons (NULL_TREE
, s1
, arglist
);
1625 call_expr
= build1 (ADDR_EXPR
,
1626 build_pointer_type (TREE_TYPE (fn
)), fn
);
1627 call_expr
= build (CALL_EXPR
, TREE_TYPE (TREE_TYPE (fn
)),
1628 call_expr
, arglist
, NULL_TREE
);
1629 TREE_SIDE_EFFECTS (call_expr
) = 1;
1630 return expand_expr (call_expr
, target
, mode
, EXPAND_NORMAL
);
1634 /* Expand a call to the strchr builtin. Return 0 if we failed the
1635 caller should emit a normal call, otherwise try to get the result
1636 in TARGET, if convenient (and in mode MODE if that's convenient). */
1639 expand_builtin_strchr (arglist
, target
, mode
)
1642 enum machine_mode mode
;
1645 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist
))) != POINTER_TYPE
1646 || TREE_CHAIN (arglist
) == 0
1647 || TREE_CODE (TREE_TYPE (TREE_VALUE (TREE_CHAIN (arglist
)))) != INTEGER_TYPE
1648 || current_function_check_memory_usage
)
1652 tree s1
= TREE_VALUE (arglist
), s2
= TREE_VALUE (TREE_CHAIN (arglist
));
1655 if (TREE_CODE (s2
) != INTEGER_CST
)
1664 if (target_char_cast (s2
, &c
))
1672 /* Return an offset into the constant string argument. */
1673 return expand_expr (fold (build (PLUS_EXPR
, TREE_TYPE (s1
),
1674 s1
, ssize_int (r
- p1
))),
1675 target
, mode
, EXPAND_NORMAL
);
1678 /* FIXME: Should use here strchrM optab so that ports can optimize
1684 /* Expand a call to the strrchr builtin. Return 0 if we failed the
1685 caller should emit a normal call, otherwise try to get the result
1686 in TARGET, if convenient (and in mode MODE if that's convenient). */
1689 expand_builtin_strrchr (arglist
, target
, mode
)
1692 enum machine_mode mode
;
1695 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist
))) != POINTER_TYPE
1696 || TREE_CHAIN (arglist
) == 0
1697 || TREE_CODE (TREE_TYPE (TREE_VALUE (TREE_CHAIN (arglist
)))) != INTEGER_TYPE
1698 || current_function_check_memory_usage
)
1702 tree s1
= TREE_VALUE (arglist
), s2
= TREE_VALUE (TREE_CHAIN (arglist
));
1706 if (TREE_CODE (s2
) != INTEGER_CST
)
1715 if (target_char_cast (s2
, &c
))
1718 r
= strrchr (p1
, c
);
1723 /* Return an offset into the constant string argument. */
1724 return expand_expr (fold (build (PLUS_EXPR
, TREE_TYPE (s1
),
1725 s1
, ssize_int (r
- p1
))),
1726 target
, mode
, EXPAND_NORMAL
);
1729 if (! integer_zerop (s2
))
1732 fn
= built_in_decls
[BUILT_IN_STRCHR
];
1736 /* Transform strrchr(s1, '\0') to strchr(s1, '\0'). */
1737 call_expr
= build1 (ADDR_EXPR
,
1738 build_pointer_type (TREE_TYPE (fn
)), fn
);
1739 call_expr
= build (CALL_EXPR
, TREE_TYPE (TREE_TYPE (fn
)),
1740 call_expr
, arglist
, NULL_TREE
);
1741 TREE_SIDE_EFFECTS (call_expr
) = 1;
1742 return expand_expr (call_expr
, target
, mode
, EXPAND_NORMAL
);
1746 /* Expand a call to the strpbrk builtin. Return 0 if we failed the
1747 caller should emit a normal call, otherwise try to get the result
1748 in TARGET, if convenient (and in mode MODE if that's convenient). */
1751 expand_builtin_strpbrk (arglist
, target
, mode
)
1754 enum machine_mode mode
;
1757 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist
))) != POINTER_TYPE
1758 || TREE_CHAIN (arglist
) == 0
1759 || TREE_CODE (TREE_TYPE (TREE_VALUE (TREE_CHAIN (arglist
)))) != POINTER_TYPE
1760 || current_function_check_memory_usage
)
1764 tree s1
= TREE_VALUE (arglist
), s2
= TREE_VALUE (TREE_CHAIN (arglist
));
1766 const char *p1
, *p2
;
1775 const char *r
= strpbrk (p1
, p2
);
1780 /* Return an offset into the constant string argument. */
1781 return expand_expr (fold (build (PLUS_EXPR
, TREE_TYPE (s1
),
1782 s1
, ssize_int (r
- p1
))),
1783 target
, mode
, EXPAND_NORMAL
);
1788 /* strpbrk(x, "") == NULL.
1789 Evaluate and ignore the arguments in case they had
1791 expand_expr (s1
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
1796 return 0; /* Really call strpbrk. */
1798 fn
= built_in_decls
[BUILT_IN_STRCHR
];
1802 /* New argument list transforming strpbrk(s1, s2) to
1803 strchr(s1, s2[0]). */
1805 build_tree_list (NULL_TREE
, build_int_2 (p2
[0], 0));
1806 arglist
= tree_cons (NULL_TREE
, s1
, arglist
);
1807 call_expr
= build1 (ADDR_EXPR
,
1808 build_pointer_type (TREE_TYPE (fn
)), fn
);
1809 call_expr
= build (CALL_EXPR
, TREE_TYPE (TREE_TYPE (fn
)),
1810 call_expr
, arglist
, NULL_TREE
);
1811 TREE_SIDE_EFFECTS (call_expr
) = 1;
1812 return expand_expr (call_expr
, target
, mode
, EXPAND_NORMAL
);
1816 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
1817 bytes from constant string DATA + OFFSET and return it as target
1821 builtin_memcpy_read_str (data
, offset
, mode
)
1823 HOST_WIDE_INT offset
;
1824 enum machine_mode mode
;
1826 const char *str
= (const char *) data
;
1828 if (offset
+ GET_MODE_SIZE (mode
) > strlen (str
) + 1)
1829 abort (); /* Attempt to read past the end of constant string. */
1831 return c_readstr (str
+ offset
, mode
);
1834 /* Expand a call to the memcpy builtin, with arguments in ARGLIST. */
1836 expand_builtin_memcpy (arglist
)
1840 /* Arg could be non-pointer if user redeclared this fcn wrong. */
1841 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist
))) != POINTER_TYPE
1842 || TREE_CHAIN (arglist
) == 0
1843 || (TREE_CODE (TREE_TYPE (TREE_VALUE (TREE_CHAIN (arglist
))))
1845 || TREE_CHAIN (TREE_CHAIN (arglist
)) == 0
1846 || (TREE_CODE (TREE_TYPE (TREE_VALUE
1847 (TREE_CHAIN (TREE_CHAIN (arglist
)))))
1852 tree dest
= TREE_VALUE (arglist
);
1853 tree src
= TREE_VALUE (TREE_CHAIN (arglist
));
1854 tree len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
1855 const char *src_str
;
1857 int src_align
= get_pointer_alignment (src
, BIGGEST_ALIGNMENT
);
1858 int dest_align
= get_pointer_alignment (dest
, BIGGEST_ALIGNMENT
);
1859 rtx dest_mem
, src_mem
, dest_addr
, len_rtx
;
1861 /* If either SRC or DEST is not a pointer type, don't do
1862 this operation in-line. */
1863 if (src_align
== 0 || dest_align
== 0)
1866 dest_mem
= get_memory_rtx (dest
);
1867 len_rtx
= expand_expr (len
, NULL_RTX
, VOIDmode
, 0);
1868 src_str
= c_getstr (src
);
1870 /* If SRC is a string constant and block move would be done
1871 by pieces, we can avoid loading the string from memory
1872 and only stored the computed constants. */
1874 && !current_function_check_memory_usage
1875 && GET_CODE (len_rtx
) == CONST_INT
1876 && (unsigned HOST_WIDE_INT
) INTVAL (len_rtx
) <= strlen (src_str
) + 1
1877 && can_store_by_pieces (INTVAL (len_rtx
), builtin_memcpy_read_str
,
1878 (PTR
) src_str
, dest_align
))
1880 store_by_pieces (dest_mem
, INTVAL (len_rtx
),
1881 builtin_memcpy_read_str
,
1882 (PTR
) src_str
, dest_align
);
1883 return force_operand (XEXP (dest_mem
, 0), NULL_RTX
);
1886 src_mem
= get_memory_rtx (src
);
1888 /* Just copy the rights of SRC to the rights of DEST. */
1889 if (current_function_check_memory_usage
)
1890 emit_library_call (chkr_copy_bitmap_libfunc
, LCT_CONST_MAKE_BLOCK
,
1891 VOIDmode
, 3, XEXP (dest_mem
, 0), Pmode
,
1892 XEXP (src_mem
, 0), Pmode
,
1893 len_rtx
, TYPE_MODE (sizetype
));
1895 /* Copy word part most expediently. */
1897 = emit_block_move (dest_mem
, src_mem
, len_rtx
,
1898 MIN (src_align
, dest_align
));
1901 dest_addr
= force_operand (XEXP (dest_mem
, 0), NULL_RTX
);
1907 /* Expand expression EXP, which is a call to the strcpy builtin. Return 0
1908 if we failed the caller should emit a normal call. */
1911 expand_builtin_strcpy (exp
)
1914 tree arglist
= TREE_OPERAND (exp
, 1);
1918 /* Arg could be non-pointer if user redeclared this fcn wrong. */
1919 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist
))) != POINTER_TYPE
1920 || TREE_CHAIN (arglist
) == 0
1921 || (TREE_CODE (TREE_TYPE (TREE_VALUE (TREE_CHAIN (arglist
))))
1926 tree len
= c_strlen (TREE_VALUE (TREE_CHAIN (arglist
)));
1931 len
= size_binop (PLUS_EXPR
, len
, ssize_int (1));
1932 chainon (arglist
, build_tree_list (NULL_TREE
, len
));
1935 result
= expand_builtin_memcpy (arglist
);
1938 TREE_CHAIN (TREE_CHAIN (arglist
)) = 0;
1942 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
1943 bytes from constant string DATA + OFFSET and return it as target
1947 builtin_strncpy_read_str (data
, offset
, mode
)
1949 HOST_WIDE_INT offset
;
1950 enum machine_mode mode
;
1952 const char *str
= (const char *) data
;
1954 if ((unsigned HOST_WIDE_INT
) offset
> strlen (str
))
1957 return c_readstr (str
+ offset
, mode
);
1960 /* Expand expression EXP, which is a call to the strncpy builtin. Return 0
1961 if we failed the caller should emit a normal call. */
1964 expand_builtin_strncpy (arglist
, target
, mode
)
1967 enum machine_mode mode
;
1970 /* Arg could be non-pointer if user redeclared this fcn wrong. */
1971 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist
))) != POINTER_TYPE
1972 || TREE_CHAIN (arglist
) == 0
1973 || (TREE_CODE (TREE_TYPE (TREE_VALUE (TREE_CHAIN (arglist
))))
1975 || TREE_CHAIN (TREE_CHAIN (arglist
)) == 0
1976 || (TREE_CODE (TREE_TYPE (TREE_VALUE
1977 (TREE_CHAIN (TREE_CHAIN (arglist
)))))
1982 tree slen
= c_strlen (TREE_VALUE (TREE_CHAIN (arglist
)));
1983 tree len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
1985 /* We must be passed a constant len parameter. */
1986 if (TREE_CODE (len
) != INTEGER_CST
)
1989 /* If the len parameter is zero, return the dst parameter. */
1990 if (compare_tree_int (len
, 0) == 0)
1992 /* Evaluate and ignore the src argument in case it has
1994 expand_expr (TREE_VALUE (TREE_CHAIN (arglist
)), const0_rtx
,
1995 VOIDmode
, EXPAND_NORMAL
);
1996 /* Return the dst parameter. */
1997 return expand_expr (TREE_VALUE (arglist
), target
, mode
,
2001 /* Now, we must be passed a constant src ptr parameter. */
2002 if (slen
== 0 || TREE_CODE (slen
) != INTEGER_CST
)
2005 slen
= size_binop (PLUS_EXPR
, slen
, ssize_int (1));
2007 /* We're required to pad with trailing zeros if the requested
2008 len is greater than strlen(s2)+1. In that case try to
2009 use store_by_pieces, if it fails, punt. */
2010 if (tree_int_cst_lt (slen
, len
))
2012 tree dest
= TREE_VALUE (arglist
);
2013 int dest_align
= get_pointer_alignment (dest
, BIGGEST_ALIGNMENT
);
2014 const char *p
= c_getstr (TREE_VALUE (TREE_CHAIN (arglist
)));
2017 if (!p
|| !dest_align
|| TREE_INT_CST_HIGH (len
)
2018 || !can_store_by_pieces (TREE_INT_CST_LOW (len
),
2019 builtin_strncpy_read_str
,
2020 (PTR
) p
, dest_align
))
2023 dest_mem
= get_memory_rtx (dest
);
2024 store_by_pieces (dest_mem
, TREE_INT_CST_LOW (len
),
2025 builtin_strncpy_read_str
,
2026 (PTR
) p
, dest_align
);
2027 return force_operand (XEXP (dest_mem
, 0), NULL_RTX
);
2030 /* OK transform into builtin memcpy. */
2031 return expand_builtin_memcpy (arglist
);
2035 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
2036 bytes from constant string DATA + OFFSET and return it as target
2040 builtin_memset_read_str (data
, offset
, mode
)
2042 HOST_WIDE_INT offset ATTRIBUTE_UNUSED
;
2043 enum machine_mode mode
;
2045 const char *c
= (const char *) data
;
2046 char *p
= alloca (GET_MODE_SIZE (mode
));
2048 memset (p
, *c
, GET_MODE_SIZE (mode
));
2050 return c_readstr (p
, mode
);
2053 /* Expand expression EXP, which is a call to the memset builtin. Return 0
2054 if we failed the caller should emit a normal call. */
2057 expand_builtin_memset (exp
)
2060 tree arglist
= TREE_OPERAND (exp
, 1);
2063 /* Arg could be non-pointer if user redeclared this fcn wrong. */
2064 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist
))) != POINTER_TYPE
2065 || TREE_CHAIN (arglist
) == 0
2066 || (TREE_CODE (TREE_TYPE (TREE_VALUE (TREE_CHAIN (arglist
))))
2068 || TREE_CHAIN (TREE_CHAIN (arglist
)) == 0
2070 != (TREE_CODE (TREE_TYPE
2072 (TREE_CHAIN (TREE_CHAIN (arglist
))))))))
2076 tree dest
= TREE_VALUE (arglist
);
2077 tree val
= TREE_VALUE (TREE_CHAIN (arglist
));
2078 tree len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
2081 int dest_align
= get_pointer_alignment (dest
, BIGGEST_ALIGNMENT
);
2082 rtx dest_mem
, dest_addr
, len_rtx
;
2084 /* If DEST is not a pointer type, don't do this
2085 operation in-line. */
2086 if (dest_align
== 0)
2089 if (TREE_CODE (val
) != INTEGER_CST
)
2092 if (target_char_cast (val
, &c
))
2097 if (TREE_CODE (len
) != INTEGER_CST
|| TREE_INT_CST_HIGH (len
))
2099 if (current_function_check_memory_usage
2100 || !can_store_by_pieces (TREE_INT_CST_LOW (len
),
2101 builtin_memset_read_str
,
2102 (PTR
) &c
, dest_align
))
2105 dest_mem
= get_memory_rtx (dest
);
2106 store_by_pieces (dest_mem
, TREE_INT_CST_LOW (len
),
2107 builtin_memset_read_str
,
2108 (PTR
) &c
, dest_align
);
2109 return force_operand (XEXP (dest_mem
, 0), NULL_RTX
);
2112 len_rtx
= expand_expr (len
, NULL_RTX
, VOIDmode
, 0);
2114 dest_mem
= get_memory_rtx (dest
);
2116 /* Just check DST is writable and mark it as readable. */
2117 if (current_function_check_memory_usage
)
2118 emit_library_call (chkr_check_addr_libfunc
, LCT_CONST_MAKE_BLOCK
,
2119 VOIDmode
, 3, XEXP (dest_mem
, 0), Pmode
,
2120 len_rtx
, TYPE_MODE (sizetype
),
2121 GEN_INT (MEMORY_USE_WO
),
2122 TYPE_MODE (integer_type_node
));
2125 dest_addr
= clear_storage (dest_mem
, len_rtx
, dest_align
);
2128 dest_addr
= force_operand (XEXP (dest_mem
, 0), NULL_RTX
);
2134 /* Expand expression EXP, which is a call to the bzero builtin. Return 0
2135 if we failed the caller should emit a normal call. */
2137 expand_builtin_bzero (exp
)
2140 tree arglist
= TREE_OPERAND (exp
, 1);
2141 tree dest
, size
, newarglist
;
2145 /* Arg could be non-pointer if user redeclared this fcn wrong. */
2146 || TREE_CODE (TREE_TYPE (dest
= TREE_VALUE (arglist
))) != POINTER_TYPE
2147 || TREE_CHAIN (arglist
) == 0
2148 || (TREE_CODE (TREE_TYPE (size
= TREE_VALUE (TREE_CHAIN (arglist
))))
2152 /* New argument list transforming bzero(ptr x, int y) to
2153 memset(ptr x, int 0, size_t y). */
2155 newarglist
= build_tree_list (NULL_TREE
, convert (sizetype
, size
));
2156 newarglist
= tree_cons (NULL_TREE
, integer_zero_node
, newarglist
);
2157 newarglist
= tree_cons (NULL_TREE
, dest
, newarglist
);
2159 TREE_OPERAND (exp
, 1) = newarglist
;
2160 result
= expand_builtin_memset(exp
);
2162 /* Always restore the original arguments. */
2163 TREE_OPERAND (exp
, 1) = arglist
;
2168 #ifdef HAVE_cmpstrsi
2169 /* Expand expression EXP, which is a call to the memcmp or the strcmp builtin.
2170 ARGLIST is the argument list for this call. Return 0 if we failed and the
2171 caller should emit a normal call, otherwise try to get the result in
2172 TARGET, if convenient. */
2174 expand_builtin_memcmp (exp
, arglist
, target
)
2179 /* If we need to check memory accesses, call the library function. */
2180 if (current_function_check_memory_usage
)
2184 /* Arg could be non-pointer if user redeclared this fcn wrong. */
2185 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist
))) != POINTER_TYPE
2186 || TREE_CHAIN (arglist
) == 0
2187 || TREE_CODE (TREE_TYPE (TREE_VALUE (TREE_CHAIN (arglist
)))) != POINTER_TYPE
2188 || TREE_CHAIN (TREE_CHAIN (arglist
)) == 0
2189 || TREE_CODE (TREE_TYPE (TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
))))) != INTEGER_TYPE
)
2193 enum machine_mode mode
;
2194 tree arg1
= TREE_VALUE (arglist
);
2195 tree arg2
= TREE_VALUE (TREE_CHAIN (arglist
));
2196 tree len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
2197 rtx arg1_rtx
, arg2_rtx
, arg3_rtx
;
2202 = get_pointer_alignment (arg1
, BIGGEST_ALIGNMENT
) / BITS_PER_UNIT
;
2204 = get_pointer_alignment (arg2
, BIGGEST_ALIGNMENT
) / BITS_PER_UNIT
;
2205 enum machine_mode insn_mode
2206 = insn_data
[(int) CODE_FOR_cmpstrsi
].operand
[0].mode
;
2208 /* If we don't have POINTER_TYPE, call the function. */
2209 if (arg1_align
== 0 || arg2_align
== 0)
2212 /* Make a place to write the result of the instruction. */
2215 && GET_CODE (result
) == REG
&& GET_MODE (result
) == insn_mode
2216 && REGNO (result
) >= FIRST_PSEUDO_REGISTER
))
2217 result
= gen_reg_rtx (insn_mode
);
2219 arg1_rtx
= get_memory_rtx (arg1
);
2220 arg2_rtx
= get_memory_rtx (arg2
);
2221 arg3_rtx
= expand_expr (len
, NULL_RTX
, VOIDmode
, 0);
2225 insn
= gen_cmpstrsi (result
, arg1_rtx
, arg2_rtx
, arg3_rtx
,
2226 GEN_INT (MIN (arg1_align
, arg2_align
)));
2231 emit_library_call_value (memcmp_libfunc
, result
, LCT_PURE_MAKE_BLOCK
,
2232 TYPE_MODE (integer_type_node
), 3,
2233 XEXP (arg1_rtx
, 0), Pmode
,
2234 XEXP (arg2_rtx
, 0), Pmode
,
2235 convert_to_mode (TYPE_MODE (sizetype
), arg3_rtx
,
2236 TREE_UNSIGNED (sizetype
)),
2237 TYPE_MODE (sizetype
));
2239 /* Return the value in the proper mode for this function. */
2240 mode
= TYPE_MODE (TREE_TYPE (exp
));
2241 if (GET_MODE (result
) == mode
)
2243 else if (target
!= 0)
2245 convert_move (target
, result
, 0);
2249 return convert_to_mode (mode
, result
, 0);
2254 /* Expand expression EXP, which is a call to the strcmp builtin. Return 0
2255 if we failed the caller should emit a normal call, otherwise try to get
2256 the result in TARGET, if convenient. */
2259 expand_builtin_strcmp (exp
, target
, mode
)
2262 enum machine_mode mode
;
2264 tree arglist
= TREE_OPERAND (exp
, 1);
2266 const char *p1
, *p2
;
2268 /* If we need to check memory accesses, call the library function. */
2269 if (current_function_check_memory_usage
)
2273 /* Arg could be non-pointer if user redeclared this fcn wrong. */
2274 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist
))) != POINTER_TYPE
2275 || TREE_CHAIN (arglist
) == 0
2276 || (TREE_CODE (TREE_TYPE (TREE_VALUE (TREE_CHAIN (arglist
))))
2280 arg1
= TREE_VALUE (arglist
);
2281 arg2
= TREE_VALUE (TREE_CHAIN (arglist
));
2283 p1
= c_getstr (arg1
);
2284 p2
= c_getstr (arg2
);
2288 const int i
= strcmp (p1
, p2
);
2289 return (i
< 0 ? constm1_rtx
: (i
> 0 ? const1_rtx
: const0_rtx
));
2292 /* If either arg is "", return an expression corresponding to
2293 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
2294 if ((p1
&& *p1
== '\0') || (p2
&& *p2
== '\0'))
2296 tree cst_uchar_node
= build_type_variant (unsigned_char_type_node
, 1, 0);
2297 tree cst_uchar_ptr_node
= build_pointer_type (cst_uchar_node
);
2299 fold (build1 (CONVERT_EXPR
, integer_type_node
,
2300 build1 (INDIRECT_REF
, cst_uchar_node
,
2301 build1 (NOP_EXPR
, cst_uchar_ptr_node
, arg1
))));
2303 fold (build1 (CONVERT_EXPR
, integer_type_node
,
2304 build1 (INDIRECT_REF
, cst_uchar_node
,
2305 build1 (NOP_EXPR
, cst_uchar_ptr_node
, arg2
))));
2306 tree result
= fold (build (MINUS_EXPR
, integer_type_node
, ind1
, ind2
));
2307 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
2310 #ifdef HAVE_cmpstrsi
2311 if (! HAVE_cmpstrsi
)
2315 tree len
= c_strlen (arg1
);
2316 tree len2
= c_strlen (arg2
);
2320 len
= size_binop (PLUS_EXPR
, ssize_int (1), len
);
2323 len2
= size_binop (PLUS_EXPR
, ssize_int (1), len2
);
2325 /* If we don't have a constant length for the first, use the length
2326 of the second, if we know it. We don't require a constant for
2327 this case; some cost analysis could be done if both are available
2328 but neither is constant. For now, assume they're equally cheap
2329 unless one has side effects.
2331 If both strings have constant lengths, use the smaller. This
2332 could arise if optimization results in strcpy being called with
2333 two fixed strings, or if the code was machine-generated. We should
2334 add some code to the `memcmp' handler below to deal with such
2335 situations, someday. */
2337 if (!len
|| TREE_CODE (len
) != INTEGER_CST
)
2339 if (len2
&& !TREE_SIDE_EFFECTS (len2
))
2344 else if (len2
&& TREE_CODE (len2
) == INTEGER_CST
2345 && tree_int_cst_lt (len2
, len
))
2348 /* If both arguments have side effects, we cannot optimize. */
2349 if (TREE_SIDE_EFFECTS (len
))
2352 chainon (arglist
, build_tree_list (NULL_TREE
, len
));
2353 result
= expand_builtin_memcmp (exp
, arglist
, target
);
2355 TREE_CHAIN (TREE_CHAIN (arglist
)) = 0;
2364 /* Expand expression EXP, which is a call to the strncmp builtin. Return 0
2365 if we failed the caller should emit a normal call, otherwise try to get
2366 the result in TARGET, if convenient. */
2368 expand_builtin_strncmp (exp
, target
, mode
)
2371 enum machine_mode mode
;
2373 tree arglist
= TREE_OPERAND (exp
, 1);
2374 tree arg1
, arg2
, arg3
;
2375 const char *p1
, *p2
;
2377 /* If we need to check memory accesses, call the library function. */
2378 if (current_function_check_memory_usage
)
2382 /* Arg could be non-pointer if user redeclared this fcn wrong. */
2383 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist
))) != POINTER_TYPE
2384 || TREE_CHAIN (arglist
) == 0
2385 || TREE_CODE (TREE_TYPE (TREE_VALUE (TREE_CHAIN (arglist
)))) != POINTER_TYPE
2386 || TREE_CHAIN (TREE_CHAIN (arglist
)) == 0
2387 || TREE_CODE (TREE_TYPE (TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
))))) != INTEGER_TYPE
)
2390 arg1
= TREE_VALUE (arglist
);
2391 arg2
= TREE_VALUE (TREE_CHAIN (arglist
));
2392 arg3
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
2394 /* We must be passed a constant len parameter. */
2395 if (TREE_CODE (arg3
) != INTEGER_CST
)
2398 /* If the len parameter is zero, return zero. */
2399 if (compare_tree_int (arg3
, 0) == 0)
2401 /* Evaluate and ignore arg1 and arg2 in case they have
2403 expand_expr (arg1
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
2404 expand_expr (arg2
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
2408 p1
= c_getstr (arg1
);
2409 p2
= c_getstr (arg2
);
2411 /* If all arguments are constant, evaluate at compile-time. */
2414 const int r
= strncmp (p1
, p2
, TREE_INT_CST_LOW (arg3
));
2415 return (r
< 0 ? constm1_rtx
: (r
> 0 ? const1_rtx
: const0_rtx
));
2418 /* If len == 1 or (either string parameter is "" and (len >= 1)),
2419 return (*(u_char*)arg1 - *(u_char*)arg2). */
2420 if (compare_tree_int (arg3
, 1) == 0
2421 || (compare_tree_int (arg3
, 1) > 0
2422 && ((p1
&& *p1
== '\0') || (p2
&& *p2
== '\0'))))
2424 tree cst_uchar_node
= build_type_variant (unsigned_char_type_node
, 1, 0);
2425 tree cst_uchar_ptr_node
= build_pointer_type (cst_uchar_node
);
2427 fold (build1 (CONVERT_EXPR
, integer_type_node
,
2428 build1 (INDIRECT_REF
, cst_uchar_node
,
2429 build1 (NOP_EXPR
, cst_uchar_ptr_node
, arg1
))));
2431 fold (build1 (CONVERT_EXPR
, integer_type_node
,
2432 build1 (INDIRECT_REF
, cst_uchar_node
,
2433 build1 (NOP_EXPR
, cst_uchar_ptr_node
, arg2
))));
2434 tree result
= fold (build (MINUS_EXPR
, integer_type_node
, ind1
, ind2
));
2435 return expand_expr (result
, target
, mode
, EXPAND_NORMAL
);
2438 #ifdef HAVE_cmpstrsi
2439 /* If the length parameter is constant (checked above) and either
2440 string parameter is constant, call expand_builtin_memcmp() using
2441 a length parameter equal to the lesser of the given length and
2442 the strlen+1 of the constant string. */
2443 if (HAVE_cmpstrsi
&& (p1
|| p2
))
2445 /* Exactly one of the strings is constant at this point, because
2446 if both were then we'd have expanded this at compile-time. */
2447 tree string_len
= p1
? c_strlen (arg1
) : c_strlen (arg2
);
2449 string_len
= size_binop (PLUS_EXPR
, string_len
, ssize_int (1));
2451 if (tree_int_cst_lt (string_len
, arg3
))
2453 /* The strlen+1 is strictly shorter, use it. */
2454 tree newarglist
= build_tree_list (NULL_TREE
, string_len
);
2455 newarglist
= tree_cons (NULL_TREE
, arg2
, newarglist
);
2456 newarglist
= tree_cons (NULL_TREE
, arg1
, newarglist
);
2457 return expand_builtin_memcmp (exp
, newarglist
, target
);
2460 return expand_builtin_memcmp (exp
, arglist
, target
);
2467 /* Expand expression EXP, which is a call to the strcat builtin.
2468 Return 0 if we failed the caller should emit a normal call,
2469 otherwise try to get the result in TARGET, if convenient. */
2471 expand_builtin_strcat (arglist
, target
, mode
)
2474 enum machine_mode mode
;
2476 /* If we need to check memory accesses, call the library function. */
2477 if (current_function_check_memory_usage
)
2481 /* Arg could be non-pointer if user redeclared this fcn wrong. */
2482 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist
))) != POINTER_TYPE
2483 || TREE_CHAIN (arglist
) == 0
2484 || (TREE_CODE (TREE_TYPE (TREE_VALUE (TREE_CHAIN (arglist
))))
2489 tree dst
= TREE_VALUE (arglist
),
2490 src
= TREE_VALUE (TREE_CHAIN (arglist
));
2491 const char *p
= c_getstr (src
);
2493 /* If the string length is zero, return the dst parameter. */
2494 if (p
&& *p
== '\0')
2495 return expand_expr (dst
, target
, mode
, EXPAND_NORMAL
);
2501 /* Expand expression EXP, which is a call to the strncat builtin.
2502 Return 0 if we failed the caller should emit a normal call,
2503 otherwise try to get the result in TARGET, if convenient. */
2505 expand_builtin_strncat (arglist
, target
, mode
)
2508 enum machine_mode mode
;
2510 /* If we need to check memory accesses, call the library function. */
2511 if (current_function_check_memory_usage
)
2515 /* Arg could be non-pointer if user redeclared this fcn wrong. */
2516 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist
))) != POINTER_TYPE
2517 || TREE_CHAIN (arglist
) == 0
2518 || (TREE_CODE (TREE_TYPE (TREE_VALUE (TREE_CHAIN (arglist
))))
2520 || TREE_CHAIN (TREE_CHAIN (arglist
)) == 0
2521 || (TREE_CODE (TREE_TYPE (TREE_VALUE
2522 (TREE_CHAIN (TREE_CHAIN (arglist
)))))
2527 tree dst
= TREE_VALUE (arglist
),
2528 src
= TREE_VALUE (TREE_CHAIN (arglist
)),
2529 len
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
2530 const char *p
= c_getstr (src
);
2532 /* If the requested length is zero, or the src parameter string
2533 length is zero, return the dst parameter. */
2534 if ((TREE_CODE (len
) == INTEGER_CST
&& compare_tree_int (len
, 0) == 0)
2535 || (p
&& *p
== '\0'))
2537 /* Evaluate and ignore the src and len parameters in case
2538 they have side-effects. */
2539 expand_expr (src
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
2540 expand_expr (len
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
2541 return expand_expr (dst
, target
, mode
, EXPAND_NORMAL
);
2544 /* If the requested len is greater than or equal to the string
2545 length, call strcat. */
2546 if (TREE_CODE (len
) == INTEGER_CST
&& p
2547 && compare_tree_int (len
, strlen (p
)) >= 0)
2549 tree call_expr
, newarglist
=
2550 tree_cons (NULL_TREE
, dst
, build_tree_list (NULL_TREE
, src
)),
2551 fn
= built_in_decls
[BUILT_IN_STRCAT
];
2553 /* If the replacement _DECL isn't initialized, don't do the
2558 call_expr
= build1 (ADDR_EXPR
,
2559 build_pointer_type (TREE_TYPE (fn
)), fn
);
2560 call_expr
= build (CALL_EXPR
, TREE_TYPE (TREE_TYPE (fn
)),
2561 call_expr
, newarglist
, NULL_TREE
);
2562 TREE_SIDE_EFFECTS (call_expr
) = 1;
2563 return expand_expr (call_expr
, target
, mode
, EXPAND_NORMAL
);
2569 /* Expand expression EXP, which is a call to the strspn builtin.
2570 Return 0 if we failed the caller should emit a normal call,
2571 otherwise try to get the result in TARGET, if convenient. */
2573 expand_builtin_strspn (arglist
, target
, mode
)
2576 enum machine_mode mode
;
2578 /* If we need to check memory accesses, call the library function. */
2579 if (current_function_check_memory_usage
)
2583 /* Arg could be non-pointer if user redeclared this fcn wrong. */
2584 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist
))) != POINTER_TYPE
2585 || TREE_CHAIN (arglist
) == 0
2586 || (TREE_CODE (TREE_TYPE (TREE_VALUE (TREE_CHAIN (arglist
))))
2591 tree s1
= TREE_VALUE (arglist
), s2
= TREE_VALUE (TREE_CHAIN (arglist
));
2592 const char *p1
= c_getstr (s1
), *p2
= c_getstr (s2
);
2594 /* If both arguments are constants, evaluate at compile-time. */
2597 const size_t r
= strspn (p1
, p2
);
2598 return expand_expr (size_int (r
), target
, mode
, EXPAND_NORMAL
);
2601 /* If either argument is "", return 0. */
2602 if ((p1
&& *p1
== '\0') || (p2
&& *p2
== '\0'))
2604 /* Evaluate and ignore both arguments in case either one has
2606 expand_expr (s1
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
2607 expand_expr (s2
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
2614 /* Expand expression EXP, which is a call to the strcspn builtin.
2615 Return 0 if we failed the caller should emit a normal call,
2616 otherwise try to get the result in TARGET, if convenient. */
2618 expand_builtin_strcspn (arglist
, target
, mode
)
2621 enum machine_mode mode
;
2623 /* If we need to check memory accesses, call the library function. */
2624 if (current_function_check_memory_usage
)
2628 /* Arg could be non-pointer if user redeclared this fcn wrong. */
2629 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist
))) != POINTER_TYPE
2630 || TREE_CHAIN (arglist
) == 0
2631 || (TREE_CODE (TREE_TYPE (TREE_VALUE (TREE_CHAIN (arglist
))))
2636 tree s1
= TREE_VALUE (arglist
), s2
= TREE_VALUE (TREE_CHAIN (arglist
));
2637 const char *p1
= c_getstr (s1
), *p2
= c_getstr (s2
);
2639 /* If both arguments are constants, evaluate at compile-time. */
2642 const size_t r
= strcspn (p1
, p2
);
2643 return expand_expr (size_int (r
), target
, mode
, EXPAND_NORMAL
);
2646 /* If the first argument is "", return 0. */
2647 if (p1
&& *p1
== '\0')
2649 /* Evaluate and ignore argument s2 in case it has
2651 expand_expr (s2
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
2655 /* If the second argument is "", return __builtin_strlen(s1). */
2656 if (p2
&& *p2
== '\0')
2658 tree call_expr
, newarglist
= build_tree_list (NULL_TREE
, s1
),
2659 fn
= built_in_decls
[BUILT_IN_STRLEN
];
2661 /* If the replacement _DECL isn't initialized, don't do the
2666 call_expr
= build1 (ADDR_EXPR
,
2667 build_pointer_type (TREE_TYPE (fn
)), fn
);
2668 call_expr
= build (CALL_EXPR
, TREE_TYPE (TREE_TYPE (fn
)),
2669 call_expr
, newarglist
, NULL_TREE
);
2670 TREE_SIDE_EFFECTS (call_expr
) = 1;
2671 return expand_expr (call_expr
, target
, mode
, EXPAND_NORMAL
);
2677 /* Expand a call to __builtin_saveregs, generating the result in TARGET,
2678 if that's convenient. */
2681 expand_builtin_saveregs ()
2685 /* Don't do __builtin_saveregs more than once in a function.
2686 Save the result of the first call and reuse it. */
2687 if (saveregs_value
!= 0)
2688 return saveregs_value
;
2690 /* When this function is called, it means that registers must be
2691 saved on entry to this function. So we migrate the call to the
2692 first insn of this function. */
2696 #ifdef EXPAND_BUILTIN_SAVEREGS
2697 /* Do whatever the machine needs done in this case. */
2698 val
= EXPAND_BUILTIN_SAVEREGS ();
2700 /* ??? We used to try and build up a call to the out of line function,
2701 guessing about what registers needed saving etc. This became much
2702 harder with __builtin_va_start, since we don't have a tree for a
2703 call to __builtin_saveregs to fall back on. There was exactly one
2704 port (i860) that used this code, and I'm unconvinced it could actually
2705 handle the general case. So we no longer try to handle anything
2706 weird and make the backend absorb the evil. */
2708 error ("__builtin_saveregs not supported by this target");
2715 saveregs_value
= val
;
2717 /* Put the sequence after the NOTE that starts the function. If this
2718 is inside a SEQUENCE, make the outer-level insn chain current, so
2719 the code is placed at the start of the function. */
2720 push_topmost_sequence ();
2721 emit_insns_after (seq
, get_insns ());
2722 pop_topmost_sequence ();
2727 /* __builtin_args_info (N) returns word N of the arg space info
2728 for the current function. The number and meanings of words
2729 is controlled by the definition of CUMULATIVE_ARGS. */
2732 expand_builtin_args_info (exp
)
2735 tree arglist
= TREE_OPERAND (exp
, 1);
2736 int nwords
= sizeof (CUMULATIVE_ARGS
) / sizeof (int);
2737 int *word_ptr
= (int *) ¤t_function_args_info
;
2739 /* These are used by the code below that is if 0'ed away */
2741 tree type
, elts
, result
;
2744 if (sizeof (CUMULATIVE_ARGS
) % sizeof (int) != 0)
2749 tree arg
= TREE_VALUE (arglist
);
2750 if (TREE_CODE (arg
) != INTEGER_CST
)
2751 error ("argument of `__builtin_args_info' must be constant");
2754 int wordnum
= TREE_INT_CST_LOW (arg
);
2756 if (wordnum
< 0 || wordnum
>= nwords
|| TREE_INT_CST_HIGH (arg
))
2757 error ("argument of `__builtin_args_info' out of range");
2759 return GEN_INT (word_ptr
[wordnum
]);
2763 error ("missing argument in `__builtin_args_info'");
2768 for (i
= 0; i
< nwords
; i
++)
2769 elts
= tree_cons (NULL_TREE
, build_int_2 (word_ptr
[i
], 0));
2771 type
= build_array_type (integer_type_node
,
2772 build_index_type (build_int_2 (nwords
, 0)));
2773 result
= build (CONSTRUCTOR
, type
, NULL_TREE
, nreverse (elts
));
2774 TREE_CONSTANT (result
) = 1;
2775 TREE_STATIC (result
) = 1;
2776 result
= build1 (INDIRECT_REF
, build_pointer_type (type
), result
);
2777 TREE_CONSTANT (result
) = 1;
2778 return expand_expr (result
, NULL_RTX
, VOIDmode
, EXPAND_MEMORY_USE_BAD
);
2782 /* Expand ARGLIST, from a call to __builtin_next_arg. */
2784 expand_builtin_next_arg (arglist
)
2787 tree fntype
= TREE_TYPE (current_function_decl
);
2789 if ((TYPE_ARG_TYPES (fntype
) == 0
2790 || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype
)))
2792 && ! current_function_varargs
)
2794 error ("`va_start' used in function with fixed args");
2800 tree last_parm
= tree_last (DECL_ARGUMENTS (current_function_decl
));
2801 tree arg
= TREE_VALUE (arglist
);
2803 /* Strip off all nops for the sake of the comparison. This
2804 is not quite the same as STRIP_NOPS. It does more.
2805 We must also strip off INDIRECT_EXPR for C++ reference
2807 while (TREE_CODE (arg
) == NOP_EXPR
2808 || TREE_CODE (arg
) == CONVERT_EXPR
2809 || TREE_CODE (arg
) == NON_LVALUE_EXPR
2810 || TREE_CODE (arg
) == INDIRECT_REF
)
2811 arg
= TREE_OPERAND (arg
, 0);
2812 if (arg
!= last_parm
)
2813 warning ("second parameter of `va_start' not last named argument");
2815 else if (! current_function_varargs
)
2816 /* Evidently an out of date version of <stdarg.h>; can't validate
2817 va_start's second argument, but can still work as intended. */
2818 warning ("`__builtin_next_arg' called without an argument");
2820 return expand_binop (Pmode
, add_optab
,
2821 current_function_internal_arg_pointer
,
2822 current_function_arg_offset_rtx
,
2823 NULL_RTX
, 0, OPTAB_LIB_WIDEN
);
2826 /* Make it easier for the backends by protecting the valist argument
2827 from multiple evaluations. */
2830 stabilize_va_list (valist
, needs_lvalue
)
2834 if (TREE_CODE (va_list_type_node
) == ARRAY_TYPE
)
2836 if (TREE_SIDE_EFFECTS (valist
))
2837 valist
= save_expr (valist
);
2839 /* For this case, the backends will be expecting a pointer to
2840 TREE_TYPE (va_list_type_node), but it's possible we've
2841 actually been given an array (an actual va_list_type_node).
2843 if (TREE_CODE (TREE_TYPE (valist
)) == ARRAY_TYPE
)
2845 tree p1
= build_pointer_type (TREE_TYPE (va_list_type_node
));
2846 tree p2
= build_pointer_type (va_list_type_node
);
2848 valist
= build1 (ADDR_EXPR
, p2
, valist
);
2849 valist
= fold (build1 (NOP_EXPR
, p1
, valist
));
2858 if (! TREE_SIDE_EFFECTS (valist
))
2861 pt
= build_pointer_type (va_list_type_node
);
2862 valist
= fold (build1 (ADDR_EXPR
, pt
, valist
));
2863 TREE_SIDE_EFFECTS (valist
) = 1;
2866 if (TREE_SIDE_EFFECTS (valist
))
2867 valist
= save_expr (valist
);
2868 valist
= fold (build1 (INDIRECT_REF
, TREE_TYPE (TREE_TYPE (valist
)),
2875 /* The "standard" implementation of va_start: just assign `nextarg' to
2878 std_expand_builtin_va_start (stdarg_p
, valist
, nextarg
)
2887 int align
= PARM_BOUNDARY
/ BITS_PER_UNIT
;
2888 int offset
= (((UNITS_PER_WORD
+ align
- 1) / align
) * align
);
2889 nextarg
= plus_constant (nextarg
, -offset
);
2892 t
= build (MODIFY_EXPR
, TREE_TYPE (valist
), valist
,
2893 make_tree (ptr_type_node
, nextarg
));
2894 TREE_SIDE_EFFECTS (t
) = 1;
2896 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
2899 /* Expand ARGLIST, which from a call to __builtin_stdarg_va_start or
2900 __builtin_varargs_va_start, depending on STDARG_P. */
2902 expand_builtin_va_start (stdarg_p
, arglist
)
2907 tree chain
= arglist
, valist
;
2910 nextarg
= expand_builtin_next_arg (chain
= TREE_CHAIN (arglist
));
2912 nextarg
= expand_builtin_next_arg (NULL_TREE
);
2914 if (TREE_CHAIN (chain
))
2915 error ("too many arguments to function `va_start'");
2917 valist
= stabilize_va_list (TREE_VALUE (arglist
), 1);
2919 #ifdef EXPAND_BUILTIN_VA_START
2920 EXPAND_BUILTIN_VA_START (stdarg_p
, valist
, nextarg
);
2922 std_expand_builtin_va_start (stdarg_p
, valist
, nextarg
);
2928 /* The "standard" implementation of va_arg: read the value from the
2929 current (padded) address and increment by the (padded) size. */
2932 std_expand_builtin_va_arg (valist
, type
)
2936 HOST_WIDE_INT align
;
2937 HOST_WIDE_INT rounded_size
;
2940 /* Compute the rounded size of the type. */
2941 align
= PARM_BOUNDARY
/ BITS_PER_UNIT
;
2942 rounded_size
= (((int_size_in_bytes (type
) + align
- 1) / align
) * align
);
2946 if (PAD_VARARGS_DOWN
)
2948 /* Small args are padded downward. */
2951 adj
= TREE_INT_CST_LOW (TYPE_SIZE (type
)) / BITS_PER_UNIT
;
2952 if (rounded_size
> align
)
2955 addr_tree
= build (PLUS_EXPR
, TREE_TYPE (addr_tree
), addr_tree
,
2956 build_int_2 (rounded_size
- adj
, 0));
2959 addr
= expand_expr (addr_tree
, NULL_RTX
, Pmode
, EXPAND_NORMAL
);
2960 addr
= copy_to_reg (addr
);
2962 /* Compute new value for AP. */
2963 t
= build (MODIFY_EXPR
, TREE_TYPE (valist
), valist
,
2964 build (PLUS_EXPR
, TREE_TYPE (valist
), valist
,
2965 build_int_2 (rounded_size
, 0)));
2966 TREE_SIDE_EFFECTS (t
) = 1;
2967 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
2972 /* Expand __builtin_va_arg, which is not really a builtin function, but
2973 a very special sort of operator. */
2976 expand_builtin_va_arg (valist
, type
)
2980 tree promoted_type
, want_va_type
, have_va_type
;
2982 /* Verify that valist is of the proper type. */
2984 want_va_type
= va_list_type_node
;
2985 have_va_type
= TREE_TYPE (valist
);
2986 if (TREE_CODE (want_va_type
) == ARRAY_TYPE
)
2988 /* If va_list is an array type, the argument may have decayed
2989 to a pointer type, e.g. by being passed to another function.
2990 In that case, unwrap both types so that we can compare the
2991 underlying records. */
2992 if (TREE_CODE (have_va_type
) == ARRAY_TYPE
2993 || TREE_CODE (have_va_type
) == POINTER_TYPE
)
2995 want_va_type
= TREE_TYPE (want_va_type
);
2996 have_va_type
= TREE_TYPE (have_va_type
);
2999 if (TYPE_MAIN_VARIANT (want_va_type
) != TYPE_MAIN_VARIANT (have_va_type
))
3001 error ("first argument to `va_arg' not of type `va_list'");
3005 /* Generate a diagnostic for requesting data of a type that cannot
3006 be passed through `...' due to type promotion at the call site. */
3007 else if ((promoted_type
= (*lang_type_promotes_to
) (type
)) != NULL_TREE
)
3009 const char *name
= "<anonymous type>", *pname
= 0;
3010 static int gave_help
;
3012 if (TYPE_NAME (type
))
3014 if (TREE_CODE (TYPE_NAME (type
)) == IDENTIFIER_NODE
)
3015 name
= IDENTIFIER_POINTER (TYPE_NAME (type
));
3016 else if (TREE_CODE (TYPE_NAME (type
)) == TYPE_DECL
3017 && DECL_NAME (TYPE_NAME (type
)))
3018 name
= IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type
)));
3020 if (TYPE_NAME (promoted_type
))
3022 if (TREE_CODE (TYPE_NAME (promoted_type
)) == IDENTIFIER_NODE
)
3023 pname
= IDENTIFIER_POINTER (TYPE_NAME (promoted_type
));
3024 else if (TREE_CODE (TYPE_NAME (promoted_type
)) == TYPE_DECL
3025 && DECL_NAME (TYPE_NAME (promoted_type
)))
3026 pname
= IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (promoted_type
)));
3029 error ("`%s' is promoted to `%s' when passed through `...'", name
, pname
);
3033 error ("(so you should pass `%s' not `%s' to `va_arg')", pname
, name
);
3040 /* Make it easier for the backends by protecting the valist argument
3041 from multiple evaluations. */
3042 valist
= stabilize_va_list (valist
, 0);
3044 #ifdef EXPAND_BUILTIN_VA_ARG
3045 addr
= EXPAND_BUILTIN_VA_ARG (valist
, type
);
3047 addr
= std_expand_builtin_va_arg (valist
, type
);
3051 result
= gen_rtx_MEM (TYPE_MODE (type
), addr
);
3052 MEM_ALIAS_SET (result
) = get_varargs_alias_set ();
3057 /* Expand ARGLIST, from a call to __builtin_va_end. */
3060 expand_builtin_va_end (arglist
)
3063 tree valist
= TREE_VALUE (arglist
);
3065 #ifdef EXPAND_BUILTIN_VA_END
3066 valist
= stabilize_va_list (valist
, 0);
3067 EXPAND_BUILTIN_VA_END(arglist
);
3069 /* Evaluate for side effects, if needed. I hate macros that don't
3071 if (TREE_SIDE_EFFECTS (valist
))
3072 expand_expr (valist
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
3078 /* Expand ARGLIST, from a call to __builtin_va_copy. We do this as a
3079 builtin rather than just as an assignment in stdarg.h because of the
3080 nastiness of array-type va_list types. */
3083 expand_builtin_va_copy (arglist
)
3088 dst
= TREE_VALUE (arglist
);
3089 src
= TREE_VALUE (TREE_CHAIN (arglist
));
3091 dst
= stabilize_va_list (dst
, 1);
3092 src
= stabilize_va_list (src
, 0);
3094 if (TREE_CODE (va_list_type_node
) != ARRAY_TYPE
)
3096 t
= build (MODIFY_EXPR
, va_list_type_node
, dst
, src
);
3097 TREE_SIDE_EFFECTS (t
) = 1;
3098 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
3102 rtx dstb
, srcb
, size
;
3104 /* Evaluate to pointers. */
3105 dstb
= expand_expr (dst
, NULL_RTX
, Pmode
, EXPAND_NORMAL
);
3106 srcb
= expand_expr (src
, NULL_RTX
, Pmode
, EXPAND_NORMAL
);
3107 size
= expand_expr (TYPE_SIZE_UNIT (va_list_type_node
), NULL_RTX
,
3108 VOIDmode
, EXPAND_NORMAL
);
3110 /* "Dereference" to BLKmode memories. */
3111 dstb
= gen_rtx_MEM (BLKmode
, dstb
);
3112 MEM_ALIAS_SET (dstb
) = get_alias_set (TREE_TYPE (TREE_TYPE (dst
)));
3113 srcb
= gen_rtx_MEM (BLKmode
, srcb
);
3114 MEM_ALIAS_SET (srcb
) = get_alias_set (TREE_TYPE (TREE_TYPE (src
)));
3117 emit_block_move (dstb
, srcb
, size
, TYPE_ALIGN (va_list_type_node
));
3123 /* Expand a call to one of the builtin functions __builtin_frame_address or
3124 __builtin_return_address. */
3126 expand_builtin_frame_address (exp
)
3129 tree fndecl
= TREE_OPERAND (TREE_OPERAND (exp
, 0), 0);
3130 tree arglist
= TREE_OPERAND (exp
, 1);
3132 /* The argument must be a nonnegative integer constant.
3133 It counts the number of frames to scan up the stack.
3134 The value is the return address saved in that frame. */
3136 /* Warning about missing arg was already issued. */
3138 else if (TREE_CODE (TREE_VALUE (arglist
)) != INTEGER_CST
3139 || tree_int_cst_sgn (TREE_VALUE (arglist
)) < 0)
3141 if (DECL_FUNCTION_CODE (fndecl
) == BUILT_IN_FRAME_ADDRESS
)
3142 error ("invalid arg to `__builtin_frame_address'");
3144 error ("invalid arg to `__builtin_return_address'");
3149 rtx tem
= expand_builtin_return_addr (DECL_FUNCTION_CODE (fndecl
),
3150 TREE_INT_CST_LOW (TREE_VALUE (arglist
)),
3151 hard_frame_pointer_rtx
);
3153 /* Some ports cannot access arbitrary stack frames. */
3156 if (DECL_FUNCTION_CODE (fndecl
) == BUILT_IN_FRAME_ADDRESS
)
3157 warning ("unsupported arg to `__builtin_frame_address'");
3159 warning ("unsupported arg to `__builtin_return_address'");
3163 /* For __builtin_frame_address, return what we've got. */
3164 if (DECL_FUNCTION_CODE (fndecl
) == BUILT_IN_FRAME_ADDRESS
)
3167 if (GET_CODE (tem
) != REG
3168 && ! CONSTANT_P (tem
))
3169 tem
= copy_to_mode_reg (Pmode
, tem
);
3174 /* Expand a call to the alloca builtin, with arguments ARGLIST. Return 0 if
3175 we failed and the caller should emit a normal call, otherwise try to get
3176 the result in TARGET, if convenient. */
3178 expand_builtin_alloca (arglist
, target
)
3185 /* Arg could be non-integer if user redeclared this fcn wrong. */
3186 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist
))) != INTEGER_TYPE
)
3189 /* Compute the argument. */
3190 op0
= expand_expr (TREE_VALUE (arglist
), NULL_RTX
, VOIDmode
, 0);
3192 /* Allocate the desired space. */
3193 return allocate_dynamic_stack_space (op0
, target
, BITS_PER_UNIT
);
3196 /* Expand a call to the ffs builtin. The arguments are in ARGLIST.
3197 Return 0 if a normal call should be emitted rather than expanding the
3198 function in-line. If convenient, the result should be placed in TARGET.
3199 SUBTARGET may be used as the target for computing one of EXP's operands. */
3201 expand_builtin_ffs (arglist
, target
, subtarget
)
3203 rtx target
, subtarget
;
3207 /* Arg could be non-integer if user redeclared this fcn wrong. */
3208 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist
))) != INTEGER_TYPE
)
3211 /* Compute the argument. */
3212 op0
= expand_expr (TREE_VALUE (arglist
), subtarget
, VOIDmode
, 0);
3213 /* Compute ffs, into TARGET if possible.
3214 Set TARGET to wherever the result comes back. */
3215 target
= expand_unop (TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist
))),
3216 ffs_optab
, op0
, target
, 1);
3222 /* If the string passed to fputs is a constant and is one character
3223 long, we attempt to transform this call into __builtin_fputc(). */
3225 expand_builtin_fputs (arglist
, ignore
)
3229 tree call_expr
, len
, fn
, fn_fputc
= built_in_decls
[BUILT_IN_FPUTC
],
3230 fn_fwrite
= built_in_decls
[BUILT_IN_FWRITE
];
3232 /* If the return value is used, or the replacement _DECL isn't
3233 initialized, don't do the transformation. */
3234 if (!ignore
|| !fn_fputc
|| !fn_fwrite
)
3237 /* Verify the arguments in the original call. */
3239 || (TREE_CODE (TREE_TYPE (TREE_VALUE (arglist
))) != POINTER_TYPE
)
3240 || TREE_CHAIN (arglist
) == 0
3241 || (TREE_CODE (TREE_TYPE (TREE_VALUE (TREE_CHAIN (arglist
))))
3243 || current_function_check_memory_usage
)
3246 /* Get the length of the string passed to fputs. If the length
3247 can't be determined, punt. */
3248 if (!(len
= c_strlen (TREE_VALUE (arglist
)))
3249 || TREE_CODE (len
) != INTEGER_CST
)
3252 switch (compare_tree_int (len
, 1))
3254 case -1: /* length is 0, delete the call entirely . */
3256 /* Evaluate and ignore the argument in case it has
3258 expand_expr (TREE_VALUE (TREE_CHAIN (arglist
)), const0_rtx
,
3259 VOIDmode
, EXPAND_NORMAL
);
3262 case 0: /* length is 1, call fputc. */
3264 const char *p
= c_getstr (TREE_VALUE (arglist
));
3268 /* New argument list transforming fputs(string, stream) to
3269 fputc(string[0], stream). */
3271 build_tree_list (NULL_TREE
, TREE_VALUE (TREE_CHAIN (arglist
)));
3273 tree_cons (NULL_TREE
, build_int_2 (p
[0], 0), arglist
);
3279 case 1: /* length is greater than 1, call fwrite. */
3281 tree string_arg
= TREE_VALUE (arglist
);
3283 /* New argument list transforming fputs(string, stream) to
3284 fwrite(string, 1, len, stream). */
3285 arglist
= build_tree_list (NULL_TREE
, TREE_VALUE (TREE_CHAIN (arglist
)));
3286 arglist
= tree_cons (NULL_TREE
, len
, arglist
);
3287 arglist
= tree_cons (NULL_TREE
, integer_one_node
, arglist
);
3288 arglist
= tree_cons (NULL_TREE
, string_arg
, arglist
);
3296 call_expr
= build1 (ADDR_EXPR
, build_pointer_type (TREE_TYPE (fn
)), fn
);
3297 call_expr
= build (CALL_EXPR
, TREE_TYPE (TREE_TYPE (fn
)),
3298 call_expr
, arglist
, NULL_TREE
);
3299 TREE_SIDE_EFFECTS (call_expr
) = 1;
3300 return expand_expr (call_expr
, (ignore
? const0_rtx
: NULL_RTX
),
3301 VOIDmode
, EXPAND_NORMAL
);
3304 /* Expand a call to __builtin_expect. We return our argument and
3305 emit a NOTE_INSN_EXPECTED_VALUE note. */
3308 expand_builtin_expect (arglist
, target
)
3315 if (arglist
== NULL_TREE
3316 || TREE_CHAIN (arglist
) == NULL_TREE
)
3318 exp
= TREE_VALUE (arglist
);
3319 c
= TREE_VALUE (TREE_CHAIN (arglist
));
3321 if (TREE_CODE (c
) != INTEGER_CST
)
3323 error ("second arg to `__builtin_expect' must be a constant");
3324 c
= integer_zero_node
;
3327 target
= expand_expr (exp
, target
, VOIDmode
, EXPAND_NORMAL
);
3329 /* Don't bother with expected value notes for integral constants. */
3330 if (GET_CODE (target
) != CONST_INT
)
3332 /* We do need to force this into a register so that we can be
3333 moderately sure to be able to correctly interpret the branch
3335 target
= force_reg (GET_MODE (target
), target
);
3337 rtx_c
= expand_expr (c
, NULL_RTX
, GET_MODE (target
), EXPAND_NORMAL
);
3339 note
= emit_note (NULL
, NOTE_INSN_EXPECTED_VALUE
);
3340 NOTE_EXPECTED_VALUE (note
) = gen_rtx_EQ (VOIDmode
, target
, rtx_c
);
3346 /* Expand an expression EXP that calls a built-in function,
3347 with result going to TARGET if that's convenient
3348 (and in mode MODE if that's convenient).
3349 SUBTARGET may be used as the target for computing one of EXP's operands.
3350 IGNORE is nonzero if the value is to be ignored. */
3353 expand_builtin (exp
, target
, subtarget
, mode
, ignore
)
3357 enum machine_mode mode
;
3360 tree fndecl
= TREE_OPERAND (TREE_OPERAND (exp
, 0), 0);
3361 tree arglist
= TREE_OPERAND (exp
, 1);
3362 enum built_in_function fcode
= DECL_FUNCTION_CODE (fndecl
);
3364 #ifdef MD_EXPAND_BUILTIN
3365 if (DECL_BUILT_IN_CLASS (fndecl
) == BUILT_IN_MD
)
3366 return MD_EXPAND_BUILTIN (exp
, target
, subtarget
, mode
, ignore
);
3369 /* When not optimizing, generate calls to library functions for a certain
3371 if (! optimize
&& ! CALLED_AS_BUILT_IN (fndecl
)
3372 && (fcode
== BUILT_IN_SIN
|| fcode
== BUILT_IN_COS
3373 || fcode
== BUILT_IN_FSQRT
|| fcode
== BUILT_IN_MEMSET
3374 || fcode
== BUILT_IN_MEMCPY
|| fcode
== BUILT_IN_MEMCMP
3375 || fcode
== BUILT_IN_BCMP
|| fcode
== BUILT_IN_BZERO
3376 || fcode
== BUILT_IN_INDEX
|| fcode
== BUILT_IN_RINDEX
3377 || fcode
== BUILT_IN_STRCHR
|| fcode
== BUILT_IN_STRRCHR
3378 || fcode
== BUILT_IN_STRLEN
|| fcode
== BUILT_IN_STRCPY
3379 || fcode
== BUILT_IN_STRNCPY
|| fcode
== BUILT_IN_STRNCMP
3380 || fcode
== BUILT_IN_STRSTR
|| fcode
== BUILT_IN_STRPBRK
3381 || fcode
== BUILT_IN_STRCAT
|| fcode
== BUILT_IN_STRNCAT
3382 || fcode
== BUILT_IN_STRSPN
|| fcode
== BUILT_IN_STRCSPN
3383 || fcode
== BUILT_IN_STRCMP
|| fcode
== BUILT_IN_FFS
3384 || fcode
== BUILT_IN_PUTCHAR
|| fcode
== BUILT_IN_PUTS
3385 || fcode
== BUILT_IN_PRINTF
|| fcode
== BUILT_IN_FPUTC
3386 || fcode
== BUILT_IN_FPUTS
|| fcode
== BUILT_IN_FWRITE
))
3387 return expand_call (exp
, target
, ignore
);
3393 case BUILT_IN_LLABS
:
3394 case BUILT_IN_IMAXABS
:
3396 /* build_function_call changes these into ABS_EXPR. */
3401 /* Treat these like sqrt, but only if the user asks for them. */
3402 if (! flag_fast_math
)
3404 case BUILT_IN_FSQRT
:
3405 target
= expand_builtin_mathfn (exp
, target
, subtarget
);
3413 case BUILT_IN_APPLY_ARGS
:
3414 return expand_builtin_apply_args ();
3416 /* __builtin_apply (FUNCTION, ARGUMENTS, ARGSIZE) invokes
3417 FUNCTION with a copy of the parameters described by
3418 ARGUMENTS, and ARGSIZE. It returns a block of memory
3419 allocated on the stack into which is stored all the registers
3420 that might possibly be used for returning the result of a
3421 function. ARGUMENTS is the value returned by
3422 __builtin_apply_args. ARGSIZE is the number of bytes of
3423 arguments that must be copied. ??? How should this value be
3424 computed? We'll also need a safe worst case value for varargs
3426 case BUILT_IN_APPLY
:
3428 /* Arg could be non-pointer if user redeclared this fcn wrong. */
3429 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist
)))
3430 || TREE_CHAIN (arglist
) == 0
3431 || TREE_CODE (TREE_TYPE (TREE_VALUE (TREE_CHAIN (arglist
)))) != POINTER_TYPE
3432 || TREE_CHAIN (TREE_CHAIN (arglist
)) == 0
3433 || TREE_CODE (TREE_TYPE (TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
))))) != INTEGER_TYPE
)
3441 for (t
= arglist
, i
= 0; t
; t
= TREE_CHAIN (t
), i
++)
3442 ops
[i
] = expand_expr (TREE_VALUE (t
), NULL_RTX
, VOIDmode
, 0);
3444 return expand_builtin_apply (ops
[0], ops
[1], ops
[2]);
3447 /* __builtin_return (RESULT) causes the function to return the
3448 value described by RESULT. RESULT is address of the block of
3449 memory returned by __builtin_apply. */
3450 case BUILT_IN_RETURN
:
3452 /* Arg could be non-pointer if user redeclared this fcn wrong. */
3453 && TREE_CODE (TREE_TYPE (TREE_VALUE (arglist
))) == POINTER_TYPE
)
3454 expand_builtin_return (expand_expr (TREE_VALUE (arglist
),
3455 NULL_RTX
, VOIDmode
, 0));
3458 case BUILT_IN_SAVEREGS
:
3459 return expand_builtin_saveregs ();
3461 case BUILT_IN_ARGS_INFO
:
3462 return expand_builtin_args_info (exp
);
3464 /* Return the address of the first anonymous stack arg. */
3465 case BUILT_IN_NEXT_ARG
:
3466 return expand_builtin_next_arg (arglist
);
3468 case BUILT_IN_CLASSIFY_TYPE
:
3469 return expand_builtin_classify_type (arglist
);
3471 case BUILT_IN_CONSTANT_P
:
3472 return expand_builtin_constant_p (exp
);
3474 case BUILT_IN_FRAME_ADDRESS
:
3475 case BUILT_IN_RETURN_ADDRESS
:
3476 return expand_builtin_frame_address (exp
);
3478 /* Returns the address of the area where the structure is returned.
3480 case BUILT_IN_AGGREGATE_INCOMING_ADDRESS
:
3482 || ! AGGREGATE_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl
)))
3483 || GET_CODE (DECL_RTL (DECL_RESULT (current_function_decl
))) != MEM
)
3486 return XEXP (DECL_RTL (DECL_RESULT (current_function_decl
)), 0);
3488 case BUILT_IN_ALLOCA
:
3489 target
= expand_builtin_alloca (arglist
, target
);
3495 target
= expand_builtin_ffs (arglist
, target
, subtarget
);
3500 case BUILT_IN_STRLEN
:
3501 target
= expand_builtin_strlen (exp
, target
);
3506 case BUILT_IN_STRCPY
:
3507 target
= expand_builtin_strcpy (exp
);
3512 case BUILT_IN_STRNCPY
:
3513 target
= expand_builtin_strncpy (arglist
, target
, mode
);
3518 case BUILT_IN_STRCAT
:
3519 target
= expand_builtin_strcat (arglist
, target
, mode
);
3524 case BUILT_IN_STRNCAT
:
3525 target
= expand_builtin_strncat (arglist
, target
, mode
);
3530 case BUILT_IN_STRSPN
:
3531 target
= expand_builtin_strspn (arglist
, target
, mode
);
3536 case BUILT_IN_STRCSPN
:
3537 target
= expand_builtin_strcspn (arglist
, target
, mode
);
3542 case BUILT_IN_STRSTR
:
3543 target
= expand_builtin_strstr (arglist
, target
, mode
);
3548 case BUILT_IN_STRPBRK
:
3549 target
= expand_builtin_strpbrk (arglist
, target
, mode
);
3554 case BUILT_IN_INDEX
:
3555 case BUILT_IN_STRCHR
:
3556 target
= expand_builtin_strchr (arglist
, target
, mode
);
3561 case BUILT_IN_RINDEX
:
3562 case BUILT_IN_STRRCHR
:
3563 target
= expand_builtin_strrchr (arglist
, target
, mode
);
3568 case BUILT_IN_MEMCPY
:
3569 target
= expand_builtin_memcpy (arglist
);
3574 case BUILT_IN_MEMSET
:
3575 target
= expand_builtin_memset (exp
);
3580 case BUILT_IN_BZERO
:
3581 target
= expand_builtin_bzero (exp
);
3586 case BUILT_IN_STRCMP
:
3587 target
= expand_builtin_strcmp (exp
, target
, mode
);
3592 case BUILT_IN_STRNCMP
:
3593 target
= expand_builtin_strncmp (exp
, target
, mode
);
3598 /* These comparison functions need an instruction that returns an actual
3599 index. An ordinary compare that just sets the condition codes
3601 #ifdef HAVE_cmpstrsi
3603 case BUILT_IN_MEMCMP
:
3604 target
= expand_builtin_memcmp (exp
, arglist
, target
);
3610 case BUILT_IN_MEMCMP
:
3614 case BUILT_IN_SETJMP
:
3615 target
= expand_builtin_setjmp (arglist
, target
);
3620 /* __builtin_longjmp is passed a pointer to an array of five words.
3621 It's similar to the C library longjmp function but works with
3622 __builtin_setjmp above. */
3623 case BUILT_IN_LONGJMP
:
3624 if (arglist
== 0 || TREE_CHAIN (arglist
) == 0
3625 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist
))) != POINTER_TYPE
)
3629 rtx buf_addr
= expand_expr (TREE_VALUE (arglist
), subtarget
,
3631 rtx value
= expand_expr (TREE_VALUE (TREE_CHAIN (arglist
)),
3632 NULL_RTX
, VOIDmode
, 0);
3634 if (value
!= const1_rtx
)
3636 error ("__builtin_longjmp second argument must be 1");
3640 expand_builtin_longjmp (buf_addr
, value
);
3647 emit_insn (gen_trap ());
3650 error ("__builtin_trap not supported by this target");
3654 case BUILT_IN_PUTCHAR
:
3656 case BUILT_IN_FPUTC
:
3657 case BUILT_IN_FWRITE
:
3659 case BUILT_IN_FPUTS
:
3660 target
= expand_builtin_fputs (arglist
, ignore
);
3665 /* Various hooks for the DWARF 2 __throw routine. */
3666 case BUILT_IN_UNWIND_INIT
:
3667 expand_builtin_unwind_init ();
3669 case BUILT_IN_DWARF_CFA
:
3670 return virtual_cfa_rtx
;
3671 #ifdef DWARF2_UNWIND_INFO
3672 case BUILT_IN_DWARF_FP_REGNUM
:
3673 return expand_builtin_dwarf_fp_regnum ();
3674 case BUILT_IN_INIT_DWARF_REG_SIZES
:
3675 expand_builtin_init_dwarf_reg_sizes (TREE_VALUE (arglist
));
3678 case BUILT_IN_FROB_RETURN_ADDR
:
3679 return expand_builtin_frob_return_addr (TREE_VALUE (arglist
));
3680 case BUILT_IN_EXTRACT_RETURN_ADDR
:
3681 return expand_builtin_extract_return_addr (TREE_VALUE (arglist
));
3682 case BUILT_IN_EH_RETURN
:
3683 expand_builtin_eh_return (TREE_VALUE (arglist
),
3684 TREE_VALUE (TREE_CHAIN (arglist
)),
3685 TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
))));
3687 case BUILT_IN_VARARGS_START
:
3688 return expand_builtin_va_start (0, arglist
);
3689 case BUILT_IN_STDARG_START
:
3690 return expand_builtin_va_start (1, arglist
);
3691 case BUILT_IN_VA_END
:
3692 return expand_builtin_va_end (arglist
);
3693 case BUILT_IN_VA_COPY
:
3694 return expand_builtin_va_copy (arglist
);
3695 case BUILT_IN_EXPECT
:
3696 return expand_builtin_expect (arglist
, target
);
3698 default: /* just do library call, if unknown builtin */
3699 error ("built-in function `%s' not currently supported",
3700 IDENTIFIER_POINTER (DECL_NAME (fndecl
)));
3703 /* The switch statement above can drop through to cause the function
3704 to be called normally. */
3705 return expand_call (exp
, target
, ignore
);
3708 /* Fold a call to __builtin_constant_p, if we know it will evaluate to a
3709 constant. ARGLIST is the argument list of the call. */
3712 fold_builtin_constant_p (arglist
)
3718 arglist
= TREE_VALUE (arglist
);
3720 /* We return 1 for a numeric type that's known to be a constant
3721 value at compile-time or for an aggregate type that's a
3722 literal constant. */
3723 STRIP_NOPS (arglist
);
3725 /* If we know this is a constant, emit the constant of one. */
3726 if (TREE_CODE_CLASS (TREE_CODE (arglist
)) == 'c'
3727 || (TREE_CODE (arglist
) == CONSTRUCTOR
3728 && TREE_CONSTANT (arglist
))
3729 || (TREE_CODE (arglist
) == ADDR_EXPR
3730 && TREE_CODE (TREE_OPERAND (arglist
, 0)) == STRING_CST
))
3731 return integer_one_node
;
3733 /* If we aren't going to be running CSE or this expression
3734 has side effects, show we don't know it to be a constant.
3735 Likewise if it's a pointer or aggregate type since in those
3736 case we only want literals, since those are only optimized
3737 when generating RTL, not later. */
3738 if (TREE_SIDE_EFFECTS (arglist
) || cse_not_expected
3739 || AGGREGATE_TYPE_P (TREE_TYPE (arglist
))
3740 || POINTER_TYPE_P (TREE_TYPE (arglist
)))
3741 return integer_zero_node
;
3746 /* Used by constant folding to eliminate some builtin calls early. EXP is
3747 the CALL_EXPR of a call to a builtin function. */
3753 tree fndecl
= TREE_OPERAND (TREE_OPERAND (exp
, 0), 0);
3754 tree arglist
= TREE_OPERAND (exp
, 1);
3755 enum built_in_function fcode
= DECL_FUNCTION_CODE (fndecl
);
3757 if (DECL_BUILT_IN_CLASS (fndecl
) == BUILT_IN_MD
)
3762 case BUILT_IN_CONSTANT_P
:
3763 return fold_builtin_constant_p (arglist
);
3765 case BUILT_IN_STRLEN
:
3767 /* Arg could be non-pointer if user redeclared this fcn wrong. */
3768 && TREE_CODE (TREE_TYPE (TREE_VALUE (arglist
))) == POINTER_TYPE
)
3770 tree len
= c_strlen (TREE_VALUE (arglist
));