aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorNick Clifton <nickc@redhat.com>2016-02-18 13:00:07 +0000
committerNick Clifton <nickc@gcc.gnu.org>2016-02-18 13:00:07 +0000
commit19233914d1b392635126ec98e691319e227c4db0 (patch)
treeb69ce481c1b4856ad7d75ac3835fef9dd38a2c86 /gcc
parent23f278396845947f49e597363aaa236ebb4f4e0e (diff)
downloadgcc-19233914d1b392635126ec98e691319e227c4db0.zip
gcc-19233914d1b392635126ec98e691319e227c4db0.tar.gz
gcc-19233914d1b392635126ec98e691319e227c4db0.tar.bz2
PR target/62554
PR target/69610 gcc * config/arm/arm.c (arm_option_override_internal): Disable interworking if the target does not support thumb instructions. (arm_reload_in_hi): Handle the case where a register to register move needs reloading because there is no simple pattern to handle it. (arm_reload_out_hi): Likewise. tests * gcc.target/arm/pr62554.c: New test. * gcc.target/arm/pr69610-1.c: New test. * gcc.target/arm/pr69610-2.c: New test. From-SVN: r233518
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog11
-rw-r--r--gcc/config/arm/arm.c31
-rw-r--r--gcc/testsuite/ChangeLog8
-rw-r--r--gcc/testsuite/gcc.target/arm/pr62554.c51
-rw-r--r--gcc/testsuite/gcc.target/arm/pr69610-1.c14
-rw-r--r--gcc/testsuite/gcc.target/arm/pr69610-2.c33
6 files changed, 148 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index f2ce850..b16cd4c 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,14 @@
+2016-02-18 Nick Clifton <nickc@redhat.com>
+
+ PR target/62554
+ PR target/69610
+ * config/arm/arm.c (arm_option_override_internal): Disable
+ interworking if the target does not support thumb instructions.
+ (arm_reload_in_hi): Handle the case where a register to register
+ move needs reloading because there is no simple pattern to handle
+ it.
+ (arm_reload_out_hi): Likewise.
+
2016-02-18 Richard Biener <rguenther@suse.de>
PR middle-end/69854
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index 6b73771..765d002 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -2874,6 +2874,14 @@ arm_option_override_internal (struct gcc_options *opts,
{
arm_override_options_after_change_1 (opts);
+ if (TARGET_INTERWORK && !ARM_FSET_HAS_CPU1 (insn_flags, FL_THUMB))
+ {
+ /* The default is to enable interworking, so this warning message would
+ be confusing to users who have just compiled with, eg, -march=armv3. */
+ /* warning (0, "ignoring -minterwork because target CPU does not support THUMB"); */
+ opts->x_target_flags &= ~MASK_INTERWORK;
+ }
+
if (TARGET_THUMB_P (opts->x_target_flags)
&& !(ARM_FSET_HAS_CPU1 (insn_flags, FL_THUMB)))
{
@@ -15440,6 +15448,17 @@ arm_reload_in_hi (rtx *operands)
else
/* The slot is out of range, or was dressed up in a SUBREG. */
base = reg_equiv_address (REGNO (ref));
+
+ /* PR 62554: If there is no equivalent memory location then just move
+ the value as an SImode register move. This happens when the target
+ architecture variant does not have an HImode register move. */
+ if (base == NULL)
+ {
+ gcc_assert (REG_P (operands[0]));
+ emit_insn (gen_movsi (gen_rtx_SUBREG (SImode, operands[0], 0),
+ gen_rtx_SUBREG (SImode, ref, 0)));
+ return;
+ }
}
else
base = find_replacement (&XEXP (ref, 0));
@@ -15557,6 +15576,17 @@ arm_reload_out_hi (rtx *operands)
else
/* The slot is out of range, or was dressed up in a SUBREG. */
base = reg_equiv_address (REGNO (ref));
+
+ /* PR 62554: If there is no equivalent memory location then just move
+ the value as an SImode register move. This happens when the target
+ architecture variant does not have an HImode register move. */
+ if (base == NULL)
+ {
+ gcc_assert (REG_P (outval));
+ emit_insn (gen_movsi (gen_rtx_SUBREG (SImode, ref, 0),
+ gen_rtx_SUBREG (SImode, outval, 0)));
+ return;
+ }
}
else
base = find_replacement (&XEXP (ref, 0));
@@ -19619,6 +19649,7 @@ output_return_instruction (rtx operand, bool really_return, bool reverse,
break;
case ARM_FT_INTERWORKED:
+ gcc_assert (arm_arch5 || arm_arch4t);
sprintf (instr, "bx%s\t%%|lr", conditional);
break;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 74a99e6..103c78d7 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,11 @@
+2016-02-18 Nick Clifton <nickc@redhat.com>
+
+ PR target/62554
+ PR target/69610
+ * gcc.target/arm/pr62554.c: New test.
+ * gcc.target/arm/pr69610-1.c: New test.
+ * gcc.target/arm/pr69610-2.c: New test.
+
2016-02-18 Richard Biener <rguenther@suse.de>
PR middle-end/69854
diff --git a/gcc/testsuite/gcc.target/arm/pr62554.c b/gcc/testsuite/gcc.target/arm/pr62554.c
new file mode 100644
index 0000000..4d6501c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/pr62554.c
@@ -0,0 +1,51 @@
+/* Check that pre ARMv4 compilation still works. */
+/* { dg-do compile } */
+/* { dg-options "-marm -march=armv3 -O" } */
+/* { dg-require-effective-target arm_arm_ok } */
+
+typedef struct
+{
+ char bits;
+ short val;
+} code;
+
+union uu
+{
+ short us;
+ char b[2];
+};
+
+int a, b, c, f, g, h;
+code *d;
+
+code e;
+
+int
+fn1 (void)
+{
+ char i;
+ do
+ if (e.bits)
+ {
+ dodist:
+ f = c;
+ if (e.bits & 6)
+ {
+ ++i;
+ if (g)
+ do
+ {
+ union uu j;
+ j.b[1] = a;
+ h = j.us;
+ }
+ while (fn1);
+ }
+ else
+ {
+ e = d[b];
+ goto dodist;
+ }
+ }
+ while (i);
+}
diff --git a/gcc/testsuite/gcc.target/arm/pr69610-1.c b/gcc/testsuite/gcc.target/arm/pr69610-1.c
new file mode 100644
index 0000000..a671b93
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/pr69610-1.c
@@ -0,0 +1,14 @@
+/* Check that pre ARMv4 compilation still works. */
+/* { dg-do compile } */
+/* { dg-options "-marm -march=armv3 -ftree-ter" } */
+/* { dg-require-effective-target arm_arm_ok } */
+
+typedef unsigned short v16u16 __attribute__ ((vector_size (16)));
+typedef unsigned int v16u32 __attribute__ ((vector_size (16)));
+
+unsigned short
+foo (v16u16 v16u16_1, v16u32 v16u32_1)
+{
+ v16u16_1 += (v16u16) v16u32_1;
+ return v16u16_1[5] + v16u32_1[1];
+}
diff --git a/gcc/testsuite/gcc.target/arm/pr69610-2.c b/gcc/testsuite/gcc.target/arm/pr69610-2.c
new file mode 100644
index 0000000..e932c63
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/pr69610-2.c
@@ -0,0 +1,33 @@
+/* Check that pre ARMv4 compilation still works. */
+/* { dg-do compile } */
+/* { dg-options "-marm -march=armv3 -O2 -fno-forward-propagate" } */
+/* { dg-require-effective-target arm_arm_ok } */
+
+typedef short v16u16 __attribute__ ((vector_size (16)));
+typedef unsigned v16u32 __attribute__ ((vector_size (16)));
+typedef long long v16u64 __attribute__ ((vector_size (16)));
+
+unsigned
+foo
+ (int
+ u16_0,
+ unsigned
+ u32_0,
+ int
+ u64_0,
+ int
+ u16_1,
+ unsigned
+ u64_1,
+ v16u16
+ v16u16_0,
+ v16u32
+ v16u32_0,
+ v16u64 v16u64_0, v16u16 v16u16_1, v16u32 v16u32_1, v16u64 v16u64_1)
+{
+ v16u16_1[3] -= v16u32_0[0];
+ v16u16_0 -= (v16u16) v16u32_0;
+ return u16_0 + u32_0 + u64_0 + u16_1 +
+ v16u16_0[0] + v16u16_0[2] + v16u16_0[3] + v16u16_0[4] + v16u16_0[5] + v16u32_0[0] + v16u32_0[1] + v16u32_0[3] + v16u64_0[1] +
+ v16u16_1[2] + v16u16_1[3] + v16u16_1[5] + v16u16_1[7] + v16u32_1[0] + v16u32_1[3] + v16u64_1[0] + v16u64_1[1];
+}