public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: Tsukasa OI <research_trasio@irq.a4lg.com>
To: Tsukasa OI <research_trasio@irq.a4lg.com>,
	Kito Cheng <kito.cheng@gmail.com>,
	Palmer Dabbelt <palmer@dabbelt.com>,
	Andrew Waterman <andrew@sifive.com>,
	Jim Wilson <jim.wilson.gcc@gmail.com>,
	Jeff Law <jeffreyalaw@gmail.com>
Cc: gcc-patches@gcc.gnu.org
Subject: [RFC PATCH v2 1/1] RISC-V: Add support for 'XVentanaCondOps' reusing 'Zicond' support
Date: Wed, 30 Aug 2023 22:54:57 +0000	[thread overview]
Message-ID: <2bcc867d332705a317d7a33c77ff65b8e1fcecc4.1693436086.git.research_trasio@irq.a4lg.com> (raw)
In-Reply-To: <cover.1693436086.git.research_trasio@irq.a4lg.com>

From: Tsukasa OI <research_trasio@irq.a4lg.com>

'XVentanaCondOps' is a vendor extension from Ventana Micro Systems
containing two instructions for conditional move and will be supported on
their Veyron V1 CPU.

And most notably (for historical reasons), 'XVentanaCondOps' and the
standard 'Zicond' extension are functionally equivalent (only encodings and
instruction names are different).

*   czero.eqz == vt.maskc
*   czero.nez == vt.maskcn

This commit adds support for the 'XVentanaCondOps' extension by extending
'Zicond' extension support.  With this, we can now reuse the optimization
using the 'Zicond' extension for the 'XVentanaCondOps' extension.

The specification for the 'XVentanaCondOps' extension is based on:
<https://github.com/ventanamicro/ventana-custom-extensions/releases/download/v1.0.1/ventana-custom-extensions-v1.0.1.pdf>

gcc/ChangeLog:

	* common/config/riscv/riscv-common.cc (riscv_ext_flag_table):
	Parse 'XVentanaCondOps' extension.
	* config/riscv/riscv-opts.h (MASK_XVENTANACONDOPS): New.
	(TARGET_XVENTANACONDOPS): Ditto.
	(TARGET_ZICOND_LIKE): New to represent targets with conditional
	moves like 'Zicond'.  It includes RV64 + 'XVentanaCondOps'.
	* config/riscv/riscv.cc (riscv_rtx_costs): Replace TARGET_ZICOND
	with TARGET_ZICOND_LIKE.
	(riscv_expand_conditional_move): Ditto.
	* config/riscv/riscv.md (mov<mode>cc): Replace TARGET_ZICOND with
	TARGET_ZICOND_LIKE.
	* config/riscv/riscv.opt: Add new riscv_xventana_subext.
	* config/riscv/zicond.md: Modify description.
	(eqz_ventana): New to match corresponding czero instructions.
	(nez_ventana): Ditto.
	(*czero.<eqz>.<GPR><X>): Emit a 'XVentanaCondOps' instruction if
	'Zicond' is not available but 'XVentanaCondOps' + RV64 is.
	(*czero.<eqz>.<GPR><X>): Ditto.
	(*czero.eqz.<GPR><X>.opt1): Ditto.

gcc/testsuite/ChangeLog:

	* gcc.target/riscv/xventanacondops-primitiveSemantics.c: New test,
	modified from zicond-primitiveSemantics.c.
	* gcc.target/riscv/xventanacondops-primitiveSemantics-rv32.c: New
	test to make sure that XVentanaCondOps instructions are disabled
	on RV32.
	* gcc.target/riscv/xventanacondops-xor-01.c: New test, modified
	from zicond-xor-01.c.
