Patchwork RX: Do not use SMOVF insn to move blocks of volatile memory.

login
register
mail settings
Submitter Nick Clifton
Date April 13, 2011, 11:30 a.m.
Message ID <m3sjtme6co.fsf@redhat.com>
Download mbox | patch
Permalink /patch/90986/
State New
Headers show

Comments

Nick Clifton - April 13, 2011, 11:30 a.m.
Hi Guys,

  I am checking in the patch below to the 4.5 branch and mainline
  sources to fix a problem with the RX's SMOVF instruction.  This
  instruction copies blocks of memory, but it always loads and stores
  aligned 32-bit values.  If necessary it will load extra bytes from the
  beginning or end of the destination block in order to be able to write
  back a whole word.  This can be a problem if the destination block is
  in the I/O address space and those extra bytes do not exist or must
  not be read.

  The patch fixes the problem by disabling the use of the SMOVF
  instruction when volatile pointers are involved.  In this case gcc
  will be forced to use another method to copy the data, most likely a
  loop of byte loads and stores.

Cheers
  Nick

PS. I am not applying the patch to the 4.6 branch since it is already
present there.

gcc/ChangeLog
2011-04-13  Nick Clifton  <nickc@redhat.com>

	* config/rx/rx.md (movmemsi): Do not use this pattern when
	volatile pointers are involved.

Patch

Index: gcc/config/rx/rx.md
===================================================================
--- gcc/config/rx/rx.md	(revision 170734)
+++ gcc/config/rx/rx.md	(working copy)
@@ -1897,6 +1897,14 @@ 
     rtx addr2 = gen_rtx_REG (SImode, 2);
     rtx len   = gen_rtx_REG (SImode, 3);
 
+    /* Do not use when the source or destination are volatile - the SMOVF
+       instruction will read and write in word sized blocks, which may be
+       outside of the valid address range.  */
+    if (MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
+      FAIL;
+    if (MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))
+      FAIL;
+
     if (REG_P (operands[0]) && (REGNO (operands[0]) == 2
 				      || REGNO (operands[0]) == 3))
       FAIL;