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]

[PATCH] Sparc .md optimizations (mul/div/shifts)


Hi!

The following patch fixes the specs so that e.g. in the bi-arch compiler
gcc -mv8 does what expected (linux64.h, sol2-sld-64.h). Maybe this part
could go for 2.95 as a bug fix as well.
The other part are optimizations which:
a) make smulcc/udivcc/sdivcc actually match
b) when -mcpu=ultrasparc, use the deprecated *mul* and *div* instructions
   even in 64bit mode, as we know it is a win. E.g. sdiv{cc} is 36, udiv{cc}
   37 and divx is 68 ticks, which is a huge difference in my eyes.
c) During playing with this, I found several places where gcc generated
   two shifts instead of one, e.g.:
	srlx    %g2, 32, %g2
	srl     %g2, 28, %g2
   instead of
	srlx    %g2, 60, %g2
   and similar. I've added patterns to optimize this.

Mon Jun  7 12:42:11 1999  Jakub Jelinek  <jj@ultra.linux.cz>

	* config/sparc/linux64.h (CC1_SPEC): Preserve CPU specified by
	the user if using the non-default arch size in BI_ARCH configuration.
	* config/sparc/sol2-sld-64.h (CC1_SPEC): Ditto.

	* config/sparc/sparc.md (cmp_mul_set, cmp_udiv_cc_set):
	Fix patterns so that they actually match.
	(cmp_sdiv_cc_set): Ditto, also don't require g0 to be zero.
	(mulsidi3_sp64, const_mulsidi3_sp64): New patterns.
	(const_mulsidi3_sp32): Renamed from const_mulsidi3, only on
	TARGET_HARD_MUL32.
	(mulsidi3): Reflect this in the expand.
	(smulsi3_highpart): Only on TARGET_ARCH32.
	(umulsidi3_sp64, const_umulsidi3_sp64): New patterns.
	(const_umulsidi3_sp32): Renamed from const_umulsidi3.
	(umulsidi3): Reflect this in the expand.
	(umulsi3_highpart): Only on TARGET_ARCH32.
	(divsi3_sp32): Renamed from divsi3, only on TARGET_ARCH32,
	don't require g0 to be zero.
	(udivsi3_sp32): Renamed from udivsi3, only on TARGET_ARCH32.
	({,u}divsi3): New expands.
	({,u}divsi3_sp64): New patterns.
	(after lshrdi3_v8plus): Four new patterns to help combiner
	optimizing nested mixed mode shifts.

	* config/sparc/sparc.c (sparc_override_options): Use deprecated
	v8 instructions if optimizing for UltraSPARC I, II, IIi, as it
	speed things up. Don't use them by default on plain v9 in 64bit
	mode, according to what SPAMv9 sais.

	* config/sparc/sparc.h: Fix comments, e.g. Linux already preserves
	top 32 bits of %[og][0-7] in signal handlers.
	Also, TARGET_HARD_MUL32 now is only true for TARGET_ARCH32.

--- config/sparc/linux64.h~	Fri May 28 07:34:15 1999
+++ config/sparc/linux64.h	Mon Jun  7 09:52:55 1999
@@ -225,7 +225,8 @@ Boston, MA 02111-1307, USA.  */
 %{mcypress:-mcpu=cypress} \
 %{msparclite:-mcpu=sparclite} %{mf930:-mcpu=f930} %{mf934:-mcpu=f934} \
 %{mv8:-mcpu=v8} %{msupersparc:-mcpu=supersparc} \
-%{m64:-mptr64 -mcpu=ultrasparc -mstack-bias} \
+%{m64:-mptr64 -mstack-bias \
+  %{!mcpu*:%{!mcypress:%{!msparclite:%{!mf930:%{!mf934:%{!mv8:%{!msupersparc:-mcpu=ultrasparc}}}}}}}} \
 "
 #else
 #define CC1_SPEC "\
@@ -233,7 +234,8 @@ Boston, MA 02111-1307, USA.  */
 %{mcypress:-mcpu=cypress} \
 %{msparclite:-mcpu=sparclite} %{mf930:-mcpu=f930} %{mf934:-mcpu=f934} \
 %{mv8:-mcpu=v8} %{msupersparc:-mcpu=supersparc} \
