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>
&& ! 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)
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