aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJ"orn Rennecke <joern.rennecke@superh.com>2003-06-16 14:56:38 +0000
committerJoern Rennecke <amylaar@gcc.gnu.org>2003-06-16 15:56:38 +0100
commit266a27326fc77e9d7ff52ff913a67ec981a38d55 (patch)
treed751ccbd131f746cedcf2fe86a10b4e93e4e234a /gcc
parent0eff02cdae2e3ede11ffca73536037869cbc8ff1 (diff)
downloadgcc-266a27326fc77e9d7ff52ff913a67ec981a38d55.zip
gcc-266a27326fc77e9d7ff52ff913a67ec981a38d55.tar.gz
gcc-266a27326fc77e9d7ff52ff913a67ec981a38d55.tar.bz2
sh.c (prepare_move_operand): Check if operand 0 is an invalid memory reference.
* sh.c (prepare_move_operand): Check if operand 0 is an invalid memory reference. Fix test that checks if operand 1 is using r0. * sh.md (movhi_i): Don't allow st.w r0,@(rX,rY) . From-SVN: r68017
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/config/sh/sh.c11
-rw-r--r--gcc/config/sh/sh.md7
3 files changed, 22 insertions, 3 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 2fea707..3612bea 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -77,7 +77,12 @@
2003-06-16 J"orn Rennecke <joern.rennecke@superh.com>
- * (REG_CLASS_FROM_CONSTRAINT): Only define if not already defined.
+ * sh.c (prepare_move_operand): Check if operand 0 is an invalid
+ memory reference. Fix test that checks if operand 1 is using r0.
+ * sh.md (movhi_i): Don't allow st.w r0,@(rX,rY) .
+
+ * defaults.h (REG_CLASS_FROM_CONSTRAINT): Only define if not already
+ defined.
2003-06-15 Nathan Sidwell <nathan@codesourcery.com>
diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c
index 3b1d829..94ca7a0 100644
--- a/gcc/config/sh/sh.c
+++ b/gcc/config/sh/sh.c
@@ -763,11 +763,20 @@ prepare_move_operands (operands, mode)
&& ! sh_register_operand (operands[1], mode))
operands[1] = copy_to_mode_reg (mode, operands[1]);
+ if (GET_CODE (operands[0]) == MEM && ! memory_operand (operands[0], mode))
+ {
+ /* This is like change_address_1 (operands[0], mode, 0, 1) ,
+ except that we can't use that function because it is static. */
+ rtx new = change_address (operands[0], mode, 0);
+ MEM_COPY_ATTRIBUTES (new, operands[0]);
+ operands[0] = new;
+ }
+
/* 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
+ else if (refers_to_regno_p (R0_REG, R0_REG + 1, operands[1], (rtx *)0)
&& GET_CODE (operands[0]) == MEM
&& GET_CODE (XEXP (operands[0], 0)) == PLUS
&& GET_CODE (XEXP (XEXP (operands[0], 0), 1)) == REG)
diff --git a/gcc/config/sh/sh.md b/gcc/config/sh/sh.md
index f662dc6..e70150a 100644
--- a/gcc/config/sh/sh.md
+++ b/gcc/config/sh/sh.md
@@ -3674,12 +3674,17 @@
operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
}")
+/* When storing r0, we have to avoid reg+reg addressing. */
(define_insn "movhi_i"
[(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,r,m,r,l,r")
(match_operand:HI 1 "general_movsrc_operand" "Q,rI,m,t,r,l,r,i"))]
"TARGET_SH1
&& (arith_reg_operand (operands[0], HImode)
- || arith_reg_operand (operands[1], HImode))"
+ || arith_reg_operand (operands[1], HImode))
+ && (GET_CODE (operands[0]) != MEM
+ || GET_CODE (XEXP (operands[0], 0)) != PLUS
+ || GET_CODE (XEXP (XEXP (operands[0], 0), 1)) != REG
+ || ! refers_to_regno_p (R0_REG, R0_REG + 1, operands[1], (rtx *)0))"
"@
mov.w %1,%0
mov %1,%0