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 rtx get_memory_rtx PARAMS ((tree));
87 static int apply_args_size PARAMS ((void));
88 static int apply_result_size PARAMS ((void));
89 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
90 static rtx result_vector PARAMS ((int, rtx));
92 static rtx expand_builtin_apply_args PARAMS ((void));
93 static rtx expand_builtin_apply_args_1 PARAMS ((void));
94 static rtx expand_builtin_apply PARAMS ((rtx, rtx, rtx));
95 static void expand_builtin_return PARAMS ((rtx));
96 static rtx expand_builtin_classify_type PARAMS ((tree));
97 static rtx expand_builtin_mathfn PARAMS ((tree, rtx, rtx));
98 static rtx expand_builtin_constant_p PARAMS ((tree));
99 static rtx expand_builtin_args_info PARAMS ((tree));
100 static rtx expand_builtin_next_arg PARAMS ((tree));
101 static rtx expand_builtin_va_start PARAMS ((int, tree));
102 static rtx expand_builtin_va_end PARAMS ((tree));
103 static rtx expand_builtin_va_copy PARAMS ((tree));
105 static rtx expand_builtin_memcmp PARAMS ((tree, tree, rtx));
107 static rtx expand_builtin_strcmp PARAMS ((tree, rtx,
109 static rtx expand_builtin_strncmp PARAMS ((tree, rtx,
111 static rtx builtin_memcpy_read_str PARAMS ((PTR, HOST_WIDE_INT,
113 static rtx expand_builtin_memcpy PARAMS ((tree));
114 static rtx expand_builtin_strcpy PARAMS ((tree));
115 static rtx builtin_strncpy_read_str PARAMS ((PTR, HOST_WIDE_INT,
117 static rtx expand_builtin_strncpy PARAMS ((tree, rtx,
119 static rtx expand_builtin_memset PARAMS ((tree));
120 static rtx expand_builtin_bzero PARAMS ((tree));
121 static rtx expand_builtin_strlen PARAMS ((tree, rtx));
122 static rtx expand_builtin_strstr PARAMS ((tree, rtx,
124 static rtx expand_builtin_strpbrk PARAMS ((tree, rtx,
126 static rtx expand_builtin_strchr PARAMS ((tree, rtx,
128 static rtx expand_builtin_strrchr PARAMS ((tree, rtx,
130 static rtx expand_builtin_alloca PARAMS ((tree, rtx));
131 static rtx expand_builtin_ffs PARAMS ((tree, rtx, rtx));
132 static rtx expand_builtin_frame_address PARAMS ((tree));
133 static rtx expand_builtin_fputs PARAMS ((tree, int));
134 static tree stabilize_va_list PARAMS ((tree, int));
135 static rtx expand_builtin_expect PARAMS ((tree, rtx));
136 static tree fold_builtin_constant_p PARAMS ((tree));
138 /* Return the alignment in bits of EXP, a pointer valued expression.
139 But don't return more than MAX_ALIGN no matter what.
140 The alignment returned is, by default, the alignment of the thing that
141 EXP points to (if it is not a POINTER_TYPE, 0 is returned).
143 Otherwise, look at the expression to see if we can do better, i.e., if the
144 expression is actually pointing at an object whose alignment is tighter. */
147 get_pointer_alignment (exp, max_align)
151 unsigned align, inner;
153 if (TREE_CODE (TREE_TYPE (exp)) != POINTER_TYPE)
156 align = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
157 align = MIN (align, max_align);
161 switch (TREE_CODE (exp))
165 case NON_LVALUE_EXPR:
166 exp = TREE_OPERAND (exp, 0);
167 if (TREE_CODE (TREE_TYPE (exp)) != POINTER_TYPE)
170 inner = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
171 align = MIN (inner, max_align);
175 /* If sum of pointer + int, restrict our maximum alignment to that
176 imposed by the integer. If not, we can't do any better than
178 if (! host_integerp (TREE_OPERAND (exp, 1), 1))
181 while (((tree_low_cst (TREE_OPERAND (exp, 1), 1) * BITS_PER_UNIT)
186 exp = TREE_OPERAND (exp, 0);
190 /* See what we are pointing at and look at its alignment. */
191 exp = TREE_OPERAND (exp, 0);
192 if (TREE_CODE (exp) == FUNCTION_DECL)
193 align = FUNCTION_BOUNDARY;
194 else if (DECL_P (exp))
195 align = DECL_ALIGN (exp);
196 #ifdef CONSTANT_ALIGNMENT
197 else if (TREE_CODE_CLASS (TREE_CODE (exp)) == 'c')
198 align = CONSTANT_ALIGNMENT (exp, align);
200 return MIN (align, max_align);
208 /* Compute the length of a C string. TREE_STRING_LENGTH is not the right
209 way, because it could contain a zero byte in the middle.
210 TREE_STRING_LENGTH is the size of the character array, not the string.
212 The value returned is of type `ssizetype'.
214 Unfortunately, string_constant can't access the values of const char
215 arrays with initializers, so neither can we do so here. */
225 src = string_constant (src, &offset_node);
229 max = TREE_STRING_LENGTH (src) - 1;
230 ptr = TREE_STRING_POINTER (src);
232 if (offset_node && TREE_CODE (offset_node) != INTEGER_CST)
234 /* If the string has an internal zero byte (e.g., "foo\0bar"), we can't
235 compute the offset to the following null if we don't know where to
236 start searching for it. */
239 for (i = 0; i < max; i++)
243 /* We don't know the starting offset, but we do know that the string
244 has no internal zero bytes. We can assume that the offset falls
245 within the bounds of the string; otherwise, the programmer deserves
246 what he gets. Subtract the offset from the length of the string,
247 and return that. This would perhaps not be valid if we were dealing
248 with named arrays in addition to literal string constants. */
250 return size_diffop (size_int (max), offset_node);
253 /* We have a known offset into the string. Start searching there for
255 if (offset_node == 0)
259 /* Did we get a long long offset? If so, punt. */
260 if (TREE_INT_CST_HIGH (offset_node) != 0)
262 offset = TREE_INT_CST_LOW (offset_node);
265 /* If the offset is known to be out of bounds, warn, and call strlen at
267 if (offset < 0 || offset > max)
269 warning ("offset outside bounds of constant string");
273 /* Use strlen to search for the first zero byte. Since any strings
274 constructed with build_string will have nulls appended, we win even
275 if we get handed something like (char[4])"abcd".
277 Since OFFSET is our starting index into the string, no further
278 calculation is needed. */
279 return ssize_int (strlen (ptr + offset));
282 /* Return a char pointer for a C string if it is a string constant
283 or sum of string constant and integer constant. */
293 src = string_constant (src, &offset_node);
297 max = TREE_STRING_LENGTH (src) - 1;
298 ptr = TREE_STRING_POINTER (src);
302 else if (TREE_CODE (offset_node) != INTEGER_CST)
306 /* Did we get a long long offset? If so, punt. */
307 if (TREE_INT_CST_HIGH (offset_node) != 0)
309 offset = TREE_INT_CST_LOW (offset_node);
310 if (offset < 0 || offset > max)
317 /* Return a CONST_INT or CONST_DOUBLE corresponding to target
318 reading GET_MODE_BITSIZE (MODE) bits from string constant
321 c_readstr (str, mode)
323 enum machine_mode mode;
329 if (GET_MODE_CLASS (mode) != MODE_INT)
334 for (i = 0; i < GET_MODE_SIZE (mode); i++)
337 if (WORDS_BIG_ENDIAN)
338 j = GET_MODE_SIZE (mode) - i - 1;
339 if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN
340 && GET_MODE_SIZE (mode) > UNITS_PER_WORD)
341 j = j + UNITS_PER_WORD - 2 * (j % UNITS_PER_WORD) - 1;
343 if (j > 2 * HOST_BITS_PER_WIDE_INT)
346 ch = (unsigned char) str[i];
347 c[j / HOST_BITS_PER_WIDE_INT] |= ch << (j % HOST_BITS_PER_WIDE_INT);
349 return immed_double_const (c[0], c[1], mode);
352 /* Given TEM, a pointer to a stack frame, follow the dynamic chain COUNT
353 times to get the address of either a higher stack frame, or a return
354 address located within it (depending on FNDECL_CODE). */
357 expand_builtin_return_addr (fndecl_code, count, tem)
358 enum built_in_function fndecl_code;
364 /* Some machines need special handling before we can access
365 arbitrary frames. For example, on the sparc, we must first flush
366 all register windows to the stack. */
367 #ifdef SETUP_FRAME_ADDRESSES
369 SETUP_FRAME_ADDRESSES ();
372 /* On the sparc, the return address is not in the frame, it is in a
373 register. There is no way to access it off of the current frame
374 pointer, but it can be accessed off the previous frame pointer by
375 reading the value from the register window save area. */
376 #ifdef RETURN_ADDR_IN_PREVIOUS_FRAME
377 if (fndecl_code == BUILT_IN_RETURN_ADDRESS)
381 /* Scan back COUNT frames to the specified frame. */
382 for (i = 0; i < count; i++)
384 /* Assume the dynamic chain pointer is in the word that the
385 frame address points to, unless otherwise specified. */
386 #ifdef DYNAMIC_CHAIN_ADDRESS
387 tem = DYNAMIC_CHAIN_ADDRESS (tem);
389 tem = memory_address (Pmode, tem);
390 tem = copy_to_reg (gen_rtx_MEM (Pmode, tem));
391 MEM_ALIAS_SET (tem) = get_frame_alias_set ();
394 /* For __builtin_frame_address, return what we've got. */
395 if (fndecl_code == BUILT_IN_FRAME_ADDRESS)
398 /* For __builtin_return_address, Get the return address from that
400 #ifdef RETURN_ADDR_RTX
401 tem = RETURN_ADDR_RTX (count, tem);
403 tem = memory_address (Pmode,
404 plus_constant (tem, GET_MODE_SIZE (Pmode)));
405 tem = gen_rtx_MEM (Pmode, tem);
406 MEM_ALIAS_SET (tem) = get_frame_alias_set ();
411 /* Alias set used for setjmp buffer. */
412 static HOST_WIDE_INT setjmp_alias_set = -1;
414 /* __builtin_setjmp is passed a pointer to an array of five words (not
415 all will be used on all machines). It operates similarly to the C
416 library function of the same name, but is more efficient. Much of
417 the code below (and for longjmp) is copied from the handling of
420 NOTE: This is intended for use by GNAT and the exception handling
421 scheme in the compiler and will only work in the method used by
425 expand_builtin_setjmp (buf_addr, target, first_label, next_label)
428 rtx first_label, next_label;
430 rtx lab1 = gen_label_rtx ();
431 enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
432 enum machine_mode value_mode;
436 value_mode = TYPE_MODE (integer_type_node);
438 if (setjmp_alias_set == -1)
439 setjmp_alias_set = new_alias_set ();
441 #ifdef POINTERS_EXTEND_UNSIGNED
442 buf_addr = convert_memory_address (Pmode, buf_addr);
445 buf_addr = force_reg (Pmode, force_operand (buf_addr, NULL_RTX));
447 if (target == 0 || GET_CODE (target) != REG
448 || REGNO (target) < FIRST_PSEUDO_REGISTER)
449 target = gen_reg_rtx (value_mode);
453 /* We store the frame pointer and the address of lab1 in the buffer
454 and use the rest of it for the stack save area, which is
455 machine-dependent. */
457 #ifndef BUILTIN_SETJMP_FRAME_VALUE
458 #define BUILTIN_SETJMP_FRAME_VALUE virtual_stack_vars_rtx
461 mem = gen_rtx_MEM (Pmode, buf_addr);
462 MEM_ALIAS_SET (mem) = setjmp_alias_set;
463 emit_move_insn (mem, BUILTIN_SETJMP_FRAME_VALUE);
465 mem = gen_rtx_MEM (Pmode, plus_constant (buf_addr, GET_MODE_SIZE (Pmode))),
466 MEM_ALIAS_SET (mem) = setjmp_alias_set;
468 emit_move_insn (validize_mem (mem),
469 force_reg (Pmode, gen_rtx_LABEL_REF (Pmode, lab1)));
471 stack_save = gen_rtx_MEM (sa_mode,
472 plus_constant (buf_addr,
473 2 * GET_MODE_SIZE (Pmode)));
474 MEM_ALIAS_SET (stack_save) = setjmp_alias_set;
475 emit_stack_save (SAVE_NONLOCAL, &stack_save, NULL_RTX);
477 /* If there is further processing to do, do it. */
478 #ifdef HAVE_builtin_setjmp_setup
479 if (HAVE_builtin_setjmp_setup)
480 emit_insn (gen_builtin_setjmp_setup (buf_addr));
483 /* Set TARGET to zero and branch to the first-time-through label. */
484 emit_move_insn (target, const0_rtx);
485 emit_jump_insn (gen_jump (first_label));
489 /* Tell flow about the strange goings on. Putting `lab1' on
490 `nonlocal_goto_handler_labels' to indicates that function
491 calls may traverse the arc back to this label. */
493 current_function_has_nonlocal_label = 1;
494 current_function_calls_setjmp = 1;
495 nonlocal_goto_handler_labels
496 = gen_rtx_EXPR_LIST (VOIDmode, lab1, nonlocal_goto_handler_labels);
498 /* Clobber the FP when we get here, so we have to make sure it's
499 marked as used by this function. */
500 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
502 /* Mark the static chain as clobbered here so life information
503 doesn't get messed up for it. */
504 emit_insn (gen_rtx_CLOBBER (VOIDmode, static_chain_rtx));
506 /* Now put in the code to restore the frame pointer, and argument
507 pointer, if needed. The code below is from expand_end_bindings
508 in stmt.c; see detailed documentation there. */
509 #ifdef HAVE_nonlocal_goto
510 if (! HAVE_nonlocal_goto)
512 emit_move_insn (virtual_stack_vars_rtx, hard_frame_pointer_rtx);
514 #if ARG_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
515 if (fixed_regs[ARG_POINTER_REGNUM])
517 #ifdef ELIMINABLE_REGS
519 static struct elims {int from, to;} elim_regs[] = ELIMINABLE_REGS;
521 for (i = 0; i < ARRAY_SIZE (elim_regs); i++)
522 if (elim_regs[i].from == ARG_POINTER_REGNUM
523 && elim_regs[i].to == HARD_FRAME_POINTER_REGNUM)
526 if (i == ARRAY_SIZE (elim_regs))
529 /* Now restore our arg pointer from the address at which it
530 was saved in our stack frame.
531 If there hasn't be space allocated for it yet, make
533 if (arg_pointer_save_area == 0)
534 arg_pointer_save_area
535 = assign_stack_local (Pmode, GET_MODE_SIZE (Pmode), 0);
536 emit_move_insn (virtual_incoming_args_rtx,
537 copy_to_reg (arg_pointer_save_area));
542 #ifdef HAVE_builtin_setjmp_receiver
543 if (HAVE_builtin_setjmp_receiver)
544 emit_insn (gen_builtin_setjmp_receiver (lab1));
547 #ifdef HAVE_nonlocal_goto_receiver
548 if (HAVE_nonlocal_goto_receiver)
549 emit_insn (gen_nonlocal_goto_receiver ());
556 /* Set TARGET, and branch to the next-time-through label. */
557 emit_move_insn (target, const1_rtx);
558 emit_jump_insn (gen_jump (next_label));
564 /* __builtin_longjmp is passed a pointer to an array of five words (not
565 all will be used on all machines). It operates similarly to the C
566 library function of the same name, but is more efficient. Much of
567 the code below is copied from the handling of non-local gotos.
569 NOTE: This is intended for use by GNAT and the exception handling
570 scheme in the compiler and will only work in the method used by
574 expand_builtin_longjmp (buf_addr, value)
578 enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
580 if (setjmp_alias_set == -1)
581 setjmp_alias_set = new_alias_set ();
583 #ifdef POINTERS_EXTEND_UNSIGNED
584 buf_addr = convert_memory_address (Pmode, buf_addr);
586 buf_addr = force_reg (Pmode, buf_addr);
588 /* We used to store value in static_chain_rtx, but that fails if pointers
589 are smaller than integers. We instead require that the user must pass
590 a second argument of 1, because that is what builtin_setjmp will
591 return. This also makes EH slightly more efficient, since we are no
592 longer copying around a value that we don't care about. */
593 if (value != const1_rtx)
596 current_function_calls_longjmp = 1;
598 #ifdef HAVE_builtin_longjmp
599 if (HAVE_builtin_longjmp)
600 emit_insn (gen_builtin_longjmp (buf_addr));
604 fp = gen_rtx_MEM (Pmode, buf_addr);
605 lab = gen_rtx_MEM (Pmode, plus_constant (buf_addr,
606 GET_MODE_SIZE (Pmode)));
608 stack = gen_rtx_MEM (sa_mode, plus_constant (buf_addr,
609 2 * GET_MODE_SIZE (Pmode)));
610 MEM_ALIAS_SET (fp) = MEM_ALIAS_SET (lab) = MEM_ALIAS_SET (stack)
613 /* Pick up FP, label, and SP from the block and jump. This code is
614 from expand_goto in stmt.c; see there for detailed comments. */
615 #if HAVE_nonlocal_goto
616 if (HAVE_nonlocal_goto)
617 /* We have to pass a value to the nonlocal_goto pattern that will
618 get copied into the static_chain pointer, but it does not matter
619 what that value is, because builtin_setjmp does not use it. */
620 emit_insn (gen_nonlocal_goto (value, fp, stack, lab));
624 lab = copy_to_reg (lab);
626 emit_move_insn (hard_frame_pointer_rtx, fp);
627 emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
629 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
630 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
631 emit_indirect_jump (lab);
636 /* Get a MEM rtx for expression EXP which is the address of an operand
637 to be used to be used in a string instruction (cmpstrsi, movstrsi, ..). */
643 rtx mem = gen_rtx_MEM (BLKmode,
644 memory_address (BLKmode,
645 expand_expr (exp, NULL_RTX,
646 ptr_mode, EXPAND_SUM)));
648 /* Get an expression we can use to find the attributes to assign to MEM.
649 If it is an ADDR_EXPR, use the operand. Otherwise, dereference it if
650 we can. First remove any nops. */
651 while ((TREE_CODE (exp) == NOP_EXPR || TREE_CODE (exp) == CONVERT_EXPR
652 || TREE_CODE (exp) == NON_LVALUE_EXPR)
653 && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (exp, 0))))
654 exp = TREE_OPERAND (exp, 0);
656 if (TREE_CODE (exp) == ADDR_EXPR)
657 exp = TREE_OPERAND (exp, 0);
658 else if (POINTER_TYPE_P (TREE_TYPE (exp)))
659 exp = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (exp)), exp);
663 set_mem_attributes (mem, exp, 0);
665 /* memcpy, memset and other builtin stringops can alias with anything. */
666 MEM_ALIAS_SET (mem) = 0;
670 /* Built-in functions to perform an untyped call and return. */
672 /* For each register that may be used for calling a function, this
673 gives a mode used to copy the register's value. VOIDmode indicates
674 the register is not used for calling a function. If the machine
675 has register windows, this gives only the outbound registers.
676 INCOMING_REGNO gives the corresponding inbound register. */
677 static enum machine_mode apply_args_mode[FIRST_PSEUDO_REGISTER];
679 /* For each register that may be used for returning values, this gives
680 a mode used to copy the register's value. VOIDmode indicates the
681 register is not used for returning values. If the machine has
682 register windows, this gives only the outbound registers.
683 INCOMING_REGNO gives the corresponding inbound register. */
684 static enum machine_mode apply_result_mode[FIRST_PSEUDO_REGISTER];
686 /* For each register that may be used for calling a function, this
687 gives the offset of that register into the block returned by
688 __builtin_apply_args. 0 indicates that the register is not
689 used for calling a function. */
690 static int apply_args_reg_offset[FIRST_PSEUDO_REGISTER];
692 /* Return the offset of register REGNO into the block returned by
693 __builtin_apply_args. This is not declared static, since it is
694 needed in objc-act.c. */
697 apply_args_register_offset (regno)
702 /* Arguments are always put in outgoing registers (in the argument
703 block) if such make sense. */
704 #ifdef OUTGOING_REGNO
705 regno = OUTGOING_REGNO(regno);
707 return apply_args_reg_offset[regno];
710 /* Return the size required for the block returned by __builtin_apply_args,
711 and initialize apply_args_mode. */
716 static int size = -1;
718 enum machine_mode mode;
720 /* The values computed by this function never change. */
723 /* The first value is the incoming arg-pointer. */
724 size = GET_MODE_SIZE (Pmode);
726 /* The second value is the structure value address unless this is
727 passed as an "invisible" first argument. */
728 if (struct_value_rtx)
729 size += GET_MODE_SIZE (Pmode);
731 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
732 if (FUNCTION_ARG_REGNO_P (regno))
734 /* Search for the proper mode for copying this register's
735 value. I'm not sure this is right, but it works so far. */
736 enum machine_mode best_mode = VOIDmode;
738 for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT);
740 mode = GET_MODE_WIDER_MODE (mode))
741 if (HARD_REGNO_MODE_OK (regno, mode)
742 && HARD_REGNO_NREGS (regno, mode) == 1)
745 if (best_mode == VOIDmode)
746 for (mode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT);
748 mode = GET_MODE_WIDER_MODE (mode))
749 if (HARD_REGNO_MODE_OK (regno, mode)
750 && (mov_optab->handlers[(int) mode].insn_code
751 != CODE_FOR_nothing))
755 if (mode == VOIDmode)
758 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
759 if (size % align != 0)
760 size = CEIL (size, align) * align;
761 apply_args_reg_offset[regno] = size;
762 size += GET_MODE_SIZE (mode);
763 apply_args_mode[regno] = mode;
767 apply_args_mode[regno] = VOIDmode;
768 apply_args_reg_offset[regno] = 0;
774 /* Return the size required for the block returned by __builtin_apply,
775 and initialize apply_result_mode. */
780 static int size = -1;
782 enum machine_mode mode;
784 /* The values computed by this function never change. */
789 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
790 if (FUNCTION_VALUE_REGNO_P (regno))
792 /* Search for the proper mode for copying this register's
793 value. I'm not sure this is right, but it works so far. */
794 enum machine_mode best_mode = VOIDmode;
796 for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT);
798 mode = GET_MODE_WIDER_MODE (mode))
799 if (HARD_REGNO_MODE_OK (regno, mode))
802 if (best_mode == VOIDmode)
803 for (mode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT);
805 mode = GET_MODE_WIDER_MODE (mode))
806 if (HARD_REGNO_MODE_OK (regno, mode)
807 && (mov_optab->handlers[(int) mode].insn_code
808 != CODE_FOR_nothing))
812 if (mode == VOIDmode)
815 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
816 if (size % align != 0)
817 size = CEIL (size, align) * align;
818 size += GET_MODE_SIZE (mode);
819 apply_result_mode[regno] = mode;
822 apply_result_mode[regno] = VOIDmode;
824 /* Allow targets that use untyped_call and untyped_return to override
825 the size so that machine-specific information can be stored here. */
826 #ifdef APPLY_RESULT_SIZE
827 size = APPLY_RESULT_SIZE;
833 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
834 /* Create a vector describing the result block RESULT. If SAVEP is true,
835 the result block is used to save the values; otherwise it is used to
836 restore the values. */
839 result_vector (savep, result)
843 int regno, size, align, nelts;
844 enum machine_mode mode;
846 rtx *savevec = (rtx *) alloca (FIRST_PSEUDO_REGISTER * sizeof (rtx));
849 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
850 if ((mode = apply_result_mode[regno]) != VOIDmode)
852 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
853 if (size % align != 0)
854 size = CEIL (size, align) * align;
855 reg = gen_rtx_REG (mode, savep ? regno : INCOMING_REGNO (regno));
856 mem = change_address (result, mode,
857 plus_constant (XEXP (result, 0), size));
858 savevec[nelts++] = (savep
859 ? gen_rtx_SET (VOIDmode, mem, reg)
860 : gen_rtx_SET (VOIDmode, reg, mem));
861 size += GET_MODE_SIZE (mode);
863 return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (nelts, savevec));
865 #endif /* HAVE_untyped_call or HAVE_untyped_return */
867 /* Save the state required to perform an untyped call with the same
868 arguments as were passed to the current function. */
871 expand_builtin_apply_args_1 ()
874 int size, align, regno;
875 enum machine_mode mode;
877 /* Create a block where the arg-pointer, structure value address,
878 and argument registers can be saved. */
879 registers = assign_stack_local (BLKmode, apply_args_size (), -1);
881 /* Walk past the arg-pointer and structure value address. */
882 size = GET_MODE_SIZE (Pmode);
883 if (struct_value_rtx)
884 size += GET_MODE_SIZE (Pmode);
886 /* Save each register used in calling a function to the block. */
887 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
888 if ((mode = apply_args_mode[regno]) != VOIDmode)
892 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
893 if (size % align != 0)
894 size = CEIL (size, align) * align;
896 tem = gen_rtx_REG (mode, INCOMING_REGNO (regno));
898 emit_move_insn (change_address (registers, mode,
899 plus_constant (XEXP (registers, 0),
902 size += GET_MODE_SIZE (mode);
905 /* Save the arg pointer to the block. */
906 emit_move_insn (change_address (registers, Pmode, XEXP (registers, 0)),
907 copy_to_reg (virtual_incoming_args_rtx));
908 size = GET_MODE_SIZE (Pmode);
910 /* Save the structure value address unless this is passed as an
911 "invisible" first argument. */
912 if (struct_value_incoming_rtx)
914 emit_move_insn (change_address (registers, Pmode,
915 plus_constant (XEXP (registers, 0),
917 copy_to_reg (struct_value_incoming_rtx));
918 size += GET_MODE_SIZE (Pmode);
921 /* Return the address of the block. */
922 return copy_addr_to_reg (XEXP (registers, 0));
925 /* __builtin_apply_args returns block of memory allocated on
926 the stack into which is stored the arg pointer, structure
927 value address, static chain, and all the registers that might
928 possibly be used in performing a function call. The code is
929 moved to the start of the function so the incoming values are
932 expand_builtin_apply_args ()
934 /* Don't do __builtin_apply_args more than once in a function.
935 Save the result of the first call and reuse it. */
936 if (apply_args_value != 0)
937 return apply_args_value;
939 /* When this function is called, it means that registers must be
940 saved on entry to this function. So we migrate the
941 call to the first insn of this function. */
946 temp = expand_builtin_apply_args_1 ();
950 apply_args_value = temp;
952 /* Put the sequence after the NOTE that starts the function.
953 If this is inside a SEQUENCE, make the outer-level insn
954 chain current, so the code is placed at the start of the
956 push_topmost_sequence ();
957 emit_insns_before (seq, NEXT_INSN (get_insns ()));
958 pop_topmost_sequence ();
963 /* Perform an untyped call and save the state required to perform an
964 untyped return of whatever value was returned by the given function. */
967 expand_builtin_apply (function, arguments, argsize)
968 rtx function, arguments, argsize;
970 int size, align, regno;
971 enum machine_mode mode;
972 rtx incoming_args, result, reg, dest, call_insn;
973 rtx old_stack_level = 0;
976 /* Create a block where the return registers can be saved. */
977 result = assign_stack_local (BLKmode, apply_result_size (), -1);
979 /* Fetch the arg pointer from the ARGUMENTS block. */
980 incoming_args = gen_reg_rtx (Pmode);
981 emit_move_insn (incoming_args,
982 gen_rtx_MEM (Pmode, arguments));
983 #ifndef STACK_GROWS_DOWNWARD
984 incoming_args = expand_binop (Pmode, sub_optab, incoming_args, argsize,
985 incoming_args, 0, OPTAB_LIB_WIDEN);
988 /* Perform postincrements before actually calling the function. */
991 /* Push a new argument block and copy the arguments. Do not allow
992 the (potential) memcpy call below to interfere with our stack
994 do_pending_stack_adjust ();
997 /* Save the stack with nonlocal if available */
998 #ifdef HAVE_save_stack_nonlocal
999 if (HAVE_save_stack_nonlocal)
1000 emit_stack_save (SAVE_NONLOCAL, &old_stack_level, NULL_RTX);
1003 emit_stack_save (SAVE_BLOCK, &old_stack_level, NULL_RTX);
1005 /* Push a block of memory onto the stack to store the memory arguments.
1006 Save the address in a register, and copy the memory arguments. ??? I
1007 haven't figured out how the calling convention macros effect this,
1008 but it's likely that the source and/or destination addresses in
1009 the block copy will need updating in machine specific ways. */
1010 dest = allocate_dynamic_stack_space (argsize, 0, BITS_PER_UNIT);
1011 emit_block_move (gen_rtx_MEM (BLKmode, dest),
1012 gen_rtx_MEM (BLKmode, incoming_args),
1013 argsize, PARM_BOUNDARY);
1015 /* Refer to the argument block. */
1017 arguments = gen_rtx_MEM (BLKmode, arguments);
1019 /* Walk past the arg-pointer and structure value address. */
1020 size = GET_MODE_SIZE (Pmode);
1021 if (struct_value_rtx)
1022 size += GET_MODE_SIZE (Pmode);
1024 /* Restore each of the registers previously saved. Make USE insns
1025 for each of these registers for use in making the call. */
1026 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1027 if ((mode = apply_args_mode[regno]) != VOIDmode)
1029 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1030 if (size % align != 0)
1031 size = CEIL (size, align) * align;
1032 reg = gen_rtx_REG (mode, regno);
1033 emit_move_insn (reg,
1034 change_address (arguments, mode,
1035 plus_constant (XEXP (arguments, 0),
1038 use_reg (&call_fusage, reg);
1039 size += GET_MODE_SIZE (mode);
1042 /* Restore the structure value address unless this is passed as an
1043 "invisible" first argument. */
1044 size = GET_MODE_SIZE (Pmode);
1045 if (struct_value_rtx)
1047 rtx value = gen_reg_rtx (Pmode);
1048 emit_move_insn (value,
1049 change_address (arguments, Pmode,
1050 plus_constant (XEXP (arguments, 0),
1052 emit_move_insn (struct_value_rtx, value);
1053 if (GET_CODE (struct_value_rtx) == REG)
1054 use_reg (&call_fusage, struct_value_rtx);
1055 size += GET_MODE_SIZE (Pmode);
1058 /* All arguments and registers used for the call are set up by now! */
1059 function = prepare_call_address (function, NULL_TREE, &call_fusage, 0);
1061 /* Ensure address is valid. SYMBOL_REF is already valid, so no need,
1062 and we don't want to load it into a register as an optimization,
1063 because prepare_call_address already did it if it should be done. */
1064 if (GET_CODE (function) != SYMBOL_REF)
1065 function = memory_address (FUNCTION_MODE, function);
1067 /* Generate the actual call instruction and save the return value. */
1068 #ifdef HAVE_untyped_call
1069 if (HAVE_untyped_call)
1070 emit_call_insn (gen_untyped_call (gen_rtx_MEM (FUNCTION_MODE, function),
1071 result, result_vector (1, result)));
1074 #ifdef HAVE_call_value
1075 if (HAVE_call_value)
1079 /* Locate the unique return register. It is not possible to
1080 express a call that sets more than one return register using
1081 call_value; use untyped_call for that. In fact, untyped_call
1082 only needs to save the return registers in the given block. */
1083 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1084 if ((mode = apply_result_mode[regno]) != VOIDmode)
1087 abort (); /* HAVE_untyped_call required. */
1088 valreg = gen_rtx_REG (mode, regno);
1091 emit_call_insn (GEN_CALL_VALUE (valreg,
1092 gen_rtx_MEM (FUNCTION_MODE, function),
1093 const0_rtx, NULL_RTX, const0_rtx));
1095 emit_move_insn (change_address (result, GET_MODE (valreg),
1103 /* Find the CALL insn we just emitted. */
1104 for (call_insn = get_last_insn ();
1105 call_insn && GET_CODE (call_insn) != CALL_INSN;
1106 call_insn = PREV_INSN (call_insn))
1112 /* Put the register usage information on the CALL. If there is already
1113 some usage information, put ours at the end. */
1114 if (CALL_INSN_FUNCTION_USAGE (call_insn))
1118 for (link = CALL_INSN_FUNCTION_USAGE (call_insn); XEXP (link, 1) != 0;
1119 link = XEXP (link, 1))
1122 XEXP (link, 1) = call_fusage;
1125 CALL_INSN_FUNCTION_USAGE (call_insn) = call_fusage;
1127 /* Restore the stack. */
1128 #ifdef HAVE_save_stack_nonlocal
1129 if (HAVE_save_stack_nonlocal)
1130 emit_stack_restore (SAVE_NONLOCAL, old_stack_level, NULL_RTX);
1133 emit_stack_restore (SAVE_BLOCK, old_stack_level, NULL_RTX);
1137 /* Return the address of the result block. */
1138 return copy_addr_to_reg (XEXP (result, 0));
1141 /* Perform an untyped return. */
1144 expand_builtin_return (result)
1147 int size, align, regno;
1148 enum machine_mode mode;
1150 rtx call_fusage = 0;
1152 apply_result_size ();
1153 result = gen_rtx_MEM (BLKmode, result);
1155 #ifdef HAVE_untyped_return
1156 if (HAVE_untyped_return)
1158 emit_jump_insn (gen_untyped_return (result, result_vector (0, result)));
1164 /* Restore the return value and note that each value is used. */
1166 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1167 if ((mode = apply_result_mode[regno]) != VOIDmode)
1169 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1170 if (size % align != 0)
1171 size = CEIL (size, align) * align;
1172 reg = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1173 emit_move_insn (reg,
1174 change_address (result, mode,
1175 plus_constant (XEXP (result, 0),
1178 push_to_sequence (call_fusage);
1179 emit_insn (gen_rtx_USE (VOIDmode, reg));
1180 call_fusage = get_insns ();
1182 size += GET_MODE_SIZE (mode);
1185 /* Put the USE insns before the return. */
1186 emit_insns (call_fusage);
1188 /* Return whatever values was restored by jumping directly to the end
1190 expand_null_return ();
1193 /* Expand a call to __builtin_classify_type with arguments found in
1196 expand_builtin_classify_type (arglist)
1201 tree type = TREE_TYPE (TREE_VALUE (arglist));
1202 enum tree_code code = TREE_CODE (type);
1203 if (code == VOID_TYPE)
1204 return GEN_INT (void_type_class);
1205 if (code == INTEGER_TYPE)
1206 return GEN_INT (integer_type_class);
1207 if (code == CHAR_TYPE)
1208 return GEN_INT (char_type_class);
1209 if (code == ENUMERAL_TYPE)
1210 return GEN_INT (enumeral_type_class);
1211 if (code == BOOLEAN_TYPE)
1212 return GEN_INT (boolean_type_class);
1213 if (code == POINTER_TYPE)
1214 return GEN_INT (pointer_type_class);
1215 if (code == REFERENCE_TYPE)
1216 return GEN_INT (reference_type_class);
1217 if (code == OFFSET_TYPE)
1218 return GEN_INT (offset_type_class);
1219 if (code == REAL_TYPE)
1220 return GEN_INT (real_type_class);
1221 if (code == COMPLEX_TYPE)
1222 return GEN_INT (complex_type_class);
1223 if (code == FUNCTION_TYPE)
1224 return GEN_INT (function_type_class);
1225 if (code == METHOD_TYPE)
1226 return GEN_INT (method_type_class);
1227 if (code == RECORD_TYPE)
1228 return GEN_INT (record_type_class);
1229 if (code == UNION_TYPE || code == QUAL_UNION_TYPE)
1230 return GEN_INT (union_type_class);
1231 if (code == ARRAY_TYPE)
1233 if (TYPE_STRING_FLAG (type))
1234 return GEN_INT (string_type_class);
1236 return GEN_INT (array_type_class);
1238 if (code == SET_TYPE)
1239 return GEN_INT (set_type_class);
1240 if (code == FILE_TYPE)
1241 return GEN_INT (file_type_class);
1242 if (code == LANG_TYPE)
1243 return GEN_INT (lang_type_class);
1245 return GEN_INT (no_type_class);
1248 /* Expand expression EXP, which is a call to __builtin_constant_p. */
1250 expand_builtin_constant_p (exp)
1253 tree arglist = TREE_OPERAND (exp, 1);
1254 enum machine_mode value_mode = TYPE_MODE (TREE_TYPE (exp));
1259 arglist = TREE_VALUE (arglist);
1261 /* We have taken care of the easy cases during constant folding. This
1262 case is not obvious, so emit (constant_p_rtx (ARGLIST)) and let CSE get a
1263 chance to see if it can deduce whether ARGLIST is constant. */
1265 tmp = expand_expr (arglist, NULL_RTX, VOIDmode, 0);
1266 tmp = gen_rtx_CONSTANT_P_RTX (value_mode, tmp);
1270 /* Expand a call to one of the builtin math functions (sin, cos, or sqrt).
1271 Return 0 if a normal call should be emitted rather than expanding the
1272 function in-line. EXP is the expression that is a call to the builtin
1273 function; if convenient, the result should be placed in TARGET.
1274 SUBTARGET may be used as the target for computing one of EXP's operands. */
1276 expand_builtin_mathfn (exp, target, subtarget)
1278 rtx target, subtarget;
1280 optab builtin_optab;
1282 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
1283 tree arglist = TREE_OPERAND (exp, 1);
1286 /* Arg could be wrong type if user redeclared this fcn wrong. */
1287 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != REAL_TYPE)
1290 /* Stabilize and compute the argument. */
1291 if (TREE_CODE (TREE_VALUE (arglist)) != VAR_DECL
1292 && TREE_CODE (TREE_VALUE (arglist)) != PARM_DECL)
1294 exp = copy_node (exp);
1295 TREE_OPERAND (exp, 1) = arglist;
1296 /* Wrap the computation of the argument in a SAVE_EXPR. That
1297 way, if we need to expand the argument again (as in the
1298 flag_errno_math case below where we cannot directly set
1299 errno), we will not perform side-effects more than once.
1300 Note that here we're mutating the original EXP as well as the
1301 copy; that's the right thing to do in case the original EXP
1302 is expanded later. */
1303 TREE_VALUE (arglist) = save_expr (TREE_VALUE (arglist));
1304 arglist = copy_node (arglist);
1306 op0 = expand_expr (TREE_VALUE (arglist), subtarget, VOIDmode, 0);
1308 /* Make a suitable register to place result in. */
1309 target = gen_reg_rtx (TYPE_MODE (TREE_TYPE (exp)));
1314 switch (DECL_FUNCTION_CODE (fndecl))
1317 builtin_optab = sin_optab; break;
1319 builtin_optab = cos_optab; break;
1320 case BUILT_IN_FSQRT:
1321 builtin_optab = sqrt_optab; break;
1326 /* Compute into TARGET.
1327 Set TARGET to wherever the result comes back. */
1328 target = expand_unop (TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist))),
1329 builtin_optab, op0, target, 0);
1331 /* If we were unable to expand via the builtin, stop the
1332 sequence (without outputting the insns) and return 0, causing
1333 a call to the library function. */
1340 /* Check the results by default. But if flag_fast_math is turned on,
1341 then assume sqrt will always be called with valid arguments. */
1343 if (flag_errno_math && ! flag_fast_math)
1347 /* Don't define the builtin FP instructions
1348 if your machine is not IEEE. */
1349 if (TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT)
1352 lab1 = gen_label_rtx ();
1354 /* Test the result; if it is NaN, set errno=EDOM because
1355 the argument was not in the domain. */
1356 emit_cmp_and_jump_insns (target, target, EQ, 0, GET_MODE (target),
1361 #ifdef GEN_ERRNO_RTX
1362 rtx errno_rtx = GEN_ERRNO_RTX;
1365 = gen_rtx_MEM (word_mode, gen_rtx_SYMBOL_REF (Pmode, "errno"));
1368 emit_move_insn (errno_rtx, GEN_INT (TARGET_EDOM));
1371 /* We can't set errno=EDOM directly; let the library call do it.
1372 Pop the arguments right away in case the call gets deleted. */
1374 expand_call (exp, target, 0);
1381 /* Output the entire sequence. */
1382 insns = get_insns ();
1389 /* Expand expression EXP which is a call to the strlen builtin. Return 0
1390 if we failed the caller should emit a normal call, otherwise
1391 try to get the result in TARGET, if convenient. */
1394 expand_builtin_strlen (exp, target)
1398 tree arglist = TREE_OPERAND (exp, 1);
1399 enum machine_mode value_mode = TYPE_MODE (TREE_TYPE (exp));
1402 /* Arg could be non-pointer if user redeclared this fcn wrong. */
1403 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE)
1408 tree src = TREE_VALUE (arglist);
1411 = get_pointer_alignment (src, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
1413 rtx result, src_reg, char_rtx, before_strlen;
1414 enum machine_mode insn_mode = value_mode, char_mode;
1415 enum insn_code icode = CODE_FOR_nothing;
1417 /* If SRC is not a pointer type, don't do this operation inline. */
1421 /* Bail out if we can't compute strlen in the right mode. */
1422 while (insn_mode != VOIDmode)
1424 icode = strlen_optab->handlers[(int) insn_mode].insn_code;
1425 if (icode != CODE_FOR_nothing)
1428 insn_mode = GET_MODE_WIDER_MODE (insn_mode);
1430 if (insn_mode == VOIDmode)
1433 /* Make a place to write the result of the instruction. */
1436 && GET_CODE (result) == REG
1437 && GET_MODE (result) == insn_mode
1438 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
1439 result = gen_reg_rtx (insn_mode);
1441 /* Make a place to hold the source address. We will not expand
1442 the actual source until we are sure that the expansion will
1443 not fail -- there are trees that cannot be expanded twice. */
1444 src_reg = gen_reg_rtx (Pmode);
1446 /* Mark the beginning of the strlen sequence so we can emit the
1447 source operand later. */
1448 before_strlen = get_last_insn();
1450 /* Check the string is readable and has an end. */
1451 if (current_function_check_memory_usage)
1452 emit_library_call (chkr_check_str_libfunc, LCT_CONST_MAKE_BLOCK,
1453 VOIDmode, 2, src_reg, Pmode,
1454 GEN_INT (MEMORY_USE_RO),
1455 TYPE_MODE (integer_type_node));
1457 char_rtx = const0_rtx;
1458 char_mode = insn_data[(int) icode].operand[2].mode;
1459 if (! (*insn_data[(int) icode].operand[2].predicate) (char_rtx,
1461 char_rtx = copy_to_mode_reg (char_mode, char_rtx);
1463 pat = GEN_FCN (icode) (result, gen_rtx_MEM (BLKmode, src_reg),
1464 char_rtx, GEN_INT (align));
1469 /* Now that we are assured of success, expand the source. */
1471 pat = memory_address (BLKmode,
1472 expand_expr (src, src_reg, ptr_mode, EXPAND_SUM));
1474 emit_move_insn (src_reg, pat);
1475 pat = gen_sequence ();
1479 emit_insn_after (pat, before_strlen);
1481 emit_insn_before (pat, get_insns ());
1483 /* Return the value in the proper mode for this function. */
1484 if (GET_MODE (result) == value_mode)
1486 else if (target != 0)
1487 convert_move (target, result, 0);
1489 target = convert_to_mode (value_mode, result, 0);
1495 /* Expand a call to the strstr builtin. Return 0 if we failed the
1496 caller should emit a normal call, otherwise try to get the result
1497 in TARGET, if convenient (and in mode MODE if that's convenient). */
1500 expand_builtin_strstr (arglist, target, mode)
1503 enum machine_mode mode;
1506 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE
1507 || TREE_CHAIN (arglist) == 0
1508 || TREE_CODE (TREE_TYPE (TREE_VALUE (TREE_CHAIN (arglist)))) != POINTER_TYPE
1509 || current_function_check_memory_usage)
1513 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
1515 const char *p1, *p2;
1524 const char *r = strstr (p1, p2);
1529 /* Return an offset into the constant string argument. */
1530 return expand_expr (fold (build (PLUS_EXPR, TREE_TYPE (s1),
1531 s1, ssize_int (r - p1))),
1532 target, mode, EXPAND_NORMAL);
1536 return expand_expr (s1, target, mode, EXPAND_NORMAL);
1541 fn = built_in_decls[BUILT_IN_STRCHR];
1545 /* New argument list transforming strstr(s1, s2) to
1546 strchr(s1, s2[0]). */
1548 build_tree_list (NULL_TREE, build_int_2 (p2[0], 0));
1549 arglist = tree_cons (NULL_TREE, s1, arglist);
1550 call_expr = build1 (ADDR_EXPR,
1551 build_pointer_type (TREE_TYPE (fn)), fn);
1552 call_expr = build (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)),
1553 call_expr, arglist, NULL_TREE);
1554 TREE_SIDE_EFFECTS (call_expr) = 1;
1555 return expand_expr (call_expr, target, mode, EXPAND_NORMAL);
1559 /* Expand a call to the strchr builtin. Return 0 if we failed the
1560 caller should emit a normal call, otherwise try to get the result
1561 in TARGET, if convenient (and in mode MODE if that's convenient). */
1564 expand_builtin_strchr (arglist, target, mode)
1567 enum machine_mode mode;
1570 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE
1571 || TREE_CHAIN (arglist) == 0
1572 || TREE_CODE (TREE_TYPE (TREE_VALUE (TREE_CHAIN (arglist)))) != INTEGER_TYPE
1573 || current_function_check_memory_usage)
1577 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
1580 if (TREE_CODE (s2) != INTEGER_CST)
1586 const char *r = strchr (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 /* FIXME: Should use here strchrM optab so that ports can optimize
1603 /* Expand a call to the strrchr builtin. Return 0 if we failed the
1604 caller should emit a normal call, otherwise try to get the result
1605 in TARGET, if convenient (and in mode MODE if that's convenient). */
1608 expand_builtin_strrchr (arglist, target, mode)
1611 enum machine_mode mode;
1614 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE
1615 || TREE_CHAIN (arglist) == 0
1616 || TREE_CODE (TREE_TYPE (TREE_VALUE (TREE_CHAIN (arglist)))) != INTEGER_TYPE
1617 || current_function_check_memory_usage)
1621 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
1625 if (TREE_CODE (s2) != INTEGER_CST)
1631 const char *r = strrchr (p1, (char) TREE_INT_CST_LOW (s2));
1636 /* Return an offset into the constant string argument. */
1637 return expand_expr (fold (build (PLUS_EXPR, TREE_TYPE (s1),
1638 s1, ssize_int (r - p1))),
1639 target, mode, EXPAND_NORMAL);
1642 if (! integer_zerop (s2))
1645 fn = built_in_decls[BUILT_IN_STRCHR];
1649 /* Transform strrchr(s1, '\0') to strchr(s1, '\0'). */
1650 call_expr = build1 (ADDR_EXPR,
1651 build_pointer_type (TREE_TYPE (fn)), fn);
1652 call_expr = build (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)),
1653 call_expr, arglist, NULL_TREE);
1654 TREE_SIDE_EFFECTS (call_expr) = 1;
1655 return expand_expr (call_expr, target, mode, EXPAND_NORMAL);
1659 /* Expand a call to the strpbrk builtin. Return 0 if we failed the
1660 caller should emit a normal call, otherwise try to get the result
1661 in TARGET, if convenient (and in mode MODE if that's convenient). */
1664 expand_builtin_strpbrk (arglist, target, mode)
1667 enum machine_mode mode;
1670 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE
1671 || TREE_CHAIN (arglist) == 0
1672 || TREE_CODE (TREE_TYPE (TREE_VALUE (TREE_CHAIN (arglist)))) != POINTER_TYPE
1673 || current_function_check_memory_usage)
1677 tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
1679 const char *p1, *p2;
1688 const char *r = strpbrk (p1, p2);
1693 /* Return an offset into the constant string argument. */
1694 return expand_expr (fold (build (PLUS_EXPR, TREE_TYPE (s1),
1695 s1, ssize_int (r - p1))),
1696 target, mode, EXPAND_NORMAL);
1701 /* strpbrk(x, "") == NULL.
1702 Evaluate and ignore the arguments in case they had
1704 expand_expr (s1, const0_rtx, VOIDmode, EXPAND_NORMAL);
1709 return 0; /* Really call strpbrk. */
1711 fn = built_in_decls[BUILT_IN_STRCHR];
1715 /* New argument list transforming strpbrk(s1, s2) to
1716 strchr(s1, s2[0]). */
1718 build_tree_list (NULL_TREE, build_int_2 (p2[0], 0));
1719 arglist = tree_cons (NULL_TREE, s1, arglist);
1720 call_expr = build1 (ADDR_EXPR,
1721 build_pointer_type (TREE_TYPE (fn)), fn);
1722 call_expr = build (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)),
1723 call_expr, arglist, NULL_TREE);
1724 TREE_SIDE_EFFECTS (call_expr) = 1;
1725 return expand_expr (call_expr, target, mode, EXPAND_NORMAL);
1729 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
1730 bytes from constant string DATA + OFFSET and return it as target
1734 builtin_memcpy_read_str (data, offset, mode)
1736 HOST_WIDE_INT offset;
1737 enum machine_mode mode;
1739 const char *str = (const char *) data;
1741 if (offset + GET_MODE_SIZE (mode) > strlen (str) + 1)
1742 abort (); /* Attempt to read past the end of constant string. */
1744 return c_readstr (str + offset, mode);
1747 /* Expand a call to the memcpy builtin, with arguments in ARGLIST. */
1749 expand_builtin_memcpy (arglist)
1753 /* Arg could be non-pointer if user redeclared this fcn wrong. */
1754 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE
1755 || TREE_CHAIN (arglist) == 0
1756 || (TREE_CODE (TREE_TYPE (TREE_VALUE (TREE_CHAIN (arglist))))
1758 || TREE_CHAIN (TREE_CHAIN (arglist)) == 0
1759 || (TREE_CODE (TREE_TYPE (TREE_VALUE
1760 (TREE_CHAIN (TREE_CHAIN (arglist)))))
1765 tree dest = TREE_VALUE (arglist);
1766 tree src = TREE_VALUE (TREE_CHAIN (arglist));
1767 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
1768 const char *src_str;
1770 int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
1771 int dest_align = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
1772 rtx dest_mem, src_mem, dest_addr, len_rtx;
1774 /* If either SRC or DEST is not a pointer type, don't do
1775 this operation in-line. */
1776 if (src_align == 0 || dest_align == 0)
1779 dest_mem = get_memory_rtx (dest);
1780 len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
1781 src_str = c_getstr (src);
1783 /* If SRC is a string constant and block move would be done
1784 by pieces, we can avoid loading the string from memory
1785 and only stored the computed constants. */
1787 && !current_function_check_memory_usage
1788 && GET_CODE (len_rtx) == CONST_INT
1789 && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
1790 && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
1791 (PTR) src_str, dest_align))
1793 store_by_pieces (dest_mem, INTVAL (len_rtx),
1794 builtin_memcpy_read_str,
1795 (PTR) src_str, dest_align);
1796 return force_operand (XEXP (dest_mem, 0), NULL_RTX);
1799 src_mem = get_memory_rtx (src);
1801 /* Just copy the rights of SRC to the rights of DEST. */
1802 if (current_function_check_memory_usage)
1803 emit_library_call (chkr_copy_bitmap_libfunc, LCT_CONST_MAKE_BLOCK,
1804 VOIDmode, 3, XEXP (dest_mem, 0), Pmode,
1805 XEXP (src_mem, 0), Pmode,
1806 len_rtx, TYPE_MODE (sizetype));
1808 /* Copy word part most expediently. */
1810 = emit_block_move (dest_mem, src_mem, len_rtx,
1811 MIN (src_align, dest_align));
1814 dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
1820 /* Expand expression EXP, which is a call to the strcpy builtin. Return 0
1821 if we failed the caller should emit a normal call. */
1824 expand_builtin_strcpy (exp)
1827 tree arglist = TREE_OPERAND (exp, 1);
1831 /* Arg could be non-pointer if user redeclared this fcn wrong. */
1832 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE
1833 || TREE_CHAIN (arglist) == 0
1834 || (TREE_CODE (TREE_TYPE (TREE_VALUE (TREE_CHAIN (arglist))))
1839 tree len = c_strlen (TREE_VALUE (TREE_CHAIN (arglist)));
1844 len = size_binop (PLUS_EXPR, len, ssize_int (1));
1845 chainon (arglist, build_tree_list (NULL_TREE, len));
1848 result = expand_builtin_memcpy (arglist);
1851 TREE_CHAIN (TREE_CHAIN (arglist)) = 0;
1855 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
1856 bytes from constant string DATA + OFFSET and return it as target
1860 builtin_strncpy_read_str (data, offset, mode)
1862 HOST_WIDE_INT offset;
1863 enum machine_mode mode;
1865 const char *str = (const char *) data;
1867 if ((unsigned HOST_WIDE_INT) offset > strlen (str))
1870 return c_readstr (str + offset, mode);
1873 /* Expand expression EXP, which is a call to the strncpy builtin. Return 0
1874 if we failed the caller should emit a normal call. */
1877 expand_builtin_strncpy (arglist, target, mode)
1880 enum machine_mode mode;
1883 /* Arg could be non-pointer if user redeclared this fcn wrong. */
1884 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE
1885 || TREE_CHAIN (arglist) == 0
1886 || (TREE_CODE (TREE_TYPE (TREE_VALUE (TREE_CHAIN (arglist))))
1888 || TREE_CHAIN (TREE_CHAIN (arglist)) == 0
1889 || (TREE_CODE (TREE_TYPE (TREE_VALUE
1890 (TREE_CHAIN (TREE_CHAIN (arglist)))))
1895 tree slen = c_strlen (TREE_VALUE (TREE_CHAIN (arglist)));
1896 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
1898 /* We must be passed a constant len parameter. */
1899 if (TREE_CODE (len) != INTEGER_CST)
1902 /* If the len parameter is zero, return the dst parameter. */
1903 if (compare_tree_int (len, 0) == 0)
1905 /* Evaluate and ignore the src argument in case it has
1907 expand_expr (TREE_VALUE (TREE_CHAIN (arglist)), const0_rtx,
1908 VOIDmode, EXPAND_NORMAL);
1909 /* Return the dst parameter. */
1910 return expand_expr (TREE_VALUE (arglist), target, mode,
1914 /* Now, we must be passed a constant src ptr parameter. */
1915 if (slen == 0 || TREE_CODE (slen) != INTEGER_CST)
1918 slen = size_binop (PLUS_EXPR, slen, ssize_int (1));
1920 /* We're required to pad with trailing zeros if the requested
1921 len is greater than strlen(s2)+1. In that case try to
1922 use store_by_pieces, if it fails, punt. */
1923 if (tree_int_cst_lt (slen, len))
1925 tree dest = TREE_VALUE (arglist);
1926 int dest_align = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
1927 const char *p = c_getstr (TREE_VALUE (TREE_CHAIN (arglist)));
1930 if (!p || !dest_align || TREE_INT_CST_HIGH (len)
1931 || !can_store_by_pieces (TREE_INT_CST_LOW (len),
1932 builtin_strncpy_read_str,
1933 (PTR) p, dest_align))
1936 dest_mem = get_memory_rtx (dest);
1937 store_by_pieces (dest_mem, TREE_INT_CST_LOW (len),
1938 builtin_strncpy_read_str,
1939 (PTR) p, dest_align);
1940 return force_operand (XEXP (dest_mem, 0), NULL_RTX);
1943 /* OK transform into builtin memcpy. */
1944 return expand_builtin_memcpy (arglist);
1948 /* Expand expression EXP, which is a call to the memset builtin. Return 0
1949 if we failed the caller should emit a normal call. */
1952 expand_builtin_memset (exp)
1955 tree arglist = TREE_OPERAND (exp, 1);
1958 /* Arg could be non-pointer if user redeclared this fcn wrong. */
1959 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE
1960 || TREE_CHAIN (arglist) == 0
1961 || (TREE_CODE (TREE_TYPE (TREE_VALUE (TREE_CHAIN (arglist))))
1963 || TREE_CHAIN (TREE_CHAIN (arglist)) == 0
1965 != (TREE_CODE (TREE_TYPE
1967 (TREE_CHAIN (TREE_CHAIN (arglist))))))))
1971 tree dest = TREE_VALUE (arglist);
1972 tree val = TREE_VALUE (TREE_CHAIN (arglist));
1973 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
1975 int dest_align = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
1976 rtx dest_mem, dest_addr, len_rtx;
1978 /* If DEST is not a pointer type, don't do this
1979 operation in-line. */
1980 if (dest_align == 0)
1983 /* If the arguments have side-effects, then we can only evaluate
1984 them at most once. The following code evaluates them twice if
1985 they are not constants because we break out to expand_call
1986 in that case. They can't be constants if they have side-effects
1987 so we can check for that first. Alternatively, we could call
1988 save_expr to make multiple evaluation safe. */
1989 if (TREE_SIDE_EFFECTS (val) || TREE_SIDE_EFFECTS (len))
1992 /* If VAL is not 0, don't do this operation in-line. */
1993 if (expand_expr (val, NULL_RTX, VOIDmode, 0) != const0_rtx)
1996 len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
1998 dest_mem = get_memory_rtx (dest);
2000 /* Just check DST is writable and mark it as readable. */
2001 if (current_function_check_memory_usage)
2002 emit_library_call (chkr_check_addr_libfunc, LCT_CONST_MAKE_BLOCK,
2003 VOIDmode, 3, XEXP (dest_mem, 0), Pmode,
2004 len_rtx, TYPE_MODE (sizetype),
2005 GEN_INT (MEMORY_USE_WO),
2006 TYPE_MODE (integer_type_node));
2009 dest_addr = clear_storage (dest_mem, len_rtx, dest_align);
2012 dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2018 /* Expand expression EXP, which is a call to the bzero builtin. Return 0
2019 if we failed the caller should emit a normal call. */
2021 expand_builtin_bzero (exp)
2024 tree arglist = TREE_OPERAND (exp, 1);
2025 tree dest, size, newarglist;
2029 /* Arg could be non-pointer if user redeclared this fcn wrong. */
2030 || TREE_CODE (TREE_TYPE (dest = TREE_VALUE (arglist))) != POINTER_TYPE
2031 || TREE_CHAIN (arglist) == 0
2032 || (TREE_CODE (TREE_TYPE (size = TREE_VALUE (TREE_CHAIN (arglist))))
2036 /* New argument list transforming bzero(ptr x, int y) to
2037 memset(ptr x, int 0, size_t y). */
2039 newarglist = build_tree_list (NULL_TREE, convert (sizetype, size));
2040 newarglist = tree_cons (NULL_TREE, integer_zero_node, newarglist);
2041 newarglist = tree_cons (NULL_TREE, dest, newarglist);
2043 TREE_OPERAND (exp, 1) = newarglist;
2044 result = expand_builtin_memset(exp);
2046 /* Always restore the original arguments. */
2047 TREE_OPERAND (exp, 1) = arglist;
2052 #ifdef HAVE_cmpstrsi
2053 /* Expand expression EXP, which is a call to the memcmp or the strcmp builtin.
2054 ARGLIST is the argument list for this call. Return 0 if we failed and the
2055 caller should emit a normal call, otherwise try to get the result in
2056 TARGET, if convenient. */
2058 expand_builtin_memcmp (exp, arglist, target)
2063 /* If we need to check memory accesses, call the library function. */
2064 if (current_function_check_memory_usage)
2068 /* Arg could be non-pointer if user redeclared this fcn wrong. */
2069 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE
2070 || TREE_CHAIN (arglist) == 0
2071 || TREE_CODE (TREE_TYPE (TREE_VALUE (TREE_CHAIN (arglist)))) != POINTER_TYPE
2072 || TREE_CHAIN (TREE_CHAIN (arglist)) == 0
2073 || TREE_CODE (TREE_TYPE (TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist))))) != INTEGER_TYPE)
2077 enum machine_mode mode;
2078 tree arg1 = TREE_VALUE (arglist);
2079 tree arg2 = TREE_VALUE (TREE_CHAIN (arglist));
2080 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2081 rtx arg1_rtx, arg2_rtx, arg3_rtx;
2086 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
2088 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
2089 enum machine_mode insn_mode
2090 = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
2092 /* If we don't have POINTER_TYPE, call the function. */
2093 if (arg1_align == 0 || arg2_align == 0)
2096 /* Make a place to write the result of the instruction. */
2099 && GET_CODE (result) == REG && GET_MODE (result) == insn_mode
2100 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
2101 result = gen_reg_rtx (insn_mode);
2103 arg1_rtx = get_memory_rtx (arg1);
2104 arg2_rtx = get_memory_rtx (arg2);
2105 arg3_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
2109 insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
2110 GEN_INT (MIN (arg1_align, arg2_align)));
2115 emit_library_call_value (memcmp_libfunc, result, LCT_PURE_MAKE_BLOCK,
2116 TYPE_MODE (integer_type_node), 3,
2117 XEXP (arg1_rtx, 0), Pmode,
2118 XEXP (arg2_rtx, 0), Pmode,
2119 convert_to_mode (TYPE_MODE (sizetype), arg3_rtx,
2120 TREE_UNSIGNED (sizetype)),
2121 TYPE_MODE (sizetype));
2123 /* Return the value in the proper mode for this function. */
2124 mode = TYPE_MODE (TREE_TYPE (exp));
2125 if (GET_MODE (result) == mode)
2127 else if (target != 0)
2129 convert_move (target, result, 0);
2133 return convert_to_mode (mode, result, 0);
2138 /* Expand expression EXP, which is a call to the strcmp builtin. Return 0
2139 if we failed the caller should emit a normal call, otherwise try to get
2140 the result in TARGET, if convenient. */
2143 expand_builtin_strcmp (exp, target, mode)
2146 enum machine_mode mode;
2148 tree arglist = TREE_OPERAND (exp, 1);
2150 const char *p1, *p2;
2152 /* If we need to check memory accesses, call the library function. */
2153 if (current_function_check_memory_usage)
2157 /* Arg could be non-pointer if user redeclared this fcn wrong. */
2158 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE
2159 || TREE_CHAIN (arglist) == 0
2160 || (TREE_CODE (TREE_TYPE (TREE_VALUE (TREE_CHAIN (arglist))))
2164 arg1 = TREE_VALUE (arglist);
2165 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
2167 p1 = c_getstr (arg1);
2168 p2 = c_getstr (arg2);
2172 int i = strcmp (p1, p2);
2174 return expand_expr (i < 0 ? build_int_2 (-1, -1)
2175 : i == 0 ? integer_zero_node
2177 target, mode, EXPAND_NORMAL);
2180 #ifdef HAVE_cmpstrsi
2181 if (! HAVE_cmpstrsi)
2185 tree len = c_strlen (arg1);
2186 tree len2 = c_strlen (arg2);
2190 len = size_binop (PLUS_EXPR, ssize_int (1), len);
2193 len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
2195 /* If we don't have a constant length for the first, use the length
2196 of the second, if we know it. We don't require a constant for
2197 this case; some cost analysis could be done if both are available
2198 but neither is constant. For now, assume they're equally cheap
2199 unless one has side effects.
2201 If both strings have constant lengths, use the smaller. This
2202 could arise if optimization results in strcpy being called with
2203 two fixed strings, or if the code was machine-generated. We should
2204 add some code to the `memcmp' handler below to deal with such
2205 situations, someday. */
2207 if (!len || TREE_CODE (len) != INTEGER_CST)
2209 if (len2 && !TREE_SIDE_EFFECTS (len2))
2214 else if (len2 && TREE_CODE (len2) == INTEGER_CST
2215 && tree_int_cst_lt (len2, len))
2218 /* If both arguments have side effects, we cannot optimize. */
2219 if (TREE_SIDE_EFFECTS (len))
2222 chainon (arglist, build_tree_list (NULL_TREE, len));
2223 result = expand_builtin_memcmp (exp, arglist, target);
2225 TREE_CHAIN (TREE_CHAIN (arglist)) = 0;
2234 /* Expand expression EXP, which is a call to the strncmp builtin. Return 0
2235 if we failed the caller should emit a normal call, otherwise try to get
2236 the result in TARGET, if convenient. */
2238 expand_builtin_strncmp (exp, target, mode)
2241 enum machine_mode mode;
2243 tree arglist = TREE_OPERAND (exp, 1);
2244 tree arg1, arg2, arg3;
2245 const char *p1, *p2;
2247 /* If we need to check memory accesses, call the library function. */
2248 if (current_function_check_memory_usage)
2252 /* Arg could be non-pointer if user redeclared this fcn wrong. */
2253 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE
2254 || TREE_CHAIN (arglist) == 0
2255 || TREE_CODE (TREE_TYPE (TREE_VALUE (TREE_CHAIN (arglist)))) != POINTER_TYPE
2256 || TREE_CHAIN (TREE_CHAIN (arglist)) == 0
2257 || TREE_CODE (TREE_TYPE (TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist))))) != INTEGER_TYPE)
2260 arg1 = TREE_VALUE (arglist);
2261 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
2262 arg3 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2264 /* We must be passed a constant len parameter. */
2265 if (TREE_CODE (arg3) != INTEGER_CST)
2268 /* If the len parameter is zero, return zero. */
2269 if (compare_tree_int (arg3, 0) == 0)
2271 /* Evaluate and ignore arg1 and arg2 in case they have
2273 expand_expr (arg1, const0_rtx, VOIDmode, EXPAND_NORMAL);
2274 expand_expr (arg2, const0_rtx, VOIDmode, EXPAND_NORMAL);
2278 p1 = c_getstr (arg1);
2279 p2 = c_getstr (arg2);
2281 /* If all arguments are constant, evaluate at compile-time. */
2284 const int r = strncmp (p1, p2, TREE_INT_CST_LOW (arg3));
2285 return (r < 0 ? constm1_rtx : (r > 0 ? const1_rtx : const0_rtx));
2288 /* If either string parameter is constant and its strlen is strictly
2289 less than the length parameter, call expand_builtin_strcmp(). */
2290 if ((p1 && compare_tree_int (arg3, strlen (p1)) > 0)
2291 || (p2 && compare_tree_int (arg3, strlen (p2)) > 0))
2294 tree_cons (NULL_TREE, arg1, build_tree_list (NULL_TREE, arg2));
2297 /* Call expand_builtin_strcmp with the modified newarglist. If
2298 the expansion does not occur, do not allow strncmp to expand to
2299 strcmp since strcmp requires that both strings be NULL
2300 terminated whereas strncmp does not. */
2301 TREE_OPERAND (exp, 1) = newarglist;
2302 result = expand_builtin_strcmp (exp, target, mode);
2303 /* Always restore the original arguments. */
2304 TREE_OPERAND (exp, 1) = arglist;
2311 /* Expand a call to __builtin_saveregs, generating the result in TARGET,
2312 if that's convenient. */
2315 expand_builtin_saveregs ()
2319 /* Don't do __builtin_saveregs more than once in a function.
2320 Save the result of the first call and reuse it. */
2321 if (saveregs_value != 0)
2322 return saveregs_value;
2324 /* When this function is called, it means that registers must be
2325 saved on entry to this function. So we migrate the call to the
2326 first insn of this function. */
2330 #ifdef EXPAND_BUILTIN_SAVEREGS
2331 /* Do whatever the machine needs done in this case. */
2332 val = EXPAND_BUILTIN_SAVEREGS ();
2334 /* ??? We used to try and build up a call to the out of line function,
2335 guessing about what registers needed saving etc. This became much
2336 harder with __builtin_va_start, since we don't have a tree for a
2337 call to __builtin_saveregs to fall back on. There was exactly one
2338 port (i860) that used this code, and I'm unconvinced it could actually
2339 handle the general case. So we no longer try to handle anything
2340 weird and make the backend absorb the evil. */
2342 error ("__builtin_saveregs not supported by this target");
2349 saveregs_value = val;
2351 /* Put the sequence after the NOTE that starts the function. If this
2352 is inside a SEQUENCE, make the outer-level insn chain current, so
2353 the code is placed at the start of the function. */
2354 push_topmost_sequence ();
2355 emit_insns_after (seq, get_insns ());
2356 pop_topmost_sequence ();
2361 /* __builtin_args_info (N) returns word N of the arg space info
2362 for the current function. The number and meanings of words
2363 is controlled by the definition of CUMULATIVE_ARGS. */
2366 expand_builtin_args_info (exp)
2369 tree arglist = TREE_OPERAND (exp, 1);
2370 int nwords = sizeof (CUMULATIVE_ARGS) / sizeof (int);
2371 int *word_ptr = (int *) ¤t_function_args_info;
2373 /* These are used by the code below that is if 0'ed away */
2375 tree type, elts, result;
2378 if (sizeof (CUMULATIVE_ARGS) % sizeof (int) != 0)
2383 tree arg = TREE_VALUE (arglist);
2384 if (TREE_CODE (arg) != INTEGER_CST)
2385 error ("argument of `__builtin_args_info' must be constant");
2388 int wordnum = TREE_INT_CST_LOW (arg);
2390 if (wordnum < 0 || wordnum >= nwords || TREE_INT_CST_HIGH (arg))
2391 error ("argument of `__builtin_args_info' out of range");
2393 return GEN_INT (word_ptr[wordnum]);
2397 error ("missing argument in `__builtin_args_info'");
2402 for (i = 0; i < nwords; i++)
2403 elts = tree_cons (NULL_TREE, build_int_2 (word_ptr[i], 0));
2405 type = build_array_type (integer_type_node,
2406 build_index_type (build_int_2 (nwords, 0)));
2407 result = build (CONSTRUCTOR, type, NULL_TREE, nreverse (elts));
2408 TREE_CONSTANT (result) = 1;
2409 TREE_STATIC (result) = 1;
2410 result = build1 (INDIRECT_REF, build_pointer_type (type), result);
2411 TREE_CONSTANT (result) = 1;
2412 return expand_expr (result, NULL_RTX, VOIDmode, EXPAND_MEMORY_USE_BAD);
2416 /* Expand ARGLIST, from a call to __builtin_next_arg. */
2418 expand_builtin_next_arg (arglist)
2421 tree fntype = TREE_TYPE (current_function_decl);
2423 if ((TYPE_ARG_TYPES (fntype) == 0
2424 || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
2426 && ! current_function_varargs)
2428 error ("`va_start' used in function with fixed args");
2434 tree last_parm = tree_last (DECL_ARGUMENTS (current_function_decl));
2435 tree arg = TREE_VALUE (arglist);
2437 /* Strip off all nops for the sake of the comparison. This
2438 is not quite the same as STRIP_NOPS. It does more.
2439 We must also strip off INDIRECT_EXPR for C++ reference
2441 while (TREE_CODE (arg) == NOP_EXPR
2442 || TREE_CODE (arg) == CONVERT_EXPR
2443 || TREE_CODE (arg) == NON_LVALUE_EXPR
2444 || TREE_CODE (arg) == INDIRECT_REF)
2445 arg = TREE_OPERAND (arg, 0);
2446 if (arg != last_parm)
2447 warning ("second parameter of `va_start' not last named argument");
2449 else if (! current_function_varargs)
2450 /* Evidently an out of date version of <stdarg.h>; can't validate
2451 va_start's second argument, but can still work as intended. */
2452 warning ("`__builtin_next_arg' called without an argument");
2454 return expand_binop (Pmode, add_optab,
2455 current_function_internal_arg_pointer,
2456 current_function_arg_offset_rtx,
2457 NULL_RTX, 0, OPTAB_LIB_WIDEN);
2460 /* Make it easier for the backends by protecting the valist argument
2461 from multiple evaluations. */
2464 stabilize_va_list (valist, needs_lvalue)
2468 if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
2470 if (TREE_SIDE_EFFECTS (valist))
2471 valist = save_expr (valist);
2473 /* For this case, the backends will be expecting a pointer to
2474 TREE_TYPE (va_list_type_node), but it's possible we've
2475 actually been given an array (an actual va_list_type_node).
2477 if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
2479 tree p1 = build_pointer_type (TREE_TYPE (va_list_type_node));
2480 tree p2 = build_pointer_type (va_list_type_node);
2482 valist = build1 (ADDR_EXPR, p2, valist);
2483 valist = fold (build1 (NOP_EXPR, p1, valist));
2492 if (! TREE_SIDE_EFFECTS (valist))
2495 pt = build_pointer_type (va_list_type_node);
2496 valist = fold (build1 (ADDR_EXPR, pt, valist));
2497 TREE_SIDE_EFFECTS (valist) = 1;
2500 if (TREE_SIDE_EFFECTS (valist))
2501 valist = save_expr (valist);
2502 valist = fold (build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (valist)),
2509 /* The "standard" implementation of va_start: just assign `nextarg' to
2512 std_expand_builtin_va_start (stdarg_p, valist, nextarg)
2521 int align = PARM_BOUNDARY / BITS_PER_UNIT;
2522 int offset = (((UNITS_PER_WORD + align - 1) / align) * align);
2523 nextarg = plus_constant (nextarg, -offset);
2526 t = build (MODIFY_EXPR, TREE_TYPE (valist), valist,
2527 make_tree (ptr_type_node, nextarg));
2528 TREE_SIDE_EFFECTS (t) = 1;
2530 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
2533 /* Expand ARGLIST, which from a call to __builtin_stdarg_va_start or
2534 __builtin_varargs_va_start, depending on STDARG_P. */
2536 expand_builtin_va_start (stdarg_p, arglist)
2541 tree chain = arglist, valist;
2544 nextarg = expand_builtin_next_arg (chain = TREE_CHAIN (arglist));
2546 nextarg = expand_builtin_next_arg (NULL_TREE);
2548 if (TREE_CHAIN (chain))
2549 error ("too many arguments to function `va_start'");
2551 valist = stabilize_va_list (TREE_VALUE (arglist), 1);
2553 #ifdef EXPAND_BUILTIN_VA_START
2554 EXPAND_BUILTIN_VA_START (stdarg_p, valist, nextarg);
2556 std_expand_builtin_va_start (stdarg_p, valist, nextarg);
2562 /* The "standard" implementation of va_arg: read the value from the
2563 current (padded) address and increment by the (padded) size. */
2566 std_expand_builtin_va_arg (valist, type)
2570 HOST_WIDE_INT align;
2571 HOST_WIDE_INT rounded_size;
2574 /* Compute the rounded size of the type. */
2575 align = PARM_BOUNDARY / BITS_PER_UNIT;
2576 rounded_size = (((int_size_in_bytes (type) + align - 1) / align) * align);
2580 if (PAD_VARARGS_DOWN)
2582 /* Small args are padded downward. */
2585 adj = TREE_INT_CST_LOW (TYPE_SIZE (type)) / BITS_PER_UNIT;
2586 if (rounded_size > align)
2589 addr_tree = build (PLUS_EXPR, TREE_TYPE (addr_tree), addr_tree,
2590 build_int_2 (rounded_size - adj, 0));
2593 addr = expand_expr (addr_tree, NULL_RTX, Pmode, EXPAND_NORMAL);
2594 addr = copy_to_reg (addr);
2596 /* Compute new value for AP. */
2597 t = build (MODIFY_EXPR, TREE_TYPE (valist), valist,
2598 build (PLUS_EXPR, TREE_TYPE (valist), valist,
2599 build_int_2 (rounded_size, 0)));
2600 TREE_SIDE_EFFECTS (t) = 1;
2601 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
2606 /* Expand __builtin_va_arg, which is not really a builtin function, but
2607 a very special sort of operator. */
2610 expand_builtin_va_arg (valist, type)
2614 tree promoted_type, want_va_type, have_va_type;
2616 /* Verify that valist is of the proper type. */
2618 want_va_type = va_list_type_node;
2619 have_va_type = TREE_TYPE (valist);
2620 if (TREE_CODE (want_va_type) == ARRAY_TYPE)
2622 /* If va_list is an array type, the argument may have decayed
2623 to a pointer type, e.g. by being passed to another function.
2624 In that case, unwrap both types so that we can compare the
2625 underlying records. */
2626 if (TREE_CODE (have_va_type) == ARRAY_TYPE
2627 || TREE_CODE (have_va_type) == POINTER_TYPE)
2629 want_va_type = TREE_TYPE (want_va_type);
2630 have_va_type = TREE_TYPE (have_va_type);
2633 if (TYPE_MAIN_VARIANT (want_va_type) != TYPE_MAIN_VARIANT (have_va_type))
2635 error ("first argument to `va_arg' not of type `va_list'");
2639 /* Generate a diagnostic for requesting data of a type that cannot
2640 be passed through `...' due to type promotion at the call site. */
2641 else if ((promoted_type = (*lang_type_promotes_to) (type)) != NULL_TREE)
2643 const char *name = "<anonymous type>", *pname = 0;
2644 static int gave_help;
2646 if (TYPE_NAME (type))
2648 if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE)
2649 name = IDENTIFIER_POINTER (TYPE_NAME (type));
2650 else if (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
2651 && DECL_NAME (TYPE_NAME (type)))
2652 name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type)));
2654 if (TYPE_NAME (promoted_type))
2656 if (TREE_CODE (TYPE_NAME (promoted_type)) == IDENTIFIER_NODE)
2657 pname = IDENTIFIER_POINTER (TYPE_NAME (promoted_type));
2658 else if (TREE_CODE (TYPE_NAME (promoted_type)) == TYPE_DECL
2659 && DECL_NAME (TYPE_NAME (promoted_type)))
2660 pname = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (promoted_type)));
2663 error ("`%s' is promoted to `%s' when passed through `...'", name, pname);
2667 error ("(so you should pass `%s' not `%s' to `va_arg')", pname, name);
2674 /* Make it easier for the backends by protecting the valist argument
2675 from multiple evaluations. */
2676 valist = stabilize_va_list (valist, 0);
2678 #ifdef EXPAND_BUILTIN_VA_ARG
2679 addr = EXPAND_BUILTIN_VA_ARG (valist, type);
2681 addr = std_expand_builtin_va_arg (valist, type);
2685 result = gen_rtx_MEM (TYPE_MODE (type), addr);
2686 MEM_ALIAS_SET (result) = get_varargs_alias_set ();
2691 /* Expand ARGLIST, from a call to __builtin_va_end. */
2694 expand_builtin_va_end (arglist)
2697 tree valist = TREE_VALUE (arglist);
2699 #ifdef EXPAND_BUILTIN_VA_END
2700 valist = stabilize_va_list (valist, 0);
2701 EXPAND_BUILTIN_VA_END(arglist);
2703 /* Evaluate for side effects, if needed. I hate macros that don't
2705 if (TREE_SIDE_EFFECTS (valist))
2706 expand_expr (valist, const0_rtx, VOIDmode, EXPAND_NORMAL);
2712 /* Expand ARGLIST, from a call to __builtin_va_copy. We do this as a
2713 builtin rather than just as an assignment in stdarg.h because of the
2714 nastiness of array-type va_list types. */
2717 expand_builtin_va_copy (arglist)
2722 dst = TREE_VALUE (arglist);
2723 src = TREE_VALUE (TREE_CHAIN (arglist));
2725 dst = stabilize_va_list (dst, 1);
2726 src = stabilize_va_list (src, 0);
2728 if (TREE_CODE (va_list_type_node) != ARRAY_TYPE)
2730 t = build (MODIFY_EXPR, va_list_type_node, dst, src);
2731 TREE_SIDE_EFFECTS (t) = 1;
2732 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
2736 rtx dstb, srcb, size;
2738 /* Evaluate to pointers. */
2739 dstb = expand_expr (dst, NULL_RTX, Pmode, EXPAND_NORMAL);
2740 srcb = expand_expr (src, NULL_RTX, Pmode, EXPAND_NORMAL);
2741 size = expand_expr (TYPE_SIZE_UNIT (va_list_type_node), NULL_RTX,
2742 VOIDmode, EXPAND_NORMAL);
2744 /* "Dereference" to BLKmode memories. */
2745 dstb = gen_rtx_MEM (BLKmode, dstb);
2746 MEM_ALIAS_SET (dstb) = get_alias_set (TREE_TYPE (TREE_TYPE (dst)));
2747 srcb = gen_rtx_MEM (BLKmode, srcb);
2748 MEM_ALIAS_SET (srcb) = get_alias_set (TREE_TYPE (TREE_TYPE (src)));
2751 emit_block_move (dstb, srcb, size, TYPE_ALIGN (va_list_type_node));
2757 /* Expand a call to one of the builtin functions __builtin_frame_address or
2758 __builtin_return_address. */
2760 expand_builtin_frame_address (exp)
2763 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
2764 tree arglist = TREE_OPERAND (exp, 1);
2766 /* The argument must be a nonnegative integer constant.
2767 It counts the number of frames to scan up the stack.
2768 The value is the return address saved in that frame. */
2770 /* Warning about missing arg was already issued. */
2772 else if (TREE_CODE (TREE_VALUE (arglist)) != INTEGER_CST
2773 || tree_int_cst_sgn (TREE_VALUE (arglist)) < 0)
2775 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
2776 error ("invalid arg to `__builtin_frame_address'");
2778 error ("invalid arg to `__builtin_return_address'");
2783 rtx tem = expand_builtin_return_addr (DECL_FUNCTION_CODE (fndecl),
2784 TREE_INT_CST_LOW (TREE_VALUE (arglist)),
2785 hard_frame_pointer_rtx);
2787 /* Some ports cannot access arbitrary stack frames. */
2790 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
2791 warning ("unsupported arg to `__builtin_frame_address'");
2793 warning ("unsupported arg to `__builtin_return_address'");
2797 /* For __builtin_frame_address, return what we've got. */
2798 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
2801 if (GET_CODE (tem) != REG
2802 && ! CONSTANT_P (tem))
2803 tem = copy_to_mode_reg (Pmode, tem);
2808 /* Expand a call to the alloca builtin, with arguments ARGLIST. Return 0 if
2809 we failed and the caller should emit a normal call, otherwise try to get
2810 the result in TARGET, if convenient. */
2812 expand_builtin_alloca (arglist, target)
2819 /* Arg could be non-integer if user redeclared this fcn wrong. */
2820 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE)
2823 /* Compute the argument. */
2824 op0 = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
2826 /* Allocate the desired space. */
2827 return allocate_dynamic_stack_space (op0, target, BITS_PER_UNIT);
2830 /* Expand a call to the ffs builtin. The arguments are in ARGLIST.
2831 Return 0 if a normal call should be emitted rather than expanding the
2832 function in-line. If convenient, the result should be placed in TARGET.
2833 SUBTARGET may be used as the target for computing one of EXP's operands. */
2835 expand_builtin_ffs (arglist, target, subtarget)
2837 rtx target, subtarget;
2841 /* Arg could be non-integer if user redeclared this fcn wrong. */
2842 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE)
2845 /* Compute the argument. */
2846 op0 = expand_expr (TREE_VALUE (arglist), subtarget, VOIDmode, 0);
2847 /* Compute ffs, into TARGET if possible.
2848 Set TARGET to wherever the result comes back. */
2849 target = expand_unop (TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist))),
2850 ffs_optab, op0, target, 1);
2856 /* If the string passed to fputs is a constant and is one character
2857 long, we attempt to transform this call into __builtin_fputc(). */
2859 expand_builtin_fputs (arglist, ignore)
2863 tree call_expr, len, fn, fn_fputc = built_in_decls[BUILT_IN_FPUTC],
2864 fn_fwrite = built_in_decls[BUILT_IN_FWRITE];
2866 /* If the return value is used, or the replacement _DECL isn't
2867 initialized, don't do the transformation. */
2868 if (!ignore || !fn_fputc || !fn_fwrite)
2871 /* Verify the arguments in the original call. */
2873 || (TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE)
2874 || TREE_CHAIN (arglist) == 0
2875 || (TREE_CODE (TREE_TYPE (TREE_VALUE (TREE_CHAIN (arglist))))
2877 || current_function_check_memory_usage)
2880 /* Get the length of the string passed to fputs. If the length
2881 can't be determined, punt. */
2882 if (!(len = c_strlen (TREE_VALUE (arglist)))
2883 || TREE_CODE (len) != INTEGER_CST)
2886 switch (compare_tree_int (len, 1))
2888 case -1: /* length is 0, delete the call entirely . */
2890 /* Evaluate and ignore the argument in case it has
2892 expand_expr (TREE_VALUE (TREE_CHAIN (arglist)), const0_rtx,
2893 VOIDmode, EXPAND_NORMAL);
2896 case 0: /* length is 1, call fputc. */
2898 const char *p = c_getstr (TREE_VALUE (arglist));
2902 /* New argument list transforming fputs(string, stream) to
2903 fputc(string[0], stream). */
2905 build_tree_list (NULL_TREE, TREE_VALUE (TREE_CHAIN (arglist)));
2907 tree_cons (NULL_TREE, build_int_2 (p[0], 0), arglist);
2913 case 1: /* length is greater than 1, call fwrite. */
2915 tree string_arg = TREE_VALUE (arglist);
2917 /* New argument list transforming fputs(string, stream) to
2918 fwrite(string, 1, len, stream). */
2919 arglist = build_tree_list (NULL_TREE, TREE_VALUE (TREE_CHAIN (arglist)));
2920 arglist = tree_cons (NULL_TREE, len, arglist);
2921 arglist = tree_cons (NULL_TREE, integer_one_node, arglist);
2922 arglist = tree_cons (NULL_TREE, string_arg, arglist);
2930 call_expr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
2931 call_expr = build (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)),
2932 call_expr, arglist, NULL_TREE);
2933 TREE_SIDE_EFFECTS (call_expr) = 1;
2934 return expand_expr (call_expr, (ignore ? const0_rtx : NULL_RTX),
2935 VOIDmode, EXPAND_NORMAL);
2938 /* Expand a call to __builtin_expect. We return our argument and
2939 emit a NOTE_INSN_EXPECTED_VALUE note. */
2942 expand_builtin_expect (arglist, target)
2949 if (arglist == NULL_TREE
2950 || TREE_CHAIN (arglist) == NULL_TREE)
2952 exp = TREE_VALUE (arglist);
2953 c = TREE_VALUE (TREE_CHAIN (arglist));
2955 if (TREE_CODE (c) != INTEGER_CST)
2957 error ("second arg to `__builtin_expect' must be a constant");
2958 c = integer_zero_node;
2961 target = expand_expr (exp, target, VOIDmode, EXPAND_NORMAL);
2963 /* Don't bother with expected value notes for integral constants. */
2964 if (GET_CODE (target) != CONST_INT)
2966 /* We do need to force this into a register so that we can be
2967 moderately sure to be able to correctly interpret the branch
2969 target = force_reg (GET_MODE (target), target);
2971 rtx_c = expand_expr (c, NULL_RTX, GET_MODE (target), EXPAND_NORMAL);
2973 note = emit_note (NULL, NOTE_INSN_EXPECTED_VALUE);
2974 NOTE_EXPECTED_VALUE (note) = gen_rtx_EQ (VOIDmode, target, rtx_c);
2980 /* Expand an expression EXP that calls a built-in function,
2981 with result going to TARGET if that's convenient
2982 (and in mode MODE if that's convenient).
2983 SUBTARGET may be used as the target for computing one of EXP's operands.
2984 IGNORE is nonzero if the value is to be ignored. */
2987 expand_builtin (exp, target, subtarget, mode, ignore)
2991 enum machine_mode mode;
2994 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
2995 tree arglist = TREE_OPERAND (exp, 1);
2996 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
2998 #ifdef MD_EXPAND_BUILTIN
2999 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
3000 return MD_EXPAND_BUILTIN (exp, target, subtarget, mode, ignore);
3003 /* When not optimizing, generate calls to library functions for a certain
3005 if (! optimize && ! CALLED_AS_BUILT_IN (fndecl)
3006 && (fcode == BUILT_IN_SIN || fcode == BUILT_IN_COS
3007 || fcode == BUILT_IN_FSQRT || fcode == BUILT_IN_MEMSET
3008 || fcode == BUILT_IN_MEMCPY || fcode == BUILT_IN_MEMCMP
3009 || fcode == BUILT_IN_BCMP || fcode == BUILT_IN_BZERO
3010 || fcode == BUILT_IN_INDEX || fcode == BUILT_IN_RINDEX
3011 || fcode == BUILT_IN_STRCHR || fcode == BUILT_IN_STRRCHR
3012 || fcode == BUILT_IN_STRLEN || fcode == BUILT_IN_STRCPY
3013 || fcode == BUILT_IN_STRNCPY || fcode == BUILT_IN_STRNCMP
3014 || fcode == BUILT_IN_STRSTR || fcode == BUILT_IN_STRPBRK
3015 || fcode == BUILT_IN_STRCMP || fcode == BUILT_IN_FFS
3016 || fcode == BUILT_IN_PUTCHAR || fcode == BUILT_IN_PUTS
3017 || fcode == BUILT_IN_PRINTF || fcode == BUILT_IN_FPUTC
3018 || fcode == BUILT_IN_FPUTS || fcode == BUILT_IN_FWRITE))
3019 return expand_call (exp, target, ignore);
3025 case BUILT_IN_LLABS:
3027 /* build_function_call changes these into ABS_EXPR. */
3032 /* Treat these like sqrt, but only if the user asks for them. */
3033 if (! flag_fast_math)
3035 case BUILT_IN_FSQRT:
3036 target = expand_builtin_mathfn (exp, target, subtarget);
3044 case BUILT_IN_APPLY_ARGS:
3045 return expand_builtin_apply_args ();
3047 /* __builtin_apply (FUNCTION, ARGUMENTS, ARGSIZE) invokes
3048 FUNCTION with a copy of the parameters described by
3049 ARGUMENTS, and ARGSIZE. It returns a block of memory
3050 allocated on the stack into which is stored all the registers
3051 that might possibly be used for returning the result of a
3052 function. ARGUMENTS is the value returned by
3053 __builtin_apply_args. ARGSIZE is the number of bytes of
3054 arguments that must be copied. ??? How should this value be
3055 computed? We'll also need a safe worst case value for varargs
3057 case BUILT_IN_APPLY:
3059 /* Arg could be non-pointer if user redeclared this fcn wrong. */
3060 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
3061 || TREE_CHAIN (arglist) == 0
3062 || TREE_CODE (TREE_TYPE (TREE_VALUE (TREE_CHAIN (arglist)))) != POINTER_TYPE
3063 || TREE_CHAIN (TREE_CHAIN (arglist)) == 0
3064 || TREE_CODE (TREE_TYPE (TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist))))) != INTEGER_TYPE)
3072 for (t = arglist, i = 0; t; t = TREE_CHAIN (t), i++)
3073 ops[i] = expand_expr (TREE_VALUE (t), NULL_RTX, VOIDmode, 0);
3075 return expand_builtin_apply (ops[0], ops[1], ops[2]);
3078 /* __builtin_return (RESULT) causes the function to return the
3079 value described by RESULT. RESULT is address of the block of
3080 memory returned by __builtin_apply. */
3081 case BUILT_IN_RETURN:
3083 /* Arg could be non-pointer if user redeclared this fcn wrong. */
3084 && TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) == POINTER_TYPE)
3085 expand_builtin_return (expand_expr (TREE_VALUE (arglist),
3086 NULL_RTX, VOIDmode, 0));
3089 case BUILT_IN_SAVEREGS:
3090 return expand_builtin_saveregs ();
3092 case BUILT_IN_ARGS_INFO:
3093 return expand_builtin_args_info (exp);
3095 /* Return the address of the first anonymous stack arg. */
3096 case BUILT_IN_NEXT_ARG:
3097 return expand_builtin_next_arg (arglist);
3099 case BUILT_IN_CLASSIFY_TYPE:
3100 return expand_builtin_classify_type (arglist);
3102 case BUILT_IN_CONSTANT_P:
3103 return expand_builtin_constant_p (exp);
3105 case BUILT_IN_FRAME_ADDRESS:
3106 case BUILT_IN_RETURN_ADDRESS:
3107 return expand_builtin_frame_address (exp);
3109 /* Returns the address of the area where the structure is returned.
3111 case BUILT_IN_AGGREGATE_INCOMING_ADDRESS:
3113 || ! AGGREGATE_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl)))
3114 || GET_CODE (DECL_RTL (DECL_RESULT (current_function_decl))) != MEM)
3117 return XEXP (DECL_RTL (DECL_RESULT (current_function_decl)), 0);
3119 case BUILT_IN_ALLOCA:
3120 target = expand_builtin_alloca (arglist, target);
3126 target = expand_builtin_ffs (arglist, target, subtarget);
3131 case BUILT_IN_STRLEN:
3132 target = expand_builtin_strlen (exp, target);
3137 case BUILT_IN_STRCPY:
3138 target = expand_builtin_strcpy (exp);
3143 case BUILT_IN_STRNCPY:
3144 target = expand_builtin_strncpy (arglist, target, mode);
3149 case BUILT_IN_STRSTR:
3150 target = expand_builtin_strstr (arglist, target, mode);
3155 case BUILT_IN_STRPBRK:
3156 target = expand_builtin_strpbrk (arglist, target, mode);
3161 case BUILT_IN_INDEX:
3162 case BUILT_IN_STRCHR:
3163 target = expand_builtin_strchr (arglist, target, mode);
3168 case BUILT_IN_RINDEX:
3169 case BUILT_IN_STRRCHR:
3170 target = expand_builtin_strrchr (arglist, target, mode);
3175 case BUILT_IN_MEMCPY:
3176 target = expand_builtin_memcpy (arglist);
3181 case BUILT_IN_MEMSET:
3182 target = expand_builtin_memset (exp);
3187 case BUILT_IN_BZERO:
3188 target = expand_builtin_bzero (exp);
3193 case BUILT_IN_STRCMP:
3194 target = expand_builtin_strcmp (exp, target, mode);
3199 case BUILT_IN_STRNCMP:
3200 target = expand_builtin_strncmp (exp, target, mode);
3205 /* These comparison functions need an instruction that returns an actual
3206 index. An ordinary compare that just sets the condition codes
3208 #ifdef HAVE_cmpstrsi
3210 case BUILT_IN_MEMCMP:
3211 target = expand_builtin_memcmp (exp, arglist, target);
3217 case BUILT_IN_MEMCMP:
3221 case BUILT_IN_SETJMP:
3223 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE)
3227 rtx buf_addr = expand_expr (TREE_VALUE (arglist), subtarget,
3229 rtx lab = gen_label_rtx ();
3230 rtx ret = expand_builtin_setjmp (buf_addr, target, lab, lab);
3235 /* __builtin_longjmp is passed a pointer to an array of five words.
3236 It's similar to the C library longjmp function but works with
3237 __builtin_setjmp above. */
3238 case BUILT_IN_LONGJMP:
3239 if (arglist == 0 || TREE_CHAIN (arglist) == 0
3240 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE)
3244 rtx buf_addr = expand_expr (TREE_VALUE (arglist), subtarget,
3246 rtx value = expand_expr (TREE_VALUE (TREE_CHAIN (arglist)),
3247 NULL_RTX, VOIDmode, 0);
3249 if (value != const1_rtx)
3251 error ("__builtin_longjmp second argument must be 1");
3255 expand_builtin_longjmp (buf_addr, value);
3262 emit_insn (gen_trap ());
3265 error ("__builtin_trap not supported by this target");
3269 case BUILT_IN_PUTCHAR:
3271 case BUILT_IN_FPUTC:
3272 case BUILT_IN_FWRITE:
3274 case BUILT_IN_FPUTS:
3275 target = expand_builtin_fputs (arglist, ignore);
3280 /* Various hooks for the DWARF 2 __throw routine. */
3281 case BUILT_IN_UNWIND_INIT:
3282 expand_builtin_unwind_init ();
3284 case BUILT_IN_DWARF_CFA:
3285 return virtual_cfa_rtx;
3286 #ifdef DWARF2_UNWIND_INFO
3287 case BUILT_IN_DWARF_FP_REGNUM:
3288 return expand_builtin_dwarf_fp_regnum ();
3289 case BUILT_IN_INIT_DWARF_REG_SIZES:
3290 expand_builtin_init_dwarf_reg_sizes (TREE_VALUE (arglist));
3293 case BUILT_IN_FROB_RETURN_ADDR:
3294 return expand_builtin_frob_return_addr (TREE_VALUE (arglist));
3295 case BUILT_IN_EXTRACT_RETURN_ADDR:
3296 return expand_builtin_extract_return_addr (TREE_VALUE (arglist));
3297 case BUILT_IN_EH_RETURN:
3298 expand_builtin_eh_return (TREE_VALUE (arglist),
3299 TREE_VALUE (TREE_CHAIN (arglist)),
3300 TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist))));
3302 case BUILT_IN_VARARGS_START:
3303 return expand_builtin_va_start (0, arglist);
3304 case BUILT_IN_STDARG_START:
3305 return expand_builtin_va_start (1, arglist);
3306 case BUILT_IN_VA_END:
3307 return expand_builtin_va_end (arglist);
3308 case BUILT_IN_VA_COPY:
3309 return expand_builtin_va_copy (arglist);
3310 case BUILT_IN_EXPECT:
3311 return expand_builtin_expect (arglist, target);
3313 default: /* just do library call, if unknown builtin */
3314 error ("built-in function `%s' not currently supported",
3315 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
3318 /* The switch statement above can drop through to cause the function
3319 to be called normally. */
3320 return expand_call (exp, target, ignore);
3323 /* Fold a call to __builtin_constant_p, if we know it will evaluate to a
3324 constant. ARGLIST is the argument list of the call. */
3327 fold_builtin_constant_p (arglist)
3333 arglist = TREE_VALUE (arglist);
3335 /* We return 1 for a numeric type that's known to be a constant
3336 value at compile-time or for an aggregate type that's a
3337 literal constant. */
3338 STRIP_NOPS (arglist);
3340 /* If we know this is a constant, emit the constant of one. */
3341 if (TREE_CODE_CLASS (TREE_CODE (arglist)) == 'c'
3342 || (TREE_CODE (arglist) == CONSTRUCTOR
3343 && TREE_CONSTANT (arglist))
3344 || (TREE_CODE (arglist) == ADDR_EXPR
3345 && TREE_CODE (TREE_OPERAND (arglist, 0)) == STRING_CST))
3346 return integer_one_node;
3348 /* If we aren't going to be running CSE or this expression
3349 has side effects, show we don't know it to be a constant.
3350 Likewise if it's a pointer or aggregate type since in those
3351 case we only want literals, since those are only optimized
3352 when generating RTL, not later. */
3353 if (TREE_SIDE_EFFECTS (arglist) || cse_not_expected
3354 || AGGREGATE_TYPE_P (TREE_TYPE (arglist))
3355 || POINTER_TYPE_P (TREE_TYPE (arglist)))
3356 return integer_zero_node;
3361 /* Used by constant folding to eliminate some builtin calls early. EXP is
3362 the CALL_EXPR of a call to a builtin function. */
3368 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
3369 tree arglist = TREE_OPERAND (exp, 1);
3370 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
3372 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
3377 case BUILT_IN_CONSTANT_P:
3378 return fold_builtin_constant_p (arglist);
3380 case BUILT_IN_STRLEN:
3382 /* Arg could be non-pointer if user redeclared this fcn wrong. */
3383 && TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) == POINTER_TYPE)
3385 tree len = c_strlen (TREE_VALUE (arglist));