1 /* Expand builtin functions.
2 Copyright (C) 1988, 92-98, 1999 Free Software Foundation, Inc.
4 This file is part of GNU CC.
6 GNU CC is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 GNU CC is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU CC; see the file COPYING. If not, write to
18 the Free Software Foundation, 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
29 #include "hard-reg-set.h"
32 #include "insn-flags.h"
33 #include "insn-codes.h"
34 #include "insn-config.h"
38 #include "typeclass.h"
42 #define CALLED_AS_BUILT_IN(NODE) \
43 (!strncmp (IDENTIFIER_POINTER (DECL_NAME (NODE)), "__builtin_", 10))
45 #define CEIL(x,y) (((x) + (y) - 1) / (y))
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 static int get_pointer_alignment PROTO((tree, unsigned));
56 static tree c_strlen PROTO((tree));
57 static rtx get_memory_rtx PROTO((tree));
58 static int apply_args_size PROTO((void));
59 static int apply_result_size PROTO((void));
60 static rtx result_vector PROTO((int, rtx));
61 static rtx expand_builtin_apply_args PROTO((void));
62 static rtx expand_builtin_apply_args_1 PROTO((void));
63 static rtx expand_builtin_apply PROTO((rtx, rtx, rtx));
64 static void expand_builtin_return PROTO((rtx));
65 static rtx expand_builtin_classify_type PROTO((tree));
66 static rtx expand_builtin_mathfn PROTO((tree, rtx, rtx));
67 static rtx expand_builtin_constant_p PROTO((tree));
68 static rtx expand_builtin_args_info PROTO((tree));
69 static rtx expand_builtin_next_arg PROTO((tree));
70 static rtx expand_builtin_va_start PROTO((int, tree));
71 static rtx expand_builtin_va_end PROTO((tree));
72 static rtx expand_builtin_va_copy PROTO((tree));
74 static rtx expand_builtin_memcmp PROTO((tree, tree, rtx));
75 static rtx expand_builtin_strcmp PROTO((tree, rtx));
77 static rtx expand_builtin_memcpy PROTO((tree));
78 static rtx expand_builtin_strcpy PROTO((tree));
79 static rtx expand_builtin_memset PROTO((tree));
80 static rtx expand_builtin_strlen PROTO((tree, rtx, enum machine_mode));
81 static rtx expand_builtin_alloca PROTO((tree, rtx));
82 static rtx expand_builtin_ffs PROTO((tree, rtx, rtx));
83 static rtx expand_builtin_frame_address PROTO((tree));
85 /* Return the alignment in bits of EXP, a pointer valued expression.
86 But don't return more than MAX_ALIGN no matter what.
87 The alignment returned is, by default, the alignment of the thing that
88 EXP points to (if it is not a POINTER_TYPE, 0 is returned).
90 Otherwise, look at the expression to see if we can do better, i.e., if the
91 expression is actually pointing at an object whose alignment is tighter. */
94 get_pointer_alignment (exp, max_align)
98 unsigned align, inner;
100 if (TREE_CODE (TREE_TYPE (exp)) != POINTER_TYPE)
103 align = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
104 align = MIN (align, max_align);
108 switch (TREE_CODE (exp))
112 case NON_LVALUE_EXPR:
113 exp = TREE_OPERAND (exp, 0);
114 if (TREE_CODE (TREE_TYPE (exp)) != POINTER_TYPE)
116 inner = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
117 align = MIN (inner, max_align);
121 /* If sum of pointer + int, restrict our maximum alignment to that
122 imposed by the integer. If not, we can't do any better than
124 if (TREE_CODE (TREE_OPERAND (exp, 1)) != INTEGER_CST)
127 while (((TREE_INT_CST_LOW (TREE_OPERAND (exp, 1)) * BITS_PER_UNIT)
132 exp = TREE_OPERAND (exp, 0);
136 /* See what we are pointing at and look at its alignment. */
137 exp = TREE_OPERAND (exp, 0);
138 if (TREE_CODE (exp) == FUNCTION_DECL)
139 align = FUNCTION_BOUNDARY;
140 else if (TREE_CODE_CLASS (TREE_CODE (exp)) == 'd')
141 align = DECL_ALIGN (exp);
142 #ifdef CONSTANT_ALIGNMENT
143 else if (TREE_CODE_CLASS (TREE_CODE (exp)) == 'c')
144 align = CONSTANT_ALIGNMENT (exp, align);
146 return MIN (align, max_align);
154 /* Compute the length of a C string. TREE_STRING_LENGTH is not the right
155 way, because it could contain a zero byte in the middle.
156 TREE_STRING_LENGTH is the size of the character array, not the string.
158 Unfortunately, string_constant can't access the values of const char
159 arrays with initializers, so neither can we do so here. */
169 src = string_constant (src, &offset_node);
172 max = TREE_STRING_LENGTH (src);
173 ptr = TREE_STRING_POINTER (src);
174 if (offset_node && TREE_CODE (offset_node) != INTEGER_CST)
176 /* If the string has an internal zero byte (e.g., "foo\0bar"), we can't
177 compute the offset to the following null if we don't know where to
178 start searching for it. */
180 for (i = 0; i < max; i++)
183 /* We don't know the starting offset, but we do know that the string
184 has no internal zero bytes. We can assume that the offset falls
185 within the bounds of the string; otherwise, the programmer deserves
186 what he gets. Subtract the offset from the length of the string,
188 /* This would perhaps not be valid if we were dealing with named
189 arrays in addition to literal string constants. */
190 return size_binop (MINUS_EXPR, size_int (max), offset_node);
193 /* We have a known offset into the string. Start searching there for
195 if (offset_node == 0)
199 /* Did we get a long long offset? If so, punt. */
200 if (TREE_INT_CST_HIGH (offset_node) != 0)
202 offset = TREE_INT_CST_LOW (offset_node);
204 /* If the offset is known to be out of bounds, warn, and call strlen at
206 if (offset < 0 || offset > max)
208 warning ("offset outside bounds of constant string");
211 /* Use strlen to search for the first zero byte. Since any strings
212 constructed with build_string will have nulls appended, we win even
213 if we get handed something like (char[4])"abcd".
215 Since OFFSET is our starting index into the string, no further
216 calculation is needed. */
217 return size_int (strlen (ptr + offset));
220 /* Given TEM, a pointer to a stack frame, follow the dynamic chain COUNT
221 times to get the address of either a higher stack frame, or a return
222 address located within it (depending on FNDECL_CODE). */
224 expand_builtin_return_addr (fndecl_code, count, tem)
225 enum built_in_function fndecl_code;
231 /* Some machines need special handling before we can access
232 arbitrary frames. For example, on the sparc, we must first flush
233 all register windows to the stack. */
234 #ifdef SETUP_FRAME_ADDRESSES
236 SETUP_FRAME_ADDRESSES ();
239 /* On the sparc, the return address is not in the frame, it is in a
240 register. There is no way to access it off of the current frame
241 pointer, but it can be accessed off the previous frame pointer by
242 reading the value from the register window save area. */
243 #ifdef RETURN_ADDR_IN_PREVIOUS_FRAME
244 if (fndecl_code == BUILT_IN_RETURN_ADDRESS)
248 /* Scan back COUNT frames to the specified frame. */
249 for (i = 0; i < count; i++)
251 /* Assume the dynamic chain pointer is in the word that the
252 frame address points to, unless otherwise specified. */
253 #ifdef DYNAMIC_CHAIN_ADDRESS
254 tem = DYNAMIC_CHAIN_ADDRESS (tem);
256 tem = memory_address (Pmode, tem);
257 tem = copy_to_reg (gen_rtx_MEM (Pmode, tem));
260 /* For __builtin_frame_address, return what we've got. */
261 if (fndecl_code == BUILT_IN_FRAME_ADDRESS)
264 /* For __builtin_return_address, Get the return address from that
266 #ifdef RETURN_ADDR_RTX
267 tem = RETURN_ADDR_RTX (count, tem);
269 tem = memory_address (Pmode,
270 plus_constant (tem, GET_MODE_SIZE (Pmode)));
271 tem = gen_rtx_MEM (Pmode, tem);
276 /* __builtin_setjmp is passed a pointer to an array of five words (not
277 all will be used on all machines). It operates similarly to the C
278 library function of the same name, but is more efficient. Much of
279 the code below (and for longjmp) is copied from the handling of
282 NOTE: This is intended for use by GNAT and the exception handling
283 scheme in the compiler and will only work in the method used by
287 expand_builtin_setjmp (buf_addr, target, first_label, next_label)
290 rtx first_label, next_label;
292 rtx lab1 = gen_label_rtx ();
293 enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
294 enum machine_mode value_mode;
297 value_mode = TYPE_MODE (integer_type_node);
299 #ifdef POINTERS_EXTEND_UNSIGNED
300 buf_addr = convert_memory_address (Pmode, buf_addr);
303 buf_addr = force_reg (Pmode, force_operand (buf_addr, NULL_RTX));
305 if (target == 0 || GET_CODE (target) != REG
306 || REGNO (target) < FIRST_PSEUDO_REGISTER)
307 target = gen_reg_rtx (value_mode);
311 /* We store the frame pointer and the address of lab1 in the buffer
312 and use the rest of it for the stack save area, which is
313 machine-dependent. */
315 #ifndef BUILTIN_SETJMP_FRAME_VALUE
316 #define BUILTIN_SETJMP_FRAME_VALUE virtual_stack_vars_rtx
319 emit_move_insn (gen_rtx_MEM (Pmode, buf_addr),
320 BUILTIN_SETJMP_FRAME_VALUE);
321 emit_move_insn (validize_mem
323 plus_constant (buf_addr,
324 GET_MODE_SIZE (Pmode)))),
325 force_reg (Pmode, gen_rtx_LABEL_REF (Pmode, lab1)));
327 stack_save = gen_rtx_MEM (sa_mode,
328 plus_constant (buf_addr,
329 2 * GET_MODE_SIZE (Pmode)));
330 emit_stack_save (SAVE_NONLOCAL, &stack_save, NULL_RTX);
332 /* If there is further processing to do, do it. */
333 #ifdef HAVE_builtin_setjmp_setup
334 if (HAVE_builtin_setjmp_setup)
335 emit_insn (gen_builtin_setjmp_setup (buf_addr));
338 /* Set TARGET to zero and branch to the first-time-through label. */
339 emit_move_insn (target, const0_rtx);
340 emit_jump_insn (gen_jump (first_label));
344 /* Tell flow about the strange goings on. Putting `lab1' on
345 `nonlocal_goto_handler_labels' to indicates that function
346 calls may traverse the arc back to this label. */
348 current_function_has_nonlocal_label = 1;
349 nonlocal_goto_handler_labels =
350 gen_rtx_EXPR_LIST (VOIDmode, lab1, nonlocal_goto_handler_labels);
352 /* Clobber the FP when we get here, so we have to make sure it's
353 marked as used by this function. */
354 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
356 /* Mark the static chain as clobbered here so life information
357 doesn't get messed up for it. */
358 emit_insn (gen_rtx_CLOBBER (VOIDmode, static_chain_rtx));
360 /* Now put in the code to restore the frame pointer, and argument
361 pointer, if needed. The code below is from expand_end_bindings
362 in stmt.c; see detailed documentation there. */
363 #ifdef HAVE_nonlocal_goto
364 if (! HAVE_nonlocal_goto)
366 emit_move_insn (virtual_stack_vars_rtx, hard_frame_pointer_rtx);
368 #if ARG_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
369 if (fixed_regs[ARG_POINTER_REGNUM])
371 #ifdef ELIMINABLE_REGS
373 static struct elims {int from, to;} elim_regs[] = ELIMINABLE_REGS;
375 for (i = 0; i < sizeof elim_regs / sizeof elim_regs[0]; i++)
376 if (elim_regs[i].from == ARG_POINTER_REGNUM
377 && elim_regs[i].to == HARD_FRAME_POINTER_REGNUM)
380 if (i == sizeof elim_regs / sizeof elim_regs [0])
383 /* Now restore our arg pointer from the address at which it
384 was saved in our stack frame.
385 If there hasn't be space allocated for it yet, make
387 if (arg_pointer_save_area == 0)
388 arg_pointer_save_area
389 = assign_stack_local (Pmode, GET_MODE_SIZE (Pmode), 0);
390 emit_move_insn (virtual_incoming_args_rtx,
391 copy_to_reg (arg_pointer_save_area));
396 #ifdef HAVE_builtin_setjmp_receiver
397 if (HAVE_builtin_setjmp_receiver)
398 emit_insn (gen_builtin_setjmp_receiver (lab1));
401 #ifdef HAVE_nonlocal_goto_receiver
402 if (HAVE_nonlocal_goto_receiver)
403 emit_insn (gen_nonlocal_goto_receiver ());
410 /* Set TARGET, and branch to the next-time-through label. */
411 emit_move_insn (target, const1_rtx);
412 emit_jump_insn (gen_jump (next_label));
418 /* __builtin_longjmp is passed a pointer to an array of five words (not
419 all will be used on all machines). It operates similarly to the C
420 library function of the same name, but is more efficient. Much of
421 the code below is copied from the handling of non-local gotos.
423 NOTE: This is intended for use by GNAT and the exception handling
424 scheme in the compiler and will only work in the method used by
428 expand_builtin_longjmp (buf_addr, value)
432 enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
434 #ifdef POINTERS_EXTEND_UNSIGNED
435 buf_addr = convert_memory_address (Pmode, buf_addr);
437 buf_addr = force_reg (Pmode, buf_addr);
439 /* We used to store value in static_chain_rtx, but that fails if pointers
440 are smaller than integers. We instead require that the user must pass
441 a second argument of 1, because that is what builtin_setjmp will
442 return. This also makes EH slightly more efficient, since we are no
443 longer copying around a value that we don't care about. */
444 if (value != const1_rtx)
447 #ifdef HAVE_builtin_longjmp
448 if (HAVE_builtin_longjmp)
449 emit_insn (gen_builtin_longjmp (buf_addr));
453 fp = gen_rtx_MEM (Pmode, buf_addr);
454 lab = gen_rtx_MEM (Pmode, plus_constant (buf_addr,
455 GET_MODE_SIZE (Pmode)));
457 stack = gen_rtx_MEM (sa_mode, plus_constant (buf_addr,
458 2 * GET_MODE_SIZE (Pmode)));
460 /* Pick up FP, label, and SP from the block and jump. This code is
461 from expand_goto in stmt.c; see there for detailed comments. */
462 #if HAVE_nonlocal_goto
463 if (HAVE_nonlocal_goto)
464 /* We have to pass a value to the nonlocal_goto pattern that will
465 get copied into the static_chain pointer, but it does not matter
466 what that value is, because builtin_setjmp does not use it. */
467 emit_insn (gen_nonlocal_goto (value, fp, stack, lab));
471 lab = copy_to_reg (lab);
473 emit_move_insn (hard_frame_pointer_rtx, fp);
474 emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
476 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
477 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
478 emit_indirect_jump (lab);
483 /* Get a MEM rtx for expression EXP which can be used in a string instruction
484 (cmpstrsi, movstrsi, ..). */
492 mem = gen_rtx_MEM (BLKmode,
493 memory_address (BLKmode,
494 expand_expr (exp, NULL_RTX,
495 ptr_mode, EXPAND_SUM)));
497 RTX_UNCHANGING_P (mem) = TREE_READONLY (exp);
499 /* Figure out the type of the object pointed to. Set MEM_IN_STRUCT_P
500 if the value is the address of a structure or if the expression is
501 cast to a pointer to structure type. */
504 while (TREE_CODE (exp) == NOP_EXPR)
506 tree cast_type = TREE_TYPE (exp);
507 if (TREE_CODE (cast_type) == POINTER_TYPE
508 && AGGREGATE_TYPE_P (TREE_TYPE (cast_type)))
513 exp = TREE_OPERAND (exp, 0);
516 if (is_aggregate == 0)
520 if (TREE_CODE (exp) == ADDR_EXPR)
521 /* If this is the address of an object, check whether the
522 object is an array. */
523 type = TREE_TYPE (TREE_OPERAND (exp, 0));
525 type = TREE_TYPE (TREE_TYPE (exp));
526 is_aggregate = AGGREGATE_TYPE_P (type);
529 MEM_SET_IN_STRUCT_P (mem, is_aggregate);
533 /* Built-in functions to perform an untyped call and return. */
535 /* For each register that may be used for calling a function, this
536 gives a mode used to copy the register's value. VOIDmode indicates
537 the register is not used for calling a function. If the machine
538 has register windows, this gives only the outbound registers.
539 INCOMING_REGNO gives the corresponding inbound register. */
540 static enum machine_mode apply_args_mode[FIRST_PSEUDO_REGISTER];
542 /* For each register that may be used for returning values, this gives
543 a mode used to copy the register's value. VOIDmode indicates the
544 register is not used for returning values. If the machine has
545 register windows, this gives only the outbound registers.
546 INCOMING_REGNO gives the corresponding inbound register. */
547 static enum machine_mode apply_result_mode[FIRST_PSEUDO_REGISTER];
549 /* For each register that may be used for calling a function, this
550 gives the offset of that register into the block returned by
551 __builtin_apply_args. 0 indicates that the register is not
552 used for calling a function. */
553 static int apply_args_reg_offset[FIRST_PSEUDO_REGISTER];
555 /* Return the offset of register REGNO into the block returned by
556 __builtin_apply_args. This is not declared static, since it is
557 needed in objc-act.c. */
560 apply_args_register_offset (regno)
565 /* Arguments are always put in outgoing registers (in the argument
566 block) if such make sense. */
567 #ifdef OUTGOING_REGNO
568 regno = OUTGOING_REGNO(regno);
570 return apply_args_reg_offset[regno];
573 /* Return the size required for the block returned by __builtin_apply_args,
574 and initialize apply_args_mode. */
579 static int size = -1;
581 enum machine_mode mode;
583 /* The values computed by this function never change. */
586 /* The first value is the incoming arg-pointer. */
587 size = GET_MODE_SIZE (Pmode);
589 /* The second value is the structure value address unless this is
590 passed as an "invisible" first argument. */
591 if (struct_value_rtx)
592 size += GET_MODE_SIZE (Pmode);
594 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
595 if (FUNCTION_ARG_REGNO_P (regno))
597 /* Search for the proper mode for copying this register's
598 value. I'm not sure this is right, but it works so far. */
599 enum machine_mode best_mode = VOIDmode;
601 for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT);
603 mode = GET_MODE_WIDER_MODE (mode))
604 if (HARD_REGNO_MODE_OK (regno, mode)
605 && HARD_REGNO_NREGS (regno, mode) == 1)
608 if (best_mode == VOIDmode)
609 for (mode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT);
611 mode = GET_MODE_WIDER_MODE (mode))
612 if (HARD_REGNO_MODE_OK (regno, mode)
613 && (mov_optab->handlers[(int) mode].insn_code
614 != CODE_FOR_nothing))
618 if (mode == VOIDmode)
621 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
622 if (size % align != 0)
623 size = CEIL (size, align) * align;
624 apply_args_reg_offset[regno] = size;
625 size += GET_MODE_SIZE (mode);
626 apply_args_mode[regno] = mode;
630 apply_args_mode[regno] = VOIDmode;
631 apply_args_reg_offset[regno] = 0;
637 /* Return the size required for the block returned by __builtin_apply,
638 and initialize apply_result_mode. */
643 static int size = -1;
645 enum machine_mode mode;
647 /* The values computed by this function never change. */
652 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
653 if (FUNCTION_VALUE_REGNO_P (regno))
655 /* Search for the proper mode for copying this register's
656 value. I'm not sure this is right, but it works so far. */
657 enum machine_mode best_mode = VOIDmode;
659 for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT);
661 mode = GET_MODE_WIDER_MODE (mode))
662 if (HARD_REGNO_MODE_OK (regno, mode))
665 if (best_mode == VOIDmode)
666 for (mode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT);
668 mode = GET_MODE_WIDER_MODE (mode))
669 if (HARD_REGNO_MODE_OK (regno, mode)
670 && (mov_optab->handlers[(int) mode].insn_code
671 != CODE_FOR_nothing))
675 if (mode == VOIDmode)
678 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
679 if (size % align != 0)
680 size = CEIL (size, align) * align;
681 size += GET_MODE_SIZE (mode);
682 apply_result_mode[regno] = mode;
685 apply_result_mode[regno] = VOIDmode;
687 /* Allow targets that use untyped_call and untyped_return to override
688 the size so that machine-specific information can be stored here. */
689 #ifdef APPLY_RESULT_SIZE
690 size = APPLY_RESULT_SIZE;
696 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
697 /* Create a vector describing the result block RESULT. If SAVEP is true,
698 the result block is used to save the values; otherwise it is used to
699 restore the values. */
702 result_vector (savep, result)
706 int regno, size, align, nelts;
707 enum machine_mode mode;
709 rtx *savevec = (rtx *) alloca (FIRST_PSEUDO_REGISTER * sizeof (rtx));
712 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
713 if ((mode = apply_result_mode[regno]) != VOIDmode)
715 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
716 if (size % align != 0)
717 size = CEIL (size, align) * align;
718 reg = gen_rtx_REG (mode, savep ? regno : INCOMING_REGNO (regno));
719 mem = change_address (result, mode,
720 plus_constant (XEXP (result, 0), size));
721 savevec[nelts++] = (savep
722 ? gen_rtx_SET (VOIDmode, mem, reg)
723 : gen_rtx_SET (VOIDmode, reg, mem));
724 size += GET_MODE_SIZE (mode);
726 return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (nelts, savevec));
728 #endif /* HAVE_untyped_call or HAVE_untyped_return */
730 /* Save the state required to perform an untyped call with the same
731 arguments as were passed to the current function. */
734 expand_builtin_apply_args_1 ()
737 int size, align, regno;
738 enum machine_mode mode;
740 /* Create a block where the arg-pointer, structure value address,
741 and argument registers can be saved. */
742 registers = assign_stack_local (BLKmode, apply_args_size (), -1);
744 /* Walk past the arg-pointer and structure value address. */
745 size = GET_MODE_SIZE (Pmode);
746 if (struct_value_rtx)
747 size += GET_MODE_SIZE (Pmode);
749 /* Save each register used in calling a function to the block. */
750 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
751 if ((mode = apply_args_mode[regno]) != VOIDmode)
755 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
756 if (size % align != 0)
757 size = CEIL (size, align) * align;
759 tem = gen_rtx_REG (mode, INCOMING_REGNO (regno));
762 /* For reg-stack.c's stack register household.
763 Compare with a similar piece of code in function.c. */
765 emit_insn (gen_rtx_USE (mode, tem));
768 emit_move_insn (change_address (registers, mode,
769 plus_constant (XEXP (registers, 0),
772 size += GET_MODE_SIZE (mode);
775 /* Save the arg pointer to the block. */
776 emit_move_insn (change_address (registers, Pmode, XEXP (registers, 0)),
777 copy_to_reg (virtual_incoming_args_rtx));
778 size = GET_MODE_SIZE (Pmode);
780 /* Save the structure value address unless this is passed as an
781 "invisible" first argument. */
782 if (struct_value_incoming_rtx)
784 emit_move_insn (change_address (registers, Pmode,
785 plus_constant (XEXP (registers, 0),
787 copy_to_reg (struct_value_incoming_rtx));
788 size += GET_MODE_SIZE (Pmode);
791 /* Return the address of the block. */
792 return copy_addr_to_reg (XEXP (registers, 0));
795 /* __builtin_apply_args returns block of memory allocated on
796 the stack into which is stored the arg pointer, structure
797 value address, static chain, and all the registers that might
798 possibly be used in performing a function call. The code is
799 moved to the start of the function so the incoming values are
802 expand_builtin_apply_args ()
804 /* Don't do __builtin_apply_args more than once in a function.
805 Save the result of the first call and reuse it. */
806 if (apply_args_value != 0)
807 return apply_args_value;
809 /* When this function is called, it means that registers must be
810 saved on entry to this function. So we migrate the
811 call to the first insn of this function. */
816 temp = expand_builtin_apply_args_1 ();
820 apply_args_value = temp;
822 /* Put the sequence after the NOTE that starts the function.
823 If this is inside a SEQUENCE, make the outer-level insn
824 chain current, so the code is placed at the start of the
826 push_topmost_sequence ();
827 emit_insns_before (seq, NEXT_INSN (get_insns ()));
828 pop_topmost_sequence ();
833 /* Perform an untyped call and save the state required to perform an
834 untyped return of whatever value was returned by the given function. */
837 expand_builtin_apply (function, arguments, argsize)
838 rtx function, arguments, argsize;
840 int size, align, regno;
841 enum machine_mode mode;
842 rtx incoming_args, result, reg, dest, call_insn;
843 rtx old_stack_level = 0;
846 /* Create a block where the return registers can be saved. */
847 result = assign_stack_local (BLKmode, apply_result_size (), -1);
849 /* ??? The argsize value should be adjusted here. */
851 /* Fetch the arg pointer from the ARGUMENTS block. */
852 incoming_args = gen_reg_rtx (Pmode);
853 emit_move_insn (incoming_args,
854 gen_rtx_MEM (Pmode, arguments));
855 #ifndef STACK_GROWS_DOWNWARD
856 incoming_args = expand_binop (Pmode, sub_optab, incoming_args, argsize,
857 incoming_args, 0, OPTAB_LIB_WIDEN);
860 /* Perform postincrements before actually calling the function. */
863 /* Push a new argument block and copy the arguments. */
864 do_pending_stack_adjust ();
866 /* Save the stack with nonlocal if available */
867 #ifdef HAVE_save_stack_nonlocal
868 if (HAVE_save_stack_nonlocal)
869 emit_stack_save (SAVE_NONLOCAL, &old_stack_level, NULL_RTX);
872 emit_stack_save (SAVE_BLOCK, &old_stack_level, NULL_RTX);
874 /* Push a block of memory onto the stack to store the memory arguments.
875 Save the address in a register, and copy the memory arguments. ??? I
876 haven't figured out how the calling convention macros effect this,
877 but it's likely that the source and/or destination addresses in
878 the block copy will need updating in machine specific ways. */
879 dest = allocate_dynamic_stack_space (argsize, 0, 0);
880 emit_block_move (gen_rtx_MEM (BLKmode, dest),
881 gen_rtx_MEM (BLKmode, incoming_args),
883 PARM_BOUNDARY / BITS_PER_UNIT);
885 /* Refer to the argument block. */
887 arguments = gen_rtx_MEM (BLKmode, arguments);
889 /* Walk past the arg-pointer and structure value address. */
890 size = GET_MODE_SIZE (Pmode);
891 if (struct_value_rtx)
892 size += GET_MODE_SIZE (Pmode);
894 /* Restore each of the registers previously saved. Make USE insns
895 for each of these registers for use in making the call. */
896 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
897 if ((mode = apply_args_mode[regno]) != VOIDmode)
899 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
900 if (size % align != 0)
901 size = CEIL (size, align) * align;
902 reg = gen_rtx_REG (mode, regno);
904 change_address (arguments, mode,
905 plus_constant (XEXP (arguments, 0),
908 use_reg (&call_fusage, reg);
909 size += GET_MODE_SIZE (mode);
912 /* Restore the structure value address unless this is passed as an
913 "invisible" first argument. */
914 size = GET_MODE_SIZE (Pmode);
915 if (struct_value_rtx)
917 rtx value = gen_reg_rtx (Pmode);
918 emit_move_insn (value,
919 change_address (arguments, Pmode,
920 plus_constant (XEXP (arguments, 0),
922 emit_move_insn (struct_value_rtx, value);
923 if (GET_CODE (struct_value_rtx) == REG)
924 use_reg (&call_fusage, struct_value_rtx);
925 size += GET_MODE_SIZE (Pmode);
928 /* All arguments and registers used for the call are set up by now! */
929 function = prepare_call_address (function, NULL_TREE, &call_fusage, 0);
931 /* Ensure address is valid. SYMBOL_REF is already valid, so no need,
932 and we don't want to load it into a register as an optimization,
933 because prepare_call_address already did it if it should be done. */
934 if (GET_CODE (function) != SYMBOL_REF)
935 function = memory_address (FUNCTION_MODE, function);
937 /* Generate the actual call instruction and save the return value. */
938 #ifdef HAVE_untyped_call
939 if (HAVE_untyped_call)
940 emit_call_insn (gen_untyped_call (gen_rtx_MEM (FUNCTION_MODE, function),
941 result, result_vector (1, result)));
944 #ifdef HAVE_call_value
949 /* Locate the unique return register. It is not possible to
950 express a call that sets more than one return register using
951 call_value; use untyped_call for that. In fact, untyped_call
952 only needs to save the return registers in the given block. */
953 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
954 if ((mode = apply_result_mode[regno]) != VOIDmode)
957 abort (); /* HAVE_untyped_call required. */
958 valreg = gen_rtx_REG (mode, regno);
961 emit_call_insn (gen_call_value (valreg,
962 gen_rtx_MEM (FUNCTION_MODE, function),
963 const0_rtx, NULL_RTX, const0_rtx));
965 emit_move_insn (change_address (result, GET_MODE (valreg),
973 /* Find the CALL insn we just emitted. */
974 for (call_insn = get_last_insn ();
975 call_insn && GET_CODE (call_insn) != CALL_INSN;
976 call_insn = PREV_INSN (call_insn))
982 /* Put the register usage information on the CALL. If there is already
983 some usage information, put ours at the end. */
984 if (CALL_INSN_FUNCTION_USAGE (call_insn))
988 for (link = CALL_INSN_FUNCTION_USAGE (call_insn); XEXP (link, 1) != 0;
989 link = XEXP (link, 1))
992 XEXP (link, 1) = call_fusage;
995 CALL_INSN_FUNCTION_USAGE (call_insn) = call_fusage;
997 /* Restore the stack. */
998 #ifdef HAVE_save_stack_nonlocal
999 if (HAVE_save_stack_nonlocal)
1000 emit_stack_restore (SAVE_NONLOCAL, old_stack_level, NULL_RTX);
1003 emit_stack_restore (SAVE_BLOCK, old_stack_level, NULL_RTX);
1005 /* Return the address of the result block. */
1006 return copy_addr_to_reg (XEXP (result, 0));
1009 /* Perform an untyped return. */
1012 expand_builtin_return (result)
1015 int size, align, regno;
1016 enum machine_mode mode;
1018 rtx call_fusage = 0;
1020 apply_result_size ();
1021 result = gen_rtx_MEM (BLKmode, result);
1023 #ifdef HAVE_untyped_return
1024 if (HAVE_untyped_return)
1026 emit_jump_insn (gen_untyped_return (result, result_vector (0, result)));
1032 /* Restore the return value and note that each value is used. */
1034 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1035 if ((mode = apply_result_mode[regno]) != VOIDmode)
1037 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1038 if (size % align != 0)
1039 size = CEIL (size, align) * align;
1040 reg = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1041 emit_move_insn (reg,
1042 change_address (result, mode,
1043 plus_constant (XEXP (result, 0),
1046 push_to_sequence (call_fusage);
1047 emit_insn (gen_rtx_USE (VOIDmode, reg));
1048 call_fusage = get_insns ();
1050 size += GET_MODE_SIZE (mode);
1053 /* Put the USE insns before the return. */
1054 emit_insns (call_fusage);
1056 /* Return whatever values was restored by jumping directly to the end
1058 expand_null_return ();
1061 /* Expand a call to __builtin_classify_type with arguments found in
1064 expand_builtin_classify_type (arglist)
1069 tree type = TREE_TYPE (TREE_VALUE (arglist));
1070 enum tree_code code = TREE_CODE (type);
1071 if (code == VOID_TYPE)
1072 return GEN_INT (void_type_class);
1073 if (code == INTEGER_TYPE)
1074 return GEN_INT (integer_type_class);
1075 if (code == CHAR_TYPE)
1076 return GEN_INT (char_type_class);
1077 if (code == ENUMERAL_TYPE)
1078 return GEN_INT (enumeral_type_class);
1079 if (code == BOOLEAN_TYPE)
1080 return GEN_INT (boolean_type_class);
1081 if (code == POINTER_TYPE)
1082 return GEN_INT (pointer_type_class);
1083 if (code == REFERENCE_TYPE)
1084 return GEN_INT (reference_type_class);
1085 if (code == OFFSET_TYPE)
1086 return GEN_INT (offset_type_class);
1087 if (code == REAL_TYPE)
1088 return GEN_INT (real_type_class);
1089 if (code == COMPLEX_TYPE)
1090 return GEN_INT (complex_type_class);
1091 if (code == FUNCTION_TYPE)
1092 return GEN_INT (function_type_class);
1093 if (code == METHOD_TYPE)
1094 return GEN_INT (method_type_class);
1095 if (code == RECORD_TYPE)
1096 return GEN_INT (record_type_class);
1097 if (code == UNION_TYPE || code == QUAL_UNION_TYPE)
1098 return GEN_INT (union_type_class);
1099 if (code == ARRAY_TYPE)
1101 if (TYPE_STRING_FLAG (type))
1102 return GEN_INT (string_type_class);
1104 return GEN_INT (array_type_class);
1106 if (code == SET_TYPE)
1107 return GEN_INT (set_type_class);
1108 if (code == FILE_TYPE)
1109 return GEN_INT (file_type_class);
1110 if (code == LANG_TYPE)
1111 return GEN_INT (lang_type_class);
1113 return GEN_INT (no_type_class);
1116 /* Expand expression EXP, which is a call to __builtin_constant_p. */
1118 expand_builtin_constant_p (exp)
1121 tree arglist = TREE_OPERAND (exp, 1);
1122 enum machine_mode value_mode = TYPE_MODE (TREE_TYPE (exp));
1128 tree arg = TREE_VALUE (arglist);
1131 /* We return 1 for a numeric type that's known to be a constant
1132 value at compile-time or for an aggregate type that's a
1133 literal constant. */
1136 /* If we know this is a constant, emit the constant of one. */
1137 if (TREE_CODE_CLASS (TREE_CODE (arg)) == 'c'
1138 || (TREE_CODE (arg) == CONSTRUCTOR
1139 && TREE_CONSTANT (arg))
1140 || (TREE_CODE (arg) == ADDR_EXPR
1141 && TREE_CODE (TREE_OPERAND (arg, 0)) == STRING_CST))
1144 /* If we aren't going to be running CSE or this expression
1145 has side effects, show we don't know it to be a constant.
1146 Likewise if it's a pointer or aggregate type since in those
1147 case we only want literals, since those are only optimized
1148 when generating RTL, not later. */
1149 if (TREE_SIDE_EFFECTS (arg) || cse_not_expected
1150 || AGGREGATE_TYPE_P (TREE_TYPE (arg))
1151 || POINTER_TYPE_P (TREE_TYPE (arg)))
1154 /* Otherwise, emit (constant_p_rtx (ARG)) and let CSE get a
1155 chance to see if it can deduce whether ARG is constant. */
1157 tmp = expand_expr (arg, NULL_RTX, VOIDmode, 0);
1158 tmp = gen_rtx_CONSTANT_P_RTX (value_mode, tmp);
1163 /* Expand a call to one of the builtin math functions (sin, cos, or sqrt).
1164 Return 0 if a normal call should be emitted rather than expanding the
1165 function in-line. EXP is the expression that is a call to the builtin
1166 function; if convenient, the result should be placed in TARGET.
1167 SUBTARGET may be used as the target for computing one of EXP's operands. */
1169 expand_builtin_mathfn (exp, target, subtarget)
1171 rtx target, subtarget;
1173 optab builtin_optab;
1175 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
1176 tree arglist = TREE_OPERAND (exp, 1);
1179 /* Arg could be wrong type if user redeclared this fcn wrong. */
1180 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != REAL_TYPE)
1183 /* Stabilize and compute the argument. */
1184 if (TREE_CODE (TREE_VALUE (arglist)) != VAR_DECL
1185 && TREE_CODE (TREE_VALUE (arglist)) != PARM_DECL)
1187 exp = copy_node (exp);
1188 arglist = copy_node (arglist);
1189 TREE_OPERAND (exp, 1) = arglist;
1190 TREE_VALUE (arglist) = save_expr (TREE_VALUE (arglist));
1192 op0 = expand_expr (TREE_VALUE (arglist), subtarget, VOIDmode, 0);
1194 /* Make a suitable register to place result in. */
1195 target = gen_reg_rtx (TYPE_MODE (TREE_TYPE (exp)));
1200 switch (DECL_FUNCTION_CODE (fndecl))
1203 builtin_optab = sin_optab; break;
1205 builtin_optab = cos_optab; break;
1206 case BUILT_IN_FSQRT:
1207 builtin_optab = sqrt_optab; break;
1212 /* Compute into TARGET.
1213 Set TARGET to wherever the result comes back. */
1214 target = expand_unop (TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist))),
1215 builtin_optab, op0, target, 0);
1217 /* If we were unable to expand via the builtin, stop the
1218 sequence (without outputting the insns) and return 0, causing
1219 a call to the library function. */
1226 /* Check the results by default. But if flag_fast_math is turned on,
1227 then assume sqrt will always be called with valid arguments. */
1229 if (flag_errno_math && ! flag_fast_math)
1233 /* Don't define the builtin FP instructions
1234 if your machine is not IEEE. */
1235 if (TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT)
1238 lab1 = gen_label_rtx ();
1240 /* Test the result; if it is NaN, set errno=EDOM because
1241 the argument was not in the domain. */
1242 emit_cmp_and_jump_insns (target, target, EQ, 0, GET_MODE (target),
1247 #ifdef GEN_ERRNO_RTX
1248 rtx errno_rtx = GEN_ERRNO_RTX;
1251 = gen_rtx_MEM (word_mode, gen_rtx_SYMBOL_REF (Pmode, "errno"));
1254 emit_move_insn (errno_rtx, GEN_INT (TARGET_EDOM));
1257 /* We can't set errno=EDOM directly; let the library call do it.
1258 Pop the arguments right away in case the call gets deleted. */
1260 expand_call (exp, target, 0);
1267 /* Output the entire sequence. */
1268 insns = get_insns ();
1275 /* Expand expression EXP which is a call to the strlen builtin. Return 0
1276 if we failed the caller should emit a normal call, otherwise
1277 try to get the result in TARGET, if convenient (and in mode MODE if that's
1280 expand_builtin_strlen (exp, target, mode)
1283 enum machine_mode mode;
1285 tree arglist = TREE_OPERAND (exp, 1);
1286 enum machine_mode value_mode = TYPE_MODE (TREE_TYPE (exp));
1289 /* Arg could be non-pointer if user redeclared this fcn wrong. */
1290 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE)
1294 tree src = TREE_VALUE (arglist);
1295 tree len = c_strlen (src);
1298 = get_pointer_alignment (src, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
1300 rtx result, src_rtx, char_rtx;
1301 enum machine_mode insn_mode = value_mode, char_mode;
1302 enum insn_code icode;
1304 /* If the length is known, just return it. */
1306 return expand_expr (len, target, mode, EXPAND_MEMORY_USE_BAD);
1308 /* If SRC is not a pointer type, don't do this operation inline. */
1312 /* Call a function if we can't compute strlen in the right mode. */
1314 while (insn_mode != VOIDmode)
1316 icode = strlen_optab->handlers[(int) insn_mode].insn_code;
1317 if (icode != CODE_FOR_nothing)
1320 insn_mode = GET_MODE_WIDER_MODE (insn_mode);
1322 if (insn_mode == VOIDmode)
1325 /* Make a place to write the result of the instruction. */
1328 && GET_CODE (result) == REG
1329 && GET_MODE (result) == insn_mode
1330 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
1331 result = gen_reg_rtx (insn_mode);
1333 /* Make sure the operands are acceptable to the predicates. */
1335 if (! (*insn_operand_predicate[(int)icode][0]) (result, insn_mode))
1336 result = gen_reg_rtx (insn_mode);
1337 src_rtx = memory_address (BLKmode,
1338 expand_expr (src, NULL_RTX, ptr_mode,
1341 if (! (*insn_operand_predicate[(int)icode][1]) (src_rtx, Pmode))
1342 src_rtx = copy_to_mode_reg (Pmode, src_rtx);
1344 /* Check the string is readable and has an end. */
1345 if (current_function_check_memory_usage)
1346 emit_library_call (chkr_check_str_libfunc, 1, VOIDmode, 2,
1348 GEN_INT (MEMORY_USE_RO),
1349 TYPE_MODE (integer_type_node));
1351 char_rtx = const0_rtx;
1352 char_mode = insn_operand_mode[(int)icode][2];
1353 if (! (*insn_operand_predicate[(int)icode][2]) (char_rtx, char_mode))
1354 char_rtx = copy_to_mode_reg (char_mode, char_rtx);
1356 emit_insn (GEN_FCN (icode) (result,
1357 gen_rtx_MEM (BLKmode, src_rtx),
1358 char_rtx, GEN_INT (align)));
1360 /* Return the value in the proper mode for this function. */
1361 if (GET_MODE (result) == value_mode)
1363 else if (target != 0)
1365 convert_move (target, result, 0);
1369 return convert_to_mode (value_mode, result, 0);
1373 /* Expand a call to the memcpy builtin, with arguments in ARGLIST. */
1375 expand_builtin_memcpy (arglist)
1379 /* Arg could be non-pointer if user redeclared this fcn wrong. */
1380 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE
1381 || TREE_CHAIN (arglist) == 0
1382 || (TREE_CODE (TREE_TYPE (TREE_VALUE (TREE_CHAIN (arglist))))
1384 || TREE_CHAIN (TREE_CHAIN (arglist)) == 0
1385 || (TREE_CODE (TREE_TYPE (TREE_VALUE
1386 (TREE_CHAIN (TREE_CHAIN (arglist)))))
1391 tree dest = TREE_VALUE (arglist);
1392 tree src = TREE_VALUE (TREE_CHAIN (arglist));
1393 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
1396 = get_pointer_alignment (src, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
1398 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
1399 rtx dest_mem, src_mem, dest_addr, len_rtx;
1401 /* If either SRC or DEST is not a pointer type, don't do
1402 this operation in-line. */
1403 if (src_align == 0 || dest_align == 0)
1406 dest_mem = get_memory_rtx (dest);
1407 src_mem = get_memory_rtx (src);
1408 len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
1410 /* Just copy the rights of SRC to the rights of DEST. */
1411 if (current_function_check_memory_usage)
1412 emit_library_call (chkr_copy_bitmap_libfunc, 1, VOIDmode, 3,
1413 XEXP (dest_mem, 0), Pmode,
1414 XEXP (src_mem, 0), Pmode,
1415 len_rtx, TYPE_MODE (sizetype));
1417 /* Copy word part most expediently. */
1419 = emit_block_move (dest_mem, src_mem, len_rtx,
1420 MIN (src_align, dest_align));
1423 dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
1429 /* Expand expression EXP, which is a call to the strcpy builtin. Return 0
1430 if we failed the caller should emit a normal call. */
1432 expand_builtin_strcpy (exp)
1435 tree arglist = TREE_OPERAND (exp, 1);
1439 /* Arg could be non-pointer if user redeclared this fcn wrong. */
1440 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE
1441 || TREE_CHAIN (arglist) == 0
1442 || TREE_CODE (TREE_TYPE (TREE_VALUE (TREE_CHAIN (arglist)))) != POINTER_TYPE)
1446 tree len = c_strlen (TREE_VALUE (TREE_CHAIN (arglist)));
1451 len = size_binop (PLUS_EXPR, len, integer_one_node);
1453 chainon (arglist, build_tree_list (NULL_TREE, len));
1455 result = expand_builtin_memcpy (arglist);
1457 TREE_CHAIN (TREE_CHAIN (arglist)) = 0;
1461 /* Expand expression EXP, which is a call to the memset builtin. Return 0
1462 if we failed the caller should emit a normal call. */
1464 expand_builtin_memset (exp)
1467 tree arglist = TREE_OPERAND (exp, 1);
1470 /* Arg could be non-pointer if user redeclared this fcn wrong. */
1471 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE
1472 || TREE_CHAIN (arglist) == 0
1473 || (TREE_CODE (TREE_TYPE (TREE_VALUE (TREE_CHAIN (arglist))))
1475 || TREE_CHAIN (TREE_CHAIN (arglist)) == 0
1477 != (TREE_CODE (TREE_TYPE
1479 (TREE_CHAIN (TREE_CHAIN (arglist))))))))
1483 tree dest = TREE_VALUE (arglist);
1484 tree val = TREE_VALUE (TREE_CHAIN (arglist));
1485 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
1488 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
1489 rtx dest_mem, dest_addr, len_rtx;
1491 /* If DEST is not a pointer type, don't do this
1492 operation in-line. */
1493 if (dest_align == 0)
1496 /* If the arguments have side-effects, then we can only evaluate
1497 them at most once. The following code evaluates them twice if
1498 they are not constants because we break out to expand_call
1499 in that case. They can't be constants if they have side-effects
1500 so we can check for that first. Alternatively, we could call
1501 save_expr to make multiple evaluation safe. */
1502 if (TREE_SIDE_EFFECTS (val) || TREE_SIDE_EFFECTS (len))
1505 /* If VAL is not 0, don't do this operation in-line. */
1506 if (expand_expr (val, NULL_RTX, VOIDmode, 0) != const0_rtx)
1509 /* If LEN does not expand to a constant, don't do this
1510 operation in-line. */
1511 len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
1512 if (GET_CODE (len_rtx) != CONST_INT)
1515 dest_mem = get_memory_rtx (dest);
1517 /* Just check DST is writable and mark it as readable. */
1518 if (current_function_check_memory_usage)
1519 emit_library_call (chkr_check_addr_libfunc, 1, VOIDmode, 3,
1520 XEXP (dest_mem, 0), Pmode,
1521 len_rtx, TYPE_MODE (sizetype),
1522 GEN_INT (MEMORY_USE_WO),
1523 TYPE_MODE (integer_type_node));
1526 dest_addr = clear_storage (dest_mem, len_rtx, dest_align);
1529 dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
1535 #ifdef HAVE_cmpstrsi
1536 /* Expand expression EXP, which is a call to the memcmp or the strcmp builtin.
1537 ARGLIST is the argument list for this call. Return 0 if we failed and the
1538 caller should emit a normal call, otherwise try to get the result in
1539 TARGET, if convenient. */
1541 expand_builtin_memcmp (exp, arglist, target)
1546 /* If we need to check memory accesses, call the library function. */
1547 if (current_function_check_memory_usage)
1551 /* Arg could be non-pointer if user redeclared this fcn wrong. */
1552 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE
1553 || TREE_CHAIN (arglist) == 0
1554 || TREE_CODE (TREE_TYPE (TREE_VALUE (TREE_CHAIN (arglist)))) != POINTER_TYPE
1555 || TREE_CHAIN (TREE_CHAIN (arglist)) == 0
1556 || TREE_CODE (TREE_TYPE (TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist))))) != INTEGER_TYPE)
1558 else if (!HAVE_cmpstrsi)
1562 enum machine_mode mode;
1563 tree arg1 = TREE_VALUE (arglist);
1564 tree arg2 = TREE_VALUE (TREE_CHAIN (arglist));
1565 tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
1569 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
1571 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
1572 enum machine_mode insn_mode
1573 = insn_operand_mode[(int) CODE_FOR_cmpstrsi][0];
1575 /* If we don't have POINTER_TYPE, call the function. */
1576 if (arg1_align == 0 || arg2_align == 0)
1579 /* Make a place to write the result of the instruction. */
1582 && GET_CODE (result) == REG && GET_MODE (result) == insn_mode
1583 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
1584 result = gen_reg_rtx (insn_mode);
1586 emit_insn (gen_cmpstrsi (result, get_memory_rtx (arg1),
1587 get_memory_rtx (arg2),
1588 expand_expr (len, NULL_RTX, VOIDmode, 0),
1589 GEN_INT (MIN (arg1_align, arg2_align))));
1591 /* Return the value in the proper mode for this function. */
1592 mode = TYPE_MODE (TREE_TYPE (exp));
1593 if (GET_MODE (result) == mode)
1595 else if (target != 0)
1597 convert_move (target, result, 0);
1601 return convert_to_mode (mode, result, 0);
1605 /* Expand expression EXP, which is a call to the strcmp builtin. Return 0
1606 if we failed the caller should emit a normal call, otherwise try to get
1607 the result in TARGET, if convenient. */
1609 expand_builtin_strcmp (exp, target)
1613 tree arglist = TREE_OPERAND (exp, 1);
1615 /* If we need to check memory accesses, call the library function. */
1616 if (current_function_check_memory_usage)
1620 /* Arg could be non-pointer if user redeclared this fcn wrong. */
1621 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE
1622 || TREE_CHAIN (arglist) == 0
1623 || TREE_CODE (TREE_TYPE (TREE_VALUE (TREE_CHAIN (arglist)))) != POINTER_TYPE)
1625 else if (!HAVE_cmpstrsi)
1628 tree arg1 = TREE_VALUE (arglist);
1629 tree arg2 = TREE_VALUE (TREE_CHAIN (arglist));
1632 len = c_strlen (arg1);
1634 len = size_binop (PLUS_EXPR, integer_one_node, len);
1635 len2 = c_strlen (arg2);
1637 len2 = size_binop (PLUS_EXPR, integer_one_node, len2);
1639 /* If we don't have a constant length for the first, use the length
1640 of the second, if we know it. We don't require a constant for
1641 this case; some cost analysis could be done if both are available
1642 but neither is constant. For now, assume they're equally cheap.
1644 If both strings have constant lengths, use the smaller. This
1645 could arise if optimization results in strcpy being called with
1646 two fixed strings, or if the code was machine-generated. We should
1647 add some code to the `memcmp' handler below to deal with such
1648 situations, someday. */
1649 if (!len || TREE_CODE (len) != INTEGER_CST)
1656 else if (len2 && TREE_CODE (len2) == INTEGER_CST)
1658 if (tree_int_cst_lt (len2, len))
1662 chainon (arglist, build_tree_list (NULL_TREE, len));
1663 result = expand_builtin_memcmp (exp, arglist, target);
1665 TREE_CHAIN (TREE_CHAIN (arglist)) = 0;
1671 /* Expand a call to __builtin_saveregs, generating the result in TARGET,
1672 if that's convenient. */
1674 expand_builtin_saveregs ()
1678 /* Don't do __builtin_saveregs more than once in a function.
1679 Save the result of the first call and reuse it. */
1680 if (saveregs_value != 0)
1681 return saveregs_value;
1683 /* When this function is called, it means that registers must be
1684 saved on entry to this function. So we migrate the call to the
1685 first insn of this function. */
1689 #ifdef EXPAND_BUILTIN_SAVEREGS
1690 /* Do whatever the machine needs done in this case. */
1691 val = EXPAND_BUILTIN_SAVEREGS ();
1693 /* ??? We used to try and build up a call to the out of line function,
1694 guessing about what registers needed saving etc. This became much
1695 harder with __builtin_va_start, since we don't have a tree for a
1696 call to __builtin_saveregs to fall back on. There was exactly one
1697 port (i860) that used this code, and I'm unconvinced it could actually
1698 handle the general case. So we no longer try to handle anything
1699 weird and make the backend absorb the evil. */
1701 error ("__builtin_saveregs not supported by this target");
1708 saveregs_value = val;
1710 /* Put the sequence after the NOTE that starts the function. If this
1711 is inside a SEQUENCE, make the outer-level insn chain current, so
1712 the code is placed at the start of the function. */
1713 push_topmost_sequence ();
1714 emit_insns_after (seq, get_insns ());
1715 pop_topmost_sequence ();
1720 /* __builtin_args_info (N) returns word N of the arg space info
1721 for the current function. The number and meanings of words
1722 is controlled by the definition of CUMULATIVE_ARGS. */
1724 expand_builtin_args_info (exp)
1727 tree arglist = TREE_OPERAND (exp, 1);
1728 int nwords = sizeof (CUMULATIVE_ARGS) / sizeof (int);
1729 int *word_ptr = (int *) ¤t_function_args_info;
1731 /* These are used by the code below that is if 0'ed away */
1733 tree type, elts, result;
1736 if (sizeof (CUMULATIVE_ARGS) % sizeof (int) != 0)
1741 tree arg = TREE_VALUE (arglist);
1742 if (TREE_CODE (arg) != INTEGER_CST)
1743 error ("argument of `__builtin_args_info' must be constant");
1746 int wordnum = TREE_INT_CST_LOW (arg);
1748 if (wordnum < 0 || wordnum >= nwords || TREE_INT_CST_HIGH (arg))
1749 error ("argument of `__builtin_args_info' out of range");
1751 return GEN_INT (word_ptr[wordnum]);
1755 error ("missing argument in `__builtin_args_info'");
1760 for (i = 0; i < nwords; i++)
1761 elts = tree_cons (NULL_TREE, build_int_2 (word_ptr[i], 0));
1763 type = build_array_type (integer_type_node,
1764 build_index_type (build_int_2 (nwords, 0)));
1765 result = build (CONSTRUCTOR, type, NULL_TREE, nreverse (elts));
1766 TREE_CONSTANT (result) = 1;
1767 TREE_STATIC (result) = 1;
1768 result = build1 (INDIRECT_REF, build_pointer_type (type), result);
1769 TREE_CONSTANT (result) = 1;
1770 return expand_expr (result, NULL_RTX, VOIDmode, EXPAND_MEMORY_USE_BAD);
1774 /* Expand ARGLIST, from a call to __builtin_next_arg. */
1776 expand_builtin_next_arg (arglist)
1779 tree fntype = TREE_TYPE (current_function_decl);
1781 if ((TYPE_ARG_TYPES (fntype) == 0
1782 || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
1784 && ! current_function_varargs)
1786 error ("`va_start' used in function with fixed args");
1792 tree last_parm = tree_last (DECL_ARGUMENTS (current_function_decl));
1793 tree arg = TREE_VALUE (arglist);
1795 /* Strip off all nops for the sake of the comparison. This
1796 is not quite the same as STRIP_NOPS. It does more.
1797 We must also strip off INDIRECT_EXPR for C++ reference
1799 while (TREE_CODE (arg) == NOP_EXPR
1800 || TREE_CODE (arg) == CONVERT_EXPR
1801 || TREE_CODE (arg) == NON_LVALUE_EXPR
1802 || TREE_CODE (arg) == INDIRECT_REF)
1803 arg = TREE_OPERAND (arg, 0);
1804 if (arg != last_parm)
1805 warning ("second parameter of `va_start' not last named argument");
1807 else if (! current_function_varargs)
1808 /* Evidently an out of date version of <stdarg.h>; can't validate
1809 va_start's second argument, but can still work as intended. */
1810 warning ("`__builtin_next_arg' called without an argument");
1812 return expand_binop (Pmode, add_optab,
1813 current_function_internal_arg_pointer,
1814 current_function_arg_offset_rtx,
1815 NULL_RTX, 0, OPTAB_LIB_WIDEN);
1818 /* Make it easier for the backends by protecting the valist argument
1819 from multiple evaluations. */
1822 stabilize_va_list (valist, was_ptr)
1826 int is_array = TREE_CODE (va_list_type_node) == ARRAY_TYPE;
1830 /* If stdarg.h took the address of an array-type valist that was passed
1831 as a parameter, we'll have taken the address of the parameter itself
1832 rather than the array as we'd intended. Undo this mistake. */
1834 && TREE_CODE (valist) == ADDR_EXPR
1835 && TREE_CODE (TREE_TYPE (TREE_OPERAND (valist, 0))) == POINTER_TYPE)
1837 valist = TREE_OPERAND (valist, 0);
1838 if (TREE_SIDE_EFFECTS (valist))
1839 valist = save_expr (valist);
1843 if (TREE_SIDE_EFFECTS (valist))
1844 valist = save_expr (valist);
1845 valist = fold (build1 (INDIRECT_REF, va_list_type_node, valist));
1848 else if (TREE_SIDE_EFFECTS (valist))
1851 valist = save_expr (valist);
1854 valist = build1 (ADDR_EXPR, build_pointer_type (va_list_type_node),
1856 TREE_SIDE_EFFECTS (valist) = 1;
1857 valist = save_expr (valist);
1858 valist = fold (build1 (INDIRECT_REF, va_list_type_node, valist));
1865 /* The "standard" implementation of va_start: just assign `nextarg' to
1868 std_expand_builtin_va_start (stdarg_p, valist, nextarg)
1869 int stdarg_p ATTRIBUTE_UNUSED;
1876 nextarg = plus_constant (nextarg, -UNITS_PER_WORD);
1878 t = build (MODIFY_EXPR, TREE_TYPE (valist), valist,
1879 make_tree (ptr_type_node, nextarg));
1880 TREE_SIDE_EFFECTS (t) = 1;
1882 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
1885 /* Expand ARGLIST, which from a call to __builtin_stdarg_va_start or
1886 __builtin_varargs_va_start, depending on STDARG_P. */
1888 expand_builtin_va_start (stdarg_p, arglist)
1893 tree chain = arglist, valist;
1896 nextarg = expand_builtin_next_arg (chain = TREE_CHAIN (arglist));
1898 nextarg = expand_builtin_next_arg (NULL_TREE);
1900 if (TREE_CHAIN (chain))
1901 error ("too many arguments to function `va_start'");
1903 valist = stabilize_va_list (TREE_VALUE (arglist), 1);
1905 #ifdef EXPAND_BUILTIN_VA_START
1906 EXPAND_BUILTIN_VA_START (stdarg_p, valist, nextarg);
1908 std_expand_builtin_va_start (stdarg_p, valist, nextarg);
1914 /* Allocate an alias set for use in storing and reading from the varargs
1917 get_varargs_alias_set ()
1919 static int set = -1;
1921 set = new_alias_set ();
1925 /* The "standard" implementation of va_arg: read the value from the
1926 current (padded) address and increment by the (padded) size. */
1928 std_expand_builtin_va_arg (valist, type)
1932 HOST_WIDE_INT align;
1933 HOST_WIDE_INT rounded_size;
1936 /* Compute the rounded size of the type. */
1937 align = PARM_BOUNDARY / BITS_PER_UNIT;
1938 rounded_size = (((int_size_in_bytes (type) + align - 1) / align) * align);
1942 if (BYTES_BIG_ENDIAN)
1944 /* Small args are padded downward. */
1947 adj = TREE_INT_CST_LOW (TYPE_SIZE (type)) / BITS_PER_UNIT;
1948 if (rounded_size > align)
1951 addr_tree = build (PLUS_EXPR, TREE_TYPE (addr_tree), addr_tree,
1952 build_int_2 (rounded_size - adj, 0));
1955 addr = expand_expr (addr_tree, NULL_RTX, Pmode, EXPAND_NORMAL);
1956 addr = copy_to_reg (addr);
1958 /* Compute new value for AP. */
1959 t = build (MODIFY_EXPR, TREE_TYPE (valist), valist,
1960 build (PLUS_EXPR, TREE_TYPE (valist), valist,
1961 build_int_2 (rounded_size, 0)));
1962 TREE_SIDE_EFFECTS (t) = 1;
1963 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
1968 /* Expand __builtin_va_arg, which is not really a builtin function, but
1969 a very special sort of operator. */
1971 expand_builtin_va_arg (valist, type)
1976 if (TYPE_MAIN_VARIANT (TREE_TYPE (valist))
1977 != TYPE_MAIN_VARIANT (va_list_type_node))
1979 error ("first argument to `__builtin_va_arg' not of type `va_list'");
1984 /* Make it easier for the backends by protecting the valist argument
1985 from multiple evaluations. */
1986 valist = stabilize_va_list (valist, 0);
1988 #ifdef EXPAND_BUILTIN_VA_ARG
1989 addr = EXPAND_BUILTIN_VA_ARG (valist, type);
1991 addr = std_expand_builtin_va_arg (valist, type);
1995 result = gen_rtx_MEM (TYPE_MODE (type), addr);
1996 MEM_ALIAS_SET (result) = get_varargs_alias_set ();
2001 /* Expand ARGLIST, from a call to __builtin_va_end. */
2003 expand_builtin_va_end (arglist)
2006 tree valist = TREE_VALUE (arglist);
2008 #ifdef EXPAND_BUILTIN_VA_END
2009 valist = stabilize_va_list (valist, 0);
2010 EXPAND_BUILTIN_VA_END(arglist);
2012 /* Evaluate for side effects, if needed. I hate macros that don't
2014 if (TREE_SIDE_EFFECTS (valist))
2015 expand_expr (valist, const0_rtx, VOIDmode, EXPAND_NORMAL);
2021 /* Expand ARGLIST, from a call to __builtin_va_copy. We do this as a
2022 builtin rather than just as an assignment in stdarg.h because of the
2023 nastiness of array-type va_list types. */
2025 expand_builtin_va_copy (arglist)
2030 dst = TREE_VALUE (arglist);
2031 src = TREE_VALUE (TREE_CHAIN (arglist));
2033 dst = stabilize_va_list (dst, 1);
2034 src = stabilize_va_list (src, 0);
2036 if (TREE_CODE (va_list_type_node) != ARRAY_TYPE)
2038 t = build (MODIFY_EXPR, va_list_type_node, dst, src);
2039 TREE_SIDE_EFFECTS (t) = 1;
2040 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
2044 emit_block_move (expand_expr (dst, NULL_RTX, Pmode, EXPAND_NORMAL),
2045 expand_expr (src, NULL_RTX, Pmode, EXPAND_NORMAL),
2046 expand_expr (TYPE_SIZE (va_list_type_node), NULL_RTX,
2047 VOIDmode, EXPAND_NORMAL),
2048 TYPE_ALIGN (va_list_type_node) / BITS_PER_UNIT);
2054 /* Expand a call to one of the builtin functions __builtin_frame_address or
2055 __builtin_return_address. */
2057 expand_builtin_frame_address (exp)
2060 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
2061 tree arglist = TREE_OPERAND (exp, 1);
2063 /* The argument must be a nonnegative integer constant.
2064 It counts the number of frames to scan up the stack.
2065 The value is the return address saved in that frame. */
2067 /* Warning about missing arg was already issued. */
2069 else if (TREE_CODE (TREE_VALUE (arglist)) != INTEGER_CST
2070 || tree_int_cst_sgn (TREE_VALUE (arglist)) < 0)
2072 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
2073 error ("invalid arg to `__builtin_frame_address'");
2075 error ("invalid arg to `__builtin_return_address'");
2080 rtx tem = expand_builtin_return_addr (DECL_FUNCTION_CODE (fndecl),
2081 TREE_INT_CST_LOW (TREE_VALUE (arglist)),
2082 hard_frame_pointer_rtx);
2084 /* Some ports cannot access arbitrary stack frames. */
2087 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
2088 warning ("unsupported arg to `__builtin_frame_address'");
2090 warning ("unsupported arg to `__builtin_return_address'");
2094 /* For __builtin_frame_address, return what we've got. */
2095 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
2098 if (GET_CODE (tem) != REG
2099 && ! CONSTANT_P (tem))
2100 tem = copy_to_mode_reg (Pmode, tem);
2105 /* Expand a call to the alloca builtin, with arguments ARGLIST. Return 0 if
2106 we failed and the caller should emit a normal call, otherwise try to get
2107 the result in TARGET, if convenient. */
2109 expand_builtin_alloca (arglist, target)
2116 /* Arg could be non-integer if user redeclared this fcn wrong. */
2117 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE)
2120 /* Compute the argument. */
2121 op0 = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
2123 /* Allocate the desired space. */
2124 return allocate_dynamic_stack_space (op0, target, BITS_PER_UNIT);
2127 /* Expand a call to the ffs builtin. The arguments are in ARGLIST.
2128 Return 0 if a normal call should be emitted rather than expanding the
2129 function in-line. If convenient, the result should be placed in TARGET.
2130 SUBTARGET may be used as the target for computing one of EXP's operands. */
2132 expand_builtin_ffs (arglist, target, subtarget)
2134 rtx target, subtarget;
2138 /* Arg could be non-integer if user redeclared this fcn wrong. */
2139 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE)
2142 /* Compute the argument. */
2143 op0 = expand_expr (TREE_VALUE (arglist), subtarget, VOIDmode, 0);
2144 /* Compute ffs, into TARGET if possible.
2145 Set TARGET to wherever the result comes back. */
2146 target = expand_unop (TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist))),
2147 ffs_optab, op0, target, 1);
2153 /* Expand an expression EXP that calls a built-in function,
2154 with result going to TARGET if that's convenient
2155 (and in mode MODE if that's convenient).
2156 SUBTARGET may be used as the target for computing one of EXP's operands.
2157 IGNORE is nonzero if the value is to be ignored. */
2160 expand_builtin (exp, target, subtarget, mode, ignore)
2164 enum machine_mode mode;
2167 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
2168 tree arglist = TREE_OPERAND (exp, 1);
2169 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
2171 /* When not optimizing, generate calls to library functions for a certain
2173 if (! optimize && ! CALLED_AS_BUILT_IN (fndecl)
2174 && (fcode == BUILT_IN_SIN || fcode == BUILT_IN_COS
2175 || fcode == BUILT_IN_FSQRT || fcode == BUILT_IN_MEMSET
2176 || fcode == BUILT_IN_MEMCPY || fcode == BUILT_IN_MEMCMP
2177 || fcode == BUILT_IN_STRLEN || fcode == BUILT_IN_STRCPY
2178 || fcode == BUILT_IN_STRCMP || fcode == BUILT_IN_FFS))
2179 return expand_call (exp, target, ignore);
2186 /* build_function_call changes these into ABS_EXPR. */
2191 /* Treat these like sqrt, but only if the user asks for them. */
2192 if (! flag_fast_math)
2194 case BUILT_IN_FSQRT:
2195 target = expand_builtin_mathfn (exp, target, subtarget);
2203 case BUILT_IN_APPLY_ARGS:
2204 return expand_builtin_apply_args ();
2206 /* __builtin_apply (FUNCTION, ARGUMENTS, ARGSIZE) invokes
2207 FUNCTION with a copy of the parameters described by
2208 ARGUMENTS, and ARGSIZE. It returns a block of memory
2209 allocated on the stack into which is stored all the registers
2210 that might possibly be used for returning the result of a
2211 function. ARGUMENTS is the value returned by
2212 __builtin_apply_args. ARGSIZE is the number of bytes of
2213 arguments that must be copied. ??? How should this value be
2214 computed? We'll also need a safe worst case value for varargs
2216 case BUILT_IN_APPLY:
2218 /* Arg could be non-pointer if user redeclared this fcn wrong. */
2219 || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
2220 || TREE_CHAIN (arglist) == 0
2221 || TREE_CODE (TREE_TYPE (TREE_VALUE (TREE_CHAIN (arglist)))) != POINTER_TYPE
2222 || TREE_CHAIN (TREE_CHAIN (arglist)) == 0
2223 || TREE_CODE (TREE_TYPE (TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist))))) != INTEGER_TYPE)
2231 for (t = arglist, i = 0; t; t = TREE_CHAIN (t), i++)
2232 ops[i] = expand_expr (TREE_VALUE (t), NULL_RTX, VOIDmode, 0);
2234 return expand_builtin_apply (ops[0], ops[1], ops[2]);
2237 /* __builtin_return (RESULT) causes the function to return the
2238 value described by RESULT. RESULT is address of the block of
2239 memory returned by __builtin_apply. */
2240 case BUILT_IN_RETURN:
2242 /* Arg could be non-pointer if user redeclared this fcn wrong. */
2243 && TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) == POINTER_TYPE)
2244 expand_builtin_return (expand_expr (TREE_VALUE (arglist),
2245 NULL_RTX, VOIDmode, 0));
2248 case BUILT_IN_SAVEREGS:
2249 return expand_builtin_saveregs ();
2251 case BUILT_IN_ARGS_INFO:
2252 return expand_builtin_args_info (exp);
2254 /* Return the address of the first anonymous stack arg. */
2255 case BUILT_IN_NEXT_ARG:
2256 return expand_builtin_next_arg (arglist);
2258 case BUILT_IN_CLASSIFY_TYPE:
2259 return expand_builtin_classify_type (arglist);
2261 case BUILT_IN_CONSTANT_P:
2262 return expand_builtin_constant_p (exp);
2264 case BUILT_IN_FRAME_ADDRESS:
2265 case BUILT_IN_RETURN_ADDRESS:
2266 return expand_builtin_frame_address (exp);
2268 /* Returns the address of the area where the structure is returned.
2270 case BUILT_IN_AGGREGATE_INCOMING_ADDRESS:
2272 || ! AGGREGATE_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl)))
2273 || GET_CODE (DECL_RTL (DECL_RESULT (current_function_decl))) != MEM)
2276 return XEXP (DECL_RTL (DECL_RESULT (current_function_decl)), 0);
2278 case BUILT_IN_ALLOCA:
2279 target = expand_builtin_alloca (arglist, target);
2285 target = expand_builtin_ffs (arglist, target, subtarget);
2290 case BUILT_IN_STRLEN:
2291 target = expand_builtin_strlen (exp, target, mode);
2296 case BUILT_IN_STRCPY:
2297 target = expand_builtin_strcpy (exp);
2302 case BUILT_IN_MEMCPY:
2303 target = expand_builtin_memcpy (arglist);
2308 case BUILT_IN_MEMSET:
2309 target = expand_builtin_memset (exp);
2314 /* These comparison functions need an instruction that returns an actual
2315 index. An ordinary compare that just sets the condition codes
2317 #ifdef HAVE_cmpstrsi
2318 case BUILT_IN_STRCMP:
2319 target = expand_builtin_strcmp (exp, target);
2324 case BUILT_IN_MEMCMP:
2325 target = expand_builtin_memcmp (exp, arglist, target);
2330 case BUILT_IN_STRCMP:
2331 case BUILT_IN_MEMCMP:
2335 case BUILT_IN_SETJMP:
2337 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE)
2341 rtx buf_addr = expand_expr (TREE_VALUE (arglist), subtarget,
2343 rtx lab = gen_label_rtx ();
2344 rtx ret = expand_builtin_setjmp (buf_addr, target, lab, lab);
2349 /* __builtin_longjmp is passed a pointer to an array of five words.
2350 It's similar to the C library longjmp function but works with
2351 __builtin_setjmp above. */
2352 case BUILT_IN_LONGJMP:
2353 if (arglist == 0 || TREE_CHAIN (arglist) == 0
2354 || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE)
2358 rtx buf_addr = expand_expr (TREE_VALUE (arglist), subtarget,
2360 rtx value = expand_expr (TREE_VALUE (TREE_CHAIN (arglist)),
2361 NULL_RTX, VOIDmode, 0);
2363 if (value != const1_rtx)
2365 error ("__builtin_longjmp second argument must be 1");
2369 expand_builtin_longjmp (buf_addr, value);
2376 emit_insn (gen_trap ());
2379 error ("__builtin_trap not supported by this target");
2383 /* Various hooks for the DWARF 2 __throw routine. */
2384 case BUILT_IN_UNWIND_INIT:
2385 expand_builtin_unwind_init ();
2387 case BUILT_IN_DWARF_CFA:
2388 return virtual_cfa_rtx;
2389 #ifdef DWARF2_UNWIND_INFO
2390 case BUILT_IN_DWARF_FP_REGNUM:
2391 return expand_builtin_dwarf_fp_regnum ();
2392 case BUILT_IN_DWARF_REG_SIZE:
2393 return expand_builtin_dwarf_reg_size (TREE_VALUE (arglist), target);
2395 case BUILT_IN_FROB_RETURN_ADDR:
2396 return expand_builtin_frob_return_addr (TREE_VALUE (arglist));
2397 case BUILT_IN_EXTRACT_RETURN_ADDR:
2398 return expand_builtin_extract_return_addr (TREE_VALUE (arglist));
2399 case BUILT_IN_EH_RETURN:
2400 expand_builtin_eh_return (TREE_VALUE (arglist),
2401 TREE_VALUE (TREE_CHAIN (arglist)),
2402 TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist))));
2404 case BUILT_IN_VARARGS_START:
2405 return expand_builtin_va_start (0, arglist);
2406 case BUILT_IN_STDARG_START:
2407 return expand_builtin_va_start (1, arglist);
2408 case BUILT_IN_VA_END:
2409 return expand_builtin_va_end (arglist);
2410 case BUILT_IN_VA_COPY:
2411 return expand_builtin_va_copy (arglist);
2413 default: /* just do library call, if unknown builtin */
2414 error ("built-in function `%s' not currently supported",
2415 IDENTIFIER_POINTER (DECL_NAME (fndecl)));
2418 /* The switch statement above can drop through to cause the function
2419 to be called normally. */
2420 return expand_call (exp, target, ignore);