diff options
author | Jim Wilson <wilson@gcc.gnu.org> | 1996-05-18 17:34:10 -0700 |
---|---|---|
committer | Jim Wilson <wilson@gcc.gnu.org> | 1996-05-18 17:34:10 -0700 |
commit | e22856e8fbeb8c059c5b3b6e867b8c797a774a8e (patch) | |
tree | 5bcf53b4bce0ff14cb17f8029d6ecf63018de758 /gcc | |
parent | a1a0806af6d53e260b5169bac55a58285dce65f7 (diff) | |
download | gcc-e22856e8fbeb8c059c5b3b6e867b8c797a774a8e.zip gcc-e22856e8fbeb8c059c5b3b6e867b8c797a774a8e.tar.gz gcc-e22856e8fbeb8c059c5b3b6e867b8c797a774a8e.tar.bz2 |
(prepare_move_operands): If source is r0, and dest is reg+reg
MEM, then copy source to a pseudo-reg.
From-SVN: r12036
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/config/sh/sh.c | 22 |
1 files changed, 17 insertions, 5 deletions
diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c index be8824a..56fe754 100644 --- a/gcc/config/sh/sh.c +++ b/gcc/config/sh/sh.c @@ -315,11 +315,23 @@ prepare_move_operands (operands, mode) rtx operands[]; enum machine_mode mode; { - /* Copy the source to a register if both operands aren't registers. */ - if (! reload_in_progress && ! reload_completed - && ! register_operand (operands[0], mode) - && ! register_operand (operands[1], mode)) - operands[1] = copy_to_mode_reg (mode, operands[1]); + if (! reload_in_progress && ! reload_completed) + { + /* Copy the source to a register if both operands aren't registers. */ + if (! register_operand (operands[0], mode) + && ! register_operand (operands[1], mode)) + operands[1] = copy_to_mode_reg (mode, operands[1]); + + /* This case can happen while generating code to move the result + of a library call to the target. Reject `st r0,@(rX,rY)' because + reload will fail to find a spill register for rX, since r0 is already + being used for the source. */ + else if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 0 + && GET_CODE (operands[0]) == MEM + && GET_CODE (XEXP (operands[0], 0)) == PLUS + && GET_CODE (XEXP (XEXP (operands[0], 0), 1)) == REG) + operands[1] = copy_to_mode_reg (mode, operands[1]); + } return 0; } |