This is the mail archive of the gcc@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]

Re: alpha himode reload problem


On Sun, Oct 26, 1997 at 04:09:47PM -0800, Richard Henderson wrote:
> Comments on the following?  The recog.c changes were necesary to 
> get combine not to undo our hard work in stmt.c.

Blah.  I should have tested this on something real like the kernel.
It needs a bit more thought, but comments on what ought to happen
are still welcome.

In the meantime, the attached patch fills out the brute force solution
Jim posted, for 8 cases (also attached) I could think of.  Any other
points that are likely to be called?

At least the kernel builds now.  We'll see how well it boots in a 
moment.  ;-)


r~
struct asdf {
  int tmp;
  unsigned short x;
  char y;
};

short * a_short();
char* a_char();
struct asdf * a_asdf();

void in1(a,b,c,d,e,f,g)
   int a,b,c,d,e,f,g;
{
  short *x = a_short();
  while (a < b)
    bar(a++,b,c,d,e,f,g);
  asm volatile("#%0" : : "r"(x[2]));
}

void in2(a,b,c,d,e,f,g)
   int a,b,c,d,e,f,g;
{
  char *x = a_char();
  while (a < b)
    bar(a++,b,c,d,e,f,g);
  asm volatile("#%0" : : "r"(x[2]));
}

void in3(a,b,c,d,e,f,g)
   int a,b,c,d,e,f,g;
{
  struct asdf *x = a_asdf();
  while (a < b)
    bar(a++,b,c,d,e,f,g);
  asm volatile("#%0" : : "r"(x->x));
}

void in4(a,b,c,d,e,f,g)
   int a,b,c,d,e,f,g;
{
  struct asdf *x = a_asdf();
  while (a < b)
    bar(a++,b,c,d,e,f,g);
  asm volatile("#%0" : : "r"(x->y));
}

void out1(a,b,c,d,e,f,g)
   int a,b,c,d,e,f,g;
{
  short *x = a_short();
  while (a < b)
    bar(a++,b,c,d,e,f,g);
  asm volatile("#%0" : "=r"(x[2]));
}

void out2(a,b,c,d,e,f,g)
   int a,b,c,d,e,f,g;
{
  char *x = a_char();
  while (a < b)
    bar(a++,b,c,d,e,f,g);
  asm volatile("#%0" : "=r"(x[2]));
}

void out3(a,b,c,d,e,f,g)
   int a,b,c,d,e,f,g;
{
  struct asdf *x = a_asdf();
  while (a < b)
    bar(a++,b,c,d,e,f,g);
  asm volatile("#%0" : "=r"(x->x));
}

void out4(a,b,c,d,e,f,g)
   int a,b,c,d,e,f,g;
{
  struct asdf *x = a_asdf();
  while (a < b)
    bar(a++,b,c,d,e,f,g);
  asm volatile("#%0" : "=r"(x->y));
}
Index: alpha.md
===================================================================
RCS file: /cvs/cvsfiles/egcs/gcc/config/alpha/alpha.md,v
retrieving revision 1.10
diff -u -p -r1.10 alpha.md
--- alpha.md	1997/10/24 22:57:54	1.10
+++ alpha.md	1997/10/27 06:38:47
@@ -4071,6 +4071,18 @@
 			 ? gen_rtx (REG, SImode, REGNO (operands[0]))
 			 : gen_reg_rtx (SImode));
 
