arc.h (EXPAND_BUILTIN_VA_START): New.
* arc.h (EXPAND_BUILTIN_VA_START): New. (EXPAND_BUILTIN_VA_ARG): New. * arc.c (arc_setup_incoming_varargs): Set alias set of varargs save area. (arc_va_start): New. (arc_va_arg): New. From-SVN: r28254
This commit is contained in:
parent
80c83e6322
commit
965eb47478
|
@ -1,3 +1,12 @@
|
|||
Sun Jul 25 22:56:47 1999 Richard Henderson <rth@cygnus.com>
|
||||
|
||||
* arc.h (EXPAND_BUILTIN_VA_START): New.
|
||||
(EXPAND_BUILTIN_VA_ARG): New.
|
||||
* arc.c (arc_setup_incoming_varargs): Set alias set of
|
||||
varargs save area.
|
||||
(arc_va_start): New.
|
||||
(arc_va_arg): New.
|
||||
|
||||
Sun Jul 25 22:45:55 1999 Richard Henderson <rth@cygnus.com>
|
||||
|
||||
* alpha.h (EXPAND_BUILTIN_SAVEREGS): Delete.
|
||||
|
|
|
@ -751,7 +751,7 @@ arc_double_limm_p (value)
|
|||
|
||||
We do things a little weird here. We're supposed to only allocate space
|
||||
for the anonymous arguments. However we need to keep the stack eight byte
|
||||
aligned. So we round the space up if necessary, and leave it to va-arc.h
|
||||
aligned. So we round the space up if necessary, and leave it to va_start
|
||||
to compensate. */
|
||||
|
||||
void
|
||||
|
@ -789,6 +789,8 @@ arc_setup_incoming_varargs (cum, mode, type, pretend_size, no_rtl)
|
|||
plus_constant (arg_pointer_rtx,
|
||||
FIRST_PARM_OFFSET (0)
|
||||
+ align_slop * UNITS_PER_WORD));
|
||||
MEM_ALIAS_SET (regblock) = get_varargs_alias_set ();
|
||||
|
||||
move_block_from_reg (first_reg_offset, regblock,
|
||||
MAX_ARC_PARM_REGS - first_reg_offset,
|
||||
((MAX_ARC_PARM_REGS - first_reg_offset)
|
||||
|
@ -2201,3 +2203,90 @@ arc_ccfsm_record_branch_deleted ()
|
|||
for the just deleted branch. */
|
||||
current_insn_set_cc_p = last_insn_set_cc_p;
|
||||
}
|
||||
|
||||
void
|
||||
arc_va_start (stdarg_p, valist, nextarg)
|
||||
int stdarg_p;
|
||||
tree valist;
|
||||
rtx nextarg;
|
||||
{
|
||||
/* See arc_setup_incoming_varargs for reasons for this oddity. */
|
||||
if (current_function_args_info < 8
|
||||
&& (current_function_args_info & 1))
|
||||
nextarg = plus_constant (nextarg, UNITS_PER_WORD);
|
||||
|
||||
std_expand_builtin_va_start (stdarg_p, valist, nextarg);
|
||||
}
|
||||
|
||||
rtx
|
||||
arc_va_arg (valist, type)
|
||||
tree valist, type;
|
||||
{
|
||||
rtx addr_rtx;
|
||||
tree addr, incr;
|
||||
tree type_ptr = build_pointer_type (type);
|
||||
|
||||
/* All aggregates are passed by reference. All scalar types larger
|
||||
than 8 bytes are passed by reference. */
|
||||
|
||||
if (AGGREGATE_TYPE_P (type) || int_size_in_bytes (type) > 8)
|
||||
{
|
||||
tree type_ptr_ptr = build_pointer_type (type_ptr);
|
||||
|
||||
addr = build (INDIRECT_REF, type_ptr,
|
||||
build (NOP_EXPR, type_ptr_ptr, valist));
|
||||
|
||||
incr = build (PLUS_EXPR, TREE_TYPE (valist),
|
||||
valist, build_int_2 (UNITS_PER_WORD, 0));
|
||||
}
|
||||
else
|
||||
{
|
||||
HOST_WIDE_INT align, rounded_size;
|
||||
|
||||
/* Compute the rounded size of the type. */
|
||||
align = PARM_BOUNDARY / BITS_PER_UNIT;
|
||||
rounded_size = (((TREE_INT_CST_LOW (TYPE_SIZE (type)) / BITS_PER_UNIT
|
||||
+ align - 1) / align) * align);
|
||||
|
||||
/* Align 8 byte operands. */
|
||||
addr = valist;
|
||||
if (TYPE_ALIGN (type) > BITS_PER_WORD)
|
||||
{
|
||||
/* AP = (TYPE *)(((int)AP + 7) & -8) */
|
||||
|
||||
addr = build (NOP_EXPR, integer_type_node, valist);
|
||||
addr = fold (build (PLUS_EXPR, integer_type_node, addr,
|
||||
build_int_2 (7, 0)));
|
||||
addr = fold (build (BIT_AND_EXPR, integer_type_node, addr,
|
||||
build_int_2 (-8, 0)));
|
||||
addr = fold (build (NOP_EXPR, TREE_TYPE (valist), addr));
|
||||
}
|
||||
|
||||
/* The increment is always rounded_size past the aligned pointer. */
|
||||
incr = fold (build (PLUS_EXPR, TREE_TYPE (addr), addr,
|
||||
build_int_2 (rounded_size, 0)));
|
||||
|
||||
/* Adjust the pointer in big-endian mode. */
|
||||
if (BYTES_BIG_ENDIAN)
|
||||
{
|
||||
HOST_WIDE_INT adj;
|
||||
adj = TREE_INT_CST_LOW (TYPE_SIZE (type)) / BITS_PER_UNIT;
|
||||
if (rounded_size > align)
|
||||
adj = rounded_size;
|
||||
|
||||
addr = fold (build (PLUS_EXPR, TREE_TYPE (addr), addr,
|
||||
build_int_2 (rounded_size - adj, 0)));
|
||||
}
|
||||
}
|
||||
|
||||
/* Evaluate the data address. */
|
||||
addr_rtx = expand_expr (addr, NULL_RTX, Pmode, EXPAND_NORMAL);
|
||||
addr_rtx = copy_to_reg (addr_rtx);
|
||||
|
||||
/* Compute new value for AP. */
|
||||
incr = build (MODIFY_EXPR, TREE_TYPE (valist), valist, incr);
|
||||
TREE_SIDE_EFFECTS (incr) = 1;
|
||||
expand_expr (incr, const0_rtx, VOIDmode, EXPAND_NORMAL);
|
||||
|
||||
return addr_rtx;
|
||||
}
|
||||
|
|
|
@ -1640,3 +1640,12 @@ enum arc_function_type {
|
|||
((TYPE) == ARC_FUNCTION_ILINK1 || (TYPE) == ARC_FUNCTION_ILINK2)
|
||||
/* Compute the type of a function from its DECL. */
|
||||
enum arc_function_type arc_compute_function_type ();
|
||||
|
||||
|
||||
/* Implement `va_start' for varargs and stdarg. */
|
||||
#define EXPAND_BUILTIN_VA_START(stdarg, valist, nextarg) \
|
||||
arc_va_start (stdarg, valist, nextarg)
|
||||
|
||||
/* Implement `va_arg'. */
|
||||
#define EXPAND_BUILTIN_VA_ARG(valist, type) \
|
||||
arc_va_arg (valist, type)
|
||||
|
|
Loading…
Reference in New Issue