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]

Re: [patch] Fix FAIL of gcc.target/sparc/pdist-3.c (PR 35574) (Take 2)


> 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?

Thanks.  However, the patch as written is not suitable for mainline since the 
SPARC port has been converted to define_constraint.

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

The comment and the code don't match.  The new predicate should be added in 
the "Predicates for numerical constants" section.

> @@ -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];
> +}
> +

I'd use the existing machinery for the CONST_VECTOR -> DImode conversion, 
namely simplify_immed_subreg invoked via simplify_subreg.  Then you'll get 
either a CONST_INT or a CONST_DOUBLE depending on HOST_BITS_PER_WIDE_INT.
No need for a separate function with this change I'd think.

> 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

The new constraint must be documented in doc/tm.texi.  Clearly it's a pity 
that I didn't choose Z for the zero vector constant, so I'd choose 'D' for 
the new constraint and make it specific to CONST_VECTOR ('d' is already as 
vector-related register constraint).

>  ;; 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"

The head comment is outdated (and still contains a typo :-).

Otherwise looks good.

-- 
Eric Botcazou


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