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] Fix FAIL of gcc.target/sparc/pdist-3.c (PR 35574) (Take 3)


Hi,

Attached is a revised patch to fix PR 35574.

The previous version of the patch was posted at:

http://gcc.gnu.org/ml/gcc-patches/2008-10/msg00787.html

In this iteration, I have:

- added the 'D' constraint to accept any integer const_vector,

- used simplify_subreg in the V64mode splitter, and

- created a mainline version of this patch.

Tested on sparc.  OK to apply to 4.3 and mainline?

Kazu Hirata

gcc-4.3
2008-11-05  Kazu Hirata  <kazu@codesourcery.com>

	PR target/35574
	* config/sparc/predicates.md (const_double_or_vector_operand):
	New.
	* config/sparc/sparc.c (sparc_extra_constraint_check): Handle the
	'D' constraint.
	* config/sparc/sparc.h: Document the 'D' constraint.
	* config/sparc/sparc.md (*movdf_insn_sp32_v9, *movdf_insn_sp64):
	Use the 'D' constraint in addition to 'F' in some alternatives.
	(DF splitter): Generalize for V64mode.
	* doc/md.texi (SPARC): Document the 'D' constraint.

Index: gcc/config/sparc/predicates.md
===================================================================
--- gcc/config/sparc/predicates.md	(revision 226562)
+++ gcc/config/sparc/predicates.md	(working copy)
@@ -475,3 +475,7 @@ (define_predicate "memory_reg_operand"
   (and (match_code "mem")
        (and (match_operand 0 "memory_operand")
 	    (match_test "REG_P (XEXP (op, 0))"))))
+
+;; Return true if OP is a const_double or const_vector.
+(define_predicate "const_double_or_vector_operand"
+  (match_code "const_double,const_vector"))
Index: gcc/config/sparc/sparc.c
===================================================================
--- gcc/config/sparc/sparc.c	(revision 226562)
+++ gcc/config/sparc/sparc.c	(working copy)
@@ -8339,6 +8339,10 @@ sparc_extra_constraint_check (rtx op, in
 
   switch (c)
     {
+    case 'D':
+      return (GET_MODE_CLASS (GET_MODE (op)) == MODE_VECTOR_INT
+	      && GET_CODE (op) == CONST_VECTOR);
+
     case 'Q':
       return fp_sethi_p (op);
 
Index: gcc/config/sparc/sparc.h
===================================================================
--- gcc/config/sparc/sparc.h	(revision 226562)
+++ gcc/config/sparc/sparc.h	(working copy)
@@ -1870,6 +1870,8 @@ do {									\
 
 /* Optional extra constraints for this machine.
 
+   'D' handles the const_vector.
+
    'Q' handles floating point constants which can be moved into
        an integer register with a single sethi instruction.
 
Index: gcc/config/sparc/sparc.md
===================================================================
--- gcc/config/sparc/sparc.md	(revision 226562)
+++ gcc/config/sparc/sparc.md	(working copy)
@@ -2531,7 +2531,7 @@ (define_insn "*movdf_insn_sp32_no_fpu"
 ;; We have available v9 double floats but not 64-bit integer registers.
 (define_insn "*movdf_insn_sp32_v9"
   [(set (match_operand:V64 0 "nonimmediate_operand" "=b,e,e,T,W,U,T,f,*r,o")
-        (match_operand:V64 1 "input_operand" "GY,e,W#F,GY,e,T,U,o#F,*roGYF,*rGYf"))]
+        (match_operand:V64 1 "input_operand" "GY,e,W#F,GY,e,T,U,o#F,*roGYDF,*rGYf"))]
   "TARGET_FPU
    && TARGET_V9
    && ! TARGET_ARCH64
@@ -2572,7 +2572,7 @@ (define_insn "*movdf_insn_sp32_v9_no_fpu
 ;; We have available both v9 double floats and 64-bit integer registers.
 (define_insn "*movdf_insn_sp64"
   [(set (match_operand:V64 0 "nonimmediate_operand" "=b,e,e,W,*r,*r,m,*r")
-        (match_operand:V64 1 "input_operand"    "GY,e,W#F,e,*rGY,m,*rGY,F"))]
+        (match_operand:V64 1 "input_operand"    "GY,e,W#F,e,*rGY,m,*rGY,DF"))]
   "TARGET_FPU
    && TARGET_ARCH64
    && (register_operand (operands[0], <V64:MODE>mode)
@@ -2603,22 +2603,17 @@ (define_insn "*movdf_insn_sp64_no_fpu"
   stx\t%r1, %0"
   [(set_attr "type" "*,load,store")])
 
-;; This pattern build DFmode constants in integer registers.
+;; This pattern builds V64mode constants in integer registers.
 (define_split
-  [(set (match_operand:DF 0 "register_operand" "")
-        (match_operand:DF 1 "const_double_operand" ""))]
+  [(set (match_operand:V64 0 "register_operand" "")
+        (match_operand:V64 1 "const_double_or_vector_operand" ""))]
   "TARGET_FPU
    && (GET_CODE (operands[0]) == REG
        && REGNO (operands[0]) < 32)
-   && ! const_zero_operand(operands[1], DFmode)
+   && ! const_zero_operand (operands[1], GET_MODE (operands[0]))
    && reload_completed"
   [(clobber (const_int 0))]
 {
-  REAL_VALUE_TYPE r;
-  long l[2];
-
-  REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
-  REAL_VALUE_TO_TARGET_DOUBLE (r, l);
   operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0]));
 
   if (TARGET_ARCH64)
@@ -2626,31 +2621,34 @@ (define_split
 #if HOST_BITS_PER_WIDE_INT == 32
       gcc_unreachable ();
 #else
-      HOST_WIDE_INT val;
-
-      val = ((HOST_WIDE_INT)(unsigned long)l[1] |
-             ((HOST_WIDE_INT)(unsigned long)l[0] << 32));
-      emit_insn (gen_movdi (operands[0], gen_int_mode (val, DImode)));
+      enum machine_mode mode = GET_MODE (operands[1]);
+      rtx tem = simplify_subreg (DImode, operands[1], mode, 0);
+      emit_insn (gen_movdi (operands[0], tem));
 #endif
     }
   else
     {
-      emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
-			    gen_int_mode (l[0], SImode)));
+      enum machine_mode mode = GET_MODE (operands[1]);
+      rtx hi = simplify_subreg (SImode, operands[1], mode, 0);
+      rtx lo = simplify_subreg (SImode, operands[1], mode, 4);
+
+      gcc_assert (GET_CODE (hi) == CONST_INT);
+      gcc_assert (GET_CODE (lo) == CONST_INT);
+
+      emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), hi));
 
       /* Slick... but this trick loses if this subreg constant part
          can be done in one insn.  */
-      if (l[1] == l[0]
-	  && ! SPARC_SETHI32_P (l[0])
-	  && ! SPARC_SIMM13_P (l[0]))
+      if (lo == hi
+	  && ! SPARC_SETHI32_P (INTVAL (hi))
+	  && ! SPARC_SIMM13_P (INTVAL (hi)))
         {
           emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
 			        gen_highpart (SImode, operands[0])));
         }
       else
         {
-          emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
-			        gen_int_mode (l[1], SImode)));
+          emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), lo));
         }
     }
   DONE;
