[4/4,RISC-V] support cm.mva01s cm.mvsa01 in zcmp

Message ID 20230607055215.29332-5-gaofei@eswincomputing.com
State Dropped
Delegated to: Kito Cheng
Headers
Series support zcmp extention |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_gcc_build--master-aarch64 success Testing passed
linaro-tcwg-bot/tcwg_gcc_build--master-arm success Testing passed

Commit Message

Fei Gao June 7, 2023, 5:52 a.m. UTC
  From: Die Li <lidie@eswincomputing.com>

Signed-off-by: Die Li <lidie@eswincomputing.com>
Co-Authored-By: Fei Gao <gaofei@eswincomputing.com>

gcc/ChangeLog:

        * config/riscv/peephole.md: New pattern.
        * config/riscv/predicates.md (a0a1_reg_operand): New predicate.
        (zcmp_mv_sreg_operand): New predicate.
        * config/riscv/riscv.md: New predicate.
        * config/riscv/zc.md (*mva01s<X:mode>): New pattern.
        (*mvsa01<X:mode>): New pattern.

gcc/testsuite/ChangeLog:

        * gcc.target/riscv/cm_mv_rv32.c: New test.
---
 gcc/config/riscv/peephole.md                | 28 +++++++++++++++++++++
 gcc/config/riscv/predicates.md              | 11 ++++++++
 gcc/config/riscv/riscv.md                   |  1 +
 gcc/config/riscv/zc.md                      | 22 ++++++++++++++++
 gcc/testsuite/gcc.target/riscv/cm_mv_rv32.c | 21 ++++++++++++++++
 5 files changed, 83 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/riscv/cm_mv_rv32.c
  

Comments

Kito Cheng July 13, 2023, 8:18 a.m. UTC | #1
LGTM, thanks, just like other zc* patches, I would like to defer this
until the binutils part landed :)

