From beeea7eddb63b424676d59c253cf72c74df31c09 Mon Sep 17 00:00:00 2001 From: mmitchel Date: Sat, 23 May 2009 01:34:53 +0000 Subject: [PATCH] * config/arm/thumb2.md: Add 16-bit multiply instructions. gcc/testsuite/ * lib/target-supports.exp (check_effective_target_arm_thumb2_ok): New function. * gcc.target/arm/thumb2-mul-space.c: New file. * gcc.target/arm/thumb2-mul-space-2.c: New file. * gcc.target/arm/thumb2-mul-space-3.c: New file. * gcc.target/arm/thumb2-mul-speed.c: New file. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@147812 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 5 ++ gcc/config/arm/thumb2.md | 65 +++++++++++++++++++++++ gcc/testsuite/ChangeLog | 9 ++++ gcc/testsuite/gcc.target/arm/thumb2-mul-space-2.c | 15 ++++++ gcc/testsuite/gcc.target/arm/thumb2-mul-space-3.c | 17 ++++++ gcc/testsuite/gcc.target/arm/thumb2-mul-space.c | 10 ++++ gcc/testsuite/gcc.target/arm/thumb2-mul-speed.c | 27 ++++++++++ gcc/testsuite/lib/target-supports.exp | 11 ++++ 8 files changed, 159 insertions(+) create mode 100644 gcc/testsuite/gcc.target/arm/thumb2-mul-space-2.c create mode 100644 gcc/testsuite/gcc.target/arm/thumb2-mul-space-3.c create mode 100644 gcc/testsuite/gcc.target/arm/thumb2-mul-space.c create mode 100644 gcc/testsuite/gcc.target/arm/thumb2-mul-speed.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 68cbe58..a064127 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2009-05-22 Mark Mitchell + + * config/arm/thumb2.md: Add 16-bit multiply instructions. + gcc/testsuite/ + 2009-05-21 Michael Meissner PR tree-optimization/40219 diff --git a/gcc/config/arm/thumb2.md b/gcc/config/arm/thumb2.md index 87926f4..82d3413 100644 --- a/gcc/config/arm/thumb2.md +++ b/gcc/config/arm/thumb2.md @@ -1162,6 +1162,71 @@ (set_attr "length" "2")] ) +;; 16-bit encodings of "muls" and "mul". We only use these when +;; optimizing for size since "muls" is slow on all known +;; implementations and since "mul" will be generated by +;; "*arm_mulsi3_v6" anyhow. The assembler will use a 16-bit encoding +;; for "mul" whenever possible anyhow. +(define_peephole2 + [(set (match_operand:SI 0 "low_register_operand" "") + (mult:SI (match_operand:SI 1 "low_register_operand" "") + (match_dup 0)))] + "TARGET_THUMB2 && optimize_size && peep2_regno_dead_p (0, CC_REGNUM)" + [(parallel + [(set (match_dup 0) + (mult:SI (match_dup 0) (match_dup 1))) + (clobber (reg:CC CC_REGNUM))])] + "" +) + +(define_peephole2 + [(set (match_operand:SI 0 "low_register_operand" "") + (mult:SI (match_dup 0) + (match_operand:SI 1 "low_register_operand" "")))] + "TARGET_THUMB2 && optimize_size && peep2_regno_dead_p (0, CC_REGNUM)" + [(parallel + [(set (match_dup 0) + (mult:SI (match_dup 0) (match_dup 1))) + (clobber (reg:CC CC_REGNUM))])] + "" +) + +(define_insn "*thumb2_mulsi_short" + [(set (match_operand:SI 0 "low_register_operand" "=l") + (mult:SI (match_operand:SI 1 "low_register_operand" "%0") + (match_operand:SI 2 "low_register_operand" "l"))) + (clobber (reg:CC CC_REGNUM))] + "TARGET_THUMB2 && optimize_size && reload_completed" + "mul%!\\t%0, %2, %0" + [(set_attr "predicable" "yes") + (set_attr "length" "2") + (set_attr "insn" "muls")]) + +(define_insn "*thumb2_mulsi_short_compare0" + [(set (reg:CC_NOOV CC_REGNUM) + (compare:CC_NOOV + (mult:SI (match_operand:SI 1 "register_operand" "%0") + (match_operand:SI 2 "register_operand" "l")) + (const_int 0))) + (set (match_operand:SI 0 "register_operand" "=l") + (mult:SI (match_dup 1) (match_dup 2)))] + "TARGET_THUMB2 && optimize_size" + "muls\\t%0, %2, %0" + [(set_attr "length" "2") + (set_attr "insn" "muls")]) + +(define_insn "*thumb2_mulsi_short_compare0_scratch" + [(set (reg:CC_NOOV CC_REGNUM) + (compare:CC_NOOV + (mult:SI (match_operand:SI 1 "register_operand" "%0") + (match_operand:SI 2 "register_operand" "l")) + (const_int 0))) + (clobber (match_scratch:SI 0 "=r"))] + "TARGET_THUMB2 && optimize_size" + "muls\\t%0, %2, %0" + [(set_attr "length" "2") + (set_attr "insn" "muls")]) + (define_insn "*thumb2_cbz" [(set (pc) (if_then_else (eq (match_operand:SI 0 "s_register_operand" "l,?r") diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index ed04544..1de60ba 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,12 @@ +2009-05-22 Mark Mitchell + + * lib/target-supports.exp (check_effective_target_arm_thumb2_ok): + New function. + * gcc.target/arm/thumb2-mul-space.c: New file. + * gcc.target/arm/thumb2-mul-space-2.c: New file. + * gcc.target/arm/thumb2-mul-space-3.c: New file. + * gcc.target/arm/thumb2-mul-speed.c: New file. + 2009-05-22 Richard Guenther PR middle-end/38964 diff --git a/gcc/testsuite/gcc.target/arm/thumb2-mul-space-2.c b/gcc/testsuite/gcc.target/arm/thumb2-mul-space-2.c new file mode 100644 index 0000000..b53df2f --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/thumb2-mul-space-2.c @@ -0,0 +1,15 @@ +/* In Thumb-2 mode, when optimizing for size, generate a "muls" + instruction and use the resulting condition flags rather than a + separate compare instruction. */ +/* { dg-options "-mthumb -Os" } */ +/* { dg-require-effective-target arm_thumb2_ok } */ +/* { dg-final { scan-assembler "muls" } } */ +/* { dg-final { scan-assembler-not "cmp" } } */ + +int x; + +void f(int i, int j) +{ + if (i * j < 0) + x = 1; +} diff --git a/gcc/testsuite/gcc.target/arm/thumb2-mul-space-3.c b/gcc/testsuite/gcc.target/arm/thumb2-mul-space-3.c new file mode 100644 index 0000000..143a6de --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/thumb2-mul-space-3.c @@ -0,0 +1,17 @@ +/* In Thumb-2 mode, when optimizing for size, generate a "muls" + instruction and use the resulting condition flags rather than a + separate compare instruction. */ +/* { dg-options "-mthumb -Os" } */ +/* { dg-require-effective-target arm_thumb2_ok } */ +/* { dg-final { scan-assembler "muls" } } */ +/* { dg-final { scan-assembler-not "cmp" } } */ + +int x; + +int f(int i, int j) +{ + i = i * j; + if (i < 0) + x = 1; + return i; +} diff --git a/gcc/testsuite/gcc.target/arm/thumb2-mul-space.c b/gcc/testsuite/gcc.target/arm/thumb2-mul-space.c new file mode 100644 index 0000000..8cf0cb4 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/thumb2-mul-space.c @@ -0,0 +1,10 @@ +/* Use 16-bit multiply instruction in Thumb-2 mode when optimizing for + size. */ +/* { dg-options "-mthumb -Os" } */ +/* { dg-require-effective-target arm_thumb2_ok } */ +/* { dg-final { scan-assembler "muls" } } */ + +int f(int i, int j) +{ + return i * j; +} diff --git a/gcc/testsuite/gcc.target/arm/thumb2-mul-speed.c b/gcc/testsuite/gcc.target/arm/thumb2-mul-speed.c new file mode 100644 index 0000000..03cccdb --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/thumb2-mul-speed.c @@ -0,0 +1,27 @@ +/* Do not use 16-bit multiply instructions in Thumb-2 mode when + optimizing for speed. */ +/* { dg-options "-mthumb -O2" } */ +/* { dg-require-effective-target arm_thumb2_ok } */ +/* { dg-final { scan-assembler-not "muls" } } */ + +int f(int i, int j) +{ + return i * j; +} + +int x; + +void g(int i, int j) +{ + if (i * j < 0) + x = 1; +} + +int h(int i, int j) +{ + i = i * j; + if (i < 0) + x = 1; + return i; +} + diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp index 3282d6d..f726e6f 100644 --- a/gcc/testsuite/lib/target-supports.exp +++ b/gcc/testsuite/lib/target-supports.exp @@ -1477,6 +1477,17 @@ proc check_effective_target_arm_thumb1_ok { } { } "-mthumb"] } +# Return 1 is this is an ARM target where -mthumb causes Thumb-2 to be +# used. + +proc check_effective_target_arm_thumb2_ok { } { + return [check_no_compiler_messages arm_thumb2_ok assembly { + #if !defined(__thumb2__) + #error FOO + #endif + } "-mthumb"] +} + # Return 1 if the target supports executing NEON instructions, 0 # otherwise. Cache the result. -- 2.7.4