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 2)


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/msg00114.html

In this iteration, I have:

- added the 'Z' constraint to accept any const_double and integer
  const_vector and

- generalized the DFmode splitter to handle V64mode.

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

Kazu Hirata

2008-10-19  Kazu Hirata  <kazu@codesourcery.com>

	PR target/35574
	* config/sparc/predicates.md (const_double_or_vector_operand):
	New.
	* config/sparc/sparc-protos.h: Add the prototype for
	sparc_v64_to_long.
	* config/sparc/sparc.c (sparc_extra_constraint_check): Handle the
	'Z' constraint.
	(sparc_v64_to_long): New.
	* config/sparc/sparc.h: Document the 'Z' constraint.
	* config/sparc/sparc.md (*movdf_insn_sp32_v9, *movdf_insn_sp64):
	Use the 'Z' constraint instead of 'F' in some alternatives.
	(DF splitter): Generalize for V64mode.

Index: gcc/config/sparc/predicates.md
===================================================================
--- gcc/config/sparc/predicates.md	(revision 224877)
+++ 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_vector.
+(define_predicate "const_double_or_vector_operand"
+  (match_code "const_double,const_vector"))
Index: gcc/config/sparc/sparc-protos.h
===================================================================
--- gcc/config/sparc/sparc-protos.h	(revision 224877)
+++ gcc/config/sparc/sparc-protos.h	(working copy)
@@ -114,6 +114,7 @@ extern int sparc_check_64 (rtx, rtx);
 extern rtx gen_df_reg (rtx, int);
 extern int sparc_extra_constraint_check (rtx, int, int);
 extern void sparc_expand_compare_and_swap_12 (rtx, rtx, rtx, rtx);
+extern void sparc_v64_to_long (rtx, long *);
 #endif /* RTX_CODE */
 
 #endif /* __SPARC_PROTOS_H__ */
Index: gcc/config/sparc/sparc.c
===================================================================
--- gcc/config/sparc/sparc.c	(revision 224877)
+++ gcc/config/sparc/sparc.c	(working copy)
@@ -8332,6 +8332,7 @@ int
 sparc_extra_constraint_check (rtx op, int c, int strict)
 {
   int reload_ok_mem;
+  enum mode_class mclass;
 
   if (TARGET_ARCH64
       && (c == 'T' || c == 'U'))
@@ -8364,6 +8365,12 @@ sparc_extra_constraint_check (rtx op, in
     case 'Y':
       return const_zero_operand (op, GET_MODE (op));
 
+    case 'Z':
+      /* Like 'F', but we allow vector constants.  */
+      mclass = GET_MODE_CLASS (GET_MODE (op));
+      return ((mclass == MODE_FLOAT && GET_CODE (op) == CONST_DOUBLE)
+	      || (mclass == MODE_VECTOR_INT && GET_CODE (op) == CONST_VECTOR));
+
     default:
       return 0;
     }
@@ -9049,4 +9056,43 @@ sparc_expand_compare_and_swap_12 (rtx re
   emit_move_insn (result, gen_lowpart (GET_MODE (result), res));
 }
 
+/* Convert a 64-bit constant X to two long integers.  The result is
+   stored in P[0] and P[1].  */
+
+void
+sparc_v64_to_long (rtx x, long *p)
+{
+  enum machine_mode mode;
+  long l[2] = { 0, 0 };
+  unsigned int i;
+
+  mode = GET_MODE (x);
+
+  if (mode == DFmode)
+    {
+      REAL_VALUE_TYPE r;
+      REAL_VALUE_FROM_CONST_DOUBLE (r, x);
+      REAL_VALUE_TO_TARGET_DOUBLE (r, l);
+    }
+  else if (VECTOR_MODE_P (mode))
+    {
+      unsigned int elms = CONST_VECTOR_NUNITS (x);
+      enum machine_mode inner_mode = GET_MODE_INNER (mode);
+      unsigned int width = GET_MODE_BITSIZE (inner_mode);
+      unsigned long mask = GET_MODE_MASK (inner_mode);
+
+      for (i = 0; i < elms; i++)
+	{
+	  rtx elt = CONST_VECTOR_ELT (x, i);
+	  l[i / (elms / 2)] |= (((unsigned long) INTVAL (elt) & mask)
+				<< ((elms - i - 1) * width % 32));
+	}
+    }
+  else
+    gcc_unreachable ();
+
+  p[0] = l[0];
+  p[1] = l[1];
+}
+
 #include "gt-sparc.h"
Index: gcc/config/sparc/sparc.h
===================================================================
--- gcc/config/sparc/sparc.h	(revision 224877)
+++ gcc/config/sparc/sparc.h	(working copy)
@@ -1888,7 +1888,9 @@ do {									\
    'W' handles the memory operand when moving operands in/out
        of 'e' constraint floating point registers.
 
-   'Y' handles the zero vector constant.  */
+   'Y' handles the zero vector constant.
+
+   'Z' handles const_double and const_vector.  */
 
 #ifndef REG_OK_STRICT
 
Index: gcc/config/sparc/sparc.md
===================================================================
--- gcc/config/sparc/sparc.md	(revision 224877)
+++ 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,*roGYZ,*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,Z"))]
   "TARGET_FPU
    && TARGET_ARCH64
    && (register_operand (operands[0], <V64:MODE>mode)
@@ -2605,20 +2605,18 @@ (define_insn "*movdf_insn_sp64_no_fpu"
 
 ;; This pattern build DFmode 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);
+  sparc_v64_to_long (operands[1], l);
   operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0]));
 
   if (TARGET_ARCH64)


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