public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
From: Roger Sayle <sayle@gcc.gnu.org>
To: gcc-cvs@gcc.gnu.org
Subject: [gcc r14-245] [xstormy16] Add support for byte and word swapping instructions.
Date: Wed, 26 Apr 2023 08:11:23 +0000 (GMT)	[thread overview]
Message-ID: <20230426081123.318493858CDA@sourceware.org> (raw)

https://gcc.gnu.org/g:1f0bfbb26e532cef7347a91439008114fd88173a

commit r14-245-g1f0bfbb26e532cef7347a91439008114fd88173a
Author: Roger Sayle <roger@nextmovesoftware.com>
Date:   Wed Apr 26 09:10:06 2023 +0100

    [xstormy16] Add support for byte and word swapping instructions.
    
    This patch adds support for xstormy16's swpb (swap bytes) and swpw (swap
    words) instructions.  The most obvious application of these to implement
    the __builtin_bswap16 and __builtin_bswap32 intrinsics.
    
    Currently, __builtin_bswap16 is implemented as:
    foo:    mov r7,r2
            shl r7,#8
            shr r2,#8
            or r2,r7
            ret
    
    but with this patch becomes:
    foo:    swpb r2
            ret
    
    Likewise, __builtin_bswap32 now becomes:
    foo:    swpb r2 | swpb r3 | swpw r2,r3
            ret
    
    Finally, the swpw instruction on its own can be used to exchange
    two word mode registers without a temporary, so a new pattern and
    peephole2 have been added to catch this.  As described in the
    PR rtl-optimization/106518, register allocation can (in theory)
    be more efficient on targets that provide a swap/exchange instruction.
    The slightly unusual swap<mode> naming matches that used in i386.md.
    
    2024-04-26  Roger Sayle  <roger@nextmovesoftware.com>
    
    gcc/ChangeLog
            * config/stormy16/stormy16.md (bswaphi2): New define_insn.
            (bswapsi2): New define_insn.
            (swaphi): New define_insn to exchange two registers (swpw).
            (define_peephole2): Recognize exchange of registers as swaphi.
    
    gcc/testsuite/ChangeLog
            * gcc.target/xstormy16/bswap16.c: New test case.
            * gcc.target/xstormy16/bswap32.c: Likewise.
            * gcc.target/xstormy16/swpb.c: Likewise.
            * gcc.target/xstormy16/swpw-1.c: Likewise.
            * gcc.target/xstormy16/swpw-2.c: Likewise.

Diff:
---
 gcc/config/stormy16/stormy16.md              | 36 ++++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/xstormy16/bswap16.c |  9 +++++++
 gcc/testsuite/gcc.target/xstormy16/bswap32.c |  9 +++++++
 gcc/testsuite/gcc.target/xstormy16/swpb.c    |  9 +++++++
 gcc/testsuite/gcc.target/xstormy16/swpw-1.c  |  8 +++++++
 gcc/testsuite/gcc.target/xstormy16/swpw-2.c  | 14 +++++++++++
 6 files changed, 85 insertions(+)

diff --git a/gcc/config/stormy16/stormy16.md b/gcc/config/stormy16/stormy16.md
index 9d92492c748..b2e86ee84fc 100644
--- a/gcc/config/stormy16/stormy16.md
+++ b/gcc/config/stormy16/stormy16.md
@@ -1265,3 +1265,39 @@
   "bp %1,#7,%l0"
   [(set_attr "length" "4")
    (set_attr "psw_operand" "nop")])
+
+(define_insn "bswaphi2"
+  [(set (match_operand:HI 0 "register_operand" "=r")
+	(bswap:HI (match_operand:HI 1 "register_operand" "0")))]
+  ""
+  "swpb %0")
+
+(define_insn "bswapsi2"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+	(bswap:SI (match_operand:SI 1 "register_operand" "0")))]
+  ""
+  "swpb %0 | swpb %h0 | swpw %0,%h0"
+  [(set_attr "length" "6")])
+
+(define_insn "swaphi"
+  [(set (match_operand:HI 0 "register_operand" "+r")
+	(match_operand:HI 1 "register_operand" "+r"))
+   (set (match_dup 1)
+	(match_dup 0))]
+  ""
+  "swpw %0,%1")
+
+(define_peephole2
+  [(set (match_operand:HI 0 "register_operand")
+	(match_operand:HI 1 "register_operand"))
+   (set (match_dup 1)
+	(match_operand:HI 2 "register_operand"))
+   (set (match_dup 2)
+	(match_dup 0))]
+  "REGNO (operands[0]) != REGNO (operands[1])
+   && REGNO (operands[0]) != REGNO (operands[2])
+   && REGNO (operands[1]) != REGNO (operands[2])
+   && peep2_reg_dead_p (3, operands[0])"
+  [(parallel [(set (match_dup 2) (match_dup 1))
+              (set (match_dup 1) (match_dup 2))])])
+
diff --git a/gcc/testsuite/gcc.target/xstormy16/bswap16.c b/gcc/testsuite/gcc.target/xstormy16/bswap16.c
new file mode 100644
index 00000000000..cf6795fabda
--- /dev/null
+++ b/gcc/testsuite/gcc.target/xstormy16/bswap16.c
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+unsigned short foo(unsigned short x)
+{
+  return __builtin_bswap16 (x);
+}
+
+/* { dg-final { scan-assembler "swpb r2" } } */
diff --git a/gcc/testsuite/gcc.target/xstormy16/bswap32.c b/gcc/testsuite/gcc.target/xstormy16/bswap32.c
new file mode 100644
index 00000000000..3287e4d8834
--- /dev/null
+++ b/gcc/testsuite/gcc.target/xstormy16/bswap32.c
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+unsigned long foo(unsigned long x)
+{
+  return __builtin_bswap32 (x);
+}
+
+/* { dg-final { scan-assembler "swpb" } } */
diff --git a/gcc/testsuite/gcc.target/xstormy16/swpb.c b/gcc/testsuite/gcc.target/xstormy16/swpb.c
new file mode 100644
index 00000000000..8ea8ff7445b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/xstormy16/swpb.c
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+unsigned short foo(unsigned short x)
+{
+  return (x>>8) | (x<<8);
+}
+
+/* { dg-final { scan-assembler "swpb r2" } } */
diff --git a/gcc/testsuite/gcc.target/xstormy16/swpw-1.c b/gcc/testsuite/gcc.target/xstormy16/swpw-1.c
new file mode 100644
index 00000000000..bde540d9ded
--- /dev/null
+++ b/gcc/testsuite/gcc.target/xstormy16/swpw-1.c
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+void ext(int x, int y);
+
+void foo(int x, int y) { ext(y,x); }
+
+/* { dg-final { scan-assembler "swpw r3,r2" } } */
diff --git a/gcc/testsuite/gcc.target/xstormy16/swpw-2.c b/gcc/testsuite/gcc.target/xstormy16/swpw-2.c
new file mode 100644
index 00000000000..b8d637b6416
--- /dev/null
+++ b/gcc/testsuite/gcc.target/xstormy16/swpw-2.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+void ext(int x, int y);
+
+void foo(int x, int y)
+{
+  int t1 = x ^ y;
+  int t2 = t1 ^ x;
+  int t3 = t1 ^ y;
+  ext(t2,t3);
+}
+
+/* { dg-final { scan-assembler "swpw r3,r2" } } */

                 reply	other threads:[~2023-04-26  8:11 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20230426081123.318493858CDA@sourceware.org \
    --to=sayle@gcc.gnu.org \
    --cc=gcc-cvs@gcc.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).