From e37ce5f6f6d7493a4a9338df33429743ed149527 Mon Sep 17 00:00:00 2001 From: Jeff Law Date: Mon, 16 Nov 1992 06:52:13 -0700 Subject: [PATCH] pa.c (output_move_double): Handle indirect stores to memory via an auto-incremented/auto-decremented... * pa.c (output_move_double): Handle indirect stores to memory via an auto-incremented/auto-decremented register in the same manner in which loads are handled. From-SVN: r2751 --- gcc/config/pa/pa.c | 45 +++++++++++++++++++++++++++++++++++++++------ 1 file changed, 39 insertions(+), 6 deletions(-) diff --git a/gcc/config/pa/pa.c b/gcc/config/pa/pa.c index b1a8d8dd4b0..8b32e194429 100644 --- a/gcc/config/pa/pa.c +++ b/gcc/config/pa/pa.c @@ -798,16 +798,49 @@ output_move_double (operands) if (optype0 == MEMOP) { + /* We have to output the address syntax ourselves, since print_operand + doesn't deal with the addresses we want to use. Fix this later. */ + rtx addr = XEXP (operands[0], 0); - if (GET_CODE (addr) == POST_INC || GET_CODE (addr) == PRE_INC) + if (GET_CODE (addr) == POST_INC || GET_CODE (addr) == POST_DEC) { - operands[0] = gen_rtx (MEM, SImode, addr); - return "stw%M0 %1,%0\n\tstw%M0 %R1,%0"; + rtx high_reg = gen_rtx (SUBREG, SImode, operands[1], 0); + + operands[0] = XEXP (addr, 0); + if (GET_CODE (operands[1]) != REG || GET_CODE (operands[0]) != REG) + abort (); + + if (!reg_overlap_mentioned_p (high_reg, addr)) + { + /* No overlap between high target register and address + register. (We do this in a non-obvious way to + save a register file writeback) */ + if (GET_CODE (addr) == POST_INC) + return "stws,ma %1,8(0,%0)\n\tstw %R1,-4(0,%0)"; + return "stws,ma %1,-8(0,%0)\n\tstw %R1,12(0,%0)"; + } + else + abort(); } - else if (GET_CODE (addr) == POST_DEC || GET_CODE (addr) == PRE_DEC) + else if (GET_CODE (addr) == PRE_INC || GET_CODE (addr) == PRE_DEC) { - operands[0] = gen_rtx (MEM, SImode, addr); - return "stw%M0 %R1,%0\n\tstw%M0 %1,%0"; + rtx high_reg = gen_rtx (SUBREG, SImode, operands[1], 0); + + operands[0] = XEXP (addr, 0); + if (GET_CODE (operands[1]) != REG || GET_CODE (operands[0]) != REG) + abort (); + + if (!reg_overlap_mentioned_p (high_reg, addr)) + { + /* No overlap between high target register and address + register. (We do this in a non-obvious way to + save a register file writeback) */ + if (GET_CODE (addr) == PRE_INC) + return "stws,mb %1,8(0,%0)\n\tstw %R1,4(0,%0)"; + return "stws,mb %1,-8(0,%0)\n\tstw %R1,4(0,%0)"; + } + else + abort(); } } if (optype1 == MEMOP) -- 2.30.2