aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBill Schmidt <wschmidt@vnet.ibm.com>2013-10-22 17:31:17 +0000
committerWilliam Schmidt <wschmidt@gcc.gnu.org>2013-10-22 17:31:17 +0000
commit843d68c67cba2d553d2b5b188dddeac7477fb6fb (patch)
tree1566eb4998c969ca8ca97a920755ae0458b871c8
parent7faffbc4be05ee2e161f78d830b143236e99f2ca (diff)
downloadgcc-843d68c67cba2d553d2b5b188dddeac7477fb6fb.zip
gcc-843d68c67cba2d553d2b5b188dddeac7477fb6fb.tar.gz
gcc-843d68c67cba2d553d2b5b188dddeac7477fb6fb.tar.bz2
rs6000.c (altivec_expand_vec_perm_const): Reverse meaning of merge-high and merge-low masks for little endian...
gcc: 2013-10-22 Bill Schmidt <wschmidt@vnet.ibm.com> * config/rs6000/rs6000.c (altivec_expand_vec_perm_const): Reverse meaning of merge-high and merge-low masks for little endian; avoid use of vector-pack masks for little endian for mismatched modes. gcc/testsuite: 2013-10-22 Bill Schmidt <wschmidt@vnet.ibm.com> * gcc.target/powerpc/altivec-perm-1.c: Move the two vector pack tests into... * gcc.target/powerpc/altivec-perm-3.c: ...this new test, which is restricted to big-endian targets. From-SVN: r203930
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/config/rs6000/rs6000.c38
-rw-r--r--gcc/testsuite/ChangeLog7
-rw-r--r--gcc/testsuite/gcc.target/powerpc/altivec-perm-1.c15
-rw-r--r--gcc/testsuite/gcc.target/powerpc/altivec-perm-3.c23
5 files changed, 68 insertions, 21 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index cfb6187..c1d3ba8 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2013-10-22 Bill Schmidt <wschmidt@vnet.ibm.com>
+
+ * config/rs6000/rs6000.c (altivec_expand_vec_perm_const): Reverse
+ meaning of merge-high and merge-low masks for little endian; avoid
+ use of vector-pack masks for little endian for mismatched modes.
+
2013-10-22 Jan-Benedict Glaw <jbglaw@lug-owl.de>
* config/tilepro/tilepro.c: Include "tree.h".
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index e054585..afd6db2 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -28838,17 +28838,23 @@ altivec_expand_vec_perm_const (rtx operands[4])
{ 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31 } },
{ OPTION_MASK_ALTIVEC, CODE_FOR_altivec_vpkuwum,
{ 2, 3, 6, 7, 10, 11, 14, 15, 18, 19, 22, 23, 26, 27, 30, 31 } },
- { OPTION_MASK_ALTIVEC, CODE_FOR_altivec_vmrghb,
+ { OPTION_MASK_ALTIVEC,
+ BYTES_BIG_ENDIAN ? CODE_FOR_altivec_vmrghb : CODE_FOR_altivec_vmrglb,
{ 0, 16, 1, 17, 2, 18, 3, 19, 4, 20, 5, 21, 6, 22, 7, 23 } },
- { OPTION_MASK_ALTIVEC, CODE_FOR_altivec_vmrghh,
+ { OPTION_MASK_ALTIVEC,
+ BYTES_BIG_ENDIAN ? CODE_FOR_altivec_vmrghh : CODE_FOR_altivec_vmrglh,
{ 0, 1, 16, 17, 2, 3, 18, 19, 4, 5, 20, 21, 6, 7, 22, 23 } },
- { OPTION_MASK_ALTIVEC, CODE_FOR_altivec_vmrghw,
+ { OPTION_MASK_ALTIVEC,
+ BYTES_BIG_ENDIAN ? CODE_FOR_altivec_vmrghw : CODE_FOR_altivec_vmrglw,
{ 0, 1, 2, 3, 16, 17, 18, 19, 4, 5, 6, 7, 20, 21, 22, 23 } },
- { OPTION_MASK_ALTIVEC, CODE_FOR_altivec_vmrglb,
+ { OPTION_MASK_ALTIVEC,
+ BYTES_BIG_ENDIAN ? CODE_FOR_altivec_vmrglb : CODE_FOR_altivec_vmrghb,
{ 8, 24, 9, 25, 10, 26, 11, 27, 12, 28, 13, 29, 14, 30, 15, 31 } },
- { OPTION_MASK_ALTIVEC, CODE_FOR_altivec_vmrglh,
+ { OPTION_MASK_ALTIVEC,
+ BYTES_BIG_ENDIAN ? CODE_FOR_altivec_vmrglh : CODE_FOR_altivec_vmrghh,
{ 8, 9, 24, 25, 10, 11, 26, 27, 12, 13, 28, 29, 14, 15, 30, 31 } },
- { OPTION_MASK_ALTIVEC, CODE_FOR_altivec_vmrglw,
+ { OPTION_MASK_ALTIVEC,
+ BYTES_BIG_ENDIAN ? CODE_FOR_altivec_vmrglw : CODE_FOR_altivec_vmrghw,
{ 8, 9, 10, 11, 24, 25, 26, 27, 12, 13, 14, 15, 28, 29, 30, 31 } },
{ OPTION_MASK_P8_VECTOR, CODE_FOR_p8_vmrgew,
{ 0, 1, 2, 3, 16, 17, 18, 19, 8, 9, 10, 11, 24, 25, 26, 27 } },
@@ -28981,6 +28987,26 @@ altivec_expand_vec_perm_const (rtx operands[4])
enum machine_mode omode = insn_data[icode].operand[0].mode;
enum machine_mode imode = insn_data[icode].operand[1].mode;
+ /* For little-endian, don't use vpkuwum and vpkuhum if the
+ underlying vector type is not V4SI and V8HI, respectively.
+ For example, using vpkuwum with a V8HI picks up the even
+ halfwords (BE numbering) when the even halfwords (LE
+ numbering) are what we need. */
+ if (!BYTES_BIG_ENDIAN
+ && icode == CODE_FOR_altivec_vpkuwum
+ && ((GET_CODE (op0) == REG
+ && GET_MODE (op0) != V4SImode)
+ || (GET_CODE (op0) == SUBREG
+ && GET_MODE (XEXP (op0, 0)) != V4SImode)))
+ continue;
+ if (!BYTES_BIG_ENDIAN
+ && icode == CODE_FOR_altivec_vpkuhum
+ && ((GET_CODE (op0) == REG
+ && GET_MODE (op0) != V8HImode)
+ || (GET_CODE (op0) == SUBREG
+ && GET_MODE (XEXP (op0, 0)) != V8HImode)))
+ continue;
+
/* For little-endian, the two input operands must be swapped
(or swapped back) to ensure proper right-to-left numbering
from 0 to 2N-1. */
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index ff48a24..446183d 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,10 @@
+2013-10-22 Bill Schmidt <wschmidt@vnet.ibm.com>
+
+ * gcc.target/powerpc/altivec-perm-1.c: Move the two vector pack
+ tests into...
+ * gcc.target/powerpc/altivec-perm-3.c: ...this new test, which is
+ restricted to big-endian targets.
+
2013-10-22 Paul Thomas <pault@gcc.gnu.org>
PR fortran 57893
diff --git a/gcc/testsuite/gcc.target/powerpc/altivec-perm-1.c b/gcc/testsuite/gcc.target/powerpc/altivec-perm-1.c
index ee5c5ee..c3cf67e 100644
--- a/gcc/testsuite/gcc.target/powerpc/altivec-perm-1.c
+++ b/gcc/testsuite/gcc.target/powerpc/altivec-perm-1.c
@@ -19,19 +19,6 @@ V b4(V x)
return __builtin_shuffle(x, (V){ 4,5,6,7, 4,5,6,7, 4,5,6,7, 4,5,6,7, });
}
-V p2(V x, V y)
-{
- return __builtin_shuffle(x, y,
- (V){ 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31 });
-
-}
-
-V p4(V x, V y)
-{
- return __builtin_shuffle(x, y,
- (V){ 2, 3, 6, 7, 10, 11, 14, 15, 18, 19, 22, 23, 26, 27, 30, 31 });
-}
-
V h1(V x, V y)
{
return __builtin_shuffle(x, y,
@@ -72,5 +59,3 @@ V l4(V x, V y)
/* { dg-final { scan-assembler "vspltb" } } */
/* { dg-final { scan-assembler "vsplth" } } */
/* { dg-final { scan-assembler "vspltw" } } */
-/* { dg-final { scan-assembler "vpkuhum" } } */
-/* { dg-final { scan-assembler "vpkuwum" } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/altivec-perm-3.c b/gcc/testsuite/gcc.target/powerpc/altivec-perm-3.c
new file mode 100644
index 0000000..d0b671e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/altivec-perm-3.c
@@ -0,0 +1,23 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target powerpc_altivec_ok } */
+/* { dg-skip-if "" { powerpc*le-*-* } { "*" } { "" } } */
+/* { dg-options "-O -maltivec -mno-vsx" } */
+
+typedef unsigned char V __attribute__((vector_size(16)));
+
+V p2(V x, V y)
+{
+ return __builtin_shuffle(x, y,
+ (V){ 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31 });
+
+}
+
+V p4(V x, V y)
+{
+ return __builtin_shuffle(x, y,
+ (V){ 2, 3, 6, 7, 10, 11, 14, 15, 18, 19, 22, 23, 26, 27, 30, 31 });
+}
+
+/* { dg-final { scan-assembler-not "vperm" } } */
+/* { dg-final { scan-assembler "vpkuhum" } } */
+/* { dg-final { scan-assembler "vpkuwum" } } */