Re: [PATCH, rs6000] Implement -maltivec=be for vec_mergeh and vec_mergel Altivec builtins

2014-01-28 Thread Bill Schmidt
Hi,

David suggested privately that I rework some of the pattern names to fit
in with existing practice.  I've done this, and the result is below.
Bootstrapped and tested on powerpc64{,le}-unknown-linux-gnu with no
regressions.  Is this ok for trunk?

Thanks,
Bill

On Thu, 2014-01-23 at 18:08 -0600, Bill Schmidt wrote:
 Hi,
 
 This patch continues the series of changes to the Altivec builtins to
 accommodate big-endian element order when targeting a little endian
 machine.  Here the focus is on the vector merge-high and merge-low
 operations.
 
 The primary change is in altivec.md.  As an example, look at the pattern
 altivec_vmrghw.  Previously, this was represented with a single
 define_insn.  Now it's been split into a define_expand to create the
 RTL, and a define_insn (*altivec_vmrghw_endian) to generate the hardware
 instruction.  This is because we need a different selection vector when
 using -maltivec=be and targeting LE.  (Normally LE and BE can use the
 same selection vector, and GCC takes care of interpreting the indices as
 left-to-right or right-to-left.)  The new define_insn also substitutes
 vmrglw with swapped operands for vmrghw for little-endian mode, since
 the hardware instruction has big-endian bias in the interpretation of
 high and low.
 
 Because -maltivec=be applies only to programmer-specified builtins, we
 need to adjust internal uses of altivec_vmrghw and friends.  Thus we
 have a new define_insn altivec_vmrghw_internal that generates the
 hardware instruction directly with none of the above transformations.
 New unspecs are needed for these internal forms.
 
 The VSX flavors of merge-high and merge-low are a little simpler (see
 vsx.md).  Here we already had a define_expand where the instructions are
 generated by separate xxpermdi patterns, and there are no internal uses
 to worry about.  So we only need to change the selection vector in the
 generated RTL.
 
 There are four new test cases that cover all of the supported data
 types.  Tests are divided between those that require only VMX
 instructions and those that require VSX instructions.  There are also
 variants for -maltivec and -maltivec=be.
 
 Bootstrapped and tested on powerpc64{,le}-unknown-linux-gnu with no
 regressions.  Ok for trunk?
 
 Thanks,
 Bill
 

gcc:

2014-01-28  Bill Schmidt  wschm...@linux.vnet.ibm.com

* config/rs6000/rs6000.c (altivec_expand_vec_perm_const):  Use
CODE_FOR_altivec_vmrg*_direct rather than CODE_FOR_altivec_vmrg*.
* config/rs6000/vsx.md (vsx_mergel_mode): Adjust for
-maltivec=be with LE targets.
(vsx_mergeh_mode): Likewise.
* config/rs6000/altivec.md (UNSPEC_VMRG[HL]_DIRECT): New
unspecs.
(mulv8hi3): Use gen_altivec_vmrg[hl]w_direct.
(altivec_vmrghb): Replace with define_expand and new
*altivec_vmrghb_internal insn; adjust for -maltivec=be with LE
targets.
(altivec_vmrghb_direct): New define_insn.
(altivec_vmrghh): Replace with define_expand and new
*altivec_vmrghh_internal insn; adjust for -maltivec=be with LE
targets.
(altivec_vmrghh_direct): New define_insn.
(altivec_vmrghw): Replace with define_expand and new
*altivec_vmrghw_internal insn; adjust for -maltivec=be with LE
targets.
(altivec_vmrghw_direct): New define_insn.
(*altivec_vmrghsf): Adjust for endianness.
(altivec_vmrglb): Replace with define_expand and new
*altivec_vmrglb_internal insn; adjust for -maltivec=be with LE
targets.
(altivec_vmrglb_direct): New define_insn.
(altivec_vmrglh): Replace with define_expand and new
*altivec_vmrglh_internal insn; adjust for -maltivec=be with LE
targets.
(altivec_vmrglh_direct): New define_insn.
(altivec_vmrglw): Replace with define_expand and new
*altivec_vmrglw_internal insn; adjust for -maltivec=be with LE
targets.
(altivec_vmrglw_direct): New define_insn.
(*altivec_vmrglsf): Adjust for endianness.
(vec_widen_umult_hi_v16qi): Use gen_altivec_vmrghh_direct.
(vec_widen_umult_lo_v16qi): Use gen_altivec_vmrglh_direct.
(vec_widen_smult_hi_v16qi): Use gen_altivec_vmrghh_direct.
(vec_widen_smult_lo_v16qi): Use gen_altivec_vmrglh_direct.
(vec_widen_umult_hi_v8hi): Use gen_altivec_vmrghw_direct.
(vec_widen_umult_lo_v8hi): Use gen_altivec_vmrglw_direct.
(vec_widen_smult_hi_v8hi): Use gen_altivec_vmrghw_direct.
(vec_widen_smult_lo_v8hi): Use gen_altivec_vmrglw_direct.