-%{m32:-mptr32 -mcpu=cypress -mno-stack-bias} \
+%{m32:-mptr32 -mno-stack-bias \
+  %{!mcpu*:%{!mcypress:%{!msparclite:%{!mf930:%{!mf934:%{!mv8:%{!msupersparc:-mcpu=cypress}}}}}}}} \
 "
 #endif
 
--- config/sparc/sol2-sld-64.h~	Wed Dec 16 22:13:25 1998
+++ config/sparc/sol2-sld-64.h	Mon Jun  7 09:59:37 1999
@@ -244,7 +244,8 @@
 %{mcypress:-mcpu=cypress} \
 %{msparclite:-mcpu=sparclite} %{mf930:-mcpu=f930} %{mf934:-mcpu=f934} \
 %{mv8:-mcpu=v8} %{msupersparc:-mcpu=supersparc} \
-%{m64:-mptr64 -mcpu=v9 -mstack-bias -mno-v8plus} \
+%{m64:-mptr64 -mstack-bias -mno-v8plus \
+  %{!mcpu*:%{!mcypress:%{!msparclite:%{!mf930:%{!mf934:%{!mv8*:%{!msupersparc:-mcpu=v9}}}}}}}} \
 "
 #else
 #define CC1_SPEC "\
@@ -252,8 +253,10 @@
 %{mcypress:-mcpu=cypress} \
 %{msparclite:-mcpu=sparclite} %{mf930:-mcpu=f930} %{mf934:-mcpu=f934} \
 %{mv8:-mcpu=v8} %{msupersparc:-mcpu=supersparc} \
-%{m32:-mptr32 -mcpu=cypress -mno-stack-bias} \
-%{mv8plus:-m32 -mptr32 -mcpu=cypress -mno-stack-bias} \
+%{m32:-mptr32 -mno-stack-bias \
+  %{!mcpu*:%{!mcypress:%{!msparclite:%{!mf930:%{!mf934:%{!mv8*:%{!msupersparc:-mcpu=cypress}}}}}}}} \
+%{mv8plus:-m32 -mptr32 -mno-stack-bias \
+  %{!mcpu*:%{!mcypress:%{!msparclite:%{!mf930:%{!mf934:%{!mv8:%{!msupersparc:-mcpu=v9}}}}}}}} \
 "
 #endif
 
--- config/sparc/sparc.md~	Mon Jun  7 09:10:21 1999
+++ config/sparc/sparc.md	Mon Jun  7 12:33:40 1999
@@ -5169,9 +5169,8 @@
 
 ;; Integer Multiply/Divide.
 
-;; The 32 bit multiply/divide instructions are deprecated on v9 and shouldn't
-;; we used.  We still use them in 32 bit v9 compilers.
-;; The 64 bit v9 compiler will (/should) widen the args and use muldi3.
+;; The 32 bit multiply/divide instructions are deprecated on v9, but at
+;; least in UltraSPARC I, II and IIi it is a win tick-wise.
 
 (define_insn "mulsi3"
   [(set (match_operand:SI 0 "register_operand" "=r")
@@ -5229,15 +5228,13 @@
 }"
   [(set_attr "length" "9,8")])
 
-;; It is not known whether this will match.
-
 (define_insn "*cmp_mul_set"
-  [(set (match_operand:SI 0 "register_operand" "=r")
-	(mult:SI (match_operand:SI 1 "arith_operand" "%r")
-		 (match_operand:SI 2 "arith_operand" "rI")))
-   (set (reg:CC_NOOV 100)
-	(compare:CC_NOOV (mult:SI (match_dup 1) (match_dup 2))
-			 (const_int 0)))]
+  [(set (reg:CC 100)
+	(compare:CC (mult:SI (match_operand:SI 1 "arith_operand" "%r")
+		    (match_operand:SI 2 "arith_operand" "rI"))
+		    (const_int 0)))
+   (set (match_operand:SI 0 "register_operand" "=r")
+	(mult:SI (match_dup 1) (match_dup 2)))]
   "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
   "smulcc\\t%1, %2, %0"
   [(set_attr "type" "imul")
@@ -5253,12 +5250,11 @@
   if (CONSTANT_P (operands[2]))
     {
       if (TARGET_V8PLUS)
-	{
-	  emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1],
-						operands[2]));
-	  DONE;
-	}
-      emit_insn (gen_const_mulsidi3 (operands[0], operands[1], operands[2]));
+	emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1],
+					      operands[2]));
+      else
+	emit_insn (gen_const_mulsidi3_sp32 (operands[0], operands[1],
+					    operands[2]));
       DONE;
     }
   if (TARGET_V8PLUS)
