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 get_memory_rtx PARAMS ((tree));
85 static int apply_args_size PARAMS ((void));
86 static int apply_result_size PARAMS ((void));
87 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
88 static rtx result_vector PARAMS ((int, rtx));
90 static rtx expand_builtin_apply_args PARAMS ((void));
91 static rtx expand_builtin_apply_args_1 PARAMS ((void));
92 static rtx expand_builtin_apply PARAMS ((rtx, rtx, rtx));
93 static void expand_builtin_return PARAMS ((rtx));
94 static rtx expand_builtin_classify_type PARAMS ((tree));
95 static rtx expand_builtin_mathfn PARAMS ((tree, rtx, rtx));
96 static rtx expand_builtin_constant_p PARAMS ((tree));
97 static rtx expand_builtin_args_info PARAMS ((tree));
98 static rtx expand_builtin_next_arg PARAMS ((tree));
99 static rtx expand_builtin_va_start PARAMS ((int, tree));
100 static rtx expand_builtin_va_end PARAMS ((tree));
101 static rtx expand_builtin_va_copy PARAMS ((tree));
103 static rtx expand_builtin_memcmp PARAMS ((tree, tree, rtx));
105 static rtx expand_builtin_strcmp PARAMS ((tree, rtx,
107 static rtx expand_builtin_memcpy PARAMS ((tree));
108 static rtx expand_builtin_strcpy PARAMS ((tree));
109 static rtx expand_builtin_memset PARAMS ((tree));
110 static rtx expand_builtin_bzero PARAMS ((tree));
111 static rtx expand_builtin_strlen PARAMS ((tree, rtx));
112 static rtx expand_builtin_strstr PARAMS ((tree, rtx,
114 static rtx expand_builtin_strpbrk PARAMS ((tree, rtx,
116 static rtx expand_builtin_strchr PARAMS ((tree, rtx,
118 static rtx expand_builtin_strrchr PARAMS ((tree, rtx,
120 static rtx expand_builtin_alloca PARAMS ((tree, rtx));
121 static rtx expand_builtin_ffs PARAMS ((tree, rtx, rtx));
122 static rtx expand_builtin_frame_address PARAMS ((tree));
123 static rtx expand_builtin_fputs PARAMS ((tree, int));
124 static tree stabilize_va_list PARAMS ((tree, int));
125 static rtx expand_builtin_expect PARAMS ((tree, rtx));
126 static tree fold_builtin_constant_p PARAMS ((tree));
128 /* Return the alignment in bits of EXP, a pointer valued expression.
129 But don't return more than MAX_ALIGN no matter what.
130 The alignment returned is, by default, the alignment of the thing that
131 EXP points to (if it is not a POINTER_TYPE, 0 is returned).
133 Otherwise, look at the expression to see if we can do better, i.e., if the
134 expression is actually pointing at an object whose alignment is tighter. */
137 get_pointer_alignment (exp, max_align)
141 unsigned align, inner;
143 if (TREE_CODE (TREE_TYPE (exp)) != POINTER_TYPE)
146 align = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
147 align = MIN (align, max_align);
151 switch (TREE_CODE (exp))
155 case NON_LVALUE_EXPR:
156 exp = TREE_OPERAND (exp, 0);
157 if (TREE_CODE (TREE_TYPE (exp)) != POINTER_TYPE)
160 inner = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
161 align = MIN (inner, max_align);
165 /* If sum of pointer + int, restrict our maximum alignment to that
166 imposed by the integer. If not, we can't do any better than
168 if (! host_integerp (TREE_OPERAND (exp, 1), 1))
171 while (((tree_low_cst (TREE_OPERAND (exp, 1), 1) * BITS_PER_UNIT)
176 exp = TREE_OPERAND (exp, 0);
180 /* See what we are pointing at and look at its alignment. */
181 exp = TREE_OPERAND (exp, 0);
182 if (TREE_CODE (exp) == FUNCTION_DECL)
183 align = FUNCTION_BOUNDARY;
184 else if (DECL_P (exp))
185 align = DECL_ALIGN (exp);
186 #ifdef CONSTANT_ALIGNMENT
187 else if (TREE_CODE_CLASS (TREE_CODE (exp)) == 'c')
188 align = CONSTANT_ALIGNMENT (exp, align);
190 return MIN (align, max_align);
198 /* Compute the length of a C string. TREE_STRING_LENGTH is not the right
199 way, because it could contain a zero byte in the middle.
200 TREE_STRING_LENGTH is the size of the character array, not the string.
202 The value returned is of type `ssizetype'.
204 Unfortunately, string_constant can't access the values of const char
205 arrays with initializers, so neither can we do so here. */
215 src = string_constant (src, &offset_node);
219 max = TREE_STRING_LENGTH (src) - 1;
220 ptr = TREE_STRING_POINTER (src);
222 if (offset_node && TREE_CODE (offset_node) != INTEGER_CST)
224 /* If the string has an internal zero byte (e.g., "foo\0bar"), we can't
225 compute the offset to the following null if we don't know where to
226 start searching for it. */
229 for (i = 0; i < max; i++)
233 /* We don't know the starting offset, but we do know that the string
234 has no internal zero bytes. We can assume that the offset falls
235 within the bounds of the string; otherwise, the programmer deserves
236 what he gets. Subtract the offset from the length of the string,
237 and return that. This would perhaps not be valid if we were dealing
238 with named arrays in addition to literal string constants. */
240 return size_diffop (size_int (max), offset_node);
243 /* We have a known offset into the string. Start searching there for
245 if (offset_node == 0)
249 /* Did we get a long long offset? If so, punt. */
250 if (TREE_INT_CST_HIGH (offset_node) != 0)
252 offset = TREE_INT_CST_LOW (offset_node);
255 /* If the offset is known to be out of bounds, warn, and call strlen at
257 if (offset < 0 || offset > max)
259 warning ("offset outside bounds of constant string");
263 /* Use strlen to search for the first zero byte. Since any strings
264 constructed with build_string will have nulls appended, we win even
265 if we get handed something like (char[4])"abcd".
267 Since OFFSET is our starting index into the string, no further
268 calculation is needed. */
269 return ssize_int (strlen (ptr + offset));
272 /* Return a char pointer for a C string if it is a string constant
273 or sum of string constant and integer constant. */
283 src = string_constant (src, &offset_node);
287 max = TREE_STRING_LENGTH (src) - 1;
288 ptr = TREE_STRING_POINTER (src);
292 else if (TREE_CODE (offset_node) != INTEGER_CST)
296 /* Did we get a long long offset? If so, punt. */
297 if (TREE_INT_CST_HIGH (offset_node) != 0)
299 offset = TREE_INT_CST_LOW (offset_node);
300 if (offset < 0 || offset > max)
304 return (const char *) ptr + offset;
307 /* Given TEM, a pointer to a stack frame, follow the dynamic chain COUNT
308 times to get the address of either a higher stack frame, or a return
309 address located within it (depending on FNDECL_CODE). */
312 expand_builtin_return_addr (fndecl_code, count, tem)
313 enum built_in_function fndecl_code;
319 /* Some machines need special handling before we can access
320 arbitrary frames. For example, on the sparc, we must first flush
321 all register windows to the stack. */
322 #ifdef SETUP_FRAME_ADDRESSES
324 SETUP_FRAME_ADDRESSES ();
327 /* On the sparc, the return address is not in the frame, it is in a
328 register. There is no way to access it off of the current frame
329 pointer, but it can be accessed off the previous frame pointer by
330 reading the value from the register window save area. */
331 #ifdef RETURN_ADDR_IN_PREVIOUS_FRAME
332 if (fndecl_code == BUILT_IN_RETURN_ADDRESS)
336 /* Scan back COUNT frames to the specified frame. */
337 for (i = 0; i < count; i++)
339 /* Assume the dynamic chain pointer is in the word that the
340 frame address points to, unless otherwise specified. */
341 #ifdef DYNAMIC_CHAIN_ADDRESS
342 tem = DYNAMIC_CHAIN_ADDRESS (tem);
344 tem = memory_address (Pmode, tem);
345 tem = copy_to_reg (gen_rtx_MEM (Pmode, tem));
346 MEM_ALIAS_SET (tem) = get_frame_alias_set ();
349 /* For __builtin_frame_address, return what we've got. */
350 if (fndecl_code == BUILT_IN_FRAME_ADDRESS)
353 /* For __builtin_return_address, Get the return address from that
355 #ifdef RETURN_ADDR_RTX
356 tem = RETURN_ADDR_RTX (count, tem);
358 tem = memory_address (Pmode,
359 plus_constant (tem, GET_MODE_SIZE (Pmode)));
360 tem = gen_rtx_MEM (Pmode, tem);
361 MEM_ALIAS_SET (tem) = get_frame_alias_set ();
366 /* Alias set used for setjmp buffer. */
367 static HOST_WIDE_INT setjmp_alias_set = -1;
369 /* __builtin_setjmp is passed a pointer to an array of five words (not
370 all will be used on all machines). It operates similarly to the C
371 library function of the same name, but is more efficient. Much of
372 the code below (and for longjmp) is copied from the handling of
375 NOTE: This is intended for use by GNAT and the exception handling
376 scheme in the compiler and will only work in the method used by
380 expand_builtin_setjmp (buf_addr, target, first_label, next_label)
383 rtx first_label, next_label;
385 rtx lab1 = gen_label_rtx ();
386 enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
387 enum machine_mode value_mode;
391 value_mode = TYPE_MODE (integer_type_node);
393 if (setjmp_alias_set == -1)
394 setjmp_alias_set = new_alias_set ();
396 #ifdef POINTERS_EXTEND_UNSIGNED
397 buf_addr = convert_memory_address (Pmode, buf_addr);
400 buf_addr = force_reg (Pmode, force_operand (buf_addr, NULL_RTX));
402 if (target == 0 || GET_CODE (target) != REG
403 || REGNO (target) < FIRST_PSEUDO_REGISTER)
404 target = gen_reg_rtx (value_mode);
408 /* We store the frame pointer and the address of lab1 in the buffer
409 and use the rest of it for the stack save area, which is
410 machine-dependent. */
412 #ifndef BUILTIN_SETJMP_FRAME_VALUE
413 #define BUILTIN_SETJMP_FRAME_VALUE virtual_stack_vars_rtx
416 mem = gen_rtx_MEM (Pmode, buf_addr);
417 MEM_ALIAS_SET (mem) = setjmp_alias_set;
418 emit_move_insn (mem, BUILTIN_SETJMP_FRAME_VALUE);
420 mem = gen_rtx_MEM (Pmode, plus_constant (buf_addr, GET_MODE_SIZE (Pmode))),
421 MEM_ALIAS_SET (mem) = setjmp_alias_set;
423 emit_move_insn (validize_mem (mem),
424 force_reg (Pmode, gen_rtx_LABEL_REF (Pmode, lab1)));
426 stack_save = gen_rtx_MEM (sa_mode,
427 plus_constant (buf_addr,
428 2 * GET_MODE_SIZE (Pmode)));
429 MEM_ALIAS_SET (stack_save) = setjmp_alias_set;
430 emit_stack_save (SAVE_NONLOCAL, &stack_save, NULL_RTX);
432 /* If there is further processing to do, do it. */
433 #ifdef HAVE_builtin_setjmp_setup
434 if (HAVE_builtin_setjmp_setup)
435 emit_insn (gen_builtin_setjmp_setup (buf_addr));
438 /* Set TARGET to zero and branch to the first-time-through label. */
439 emit_move_insn (target, const0_rtx);
440 emit_jump_insn (gen_jump (first_label));
444 /* Tell flow about the strange goings on. Putting `lab1' on
445 `nonlocal_goto_handler_labels' to indicates that function
446 calls may traverse the arc back to this label. */
448 current_function_has_nonlocal_label = 1;
449 current_function_calls_setjmp = 1;
450 nonlocal_goto_handler_labels
451 = gen_rtx_EXPR_LIST (VOIDmode, lab1, nonlocal_goto_handler_labels);
453 /* Clobber the FP when we get here, so we have to make sure it's
454 marked as used by this function. */
455 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
457 /* Mark the static chain as clobbered here so life information
458 doesn't get messed up for it. */
459 emit_insn (gen_rtx_CLOBBER (VOIDmode, static_chain_rtx));
461 /* Now put in the code to restore the frame pointer, and argument
462 pointer, if needed. The code below is from expand_end_bindings
463 in stmt.c; see detailed documentation there. */
464 #ifdef HAVE_nonlocal_goto
465 if (! HAVE_nonlocal_goto)
467 emit_move_insn (virtual_stack_vars_rtx, hard_frame_pointer_rtx);
469 #if ARG_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
470 if (fixed_regs[ARG_POINTER_REGNUM])
472 #ifdef ELIMINABLE_REGS
474 static struct elims {int from, to;} elim_regs[] = ELIMINABLE_REGS;
476 for (i = 0; i < ARRAY_SIZE (elim_regs); i++)
477 if (elim_regs[i].from == ARG_POINTER_REGNUM
478 && elim_regs[i].to == HARD_FRAME_POINTER_REGNUM)
481 if (i == ARRAY_SIZE (elim_regs))
484 /* Now restore our arg pointer from the address at which it
485 was saved in our stack frame.
486 If there hasn't be space allocated for it yet, make
488 if (arg_pointer_save_area == 0)
489 arg_pointer_save_area
490 = assign_stack_local (Pmode, GET_MODE_SIZE (Pmode), 0);
491 emit_move_insn (virtual_incoming_args_rtx,
492 copy_to_reg (arg_pointer_save_area));
497 #ifdef HAVE_builtin_setjmp_receiver
498 if (HAVE_builtin_setjmp_receiver)
499 emit_insn (gen_builtin_setjmp_receiver (lab1));
502 #ifdef HAVE_nonlocal_goto_receiver
503 if (HAVE_nonlocal_goto_receiver)
504 emit_insn (gen_nonlocal_goto_receiver ());
511 /* Set TARGET, and branch to the next-time-through label. */
512 emit_move_insn (target, const1_rtx);
513 emit_jump_insn (gen_jump (next_label));
519 /* __builtin_longjmp is passed a pointer to an array of five words (not
520 all will be used on all machines). It operates similarly to the C
521 library function of the same name, but is more efficient. Much of
522 the code below is copied from the handling of non-local gotos.
524 NOTE: This is intended for use by GNAT and the exception handling
525 scheme in the compiler and will only work in the method used by
529 expand_builtin_longjmp (buf_addr, value)
533 enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
535 if (setjmp_alias_set == -1)
536 setjmp_alias_set = new_alias_set ();
538 #ifdef POINTERS_EXTEND_UNSIGNED
539 buf_addr = convert_memory_address (Pmode, buf_addr);
541 buf_addr = force_reg (Pmode, buf_addr);
543 /* We used to store value in static_chain_rtx, but that fails if pointers
544 are smaller than integers. We instead require that the user must pass
545 a second argument of 1, because that is what builtin_setjmp will
546 return. This also makes EH slightly more efficient, since we are no
547 longer copying around a value that we don't care about. */
548 if (value != const1_rtx)
551 current_function_calls_longjmp = 1;
553 #ifdef HAVE_builtin_longjmp
554 if (HAVE_builtin_longjmp)
555 emit_insn (gen_builtin_longjmp (buf_addr));
559 fp = gen_rtx_MEM (Pmode, buf_addr);
560 lab = gen_rtx_MEM (Pmode, plus_constant (buf_addr,
561 GET_MODE_SIZE (Pmode)));
563 stack = gen_rtx_MEM (sa_mode, plus_constant (buf_addr,
564 2 * GET_MODE_SIZE (Pmode)));
565 MEM_ALIAS_SET (fp) = MEM_ALIAS_SET (lab) = MEM_ALIAS_SET (stack)
568 /* Pick up FP, label, and SP from the block and jump. This code is
569 from expand_goto in stmt.c; see there for detailed comments. */
570 #if HAVE_nonlocal_goto
571 if (HAVE_nonlocal_goto)
572 /* We have to pass a value to the nonlocal_goto pattern that will
573 get copied into the static_chain pointer, but it does not matter
574 what that value is, because builtin_setjmp does not use it. */
575 emit_insn (gen_nonlocal_goto (value, fp, stack, lab));
579 lab = copy_to_reg (lab);
581 emit_move_insn (hard_frame_pointer_rtx, fp);
582 emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
584 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
585 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
586 emit_indirect_jump (lab);
591 /* Get a MEM rtx for expression EXP which is the address of an operand
592 to be used to be used in a string instruction (cmpstrsi, movstrsi, ..). */
598 rtx mem = gen_rtx_MEM (BLKmode,
599 memory_address (BLKmode,
600 expand_expr (exp, NULL_RTX,
601 ptr_mode, EXPAND_SUM)));
603 /* Get an expression we can use to find the attributes to assign to MEM.
604 If it is an ADDR_EXPR, use the operand. Otherwise, dereference it if
605 we can. First remove any nops. */
606 while ((TREE_CODE (exp) == NOP_EXPR || TREE_CODE (exp) == CONVERT_EXPR
607 || TREE_CODE (exp) == NON_LVALUE_EXPR)
608 && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (exp, 0))))
609 exp = TREE_OPERAND (exp, 0);
611 if (TREE_CODE (exp) == ADDR_EXPR)
612 exp = TREE_OPERAND (exp, 0);
613 else if (POINTER_TYPE_P (TREE_TYPE (exp)))
614 exp = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (exp)), exp);
618 set_mem_attributes (mem, exp, 0);
620 /* memcpy, memset and other builtin stringops can alias with anything. */
621 MEM_ALIAS_SET (mem) = 0;
625 /* Built-in functions to perform an untyped call and return. */
627 /* For each register that may be used for calling a function, this
628 gives a mode used to copy the register's value. VOIDmode indicates
629 the register is not used for calling a function. If the machine
630 has register windows, this gives only the outbound registers.
631 INCOMING_REGNO gives the corresponding inbound register. */
632 static enum machine_mode apply_args_mode[FIRST_PSEUDO_REGISTER];
634 /* For each register that may be used for returning values, this gives
635 a mode used to copy the register's value. VOIDmode indicates the
636 register is not used for returning values. If the machine has
637 register windows, this gives only the outbound registers.
638 INCOMING_REGNO gives the corresponding inbound register. */
639 static enum machine_mode apply_result_mode[FIRST_PSEUDO_REGISTER];
641 /* For each register that may be used for calling a function, this
642 gives the offset of that register into the block returned by
643 __builtin_apply_args. 0 indicates that the register is not
644 used for calling a function. */
645 static int apply_args_reg_offset[FIRST_PSEUDO_REGISTER];
647 /* Return the offset of register REGNO into the block returned by
648 __builtin_apply_args. This is not declared static, since it is
649 needed in objc-act.c. */
652 apply_args_register_offset (regno)
657 /* Arguments are always put in outgoing registers (in the argument
658 block) if such make sense. */
659 #ifdef OUTGOING_REGNO
660 regno = OUTGOING_REGNO(regno);
662 return apply_args_reg_offset[regno];
665 /* Return the size required for the block returned by __builtin_apply_args,
666 and initialize apply_args_mode. */
671 static int size = -1;
673 enum machine_mode mode;
675 /* The values computed by this function never change. */
678 /* The first value is the incoming arg-pointer. */
679 size = GET_MODE_SIZE (Pmode);
681 /* The second value is the structure value address unless this is
682 passed as an "invisible" first argument. */
683 if (struct_value_rtx)
684 size += GET_MODE_SIZE (Pmode);
686 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
687 if (FUNCTION_ARG_REGNO_P (regno))
689 /* Search for the proper mode for copying this register's
690 value. I'm not sure this is right, but it works so far. */
691 enum machine_mode best_mode = VOIDmode;
693 for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT);
695 mode = GET_MODE_WIDER_MODE (mode))
696 if (HARD_REGNO_MODE_OK (regno, mode)
697 && HARD_REGNO_NREGS (regno, mode) == 1)
700 if (best_mode == VOIDmode)
701 for (mode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT);
703 mode = GET_MODE_WIDER_MODE (mode))
704 if (HARD_REGNO_MODE_OK (regno, mode)
705 && (mov_optab->handlers[(int) mode].insn_code
706 != CODE_FOR_nothing))
710 if (mode == VOIDmode)
713 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
714 if (size % align != 0)
715 size = CEIL (size, align) * align;
716 apply_args_reg_offset[regno] = size;
717 size += GET_MODE_SIZE (mode);
718 apply_args_mode[regno] = mode;
722 apply_args_mode[regno] = VOIDmode;
723 apply_args_reg_offset[regno] = 0;
729 /* Return the size required for the block returned by __builtin_apply,
730 and initialize apply_result_mode. */
735 static int size = -1;
737 enum machine_mode mode;
739 /* The values computed by this function never change. */
744 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
745 if (FUNCTION_VALUE_REGNO_P (regno))
747 /* Search for the proper mode for copying this register's
748 value. I'm not sure this is right, but it works so far. */
749 enum machine_mode best_mode = VOIDmode;
751 for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT);
753 mode = GET_MODE_WIDER_MODE (mode))
754 if (HARD_REGNO_MODE_OK (regno, mode))
757 if (best_mode == VOIDmode)
758 for (mode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT);
760 mode = GET_MODE_WIDER_MODE (mode))
761 if (HARD_REGNO_MODE_OK (regno, mode)
762 && (mov_optab->handlers[(int) mode].insn_code
763 != CODE_FOR_nothing))
767 if (mode == VOIDmode)
770 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
771 if (size % align != 0)
772 size = CEIL (size, align) * align;
773 size += GET_MODE_SIZE (mode);
774 apply_result_mode[regno] = mode;
777 apply_result_mode[regno] = VOIDmode;
779 /* Allow targets that use untyped_call and untyped_return to override
780 the size so that machine-specific information can be stored here. */
781 #ifdef APPLY_RESULT_SIZE
782 size = APPLY_RESULT_SIZE;
788 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
789 /* Create a vector describing the result block RESULT. If SAVEP is true,
790 the result block is used to save the values; otherwise it is used to
791 restore the values. */
794 result_vector (savep, result)
798 int regno, size, align, nelts;
799 enum machine_mode mode;
801 rtx *savevec = (rtx *) alloca (FIRST_PSEUDO_REGISTER * sizeof (rtx));
804 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
805 if ((mode = apply_result_mode[regno]) != VOIDmode)
807 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
808 if (size % align != 0)
809 size = CEIL (size, align) * align;
810 reg = gen_rtx_REG (mode, savep ? regno : INCOMING_REGNO (regno));
811 mem = change_address (result, mode,
812 plus_constant (XEXP (result, 0), size));
813 savevec[nelts++] = (savep
814 ? gen_rtx_SET (VOIDmode, mem, reg)
815 : gen_rtx_SET (VOIDmode, reg, mem));
816 size += GET_MODE_SIZE (mode);
818 return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (nelts, savevec));
820 #endif /* HAVE_untyped_call or HAVE_untyped_return */
822 /* Save the state required to perform an untyped call with the same
823 arguments as were passed to the current function. */
826 expand_builtin_apply_args_1 ()
829 int size, align, regno;
830 enum machine_mode mode;
832 /* Create a block where the arg-pointer, structure value address,
833 and argument registers can be saved. */
834 registers = assign_stack_local (BLKmode, apply_args_size (), -1);
836 /* Walk past the arg-pointer and structure value address. */
837 size = GET_MODE_SIZE (Pmode);
838 if (struct_value_rtx)
839 size += GET_MODE_SIZE (Pmode);
841 /* Save each register used in calling a function to the block. */
842 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
843 if ((mode = apply_args_mode[regno]) != VOIDmode)
847 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
848 if (size % align != 0)
849 size = CEIL (size, align) * align;
851 tem = gen_rtx_REG (mode, INCOMING_REGNO (regno));
853 emit_move_insn (change_address (registers, mode,
854 plus_constant (XEXP (registers, 0),
857 size += GET_MODE_SIZE (mode);
860 /* Save the arg pointer to the block. */
861 emit_move_insn (change_address (registers, Pmode, XEXP (registers, 0)),
862 copy_to_reg (virtual_incoming_args_rtx));
863 size = GET_MODE_SIZE (Pmode);
865 /* Save the structure value address unless this is passed as an
866 "invisible" first argument. */
867 if (struct_value_incoming_rtx)
869 emit_move_insn (change_address (registers, Pmode,
870 plus_constant (XEXP (registers, 0),
872 copy_to_reg (struct_value_incoming_rtx));
873 size += GET_MODE_SIZE (Pmode);
876 /* Return the address of the block. */
877 return copy_addr_to_reg (XEXP (registers, 0));
880 /* __builtin_apply_args returns block of memory allocated on
881 the stack into which is stored the arg pointer, structure
882 value address, static chain, and all the registers that might
883 possibly be used in performing a function call. The code is
884 moved to the start of the function so the incoming values are
887 expand_builtin_apply_args ()
889 /* Don't do __builtin_apply_args more than once in a function.
890 Save the result of the first call and reuse it. */
891 if (apply_args_value != 0)
892 return apply_args_value;
894 /* When this function is called, it means that registers must be
895 saved on entry to this function. So we migrate the
896 call to the first insn of this function. */
901 temp = expand_builtin_apply_args_1 ();
905 apply_args_value = temp;
907 /* Put the sequence after the NOTE that starts the function.
908 If this is inside a SEQUENCE, make the outer-level insn
909 chain current, so the code is placed at the start of the
911 push_topmost_sequence ();
912 emit_insns_before (seq, NEXT_INSN (get_insns ()));
913 pop_topmost_sequence ();
918 /* Perform an untyped call and save the state required to perform an
919 untyped return of whatever value was returned by the given function. */
922 expand_builtin_apply (function, arguments, argsize)
923 rtx function, arguments, argsize;
925 int size, align, regno;
926 enum machine_mode mode;
927 rtx incoming_args, result, reg, dest, call_insn;
928 rtx old_stack_level = 0;
931 /* Create a block where the return registers can be saved. */
932 result = assign_stack_local (BLKmode, apply_result_size (), -1);
934 /* Fetch the arg pointer from the ARGUMENTS block. */
935 incoming_args = gen_reg_rtx (Pmode);
936 emit_move_insn (incoming_args,
937 gen_rtx_MEM (Pmode, arguments));
938 #ifndef STACK_GROWS_DOWNWARD
939 incoming_args = expand_binop (Pmode, sub_optab, incoming_args, argsize,
940 incoming_args, 0, OPTAB_LIB_WIDEN);
943 /* Perform postincrements before actually calling the function. */
946 /* Push a new argument block and copy the arguments. Do not allow
947 the (potential) memcpy call below to interfere with our stack
949 do_pending_stack_adjust ();
952 /* Save the stack with nonlocal if available */
953 #ifdef HAVE_save_stack_nonlocal
954 if (HAVE_save_stack_nonlocal)
955 emit_stack_save (SAVE_NONLOCAL, &old_stack_level, NULL_RTX);
958 emit_stack_save (SAVE_BLOCK, &old_stack_level, NULL_RTX);
960 /* Push a block of memory onto the stack to store the memory arguments.
961 Save the address in a register, and copy the memory arguments. ??? I
962 haven't figured out how the calling convention macros effect this,
963 but it's likely that the source and/or destination addresses in
964 the block copy will need updating in machine specific ways. */
965 dest = allocate_dynamic_stack_space (argsize, 0, BITS_PER_UNIT);
966 emit_block_move (gen_rtx_MEM (BLKmode, dest),
967 gen_rtx_MEM (BLKmode, incoming_args),
968 argsize, PARM_BOUNDARY);
970 /* Refer to the argument block. */
972 arguments = gen_rtx_MEM (BLKmode, arguments);
974 /* Walk past the arg-pointer and structure value address. */
975 size = GET_MODE_SIZE (Pmode);
976 if (struct_value_rtx)
977 size += GET_MODE_SIZE (Pmode);
979 /* Restore each of the registers previously saved. Make USE insns
980 for each of these registers for use in making the call. */
981 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
982 if ((mode = apply_args_mode[regno]) != VOIDmode)
984 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
985 if (size % align != 0)
986 size = CEIL (size, align) * align;
987 reg = gen_rtx_REG (mode, regno);
989 change_address (arguments, mode,
990 plus_constant (XEXP (arguments, 0),
993 use_reg (&call_fusage, reg);
994 size += GET_MODE_SIZE (mode);
997 /* Restore the structure value address unless this is passed as an
998 "invisible" first argument. */
999 size = GET_MODE_SIZE (Pmode);
1000 if (struct_value_rtx)
1002 rtx value = gen_reg_rtx (Pmode);
1003 emit_move_insn (value,
1004 change_address (arguments, Pmode,
1005 plus_constant (XEXP (arguments, 0),
1007 emit_move_insn (struct_value_rtx, value);
1008 if (GET_CODE (struct_value_rtx) == REG)
1009 use_reg (&call_fusage, struct_value_rtx);
1010 size += GET_MODE_SIZE (Pmode);
1013 /* All arguments and registers used for the call are set up by now! */
1014 function = prepare_call_address (function, NULL_TREE, &call_fusage, 0);
1016 /* Ensure address is valid. SYMBOL_REF is already valid, so no need,
1017 and we don't want to load it into a register as an optimization,
1018 because prepare_call_address already did it if it should be done. */
1019 if (GET_CODE (function) != SYMBOL_REF)
1020 function = memory_address (FUNCTION_MODE, function);
1022 /* Generate the actual call instruction and save the return value. */
1023 #ifdef HAVE_untyped_call
1024 if (HAVE_untyped_call)
1025 emit_call_insn (gen_untyped_call (gen_rtx_MEM (FUNCTION_MODE, function),
1026 result, result_vector (1, result)));
1029 #ifdef HAVE_call_value
1030 if (HAVE_call_value)
1034 /* Locate the unique return register. It is not possible to
1035 express a call that sets more than one return register using
1036 call_value; use untyped_call for that. In fact, untyped_call
1037 only needs to save the return registers in the given block. */
1038 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1039 if ((mode = apply_result_mode[regno]) != VOIDmode)
1042 abort (); /* HAVE_untyped_call required. */
1043 valreg = gen_rtx_REG (mode, regno);
1046 emit_call_insn (GEN_CALL_VALUE (valreg,
1047 gen_rtx_MEM (FUNCTION_MODE, function),
1048 const0_rtx, NULL_RTX, const0_rtx));
1050 emit_move_insn (change_address (result, GET_MODE (valreg),
1058 /* Find the CALL insn we just emitted. */
1059 for (call_insn = get_last_insn ();
1060 call_insn && GET_CODE (call_insn) != CALL_INSN;
1061 call_insn = PREV_INSN (call_insn))
1067 /* Put the register usage information on the CALL. If there is already
1068 some usage information, put ours at the end. */
1069 if (CALL_INSN_FUNCTION_USAGE (call_insn))
1073 for (link = CALL_INSN_FUNCTION_USAGE (call_insn); XEXP (link, 1) != 0;
1074 link = XEXP (link, 1))
1077 XEXP (link, 1) = call_fusage;
1080 CALL_INSN_FUNCTION_USAGE (call_insn) = call_fusage;
1082 /* Restore the stack. */
1083 #ifdef HAVE_save_stack_nonlocal
1084 if (HAVE_save_stack_nonlocal)
1085 emit_stack_restore (SAVE_NONLOCAL, old_stack_level, NULL_RTX);
1088 emit_stack_restore (SAVE_BLOCK, old_stack_level, NULL_RTX);
1092 /* Return the address of the result block. */
1093 return copy_addr_to_reg (XEXP (result, 0));
1096 /* Perform an untyped return. */
1099 expand_builtin_return (result)
1102 int size, align, regno;
1103 enum machine_mode mode;
1105 rtx call_fusage = 0;
1107 apply_result_size ();
1108 result = gen_rtx_MEM (BLKmode, result);
1110 #ifdef HAVE_untyped_return
1111 if (HAVE_untyped_return)
1113 emit_jump_insn (gen_untyped_return (result, result_vector (0, result)));
1119 /* Restore the return value and note that each value is used. */
1121 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1122 if ((mode = apply_result_mode[regno]) != VOIDmode)
1124 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1125 if (size % align != 0)
1126 size = CEIL (size, align) * align;
1127 reg = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1128 emit_move_insn (reg,
1129 change_address (result, mode,
1130 plus_constant (XEXP (result, 0),
1133 push_to_sequence (call_fusage);
1134 emit_insn (gen_rtx_USE (VOIDmode, reg));
1135 call_fusage = get_insns ();
1137 size += GET_MODE_SIZE (mode);
1140 /* Put the USE insns before the return. */
1141 emit_insns (call_fusage);
1143 /* Return whatever values was restored by jumping directly to the end
1145 expand_null_return ();
1148 /* Expand a call to __builtin_classify_type with arguments found in
1151 expand_builtin_classify_type (arglist)
1156 tree type = TREE_TYPE (TREE_VALUE (arglist));
1157 enum tree_code code = TREE_CODE (type);
1158 if (code == VOID_TYPE)
1159 return GEN_INT (void_type_class);
1160 if (code == INTEGER_TYPE)
1161 return GEN_INT (integer_type_class);
1162 if (code == CHAR_TYPE)
1163 return GEN_INT (char_type_class);
1164 if (code == ENUMERAL_TYPE)
1165 return GEN_INT (enumeral_type_class);
1166 if (code == BOOLEAN_TYPE)
1167 return GEN_INT (boolean_type_class);
1168 if (code == POINTER_TYPE)
1169 return GEN_INT (pointer_type_class);
1170 if (code == REFERENCE_TYPE)
1171 return GEN_INT (reference_type_class);
1172 if (code == OFFSET_TYPE)
1173 return GEN_INT (offset_type_class);
1174 if (code == REAL_TYPE)
1175 return GEN_INT (real_type_class);
1176 if (code == COMPLEX_TYPE)
1177 return GEN_INT (complex_type_class);
1178 if (code == FUNCTION_TYPE)
1179 return GEN_INT (function_type_class);
1180 if (code == METHOD_TYPE)
1181 return GEN_INT (method_type_class);
1182 if (code == RECORD_TYPE)
1183 return GEN_INT (record_type_class);
1184 if (code == UNION_TYPE || code == QUAL_UNION_TYPE)
1185 return GEN_INT (union_type_class);
1186 if (code == ARRAY_TYPE)
1188 if (TYPE_STRING_FLAG (type))
1189 return GEN_INT (string_type_class);
1191 return GEN_INT (array_type_class);
1193 if (code == SET_TYPE)
1194 return GEN_INT (set_type_class);
1195 if (code == FILE_TYPE)
1196 return GEN_INT (file_type_class);
1197 if (code == LANG_TYPE)
1198 return GEN_INT (lang_type_class);
1200 return GEN_INT (no_type_class);
1203 /* Expand expression EXP, which is a call to __builtin_constant_p. */
1205 expand_builtin_constant_p (exp)
1208 tree arglist = TREE_OPERAND (exp, 1);
1209 enum machine_mode value_mode = TYPE_MODE (TREE_TYPE (exp));
1214 arglist = TREE_VALUE (arglist);
1216 /* We have taken care of the easy cases during constant folding. This
1217 case is not obvious, so emit (constant_p_rtx (ARGLIST)) and let CSE get a
1218 chance to see if it can deduce whether ARGLIST is constant. */
1220 tmp = expand_expr (arglist, NULL_RTX, VOIDmode, 0);
1221 tmp = gen_rtx_CONSTANT_P_RTX (value_mode, tmp);
1225 /* Expand a call to one of the builtin math functions (sin, cos, or sqrt).
1226 Return 0 if a normal call should be emitted rather than expanding the
1227 function in-line. EXP is the expression that is a call to the builtin
1228 function; if convenient, the result should be placed in TARGET.
1229 SUBTARGET may be used as the target for computing one of EXP's operands. */
1231 expand_builtin_mathfn (exp, target, subtarget)
1233 rtx target, subtarget;
1235 optab builtin_optab;
1237 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
1238 tree arglist = TREE_OPERAND (exp, 1);
1241 /* Arg could be wrong type if user redeclared this fcn wrong. */
1242 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != REAL_TYPE)
1245 /* Stabilize and compute the argument. */
1246 if (TREE_CODE (TREE_VALUE (arglist)) != VAR_DECL
1247 && TREE_CODE (TREE_VALUE (arglist)) != PARM_DECL)
1249 exp = copy_node (exp);
1250 TREE_OPERAND (exp, 1) = arglist;
1251 /* Wrap the computation of the argument in a SAVE_EXPR. That
1252 way, if we need to expand the argument again (as in the
1253 flag_errno_math case below where we cannot directly set
1254 errno), we will not perform side-effects more than once.
1255 Note that here we're mutating the original EXP as well as the
1256 copy; that's the right thing to do in case the original EXP
1257 is expanded later. */
1258 TREE_VALUE (arglist) = save_expr (TREE_VALUE (arglist));
1259 arglist = copy_node (arglist);
1261 op0 = expand_expr (TREE_VALUE (arglist), subtarget, VOIDmode, 0);
1263 /* Make a suitable register to place result in. */
1264 target = gen_reg_rtx (TYPE_MODE (TREE_TYPE (exp)));
1269 switch (DECL_FUNCTION_CODE (fndecl))
1272 builtin_optab = sin_optab; break;
1274 builtin_optab = cos_optab; break;
1275 case BUILT_IN_FSQRT:
1276 builtin_optab = sqrt_optab; break;
1281 /* Compute into TARGET.
1282 Set TARGET to wherever the result comes back. */
1283 target = expand_unop (TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist))),
1284 builtin_optab, op0, target, 0);
1286 /* If we were unable to expand via the builtin, stop the
1287 sequence (without outputting the insns) and return 0, causing
1288 a call to the library function. */
1295 /* Check the results by default. But if flag_fast_math is turned on,
1296 then assume sqrt will always be called with valid arguments. */
1298 if (flag_errno_math && ! flag_fast_math)
1302 /* Don't define the builtin FP instructions
1303 if your machine is not IEEE. */
1304 if (TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT)
1307 lab1 = gen_label_rtx ();
1309 /* Test the result; if it is NaN, set errno=EDOM because
1310 the argument was not in the domain. */
1311 emit_cmp_and_jump_insns (target, target, EQ, 0, GET_MODE (target),
1316 #ifdef GEN_ERRNO_RTX
1317 rtx errno_rtx = GEN_ERRNO_RTX;
1320 = gen_rtx_MEM (word_mode, gen_rtx_SYMBOL_REF (Pmode, "errno"));
1323 emit_move_insn (errno_rtx, GEN_INT (TARGET_EDOM));
1326 /* We can't set errno=EDOM directly; let the library call do it.
1327 Pop the arguments right away in case the call gets deleted. */
1329 expand_call (exp, target, 0);
1336 /* Output the entire sequence. */
1337 insns = get_insns ();
1344 /* Expand expression EXP which is a call to the strlen builtin. Return 0
1345 if we failed the caller should emit a normal call, otherwise
1346 try to get the result in TARGET, if convenient. */
1349 expand_builtin_strlen (exp, target)
1353 tree arglist = TREE_OPERAND (exp, 1);
1354 enum machine_mode value_mode = TYPE_MODE (TREE_TYPE (exp));
1357 /* Arg could be non-pointer if user redeclared this fcn wrong. */
1358 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE)
1363 tree src = TREE_VALUE (arglist);
1366 = get_pointer_alignment (src, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
1368 rtx result, src_reg, char_rtx, before_strlen;
1369 enum machine_mode insn_mode = value_mode, char_mode;
1370 enum insn_code icode = CODE_FOR_nothing;
1372 /* If SRC is not a pointer type, don't do this operation inline. */
1376 /* Bail out if we can't compute strlen in the right mode. */
1377 while (insn_mode != VOIDmode)
1379 icode = strlen_optab->handlers[(int) insn_mode].insn_code;
1380 if (icode != CODE_FOR_nothing)
1383 insn_mode = GET_MODE_WIDER_MODE (insn_mode);
1385 if (insn_mode == VOIDmode)
1388 /* Make a place to write the result of the instruction. */
1391 && GET_CODE (result) == REG
1392 && GET_MODE (result) == insn_mode
1393 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
1394 result = gen_reg_rtx (insn_mode);
1396 /* Make a place to hold the source address. We will not expand
1397 the actual source until we are sure that the expansion will
1398 not fail -- there are trees that cannot be expanded twice. */
1399 src_reg = gen_reg_rtx (Pmode);
1401 /* Mark the beginning of the strlen sequence so we can emit the
1402 source operand later. */
1403 before_strlen = get_last_insn();
1405 /* Check the string is readable and has an end. */
1406 if (current_function_check_memory_usage)
1407 emit_library_call (chkr_check_str_libfunc, LCT_CONST_MAKE_BLOCK,
1408 VOIDmode, 2, src_reg, Pmode,
1409 GEN_INT (MEMORY_USE_RO),
1410 TYPE_MODE (integer_type_node));
1412 char_rtx = const0_rtx;
1413 char_mode = insn_data[(int) icode].operand[2].mode;
1414 if (! (*insn_data[(int) icode].operand[2].predicate) (char_rtx,
1416 char_rtx = copy_to_mode_reg (char_mode, char_rtx);
1418 pat = GEN_FCN (icode) (result, gen_rtx_MEM (BLKmode, src_reg),
1419 char_rtx, GEN_INT (align));
1424 /* Now that we are assured of success, expand the source. */
1426 pat = memory_address (BLKmode,
1427 expand_expr (src, src_reg, ptr_mode, EXPAND_SUM));
1429 emit_move_insn (src_reg, pat);
1430 pat = gen_sequence ();
1434 emit_insn_after (pat, before_strlen);
1436 emit_insn_before (pat, get_insns ());
1438 /* Return the value in the proper mode for this function. */
1439 if (GET_MODE (result) == value_mode)
1441 else if (target != 0)
1442 convert_move (target, result, 0);
1444 target = convert_to_mode (value_mode, result, 0);
1450 /* Expand a call to the strstr builtin. Return 0 if we failed the
1451 caller should emit a normal call, otherwise try to get the result
1452 in TARGET, if convenient (and in mode MODE if that's convenient). */
1455 expand_builtin_strstr (arglist, target, mode)
1458 enum machine_mode mode;
1461 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE
1462 || TREE_CHAIN (arglist) == 0
1463 || TREE_CODE (TREE_TYPE (TREE_VALUE (TREE_CHAIN (arglist)))) != POINTER_TYPE
1464 || current_function_check_memory_usage)
1468 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
1470 const char *p1, *p2;
1479 const char *r = strstr (p1, p2);
1484 /* Return an offset into the constant string argument. */
1485 return expand_expr (fold (build (PLUS_EXPR, TREE_TYPE (s1),
1486 s1, ssize_int (r - p1))),
1487 target, mode, EXPAND_NORMAL);
1491 return expand_expr (s1, target, mode, EXPAND_NORMAL);
1496 fn = built_in_decls[BUILT_IN_STRCHR];
1500 /* New argument list transforming strstr(s1, s2) to
1501 strchr(s1, s2[0]). */
1503 build_tree_list (NULL_TREE, build_int_2 (p2[0], 0));
1504 arglist = tree_cons (NULL_TREE, s1, arglist);
1505 call_expr = build1 (ADDR_EXPR,
1506 build_pointer_type (TREE_TYPE (fn)), fn);
1507 call_expr = build (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)),
1508 call_expr, arglist, NULL_TREE);
1509 TREE_SIDE_EFFECTS (call_expr) = 1;
1510 return expand_expr (call_expr, target, mode, EXPAND_NORMAL);
1514 /* Expand a call to the strchr builtin. Return 0 if we failed the
1515 caller should emit a normal call, otherwise try to get the result
1516 in TARGET, if convenient (and in mode MODE if that's convenient). */
1519 expand_builtin_strchr (arglist, target, mode)
1522 enum machine_mode mode;
1525 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE
1526 || TREE_CHAIN (arglist) == 0
1527 || TREE_CODE (TREE_TYPE (TREE_VALUE (TREE_CHAIN (arglist)))) != INTEGER_TYPE
1528 || current_function_check_memory_usage)
1532 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
1535 if (TREE_CODE (s2) != INTEGER_CST)
1541 const char *r = strchr (p1, (char) TREE_INT_CST_LOW (s2));
1546 /* Return an offset into the constant string argument. */
1547 return expand_expr (fold (build (PLUS_EXPR, TREE_TYPE (s1),
1548 s1, ssize_int (r - p1))),
1549 target, mode, EXPAND_NORMAL);
1552 /* FIXME: Should use here strchrM optab so that ports can optimize
1558 /* Expand a call to the strrchr builtin. Return 0 if we failed the
1559 caller should emit a normal call, otherwise try to get the result
1560 in TARGET, if convenient (and in mode MODE if that's convenient). */
1563 expand_builtin_strrchr (arglist, target, mode)
1566 enum machine_mode mode;
1569 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE
1570 || TREE_CHAIN (arglist) == 0
1571 || TREE_CODE (TREE_TYPE (TREE_VALUE (TREE_CHAIN (arglist)))) != INTEGER_TYPE
1572 || current_function_check_memory_usage)
1576 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
1580 if (TREE_CODE (s2) != INTEGER_CST)
1586 const char *r = strrchr (p1, (char) TREE_INT_CST_LOW (s2));
1591 /* Return an offset into the constant string argument. */
1592 return expand_expr (fold (build (PLUS_EXPR, TREE_TYPE (s1),
1593 s1, ssize_int (r - p1))),
1594 target, mode, EXPAND_NORMAL);
1597 if (! integer_zerop (s2))
1600 fn = built_in_decls[BUILT_IN_STRCHR];
1604 /* Transform strrchr(s1, '\0') to strchr(s1, '\0'). */
1605 call_expr = build1 (ADDR_EXPR,
1606 build_pointer_type (TREE_TYPE (fn)), fn);
1607 call_expr = build (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)),
1608 call_expr, arglist, NULL_TREE);
1609 TREE_SIDE_EFFECTS (call_expr) = 1;
1610 return expand_expr (call_expr, target, mode, EXPAND_NORMAL);
1614 /* Expand a call to the strpbrk builtin. Return 0 if we failed the
1615 caller should emit a normal call, otherwise try to get the result
1616 in TARGET, if convenient (and in mode MODE if that's convenient). */
1619 expand_builtin_strpbrk (arglist, target, mode)
1622 enum machine_mode mode;
1625 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE
1626 || TREE_CHAIN (arglist) == 0
1627 || TREE_CODE (TREE_TYPE (TREE_VALUE (TREE_CHAIN (arglist)))) != POINTER_TYPE
1628 || current_function_check_memory_usage)
1632 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
1634 const char *p1, *p2;
1643 const char *r = strpbrk (p1, p2);
1648 /* Return an offset into the constant string argument. */
1649 return expand_expr (fold (build (PLUS_EXPR, TREE_TYPE (s1),
1650 s1, ssize_int (r - p1))),
1651 target, mode, EXPAND_NORMAL);
1656 /* strpbrk(x, "") == NULL.
1657 Evaluate and ignore the arguments in case they had
1659 expand_expr (s1, const0_rtx, VOIDmode, EXPAND_NORMAL);
1664 return 0; /* Really call strpbrk. */
1666 fn = built_in_decls[BUILT_IN_STRCHR];
1670 /* New argument list transforming strpbrk(s1, s2) to
1671 strchr(s1, s2[0]). */
1673 build_tree_list (NULL_TREE, build_int_2 (p2[0], 0));
1674 arglist = tree_cons (NULL_TREE, s1, arglist);
1675 call_expr = build1 (ADDR_EXPR,
1676 build_pointer_type (TREE_TYPE (fn)), fn);
1677 call_expr = build (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)),
1678 call_expr, arglist, NULL_TREE);
1679 TREE_SIDE_EFFECTS (call_expr) = 1;
1680 return expand_expr (call_expr, target, mode, EXPAND_NORMAL);
1684 /* Expand a call to the memcpy builtin, with arguments in ARGLIST. */
1686 expand_builtin_memcpy (arglist)
1690 /* Arg could be non-pointer if user redeclared this fcn wrong. */
1691 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE
1692 || TREE_CHAIN (arglist) == 0
1693 || (TREE_CODE (TREE_TYPE (TREE_VALUE (TREE_CHAIN (arglist))))
1695 || TREE_CHAIN (TREE_CHAIN (arglist)) == 0
1696 || (TREE_CODE (TREE_TYPE (TREE_VALUE
1697 (TREE_CHAIN (TREE_CHAIN (arglist)))))
1702 tree dest = TREE_VALUE (arglist);
1703 tree src = TREE_VALUE (TREE_CHAIN (arglist));
1704 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
1706 int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
1707 int dest_align = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
1708 rtx dest_mem, src_mem, dest_addr, len_rtx;
1710 /* If either SRC or DEST is not a pointer type, don't do
1711 this operation in-line. */
1712 if (src_align == 0 || dest_align == 0)
1715 dest_mem = get_memory_rtx (dest);
1716 src_mem = get_memory_rtx (src);
1717 len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
1719 /* Just copy the rights of SRC to the rights of DEST. */
1720 if (current_function_check_memory_usage)
1721 emit_library_call (chkr_copy_bitmap_libfunc, LCT_CONST_MAKE_BLOCK,
1722 VOIDmode, 3, XEXP (dest_mem, 0), Pmode,
1723 XEXP (src_mem, 0), Pmode,
1724 len_rtx, TYPE_MODE (sizetype));
1726 /* Copy word part most expediently. */
1728 = emit_block_move (dest_mem, src_mem, len_rtx,
1729 MIN (src_align, dest_align));
1732 dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
1738 /* Expand expression EXP, which is a call to the strcpy builtin. Return 0
1739 if we failed the caller should emit a normal call. */
1742 expand_builtin_strcpy (exp)
1745 tree arglist = TREE_OPERAND (exp, 1);
1749 /* Arg could be non-pointer if user redeclared this fcn wrong. */
1750 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE
1751 || TREE_CHAIN (arglist) == 0
1752 || (TREE_CODE (TREE_TYPE (TREE_VALUE (TREE_CHAIN (arglist))))
1757 tree len = c_strlen (TREE_VALUE (TREE_CHAIN (arglist)));
1762 len = size_binop (PLUS_EXPR, len, ssize_int (1));
1763 chainon (arglist, build_tree_list (NULL_TREE, len));
1766 result = expand_builtin_memcpy (arglist);
1769 TREE_CHAIN (TREE_CHAIN (arglist)) = 0;
1773 /* Expand expression EXP, which is a call to the memset builtin. Return 0
1774 if we failed the caller should emit a normal call. */
1777 expand_builtin_memset (exp)
1780 tree arglist = TREE_OPERAND (exp, 1);
1783 /* Arg could be non-pointer if user redeclared this fcn wrong. */
1784 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE
1785 || TREE_CHAIN (arglist) == 0
1786 || (TREE_CODE (TREE_TYPE (TREE_VALUE (TREE_CHAIN (arglist))))
1788 || TREE_CHAIN (TREE_CHAIN (arglist)) == 0
1790 != (TREE_CODE (TREE_TYPE
1792 (TREE_CHAIN (TREE_CHAIN (arglist))))))))
1796 tree dest = TREE_VALUE (arglist);
1797 tree val = TREE_VALUE (TREE_CHAIN (arglist));
1798 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
1800 int dest_align = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
1801 rtx dest_mem, dest_addr, len_rtx;
1803 /* If DEST is not a pointer type, don't do this
1804 operation in-line. */
1805 if (dest_align == 0)
1808 /* If the arguments have side-effects, then we can only evaluate
1809 them at most once. The following code evaluates them twice if
1810 they are not constants because we break out to expand_call
1811 in that case. They can't be constants if they have side-effects
1812 so we can check for that first. Alternatively, we could call
1813 save_expr to make multiple evaluation safe. */
1814 if (TREE_SIDE_EFFECTS (val) || TREE_SIDE_EFFECTS (len))
1817 /* If VAL is not 0, don't do this operation in-line. */
1818 if (expand_expr (val, NULL_RTX, VOIDmode, 0) != const0_rtx)
1821 len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
1823 dest_mem = get_memory_rtx (dest);
1825 /* Just check DST is writable and mark it as readable. */
1826 if (current_function_check_memory_usage)
1827 emit_library_call (chkr_check_addr_libfunc, LCT_CONST_MAKE_BLOCK,
1828 VOIDmode, 3, XEXP (dest_mem, 0), Pmode,
1829 len_rtx, TYPE_MODE (sizetype),
1830 GEN_INT (MEMORY_USE_WO),
1831 TYPE_MODE (integer_type_node));
1834 dest_addr = clear_storage (dest_mem, len_rtx, dest_align);
1837 dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
1843 /* Expand expression EXP, which is a call to the bzero builtin. Return 0
1844 if we failed the caller should emit a normal call. */
1846 expand_builtin_bzero (exp)
1849 tree arglist = TREE_OPERAND (exp, 1);
1850 tree dest, size, newarglist;
1854 /* Arg could be non-pointer if user redeclared this fcn wrong. */
1855 || TREE_CODE (TREE_TYPE (dest = TREE_VALUE (arglist))) != POINTER_TYPE
1856 || TREE_CHAIN (arglist) == 0
1857 || (TREE_CODE (TREE_TYPE (size = TREE_VALUE (TREE_CHAIN (arglist))))
1861 /* New argument list transforming bzero(ptr x, int y) to
1862 memset(ptr x, int 0, size_t y). */
1864 newarglist = build_tree_list (NULL_TREE, convert (sizetype, size));
1865 newarglist = tree_cons (NULL_TREE, integer_zero_node, newarglist);
1866 newarglist = tree_cons (NULL_TREE, dest, newarglist);
1868 TREE_OPERAND (exp, 1) = newarglist;
1869 result = expand_builtin_memset(exp);
1871 /* Always restore the original arguments. */
1872 TREE_OPERAND (exp, 1) = arglist;
1877 #ifdef HAVE_cmpstrsi
1878 /* Expand expression EXP, which is a call to the memcmp or the strcmp builtin.
1879 ARGLIST is the argument list for this call. Return 0 if we failed and the
1880 caller should emit a normal call, otherwise try to get the result in
1881 TARGET, if convenient. */
1883 expand_builtin_memcmp (exp, arglist, target)
1888 /* If we need to check memory accesses, call the library function. */
1889 if (current_function_check_memory_usage)
1893 /* Arg could be non-pointer if user redeclared this fcn wrong. */
1894 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE
1895 || TREE_CHAIN (arglist) == 0
1896 || TREE_CODE (TREE_TYPE (TREE_VALUE (TREE_CHAIN (arglist)))) != POINTER_TYPE
1897 || TREE_CHAIN (TREE_CHAIN (arglist)) == 0
1898 || TREE_CODE (TREE_TYPE (TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist))))) != INTEGER_TYPE)
1902 enum machine_mode mode;
1903 tree arg1 = TREE_VALUE (arglist);
1904 tree arg2 = TREE_VALUE (TREE_CHAIN (arglist));
1905 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
1906 rtx arg1_rtx, arg2_rtx, arg3_rtx;
1911 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
1913 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
1914 enum machine_mode insn_mode
1915 = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
1917 /* If we don't have POINTER_TYPE, call the function. */
1918 if (arg1_align == 0 || arg2_align == 0)
1921 /* Make a place to write the result of the instruction. */
1924 && GET_CODE (result) == REG && GET_MODE (result) == insn_mode
1925 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
1926 result = gen_reg_rtx (insn_mode);
1928 arg1_rtx = get_memory_rtx (arg1);
1929 arg2_rtx = get_memory_rtx (arg2);
1930 arg3_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
1934 insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
1935 GEN_INT (MIN (arg1_align, arg2_align)));
1940 emit_library_call_value (memcmp_libfunc, result, LCT_PURE_MAKE_BLOCK,
1941 TYPE_MODE (integer_type_node), 3,
1942 XEXP (arg1_rtx, 0), Pmode,
1943 XEXP (arg2_rtx, 0), Pmode,
1944 convert_to_mode (TYPE_MODE (sizetype), arg3_rtx,
1945 TREE_UNSIGNED (sizetype)),
1946 TYPE_MODE (sizetype));
1948 /* Return the value in the proper mode for this function. */
1949 mode = TYPE_MODE (TREE_TYPE (exp));
1950 if (GET_MODE (result) == mode)
1952 else if (target != 0)
1954 convert_move (target, result, 0);
1958 return convert_to_mode (mode, result, 0);
1963 /* Expand expression EXP, which is a call to the strcmp builtin. Return 0
1964 if we failed the caller should emit a normal call, otherwise try to get
1965 the result in TARGET, if convenient. */
1968 expand_builtin_strcmp (exp, target, mode)
1971 enum machine_mode mode;
1973 tree arglist = TREE_OPERAND (exp, 1);
1975 const char *p1, *p2;
1977 /* If we need to check memory accesses, call the library function. */
1978 if (current_function_check_memory_usage)
1982 /* Arg could be non-pointer if user redeclared this fcn wrong. */
1983 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE
1984 || TREE_CHAIN (arglist) == 0
1985 || (TREE_CODE (TREE_TYPE (TREE_VALUE (TREE_CHAIN (arglist))))
1989 arg1 = TREE_VALUE (arglist);
1990 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
1992 p1 = c_getstr (arg1);
1993 p2 = c_getstr (arg2);
1997 int i = strcmp (p1, p2);
1999 return expand_expr (i < 0 ? build_int_2 (-1, -1)
2000 : i == 0 ? integer_zero_node
2002 target, mode, EXPAND_NORMAL);
2005 #ifdef HAVE_cmpstrsi
2006 if (! HAVE_cmpstrsi)
2010 tree len = c_strlen (arg1);
2011 tree len2 = c_strlen (arg2);
2015 len = size_binop (PLUS_EXPR, ssize_int (1), len);
2018 len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
2020 /* If we don't have a constant length for the first, use the length
2021 of the second, if we know it. We don't require a constant for
2022 this case; some cost analysis could be done if both are available
2023 but neither is constant. For now, assume they're equally cheap.
2025 If both strings have constant lengths, use the smaller. This
2026 could arise if optimization results in strcpy being called with
2027 two fixed strings, or if the code was machine-generated. We should
2028 add some code to the `memcmp' handler below to deal with such
2029 situations, someday. */
2031 if (!len || TREE_CODE (len) != INTEGER_CST)
2038 else if (len2 && TREE_CODE (len2) == INTEGER_CST
2039 && tree_int_cst_lt (len2, len))
2042 chainon (arglist, build_tree_list (NULL_TREE, len));
2043 result = expand_builtin_memcmp (exp, arglist, target);
2045 TREE_CHAIN (TREE_CHAIN (arglist)) = 0;
2054 /* Expand a call to __builtin_saveregs, generating the result in TARGET,
2055 if that's convenient. */
2058 expand_builtin_saveregs ()
2062 /* Don't do __builtin_saveregs more than once in a function.
2063 Save the result of the first call and reuse it. */
2064 if (saveregs_value != 0)
2065 return saveregs_value;
2067 /* When this function is called, it means that registers must be
2068 saved on entry to this function. So we migrate the call to the
2069 first insn of this function. */
2073 #ifdef EXPAND_BUILTIN_SAVEREGS
2074 /* Do whatever the machine needs done in this case. */
2075 val = EXPAND_BUILTIN_SAVEREGS ();
2077 /* ??? We used to try and build up a call to the out of line function,
2078 guessing about what registers needed saving etc. This became much
2079 harder with __builtin_va_start, since we don't have a tree for a
2080 call to __builtin_saveregs to fall back on. There was exactly one
2081 port (i860) that used this code, and I'm unconvinced it could actually
2082 handle the general case. So we no longer try to handle anything
2083 weird and make the backend absorb the evil. */
2085 error ("__builtin_saveregs not supported by this target");
2092 saveregs_value = val;
2094 /* Put the sequence after the NOTE that starts the function. If this
2095 is inside a SEQUENCE, make the outer-level insn chain current, so
2096 the code is placed at the start of the function. */
2097 push_topmost_sequence ();
2098 emit_insns_after (seq, get_insns ());
2099 pop_topmost_sequence ();
2104 /* __builtin_args_info (N) returns word N of the arg space info
2105 for the current function. The number and meanings of words
2106 is controlled by the definition of CUMULATIVE_ARGS. */
2109 expand_builtin_args_info (exp)
2112 tree arglist = TREE_OPERAND (exp, 1);
2113 int nwords = sizeof (CUMULATIVE_ARGS) / sizeof (int);
2114 int *word_ptr = (int *) ¤t_function_args_info;
2116 /* These are used by the code below that is if 0'ed away */
2118 tree type, elts, result;
2121 if (sizeof (CUMULATIVE_ARGS) % sizeof (int) != 0)
2126 tree arg = TREE_VALUE (arglist);
2127 if (TREE_CODE (arg) != INTEGER_CST)
2128 error ("argument of `__builtin_args_info' must be constant");
2131 int wordnum = TREE_INT_CST_LOW (arg);
2133 if (wordnum < 0 || wordnum >= nwords || TREE_INT_CST_HIGH (arg))
2134 error ("argument of `__builtin_args_info' out of range");
2136 return GEN_INT (word_ptr[wordnum]);
2140 error ("missing argument in `__builtin_args_info'");
2145 for (i = 0; i < nwords; i++)
2146 elts = tree_cons (NULL_TREE, build_int_2 (word_ptr[i], 0));
2148 type = build_array_type (integer_type_node,
2149 build_index_type (build_int_2 (nwords, 0)));
2150 result = build (CONSTRUCTOR, type, NULL_TREE, nreverse (elts));
2151 TREE_CONSTANT (result) = 1;
2152 TREE_STATIC (result) = 1;
2153 result = build1 (INDIRECT_REF, build_pointer_type (type), result);
2154 TREE_CONSTANT (result) = 1;
2155 return expand_expr (result, NULL_RTX, VOIDmode, EXPAND_MEMORY_USE_BAD);
2159 /* Expand ARGLIST, from a call to __builtin_next_arg. */
2161 expand_builtin_next_arg (arglist)
2164 tree fntype = TREE_TYPE (current_function_decl);
2166 if ((TYPE_ARG_TYPES (fntype) == 0
2167 || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
2169 && ! current_function_varargs)
2171 error ("`va_start' used in function with fixed args");
2177 tree last_parm = tree_last (DECL_ARGUMENTS (current_function_decl));
2178 tree arg = TREE_VALUE (arglist);
2180 /* Strip off all nops for the sake of the comparison. This
2181 is not quite the same as STRIP_NOPS. It does more.
2182 We must also strip off INDIRECT_EXPR for C++ reference
2184 while (TREE_CODE (arg) == NOP_EXPR
2185 || TREE_CODE (arg) == CONVERT_EXPR
2186 || TREE_CODE (arg) == NON_LVALUE_EXPR
2187 || TREE_CODE (arg) == INDIRECT_REF)
2188 arg = TREE_OPERAND (arg, 0);
2189 if (arg != last_parm)
2190 warning ("second parameter of `va_start' not last named argument");
2192 else if (! current_function_varargs)
2193 /* Evidently an out of date version of <stdarg.h>; can't validate
2194 va_start's second argument, but can still work as intended. */
2195 warning ("`__builtin_next_arg' called without an argument");
2197 return expand_binop (Pmode, add_optab,
2198 current_function_internal_arg_pointer,
2199 current_function_arg_offset_rtx,
2200 NULL_RTX, 0, OPTAB_LIB_WIDEN);
2203 /* Make it easier for the backends by protecting the valist argument
2204 from multiple evaluations. */
2207 stabilize_va_list (valist, needs_lvalue)
2211 if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
2213 if (TREE_SIDE_EFFECTS (valist))
2214 valist = save_expr (valist);
2216 /* For this case, the backends will be expecting a pointer to
2217 TREE_TYPE (va_list_type_node), but it's possible we've
2218 actually been given an array (an actual va_list_type_node).
2220 if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
2222 tree p1 = build_pointer_type (TREE_TYPE (va_list_type_node));
2223 tree p2 = build_pointer_type (va_list_type_node);
2225 valist = build1 (ADDR_EXPR, p2, valist);
2226 valist = fold (build1 (NOP_EXPR, p1, valist));
2235 if (! TREE_SIDE_EFFECTS (valist))
2238 pt = build_pointer_type (va_list_type_node);
2239 valist = fold (build1 (ADDR_EXPR, pt, valist));
2240 TREE_SIDE_EFFECTS (valist) = 1;
2243 if (TREE_SIDE_EFFECTS (valist))
2244 valist = save_expr (valist);
2245 valist = fold (build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (valist)),
2252 /* The "standard" implementation of va_start: just assign `nextarg' to
2255 std_expand_builtin_va_start (stdarg_p, valist, nextarg)
2264 int align = PARM_BOUNDARY / BITS_PER_UNIT;
2265 int offset = (((UNITS_PER_WORD + align - 1) / align) * align);
2266 nextarg = plus_constant (nextarg, -offset);
2269 t = build (MODIFY_EXPR, TREE_TYPE (valist), valist,
2270 make_tree (ptr_type_node, nextarg));
2271 TREE_SIDE_EFFECTS (t) = 1;
2273 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
2276 /* Expand ARGLIST, which from a call to __builtin_stdarg_va_start or
2277 __builtin_varargs_va_start, depending on STDARG_P. */
2279 expand_builtin_va_start (stdarg_p, arglist)
2284 tree chain = arglist, valist;
2287 nextarg = expand_builtin_next_arg (chain = TREE_CHAIN (arglist));
2289 nextarg = expand_builtin_next_arg (NULL_TREE);
2291 if (TREE_CHAIN (chain))
2292 error ("too many arguments to function `va_start'");
2294 valist = stabilize_va_list (TREE_VALUE (arglist), 1);
2296 #ifdef EXPAND_BUILTIN_VA_START
2297 EXPAND_BUILTIN_VA_START (stdarg_p, valist, nextarg);
2299 std_expand_builtin_va_start (stdarg_p, valist, nextarg);
2305 /* The "standard" implementation of va_arg: read the value from the
2306 current (padded) address and increment by the (padded) size. */
2309 std_expand_builtin_va_arg (valist, type)
2313 HOST_WIDE_INT align;
2314 HOST_WIDE_INT rounded_size;
2317 /* Compute the rounded size of the type. */
2318 align = PARM_BOUNDARY / BITS_PER_UNIT;
2319 rounded_size = (((int_size_in_bytes (type) + align - 1) / align) * align);
2323 if (PAD_VARARGS_DOWN)
2325 /* Small args are padded downward. */
2328 adj = TREE_INT_CST_LOW (TYPE_SIZE (type)) / BITS_PER_UNIT;
2329 if (rounded_size > align)
2332 addr_tree = build (PLUS_EXPR, TREE_TYPE (addr_tree), addr_tree,
2333 build_int_2 (rounded_size - adj, 0));
2336 addr = expand_expr (addr_tree, NULL_RTX, Pmode, EXPAND_NORMAL);
2337 addr = copy_to_reg (addr);
2339 /* Compute new value for AP. */
2340 t = build (MODIFY_EXPR, TREE_TYPE (valist), valist,
2341 build (PLUS_EXPR, TREE_TYPE (valist), valist,
2342 build_int_2 (rounded_size, 0)));
2343 TREE_SIDE_EFFECTS (t) = 1;
2344 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
2349 /* Expand __builtin_va_arg, which is not really a builtin function, but
2350 a very special sort of operator. */
2353 expand_builtin_va_arg (valist, type)
2357 tree promoted_type, want_va_type, have_va_type;
2359 /* Verify that valist is of the proper type. */
2361 want_va_type = va_list_type_node;
2362 have_va_type = TREE_TYPE (valist);
2363 if (TREE_CODE (want_va_type) == ARRAY_TYPE)
2365 /* If va_list is an array type, the argument may have decayed
2366 to a pointer type, e.g. by being passed to another function.
2367 In that case, unwrap both types so that we can compare the
2368 underlying records. */
2369 if (TREE_CODE (have_va_type) == ARRAY_TYPE
2370 || TREE_CODE (have_va_type) == POINTER_TYPE)
2372 want_va_type = TREE_TYPE (want_va_type);
2373 have_va_type = TREE_TYPE (have_va_type);
2376 if (TYPE_MAIN_VARIANT (want_va_type) != TYPE_MAIN_VARIANT (have_va_type))
2378 error ("first argument to `va_arg' not of type `va_list'");
2382 /* Generate a diagnostic for requesting data of a type that cannot
2383 be passed through `...' due to type promotion at the call site. */
2384 else if ((promoted_type = (*lang_type_promotes_to) (type)) != NULL_TREE)
2386 const char *name = "<anonymous type>", *pname = 0;
2387 static int gave_help;
2389 if (TYPE_NAME (type))
2391 if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE)
2392 name = IDENTIFIER_POINTER (TYPE_NAME (type));
2393 else if (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
2394 && DECL_NAME (TYPE_NAME (type)))
2395 name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type)));
2397 if (TYPE_NAME (promoted_type))
2399 if (TREE_CODE (TYPE_NAME (promoted_type)) == IDENTIFIER_NODE)
2400 pname = IDENTIFIER_POINTER (TYPE_NAME (promoted_type));
2401 else if (TREE_CODE (TYPE_NAME (promoted_type)) == TYPE_DECL
2402 && DECL_NAME (TYPE_NAME (promoted_type)))
2403 pname = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (promoted_type)));
2406 error ("`%s' is promoted to `%s' when passed through `...'", name, pname);
2410 error ("(so you should pass `%s' not `%s' to `va_arg')", pname, name);
2417 /* Make it easier for the backends by protecting the valist argument
2418 from multiple evaluations. */
2419 valist = stabilize_va_list (valist, 0);
2421 #ifdef EXPAND_BUILTIN_VA_ARG
2422 addr = EXPAND_BUILTIN_VA_ARG (valist, type);
2424 addr = std_expand_builtin_va_arg (valist, type);
2428 result = gen_rtx_MEM (TYPE_MODE (type), addr);
2429 MEM_ALIAS_SET (result) = get_varargs_alias_set ();
2434 /* Expand ARGLIST, from a call to __builtin_va_end. */
2437 expand_builtin_va_end (arglist)
2440 tree valist = TREE_VALUE (arglist);
2442 #ifdef EXPAND_BUILTIN_VA_END
2443 valist = stabilize_va_list (valist, 0);
2444 EXPAND_BUILTIN_VA_END(arglist);
2446 /* Evaluate for side effects, if needed. I hate macros that don't
2448 if (TREE_SIDE_EFFECTS (valist))
2449 expand_expr (valist, const0_rtx, VOIDmode, EXPAND_NORMAL);
2455 /* Expand ARGLIST, from a call to __builtin_va_copy. We do this as a
2456 builtin rather than just as an assignment in stdarg.h because of the
2457 nastiness of array-type va_list types. */
2460 expand_builtin_va_copy (arglist)
2465 dst = TREE_VALUE (arglist);
2466 src = TREE_VALUE (TREE_CHAIN (arglist));
2468 dst = stabilize_va_list (dst, 1);
2469 src = stabilize_va_list (src, 0);
2471 if (TREE_CODE (va_list_type_node) != ARRAY_TYPE)
2473 t = build (MODIFY_EXPR, va_list_type_node, dst, src);
2474 TREE_SIDE_EFFECTS (t) = 1;
2475 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
2479 rtx dstb, srcb, size;
2481 /* Evaluate to pointers. */
2482 dstb = expand_expr (dst, NULL_RTX, Pmode, EXPAND_NORMAL);
2483 srcb = expand_expr (src, NULL_RTX, Pmode, EXPAND_NORMAL);
2484 size = expand_expr (TYPE_SIZE_UNIT (va_list_type_node), NULL_RTX,
2485 VOIDmode, EXPAND_NORMAL);
2487 /* "Dereference" to BLKmode memories. */
2488 dstb = gen_rtx_MEM (BLKmode, dstb);
2489 MEM_ALIAS_SET (dstb) = get_alias_set (TREE_TYPE (TREE_TYPE (dst)));
2490 srcb = gen_rtx_MEM (BLKmode, srcb);
2491 MEM_ALIAS_SET (srcb) = get_alias_set (TREE_TYPE (TREE_TYPE (src)));
2494 emit_block_move (dstb, srcb, size, TYPE_ALIGN (va_list_type_node));
2500 /* Expand a call to one of the builtin functions __builtin_frame_address or
2501 __builtin_return_address. */
2503 expand_builtin_frame_address (exp)
2506 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
2507 tree arglist = TREE_OPERAND (exp, 1);
2509 /* The argument must be a nonnegative integer constant.
2510 It counts the number of frames to scan up the stack.
2511 The value is the return address saved in that frame. */
2513 /* Warning about missing arg was already issued. */
2515 else if (TREE_CODE (TREE_VALUE (arglist)) != INTEGER_CST
2516 || tree_int_cst_sgn (TREE_VALUE (arglist)) < 0)
2518 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
2519 error ("invalid arg to `__builtin_frame_address'");
2521 error ("invalid arg to `__builtin_return_address'");
2526 rtx tem = expand_builtin_return_addr (DECL_FUNCTION_CODE (fndecl),
2527 TREE_INT_CST_LOW (TREE_VALUE (arglist)),
2528 hard_frame_pointer_rtx);
2530 /* Some ports cannot access arbitrary stack frames. */
2533 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
2534 warning ("unsupported arg to `__builtin_frame_address'");
2536 warning ("unsupported arg to `__builtin_return_address'");
2540 /* For __builtin_frame_address, return what we've got. */
2541 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
2544 if (GET_CODE (tem) != REG
2545 && ! CONSTANT_P (tem))
2546 tem = copy_to_mode_reg (Pmode, tem);
2551 /* Expand a call to the alloca builtin, with arguments ARGLIST. Return 0 if
2552 we failed and the caller should emit a normal call, otherwise try to get
2553 the result in TARGET, if convenient. */
2555 expand_builtin_alloca (arglist, target)
2562 /* Arg could be non-integer if user redeclared this fcn wrong. */
2563 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE)
2566 /* Compute the argument. */
2567 op0 = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
2569 /* Allocate the desired space. */
2570 return allocate_dynamic_stack_space (op0, target, BITS_PER_UNIT);
2573 /* Expand a call to the ffs builtin. The arguments are in ARGLIST.
2574 Return 0 if a normal call should be emitted rather than expanding the
2575 function in-line. If convenient, the result should be placed in TARGET.
2576 SUBTARGET may be used as the target for computing one of EXP's operands. */
2578 expand_builtin_ffs (arglist, target, subtarget)
2580 rtx target, subtarget;
2584 /* Arg could be non-integer if user redeclared this fcn wrong. */
2585 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE)
2588 /* Compute the argument. */
2589 op0 = expand_expr (TREE_VALUE (arglist), subtarget, VOIDmode, 0);
2590 /* Compute ffs, into TARGET if possible.
2591 Set TARGET to wherever the result comes back. */
2592 target = expand_unop (TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist))),
2593 ffs_optab, op0, target, 1);
2599 /* If the string passed to fputs is a constant and is one character
2600 long, we attempt to transform this call into __builtin_fputc(). */
2602 expand_builtin_fputs (arglist, ignore)
2606 tree call_expr, len, fn, fn_fputc = built_in_decls[BUILT_IN_FPUTC],
2607 fn_fwrite = built_in_decls[BUILT_IN_FWRITE];
2609 /* If the return value is used, or the replacement _DECL isn't
2610 initialized, don't do the transformation. */
2611 if (!ignore || !fn_fputc || !fn_fwrite)
2614 /* Verify the arguments in the original call. */
2616 || (TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE)
2617 || TREE_CHAIN (arglist) == 0
2618 || (TREE_CODE (TREE_TYPE (TREE_VALUE (TREE_CHAIN (arglist))))
2620 || current_function_check_memory_usage)
2623 /* Get the length of the string passed to fputs. If the length
2624 can't be determined, punt. */
2625 if (!(len = c_strlen (TREE_VALUE (arglist))))
2628 switch (compare_tree_int (len, 1))
2630 case -1: /* length is 0, delete the call entirely . */
2632 /* Evaluate and ignore the argument in case it has
2634 expand_expr (TREE_VALUE (TREE_CHAIN (arglist)), const0_rtx,
2635 VOIDmode, EXPAND_NORMAL);
2638 case 0: /* length is 1, call fputc. */
2640 const char *p = c_getstr (TREE_VALUE (arglist));
2644 /* New argument list transforming fputs(string, stream) to
2645 fputc(string[0], stream). */
2647 build_tree_list (NULL_TREE, TREE_VALUE (TREE_CHAIN (arglist)));
2649 tree_cons (NULL_TREE, build_int_2 (p[0], 0), arglist);
2655 case 1: /* length is greater than 1, call fwrite. */
2657 tree string_arg = TREE_VALUE (arglist);
2659 /* New argument list transforming fputs(string, stream) to
2660 fwrite(string, 1, len, stream). */
2661 arglist = build_tree_list (NULL_TREE, TREE_VALUE (TREE_CHAIN (arglist)));
2662 arglist = tree_cons (NULL_TREE, len, arglist);
2663 arglist = tree_cons (NULL_TREE, integer_one_node, arglist);
2664 arglist = tree_cons (NULL_TREE, string_arg, arglist);
2672 call_expr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
2673 call_expr = build (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)),
2674 call_expr, arglist, NULL_TREE);
2675 TREE_SIDE_EFFECTS (call_expr) = 1;
2676 return expand_expr (call_expr, (ignore ? const0_rtx : NULL_RTX),
2677 VOIDmode, EXPAND_NORMAL);
2680 /* Expand a call to __builtin_expect. We return our argument and
2681 emit a NOTE_INSN_EXPECTED_VALUE note. */
2684 expand_builtin_expect (arglist, target)
2691 if (arglist == NULL_TREE
2692 || TREE_CHAIN (arglist) == NULL_TREE)
2694 exp = TREE_VALUE (arglist);
2695 c = TREE_VALUE (TREE_CHAIN (arglist));
2697 if (TREE_CODE (c) != INTEGER_CST)
2699 error ("second arg to `__builtin_expect' must be a constant");
2700 c = integer_zero_node;
2703 target = expand_expr (exp, target, VOIDmode, EXPAND_NORMAL);
2705 /* Don't bother with expected value notes for integral constants. */
2706 if (GET_CODE (target) != CONST_INT)
2708 /* We do need to force this into a register so that we can be
2709 moderately sure to be able to correctly interpret the branch
2711 target = force_reg (GET_MODE (target), target);
2713 rtx_c = expand_expr (c, NULL_RTX, GET_MODE (target), EXPAND_NORMAL);
2715 note = emit_note (NULL, NOTE_INSN_EXPECTED_VALUE);
2716 NOTE_EXPECTED_VALUE (note) = gen_rtx_EQ (VOIDmode, target, rtx_c);
2722 /* Expand an expression EXP that calls a built-in function,
2723 with result going to TARGET if that's convenient
2724 (and in mode MODE if that's convenient).
2725 SUBTARGET may be used as the target for computing one of EXP's operands.
2726 IGNORE is nonzero if the value is to be ignored. */
2729 expand_builtin (exp, target, subtarget, mode, ignore)
2733 enum machine_mode mode;
2736 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
2737 tree arglist = TREE_OPERAND (exp, 1);
2738 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
2740 #ifdef MD_EXPAND_BUILTIN
2741 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
2742 return MD_EXPAND_BUILTIN (exp, target, subtarget, mode, ignore);
2745 /* When not optimizing, generate calls to library functions for a certain
2747 if (! optimize && ! CALLED_AS_BUILT_IN (fndecl)
2748 && (fcode == BUILT_IN_SIN || fcode == BUILT_IN_COS
2749 || fcode == BUILT_IN_FSQRT || fcode == BUILT_IN_MEMSET
2750 || fcode == BUILT_IN_MEMCPY || fcode == BUILT_IN_MEMCMP
2751 || fcode == BUILT_IN_BCMP || fcode == BUILT_IN_BZERO
2752 || fcode == BUILT_IN_INDEX || fcode == BUILT_IN_RINDEX
2753 || fcode == BUILT_IN_STRCHR || fcode == BUILT_IN_STRRCHR
2754 || fcode == BUILT_IN_STRLEN || fcode == BUILT_IN_STRCPY
2755 || fcode == BUILT_IN_STRSTR || fcode == BUILT_IN_STRPBRK
2756 || fcode == BUILT_IN_STRCMP || fcode == BUILT_IN_FFS
2757 || fcode == BUILT_IN_PUTCHAR || fcode == BUILT_IN_PUTS
2758 || fcode == BUILT_IN_PRINTF || fcode == BUILT_IN_FPUTC
2759 || fcode == BUILT_IN_FPUTS || fcode == BUILT_IN_FWRITE))
2760 return expand_call (exp, target, ignore);
2766 case BUILT_IN_LLABS:
2768 /* build_function_call changes these into ABS_EXPR. */
2773 /* Treat these like sqrt, but only if the user asks for them. */
2774 if (! flag_fast_math)
2776 case BUILT_IN_FSQRT:
2777 target = expand_builtin_mathfn (exp, target, subtarget);
2785 case BUILT_IN_APPLY_ARGS:
2786 return expand_builtin_apply_args ();
2788 /* __builtin_apply (FUNCTION, ARGUMENTS, ARGSIZE) invokes
2789 FUNCTION with a copy of the parameters described by
2790 ARGUMENTS, and ARGSIZE. It returns a block of memory
2791 allocated on the stack into which is stored all the registers
2792 that might possibly be used for returning the result of a
2793 function. ARGUMENTS is the value returned by
2794 __builtin_apply_args. ARGSIZE is the number of bytes of
2795 arguments that must be copied. ??? How should this value be
2796 computed? We'll also need a safe worst case value for varargs
2798 case BUILT_IN_APPLY:
2800 /* Arg could be non-pointer if user redeclared this fcn wrong. */
2801 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
2802 || TREE_CHAIN (arglist) == 0
2803 || TREE_CODE (TREE_TYPE (TREE_VALUE (TREE_CHAIN (arglist)))) != POINTER_TYPE
2804 || TREE_CHAIN (TREE_CHAIN (arglist)) == 0
2805 || TREE_CODE (TREE_TYPE (TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist))))) != INTEGER_TYPE)
2813 for (t = arglist, i = 0; t; t = TREE_CHAIN (t), i++)
2814 ops[i] = expand_expr (TREE_VALUE (t), NULL_RTX, VOIDmode, 0);
2816 return expand_builtin_apply (ops[0], ops[1], ops[2]);
2819 /* __builtin_return (RESULT) causes the function to return the
2820 value described by RESULT. RESULT is address of the block of
2821 memory returned by __builtin_apply. */
2822 case BUILT_IN_RETURN:
2824 /* Arg could be non-pointer if user redeclared this fcn wrong. */
2825 && TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) == POINTER_TYPE)
2826 expand_builtin_return (expand_expr (TREE_VALUE (arglist),
2827 NULL_RTX, VOIDmode, 0));
2830 case BUILT_IN_SAVEREGS:
2831 return expand_builtin_saveregs ();
2833 case BUILT_IN_ARGS_INFO:
2834 return expand_builtin_args_info (exp);
2836 /* Return the address of the first anonymous stack arg. */
2837 case BUILT_IN_NEXT_ARG:
2838 return expand_builtin_next_arg (arglist);
2840 case BUILT_IN_CLASSIFY_TYPE:
2841 return expand_builtin_classify_type (arglist);
2843 case BUILT_IN_CONSTANT_P:
2844 return expand_builtin_constant_p (exp);
2846 case BUILT_IN_FRAME_ADDRESS:
2847 case BUILT_IN_RETURN_ADDRESS:
2848 return expand_builtin_frame_address (exp);
2850 /* Returns the address of the area where the structure is returned.
2852 case BUILT_IN_AGGREGATE_INCOMING_ADDRESS:
2854 || ! AGGREGATE_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl)))
2855 || GET_CODE (DECL_RTL (DECL_RESULT (current_function_decl))) != MEM)
2858 return XEXP (DECL_RTL (DECL_RESULT (current_function_decl)), 0);
2860 case BUILT_IN_ALLOCA:
2861 target = expand_builtin_alloca (arglist, target);
2867 target = expand_builtin_ffs (arglist, target, subtarget);
2872 case BUILT_IN_STRLEN:
2873 target = expand_builtin_strlen (exp, target);
2878 case BUILT_IN_STRCPY:
2879 target = expand_builtin_strcpy (exp);
2884 case BUILT_IN_STRSTR:
2885 target = expand_builtin_strstr (arglist, target, mode);
2890 case BUILT_IN_STRPBRK:
2891 target = expand_builtin_strpbrk (arglist, target, mode);
2896 case BUILT_IN_INDEX:
2897 case BUILT_IN_STRCHR:
2898 target = expand_builtin_strchr (arglist, target, mode);
2903 case BUILT_IN_RINDEX:
2904 case BUILT_IN_STRRCHR:
2905 target = expand_builtin_strrchr (arglist, target, mode);
2910 case BUILT_IN_MEMCPY:
2911 target = expand_builtin_memcpy (arglist);
2916 case BUILT_IN_MEMSET:
2917 target = expand_builtin_memset (exp);
2922 case BUILT_IN_BZERO:
2923 target = expand_builtin_bzero (exp);
2928 case BUILT_IN_STRCMP:
2929 target = expand_builtin_strcmp (exp, target, mode);
2934 /* These comparison functions need an instruction that returns an actual
2935 index. An ordinary compare that just sets the condition codes
2937 #ifdef HAVE_cmpstrsi
2939 case BUILT_IN_MEMCMP:
2940 target = expand_builtin_memcmp (exp, arglist, target);
2946 case BUILT_IN_MEMCMP:
2950 case BUILT_IN_SETJMP:
2952 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE)
2956 rtx buf_addr = expand_expr (TREE_VALUE (arglist), subtarget,
2958 rtx lab = gen_label_rtx ();
2959 rtx ret = expand_builtin_setjmp (buf_addr, target, lab, lab);
2964 /* __builtin_longjmp is passed a pointer to an array of five words.
2965 It's similar to the C library longjmp function but works with
2966 __builtin_setjmp above. */
2967 case BUILT_IN_LONGJMP:
2968 if (arglist == 0 || TREE_CHAIN (arglist) == 0
2969 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE)
2973 rtx buf_addr = expand_expr (TREE_VALUE (arglist), subtarget,
2975 rtx value = expand_expr (TREE_VALUE (TREE_CHAIN (arglist)),
2976 NULL_RTX, VOIDmode, 0);
2978 if (value != const1_rtx)
2980 error ("__builtin_longjmp second argument must be 1");
2984 expand_builtin_longjmp (buf_addr, value);
2991 emit_insn (gen_trap ());
2994 error ("__builtin_trap not supported by this target");
2998 case BUILT_IN_PUTCHAR:
3000 case BUILT_IN_FPUTC:
3001 case BUILT_IN_FWRITE:
3003 case BUILT_IN_FPUTS:
3004 target = expand_builtin_fputs (arglist, ignore);
3009 /* Various hooks for the DWARF 2 __throw routine. */
3010 case BUILT_IN_UNWIND_INIT:
3011 expand_builtin_unwind_init ();
3013 case BUILT_IN_DWARF_CFA:
3014 return virtual_cfa_rtx;
3015 #ifdef DWARF2_UNWIND_INFO
3016 case BUILT_IN_DWARF_FP_REGNUM:
3017 return expand_builtin_dwarf_fp_regnum ();
3018 case BUILT_IN_INIT_DWARF_REG_SIZES:
3019 expand_builtin_init_dwarf_reg_sizes (TREE_VALUE (arglist));
3022 case BUILT_IN_FROB_RETURN_ADDR:
3023 return expand_builtin_frob_return_addr (TREE_VALUE (arglist));
3024 case BUILT_IN_EXTRACT_RETURN_ADDR:
3025 return expand_builtin_extract_return_addr (TREE_VALUE (arglist));
3026 case BUILT_IN_EH_RETURN:
3027 expand_builtin_eh_return (TREE_VALUE (arglist),
3028 TREE_VALUE (TREE_CHAIN (arglist)),
3029 TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist))));
3031 case BUILT_IN_VARARGS_START:
3032 return expand_builtin_va_start (0, arglist);
3033 case BUILT_IN_STDARG_START:
3034 return expand_builtin_va_start (1, arglist);
3035 case BUILT_IN_VA_END:
3036 return expand_builtin_va_end (arglist);
3037 case BUILT_IN_VA_COPY:
3038 return expand_builtin_va_copy (arglist);
3039 case BUILT_IN_EXPECT:
3040 return expand_builtin_expect (arglist, target);
3042 default: /* just do library call, if unknown builtin */
3043 error ("built-in function `%s' not currently supported",
3044 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
3047 /* The switch statement above can drop through to cause the function
3048 to be called normally. */
3049 return expand_call (exp, target, ignore);
3052 /* Fold a call to __builtin_constant_p, if we know it will evaluate to a
3053 constant. ARGLIST is the argument list of the call. */
3056 fold_builtin_constant_p (arglist)
3062 arglist = TREE_VALUE (arglist);
3064 /* We return 1 for a numeric type that's known to be a constant
3065 value at compile-time or for an aggregate type that's a
3066 literal constant. */
3067 STRIP_NOPS (arglist);
3069 /* If we know this is a constant, emit the constant of one. */
3070 if (TREE_CODE_CLASS (TREE_CODE (arglist)) == 'c'
3071 || (TREE_CODE (arglist) == CONSTRUCTOR
3072 && TREE_CONSTANT (arglist))
3073 || (TREE_CODE (arglist) == ADDR_EXPR
3074 && TREE_CODE (TREE_OPERAND (arglist, 0)) == STRING_CST))
3075 return integer_one_node;
3077 /* If we aren't going to be running CSE or this expression
3078 has side effects, show we don't know it to be a constant.
3079 Likewise if it's a pointer or aggregate type since in those
3080 case we only want literals, since those are only optimized
3081 when generating RTL, not later. */
3082 if (TREE_SIDE_EFFECTS (arglist) || cse_not_expected
3083 || AGGREGATE_TYPE_P (TREE_TYPE (arglist))
3084 || POINTER_TYPE_P (TREE_TYPE (arglist)))
3085 return integer_zero_node;
3090 /* Used by constant folding to eliminate some builtin calls early. EXP is
3091 the CALL_EXPR of a call to a builtin function. */
3097 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
3098 tree arglist = TREE_OPERAND (exp, 1);
3099 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
3101 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
3106 case BUILT_IN_CONSTANT_P:
3107 return fold_builtin_constant_p (arglist);
3109 case BUILT_IN_STRLEN:
3111 /* Arg could be non-pointer if user redeclared this fcn wrong. */
3112 && TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) == POINTER_TYPE)
3114 tree len = c_strlen (TREE_VALUE (arglist));