diff options
author | Miod Vallat <miod@cvs.openbsd.org> | 2012-11-17 01:47:43 +0000 |
---|---|---|
committer | Miod Vallat <miod@cvs.openbsd.org> | 2012-11-17 01:47:43 +0000 |
commit | ac900bbb63ff7258e980be1d094d09117d67372d (patch) | |
tree | 32ece4144cfe651eacdb84fa97872c72b9e1ebd2 /gnu | |
parent | 3abd55993412af704a6be472dff0c0a4d1d3064a (diff) |
In the expansion of __builtin_saveregs(), use double store instructions to
spill the registers on __va_reg instead of calling move_block_from_reg().
Diffstat (limited to 'gnu')
-rw-r--r-- | gnu/usr.bin/gcc/gcc/config/m88k/m88k.c | 32 |
1 files changed, 29 insertions, 3 deletions
diff --git a/gnu/usr.bin/gcc/gcc/config/m88k/m88k.c b/gnu/usr.bin/gcc/gcc/config/m88k/m88k.c index 4155c6667a3..3bbf8331e7d 100644 --- a/gnu/usr.bin/gcc/gcc/config/m88k/m88k.c +++ b/gnu/usr.bin/gcc/gcc/config/m88k/m88k.c @@ -2669,9 +2669,35 @@ m88k_builtin_saveregs () /* Now store the incoming registers. */ if (regcnt != 0) - move_block_from_reg (2 + m88k_first_vararg, - adjust_address (addr, Pmode, delta * UNITS_PER_WORD), - regcnt, UNITS_PER_WORD * regcnt); + { + /* The following is equivalent to + move_block_from_reg (2 + m88k_first_vararg, + adjust_address (addr, Pmode, + delta * UNITS_PER_WORD), + regcnt, UNITS_PER_WORD * regcnt); + but using double store instruction since the stack is properly + aligned. */ + rtx dst = addr; + int regno = 2 + m88k_first_vararg; + int offs; + + if (delta != 0) + { + dst = adjust_address (dst, Pmode, UNITS_PER_WORD); + emit_move_insn (operand_subword (dst, 0, 1, BLKmode), + gen_rtx_REG (SImode, regno)); + regno++; + } + + offs = delta; + while (regno < 10) + { + emit_move_insn (adjust_address (dst, DImode, offs * UNITS_PER_WORD), + gen_rtx_REG (DImode, regno)); + offs += 2; + regno += 2; + } + } /* Return the address of the hypothetical save area containing all the argument registers (to help va_arg() computations), but don't put it in a |