From: Alex Velenko Date: Mon, 18 May 2015 14:38:41 +0000 (+0000) Subject: arm.md (andsi_not_shiftsi_si_scc): New pattern. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=0454e698401a3ec49700e59855e44493ab9fdbdb;p=gcc.git arm.md (andsi_not_shiftsi_si_scc): New pattern. gcc/config 2015-05-18 Alex Velenko * arm/arm.md (andsi_not_shiftsi_si_scc): New pattern. (andsi_not_shiftsi_si_scc_no_reuse): New pattern. gcc/testsuite 2015-05-18 Alex Velenko * 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. From-SVN: r223295 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 27b4d266d20..e82485baa5b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2015-05-18 Alex Velenko + + * config/arm/arm.md (andsi_not_shiftsi_si_scc): New pattern. + (andsi_not_shiftsi_si_scc_no_reuse): New pattern. + 2015-05-18 Robert Suchanek * config/mips/mips.c (micromips_globals): New variable. diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index 9a71b79fc5d..191f5e76827 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -2783,6 +2783,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 "=r"))] + "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" "=r") + (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/ChangeLog b/gcc/testsuite/ChangeLog index 5206d883a15..8a29d995a4f 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2015-05-18 Alex Velenko + + * 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. + 2015-05-18 Robert Suchanek * gcc.target/mips/umips-attr.c: New test. 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 00000000000..173eb891d3a --- /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 = a & ~b; + + /* { dg-final { scan-assembler-times "bics\tr\[0-9\]+, r\[0-9\]+, r\[0-9\]+" 2 } } */ + if (d == 0) + return a + c; + else + return b + d + c; +} + +int +bics_si_test2 (int a, int b, int c) +{ + int d = a & ~(b << 3); + + /* { dg-final { scan-assembler-times "bics\tr\[0-9\]+, r\[0-9\]+, r\[0-9\]+, .sl \#3" 1 } } */ + if (d == 0) + return a + c; + else + return b + d + c; +} + +int +main () +{ + int x; + + x = bics_si_test1 (29, ~4, 5); + if (x != ((29 & 4) + ~4 + 5)) + abort (); + + x = bics_si_test1 (5, ~2, 20); + if (x != 25) + abort (); + + x = bics_si_test2 (35, ~4, 5); + if (x != ((35 & ~(~4 << 3)) + ~4 + 5)) + abort (); + + x = bics_si_test2 (96, ~2, 20); + if (x != 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 00000000000..740d7c913f0 --- /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 = 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 <= 0) + return a + c; + else + return b + d + c; +} + +int +bics_si_test2 (int a, int b, int c) +{ + int d = 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 <= 0) + return a + c; + else + return b + d + c; +} + +int +main () +{ + int x; + + x = bics_si_test1 (29, ~4, 5); + if (x != ((29 & 4) + ~4 + 5)) + abort (); + + x = bics_si_test1 (5, ~2, 20); + if (x != 25) + abort (); + + x = bics_si_test2 (35, ~4, 5); + if (x != ((35 & ~(~4 << 3)) + ~4 + 5)) + abort (); + + x = bics_si_test2 (96, ~2, 20); + if (x != 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 00000000000..e2b1c72cfde --- /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 = 5; + int b = 5; + int c = 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 00000000000..8f2faf01a0d --- /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) == a) + return a; + else + return c; +} + +int +bics_si_test2 (int a, int b, int c) +{ + if ((a & b) == b) + return b; + else + return c; +} + +int +main () +{ + int x; + x = bics_si_test1 (0xf00d, 0xf11f, 0); + if (x != 0xf00d) + abort (); + + x = bics_si_test1 (0xf11f, 0xf00d, 0); + if (x != 0) + abort (); + + x = bics_si_test2 (0xf00d, 0xf11f, 0); + if (x != 0) + abort (); + + x = bics_si_test2 (0xf11f, 0xf00d, 0); + if (x != 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 } } */