diff options
author | Roger Sayle <roger@nextmovesoftware.com> | 2023-04-29 20:18:23 +0100 |
---|---|---|
committer | Roger Sayle <roger@nextmovesoftware.com> | 2023-04-29 20:18:23 +0100 |
commit | e2b204c31ba2b77dfe4a062b194129b7c97c81ad (patch) | |
tree | c12fb1a3df83fff7214c8c393b5a0aa63d3a2fc4 | |
parent | 58f3cbbd7e02c29f2abd6300c0fec053559e35b4 (diff) | |
download | gcc-e2b204c31ba2b77dfe4a062b194129b7c97c81ad.zip gcc-e2b204c31ba2b77dfe4a062b194129b7c97c81ad.tar.gz gcc-e2b204c31ba2b77dfe4a062b194129b7c97c81ad.tar.bz2 |
[xstormy16] Efficient HImode rotate left by a single bit.
This patch contains some minor tweak to xstormy16's machine description
most significantly providing a pattern for HImode rotate left by a single
bit that requires only two instructions.
unsigned short foo(unsigned short x)
{
return (x << 1) | (x >> 15);
}
currently with -O2 generates:
foo: mov r7,r2
shr r7,#15
shl r2,#1
or r2,r7
ret
with this patch, GCC now generates:
foo: shl r2,#1 | adc r2,#0
ret
Additionally neghi2 is converted to a define_insn (so that the RTL
optimizers see the negation semantics), and HImode rotations by
8-bits can now be recognized and implemented using swpb.
2023-04-29 Roger Sayle <roger@nextmovesoftware.com>
gcc/ChangeLog
* config/stormy16/stormy16.md (neghi2): Convert from a define_expand
to a define_insn.
(*rotatehi_1): New define_insn for efficient 2 insn sequence.
(*rotatehi_8, *rotaterthi_8): New define_insn to emit a swpb.
gcc/testsuite/ChangeLog
* gcc.target/xstormy16/neghi2.c: New test case.
* gcc.target/xstormy16/rotatehi-1.c: Likewise.
-rw-r--r-- | gcc/config/stormy16/stormy16.md | 28 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/xstormy16/neghi2.c | 8 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/xstormy16/rotatehi-1.c | 10 |
3 files changed, 41 insertions, 5 deletions
diff --git a/gcc/config/stormy16/stormy16.md b/gcc/config/stormy16/stormy16.md index 87e9287..be1ee04 100644 --- a/gcc/config/stormy16/stormy16.md +++ b/gcc/config/stormy16/stormy16.md @@ -518,13 +518,13 @@ ;; Negation -(define_expand "neghi2" - [(set (match_operand:HI 0 "register_operand" "") - (not:HI (match_operand:HI 1 "register_operand" ""))) - (parallel [(set (match_dup 0) (plus:HI (match_dup 0) (const_int 1))) +(define_insn "neghi2" + [(parallel [(set (match_operand:HI 0 "register_operand" "=r") + (neg:HI (match_operand:HI 1 "register_operand" "0"))) (clobber (reg:BI CARRY_REG))])] "" - "") + "not %0 | add %0,#1" + [(set_attr "length" "4")]) ;; :::::::::::::::::::: ;; :: @@ -558,6 +558,24 @@ (clobber (reg:BI CARRY_REG))] "" "shr %0,%2") + +;; HImode rotate left by 1 bit +(define_insn "*rotatehi_1" + [(set (match_operand:HI 0 "register_operand" "=r") + (rotate:HI (match_operand:HI 1 "register_operand" "0") + (const_int 1))) + (clobber (reg:BI CARRY_REG))] + "" + "shl %0,#1 | adc %0,#0" + [(set_attr "length" "4")]) + +;; HImode rotate left by 8 bits +(define_insn "*<code>hi_8" + [(set (match_operand:HI 0 "register_operand" "=r") + (any_rotate:HI (match_operand:HI 1 "register_operand" "0") + (const_int 8)))] + "" + "swpb %0") ;; :::::::::::::::::::: ;; :: diff --git a/gcc/testsuite/gcc.target/xstormy16/neghi2.c b/gcc/testsuite/gcc.target/xstormy16/neghi2.c new file mode 100644 index 0000000..dd3dd1e --- /dev/null +++ b/gcc/testsuite/gcc.target/xstormy16/neghi2.c @@ -0,0 +1,8 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +short neg(short x) +{ + return -x; +} +/* { dg-final { scan-assembler "not r2 | add r2,#1" } } */ diff --git a/gcc/testsuite/gcc.target/xstormy16/rotatehi-1.c b/gcc/testsuite/gcc.target/xstormy16/rotatehi-1.c new file mode 100644 index 0000000..586e7dc --- /dev/null +++ b/gcc/testsuite/gcc.target/xstormy16/rotatehi-1.c @@ -0,0 +1,10 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +unsigned short foo(unsigned short x) +{ + return (x << 1) | (x >> 15); +} + +/* { dg-final { scan-assembler "shl r2,#1" } } */ +/* { dg-final { scan-assembler "adc r2,#0" } } */ |