---
 gcc/common/config/riscv/riscv-common.cc       |  2 +
 gcc/config/riscv/riscv-opts.h                 |  6 +++
 gcc/config/riscv/riscv.cc                     |  4 +-
 gcc/config/riscv/riscv.md                     |  2 +-
 gcc/config/riscv/riscv.opt                    |  3 ++
 gcc/config/riscv/zicond.md                    | 52 ++++++++++++-------
 .../xventanacondops-primitiveSemantics-rv32.c | 45 ++++++++++++++++
 .../xventanacondops-primitiveSemantics.c      | 48 +++++++++++++++++
 .../gcc.target/riscv/xventanacondops-xor-01.c | 14 +++++
 9 files changed, 154 insertions(+), 22 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/riscv/xventanacondops-primitiveSemantics-rv32.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xventanacondops-primitiveSemantics.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xventanacondops-xor-01.c

diff --git a/gcc/common/config/riscv/riscv-common.cc b/gcc/common/config/riscv/riscv-common.cc
index f142212f2edc..9a0a68fe5db3 100644
--- a/gcc/common/config/riscv/riscv-common.cc
+++ b/gcc/common/config/riscv/riscv-common.cc
@@ -1493,6 +1493,8 @@ static const riscv_ext_flag_table_t riscv_ext_flag_table[] =
   {"xtheadmempair", &gcc_options::x_riscv_xthead_subext, MASK_XTHEADMEMPAIR},
   {"xtheadsync",    &gcc_options::x_riscv_xthead_subext, MASK_XTHEADSYNC},
 
+  {"xventanacondops", &gcc_options::x_riscv_xventana_subext, MASK_XVENTANACONDOPS},
+
   {NULL, NULL, 0}
 };
 
diff --git a/gcc/config/riscv/riscv-opts.h b/gcc/config/riscv/riscv-opts.h
index 5ed69abd214d..a4fb0a0a5946 100644
--- a/gcc/config/riscv/riscv-opts.h
+++ b/gcc/config/riscv/riscv-opts.h
@@ -319,6 +319,12 @@ enum riscv_entity
 #define TARGET_XTHEADMEMPAIR ((riscv_xthead_subext & MASK_XTHEADMEMPAIR) != 0)
 #define TARGET_XTHEADSYNC    ((riscv_xthead_subext & MASK_XTHEADSYNC) != 0)
 
+#define MASK_XVENTANACONDOPS  (1 << 0)
+
+#define TARGET_XVENTANACONDOPS ((riscv_xventana_subext & MASK_XVENTANACONDOPS) != 0)
+
+#define TARGET_ZICOND_LIKE (TARGET_ZICOND || (TARGET_XVENTANACONDOPS && TARGET_64BIT))
+
 /* We only enable VLS modes for VLA vectorization since fixed length VLMAX mode
    is the highest priority choice and should not conflict with VLS modes.  */
 #define TARGET_VECTOR_VLS                                                      \
diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index 5dc303f89c79..89af39a08190 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -2744,7 +2744,7 @@ riscv_rtx_costs (rtx x, machine_mode mode, int outer_code, int opno ATTRIBUTE_UN
 	  *total = COSTS_N_INSNS (1);
 	  return true;
 	}
-      else if (TARGET_ZICOND
+      else if (TARGET_ZICOND_LIKE
 	       && outer_code == SET
 	       && ((GET_CODE (XEXP (x, 1)) == REG
 		    && XEXP (x, 2) == CONST0_RTX (GET_MODE (XEXP (x, 1))))
@@ -3841,7 +3841,7 @@ riscv_expand_conditional_move (rtx dest, rtx op, rtx cons, rtx alt)
 							  cond, cons, alt)));
       return true;
     }