gcc/testsuite:

2014-01-28  Bill Schmidt  wschm...@linux.vnet.ibm.com

* gcc.dg/vmx/merge-be-order.c: New.
* gcc.dg/vmx/merge.c: New.
* gcc.dg/vmx/merge-vsx-be-order.c: New.
* gcc.dg/vmx/merge-vsx.c: New.


Index: gcc/testsuite/gcc.dg/vmx/merge-be-order.c
===
--- gcc/testsuite/gcc.dg/vmx/merge-be-order.c   

Re: [PATCH, rs6000] Implement -maltivec=be for vec_mergeh and vec_mergel Altivec builtins

2014-01-28 Thread David Edelsohn
On Tue, Jan 28, 2014 at 7:17 PM, Bill Schmidt
wschm...@linux.vnet.ibm.com wrote:

 David suggested privately that I rework some of the pattern names to fit
 in with existing practice.  I've done this, and the result is below.
 Bootstrapped and tested on powerpc64{,le}-unknown-linux-gnu with no
 regressions.  Is this ok for trunk?

 gcc:

 2014-01-28  Bill Schmidt  wschm...@linux.vnet.ibm.com

 * config/rs6000/rs6000.c (altivec_expand_vec_perm_const):  Use
 CODE_FOR_altivec_vmrg*_direct rather than CODE_FOR_altivec_vmrg*.
 * config/rs6000/vsx.md (vsx_mergel_mode): Adjust for
 -maltivec=be with LE targets.
 (vsx_mergeh_mode): Likewise.
 * config/rs6000/altivec.md (UNSPEC_VMRG[HL]_DIRECT): New
 unspecs.
 (mulv8hi3): Use gen_altivec_vmrg[hl]w_direct.
 (altivec_vmrghb): Replace with define_expand and new
 *altivec_vmrghb_internal insn; adjust for -maltivec=be with LE
 targets.
 (altivec_vmrghb_direct): New define_insn.
 (altivec_vmrghh): Replace with define_expand and new
 *altivec_vmrghh_internal insn; adjust for -maltivec=be with LE
 targets.
 (altivec_vmrghh_direct): New define_insn.
 (altivec_vmrghw): Replace with define_expand and new
 *altivec_vmrghw_internal insn; adjust for -maltivec=be with LE
 targets.
 (altivec_vmrghw_direct): New define_insn.
 (*altivec_vmrghsf): Adjust for endianness.
 (altivec_vmrglb): Replace with define_expand and new
 *altivec_vmrglb_internal insn; adjust for -maltivec=be with LE
 targets.
 (altivec_vmrglb_direct): New define_insn.
 (altivec_vmrglh): Replace with define_expand and new
 *altivec_vmrglh_internal insn; adjust for -maltivec=be with LE
 targets.
 (altivec_vmrglh_direct): New define_insn.
 (altivec_vmrglw): Replace with define_expand and new
 *altivec_vmrglw_internal insn; adjust for -maltivec=be with LE
 targets.
 (altivec_vmrglw_direct): New define_insn.
 (*altivec_vmrglsf): Adjust for endianness.
 (vec_widen_umult_hi_v16qi): Use gen_altivec_vmrghh_direct.
 (vec_widen_umult_lo_v16qi): Use gen_altivec_vmrglh_direct.
 (vec_widen_smult_hi_v16qi): Use gen_altivec_vmrghh_direct.
 (vec_widen_smult_lo_v16qi): Use gen_altivec_vmrglh_direct.
 (vec_widen_umult_hi_v8hi): Use gen_altivec_vmrghw_direct.
 (vec_widen_umult_lo_v8hi): Use gen_altivec_vmrglw_direct.
 (vec_widen_smult_hi_v8hi): Use gen_altivec_vmrghw_direct.
 (vec_widen_smult_lo_v8hi): Use gen_altivec_vmrglw_direct.

 gcc/testsuite:

 2014-01-28  Bill Schmidt  wschm...@linux.vnet.ibm.com

 * gcc.dg/vmx/merge-be-order.c: New.
 * gcc.dg/vmx/merge.c: New.
 * gcc.dg/vmx/merge-vsx-be-order.c: New.
 * gcc.dg/vmx/merge-vsx.c: New.

Thanks for adjusting the patch to be more consistent with the pattern
names used in the rest of the port.  The patch is okay.

Thanks, David


[PATCH, rs6000] Implement -maltivec=be for vec_mergeh and vec_mergel Altivec builtins

2014-01-23 Thread Bill Schmidt
Hi,

This patch continues the series of changes to the Altivec builtins to
accommodate big-endian element order when targeting a little endian
machine.  Here the focus is on the vector merge-high and merge-low
operations.