@@ -5308,14 +5304,22 @@
 	(if_then_else (eq_attr "isa" "sparclet")
 		      (const_int 1) (const_int 2)))])
 
+(define_insn "*mulsidi3_sp64"
+  [(set (match_operand:DI 0 "register_operand" "=r")
+	(mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
+		 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
+  "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
+  "smul\\t%1, %2, %0"
+  [(set_attr "length" "1")])
+
 ;; Extra pattern, because sign_extend of a constant isn't valid.
 
 ;; XXX
-(define_insn "const_mulsidi3"
+(define_insn "const_mulsidi3_sp32"
   [(set (match_operand:DI 0 "register_operand" "=r")
 	(mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
 		 (match_operand:SI 2 "small_int" "I")))]
-  "TARGET_HARD_MUL"
+  "TARGET_HARD_MUL32"
   "*
 {
   return TARGET_SPARCLET ? \"smuld\\t%1, %2, %L0\" : \"smul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
@@ -5324,13 +5328,21 @@
 	(if_then_else (eq_attr "isa" "sparclet")
 		      (const_int 1) (const_int 2)))])
 
+(define_insn "const_mulsidi3_sp64"
+  [(set (match_operand:DI 0 "register_operand" "=r")
+	(mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
+		 (match_operand:SI 2 "small_int" "I")))]
+  "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
+  "smul\\t%1, %2, %0"
+  [(set_attr "length" "1")])
+
 (define_expand "smulsi3_highpart"
   [(set (match_operand:SI 0 "register_operand" "")
 	(truncate:SI
 	 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
 			       (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
 		      (const_int 32))))]
-  "TARGET_HARD_MUL"
+  "TARGET_HARD_MUL && TARGET_ARCH32"
   "
 {
   if (CONSTANT_P (operands[2]))
@@ -5406,8 +5418,7 @@
 	 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
 			       (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
 		      (const_int 32))))]
-  "TARGET_HARD_MUL32
-   && ! TARGET_LIVE_G0"
+  "TARGET_HARD_MUL32 && ! TARGET_LIVE_G0"
   "smul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
   [(set_attr "length" "2")])
 
@@ -5418,8 +5429,7 @@
 	 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
 			       (match_operand:SI 2 "register_operand" "r"))
 		      (const_int 32))))]
-  "TARGET_HARD_MUL32
-   && ! TARGET_LIVE_G0"
+  "TARGET_HARD_MUL32 && ! TARGET_LIVE_G0"
   "smul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
   [(set_attr "length" "2")])
 
@@ -5433,12 +5443,11 @@
   if (CONSTANT_P (operands[2]))
     {
       if (TARGET_V8PLUS)
-	{
-	  emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1],
-						 operands[2]));
-	  DONE;
-	}
-      emit_insn (gen_const_umulsidi3 (operands[0], operands[1], operands[2]));
+	emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1],
+					       operands[2]));
+      else
+	emit_insn (gen_const_umulsidi3_sp32 (operands[0], operands[1],
+					     operands[2]));
       DONE;
     }
   if (TARGET_V8PLUS)
@@ -5474,10 +5483,18 @@
 	(if_then_else (eq_attr "isa" "sparclet")
 		      (const_int 1) (const_int 2)))])
 
