Message ID | 555632A9.6050007@arm.com |
---|---|
State | New |
Headers | show |
Hi Alex, On 15/05/15 18:53, Alex Velenko wrote: > On 01/05/15 10:28, Kyrill Tkachov wrote: >> Can you please confirm that bootstraps with both arm and thumb pass? >> That is, configured with --with-mode=arm and --with-mode=thumb >> > Hi Kyrill, > > Bootstrapped on arm-none-gnueabihf with arm and thumb mode. > > Following patch requires bics shift operand on Thumb2 to be > const int, as bics shifted by register is not supported by > Thumb2. > > Is patch ok? > > gcc > > 2015-05-15 Alex Velenko <Alex.Velenko@arm.com> > > * config/arm/arm.md (andsi_not_shiftsi_si_scc): New pattern. > * (andsi_not_shiftsi_si_scc_no_reuse): New pattern. No need for the '*', just: * config/arm/arm.md (andsi_not_shiftsi_si_scc): New pattern. (andsi_not_shiftsi_si_scc_no_reuse): Likewise. will do. Ok for trunk with that ChangeLog nit. Thanks, Kyrill > > gcc/testsuite > > 2015-05-15 Alex Velenko <Alex.Velenko@arm.com> > > * gcc.target/arm/bics_1.c : New testcase. > * gcc.target/arm/bics_2.c : New testcase. > * gcc.target/arm/bics_3.c : New testcase. > * gcc.target/arm/bics_4.c : New testcase. > --- > gcc/config/arm/arm.md | 49 ++++++++++++++++++++++++++++++ > gcc/testsuite/gcc.target/arm/bics_1.c | 54 > +++++++++++++++++++++++++++++++++ > gcc/testsuite/gcc.target/arm/bics_2.c | 57 > +++++++++++++++++++++++++++++++++++ > gcc/testsuite/gcc.target/arm/bics_3.c | 41 +++++++++++++++++++++++++ > gcc/testsuite/gcc.target/arm/bics_4.c | 49 ++++++++++++++++++++++++++++++ > 5 files changed, 250 insertions(+) > create mode 100644 gcc/testsuite/gcc.target/arm/bics_1.c > create mode 100644 gcc/testsuite/gcc.target/arm/bics_2.c > create mode 100644 gcc/testsuite/gcc.target/arm/bics_3.c > create mode 100644 gcc/testsuite/gcc.target/arm/bics_4.c > > diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md > index 164ac13..26d3ad2 100644 > --- a/gcc/config/arm/arm.md > +++ b/gcc/config/arm/arm.md > @@ -2768,6 +2768,55 @@ > (const_string "logic_shift_reg")))] > ) > > +;; Shifted bics pattern used to set up CC status register and not reusing > +;; bics output. Pattern restricts Thumb2 shift operand as bics for Thumb2 > +;; does not support shift by register. > +(define_insn "andsi_not_shiftsi_si_scc_no_reuse" > + [(set (reg:CC_NOOV CC_REGNUM) > + (compare:CC_NOOV > + (and:SI (not:SI (match_operator:SI 0 "shift_operator" > + [(match_operand:SI 1 "s_register_operand" "r") > + (match_operand:SI 2 "arm_rhs_operand" "rM")])) > + (match_operand:SI 3 "s_register_operand" "r")) > + (const_int 0))) > + (clobber (match_scratch:SI 4 "=3Dr"))] > + "TARGET_ARM || (TARGET_THUMB2 && CONST_INT_P (operands[2]))" > + "bic%.%?\\t%4, %3, %1%S0" > + [(set_attr "predicable" "yes") > + (set_attr "predicable_short_it" "no") > + (set_attr "conds" "set") > + (set_attr "shift" "1") > + (set (attr "type") (if_then_else (match_operand 2 > "const_int_operand" "") > + (const_string "logic_shift_imm") > + (const_string "logic_shift_reg")))] > +) > + > +;; Same as andsi_not_shiftsi_si_scc_no_reuse, but the bics result is also > +;; getting reused later. > +(define_insn "andsi_not_shiftsi_si_scc" > + [(parallel [(set (reg:CC_NOOV CC_REGNUM) > + (compare:CC_NOOV > + (and:SI (not:SI (match_operator:SI 0 "shift_operator" > + [(match_operand:SI 1 "s_register_operand" "r") > + (match_operand:SI 2 "arm_rhs_operand" "rM")])) > + (match_operand:SI 3 "s_register_operand" "r")) > + (const_int 0))) > + (set (match_operand:SI 4 "s_register_operand" "=3Dr") > + (and:SI (not:SI (match_op_dup 0 > + [(match_dup 1) > + (match_dup 2)])) > + (match_dup 3)))])] > + "TARGET_ARM || (TARGET_THUMB2 && CONST_INT_P (operands[2]))" > + "bic%.%?\\t%4, %3, %1%S0" > + [(set_attr "predicable" "yes") > + (set_attr "predicable_short_it" "no") > + (set_attr "conds" "set") > + (set_attr "shift" "1") > + (set (attr "type") (if_then_else (match_operand 2 > "const_int_operand" "") > + (const_string "logic_shift_imm") > + (const_string "logic_shift_reg")))] > +) > + > (define_insn "*andsi_notsi_si_compare0" > [(set (reg:CC_NOOV CC_REGNUM) > (compare:CC_NOOV > diff --git a/gcc/testsuite/gcc.target/arm/bics_1.c > b/gcc/testsuite/gcc.target/arm/bics_1.c > new file mode 100644 > index 0000000..173eb89 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/arm/bics_1.c > @@ -0,0 +1,54 @@ > +/* { dg-do run } */ > +/* { dg-options "-O2 --save-temps -fno-inline" } */ > +/* { dg-require-effective-target arm32 } */ > + > +extern void abort (void); > + > +int > +bics_si_test1 (int a, int b, int c) > +{ > + int d =3D a & ~b; > + > + /* { dg-final { scan-assembler-times "bics\tr\[0-9\]+, r\[0-9\]+, > r\[0-9\]+" 2 } } */ > + if (d =3D=3D 0) > + return a + c; > + else > + return b + d + c; > +} > + > +int > +bics_si_test2 (int a, int b, int c) > +{ > + int d =3D a & ~(b << 3); > + > + /* { dg-final { scan-assembler-times "bics\tr\[0-9\]+, r\[0-9\]+, > r\[0-9\]+, .sl \#3" 1 } } */ > + if (d =3D=3D 0) > + return a + c; > + else > + return b + d + c; > +} > + > +int > +main () > +{ > + int x; > + > + x =3D bics_si_test1 (29, ~4, 5); > + if (x !=3D ((29 & 4) + ~4 + 5)) > + abort (); > + > + x =3D bics_si_test1 (5, ~2, 20); > + if (x !=3D 25) > + abort (); > + > + x =3D bics_si_test2 (35, ~4, 5); > + if (x !=3D ((35 & ~(~4 << 3)) + ~4 + 5)) > + abort (); > + > + x =3D bics_si_test2 (96, ~2, 20); > + if (x !=3D 116) > + abort (); > + > + return 0; > +} > +/* { dg-final { cleanup-saved-temps } } */ > diff --git a/gcc/testsuite/gcc.target/arm/bics_2.c > b/gcc/testsuite/gcc.target/arm/bics_2.c > new file mode 100644 > index 0000000..740d7c9 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/arm/bics_2.c > @@ -0,0 +1,57 @@ > +/* { dg-do run } */ > +/* { dg-options "-O2 --save-temps -fno-inline" } */ > +/* { dg-require-effective-target arm32 } */ > + > +extern void abort (void); > + > +int > +bics_si_test1 (int a, int b, int c) > +{ > + int d =3D a & ~b; > + > + /* { dg-final { scan-assembler-not "bics\tr\[0-9\]+, r\[0-9\]+, > r\[0-9\]+" } } */ > + /* { dg-final { scan-assembler-times "bic\tr\[0-9\]+, r\[0-9\]+, > r\[0-9\]+" 2 } } */ > + if (d <=3D 0) > + return a + c; > + else > + return b + d + c; > +} > + > +int > +bics_si_test2 (int a, int b, int c) > +{ > + int d =3D a & ~(b << 3); > + > + /* { dg-final { scan-assembler-not "bics\tr\[0-9\]+, r\[0-9\]+, > r\[0-9\]+, .sl \#3" } } */ > + /* { dg-final { scan-assembler "bic\tr\[0-9\]+, r\[0-9\]+, r\[0-9\]+, > .sl \#3" } } */ > + if (d <=3D 0) > + return a + c; > + else > + return b + d + c; > +} > + > +int > +main () > +{ > + int x; > + > + x =3D bics_si_test1 (29, ~4, 5); > + if (x !=3D ((29 & 4) + ~4 + 5)) > + abort (); > + > + x =3D bics_si_test1 (5, ~2, 20); > + if (x !=3D 25) > + abort (); > + > + x =3D bics_si_test2 (35, ~4, 5); > + if (x !=3D ((35 & ~(~4 << 3)) + ~4 + 5)) > + abort (); > + > + x =3D bics_si_test2 (96, ~2, 20); > + if (x !=3D 116) > + abort (); > + > + return 0; > +} > + > +/* { dg-final { cleanup-saved-temps } } */ > diff --git a/gcc/testsuite/gcc.target/arm/bics_3.c > b/gcc/testsuite/gcc.target/arm/bics_3.c > new file mode 100644 > index 0000000..e2b1c72 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/arm/bics_3.c > @@ -0,0 +1,41 @@ > +/* { dg-do run } */ > +/* { dg-options "-O2 --save-temps -fno-inline" } */ > +/* { dg-require-effective-target arm32 } */ > + > +extern void abort (void); > + > +int > +bics_si_test (int a, int b) > +{ > + if (a & ~b) > + return 1; > + else > + return 0; > +} > + > +int > +bics_si_test2 (int a, int b) > +{ > + if (a & ~ (b << 2)) > + return 1; > + else > + return 0; > +} > + > +int > +main (void) > +{ > + int a =3D 5; > + int b =3D 5; > + int c =3D 20; > + if (bics_si_test (a, b)) > + abort (); > + if (bics_si_test2 (c, b)) > + abort (); > + return 0; > +} > + > +/* { dg-final { scan-assembler-times "bics\tr\[0-9\]+, r\[0-9\]+, > r\[0-9\]+" 2 } } */ > +/* { dg-final { scan-assembler-times "bics\tr\[0-9\]+, r\[0-9\]+, > r\[0-9\]+, .sl #2" 1 } } */ > + > +/* { dg-final { cleanup-saved-temps } } */ > diff --git a/gcc/testsuite/gcc.target/arm/bics_4.c > b/gcc/testsuite/gcc.target/arm/bics_4.c > new file mode 100644 > index 0000000..8f2faf0 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/arm/bics_4.c > @@ -0,0 +1,49 @@ > +/* { dg-do run } */ > +/* { dg-options "-O2 --save-temps -fno-inline" } */ > +/* { dg-require-effective-target arm32 } */ > + > +extern void abort (void); > + > +int > +bics_si_test1 (int a, int b, int c) > +{ > + if ((a & b) =3D=3D a) > + return a; > + else > + return c; > +} > + > +int > +bics_si_test2 (int a, int b, int c) > +{ > + if ((a & b) =3D=3D b) > + return b; > + else > + return c; > +} > + > +int > +main () > +{ > + int x; > + x =3D bics_si_test1 (0xf00d, 0xf11f, 0); > + if (x !=3D 0xf00d) > + abort (); > + > + x =3D bics_si_test1 (0xf11f, 0xf00d, 0); > + if (x !=3D 0) > + abort (); > + > + x =3D bics_si_test2 (0xf00d, 0xf11f, 0); > + if (x !=3D 0) > + abort (); > + > + x =3D bics_si_test2 (0xf11f, 0xf00d, 0); > + if (x !=3D 0xf00d) > + abort (); > + > + return 0; > +} > + > +/* { dg-final { scan-assembler-times "bics\tr\[0-9\]+, r\[0-9\]+, > r\[0-9\]+" 2 } } */ > +/* { dg-final { cleanup-saved-temps } } */ > -- > 1.8.1.2
Committed r223295. Alex.
diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index 164ac13..26d3ad2 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -2768,6 +2768,55 @@ (const_string "logic_shift_reg")))] ) +;; Shifted bics pattern used to set up CC status register and not reusing +;; bics output. Pattern restricts Thumb2 shift operand as bics for Thumb2 +;; does not support shift by register. +(define_insn "andsi_not_shiftsi_si_scc_no_reuse" + [(set (reg:CC_NOOV CC_REGNUM) + (compare:CC_NOOV + (and:SI (not:SI (match_operator:SI 0 "shift_operator" + [(match_operand:SI 1 "s_register_operand" "r") + (match_operand:SI 2 "arm_rhs_operand" "rM")])) + (match_operand:SI 3 "s_register_operand" "r")) + (const_int 0))) + (clobber (match_scratch:SI 4 "=3Dr"))] + "TARGET_ARM || (TARGET_THUMB2 && CONST_INT_P (operands[2]))" + "bic%.%?\\t%4, %3, %1%S0" + [(set_attr "predicable" "yes") + (set_attr "predicable_short_it" "no") + (set_attr "conds" "set") + (set_attr "shift" "1") + (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "") + (const_string "logic_shift_imm") + (const_string "logic_shift_reg")))] +) + +;; Same as andsi_not_shiftsi_si_scc_no_reuse, but the bics result is also +;; getting reused later. +(define_insn "andsi_not_shiftsi_si_scc" + [(parallel [(set (reg:CC_NOOV CC_REGNUM) + (compare:CC_NOOV + (and:SI (not:SI (match_operator:SI 0 "shift_operator" + [(match_operand:SI 1 "s_register_operand" "r") + (match_operand:SI 2 "arm_rhs_operand" "rM")])) + (match_operand:SI 3 "s_register_operand" "r")) + (const_int 0))) + (set (match_operand:SI 4 "s_register_operand" "=3Dr") + (and:SI (not:SI (match_op_dup 0 + [(match_dup 1) + (match_dup 2)])) + (match_dup 3)))])] + "TARGET_ARM || (TARGET_THUMB2 && CONST_INT_P (operands[2]))" + "bic%.%?\\t%4, %3, %1%S0" + [(set_attr "predicable" "yes") + (set_attr "predicable_short_it" "no") + (set_attr "conds" "set") + (set_attr "shift" "1") + (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "") + (const_string "logic_shift_imm") + (const_string "logic_shift_reg")))] +) + (define_insn "*andsi_notsi_si_compare0" [(set (reg:CC_NOOV CC_REGNUM) (compare:CC_NOOV diff --git a/gcc/testsuite/gcc.target/arm/bics_1.c b/gcc/testsuite/gcc.target/arm/bics_1.c new file mode 100644 index 0000000..173eb89 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/bics_1.c @@ -0,0 +1,54 @@ +/* { dg-do run } */ +/* { dg-options "-O2 --save-temps -fno-inline" } */ +/* { dg-require-effective-target arm32 } */ + +extern void abort (void); + +int +bics_si_test1 (int a, int b, int c) +{ + int d =3D a & ~b; + + /* { dg-final { scan-assembler-times "bics\tr\[0-9\]+, r\[0-9\]+, r\[0-9\]+" 2 } } */ + if (d =3D=3D 0) + return a + c; + else + return b + d + c; +} + +int +bics_si_test2 (int a, int b, int c) +{ + int d =3D a & ~(b << 3); + + /* { dg-final { scan-assembler-times "bics\tr\[0-9\]+, r\[0-9\]+, r\[0-9\]+, .sl \#3" 1 } } */ + if (d =3D=3D 0) + return a + c; + else + return b + d + c; +} + +int +main () +{ + int x; + + x =3D bics_si_test1 (29, ~4, 5); + if (x !=3D ((29 & 4) + ~4 + 5)) + abort (); + + x =3D bics_si_test1 (5, ~2, 20); + if (x !=3D 25) + abort (); + + x =3D bics_si_test2 (35, ~4, 5); + if (x !=3D ((35 & ~(~4 << 3)) + ~4 + 5)) + abort (); + + x =3D bics_si_test2 (96, ~2, 20); + if (x !=3D 116) + abort (); + + return 0; +} +/* { dg-final { cleanup-saved-temps } } */ diff --git a/gcc/testsuite/gcc.target/arm/bics_2.c b/gcc/testsuite/gcc.target/arm/bics_2.c new file mode 100644 index 0000000..740d7c9 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/bics_2.c @@ -0,0 +1,57 @@ +/* { dg-do run } */ +/* { dg-options "-O2 --save-temps -fno-inline" } */ +/* { dg-require-effective-target arm32 } */ + +extern void abort (void); + +int +bics_si_test1 (int a, int b, int c) +{ + int d =3D a & ~b; + + /* { dg-final { scan-assembler-not "bics\tr\[0-9\]+, r\[0-9\]+, r\[0-9\]+" } } */ + /* { dg-final { scan-assembler-times "bic\tr\[0-9\]+, r\[0-9\]+, r\[0-9\]+" 2 } } */ + if (d <=3D 0) + return a + c; + else + return b + d + c; +} + +int +bics_si_test2 (int a, int b, int c) +{ + int d =3D a & ~(b << 3); + + /* { dg-final { scan-assembler-not "bics\tr\[0-9\]+, r\[0-9\]+, r\[0-9\]+, .sl \#3" } } */ + /* { dg-final { scan-assembler "bic\tr\[0-9\]+, r\[0-9\]+, r\[0-9\]+, .sl \#3" } } */ + if (d <=3D 0) + return a + c; + else + return b + d + c; +} + +int +main () +{ + int x; + + x =3D bics_si_test1 (29, ~4, 5); + if (x !=3D ((29 & 4) + ~4 + 5)) + abort (); + + x =3D bics_si_test1 (5, ~2, 20); + if (x !=3D 25) + abort (); + + x =3D bics_si_test2 (35, ~4, 5); + if (x !=3D ((35 & ~(~4 << 3)) + ~4 + 5)) + abort (); + + x =3D bics_si_test2 (96, ~2, 20); + if (x !=3D 116) + abort (); + + return 0; +} + +/* { dg-final { cleanup-saved-temps } } */ diff --git a/gcc/testsuite/gcc.target/arm/bics_3.c b/gcc/testsuite/gcc.target/arm/bics_3.c new file mode 100644 index 0000000..e2b1c72 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/bics_3.c @@ -0,0 +1,41 @@ +/* { dg-do run } */ +/* { dg-options "-O2 --save-temps -fno-inline" } */ +/* { dg-require-effective-target arm32 } */ + +extern void abort (void); + +int +bics_si_test (int a, int b) +{ + if (a & ~b) + return 1; + else + return 0; +} + +int +bics_si_test2 (int a, int b) +{ + if (a & ~ (b << 2)) + return 1; + else + return 0; +} + +int +main (void) +{ + int a =3D 5; + int b =3D 5; + int c =3D 20; + if (bics_si_test (a, b)) + abort (); + if (bics_si_test2 (c, b)) + abort (); + return 0; +} + +/* { dg-final { scan-assembler-times "bics\tr\[0-9\]+, r\[0-9\]+, r\[0-9\]+" 2 } } */ +/* { dg-final { scan-assembler-times "bics\tr\[0-9\]+, r\[0-9\]+, r\[0-9\]+, .sl #2" 1 } } */ + +/* { dg-final { cleanup-saved-temps } } */ diff --git a/gcc/testsuite/gcc.target/arm/bics_4.c b/gcc/testsuite/gcc.target/arm/bics_4.c new file mode 100644 index 0000000..8f2faf0 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/bics_4.c @@ -0,0 +1,49 @@ +/* { dg-do run } */ +/* { dg-options "-O2 --save-temps -fno-inline" } */ +/* { dg-require-effective-target arm32 } */ + +extern void abort (void); + +int +bics_si_test1 (int a, int b, int c) +{ + if ((a & b) =3D=3D a) + return a; + else + return c; +} + +int +bics_si_test2 (int a, int b, int c) +{ + if ((a & b) =3D=3D b) + return b; + else + return c; +} + +int +main () +{ + int x; + x =3D bics_si_test1 (0xf00d, 0xf11f, 0); + if (x !=3D 0xf00d) + abort (); + + x =3D bics_si_test1 (0xf11f, 0xf00d, 0); + if (x !=3D 0) + abort (); + + x =3D bics_si_test2 (0xf00d, 0xf11f, 0); + if (x !=3D 0) + abort (); + + x =3D bics_si_test2 (0xf11f, 0xf00d, 0); + if (x !=3D 0xf00d) + abort (); + + return 0; +} + +/* { dg-final { scan-assembler-times "bics\tr\[0-9\]+, r\[0-9\]+, r\[0-9\]+" 2 } } */