The primary change is in altivec.md.  As an example, look at the pattern
altivec_vmrghw.  Previously, this was represented with a single
define_insn.  Now it's been split into a define_expand to create the
RTL, and a define_insn (*altivec_vmrghw_endian) to generate the hardware
instruction.  This is because we need a different selection vector when
using -maltivec=be and targeting LE.  (Normally LE and BE can use the
same selection vector, and GCC takes care of interpreting the indices as
left-to-right or right-to-left.)  The new define_insn also substitutes
vmrglw with swapped operands for vmrghw for little-endian mode, since
the hardware instruction has big-endian bias in the interpretation of
high and low.

Because -maltivec=be applies only to programmer-specified builtins, we
need to adjust internal uses of altivec_vmrghw and friends.  Thus we
have a new define_insn altivec_vmrghw_internal that generates the
hardware instruction directly with none of the above transformations.
New unspecs are needed for these internal forms.

The VSX flavors of merge-high and merge-low are a little simpler (see
vsx.md).  Here we already had a define_expand where the instructions are
generated by separate xxpermdi patterns, and there are no internal uses
to worry about.  So we only need to change the selection vector in the
generated RTL.

There are four new test cases that cover all of the supported data
types.  Tests are divided between those that require only VMX
instructions and those that require VSX instructions.  There are also
variants for -maltivec and -maltivec=be.

Bootstrapped and tested on powerpc64{,le}-unknown-linux-gnu with no
regressions.  Ok for trunk?

Thanks,
Bill


gcc:

2014-01-23  Bill Schmidt  wschm...@linux.vnet.ibm.com

* config/rs6000/rs6000.c (altivec_expand_vec_perm_const):  Use
CODE_FOR_altivec_vmrg*_internal rather than
CODE_FOR_altivec_vmrg*.
* config/rs6000/vsx.md (vsx_mergel_mode): Adjust for
-maltivec=be with LE targets.
(vsx_mergeh_mode): Likewise.
* config/rs6000/altivec.md (UNSPEC_VMRG[HL][BHW]_INTERNAL): New
unspecs.
(mulv8hi3): Use gen_altivec_vmrg[hl]w_internal.
(altivec_vmrghb): Replace with define_expand and new
*altivec_vmrghb_endian insn; adjust for -maltivec=be with LE
targets.
(altivec_vmrghb_internal): New define_insn.
(altivec_vmrghh): Replace with define_expand and new
*altivec_vmrghh_endian insn; adjust for -maltivec=be with LE
targets.
(altivec_vmrghh_internal): New define_insn.
(altivec_vmrghw): Replace with define_expand and new
*altivec_vmrghw_endian insn; adjust for -maltivec=be with LE
targets.
(altivec_vmrghw_internal): New define_insn.
(*altivec_vmrghsf): Adjust for endianness.
(altivec_vmrglb): Replace with define_expand and new
*altivec_vmrglb_endian insn; adjust for -maltivec=be with LE
targets.
(altivec_vmrglb_internal): New define_insn.
(altivec_vmrglh): Replace with define_expand and new
*altivec_vmrglh_endian insn; adjust for -maltivec=be with LE
targets.
(altivec_vmrglh_internal): New define_insn.
(altivec_vmrglw): Replace with define_expand and new
*altivec_vmrglw_endian insn; adjust for -maltivec=be with LE
targets.
(altivec_vmrglw_internal): New define_insn.
(*altivec_vmrglsf): Adjust for endianness.
(vec_widen_umult_hi_v16qi): Use gen_altivec_vmrghh_internal.
(vec_widen_umult_lo_v16qi): Use gen_altivec_vmrglh_internal.
(vec_widen_smult_hi_v16qi): Use gen_altivec_vmrghh_internal.
(vec_widen_smult_lo_v16qi): Use gen_altivec_vmrglh_internal.
(vec_widen_umult_hi_v8hi): Use gen_altivec_vmrghw_internal.
(vec_widen_umult_lo_v8hi): Use gen_altivec_vmrglw_internal.
(vec_widen_smult_hi_v8hi): Use gen_altivec_vmrghw_internal.
(vec_widen_smult_lo_v8hi): Use gen_altivec_vmrglw_internal.

gcc/testsuite:

2014-01-23  Bill Schmidt  wschm...@linux.vnet.ibm.com

* gcc.dg/vmx/merge-be-order.c: New.
* gcc.dg/vmx/merge.c: New.
* gcc.dg/vmx/merge-vsx-be-order.c: New.
* gcc.dg/vmx/merge-vsx.c: New.


Index: gcc/testsuite/gcc.dg/vmx/merge-be-order.c
===
--- gcc/testsuite/gcc.dg/vmx/merge-be-order.c   (revision 0)
+++ gcc/testsuite/gcc.dg/vmx/merge-be-order.c   (revision 0)
@@ -0,0 +1,96 @@
+/* { dg-options -maltivec=be -mabi=altivec -std=gnu99 -mno-vsx } */
+
+#include harness.h
+
+static void test()
+{
+  /* Input vectors.  */
+  vector unsigned char vuca = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
+  vector unsigned char