aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorMichael Meissner <meissner@linux.vnet.ibm.com>2013-06-28 16:15:17 +0000
committerMichael Meissner <meissner@gcc.gnu.org>2013-06-28 16:15:17 +0000
commitf161bfd3300fb19ae04a865806612e4f8e7847d7 (patch)
tree67dc85a8d10766cb6d86972ba83068da0b058c27 /gcc
parent7d9800e39ad29174231a13405f11e82dd9d430d2 (diff)
downloadgcc-f161bfd3300fb19ae04a865806612e4f8e7847d7.zip
gcc-f161bfd3300fb19ae04a865806612e4f8e7847d7.tar.gz
gcc-f161bfd3300fb19ae04a865806612e4f8e7847d7.tar.bz2
re PR target/57744 (Power8 support has problems with quad word atomic instructions)
[gcc] 2013-06-28 Michael Meissner <meissner@linux.vnet.ibm.com> PR target/57744 * config/rs6000/rs6000.h (MODES_TIEABLE_P): Do not allow PTImode to tie with any other modes. Eliminate Altivec vector mode tests, since these are a subset of ALTIVEC or VSX vector modes. Simplify code, to return 0 if testing MODE2 for a condition, if we've already tested MODE1 for the same condition. [gcc/testsuite] 2013-06-28 Michael Meissner <meissner@linux.vnet.ibm.com> PR target/57744 * gcc.target/powerpc/pr57744.c: New test to make sure lqarx and stqcx. get even registers. From-SVN: r200538
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/config/rs6000/rs6000.h24
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/gcc.target/powerpc/pr57744.c37
4 files changed, 66 insertions, 10 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index dbd82a2..6c86c25 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,12 @@
+2013-06-28 Michael Meissner <meissner@linux.vnet.ibm.com>
+
+ PR target/57744
+ * config/rs6000/rs6000.h (MODES_TIEABLE_P): Do not allow PTImode
+ to tie with any other modes. Eliminate Altivec vector mode tests,
+ since these are a subset of ALTIVEC or VSX vector modes. Simplify
+ code, to return 0 if testing MODE2 for a condition, if we've
+ already tested MODE1 for the same condition.
+
2013-06-28 Marcus Shawcroft <marcus.shawcroft@arm.com>
* config/aarch64/aarch64.c (aarch64_cannot_force_const_mem): Adjust
diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h
index 633d789..98a44aa 100644
--- a/gcc/config/rs6000/rs6000.h
+++ b/gcc/config/rs6000/rs6000.h
@@ -1180,28 +1180,32 @@ enum data_align { align_abi, align_opt, align_both };
/* Value is 1 if it is a good idea to tie two pseudo registers
when one has mode MODE1 and one has mode MODE2.
If HARD_REGNO_MODE_OK could produce different values for MODE1 and MODE2,
- for any hard reg, then this must be 0 for correct output. */
+ for any hard reg, then this must be 0 for correct output.
+
+ PTImode cannot tie with other modes because PTImode is restricted to even
+ GPR registers, and TImode can go in any GPR as well as VSX registers (PR
+ 57744). */
#define MODES_TIEABLE_P(MODE1, MODE2) \
- (SCALAR_FLOAT_MODE_P (MODE1) \
+ ((MODE1) == PTImode \
+ ? (MODE2) == PTImode \
+ : (MODE2) == PTImode \
+ ? 0 \
+ : SCALAR_FLOAT_MODE_P (MODE1) \
? SCALAR_FLOAT_MODE_P (MODE2) \
: SCALAR_FLOAT_MODE_P (MODE2) \
- ? SCALAR_FLOAT_MODE_P (MODE1) \
+ ? 0 \
: GET_MODE_CLASS (MODE1) == MODE_CC \
? GET_MODE_CLASS (MODE2) == MODE_CC \
: GET_MODE_CLASS (MODE2) == MODE_CC \
- ? GET_MODE_CLASS (MODE1) == MODE_CC \
+ ? 0 \
: SPE_VECTOR_MODE (MODE1) \
? SPE_VECTOR_MODE (MODE2) \
: SPE_VECTOR_MODE (MODE2) \
- ? SPE_VECTOR_MODE (MODE1) \
+ ? 0 \
: ALTIVEC_OR_VSX_VECTOR_MODE (MODE1) \
? ALTIVEC_OR_VSX_VECTOR_MODE (MODE2) \
: ALTIVEC_OR_VSX_VECTOR_MODE (MODE2) \
- ? ALTIVEC_OR_VSX_VECTOR_MODE (MODE1) \
- : ALTIVEC_VECTOR_MODE (MODE1) \
- ? ALTIVEC_VECTOR_MODE (MODE2) \
- : ALTIVEC_VECTOR_MODE (MODE2) \
- ? ALTIVEC_VECTOR_MODE (MODE1) \
+ ? 0 \
: 1)
/* Post-reload, we can't use any new AltiVec registers, as we already
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 9e7d857..c0b5284 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2013-06-28 Michael Meissner <meissner@linux.vnet.ibm.com>
+
+ PR target/57744
+ * gcc.target/powerpc/pr57744.c: New test to make sure lqarx and
+ stqcx. get even registers.
+
2013-06-28 Marc Glisse <marc.glisse@inria.fr>
PR c++/57509
diff --git a/gcc/testsuite/gcc.target/powerpc/pr57744.c b/gcc/testsuite/gcc.target/powerpc/pr57744.c
new file mode 100644
index 0000000..d1522f7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/pr57744.c
@@ -0,0 +1,37 @@
+/* { dg-do run { target { powerpc*-*-* && lp64 } } } */
+/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
+/* { dg-require-effective-target powerpc_p8vector_ok } */
+/* { dg-options "-mcpu=power8 -O3" } */
+
+typedef unsigned U_16 __attribute__((mode(TI)));
+
+extern int libat_compare_exchange_16 (U_16 *, U_16 *, U_16, int, int)
+ __attribute__((__noinline__));
+
+/* PR 57744: lqarx/stqcx needs even/odd register pairs. The assembler will
+ complain if the compiler gets an odd/even register pair. Create a function
+ which has the 16 byte compare and exchange instructions, but don't actually
+ execute it, so that we can detect these failures on older machines. */
+
+int
+libat_compare_exchange_16 (U_16 *mptr, U_16 *eptr, U_16 newval,
+ int smodel, int fmodel __attribute__((unused)))
+{
+ if (((smodel) == 0))
+ return __atomic_compare_exchange_n (mptr, eptr, newval, 0, 0, 0);
+ else if (((smodel) != 5))
+ return __atomic_compare_exchange_n (mptr, eptr, newval, 0, 4, 0);
+ else
+ return __atomic_compare_exchange_n (mptr, eptr, newval, 0, 5, 0);
+}
+
+U_16 a = 1, b = 1, c = -2;
+volatile int do_test = 0;
+
+int main (void)
+{
+ if (do_test && !libat_compare_exchange_16 (&a, &b, c, 0, 0))
+ aborrt ();
+
+ return 0;
+}