mirror of
git://gcc.gnu.org/git/gcc.git
synced 2024-12-20 19:19:59 +08:00
mips.c (mips_va_arg): When using the struct version of the EABI va_list...
* config/mips/mips.c (mips_va_arg): When using the struct version of the EABI va_list, allow arguments in the register save area to take up less room than a stack argument. From-SVN: r52125
This commit is contained in:
parent
ba3307c092
commit
bf6d4777dd
@ -1,3 +1,9 @@
|
||||
2002-04-10 Richard Sandiford <rsandifo@redhat.com>
|
||||
|
||||
* config/mips/mips.c (mips_va_arg): When using the struct version
|
||||
of the EABI va_list, allow arguments in the register save area to
|
||||
take up less room than a stack argument.
|
||||
|
||||
2002-04-10 Richard Henderson <rth@redhat.com>
|
||||
|
||||
* expr.c (expand_expr) [INTEGER_CST]: Don't force into registers
|
||||
|
@ -4582,6 +4582,7 @@ mips_va_arg (valist, type)
|
||||
tree f_ovfl, f_gtop, f_ftop, f_goff, f_foff;
|
||||
tree ovfl, top, off;
|
||||
rtx lab_over = NULL_RTX, lab_false;
|
||||
HOST_WIDE_INT osize;
|
||||
|
||||
f_ovfl = TYPE_FIELDS (va_list_type_node);
|
||||
f_gtop = TREE_CHAIN (f_ovfl);
|
||||
@ -4596,7 +4597,11 @@ mips_va_arg (valist, type)
|
||||
TOP be the top of the register save area;
|
||||
OFF be the offset from TOP of the next register;
|
||||
ADDR_RTX be the address of the argument; and
|
||||
RSIZE be the number of bytes used to store the argument.
|
||||
RSIZE be the number of bytes used to store the argument
|
||||
when it's in the register save area
|
||||
OSIZE be the number of bytes used to store it when it's
|
||||
in the stack overflow area
|
||||
PADDING be (BYTES_BIG_ENDIAN ? OSIZE - RSIZE : 0)
|
||||
|
||||
The code we want is:
|
||||
|
||||
@ -4608,10 +4613,10 @@ mips_va_arg (valist, type)
|
||||
6: }
|
||||
7: else
|
||||
8: {
|
||||
9: ovfl += ((intptr_t) ovfl + rsize - 1) & -rsize;
|
||||
10: addr_rtx = ovfl;
|
||||
11: ovfl += rsize;
|
||||
12: }
|
||||
9: ovfl += ((intptr_t) ovfl + osize - 1) & -osize;
|
||||
10: addr_rtx = ovfl + PADDING;
|
||||
11: ovfl += osize;
|
||||
14: }
|
||||
|
||||
[1] and [9] can sometimes be optimized away. */
|
||||
|
||||
@ -4643,6 +4648,13 @@ mips_va_arg (valist, type)
|
||||
expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
|
||||
}
|
||||
}
|
||||
/* Every overflow argument must take up at least UNITS_PER_WORD
|
||||
bytes (= PARM_BOUNDARY bits). RSIZE can sometimes be smaller
|
||||
than that, such as in the combination -mgp64 -msingle-float
|
||||
-fshort-double. Doubles passed in registers will then take
|
||||
up UNITS_PER_FPVALUE bytes, but those passed on the stack
|
||||
take up UNITS_PER_WORD bytes. */
|
||||
osize = MAX (rsize, UNITS_PER_WORD);
|
||||
|
||||
/* [2] Emit code to branch if off == 0. */
|
||||
r = expand_expr (off, NULL_RTX, TYPE_MODE (TREE_TYPE (off)),
|
||||
@ -4668,21 +4680,25 @@ mips_va_arg (valist, type)
|
||||
emit_barrier ();
|
||||
emit_label (lab_false);
|
||||
|
||||
if (rsize > UNITS_PER_WORD)
|
||||
if (osize > UNITS_PER_WORD)
|
||||
{
|
||||
/* [9] Emit: ovfl += ((intptr_t) ovfl + rsize - 1) & -rsize. */
|
||||
/* [9] Emit: ovfl += ((intptr_t) ovfl + osize - 1) & -osize. */
|
||||
t = build (PLUS_EXPR, TREE_TYPE (ovfl), ovfl,
|
||||
build_int_2 (rsize - 1, 0));
|
||||
build_int_2 (osize - 1, 0));
|
||||
t = build (BIT_AND_EXPR, TREE_TYPE (ovfl), t,
|
||||
build_int_2 (-rsize, -1));
|
||||
build_int_2 (-osize, -1));
|
||||
t = build (MODIFY_EXPR, TREE_TYPE (ovfl), ovfl, t);
|
||||
expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
|
||||
}
|
||||
|
||||
/* [10, 11]. Emit code to store ovfl in addr_rtx, then
|
||||
post-increment ovfl by rsize. */
|
||||
post-increment ovfl by osize. On big-endian machines,
|
||||
the argument has OSIZE - RSIZE bytes of leading padding. */
|
||||
t = build (POSTINCREMENT_EXPR, TREE_TYPE (ovfl), ovfl,
|
||||
size_int (rsize));
|
||||
size_int (osize));
|
||||
if (BYTES_BIG_ENDIAN && osize > rsize)
|
||||
t = build (PLUS_EXPR, TREE_TYPE (t), t,
|
||||
build_int_2 (osize - rsize, 0));
|
||||
r = expand_expr (t, addr_rtx, Pmode, EXPAND_NORMAL);
|
||||
if (r != addr_rtx)
|
||||
emit_move_insn (addr_rtx, r);
|
||||
|
Loading…
Reference in New Issue
Block a user