Index: gcc/doc/md.texi
===================================================================
--- gcc/doc/md.texi	(revision 226562)
+++ gcc/doc/md.texi	(working copy)
@@ -2722,6 +2722,9 @@ when the Visual Instruction Set is avail
 @item h
 64-bit global or out register for the SPARC-V8+ architecture.
 
+@item D
+A vector constant
+
 @item I
 Signed 13-bit constant
 
gcc-mainline
2008-11-05  Kazu Hirata  <kazu@codesourcery.com>

	PR target/35574
	* config/sparc/constraints.md (D): New.
	* config/sparc/predicates.md (const_double_or_vector_operand):
	New.
	* config/sparc/sparc.c (sparc_extra_constraint_check): Handle the
	'D' constraint.
	* config/sparc/sparc.md (*movdf_insn_sp32_v9, *movdf_insn_sp64):
	Use the 'D' constraint in addition to 'F' in some alternatives.
	(DF splitter): Generalize for V64mode.
	* doc/md.texi (SPARC): Document the 'D' constraint.

Index: gcc/config/sparc/constraints.md
===================================================================
--- gcc/config/sparc/constraints.md	(revision 141527)
+++ gcc/config/sparc/constraints.md	(working copy)
@@ -100,6 +100,11 @@ (define_constraint "O"
 ;; Our memory extra constraints have to emulate the behavior of 'm' and 'o',
 ;; i.e. accept pseudo-registers during reload.
 
+(define_constraint "D"
+ "const_vector"
+  (and (match_code "const_vector")
+       (match_test "GET_MODE_CLASS (GET_MODE (op)) == MODE_VECTOR_INT")))
+
 (define_constraint "Q"
  "Floating-point constant that can be loaded with a sethi instruction"
  (and (match_code "const_double")
Index: gcc/config/sparc/predicates.md
===================================================================
--- gcc/config/sparc/predicates.md	(revision 141527)
+++ gcc/config/sparc/predicates.md	(working copy)
@@ -475,3 +475,7 @@ (define_predicate "memory_reg_operand"
   (and (match_code "mem")
        (and (match_operand 0 "memory_operand")
 	    (match_test "REG_P (XEXP (op, 0))"))))
+
+;; Return true if OP is a const_double or const_vector.
+(define_predicate "const_double_or_vector_operand"
+  (match_code "const_double,const_vector"))
Index: gcc/config/sparc/sparc.md
===================================================================
--- gcc/config/sparc/sparc.md	(revision 141527)
+++ gcc/config/sparc/sparc.md	(working copy)
@@ -2571,7 +2571,7 @@ (define_insn "*movdf_insn_sp32_no_fpu"
 ;; We have available v9 double floats but not 64-bit integer registers.
 (define_insn "*movdf_insn_sp32_v9"
   [(set (match_operand:V64 0 "nonimmediate_operand" "=b,e,e,T,W,U,T,f,*r,o")
-        (match_operand:V64 1 "input_operand" "GY,e,W#F,GY,e,T,U,o#F,*roGYF,*rGYf"))]
+        (match_operand:V64 1 "input_operand" "GY,e,W#F,GY,e,T,U,o#F,*roGYDF,*rGYf"))]
   "TARGET_FPU
    && TARGET_V9
    && ! TARGET_ARCH64
@@ -2612,7 +2612,7 @@ (define_insn "*movdf_insn_sp32_v9_no_fpu
 ;; We have available both v9 double floats and 64-bit integer registers.
 (define_insn "*movdf_insn_sp64"
   [(set (match_operand:V64 0 "nonimmediate_operand" "=b,e,e,W,*r,*r,m,*r")
-        (match_operand:V64 1 "input_operand"    "GY,e,W#F,e,*rGY,m,*rGY,F"))]
+        (match_operand:V64 1 "input_operand"    "GY,e,W#F,e,*rGY,m,*rGY,DF"))]
   "TARGET_FPU
    && TARGET_ARCH64
    && (register_operand (operands[0], <V64:MODE>mode)
@@ -2643,22 +2643,17 @@ (define_insn "*movdf_insn_sp64_no_fpu"
   stx\t%r1, %0"
   [(set_attr "type" "*,load,store")])
 
-;; This pattern build DFmode constants in integer registers.
+;; This pattern builds V64mode constants in integer registers.
 (define_split
-  [(set (match_operand:DF 0 "register_operand" "")
-        (match_operand:DF 1 "const_double_operand" ""))]
+  [(set (match_operand:V64 0 "register_operand" "")
+        (match_operand:V64 1 "const_double_or_vector_operand" ""))]
   "TARGET_FPU
    && (GET_CODE (operands[0]) == REG
        && REGNO (operands[0]) < 32)
-   && ! const_zero_operand(operands[1], DFmode)
+   && ! const_zero_operand (operands[1], GET_MODE (operands[0]))
    && reload_completed"
   [(clobber (const_int 0))]
 {
-  REAL_VALUE_TYPE r;
-  long l[2];
-
-  REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
-  REAL_VALUE_TO_TARGET_DOUBLE (r, l);
   operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0]));
 
   if (TARGET_ARCH64)
@@ -2666,31 +2661,34 @@ (define_split
 #if HOST_BITS_PER_WIDE_INT == 32
       gcc_unreachable ();
 #else
-      HOST_WIDE_INT val;
-
-      val = ((HOST_WIDE_INT)(unsigned long)l[1] |
-             ((HOST_WIDE_INT)(unsigned long)l[0] << 32));
-      emit_insn (gen_movdi (operands[0], gen_int_mode (val, DImode)));
+      enum machine_mode mode = GET_MODE (operands[1]);
+      rtx tem = simplify_subreg (DImode, operands[1], mode, 0);
+      emit_insn (gen_movdi (operands[0], tem));
 #endif
     }
   else
     {
-      emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
-			    gen_int_mode (l[0], SImode)));
+      enum machine_mode mode = GET_MODE (operands[1]);
+      rtx hi = simplify_subreg (SImode, operands[1], mode, 0);
+      rtx lo = simplify_subreg (SImode, operands[1], mode, 4);
+
+      gcc_assert (GET_CODE (hi) == CONST_INT);
+      gcc_assert (GET_CODE (lo) == CONST_INT);
+
+      emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), hi));
 
       /* Slick... but this trick loses if this subreg constant part
          can be done in one insn.  */
-      if (l[1] == l[0]
-	  && ! SPARC_SETHI32_P (l[0])
-	  && ! SPARC_SIMM13_P (l[0]))
+      if (lo == hi
+	  && ! SPARC_SETHI32_P (INTVAL (hi))
+	  && ! SPARC_SIMM13_P (INTVAL (hi)))
         {
           emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
 			        gen_highpart (SImode, operands[0])));
         }
       else
         {
-          emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
-			        gen_int_mode (l[1], SImode)));
+          emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), lo));
         }
     }
   DONE;
Index: gcc/doc/md.texi
===================================================================
--- gcc/doc/md.texi	(revision 141527)
+++ gcc/doc/md.texi	(working copy)
@@ -2738,6 +2738,9 @@ when the Visual Instruction Set is avail
 @item h
 64-bit global or out register for the SPARC-V8+ architecture.
 
+@item D
+A vector constant
+
 @item I
 Signed 13-bit constant
 


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