From f67325e8386753732d594aa81e9fffecbaec24c4 Mon Sep 17 00:00:00 2001 From: Ramana Radhakrishnan <ramana.radhakrishnan@arm.com> Date: Thu, 22 Jul 2010 08:30:36 +0000 Subject: [PATCH] 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 --- gcc/ChangeLog | 6 ++++ gcc/config/arm/arm.md | 20 +++++++++----- gcc/testsuite/ChangeLog | 5 ++++ gcc/testsuite/gcc.target/arm/pr43698.c | 38 ++++++++++++++++++++++++++ 4 files changed, 62 insertions(+), 7 deletions(-) create mode 100644 gcc/testsuite/gcc.target/arm/pr43698.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e026ca1d1d8f..2cb8a104e94a 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 bbe65ec27ba8..33b6931de14a 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 d284060a19b6..9c67b0a4e73c 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 000000000000..407cf7eac2cb --- /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); +} -- GitLab