21164 compare+branch optimization

Richard Henderson rth@cygnus.com
Mon Sep 29 13:04:00 GMT 1997


On the 21164, there exists a special bypass whereby logical insns
and conditional insns can dual-issue despite a data dependancy. 
This is not the case with arithmetic insns.

So prefer cmpeq+bne over plus+beq, but don't needlessly reload small
integers.


r~



Mon Sep 29 12:53:41 1997  Richard Henderson  <rth@cygnus.com>

	* alpha.md (beq): For registers and ints 0-255, use cmpeq+bne, since
	that pair will dual-issue on the 21164 and plus+beq won't.
	(bne): Likewise for cmpeq+beq.


--- config/alpha/alpha.md.cmp	Mon Sep 15 16:45:55 1997
+++ config/alpha/alpha.md	Mon Sep 29 12:49:47 1997
@@ -2478,16 +2478,23 @@
   "
 {
   enum machine_mode mode;
-  enum rtx_code compare_code, branch_code;
+  enum rtx_code compare_code = EQ, branch_code = NE;
 
   if (alpha_compare_fp_p)
-    mode = DFmode, compare_code = EQ, branch_code = NE;
+    mode = DFmode;
   else
     {
-      mode = DImode, compare_code = MINUS, branch_code = EQ;
-      if (GET_CODE (alpha_compare_op1) == CONST_INT)
+      mode = DImode;
+      /* We want to use cmpeq/bne when we can, since there is a zero-delay
+	 bypass between logicals and br/cmov on the 21164.  But we don't
+	 want to force valid immediate constants into registers needlessly.  */
+      if (GET_CODE (alpha_compare_op1) == CONST_INT
+	  && ((INTVAL (alpha_compare_op1) >= -0x8000
+	       && INTVAL (alpha_compare_op1) < 0)
+	      || (INTVAL (alpha_compare_op1) > 0xff
+		  && INTVAL (alpha_compare_op1) < 0x8000)))
 	{
-	  compare_code = PLUS;
+	  compare_code = PLUS, branch_code = EQ;
 	  alpha_compare_op1 = GEN_INT (- INTVAL (alpha_compare_op1));
 	}
     }
@@ -2509,16 +2516,23 @@
   "
 {
   enum machine_mode mode;
-  enum rtx_code compare_code, branch_code;
+  enum rtx_code compare_code = EQ, branch_code = EQ;
 
   if (alpha_compare_fp_p)
-    mode = DFmode, compare_code = EQ, branch_code = EQ;
+    mode = DFmode;
   else
     {
-      mode = DImode, compare_code = MINUS, branch_code = NE;
-      if (GET_CODE (alpha_compare_op1) == CONST_INT)
+      mode = DImode;
+      /* We want to use cmpeq/bne when we can, since there is a zero-delay
+	 bypass between logicals and br/cmov on the 21164.  But we don't
+	 want to force valid immediate constants into registers needlessly.  */
+      if (GET_CODE (alpha_compare_op1) == CONST_INT
+	  && ((INTVAL (alpha_compare_op1) >= -0x8000
+	       && INTVAL (alpha_compare_op1) < 0)
+	      || (INTVAL (alpha_compare_op1) > 0xff
+		  && INTVAL (alpha_compare_op1) < 0x8000)))
 	{
-	  compare_code = PLUS;
+	  compare_code = PLUS, branch_code = NE;
 	  alpha_compare_op1 = GEN_INT (- INTVAL (alpha_compare_op1));
 	}
     }



More information about the Gcc mailing list