On Wed, Jun 7, 2023 at 1:54 PM Fei Gao <gaofei@eswincomputing.com> wrote:
>
> From: Die Li <lidie@eswincomputing.com>
>
> Signed-off-by: Die Li <lidie@eswincomputing.com>
> Co-Authored-By: Fei Gao <gaofei@eswincomputing.com>
>
> gcc/ChangeLog:
>
>         * config/riscv/peephole.md: New pattern.
>         * config/riscv/predicates.md (a0a1_reg_operand): New predicate.
>         (zcmp_mv_sreg_operand): New predicate.
>         * config/riscv/riscv.md: New predicate.
>         * config/riscv/zc.md (*mva01s<X:mode>): New pattern.
>         (*mvsa01<X:mode>): New pattern.
>
> gcc/testsuite/ChangeLog:
>
>         * gcc.target/riscv/cm_mv_rv32.c: New test.
> ---
>  gcc/config/riscv/peephole.md                | 28 +++++++++++++++++++++
>  gcc/config/riscv/predicates.md              | 11 ++++++++
>  gcc/config/riscv/riscv.md                   |  1 +
>  gcc/config/riscv/zc.md                      | 22 ++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/cm_mv_rv32.c | 21 ++++++++++++++++
>  5 files changed, 83 insertions(+)
>  create mode 100644 gcc/testsuite/gcc.target/riscv/cm_mv_rv32.c
>
> diff --git a/gcc/config/riscv/peephole.md b/gcc/config/riscv/peephole.md
> index 67e7046d7e6..e8cb1ba4838 100644
> --- a/gcc/config/riscv/peephole.md
> +++ b/gcc/config/riscv/peephole.md
> @@ -94,3 +94,31 @@
>  {
>    th_mempair_order_operands (operands, true, SImode);
>  })
> +
> +;; ZCMP
> +(define_peephole2
> +  [(set (match_operand:X 0 "a0a1_reg_operand")
> +        (match_operand:X 1 "zcmp_mv_sreg_operand"))
> +   (set (match_operand:X 2 "a0a1_reg_operand")
> +        (match_operand:X 3 "zcmp_mv_sreg_operand"))]
> +  "TARGET_ZCMP
> +   && (REGNO (operands[2]) != REGNO (operands[0]))"
> +  [(parallel [(set (match_dup 0)
> +                   (match_dup 1))
> +              (set (match_dup 2)
> +                   (match_dup 3))])]
> +)
> +
> +(define_peephole2
> +  [(set (match_operand:X 0 "zcmp_mv_sreg_operand")
> +        (match_operand:X 1 "a0a1_reg_operand"))
> +   (set (match_operand:X 2 "zcmp_mv_sreg_operand")
> +        (match_operand:X 3 "a0a1_reg_operand"))]
> +  "TARGET_ZCMP
> +   && (REGNO (operands[0]) != REGNO (operands[2]))
> +   && (REGNO (operands[1]) != REGNO (operands[3]))"
> +  [(parallel [(set (match_dup 0)
> +                   (match_dup 1))
> +              (set (match_dup 2)
> +                   (match_dup 3))])]
> +)
> diff --git a/gcc/config/riscv/predicates.md b/gcc/config/riscv/predicates.md
> index a1b9367b997..6d5e8630cb5 100644
> --- a/gcc/config/riscv/predicates.md
> +++ b/gcc/config/riscv/predicates.md
> @@ -207,6 +207,17 @@
>    (and (match_code "const_int")
>         (match_test "riscv_zcmp_valid_stack_adj_bytes_p (INTVAL (op), 13)")))
>
> +;; ZCMP predicates
> +(define_predicate "a0a1_reg_operand"
> +  (and (match_operand 0 "register_operand")
> +       (match_test "IN_RANGE (REGNO (op), A0_REGNUM, A1_REGNUM)")))
> +
> +(define_predicate "zcmp_mv_sreg_operand"
> +  (and (match_operand 0 "register_operand")
> +       (match_test "TARGET_RVE ? IN_RANGE (REGNO (op), S0_REGNUM, S1_REGNUM)
> +                    : IN_RANGE (REGNO (op), S0_REGNUM, S1_REGNUM)
> +                    || IN_RANGE (REGNO (op), S2_REGNUM, S7_REGNUM)")))
> +
>  ;; Only use branch-on-bit sequences when the mask is not an ANDI immediate.
>  (define_predicate "branch_on_bit_operand"
>    (and (match_code "const_int")
> diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md
> index 02802d2685d..25bc3e6ab4c 100644
> --- a/gcc/config/riscv/riscv.md
> +++ b/gcc/config/riscv/riscv.md
> @@ -121,6 +121,7 @@
>     (S0_REGNUM                  8)
>     (S1_REGNUM                  9)
>     (A0_REGNUM                  10)
> +   (A1_REGNUM                  11)
>     (S2_REGNUM                  18)
>     (S3_REGNUM                  19)
>     (S4_REGNUM                  20)
> diff --git a/gcc/config/riscv/zc.md b/gcc/config/riscv/zc.md
> index 217e115035b..bb4975cd333 100644
> --- a/gcc/config/riscv/zc.md
> +++ b/gcc/config/riscv/zc.md
> @@ -1433,3 +1433,25 @@
>    "TARGET_ZCMP"
>    "cm.push     {ra, s0-s11}, %0"
>  )
> +
> +;; ZCMP mv
> +(define_insn "*mva01s<X:mode>"
> +  [(set (match_operand:X 0 "a0a1_reg_operand" "=r")
> +        (match_operand:X 1 "zcmp_mv_sreg_operand" "r"))
> +   (set (match_operand:X 2 "a0a1_reg_operand" "=r")
> +        (match_operand:X 3 "zcmp_mv_sreg_operand" "r"))]
> +  "TARGET_ZCMP
> +   && (REGNO (operands[2]) != REGNO (operands[0]))"
> +  { return (REGNO (operands[0]) == A0_REGNUM)?"cm.mva01s\t%1,%3":"cm.mva01s\t%3,%1"; }
> +  [(set_attr "mode" "<X:MODE>")])
> +
> +(define_insn "*mvsa01<X:mode>"
> +  [(set (match_operand:X 0 "zcmp_mv_sreg_operand" "=r")
> +        (match_operand:X 1 "a0a1_reg_operand" "r"))
> +   (set (match_operand:X 2 "zcmp_mv_sreg_operand" "=r")
> +        (match_operand:X 3 "a0a1_reg_operand" "r"))]
> +  "TARGET_ZCMP
> +   && (REGNO (operands[0]) != REGNO (operands[2]))
> +   && (REGNO (operands[1]) != REGNO (operands[3]))"
> +  { return (REGNO (operands[1]) == A0_REGNUM)?"cm.mvsa01\t%0,%2":"cm.mvsa01\t%2,%0"; }
> +  [(set_attr "mode" "<X:MODE>")])
> diff --git a/gcc/testsuite/gcc.target/riscv/cm_mv_rv32.c b/gcc/testsuite/gcc.target/riscv/cm_mv_rv32.c
> new file mode 100644
> index 00000000000..49c94c01603
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/cm_mv_rv32.c
> @@ -0,0 +1,21 @@
> +/* { dg-do compile } */
> +/* { dg-options " -Os -march=rv32i_zca_zcmp -mabi=ilp32 " } */
> +/* { dg-skip-if "" { *-*-* } {"-O0" "-O1" "-O2" "-Og" "-O3" "-Oz" "-flto"} } */
> +/* { dg-final { check-function-bodies "**" "" } } */
> +
> +int func (int a, int b);
> +
> +/*
> +**sum:
> +**     ...
> +**     cm.mvsa01       s1,s2
> +**     call    func
> +**     mv      s0,a0
> +**     cm.mva01s       s1,s2
> +**     call    func
> +**     ...
> +*/
> +int sum (int a, int b)
> +{
> +        return func (a, b) + func (a, b);
> +}
> --
> 2.17.1
>
  

Patch

diff --git a/gcc/config/riscv/peephole.md b/gcc/config/riscv/peephole.md
index 67e7046d7e6..e8cb1ba4838 100644
--- a/gcc/config/riscv/peephole.md
+++ b/gcc/config/riscv/peephole.md
@@ -94,3 +94,31 @@ 
 {
   th_mempair_order_operands (operands, true, SImode);
 })
+
+;; ZCMP
+(define_peephole2
+  [(set (match_operand:X 0 "a0a1_reg_operand")
+        (match_operand:X 1 "zcmp_mv_sreg_operand"))
+   (set (match_operand:X 2 "a0a1_reg_operand")
+        (match_operand:X 3 "zcmp_mv_sreg_operand"))]
+  "TARGET_ZCMP
+   && (REGNO (operands[2]) != REGNO (operands[0]))"
+  [(parallel [(set (match_dup 0)
+                   (match_dup 1))
+              (set (match_dup 2)
+                   (match_dup 3))])]
+)
+
+(define_peephole2
+  [(set (match_operand:X 0 "zcmp_mv_sreg_operand")
+        (match_operand:X 1 "a0a1_reg_operand"))
+   (set (match_operand:X 2 "zcmp_mv_sreg_operand")
+        (match_operand:X 3 "a0a1_reg_operand"))]
+  "TARGET_ZCMP
+   && (REGNO (operands[0]) != REGNO (operands[2]))
+   && (REGNO (operands[1]) != REGNO (operands[3]))"
+  [(parallel [(set (match_dup 0)
+                   (match_dup 1))
+              (set (match_dup 2)
+                   (match_dup 3))])]
+)
diff --git a/gcc/config/riscv/predicates.md b/gcc/config/riscv/predicates.md
index a1b9367b997..6d5e8630cb5 100644
--- a/gcc/config/riscv/predicates.md
+++ b/gcc/config/riscv/predicates.md
@@ -207,6 +207,17 @@ 
   (and (match_code "const_int")
        (match_test "riscv_zcmp_valid_stack_adj_bytes_p (INTVAL (op), 13)")))
 
+;; ZCMP predicates
+(define_predicate "a0a1_reg_operand"
+  (and (match_operand 0 "register_operand")
+       (match_test "IN_RANGE (REGNO (op), A0_REGNUM, A1_REGNUM)")))
+
+(define_predicate "zcmp_mv_sreg_operand"
+  (and (match_operand 0 "register_operand")
+       (match_test "TARGET_RVE ? IN_RANGE (REGNO (op), S0_REGNUM, S1_REGNUM)
+                    : IN_RANGE (REGNO (op), S0_REGNUM, S1_REGNUM)
+                    || IN_RANGE (REGNO (op), S2_REGNUM, S7_REGNUM)")))
+
 ;; Only use branch-on-bit sequences when the mask is not an ANDI immediate.
 (define_predicate "branch_on_bit_operand"
   (and (match_code "const_int")
diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md
index 02802d2685d..25bc3e6ab4c 100644
--- a/gcc/config/riscv/riscv.md
+++ b/gcc/config/riscv/riscv.md
@@ -121,6 +121,7 @@ 
    (S0_REGNUM			8)
    (S1_REGNUM			9)
    (A0_REGNUM			10)
+   (A1_REGNUM			11)
    (S2_REGNUM			18)
    (S3_REGNUM			19)
    (S4_REGNUM			20)
diff --git a/gcc/config/riscv/zc.md b/gcc/config/riscv/zc.md
index 217e115035b..bb4975cd333 100644
--- a/gcc/config/riscv/zc.md
+++ b/gcc/config/riscv/zc.md
@@ -1433,3 +1433,25 @@ 
   "TARGET_ZCMP"
   "cm.push	{ra, s0-s11}, %0"
 )
+
+;; ZCMP mv
+(define_insn "*mva01s<X:mode>"
+  [(set (match_operand:X 0 "a0a1_reg_operand" "=r")
+        (match_operand:X 1 "zcmp_mv_sreg_operand" "r"))
+   (set (match_operand:X 2 "a0a1_reg_operand" "=r")
+        (match_operand:X 3 "zcmp_mv_sreg_operand" "r"))]
+  "TARGET_ZCMP
+   && (REGNO (operands[2]) != REGNO (operands[0]))"
+  { return (REGNO (operands[0]) == A0_REGNUM)?"cm.mva01s\t%1,%3":"cm.mva01s\t%3,%1"; }
+  [(set_attr "mode" "<X:MODE>")])
+
+(define_insn "*mvsa01<X:mode>"
+  [(set (match_operand:X 0 "zcmp_mv_sreg_operand" "=r")
+        (match_operand:X 1 "a0a1_reg_operand" "r"))
+   (set (match_operand:X 2 "zcmp_mv_sreg_operand" "=r")
+        (match_operand:X 3 "a0a1_reg_operand" "r"))]
+  "TARGET_ZCMP
+   && (REGNO (operands[0]) != REGNO (operands[2]))
+   && (REGNO (operands[1]) != REGNO (operands[3]))"
+  { return (REGNO (operands[1]) == A0_REGNUM)?"cm.mvsa01\t%0,%2":"cm.mvsa01\t%2,%0"; }
+  [(set_attr "mode" "<X:MODE>")])
diff --git a/gcc/testsuite/gcc.target/riscv/cm_mv_rv32.c b/gcc/testsuite/gcc.target/riscv/cm_mv_rv32.c
new file mode 100644
index 00000000000..49c94c01603
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/cm_mv_rv32.c
@@ -0,0 +1,21 @@ 
+/* { dg-do compile } */
+/* { dg-options " -Os -march=rv32i_zca_zcmp -mabi=ilp32 " } */
+/* { dg-skip-if "" { *-*-* } {"-O0" "-O1" "-O2" "-Og" "-O3" "-Oz" "-flto"} } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+int func (int a, int b);
+
+/*
+**sum:
+**	...
+**	cm.mvsa01	s1,s2
+**	call	func
+**	mv	s0,a0
+**	cm.mva01s	s1,s2
+**	call	func
+**	...
+*/
+int sum (int a, int b)
+{
+        return func (a, b) + func (a, b);
+}