]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR target/43698 (Wrong use of ARMv6 REV instruction for endian bytewapping with...
authorRamana Radhakrishnan <ramana.radhakrishnan@arm.com>
Thu, 22 Jul 2010 08:30:36 +0000 (08:30 +0000)
committerRamana Radhakrishnan <ramana@gcc.gnu.org>
Thu, 22 Jul 2010 08:30:36 +0000 (08:30 +0000)
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

gcc/ChangeLog
gcc/config/arm/arm.md
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/arm/pr43698.c [new file with mode: 0644]

index e026ca1d1d8f7c535aae0c08be0a617f26ae381b..2cb8a104e94a1c9f8c6e01e189a03d95b894988e 100644 (file)
@@ -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...
index bbe65ec27ba8bd51e11c4be0e0b329d82b566596..33b6931de14abb397efcf8c940f23a967969a1b8 100644 (file)
    (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"
index d284060a19b6f942f5fe5c9be2e6fe3a1f87b23c..9c67b0a4e73c9674d25def8dd323023ab9f15382 100644 (file)
@@ -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 (file)
index 0000000..407cf7e
--- /dev/null
@@ -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);
+}