summaryrefslogtreecommitdiff
path: root/gnu
diff options
context:
space:
mode:
authorMiod Vallat <miod@cvs.openbsd.org>2012-11-17 01:47:43 +0000
committerMiod Vallat <miod@cvs.openbsd.org>2012-11-17 01:47:43 +0000
commitac900bbb63ff7258e980be1d094d09117d67372d (patch)
tree32ece4144cfe651eacdb84fa97872c72b9e1ebd2 /gnu
parent3abd55993412af704a6be472dff0c0a4d1d3064a (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.c32
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