+(define_insn "*umulsidi3_sp64"
+  [(set (match_operand:DI 0 "register_operand" "=r")
+	(mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
+		 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
+  "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
+  "umul\\t%1, %2, %0"
+  [(set_attr "length" "1")])
+
 ;; Extra pattern, because sign_extend of a constant isn't valid.
 
 ;; XXX
-(define_insn "const_umulsidi3"
+(define_insn "const_umulsidi3_sp32"
   [(set (match_operand:DI 0 "register_operand" "=r")
 	(mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
 		 (match_operand:SI 2 "uns_small_int" "")))]
@@ -5490,6 +5507,14 @@
 	(if_then_else (eq_attr "isa" "sparclet")
 		      (const_int 1) (const_int 2)))])
 
+(define_insn "const_umulsidi3_sp64"
+  [(set (match_operand:DI 0 "register_operand" "=r")
+	(mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
+		 (match_operand:SI 2 "uns_small_int" "")))]
+  "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
+  "umul\\t%1, %2, %0"
+  [(set_attr "length" "1")])
+
 ;; XXX
 (define_insn "const_umulsidi3_v8plus"
   [(set (match_operand:DI 0 "register_operand" "=h,r")
@@ -5508,7 +5533,7 @@
 	 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
 			       (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
 		      (const_int 32))))]
-  "TARGET_HARD_MUL"
+  "TARGET_HARD_MUL && TARGET_ARCH32"
   "
 {
   if (CONSTANT_P (operands[2]))
@@ -5567,8 +5592,7 @@
 	 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
 			       (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
 		      (const_int 32))))]
-  "TARGET_HARD_MUL32
-   && ! TARGET_LIVE_G0"
+  "TARGET_HARD_MUL32 && ! TARGET_LIVE_G0"
   "umul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
   [(set_attr "length" "2")])
 
@@ -5579,40 +5603,64 @@
 	 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
 			       (match_operand:SI 2 "uns_small_int" ""))
 		      (const_int 32))))]
-  "TARGET_HARD_MUL32
-   && ! TARGET_LIVE_G0"
+  "TARGET_HARD_MUL32 && ! TARGET_LIVE_G0"
   "umul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
   [(set_attr "length" "2")])
 
 ;; The v8 architecture specifies that there must be 3 instructions between
 ;; a y register write and a use of it for correct results.
 
-;; XXX SHEESH
-(define_insn "divsi3"
+(define_expand "divsi3"
+  [(parallel [(set (match_operand:SI 0 "register_operand" "=r,r")
+		   (div:SI (match_operand:SI 1 "register_operand" "r,r")
+			   (match_operand:SI 2 "input_operand" "rI,m")))
+	      (clobber (match_scratch:SI 3 "=&r,&r"))])]
+  "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
+  "
+{
+  if (TARGET_ARCH64)
+    {
+      operands[3] = gen_reg_rtx(SImode);
+      emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31)));
+      emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2],
+				  operands[3]));
+      DONE;
+    }
+}")
+
+(define_insn "divsi3_sp32"
   [(set (match_operand:SI 0 "register_operand" "=r,r")
 	(div:SI (match_operand:SI 1 "register_operand" "r,r")
 		(match_operand:SI 2 "input_operand" "rI,m")))
    (clobber (match_scratch:SI 3 "=&r,&r"))]
-  "(TARGET_V8
-    || TARGET_DEPRECATED_V8_INSNS)
-   && ! TARGET_LIVE_G0"
+  "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS)
+   && TARGET_ARCH32"
   "*
 {
   if (which_alternative == 0)
-  if (TARGET_V9)
-    return \"sra\\t%1, 31, %3\\n\\twr\\t%%g0, %3, %%y\\n\\tsdiv\\t%1, %2, %0\";
-  else
-    return \"sra\\t%1, 31, %3\\n\\twr\\t%%g0, %3, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tsdiv\\t%1, %2, %0\";
+    if (TARGET_V9)
+      return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tsdiv\\t%1, %2, %0\";
+    else
+      return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tsdiv\\t%1, %2, %0\";
   else
     if (TARGET_V9)
-      return \"sra\\t%1, 31, %3\\n\\twr\\t%%g0, %3, %%y\\n\\tld\\t%2, %3\\n\\tsdiv\\t%1, %3, %0\";
+      return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tld\\t%2, %3\\n\\tsdiv\\t%1, %3, %0\";
     else
-      return \"sra\\t%1, 31, %3\\n\\twr\\t%%g0, %3, %%y\\n\\tld\\t%2, %3\\n\\tnop\\n\\tnop\\n\\tsdiv\\t%1, %3, %0\";
+      return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tld\\t%2, %3\\n\\tnop\\n\\tnop\\n\\tsdiv\\t%1, %3, %0\";
 }"
   [(set (attr "length")
 	(if_then_else (eq_attr "isa" "v9")
 		      (const_int 4) (const_int 7)))])
 