+	  /* ??? This code creates a new MEM rtx.  If we were called during
+	     reload, then we must be careful to make sure that the new rtx
+	     will not need reloading.  */
+	  if (reload_in_progress
+	      && GET_CODE (operands[1]) == MEM
+	      && ! strict_memory_address_p (SImode, XEXP (operands[1], 0)))
+	    {
+	      rtx tmp = gen_rtx (REG, Pmode, REGNO (operands[0]));
+	      emit_insn (gen_move_insn (tmp, XEXP (operands[1], 0)));
+	      XEXP (operands[1], 0) = tmp;
+	    }
+
 	  get_aligned_mem (operands[1], &aligned_mem, &bitnum);
 
 	  emit_insn (gen_aligned_loadqi (operands[0], aligned_mem, bitnum,
@@ -4183,6 +4195,18 @@
 			 ? gen_rtx (REG, SImode, REGNO (operands[0]))
 			 : gen_reg_rtx (SImode));
 
+	  /* ??? This code creates a new MEM rtx.  If we were called during
+	     reload, then we must be careful to make sure that the new rtx
+	     will not need reloading.  */
+	  if (reload_in_progress
+	      && GET_CODE (operands[1]) == MEM
+	      && ! strict_memory_address_p (SImode, XEXP (operands[1], 0)))
+	    {
+	      rtx tmp = gen_rtx (REG, Pmode, REGNO (operands[0]));
+	      emit_insn (gen_move_insn (tmp, XEXP (operands[1], 0)));
+	      XEXP (operands[1], 0) = tmp;
+	    }
+
 	  get_aligned_mem (operands[1], &aligned_mem, &bitnum);
 
 	  emit_insn (gen_aligned_loadhi (operands[0], aligned_mem, bitnum,
@@ -4257,15 +4281,26 @@
   "! TARGET_BYTE_OPS"
   "
 { extern rtx get_unaligned_address ();
-  rtx addr = get_unaligned_address (operands[1], 0);
+  rtx addr, scratch, seq, tmp;
+
   /* It is possible that one of the registers we got for operands[2]
      might coincide with that of operands[0] (which is why we made
      it TImode).  Pick the other one to use as our scratch.  */
-  rtx scratch = gen_rtx (REG, DImode,
-			 REGNO (operands[0]) == REGNO (operands[2]) 
-			 ? REGNO (operands[2]) + 1 : REGNO (operands[2]));
-  rtx seq = gen_unaligned_loadqi (operands[0], addr, scratch,
-				  gen_rtx (REG, DImode, REGNO (operands[0])));
+  scratch = gen_rtx (REG, DImode,
+		     REGNO (operands[0]) == REGNO (operands[2]) 
+		     ? REGNO (operands[2]) + 1 : REGNO (operands[2]));
+
+  /* We must be careful to make sure that the new rtx won't need reloading.  */
+  if (! strict_memory_address_p (DImode, XEXP (operands[1], 0)))
+    {
+      tmp = gen_rtx (REG, Pmode, REGNO (operands[0]));
+      emit_insn (gen_move_insn (tmp, XEXP (operands[1], 0)));
+      XEXP (operands[1], 0) = tmp;
+    }
+  addr = get_unaligned_address (operands[1], 0);
+
+  seq = gen_unaligned_loadqi (operands[0], addr, scratch,
+			      gen_rtx (REG, DImode, REGNO (operands[0])));
 
   alpha_set_memflags (seq, operands[1]);
   emit_insn (seq);
@@ -4279,15 +4314,26 @@
   "! TARGET_BYTE_OPS"
   "
 { extern rtx get_unaligned_address ();
-  rtx addr = get_unaligned_address (operands[1], 0);
+  rtx scratch, seq, tmp, addr;
+
   /* It is possible that one of the registers we got for operands[2]
      might coincide with that of operands[0] (which is why we made
      it TImode).  Pick the other one to use as our scratch.  */
-  rtx scratch = gen_rtx (REG, DImode,
-			 REGNO (operands[0]) == REGNO (operands[2]) 
-			 ? REGNO (operands[2]) + 1 : REGNO (operands[2]));
-  rtx seq = gen_unaligned_loadhi (operands[0], addr, scratch,
-				  gen_rtx (REG, DImode, REGNO (operands[0])));
+  scratch = gen_rtx (REG, DImode,
+		     REGNO (operands[0]) == REGNO (operands[2]) 
+		     ? REGNO (operands[2]) + 1 : REGNO (operands[2]));
+
+  /* We must be careful to make sure that the new rtx won't need reloading.  */
+  if (!strict_memory_address_p (DImode, XEXP (operands[1], 0)))
+    {
+      tmp = gen_rtx (REG, Pmode, REGNO (operands[0]));
+      emit_insn (gen_move_insn (tmp, XEXP (operands[1], 0)));
+      XEXP (operands[1], 0) = tmp;
+    }
+  addr = get_unaligned_address (operands[1], 0);
+
+  seq = gen_unaligned_loadhi (operands[0], addr, scratch,
+			      gen_rtx (REG, DImode, REGNO (operands[0])));
 
   alpha_set_memflags (seq, operands[1]);
   emit_insn (seq);
@@ -4302,6 +4348,13 @@
   "
 { extern rtx get_unaligned_address ();
 
+  if (!strict_memory_address_p (DImode, XEXP (operands[0], 0)))
+    {
+      rtx scratch1 = gen_rtx (REG, DImode, REGNO (operands[2]));
+      emit_insn (gen_move_insn (scratch1, XEXP (operands[0], 0)));
+      XEXP (operands[0], 0) = scratch1;
+    }
+
   if (aligned_memory_operand (operands[0], QImode))
     {
       rtx aligned_mem, bitnum;
@@ -4340,6 +4393,13 @@
   "! TARGET_BYTE_OPS"
   "
 { extern rtx get_unaligned_address ();
+
+  if (!strict_memory_address_p (DImode, XEXP (operands[0], 0)))
+    {
+      rtx scratch1 = gen_rtx (REG, DImode, REGNO (operands[2]));
+      emit_insn (gen_move_insn (scratch1, XEXP (operands[0], 0)));
+      XEXP (operands[0], 0) = scratch1;
+    }
 
   if (aligned_memory_operand (operands[0], HImode))
     {

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