This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH] Add sparc VIS 2.0 builtins, intrinsics, and option to control them.
- From: David Miller <davem at davemloft dot net>
- To: rth at redhat dot com
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Mon, 03 Oct 2011 01:28:11 -0400 (EDT)
- Subject: Re: [PATCH] Add sparc VIS 2.0 builtins, intrinsics, and option to control them.
- References: <20110930.035938.868908024383419283.davem@davemloft.net> <4E862EB8.7020301@redhat.com>
From: Richard Henderson <rth@redhat.com>
Date: Fri, 30 Sep 2011 14:03:52 -0700
> On 09/30/2011 12:59 AM, David Miller wrote:
>>
>>[ VIS 2.0 bmask patterns ]
>
> I think this is wrong. I think you want to model this as
>
> [(set (match_operand:DI 0 "register_operand" "=r")
> (plus:DI (match_operand:DI 1 "register_or_zero_operand" "rJ")
> (match_operand:DI 2 "register_or_zero_operand" "rJ")))
> (set (zero_extract:DI
> (reg:DI GSR_REG)
> (const_int 32)
> (const_int 32))
> (plus:DI (match_dup 1) (match_dup 2)))]
Yep, perfect for 64-bit.
> (3) I realize this version makes things difficult for 32-bit mode.
> There, I think you may have to settle for an unspec. And perhaps
> the possible benefit of Properly representing the GSR change isn't
> that helpful. In which case:
>
> (set (reg:DI GSR_REG)
> (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI GSR_REG)]
> UNSPEC_BMASK))
Actually, can't we just use a (zero_extend:DI (plus:SI ...)) for the
32-bit case? It seems to work fine.
>> +(define_insn "bshuffle<V64I:mode>_vis"
>> + [(set (match_operand:V64I 0 "register_operand" "=e")
>> + (unspec:V64I [(match_operand:V64I 1 "register_operand" "e")
>> + (match_operand:V64I 2 "register_operand" "e")]
>> + UNSPEC_BSHUFFLE))
>> + (use (reg:SI GSR_REG))]
>
> Better to push the use of the GSR_REG into the unspec, and not leave
> it separate in the parallel.
This is actually just a non-constant vec_merge, and even though the internals
documentation says that the 'items' operand has to be a const_int, the compiler
actually doesn't care.
The only two places vec_merge is even inspected semantically by the
compiler is in the RTX simplifier where it already checks explicitly
for const_int, and in dwarf2out.c where it just ignores the vec_merge
construct entirely since it can't be represented.
So if we just code this as:
(set (match_operand:V64I 0 "register_operand" "=e")
(vec_merge:V64I (match_operand:V64I 2 "register_operand" "e")
(match_operand:V64I 1 "register_operand" "e")
(zero_extract:DI (reg:DI GSR_REG)
(const_int 32)
(const_int 32))))
it would mostly work. The only problem with this is that we provide
the bshuffle builtin for DI mode just as we do for the faligndata
instruction. simplify-rtx.c isn't happy seeing a non-vector mode
and VECTOR_MODES () in a foo-modes.def file won't generate modes
like V1DI and V1SI.
I guess I could explicitly generate those single entry vector modes
like i386 does.
But, as-is, the above pattern does work for all the "actual" vector
modes.
More generally, rtl.def is non-specific about what operand 2 of a
vec_merge has to be, it just says a bitmask, it doesn't say that it
has to be a const_int.
I think we should explicitly allow non-const_int objects here, and state
so in the internals documentation.