-  else if (TARGET_ZICOND
+  else if (TARGET_ZICOND_LIKE
 	   && GET_MODE_CLASS (mode) == MODE_INT)
     {
       /* The comparison must be comparing WORD_MODE objects.   We must
diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md
index 4041875e0e35..29ce75cf280c 100644
--- a/gcc/config/riscv/riscv.md
+++ b/gcc/config/riscv/riscv.md
@@ -2580,7 +2580,7 @@
 	(if_then_else:GPR (match_operand 1 "comparison_operator")
 			  (match_operand:GPR 2 "sfb_alu_operand")
 			  (match_operand:GPR 3 "sfb_alu_operand")))]
-  "TARGET_SFB_ALU || TARGET_XTHEADCONDMOV || TARGET_ZICOND"
+  "TARGET_SFB_ALU || TARGET_XTHEADCONDMOV || TARGET_ZICOND_LIKE"
 {
   if (riscv_expand_conditional_move (operands[0], operands[1],
 				     operands[2], operands[3]))
diff --git a/gcc/config/riscv/riscv.opt b/gcc/config/riscv/riscv.opt
index d2407c3c5021..a3bb3ad3089d 100644
--- a/gcc/config/riscv/riscv.opt
+++ b/gcc/config/riscv/riscv.opt
@@ -257,6 +257,9 @@ int riscv_ztso_subext
 TargetVariable
 int riscv_xthead_subext
 
+TargetVariable
+int riscv_xventana_subext
+
 Enum
 Name(isa_spec_class) Type(enum riscv_isa_spec_class)
 Supported ISA specs (for use with the -misa-spec= option):
diff --git a/gcc/config/riscv/zicond.md b/gcc/config/riscv/zicond.md
index 4619220ef8ac..404fbebabf08 100644
--- a/gcc/config/riscv/zicond.md
+++ b/gcc/config/riscv/zicond.md
@@ -1,4 +1,5 @@
-;; Machine description for the RISC-V Zicond extension
+;; Machine description for the RISC-V Zicond extension and functionally-
+;; equivalent XVentanaCondOps vendor extension
 ;; Copyright (C) 2022-23 Free Software Foundation, Inc.
 
 ;; This file is part of GCC.
@@ -20,6 +21,8 @@
 (define_code_iterator eq_or_ne [eq ne])
 (define_code_attr eqz [(eq "nez") (ne "eqz")])
 (define_code_attr nez [(eq "eqz") (ne "nez")])
+(define_code_attr eqz_ventana [(eq "maskcn") (ne "maskc")])
+(define_code_attr nez_ventana [(eq "maskc") (ne "maskcn")])
 
 ;; Zicond
 (define_insn "*czero.<eqz>.<GPR:mode><X:mode>"
@@ -28,8 +31,15 @@
                                     (const_int 0))
                           (match_operand:GPR 2 "register_operand"    "r")
                           (const_int 0)))]
-  "TARGET_ZICOND"
-  "czero.<eqz>\t%0,%2,%1"
+  "TARGET_ZICOND_LIKE"
+  {
+    if (TARGET_ZICOND)
+      return "czero.<eqz>\t%0,%2,%1";
+    else if (TARGET_XVENTANACONDOPS && TARGET_64BIT)
+      return "vt.<eqz_ventana>\t%0,%2,%1";
+    else
+      gcc_unreachable ();
+  }
 )
 
 (define_insn "*czero.<nez>.<GPR:mode><X:mode>"
@@ -38,8 +48,15 @@
                                     (const_int 0))
                           (const_int 0)
                           (match_operand:GPR 2 "register_operand"   "r")))]
-  "TARGET_ZICOND"
-  "czero.<nez>\t%0,%2,%1"
+  "TARGET_ZICOND_LIKE"
+  {
+    if (TARGET_ZICOND)
+      return "czero.<nez>\t%0,%2,%1";
+    else if (TARGET_XVENTANACONDOPS && TARGET_64BIT)
+      return "vt.<nez_ventana>\t%0,%2,%1";
+    else
+      gcc_unreachable ();
+  }
 )
 
 ;; Special optimization under eq/ne in primitive semantics
@@ -49,18 +66,15 @@
                               (const_int 0))
                           (match_operand:GPR 2 "register_operand" "1")
                           (match_operand:GPR 3 "register_operand" "r")))]
-  "TARGET_ZICOND && rtx_equal_p (operands[1], operands[2])"
-  "czero.eqz\t%0,%3,%1"
-)
-
-(define_insn "*czero.nez.<GPR:mode><X:mode>.opt2"
-  [(set (match_operand:GPR 0 "register_operand"                   "=r")
-        (if_then_else:GPR (ne (match_operand:X 1 "register_operand" "r")
-                              (const_int 0))
-                          (match_operand:GPR 2 "register_operand" "r")
-                          (match_operand:GPR 3 "register_operand" "1")))]
-  "TARGET_ZICOND && rtx_equal_p (operands[1], operands[3])"
-  "czero.nez\t%0,%2,%1"
+  "TARGET_ZICOND_LIKE && rtx_equal_p (operands[1], operands[2])"
+  {
+    if (TARGET_ZICOND)
+      return "czero.eqz\t%0,%3,%1";
+    else if (TARGET_XVENTANACONDOPS && TARGET_64BIT)
+      return "vt.maskc\t%0,%3,%1";
+    else
+      gcc_unreachable ();
+  }
 )
 
 ;; Combine creates this form in some cases (particularly the coremark
@@ -72,7 +86,7 @@
 			       (match_operand 2 "immediate_operand"))
 	       (match_operand:X 3 "register_operand")))
    (clobber (match_operand:X 4 "register_operand"))]
-  "TARGET_ZICOND && TARGET_ZBS"
+  "TARGET_ZICOND_LIKE && TARGET_ZBS"
   [(set (match_dup 4) (zero_extract:X (match_dup 1) (const_int 1) (match_dup 2)))
    (set (match_dup 0) (if_then_else:X (eq:X (match_dup 4) (const_int 0))
 				      (const_int 0)
@@ -85,7 +99,7 @@
 			       (match_operand 2 "immediate_operand"))
 	       (match_operand:X 3 "register_operand")))
    (clobber (match_operand:X 4 "register_operand"))]
-  "TARGET_ZICOND && !TARGET_ZBS && (UINTVAL (operands[2]) < 11)"
+  "TARGET_ZICOND_LIKE && !TARGET_ZBS && (UINTVAL (operands[2]) < 11)"
   [(set (match_dup 4) (and:X (match_dup 1) (match_dup 2)))
    (set (match_dup 0) (if_then_else:X (eq:X (match_dup 4) (const_int 0))
 				      (const_int 0)
diff --git a/gcc/testsuite/gcc.target/riscv/xventanacondops-primitiveSemantics-rv32.c b/gcc/testsuite/gcc.target/riscv/xventanacondops-primitiveSemantics-rv32.c
new file mode 100644
index 000000000000..992f1425c54f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/xventanacondops-primitiveSemantics-rv32.c
@@ -0,0 +1,45 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv32gc_xventanacondops -mabi=ilp32d" } */
+
+long primitiveSemantics_00(long a, long b) { return a == 0 ? 0 : b; }
+
+long primitiveSemantics_01(long a, long b) { return a != 0 ? 0 : b; }
+
+long primitiveSemantics_02(long a, long b) { return a == 0 ? b : 0; }
+
+long primitiveSemantics_03(long a, long b) { return a != 0 ? b : 0; }
+
+long primitiveSemantics_04(long a, long b) {
+  if (a)
+    b = 0;
+  return b;
+}
+
+long primitiveSemantics_05(long a, long b) {
+  if (!a)
+    b = 0;
+  return b;
+}
+
+int primitiveSemantics_06(int a, int b) { return a == 0 ? 0 : b; }
+
+int primitiveSemantics_07(int a, int b) { return a != 0 ? 0 : b; }
+
+int primitiveSemantics_08(int a, int b) { return a == 0 ? b : 0; }
+
+int primitiveSemantics_09(int a, int b) { return a != 0 ? b : 0; }
+
+int primitiveSemantics_10(int a, int b) {
+  if (a)
+    b = 0;
+  return b;
+}
+
+int primitiveSemantics_11(int a, int b) {
+  if (!a)
+    b = 0;
+  return b;
+}
+
+/* { dg-final { scan-assembler-not "vt\\.maskc\t" } } */
+/* { dg-final { scan-assembler-not "vt\\.maskcn\t" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/xventanacondops-primitiveSemantics.c b/gcc/testsuite/gcc.target/riscv/xventanacondops-primitiveSemantics.c
new file mode 100644
index 000000000000..04947de6156b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/xventanacondops-primitiveSemantics.c
@@ -0,0 +1,48 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_xventanacondops -mabi=lp64d" } */
+/* { dg-skip-if "" { *-*-* } {"-O0" "-Og"} } */
+
+long primitiveSemantics_00(long a, long b) { return a == 0 ? 0 : b; }
+
+long primitiveSemantics_01(long a, long b) { return a != 0 ? 0 : b; }
+
+long primitiveSemantics_02(long a, long b) { return a == 0 ? b : 0; }
+
+long primitiveSemantics_03(long a, long b) { return a != 0 ? b : 0; }
+
+long primitiveSemantics_04(long a, long b) {
+  if (a)
+    b = 0;
+  return b;
+}
+
+long primitiveSemantics_05(long a, long b) {
+  if (!a)
+    b = 0;
+  return b;
+}
+
+int primitiveSemantics_06(int a, int b) { return a == 0 ? 0 : b; }
+
+int primitiveSemantics_07(int a, int b) { return a != 0 ? 0 : b; }
+
+int primitiveSemantics_08(int a, int b) { return a == 0 ? b : 0; }
+
+int primitiveSemantics_09(int a, int b) { return a != 0 ? b : 0; }
+
+int primitiveSemantics_10(int a, int b) {
+  if (a)
+    b = 0;
+  return b;
+}
+
+int primitiveSemantics_11(int a, int b) {
+  if (!a)
+    b = 0;
+  return b;
+}
+
+/* { dg-final { scan-assembler-times "vt\\.maskc\t" 6 } } */
+/* { dg-final { scan-assembler-times "vt\\.maskcn\t" 6 } } */
+/* { dg-final { scan-assembler-not "beq" } } */
+/* { dg-final { scan-assembler-not "bne" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/xventanacondops-xor-01.c b/gcc/testsuite/gcc.target/riscv/xventanacondops-xor-01.c
new file mode 100644
index 000000000000..c2f0dc041cb1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/xventanacondops-xor-01.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_xventanacondops -mabi=lp64d" } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-Os" "-Oz" } } */
+
+long xor1(long crc, long poly)
+{
+  if (crc & 1)
+    crc ^= poly;
+
+  return crc;
+}
+
+/* { dg-final { scan-assembler-times "vt\\.maskc\t" 1 } } */
+/* { dg-final { scan-assembler-times "xor\t" 1 } } */
-- 
2.42.0


  reply	other threads:[~2023-08-30 22:55 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-08-30  6:44 [RFC PATCH] " Tsukasa OI
2023-08-30 22:54 ` [RFC PATCH v2 0/1] " Tsukasa OI
2023-08-30 22:54   ` Tsukasa OI [this message]
2023-09-05 12:10   ` [PATCH v3 " Tsukasa OI
2023-09-05 12:10     ` [PATCH v3 1/1] " Tsukasa OI
2023-09-06  0:17       ` Jeff Law
2023-09-06  2:33         ` Tsukasa OI
2023-09-06  3:07           ` Jeff Law
2023-09-06  3:16             ` Palmer Dabbelt
2023-09-06  5:47     ` [PATCH v4 0/1] " Tsukasa OI
2023-09-06  5:47       ` [PATCH v4 1/1] " Tsukasa OI
2023-09-06 14:04         ` Jeff Law

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=2bcc867d332705a317d7a33c77ff65b8e1fcecc4.1693436086.git.research_trasio@irq.a4lg.com \
    --to=research_trasio@irq.a4lg.com \
    --cc=andrew@sifive.com \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=jeffreyalaw@gmail.com \
    --cc=jim.wilson.gcc@gmail.com \
    --cc=kito.cheng@gmail.com \
    --cc=palmer@dabbelt.com \
    /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).