+(define_insn "divsi3_sp64"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+	(div:SI (match_operand:SI 1 "register_operand" "r")
+		(match_operand:SI 2 "input_operand" "rI")))
+   (use (match_operand:SI 3 "register_operand" "r"))]
+  "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
+  "wr\\t%%g0, %3, %%y\\n\\tsdiv\\t%1, %2, %0"
+  [(set_attr "length" "2")])
+
 (define_insn "divdi3"
   [(set (match_operand:DI 0 "register_operand" "=r")
 	(div:DI (match_operand:DI 1 "register_operand" "r")
@@ -5620,47 +5668,47 @@
   "TARGET_ARCH64"
   "sdivx\\t%1, %2, %0")
 
-;; It is not known whether this will match.
-
-;; XXX I hope it doesn't fucking match...
 (define_insn "*cmp_sdiv_cc_set"
-  [(set (match_operand:SI 0 "register_operand" "=r")
-	(div:SI (match_operand:SI 1 "register_operand" "r")
-		(match_operand:SI 2 "arith_operand" "rI")))
-   (set (reg:CC 100)
-	(compare:CC (div:SI (match_dup 1) (match_dup 2))
+  [(set (reg:CC 100)
+	(compare:CC (div:SI (match_operand:SI 1 "register_operand" "r")
+			    (match_operand:SI 2 "arith_operand" "rI"))
 		    (const_int 0)))
+   (set (match_operand:SI 0 "register_operand" "=r")
+	(div:SI (match_dup 1) (match_dup 2)))
    (clobber (match_scratch:SI 3 "=&r"))]
-  "(TARGET_V8
-    || TARGET_DEPRECATED_V8_INSNS)
-   && ! TARGET_LIVE_G0"
+  "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
   "*
 {
   if (TARGET_V9)
-    return \"sra\\t%1, 31, %3\\n\\twr\\t%%g0, %3, %%y\\n\\tsdivcc\\t%1, %2, %0\";
+    return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tsdivcc\\t%1, %2, %0\";
   else
-    return \"sra\\t%1, 31, %3\\n\\twr\\t%%g0, %3, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tsdivcc\\t%1, %2, %0\";
+    return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tsdivcc\\t%1, %2, %0\";
 }"
   [(set (attr "length")
 	(if_then_else (eq_attr "isa" "v9")
 		      (const_int 3) (const_int 6)))])
 
 ;; XXX
-(define_insn "udivsi3"
+(define_expand "udivsi3"
+  [(set (match_operand:SI 0 "register_operand" "")
+	(udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "")
+		 (match_operand:SI 2 "input_operand" "")))]
+  "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS) && ! TARGET_LIVE_G0"
+  "")
+
+(define_insn "udivsi3_sp32"
   [(set (match_operand:SI 0 "register_operand" "=r,&r,&r")
 	(udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r,r,m")
 		 (match_operand:SI 2 "input_operand" "rI,m,r")))]
   "(TARGET_V8
     || TARGET_DEPRECATED_V8_INSNS)
-   && ! TARGET_LIVE_G0"
+   && TARGET_ARCH32 && ! TARGET_LIVE_G0"
   "*
 {
   output_asm_insn (\"wr\\t%%g0, %%g0, %%y\", operands);
   switch (which_alternative)
     {
     default:
-  if (TARGET_V9)
-	return \"udiv\\t%1, %2, %0\";
       return \"nop\\n\\tnop\\n\\tnop\\n\\tudiv\\t%1, %2, %0\";
     case 1:
       return \"ld\\t%2, %0\\n\\tnop\\n\\tnop\\n\\tudiv\\t%1, %0, %0\";
@@ -5668,10 +5716,15 @@
       return \"ld\\t%1, %0\\n\\tnop\\n\\tnop\\n\\tudiv\\t%0, %2, %0\";
     }
 }"
-  [(set (attr "length")
-	(if_then_else (and (eq_attr "isa" "v9")
-			   (eq_attr "alternative" "0"))
-		      (const_int 2) (const_int 5)))])
+  [(set_attr "length" "5")])
+
+(define_insn "udivsi3_sp64"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+	(udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r")
+		 (match_operand:SI 2 "input_operand" "rI")))]
+  "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
+  "wr\\t%%g0, 0, %%y\\n\\tudiv\\t%1, %2, %0"
+  [(set_attr "length" "2")])
 
 (define_insn "udivdi3"
   [(set (match_operand:DI 0 "register_operand" "=r")
@@ -5680,16 +5733,13 @@
   "TARGET_ARCH64"
   "udivx\\t%1, %2, %0")
 
-;; It is not known whether this will match.
-
-;; XXX I hope it doesn't fucking match...
 (define_insn "*cmp_udiv_cc_set"
-  [(set (match_operand:SI 0 "register_operand" "=r")
-	(udiv:SI (match_operand:SI 1 "register_operand" "r")
-		(match_operand:SI 2 "arith_operand" "rI")))
-   (set (reg:CC 100)
-	(compare:CC (udiv:SI (match_dup 1) (match_dup 2))
-		    (const_int 0)))]
+  [(set (reg:CC 100)
+	(compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r")
+			     (match_operand:SI 2 "arith_operand" "rI"))
+		    (const_int 0)))
+   (set (match_operand:SI 0 "register_operand" "=r")
+	(udiv:SI (match_dup 1) (match_dup 2)))]
   "(TARGET_V8
     || TARGET_DEPRECATED_V8_INSNS)
    && ! TARGET_LIVE_G0"
@@ -7251,6 +7301,84 @@
   "TARGET_V8PLUS"
   "*return sparc_v8plus_shift (operands, insn, \"srlx\");"
   [(set_attr "length" "5,5,6")])
+
+(define_insn ""
+  [(set (match_operand:SI 0 "register_operand" "=r")
+	(ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
+					     (const_int 32)) 0)
+		     (match_operand:SI 2 "small_int_or_double" "n")))]
+  "TARGET_ARCH64
+   && ((GET_CODE (operands[2]) == CONST_INT
+        && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
+       || (GET_CODE (operands[2]) == CONST_DOUBLE
+	   && !CONST_DOUBLE_HIGH (operands[2])
+           && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
+  "*
+{
+  operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
+
+  return \"srax\\t%1, %2, %0\";
+}"
+  [(set_attr "type" "shift")
+   (set_attr "length" "1")])
+
+(define_insn ""
+  [(set (match_operand:SI 0 "register_operand" "=r")
+	(lshiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
+					     (const_int 32)) 0)
+		     (match_operand:SI 2 "small_int_or_double" "n")))]
+  "TARGET_ARCH64
+   && ((GET_CODE (operands[2]) == CONST_INT
+        && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
+       || (GET_CODE (operands[2]) == CONST_DOUBLE
+	   && !CONST_DOUBLE_HIGH (operands[2])
+           && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
+  "*
+{
+  operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
+
+  return \"srlx\\t%1, %2, %0\";
+}"
+  [(set_attr "type" "shift")
+   (set_attr "length" "1")])
+
+(define_insn ""
+  [(set (match_operand:SI 0 "register_operand" "=r")
+	(ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
+					     (match_operand:SI 2 "small_int_or_double" "n")) 0)
+		     (match_operand:SI 3 "small_int_or_double" "n")))]
+  "TARGET_ARCH64
+   && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT
+   && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
+   && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
+   && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
+  "*
+{
+  operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
+
+  return \"srax\\t%1, %2, %0\";
+}"
+  [(set_attr "type" "shift")
+   (set_attr "length" "1")])
+
+(define_insn ""
+  [(set (match_operand:SI 0 "register_operand" "=r")
+	(lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
+					     (match_operand:SI 2 "small_int_or_double" "n")) 0)
+		     (match_operand:SI 3 "small_int_or_double" "n")))]
+  "TARGET_ARCH64
+   && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT
+   && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
+   && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
+   && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
+  "*
+{
+  operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
+
+  return \"srlx\\t%1, %2, %0\";
+}"
+  [(set_attr "type" "shift")
+   (set_attr "length" "1")])
 
 ;; Unconditional and other jump instructions
 ;; On the Sparc, by setting the annul bit on an unconditional branch, the
