This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [patch] Fix FAIL of gcc.target/sparc/pdist-3.c (PR 35574) (Take 2)
- From: Eric Botcazou <ebotcazou at adacore dot com>
- To: Kazu Hirata <kazu at codesourcery dot com>
- Cc: gcc-patches at gcc dot gnu dot org, rth at redhat dot com, davem at redhat dot com, jakub at redhat dot com
- Date: Sat, 25 Oct 2008 17:54:16 +0200
- Subject: Re: [patch] Fix FAIL of gcc.target/sparc/pdist-3.c (PR 35574) (Take 2)
- References: <20081019163146.5C45B6F6208F@daisy.codesourcery.com>
> 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