diff options
author | Greta Yorsh <greta.yorsh@arm.com> | 2013-04-05 18:05:03 +0100 |
---|---|---|
committer | Greta Yorsh <gretay@gcc.gnu.org> | 2013-04-05 18:05:03 +0100 |
commit | 045e472c6eebe085feb5d3b95666409b78ba2b5b (patch) | |
tree | 88d13dd89c6dff412e90c30dd5eb0675a903cf66 | |
parent | adcef07c9bf0b575fd5d4cf1891a894bc4333a30 (diff) | |
download | gcc-045e472c6eebe085feb5d3b95666409b78ba2b5b.zip gcc-045e472c6eebe085feb5d3b95666409b78ba2b5b.tar.gz gcc-045e472c6eebe085feb5d3b95666409b78ba2b5b.tar.bz2 |
arm.md (negdi_extendsidi): New pattern.
2013-04-05 Greta Yorsh <Greta.Yorsh@arm.com>
gcc/
* config/arm/arm.md (negdi_extendsidi): New pattern.
(negdi_zero_extendsidi): Likewise.
gcc/testsuite
* gcc.target/arm/negdi-1.c: New test.
* gcc.target/arm/negdi-2.c: Likewise.
* gcc.target/arm/negdi-3.c: Likewise.
* gcc.target/arm/negdi-4.c: Likewise.
From-SVN: r197526
-rw-r--r-- | gcc/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/config/arm/arm.md | 67 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/arm/negdi-1.c | 17 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/arm/negdi-2.c | 16 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/arm/negdi-3.c | 17 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/arm/negdi-4.c | 16 |
7 files changed, 145 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index f3a799c..09eb000 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,10 @@ 2013-04-05 Greta Yorsh <Greta.Yorsh@arm.com> + * config/arm/arm.md (negdi_extendsidi): New pattern. + (negdi_zero_extendsidi): Likewise. + +2013-04-05 Greta Yorsh <Greta.Yorsh@arm.com> + * config/arm/arm.md (andsi_iorsi3_notsi): Convert define_insn into define_insn_and_split. (arm_negdi2,arm_abssi2,arm_neg_abssi2): Likewise. diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index 5c6d30e..e7c34bd 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -4344,6 +4344,73 @@ "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" "") +;; Negate an extended 32-bit value. +(define_insn_and_split "*negdi_extendsidi" + [(set (match_operand:DI 0 "s_register_operand" "=r,&r,l,&l") + (neg:DI (sign_extend:DI (match_operand:SI 1 "s_register_operand" "0,r,0,l")))) + (clobber (reg:CC CC_REGNUM))] + "TARGET_32BIT" + "#" ; rsb\\t%Q0, %1, #0\;asr\\t%R0, %Q0, #31 + "&& reload_completed" + [(const_int 0)] + { + operands[2] = gen_highpart (SImode, operands[0]); + operands[0] = gen_lowpart (SImode, operands[0]); + rtx tmp = gen_rtx_SET (VOIDmode, + operands[0], + gen_rtx_MINUS (SImode, + const0_rtx, + operands[1])); + if (TARGET_ARM) + { + emit_insn (tmp); + } + else + { + /* Set the flags, to emit the short encoding in Thumb2. */ + rtx flags = gen_rtx_SET (VOIDmode, + gen_rtx_REG (CCmode, CC_REGNUM), + gen_rtx_COMPARE (CCmode, + const0_rtx, + operands[1])); + emit_insn (gen_rtx_PARALLEL (VOIDmode, + gen_rtvec (2, + flags, + tmp))); + } + emit_insn (gen_rtx_SET (VOIDmode, + operands[2], + gen_rtx_ASHIFTRT (SImode, + operands[0], + GEN_INT (31)))); + DONE; + } + [(set_attr "length" "8,8,4,4") + (set_attr "arch" "a,a,t2,t2")] +) + +(define_insn_and_split "*negdi_zero_extendsidi" + [(set (match_operand:DI 0 "s_register_operand" "=r,&r") + (neg:DI (zero_extend:DI (match_operand:SI 1 "s_register_operand" "0,r")))) + (clobber (reg:CC CC_REGNUM))] + "TARGET_32BIT" + "#" ; "rsbs\\t%Q0, %1, #0\;sbc\\t%R0,%R0,%R0" + ;; Don't care what register is input to sbc, + ;; since we just just need to propagate the carry. + "&& reload_completed" + [(parallel [(set (reg:CC CC_REGNUM) + (compare:CC (const_int 0) (match_dup 1))) + (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))]) + (set (match_dup 2) (minus:SI (minus:SI (match_dup 2) (match_dup 2)) + (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))] + { + operands[2] = gen_highpart (SImode, operands[0]); + operands[0] = gen_lowpart (SImode, operands[0]); + } + [(set_attr "conds" "clob") + (set_attr "length" "8")] ;; length in thumb is 4 +) + ;; abssi2 doesn't really clobber the condition codes if a different register ;; is being set. To keep things simple, assume during rtl manipulations that ;; it does, but tell the final scan operator the truth. Similarly for diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index a12f1f4..b60003f 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2013-04-05 Greta Yorsh <Greta.Yorsh@arm.com> + + * gcc.target/arm/negdi-1.c: New test. + * gcc.target/arm/negdi-2.c: Likewise. + * gcc.target/arm/negdi-3.c: Likewise. + * gcc.target/arm/negdi-4.c: Likewise. + 2013-04-05 Kyrylo Tkachov <kyrylo.tkachov@arm.com> * lib/target-supports.exp (add_options_for_arm_v8_neon): diff --git a/gcc/testsuite/gcc.target/arm/negdi-1.c b/gcc/testsuite/gcc.target/arm/negdi-1.c new file mode 100644 index 0000000..c9bef04 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/negdi-1.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target arm32 } */ +/* { dg-options "-O2" } */ + +signed long long extendsidi_negsi (signed int x) +{ + return -x; +} + +/* +Expected output: + rsb r0, r0, #0 + mov r1, r0, asr #31 +*/ +/* { dg-final { scan-assembler-times "rsb" 1 { target { arm_nothumb } } } } */ +/* { dg-final { scan-assembler-times "negs\\t" 1 { target { ! { arm_nothumb } } } } } */ +/* { dg-final { scan-assembler-times "asr" 1 } } */ diff --git a/gcc/testsuite/gcc.target/arm/negdi-2.c b/gcc/testsuite/gcc.target/arm/negdi-2.c new file mode 100644 index 0000000..96bbcab --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/negdi-2.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target arm32 } */ +/* { dg-options "-O2" } */ + +signed long long zero_extendsidi_negsi (unsigned int x) +{ + return -x; +} +/* +Expected output: + rsb r0, r0, #0 + mov r1, #0 +*/ +/* { dg-final { scan-assembler-times "rsb\\tr0, r0, #0" 1 { target { arm_nothumb } } } } */ +/* { dg-final { scan-assembler-times "negs\\tr0, r0" 1 { target { ! arm_nothumb } } } } */ +/* { dg-final { scan-assembler-times "mov" 1 } } */ diff --git a/gcc/testsuite/gcc.target/arm/negdi-3.c b/gcc/testsuite/gcc.target/arm/negdi-3.c new file mode 100644 index 0000000..76ddf49 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/negdi-3.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target arm32 } */ +/* { dg-options "-O2" } */ + +signed long long negdi_zero_extendsidi (unsigned int x) +{ + return -((signed long long) x); +} +/* +Expected output: + rsbs r0, r0, #0 + sbc r1, r1, r1 +*/ +/* { dg-final { scan-assembler-times "rsb" 1 } } */ +/* { dg-final { scan-assembler-times "sbc" 1 } } */ +/* { dg-final { scan-assembler-times "mov" 0 } } */ +/* { dg-final { scan-assembler-times "rsc" 0 } } */ diff --git a/gcc/testsuite/gcc.target/arm/negdi-4.c b/gcc/testsuite/gcc.target/arm/negdi-4.c new file mode 100644 index 0000000..dc3deaa --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/negdi-4.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target arm32 } */ +/* { dg-options "-O2" } */ + +signed long long negdi_extendsidi (signed int x) +{ + return -((signed long long) x); +} +/* +Expected output: + rsbs r0, r0, #0 + mov r1, r0, asr #31 +*/ +/* { dg-final { scan-assembler-times "rsb" 1 } } */ +/* { dg-final { scan-assembler-times "asr" 1 } } */ +/* { dg-final { scan-assembler-times "rsc" 0 } } */ |