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]

[power7-meissner] Fix xxpermdi instruciton on power7


This patch fixes the xxpermdi instruction generation to match the hardware, and
allows 6 of the Spec 2006 benchmarks to validate.

2009-03-10  Michael Meissner  <meissner@linux.vnet.ibm.com>

	* config/rs6000/vsx.md (vsx_concat_v2df): Add explicit 'f'
	register class for scalar data, correct uses of the xxpermdi
	instruction.
	(vsx_set_v2df): Ditto.
	(vsx_extract_v2df): Ditto.
	(vsx_xxpermdi): Ditto.
	(vsx_splatv2df): Ditto.
	(vsx_xxmrghw): Use wf instead of v constraints.
	(vsx_xxmrglw): Ditto.

Index: gcc/config/rs6000/vsx.md
===================================================================
--- gcc/config/rs6000/vsx.md	(revision 144734)
+++ gcc/config/rs6000/vsx.md	(working copy)
@@ -753,8 +753,8 @@
 (define_insn "vsx_concat_v2df"
   [(set (match_operand:V2DF 0 "vsx_register_operand" "=wd,?wa")
 	(unspec:V2DF
-	 [(match_operand:DF 1 "vsx_register_operand" "f,wa")
-	  (match_operand:DF 2 "vsx_register_operand" "f,wa")]
+	 [(match_operand:DF 1 "vsx_register_operand" "ws,wa")
+	  (match_operand:DF 2 "vsx_register_operand" "ws,wa")]
 	 UNSPEC_VSX_CONCAT_V2DF))]
   "VECTOR_UNIT_VSX_P (V2DFmode)"
   "xxpermdi %x0,%x1,%x2,0"
@@ -762,32 +762,37 @@
 
 ;; Set a double into one element
 (define_insn "vsx_set_v2df"
-  [(set (match_operand:V2DF 0 "vsx_register_operand" "=wd")
+  [(set (match_operand:V2DF 0 "vsx_register_operand" "=wd,?wa")
 	(vec_merge:V2DF
-	 (match_operand:V2DF 1 "vsx_register_operand" "wd")
-	 (vec_duplicate:V2DF (match_operand:DF 2 "vsx_register_operand" "ws"))
-	 (match_operand:QI 3 "u5bit_cint_operand" "i")))]
+	 (match_operand:V2DF 1 "vsx_register_operand" "wd,wa")
+	 (vec_duplicate:V2DF (match_operand:DF 2 "vsx_register_operand" "ws,f"))
+	 (match_operand:QI 3 "u5bit_cint_operand" "i,i")))]
   "VECTOR_UNIT_VSX_P (V2DFmode)"
 {
-  operands[3] = GEN_INT (INTVAL (operands[3]) & 1);
-  return \"xxpermdi %x0,%x1,%x2,%3\";
+  if (INTVAL (operands[3]) == 0)
+    return \"xxpermdi %x0,%x1,%x2,1\";
+  else if (INTVAL (operands[3]) == 1)
+    return \"xxpermdi %x0,%x2,%x1,0\";
+  else
+    gcc_unreachable ();
 }
   [(set_attr "type" "vecperm")])
 
 ;; Extract a DF element from V2DF
 (define_insn "vsx_extract_v2df"
-  [(set (match_operand:DF 0 "vsx_register_operand" "=ws")
-	(vec_select:DF (match_operand:V2DF 1 "vsx_register_operand" "wd")
+  [(set (match_operand:DF 0 "vsx_register_operand" "=ws,f,?wa")
+	(vec_select:DF (match_operand:V2DF 1 "vsx_register_operand" "wd,wd,wa")
 		       (parallel
-			[(match_operand:QI 2 "u5bit_cint_operand" "i")])))]
+			[(match_operand:QI 2 "u5bit_cint_operand" "i,i,i")])))]
   "VECTOR_UNIT_VSX_P (V2DFmode)"
 {
-  operands[3] = GEN_INT (INTVAL (operands[2]) & 1);
+  gcc_assert (UINTVAL (operands[2]) <= 1);
+  operands[3] = GEN_INT (INTVAL (operands[2]) << 1);
   return \"xxpermdi %x0,%x1,%x1,%3\";
 }
   [(set_attr "type" "vecperm")])
 
-;; General V2DF permute
+;; General V2DF permute, extract_{high,low,even,odd}
 (define_insn "vsx_xxpermdi"
   [(set (match_operand:V2DF 0 "vsx_register_operand" "=wd")
 	(vec_concat:V2DF
@@ -799,6 +804,7 @@
 			 [(match_operand:QI 4 "u5bit_cint_operand" "i")]))))]
   "VECTOR_UNIT_VSX_P (V2DFmode)"
 {
+  gcc_assert ((UINTVAL (operands[2]) <= 1) && (UINTVAL (operands[4]) <= 1));
   operands[5] = GEN_INT (((INTVAL (operands[2]) & 1) << 1)
 			 | (INTVAL (operands[4]) & 1));
   return \"xxpermdi %x0,%x1,%x3,%5\";
@@ -807,14 +813,15 @@
 
 ;; V2DF splat
 (define_insn "vsx_splatv2df"
-  [(set (match_operand:V2DF 0 "vsx_register_operand" "=wd,wd")
+  [(set (match_operand:V2DF 0 "vsx_register_operand" "=wd,wd,wd")
 	(vec_duplicate:V2DF
-	 (match_operand:DF 1 "input_operand" "ws,Z")))]
+	 (match_operand:DF 1 "input_operand" "ws,f,Z")))]
   "VECTOR_UNIT_VSX_P (V2DFmode)"
   "@
    xxpermdi %x0,%x1,%x1,0
+   xxpermdi %x0,%x1,%x1,0
    lxvdsx %x0,%y1"
-  [(set_attr "type" "vecperm,vecload")])
+  [(set_attr "type" "vecperm,vecperm,vecload")])
 
 ;; V4SF splat
 (define_insn "*vsx_xxspltw"
@@ -829,13 +836,13 @@
 
 ;; V4SF interleave
 (define_insn "*vsx_xxmrghw"
-  [(set (match_operand:V4SF 0 "register_operand" "=v")
-        (vec_merge:V4SF (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "v")
+  [(set (match_operand:V4SF 0 "register_operand" "=wf")
+        (vec_merge:V4SF (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "wf")
                                          (parallel [(const_int 0)
                                                     (const_int 2)
                                                     (const_int 1)
                                                     (const_int 3)]))
-                        (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "v")
+                        (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "wf")
                                          (parallel [(const_int 2)
                                                     (const_int 0)
                                                     (const_int 3)
@@ -846,14 +853,14 @@
   [(set_attr "type" "vecperm")])
 
 (define_insn "*vsx_xxmrglw"
-  [(set (match_operand:V4SF 0 "register_operand" "=v")
+  [(set (match_operand:V4SF 0 "register_operand" "=wf")
         (vec_merge:V4SF
-	 (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "v")
+	 (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "wf")
 			  (parallel [(const_int 2)
 				     (const_int 0)
 				     (const_int 3)
 				     (const_int 1)]))
-	 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "v")
+	 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "wf")
 			  (parallel [(const_int 0)
 				     (const_int 2)
 				     (const_int 1)


-- 
Michael Meissner, IBM
4 Technology Place Drive, MS 2203A, Westford, MA, 01886, USA
meissner@linux.vnet.ibm.com


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