diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a25c1a065a4..7dad4a763a7 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +Wed Jul 28 11:23:48 1999 Richard Henderson + + * pa.c (hppa_builtin_saveregs): Use get_varargs_alias_set + and tag the spill mems. + (hppa_va_start): New. + (hppa_va_arg): New. + * pa.h (EXPAND_BUILTIN_VA_START): New. + (EXPAND_BUILTIN_VA_ARG): New. + Wed Jul 28 11:22:21 1999 Richard Henderson * mn10300.c (mn10300_builtin_saveregs): Use get_varargs_alias_set diff --git a/gcc/config/pa/pa.c b/gcc/config/pa/pa.c index 33efebca79b..92c5dae1f69 100644 --- a/gcc/config/pa/pa.c +++ b/gcc/config/pa/pa.c @@ -4283,6 +4283,7 @@ hppa_builtin_saveregs () dest = gen_rtx_MEM (BLKmode, plus_constant (current_function_internal_arg_pointer, -16)); + MEM_ALIAS_SET (dest) = get_varargs_alias_set (); move_block_from_reg (23, dest, 4, 4 * UNITS_PER_WORD); /* move_block_from_reg will emit code to store the argument registers @@ -4308,6 +4309,73 @@ hppa_builtin_saveregs () offset, 0, 0, OPTAB_LIB_WIDEN)); } +void +hppa_va_start (stdarg_p, valist, nextarg) + int stdarg_p; + tree valist; + rtx nextarg; +{ + nextarg = expand_builtin_saveregs (); + std_expand_builtin_va_start (stdarg_p, valist, nextarg); +} + +rtx +hppa_va_arg (valist, type) + tree valist, type; +{ + HOST_WIDE_INT align, size, ofs; + tree t, ptr, pptr; + + /* Compute the rounded size of the type. */ + align = PARM_BOUNDARY / BITS_PER_UNIT; + size = int_size_in_bytes (type); + + ptr = build_pointer_type (type); + + /* "Large" types are passed by reference. */ + if (size > 8) + { + t = build (PREDECREMENT_EXPR, TREE_TYPE (valist), valist, + build_int_2 (POINTER_SIZE / BITS_PER_UNIT, 0)); + TREE_SIDE_EFFECTS (t) = 1; + + pptr = build_pointer_type (ptr); + t = build1 (NOP_EXPR, pptr, t); + TREE_SIDE_EFFECTS (t) = 1; + + t = build1 (INDIRECT_REF, ptr, t); + TREE_SIDE_EFFECTS (t) = 1; + } + else + { + t = build (PLUS_EXPR, TREE_TYPE (valist), valist, + build_int_2 (-size, -1)); + + /* ??? Copied from va-pa.h, but we probably don't need to align + to word size, since we generate and preserve that invariant. */ + t = build (BIT_AND_EXPR, TREE_TYPE (valist), t, + build_int_2 ((size > 4 ? -8 : -4), -1)); + + t = build (MODIFY_EXPR, TREE_TYPE (valist), valist, t); + TREE_SIDE_EFFECTS (t) = 1; + + ofs = (8 - size) % 4; + if (ofs) + { + t = build (PLUS_EXPR, TREE_TYPE (valist), t, build_int_2 (ofs, 0)); + TREE_SIDE_EFFECTS (t) = 1; + } + + t = build1 (NOP_EXPR, ptr, t); + TREE_SIDE_EFFECTS (t) = 1; + } + + /* Calculate! */ + return expand_expr (t, NULL_RTX, Pmode, EXPAND_NORMAL); +} + + + /* This routine handles all the normal conditional branch sequences we might need to generate. It handles compare immediate vs compare register, nullification of delay slots, varying length branches, diff --git a/gcc/config/pa/pa.h b/gcc/config/pa/pa.h index ce2e555d197..612993ec5ef 100644 --- a/gcc/config/pa/pa.h +++ b/gcc/config/pa/pa.h @@ -1219,6 +1219,17 @@ extern union tree_node *current_function_decl; extern struct rtx_def *hppa_builtin_saveregs (); #define EXPAND_BUILTIN_SAVEREGS() hppa_builtin_saveregs () +/* Implement `va_start' for varargs and stdarg. */ + +extern void hppa_va_start(); +#define EXPAND_BUILTIN_VA_START(stdarg, valist, nextarg) \ + hppa_va_start (stdarg, valist, nextarg) + +/* Implement `va_arg'. */ + +extern struct rtx_def *hppa_va_arg(); +#define EXPAND_BUILTIN_VA_ARG(valist, type) \ + hppa_va_arg (valist, type) /* Addressing modes, and classification of registers for them.