--- config/sparc/sparc.c~	Sun Apr 18 15:09:33 1999
+++ config/sparc/sparc.c	Mon Jun  7 10:03:41 1999
@@ -212,8 +212,11 @@ sparc_override_options ()
     /* TEMIC sparclet */
     { "tsc701",     PROCESSOR_TSC701, MASK_ISA, MASK_SPARCLET },
     { "v9",         PROCESSOR_V9, MASK_ISA, MASK_V9 },
-    /* TI ultrasparc */
-    { "ultrasparc", PROCESSOR_ULTRASPARC, MASK_ISA, MASK_V9 },
+    /* TI ultrasparc I, II, IIi */
+    { "ultrasparc", PROCESSOR_ULTRASPARC, MASK_ISA, MASK_V9
+    /* Although insns using %y are deprecated, it is a clear win on current
+       ultrasparcs. */
+    						    |MASK_DEPRECATED_V8_INSNS },
     { 0, 0, 0, 0 }
   };
   struct cpu_table *cpu;
--- config/sparc/sparc.h~	Mon Jun  7 09:21:43 1999
+++ config/sparc/sparc.h	Mon Jun  7 10:03:41 1999
@@ -50,11 +50,11 @@ Boston, MA 02111-1307, USA.  */
 
 /* Code model selection.
    -mcmodel is used to select the v9 code model.
-   Different code models aren't supported for v8 code.
+   Different code models aren't supported for v7/8 code.
 
    TARGET_CM_32:     32 bit address space, top 32 bits = 0,
 		     pointers are 32 bits.  Note that this isn't intended
-                     to imply a v8 abi.
+                     to imply a v7/8 abi.
 
    TARGET_CM_MEDLOW: 32 bit address space, top 32 bits = 0,
                      avoid generating %uhi and %ulo terms,
@@ -542,9 +542,8 @@ extern int target_flags;
 #define TARGET_VIS (target_flags & MASK_VIS)
 
 /* Compile for Solaris V8+.  32 bit Solaris preserves the high bits of
-   the current out and global registers.  Linux saves the high bits on
-   context switches but not signals.  */
-#define MASK_V8PLUS 0x2000000                 
+   the current out and global registers and Linux 2.2+ as well.  */
+#define MASK_V8PLUS 0x2000000
 #define TARGET_V8PLUS (target_flags & MASK_V8PLUS)                            
 
 /* TARGET_HARD_MUL: Use hardware multiply instructions but not %y.
@@ -555,7 +554,7 @@ extern int target_flags;
 #define TARGET_HARD_MUL32				\
   ((TARGET_V8 || TARGET_SPARCLITE			\
     || TARGET_SPARCLET || TARGET_DEPRECATED_V8_INSNS)	\
-   && ! TARGET_V8PLUS)
+   && ! TARGET_V8PLUS && TARGET_ARCH32)
 
 #define TARGET_HARD_MUL					\
   (TARGET_V8 || TARGET_SPARCLITE || TARGET_SPARCLET	\

Cheers,
    Jakub
___________________________________________________________________
Jakub Jelinek | jj@sunsite.mff.cuni.cz | http://sunsite.mff.cuni.cz
Administrator of SunSITE Czech Republic, MFF, Charles University
___________________________________________________________________
UltraLinux  |  http://ultra.linux.cz/  |  http://ultra.penguin.cz/
Linux version 2.3.4 on a sparc64 machine (1343.49 BogoMips)
___________________________________________________________________


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