aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRamana Radhakrishnan <ramana.radhakrishnan@arm.com>2010-07-22 08:30:36 +0000
committerRamana Radhakrishnan <ramana@gcc.gnu.org>2010-07-22 08:30:36 +0000
commitf67325e8386753732d594aa81e9fffecbaec24c4 (patch)
treed10bcca1342935245dbfb3621d1cbfe44f35cc04 /gcc
parent50eb566f049aed7b21a580d75abd197430538f1d (diff)
downloadgcc-f67325e8386753732d594aa81e9fffecbaec24c4.zip
gcc-f67325e8386753732d594aa81e9fffecbaec24c4.tar.gz
gcc-f67325e8386753732d594aa81e9fffecbaec24c4.tar.bz2
re PR target/43698 (Wrong use of ARMv6 REV instruction for endian bytewapping with -Os or -O2 optimizations)
Fix PR target/43698 2010-07-22 Ramana Radhakrishnan <ramana.radhakrishnan@arm.com> PR target/43698 * config/arm/arm.md: Split arm_rev into *arm_rev and *thumb1_rev. Set *arm_rev to be predicable. 2010-07-22 Ramana Radhakrishnan <ramana.radhakrishnan@arm.com> PR target/43698 * gcc.target/arm/pr43698.c: New test. From-SVN: r162404
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/config/arm/arm.md20
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.target/arm/pr43698.c38
4 files changed, 62 insertions, 7 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index e026ca1..2cb8a10 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2010-07-22 Ramana Radhakrishnan <ramana.radhakrishnan@arm.com>
+
+ PR target/43698
+ * config/arm/arm.md: Split arm_rev into *arm_rev
+ and *thumb1_rev. Set *arm_rev to be predicable.
+
2010-07-22 Iain Sandoe <iains@gcc.gnu.org>
* config/darwin.h (LINK_COMMAND_SPEC): Split into...
diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md
index bbe65ec..33b6931 100644
--- a/gcc/config/arm/arm.md
+++ b/gcc/config/arm/arm.md
@@ -11305,15 +11305,21 @@
(set_attr "length" "4")]
)
-(define_insn "arm_rev"
+(define_insn "*arm_rev"
[(set (match_operand:SI 0 "s_register_operand" "=r")
(bswap:SI (match_operand:SI 1 "s_register_operand" "r")))]
- "TARGET_EITHER && arm_arch6"
- "rev\t%0, %1"
- [(set (attr "length")
- (if_then_else (eq_attr "is_thumb" "yes")
- (const_int 2)
- (const_int 4)))]
+ "TARGET_32BIT && arm_arch6"
+ "rev%?\t%0, %1"
+ [(set_attr "predicable" "yes")
+ (set_attr "length" "4")]
+)
+
+(define_insn "*thumb1_rev"
+ [(set (match_operand:SI 0 "s_register_operand" "=l")
+ (bswap:SI (match_operand:SI 1 "s_register_operand" "l")))]
+ "TARGET_THUMB1 && arm_arch6"
+ "rev\t%0, %1"
+ [(set_attr "length" "2")]
)
(define_expand "arm_legacy_rev"
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index d284060..9c67b0a 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2010-07-22 Ramana Radhakrishnan <ramana.radhakrishnan@arm.com>
+
+ PR target/43698
+ * gcc.target/arm/pr43698.c: New test.
+
2010-07-21 Steven G. Kargl <kargl@gcc.gnu.org>
PR fortran/44929
diff --git a/gcc/testsuite/gcc.target/arm/pr43698.c b/gcc/testsuite/gcc.target/arm/pr43698.c
new file mode 100644
index 0000000..407cf7e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/pr43698.c
@@ -0,0 +1,38 @@
+/* { dg-do run } */
+/* { dg-options "-Os -march=armv7-a" } */
+#include <stdint.h>
+#include <stdlib.h>
+
+
+char do_reverse_endian = 0;
+
+# define bswap_32(x) \
+ ((((x) & 0xff000000) >> 24) | \
+ (((x) & 0x00ff0000) >> 8) | \
+ (((x) & 0x0000ff00) << 8) | \
+ (((x) & 0x000000ff) << 24))
+
+#define EGET(X) \
+ (__extension__ ({ \
+ uint64_t __res; \
+ if (!do_reverse_endian) { __res = (X); \
+ } else if (sizeof(X) == 4) { __res = bswap_32((X)); \
+ } \
+ __res; \
+ }))
+
+void __attribute__((noinline)) X(char **phdr, char **data, int *phoff)
+{
+ *phdr = *data + EGET(*phoff);
+}
+
+int main()
+{
+ char *phdr;
+ char *data = (char *)0x40164000;
+ int phoff = 0x34;
+ X(&phdr, &data, &phoff);
+ if (phdr != (char *)0x40164034)
+ abort ();
+ exit (0);
+}