This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] FR30: fix bad code generated in fr30_move_double


Hi,

in fr30_move_double in fr30.c, if the move goes from MEM to REG, the
following code is executed:

---8<---

int reverse = (refers_to_regno_p (dregno, dregno + 1, addr, 0) != 0);

dest0 = operand_subword (dest, reverse, TRUE, mode);
dest1 = operand_subword (dest, !reverse, TRUE, mode);

if (reverse)
   {
     emit_insn (gen_rtx_SET (VOIDmode, dest1,
                             adjust_address (src, SImode, 0)));
     emit_insn (gen_rtx_SET (SImode, dest0,
                             gen_rtx_REG (SImode, REGNO (addr))));
     emit_insn (gen_rtx_SET (SImode, dest0,
                             plus_constant (dest0, UNITS_PER_WORD)));

     new_mem = gen_rtx_MEM (SImode, dest0);
     MEM_COPY_ATTRIBUTES (new_mem, src);

     emit_insn (gen_rtx_SET (VOIDmode, dest0, new_mem));
   }
else
   {
     emit_insn (gen_rtx_SET (VOIDmode, dest0,
                             adjust_address (src, SImode, 0)));
     emit_insn (gen_rtx_SET (SImode, dest1,
                             gen_rtx_REG (SImode, REGNO (addr))));
     emit_insn (gen_rtx_SET (SImode, dest1,
                             plus_constant (dest1, UNITS_PER_WORD)));

     new_mem = gen_rtx_MEM (SImode, dest1);
     MEM_COPY_ATTRIBUTES (new_mem, src);

     emit_insn (gen_rtx_SET (VOIDmode, dest1, new_mem));
   }

--->8---

If you examine the case where reverse is true, you'll find that it
generates exactly the same code as the case where reverse if false
(dest0 and dest1 are swapped twice).

But even if this is fixed, there are still cases where the generated
code is wrong. Therefore I suggest to replace this code by a simpler
version that uses the fixed scratch register (zero) and works for all
combinations of src/dest registers.

Best regards,

Thomas


Index: fr30.c
===================================================================
--- fr30.c	(revision 125771)
+++ fr30.c	(working copy)
@@ -830,45 +830,27 @@
 	  int dregno = REGNO (dest);
 	  rtx dest0;
 	  rtx dest1;
+	  rtx scratch;
 	  rtx new_mem;
 	  
-	  /* If the high-address word is used in the address, we
-	     must load it last.  Otherwise, load it first.  */
-	  int reverse = (refers_to_regno_p (dregno, dregno + 1, addr, 0) != 0);
-
 	  gcc_assert (GET_CODE (addr) == REG);
 	  
-	  dest0 = operand_subword (dest, reverse, TRUE, mode);
-	  dest1 = operand_subword (dest, !reverse, TRUE, mode);
+	  dest0 = operand_subword (dest, 0, TRUE, mode);
+	  dest1 = operand_subword (dest, 1, TRUE, mode);
+	  scratch = gen_rtx_REG (SImode, 0);
 
-	  if (reverse)
-	    {
-	      emit_insn (gen_rtx_SET (VOIDmode, dest1,
-				      adjust_address (src, SImode, 0)));
-	      emit_insn (gen_rtx_SET (SImode, dest0,
-				      gen_rtx_REG (SImode, REGNO (addr))));
-	      emit_insn (gen_rtx_SET (SImode, dest0,
-				      plus_constant (dest0, UNITS_PER_WORD)));
 
-	      new_mem = gen_rtx_MEM (SImode, dest0);
-	      MEM_COPY_ATTRIBUTES (new_mem, src);
-	      
-	      emit_insn (gen_rtx_SET (VOIDmode, dest0, new_mem));
-	    }
-	  else
-	    {
-	      emit_insn (gen_rtx_SET (VOIDmode, dest0,
-				      adjust_address (src, SImode, 0)));
-	      emit_insn (gen_rtx_SET (SImode, dest1,
-				      gen_rtx_REG (SImode, REGNO (addr))));
-	      emit_insn (gen_rtx_SET (SImode, dest1,
-				      plus_constant (dest1, UNITS_PER_WORD)));
+          emit_insn (gen_rtx_SET (SImode, scratch,
+                                  gen_rtx_REG (SImode, REGNO (addr))));
+          emit_insn (gen_rtx_SET (VOIDmode, dest0,
+                                  adjust_address (src, SImode, 0)));
+          emit_insn (gen_rtx_SET (SImode, scratch,
+                                  plus_constant (scratch, UNITS_PER_WORD)));
+          
+          new_mem = gen_rtx_MEM (SImode, scratch);
+          MEM_COPY_ATTRIBUTES (new_mem, src);
 
-	      new_mem = gen_rtx_MEM (SImode, dest1);
-	      MEM_COPY_ATTRIBUTES (new_mem, src);
-	      
-	      emit_insn (gen_rtx_SET (VOIDmode, dest1, new_mem));
-	    }
+          emit_insn (gen_rtx_SET (VOIDmode, dest1, new_mem));         
 	}
       else if (src_code == CONST_INT || src_code == CONST_DOUBLE)
 	{


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]